From cbaf56cbb3849e4e86882e88376fb714e20c6b3e Mon Sep 17 00:00:00 2001 From: MrJeremyFisher Date: Fri, 21 Jun 2024 17:51:55 -0400 Subject: [PATCH] Format --- plugins/.editorconfig | 2 +- plugins/banstick-paper/README.md | 18 +- plugins/banstick-paper/build.gradle.kts | 18 +- .../minecraft/banstick/BanStick.java | 416 +- .../commands/BanRegistrarCommand.java | 81 +- .../banstick/commands/BanSaveCommand.java | 16 +- .../banstick/commands/BanStickCommand.java | 285 +- .../banstick/commands/DoubleTapCommand.java | 420 +- .../banstick/commands/DowsingRodCommand.java | 303 +- .../banstick/commands/DrillDownCommand.java | 730 +-- .../banstick/commands/ForgiveCommand.java | 525 +- .../banstick/commands/GetAltsCommand.java | 79 +- .../banstick/commands/LoveTapCommand.java | 676 +- .../banstick/commands/TakeItBackCommand.java | 314 +- .../banstick/commands/UntangleCommand.java | 207 +- .../banstick/commands/package-info.java | 3 +- .../banstick/containers/BanResult.java | 133 +- .../banstick/containers/package-info.java | 3 +- .../minecraft/banstick/data/BSBan.java | 1445 ++--- .../minecraft/banstick/data/BSExclusion.java | 499 +- .../minecraft/banstick/data/BSExclusions.java | 215 +- .../minecraft/banstick/data/BSIP.java | 1226 ++-- .../minecraft/banstick/data/BSIPData.java | 1500 ++--- .../minecraft/banstick/data/BSIPs.java | 241 +- .../minecraft/banstick/data/BSLog.java | 248 +- .../minecraft/banstick/data/BSPlayer.java | 1359 ++-- .../minecraft/banstick/data/BSRegistrars.java | 214 +- .../minecraft/banstick/data/BSSession.java | 716 +- .../minecraft/banstick/data/BSSessions.java | 217 +- .../minecraft/banstick/data/BSShare.java | 891 +-- .../minecraft/banstick/data/BSShares.java | 615 +- .../minecraft/banstick/data/package-info.java | 2 +- .../banstick/handler/BanHandler.java | 684 +- .../handler/BanStickCommandHandler.java | 51 +- .../handler/BanStickDatabaseHandler.java | 761 +-- .../handler/BanStickEventHandler.java | 1082 ++-- .../handler/BanStickIPDataHandler.java | 705 +- .../handler/BanStickIPHubHandler.java | 642 +- .../handler/BanStickImportHandler.java | 130 +- .../handler/BanStickProxyHandler.java | 139 +- .../handler/BanStickScrapeHandler.java | 136 +- .../banstick/handler/BanStickTorUpdater.java | 364 +- .../banstick/handler/ImportWorker.java | 111 +- .../banstick/handler/ProxyLoader.java | 125 +- .../banstick/handler/ScraperWorker.java | 384 +- .../banstick/handler/package-info.java | 7 +- .../importer/IpCheckImportWorker.java | 533 +- .../banstick/proxy/Cloud9ProxyLoader.java | 318 +- .../banstick/scraper/ScrapeFreeProxyList.java | 234 +- .../src/main/resources/plugin.yml | 16 +- plugins/bastion-paper/README.md | 111 +- plugins/bastion-paper/build.gradle.kts | 14 +- .../src/main/java/isaac/bastion/Bastion.java | 251 +- .../main/java/isaac/bastion/BastionBlock.java | 814 +-- .../main/java/isaac/bastion/BastionGroup.java | 45 +- .../main/java/isaac/bastion/BastionType.java | 1125 ++-- .../java/isaac/bastion/CommonSettings.java | 53 +- .../main/java/isaac/bastion/Permissions.java | 11 +- .../commands/BastionCommandManager.java | 66 +- .../bastion/commands/ModeChangeCommand.java | 70 +- .../isaac/bastion/commands/PlayersStates.java | 100 +- .../bastion/event/BastionCreateEvent.java | 109 +- .../bastion/event/BastionDamageEvent.java | 156 +- .../bastion/event/BastionDestroyedEvent.java | 65 +- .../listeners/BastionBreakListener.java | 287 +- .../listeners/BastionDamageListener.java | 329 +- .../listeners/BastionInteractListener.java | 290 +- .../bastion/listeners/CitadelListener.java | 44 +- .../bastion/listeners/ElytraListener.java | 78 +- .../isaac/bastion/listeners/ModeListener.java | 246 +- .../bastion/listeners/NameLayerListener.java | 31 +- .../bastion/manager/BastionBlockManager.java | 534 +- .../isaac/bastion/manager/ElytraManager.java | 464 +- .../bastion/manager/EnderPearlManager.java | 799 +-- .../bastion/storage/BastionBlockStorage.java | 954 +-- .../bastion/storage/BastionGroupStorage.java | 437 +- .../java/isaac/bastion/storage/Database.java | 47 +- .../bastion/utils/BastionSettingManager.java | 64 +- .../java/isaac/bastion/utils/ChatFiller.java | 406 +- .../src/main/resources/config.yml | 12 +- .../src/main/resources/plugin.yml | 96 +- plugins/castlegates-paper/README.md | 1 + plugins/castlegates-paper/build.gradle.kts | 18 +- .../com/aleksey/castlegates/CastleGates.java | 62 +- .../command/CastleGatesCommand.java | 194 +- .../castlegates/config/ConfigDefaults.java | 422 +- .../castlegates/config/ConfigManager.java | 477 +- .../castlegates/database/GearblockInfo.java | 16 +- .../castlegates/database/GearblockSource.java | 168 +- .../castlegates/database/LinkInfo.java | 10 +- .../castlegates/database/LinkSource.java | 174 +- .../database/ReinforcementInfo.java | 16 +- .../database/ReinforcementSource.java | 90 +- .../castlegates/database/SqlDatabase.java | 38 +- .../engine/CastleGatesManager.java | 152 +- .../engine/PlayerStateManager.java | 150 +- .../castlegates/engine/StorageManager.java | 17 +- .../engine/bridge/BridgeEventHandler.java | 185 +- .../engine/bridge/BridgeManager.java | 1176 ++-- .../events/CastleGatesDrawGateEvent.java | 38 +- .../events/CastleGatesUndrawGateEvent.java | 42 +- .../castlegates/events/package-info.java | 4 +- .../castlegates/listener/BlockListener.java | 40 +- .../castlegates/listener/EntityListener.java | 24 +- .../plugins/bastion/BastionManager.java | 114 +- .../plugins/bastion/IBastionManager.java | 7 +- .../plugins/bastion/NoBastionManager.java | 12 +- .../castlegates/plugins/citadel/Citadel.java | 15 +- .../plugins/citadel/CitadelManager.java | 301 +- .../castlegates/plugins/citadel/ICitadel.java | 3 + .../plugins/citadel/ICitadelManager.java | 31 +- .../plugins/citadel/NoCitadel.java | 15 +- .../plugins/citadel/NoCitadelManager.java | 74 +- .../plugins/jukealert/IJukeAlertManager.java | 5 +- .../plugins/jukealert/JukeAlertManager.java | 42 +- .../plugins/jukealert/NoJukeAlertManager.java | 5 +- .../aleksey/castlegates/types/BlockCoord.java | 133 +- .../aleksey/castlegates/types/BlockState.java | 57 +- .../castlegates/types/CommandMode.java | 13 +- .../aleksey/castlegates/types/Gearblock.java | 166 +- .../castlegates/types/GearblockForUpdate.java | 5 +- .../castlegates/types/GearblockLink.java | 92 +- .../castlegates/types/LinkForUpdate.java | 11 +- .../castlegates/types/PowerResult.java | 59 +- .../aleksey/castlegates/types/TimerBatch.java | 157 +- .../aleksey/castlegates/types/TimerLink.java | 25 +- .../castlegates/types/TimerOperation.java | 6 +- .../aleksey/castlegates/utils/DataWorker.java | 582 +- .../com/aleksey/castlegates/utils/Helper.java | 212 +- .../castlegates/utils/InvalidLinkLogger.java | 12 +- .../castlegates/utils/ParticleHelper.java | 39 +- .../castlegates/utils/PowerResultHelper.java | 128 +- .../castlegates/utils/ResourceHelper.java | 51 +- .../castlegates/utils/TimerWorker.java | 36 +- .../src/main/resources/plugin.yml | 26 +- plugins/citadel-paper/build.gradle.kts | 14 +- .../java/vg/civcraft/mc/citadel/Citadel.java | 254 +- .../mc/citadel/CitadelConfigManager.java | 506 +- .../mc/citadel/CitadelPermissionHandler.java | 184 +- .../civcraft/mc/citadel/CitadelUtility.java | 369 +- .../mc/citadel/ReinforcementLogic.java | 692 +- .../mc/citadel/ReinforcementManager.java | 72 +- .../mc/citadel/acidtypes/AcidType.java | 10 +- .../mc/citadel/activity/ActivityMap.java | 958 +-- .../mc/citadel/activity/ActivityMapStat.java | 21 +- .../citadel/activity/ActivityMapTimePoll.java | 149 +- .../mc/citadel/activity/ChunkCoord.java | 11 +- .../mc/citadel/activity/GroupData.java | 11 +- .../mc/citadel/activity/PlayerUpdate.java | 3 +- .../mc/citadel/activity/RegionCoord.java | 11 +- .../mc/citadel/activity/RegionData.java | 51 +- .../civcraft/mc/citadel/activity/XZKey.java | 11 +- .../vg/civcraft/mc/citadel/command/Acid.java | 174 +- .../civcraft/mc/citadel/command/Activity.java | 61 +- .../command/AdvancedFortification.java | 130 +- .../mc/citadel/command/AreaReinforce.java | 160 +- .../civcraft/mc/citadel/command/Bypass.java | 26 +- .../command/CitadelCommandManager.java | 52 +- .../civcraft/mc/citadel/command/EasyMode.java | 26 +- .../mc/citadel/command/Fortification.java | 106 +- .../mc/citadel/command/Information.java | 16 +- .../civcraft/mc/citadel/command/Insecure.java | 22 +- .../vg/civcraft/mc/citadel/command/Off.java | 26 +- .../mc/citadel/command/PatchMode.java | 24 +- .../mc/citadel/command/Reinforce.java | 82 +- .../mc/citadel/command/ReinforcementsGUI.java | 105 +- .../civcraft/mc/citadel/command/Reload.java | 14 +- .../citadel/events/ReinforcedBlockBreak.java | 45 +- .../events/ReinforcementAcidBlockedEvent.java | 44 +- .../events/ReinforcementBypassEvent.java | 23 +- .../events/ReinforcementChangeTypeEvent.java | 40 +- .../events/ReinforcementCreationEvent.java | 23 +- .../events/ReinforcementDamageEvent.java | 59 +- .../events/ReinforcementDestructionEvent.java | 89 +- .../mc/citadel/events/ReinforcementEvent.java | 42 +- .../events/ReinforcementGroupChangeEvent.java | 33 +- .../events/ReinforcementModeSwitchEvent.java | 75 +- .../events/ReinforcementRepairEvent.java | 25 +- .../mc/citadel/listener/ActivityListener.java | 52 +- .../mc/citadel/listener/BlockListener.java | 1412 ++-- .../mc/citadel/listener/EntityListener.java | 588 +- .../citadel/listener/InventoryListener.java | 214 +- .../mc/citadel/listener/ModeListener.java | 458 +- .../mc/citadel/listener/RedstoneListener.java | 356 +- .../citadel/listener/WorldBorderListener.java | 34 +- .../mc/citadel/model/AcidManager.java | 118 +- .../civcraft/mc/citadel/model/ActivityDB.java | 155 +- .../mc/citadel/model/ActivityItem.java | 16 +- .../mc/citadel/model/CitadelChunkData.java | 6 +- .../civcraft/mc/citadel/model/CitadelDAO.java | 755 +-- .../citadel/model/CitadelSettingManager.java | 316 +- .../mc/citadel/model/HologramManager.java | 277 +- .../mc/citadel/model/Reinforcement.java | 351 +- .../mc/citadel/model/WorldBorderBuffers.java | 43 +- .../playerstate/AbstractPlayerState.java | 148 +- .../AdvancedFortificationState.java | 136 +- .../playerstate/FortificationState.java | 95 +- .../mc/citadel/playerstate/InsecureState.java | 84 +- .../mc/citadel/playerstate/NormalState.java | 108 +- .../mc/citadel/playerstate/PatchState.java | 158 +- .../playerstate/PlayerStateManager.java | 80 +- .../citadel/playerstate/ReinforcingState.java | 312 +- .../ReinforcementEffect.java | 155 +- .../reinforcementtypes/ReinforcementType.java | 391 +- .../ReinforcementTypeManager.java | 118 +- .../src/main/resources/config.yml | 248 +- .../src/main/resources/plugin.yml | 24 +- plugins/civchat2-paper/build.gradle.kts | 12 +- .../vg/civcraft/mc/civchat2/ChatStrings.java | 52 +- .../vg/civcraft/mc/civchat2/CivChat2.java | 133 +- .../civcraft/mc/civchat2/CivChat2Manager.java | 804 ++- .../vg/civcraft/mc/civchat2/commands/Afk.java | 20 +- .../commands/CivChatCommandManager.java | 50 +- .../civcraft/mc/civchat2/commands/Exit.java | 30 +- .../mc/civchat2/commands/GlobalChat.java | 105 +- .../mc/civchat2/commands/GlobalMute.java | 90 +- .../mc/civchat2/commands/GroupChat.java | 160 +- .../civcraft/mc/civchat2/commands/Ignore.java | 54 +- .../mc/civchat2/commands/IgnoreGroup.java | 50 +- .../mc/civchat2/commands/IgnoreList.java | 120 +- .../mc/civchat2/commands/LocalChat.java | 27 +- .../civcraft/mc/civchat2/commands/Reply.java | 56 +- .../civcraft/mc/civchat2/commands/Tell.java | 92 +- .../civcraft/mc/civchat2/commands/WhoAmI.java | 28 +- .../mc/civchat2/database/CivChatDAO.java | 440 +- .../mc/civchat2/database/Database.java | 202 +- .../mc/civchat2/event/GlobalChatEvent.java | 82 +- .../mc/civchat2/event/GroupChatEvent.java | 82 +- .../civchat2/event/PrivateMessageEvent.java | 82 +- .../civchat2/listeners/CivChat2Listener.java | 236 +- .../mc/civchat2/listeners/KillListener.java | 128 +- .../mc/civchat2/utility/CivChat2Config.java | 154 +- .../mc/civchat2/utility/CivChat2Executor.java | 138 +- .../civchat2/utility/CivChat2FileLogger.java | 80 +- .../mc/civchat2/utility/CivChat2Log.java | 37 +- .../utility/CivChat2SettingsManager.java | 196 +- .../mc/civchat2/utility/ScoreboardHUD.java | 76 +- .../src/main/resources/log4j2.xml | 69 +- .../src/main/resources/plugin.yml | 8 +- plugins/civduties-paper/README.md | 5 +- .../vg/civcraft/mc/civduties/CivDuties.java | 137 +- .../vg/civcraft/mc/civduties/ModeManager.java | 161 +- .../command/CivDutiesCommandHandler.java | 18 +- .../mc/civduties/command/commands/Duty.java | 95 +- .../mc/civduties/configuration/Command.java | 103 +- .../configuration/DutiesConfigManager.java | 219 +- .../mc/civduties/configuration/Tier.java | 93 +- .../civduties/database/DatabaseManager.java | 123 +- .../mc/civduties/database/PlayerData.java | 37 +- .../civduties/external/CombatTagHandler.java | 14 +- .../mc/civduties/external/VaultManager.java | 134 +- .../civduties/listeners/PlayerListener.java | 103 +- .../src/main/resources/plugin.yml | 10 +- plugins/civmodcore-paper/README.md | 9 +- plugins/civmodcore-paper/build.gradle.kts | 32 +- .../java/org/bukkit/pseudo/PseudoServer.java | 2324 +++---- .../vg/civcraft/mc/civmodcore/ACivMod.java | 312 +- .../mc/civmodcore/CivModCoreConfig.java | 100 +- .../mc/civmodcore/CivModCorePlugin.java | 241 +- .../mc/civmodcore/chat/ChatUtils.java | 705 +- .../mc/civmodcore/chat/Componentify.java | 105 +- .../mc/civmodcore/chat/dialog/Dialog.java | 89 +- .../civmodcore/chat/dialog/DialogManager.java | 93 +- .../civmodcore/commands/ChunkMetaCommand.java | 26 +- .../civmodcore/commands/CommandHelpers.java | 193 +- .../civmodcore/commands/CommandManager.java | 307 +- .../mc/civmodcore/commands/NamedCommand.java | 8 +- .../mc/civmodcore/commands/StatCommand.java | 65 +- .../mc/civmodcore/commands/TabComplete.java | 5 +- .../mc/civmodcore/config/ConfigHelper.java | 1001 ++- .../mc/civmodcore/config/ConfigParser.java | 115 +- .../mc/civmodcore/config/ConfigSection.java | 22 +- .../mc/civmodcore/dao/ConnectionPool.java | 225 +- .../civmodcore/dao/DatabaseCredentials.java | 106 +- .../mc/civmodcore/dao/DatabaseMigration.java | 72 +- .../mc/civmodcore/dao/ManagedDatasource.java | 898 ++- .../mc/civmodcore/dao/package-info.java | 9 +- .../mc/civmodcore/entities/EntityUtils.java | 49 +- .../mc/civmodcore/events/EventUtils.java | 22 +- .../civmodcore/inventory/ClonedInventory.java | 409 +- .../civmodcore/inventory/InventoryUtils.java | 415 +- .../civmodcore/inventory/RecipeManager.java | 121 +- .../inventory/gui/AnimatedClickable.java | 82 +- .../civmodcore/inventory/gui/Clickable.java | 30 +- .../inventory/gui/ClickableInventory.java | 594 +- .../gui/ClickableInventoryListener.java | 44 +- .../inventory/gui/DecorationStack.java | 42 +- .../inventory/gui/FastMultiPageView.java | 209 +- .../civmodcore/inventory/gui/IClickable.java | 216 +- .../civmodcore/inventory/gui/LClickable.java | 57 +- .../inventory/gui/MultiPageView.java | 242 +- .../gui/components/ComponableInventory.java | 94 +- .../gui/components/ComponableSection.java | 207 +- .../gui/components/ContentAligner.java | 7 +- .../gui/components/ContentAligners.java | 213 +- .../gui/components/InventoryComponent.java | 84 +- .../inventory/gui/components/Scrollbar.java | 234 +- .../gui/components/SlotPredicates.java | 109 +- .../gui/components/StaticDisplaySection.java | 65 +- .../gui/components/impl/CommonGUIs.java | 18 +- .../inventory/gui/history/HistoryItem.java | 2 +- .../inventory/gui/history/HistoryTracker.java | 164 +- .../inventory/items/EnchantUtils.java | 338 +- .../civmodcore/inventory/items/ItemMap.java | 1292 ++-- .../civmodcore/inventory/items/ItemUtils.java | 1077 ++- .../inventory/items/MaterialUtils.java | 80 +- .../civmodcore/inventory/items/MetaUtils.java | 515 +- .../civmodcore/inventory/items/MoreTags.java | 580 +- .../inventory/items/PotionUtils.java | 102 +- .../inventory/items/SpawnEggUtils.java | 258 +- .../inventory/items/TreeTypeUtils.java | 304 +- .../mc/civmodcore/nbt/NBTDeserializer.java | 4 +- .../civcraft/mc/civmodcore/nbt/NBTHelper.java | 112 +- .../mc/civmodcore/nbt/NBTSerializable.java | 44 +- .../mc/civmodcore/nbt/NBTSerialization.java | 248 +- .../nbt/NBTSerializationException.java | 30 +- .../civcraft/mc/civmodcore/nbt/NBTType.java | 28 +- .../extensions/NBTTagCompoundExtensions.java | 186 +- .../nbt/extensions/NBTTagListExtensions.java | 1086 ++-- .../civmodcore/nbt/wrappers/NBTCompound.java | 1734 +++-- .../pdc/AbstractPersistentDataType.java | 66 +- .../civmodcore/pdc/PersistentDataTypes.java | 73 +- .../pdc/PersistentEnumDataType.java | 86 +- .../civmodcore/pdc/PersistentMapDataType.java | 108 +- .../PersistentDataContainerExtensions.java | 142 +- .../mc/civmodcore/players/PlayerNames.java | 44 +- .../players/scoreboard/bottom/BottomLine.java | 166 +- .../scoreboard/bottom/BottomLineAPI.java | 112 +- .../scoreboard/side/CivScoreBoard.java | 200 +- .../scoreboard/side/ScoreBoardAPI.java | 145 +- .../scoreboard/side/ScoreBoardListener.java | 10 +- .../players/settings/AltRequestEvent.java | 64 +- .../players/settings/MenuDialog.java | 52 +- .../players/settings/PlayerSetting.java | 455 +- .../players/settings/PlayerSettingAPI.java | 222 +- .../settings/SettingChangeListener.java | 4 +- .../players/settings/SettingTypeManager.java | 46 +- .../settings/commands/ConfigCommand.java | 143 +- .../settings/gui/ClickableMenuItem.java | 20 +- .../players/settings/gui/MenuItem.java | 36 +- .../players/settings/gui/MenuOption.java | 40 +- .../players/settings/gui/MenuSection.java | 142 +- .../settings/impl/AltConsistentSetting.java | 95 +- .../players/settings/impl/BooleanSetting.java | 140 +- .../settings/impl/BoundedIntegerSetting.java | 54 +- .../settings/impl/CommandReplySetting.java | 113 +- .../settings/impl/DecimalFormatSetting.java | 66 +- .../settings/impl/DisplayLocationSetting.java | 132 +- .../players/settings/impl/DoubleSetting.java | 72 +- .../players/settings/impl/EnumSetting.java | 114 +- .../players/settings/impl/FloatSetting.java | 72 +- .../players/settings/impl/IntegerSetting.java | 90 +- .../players/settings/impl/JsonSetting.java | 57 +- .../settings/impl/LimitedStringSetting.java | 56 +- .../players/settings/impl/LongSetting.java | 56 +- .../players/settings/impl/StringSetting.java | 46 +- .../collection/AbstractCollectionSetting.java | 354 +- .../settings/impl/collection/ListSetting.java | 29 +- .../settings/impl/collection/SetSetting.java | 29 +- .../utilities/BiasedRandomPicker.java | 146 +- .../utilities/BukkitComparators.java | 36 +- .../mc/civmodcore/utilities/CivLogger.java | 172 +- .../civmodcore/utilities/DelayedItemDrop.java | 66 +- .../civmodcore/utilities/DependencyGlue.java | 186 +- .../utilities/DoubleInteractFixer.java | 58 +- .../mc/civmodcore/utilities/KeyedUtils.java | 112 +- .../civmodcore/utilities/MoreArrayUtils.java | 266 +- .../utilities/MoreCollectionUtils.java | 370 +- .../mc/civmodcore/utilities/MoreMapUtils.java | 248 +- .../mc/civmodcore/utilities/MoreMath.java | 320 +- .../civmodcore/utilities/MoreObjectUtils.java | 26 +- .../civmodcore/utilities/MoreStringUtils.java | 54 +- .../mc/civmodcore/utilities/NullUtils.java | 88 +- .../mc/civmodcore/utilities/Resettable.java | 16 +- .../mc/civmodcore/utilities/SkinCache.java | 265 +- .../mc/civmodcore/utilities/TextUtil.java | 146 +- .../mc/civmodcore/utilities/Title.java | 180 +- .../mc/civmodcore/utilities/UuidUtils.java | 135 +- .../mc/civmodcore/utilities/Validation.java | 30 +- .../utilities/cooldowns/ICoolDownHandler.java | 75 +- .../cooldowns/MilliSecCoolDownHandler.java | 81 +- .../cooldowns/TickCoolDownHandler.java | 89 +- .../utilities/progress/ProgressTrackable.java | 6 +- .../utilities/progress/ProgressTracker.java | 98 +- .../utilities/ratelimiting/RateLimiter.java | 156 +- .../utilities/ratelimiting/RateLimiting.java | 132 +- .../utilities/ratelimiting/TokenBucket.java | 64 +- .../mc/civmodcore/world/BeaconTracker.java | 122 +- .../mc/civmodcore/world/BlockProperties.java | 82 +- .../civmodcore/world/ChunkLoadedFilter.java | 104 +- .../mc/civmodcore/world/WorldTracker.java | 52 +- .../mc/civmodcore/world/WorldUtils.java | 921 ++- .../mc/civmodcore/world/locations/QTBox.java | 12 +- .../civmodcore/world/locations/QTBoxImpl.java | 76 +- .../world/locations/SparseQuadTree.java | 552 +- .../world/locations/chunkmeta/CacheState.java | 34 +- .../world/locations/chunkmeta/ChunkCoord.java | 405 +- .../world/locations/chunkmeta/ChunkMeta.java | 243 +- .../locations/chunkmeta/ChunkMetaFactory.java | 42 +- .../chunkmeta/ChunkMetaInitializer.java | 12 +- .../chunkmeta/ChunkMetaListener.java | 101 +- .../chunkmeta/ChunkMetaLoadStatus.java | 13 +- .../chunkmeta/GlobalChunkMetaManager.java | 244 +- .../chunkmeta/WorldChunkMetaManager.java | 594 +- .../world/locations/chunkmeta/XZWCoord.java | 144 +- .../locations/chunkmeta/api/APIView.java | 20 +- .../api/BlockBasedChunkMetaView.java | 372 +- .../locations/chunkmeta/api/ChunkMetaAPI.java | 184 +- .../chunkmeta/api/ChunkMetaView.java | 356 +- .../chunkmeta/api/ChunkMetaViewTracker.java | 65 +- .../chunkmeta/api/SingleBlockAPIView.java | 80 +- .../chunkmeta/block/BlockBasedChunkMeta.java | 645 +- .../block/BlockBasedStorageEngine.java | 8 +- .../chunkmeta/block/BlockDataObject.java | 60 +- .../block/BlockDataObjectLoadStatus.java | 13 +- .../chunkmeta/block/StorageEngine.java | 25 +- .../block/auto/AutoBlockChunkMeta.java | 82 +- .../block/auto/AutoStorageEngine.java | 314 +- .../block/auto/JsonStorageEngine.java | 14 +- .../block/auto/JsonableDataObject.java | 22 +- .../block/auto/SerializableDataObject.java | 12 +- .../chunkmeta/block/auto/YamlDataObject.java | 24 +- .../block/auto/YamlStorageEngine.java | 24 +- .../block/fallback/SingleBlockTracker.java | 84 +- .../block/table/TableBasedBlockChunkMeta.java | 169 +- .../block/table/TableBasedDataObject.java | 32 +- .../block/table/TableStorageEngine.java | 76 +- .../chunkmeta/stat/LoadStatistic.java | 59 +- .../chunkmeta/stat/LoadStatisticManager.java | 290 +- .../chunkmeta/stat/PluginStatistic.java | 45 +- .../world/locations/global/CMCWorldDAO.java | 188 +- .../global/GlobalLocationTracker.java | 234 +- .../locations/global/GlobalTrackableDAO.java | 50 +- .../locations/global/LocationTrackable.java | 70 +- .../locations/global/WorldIDManager.java | 154 +- .../world/model/AbstractYLimitedArea.java | 50 +- .../civmodcore/world/model/EllipseArea.java | 138 +- .../world/model/GlobalYLimitedArea.java | 56 +- .../mc/civmodcore/world/model/IArea.java | 61 +- .../civmodcore/world/model/PseudoChunk.java | 52 +- .../civmodcore/world/model/RectangleArea.java | 122 +- .../src/main/resources/plugin.yml | 2 +- .../mc/civmodcore/config/ConfigTests.java | 30 +- .../mc/civmodcore/inheritance/ChildClass.java | 1 + .../inheritance/InheritanceTests.java | 27 +- .../civmodcore/inheritance/ParentClass.java | 6 +- .../mc/civmodcore/items/ItemMetaTests.java | 106 +- .../civcraft/mc/civmodcore/nbt/NBTTests.java | 258 +- .../mc/civmodcore/text/TextTests.java | 52 +- .../mc/civmodcore/uuid/UuidTests.java | 20 +- plugins/civspy-api/README.md | 62 +- plugins/civspy-api/build.gradle.kts | 4 +- .../minecraft/civspy/database/Database.java | 879 +-- plugins/civspy-bungee/README.md | 10 +- plugins/civspy-bungee/build.gradle.kts | 8 +- .../minecraft/civspy/CivSpyBungee.java | 318 +- .../minecraft/civspy/CivSpyPlayerCount.java | 31 +- .../src/main/resources/config.yml | 18 +- plugins/civspy-paper/README.md | 156 +- plugins/civspy-paper/build.gradle.kts | 30 +- .../minecraft/civspy/CivSpy.java | 390 +- .../minecraft/civspy/Config.java | 344 +- .../minecraft/civspy/DataAggregate.java | 80 +- .../minecraft/civspy/DataBatcher.java | 494 +- .../minecraft/civspy/DataListener.java | 74 +- .../minecraft/civspy/DataManager.java | 1076 +-- .../minecraft/civspy/DataSample.java | 84 +- .../minecraft/civspy/DataSampleKey.java | 229 +- .../minecraft/civspy/DataSampler.java | 179 +- .../minecraft/civspy/MultiDataSampler.java | 62 +- .../minecraft/civspy/PeriodicDataSample.java | 38 +- .../minecraft/civspy/PointDataSample.java | 36 +- .../minecraft/civspy/SingleDataSampler.java | 57 +- .../civspy/listeners/ServerDataListener.java | 57 +- .../civspy/listeners/impl/BreakListener.java | 106 +- .../civspy/listeners/impl/BucketListener.java | 153 +- .../civspy/listeners/impl/CombatListener.java | 210 +- .../listeners/impl/ConsumeListener.java | 64 +- .../listeners/impl/CraftingListener.java | 97 +- .../civspy/listeners/impl/DropListener.java | 109 +- .../listeners/impl/FishingListener.java | 67 +- .../listeners/impl/HuntingListener.java | 298 +- .../listeners/impl/InventoryListener.java | 483 +- .../listeners/impl/MovementListener.java | 176 +- .../civspy/listeners/impl/PickupListener.java | 185 +- .../civspy/listeners/impl/PlaceListener.java | 66 +- .../listeners/impl/RedstoneListener.java | 78 +- .../minecraft/civspy/listeners/package.html | 61 +- .../samplers/ServerMultiDataSampler.java | 55 +- .../samplers/ServerSingleDataSampler.java | 57 +- .../samplers/impl/PlayerCountSampler.java | 38 +- .../civspy/samplers/impl/TPSSampler.java | 132 +- .../impl/WorldPlayerCountSampler.java | 54 +- .../minecraft/civspy/samplers/package.html | 69 +- .../civspy/util/ItemStackToString.java | 384 +- .../src/main/resources/config.yml | 36 +- .../src/main/resources/plugin.yml | 4 +- plugins/combattagplus-paper/README.md | 25 +- .../net/minelink/ctplus/CombatTagPlus.java | 2 +- .../java/net/minelink/ctplus/NpcManager.java | 1 + .../java/net/minelink/ctplus/Settings.java | 4 +- .../java/net/minelink/ctplus/TagManager.java | 4 +- .../ctplus/event/NpcDespawnEvent.java | 6 +- .../ctplus/event/NpcDespawnReason.java | 6 +- .../ctplus/listener/ForceFieldListener.java | 5 +- .../ctplus/listener/InstakillListener.java | 1 + .../minelink/ctplus/listener/NpcListener.java | 3 +- .../ctplus/listener/PlayerListener.java | 18 +- .../minelink/ctplus/listener/TagListener.java | 20 +- .../ctplus/nms/NpcNetworkManager.java | 1 + .../net/minelink/ctplus/nms/NpcPlayer.java | 3 +- .../ctplus/nms/NpcPlayerConnection.java | 1 + .../ctplus/nms/NpcPlayerHelperImpl.java | 3 +- .../minelink/ctplus/task/ForceFieldTask.java | 1 + .../minelink/ctplus/task/SafeLogoutTask.java | 2 +- .../net/minelink/ctplus/util/BarUtils.java | 3 + .../minelink/ctplus/util/EmptyChannel.java | 3 +- .../src/main/resources/config.yml | 6 +- .../src/main/resources/plugin.yml | 36 +- plugins/donum-paper/README.md | 9 +- .../java/com/github/civcraft/donum/Donum.java | 70 +- .../com/github/civcraft/donum/DonumAPI.java | 56 +- .../civcraft/donum/DonumConfiguration.java | 126 +- .../github/civcraft/donum/DonumManager.java | 263 +- .../donum/commands/commands/Deliver.java | 27 +- .../donum/commands/commands/DeliverDeath.java | 53 +- .../commands/commands/OpenDeliveries.java | 24 +- .../civcraft/donum/database/Database.java | 234 +- .../civcraft/donum/database/DonumDAO.java | 682 +- .../civcraft/donum/gui/AdminDeliveryGUI.java | 43 +- .../civcraft/donum/gui/DeathInventoryGUI.java | 227 +- .../civcraft/donum/gui/DeliveryGUI.java | 282 +- .../inventories/AbstractInventoryStorage.java | 32 +- .../donum/inventories/DeathInventory.java | 54 +- .../donum/inventories/DeliveryInventory.java | 28 +- .../listeners/AdminDeliveryListener.java | 34 +- .../donum/listeners/PlayerListener.java | 10 +- .../listeners/storage/BukkitListener.java | 18 +- .../donum/misc/ItemMapBlobHandling.java | 220 +- .../donum/storage/DatabaseStorage.java | 44 +- .../donum/storage/IDeliveryStorage.java | 30 +- .../donum-paper/src/main/resources/config.yml | 8 +- .../donum-paper/src/main/resources/plugin.yml | 2 +- plugins/essenceglue-paper/README.md | 7 +- plugins/essenceglue-paper/build.gradle.kts | 18 +- .../essenceglue/EssenceConfigManager.java | 148 +- .../maxopoly/essenceglue/EssenceDAO.java | 74 +- .../essenceglue/EssenceGluePlugin.java | 122 +- .../essenceglue/ExilePearListener.java | 28 +- .../maxopoly/essenceglue/NewNameResolver.java | 40 +- .../maxopoly/essenceglue/RewardManager.java | 64 +- .../maxopoly/essenceglue/StreakManager.java | 300 +- .../maxopoly/essenceglue/VotifyManager.java | 184 +- .../maxopoly/essenceglue/VotingSite.java | 44 +- .../essenceglue/commands/StreakCommand.java | 30 +- .../essenceglue/commands/VoteCommand.java | 60 +- .../src/main/resources/plugin.yml | 6 +- plugins/exilepearl-paper/README.md | 28 +- plugins/exilepearl-paper/build.gradle.kts | 26 +- .../com/devotedmc/ExilePearl/BrewHandler.java | 18 +- .../devotedmc/ExilePearl/DamageLogger.java | 70 +- .../com/devotedmc/ExilePearl/ExilePearl.java | 421 +- .../devotedmc/ExilePearl/ExilePearlApi.java | 246 +- .../ExilePearl/ExilePearlPlugin.java | 69 +- .../com/devotedmc/ExilePearl/ExileRule.java | 179 +- .../java/com/devotedmc/ExilePearl/Lang.java | 114 +- .../devotedmc/ExilePearl/LoreProvider.java | 80 +- .../com/devotedmc/ExilePearl/PearlAccess.java | 313 +- .../devotedmc/ExilePearl/PearlFactory.java | 67 +- .../devotedmc/ExilePearl/PearlFreeReason.java | 26 +- .../com/devotedmc/ExilePearl/PearlLogger.java | 39 +- .../devotedmc/ExilePearl/PearlManager.java | 53 +- .../com/devotedmc/ExilePearl/PearlType.java | 80 +- .../devotedmc/ExilePearl/PlayerProvider.java | 53 +- .../devotedmc/ExilePearl/RepairMaterial.java | 139 +- .../devotedmc/ExilePearl/StorageProvider.java | 13 +- .../devotedmc/ExilePearl/SuicideHandler.java | 24 +- .../broadcast/BroadcastListener.java | 26 +- .../broadcast/NLGroupBroadcastListener.java | 63 +- .../broadcast/PlayerBroadcastListener.java | 54 +- .../devotedmc/ExilePearl/command/AutoTab.java | 60 +- .../ExilePearl/command/BaseCommand.java | 1811 +++--- .../command/CmdAdminCheckExiled.java | 60 +- .../ExilePearl/command/CmdAdminDecay.java | 24 +- .../ExilePearl/command/CmdAdminExileAny.java | 204 +- .../ExilePearl/command/CmdAdminFreeAny.java | 54 +- .../command/CmdAdminListExiled.java | 54 +- .../ExilePearl/command/CmdAdminReload.java | 42 +- .../ExilePearl/command/CmdAdminSetDate.java | 62 +- .../ExilePearl/command/CmdAdminSetHealth.java | 64 +- .../ExilePearl/command/CmdAdminSetKiller.java | 58 +- .../ExilePearl/command/CmdAdminSetType.java | 72 +- .../ExilePearl/command/CmdAutoHelp.java | 52 +- .../ExilePearl/command/CmdConfig.java | 32 +- .../ExilePearl/command/CmdConfigList.java | 125 +- .../ExilePearl/command/CmdConfigLoad.java | 29 +- .../ExilePearl/command/CmdConfigSave.java | 27 +- .../ExilePearl/command/CmdConfigSet.java | 65 +- .../ExilePearl/command/CmdDowngrade.java | 62 +- .../ExilePearl/command/CmdExilePearl.java | 104 +- .../ExilePearl/command/CmdLegacy.java | 19 +- .../ExilePearl/command/CmdPearlBroadcast.java | 122 +- .../command/CmdPearlBroadcastAccept.java | 34 +- .../command/CmdPearlBroadcastSilence.java | 52 +- .../ExilePearl/command/CmdPearlFree.java | 36 +- .../ExilePearl/command/CmdPearlLocate.java | 38 +- .../ExilePearl/command/CmdReturn.java | 38 +- .../ExilePearl/command/CmdShowAllPearls.java | 370 +- .../ExilePearl/command/CmdSuicide.java | 39 +- .../ExilePearl/command/CmdSummon.java | 68 +- .../ExilePearl/command/CmdSummonConfirm.java | 64 +- .../ExilePearl/command/CmdUpgrade.java | 88 +- .../ExilePearl/command/CommandArg.java | 46 +- .../ExilePearl/command/CommandVisibility.java | 33 +- .../command/OptionalCommandArg.java | 80 +- .../ExilePearl/command/PearlCommand.java | 136 +- .../command/RequiredCommandArg.java | 58 +- .../ExilePearl/config/Configurable.java | 13 +- .../devotedmc/ExilePearl/config/Document.java | 316 +- .../ExilePearl/config/DocumentConfig.java | 40 +- .../ExilePearl/config/MySqlConfig.java | 121 +- .../ExilePearl/config/PearlConfig.java | 330 +- .../ExilePearl/core/BreweryHandler.java | 8 +- .../devotedmc/ExilePearl/core/CoreClock.java | 8 +- .../ExilePearl/core/CoreDamageLogger.java | 431 +- .../ExilePearl/core/CoreExilePearl.java | 813 +-- .../ExilePearl/core/CoreLoreGenerator.java | 339 +- .../ExilePearl/core/CorePearlConfig.java | 960 +-- .../ExilePearl/core/CorePearlManager.java | 948 +-- .../ExilePearl/core/CorePluginFactory.java | 244 +- .../devotedmc/ExilePearl/core/DamageLog.java | 242 +- .../ExilePearl/core/DamageRecord.java | 204 +- .../ExilePearl/core/ExilePearlCore.java | 1057 +-- .../ExilePearl/core/ExilePearlTask.java | 112 +- .../ExilePearl/core/NoBrewHandler.java | 14 +- .../ExilePearl/core/PearlBoundaryTask.java | 659 +- .../ExilePearl/core/PearlDecayTask.java | 89 +- .../ExilePearl/core/PlayerSuicideTask.java | 157 +- .../ExilePearl/core/package-info.java | 4 +- .../ExilePearl/event/PearlDecayEvent.java | 129 +- .../ExilePearl/event/PearlMovedEvent.java | 99 +- .../ExilePearl/event/PearlReturnEvent.java | 53 +- .../ExilePearl/event/PearlSummonEvent.java | 89 +- .../ExilePearl/event/PlayerFreedEvent.java | 112 +- .../ExilePearl/event/PlayerPearledEvent.java | 89 +- .../ExilePearl/holder/BlockHolder.java | 175 +- .../ExilePearl/holder/EntityHolder.java | 93 +- .../ExilePearl/holder/HolderVerifyResult.java | 74 +- .../ExilePearl/holder/ItemHolder.java | 79 +- .../ExilePearl/holder/PearlHolder.java | 73 +- .../ExilePearl/holder/PlayerHolder.java | 129 +- .../ExilePearl/listener/BanStickListener.java | 12 +- .../ExilePearl/listener/BastionListener.java | 40 +- .../ExilePearl/listener/CitadelListener.java | 42 +- .../ExilePearl/listener/CivChatListener.java | 23 +- .../ExilePearl/listener/ExileListener.java | 628 +- .../listener/JukeAlertListener.java | 29 +- .../ExilePearl/listener/PlayerListener.java | 2573 ++++---- .../listener/RandomSpawnListener.java | 31 +- .../ExilePearl/listener/RuleListener.java | 104 +- .../ExilePearl/storage/AsyncPearlRecord.java | 90 +- .../storage/AsyncStorageWriter.java | 325 +- .../storage/CoreStorageProvider.java | 64 +- .../ExilePearl/storage/FileStorage.java | 282 +- .../ExilePearl/storage/MySqlStorage.java | 1179 ++-- .../ExilePearl/storage/PearlStorage.java | 33 +- .../storage/PearlUpdateStorage.java | 99 +- .../ExilePearl/storage/PluginStorage.java | 30 +- .../ExilePearl/storage/RamStorage.java | 92 +- .../ExilePearl/storage/StorageType.java | 46 +- .../ExilePearl/util/BastionWrapper.java | 97 +- .../com/devotedmc/ExilePearl/util/Clock.java | 9 +- .../util/EntityCombustEventWrapper.java | 61 +- .../util/EntityDamageEventWrapper.java | 61 +- .../ExilePearl/util/ExilePearlRunnable.java | 46 +- .../ExilePearl/util/NameLayerPermissions.java | 5 +- .../devotedmc/ExilePearl/util/Permission.java | 50 +- .../devotedmc/ExilePearl/util/SpawnUtil.java | 41 +- .../util/StringListIgnoresCase.java | 6 +- .../src/main/resources/config.yml | 20 +- .../src/main/resources/plugin.yml | 6 +- plugins/factorymod-paper/README.md | 25 +- plugins/factorymod-paper/build.gradle.kts | 14 +- .../igotyou/FactoryMod/ConfigParser.java | 1915 +++--- .../github/igotyou/FactoryMod/FactoryMod.java | 89 +- .../igotyou/FactoryMod/FactoryModManager.java | 1000 +-- .../FactoryMod/FactoryModPlayerSettings.java | 94 +- .../FactoryMod/commands/CheatOutput.java | 56 +- .../igotyou/FactoryMod/commands/Create.java | 156 +- .../FactoryMod/commands/FMCommandManager.java | 36 +- .../FactoryMod/commands/FactoryMenu.java | 36 +- .../FactoryMod/commands/ItemUseMenu.java | 36 +- .../commands/RunAmountSetterCommand.java | 45 +- .../FactoryMod/eggs/FurnCraftChestEgg.java | 262 +- .../igotyou/FactoryMod/eggs/IFactoryEgg.java | 92 +- .../igotyou/FactoryMod/eggs/PipeEgg.java | 183 +- .../igotyou/FactoryMod/eggs/SorterEgg.java | 161 +- .../events/FactoryActivateEvent.java | 75 +- .../FactoryMod/events/ItemTransferEvent.java | 60 +- .../FactoryMod/events/RecipeExecuteEvent.java | 78 +- .../igotyou/FactoryMod/factories/Factory.java | 250 +- .../factories/FurnCraftChestFactory.java | 1308 ++-- .../igotyou/FactoryMod/factories/Pipe.java | 359 +- .../igotyou/FactoryMod/factories/Sorter.java | 401 +- .../FurnCraftChestInteractionManager.java | 628 +- .../IInteractionManager.java | 73 +- .../PipeInteractionManager.java | 151 +- .../SorterInteractionManager.java | 164 +- .../FactoryMod/listeners/CitadelListener.java | 38 +- .../listeners/CompactItemListener.java | 282 +- .../listeners/FactoryModListener.java | 354 +- .../listeners/NetherPortalListener.java | 38 +- .../powerManager/FurnacePowerManager.java | 160 +- .../powerManager/IPowerManager.java | 68 +- .../FactoryMod/recipes/AOERepairRecipe.java | 309 +- .../FactoryMod/recipes/CompactingRecipe.java | 336 +- .../recipes/DecompactingRecipe.java | 308 +- .../DeterministicEnchantingRecipe.java | 209 +- .../recipes/DummyParsingRecipe.java | 54 +- .../FactoryMod/recipes/EffectFeasibility.java | 4 +- .../recipes/FactoryMaterialReturnRecipe.java | 164 +- .../igotyou/FactoryMod/recipes/IRecipe.java | 91 +- .../FactoryMod/recipes/InputRecipe.java | 389 +- .../FactoryMod/recipes/LoreEnchantRecipe.java | 278 +- .../FactoryMod/recipes/PlayerHeadRecipe.java | 105 +- .../FactoryMod/recipes/PrintBookRecipe.java | 227 +- .../FactoryMod/recipes/PrintNoteRecipe.java | 224 +- .../recipes/PrintingPlateJsonRecipe.java | 537 +- .../recipes/PrintingPlateRecipe.java | 237 +- .../recipes/PrintingPressRecipe.java | 20 +- .../FactoryMod/recipes/ProductionRecipe.java | 278 +- .../FactoryMod/recipes/PylonRecipe.java | 234 +- .../recipes/RandomEnchantingRecipe.java | 206 +- .../recipes/RandomOutputRecipe.java | 206 +- .../recipes/RecipeScalingUpgradeRecipe.java | 157 +- .../FactoryMod/recipes/RepairRecipe.java | 110 +- .../FactoryMod/recipes/Upgraderecipe.java | 203 +- .../FactoryMod/recipes/WordBankRecipe.java | 322 +- .../scaling/ProductionRecipeModifier.java | 140 +- .../repairManager/IRepairManager.java | 34 +- .../NoRepairDestroyOnBreakManager.java | 83 +- .../PercentageHealthRepairManager.java | 159 +- .../structures/BlockFurnaceStructure.java | 92 +- .../structures/FurnCraftChestStructure.java | 162 +- .../structures/MultiBlockStructure.java | 238 +- .../FactoryMod/structures/PipeStructure.java | 260 +- .../igotyou/FactoryMod/utility/Direction.java | 140 +- .../utility/FactoryGarbageCollector.java | 45 +- .../FactoryMod/utility/FactoryModGUI.java | 613 +- .../utility/FactoryModPermissionManager.java | 36 +- .../FactoryMod/utility/FileHandler.java | 692 +- .../utility/IIOFInventoryProvider.java | 24 +- .../FactoryMod/utility/IOConfigSection.java | 336 +- .../FactoryMod/utility/IOSelector.java | 358 +- .../FactoryMod/utility/ItemUseGUI.java | 282 +- .../FactoryMod/utility/LoggingUtils.java | 58 +- .../utility/MultiInventoryWrapper.java | 638 +- .../src/main/resources/config.yml | 68 +- .../src/main/resources/plugin.yml | 12 +- plugins/finale-paper/README.md | 9 +- plugins/finale-paper/build.gradle.kts | 16 +- .../github/maxopoly/finale/ConfigParser.java | 855 +-- .../com/github/maxopoly/finale/Finale.java | 164 +- .../github/maxopoly/finale/FinaleManager.java | 160 +- .../finale/combat/AsyncPacketHandler.java | 208 +- .../maxopoly/finale/combat/CPSHandler.java | 110 +- .../maxopoly/finale/combat/CombatConfig.java | 258 +- .../finale/combat/CombatSoundConfig.java | 50 +- .../maxopoly/finale/combat/CombatUtil.java | 452 +- .../finale/combat/event/CritHitEvent.java | 70 +- .../finale/command/CardinalCommand.java | 93 +- .../finale/command/CombatConfigCommand.java | 186 +- .../finale/command/GammaBrightCommand.java | 12 +- .../finale/command/ReloadFinaleCommand.java | 14 +- .../finale/command/ShowCpsCommand.java | 26 +- .../finale/external/CombatTagPlusManager.java | 28 +- .../finale/external/FinaleSettingManager.java | 218 +- .../finale/listeners/DamageListener.java | 234 +- .../listeners/EnchantmentDisableListener.java | 68 +- .../listeners/ExtraDurabilityListener.java | 16 +- .../listeners/GappleCooldownListener.java | 144 +- .../listeners/PearlCoolDownListener.java | 218 +- .../finale/listeners/PlayerListener.java | 228 +- .../finale/listeners/PotionListener.java | 222 +- .../listeners/ToolProtectionListener.java | 56 +- .../finale/listeners/VelocityFixListener.java | 22 +- .../listeners/WeaponModificationListener.java | 66 +- .../maxopoly/finale/misc/ArmourModifier.java | 149 +- .../finale/misc/AttributeModifier.java | 84 +- .../finale/misc/DamageModificationConfig.java | 50 +- .../finale/misc/ExtraDurabilityTracker.java | 42 +- .../github/maxopoly/finale/misc/ItemUtil.java | 266 +- .../maxopoly/finale/misc/MultiplierMode.java | 24 +- .../finale/misc/PotionArrowHandler.java | 85 +- .../misc/SaturationHealthRegenHandler.java | 209 +- .../com/github/maxopoly/finale/misc/Slot.java | 86 +- .../maxopoly/finale/misc/WeaponModifier.java | 87 +- .../misc/knockback/KnockbackConfig.java | 68 +- .../misc/knockback/KnockbackModifier.java | 50 +- .../finale/misc/knockback/KnockbackType.java | 32 +- .../misc/velocity/NormalVelocityConfig.java | 16 +- .../misc/velocity/RevertedVelocityConfig.java | 60 +- .../finale/misc/velocity/VelocityConfig.java | 70 +- .../finale/misc/velocity/VelocityHandler.java | 24 +- .../finale/overlay/ScoreboardHUD.java | 400 +- .../maxopoly/finale/potion/PotionHandler.java | 68 +- .../finale/potion/PotionModification.java | 90 +- .../src/main/resources/plugin.yml | 16 +- plugins/hiddenore-paper/README.md | 156 +- plugins/hiddenore-paper/build.gradle.kts | 8 +- .../devotedmc/hiddenore/BlockConfig.java | 193 +- .../github/devotedmc/hiddenore/Config.java | 909 ++- .../devotedmc/hiddenore/DropConfig.java | 373 +- .../devotedmc/hiddenore/DropItemConfig.java | 65 +- .../devotedmc/hiddenore/DropLimitsConfig.java | 49 +- .../github/devotedmc/hiddenore/HiddenOre.java | 130 +- .../devotedmc/hiddenore/NameConfig.java | 18 +- .../hiddenore/PlayerStateConfig.java | 112 +- .../devotedmc/hiddenore/ToolConfig.java | 483 +- .../devotedmc/hiddenore/VeinConfig.java | 101 +- .../github/devotedmc/hiddenore/XPConfig.java | 37 +- .../hiddenore/commands/CommandHandler.java | 154 +- .../hiddenore/events/HiddenOreEvent.java | 81 +- .../events/HiddenOreGenerateEvent.java | 79 +- .../listeners/BlockBreakListener.java | 766 +-- .../listeners/ConfigDeferralListener.java | 92 +- .../hiddenore/listeners/ExploitListener.java | 319 +- .../listeners/WorldGenerationListener.java | 304 +- .../hiddenore/tracking/BreakTracking.java | 1163 ++-- .../devotedmc/hiddenore/util/FakePlayer.java | 5757 +++++++++-------- .../src/main/resources/config-advanced.yml | 192 +- .../src/main/resources/config-test.yml | 430 +- .../src/main/resources/config-veins.yml | 596 +- .../src/main/resources/config.yml | 980 +-- .../src/main/resources/plugin.yml | 32 +- plugins/itemexchange-paper/README.md | 159 +- plugins/itemexchange-paper/build.gradle.kts | 16 +- .../itemexchange/ItemExchangeConfig.java | 485 +- .../itemexchange/ItemExchangeListener.java | 480 +- .../itemexchange/ItemExchangePlugin.java | 126 +- .../commands/CommandRegistrar.java | 42 +- .../itemexchange/commands/CreateCommand.java | 272 +- .../itemexchange/commands/DebugCommand.java | 18 +- .../itemexchange/commands/InfoCommand.java | 66 +- .../itemexchange/commands/ReloadCommand.java | 26 +- .../itemexchange/commands/SetCommand.java | 98 +- .../events/BlockInventoryRequestEvent.java | 209 +- .../events/BrowseOrPurchaseEvent.java | 170 +- .../events/SuccessfulPurchaseEvent.java | 70 +- .../glues/citadel/CitadelGlue.java | 64 +- .../glues/jukealert/JukeAlertGlue.java | 56 +- .../glues/jukealert/ShopPurchaseAction.java | 106 +- .../glues/namelayer/GroupModifier.java | 166 +- .../glues/namelayer/NameLayerGlue.java | 58 +- .../glues/namelayer/PermissionsGlue.java | 130 +- .../itemexchange/rules/BulkExchangeRule.java | 132 +- .../itemexchange/rules/ExchangeRule.java | 789 ++- .../itemexchange/rules/ModifierRegistrar.java | 148 +- .../itemexchange/rules/ShopRule.java | 373 +- .../itemexchange/rules/TradeRule.java | 180 +- .../rules/interfaces/ExchangeData.java | 54 +- .../rules/interfaces/Modifier.java | 16 +- .../rules/interfaces/ModifierData.java | 194 +- .../rules/modifiers/BookModifier.java | 340 +- .../rules/modifiers/DamageableModifier.java | 257 +- .../rules/modifiers/DisplayNameModifier.java | 195 +- .../rules/modifiers/EnchantModifier.java | 403 +- .../modifiers/EnchantStorageModifier.java | 171 +- .../rules/modifiers/LoreModifier.java | 196 +- .../rules/modifiers/PotionModifier.java | 206 +- .../rules/modifiers/RepairModifier.java | 225 +- .../rules/modifiers/_ExampleModifier.java | 152 +- .../itemexchange/utility/ModifierHandler.java | 107 +- .../itemexchange/utility/ModifierStorage.java | 288 +- .../itemexchange/utility/NBTEncodings.java | 170 +- .../itemexchange/utility/RuleHandler.java | 132 +- .../itemexchange/utility/Utilities.java | 334 +- .../utility/functional/NonNullSupplier.java | 6 +- .../src/main/resources/plugin.yml | 6 +- plugins/jukealert-paper/README.md | 13 +- plugins/jukealert-paper/build.gradle.kts | 14 +- .../jukealert/JAConfigManager.java | 57 +- .../com/untamedears/jukealert/JukeAlert.java | 166 +- .../jukealert/SnitchCullManager.java | 34 +- .../untamedears/jukealert/SnitchManager.java | 219 +- .../jukealert/commands/ClearCommand.java | 36 +- .../jukealert/commands/GUICommand.java | 66 +- .../jukealert/commands/InfoCommand.java | 346 +- .../jukealert/commands/JACommandManager.java | 30 +- .../jukealert/commands/ListCommand.java | 136 +- .../jukealert/commands/MuteCommand.java | 43 +- .../jukealert/commands/NameAtCommand.java | 161 +- .../jukealert/commands/NameCommand.java | 53 +- .../commands/ToggleLeverCommand.java | 42 +- .../jukealert/database/JukeAlertDAO.java | 1198 ++-- .../events/PlayerHitSnitchEvent.java | 33 +- .../events/PlayerLoginSnitchEvent.java | 33 +- .../events/PlayerLogoutSnitchEvent.java | 33 +- .../jukealert/gui/SnitchLogGUI.java | 455 +- .../jukealert/gui/SnitchOverviewGUI.java | 150 +- .../listener/LoggableActionListener.java | 424 +- .../listener/SnitchLifeCycleListener.java | 225 +- .../untamedears/jukealert/model/Snitch.java | 457 +- .../jukealert/model/SnitchFactoryType.java | 86 +- .../jukealert/model/SnitchQTEntry.java | 18 +- .../jukealert/model/SnitchTypeManager.java | 342 +- .../model/actions/ActionCacheState.java | 2 +- .../model/actions/LoggedActionFactory.java | 162 +- .../actions/LoggedActionPersistence.java | 264 +- .../model/actions/LoggedActionProvider.java | 4 +- .../model/actions/abstr/LoggableAction.java | 36 +- .../actions/abstr/LoggableBlockAction.java | 314 +- .../actions/abstr/LoggablePlayerAction.java | 193 +- .../abstr/LoggablePlayerVictimAction.java | 42 +- .../model/actions/abstr/PlayerAction.java | 47 +- .../model/actions/abstr/SnitchAction.java | 68 +- .../model/actions/impl/BlockBreakAction.java | 34 +- .../model/actions/impl/BlockPlaceAction.java | 30 +- .../actions/impl/DestroyVehicleAction.java | 52 +- .../actions/impl/DismountEntityAction.java | 38 +- .../model/actions/impl/EmptyBucketAction.java | 26 +- .../model/actions/impl/EnterFieldAction.java | 44 +- .../actions/impl/EnterVehicleAction.java | 50 +- .../model/actions/impl/ExitVehicleAction.java | 52 +- .../model/actions/impl/FillBucketAction.java | 26 +- .../model/actions/impl/IgniteBlockAction.java | 80 +- .../actions/impl/KillLivingEntityAction.java | 40 +- .../model/actions/impl/KillPlayerAction.java | 58 +- .../model/actions/impl/LeaveFieldAction.java | 32 +- .../model/actions/impl/LoginAction.java | 40 +- .../model/actions/impl/LogoutAction.java | 42 +- .../model/actions/impl/MountEntityAction.java | 38 +- .../actions/impl/OpenContainerAction.java | 26 +- .../actions/internal/DestroySnitchAction.java | 50 +- .../appender/AbstractSnitchAppender.java | 68 +- .../appender/BroadcastEntryAppender.java | 103 +- .../appender/ConfigurableSnitchAppender.java | 46 +- .../appender/DormantCullingAppender.java | 390 +- .../model/appender/LeverToggleAppender.java | 126 +- .../appender/ShowOwnerOnDestroyAppender.java | 76 +- .../model/appender/SnitchLogAppender.java | 179 +- .../model/appender/config/AppenderConfig.java | 1 - .../appender/config/DormantCullingConfig.java | 56 +- .../appender/config/LeverToggleConfig.java | 117 +- .../config/LimitedActionTriggerConfig.java | 58 +- .../jukealert/model/field/FieldManager.java | 8 +- .../model/field/SingleCuboidRangeManager.java | 6 +- .../field/VariableSizeCuboidRangeManager.java | 62 +- .../jukealert/util/JASettingsManager.java | 118 +- .../untamedears/jukealert/util/JAUtility.java | 286 +- .../util/JukeAlertPermissionHandler.java | 98 +- .../jukealert/util/OverlayManager.java | 24 +- .../jukealert/util/TimeZoneSetting.java | 26 +- .../src/main/resources/config.yml | 4 +- .../src/main/resources/plugin.yml | 54 +- plugins/kirabukkitgateway-paper/README.md | 8 +- .../kirabukkitgateway-paper/build.gradle.kts | 22 +- .../KiraBukkitGateway/ConfigParser.java | 143 +- .../KiraBukkitGatewayPlugin.java | 160 +- .../maxopoly/KiraBukkitGateway/KiraUtil.java | 8 +- .../auth/AuthcodeManager.java | 58 +- .../CreateDiscordGroupChatCommand.java | 44 +- .../DeleteDiscordGroupChatCommand.java | 34 +- .../GenerateDiscordAuthCodeCommand.java | 34 +- .../command/ReloadKiraCommand.java | 14 +- .../SyncDiscordChannelAccessCommand.java | 46 +- .../InvalidCommandAttemptException.java | 14 +- .../impersonation/KiraLuckPermsWrapper.java | 36 +- .../impersonation/PseudoConsoleSender.java | 274 +- .../impersonation/PseudoPlayer.java | 2636 ++++---- .../impersonation/PseudoPlayerIdentity.java | 18 +- .../impersonation/PseudoSpigotPlayer.java | 54 +- .../listener/CivChatListener.java | 10 +- .../listener/JukeAlertListener.java | 64 +- .../listener/SkynetListener.java | 22 +- .../listener/SnitchHitType.java | 8 +- .../log/KiraLogAppender.java | 30 +- .../rabbit/RabbitCommands.java | 266 +- .../rabbit/RabbitHandler.java | 138 +- .../KiraBukkitGateway/rabbit/RabbitInput.java | 16 +- .../rabbit/RabbitInputHandler.java | 80 +- .../rabbit/in/GroupChatMessageHandler.java | 50 +- .../in/RequestRelayCreationHandler.java | 76 +- .../rabbit/in/RequestSessionHandler.java | 68 +- .../rabbit/in/SendMessageHandler.java | 31 +- .../request/AbstractRequestHandler.java | 44 +- .../rabbit/request/ApiPermsHandler.java | 56 +- .../rabbit/request/ConsoleCommandHandler.java | 66 +- .../rabbit/request/IngameCommandHandler.java | 60 +- .../request/PermissionCheckHandler.java | 46 +- .../src/main/resources/plugin.yml | 10 +- plugins/namecolors-paper/README.md | 4 +- .../namecolors/NameColorSetting.java | 232 +- .../biggestnerd/namecolors/NameColors.java | 145 +- .../src/main/resources/plugin.yml | 6 +- plugins/namelayer-bungee/build.gradle.kts | 8 +- .../mc/namelayer/bungee/BungeeListener.java | 170 +- .../mc/namelayer/bungee/ConfigManager.java | 82 +- .../mc/namelayer/bungee/DataBaseManager.java | 150 +- .../mc/namelayer/bungee/Database.java | 203 +- .../mc/namelayer/bungee/NameLayerBungee.java | 126 +- .../src/main/resources/bungee/config.yml | 18 +- plugins/namelayer-paper/README.md | 4 +- plugins/namelayer-paper/build.gradle.kts | 10 +- .../civcraft/mc/namelayer/GroupManager.java | 1228 ++-- .../vg/civcraft/mc/namelayer/MojangNames.java | 178 +- .../vg/civcraft/mc/namelayer/NameAPI.java | 143 +- .../mc/namelayer/NameLayerPlugin.java | 346 +- .../mc/namelayer/RunnableOnGroup.java | 26 +- .../namelayer/command/BaseCommandMiddle.java | 27 +- .../mc/namelayer/command/CommandHandler.java | 100 +- .../GroupMemberTabCompleter.java | 31 +- .../TabCompleters/GroupTabCompleter.java | 21 +- .../TabCompleters/InviteTabCompleter.java | 25 +- .../TabCompleters/MemberTypeCompleter.java | 11 +- .../TabCompleters/PermissionCompleter.java | 5 +- .../command/commands/AcceptInvite.java | 68 +- .../command/commands/AddBlacklist.java | 68 +- .../command/commands/ChangePlayerName.java | 8 +- .../command/commands/CreateGroup.java | 146 +- .../command/commands/DeleteGroup.java | 139 +- .../command/commands/DisciplineGroup.java | 47 +- .../command/commands/GetDefaultGroup.java | 43 +- .../command/commands/GlobalStats.java | 28 +- .../command/commands/GroupStats.java | 127 +- .../namelayer/command/commands/InfoDump.java | 168 +- .../command/commands/InvitePlayer.java | 269 +- .../namelayer/command/commands/JoinGroup.java | 78 +- .../command/commands/LeaveGroup.java | 44 +- .../command/commands/LinkGroups.java | 128 +- .../command/commands/ListCurrentInvites.java | 12 +- .../command/commands/ListGroups.java | 138 +- .../command/commands/ListInvites.java | 4 +- .../command/commands/ListMembers.java | 136 +- .../command/commands/ListPermissions.java | 69 +- .../command/commands/ListPlayerTypes.java | 20 +- .../command/commands/ListSubGroups.java | 122 +- .../command/commands/MergeGroups.java | 88 +- .../command/commands/ModifyPermissions.java | 153 +- .../command/commands/NameLayerGroupGui.java | 50 +- .../command/commands/PromotePlayer.java | 254 +- .../command/commands/RejectInvite.java | 64 +- .../command/commands/RemoveBlacklist.java | 70 +- .../command/commands/RemoveMember.java | 134 +- .../command/commands/RevokeInvite.java | 146 +- .../command/commands/SetDefaultGroup.java | 61 +- .../command/commands/SetPassword.java | 64 +- .../command/commands/ShowBlacklist.java | 74 +- .../commands/ToggleAutoAcceptInvites.java | 35 +- .../command/commands/TransferGroup.java | 114 +- .../command/commands/UnlinkGroups.java | 116 +- .../command/commands/UpdateName.java | 170 +- .../namelayer/database/AssociationList.java | 349 +- .../namelayer/database/GroupManagerDao.java | 3165 ++++----- .../namelayer/events/GroupAddInvitation.java | 121 +- .../mc/namelayer/events/GroupCreateEvent.java | 132 +- .../mc/namelayer/events/GroupDeleteEvent.java | 101 +- .../events/GroupInvalidationEvent.java | 41 +- .../mc/namelayer/events/GroupMergeEvent.java | 103 +- .../events/GroupPermissionAdditionEvent.java | 104 +- .../events/GroupPermissionRemovalEvent.java | 104 +- .../events/GroupRemoveInvitation.java | 85 +- .../namelayer/events/GroupTransferEvent.java | 82 +- .../namelayer/events/PromotePlayerEvent.java | 111 +- .../mc/namelayer/group/AutoAcceptHandler.java | 50 +- .../mc/namelayer/group/BlackList.java | 167 +- .../namelayer/group/DefaultGroupHandler.java | 87 +- .../vg/civcraft/mc/namelayer/group/Group.java | 1252 ++-- .../mc/namelayer/gui/AbstractGroupGUI.java | 172 +- .../mc/namelayer/gui/AdminFunctionsGUI.java | 397 +- .../mc/namelayer/gui/GUIGroupOverview.java | 770 ++- .../mc/namelayer/gui/InvitationGUI.java | 186 +- .../civcraft/mc/namelayer/gui/LinkingGUI.java | 736 +-- .../mc/namelayer/gui/MainGroupGUI.java | 2384 +++---- .../civcraft/mc/namelayer/gui/MenuUtils.java | 126 +- .../civcraft/mc/namelayer/gui/MergeGUI.java | 372 +- .../mc/namelayer/gui/PermissionManageGUI.java | 402 +- .../listeners/AssociationListener.java | 85 +- .../namelayer/listeners/PlayerListener.java | 233 +- .../mc/namelayer/misc/ClassHandler.java | 64 +- .../mc/namelayer/misc/MaterialInterface.java | 11 +- .../mc/namelayer/misc/MaterialMap.java | 38 +- .../mc/namelayer/misc/NameCleanser.java | 176 +- .../mc/namelayer/misc/NameFetcher.java | 6 +- .../mc/namelayer/misc/ProfileInterface.java | 2 +- .../mc/namelayer/misc/ProfileModifier.java | 36 +- .../namelayer/permission/GroupPermission.java | 211 +- .../permission/PermissionHandler.java | 42 +- .../namelayer/permission/PermissionType.java | 287 +- .../src/main/resources/config.yml | 4 +- .../src/main/resources/plugin.yml | 4 +- plugins/railswitch-paper/README.md | 9 +- plugins/railswitch-paper/build.gradle.kts | 2 +- .../sh/okx/railswitch/glue/CitadelGlue.java | 4 +- .../settings/DestinationSetting.java | 2 +- .../railswitch/settings/RailSwitchMenu.java | 2 +- .../railswitch/settings/SettingsManager.java | 11 +- .../railswitch/switches/SwitchListener.java | 15 +- .../okx/railswitch/switches/SwitchType.java | 10 +- .../src/main/resources/plugin.yml | 8 +- plugins/randomspawn-paper/README.md | 23 +- plugins/randomspawn-paper/build.gradle.kts | 14 +- .../me/josvth/randomspawn/RandomSpawn.java | 116 +- .../randomspawn/commands/AbstractCommand.java | 96 +- .../commands/AddSpawnPointCommand.java | 165 +- .../randomspawn/commands/BedsCommand.java | 96 +- .../randomspawn/commands/DisableCommand.java | 28 +- .../randomspawn/commands/EnableCommand.java | 50 +- .../commands/FirstJoinCommand.java | 86 +- .../randomspawn/commands/HelpCommand.java | 60 +- .../randomspawn/commands/InfoCommand.java | 128 +- .../commands/KeepSpawnsCommand.java | 71 +- .../randomspawn/commands/ReloadCommand.java | 48 +- .../commands/RemoveSpawnPointCommand.java | 87 +- .../randomspawn/commands/SetAreaCommand.java | 220 +- .../commands/SetFirstSpawnCommand.java | 80 +- .../randomspawn/commands/SpawnCommand.java | 108 +- .../commands/TpFirstSpawnCommand.java | 68 +- .../commands/UnsetFirstSpawnCommand.java | 38 +- .../randomspawn/events/NewPlayerSpawn.java | 65 +- .../randomspawn/handlers/CommandHandler.java | 122 +- .../randomspawn/handlers/YamlHandler.java | 82 +- .../randomspawn/listeners/DamageListener.java | 37 +- .../randomspawn/listeners/JoinListener.java | 202 +- .../listeners/RespawnListener.java | 136 +- .../randomspawn/listeners/SignListener.java | 131 +- .../listeners/WorldChangeListener.java | 69 +- .../randomspawn/spawn/AsyncSpawnSelector.java | 192 +- .../spawn/BlockingSpawnSelector.java | 579 +- .../randomspawn/spawn/SpawnSelector.java | 38 +- .../src/main/resources/config.yml | 4 +- .../src/main/resources/plugin.yml | 38 +- .../src/main/resources/worlds.yml | 10 +- plugins/realisticbiomes-paper/README.md | 22 +- .../realisticbiomes-paper/build.gradle.kts | 16 +- .../realisticbiomes/AnimalConfigManager.java | 15 +- .../realisticbiomes/GrowthConfigManager.java | 143 +- .../realisticbiomes/PlantLogicManager.java | 492 +- .../realisticbiomes/PlantManager.java | 52 +- .../realisticbiomes/PlantProgressManager.java | 37 +- .../realisticbiomes/RBConfigManager.java | 780 +-- .../realisticbiomes/RealisticBiomes.java | 162 +- .../realisticbiomes/commands/GrowCommand.java | 10 +- .../realisticbiomes/commands/Menu.java | 56 +- .../commands/RBCommandManager.java | 26 +- .../RealisticBiomesBlockBreakEvent.java | 33 +- .../events/RealisticBiomesBlockGrowEvent.java | 33 +- .../RealisticBiomesStructureGrowEvent.java | 35 +- .../realisticbiomes/events/package-info.java | 10 +- .../realisticbiomes/growth/AgeableGrower.java | 84 +- .../realisticbiomes/growth/BambooGrower.java | 97 +- .../growth/ColumnPlantGrower.java | 10 +- .../growth/CustomTreeGrower.java | 54 +- .../growth/DownwardsGrower.java | 10 +- .../realisticbiomes/growth/FruitGrower.java | 196 +- .../realisticbiomes/growth/FungusGrower.java | 82 +- .../growth/HorizontalBlockSpreadGrower.java | 234 +- .../growth/IArtificialGrower.java | 111 +- .../realisticbiomes/growth/KelpGrower.java | 186 +- .../growth/SchematicGrower.java | 72 +- .../growth/SeaPickleGrower.java | 64 +- .../realisticbiomes/growth/StemGrower.java | 60 +- .../realisticbiomes/growth/TipGrower.java | 206 +- .../realisticbiomes/growth/TreeGrower.java | 334 +- .../growth/VerticalGrower.java | 253 +- .../growthconfig/AbstractGrowthConfig.java | 20 +- .../growthconfig/AnimalMateConfig.java | 26 +- .../growthconfig/FishingConfig.java | 20 +- .../growthconfig/PlantGrowthConfig.java | 827 +-- .../growthconfig/inner/BiomeGrowthConfig.java | 44 +- .../inner/ChanceBasedGrowthConfig.java | 37 +- .../inner/PersistentGrowthConfig.java | 49 +- .../listener/AnimalListener.java | 66 +- .../listener/BonemealListener.java | 54 +- .../realisticbiomes/listener/MobListener.java | 66 +- .../listener/PlantListener.java | 236 +- .../listener/PlayerListener.java | 300 +- .../realisticbiomes/model/Plant.java | 171 +- .../realisticbiomes/model/PlantLoadState.java | 13 +- .../realisticbiomes/model/RBChunkCache.java | 128 +- .../realisticbiomes/model/RBDAO.java | 525 +- .../realisticbiomes/model/RBSchematic.java | 84 +- .../model/gauss/DeviatingDouble.java | 64 +- .../model/gauss/GaussProperty.java | 72 +- .../model/gauss/GaussTree.java | 270 +- .../model/gauss/GaussTreeConfig.java | 100 +- .../model/gauss/drop/BlockDrop.java | 48 +- .../model/ltree/BlockTransformation.java | 68 +- .../realisticbiomes/model/ltree/LStep.java | 66 +- .../model/ltree/LStepConfig.java | 247 +- .../realisticbiomes/model/ltree/LTree.java | 92 +- .../model/ltree/SpreadRule.java | 44 +- .../replant/AutoReplantListener.java | 364 +- .../realisticbiomes/utils/Constants.java | 3 +- .../realisticbiomes/utils/RBUtils.java | 294 +- .../utils/RealisticBiomesGUI.java | 213 +- .../realisticbiomes/utils/SchematicUtils.java | 65 +- .../src/main/resources/plugin.yml | 24 +- plugins/simpleadminhacks-paper/README.md | 106 +- .../simpleadminhacks-paper/build.gradle.kts | 24 +- .../simpleadminhacks/SimpleAdminHacks.java | 269 +- .../SimpleAdminHacksConfig.java | 50 +- .../SimpleAdminHacksSettingManager.java | 25 +- .../configs/BadBoyWatchConfig.java | 110 +- .../configs/BetterRailsConfig.java | 78 +- .../configs/CTAnnounceConfig.java | 111 +- .../configs/DisableAIConfig.java | 126 +- .../configs/ElytraFeaturesConfig.java | 141 +- .../configs/ExperimentalConfig.java | 59 +- .../configs/GameFeaturesConfig.java | 272 +- .../configs/GameFixesConfig.java | 277 +- .../configs/GameTuningConfig.java | 503 +- .../configs/HorseStatsConfig.java | 22 +- .../configs/InsightConfig.java | 40 +- .../configs/IntrobookConfig.java | 200 +- .../configs/InvControlConfig.java | 16 +- .../configs/NewfriendAssistConfig.java | 157 +- .../configs/OneTimeTeleportConfig.java | 112 +- .../configs/ReinforcedChestBreakConfig.java | 2 +- .../configs/SanityHackConfig.java | 50 +- .../configs/SaplingConfig.java | 54 +- .../configs/TimingsHackConfig.java | 88 +- .../configs/ToggleLampConfig.java | 26 +- .../simpleadminhacks/framework/BasicHack.java | 34 +- .../framework/BasicHackConfig.java | 11 +- .../framework/HackManager.java | 335 +- .../framework/SimpleHack.java | 404 +- .../framework/SimpleHackConfig.java | 213 +- .../framework/autoload/AutoLoad.java | 44 +- .../framework/autoload/DataParser.java | 59 +- .../framework/commands/CommandRegistrar.java | 46 +- .../framework/commands/HacksCommand.java | 263 +- .../exceptions/InvalidConfigException.java | 14 +- .../framework/utilities/BetterToString.java | 28 +- .../framework/utilities/BroadcastLevel.java | 10 +- .../framework/utilities/PacketManager.java | 30 +- .../framework/utilities/TeleportUtil.java | 160 +- .../simpleadminhacks/hacks/BadBoyWatch.java | 358 +- .../simpleadminhacks/hacks/BetterRails.java | 146 +- .../simpleadminhacks/hacks/CTAnnounce.java | 180 +- .../simpleadminhacks/hacks/DisableAI.java | 79 +- .../hacks/ElytraFeatures.java | 241 +- .../simpleadminhacks/hacks/Experimental.java | 393 +- .../simpleadminhacks/hacks/GameFeatures.java | 969 ++- .../simpleadminhacks/hacks/GameFixes.java | 625 +- .../simpleadminhacks/hacks/GameTuning.java | 733 +-- .../simpleadminhacks/hacks/HorseStats.java | 147 +- .../simpleadminhacks/hacks/Insight.java | 703 +- .../simpleadminhacks/hacks/Introbook.java | 349 +- .../simpleadminhacks/hacks/InvControl.java | 344 +- .../hacks/NewfriendAssist.java | 512 +- .../hacks/OneTimeTeleport.java | 696 +- .../hacks/ReinforcedChestBreak.java | 120 +- .../simpleadminhacks/hacks/SanityHack.java | 138 +- .../simpleadminhacks/hacks/SaplingHack.java | 132 +- .../simpleadminhacks/hacks/TimingsHack.java | 2036 +++--- .../simpleadminhacks/hacks/ToggleLamp.java | 182 +- .../hacks/basic/AntiDerailment.java | 112 +- .../hacks/basic/AntiFastBreak.java | 326 +- .../hacks/basic/AntiStatisChamber.java | 84 +- .../hacks/basic/ArmourBound.java | 294 +- .../hacks/basic/ArthropodEggHack.java | 106 +- .../hacks/basic/AttrHider.java | 356 +- .../hacks/basic/AutoRespawn.java | 314 +- .../hacks/basic/BedLocator.java | 91 +- .../hacks/basic/BeeKeeping.java | 309 +- .../hacks/basic/BuffSpanker.java | 58 +- .../hacks/basic/CopperRail.java | 278 +- .../hacks/basic/DebugWand.java | 181 +- .../hacks/basic/DespawnFix.java | 50 +- .../hacks/basic/DogFacts.java | 92 +- .../hacks/basic/EventDebugHack.java | 342 +- .../hacks/basic/EventHandlerList.java | 244 +- .../hacks/basic/FasterHorses.java | 93 +- .../hacks/basic/GoldBlockElevators.java | 242 +- .../hacks/basic/HumbugBatchOne.java | 643 +- .../hacks/basic/ItemMetaConverterHack.java | 98 +- .../hacks/basic/MapCopyProtection.java | 30 +- .../hacks/basic/MobCondenser.java | 171 +- .../hacks/basic/OldEnchanting.java | 1064 ++- .../hacks/basic/PhantomMenace.java | 157 +- .../hacks/basic/PlayerRevive.java | 88 +- .../hacks/basic/PlayerStatistics.java | 170 +- .../hacks/basic/PortalModifyHack.java | 159 +- .../hacks/basic/PortalSpawnModifier.java | 222 +- .../hacks/basic/SafeOreBreak.java | 172 +- .../hacks/basic/ShipOutOfLuck.java | 156 +- .../hacks/basic/StrayStats.java | 112 +- .../hacks/basic/StriderBreeding.java | 163 +- .../hacks/basic/TestConfigHack.java | 167 +- .../src/main/resources/config.yml | 70 +- .../src/main/resources/plugin.yml | 8 +- 1292 files changed, 115798 insertions(+), 114823 deletions(-) diff --git a/plugins/.editorconfig b/plugins/.editorconfig index 1eb461bec..6eece638a 100644 --- a/plugins/.editorconfig +++ b/plugins/.editorconfig @@ -23,7 +23,7 @@ ij_java_blank_lines_after_anonymous_class_header = 0 ij_java_blank_lines_after_class_header = 1 ij_java_blank_lines_before_imports = 1 ij_java_class_count_to_use_import_on_demand = 999 -ij_java_imports_layout = $*,|,* +ij_java_imports_layout = $*, |, * ij_java_layout_static_imports_separately = true ij_java_names_count_to_use_import_on_demand = 999 ij_java_use_single_class_imports = true diff --git a/plugins/banstick-paper/README.md b/plugins/banstick-paper/README.md index dfceb6d82..6c7d9744f 100644 --- a/plugins/banstick-paper/README.md +++ b/plugins/banstick-paper/README.md @@ -9,13 +9,19 @@ Ban 'em, investigate and ban their providers, breath easy again. -------- #Main features: -* Supports range-bans: Ban players by name, IP address, and subnet -- also ban a player's entire subnet with a single command. -* Supports auto-VPN/VPS flagging: Growing list of vpn/vps range loading for easy vpn / vps proxy flagging. + +* Supports range-bans: Ban players by name, IP address, and subnet -- also ban a player's entire subnet with a single + command. +* Supports auto-VPN/VPS flagging: Growing list of vpn/vps range loading for easy vpn / vps proxy flagging. * Supports scraping of anon proxies: Scrape a number of anonymous proxy providers in a sustainable interval. -* Supports grabbing of up-to-date Tor exit nodes: Good Tor ban citizen, only grabs and blocks Tor exit notes, configurably. -* Supports automatic grabbing of IP geodata: Uses a batch-request service to never exceed TOS while still providing quality IP geo data. -* Easy expansion: VPN/VPS/Proxy list, HTML Proxy list Scraping, and Tor exit scrapers are easily expanded to include new sources. -* Automatic multi-account support and banning: Set a valid limit of multi-accounts with auto-banning of new accounts that exceed that limit. +* Supports grabbing of up-to-date Tor exit nodes: Good Tor ban citizen, only grabs and blocks Tor exit notes, + configurably. +* Supports automatic grabbing of IP geodata: Uses a batch-request service to never exceed TOS while still providing + quality IP geo data. +* Easy expansion: VPN/VPS/Proxy list, HTML Proxy list Scraping, and Tor exit scrapers are easily expanded to include new + sources. +* Automatic multi-account support and banning: Set a valid limit of multi-accounts with auto-banning of new accounts + that exceed that limit. * Easily manage existing bans, exemptions by ban class (IP / Proxy / Share) * Import data from IP-Check (room for expansion to other tools) including preserving pardons / exclusions diff --git a/plugins/banstick-paper/build.gradle.kts b/plugins/banstick-paper/build.gradle.kts index 5cb7f26ac..d83b5ab44 100644 --- a/plugins/banstick-paper/build.gradle.kts +++ b/plugins/banstick-paper/build.gradle.kts @@ -1,18 +1,18 @@ plugins { - id("io.papermc.paperweight.userdev") - id("com.github.johnrengelman.shadow") + id("io.papermc.paperweight.userdev") + id("com.github.johnrengelman.shadow") } version = "2.0.1" dependencies { - paperweight { - paperDevBundle("1.20.4-R0.1-SNAPSHOT") - } + paperweight { + paperDevBundle("1.20.4-R0.1-SNAPSHOT") + } - compileOnly(project(":plugins:civmodcore-paper")) - compileOnly(project(":plugins:namelayer-paper")) + compileOnly(project(":plugins:civmodcore-paper")) + compileOnly(project(":plugins:namelayer-paper")) - implementation("com.github.seancfoley:ipaddress:2.0.2") - implementation("org.jsoup:jsoup:1.13.1") + implementation("com.github.seancfoley:ipaddress:2.0.2") + implementation("org.jsoup:jsoup:1.13.1") } diff --git a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/BanStick.java b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/BanStick.java index e3406953c..1b245da0c 100644 --- a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/BanStick.java +++ b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/BanStick.java @@ -15,239 +15,239 @@ import vg.civcraft.mc.civmodcore.ACivMod; public class BanStick extends ACivMod { - private static BanStick instance; + private static BanStick instance; - @SuppressWarnings("unused") - private BanStickCommandHandler commandHandler; - private BanStickEventHandler eventHandler; - private BanStickDatabaseHandler databaseHandler; - private BanStickTorUpdater torUpdater; - private BanStickProxyHandler proxyHandler; - private BanStickIPDataHandler ipDataUpdater; - private BanStickIPHubHandler ipHubUpdater; - private BanStickScrapeHandler scrapeHandler; - private BanStickImportHandler importHandler; - private BSLog logHandler; - private BSRegistrars bannedRegistrars; + @SuppressWarnings("unused") + private BanStickCommandHandler commandHandler; + private BanStickEventHandler eventHandler; + private BanStickDatabaseHandler databaseHandler; + private BanStickTorUpdater torUpdater; + private BanStickProxyHandler proxyHandler; + private BanStickIPDataHandler ipDataUpdater; + private BanStickIPHubHandler ipHubUpdater; + private BanStickScrapeHandler scrapeHandler; + private BanStickImportHandler importHandler; + private BSLog logHandler; + private BSRegistrars bannedRegistrars; - private boolean slaveMode; + private boolean slaveMode; - @Override - public void onEnable() { - instance = this; - super.onEnable(); + @Override + public void onEnable() { + instance = this; + super.onEnable(); - saveDefaultConfig(); + saveDefaultConfig(); - connectDatabase(); - if (!isEnabled()) { - return; - } + connectDatabase(); + if (!isEnabled()) { + return; + } - if (getConfig().getBoolean("slaveMode", false)) { - this.slaveMode = true; - } + if (getConfig().getBoolean("slaveMode", false)) { + this.slaveMode = true; + } - registerEventHandler(); - registerCommandHandler(); - registerTorHandler(); - registerProxyHandler(); - registerIPDataHandler(); - registerIPHubHandler(); - registerScrapeHandler(); - registerImportHandler(); - registerLogHandler(); - registerRegistrarHandler(); - } + registerEventHandler(); + registerCommandHandler(); + registerTorHandler(); + registerProxyHandler(); + registerIPDataHandler(); + registerIPHubHandler(); + registerScrapeHandler(); + registerImportHandler(); + registerLogHandler(); + registerRegistrarHandler(); + } - @Override - public void onDisable() { - if (this.eventHandler != null) { - this.eventHandler.shutdown(); - } - if (this.proxyHandler != null) { - this.proxyHandler.shutdown(); - } - if (this.scrapeHandler != null) { - this.scrapeHandler.shutdown(); - } - if (this.ipDataUpdater != null) { - this.ipDataUpdater.end(); - } - if (this.ipHubUpdater != null) { - this.ipHubUpdater.end(); - } - if (this.torUpdater != null) { - this.torUpdater.shutdown(); - } - if (this.importHandler != null) { - this.importHandler.shutdown(); - } - if (this.logHandler != null) { - this.logHandler.disable(); - } - if (this.databaseHandler != null) { - this.databaseHandler.doShutdown(); - } + @Override + public void onDisable() { + if (this.eventHandler != null) { + this.eventHandler.shutdown(); + } + if (this.proxyHandler != null) { + this.proxyHandler.shutdown(); + } + if (this.scrapeHandler != null) { + this.scrapeHandler.shutdown(); + } + if (this.ipDataUpdater != null) { + this.ipDataUpdater.end(); + } + if (this.ipHubUpdater != null) { + this.ipHubUpdater.end(); + } + if (this.torUpdater != null) { + this.torUpdater.shutdown(); + } + if (this.importHandler != null) { + this.importHandler.shutdown(); + } + if (this.logHandler != null) { + this.logHandler.disable(); + } + if (this.databaseHandler != null) { + this.databaseHandler.doShutdown(); + } - super.onDisable(); - } + super.onDisable(); + } - private void connectDatabase() { - try { - this.databaseHandler = new BanStickDatabaseHandler(getConfig()); - } catch (Exception e) { - severe("Failed to establish database", e); - setEnabled(false); - } - } + private void connectDatabase() { + try { + this.databaseHandler = new BanStickDatabaseHandler(getConfig()); + } catch (Exception e) { + severe("Failed to establish database", e); + setEnabled(false); + } + } - public BanStickIPDataHandler getIPDataHandler() { - return this.ipDataUpdater; - } + public BanStickIPDataHandler getIPDataHandler() { + return this.ipDataUpdater; + } - public BanStickIPHubHandler getIPHubHandler() { - return this.ipHubUpdater; - } + public BanStickIPHubHandler getIPHubHandler() { + return this.ipHubUpdater; + } - public BanStickEventHandler getEventHandler() { - return this.eventHandler; - } + public BanStickEventHandler getEventHandler() { + return this.eventHandler; + } - private void registerCommandHandler() { - if (!isEnabled()) { - return; - } - try { - this.commandHandler = new BanStickCommandHandler(getConfig()); - } catch (Exception e) { - severe("Failed to set up command handling", e); - setEnabled(false); - } - } + private void registerCommandHandler() { + if (!isEnabled()) { + return; + } + try { + this.commandHandler = new BanStickCommandHandler(getConfig()); + } catch (Exception e) { + severe("Failed to set up command handling", e); + setEnabled(false); + } + } - private void registerEventHandler() { - if (!isEnabled()) { - return; - } - try { - this.eventHandler = new BanStickEventHandler(getConfig()); - } catch (Exception e) { - severe("Failed to set up event capture / handling", e); - setEnabled(false); - } - } + private void registerEventHandler() { + if (!isEnabled()) { + return; + } + try { + this.eventHandler = new BanStickEventHandler(getConfig()); + } catch (Exception e) { + severe("Failed to set up event capture / handling", e); + setEnabled(false); + } + } - private void registerTorHandler() { - if (!isEnabled()) { - return; - } - try { - this.torUpdater = new BanStickTorUpdater(getConfig()); - } catch (Exception e) { - severe("Failed to set up TOR updater!", e); - } - } + private void registerTorHandler() { + if (!isEnabled()) { + return; + } + try { + this.torUpdater = new BanStickTorUpdater(getConfig()); + } catch (Exception e) { + severe("Failed to set up TOR updater!", e); + } + } - private void registerProxyHandler() { - if (!isEnabled()) { - return; - } - try { - this.proxyHandler = new BanStickProxyHandler(getConfig(), getClassLoader()); - } catch (Exception e) { - severe("Failed to set up Proxy updaters!", e); - } - } + private void registerProxyHandler() { + if (!isEnabled()) { + return; + } + try { + this.proxyHandler = new BanStickProxyHandler(getConfig(), getClassLoader()); + } catch (Exception e) { + severe("Failed to set up Proxy updaters!", e); + } + } - private void registerIPDataHandler() { - if (!isEnabled()) { - return; - } - try { - this.ipDataUpdater = new BanStickIPDataHandler(getConfig()); - } catch (Exception e) { - severe("Failed to set up dynamic IPData updater!", e); - } - } + private void registerIPDataHandler() { + if (!isEnabled()) { + return; + } + try { + this.ipDataUpdater = new BanStickIPDataHandler(getConfig()); + } catch (Exception e) { + severe("Failed to set up dynamic IPData updater!", e); + } + } - private void registerIPHubHandler() { - if (!isEnabled()) { - return; - } - try { - this.ipHubUpdater = new BanStickIPHubHandler(getConfig()); - } catch (Exception e) { - severe("Failed to set up dynamic IPHub.info updater!", e); - } - } + private void registerIPHubHandler() { + if (!isEnabled()) { + return; + } + try { + this.ipHubUpdater = new BanStickIPHubHandler(getConfig()); + } catch (Exception e) { + severe("Failed to set up dynamic IPHub.info updater!", e); + } + } - private void registerScrapeHandler() { - if (!isEnabled()) { - return; - } - try { - this.scrapeHandler = new BanStickScrapeHandler(getConfig(), getClassLoader()); - } catch (Exception e) { - severe("Failed to set up anonymous proxy scrapers", e); - } - } + private void registerScrapeHandler() { + if (!isEnabled()) { + return; + } + try { + this.scrapeHandler = new BanStickScrapeHandler(getConfig(), getClassLoader()); + } catch (Exception e) { + severe("Failed to set up anonymous proxy scrapers", e); + } + } - private void registerImportHandler() { - if (!isEnabled()) { - return; - } - try { - this.importHandler = new BanStickImportHandler(getConfig(), getClassLoader()); - } catch (Exception e) { - severe("Failed to set up data imports", e); - } - } + private void registerImportHandler() { + if (!isEnabled()) { + return; + } + try { + this.importHandler = new BanStickImportHandler(getConfig(), getClassLoader()); + } catch (Exception e) { + severe("Failed to set up data imports", e); + } + } - private void registerLogHandler() { - if (!isEnabled()) { - return; - } - try { - this.logHandler = new BSLog(getConfig()); - this.logHandler.runTaskTimerAsynchronously(this, this.logHandler.getDelay(), this.logHandler.getPeriod()); - } catch (Exception e) { - severe("Failed to set up ban log handler", e); - } - } - - private void registerRegistrarHandler() { - if (!isEnabled()) { - return; - } - try { - this.bannedRegistrars = new BSRegistrars(); - } catch (Exception e) { - severe("Failed to set up registrar ban handler", e); - } - } - - public BSRegistrars getRegistrarHandler() { - return bannedRegistrars; - } + private void registerLogHandler() { + if (!isEnabled()) { + return; + } + try { + this.logHandler = new BSLog(getConfig()); + this.logHandler.runTaskTimerAsynchronously(this, this.logHandler.getDelay(), this.logHandler.getPeriod()); + } catch (Exception e) { + severe("Failed to set up ban log handler", e); + } + } - public BSLog getLogHandler() { - return this.logHandler; - } + private void registerRegistrarHandler() { + if (!isEnabled()) { + return; + } + try { + this.bannedRegistrars = new BSRegistrars(); + } catch (Exception e) { + severe("Failed to set up registrar ban handler", e); + } + } - /** - * @return the static global instance. Not my fav pattern, but whatever. - */ - public static BanStick getPlugin() { - return instance; - } + public BSRegistrars getRegistrarHandler() { + return bannedRegistrars; + } - public void saveCache() { - this.databaseHandler.doShutdown(); - } + public BSLog getLogHandler() { + return this.logHandler; + } - public static boolean slave() { - return instance.slaveMode; - } + /** + * @return the static global instance. Not my fav pattern, but whatever. + */ + public static BanStick getPlugin() { + return instance; + } + + public void saveCache() { + this.databaseHandler.doShutdown(); + } + + public static boolean slave() { + return instance.slaveMode; + } } diff --git a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/commands/BanRegistrarCommand.java b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/commands/BanRegistrarCommand.java index f4142e32f..f72cf2714 100644 --- a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/commands/BanRegistrarCommand.java +++ b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/commands/BanRegistrarCommand.java @@ -17,48 +17,47 @@ import vg.civcraft.mc.namelayer.NameAPI; public class BanRegistrarCommand implements CommandExecutor { - public static final String name = "banprovider"; + public static final String name = "banprovider"; - @Override - public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { - if (args.length == 0) { - sender.sendMessage(ChatColor.RED + "You must specify a player whose last provider will be banned"); - return true; - } - UUID uuid = NameAPI.getUUID(args[0]); - if (uuid == null) { - sender.sendMessage(ChatColor.RED + "No player " + args[0] + " is known"); - return true; - } - BSPlayer player = BSPlayer.byUUID(uuid); - BSSession lastSession = player.getLatestSession(); - BSIP ip = lastSession.getIP(); - List proxyChecks = BSIPData.allByIP(ip); - if (proxyChecks.isEmpty()) { + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (args.length == 0) { + sender.sendMessage(ChatColor.RED + "You must specify a player whose last provider will be banned"); + return true; + } + UUID uuid = NameAPI.getUUID(args[0]); + if (uuid == null) { + sender.sendMessage(ChatColor.RED + "No player " + args[0] + " is known"); + return true; + } + BSPlayer player = BSPlayer.byUUID(uuid); + BSSession lastSession = player.getLatestSession(); + BSIP ip = lastSession.getIP(); + List proxyChecks = BSIPData.allByIP(ip); + if (proxyChecks.isEmpty()) { - } - BSRegistrars handler = BanStick.getPlugin().getRegistrarHandler(); - for (BSIPData data : proxyChecks) { - if (data.getRegisteredAs() == null || data.getRegisteredAs().isEmpty()) { - sender.sendMessage(ChatColor.RED + "Can not ban registrar, because none was known"); - continue; - } - if (args.length >= 2) { - handler.unbanRegistrar(data); - sender.sendMessage( - ChatColor.GREEN + "Forgave registrar " + data.getRegisteredAs() + " of " + data.toString()); - } - else { - handler.banRegistrar(data); - sender.sendMessage( - ChatColor.GREEN + "Banning registrar " + data.getRegisteredAs() + " of " + data.toString()); - } - } - if (args.length == 1) { - //also give them an ip ban on the way if they dont have one already - BanHandler.doIPBan(ip, null, null, true, false); - } - return true; - } + } + BSRegistrars handler = BanStick.getPlugin().getRegistrarHandler(); + for (BSIPData data : proxyChecks) { + if (data.getRegisteredAs() == null || data.getRegisteredAs().isEmpty()) { + sender.sendMessage(ChatColor.RED + "Can not ban registrar, because none was known"); + continue; + } + if (args.length >= 2) { + handler.unbanRegistrar(data); + sender.sendMessage( + ChatColor.GREEN + "Forgave registrar " + data.getRegisteredAs() + " of " + data.toString()); + } else { + handler.banRegistrar(data); + sender.sendMessage( + ChatColor.GREEN + "Banning registrar " + data.getRegisteredAs() + " of " + data.toString()); + } + } + if (args.length == 1) { + //also give them an ip ban on the way if they dont have one already + BanHandler.doIPBan(ip, null, null, true, false); + } + return true; + } } diff --git a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/commands/BanSaveCommand.java b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/commands/BanSaveCommand.java index cd49ccc34..ac3ac8297 100644 --- a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/commands/BanSaveCommand.java +++ b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/commands/BanSaveCommand.java @@ -7,13 +7,13 @@ import org.bukkit.command.CommandSender; public class BanSaveCommand implements CommandExecutor { - public static String name = "bansave"; - - @Override - public boolean onCommand(CommandSender sender, Command cmd, String cmdString, String[] arguments) { - BanStick.getPlugin().saveCache(); - - return true; - } + public static String name = "bansave"; + + @Override + public boolean onCommand(CommandSender sender, Command cmd, String cmdString, String[] arguments) { + BanStick.getPlugin().saveCache(); + + return true; + } } diff --git a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/commands/BanStickCommand.java b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/commands/BanStickCommand.java index 83bf7e996..19e175f79 100644 --- a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/commands/BanStickCommand.java +++ b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/commands/BanStickCommand.java @@ -24,159 +24,158 @@ import vg.civcraft.mc.namelayer.NameAPI; /** * BanStick! BanStick! Ban all the nerds by name, CIDR, IP, or some combo. - * - * @author ProgrammerDan * + * @author ProgrammerDan */ public class BanStickCommand implements CommandExecutor { - public static String name = "banstick"; - - /** - * Behavior: If given a name or uuid, bans that uuid with a new ban if none exists for that uuid. - * Returns ban details. - * - *

If name or uuid with a CIDR postfix, bans that uuid, AND issues a ban against their IP address / subnet. - * - *

If IP, bans that IP and all players who have used it. - * - *

If IP/CIDR, bans that IP subnet and all players who have used it. - * - */ - @Override - public boolean onCommand(CommandSender sender, Command cmd, String cmdString, String[] arguments) { + public static String name = "banstick"; + + /** + * Behavior: If given a name or uuid, bans that uuid with a new ban if none exists for that uuid. + * Returns ban details. + * + *

If name or uuid with a CIDR postfix, bans that uuid, AND issues a ban against their IP address / subnet. + * + *

If IP, bans that IP and all players who have used it. + * + *

If IP/CIDR, bans that IP subnet and all players who have used it. + */ + @Override + public boolean onCommand(CommandSender sender, Command cmd, String cmdString, String[] arguments) { /* * - / [ip] [banend: mm/dd/yyyy [hh:mm:ss]] [message] - / [ip]/[CIDR] [banend: mm/dd/yyyy [hh:mm:ss]] [message] - / [name/uuid] [banend: mm/dd/yyyy [hh:mm:ss]] [message] - / [name/uuid]/[CIDR] [banend: mm/dd/yyyy [hh:mm:ss]] [message] */ - // Check if name. Check if uuid. Check if ip-ipv4 vs. ipv6. - if (arguments.length < 1) { - return false; - } - - String preBan = arguments[0]; - int locCIDR = preBan.indexOf('/'); - Boolean hasCIDR = locCIDR > -1; - Integer cidr = (hasCIDR) ? Integer.valueOf(preBan.substring(locCIDR + 1)) : null; - String toBan = (hasCIDR) ? preBan.substring(0, locCIDR) : preBan; - String endDate = (arguments.length >= 2 ? arguments[1] : null); - String endTime = (arguments.length >= 3 ? arguments[2] : null); - SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy"); - SimpleDateFormat combinedFormat = new SimpleDateFormat("MM/dd/yyyy HH:mms:ss"); - Date banEndDate = null; - Date banEndTime = null; - Date banEnd = null; - int messageStart = 1; + // Check if name. Check if uuid. Check if ip-ipv4 vs. ipv6. + if (arguments.length < 1) { + return false; + } - BanStick.getPlugin().debug("preBan: {0}, CIDR? {1}, toBan: {2}, endDate: {3}, endTime: {4}", - preBan, cidr, toBan, endDate, endTime); - - if (endDate != null) { - try { - banEndDate = dateFormat.parse(endDate); - banEnd = banEndDate; - messageStart ++; - } catch (ParseException pe) { - banEndDate = null; - } + String preBan = arguments[0]; + int locCIDR = preBan.indexOf('/'); + Boolean hasCIDR = locCIDR > -1; + Integer cidr = (hasCIDR) ? Integer.valueOf(preBan.substring(locCIDR + 1)) : null; + String toBan = (hasCIDR) ? preBan.substring(0, locCIDR) : preBan; + String endDate = (arguments.length >= 2 ? arguments[1] : null); + String endTime = (arguments.length >= 3 ? arguments[2] : null); + SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy"); + SimpleDateFormat combinedFormat = new SimpleDateFormat("MM/dd/yyyy HH:mms:ss"); + Date banEndDate = null; + Date banEndTime = null; + Date banEnd = null; + int messageStart = 1; - if (banEndDate != null && endTime != null) { - try { - banEndTime = combinedFormat.parse(endDate + " " + endTime); - banEnd = banEndTime; - messageStart ++; - } catch (ParseException pe) { - banEndTime = null; - } - } - } - - String message = (arguments.length >= messageStart - ? String.join(" ", Arrays.copyOfRange(arguments, messageStart, arguments.length)) : null); - - BanStick.getPlugin().debug("message: {0}", message); - - try { - IPAddress ipcheck = new IPAddressString(toBan).toAddress(); - if (!sender.hasPermission("banstick.ips")) { - sender.sendMessage(ChatColor.RED + "You don't have permission to use / view IPs"); - return true; - } - - BSIP exact = !hasCIDR ? BSIP.byIPAddress(ipcheck) : BSIP.byCIDR(ipcheck.toString(), cidr); - if (exact == null) { - // new IP record. - exact = hasCIDR ? BSIP.create(ipcheck, cidr) : BSIP.create(ipcheck); - } - - BanResult result = hasCIDR ? BanHandler.doCIDRBan(exact, message, banEnd, true, false) : - BanHandler.doIPBan(exact, message, banEnd, true, false); - - result.informCommandSender(sender); - - return true; - } catch (IPAddressStringException e) { - // Not an IP address! - UUID playerId = null; - if (toBan.length() <= 16) { - try { - playerId = null; - try { - playerId = NameAPI.getUUID(toBan); - } catch (NoClassDefFoundError ncde) { } - - if (playerId == null) { - Player match = Bukkit.getPlayer(toBan); - if (match != null) { - playerId = match.getUniqueId(); - } - } - } catch (Exception ee) { - sender.sendMessage(ChatColor.RED + "Unable to find player " + ChatColor.DARK_RED + toBan); - } - } else if (toBan.length() == 36) { - try { - playerId = UUID.fromString(toBan); - } catch (IllegalArgumentException iae) { - sender.sendMessage(ChatColor.RED + "Unable to process uuid " + ChatColor.DARK_RED + toBan); - } - } else { - sender.sendMessage(ChatColor.RED + "Unable to interpret " + ChatColor.DARK_RED + toBan); - } - - if (playerId != null) { - BanResult result = null; - - if (hasCIDR) { // we only do an IP ban for a player if with CIDR, and then a CIDR on their current IP. - Player target = Bukkit.getPlayer(playerId); - - if (target != null) { - InetSocketAddress isa = target.getAddress(); - InetAddress na = isa != null ? isa.getAddress() : null; - - // target's address is @nullable so we need to explicitly handle that. - if (na != null) { - BSIP exact = BSIP.byCIDR(na, cidr); - if (exact == null) { - // new IP record. - exact = BSIP.create(na, cidr); - } - - result = BanHandler.doCIDRBan(exact, message, banEnd, true, false); - result.informCommandSender(sender); - } - } - } - - result = BanHandler.doUUIDBan(playerId, message, banEnd, true); - result.informCommandSender(sender); - return true; - } else { - sender.sendMessage(ChatColor.RED + "Unable to find " + ChatColor.DARK_RED + toBan); - } - } - return false; - } + BanStick.getPlugin().debug("preBan: {0}, CIDR? {1}, toBan: {2}, endDate: {3}, endTime: {4}", + preBan, cidr, toBan, endDate, endTime); + + if (endDate != null) { + try { + banEndDate = dateFormat.parse(endDate); + banEnd = banEndDate; + messageStart++; + } catch (ParseException pe) { + banEndDate = null; + } + + if (banEndDate != null && endTime != null) { + try { + banEndTime = combinedFormat.parse(endDate + " " + endTime); + banEnd = banEndTime; + messageStart++; + } catch (ParseException pe) { + banEndTime = null; + } + } + } + + String message = (arguments.length >= messageStart + ? String.join(" ", Arrays.copyOfRange(arguments, messageStart, arguments.length)) : null); + + BanStick.getPlugin().debug("message: {0}", message); + + try { + IPAddress ipcheck = new IPAddressString(toBan).toAddress(); + if (!sender.hasPermission("banstick.ips")) { + sender.sendMessage(ChatColor.RED + "You don't have permission to use / view IPs"); + return true; + } + + BSIP exact = !hasCIDR ? BSIP.byIPAddress(ipcheck) : BSIP.byCIDR(ipcheck.toString(), cidr); + if (exact == null) { + // new IP record. + exact = hasCIDR ? BSIP.create(ipcheck, cidr) : BSIP.create(ipcheck); + } + + BanResult result = hasCIDR ? BanHandler.doCIDRBan(exact, message, banEnd, true, false) : + BanHandler.doIPBan(exact, message, banEnd, true, false); + + result.informCommandSender(sender); + + return true; + } catch (IPAddressStringException e) { + // Not an IP address! + UUID playerId = null; + if (toBan.length() <= 16) { + try { + playerId = null; + try { + playerId = NameAPI.getUUID(toBan); + } catch (NoClassDefFoundError ncde) { + } + + if (playerId == null) { + Player match = Bukkit.getPlayer(toBan); + if (match != null) { + playerId = match.getUniqueId(); + } + } + } catch (Exception ee) { + sender.sendMessage(ChatColor.RED + "Unable to find player " + ChatColor.DARK_RED + toBan); + } + } else if (toBan.length() == 36) { + try { + playerId = UUID.fromString(toBan); + } catch (IllegalArgumentException iae) { + sender.sendMessage(ChatColor.RED + "Unable to process uuid " + ChatColor.DARK_RED + toBan); + } + } else { + sender.sendMessage(ChatColor.RED + "Unable to interpret " + ChatColor.DARK_RED + toBan); + } + + if (playerId != null) { + BanResult result = null; + + if (hasCIDR) { // we only do an IP ban for a player if with CIDR, and then a CIDR on their current IP. + Player target = Bukkit.getPlayer(playerId); + + if (target != null) { + InetSocketAddress isa = target.getAddress(); + InetAddress na = isa != null ? isa.getAddress() : null; + + // target's address is @nullable so we need to explicitly handle that. + if (na != null) { + BSIP exact = BSIP.byCIDR(na, cidr); + if (exact == null) { + // new IP record. + exact = BSIP.create(na, cidr); + } + + result = BanHandler.doCIDRBan(exact, message, banEnd, true, false); + result.informCommandSender(sender); + } + } + } + + result = BanHandler.doUUIDBan(playerId, message, banEnd, true); + result.informCommandSender(sender); + return true; + } else { + sender.sendMessage(ChatColor.RED + "Unable to find " + ChatColor.DARK_RED + toBan); + } + } + return false; + } } diff --git a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/commands/DoubleTapCommand.java b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/commands/DoubleTapCommand.java index 56c60d329..82fc98783 100644 --- a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/commands/DoubleTapCommand.java +++ b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/commands/DoubleTapCommand.java @@ -27,15 +27,14 @@ import vg.civcraft.mc.namelayer.NameAPI; /** * Always finish with a DoubleTap to the head -- handles manually unpardoning and perhaps banning nerds who multiaccount - * - * @author ProgrammerDan * + * @author ProgrammerDan */ public class DoubleTapCommand implements CommandExecutor { - public static String name = "doubletap"; - - /** + public static String name = "doubletap"; + + /** * doubletap [+][ip] [banend: mm/dd/yyyy [hh:mm:ss]] [message] * Finds all sessions that use this IP, finds all Shares connected to those Sessions, unpardons any pardoned shares. * If [+] before the IP, also Share-bans all non-pardoned players. @@ -43,214 +42,215 @@ public class DoubleTapCommand implements CommandExecutor { * doubletap [+][name/uuid] [+][name/uuid] [banend: mm/dd/yyyy [hh:mm:ss]] [message] * Finds all Shares between the two named players, unpardons them if pardoned. * If [+] before a name, also Share-bans that player, removing any Share pardons if they existed. - * - */ - @Override - public boolean onCommand(CommandSender sender, Command cmd, String cmdString, String[] arguments) { - // Check if name. Check if uuid. Check if ip-ipv4 vs. ipv6. - if (arguments.length < 1) { - return false; - } - - String preBan = arguments[0]; - boolean doBan = preBan.indexOf('+') > -1; - String toBan = doBan ? preBan.substring(1) : preBan; - boolean secondDoBan = false; - String secondBan = null; - IPAddress ipcheck = null; - int offset = 0; - - // check if IP path - try { - ipcheck = new IPAddressString(toBan).toAddress(); - } catch (IPAddressStringException | IPAddressTypeException e) { - ipcheck = null; + */ + @Override + public boolean onCommand(CommandSender sender, Command cmd, String cmdString, String[] arguments) { + // Check if name. Check if uuid. Check if ip-ipv4 vs. ipv6. + if (arguments.length < 1) { + return false; + } - if (arguments.length < 2) { - return false; - } + String preBan = arguments[0]; + boolean doBan = preBan.indexOf('+') > -1; + String toBan = doBan ? preBan.substring(1) : preBan; + boolean secondDoBan = false; + String secondBan = null; + IPAddress ipcheck = null; + int offset = 0; - offset = 1; - secondDoBan = arguments[1].indexOf('+') > -1; - secondBan = secondDoBan ? arguments[1].substring(1) : arguments[1]; - } - - String endDate = (arguments.length >= (2 + offset) ? arguments[1 + offset] : null); - String endTime = (arguments.length >= (3 + offset) ? arguments[2 + offset] : null); - SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy"); - SimpleDateFormat combinedFormat = new SimpleDateFormat("MM/dd/yyyy HH:mms:ss"); - Date banEndDate = null; - Date banEndTime = null; - Date banEnd = null; - int messageStart = 1 + offset; + // check if IP path + try { + ipcheck = new IPAddressString(toBan).toAddress(); + } catch (IPAddressStringException | IPAddressTypeException e) { + ipcheck = null; - BanStick.getPlugin().debug( - "preBan: {0}, doBan? {1}, toBan: {2}, sDoBan? {3}, sBan: {4}, endDate: {5}, endTime: {6}", - preBan, doBan, toBan, secondDoBan, secondBan, endDate, endTime); - - if (endDate != null) { - try { - banEndDate = dateFormat.parse(endDate); - banEnd = banEndDate; - messageStart ++; - } catch (ParseException pe) { - banEndDate = null; - } + if (arguments.length < 2) { + return false; + } - if (banEndDate != null && endTime != null) { - try { - banEndTime = combinedFormat.parse(endDate + " " + endTime); - banEnd = banEndTime; - messageStart ++; - } catch (ParseException pe) { - banEndTime = null; - } - } - } - - String message = (arguments.length >= messageStart ? String.join(" ", - Arrays.copyOfRange(arguments, messageStart, arguments.length)) : null); - - BanStick.getPlugin().debug("message: {0}", message); - - if (ipcheck != null) { - if (!sender.hasPermission("banstick.ips")) { - sender.sendMessage(ChatColor.RED + "You don't have permission to use / view IPs"); - return true; - } - - BSIP exact = BSIP.byIPAddress(ipcheck); - if (exact == null) { - sender.sendMessage(ChatColor.YELLOW + "That IP address not found, no shares modified."); - return true; - } - - List sessions = BSSession.byIP(exact); - - if (sessions == null || sessions.isEmpty()) { - sender.sendMessage(ChatColor.YELLOW + "That IP address does not connect to any sessions."); - return true; - } - - int unpardoned = 0; - int banned = 0; - for (BSSession session : sessions) { - List shares = BSShare.bySession(session); - for (BSShare share : shares) { - if (share.isPardoned()) { - share.setPardonTime(null); - unpardoned ++; - sender.sendMessage(ChatColor.GREEN + "Unpardoned Shared session: " - + share.toFullString(sender.hasPermission("banstick.ips"))); - } - if (doBan) { - BanResult result = BanHandler.doShareBan(share, null, message, banEnd, true); - result.informCommandSender(sender); - banned ++; - } - } - } - sender.sendMessage(ChatColor.GREEN + "Unpardoned " + unpardoned + " shared and attempted " - + banned + " share bans."); + offset = 1; + secondDoBan = arguments[1].indexOf('+') > -1; + secondBan = secondDoBan ? arguments[1].substring(1) : arguments[1]; + } - return true; - } else { - // Not an IP address! - UUID playerId = null; - if (toBan.length() <= 16) { - try { - playerId = null; - - try { - playerId = NameAPI.getUUID(toBan); - } catch (NoClassDefFoundError ncde) { } - - if (playerId == null) { - Player match = Bukkit.getPlayer(toBan); - if (match != null) { - playerId = match.getUniqueId(); - } - } - } catch (Exception ee) { - sender.sendMessage(ChatColor.RED + "Unable to find player " + ChatColor.DARK_RED + toBan); - return true; - } - } else if (toBan.length() == 36) { - try { - playerId = UUID.fromString(toBan); - } catch (IllegalArgumentException iae) { - sender.sendMessage(ChatColor.RED + "Unable to process uuid " + ChatColor.DARK_RED + toBan); - return true; - } - } else { - sender.sendMessage(ChatColor.RED + "Unable to interpret " + ChatColor.DARK_RED + toBan); - return true; - } - - UUID secondPlayerId = null; - if (secondBan.length() <= 16) { - try { - secondPlayerId = null; - - try { - secondPlayerId = NameAPI.getUUID(secondBan); - } catch (NoClassDefFoundError ncde) { } - - if (secondPlayerId == null) { - Player match = Bukkit.getPlayer(secondBan); - if (match != null) { - secondPlayerId = match.getUniqueId(); - } - } - } catch (Exception ee) { - sender.sendMessage(ChatColor.RED + "Unable to find player " + ChatColor.DARK_RED + secondBan); - return true; - } - } else if (secondBan.length() == 36) { - try { - secondPlayerId = UUID.fromString(secondBan); - } catch (IllegalArgumentException iae) { - sender.sendMessage(ChatColor.RED + "Unable to process uuid " + ChatColor.DARK_RED + secondBan); - return true; - } - } else { - sender.sendMessage(ChatColor.RED + "Unable to interpret " + ChatColor.DARK_RED + secondBan); - return true; - } - - BSPlayer player1 = BSPlayer.byUUID(playerId); - BSPlayer player2 = BSPlayer.byUUID(secondPlayerId); - - if (player1 != null && player2 != null) { - List shares = player1.sharesWith(player2); - if (shares != null && !shares.isEmpty()) { - for (BSShare share : shares) { - if (share.isPardoned()) { - share.setPardonTime(null); - sender.sendMessage(ChatColor.GREEN + "Unpardoned Shared session: " - + share.toFullString(sender.hasPermission("banstick.ips"))); - } - } - if (doBan || secondDoBan) { - BanResult result = BanHandler.doShareBan(shares.get(shares.size() - 1), - doBan && !secondDoBan ? player1 : !doBan && secondDoBan ? player2 : null, - message, banEnd, true); - result.informCommandSender(sender); - } - } else { - sender.sendMessage(ChatColor.RED + "Those players have not shared a connection."); - } - - return true; - } else { - if (player1 == null) { - sender.sendMessage(ChatColor.RED + "Unable to find " + ChatColor.DARK_RED + toBan); - } - if (player2 == null) { - sender.sendMessage(ChatColor.RED + "Unable to find " + ChatColor.DARK_RED + secondBan); - } - } - } - return false; - } + String endDate = (arguments.length >= (2 + offset) ? arguments[1 + offset] : null); + String endTime = (arguments.length >= (3 + offset) ? arguments[2 + offset] : null); + SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy"); + SimpleDateFormat combinedFormat = new SimpleDateFormat("MM/dd/yyyy HH:mms:ss"); + Date banEndDate = null; + Date banEndTime = null; + Date banEnd = null; + int messageStart = 1 + offset; + + BanStick.getPlugin().debug( + "preBan: {0}, doBan? {1}, toBan: {2}, sDoBan? {3}, sBan: {4}, endDate: {5}, endTime: {6}", + preBan, doBan, toBan, secondDoBan, secondBan, endDate, endTime); + + if (endDate != null) { + try { + banEndDate = dateFormat.parse(endDate); + banEnd = banEndDate; + messageStart++; + } catch (ParseException pe) { + banEndDate = null; + } + + if (banEndDate != null && endTime != null) { + try { + banEndTime = combinedFormat.parse(endDate + " " + endTime); + banEnd = banEndTime; + messageStart++; + } catch (ParseException pe) { + banEndTime = null; + } + } + } + + String message = (arguments.length >= messageStart ? String.join(" ", + Arrays.copyOfRange(arguments, messageStart, arguments.length)) : null); + + BanStick.getPlugin().debug("message: {0}", message); + + if (ipcheck != null) { + if (!sender.hasPermission("banstick.ips")) { + sender.sendMessage(ChatColor.RED + "You don't have permission to use / view IPs"); + return true; + } + + BSIP exact = BSIP.byIPAddress(ipcheck); + if (exact == null) { + sender.sendMessage(ChatColor.YELLOW + "That IP address not found, no shares modified."); + return true; + } + + List sessions = BSSession.byIP(exact); + + if (sessions == null || sessions.isEmpty()) { + sender.sendMessage(ChatColor.YELLOW + "That IP address does not connect to any sessions."); + return true; + } + + int unpardoned = 0; + int banned = 0; + for (BSSession session : sessions) { + List shares = BSShare.bySession(session); + for (BSShare share : shares) { + if (share.isPardoned()) { + share.setPardonTime(null); + unpardoned++; + sender.sendMessage(ChatColor.GREEN + "Unpardoned Shared session: " + + share.toFullString(sender.hasPermission("banstick.ips"))); + } + if (doBan) { + BanResult result = BanHandler.doShareBan(share, null, message, banEnd, true); + result.informCommandSender(sender); + banned++; + } + } + } + sender.sendMessage(ChatColor.GREEN + "Unpardoned " + unpardoned + " shared and attempted " + + banned + " share bans."); + + return true; + } else { + // Not an IP address! + UUID playerId = null; + if (toBan.length() <= 16) { + try { + playerId = null; + + try { + playerId = NameAPI.getUUID(toBan); + } catch (NoClassDefFoundError ncde) { + } + + if (playerId == null) { + Player match = Bukkit.getPlayer(toBan); + if (match != null) { + playerId = match.getUniqueId(); + } + } + } catch (Exception ee) { + sender.sendMessage(ChatColor.RED + "Unable to find player " + ChatColor.DARK_RED + toBan); + return true; + } + } else if (toBan.length() == 36) { + try { + playerId = UUID.fromString(toBan); + } catch (IllegalArgumentException iae) { + sender.sendMessage(ChatColor.RED + "Unable to process uuid " + ChatColor.DARK_RED + toBan); + return true; + } + } else { + sender.sendMessage(ChatColor.RED + "Unable to interpret " + ChatColor.DARK_RED + toBan); + return true; + } + + UUID secondPlayerId = null; + if (secondBan.length() <= 16) { + try { + secondPlayerId = null; + + try { + secondPlayerId = NameAPI.getUUID(secondBan); + } catch (NoClassDefFoundError ncde) { + } + + if (secondPlayerId == null) { + Player match = Bukkit.getPlayer(secondBan); + if (match != null) { + secondPlayerId = match.getUniqueId(); + } + } + } catch (Exception ee) { + sender.sendMessage(ChatColor.RED + "Unable to find player " + ChatColor.DARK_RED + secondBan); + return true; + } + } else if (secondBan.length() == 36) { + try { + secondPlayerId = UUID.fromString(secondBan); + } catch (IllegalArgumentException iae) { + sender.sendMessage(ChatColor.RED + "Unable to process uuid " + ChatColor.DARK_RED + secondBan); + return true; + } + } else { + sender.sendMessage(ChatColor.RED + "Unable to interpret " + ChatColor.DARK_RED + secondBan); + return true; + } + + BSPlayer player1 = BSPlayer.byUUID(playerId); + BSPlayer player2 = BSPlayer.byUUID(secondPlayerId); + + if (player1 != null && player2 != null) { + List shares = player1.sharesWith(player2); + if (shares != null && !shares.isEmpty()) { + for (BSShare share : shares) { + if (share.isPardoned()) { + share.setPardonTime(null); + sender.sendMessage(ChatColor.GREEN + "Unpardoned Shared session: " + + share.toFullString(sender.hasPermission("banstick.ips"))); + } + } + if (doBan || secondDoBan) { + BanResult result = BanHandler.doShareBan(shares.get(shares.size() - 1), + doBan && !secondDoBan ? player1 : !doBan && secondDoBan ? player2 : null, + message, banEnd, true); + result.informCommandSender(sender); + } + } else { + sender.sendMessage(ChatColor.RED + "Those players have not shared a connection."); + } + + return true; + } else { + if (player1 == null) { + sender.sendMessage(ChatColor.RED + "Unable to find " + ChatColor.DARK_RED + toBan); + } + if (player2 == null) { + sender.sendMessage(ChatColor.RED + "Unable to find " + ChatColor.DARK_RED + secondBan); + } + } + } + return false; + } } diff --git a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/commands/DowsingRodCommand.java b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/commands/DowsingRodCommand.java index b933b2022..d978dc5e9 100644 --- a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/commands/DowsingRodCommand.java +++ b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/commands/DowsingRodCommand.java @@ -19,18 +19,17 @@ import org.bukkit.entity.Player; /** * This command is complex, but basically allows you to investigate the current * data known to the server live as an admin. - * - *

This gives you great investigative power and also clickthroughs for deep dives. - * - * @author ProgrammerDan * + *

This gives you great investigative power and also clickthroughs for deep dives. + * + * @author ProgrammerDan */ -public class DowsingRodCommand implements CommandExecutor { +public class DowsingRodCommand implements CommandExecutor { - public static String name = "dowsingrod"; - - @Override - public boolean onCommand(CommandSender sender, Command cmd, String cmdString, String[] arguments) { + public static String name = "dowsingrod"; + + @Override + public boolean onCommand(CommandSender sender, Command cmd, String cmdString, String[] arguments) { /* * /dowsingrod [CONTINENT|COUNTRY|REGION|STATE|CITY|POSTAL|ZIP|DOMAIN|PROVIDER|REGISTEREDAS|CONNECTION] * page# perpage @@ -55,149 +54,149 @@ public class DowsingRodCommand implements CommandExecutor { " comment TEXT," + */ - int page = 0; - int perpage = 20; - ArrayList sorts = new ArrayList<>(); - boolean hasPage = false; - - for (String arg : arguments) { - String toAdd = null; - if (arg.equalsIgnoreCase("CONTINENT")) { - toAdd = "continent"; - } else if (arg.equalsIgnoreCase("COUNTRY")) { - toAdd = "country"; - } else if (arg.equalsIgnoreCase("REGION") || arg.equalsIgnoreCase("STATE")) { - toAdd = "region"; - } else if (arg.equalsIgnoreCase("CITY")) { - toAdd = "city"; - } else if (arg.equalsIgnoreCase("POSTAL") || arg.equalsIgnoreCase("ZIP") - || arg.equalsIgnoreCase("ZIPCODE")) { - toAdd = "postal"; - } else if (arg.equalsIgnoreCase("DOMAIN")) { - toAdd = "domain"; - } else if (arg.equalsIgnoreCase("PROVIDER")) { - toAdd = "provider"; - } else if (arg.equalsIgnoreCase("REGISTEREDAS") || arg.equalsIgnoreCase("REGISTERED")) { - toAdd = "registered_as"; - } else if (arg.equalsIgnoreCase("CONNECTION")) { - toAdd = "connection"; - } else { - try { - int val = Integer.parseInt(arg); - if (hasPage) { - perpage = val; - } else { - page = val; - hasPage = true; - } - } catch (NumberFormatException e) { - } - } - if (toAdd != null && sorts.size() < 3) { - sorts.add(toAdd); - } - } - if (sorts.isEmpty()) { - sorts.add("provider"); - } - - int[] widths = new int[sorts.size() + 1]; - Arrays.fill(widths, 20); - ArrayList toDisplay = new ArrayList<>(perpage); - - StringBuilder subString = new StringBuilder(); - StringBuilder queryString = new StringBuilder(); - queryString.append("SELECT "); - for (String sort : sorts) { - subString.append(sort).append(", "); - } - queryString.append(subString).append("count(*) FROM bs_ip_data GROUP BY ") - .append(subString.substring(0, subString.length() - 2)) - .append(" ORDER BY count(*) DESC LIMIT ").append(page * perpage).append(',').append(perpage); - BanStick.getPlugin().debug("Running query: " + queryString.toString()); - long requestLen = System.currentTimeMillis(); - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); + int page = 0; + int perpage = 20; + ArrayList sorts = new ArrayList<>(); + boolean hasPage = false; + + for (String arg : arguments) { + String toAdd = null; + if (arg.equalsIgnoreCase("CONTINENT")) { + toAdd = "continent"; + } else if (arg.equalsIgnoreCase("COUNTRY")) { + toAdd = "country"; + } else if (arg.equalsIgnoreCase("REGION") || arg.equalsIgnoreCase("STATE")) { + toAdd = "region"; + } else if (arg.equalsIgnoreCase("CITY")) { + toAdd = "city"; + } else if (arg.equalsIgnoreCase("POSTAL") || arg.equalsIgnoreCase("ZIP") + || arg.equalsIgnoreCase("ZIPCODE")) { + toAdd = "postal"; + } else if (arg.equalsIgnoreCase("DOMAIN")) { + toAdd = "domain"; + } else if (arg.equalsIgnoreCase("PROVIDER")) { + toAdd = "provider"; + } else if (arg.equalsIgnoreCase("REGISTEREDAS") || arg.equalsIgnoreCase("REGISTERED")) { + toAdd = "registered_as"; + } else if (arg.equalsIgnoreCase("CONNECTION")) { + toAdd = "connection"; + } else { + try { + int val = Integer.parseInt(arg); + if (hasPage) { + perpage = val; + } else { + page = val; + hasPage = true; + } + } catch (NumberFormatException e) { + } + } + if (toAdd != null && sorts.size() < 3) { + sorts.add(toAdd); + } + } + if (sorts.isEmpty()) { + sorts.add("provider"); + } + + int[] widths = new int[sorts.size() + 1]; + Arrays.fill(widths, 20); + ArrayList toDisplay = new ArrayList<>(perpage); + + StringBuilder subString = new StringBuilder(); + StringBuilder queryString = new StringBuilder(); + queryString.append("SELECT "); + for (String sort : sorts) { + subString.append(sort).append(", "); + } + queryString.append(subString).append("count(*) FROM bs_ip_data GROUP BY ") + .append(subString.substring(0, subString.length() - 2)) + .append(" ORDER BY count(*) DESC LIMIT ").append(page * perpage).append(',').append(perpage); + BanStick.getPlugin().debug("Running query: " + queryString.toString()); + long requestLen = System.currentTimeMillis(); + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); PreparedStatement complex = connection.prepareStatement(queryString.toString()); ResultSet results = complex.executeQuery()) { - while (results.next()) { - String[] storage = new String[sorts.size() + 2]; - StringBuilder detailCmd = new StringBuilder("/drilldown SUMMARY "); - for (int i = 0; i <= sorts.size(); i++) { - storage[i] = i < sorts.size() ? results.getString(i + 1) : Integer.toString(results.getInt(i + 1)); - if (results.wasNull()) { - storage[i] = "NULL"; - } - if (i < sorts.size()) { - detailCmd.append(sorts.get(i)).append(" \"").append(storage[i]).append("\" "); - } - if (storage[i].length() > widths[i]) { - widths[i] = storage[i].length(); - } - } - storage[sorts.size() + 1] = detailCmd.toString(); - toDisplay.add(storage); - } - } catch (SQLException e) { - BanStick.getPlugin().severe("Failure to satisfy request at a DB level!", e); - sender.sendMessage(ChatColor.RED + "There was a database failure, try again later."); - return true; - } finally { - requestLen = System.currentTimeMillis() - requestLen; - } - - if (toDisplay.isEmpty()) { - sender.sendMessage(ChatColor.YELLOW + "No results. " + ChatColor.DARK_GRAY + " took " + requestLen + " ms"); - return true; - } else { - StringBuilder formatString = new StringBuilder(); - for (int i = 0; i <= sorts.size(); i++) { - formatString.append("%").append(widths[i]).append("s "); - } - @SuppressWarnings("unchecked") - ArrayList headers = (ArrayList) sorts.clone(); - headers.add("Count"); - sender.sendMessage(ChatColor.BOLD.toString() + ChatColor.DARK_AQUA.toString() - + String.format(formatString.toString(), headers.toArray()) + ChatColor.RESET.toString()); - for (String[] data : toDisplay) { - TextComponent line = new TextComponent(String.format(formatString.toString(), - (Object[]) Arrays.copyOfRange(data, 0, data.length - 1))); - line.setColor(net.md_5.bungee.api.ChatColor.WHITE); - line.setBold(true); - if (sender instanceof Player) { - line.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, data[data.length - 1])); - ((Player) sender).spigot().sendMessage(line); - } else { - sender.sendMessage(line.toLegacyText()); - } - } - if (sender instanceof Player) { - TextComponent controls = new TextComponent("Controls "); - controls.setColor(net.md_5.bungee.api.ChatColor.DARK_AQUA); - if (page > 0) { - TextComponent priorPage = new TextComponent("Prior "); - @SuppressWarnings("unchecked") - ArrayList cmdH = (ArrayList) sorts.clone(); - cmdH.add((page - 1) + " " + perpage); - priorPage.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, - "/dowsingrod " + String.format(formatString.toString(), cmdH.toArray()))); - priorPage.setColor(net.md_5.bungee.api.ChatColor.GOLD); - controls.addExtra(priorPage); - } - if (toDisplay.size() == perpage) { - TextComponent nextPage = new TextComponent("Next "); - @SuppressWarnings("unchecked") - ArrayList cmdH = (ArrayList) sorts.clone(); - cmdH.add((page + 1) + " " + perpage); - nextPage.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, - "/dowsingrod " + String.format(formatString.toString(), cmdH.toArray()))); - nextPage.setColor(net.md_5.bungee.api.ChatColor.GOLD); - controls.addExtra(nextPage); - } - Player player = (Player) sender; - player.spigot().sendMessage(controls); - } - sender.sendMessage(ChatColor.DARK_GRAY + "query took " + requestLen + " ms"); - return true; - } - } + while (results.next()) { + String[] storage = new String[sorts.size() + 2]; + StringBuilder detailCmd = new StringBuilder("/drilldown SUMMARY "); + for (int i = 0; i <= sorts.size(); i++) { + storage[i] = i < sorts.size() ? results.getString(i + 1) : Integer.toString(results.getInt(i + 1)); + if (results.wasNull()) { + storage[i] = "NULL"; + } + if (i < sorts.size()) { + detailCmd.append(sorts.get(i)).append(" \"").append(storage[i]).append("\" "); + } + if (storage[i].length() > widths[i]) { + widths[i] = storage[i].length(); + } + } + storage[sorts.size() + 1] = detailCmd.toString(); + toDisplay.add(storage); + } + } catch (SQLException e) { + BanStick.getPlugin().severe("Failure to satisfy request at a DB level!", e); + sender.sendMessage(ChatColor.RED + "There was a database failure, try again later."); + return true; + } finally { + requestLen = System.currentTimeMillis() - requestLen; + } + + if (toDisplay.isEmpty()) { + sender.sendMessage(ChatColor.YELLOW + "No results. " + ChatColor.DARK_GRAY + " took " + requestLen + " ms"); + return true; + } else { + StringBuilder formatString = new StringBuilder(); + for (int i = 0; i <= sorts.size(); i++) { + formatString.append("%").append(widths[i]).append("s "); + } + @SuppressWarnings("unchecked") + ArrayList headers = (ArrayList) sorts.clone(); + headers.add("Count"); + sender.sendMessage(ChatColor.BOLD.toString() + ChatColor.DARK_AQUA.toString() + + String.format(formatString.toString(), headers.toArray()) + ChatColor.RESET.toString()); + for (String[] data : toDisplay) { + TextComponent line = new TextComponent(String.format(formatString.toString(), + (Object[]) Arrays.copyOfRange(data, 0, data.length - 1))); + line.setColor(net.md_5.bungee.api.ChatColor.WHITE); + line.setBold(true); + if (sender instanceof Player) { + line.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, data[data.length - 1])); + ((Player) sender).spigot().sendMessage(line); + } else { + sender.sendMessage(line.toLegacyText()); + } + } + if (sender instanceof Player) { + TextComponent controls = new TextComponent("Controls "); + controls.setColor(net.md_5.bungee.api.ChatColor.DARK_AQUA); + if (page > 0) { + TextComponent priorPage = new TextComponent("Prior "); + @SuppressWarnings("unchecked") + ArrayList cmdH = (ArrayList) sorts.clone(); + cmdH.add((page - 1) + " " + perpage); + priorPage.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, + "/dowsingrod " + String.format(formatString.toString(), cmdH.toArray()))); + priorPage.setColor(net.md_5.bungee.api.ChatColor.GOLD); + controls.addExtra(priorPage); + } + if (toDisplay.size() == perpage) { + TextComponent nextPage = new TextComponent("Next "); + @SuppressWarnings("unchecked") + ArrayList cmdH = (ArrayList) sorts.clone(); + cmdH.add((page + 1) + " " + perpage); + nextPage.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, + "/dowsingrod " + String.format(formatString.toString(), cmdH.toArray()))); + nextPage.setColor(net.md_5.bungee.api.ChatColor.GOLD); + controls.addExtra(nextPage); + } + Player player = (Player) sender; + player.spigot().sendMessage(controls); + } + sender.sendMessage(ChatColor.DARK_GRAY + "query took " + requestLen + " ms"); + return true; + } + } } diff --git a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/commands/DrillDownCommand.java b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/commands/DrillDownCommand.java index 5ee41f710..8bb7ed009 100644 --- a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/commands/DrillDownCommand.java +++ b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/commands/DrillDownCommand.java @@ -29,43 +29,43 @@ import org.bukkit.entity.Player; /** * A command to delve deep into available data on a particular player. - * - * @author ProgrammerDan * + * @author ProgrammerDan */ -public class DrillDownCommand implements CommandExecutor { +public class DrillDownCommand implements CommandExecutor { - public enum Action { - PLAYER, - IPDATASUMMARY, - SUMMARY, - IPDATA, - IP; - - /** - * Check if a string matches one of these actions. - * @param value - * @return - */ - public static Action match(String value) { - if (value != null && value.length() > 0) { - for (Action action : Action.values()) { - if (value.toLowerCase().contains(action.name().toLowerCase())) { - return action; - } - } - } - throw new IllegalArgumentException("Could not find Action match with " + value); - } - } - - public static String name = "drilldown"; - - @Override - public boolean onCommand(CommandSender sender, Command cmd, String cmdString, String[] arguments) { - if (arguments.length < 3) { - return false; - } + public enum Action { + PLAYER, + IPDATASUMMARY, + SUMMARY, + IPDATA, + IP; + + /** + * Check if a string matches one of these actions. + * + * @param value + * @return + */ + public static Action match(String value) { + if (value != null && value.length() > 0) { + for (Action action : Action.values()) { + if (value.toLowerCase().contains(action.name().toLowerCase())) { + return action; + } + } + } + throw new IllegalArgumentException("Could not find Action match with " + value); + } + } + + public static String name = "drilldown"; + + @Override + public boolean onCommand(CommandSender sender, Command cmd, String cmdString, String[] arguments) { + if (arguments.length < 3) { + return false; + } /* * /drilldown [SUMMARY|PLAYER|IP|IPDATA|IPDATASUMMARY] @@ -90,336 +90,336 @@ public class DrillDownCommand implements CommandExecutor { " comment TEXT," + */ - - //int page = 0; - //int perpage = 20; - ArrayList values = new ArrayList<>(); - StringBuilder nextValue = new StringBuilder(); - //boolean hasPage = false; - boolean foundAnchor = false; - Action preaction = Action.SUMMARY; - try { - preaction = Action.match(arguments[0]); - } catch (IllegalArgumentException iae) { - return false; - } - final Action action = preaction; - - for (String arg : Arrays.copyOfRange(arguments, 1, arguments.length)) { - String toAdd = null; - if (arg.equals("continent")) { - if (foundAnchor) { - values.add(nextValue.toString()); - nextValue = new StringBuilder(); - } - toAdd = "continent"; - foundAnchor = true; - } else if (arg.equals("country")) { - if (foundAnchor) { - values.add(nextValue.toString()); - nextValue = new StringBuilder(); - } - toAdd = "country"; - foundAnchor = true; - } else if (arg.equalsIgnoreCase("region")) { - if (foundAnchor) { - values.add(nextValue.toString()); - nextValue = new StringBuilder(); - } - toAdd = "region"; - foundAnchor = true; - } else if (arg.equalsIgnoreCase("city")) { - if (foundAnchor) { - values.add(nextValue.toString()); - nextValue = new StringBuilder(); - } - toAdd = "city"; - foundAnchor = true; - } else if (arg.equalsIgnoreCase("postal")) { - if (foundAnchor) { - values.add(nextValue.toString()); - nextValue = new StringBuilder(); - } - toAdd = "postal"; - foundAnchor = true; - } else if (arg.equalsIgnoreCase("domain")) { - if (foundAnchor) { - values.add(nextValue.toString()); - nextValue = new StringBuilder(); - } - toAdd = "domain"; - foundAnchor = true; - } else if (arg.equalsIgnoreCase("provider")) { - if (foundAnchor) { - values.add(nextValue.toString()); - nextValue = new StringBuilder(); - } - toAdd = "provider"; - foundAnchor = true; - } else if (arg.equalsIgnoreCase("registered_as")) { - if (foundAnchor) { - values.add(nextValue.toString()); - nextValue = new StringBuilder(); - } - toAdd = "registered_as"; - foundAnchor = true; - } else if (arg.equalsIgnoreCase("connection")) { - if (foundAnchor) { - values.add(nextValue.toString()); - nextValue = new StringBuilder(); - } - toAdd = "connection"; - foundAnchor = true; - } else { - nextValue.append(" ").append(arg); - } - if (toAdd != null && values.size() < 6) { - values.add(toAdd); - } - } - if (values.isEmpty()) { - return false; - } - if (foundAnchor) { - values.add(nextValue.toString()); - } - - sender.sendMessage(ChatColor.GRAY + " " + ChatColor.ITALIC + "Preparing drilldown query..."); - Bukkit.getScheduler().runTaskAsynchronously(BanStick.getPlugin(), new Runnable() { - @Override - public void run() { - StringBuilder subString = new StringBuilder(); - StringBuilder queryString = new StringBuilder(); - for (int i = 0; i < values.size(); i += 2) { - if (values.get(i + 1).contains("\"NULL\"")) { - subString.append(values.get(i)).append(" IS NULL"); - } else { - subString.append(values.get(i)).append(" = ?"); - } - subString.append(" AND "); - } - queryString.append("SELECT idid, iid FROM bs_ip_data WHERE ").append(subString.toString()) - .append("valid = TRUE ORDER BY create_time DESC"); - - BanStick.getPlugin().debug("Running query: " + queryString.toString()); - int found = 0; - long requestLen = System.currentTimeMillis(); - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); + + //int page = 0; + //int perpage = 20; + ArrayList values = new ArrayList<>(); + StringBuilder nextValue = new StringBuilder(); + //boolean hasPage = false; + boolean foundAnchor = false; + Action preaction = Action.SUMMARY; + try { + preaction = Action.match(arguments[0]); + } catch (IllegalArgumentException iae) { + return false; + } + final Action action = preaction; + + for (String arg : Arrays.copyOfRange(arguments, 1, arguments.length)) { + String toAdd = null; + if (arg.equals("continent")) { + if (foundAnchor) { + values.add(nextValue.toString()); + nextValue = new StringBuilder(); + } + toAdd = "continent"; + foundAnchor = true; + } else if (arg.equals("country")) { + if (foundAnchor) { + values.add(nextValue.toString()); + nextValue = new StringBuilder(); + } + toAdd = "country"; + foundAnchor = true; + } else if (arg.equalsIgnoreCase("region")) { + if (foundAnchor) { + values.add(nextValue.toString()); + nextValue = new StringBuilder(); + } + toAdd = "region"; + foundAnchor = true; + } else if (arg.equalsIgnoreCase("city")) { + if (foundAnchor) { + values.add(nextValue.toString()); + nextValue = new StringBuilder(); + } + toAdd = "city"; + foundAnchor = true; + } else if (arg.equalsIgnoreCase("postal")) { + if (foundAnchor) { + values.add(nextValue.toString()); + nextValue = new StringBuilder(); + } + toAdd = "postal"; + foundAnchor = true; + } else if (arg.equalsIgnoreCase("domain")) { + if (foundAnchor) { + values.add(nextValue.toString()); + nextValue = new StringBuilder(); + } + toAdd = "domain"; + foundAnchor = true; + } else if (arg.equalsIgnoreCase("provider")) { + if (foundAnchor) { + values.add(nextValue.toString()); + nextValue = new StringBuilder(); + } + toAdd = "provider"; + foundAnchor = true; + } else if (arg.equalsIgnoreCase("registered_as")) { + if (foundAnchor) { + values.add(nextValue.toString()); + nextValue = new StringBuilder(); + } + toAdd = "registered_as"; + foundAnchor = true; + } else if (arg.equalsIgnoreCase("connection")) { + if (foundAnchor) { + values.add(nextValue.toString()); + nextValue = new StringBuilder(); + } + toAdd = "connection"; + foundAnchor = true; + } else { + nextValue.append(" ").append(arg); + } + if (toAdd != null && values.size() < 6) { + values.add(toAdd); + } + } + if (values.isEmpty()) { + return false; + } + if (foundAnchor) { + values.add(nextValue.toString()); + } + + sender.sendMessage(ChatColor.GRAY + " " + ChatColor.ITALIC + "Preparing drilldown query..."); + Bukkit.getScheduler().runTaskAsynchronously(BanStick.getPlugin(), new Runnable() { + @Override + public void run() { + StringBuilder subString = new StringBuilder(); + StringBuilder queryString = new StringBuilder(); + for (int i = 0; i < values.size(); i += 2) { + if (values.get(i + 1).contains("\"NULL\"")) { + subString.append(values.get(i)).append(" IS NULL"); + } else { + subString.append(values.get(i)).append(" = ?"); + } + subString.append(" AND "); + } + queryString.append("SELECT idid, iid FROM bs_ip_data WHERE ").append(subString.toString()) + .append("valid = TRUE ORDER BY create_time DESC"); + + BanStick.getPlugin().debug("Running query: " + queryString.toString()); + int found = 0; + long requestLen = System.currentTimeMillis(); + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); PreparedStatement complex = connection.prepareStatement(queryString.toString());) { - for (int i = 1, j = 1; i < values.size(); i += 2, j ++) { - String searchTerm = values.get(i).trim(); - if (searchTerm.startsWith("\"") && searchTerm.endsWith("\"")) { - searchTerm = searchTerm.substring(1, searchTerm.length() - 1); - } - if (searchTerm.equals("NULL")) { - j--; - } else { - complex.setString(j, searchTerm); - } - } - Set ips = null; - if (Action.IP.equals(action) || Action.SUMMARY.equals(action)) { - ips = new HashSet<>(); - } - Set players = null; - if (Action.PLAYER.equals(action) || Action.SUMMARY.equals(action)) { - players = new HashSet<>(); - } - Set datas = null; - if (Action.SUMMARY.equals(action) || Action.IPDATASUMMARY.equals(action)) { - datas = new HashSet<>(); - } - Map> dataIPs = null; - Map> dataPlayers = null; - if (Action.IPDATASUMMARY.equals(action)) { - dataIPs = new HashMap<>(); - dataPlayers = new HashMap<>(); - } - try (ResultSet results = complex.executeQuery()) { - while (results.next()) { - BSIPData data = BSIPData.byId(results.getLong(1)); - BSIP ip = BSIP.byId(results.getLong(2)); - - if (Action.IPDATA.equals(action)) { - StringBuilder detailCmd = new StringBuilder("/lovetap "); - detailCmd.append(ip.toString()); - - TextComponent line = new TextComponent(" " - + data.toFullString(sender.hasPermission("banstick.ips"))); - line.setColor(net.md_5.bungee.api.ChatColor.WHITE); - line.setBold(true); - if (sender instanceof Player && sender.hasPermission("banstick.ips")) { - line.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, - detailCmd.toString())); - ((Player) sender).spigot().sendMessage(line); - } else { - sender.sendMessage(line.toLegacyText()); - } - } - if (Action.IPDATASUMMARY.equals(action)) { - datas.add(data); - Set contained = dataIPs.get(data.getId()); - if (contained == null) { - contained = new HashSet<>(); - dataIPs.put(data.getId(), contained); - } - contained.add(ip); - } - if (Action.SUMMARY.equals(action)) { - datas.add(data); - ips.add(ip); - } - if (Action.SUMMARY.equals(action) || Action.IPDATASUMMARY.equals(action) - || Action.PLAYER.equals(action)) { - List sessions = BSSession.byIP(ip); - if (sessions != null) { - for (BSSession session : sessions) { - if (Action.PLAYER.equals(action) || Action.SUMMARY.equals(action)) { - players.add(session.getPlayer()); - } else { // IPDATASUMMARY - Set playerSet = dataPlayers.get(data.getId()); - if (playerSet == null) { - playerSet = new HashSet<>(); - dataPlayers.put(data.getId(), playerSet); - } - playerSet.add(session.getPlayer()); - } - } - } - } - found++; - } - } - if (Action.SUMMARY.equals(action)) { - StringBuilder sb = new StringBuilder(); - for (int i = 1; i < arguments.length; i++) { - sb.append(" ").append(arguments[i]); - } - TextComponent summary = new TextComponent("Found "); - summary.setColor(net.md_5.bungee.api.ChatColor.AQUA); - TextComponent plExt = new TextComponent(players.size() + " players, "); - plExt.setColor(net.md_5.bungee.api.ChatColor.WHITE); - plExt.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, - "/drilldown PLAYER" + sb.toString())); - TextComponent daExt = new TextComponent(datas.size() + " subnet records, "); - daExt.setColor(net.md_5.bungee.api.ChatColor.WHITE); - daExt.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, - "/drilldown IPDATA" + sb.toString())); - TextComponent ipExt = new TextComponent(ips.size() + " ips "); - ipExt.setColor(net.md_5.bungee.api.ChatColor.WHITE); - ipExt.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, - "/drilldown IP" + sb.toString())); - summary.addExtra(plExt); - summary.addExtra(daExt); - summary.addExtra(ipExt); - TextComponent orDetail = new TextComponent(" [get breakdown by subnet/proxy]"); - orDetail.setColor(net.md_5.bungee.api.ChatColor.GOLD); - orDetail.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, - "/drilldown IPDATASUMMARY" + sb.toString())); - - if (sender instanceof Player) { - ((Player) sender).spigot().sendMessage(summary, orDetail); - } else { - sender.sendMessage(summary.toLegacyText()); - } - } else if (Action.IP.equals(action)) { - for (BSIP ip : ips) { - StringBuilder detailCmd = new StringBuilder("/lovetap "); - detailCmd.append(ip.toString()); - - TextComponent line = new TextComponent(" " - + ip.toFullString(sender.hasPermission("banstick.ips"))); - line.setColor(net.md_5.bungee.api.ChatColor.WHITE); - if (sender instanceof Player && sender.hasPermission("banstick.ips")) { - line.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, - detailCmd.toString())); - ((Player) sender).spigot().sendMessage(line); - } else { - sender.sendMessage(line.toLegacyText()); - } - } - } else if (Action.PLAYER.equals(action)) { - for (BSPlayer player : players) { - StringBuilder detailCmd = new StringBuilder("/lovetap "); - detailCmd.append(player.getUUID().toString()); - - TextComponent line = new TextComponent(" " + player.toString()); - line.setColor(net.md_5.bungee.api.ChatColor.WHITE); - if (sender instanceof Player) { - line.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, - detailCmd.toString())); - ((Player) sender).spigot().sendMessage(line); - } else { - sender.sendMessage(line.toLegacyText()); - } - } - } else if (Action.IPDATASUMMARY.equals(action)) { - for (BSIPData data : datas) { - BaseComponent[] preline = TextComponent.fromLegacyText( - data.toFullString(sender.hasPermission("banstick.ips"))); - TextComponent bline = new TextComponent("Subnet Record: "); - bline.setColor(net.md_5.bungee.api.ChatColor.AQUA); - bline.setBold(true); - bline.setExtra(Arrays.asList(preline)); - if (sender instanceof Player) { - ((Player) sender).spigot().sendMessage(bline); - } else { - sender.sendMessage(bline.toLegacyText()); - } - if (dataIPs.get(data.getId()) != null) { - sender.sendMessage(ChatColor.AQUA + "IP Details:"); - for (BSIP ip : dataIPs.get(data.getId())) { - StringBuilder detailCmd = new StringBuilder("/lovetap "); - detailCmd.append(ip.toString()); - - TextComponent line = new TextComponent(" " - + ip.toFullString(sender.hasPermission("banstick.ips"))); - line.setColor(net.md_5.bungee.api.ChatColor.WHITE); - if (sender instanceof Player && sender.hasPermission("banstick.ips")) { - line.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, - detailCmd.toString())); - ((Player) sender).spigot().sendMessage(line); - } else { - sender.sendMessage(line.toLegacyText()); - } - } - } - if (dataPlayers.get(data.getId()) != null) { - sender.sendMessage(ChatColor.AQUA + "Player Details:"); - for (BSPlayer player : dataPlayers.get(data.getId())) { - StringBuilder detailCmd = new StringBuilder("/lovetap "); - detailCmd.append(player.getUUID().toString()); - - TextComponent line = new TextComponent(" " + player.toString()); - line.setColor(net.md_5.bungee.api.ChatColor.WHITE); - if (sender instanceof Player) { - line.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, - detailCmd.toString())); - ((Player) sender).spigot().sendMessage(line); - } else { - sender.sendMessage(line.toLegacyText()); - } - } - } - } - } // IPDATA is done in-stream. - } catch (SQLException e) { - BanStick.getPlugin().severe("Failure to satisfy request at a DB level!", e); - sender.sendMessage(ChatColor.RED + "There was a database failure, try again later."); - return; - } finally { - requestLen = System.currentTimeMillis() - requestLen; - } - - if (found == 0) { - sender.sendMessage(ChatColor.YELLOW + "No results. " + ChatColor.DARK_GRAY - + " took " + requestLen + " ms"); - } else { - sender.sendMessage(ChatColor.DARK_GRAY + Integer.toString(found) - + " results in " + requestLen + " ms"); - } - } - }); - return true; - } + for (int i = 1, j = 1; i < values.size(); i += 2, j++) { + String searchTerm = values.get(i).trim(); + if (searchTerm.startsWith("\"") && searchTerm.endsWith("\"")) { + searchTerm = searchTerm.substring(1, searchTerm.length() - 1); + } + if (searchTerm.equals("NULL")) { + j--; + } else { + complex.setString(j, searchTerm); + } + } + Set ips = null; + if (Action.IP.equals(action) || Action.SUMMARY.equals(action)) { + ips = new HashSet<>(); + } + Set players = null; + if (Action.PLAYER.equals(action) || Action.SUMMARY.equals(action)) { + players = new HashSet<>(); + } + Set datas = null; + if (Action.SUMMARY.equals(action) || Action.IPDATASUMMARY.equals(action)) { + datas = new HashSet<>(); + } + Map> dataIPs = null; + Map> dataPlayers = null; + if (Action.IPDATASUMMARY.equals(action)) { + dataIPs = new HashMap<>(); + dataPlayers = new HashMap<>(); + } + try (ResultSet results = complex.executeQuery()) { + while (results.next()) { + BSIPData data = BSIPData.byId(results.getLong(1)); + BSIP ip = BSIP.byId(results.getLong(2)); + + if (Action.IPDATA.equals(action)) { + StringBuilder detailCmd = new StringBuilder("/lovetap "); + detailCmd.append(ip.toString()); + + TextComponent line = new TextComponent(" " + + data.toFullString(sender.hasPermission("banstick.ips"))); + line.setColor(net.md_5.bungee.api.ChatColor.WHITE); + line.setBold(true); + if (sender instanceof Player && sender.hasPermission("banstick.ips")) { + line.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, + detailCmd.toString())); + ((Player) sender).spigot().sendMessage(line); + } else { + sender.sendMessage(line.toLegacyText()); + } + } + if (Action.IPDATASUMMARY.equals(action)) { + datas.add(data); + Set contained = dataIPs.get(data.getId()); + if (contained == null) { + contained = new HashSet<>(); + dataIPs.put(data.getId(), contained); + } + contained.add(ip); + } + if (Action.SUMMARY.equals(action)) { + datas.add(data); + ips.add(ip); + } + if (Action.SUMMARY.equals(action) || Action.IPDATASUMMARY.equals(action) + || Action.PLAYER.equals(action)) { + List sessions = BSSession.byIP(ip); + if (sessions != null) { + for (BSSession session : sessions) { + if (Action.PLAYER.equals(action) || Action.SUMMARY.equals(action)) { + players.add(session.getPlayer()); + } else { // IPDATASUMMARY + Set playerSet = dataPlayers.get(data.getId()); + if (playerSet == null) { + playerSet = new HashSet<>(); + dataPlayers.put(data.getId(), playerSet); + } + playerSet.add(session.getPlayer()); + } + } + } + } + found++; + } + } + if (Action.SUMMARY.equals(action)) { + StringBuilder sb = new StringBuilder(); + for (int i = 1; i < arguments.length; i++) { + sb.append(" ").append(arguments[i]); + } + TextComponent summary = new TextComponent("Found "); + summary.setColor(net.md_5.bungee.api.ChatColor.AQUA); + TextComponent plExt = new TextComponent(players.size() + " players, "); + plExt.setColor(net.md_5.bungee.api.ChatColor.WHITE); + plExt.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, + "/drilldown PLAYER" + sb.toString())); + TextComponent daExt = new TextComponent(datas.size() + " subnet records, "); + daExt.setColor(net.md_5.bungee.api.ChatColor.WHITE); + daExt.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, + "/drilldown IPDATA" + sb.toString())); + TextComponent ipExt = new TextComponent(ips.size() + " ips "); + ipExt.setColor(net.md_5.bungee.api.ChatColor.WHITE); + ipExt.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, + "/drilldown IP" + sb.toString())); + summary.addExtra(plExt); + summary.addExtra(daExt); + summary.addExtra(ipExt); + TextComponent orDetail = new TextComponent(" [get breakdown by subnet/proxy]"); + orDetail.setColor(net.md_5.bungee.api.ChatColor.GOLD); + orDetail.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, + "/drilldown IPDATASUMMARY" + sb.toString())); + + if (sender instanceof Player) { + ((Player) sender).spigot().sendMessage(summary, orDetail); + } else { + sender.sendMessage(summary.toLegacyText()); + } + } else if (Action.IP.equals(action)) { + for (BSIP ip : ips) { + StringBuilder detailCmd = new StringBuilder("/lovetap "); + detailCmd.append(ip.toString()); + + TextComponent line = new TextComponent(" " + + ip.toFullString(sender.hasPermission("banstick.ips"))); + line.setColor(net.md_5.bungee.api.ChatColor.WHITE); + if (sender instanceof Player && sender.hasPermission("banstick.ips")) { + line.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, + detailCmd.toString())); + ((Player) sender).spigot().sendMessage(line); + } else { + sender.sendMessage(line.toLegacyText()); + } + } + } else if (Action.PLAYER.equals(action)) { + for (BSPlayer player : players) { + StringBuilder detailCmd = new StringBuilder("/lovetap "); + detailCmd.append(player.getUUID().toString()); + + TextComponent line = new TextComponent(" " + player.toString()); + line.setColor(net.md_5.bungee.api.ChatColor.WHITE); + if (sender instanceof Player) { + line.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, + detailCmd.toString())); + ((Player) sender).spigot().sendMessage(line); + } else { + sender.sendMessage(line.toLegacyText()); + } + } + } else if (Action.IPDATASUMMARY.equals(action)) { + for (BSIPData data : datas) { + BaseComponent[] preline = TextComponent.fromLegacyText( + data.toFullString(sender.hasPermission("banstick.ips"))); + TextComponent bline = new TextComponent("Subnet Record: "); + bline.setColor(net.md_5.bungee.api.ChatColor.AQUA); + bline.setBold(true); + bline.setExtra(Arrays.asList(preline)); + if (sender instanceof Player) { + ((Player) sender).spigot().sendMessage(bline); + } else { + sender.sendMessage(bline.toLegacyText()); + } + if (dataIPs.get(data.getId()) != null) { + sender.sendMessage(ChatColor.AQUA + "IP Details:"); + for (BSIP ip : dataIPs.get(data.getId())) { + StringBuilder detailCmd = new StringBuilder("/lovetap "); + detailCmd.append(ip.toString()); + + TextComponent line = new TextComponent(" " + + ip.toFullString(sender.hasPermission("banstick.ips"))); + line.setColor(net.md_5.bungee.api.ChatColor.WHITE); + if (sender instanceof Player && sender.hasPermission("banstick.ips")) { + line.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, + detailCmd.toString())); + ((Player) sender).spigot().sendMessage(line); + } else { + sender.sendMessage(line.toLegacyText()); + } + } + } + if (dataPlayers.get(data.getId()) != null) { + sender.sendMessage(ChatColor.AQUA + "Player Details:"); + for (BSPlayer player : dataPlayers.get(data.getId())) { + StringBuilder detailCmd = new StringBuilder("/lovetap "); + detailCmd.append(player.getUUID().toString()); + + TextComponent line = new TextComponent(" " + player.toString()); + line.setColor(net.md_5.bungee.api.ChatColor.WHITE); + if (sender instanceof Player) { + line.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, + detailCmd.toString())); + ((Player) sender).spigot().sendMessage(line); + } else { + sender.sendMessage(line.toLegacyText()); + } + } + } + } + } // IPDATA is done in-stream. + } catch (SQLException e) { + BanStick.getPlugin().severe("Failure to satisfy request at a DB level!", e); + sender.sendMessage(ChatColor.RED + "There was a database failure, try again later."); + return; + } finally { + requestLen = System.currentTimeMillis() - requestLen; + } + + if (found == 0) { + sender.sendMessage(ChatColor.YELLOW + "No results. " + ChatColor.DARK_GRAY + + " took " + requestLen + " ms"); + } else { + sender.sendMessage(ChatColor.DARK_GRAY + Integer.toString(found) + + " results in " + requestLen + " ms"); + } + } + }); + return true; + } } diff --git a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/commands/ForgiveCommand.java b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/commands/ForgiveCommand.java index 180b647e9..2bf0250f8 100644 --- a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/commands/ForgiveCommand.java +++ b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/commands/ForgiveCommand.java @@ -24,280 +24,281 @@ import vg.civcraft.mc.namelayer.NameAPI; /** * The best thing is forgiveness. This command can pardon most kinds of bans. - * - * @author ProgrammerDan * + * @author ProgrammerDan */ public class ForgiveCommand implements CommandExecutor { - public static String name = "forgive"; - - @Override - public boolean onCommand(CommandSender sender, Command cmd, String cmdString, String[] arguments) { - if (arguments.length < 1) { - return false; - } + public static String name = "forgive"; + + @Override + public boolean onCommand(CommandSender sender, Command cmd, String cmdString, String[] arguments) { + if (arguments.length < 1) { + return false; + } /* / [ip] / [ip]/[CIDR] / [name/uuid] / [name/uuid] [BAN] [IP] [PROXY] [SHARED] */ - - String preForgive = arguments[0]; - int locCIDR = preForgive.indexOf('/'); - Boolean hasCIDR = locCIDR > -1; - Integer cidr = (hasCIDR) ? Integer.valueOf(preForgive.substring(locCIDR + 1)) : null; - String toForgive = (hasCIDR) ? preForgive.substring(0, locCIDR) : preForgive; - List pardons = (arguments.length > 1) ? Arrays.asList( - Arrays.copyOfRange(arguments, 1, arguments.length)) : null; - BanStick.getPlugin().debug("preForgive: {0}, CIDR? {1}, toForgive: {2}, pardons: {3}", - preForgive, cidr, toForgive, pardons); - - try { - IPAddress ipcheck = new IPAddressString(toForgive).toAddress(); - if (!sender.hasPermission("banstick.ips")) { - sender.sendMessage(ChatColor.RED + "You don't have permission to use / view IPs"); - return true; - } - - BSIP exact = !hasCIDR ? BSIP.byIPAddress(ipcheck) : BSIP.byCIDR(ipcheck.toString(), cidr); - if (exact == null) { - sender.sendMessage(ChatColor.RED + "Can't find " + (hasCIDR ? ipcheck.toString() - + "/" + cidr : ipcheck.toString())); - return true; - } - - List bans = BSBan.byIP(exact, false); - - int banLifted = 0; - for (BSBan ban : bans) { - ban.setBanEndTime(new Date()); - banLifted ++; - } - - sender.sendMessage(ChatColor.GREEN + "Forgave " + banLifted + " active bans"); - - try { - Bukkit.unbanIP(toForgive); - BanStick.getPlugin().debug("Also forgave any underlying bukkit ban on IP"); - } catch (Exception e) { - BanStick.getPlugin().debug("Failed to forgive any underlying bukkit ban on IP"); - } - - return true; - } catch (IPAddressStringException e) { - // Not an IP address! - UUID playerId = null; - if (toForgive.length() <= 16) { - try { - playerId = null; - - try { - playerId = NameAPI.getUUID(toForgive); - } catch (NoClassDefFoundError ncde) { } - - if (playerId == null) { - Player match = Bukkit.getPlayer(toForgive); - if (match != null) { - playerId = match.getUniqueId(); - } - } - } catch (Exception ee) { - sender.sendMessage(ChatColor.RED + "Unable to find player " + ChatColor.DARK_RED + toForgive); - } - } else if (toForgive.length() == 36) { - try { - playerId = UUID.fromString(toForgive); - } catch (IllegalArgumentException iae) { - sender.sendMessage(ChatColor.RED + "Unable to process uuid " + ChatColor.DARK_RED + toForgive); - } - } else { - sender.sendMessage(ChatColor.RED + "Unable to interpret " + ChatColor.DARK_RED + toForgive); - } - - if (playerId != null) { - BSPlayer player = BSPlayer.byUUID(playerId); - - if (pardons == null) { // unban - if (player.getBan() != null) { - player.setBan(null); - sender.sendMessage(ChatColor.GREEN + "Player " + player.getName() + " is unbanned."); - } else { - sender.sendMessage(ChatColor.GREEN + "Player " + player.getName() + " is not banned."); - } - - try { - Player underlyingUnban = Bukkit.getPlayer(playerId); - if (underlyingUnban != null && underlyingUnban.isBanned()) { - //underlyingUnban.setBanned(false); // REMOVED 1.12 - BanList legacyBans = Bukkit.getBanList(Type.NAME); - legacyBans.pardon(playerId.toString()); - legacyBans.pardon(player.getName()); - BanStick.getPlugin().debug("Also forgave any underlying bukkit ban on uuid / player name"); - } else { - BanStick.getPlugin().debug("Underlying bukkit ban might remain on uuid / player name"); - } - } catch (Exception q) { - BanStick.getPlugin().debug("Failed to forgive any underlying bukkit ban on uuid / player name"); - } + String preForgive = arguments[0]; + int locCIDR = preForgive.indexOf('/'); + Boolean hasCIDR = locCIDR > -1; + Integer cidr = (hasCIDR) ? Integer.valueOf(preForgive.substring(locCIDR + 1)) : null; + String toForgive = (hasCIDR) ? preForgive.substring(0, locCIDR) : preForgive; + List pardons = (arguments.length > 1) ? Arrays.asList( + Arrays.copyOfRange(arguments, 1, arguments.length)) : null; - return true; - } else { - boolean match = false; - for (String pardon : pardons) { - if ("BAN".equalsIgnoreCase(pardon)) { - if (player.getBan() != null) { - player.setBan(null); - sender.sendMessage(ChatColor.GREEN + "Player " + player.getName() + " is unbanned."); - } else { - sender.sendMessage(ChatColor.GREEN + "Player " + player.getName() + " is not banned."); - } + BanStick.getPlugin().debug("preForgive: {0}, CIDR? {1}, toForgive: {2}, pardons: {3}", + preForgive, cidr, toForgive, pardons); - try { - Player underlyingUnban = Bukkit.getPlayer(playerId); - if (underlyingUnban != null && underlyingUnban.isBanned()) { - //underlyingUnban.setBanned(false); // REMOVED 1.12 - BanList legacyBans = Bukkit.getBanList(Type.NAME); - legacyBans.pardon(playerId.toString()); - legacyBans.pardon(player.getName()); - BanStick.getPlugin().debug( - "Also forgave any underlying bukkit ban on uuid / player name"); - } else { - BanStick.getPlugin().debug( - "Unable to forgive any underlying bukkit ban on uuid / player name"); - } - } catch (Exception q) { - BanStick.getPlugin().debug( - "Failed to forgive any underlying bukkit ban on uuid / player name"); - } - match = true; - } - - if ("IP".equalsIgnoreCase(pardon)) { - if (player.getIPPardonTime() == null) { - player.setIPPardonTime(new Date()); - sender.sendMessage(ChatColor.GREEN + "Player " + player.getName() - + " is pardoned from future IP bans. Existing bans aren't impacted."); - } else { - sender.sendMessage(ChatColor.GREEN + "Player " + player.getName() - + " is already pardoned from IP bans."); - } - match = true; - } - - if ("PROXY".equalsIgnoreCase(pardon)) { - if (player.getProxyPardonTime() == null) { - player.setProxyPardonTime(new Date()); - sender.sendMessage(ChatColor.GREEN + "Player " + player.getName() - + " is pardoned from future Proxy bans. Existing warnings aren't impacted."); - } else { - sender.sendMessage(ChatColor.GREEN + "Player " + player.getName() - + " is already pardoned from Proxy bans."); - } - match = true; - } - - if ("SHARED".equalsIgnoreCase(pardon)) { - if (player.getSharedPardonTime() == null) { - player.setSharedPardonTime(new Date()); - sender.sendMessage(ChatColor.GREEN + "Player " + player.getName() - + " is pardoned from future Share warnings/bans." - + " Existing warning/bans aren't impacted."); - } else { - sender.sendMessage(ChatColor.GREEN + "Player " + player.getName() - + " is already pardoned from Share warnings/bans."); - } - match = true; - } - - } - if (match) { - return true; - } else if (!pardons.isEmpty()) { - toForgive = pardons.get(0); - UUID playerId2 = null; - if (toForgive.length() <= 16) { - try { - playerId2 = null; - - try { - playerId2 = NameAPI.getUUID(toForgive); - } catch (NoClassDefFoundError ncde) { } - - if (playerId2 == null) { - Player mcatch = Bukkit.getPlayer(toForgive); - if (mcatch != null) { - playerId2 = mcatch.getUniqueId(); - } - } - } catch (Exception ee) { - sender.sendMessage(ChatColor.RED + "Unable to find player " - + ChatColor.DARK_RED + toForgive); - } - } else if (toForgive.length() == 36) { - try { - playerId2 = UUID.fromString(toForgive); - } catch (IllegalArgumentException iae) { - sender.sendMessage(ChatColor.RED + "Unable to process uuid " - + ChatColor.DARK_RED + toForgive); - } - } else { - sender.sendMessage(ChatColor.RED + "Unable to interpret " + ChatColor.DARK_RED + toForgive); - } - if (playerId2 != null) { - BSPlayer player2 = BSPlayer.byUUID(playerId2); - List shares = player.sharesWith(player2); - int banLifted = 0; - int pardonsGranted = 0; - if (shares != null && !shares.isEmpty()) { - sender.sendMessage(ChatColor.GREEN + "Checking " + shares.size() - + " shared sessions for ones needing pardon"); - boolean alsoUnban = pardons.size() > 1 && "ALL".equalsIgnoreCase(pardons.get(1)); - for (BSShare share : shares) { - if (alsoUnban) { - List bans = BSBan.byShare(share, false); - for (BSBan ban : bans) { - ban.setBanEndTime(new Date()); - banLifted ++; - } - } - - if (!share.isPardoned()) { - share.setPardonTime(new Date()); - pardonsGranted++; - } - } - if (alsoUnban && banLifted > 0) { - sender.sendMessage(ChatColor.GREEN + "Forgave " + banLifted + " active bans"); - } else if (alsoUnban) { - sender.sendMessage(ChatColor.YELLOW - + "Found no bans due to shared sessions to forgive"); - } - if (pardonsGranted > 0) { - sender.sendMessage(ChatColor.GREEN + "Pardoned " - + pardonsGranted + " shared sessions"); - } else { - sender.sendMessage(ChatColor.YELLOW - + "Found no shared sessions still needing pardon"); - } - } else { - sender.sendMessage(ChatColor.YELLOW + "Player " + player.getName() - + " does not share any connections with " + player2.getName()); - } - return true; - } - } - sender.sendMessage(ChatColor.RED + "Unrecognized forgiveness: " + pardons - + ". Please use BAN, IP, PROXY, or SHARED. Or, another user / BAN. Or none to just unban."); - } - return false; - } else { - sender.sendMessage(ChatColor.RED + "Unable to find " + ChatColor.DARK_RED + toForgive); - } - } - return false; - } + try { + IPAddress ipcheck = new IPAddressString(toForgive).toAddress(); + if (!sender.hasPermission("banstick.ips")) { + sender.sendMessage(ChatColor.RED + "You don't have permission to use / view IPs"); + return true; + } + + BSIP exact = !hasCIDR ? BSIP.byIPAddress(ipcheck) : BSIP.byCIDR(ipcheck.toString(), cidr); + if (exact == null) { + sender.sendMessage(ChatColor.RED + "Can't find " + (hasCIDR ? ipcheck.toString() + + "/" + cidr : ipcheck.toString())); + return true; + } + + List bans = BSBan.byIP(exact, false); + + int banLifted = 0; + for (BSBan ban : bans) { + ban.setBanEndTime(new Date()); + banLifted++; + } + + sender.sendMessage(ChatColor.GREEN + "Forgave " + banLifted + " active bans"); + + try { + Bukkit.unbanIP(toForgive); + BanStick.getPlugin().debug("Also forgave any underlying bukkit ban on IP"); + } catch (Exception e) { + BanStick.getPlugin().debug("Failed to forgive any underlying bukkit ban on IP"); + } + + return true; + } catch (IPAddressStringException e) { + // Not an IP address! + UUID playerId = null; + if (toForgive.length() <= 16) { + try { + playerId = null; + + try { + playerId = NameAPI.getUUID(toForgive); + } catch (NoClassDefFoundError ncde) { + } + + if (playerId == null) { + Player match = Bukkit.getPlayer(toForgive); + if (match != null) { + playerId = match.getUniqueId(); + } + } + } catch (Exception ee) { + sender.sendMessage(ChatColor.RED + "Unable to find player " + ChatColor.DARK_RED + toForgive); + } + } else if (toForgive.length() == 36) { + try { + playerId = UUID.fromString(toForgive); + } catch (IllegalArgumentException iae) { + sender.sendMessage(ChatColor.RED + "Unable to process uuid " + ChatColor.DARK_RED + toForgive); + } + } else { + sender.sendMessage(ChatColor.RED + "Unable to interpret " + ChatColor.DARK_RED + toForgive); + } + + if (playerId != null) { + BSPlayer player = BSPlayer.byUUID(playerId); + + if (pardons == null) { // unban + if (player.getBan() != null) { + player.setBan(null); + sender.sendMessage(ChatColor.GREEN + "Player " + player.getName() + " is unbanned."); + } else { + sender.sendMessage(ChatColor.GREEN + "Player " + player.getName() + " is not banned."); + } + + try { + Player underlyingUnban = Bukkit.getPlayer(playerId); + if (underlyingUnban != null && underlyingUnban.isBanned()) { + //underlyingUnban.setBanned(false); // REMOVED 1.12 + BanList legacyBans = Bukkit.getBanList(Type.NAME); + legacyBans.pardon(playerId.toString()); + legacyBans.pardon(player.getName()); + BanStick.getPlugin().debug("Also forgave any underlying bukkit ban on uuid / player name"); + } else { + BanStick.getPlugin().debug("Underlying bukkit ban might remain on uuid / player name"); + } + } catch (Exception q) { + BanStick.getPlugin().debug("Failed to forgive any underlying bukkit ban on uuid / player name"); + } + + return true; + } else { + boolean match = false; + for (String pardon : pardons) { + if ("BAN".equalsIgnoreCase(pardon)) { + if (player.getBan() != null) { + player.setBan(null); + sender.sendMessage(ChatColor.GREEN + "Player " + player.getName() + " is unbanned."); + } else { + sender.sendMessage(ChatColor.GREEN + "Player " + player.getName() + " is not banned."); + } + + try { + Player underlyingUnban = Bukkit.getPlayer(playerId); + if (underlyingUnban != null && underlyingUnban.isBanned()) { + //underlyingUnban.setBanned(false); // REMOVED 1.12 + BanList legacyBans = Bukkit.getBanList(Type.NAME); + legacyBans.pardon(playerId.toString()); + legacyBans.pardon(player.getName()); + BanStick.getPlugin().debug( + "Also forgave any underlying bukkit ban on uuid / player name"); + } else { + BanStick.getPlugin().debug( + "Unable to forgive any underlying bukkit ban on uuid / player name"); + } + } catch (Exception q) { + BanStick.getPlugin().debug( + "Failed to forgive any underlying bukkit ban on uuid / player name"); + } + match = true; + } + + if ("IP".equalsIgnoreCase(pardon)) { + if (player.getIPPardonTime() == null) { + player.setIPPardonTime(new Date()); + sender.sendMessage(ChatColor.GREEN + "Player " + player.getName() + + " is pardoned from future IP bans. Existing bans aren't impacted."); + } else { + sender.sendMessage(ChatColor.GREEN + "Player " + player.getName() + + " is already pardoned from IP bans."); + } + match = true; + } + + if ("PROXY".equalsIgnoreCase(pardon)) { + if (player.getProxyPardonTime() == null) { + player.setProxyPardonTime(new Date()); + sender.sendMessage(ChatColor.GREEN + "Player " + player.getName() + + " is pardoned from future Proxy bans. Existing warnings aren't impacted."); + } else { + sender.sendMessage(ChatColor.GREEN + "Player " + player.getName() + + " is already pardoned from Proxy bans."); + } + match = true; + } + + if ("SHARED".equalsIgnoreCase(pardon)) { + if (player.getSharedPardonTime() == null) { + player.setSharedPardonTime(new Date()); + sender.sendMessage(ChatColor.GREEN + "Player " + player.getName() + + " is pardoned from future Share warnings/bans." + + " Existing warning/bans aren't impacted."); + } else { + sender.sendMessage(ChatColor.GREEN + "Player " + player.getName() + + " is already pardoned from Share warnings/bans."); + } + match = true; + } + + } + if (match) { + return true; + } else if (!pardons.isEmpty()) { + toForgive = pardons.get(0); + UUID playerId2 = null; + if (toForgive.length() <= 16) { + try { + playerId2 = null; + + try { + playerId2 = NameAPI.getUUID(toForgive); + } catch (NoClassDefFoundError ncde) { + } + + if (playerId2 == null) { + Player mcatch = Bukkit.getPlayer(toForgive); + if (mcatch != null) { + playerId2 = mcatch.getUniqueId(); + } + } + } catch (Exception ee) { + sender.sendMessage(ChatColor.RED + "Unable to find player " + + ChatColor.DARK_RED + toForgive); + } + } else if (toForgive.length() == 36) { + try { + playerId2 = UUID.fromString(toForgive); + } catch (IllegalArgumentException iae) { + sender.sendMessage(ChatColor.RED + "Unable to process uuid " + + ChatColor.DARK_RED + toForgive); + } + } else { + sender.sendMessage(ChatColor.RED + "Unable to interpret " + ChatColor.DARK_RED + toForgive); + } + if (playerId2 != null) { + BSPlayer player2 = BSPlayer.byUUID(playerId2); + List shares = player.sharesWith(player2); + int banLifted = 0; + int pardonsGranted = 0; + if (shares != null && !shares.isEmpty()) { + sender.sendMessage(ChatColor.GREEN + "Checking " + shares.size() + + " shared sessions for ones needing pardon"); + boolean alsoUnban = pardons.size() > 1 && "ALL".equalsIgnoreCase(pardons.get(1)); + for (BSShare share : shares) { + if (alsoUnban) { + List bans = BSBan.byShare(share, false); + for (BSBan ban : bans) { + ban.setBanEndTime(new Date()); + banLifted++; + } + } + + if (!share.isPardoned()) { + share.setPardonTime(new Date()); + pardonsGranted++; + } + } + if (alsoUnban && banLifted > 0) { + sender.sendMessage(ChatColor.GREEN + "Forgave " + banLifted + " active bans"); + } else if (alsoUnban) { + sender.sendMessage(ChatColor.YELLOW + + "Found no bans due to shared sessions to forgive"); + } + if (pardonsGranted > 0) { + sender.sendMessage(ChatColor.GREEN + "Pardoned " + + pardonsGranted + " shared sessions"); + } else { + sender.sendMessage(ChatColor.YELLOW + + "Found no shared sessions still needing pardon"); + } + } else { + sender.sendMessage(ChatColor.YELLOW + "Player " + player.getName() + + " does not share any connections with " + player2.getName()); + } + return true; + } + } + sender.sendMessage(ChatColor.RED + "Unrecognized forgiveness: " + pardons + + ". Please use BAN, IP, PROXY, or SHARED. Or, another user / BAN. Or none to just unban."); + } + return false; + } else { + sender.sendMessage(ChatColor.RED + "Unable to find " + ChatColor.DARK_RED + toForgive); + } + } + return false; + } } diff --git a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/commands/GetAltsCommand.java b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/commands/GetAltsCommand.java index b958177fe..69c90662b 100644 --- a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/commands/GetAltsCommand.java +++ b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/commands/GetAltsCommand.java @@ -10,52 +10,51 @@ import org.bukkit.command.CommandSender; /** * Gets all transitive shares for a particular player (alt group). - * - * @author Maxopoly * + * @author Maxopoly */ public class GetAltsCommand implements CommandExecutor { - public static String name = "getalts"; + public static String name = "getalts"; - @Override - public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { - if (args.length != 1) { - sender.sendMessage(ChatColor.RED + "You must specify a single player name or uuid"); - return false; - } - UUID uuid = UntangleCommand.resolveName(args[0]); - if (uuid == null) { - sender.sendMessage(ChatColor.RED + "Could not parse player: " + args[0]); - return false; - } - BSPlayer player = BSPlayer.byUUID(uuid); - if (player == null) { - sender.sendMessage(ChatColor.RED + "Player with uuid is not known: " + uuid.toString()); - return false; - } + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (args.length != 1) { + sender.sendMessage(ChatColor.RED + "You must specify a single player name or uuid"); + return false; + } + UUID uuid = UntangleCommand.resolveName(args[0]); + if (uuid == null) { + sender.sendMessage(ChatColor.RED + "Could not parse player: " + args[0]); + return false; + } + BSPlayer player = BSPlayer.byUUID(uuid); + if (player == null) { + sender.sendMessage(ChatColor.RED + "Player with uuid is not known: " + uuid.toString()); + return false; + } - Set directAssoc = player.getTransitiveSharedPlayers(true); - StringBuilder sb = new StringBuilder(); - sb.append(ChatColor.GOLD + "Directly associated accounts for " + player.getName() + " are: "); - for (BSPlayer alt : directAssoc) { - sb.append(alt.getName()); - sb.append(" "); - } - sender.sendMessage(sb.toString()); + Set directAssoc = player.getTransitiveSharedPlayers(true); + StringBuilder sb = new StringBuilder(); + sb.append(ChatColor.GOLD + "Directly associated accounts for " + player.getName() + " are: "); + for (BSPlayer alt : directAssoc) { + sb.append(alt.getName()); + sb.append(" "); + } + sender.sendMessage(sb.toString()); - Set ignoredAssoc = player.getTransitiveSharedPlayers(false); - sb = new StringBuilder(); - sb.append(ChatColor.GOLD + "Associated accounts split off through exclusions are: "); - for (BSPlayer alt : ignoredAssoc) { - if (directAssoc.contains(alt)) { - continue; - } - sb.append(alt.getName()); - sb.append(" "); - } - sender.sendMessage(sb.toString()); - return true; - } + Set ignoredAssoc = player.getTransitiveSharedPlayers(false); + sb = new StringBuilder(); + sb.append(ChatColor.GOLD + "Associated accounts split off through exclusions are: "); + for (BSPlayer alt : ignoredAssoc) { + if (directAssoc.contains(alt)) { + continue; + } + sb.append(alt.getName()); + sb.append(" "); + } + sender.sendMessage(sb.toString()); + return true; + } } diff --git a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/commands/LoveTapCommand.java b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/commands/LoveTapCommand.java index c0b9648e5..e9bab8fe1 100644 --- a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/commands/LoveTapCommand.java +++ b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/commands/LoveTapCommand.java @@ -30,349 +30,349 @@ import vg.civcraft.mc.namelayer.NameAPI; /** * Sometimes you need some love, so lovetap - * - * @author ProgrammerDan * + * @author ProgrammerDan */ -public class LoveTapCommand implements CommandExecutor { +public class LoveTapCommand implements CommandExecutor { - public static String name = "lovetap"; - - @Override - public boolean onCommand(CommandSender sender, Command cmd, String cmdString, String[] arguments) { - if (arguments.length < 1) { - return false; - } - - String preTap = arguments[0]; - int locCIDR = preTap.indexOf('/'); - Boolean hasCIDR = locCIDR > -1; - Integer cidr = (hasCIDR) ? Integer.valueOf(preTap.substring(locCIDR + 1)) : null; - String toTap = (hasCIDR) ? preTap.substring(0, locCIDR) : preTap; - Integer sessionLimit = Integer.MAX_VALUE; - try { - sessionLimit = Integer.valueOf(arguments[1]); - } catch (NumberFormatException | ArrayIndexOutOfBoundsException ex) { - sender.sendMessage(ChatColor.RED + "You didn't enter a number of sessions properly, defaulting to all"); - } + public static String name = "lovetap"; - BanStick.getPlugin().debug("preTap: {0}, CIDR? {1}, toTap: {2}", - preTap, cidr, toTap); - - try { - IPAddress ipcheck = new IPAddressString(toTap).toAddress(); - if (ipcheck == null) { - throw new IPAddressStringException("Null -- but no error?"); - } - if (!sender.hasPermission("banstick.ips")) { - sender.sendMessage(ChatColor.RED + "You don't have permission to use / view IPs"); - return true; - } - if (hasCIDR) { // MOAR, but aggregates. - sender.sendMessage(ChatColor.GREEN + "Please wait, searching for all contained IP records"); - Bukkit.getScheduler().runTaskAsynchronously(BanStick.getPlugin(), new Runnable() { - @Override - public void run() { - List contains = BSIP.allContained(ipcheck, cidr); - if (contains != null && !contains.isEmpty()) { - sender.sendMessage(ChatColor.GREEN + "Found " + contains.size() - + " contained by " + ChatColor.WHITE + ipcheck.toString() + "/" + cidr); - for (BSIP bsip : contains) { - List bans = BSBan.byIP(bsip, false); - List sessions = BSSession.byIP(bsip); - Set playerIds = new HashSet<>(); - List players = new ArrayList<>(); - List playerBans = new ArrayList<>(); - StringBuilder playerList = new StringBuilder(); - StringBuilder playerBanList = new StringBuilder(); - for (BSSession session : sessions) { - BSPlayer player = session.getPlayer(); - if (playerIds.contains(player.getId())) { - continue; - } - playerIds.add(player.getId()); - playerList.append(player.getName()).append(", "); - players.add(player); - if (player.getBan() != null) { - playerBans.add(player.getBan()); - playerBanList.append(player.getName()).append(", "); - } - } - BSIPData proxy = BSIPData.byExactIP(bsip); - - TextComponent ipBase = new TextComponent("IP "); - ipBase.setColor(net.md_5.bungee.api.ChatColor.BLUE); - TextComponent ipStr = new TextComponent(bsip.toString()); - ipStr.setColor(net.md_5.bungee.api.ChatColor.WHITE); - ipStr.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, - new Text("Click to lovetap this IP"))); - ipStr.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, - "/lovetap " + bsip.toString())); - ipBase.addExtra(ipStr); - // TODO: Add a hover and clickable that issues a lovetap for this IP specifically. - //sb.append(ChatColor.BLUE).append("IP ").append(ChatColor.WHITE).append(bsip.toString()).toString()); - - TextComponent ipBanBase = new TextComponent(" IPBans: "); - ipBanBase.setColor(net.md_5.bungee.api.ChatColor.AQUA); - TextComponent ipBanStr = new TextComponent(Integer.toString(bans == null ? 0 - : bans.size())); - ipBanStr.setColor(net.md_5.bungee.api.ChatColor.WHITE); - ipBanBase.addExtra(ipBanStr); - ipBase.addExtra(ipBanBase); - //sb.append(ChatColor.AQUA).append(" IPBans: ").append(ChatColor.WHITE).append(bans == null ? 0 : bans.size()); - - TextComponent sessionBase = new TextComponent(" Sessions: "); - sessionBase.setColor(net.md_5.bungee.api.ChatColor.AQUA); - TextComponent sessionStr = new TextComponent(Integer.toString(sessions == null ? 0 - : sessions.size())); - sessionStr.setColor(net.md_5.bungee.api.ChatColor.WHITE); - sessionBase.addExtra(sessionStr); - ipBase.addExtra(sessionBase); - //sb.append(ChatColor.AQUA).append(" Sessions: ").append(ChatColor.WHITE).append(sessions == null ? 0 : sessions.size()); - - // TODO: Add a hover showing all the player's names - TextComponent playerBase = new TextComponent(" Players: "); - playerBase.setColor(net.md_5.bungee.api.ChatColor.AQUA); - TextComponent playerStr = new TextComponent(Integer.toString(players == null ? 0 - : players.size())); - playerStr.setColor(net.md_5.bungee.api.ChatColor.WHITE); - if (!players.isEmpty()) { - playerStr.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, - new Text((playerList.substring(0, playerList.length() - 2))))); - } - playerBase.addExtra(playerStr); - ipBase.addExtra(playerBase); - //sb.append(ChatColor.AQUA).append(" Players: ").append(ChatColor.WHITE).append(players == null ? 0 : players.size()); + @Override + public boolean onCommand(CommandSender sender, Command cmd, String cmdString, String[] arguments) { + if (arguments.length < 1) { + return false; + } - TextComponent plBanBase = new TextComponent(" PlayerBans: "); - plBanBase.setColor(net.md_5.bungee.api.ChatColor.AQUA); - TextComponent plBanStr = new TextComponent(Integer.toString(playerBans == null ? 0 - : playerBans.size())); - plBanStr.setColor(net.md_5.bungee.api.ChatColor.WHITE); - if (!playerBans.isEmpty()) { - plBanStr.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, - new Text((playerBanList.substring(0, playerBanList.length() - 2))))); - } - plBanBase.addExtra(plBanStr); - ipBase.addExtra(plBanBase); - //sb.append(ChatColor.AQUA).append(" PlayerBans: ").append(ChatColor.WHITE).append(playerBans == null ? 0 : playerBans.size()); - - if (proxy != null) { - TextComponent proxyBase = new TextComponent("\n " + proxy.toString()); - proxyBase.setColor(net.md_5.bungee.api.ChatColor.WHITE); - proxyBase.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, - new Text(("View other players in same city")))); - proxyBase.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, - "/drilldown PLAYER country \"" + proxy.getCountry() - + "\" region \"" + proxy.getRegion() + "\" city \"" - + proxy.getCity() + "\"")); - ipBase.addExtra(proxyBase); - } - //if (proxy != null) sb.append("\n ").append(proxy.toString()); - - if (sender instanceof Player) { - ((Player) sender).spigot().sendMessage(ipBase); - } else { - sender.sendMessage(ipBase.toLegacyText()); - } - //sender.sendMessage(sb.toString()); - } - } else { - sender.sendMessage(ChatColor.RED + "No IPs found contained by " - + ChatColor.WHITE + ipcheck.toString() + "/" + cidr); - } - } - }); - } - // LESS, but details - - BSIP exact = !hasCIDR ? BSIP.byIPAddress(ipcheck) : BSIP.byCIDR(ipcheck.toString(), cidr); - if (exact == null) { - sender.sendMessage(ChatColor.RED + "Can't find exact " + (hasCIDR ? ipcheck.toString() - + "/" + cidr : ipcheck.toString())); - return true; - } - - List bans = BSBan.byIP(exact, false); - List sessions = BSSession.byIP(exact); - List proxies = BSIPData.allByIP(exact); - - StringBuilder sb = new StringBuilder(); - sb.append(ChatColor.BLUE).append("Data for IP ").append(ChatColor.WHITE).append(exact.toString()); - sb.append('\n'); - sb.append(ChatColor.BLUE).append("\nDetail Data: \n"); - if (proxies == null || proxies.isEmpty()) { - sb.append(ChatColor.AQUA).append(" None.\n"); - } else { - for (BSIPData data : proxies) { - sb.append(ChatColor.WHITE).append(" ").append(data.toString()).append('\n'); - } - } - - sb.append('\n'); - sb.append(ChatColor.BLUE).append("Sessions: \n"); - if (sessions == null || sessions.isEmpty()) { - sb.append(ChatColor.AQUA).append(" None.\n"); - } else { - for (int i = 0; i <= sessionLimit - 1; i++) { - try { - sb.append(ChatColor.WHITE).append(" ").append(sessions.get(i).toString()).append('\n'); - } catch (IndexOutOfBoundsException exception) { - break; - } - } - } - - sb.append('\n'); - sb.append(ChatColor.BLUE).append("Bans: \n"); - if (bans == null || bans.isEmpty()) { - sb.append(ChatColor.AQUA).append(" None.\n"); - } else { - for (BSBan ban : bans) { - sb.append(ChatColor.WHITE).append(" ").append(ban.toString()).append('\n'); - } - } - sender.sendMessage(sb.toString()); - - return true; - } catch (IPAddressStringException e) { - // Not an IP address! - UUID playerId = null; - if (toTap.length() <= 16) { - try { - playerId = null; - try { - playerId = NameAPI.getUUID(toTap); - } catch (NoClassDefFoundError ncde) { } - - if (playerId == null) { - Player match = Bukkit.getPlayer(toTap); - if (match != null) { - playerId = match.getUniqueId(); - } - } - } catch (Exception ee) { - sender.sendMessage(ChatColor.RED + "Unable to find player " + ChatColor.DARK_RED + toTap); - } - } else if (toTap.length() == 36) { - try { - playerId = UUID.fromString(toTap); - } catch (IllegalArgumentException iae) { - sender.sendMessage(ChatColor.RED + "Unable to process uuid " + ChatColor.DARK_RED + toTap); - } - } else { - sender.sendMessage(ChatColor.RED + "Unable to interpret " + ChatColor.DARK_RED + toTap); - } - - if (playerId != null) { - BSPlayer player = BSPlayer.byUUID(playerId); - if (player == null) { - sender.sendMessage("No Player records for " + toTap); - } + String preTap = arguments[0]; + int locCIDR = preTap.indexOf('/'); + Boolean hasCIDR = locCIDR > -1; + Integer cidr = (hasCIDR) ? Integer.valueOf(preTap.substring(locCIDR + 1)) : null; + String toTap = (hasCIDR) ? preTap.substring(0, locCIDR) : preTap; + Integer sessionLimit = Integer.MAX_VALUE; + try { + sessionLimit = Integer.valueOf(arguments[1]); + } catch (NumberFormatException | ArrayIndexOutOfBoundsException ex) { + sender.sendMessage(ChatColor.RED + "You didn't enter a number of sessions properly, defaulting to all"); + } - if (hasCIDR) { - if (!sender.hasPermission("banstick.ips")) { - sender.sendMessage(ChatColor.RED + "You don't have permission to use / view IPs"); - return true; - } - - BSSession latest = player.getLatestSession(); - if (latest != null) { - BSIP latestIP = latest.getIP(); - if (latestIP == null) { - sender.sendMessage("CIDR " + cidr + " of latest IP requested but player has no latest IP"); - return true; - } - String ipRequest = latestIP.toString(); - if (ipRequest.indexOf('/') > -1) { - ipRequest = ipRequest.substring(0, ipRequest.indexOf('/')); - } - return onCommand(sender, cmd, cmdString, new String[] {ipRequest + "/" + cidr}); - } - } - - BSBan ban = player.getBan(); - List history = player.getAllSessions(); - BSSession latest = player.getLatestSession(); - - BSIPData latestProxy = latest != null ? BSIPData.byContainsIP(latest.getIP()) : null; - - List shares = player.getAllShares(); - - StringBuilder sb = new StringBuilder(); - if (history != null) { - Collections.reverse(history); - sb.append(ChatColor.BLUE).append("Session History: ").append(ChatColor.DARK_AQUA) - .append("(First Join: ").append(ChatColor.WHITE).append(player.getFirstAdd()) - .append(ChatColor.DARK_AQUA).append(")\n"); - for (int i = 0; i <= sessionLimit - 1; i++) { - try { - sb.append(ChatColor.WHITE + " " + history.get(i).toFullString( - sender.hasPermission("banstick.ips")) + "\n"); - } catch (IndexOutOfBoundsException exception) { - break; - } - } - sb.append("\n"); - } - if (latest != null) { - sb.append(ChatColor.GREEN + "Most Recent Session: \n"); - sb.append(ChatColor.WHITE + " " + latest.toFullString( - sender.hasPermission("banstick.ips")) + "\n"); - } - - if (shares != null && !shares.isEmpty()) { - sb.append(ChatColor.BLUE).append("Share History: ").append("\n"); - for (BSShare histShare : shares) { - sb.append(ChatColor.WHITE + " " - + histShare.toFullString(sender.hasPermission("banstick.ips")) + "\n"); - } - sb.append("\n"); - } - - if (latestProxy != null && sender.hasPermission("banstick.ips")) { - sb.append(ChatColor.GRAY + " Network: " + ChatColor.WHITE + latestProxy.toString() + "\n"); - } - sb.append("\n"); - if (ban != null) { - sb.append(ChatColor.RED + "Active Ban: \n"); - sb.append(ChatColor.WHITE + " " + ban.toString() + "\n"); - } - sb.append("\n"); - sb.append(ChatColor.GREEN + "Pardoned from future:\n"); - if (player.getIPPardonTime() != null) { - sb.append(ChatColor.GREEN + " IP Bans\n"); - } - if (player.getProxyPardonTime() != null) { - sb.append(ChatColor.GREEN + " Proxy Bans\n"); - } - if (player.getSharedPardonTime() != null) { - sb.append(ChatColor.GREEN + " Shared Connection Bans\n"); - } - if (player.getIPPardonTime() == null && player.getProxyPardonTime() == null - && player.getSharedPardonTime() == null) { - sb.append(ChatColor.RED + " Nothing\n"); - } - - sb.append("\n"); - sb.append(ChatColor.WHITE + player.getName() + " [" + player.getUUID() + "]"); - - sender.sendMessage(sb.toString()); - if (latestProxy != null && sender instanceof Player) { - TextComponent proxyBase = new TextComponent("\n View other players in same city"); - proxyBase.setColor(net.md_5.bungee.api.ChatColor.GOLD); - proxyBase.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, - "/drilldown PLAYER country \"" + latestProxy.getCountry() + "\" region \"" - + latestProxy.getRegion() + "\" city \"" + latestProxy.getCity() + "\"")); - ((Player) sender).spigot().sendMessage(proxyBase); - } - - return true; - } else { - sender.sendMessage(ChatColor.RED + "Unable to find " + ChatColor.DARK_RED + toTap); - } - } + BanStick.getPlugin().debug("preTap: {0}, CIDR? {1}, toTap: {2}", + preTap, cidr, toTap); - return false; - } + try { + IPAddress ipcheck = new IPAddressString(toTap).toAddress(); + if (ipcheck == null) { + throw new IPAddressStringException("Null -- but no error?"); + } + if (!sender.hasPermission("banstick.ips")) { + sender.sendMessage(ChatColor.RED + "You don't have permission to use / view IPs"); + return true; + } + if (hasCIDR) { // MOAR, but aggregates. + sender.sendMessage(ChatColor.GREEN + "Please wait, searching for all contained IP records"); + Bukkit.getScheduler().runTaskAsynchronously(BanStick.getPlugin(), new Runnable() { + @Override + public void run() { + List contains = BSIP.allContained(ipcheck, cidr); + if (contains != null && !contains.isEmpty()) { + sender.sendMessage(ChatColor.GREEN + "Found " + contains.size() + + " contained by " + ChatColor.WHITE + ipcheck.toString() + "/" + cidr); + for (BSIP bsip : contains) { + List bans = BSBan.byIP(bsip, false); + List sessions = BSSession.byIP(bsip); + Set playerIds = new HashSet<>(); + List players = new ArrayList<>(); + List playerBans = new ArrayList<>(); + StringBuilder playerList = new StringBuilder(); + StringBuilder playerBanList = new StringBuilder(); + for (BSSession session : sessions) { + BSPlayer player = session.getPlayer(); + if (playerIds.contains(player.getId())) { + continue; + } + playerIds.add(player.getId()); + playerList.append(player.getName()).append(", "); + players.add(player); + if (player.getBan() != null) { + playerBans.add(player.getBan()); + playerBanList.append(player.getName()).append(", "); + } + } + BSIPData proxy = BSIPData.byExactIP(bsip); + + TextComponent ipBase = new TextComponent("IP "); + ipBase.setColor(net.md_5.bungee.api.ChatColor.BLUE); + TextComponent ipStr = new TextComponent(bsip.toString()); + ipStr.setColor(net.md_5.bungee.api.ChatColor.WHITE); + ipStr.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, + new Text("Click to lovetap this IP"))); + ipStr.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, + "/lovetap " + bsip.toString())); + ipBase.addExtra(ipStr); + // TODO: Add a hover and clickable that issues a lovetap for this IP specifically. + //sb.append(ChatColor.BLUE).append("IP ").append(ChatColor.WHITE).append(bsip.toString()).toString()); + + TextComponent ipBanBase = new TextComponent(" IPBans: "); + ipBanBase.setColor(net.md_5.bungee.api.ChatColor.AQUA); + TextComponent ipBanStr = new TextComponent(Integer.toString(bans == null ? 0 + : bans.size())); + ipBanStr.setColor(net.md_5.bungee.api.ChatColor.WHITE); + ipBanBase.addExtra(ipBanStr); + ipBase.addExtra(ipBanBase); + //sb.append(ChatColor.AQUA).append(" IPBans: ").append(ChatColor.WHITE).append(bans == null ? 0 : bans.size()); + + TextComponent sessionBase = new TextComponent(" Sessions: "); + sessionBase.setColor(net.md_5.bungee.api.ChatColor.AQUA); + TextComponent sessionStr = new TextComponent(Integer.toString(sessions == null ? 0 + : sessions.size())); + sessionStr.setColor(net.md_5.bungee.api.ChatColor.WHITE); + sessionBase.addExtra(sessionStr); + ipBase.addExtra(sessionBase); + //sb.append(ChatColor.AQUA).append(" Sessions: ").append(ChatColor.WHITE).append(sessions == null ? 0 : sessions.size()); + + // TODO: Add a hover showing all the player's names + TextComponent playerBase = new TextComponent(" Players: "); + playerBase.setColor(net.md_5.bungee.api.ChatColor.AQUA); + TextComponent playerStr = new TextComponent(Integer.toString(players == null ? 0 + : players.size())); + playerStr.setColor(net.md_5.bungee.api.ChatColor.WHITE); + if (!players.isEmpty()) { + playerStr.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, + new Text((playerList.substring(0, playerList.length() - 2))))); + } + playerBase.addExtra(playerStr); + ipBase.addExtra(playerBase); + //sb.append(ChatColor.AQUA).append(" Players: ").append(ChatColor.WHITE).append(players == null ? 0 : players.size()); + + TextComponent plBanBase = new TextComponent(" PlayerBans: "); + plBanBase.setColor(net.md_5.bungee.api.ChatColor.AQUA); + TextComponent plBanStr = new TextComponent(Integer.toString(playerBans == null ? 0 + : playerBans.size())); + plBanStr.setColor(net.md_5.bungee.api.ChatColor.WHITE); + if (!playerBans.isEmpty()) { + plBanStr.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, + new Text((playerBanList.substring(0, playerBanList.length() - 2))))); + } + plBanBase.addExtra(plBanStr); + ipBase.addExtra(plBanBase); + //sb.append(ChatColor.AQUA).append(" PlayerBans: ").append(ChatColor.WHITE).append(playerBans == null ? 0 : playerBans.size()); + + if (proxy != null) { + TextComponent proxyBase = new TextComponent("\n " + proxy.toString()); + proxyBase.setColor(net.md_5.bungee.api.ChatColor.WHITE); + proxyBase.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, + new Text(("View other players in same city")))); + proxyBase.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, + "/drilldown PLAYER country \"" + proxy.getCountry() + + "\" region \"" + proxy.getRegion() + "\" city \"" + + proxy.getCity() + "\"")); + ipBase.addExtra(proxyBase); + } + //if (proxy != null) sb.append("\n ").append(proxy.toString()); + + if (sender instanceof Player) { + ((Player) sender).spigot().sendMessage(ipBase); + } else { + sender.sendMessage(ipBase.toLegacyText()); + } + //sender.sendMessage(sb.toString()); + } + } else { + sender.sendMessage(ChatColor.RED + "No IPs found contained by " + + ChatColor.WHITE + ipcheck.toString() + "/" + cidr); + } + } + }); + } + // LESS, but details + + BSIP exact = !hasCIDR ? BSIP.byIPAddress(ipcheck) : BSIP.byCIDR(ipcheck.toString(), cidr); + if (exact == null) { + sender.sendMessage(ChatColor.RED + "Can't find exact " + (hasCIDR ? ipcheck.toString() + + "/" + cidr : ipcheck.toString())); + return true; + } + + List bans = BSBan.byIP(exact, false); + List sessions = BSSession.byIP(exact); + List proxies = BSIPData.allByIP(exact); + + StringBuilder sb = new StringBuilder(); + sb.append(ChatColor.BLUE).append("Data for IP ").append(ChatColor.WHITE).append(exact.toString()); + sb.append('\n'); + sb.append(ChatColor.BLUE).append("\nDetail Data: \n"); + if (proxies == null || proxies.isEmpty()) { + sb.append(ChatColor.AQUA).append(" None.\n"); + } else { + for (BSIPData data : proxies) { + sb.append(ChatColor.WHITE).append(" ").append(data.toString()).append('\n'); + } + } + + sb.append('\n'); + sb.append(ChatColor.BLUE).append("Sessions: \n"); + if (sessions == null || sessions.isEmpty()) { + sb.append(ChatColor.AQUA).append(" None.\n"); + } else { + for (int i = 0; i <= sessionLimit - 1; i++) { + try { + sb.append(ChatColor.WHITE).append(" ").append(sessions.get(i).toString()).append('\n'); + } catch (IndexOutOfBoundsException exception) { + break; + } + } + } + + sb.append('\n'); + sb.append(ChatColor.BLUE).append("Bans: \n"); + if (bans == null || bans.isEmpty()) { + sb.append(ChatColor.AQUA).append(" None.\n"); + } else { + for (BSBan ban : bans) { + sb.append(ChatColor.WHITE).append(" ").append(ban.toString()).append('\n'); + } + } + sender.sendMessage(sb.toString()); + + return true; + } catch (IPAddressStringException e) { + // Not an IP address! + UUID playerId = null; + if (toTap.length() <= 16) { + try { + playerId = null; + try { + playerId = NameAPI.getUUID(toTap); + } catch (NoClassDefFoundError ncde) { + } + + if (playerId == null) { + Player match = Bukkit.getPlayer(toTap); + if (match != null) { + playerId = match.getUniqueId(); + } + } + } catch (Exception ee) { + sender.sendMessage(ChatColor.RED + "Unable to find player " + ChatColor.DARK_RED + toTap); + } + } else if (toTap.length() == 36) { + try { + playerId = UUID.fromString(toTap); + } catch (IllegalArgumentException iae) { + sender.sendMessage(ChatColor.RED + "Unable to process uuid " + ChatColor.DARK_RED + toTap); + } + } else { + sender.sendMessage(ChatColor.RED + "Unable to interpret " + ChatColor.DARK_RED + toTap); + } + + if (playerId != null) { + BSPlayer player = BSPlayer.byUUID(playerId); + if (player == null) { + sender.sendMessage("No Player records for " + toTap); + } + + if (hasCIDR) { + if (!sender.hasPermission("banstick.ips")) { + sender.sendMessage(ChatColor.RED + "You don't have permission to use / view IPs"); + return true; + } + + BSSession latest = player.getLatestSession(); + if (latest != null) { + BSIP latestIP = latest.getIP(); + if (latestIP == null) { + sender.sendMessage("CIDR " + cidr + " of latest IP requested but player has no latest IP"); + return true; + } + String ipRequest = latestIP.toString(); + if (ipRequest.indexOf('/') > -1) { + ipRequest = ipRequest.substring(0, ipRequest.indexOf('/')); + } + return onCommand(sender, cmd, cmdString, new String[]{ipRequest + "/" + cidr}); + } + } + + BSBan ban = player.getBan(); + List history = player.getAllSessions(); + BSSession latest = player.getLatestSession(); + + BSIPData latestProxy = latest != null ? BSIPData.byContainsIP(latest.getIP()) : null; + + List shares = player.getAllShares(); + + StringBuilder sb = new StringBuilder(); + if (history != null) { + Collections.reverse(history); + sb.append(ChatColor.BLUE).append("Session History: ").append(ChatColor.DARK_AQUA) + .append("(First Join: ").append(ChatColor.WHITE).append(player.getFirstAdd()) + .append(ChatColor.DARK_AQUA).append(")\n"); + for (int i = 0; i <= sessionLimit - 1; i++) { + try { + sb.append(ChatColor.WHITE + " " + history.get(i).toFullString( + sender.hasPermission("banstick.ips")) + "\n"); + } catch (IndexOutOfBoundsException exception) { + break; + } + } + sb.append("\n"); + } + if (latest != null) { + sb.append(ChatColor.GREEN + "Most Recent Session: \n"); + sb.append(ChatColor.WHITE + " " + latest.toFullString( + sender.hasPermission("banstick.ips")) + "\n"); + } + + if (shares != null && !shares.isEmpty()) { + sb.append(ChatColor.BLUE).append("Share History: ").append("\n"); + for (BSShare histShare : shares) { + sb.append(ChatColor.WHITE + " " + + histShare.toFullString(sender.hasPermission("banstick.ips")) + "\n"); + } + sb.append("\n"); + } + + if (latestProxy != null && sender.hasPermission("banstick.ips")) { + sb.append(ChatColor.GRAY + " Network: " + ChatColor.WHITE + latestProxy.toString() + "\n"); + } + sb.append("\n"); + if (ban != null) { + sb.append(ChatColor.RED + "Active Ban: \n"); + sb.append(ChatColor.WHITE + " " + ban.toString() + "\n"); + } + sb.append("\n"); + sb.append(ChatColor.GREEN + "Pardoned from future:\n"); + if (player.getIPPardonTime() != null) { + sb.append(ChatColor.GREEN + " IP Bans\n"); + } + if (player.getProxyPardonTime() != null) { + sb.append(ChatColor.GREEN + " Proxy Bans\n"); + } + if (player.getSharedPardonTime() != null) { + sb.append(ChatColor.GREEN + " Shared Connection Bans\n"); + } + if (player.getIPPardonTime() == null && player.getProxyPardonTime() == null + && player.getSharedPardonTime() == null) { + sb.append(ChatColor.RED + " Nothing\n"); + } + + sb.append("\n"); + sb.append(ChatColor.WHITE + player.getName() + " [" + player.getUUID() + "]"); + + sender.sendMessage(sb.toString()); + if (latestProxy != null && sender instanceof Player) { + TextComponent proxyBase = new TextComponent("\n View other players in same city"); + proxyBase.setColor(net.md_5.bungee.api.ChatColor.GOLD); + proxyBase.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, + "/drilldown PLAYER country \"" + latestProxy.getCountry() + "\" region \"" + + latestProxy.getRegion() + "\" city \"" + latestProxy.getCity() + "\"")); + ((Player) sender).spigot().sendMessage(proxyBase); + } + + return true; + } else { + sender.sendMessage(ChatColor.RED + "Unable to find " + ChatColor.DARK_RED + toTap); + } + } + + return false; + } } diff --git a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/commands/TakeItBackCommand.java b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/commands/TakeItBackCommand.java index 1cb9887b5..73299604a 100644 --- a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/commands/TakeItBackCommand.java +++ b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/commands/TakeItBackCommand.java @@ -16,167 +16,169 @@ import vg.civcraft.mc.namelayer.NameAPI; /** * TakeItBackCommand, for when you pardoned someone but regretted it - * - * @author ProgrammerDan * + * @author ProgrammerDan */ public class TakeItBackCommand implements CommandExecutor { - public static String name = "takeitback"; - - // TODO: Unsafe command structure as player could have name of IP or PROXY or SHARED - // and that would break this command. - /** - * takeitback [name/uuid] [IP] [PROXY] [SHARED] - * IP - Allows new bans on this player due to IP matches - * PROXY - Allows new bans on this player due to IPData ban matches - * SHARED - Allows new bans on this player due to Share connection ban matches - *
- * takeitback [name/uuid] [name/uuid] - * Immediately unpardons all shares between these two players. - */ - @Override - public boolean onCommand(CommandSender sender, Command cmd, String cmdString, String[] arguments) { - if (arguments.length < 2) { - return false; - } - - String toRevoke = arguments[0]; - String secRevoke = arguments[1]; - List revokes = Arrays.asList(Arrays.copyOfRange(arguments, 1, arguments.length)); + public static String name = "takeitback"; - BanStick.getPlugin().debug("toRevoke: {0}, secRevoke: {1}, revokes: {2}", - toRevoke, secRevoke, revokes); - - UUID playerId = null; - if (toRevoke.length() <= 16) { - try { - playerId = null; - try { - playerId = NameAPI.getUUID(toRevoke); - } catch (NoClassDefFoundError ncde) { } - - if (playerId == null) { - Player match = Bukkit.getPlayer(toRevoke); - if (match != null) { - playerId = match.getUniqueId(); - } - } - } catch (Exception ee) { - sender.sendMessage(ChatColor.RED + "Unable to find player " + ChatColor.DARK_RED + toRevoke); - return true; - } - } else if (toRevoke.length() == 36) { - try { - playerId = UUID.fromString(toRevoke); - } catch (IllegalArgumentException iae) { - sender.sendMessage(ChatColor.RED + "Unable to process uuid " + ChatColor.DARK_RED + toRevoke); - return true; - } - } else { - sender.sendMessage(ChatColor.RED + "Unable to interpret " + ChatColor.DARK_RED + toRevoke); - return true; - } - - UUID secondPlayerId = null; - if (secRevoke.length() <= 16) { - try { - secondPlayerId = null; - try { - secondPlayerId = NameAPI.getUUID(secRevoke); - } catch (NoClassDefFoundError ncde) { } - - if (secondPlayerId == null) { - Player match = Bukkit.getPlayer(secRevoke); - if (match != null) { - secondPlayerId = match.getUniqueId(); - } - } - } catch (Exception ee) { - // not a player, but might be a pardon - } - } else if (secRevoke.length() == 36) { - try { - secondPlayerId = UUID.fromString(secRevoke); - } catch (IllegalArgumentException iae) { - sender.sendMessage(ChatColor.RED + "Unable to process uuid " + ChatColor.DARK_RED + secRevoke); - return true; - } - } else { - sender.sendMessage(ChatColor.RED + "Unable to interpret " + ChatColor.DARK_RED + secRevoke); - return true; - } - - BSPlayer player = BSPlayer.byUUID(playerId); - if (secondPlayerId == null) { // single player unpardon. - boolean match = false; - for (String pardon : revokes) { - if ("IP".equalsIgnoreCase(pardon)) { - if (player.getIPPardonTime() != null) { - player.setIPPardonTime(null); - sender.sendMessage(ChatColor.GREEN + "Player " + player.getName() - + " is exposed to future IP bans. Existing bans aren't impacted."); - } else { - sender.sendMessage(ChatColor.GREEN + "Player " + player.getName() - + " is already exposed to IP bans."); - } - match = true; - } - - if ("PROXY".equalsIgnoreCase(pardon)) { - if (player.getProxyPardonTime() != null) { - player.setProxyPardonTime(null); - sender.sendMessage(ChatColor.GREEN + "Player " + player.getName() - + " is exposed to future Proxy bans. Existing warnings aren't impacted."); - } else { - sender.sendMessage(ChatColor.GREEN + "Player " + player.getName() - + " is already exposed to Proxy bans."); - } - match = true; - } - - if ("SHARED".equalsIgnoreCase(pardon)) { - if (player.getSharedPardonTime() != null) { - player.setSharedPardonTime(null); - sender.sendMessage(ChatColor.GREEN + "Player " + player.getName() - + " is exposed to future Share warnings/bans. Existing warning/bans aren't impacted."); - } else { - sender.sendMessage(ChatColor.GREEN + "Player " + player.getName() - + " is already exposed to Share warnings/bans."); - } - match = true; - } - } + // TODO: Unsafe command structure as player could have name of IP or PROXY or SHARED + // and that would break this command. - if (match) { - return true; - } else { - sender.sendMessage(ChatColor.RED + "Could not determine what to do."); - return false; - } - } else { - // unpardon shares between two people - BSPlayer player2 = BSPlayer.byUUID(secondPlayerId); - List shares = player.sharesWith(player2); - int pardonsRevoked = 0; - if (shares != null && !shares.isEmpty()) { - for (BSShare share : shares) { - if (share.isPardoned()) { - share.setPardonTime(null); - pardonsRevoked++; - } - } - if (pardonsRevoked > 0) { - sender.sendMessage(ChatColor.GREEN + "Revoked pardons for " + pardonsRevoked + " shared sessions"); - } else { - sender.sendMessage(ChatColor.YELLOW + "Found no shared sessions needing pardon revocation"); - } - } else { - sender.sendMessage(ChatColor.YELLOW + "Player " + player.getName() - + " does not share any connections with " + player2.getName()); - } - return true; - } - } + /** + * takeitback [name/uuid] [IP] [PROXY] [SHARED] + * IP - Allows new bans on this player due to IP matches + * PROXY - Allows new bans on this player due to IPData ban matches + * SHARED - Allows new bans on this player due to Share connection ban matches + *
+ * takeitback [name/uuid] [name/uuid] + * Immediately unpardons all shares between these two players. + */ + @Override + public boolean onCommand(CommandSender sender, Command cmd, String cmdString, String[] arguments) { + if (arguments.length < 2) { + return false; + } + + String toRevoke = arguments[0]; + String secRevoke = arguments[1]; + List revokes = Arrays.asList(Arrays.copyOfRange(arguments, 1, arguments.length)); + + BanStick.getPlugin().debug("toRevoke: {0}, secRevoke: {1}, revokes: {2}", + toRevoke, secRevoke, revokes); + + UUID playerId = null; + if (toRevoke.length() <= 16) { + try { + playerId = null; + try { + playerId = NameAPI.getUUID(toRevoke); + } catch (NoClassDefFoundError ncde) { + } + + if (playerId == null) { + Player match = Bukkit.getPlayer(toRevoke); + if (match != null) { + playerId = match.getUniqueId(); + } + } + } catch (Exception ee) { + sender.sendMessage(ChatColor.RED + "Unable to find player " + ChatColor.DARK_RED + toRevoke); + return true; + } + } else if (toRevoke.length() == 36) { + try { + playerId = UUID.fromString(toRevoke); + } catch (IllegalArgumentException iae) { + sender.sendMessage(ChatColor.RED + "Unable to process uuid " + ChatColor.DARK_RED + toRevoke); + return true; + } + } else { + sender.sendMessage(ChatColor.RED + "Unable to interpret " + ChatColor.DARK_RED + toRevoke); + return true; + } + + UUID secondPlayerId = null; + if (secRevoke.length() <= 16) { + try { + secondPlayerId = null; + try { + secondPlayerId = NameAPI.getUUID(secRevoke); + } catch (NoClassDefFoundError ncde) { + } + + if (secondPlayerId == null) { + Player match = Bukkit.getPlayer(secRevoke); + if (match != null) { + secondPlayerId = match.getUniqueId(); + } + } + } catch (Exception ee) { + // not a player, but might be a pardon + } + } else if (secRevoke.length() == 36) { + try { + secondPlayerId = UUID.fromString(secRevoke); + } catch (IllegalArgumentException iae) { + sender.sendMessage(ChatColor.RED + "Unable to process uuid " + ChatColor.DARK_RED + secRevoke); + return true; + } + } else { + sender.sendMessage(ChatColor.RED + "Unable to interpret " + ChatColor.DARK_RED + secRevoke); + return true; + } + + BSPlayer player = BSPlayer.byUUID(playerId); + if (secondPlayerId == null) { // single player unpardon. + boolean match = false; + for (String pardon : revokes) { + if ("IP".equalsIgnoreCase(pardon)) { + if (player.getIPPardonTime() != null) { + player.setIPPardonTime(null); + sender.sendMessage(ChatColor.GREEN + "Player " + player.getName() + + " is exposed to future IP bans. Existing bans aren't impacted."); + } else { + sender.sendMessage(ChatColor.GREEN + "Player " + player.getName() + + " is already exposed to IP bans."); + } + match = true; + } + + if ("PROXY".equalsIgnoreCase(pardon)) { + if (player.getProxyPardonTime() != null) { + player.setProxyPardonTime(null); + sender.sendMessage(ChatColor.GREEN + "Player " + player.getName() + + " is exposed to future Proxy bans. Existing warnings aren't impacted."); + } else { + sender.sendMessage(ChatColor.GREEN + "Player " + player.getName() + + " is already exposed to Proxy bans."); + } + match = true; + } + + if ("SHARED".equalsIgnoreCase(pardon)) { + if (player.getSharedPardonTime() != null) { + player.setSharedPardonTime(null); + sender.sendMessage(ChatColor.GREEN + "Player " + player.getName() + + " is exposed to future Share warnings/bans. Existing warning/bans aren't impacted."); + } else { + sender.sendMessage(ChatColor.GREEN + "Player " + player.getName() + + " is already exposed to Share warnings/bans."); + } + match = true; + } + } + + if (match) { + return true; + } else { + sender.sendMessage(ChatColor.RED + "Could not determine what to do."); + return false; + } + } else { + // unpardon shares between two people + BSPlayer player2 = BSPlayer.byUUID(secondPlayerId); + List shares = player.sharesWith(player2); + int pardonsRevoked = 0; + if (shares != null && !shares.isEmpty()) { + for (BSShare share : shares) { + if (share.isPardoned()) { + share.setPardonTime(null); + pardonsRevoked++; + } + } + if (pardonsRevoked > 0) { + sender.sendMessage(ChatColor.GREEN + "Revoked pardons for " + pardonsRevoked + " shared sessions"); + } else { + sender.sendMessage(ChatColor.YELLOW + "Found no shared sessions needing pardon revocation"); + } + } else { + sender.sendMessage(ChatColor.YELLOW + "Player " + player.getName() + + " does not share any connections with " + player2.getName()); + } + return true; + } + } } diff --git a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/commands/UntangleCommand.java b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/commands/UntangleCommand.java index 1cba654b4..b897aadaf 100644 --- a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/commands/UntangleCommand.java +++ b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/commands/UntangleCommand.java @@ -16,118 +16,117 @@ import vg.civcraft.mc.namelayer.NameAPI; /** * Untangle command, creates a new altgraph based on imputs. - * - * @author Maxopoly * + * @author Maxopoly */ public class UntangleCommand implements CommandExecutor { - public static String name = "untangle"; + public static String name = "untangle"; - @Override - public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { - if (args.length == 0) { - sender.sendMessage(ChatColor.RED + "You must specify player names or uuids"); - return true; - } - Set subGraphPlayers = new HashSet<>(); - Set allGraphPlayers = new HashSet<>(); - // parse uuids out of the command - for (String arg : args) { - UUID uuid = resolveName(arg); - if (uuid == null) { - sender.sendMessage(ChatColor.RED + "Could not parse player: " + arg); - return false; - } - subGraphPlayers.add(BSPlayer.byUUID(uuid)); - } - // Determine all nodes (players) in the graph (association network) we are - // creating a subgraph off - for (BSPlayer player : subGraphPlayers) { - allGraphPlayers.addAll(player.getTransitiveSharedPlayers(true)); - } + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (args.length == 0) { + sender.sendMessage(ChatColor.RED + "You must specify player names or uuids"); + return true; + } + Set subGraphPlayers = new HashSet<>(); + Set allGraphPlayers = new HashSet<>(); + // parse uuids out of the command + for (String arg : args) { + UUID uuid = resolveName(arg); + if (uuid == null) { + sender.sendMessage(ChatColor.RED + "Could not parse player: " + arg); + return false; + } + subGraphPlayers.add(BSPlayer.byUUID(uuid)); + } + // Determine all nodes (players) in the graph (association network) we are + // creating a subgraph off + for (BSPlayer player : subGraphPlayers) { + allGraphPlayers.addAll(player.getTransitiveSharedPlayers(true)); + } - int delCounter = 0; - // Delete all preexisting exclusions within this graph - for (BSPlayer playerOuter : allGraphPlayers) { - for (BSPlayer playerInner : allGraphPlayers) { - BSExclusion excl = playerOuter.getExclusionWith(playerInner); - if (excl != null) { - excl.delete(); - delCounter++; - } - } - } + int delCounter = 0; + // Delete all preexisting exclusions within this graph + for (BSPlayer playerOuter : allGraphPlayers) { + for (BSPlayer playerInner : allGraphPlayers) { + BSExclusion excl = playerOuter.getExclusionWith(playerInner); + if (excl != null) { + excl.delete(); + delCounter++; + } + } + } - int createCounter = 0; - // create exclusions between all players in the new subgraph and all players not - // in the new subgraph - Set outsideSubGraphPlayers = new HashSet<>(allGraphPlayers); - outsideSubGraphPlayers.removeAll(subGraphPlayers); - for (BSPlayer inside : subGraphPlayers) { - for (BSPlayer outside : outsideSubGraphPlayers) { - BSExclusion excl = BSExclusion.create(inside, outside); - inside.addExclusion(excl); - outside.addExclusion(excl); - createCounter++; - } - } - sender.sendMessage(ChatColor.GREEN + String.format( - "Added exclusions to group containing %d players. %d exclusions were created and %d exclusions were deleted", - allGraphPlayers.size(), createCounter, delCounter)); - StringBuilder sb = new StringBuilder(); - for (BSPlayer player : subGraphPlayers) { - sb.append(player.getName()); - sb.append(":"); - sb.append(player.getUUID()); - sb.append(" "); - } - sender.sendMessage(ChatColor.GREEN - + String.format("First group created contains %d players: %s", subGraphPlayers.size(), sb.toString())); + int createCounter = 0; + // create exclusions between all players in the new subgraph and all players not + // in the new subgraph + Set outsideSubGraphPlayers = new HashSet<>(allGraphPlayers); + outsideSubGraphPlayers.removeAll(subGraphPlayers); + for (BSPlayer inside : subGraphPlayers) { + for (BSPlayer outside : outsideSubGraphPlayers) { + BSExclusion excl = BSExclusion.create(inside, outside); + inside.addExclusion(excl); + outside.addExclusion(excl); + createCounter++; + } + } + sender.sendMessage(ChatColor.GREEN + String.format( + "Added exclusions to group containing %d players. %d exclusions were created and %d exclusions were deleted", + allGraphPlayers.size(), createCounter, delCounter)); + StringBuilder sb = new StringBuilder(); + for (BSPlayer player : subGraphPlayers) { + sb.append(player.getName()); + sb.append(":"); + sb.append(player.getUUID()); + sb.append(" "); + } + sender.sendMessage(ChatColor.GREEN + + String.format("First group created contains %d players: %s", subGraphPlayers.size(), sb.toString())); - sb = new StringBuilder(); - for (BSPlayer player : outsideSubGraphPlayers) { - sb.append(player.getName()); - sb.append(":"); - sb.append(player.getUUID()); - sb.append(" "); - } - sender.sendMessage(ChatColor.GREEN + String.format("Second group created contains %d players: %s", - outsideSubGraphPlayers.size(), sb.toString())); - return true; - } + sb = new StringBuilder(); + for (BSPlayer player : outsideSubGraphPlayers) { + sb.append(player.getName()); + sb.append(":"); + sb.append(player.getUUID()); + sb.append(" "); + } + sender.sendMessage(ChatColor.GREEN + String.format("Second group created contains %d players: %s", + outsideSubGraphPlayers.size(), sb.toString())); + return true; + } - /** - * Given a string, determine if name or uuid, and return uuid that relates. - * - * @param input a string - * @return a UUID that matches, or null if no match. - */ - public static UUID resolveName(String input) { - if (input.length() <= 16) { - // interpret as player name - try { - return NameAPI.getUUID(input); - } catch (NoClassDefFoundError ncde) { - } - Player match = Bukkit.getPlayer(input); - if (match != null) { - return match.getUniqueId(); - } else { - @SuppressWarnings("deprecation") - OfflinePlayer offPlay = Bukkit.getOfflinePlayer(input); - if (offPlay != null) { - return offPlay.getUniqueId(); - } - } - } else if (input.length() == 36) { - try { - return UUID.fromString(input); - } catch (IllegalArgumentException iae) { - return null; - } - } - return null; - } + /** + * Given a string, determine if name or uuid, and return uuid that relates. + * + * @param input a string + * @return a UUID that matches, or null if no match. + */ + public static UUID resolveName(String input) { + if (input.length() <= 16) { + // interpret as player name + try { + return NameAPI.getUUID(input); + } catch (NoClassDefFoundError ncde) { + } + Player match = Bukkit.getPlayer(input); + if (match != null) { + return match.getUniqueId(); + } else { + @SuppressWarnings("deprecation") + OfflinePlayer offPlay = Bukkit.getOfflinePlayer(input); + if (offPlay != null) { + return offPlay.getUniqueId(); + } + } + } else if (input.length() == 36) { + try { + return UUID.fromString(input); + } catch (IllegalArgumentException iae) { + return null; + } + } + return null; + } } diff --git a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/commands/package-info.java b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/commands/package-info.java index fcd987fc3..f746d0d38 100644 --- a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/commands/package-info.java +++ b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/commands/package-info.java @@ -1,7 +1,6 @@ /** * All the commands! - * - * @author ProgrammerDan * + * @author ProgrammerDan */ package com.programmerdan.minecraft.banstick.commands; diff --git a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/containers/BanResult.java b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/containers/BanResult.java index b55ce9902..797711ff5 100644 --- a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/containers/BanResult.java +++ b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/containers/BanResult.java @@ -13,75 +13,76 @@ import org.bukkit.command.CommandSender; /** * Used to store bans issued and then transmit the results to various parties. * Basically a logic wrapper. - * - * @author ProgrammerDan * + * @author ProgrammerDan */ public class BanResult { - private Set playerBans; - private Set bans; - - public BanResult() { - playerBans = new HashSet<>(); - bans = new HashSet<>(); - } - - public static SimpleDateFormat getUsualDateTime() { - return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - } - /** - * Let the command sender know the result of the ban(s) and player(s). - * @param sender the sender of commands. - */ - public void informCommandSender(CommandSender sender) { - if (bans.isEmpty() && playerBans.isEmpty()) { - sender.sendMessage("No bans issued."); - } - StringBuilder sb = new StringBuilder(); - if (playerBans.size() > 1) { - sb.append(playerBans.size()).append(" player bans issued.\n"); - } - for (BSPlayer banned : playerBans) { - BSBan ban = banned.getBan(); - sb.append(" Banned ").append(banned.getName()).append(" for ").append(ban.getMessage()); - if (ban.getBanEndTime() != null) { - sb.append(" until ").append(getUsualDateTime().format(ban.getBanEndTime())).append("\n"); - } else { - sb.append(" forever\n"); - } - } - if (bans.size() > 1) { - sb.append(bans.size()).append(" other bans issued.\n"); - } - for (BSBan banned : bans) { - sb.append(" Banned "); - BSIP bip = banned.getIPBan(); - if (bip != null) { - sb.append(" IP ").append(bip.toFullString(sender.hasPermission("banstick.ips"))); - } - BSIPData vip = banned.getProxyBan(); - if (vip != null) { - sb.append(" VPN ").append(vip.toFullString(sender.hasPermission("banstick.ips"))); - } - BSShare sid = banned.getShareBan(); - if (sid != null) { - sb.append(" Share ").append(sid.toFullString(sender.hasPermission("banstick.ips"))); - } - if (banned.getBanEndTime() != null) { - sb.append(" until ").append(getUsualDateTime().format(banned.getBanEndTime())).append("\n"); - } else { - sb.append(" forever\n"); - } - } - sender.sendMessage(sb.toString()); - } + private Set playerBans; + private Set bans; - public void addPlayer(BSPlayer player) { - playerBans.add(player); - } - - public void addBan(BSBan ban) { - bans.add(ban); - } + public BanResult() { + playerBans = new HashSet<>(); + bans = new HashSet<>(); + } + + public static SimpleDateFormat getUsualDateTime() { + return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + } + + /** + * Let the command sender know the result of the ban(s) and player(s). + * + * @param sender the sender of commands. + */ + public void informCommandSender(CommandSender sender) { + if (bans.isEmpty() && playerBans.isEmpty()) { + sender.sendMessage("No bans issued."); + } + StringBuilder sb = new StringBuilder(); + if (playerBans.size() > 1) { + sb.append(playerBans.size()).append(" player bans issued.\n"); + } + for (BSPlayer banned : playerBans) { + BSBan ban = banned.getBan(); + sb.append(" Banned ").append(banned.getName()).append(" for ").append(ban.getMessage()); + if (ban.getBanEndTime() != null) { + sb.append(" until ").append(getUsualDateTime().format(ban.getBanEndTime())).append("\n"); + } else { + sb.append(" forever\n"); + } + } + if (bans.size() > 1) { + sb.append(bans.size()).append(" other bans issued.\n"); + } + for (BSBan banned : bans) { + sb.append(" Banned "); + BSIP bip = banned.getIPBan(); + if (bip != null) { + sb.append(" IP ").append(bip.toFullString(sender.hasPermission("banstick.ips"))); + } + BSIPData vip = banned.getProxyBan(); + if (vip != null) { + sb.append(" VPN ").append(vip.toFullString(sender.hasPermission("banstick.ips"))); + } + BSShare sid = banned.getShareBan(); + if (sid != null) { + sb.append(" Share ").append(sid.toFullString(sender.hasPermission("banstick.ips"))); + } + if (banned.getBanEndTime() != null) { + sb.append(" until ").append(getUsualDateTime().format(banned.getBanEndTime())).append("\n"); + } else { + sb.append(" forever\n"); + } + } + sender.sendMessage(sb.toString()); + } + + public void addPlayer(BSPlayer player) { + playerBans.add(player); + } + + public void addBan(BSBan ban) { + bans.add(ban); + } } diff --git a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/containers/package-info.java b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/containers/package-info.java index c535d3a27..aa8bd60f5 100644 --- a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/containers/package-info.java +++ b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/containers/package-info.java @@ -1,7 +1,6 @@ /** * Handles containment of results or other things. - * - * @author ProgrammerDan * + * @author ProgrammerDan */ package com.programmerdan.minecraft.banstick.containers; diff --git a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/data/BSBan.java b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/data/BSBan.java index 6edc3529e..35068da33 100644 --- a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/data/BSBan.java +++ b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/data/BSBan.java @@ -22,741 +22,742 @@ import javax.annotation.Nonnull; /** * BSBan object, wraps an actual ban. * Might link with an IP, Proxy, or Share. - * + * * @author ProgrammerDan * Email: programmerdan@gmail.com - * */ public final class BSBan { - private static final String NO_BID_RETURNED = "No BID returned on ban insert?!"; - private static Map allBanID = new HashMap(); - private static ConcurrentLinkedQueue> dirtyBans = - new ConcurrentLinkedQueue>(); - private boolean dirty; + private static final String NO_BID_RETURNED = "No BID returned on ban insert?!"; + private static Map allBanID = new HashMap(); + private static ConcurrentLinkedQueue> dirtyBans = + new ConcurrentLinkedQueue>(); + private boolean dirty; - private long bid; - private Timestamp banTime; - private Long deferIpBan; - private BSIP ipBan; - private Long deferProxyBan; - private BSIPData proxyBan; - private Long deferShareBan; - private BSShare shareBan; - private boolean isAdminBan; - private String message; //mutable - private Timestamp banEnd; //mutable + private long bid; + private Timestamp banTime; + private Long deferIpBan; + private BSIP ipBan; + private Long deferProxyBan; + private BSIPData proxyBan; + private Long deferShareBan; + private BSShare shareBan; + private boolean isAdminBan; + private String message; //mutable + private Timestamp banEnd; //mutable - private BSBan() { } - - public long getId() { - return this.bid; - } + private BSBan() { + } - public Date getBanTime() { - return banTime; - } - - /** - * Gets the IP Ban component of this ban, if set. - * - * @return IP of this ban, null if not set. - */ - public BSIP getIPBan() { - if (ipBan == null && deferIpBan != null) { - ipBan = BSIP.byId(deferIpBan); - } - return ipBan; - } - - /** - * Gets the Proxy (gateway / tor / similar) of this ban, if set. - * - * @return IP Data (Proxy) of this ban, null if not set. - */ - public BSIPData getProxyBan() { - if (proxyBan == null && deferProxyBan != null) { - proxyBan = BSIPData.byId(deferProxyBan); - } - return proxyBan; - } - - /** - * Gets the Share of this ban, if set. - * - * @return Share for this ban, null if not set. - */ - public BSShare getShareBan() { - if (shareBan == null && deferShareBan != null) { - shareBan = BSShare.byId(deferShareBan); - } - return shareBan; - } - - /** - * Returns the message on this ban. - * - * @return the message, null if none set. - */ - public String getMessage() { - return message; - } - - /** - * Sets the message for this ban. Marks this ban as dirty (for commit). - * - * @param message Ban message. - */ - public void setMessage(String message) { - this.message = message; - this.dirty = true; - dirtyBans.offer(new WeakReference(this)); - } + public long getId() { + return this.bid; + } - /** - * @return Returns true if this ban's expiry date has passed based on the current time. - */ - public boolean hasBanExpired() { - return this.banEnd != null && this.banEnd.before(new Date()); - } + public Date getBanTime() { + return banTime; + } - /** - * Gets the end time of this ban, if any. - * @return ban time, null if none set. - */ - public Date getBanEndTime() { - return banEnd; - } + /** + * Gets the IP Ban component of this ban, if set. + * + * @return IP of this ban, null if not set. + */ + public BSIP getIPBan() { + if (ipBan == null && deferIpBan != null) { + ipBan = BSIP.byId(deferIpBan); + } + return ipBan; + } - /** - * Unsafe to use setBanEndTime(null), use this instead, to clear the - * ban end (make it endless). - * - */ - public void clearBanEndTime() { - this.banEnd = null; - this.dirty = true; - dirtyBans.offer(new WeakReference(this)); - } - - /** - * Sets the ban end time from a normal Java Date. - * - * @param banEndTo the time to end the ban. - */ - public void setBanEndTime(@Nonnull Date banEndTo) { - setBanEndTime(new Timestamp(banEndTo.getTime())); - } - - /** - * Sets the ban end time from a SQL Timestamp. - * - * @param banEndTo the time to end the ban. - */ - public void setBanEndTime(@Nonnull Timestamp banEndTo) { - this.banEnd = banEndTo; - this.dirty = true; - dirtyBans.offer(new WeakReference(this)); - } - - /** - * Returns if this is an admin triggered ban or not (automatic or not, basically). - * @return true if admin ban. - */ - public boolean isAdminBan() { - return isAdminBan; - } - - /** - * Sets if this is an admin triggered ban or not. - * - * @param adminBan value to set to. - */ - public void setAdminBan(boolean adminBan) { - this.isAdminBan = adminBan; - } - - /** - * This leverages a fun queue of WeakReferences, where if a player is forcibly flush()'d we don't care, - * or if a player is in the queue more then once we don't care, b/c we only save a dirty player once; - * and since we all store references and no copies, everything is nice and synchronized. - */ - public static void saveDirty() { - int batchSize = 0; - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); - PreparedStatement save = connection.prepareStatement( - "UPDATE bs_ban SET admin_ban = ?, message = ?, ban_end = ? WHERE bid = ?");) { - while (!dirtyBans.isEmpty()) { - WeakReference rban = dirtyBans.poll(); - BSBan ban = rban.get(); - if (ban != null && ban.dirty) { - ban.dirty = false; - ban.saveToStatement(save); - save.addBatch(); - batchSize ++; - } - if (batchSize > 0 && batchSize % 100 == 0) { - int[] batchRun = save.executeBatch(); - if (batchRun.length != batchSize) { - BanStick.getPlugin().severe("Some elements of the dirty batch didn't save? " - + batchSize + " vs " + batchRun.length); - } else { - BanStick.getPlugin().debug("Ban batch: {0} saves", batchRun.length); - } - batchSize = 0; - } - } - if (batchSize > 0 && batchSize % 100 > 0) { - int[] batchRun = save.executeBatch(); - if (batchRun.length != batchSize) { - BanStick.getPlugin().severe("Some elements of the dirty batch didn't save? " - + batchSize + " vs " + batchRun.length); - } else { - BanStick.getPlugin().debug("Ban batch: {0} saves", batchRun.length); - } - } - } catch (SQLException se) { - BanStick.getPlugin().severe("Save of BSBan dirty batch failed!: ", se); - } - } - - /** - * Saves the BSBan; only for internal use. Outside code must use Flush(); - */ - private void save() { - if (!dirty) { - return; - } - this.dirty = false; // don't let anyone else in! - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); - PreparedStatement save = connection.prepareStatement( - "UPDATE bs_ban SET admin_ban = ?, message = ?, ban_end = ? WHERE bid = ?");) { - saveToStatement(save); - int effects = save.executeUpdate(); - if (effects == 0) { - BanStick.getPlugin().severe("Failed to save BSBan or no update? " + this.bid); - } - } catch (SQLException se) { - BanStick.getPlugin().severe("Save of BSBan failed!: ", se); - } - } - - /** - * Given a prepared statement, writes the ban values to it. Internal use only. - */ - private void saveToStatement(PreparedStatement save) throws SQLException { - save.setBoolean(1, this.isAdminBan); - save.setString(2, this.message); - if (this.banEnd == null) { - save.setNull(3, Types.TIMESTAMP); - } else { - save.setTimestamp(3, this.banEnd); - } - save.setLong(4, this.bid); - } - - /** - * Cleanly saves this ban if necessary, and removes it from the references lists. - */ - public void flush() { - if (dirty) { - save(); - } - allBanID.remove(this.bid); - this.deferIpBan = null; - this.ipBan = null; - this.deferProxyBan = null; - this.proxyBan = null; - this.deferShareBan = null; - this.shareBan = null; - } - - /** - * Retrieves a ban using ban id. Attempts to pull from cache first, then from database if not in cache. - * Puts in cache if retrieved successfully. - * - * @param bid the Ban to retrieve, by ID. - * @return BSBan from bid if found, otherwise null. - */ - public static BSBan byId(long bid) { - if (allBanID.containsKey(bid)) { - return allBanID.get(bid); - } - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); - PreparedStatement getId = connection.prepareStatement( - "SELECT * FROM bs_ban WHERE bid = ?");) { - getId.setLong(1, bid); - try (ResultSet rs = getId.executeQuery();) { - if (rs.next()) { - BSBan ban = extractBan(rs); - allBanID.put(bid, ban); - return ban; - } else { - BanStick.getPlugin().warning("Failed to retrieve Ban by id: " + bid + " - not found"); - } - } - } catch (SQLException se) { - BanStick.getPlugin().severe("Retrieval of ban by ID failed: " + bid, se); - } - return null; - } + /** + * Gets the Proxy (gateway / tor / similar) of this ban, if set. + * + * @return IP Data (Proxy) of this ban, null if not set. + */ + public BSIPData getProxyBan() { + if (proxyBan == null && deferProxyBan != null) { + proxyBan = BSIPData.byId(deferProxyBan); + } + return proxyBan; + } - /** - * Attempts to find bans for a given IP address (as per a BSIP) - * - * @param exactIP The IP to match - * @param includeExpired true to include expired - * @return a List of BSBans. List is empty if none are found. - */ - public static List byIP(BSIP exactIP, boolean includeExpired) { - List results = new ArrayList<>(); - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); - PreparedStatement findBans = connection.prepareStatement( - includeExpired ? "SELECT * FROM bs_ban WHERE ip_ban = ? ORDER BY ban_time" : - "SELECT * FROM bs_ban WHERE ip_ban = ? AND (ban_end IS NULL OR ban_end >= CURRENT_TIMESTAMP) ORDER BY ban_time");) { - findBans.setLong(1, exactIP.getId()); - try (ResultSet rs = findBans.executeQuery()) { - while (rs.next()) { - BSBan ban = extractBan(rs); - if (allBanID.containsKey(ban.bid)) { - results.add(allBanID.get(ban.bid)); - } else { - results.add(ban); - allBanID.put(ban.bid, ban); - } - } - } - } catch (SQLException se) { - BanStick.getPlugin().severe("Failed to lookup bans by IP: " + exactIP, se); - } - return results; - } + /** + * Gets the Share of this ban, if set. + * + * @return Share for this ban, null if not set. + */ + public BSShare getShareBan() { + if (shareBan == null && deferShareBan != null) { + shareBan = BSShare.byId(deferShareBan); + } + return shareBan; + } - /** - * Attempts to find bans for a given proxy (as per BSIPData) - * - * @param data the Proxy to match - * @param includeExpired true to include expired - * @return a List of BSBans. List is empty if none are found. - */ - public static List byProxy(BSIPData data, boolean includeExpired) { - List results = new ArrayList<>(); - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); - PreparedStatement findBans = connection.prepareStatement( - includeExpired ? "SELECT * FROM bs_ban WHERE proxy_ban = ? ORDER BY ban_time" : - "SELECT * FROM bs_ban WHERE proxy_ban = ? AND (ban_end IS NULL OR ban_end >= CURRENT_TIMESTAMP) ORDER BY ban_time");) { - findBans.setLong(1, data.getId()); - try (ResultSet rs = findBans.executeQuery()) { - while (rs.next()) { - BSBan ban = extractBan(rs); - if (allBanID.containsKey(ban.bid)) { - results.add(allBanID.get(ban.bid)); - } else { - results.add(ban); - allBanID.put(ban.bid, ban); - } - } - } - } catch (SQLException se) { - BanStick.getPlugin().severe("Failed to lookup bans by IP Data: " + data, se); - } - return results; - } + /** + * Returns the message on this ban. + * + * @return the message, null if none set. + */ + public String getMessage() { + return message; + } - /** - * Attempts to find bans for a given share (as per BSShare) - * - * @param data the Share to match - * @param includeExpired true to include expired - * @return a List of BSBans. List is empty if none are found. - */ - public static List byShare(BSShare data, boolean includeExpired) { - List results = new ArrayList<>(); - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); - PreparedStatement findBans = connection.prepareStatement( - includeExpired ? "SELECT * FROM bs_ban WHERE share_ban = ? ORDER BY ban_time" : - "SELECT * FROM bs_ban WHERE share_ban = ? AND (ban_end IS NULL OR ban_end >= CURRENT_TIMESTAMP) ORDER BY ban_time");) { - findBans.setLong(1, data.getId()); - try (ResultSet rs = findBans.executeQuery()) { - while (rs.next()) { - BSBan ban = extractBan(rs); - if (allBanID.containsKey(ban.bid)) { - results.add(allBanID.get(ban.bid)); - } else { - results.add(ban); - allBanID.put(ban.bid, ban); - } - } - } - } catch (SQLException se) { - BanStick.getPlugin().severe("Failed to lookup bans by Share: " + data, se); - } - return results; - } - - /** - * Creates a new ban with optional message, end date, and admin ban indicator. - * - * @param message the ban message - * @param banEnd end of ban, or null - * @param adminBan true for admin ban - * @return the newly created ban, or null if something went wrong. - */ - public static BSBan create(String message, Date banEnd, boolean adminBan) { - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection()) { - BSBan newBan = new BSBan(); - newBan.dirty = false; - newBan.banTime = new Timestamp(Calendar.getInstance().getTimeInMillis()); - newBan.banEnd = banEnd != null ? new Timestamp(banEnd.getTime()) : null; - newBan.message = message; - newBan.isAdminBan = adminBan; - - try (PreparedStatement insertBan = connection.prepareStatement( - "INSERT INTO bs_ban(ban_time, message, ban_end, admin_ban) VALUES (?, ?, ?, ?);", - Statement.RETURN_GENERATED_KEYS)) { - insertBan.setTimestamp(1, newBan.banTime); - if (newBan.message != null) { - insertBan.setString(2, newBan.message); - } else { - insertBan.setNull(2, Types.VARCHAR); - } - if (newBan.banEnd != null) { - insertBan.setTimestamp(3, newBan.banEnd); - } else { - insertBan.setNull(3, Types.TIMESTAMP); - } - insertBan.setBoolean(4, adminBan); - insertBan.execute(); - try (ResultSet rs = insertBan.getGeneratedKeys()) { - if (rs.next()) { - newBan.bid = rs.getLong(1); - } else { - BanStick.getPlugin().severe(NO_BID_RETURNED); - return null; // no bid? error. - } - } - } - - allBanID.put(newBan.bid, newBan); - return newBan; - } catch (SQLException se) { - BanStick.getPlugin().severe("Failed to create a new ban record: ", se); - } - return null; - } - - /** - * Creates a new Ban for a specific IP address. - * @param exactIP the already-created BSIP object to ban. - * @param message the ban message, if provided - * @param banEnd the end time for the ban, if provided - * @param adminBan true if this is an admin ban - * @return the new BSBan, or null if creation failed. - */ - public static BSBan create(BSIP exactIP, String message, Date banEnd, boolean adminBan) { - // TODO: Check if this IP is already actively banned! - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection()) { - BSBan newBan = new BSBan(); - newBan.dirty = false; - newBan.deferIpBan = exactIP.getId(); - newBan.ipBan = exactIP; - newBan.banTime = new Timestamp(Calendar.getInstance().getTimeInMillis()); - newBan.banEnd = banEnd != null ? new Timestamp(banEnd.getTime()) : null; - newBan.message = message; - newBan.isAdminBan = adminBan; - - try (PreparedStatement insertBan = connection.prepareStatement( - "INSERT INTO bs_ban(ban_time, message, ban_end, admin_ban, ip_ban) VALUES (?, ?, ?, ?, ?);", - Statement.RETURN_GENERATED_KEYS)) { - insertBan.setTimestamp(1, newBan.banTime); - if (newBan.message != null) { - insertBan.setString(2, newBan.message); - } else { - insertBan.setNull(2, Types.VARCHAR); - } - if (newBan.banEnd != null) { - insertBan.setTimestamp(3, newBan.banEnd); - } else { - insertBan.setNull(3, Types.TIMESTAMP); - } - insertBan.setBoolean(4, adminBan); - insertBan.setLong(5, newBan.ipBan.getId()); - insertBan.execute(); - try (ResultSet rs = insertBan.getGeneratedKeys()) { - if (rs.next()) { - newBan.bid = rs.getLong(1); - } else { - BanStick.getPlugin().severe(NO_BID_RETURNED); - return null; // no bid? error. - } - } - } - - allBanID.put(newBan.bid, newBan); - return newBan; - } catch (SQLException se) { - BanStick.getPlugin().severe("Failed to create a new ip ban record: ", se); - } - return null; - } + /** + * Sets the message for this ban. Marks this ban as dirty (for commit). + * + * @param message Ban message. + */ + public void setMessage(String message) { + this.message = message; + this.dirty = true; + dirtyBans.offer(new WeakReference(this)); + } - /** - * Creates a new Ban for a given Proxy. - * - * @param proxy The Proxy to ban. - * @param message The message to use, if any - * @param banEnd The end of the ban, if any. - * @param adminBan Set to true for an admin ban. - * @return the new BSBan or null if create fails. - */ - public static BSBan create(BSIPData proxy, String message, Date banEnd, boolean adminBan) { - // TODO: Check if this IP is already actively banned! - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection()) { - BSBan newBan = new BSBan(); - newBan.dirty = false; - newBan.deferProxyBan = proxy.getId(); - newBan.proxyBan = proxy; - newBan.banTime = new Timestamp(Calendar.getInstance().getTimeInMillis()); - newBan.banEnd = banEnd != null ? new Timestamp(banEnd.getTime()) : null; - newBan.message = message; - newBan.isAdminBan = adminBan; - - try (PreparedStatement insertBan = connection.prepareStatement( - "INSERT INTO bs_ban(ban_time, message, ban_end, admin_ban, proxy_ban) VALUES (?, ?, ?, ?, ?);", - Statement.RETURN_GENERATED_KEYS)) { - insertBan.setTimestamp(1, newBan.banTime); - if (newBan.message != null) { - insertBan.setString(2, newBan.message); - } else { - insertBan.setNull(2, Types.VARCHAR); - } - if (newBan.banEnd != null) { - insertBan.setTimestamp(3, newBan.banEnd); - } else { - insertBan.setNull(3, Types.TIMESTAMP); - } - insertBan.setBoolean(4, adminBan); - insertBan.setLong(5, newBan.proxyBan.getId()); - insertBan.execute(); - try (ResultSet rs = insertBan.getGeneratedKeys()) { - if (rs.next()) { - newBan.bid = rs.getLong(1); - } else { - BanStick.getPlugin().severe(NO_BID_RETURNED); - return null; // no bid? error. - } - } - } - - allBanID.put(newBan.bid, newBan); - return newBan; - } catch (SQLException se) { - BanStick.getPlugin().severe("Failed to create a new proxy ban record: ", se); - } - return null; - } - - /** - * Create a new ban based on this specific Share. - * - * @param share The share to ban. - * @param message The message to use, if any. - * @param banEnd The end of the ban, if any - * @param adminBan True if the ban is admin. - * @return the new ban, or null if something went wrong. - */ - public static BSBan create(BSShare share, String message, Date banEnd, boolean adminBan) { - // TODO: Check if this share is already actively banned! - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection()) { - BSBan newBan = new BSBan(); - newBan.dirty = false; - newBan.deferShareBan = share.getId(); - newBan.shareBan = share; - newBan.banTime = new Timestamp(Calendar.getInstance().getTimeInMillis()); - newBan.banEnd = banEnd != null ? new Timestamp(banEnd.getTime()) : null; - newBan.message = message; - newBan.isAdminBan = adminBan; - - try (PreparedStatement insertBan = connection.prepareStatement( - "INSERT INTO bs_ban(ban_time, message, ban_end, admin_ban, share_ban) VALUES (?, ?, ?, ?, ?);", - Statement.RETURN_GENERATED_KEYS)) { - insertBan.setTimestamp(1, newBan.banTime); - if (newBan.message != null) { - insertBan.setString(2, newBan.message); - } else { - insertBan.setNull(2, Types.VARCHAR); - } - if (newBan.banEnd != null) { - insertBan.setTimestamp(3, newBan.banEnd); - } else { - insertBan.setNull(3, Types.TIMESTAMP); - } - insertBan.setBoolean(4, adminBan); - insertBan.setLong(5, newBan.shareBan.getId()); - insertBan.execute(); - try (ResultSet rs = insertBan.getGeneratedKeys()) { - if (rs.next()) { - newBan.bid = rs.getLong(1); - } else { - BanStick.getPlugin().severe(NO_BID_RETURNED); - return null; // no bid? error. - } - } - } - - allBanID.put(newBan.bid, newBan); - return newBan; - } catch (SQLException se) { - BanStick.getPlugin().severe("Failed to create a new share ban record: ", se); - } - return null; - } - - /** - * Given a result set, extract a BSBan object and return it. Internal use. - * - * @param rs The ResultSet object. - * @return the new ban to return. - * - * @throws SQLException if something goes wrong with the SQL. - */ - private static BSBan extractBan(ResultSet rs) throws SQLException { - BSBan newBan = new BSBan(); - newBan.bid = rs.getLong(1); - newBan.banTime = rs.getTimestamp(2); - long iid = rs.getLong(3); - if (!rs.wasNull()) { - newBan.deferIpBan = iid; - } - long vid = rs.getLong(4); - if (!rs.wasNull()) { - newBan.deferProxyBan = vid; - } - long sid = rs.getLong(5); - if (!rs.wasNull()) { - newBan.deferShareBan = sid; - } - newBan.isAdminBan = rs.getBoolean(6); - newBan.message = rs.getString(7); - try { - newBan.banEnd = rs.getTimestamp(8); - } catch (SQLException se) { - newBan.banEnd = null; - } - newBan.dirty = false; - return newBan; - } - - /** - * Preloads a segment of ban data. Depending on parameters, loads only active bans or loads all bans. - * - * @param offset Offset to begin at - * @param limit How many to load - * @param includeExpired Include old (expired) bans or no - * @return last ID encountered, or -1 if none. - */ - public static long preload(long offset, int limit, boolean includeExpired) { - long maxId = -1; - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); - PreparedStatement loadBans = connection.prepareStatement( - includeExpired ? "SELECT * FROM bs_ban WHERE bid > ? ORDER BY bid LIMIT ?" : - "SELECT * FROM bs_ban WHERE bid > ? AND (ban_end IS NULL OR ban_end >= CURRENT_TIMESTAMP ) ORDER BY bid LIMIT ? ");) { - loadBans.setLong(1, offset); - loadBans.setInt(2, limit); - try (ResultSet rs = loadBans.executeQuery()) { - while (rs.next()) { - BSBan ban = extractBan(rs); - if (!allBanID.containsKey(ban.bid)) { - allBanID.put(ban.bid, ban); - } - if (ban.bid > maxId) { - maxId = ban.bid; - } - } - } - } catch (SQLException se) { - BanStick.getPlugin().severe("Failed during Ban preload, offset " + offset - + " limit " + limit, se); - } - return maxId; - } - - @Override - public String toString() { - StringBuffer sb = new StringBuffer(); - if (getIPBan() != null) { - sb.append("IP Ban: ").append(ipBan.toString()); - } else if (getProxyBan() != null) { - sb.append("Proxy Ban: ").append(proxyBan.toString()); - } else if (getShareBan() != null) { - sb.append("Share Ban: ").append(shareBan.toString()); - } else { - sb.append("Player Ban"); - } - - if (isAdminBan()) { - sb.append(" (administrative)"); - } - - if (getBanEndTime() != null) { - if ((new Date()).after(getBanEndTime())) { // passed - sb.append(" - Expired"); - } else { - sb.append(" - Until ").append(getBanEndTime()); - } - } else { - sb.append(" - Forever"); - } - - sb.append(" with message \"").append(message).append("\""); - return sb.toString(); - } - - /** - * Custom toString including full details. - * - * @param showIPs True to include IP addresses - * @return a String - */ - public String toFullString(boolean showIPs) { - StringBuilder sb = new StringBuilder(); - if (showIPs) { - if (getIPBan() != null) { - sb.append("IP Ban: ").append(ipBan.toString()); - } else if (getProxyBan() != null) { - sb.append("Proxy Ban: ").append(proxyBan.toString()); - } else if (getShareBan() != null) { - sb.append("Share Ban: ").append(shareBan.toString()); - } else { - sb.append("Player Ban"); - } - } else { - if (getIPBan() != null) { - sb.append("IP Ban: ").append(ipBan.getId()); - } else if (getProxyBan() != null) { - sb.append("Proxy Ban: ").append(proxyBan.getId()); - } else if (getShareBan() != null) { - sb.append("Share Ban: ").append(shareBan.toFullString(showIPs)); - } else { - sb.append("Player Ban"); - } - } - - if (isAdminBan()) { - sb.append(" (administrative)"); - } - - if (getBanEndTime() != null) { - if ((new Date()).after(getBanEndTime())) { // passed - sb.append(" - Expired"); - } else { - sb.append(" - Until ").append(getBanEndTime()); - } - } else { - sb.append(" - Forever"); - } - - sb.append(" with message \"").append(message).append("\""); - return sb.toString(); - } + /** + * @return Returns true if this ban's expiry date has passed based on the current time. + */ + public boolean hasBanExpired() { + return this.banEnd != null && this.banEnd.before(new Date()); + } + + /** + * Gets the end time of this ban, if any. + * + * @return ban time, null if none set. + */ + public Date getBanEndTime() { + return banEnd; + } + + /** + * Unsafe to use setBanEndTime(null), use this instead, to clear the + * ban end (make it endless). + */ + public void clearBanEndTime() { + this.banEnd = null; + this.dirty = true; + dirtyBans.offer(new WeakReference(this)); + } + + /** + * Sets the ban end time from a normal Java Date. + * + * @param banEndTo the time to end the ban. + */ + public void setBanEndTime(@Nonnull Date banEndTo) { + setBanEndTime(new Timestamp(banEndTo.getTime())); + } + + /** + * Sets the ban end time from a SQL Timestamp. + * + * @param banEndTo the time to end the ban. + */ + public void setBanEndTime(@Nonnull Timestamp banEndTo) { + this.banEnd = banEndTo; + this.dirty = true; + dirtyBans.offer(new WeakReference(this)); + } + + /** + * Returns if this is an admin triggered ban or not (automatic or not, basically). + * + * @return true if admin ban. + */ + public boolean isAdminBan() { + return isAdminBan; + } + + /** + * Sets if this is an admin triggered ban or not. + * + * @param adminBan value to set to. + */ + public void setAdminBan(boolean adminBan) { + this.isAdminBan = adminBan; + } + + /** + * This leverages a fun queue of WeakReferences, where if a player is forcibly flush()'d we don't care, + * or if a player is in the queue more then once we don't care, b/c we only save a dirty player once; + * and since we all store references and no copies, everything is nice and synchronized. + */ + public static void saveDirty() { + int batchSize = 0; + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); + PreparedStatement save = connection.prepareStatement( + "UPDATE bs_ban SET admin_ban = ?, message = ?, ban_end = ? WHERE bid = ?");) { + while (!dirtyBans.isEmpty()) { + WeakReference rban = dirtyBans.poll(); + BSBan ban = rban.get(); + if (ban != null && ban.dirty) { + ban.dirty = false; + ban.saveToStatement(save); + save.addBatch(); + batchSize++; + } + if (batchSize > 0 && batchSize % 100 == 0) { + int[] batchRun = save.executeBatch(); + if (batchRun.length != batchSize) { + BanStick.getPlugin().severe("Some elements of the dirty batch didn't save? " + + batchSize + " vs " + batchRun.length); + } else { + BanStick.getPlugin().debug("Ban batch: {0} saves", batchRun.length); + } + batchSize = 0; + } + } + if (batchSize > 0 && batchSize % 100 > 0) { + int[] batchRun = save.executeBatch(); + if (batchRun.length != batchSize) { + BanStick.getPlugin().severe("Some elements of the dirty batch didn't save? " + + batchSize + " vs " + batchRun.length); + } else { + BanStick.getPlugin().debug("Ban batch: {0} saves", batchRun.length); + } + } + } catch (SQLException se) { + BanStick.getPlugin().severe("Save of BSBan dirty batch failed!: ", se); + } + } + + /** + * Saves the BSBan; only for internal use. Outside code must use Flush(); + */ + private void save() { + if (!dirty) { + return; + } + this.dirty = false; // don't let anyone else in! + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); + PreparedStatement save = connection.prepareStatement( + "UPDATE bs_ban SET admin_ban = ?, message = ?, ban_end = ? WHERE bid = ?");) { + saveToStatement(save); + int effects = save.executeUpdate(); + if (effects == 0) { + BanStick.getPlugin().severe("Failed to save BSBan or no update? " + this.bid); + } + } catch (SQLException se) { + BanStick.getPlugin().severe("Save of BSBan failed!: ", se); + } + } + + /** + * Given a prepared statement, writes the ban values to it. Internal use only. + */ + private void saveToStatement(PreparedStatement save) throws SQLException { + save.setBoolean(1, this.isAdminBan); + save.setString(2, this.message); + if (this.banEnd == null) { + save.setNull(3, Types.TIMESTAMP); + } else { + save.setTimestamp(3, this.banEnd); + } + save.setLong(4, this.bid); + } + + /** + * Cleanly saves this ban if necessary, and removes it from the references lists. + */ + public void flush() { + if (dirty) { + save(); + } + allBanID.remove(this.bid); + this.deferIpBan = null; + this.ipBan = null; + this.deferProxyBan = null; + this.proxyBan = null; + this.deferShareBan = null; + this.shareBan = null; + } + + /** + * Retrieves a ban using ban id. Attempts to pull from cache first, then from database if not in cache. + * Puts in cache if retrieved successfully. + * + * @param bid the Ban to retrieve, by ID. + * @return BSBan from bid if found, otherwise null. + */ + public static BSBan byId(long bid) { + if (allBanID.containsKey(bid)) { + return allBanID.get(bid); + } + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); + PreparedStatement getId = connection.prepareStatement( + "SELECT * FROM bs_ban WHERE bid = ?");) { + getId.setLong(1, bid); + try (ResultSet rs = getId.executeQuery();) { + if (rs.next()) { + BSBan ban = extractBan(rs); + allBanID.put(bid, ban); + return ban; + } else { + BanStick.getPlugin().warning("Failed to retrieve Ban by id: " + bid + " - not found"); + } + } + } catch (SQLException se) { + BanStick.getPlugin().severe("Retrieval of ban by ID failed: " + bid, se); + } + return null; + } + + /** + * Attempts to find bans for a given IP address (as per a BSIP) + * + * @param exactIP The IP to match + * @param includeExpired true to include expired + * @return a List of BSBans. List is empty if none are found. + */ + public static List byIP(BSIP exactIP, boolean includeExpired) { + List results = new ArrayList<>(); + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); + PreparedStatement findBans = connection.prepareStatement( + includeExpired ? "SELECT * FROM bs_ban WHERE ip_ban = ? ORDER BY ban_time" : + "SELECT * FROM bs_ban WHERE ip_ban = ? AND (ban_end IS NULL OR ban_end >= CURRENT_TIMESTAMP) ORDER BY ban_time");) { + findBans.setLong(1, exactIP.getId()); + try (ResultSet rs = findBans.executeQuery()) { + while (rs.next()) { + BSBan ban = extractBan(rs); + if (allBanID.containsKey(ban.bid)) { + results.add(allBanID.get(ban.bid)); + } else { + results.add(ban); + allBanID.put(ban.bid, ban); + } + } + } + } catch (SQLException se) { + BanStick.getPlugin().severe("Failed to lookup bans by IP: " + exactIP, se); + } + return results; + } + + /** + * Attempts to find bans for a given proxy (as per BSIPData) + * + * @param data the Proxy to match + * @param includeExpired true to include expired + * @return a List of BSBans. List is empty if none are found. + */ + public static List byProxy(BSIPData data, boolean includeExpired) { + List results = new ArrayList<>(); + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); + PreparedStatement findBans = connection.prepareStatement( + includeExpired ? "SELECT * FROM bs_ban WHERE proxy_ban = ? ORDER BY ban_time" : + "SELECT * FROM bs_ban WHERE proxy_ban = ? AND (ban_end IS NULL OR ban_end >= CURRENT_TIMESTAMP) ORDER BY ban_time");) { + findBans.setLong(1, data.getId()); + try (ResultSet rs = findBans.executeQuery()) { + while (rs.next()) { + BSBan ban = extractBan(rs); + if (allBanID.containsKey(ban.bid)) { + results.add(allBanID.get(ban.bid)); + } else { + results.add(ban); + allBanID.put(ban.bid, ban); + } + } + } + } catch (SQLException se) { + BanStick.getPlugin().severe("Failed to lookup bans by IP Data: " + data, se); + } + return results; + } + + /** + * Attempts to find bans for a given share (as per BSShare) + * + * @param data the Share to match + * @param includeExpired true to include expired + * @return a List of BSBans. List is empty if none are found. + */ + public static List byShare(BSShare data, boolean includeExpired) { + List results = new ArrayList<>(); + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); + PreparedStatement findBans = connection.prepareStatement( + includeExpired ? "SELECT * FROM bs_ban WHERE share_ban = ? ORDER BY ban_time" : + "SELECT * FROM bs_ban WHERE share_ban = ? AND (ban_end IS NULL OR ban_end >= CURRENT_TIMESTAMP) ORDER BY ban_time");) { + findBans.setLong(1, data.getId()); + try (ResultSet rs = findBans.executeQuery()) { + while (rs.next()) { + BSBan ban = extractBan(rs); + if (allBanID.containsKey(ban.bid)) { + results.add(allBanID.get(ban.bid)); + } else { + results.add(ban); + allBanID.put(ban.bid, ban); + } + } + } + } catch (SQLException se) { + BanStick.getPlugin().severe("Failed to lookup bans by Share: " + data, se); + } + return results; + } + + /** + * Creates a new ban with optional message, end date, and admin ban indicator. + * + * @param message the ban message + * @param banEnd end of ban, or null + * @param adminBan true for admin ban + * @return the newly created ban, or null if something went wrong. + */ + public static BSBan create(String message, Date banEnd, boolean adminBan) { + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection()) { + BSBan newBan = new BSBan(); + newBan.dirty = false; + newBan.banTime = new Timestamp(Calendar.getInstance().getTimeInMillis()); + newBan.banEnd = banEnd != null ? new Timestamp(banEnd.getTime()) : null; + newBan.message = message; + newBan.isAdminBan = adminBan; + + try (PreparedStatement insertBan = connection.prepareStatement( + "INSERT INTO bs_ban(ban_time, message, ban_end, admin_ban) VALUES (?, ?, ?, ?);", + Statement.RETURN_GENERATED_KEYS)) { + insertBan.setTimestamp(1, newBan.banTime); + if (newBan.message != null) { + insertBan.setString(2, newBan.message); + } else { + insertBan.setNull(2, Types.VARCHAR); + } + if (newBan.banEnd != null) { + insertBan.setTimestamp(3, newBan.banEnd); + } else { + insertBan.setNull(3, Types.TIMESTAMP); + } + insertBan.setBoolean(4, adminBan); + insertBan.execute(); + try (ResultSet rs = insertBan.getGeneratedKeys()) { + if (rs.next()) { + newBan.bid = rs.getLong(1); + } else { + BanStick.getPlugin().severe(NO_BID_RETURNED); + return null; // no bid? error. + } + } + } + + allBanID.put(newBan.bid, newBan); + return newBan; + } catch (SQLException se) { + BanStick.getPlugin().severe("Failed to create a new ban record: ", se); + } + return null; + } + + /** + * Creates a new Ban for a specific IP address. + * + * @param exactIP the already-created BSIP object to ban. + * @param message the ban message, if provided + * @param banEnd the end time for the ban, if provided + * @param adminBan true if this is an admin ban + * @return the new BSBan, or null if creation failed. + */ + public static BSBan create(BSIP exactIP, String message, Date banEnd, boolean adminBan) { + // TODO: Check if this IP is already actively banned! + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection()) { + BSBan newBan = new BSBan(); + newBan.dirty = false; + newBan.deferIpBan = exactIP.getId(); + newBan.ipBan = exactIP; + newBan.banTime = new Timestamp(Calendar.getInstance().getTimeInMillis()); + newBan.banEnd = banEnd != null ? new Timestamp(banEnd.getTime()) : null; + newBan.message = message; + newBan.isAdminBan = adminBan; + + try (PreparedStatement insertBan = connection.prepareStatement( + "INSERT INTO bs_ban(ban_time, message, ban_end, admin_ban, ip_ban) VALUES (?, ?, ?, ?, ?);", + Statement.RETURN_GENERATED_KEYS)) { + insertBan.setTimestamp(1, newBan.banTime); + if (newBan.message != null) { + insertBan.setString(2, newBan.message); + } else { + insertBan.setNull(2, Types.VARCHAR); + } + if (newBan.banEnd != null) { + insertBan.setTimestamp(3, newBan.banEnd); + } else { + insertBan.setNull(3, Types.TIMESTAMP); + } + insertBan.setBoolean(4, adminBan); + insertBan.setLong(5, newBan.ipBan.getId()); + insertBan.execute(); + try (ResultSet rs = insertBan.getGeneratedKeys()) { + if (rs.next()) { + newBan.bid = rs.getLong(1); + } else { + BanStick.getPlugin().severe(NO_BID_RETURNED); + return null; // no bid? error. + } + } + } + + allBanID.put(newBan.bid, newBan); + return newBan; + } catch (SQLException se) { + BanStick.getPlugin().severe("Failed to create a new ip ban record: ", se); + } + return null; + } + + /** + * Creates a new Ban for a given Proxy. + * + * @param proxy The Proxy to ban. + * @param message The message to use, if any + * @param banEnd The end of the ban, if any. + * @param adminBan Set to true for an admin ban. + * @return the new BSBan or null if create fails. + */ + public static BSBan create(BSIPData proxy, String message, Date banEnd, boolean adminBan) { + // TODO: Check if this IP is already actively banned! + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection()) { + BSBan newBan = new BSBan(); + newBan.dirty = false; + newBan.deferProxyBan = proxy.getId(); + newBan.proxyBan = proxy; + newBan.banTime = new Timestamp(Calendar.getInstance().getTimeInMillis()); + newBan.banEnd = banEnd != null ? new Timestamp(banEnd.getTime()) : null; + newBan.message = message; + newBan.isAdminBan = adminBan; + + try (PreparedStatement insertBan = connection.prepareStatement( + "INSERT INTO bs_ban(ban_time, message, ban_end, admin_ban, proxy_ban) VALUES (?, ?, ?, ?, ?);", + Statement.RETURN_GENERATED_KEYS)) { + insertBan.setTimestamp(1, newBan.banTime); + if (newBan.message != null) { + insertBan.setString(2, newBan.message); + } else { + insertBan.setNull(2, Types.VARCHAR); + } + if (newBan.banEnd != null) { + insertBan.setTimestamp(3, newBan.banEnd); + } else { + insertBan.setNull(3, Types.TIMESTAMP); + } + insertBan.setBoolean(4, adminBan); + insertBan.setLong(5, newBan.proxyBan.getId()); + insertBan.execute(); + try (ResultSet rs = insertBan.getGeneratedKeys()) { + if (rs.next()) { + newBan.bid = rs.getLong(1); + } else { + BanStick.getPlugin().severe(NO_BID_RETURNED); + return null; // no bid? error. + } + } + } + + allBanID.put(newBan.bid, newBan); + return newBan; + } catch (SQLException se) { + BanStick.getPlugin().severe("Failed to create a new proxy ban record: ", se); + } + return null; + } + + /** + * Create a new ban based on this specific Share. + * + * @param share The share to ban. + * @param message The message to use, if any. + * @param banEnd The end of the ban, if any + * @param adminBan True if the ban is admin. + * @return the new ban, or null if something went wrong. + */ + public static BSBan create(BSShare share, String message, Date banEnd, boolean adminBan) { + // TODO: Check if this share is already actively banned! + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection()) { + BSBan newBan = new BSBan(); + newBan.dirty = false; + newBan.deferShareBan = share.getId(); + newBan.shareBan = share; + newBan.banTime = new Timestamp(Calendar.getInstance().getTimeInMillis()); + newBan.banEnd = banEnd != null ? new Timestamp(banEnd.getTime()) : null; + newBan.message = message; + newBan.isAdminBan = adminBan; + + try (PreparedStatement insertBan = connection.prepareStatement( + "INSERT INTO bs_ban(ban_time, message, ban_end, admin_ban, share_ban) VALUES (?, ?, ?, ?, ?);", + Statement.RETURN_GENERATED_KEYS)) { + insertBan.setTimestamp(1, newBan.banTime); + if (newBan.message != null) { + insertBan.setString(2, newBan.message); + } else { + insertBan.setNull(2, Types.VARCHAR); + } + if (newBan.banEnd != null) { + insertBan.setTimestamp(3, newBan.banEnd); + } else { + insertBan.setNull(3, Types.TIMESTAMP); + } + insertBan.setBoolean(4, adminBan); + insertBan.setLong(5, newBan.shareBan.getId()); + insertBan.execute(); + try (ResultSet rs = insertBan.getGeneratedKeys()) { + if (rs.next()) { + newBan.bid = rs.getLong(1); + } else { + BanStick.getPlugin().severe(NO_BID_RETURNED); + return null; // no bid? error. + } + } + } + + allBanID.put(newBan.bid, newBan); + return newBan; + } catch (SQLException se) { + BanStick.getPlugin().severe("Failed to create a new share ban record: ", se); + } + return null; + } + + /** + * Given a result set, extract a BSBan object and return it. Internal use. + * + * @param rs The ResultSet object. + * @return the new ban to return. + * @throws SQLException if something goes wrong with the SQL. + */ + private static BSBan extractBan(ResultSet rs) throws SQLException { + BSBan newBan = new BSBan(); + newBan.bid = rs.getLong(1); + newBan.banTime = rs.getTimestamp(2); + long iid = rs.getLong(3); + if (!rs.wasNull()) { + newBan.deferIpBan = iid; + } + long vid = rs.getLong(4); + if (!rs.wasNull()) { + newBan.deferProxyBan = vid; + } + long sid = rs.getLong(5); + if (!rs.wasNull()) { + newBan.deferShareBan = sid; + } + newBan.isAdminBan = rs.getBoolean(6); + newBan.message = rs.getString(7); + try { + newBan.banEnd = rs.getTimestamp(8); + } catch (SQLException se) { + newBan.banEnd = null; + } + newBan.dirty = false; + return newBan; + } + + /** + * Preloads a segment of ban data. Depending on parameters, loads only active bans or loads all bans. + * + * @param offset Offset to begin at + * @param limit How many to load + * @param includeExpired Include old (expired) bans or no + * @return last ID encountered, or -1 if none. + */ + public static long preload(long offset, int limit, boolean includeExpired) { + long maxId = -1; + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); + PreparedStatement loadBans = connection.prepareStatement( + includeExpired ? "SELECT * FROM bs_ban WHERE bid > ? ORDER BY bid LIMIT ?" : + "SELECT * FROM bs_ban WHERE bid > ? AND (ban_end IS NULL OR ban_end >= CURRENT_TIMESTAMP ) ORDER BY bid LIMIT ? ");) { + loadBans.setLong(1, offset); + loadBans.setInt(2, limit); + try (ResultSet rs = loadBans.executeQuery()) { + while (rs.next()) { + BSBan ban = extractBan(rs); + if (!allBanID.containsKey(ban.bid)) { + allBanID.put(ban.bid, ban); + } + if (ban.bid > maxId) { + maxId = ban.bid; + } + } + } + } catch (SQLException se) { + BanStick.getPlugin().severe("Failed during Ban preload, offset " + offset + + " limit " + limit, se); + } + return maxId; + } + + @Override + public String toString() { + StringBuffer sb = new StringBuffer(); + if (getIPBan() != null) { + sb.append("IP Ban: ").append(ipBan.toString()); + } else if (getProxyBan() != null) { + sb.append("Proxy Ban: ").append(proxyBan.toString()); + } else if (getShareBan() != null) { + sb.append("Share Ban: ").append(shareBan.toString()); + } else { + sb.append("Player Ban"); + } + + if (isAdminBan()) { + sb.append(" (administrative)"); + } + + if (getBanEndTime() != null) { + if ((new Date()).after(getBanEndTime())) { // passed + sb.append(" - Expired"); + } else { + sb.append(" - Until ").append(getBanEndTime()); + } + } else { + sb.append(" - Forever"); + } + + sb.append(" with message \"").append(message).append("\""); + return sb.toString(); + } + + /** + * Custom toString including full details. + * + * @param showIPs True to include IP addresses + * @return a String + */ + public String toFullString(boolean showIPs) { + StringBuilder sb = new StringBuilder(); + if (showIPs) { + if (getIPBan() != null) { + sb.append("IP Ban: ").append(ipBan.toString()); + } else if (getProxyBan() != null) { + sb.append("Proxy Ban: ").append(proxyBan.toString()); + } else if (getShareBan() != null) { + sb.append("Share Ban: ").append(shareBan.toString()); + } else { + sb.append("Player Ban"); + } + } else { + if (getIPBan() != null) { + sb.append("IP Ban: ").append(ipBan.getId()); + } else if (getProxyBan() != null) { + sb.append("Proxy Ban: ").append(proxyBan.getId()); + } else if (getShareBan() != null) { + sb.append("Share Ban: ").append(shareBan.toFullString(showIPs)); + } else { + sb.append("Player Ban"); + } + } + + if (isAdminBan()) { + sb.append(" (administrative)"); + } + + if (getBanEndTime() != null) { + if ((new Date()).after(getBanEndTime())) { // passed + sb.append(" - Expired"); + } else { + sb.append(" - Until ").append(getBanEndTime()); + } + } else { + sb.append(" - Forever"); + } + + sb.append(" with message \"").append(message).append("\""); + return sb.toString(); + } } diff --git a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/data/BSExclusion.java b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/data/BSExclusion.java index 0289a1708..65e968790 100644 --- a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/data/BSExclusion.java +++ b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/data/BSExclusion.java @@ -34,276 +34,277 @@ import org.bukkit.ChatColor; */ public final class BSExclusion { - private static Map allExclussionsID = new HashMap<>(); + private static Map allExclussionsID = new HashMap<>(); - private long eid; + private long eid; - private long deferFirstPlayer; - private BSPlayer firstPlayer; - private long deferSecondPlayer; - private BSPlayer secondPlayer; + private long deferFirstPlayer; + private BSPlayer firstPlayer; + private long deferSecondPlayer; + private BSPlayer secondPlayer; - private Timestamp createTime; + private Timestamp createTime; - /** - * Creation only possible over the static methods - */ - private BSExclusion() { - } + /** + * Creation only possible over the static methods + */ + private BSExclusion() { + } - /** - * @return Unique id of this exclusion, which is also its primary key in the - * database - */ - public long getId() { - return this.eid; - } + /** + * @return Unique id of this exclusion, which is also its primary key in the + * database + */ + public long getId() { + return this.eid; + } - /** - * @return When this exclusion was created - */ - public Date getCreateTime() { - return createTime; - } + /** + * @return When this exclusion was created + */ + public Date getCreateTime() { + return createTime; + } - /** - * @return First player part of this exclusion - */ - public BSPlayer getFirstPlayer() { - if (firstPlayer == null) { - firstPlayer = BSPlayer.byId(deferFirstPlayer); - } - return firstPlayer; - } + /** + * @return First player part of this exclusion + */ + public BSPlayer getFirstPlayer() { + if (firstPlayer == null) { + firstPlayer = BSPlayer.byId(deferFirstPlayer); + } + return firstPlayer; + } - /** - * @return BanStick internal id of the first player part of this exclusion - */ - public long getFirstPlayerID() { - return deferFirstPlayer; - } + /** + * @return BanStick internal id of the first player part of this exclusion + */ + public long getFirstPlayerID() { + return deferFirstPlayer; + } - /** - * @return BanStick internal id of the second player part of this exclusion - */ - public long getSecondPlayerID() { - return deferSecondPlayer; - } + /** + * @return BanStick internal id of the second player part of this exclusion + */ + public long getSecondPlayerID() { + return deferSecondPlayer; + } - /** - * @return Second player part of this exclusion - */ - public BSPlayer getSecondPlayer() { - if (secondPlayer == null) { - secondPlayer = BSPlayer.byId(deferSecondPlayer); - } - return secondPlayer; - } + /** + * @return Second player part of this exclusion + */ + public BSPlayer getSecondPlayer() { + if (secondPlayer == null) { + secondPlayer = BSPlayer.byId(deferSecondPlayer); + } + return secondPlayer; + } - /** - * Deletes this exclusion completly from both the cache and the database - */ - public void delete() { - allExclussionsID.remove(this.eid); - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); - PreparedStatement ps = connection.prepareStatement("DELETE FROM bs_exclusion WHERE eid = ?");) { - ps.setLong(1, eid); - ps.execute(); - } catch (SQLException se) { - BanStick.getPlugin().severe("Removal of Exclusion failed: " + eid, se); - } - getFirstPlayer().removeExclusion(this); - getSecondPlayer().removeExclusion(this); - } + /** + * Deletes this exclusion completly from both the cache and the database + */ + public void delete() { + allExclussionsID.remove(this.eid); + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); + PreparedStatement ps = connection.prepareStatement("DELETE FROM bs_exclusion WHERE eid = ?");) { + ps.setLong(1, eid); + ps.execute(); + } catch (SQLException se) { + BanStick.getPlugin().severe("Removal of Exclusion failed: " + eid, se); + } + getFirstPlayer().removeExclusion(this); + getSecondPlayer().removeExclusion(this); + } - /** - * Retrieves an exclusion based on its id. If the exclusion is known in the - * cache it'll be loaded from there, otherwise it'll attempted to be loaded from - * the database - * - * @param eid ID of the exclusion to load - * @return BSExclusion with the given ID or null if no such BSExclusion was - * found - */ - public static BSExclusion byId(long eid) { - if (allExclussionsID.containsKey(eid)) { - return allExclussionsID.get(eid); - } - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); - PreparedStatement getId = connection.prepareStatement("SELECT * FROM bs_exclusion WHERE eid = ?");) { - getId.setLong(1, eid); - try (ResultSet rs = getId.executeQuery();) { - if (rs.next()) { - BSExclusion excl = internalGetExclusion(rs); - allExclussionsID.put(eid, excl); - return excl; - } else { - BanStick.getPlugin().warning("Failed to retrieve exclusion by id: " + eid + " - not found"); - } - } - } catch (SQLException se) { - BanStick.getPlugin().severe("Retrieval of Exclusion by ID failed: " + eid, se); - } + /** + * Retrieves an exclusion based on its id. If the exclusion is known in the + * cache it'll be loaded from there, otherwise it'll attempted to be loaded from + * the database + * + * @param eid ID of the exclusion to load + * @return BSExclusion with the given ID or null if no such BSExclusion was + * found + */ + public static BSExclusion byId(long eid) { + if (allExclussionsID.containsKey(eid)) { + return allExclussionsID.get(eid); + } + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); + PreparedStatement getId = connection.prepareStatement("SELECT * FROM bs_exclusion WHERE eid = ?");) { + getId.setLong(1, eid); + try (ResultSet rs = getId.executeQuery();) { + if (rs.next()) { + BSExclusion excl = internalGetExclusion(rs); + allExclussionsID.put(eid, excl); + return excl; + } else { + BanStick.getPlugin().warning("Failed to retrieve exclusion by id: " + eid + " - not found"); + } + } + } catch (SQLException se) { + BanStick.getPlugin().severe("Retrieval of Exclusion by ID failed: " + eid, se); + } - return null; - } + return null; + } - /** - * Retrieves all exclusions for a given player from the database. If some - * exclusions were already cached, the cached object will be priorized. The - * returned map will use the id of the other player in the exclusion as key, but - * no guarantee can be made regarding whether the player the exclusions were - * requested for is the first or second player within the exclusion itself. - * - * @param player Player to retrieve exclusions for - * @return Map using PID of the other player in the exclusion as key and the - * exclusion itself as value - */ - static Map byPlayer(BSPlayer player) { - Map exclusions = new HashMap<>(); - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); - PreparedStatement getId = connection - .prepareStatement("SELECT * FROM bs_exclusion WHERE first_pid = ? OR second_pid = ?");) { - getId.setLong(1, player.getId()); - getId.setLong(2, player.getId()); - try (ResultSet rs = getId.executeQuery();) { - while (rs.next()) { - if (allExclussionsID.containsKey(rs.getLong(1))) { - BSExclusion existingExcl = allExclussionsID.get(rs.getLong(1)); - long otherID = existingExcl.deferFirstPlayer == player.getId() ? existingExcl.deferSecondPlayer - : existingExcl.deferFirstPlayer; - exclusions.put(otherID, existingExcl); - continue; - } - BSExclusion loadedExcl = internalGetExclusion(rs); - long otherID = loadedExcl.deferFirstPlayer == player.getId() ? loadedExcl.deferSecondPlayer - : loadedExcl.deferFirstPlayer; - allExclussionsID.put(rs.getLong(1), loadedExcl); - exclusions.put(otherID, loadedExcl); - } - } - } catch (SQLException se) { - BanStick.getPlugin().severe("Retrieval of Exclusions by Player failed: " + player.toString(), se); - } - return exclusions; - } + /** + * Retrieves all exclusions for a given player from the database. If some + * exclusions were already cached, the cached object will be priorized. The + * returned map will use the id of the other player in the exclusion as key, but + * no guarantee can be made regarding whether the player the exclusions were + * requested for is the first or second player within the exclusion itself. + * + * @param player Player to retrieve exclusions for + * @return Map using PID of the other player in the exclusion as key and the + * exclusion itself as value + */ + static Map byPlayer(BSPlayer player) { + Map exclusions = new HashMap<>(); + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); + PreparedStatement getId = connection + .prepareStatement("SELECT * FROM bs_exclusion WHERE first_pid = ? OR second_pid = ?");) { + getId.setLong(1, player.getId()); + getId.setLong(2, player.getId()); + try (ResultSet rs = getId.executeQuery();) { + while (rs.next()) { + if (allExclussionsID.containsKey(rs.getLong(1))) { + BSExclusion existingExcl = allExclussionsID.get(rs.getLong(1)); + long otherID = existingExcl.deferFirstPlayer == player.getId() ? existingExcl.deferSecondPlayer + : existingExcl.deferFirstPlayer; + exclusions.put(otherID, existingExcl); + continue; + } + BSExclusion loadedExcl = internalGetExclusion(rs); + long otherID = loadedExcl.deferFirstPlayer == player.getId() ? loadedExcl.deferSecondPlayer + : loadedExcl.deferFirstPlayer; + allExclussionsID.put(rs.getLong(1), loadedExcl); + exclusions.put(otherID, loadedExcl); + } + } + } catch (SQLException se) { + BanStick.getPlugin().severe("Retrieval of Exclusions by Player failed: " + player.toString(), se); + } + return exclusions; + } - /** - * Internal method to retrieve parts of a BSExclusion from a ResultSet and fill - * them into a new instance - * - * @param rs ResultSet to retrieve data from - * @return Constructed BSExclusion - * @throws SQLException - */ - private static BSExclusion internalGetExclusion(ResultSet rs) throws SQLException { - BSExclusion excl = new BSExclusion(); - excl.eid = rs.getLong(1); - excl.createTime = rs.getTimestamp(2); - excl.deferFirstPlayer = rs.getLong(3); - excl.deferSecondPlayer = rs.getLong(4); - return excl; - } + /** + * Internal method to retrieve parts of a BSExclusion from a ResultSet and fill + * them into a new instance + * + * @param rs ResultSet to retrieve data from + * @return Constructed BSExclusion + * @throws SQLException + */ + private static BSExclusion internalGetExclusion(ResultSet rs) throws SQLException { + BSExclusion excl = new BSExclusion(); + excl.eid = rs.getLong(1); + excl.createTime = rs.getTimestamp(2); + excl.deferFirstPlayer = rs.getLong(3); + excl.deferSecondPlayer = rs.getLong(4); + return excl; + } - /** - * Preloads exclusions from the database by their index - * - * @param offset Offset of the section to load - * @param limit How many exclusions to load - * @return Highest id that was successfully loaded - */ - public static long preload(long offset, int limit) { - long maxId = -1; - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); - PreparedStatement loadExclusions = connection - .prepareStatement("SELECT * FROM bs_exclusion WHERE eid > ? ORDER BY eid LIMIT ?");) { - loadExclusions.setLong(1, offset); - loadExclusions.setInt(2, limit); - try (ResultSet rs = loadExclusions.executeQuery()) { - while (rs.next()) { - if (rs.getLong(1) > maxId) { - maxId = rs.getLong(1); - } - if (allExclussionsID.containsKey(rs.getLong(1))) { - continue; - } + /** + * Preloads exclusions from the database by their index + * + * @param offset Offset of the section to load + * @param limit How many exclusions to load + * @return Highest id that was successfully loaded + */ + public static long preload(long offset, int limit) { + long maxId = -1; + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); + PreparedStatement loadExclusions = connection + .prepareStatement("SELECT * FROM bs_exclusion WHERE eid > ? ORDER BY eid LIMIT ?");) { + loadExclusions.setLong(1, offset); + loadExclusions.setInt(2, limit); + try (ResultSet rs = loadExclusions.executeQuery()) { + while (rs.next()) { + if (rs.getLong(1) > maxId) { + maxId = rs.getLong(1); + } + if (allExclussionsID.containsKey(rs.getLong(1))) { + continue; + } - BSExclusion excl = internalGetExclusion(rs); - allExclussionsID.put(excl.eid, excl); - } - } - } catch (SQLException se) { - BanStick.getPlugin().severe("Failed during Exclusion preload, offset " + offset + " limit " + limit, se); - } - return maxId; - } + BSExclusion excl = internalGetExclusion(rs); + allExclussionsID.put(excl.eid, excl); + } + } + } catch (SQLException se) { + BanStick.getPlugin().severe("Failed during Exclusion preload, offset " + offset + " limit " + limit, se); + } + return maxId; + } - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append(ChatColor.DARK_PURPLE).append("Exclusion between ").append(ChatColor.WHITE) - .append(getFirstPlayer().getName()).append(ChatColor.DARK_PURPLE).append(" and ") - .append(ChatColor.WHITE).append(getSecondPlayer().getName()); - return sb.toString(); - } + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(ChatColor.DARK_PURPLE).append("Exclusion between ").append(ChatColor.WHITE) + .append(getFirstPlayer().getName()).append(ChatColor.DARK_PURPLE).append(" and ") + .append(ChatColor.WHITE).append(getSecondPlayer().getName()); + return sb.toString(); + } - /** - * @return Complete details toString - */ - public String toFullString() { - StringBuilder sb = new StringBuilder(); - sb.append(ChatColor.DARK_PURPLE).append("Exclusion between ").append(ChatColor.WHITE) - .append(getFirstPlayer().getName()).append(ChatColor.DARK_PURPLE).append(" and ") - .append(ChatColor.WHITE).append(getSecondPlayer().getName()).append(ChatColor.DARK_PURPLE); - return sb.toString(); - } + /** + * @return Complete details toString + */ + public String toFullString() { + StringBuilder sb = new StringBuilder(); + sb.append(ChatColor.DARK_PURPLE).append("Exclusion between ").append(ChatColor.WHITE) + .append(getFirstPlayer().getName()).append(ChatColor.DARK_PURPLE).append(" and ") + .append(ChatColor.WHITE).append(getSecondPlayer().getName()).append(ChatColor.DARK_PURPLE); + return sb.toString(); + } - /** - * Create a new exclusion between two players. - * @param first The first player as a BSPlayer - * @param second The second player as a BSPlayer - * @return a new BSExclusion or null if failure. - * @throws IllegalArgumentException if either of the player params is null. - */ - public static BSExclusion create(BSPlayer first, BSPlayer second) { - if (first == null || second == null) { - throw new IllegalArgumentException("Can not create exclusion based on player null"); - } - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); - PreparedStatement ps = connection.prepareStatement( - "INSERT INTO bs_exclusion(create_time, first_pid, second_pid) VALUES (?, ?, ?)", - Statement.RETURN_GENERATED_KEYS);) { - BSExclusion exclusion = new BSExclusion(); - exclusion.createTime = new Timestamp(Calendar.getInstance().getTimeInMillis()); - exclusion.deferFirstPlayer = first.getId(); - exclusion.firstPlayer = first; - exclusion.deferSecondPlayer = second.getId(); - exclusion.secondPlayer = second; + /** + * Create a new exclusion between two players. + * + * @param first The first player as a BSPlayer + * @param second The second player as a BSPlayer + * @return a new BSExclusion or null if failure. + * @throws IllegalArgumentException if either of the player params is null. + */ + public static BSExclusion create(BSPlayer first, BSPlayer second) { + if (first == null || second == null) { + throw new IllegalArgumentException("Can not create exclusion based on player null"); + } + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); + PreparedStatement ps = connection.prepareStatement( + "INSERT INTO bs_exclusion(create_time, first_pid, second_pid) VALUES (?, ?, ?)", + Statement.RETURN_GENERATED_KEYS);) { + BSExclusion exclusion = new BSExclusion(); + exclusion.createTime = new Timestamp(Calendar.getInstance().getTimeInMillis()); + exclusion.deferFirstPlayer = first.getId(); + exclusion.firstPlayer = first; + exclusion.deferSecondPlayer = second.getId(); + exclusion.secondPlayer = second; - ps.setTimestamp(1, exclusion.createTime); - ps.setLong(2, exclusion.firstPlayer.getId()); - ps.setLong(3, exclusion.secondPlayer.getId()); - int ins = ps.executeUpdate(); - if (ins < 1) { - BanStick.getPlugin().warning("Insert reported no exclusion inserted? " + exclusion.getId()); - } + ps.setTimestamp(1, exclusion.createTime); + ps.setLong(2, exclusion.firstPlayer.getId()); + ps.setLong(3, exclusion.secondPlayer.getId()); + int ins = ps.executeUpdate(); + if (ins < 1) { + BanStick.getPlugin().warning("Insert reported no exclusion inserted? " + exclusion.getId()); + } - try (ResultSet rs = ps.getGeneratedKeys()) { - if (rs.next()) { - long eid = rs.getLong(1); - exclusion.eid = eid; - allExclussionsID.put(eid, exclusion); - return exclusion; - } else { - BanStick.getPlugin().severe( - "Failed to get ID from inserted exclusion!? " + first.getId() + " - " + second.getId()); - return null; - } - } - } catch (SQLException se) { - BanStick.getPlugin().severe("Failed to insert new exclusion for sessions!", se); - } - return null; - } + try (ResultSet rs = ps.getGeneratedKeys()) { + if (rs.next()) { + long eid = rs.getLong(1); + exclusion.eid = eid; + allExclussionsID.put(eid, exclusion); + return exclusion; + } else { + BanStick.getPlugin().severe( + "Failed to get ID from inserted exclusion!? " + first.getId() + " - " + second.getId()); + return null; + } + } + } catch (SQLException se) { + BanStick.getPlugin().severe("Failed to insert new exclusion for sessions!", se); + } + return null; + } } diff --git a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/data/BSExclusions.java b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/data/BSExclusions.java index 41e0da15e..fea8eb0a3 100644 --- a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/data/BSExclusions.java +++ b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/data/BSExclusions.java @@ -8,128 +8,127 @@ import java.util.Set; /** * A list of exclusions for a particular player. - * - * @author Maxopoly * + * @author Maxopoly */ public final class BSExclusions { - private BSPlayer forPlayer; - private List exclusionList; + private BSPlayer forPlayer; + private List exclusionList; - private BSExclusions() { - } + private BSExclusions() { + } - /** - * Get the exclusions list for a particular player. - * - * @param player The player to retrieve, as a BSPlayer - * @return a new BSExclusions for this player. - */ - public static BSExclusions onlyFor(BSPlayer player) { - BSExclusions exclusions = new BSExclusions(); - exclusions.forPlayer = player; - return exclusions; - } + /** + * Get the exclusions list for a particular player. + * + * @param player The player to retrieve, as a BSPlayer + * @return a new BSExclusions for this player. + */ + public static BSExclusions onlyFor(BSPlayer player) { + BSExclusions exclusions = new BSExclusions(); + exclusions.forPlayer = player; + return exclusions; + } - /** - * @return a new list of exclusions (clone) - */ - public List getAll() { - if (exclusionList == null) { - fill(); - } - return new LinkedList<>(exclusionList); - } + /** + * @return a new list of exclusions (clone) + */ + public List getAll() { + if (exclusionList == null) { + fill(); + } + return new LinkedList<>(exclusionList); + } - /** - * @return Set containing player ids of all players this one has an exclusion - * with - */ - public Set getExcludedPlayerIDs() { - Set pids = new HashSet<>(); - for (BSExclusion excl : getAll()) { - pids.add(excl.getFirstPlayerID()); - pids.add(excl.getSecondPlayerID()); - } - pids.remove(forPlayer.getId()); - return pids; - } + /** + * @return Set containing player ids of all players this one has an exclusion + * with + */ + public Set getExcludedPlayerIDs() { + Set pids = new HashSet<>(); + for (BSExclusion excl : getAll()) { + pids.add(excl.getFirstPlayerID()); + pids.add(excl.getSecondPlayerID()); + } + pids.remove(forPlayer.getId()); + return pids; + } - /** - * @return Set containing all players this one has an exclusion with - */ - public Set getExcludedPlayers() { - Set pids = new HashSet<>(); - for (BSExclusion excl : getAll()) { - pids.add(excl.getFirstPlayer()); - pids.add(excl.getSecondPlayer()); - } - pids.remove(forPlayer); - return pids; - } + /** + * @return Set containing all players this one has an exclusion with + */ + public Set getExcludedPlayers() { + Set pids = new HashSet<>(); + for (BSExclusion excl : getAll()) { + pids.add(excl.getFirstPlayer()); + pids.add(excl.getSecondPlayer()); + } + pids.remove(forPlayer); + return pids; + } - public boolean hasExclusionWith(BSPlayer player) { - return getExclusionWith(player) != null; - } + public boolean hasExclusionWith(BSPlayer player) { + return getExclusionWith(player) != null; + } - /** - * @param player to retrieve mutual exclusions - * @return an exclusion that covers given player and this BSExclusions' player, - * or null if none found. - */ - public BSExclusion getExclusionWith(BSPlayer player) { - if (forPlayer.getId() == player.getId()) { - return null; - } - for (BSExclusion excl : getAll()) { - if (excl.getFirstPlayerID() == player.getId() || excl.getSecondPlayerID() == player.getId()) { - return excl; - } - } - return null; - } + /** + * @param player to retrieve mutual exclusions + * @return an exclusion that covers given player and this BSExclusions' player, + * or null if none found. + */ + public BSExclusion getExclusionWith(BSPlayer player) { + if (forPlayer.getId() == player.getId()) { + return null; + } + for (BSExclusion excl : getAll()) { + if (excl.getFirstPlayerID() == player.getId() || excl.getSecondPlayerID() == player.getId()) { + return excl; + } + } + return null; + } - /** - * Removes a particular exclusion from the exclusion list. - * - * @param excl the exclusion to remove. Removes by object reference - */ - public void remove(BSExclusion excl) { - if (exclusionList == null) { - fill(); - } - exclusionList.remove(excl); - } + /** + * Removes a particular exclusion from the exclusion list. + * + * @param excl the exclusion to remove. Removes by object reference + */ + public void remove(BSExclusion excl) { + if (exclusionList == null) { + fill(); + } + exclusionList.remove(excl); + } - /** - * Resets and refills the exclusion list. - */ - private void fill() { - exclusionList = new ArrayList<>(); - exclusionList.addAll(BSExclusion.byPlayer(forPlayer).values()); - } + /** + * Resets and refills the exclusion list. + */ + private void fill() { + exclusionList = new ArrayList<>(); + exclusionList.addAll(BSExclusion.byPlayer(forPlayer).values()); + } - /** - * Adds a new exclusion to the exclusion list. Does not check if already there. - * - * @param excl the exclusion to add. Adds by object reference - */ - public void addNew(BSExclusion excl) { - if (exclusionList == null) { - fill(); - } - this.exclusionList.add(excl); + /** + * Adds a new exclusion to the exclusion list. Does not check if already there. + * + * @param excl the exclusion to add. Adds by object reference + */ + public void addNew(BSExclusion excl) { + if (exclusionList == null) { + fill(); + } + this.exclusionList.add(excl); - } + } - /** - * @return the size of the Exclusions list. - */ - public int getOrdinality() { - if (exclusionList == null) { - fill(); - } - return this.exclusionList.size(); - } + /** + * @return the size of the Exclusions list. + */ + public int getOrdinality() { + if (exclusionList == null) { + fill(); + } + return this.exclusionList.size(); + } } diff --git a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/data/BSIP.java b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/data/BSIP.java index b120947d5..e6c715a3a 100644 --- a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/data/BSIP.java +++ b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/data/BSIP.java @@ -23,620 +23,630 @@ import java.util.Map; /** * Internal IP address representation and lookups, can be a v4 or v6 IP. - * - * @author ProgrammerDan * + * @author ProgrammerDan */ public final class BSIP { - private static Map allIPNA = new HashMap<>(); - private static Map allIPId = new HashMap<>(); - - private long iid; - private Timestamp createTime; - private IPv4Address basev4; - private IPv6Address basev6; - - private BSIP() { } - - public long getId() { - return iid; - } - - public Date getCreateTime() { - return createTime; - } - - public IPv4Address getIPv4Address() { - return basev4; - } - - public IPv6Address getIPv6Address() { - return basev6; - } - - /** - * Gets either the v4 or v6 address. - * - * @return either v4 or v6 address - */ - public IPAddress getIPAddress() { - return basev4 != null ? basev4 : basev6; - } - - public boolean isIPv4() { - return basev4 != null; - } - - public boolean isIPv6() { - return basev6 != null; - } - - /** - * This method finds all records for which this exact address is a member, based on subnet. - * - * @param netAddress IP address to match - * @return All the subnet records that match it - */ - public static List allMatching(InetAddress netAddress) { - IPAddress lookup = IPAddress.from(netAddress); - return allMatching(lookup); - } - - /** - * @param lookup The IP address to look up - * @return All matching subnet records - * @see #allMatching(InetAddress) - */ - public static List allMatching(IPAddress lookup) { - List matches = new ArrayList<>(); - if (lookup.isIPv4()) { - fillFromCIDRs(lookup, 32, matches); - } else if (lookup.isIPv6()) { - fillFromCIDRs(lookup, 128, matches); - } - return matches; - } - - /** - * Expands CIDR restrictions for subnet matching -- find all networks containing this network - * - * @param lookup The ipaddress as root of the subnet - * @param cidr The CIDR to begin as smallest subnet - * @return The subnet records containing this subnet - * @see #allMatching(InetAddress) - */ - public static List allMatching(IPAddress lookup, int cidr) { - List matches = new ArrayList(); - if (lookup.isIPv4()) { - fillFromCIDRs(lookup, cidr, matches); - } else if (lookup.isIPv6()) { - fillFromCIDRs(lookup, cidr, matches); - } - return matches; - } + private static Map allIPNA = new HashMap<>(); + private static Map allIPId = new HashMap<>(); - /** - * SLOW!!! - * - *

This method finds all records, CIDR and exact, that are members of this subnet. - * - * @param lookup The base IP address to use - * @param cidr The largest subnet to consider. - * @return All the IP records contained in the given subnet - */ - public static List allContained(IPAddress lookup, int cidr) { - List returns = new ArrayList<>(); - IPAddress newBase = lookup.toSubnet(cidr); - StringBuilder sb = new StringBuilder("SELECT * FROM bs_ip WHERE "); - if (newBase.isIPv4()) { - sb.append("ip4 LIKE \"").append(newBase.toSQLWildcardString()).append("\""); - } else { - newBase.getNetworkSection(cidr).getStartsWithSQLClause(sb, "ip6"); - } - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); - PreparedStatement getIP = connection.prepareStatement(sb.toString()); - ResultSet rs = getIP.executeQuery();) { - while (rs.next()) { - BSIP bsip = new BSIP(); - bsip.iid = rs.getLong(1); - if (allIPId.containsKey(bsip.iid)) { - returns.add(allIPId.get(bsip.iid)); - continue; - } - - bsip.createTime = rs.getTimestamp(2); - String ipv4 = rs.getString(3); - int ipv4cidr = rs.getInt(4); - if (rs.wasNull()) { - ipv4cidr = 32; - } - - String ipv6 = rs.getString(5); - int ipv6cidr = rs.getInt(6); - if (rs.wasNull()) { - ipv6cidr = 128; - } - - if (ipv4 != null) { // ipv4 specific entry. Typical for player-entries. - IPAddressString ips = new IPAddressString(ipv4 + "/" + ipv4cidr); - if (ips.isIPv4()) { - bsip.basev4 = ips.getAddress().toIPv4(); - if (!BSIP.allIPNA.containsKey(bsip.basev4)) { - BSIP.allIPNA.put(bsip.basev4, bsip); - } - } else { - BanStick.getPlugin().warning("Conversion of ipv4 address to ipv4 failed??: " - + bsip.iid + " - " + ipv4); - continue; - // TODO: exception - } - } else if (ipv6 != null) { //ipv6 specific entry. - IPAddressString ips = new IPAddressString(ipv6 + "/" + ipv6cidr); - if (ips.isIPv6()) { - bsip.basev6 = ips.getAddress().toIPv6(); - if (!BSIP.allIPNA.containsKey(bsip.basev6)) { - BSIP.allIPNA.put(bsip.basev6, bsip); - } - } else { - BanStick.getPlugin().warning("Conversion of ipv6 address to ipv6 failed??: " - + bsip.iid + " - " + ipv6); - continue; - // TODO: exception - } - } else { - BanStick.getPlugin().warning("Empty ip entry?!: " + bsip.iid); - continue; - // TODO: exception - } - - if (!BSIP.allIPId.containsKey(bsip.iid)) { - BSIP.allIPId.put(bsip.iid, bsip); - } - returns.add(bsip); - } + private long iid; + private Timestamp createTime; - } catch (SQLException e) { - BanStick.getPlugin().severe("Failed during search for IPs contained by " - + newBase.toCanonicalString(), e); - } - return returns; - } - - /** - * Starting at max CIDR passed in and moving towards largest, check for host matches. - * These can then be used to check for bans on those matching host networks. - * - *

Shorthand: Looks to find host networks for the specified IP/subnet that have IP table entries - * to use for ban-lookups. - * - *

I recommend this be non-synchronous! - * - * @param lookup The IPAddress to lookup from (root, smallest subnet base IP) - * @param maxCIDR The smallest CIDR to consider - * @param matches The List to fill with foud matches - */ - private static void fillFromCIDRs(IPAddress lookup, int maxCIDR, List matches) { - for (int curCIDR = maxCIDR; curCIDR > 0; curCIDR--) { - BSIP prospect = byCIDR(lookup.toSubnet(curCIDR).getLower().toString(), curCIDR); - if (prospect != null) { - matches.add(prospect); - } - } - } - - /** - * Exact lookup of netAddress by CIDR (InetAddress version) - * - * @param netAddress The IP Address to lookup from (root, smallest subnet base IP) - * @param cidr The CIDR to match - * @return The IPAddress/CIDR match, if found. - */ - public static BSIP byCIDR(InetAddress netAddress, int cidr) { - return BSIP.byCIDR(netAddress.getHostAddress(), cidr); - } - - /** - * Exact lookup of netAddress by CIDR - * @param netAddress The IPAddress as a string to match - * @param cidr The subnet CIDR to match - * @return The exact matching IP record or null if not found. - */ - public static BSIP byCIDR(String netAddress, int cidr) { - IPAddressString ips = new IPAddressString(netAddress + "/" + cidr); - //BanStick.getPlugin().debug("Check for CIDR IP: {0}", ips.toString()); - IPAddress lookup = ips.getAddress(); - if (allIPNA.containsKey(lookup)) { - return allIPNA.get(lookup); - } - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection();) { - PreparedStatement getIP = null; - if (lookup.isIPv4()) { - getIP = connection.prepareStatement("SELECT * FROM bs_ip WHERE ip4 = ? and ip4cidr = ?"); - } else if (lookup.isIPv6()) { - getIP = connection.prepareStatement("SELECT * FROM bs_ip WHERE ip6 = ? and ip6cidr = ?"); - } else { - BanStick.getPlugin().severe("Unknown Inet address type: " + netAddress.toString()); - return null; - } - getIP.setString(1, lookup.toSubnet(cidr).getLower().toString()); - getIP.setInt(2, cidr); - - BSIP bsip = null; - try (ResultSet rs = getIP.executeQuery();) { - bsip = internalGetResult(rs); - } - getIP.close(); - return bsip; - } catch (SQLException se) { - BanStick.getPlugin().severe("Unable to retrieve BPID: " + netAddress + "/" + cidr, se); - } - return null; - } - - /** - * Get IP by exact Inet Address IP. Either matches or fails. - * - * @param netAddress Exact IPAddress to match - * @return The matching IP or null - */ - public static BSIP byInetAddress(InetAddress netAddress) { - IPAddress lookup = IPAddress.from(netAddress); - return byIPAddress(lookup); - } - - /** - * Get IP by a v4 or v6 IPAddress - * @param lookup the IP address to match - * @return the matching IP or null - */ - public static BSIP byIPAddress(IPAddress lookup) { - //BanStick.getPlugin().debug("Check for IP: {0}", lookup.toString()); - if (allIPNA.containsKey(lookup)) { - return allIPNA.get(lookup); - } - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection();) { - PreparedStatement getIP = null; - if (lookup.isIPv4()) { - getIP = connection.prepareStatement("SELECT * FROM bs_ip WHERE ip4 = ? and ip4cidr = 32"); - getIP.setString(1, lookup.toString()); - } else if (lookup.isIPv6()) { - getIP = connection.prepareStatement("SELECT * FROM bs_ip WHERE ip6 = ? and ip6cidr = 128"); - getIP.setString(1, lookup.toString()); - } else { - BanStick.getPlugin().severe("Unknown Inet address type: " + lookup.toString()); - return null; - } - BSIP bsip = null; - try (ResultSet rs = getIP.executeQuery();) { - bsip = internalGetResult(rs); - } - getIP.close(); - return bsip; - } catch (SQLException se) { - BanStick.getPlugin().severe("Failed to execute query to get IP: " + lookup.toString(), se); - } - - return null; - } + private IPv4Address basev4; + private IPv6Address basev6; - /** - * Get IP by exact ID. Either matches or fails. - * - * @param iid The IP database ID - * @return The exact IP data record or null if not found - */ - public static BSIP byId(long iid) { - if (allIPId.containsKey(iid)) { - return allIPId.get(iid); - } - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); - PreparedStatement getIP = connection.prepareStatement("SELECT * FROM bs_ip WHERE iid = ?");) { - getIP.setLong(1, iid); - try (ResultSet rs = getIP.executeQuery();) { - return internalGetResult(rs); - } - } catch (SQLException se) { - BanStick.getPlugin().severe("Unable to retrieve BPID: " + iid, se); - } - return null; // TODO: exception - } - - /** - * Leverages a ResultSet to construct an IP - * @param rs the ResultSet - * @return the internal BSIP, or null if retrieval failed. - * @throws SQLException If something goes wrong. - */ - private static BSIP internalGetResult(ResultSet rs) throws SQLException { - if (rs.next()) { - // found - BSIP bsip = new BSIP(); - bsip.iid = rs.getLong(1); - if (BSIP.allIPId.containsKey(bsip.iid)) { - return BSIP.allIPId.get(bsip.iid); - } - bsip.createTime = rs.getTimestamp(2); - String ipv4 = rs.getString(3); - int ipv4cidr = rs.getInt(4); - if (rs.wasNull()) { - ipv4cidr = 32; - } - - String ipv6 = rs.getString(5); - int ipv6cidr = rs.getInt(6); - if (rs.wasNull()) { - ipv6cidr = 128; - } - - if (ipv4 != null) { // ipv4 specific entry. Typical for player-entries. - IPAddressString ips = new IPAddressString(ipv4 + "/" + ipv4cidr); - if (ips.isIPv4()) { - bsip.basev4 = ips.getAddress().toIPv4(); - BSIP.allIPNA.put(bsip.basev4, bsip); - } else { - BanStick.getPlugin().warning("Conversion of ipv4 address to ipv4 failed??: " - + bsip.iid + " - " + ipv4); - return null; // TODO: exception - } - } else if (ipv6 != null) { //ipv6 specific entry. - IPAddressString ips = new IPAddressString(ipv6 + "/" + ipv6cidr); - if (ips.isIPv6()) { - bsip.basev6 = ips.getAddress().toIPv6(); - BSIP.allIPNA.put(bsip.basev6, bsip); - } else { - BanStick.getPlugin().warning("Conversion of ipv6 address to ipv6 failed??: " - + bsip.iid + " - " + ipv6); - return null; // TODO: exception - } - } else { - BanStick.getPlugin().warning("Empty ip entry?!: " + bsip.iid); - return null; // TODO: exception - } - - BSIP.allIPId.put(bsip.iid, bsip); - - return bsip; - } else { - //BanStick.getPlugin().warning("Failed to find IP"); - return null; // TODO: exception - } - } + private BSIP() { + } - /** - * Creates a BSIP from an InetAddress object - * @param netAddress the InetAddress object - * @return a BSIP object, or null if failure. - */ - public static BSIP create(InetAddress netAddress) { - IPAddress lookup = IPAddress.from(netAddress); - return create(lookup); - } - - /** - * Creates a BSIP from an IPAddress object - * @param lookup the IPAddress object - * @return a BSIP object, or null if failure. - */ - public static BSIP create(IPAddress lookup) { - if (allIPNA.containsKey(lookup)) { - return allIPNA.get(lookup); - } - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); - PreparedStatement statement = connection.prepareStatement( - "INSERT INTO bs_ip(ip4, ip4cidr, ip6, ip6cidr, create_time) VALUES (?, ?, ?, ?, ?);", - Statement.RETURN_GENERATED_KEYS);) { - BSIP newIP = new BSIP(); - if (lookup.isIPv4()) { - statement.setNull(3, Types.CHAR); - statement.setNull(4, Types.SMALLINT); - statement.setString(1, lookup.toString()); - statement.setInt(2, 32); - newIP.basev4 = lookup.toIPv4(); - } else { - statement.setNull(1, Types.CHAR); - statement.setNull(2, Types.SMALLINT); - statement.setString(3, lookup.toString()); - statement.setInt(4, 128); - newIP.basev6 = lookup.toIPv6(); - } - newIP.createTime = new Timestamp(Calendar.getInstance().getTimeInMillis()); - statement.setTimestamp(5, newIP.createTime); - - int ins = statement.executeUpdate(); - if (ins < 1) { - BanStick.getPlugin().warning("Insert reported nothing inserted? " + lookup.toString()); - } - - try (ResultSet rs = statement.getGeneratedKeys()) { - if (rs.next()) { - long iid = rs.getLong(1); - newIP.iid = iid; - BSIP.allIPId.put(iid, newIP); - BSIP.allIPNA.put((newIP.basev4 == null ? newIP.basev6 : newIP.basev4), newIP); - if (BanStick.getPlugin().getIPDataHandler() != null) { - BanStick.getPlugin().getIPDataHandler().offer(newIP); - } - return newIP; - } else { - BanStick.getPlugin().severe("Failed to get ID from inserted record!? " + lookup.toString()); - return null; - } - } - } catch (SQLException se) { - BanStick.getPlugin().severe("Failed to create IP from " + lookup.toString(), se); - } - return null; - } - - /** - * Creates a CIDR IP address from an InetAddress and a CIDR - * @param netAddress the InetAddress - * @param cidr the CIDR mask - * @return a new BSIP or null if failed - */ - public static BSIP create(InetAddress netAddress, int cidr) { - IPAddress lookup = IPAddress.from(netAddress).toSubnet(cidr).getLower(); - return create(lookup, cidr); - } - - /** - * Creates a CIDR IP address from an IPAddress object and a CIDR - * @param lookup the IPAddress - * @param cidr the CIDR mask - * @return - */ - public static BSIP create(IPAddress lookup, int cidr) { - // TODO: reconsider the CIDR handling in the caching and saving and such. - // might not be necessary to separate out the CIDR like I am here. - if (allIPNA.containsKey(lookup)) { - return allIPNA.get(lookup); - } - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); - PreparedStatement statement = connection.prepareStatement( - "INSERT INTO bs_ip(ip4, ip4cidr, ip6, ip6cidr, create_time) VALUES (?, ?, ?, ?, ?);", - Statement.RETURN_GENERATED_KEYS);) { - BSIP newIP = new BSIP(); - if (lookup.isIPv4()) { - statement.setNull(3, Types.CHAR); - statement.setNull(4, Types.SMALLINT); - statement.setString(1, lookup.toString()); - statement.setInt(2, cidr); - newIP.basev4 = lookup.toIPv4(); - } else { - statement.setNull(1, Types.CHAR); - statement.setNull(2, Types.SMALLINT); - statement.setString(3, lookup.toString()); - statement.setInt(4, cidr); - newIP.basev6 = lookup.toIPv6(); - } - newIP.createTime = new Timestamp(Calendar.getInstance().getTimeInMillis()); - statement.setTimestamp(5, newIP.createTime); - - int ins = statement.executeUpdate(); - if (ins < 1) { - BanStick.getPlugin().warning("Insert reported nothing inserted? " - + lookup.toString() + "/" + cidr); - } - - try (ResultSet rs = statement.getGeneratedKeys()) { - if (rs.next()) { - long iid = rs.getLong(1); - newIP.iid = iid; - BSIP.allIPId.put(iid, newIP); - BSIP.allIPNA.put((newIP.basev4 == null ? newIP.basev6 : newIP.basev4), newIP); - if (BanStick.getPlugin().getIPDataHandler() != null - && (newIP.basev4 == null ? cidr == 128 : cidr == 32)) { - BanStick.getPlugin().getIPDataHandler().offer(newIP); - } - return newIP; - } else { - BanStick.getPlugin().severe("Failed to get ID from inserted record!? " - + lookup.toString() + "/" + cidr); - return null; - } - } - } catch (SQLException se) { - BanStick.getPlugin().severe("Failed to create IP from " + lookup.toString() + "/" + cidr, se); - } - return null; - } - - /** - * Preloads a chunk of BSIPs. - * @param offset starting offset for load - * @param limit how many to load in this chunk of preload - * @return How many were actually loaded - */ - public static long preload(long offset, int limit) { - long maxId = -1; - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); - PreparedStatement loadIPs = connection.prepareStatement( - "SELECT * FROM bs_ip WHERE iid > ? ORDER BY iid LIMIT ?");) { - loadIPs.setLong(1, offset); - loadIPs.setInt(2, limit); - try (ResultSet rs = loadIPs.executeQuery()) { - while (rs.next()) { - BSIP bsip = new BSIP(); - bsip.iid = rs.getLong(1); - if (bsip.iid > maxId) { - maxId = bsip.iid; - } - if (BSIP.allIPId.containsKey(bsip.iid)) { // already cached. - continue; - } - bsip.createTime = rs.getTimestamp(2); - String ipv4 = rs.getString(3); - int ipv4cidr = rs.getInt(4); - if (rs.wasNull()) { - ipv4cidr = 32; - } - - String ipv6 = rs.getString(5); - int ipv6cidr = rs.getInt(6); - if (rs.wasNull()) { - ipv6cidr = 128; - } - - if (ipv4 != null) { // ipv4 specific entry. Typical for player-entries. - IPAddressString ips = new IPAddressString(ipv4 + "/" + ipv4cidr); - if (ips.isIPv4()) { - bsip.basev4 = ips.getAddress().toIPv4(); - if (!BSIP.allIPNA.containsKey(bsip.basev4)) { - BSIP.allIPNA.put(bsip.basev4, bsip); - } - } else { - BanStick.getPlugin().warning("Conversion of ipv4 address to ipv4 failed??: " - + bsip.iid + " - " + ipv4); - continue; - // TODO: exception - } - } else if (ipv6 != null) { //ipv6 specific entry. - IPAddressString ips = new IPAddressString(ipv6 + "/" + ipv6cidr); - if (ips.isIPv6()) { - bsip.basev6 = ips.getAddress().toIPv6(); - if (!BSIP.allIPNA.containsKey(bsip.basev6)) { - BSIP.allIPNA.put(bsip.basev6, bsip); - } - } else { - BanStick.getPlugin().warning("Conversion of ipv6 address to ipv6 failed??: " - + bsip.iid + " - " + ipv6); - continue; - // TODO: exception - } - } else { - BanStick.getPlugin().warning("Empty ip entry?!: " + bsip.iid); - continue; - // TODO: exception - } - - if (!BSIP.allIPId.containsKey(bsip.iid)) { - BSIP.allIPId.put(bsip.iid, bsip); - } - } - } - } catch (SQLException se) { - BanStick.getPlugin().severe("Failed during IP preload, offset " + offset - + " limit " + limit, se); - } - return maxId; - } - - @Override - public String toString() { - if (basev4 != null) { - return basev4.toCanonicalString(); - } else { - return basev6.toCanonicalString(); - } - } - - /** - * Full details of IP - * @param showIPs do we show the IP? - * @return a String - */ - public String toFullString(boolean showIPs) { - return showIPs ? toString() : String.valueOf(this.iid); - } + public long getId() { + return iid; + } + + public Date getCreateTime() { + return createTime; + } + + public IPv4Address getIPv4Address() { + return basev4; + } + + public IPv6Address getIPv6Address() { + return basev6; + } + + /** + * Gets either the v4 or v6 address. + * + * @return either v4 or v6 address + */ + public IPAddress getIPAddress() { + return basev4 != null ? basev4 : basev6; + } + + public boolean isIPv4() { + return basev4 != null; + } + + public boolean isIPv6() { + return basev6 != null; + } + + /** + * This method finds all records for which this exact address is a member, based on subnet. + * + * @param netAddress IP address to match + * @return All the subnet records that match it + */ + public static List allMatching(InetAddress netAddress) { + IPAddress lookup = IPAddress.from(netAddress); + return allMatching(lookup); + } + + /** + * @param lookup The IP address to look up + * @return All matching subnet records + * @see #allMatching(InetAddress) + */ + public static List allMatching(IPAddress lookup) { + List matches = new ArrayList<>(); + if (lookup.isIPv4()) { + fillFromCIDRs(lookup, 32, matches); + } else if (lookup.isIPv6()) { + fillFromCIDRs(lookup, 128, matches); + } + return matches; + } + + /** + * Expands CIDR restrictions for subnet matching -- find all networks containing this network + * + * @param lookup The ipaddress as root of the subnet + * @param cidr The CIDR to begin as smallest subnet + * @return The subnet records containing this subnet + * @see #allMatching(InetAddress) + */ + public static List allMatching(IPAddress lookup, int cidr) { + List matches = new ArrayList(); + if (lookup.isIPv4()) { + fillFromCIDRs(lookup, cidr, matches); + } else if (lookup.isIPv6()) { + fillFromCIDRs(lookup, cidr, matches); + } + return matches; + } + + /** + * SLOW!!! + * + *

This method finds all records, CIDR and exact, that are members of this subnet. + * + * @param lookup The base IP address to use + * @param cidr The largest subnet to consider. + * @return All the IP records contained in the given subnet + */ + public static List allContained(IPAddress lookup, int cidr) { + List returns = new ArrayList<>(); + IPAddress newBase = lookup.toSubnet(cidr); + StringBuilder sb = new StringBuilder("SELECT * FROM bs_ip WHERE "); + if (newBase.isIPv4()) { + sb.append("ip4 LIKE \"").append(newBase.toSQLWildcardString()).append("\""); + } else { + newBase.getNetworkSection(cidr).getStartsWithSQLClause(sb, "ip6"); + } + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); + PreparedStatement getIP = connection.prepareStatement(sb.toString()); + ResultSet rs = getIP.executeQuery();) { + while (rs.next()) { + BSIP bsip = new BSIP(); + bsip.iid = rs.getLong(1); + if (allIPId.containsKey(bsip.iid)) { + returns.add(allIPId.get(bsip.iid)); + continue; + } + + bsip.createTime = rs.getTimestamp(2); + String ipv4 = rs.getString(3); + int ipv4cidr = rs.getInt(4); + if (rs.wasNull()) { + ipv4cidr = 32; + } + + String ipv6 = rs.getString(5); + int ipv6cidr = rs.getInt(6); + if (rs.wasNull()) { + ipv6cidr = 128; + } + + if (ipv4 != null) { // ipv4 specific entry. Typical for player-entries. + IPAddressString ips = new IPAddressString(ipv4 + "/" + ipv4cidr); + if (ips.isIPv4()) { + bsip.basev4 = ips.getAddress().toIPv4(); + if (!BSIP.allIPNA.containsKey(bsip.basev4)) { + BSIP.allIPNA.put(bsip.basev4, bsip); + } + } else { + BanStick.getPlugin().warning("Conversion of ipv4 address to ipv4 failed??: " + + bsip.iid + " - " + ipv4); + continue; + // TODO: exception + } + } else if (ipv6 != null) { //ipv6 specific entry. + IPAddressString ips = new IPAddressString(ipv6 + "/" + ipv6cidr); + if (ips.isIPv6()) { + bsip.basev6 = ips.getAddress().toIPv6(); + if (!BSIP.allIPNA.containsKey(bsip.basev6)) { + BSIP.allIPNA.put(bsip.basev6, bsip); + } + } else { + BanStick.getPlugin().warning("Conversion of ipv6 address to ipv6 failed??: " + + bsip.iid + " - " + ipv6); + continue; + // TODO: exception + } + } else { + BanStick.getPlugin().warning("Empty ip entry?!: " + bsip.iid); + continue; + // TODO: exception + } + + if (!BSIP.allIPId.containsKey(bsip.iid)) { + BSIP.allIPId.put(bsip.iid, bsip); + } + returns.add(bsip); + } + + } catch (SQLException e) { + BanStick.getPlugin().severe("Failed during search for IPs contained by " + + newBase.toCanonicalString(), e); + } + return returns; + } + + /** + * Starting at max CIDR passed in and moving towards largest, check for host matches. + * These can then be used to check for bans on those matching host networks. + * + *

Shorthand: Looks to find host networks for the specified IP/subnet that have IP table entries + * to use for ban-lookups. + * + *

I recommend this be non-synchronous! + * + * @param lookup The IPAddress to lookup from (root, smallest subnet base IP) + * @param maxCIDR The smallest CIDR to consider + * @param matches The List to fill with foud matches + */ + private static void fillFromCIDRs(IPAddress lookup, int maxCIDR, List matches) { + for (int curCIDR = maxCIDR; curCIDR > 0; curCIDR--) { + BSIP prospect = byCIDR(lookup.toSubnet(curCIDR).getLower().toString(), curCIDR); + if (prospect != null) { + matches.add(prospect); + } + } + } + + /** + * Exact lookup of netAddress by CIDR (InetAddress version) + * + * @param netAddress The IP Address to lookup from (root, smallest subnet base IP) + * @param cidr The CIDR to match + * @return The IPAddress/CIDR match, if found. + */ + public static BSIP byCIDR(InetAddress netAddress, int cidr) { + return BSIP.byCIDR(netAddress.getHostAddress(), cidr); + } + + /** + * Exact lookup of netAddress by CIDR + * + * @param netAddress The IPAddress as a string to match + * @param cidr The subnet CIDR to match + * @return The exact matching IP record or null if not found. + */ + public static BSIP byCIDR(String netAddress, int cidr) { + IPAddressString ips = new IPAddressString(netAddress + "/" + cidr); + //BanStick.getPlugin().debug("Check for CIDR IP: {0}", ips.toString()); + IPAddress lookup = ips.getAddress(); + if (allIPNA.containsKey(lookup)) { + return allIPNA.get(lookup); + } + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection();) { + PreparedStatement getIP = null; + if (lookup.isIPv4()) { + getIP = connection.prepareStatement("SELECT * FROM bs_ip WHERE ip4 = ? and ip4cidr = ?"); + } else if (lookup.isIPv6()) { + getIP = connection.prepareStatement("SELECT * FROM bs_ip WHERE ip6 = ? and ip6cidr = ?"); + } else { + BanStick.getPlugin().severe("Unknown Inet address type: " + netAddress.toString()); + return null; + } + getIP.setString(1, lookup.toSubnet(cidr).getLower().toString()); + getIP.setInt(2, cidr); + + BSIP bsip = null; + try (ResultSet rs = getIP.executeQuery();) { + bsip = internalGetResult(rs); + } + getIP.close(); + return bsip; + } catch (SQLException se) { + BanStick.getPlugin().severe("Unable to retrieve BPID: " + netAddress + "/" + cidr, se); + } + return null; + } + + /** + * Get IP by exact Inet Address IP. Either matches or fails. + * + * @param netAddress Exact IPAddress to match + * @return The matching IP or null + */ + public static BSIP byInetAddress(InetAddress netAddress) { + IPAddress lookup = IPAddress.from(netAddress); + return byIPAddress(lookup); + } + + /** + * Get IP by a v4 or v6 IPAddress + * + * @param lookup the IP address to match + * @return the matching IP or null + */ + public static BSIP byIPAddress(IPAddress lookup) { + //BanStick.getPlugin().debug("Check for IP: {0}", lookup.toString()); + if (allIPNA.containsKey(lookup)) { + return allIPNA.get(lookup); + } + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection();) { + PreparedStatement getIP = null; + if (lookup.isIPv4()) { + getIP = connection.prepareStatement("SELECT * FROM bs_ip WHERE ip4 = ? and ip4cidr = 32"); + getIP.setString(1, lookup.toString()); + } else if (lookup.isIPv6()) { + getIP = connection.prepareStatement("SELECT * FROM bs_ip WHERE ip6 = ? and ip6cidr = 128"); + getIP.setString(1, lookup.toString()); + } else { + BanStick.getPlugin().severe("Unknown Inet address type: " + lookup.toString()); + return null; + } + BSIP bsip = null; + try (ResultSet rs = getIP.executeQuery();) { + bsip = internalGetResult(rs); + } + getIP.close(); + return bsip; + } catch (SQLException se) { + BanStick.getPlugin().severe("Failed to execute query to get IP: " + lookup.toString(), se); + } + + return null; + } + + /** + * Get IP by exact ID. Either matches or fails. + * + * @param iid The IP database ID + * @return The exact IP data record or null if not found + */ + public static BSIP byId(long iid) { + if (allIPId.containsKey(iid)) { + return allIPId.get(iid); + } + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); + PreparedStatement getIP = connection.prepareStatement("SELECT * FROM bs_ip WHERE iid = ?");) { + getIP.setLong(1, iid); + try (ResultSet rs = getIP.executeQuery();) { + return internalGetResult(rs); + } + } catch (SQLException se) { + BanStick.getPlugin().severe("Unable to retrieve BPID: " + iid, se); + } + return null; // TODO: exception + } + + /** + * Leverages a ResultSet to construct an IP + * + * @param rs the ResultSet + * @return the internal BSIP, or null if retrieval failed. + * @throws SQLException If something goes wrong. + */ + private static BSIP internalGetResult(ResultSet rs) throws SQLException { + if (rs.next()) { + // found + BSIP bsip = new BSIP(); + bsip.iid = rs.getLong(1); + if (BSIP.allIPId.containsKey(bsip.iid)) { + return BSIP.allIPId.get(bsip.iid); + } + bsip.createTime = rs.getTimestamp(2); + String ipv4 = rs.getString(3); + int ipv4cidr = rs.getInt(4); + if (rs.wasNull()) { + ipv4cidr = 32; + } + + String ipv6 = rs.getString(5); + int ipv6cidr = rs.getInt(6); + if (rs.wasNull()) { + ipv6cidr = 128; + } + + if (ipv4 != null) { // ipv4 specific entry. Typical for player-entries. + IPAddressString ips = new IPAddressString(ipv4 + "/" + ipv4cidr); + if (ips.isIPv4()) { + bsip.basev4 = ips.getAddress().toIPv4(); + BSIP.allIPNA.put(bsip.basev4, bsip); + } else { + BanStick.getPlugin().warning("Conversion of ipv4 address to ipv4 failed??: " + + bsip.iid + " - " + ipv4); + return null; // TODO: exception + } + } else if (ipv6 != null) { //ipv6 specific entry. + IPAddressString ips = new IPAddressString(ipv6 + "/" + ipv6cidr); + if (ips.isIPv6()) { + bsip.basev6 = ips.getAddress().toIPv6(); + BSIP.allIPNA.put(bsip.basev6, bsip); + } else { + BanStick.getPlugin().warning("Conversion of ipv6 address to ipv6 failed??: " + + bsip.iid + " - " + ipv6); + return null; // TODO: exception + } + } else { + BanStick.getPlugin().warning("Empty ip entry?!: " + bsip.iid); + return null; // TODO: exception + } + + BSIP.allIPId.put(bsip.iid, bsip); + + return bsip; + } else { + //BanStick.getPlugin().warning("Failed to find IP"); + return null; // TODO: exception + } + } + + /** + * Creates a BSIP from an InetAddress object + * + * @param netAddress the InetAddress object + * @return a BSIP object, or null if failure. + */ + public static BSIP create(InetAddress netAddress) { + IPAddress lookup = IPAddress.from(netAddress); + return create(lookup); + } + + /** + * Creates a BSIP from an IPAddress object + * + * @param lookup the IPAddress object + * @return a BSIP object, or null if failure. + */ + public static BSIP create(IPAddress lookup) { + if (allIPNA.containsKey(lookup)) { + return allIPNA.get(lookup); + } + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); + PreparedStatement statement = connection.prepareStatement( + "INSERT INTO bs_ip(ip4, ip4cidr, ip6, ip6cidr, create_time) VALUES (?, ?, ?, ?, ?);", + Statement.RETURN_GENERATED_KEYS);) { + BSIP newIP = new BSIP(); + if (lookup.isIPv4()) { + statement.setNull(3, Types.CHAR); + statement.setNull(4, Types.SMALLINT); + statement.setString(1, lookup.toString()); + statement.setInt(2, 32); + newIP.basev4 = lookup.toIPv4(); + } else { + statement.setNull(1, Types.CHAR); + statement.setNull(2, Types.SMALLINT); + statement.setString(3, lookup.toString()); + statement.setInt(4, 128); + newIP.basev6 = lookup.toIPv6(); + } + newIP.createTime = new Timestamp(Calendar.getInstance().getTimeInMillis()); + statement.setTimestamp(5, newIP.createTime); + + int ins = statement.executeUpdate(); + if (ins < 1) { + BanStick.getPlugin().warning("Insert reported nothing inserted? " + lookup.toString()); + } + + try (ResultSet rs = statement.getGeneratedKeys()) { + if (rs.next()) { + long iid = rs.getLong(1); + newIP.iid = iid; + BSIP.allIPId.put(iid, newIP); + BSIP.allIPNA.put((newIP.basev4 == null ? newIP.basev6 : newIP.basev4), newIP); + if (BanStick.getPlugin().getIPDataHandler() != null) { + BanStick.getPlugin().getIPDataHandler().offer(newIP); + } + return newIP; + } else { + BanStick.getPlugin().severe("Failed to get ID from inserted record!? " + lookup.toString()); + return null; + } + } + } catch (SQLException se) { + BanStick.getPlugin().severe("Failed to create IP from " + lookup.toString(), se); + } + return null; + } + + /** + * Creates a CIDR IP address from an InetAddress and a CIDR + * + * @param netAddress the InetAddress + * @param cidr the CIDR mask + * @return a new BSIP or null if failed + */ + public static BSIP create(InetAddress netAddress, int cidr) { + IPAddress lookup = IPAddress.from(netAddress).toSubnet(cidr).getLower(); + return create(lookup, cidr); + } + + /** + * Creates a CIDR IP address from an IPAddress object and a CIDR + * + * @param lookup the IPAddress + * @param cidr the CIDR mask + * @return + */ + public static BSIP create(IPAddress lookup, int cidr) { + // TODO: reconsider the CIDR handling in the caching and saving and such. + // might not be necessary to separate out the CIDR like I am here. + if (allIPNA.containsKey(lookup)) { + return allIPNA.get(lookup); + } + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); + PreparedStatement statement = connection.prepareStatement( + "INSERT INTO bs_ip(ip4, ip4cidr, ip6, ip6cidr, create_time) VALUES (?, ?, ?, ?, ?);", + Statement.RETURN_GENERATED_KEYS);) { + BSIP newIP = new BSIP(); + if (lookup.isIPv4()) { + statement.setNull(3, Types.CHAR); + statement.setNull(4, Types.SMALLINT); + statement.setString(1, lookup.toString()); + statement.setInt(2, cidr); + newIP.basev4 = lookup.toIPv4(); + } else { + statement.setNull(1, Types.CHAR); + statement.setNull(2, Types.SMALLINT); + statement.setString(3, lookup.toString()); + statement.setInt(4, cidr); + newIP.basev6 = lookup.toIPv6(); + } + newIP.createTime = new Timestamp(Calendar.getInstance().getTimeInMillis()); + statement.setTimestamp(5, newIP.createTime); + + int ins = statement.executeUpdate(); + if (ins < 1) { + BanStick.getPlugin().warning("Insert reported nothing inserted? " + + lookup.toString() + "/" + cidr); + } + + try (ResultSet rs = statement.getGeneratedKeys()) { + if (rs.next()) { + long iid = rs.getLong(1); + newIP.iid = iid; + BSIP.allIPId.put(iid, newIP); + BSIP.allIPNA.put((newIP.basev4 == null ? newIP.basev6 : newIP.basev4), newIP); + if (BanStick.getPlugin().getIPDataHandler() != null + && (newIP.basev4 == null ? cidr == 128 : cidr == 32)) { + BanStick.getPlugin().getIPDataHandler().offer(newIP); + } + return newIP; + } else { + BanStick.getPlugin().severe("Failed to get ID from inserted record!? " + + lookup.toString() + "/" + cidr); + return null; + } + } + } catch (SQLException se) { + BanStick.getPlugin().severe("Failed to create IP from " + lookup.toString() + "/" + cidr, se); + } + return null; + } + + /** + * Preloads a chunk of BSIPs. + * + * @param offset starting offset for load + * @param limit how many to load in this chunk of preload + * @return How many were actually loaded + */ + public static long preload(long offset, int limit) { + long maxId = -1; + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); + PreparedStatement loadIPs = connection.prepareStatement( + "SELECT * FROM bs_ip WHERE iid > ? ORDER BY iid LIMIT ?");) { + loadIPs.setLong(1, offset); + loadIPs.setInt(2, limit); + try (ResultSet rs = loadIPs.executeQuery()) { + while (rs.next()) { + BSIP bsip = new BSIP(); + bsip.iid = rs.getLong(1); + if (bsip.iid > maxId) { + maxId = bsip.iid; + } + if (BSIP.allIPId.containsKey(bsip.iid)) { // already cached. + continue; + } + bsip.createTime = rs.getTimestamp(2); + String ipv4 = rs.getString(3); + int ipv4cidr = rs.getInt(4); + if (rs.wasNull()) { + ipv4cidr = 32; + } + + String ipv6 = rs.getString(5); + int ipv6cidr = rs.getInt(6); + if (rs.wasNull()) { + ipv6cidr = 128; + } + + if (ipv4 != null) { // ipv4 specific entry. Typical for player-entries. + IPAddressString ips = new IPAddressString(ipv4 + "/" + ipv4cidr); + if (ips.isIPv4()) { + bsip.basev4 = ips.getAddress().toIPv4(); + if (!BSIP.allIPNA.containsKey(bsip.basev4)) { + BSIP.allIPNA.put(bsip.basev4, bsip); + } + } else { + BanStick.getPlugin().warning("Conversion of ipv4 address to ipv4 failed??: " + + bsip.iid + " - " + ipv4); + continue; + // TODO: exception + } + } else if (ipv6 != null) { //ipv6 specific entry. + IPAddressString ips = new IPAddressString(ipv6 + "/" + ipv6cidr); + if (ips.isIPv6()) { + bsip.basev6 = ips.getAddress().toIPv6(); + if (!BSIP.allIPNA.containsKey(bsip.basev6)) { + BSIP.allIPNA.put(bsip.basev6, bsip); + } + } else { + BanStick.getPlugin().warning("Conversion of ipv6 address to ipv6 failed??: " + + bsip.iid + " - " + ipv6); + continue; + // TODO: exception + } + } else { + BanStick.getPlugin().warning("Empty ip entry?!: " + bsip.iid); + continue; + // TODO: exception + } + + if (!BSIP.allIPId.containsKey(bsip.iid)) { + BSIP.allIPId.put(bsip.iid, bsip); + } + } + } + } catch (SQLException se) { + BanStick.getPlugin().severe("Failed during IP preload, offset " + offset + + " limit " + limit, se); + } + return maxId; + } + + @Override + public String toString() { + if (basev4 != null) { + return basev4.toCanonicalString(); + } else { + return basev6.toCanonicalString(); + } + } + + /** + * Full details of IP + * + * @param showIPs do we show the IP? + * @return a String + */ + public String toFullString(boolean showIPs) { + return showIPs ? toString() : String.valueOf(this.iid); + } } diff --git a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/data/BSIPData.java b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/data/BSIPData.java index c9d88185e..ae0a3ef36 100644 --- a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/data/BSIPData.java +++ b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/data/BSIPData.java @@ -21,763 +21,769 @@ import net.md_5.bungee.api.ChatColor; /** * Static storage and management of Proxy data as BSIPData. - * + * * @author ProgrammerDan */ public final class BSIPData { - private static Map allIPDataID = new HashMap<>(); - private static ConcurrentLinkedQueue> dirtyIPData = new ConcurrentLinkedQueue<>(); - private boolean dirty; - private long idid; - private Long deferIid; - private BSIP iid; - private Timestamp createTime; - private boolean valid; // mutable - private String continent; - private String country; - private String region; - private String city; - private String postal; - private Double lat; - private Double lon; - private String domain; - private String provider; - private String registeredAs; - private String connection; - private float proxy; // mutable - private String source; // mutable - private String comment; // mutable - - private BSIPData() { } + private static Map allIPDataID = new HashMap<>(); + private static ConcurrentLinkedQueue> dirtyIPData = new ConcurrentLinkedQueue<>(); + private boolean dirty; - public long getId() { - return this.idid; - } - - /** - * Marks this proxy data as invalid, triggers that the backing data should be - * updated. - */ - public void invalidate() { - if (this.valid) { - this.valid = false; - dirtyIPData.offer(new WeakReference(this)); - } - } - - public boolean isValid() { - return this.valid; - } - - public Date getCreateTime() { - return this.createTime; - } - - /** - * @return the BSIP associated with this Proxy (usually a CIDR address). - */ - public BSIP getIP() { - if (this.iid == null && this.deferIid != null) { - this.iid = BSIP.byId(this.deferIid); - } - return this.iid; - } - - public String getContinent() { - return this.continent; - } - - public String getCountry() { - return this.country; - } - - public String getRegion() { - return this.region; - } - - public String getCity() { - return this.city; - } - - public String getPostal() { - return this.postal; - } - - public Double getLat() { - return this.lat; - } - - public Double getLon() { - return this.lon; - } - - public String getDomain() { - return this.domain; - } - - public String getProvider() { - return this.provider; - } - - public String getRegisteredAs() { - return this.registeredAs; - } - - public String getConnection() { - return this.connection; - } - - public float getProxy() { - return this.proxy; - } - - /** - * Updates the proxy "level", based on threshold could trigger bans. - * Triggers a dirty flag update. - * - * @param proxy the new proxy value. - */ - public void setProxy(float proxy) { - this.proxy = proxy; - dirtyIPData.offer(new WeakReference(this)); - } - - public String getSource() { - return this.source; - } - - /** - * Sets the string-value "source" of this proxy. Can be updated using - * this method, triggers a dirty flag update. - * - * @param source The new source. - */ - public void setSource(String source) { - this.source = source; - dirtyIPData.offer(new WeakReference(this)); - - } - - public String getComment() { - return this.comment; - } - - /** - * Sets the string-value "comment" for this proxy. Can be updated using - * this method, triggers a dirty flag update. - * - * @param comment The new comment - */ - public void setComment(String comment) { - this.comment = comment; - dirtyIPData.offer(new WeakReference(this)); - } + private long idid; + private Long deferIid; + private BSIP iid; + private Timestamp createTime; + private boolean valid; // mutable + private String continent; + private String country; + private String region; + private String city; + private String postal; + private Double lat; + private Double lon; + private String domain; + private String provider; + private String registeredAs; + private String connection; + private float proxy; // mutable + private String source; // mutable + private String comment; // mutable - /** - * Retrieve a specific Proxy by its identifier. - * - * @param idid the ID of the Proxy to retrieve - * @return the BSIPData object with that ID if found, otherwise null. - */ - public static BSIPData byId(long idid) { - if (allIPDataID.containsKey(idid)) { - return allIPDataID.get(idid); - } - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); - PreparedStatement getId = connection.prepareStatement( - "SELECT * FROM bs_ip_data WHERE idid = ?");) { - getId.setLong(1, idid); - try (ResultSet rs = getId.executeQuery();) { - if (rs.next()) { - BSIPData data = extractData(rs); - allIPDataID.put(idid, data); - return data; - } else { - BanStick.getPlugin().warning("Failed to retrieve IP Data by id: " + idid + " - not found"); - } - } - } catch (SQLException se) { - BanStick.getPlugin().severe("Retrieval of IP Data by ID failed: " + idid, se); - } - return null; - } - - /** - * Internal tool to create a BSIPData object from a ResultSet - * @param rs the ResultSet to unpack - * @return a BSIPData from that ResultSet - * @throws SQLException if something goes wrong - */ - private static BSIPData extractData(ResultSet rs) throws SQLException { - BSIPData data = new BSIPData(); - data.idid = rs.getLong(1); - data.deferIid = rs.getLong(2); - //data.iid = BSIP.byId(rs.getLong(2)); - data.createTime = rs.getTimestamp(3); - data.valid = rs.getBoolean(4); - data.continent = rs.getString(5); - data.country = rs.getString(6); - data.region = rs.getString(7); - data.city = rs.getString(8); - data.postal = rs.getString(9); - data.lat = rs.getDouble(10); - if (rs.wasNull()) { - data.lat = null; - } - data.lon = rs.getDouble(11); - if (rs.wasNull()) { - data.lon = null; - } - data.domain = rs.getString(12); - data.provider = rs.getString(13); - data.registeredAs = rs.getString(14); - data.connection = rs.getString(15); - data.proxy = rs.getFloat(16); - data.source = rs.getString(17); - data.comment = rs.getString(18); - data.dirty = false; - return data; - } - - /** - * As described in method header; finds the other non-same IPData records that - * geolocate to the same country/region/city pairing. - * - * @param source The IPData to use to seed the search - * @return A list of IPDatas in the same region, or nothing if none found. - */ - public static List bySameCity(BSIPData source) { - List found = new ArrayList<>(); - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); - PreparedStatement getSame = connection.prepareStatement( - "SELECT * FROM bs_ip_data WHERE country = ? and region = ? and city = ? and idid != ? and valid = true ORDER BY create_time");) { - getSame.setString(1, source.getCountry()); - getSame.setString(2, source.getRegion()); - getSame.setString(3, source.getCity()); - getSame.setLong(4, source.getId()); - try (ResultSet rs = getSame.executeQuery();) { - while (rs.next()) { - if (allIPDataID.containsKey(rs.getLong(1))) { - found.add(allIPDataID.get(rs.getLong(1))); - } - BSIPData data = extractData(rs); - allIPDataID.put(data.idid, data); - found.add(data); - } - if (found.isEmpty()) { - BanStick.getPlugin().debug("Found no other IP Data in same city as {0}", source); - } - } - } catch (SQLException se) { - BanStick.getPlugin().severe("Retrieval of same-city IP Data by IP Data failed: " + source, se); - } - return found; - } + private BSIPData() { + } - /** - * Returns only the latest valid BSIPData records by exact match with the IP - * @param ip The BSIP record to use for IPData retrieval - * @return the matching BSIPData or null if no match - */ - public static BSIPData byExactIP(BSIP ip) { - if (ip == null) { - BanStick.getPlugin().warning("Weird failure, byExactIP with null IP"); - return null; - } - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); - PreparedStatement getId = connection.prepareStatement( - "SELECT * FROM bs_ip_data WHERE iid = ? and valid = true ORDER BY create_time DESC LIMIT 1");) { - getId.setLong(1, ip.getId()); - try (ResultSet rs = getId.executeQuery();) { - if (rs.next()) { - if (allIPDataID.containsKey(rs.getLong(1))) { - return allIPDataID.get(rs.getLong(1)); - } - BSIPData data = extractData(rs); - allIPDataID.put(data.idid, data); - return data; - } else { - BanStick.getPlugin().warning("Failed to retrieve IP Data by exact IP: {0} - not found", ip); - } - } - } catch (SQLException se) { - BanStick.getPlugin().severe("Retrieval of IP Data by exact IP failed: " + ip, se); - } - return null; - } - - /** - * @return the average proxy value for BSIPData entries having the same registeredAs. - */ - public double getAverageForRegistrar() { - if (this.registeredAs == null) { - return 0; - } - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); - PreparedStatement getSame = connection.prepareStatement( - "SELECT avg(proxy) FROM bs_ip_data WHERE registered_as = ?");) { - getSame.setString(1, this.registeredAs); - try (ResultSet rs = getSame.executeQuery();) { - rs.next(); - return rs.getDouble(1); //returns 0 for no matches - } - } catch (SQLException se) { - BanStick.getPlugin().severe("Failed to load average proxy score for registrar " - + this.registeredAs, se); - return 0; - } - } - - /** - * Finds the first subnet that fully contains the given BSIP's IP/CIDR, if any. - * - * @param ip The BSIP record to base the lookup on - * @return The BSIPData record that contains the IP/CIDR, or null if none found. - */ - public static BSIPData byContainsIP(BSIP ip) { - try { - if (ip == null) { - BanStick.getPlugin().warning("Weird failure, byContainsIP with null IP"); - return null; - } - IPAddress address = ip.getIPAddress(); - if (address == null) { - BanStick.getPlugin().warning("Weird failure, no ip _in_ {0}", ip.toString()); - return null; - } - Integer cidr = address.getNetworkPrefixLength(); - if (cidr == null) { - cidr = address.isIPv4() ? 32 : 128; - } - List knownContains = BSIP.allMatching(address, cidr); - - if (knownContains != null) { - for (BSIP maybe : knownContains) { - BSIPData data = byExactIP(maybe); - if (data != null) { - return data; - } - } - } - BanStick.getPlugin().warning("No IPData records contain IP {0}", ip); - } catch (Exception e) { - BanStick.getPlugin().warning("Failure during IPData retrieval", e); - } - return null; - } - - /** - * Returns all BSIPData that relate to or contain the given IP/CIDR. - * - * @param ip The BSIP to use for matching. - * @return a list; empty if nothing found. - */ - public static List allByIP(BSIP ip) { - List returns = new ArrayList<>(); - try { - if (ip == null) { - BanStick.getPlugin().warning("Weird failure, allByIP with null IP"); - return returns; - } - IPAddress address = ip.getIPAddress(); - if (address == null) { - BanStick.getPlugin().warning("Weird failure, no ip _in_ {0}", ip.toString()); - return returns; - } - Integer cidr = address.getNetworkPrefixLength(); - if (cidr == null) { - cidr = address.isIPv4() ? 32 : 128; - } - List knownContains = BSIP.allMatching(address, cidr); - - if (knownContains != null) { - for (BSIP maybe : knownContains) { - BSIPData data = byExactIP(maybe); - if (data != null) { - returns.add(data); - } - } - } - if (returns.isEmpty()) { - BanStick.getPlugin().warning("No IPData records contain IP {0}", ip); - } - } catch (Exception e) { - BanStick.getPlugin().warning("Failure during IPData retrieval", e); - } - return returns; - } - - /** - * This does NOT check for prior existence. Must be managed elsewhere. - * - * @param ip The BSIP record to bind to. Must not be null. - * @param continent The continent where this IP is registered to - * @param country The country where this IP is registered to - * @param region The region where this IP is registered to - * @param city The city where this IP is registered to - * @param postal The postal / zip code where this IP is registered to - * @param lat The latitude - * @param lon The longitude - * @param domain The domain that maps to this IP / range - * @param provider The provider for this IP / range - * @param registeredAs Any registration information for this IP / range - * @param connectionSource The connection source for this IP / range - * @param proxy The likelihood this is a proxy -- higher number for more likelihood. - * Assumes 0 - no, 3 - likely, 4 - definite - * @param source The source of this record (Cloud9? Tor? IP-API?) - * @param comment Any comments recorded against the BSIPData. - * @return The new BSIPData if successful - */ - public static BSIPData create(BSIP ip, String continent, String country, String region, - String city, String postal, Double lat, Double lon, String domain, String provider, - String registeredAs, String connectionSource, float proxy, String source, String comment) { - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection()) { - BSIPData newData = new BSIPData(); - newData.valid = true; - newData.dirty = false; - newData.continent = continent; - newData.deferIid = ip.getId(); - newData.iid = ip; - newData.country = country; - newData.region = region; - newData.city = city; - newData.postal = postal; - newData.lat = lat; - newData.lon = lon; - newData.domain = domain; - newData.provider = provider; - newData.registeredAs = registeredAs; - newData.connection = connectionSource; - newData.proxy = proxy; - newData.source = source; - newData.comment = comment; - - try (PreparedStatement insertData = connection.prepareStatement( - "INSERT INTO bs_ip_data(iid, continent, country, region, city, postal, lat, lon, domain, provider, registered_as, connection, proxy, source, comment) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);", - Statement.RETURN_GENERATED_KEYS)) { - insertData.setLong(1, newData.iid.getId()); - if (newData.continent == null) { - insertData.setNull(2, Types.VARCHAR); - } else { - insertData.setString(2, newData.continent); - } - if (newData.country == null) { - insertData.setNull(3, Types.VARCHAR); - } else { - insertData.setString(3, newData.country); - } - if (newData.region == null) { - insertData.setNull(4, Types.VARCHAR); - } else { - insertData.setString(4, newData.region); - } - if (newData.region == null) { - insertData.setNull(5, Types.VARCHAR); - } else { - insertData.setString(5, newData.city); - } - if (newData.postal == null) { - insertData.setNull(6, Types.VARCHAR); - } else { - insertData.setString(6, newData.postal); - } - if (newData.lat == null) { - insertData.setNull(7, Types.DOUBLE); - } else { - insertData.setDouble(7, newData.lat); - } - if (newData.lon == null) { - insertData.setNull(8, Types.DOUBLE); - } else { - insertData.setDouble(8, newData.lon); - } - if (newData.domain == null) { - insertData.setNull(9, Types.VARCHAR); - } else { - insertData.setString(9, newData.domain); - } - if (newData.domain == null) { - insertData.setNull(10, Types.VARCHAR); - } else { - insertData.setString(10, newData.provider); - } - if (newData.registeredAs == null) { - insertData.setNull(11, Types.VARCHAR); - } else { - insertData.setString(11, newData.registeredAs); - } - if (newData.connection == null) { - insertData.setNull(12, Types.VARCHAR); - } else { - insertData.setString(12, newData.connection); - } - insertData.setFloat(13, newData.proxy); - if (newData.source == null) { - insertData.setNull(14, Types.VARCHAR); - } else { - insertData.setString(14, newData.source); - } - if (newData.comment == null) { - insertData.setNull(15, Types.VARCHAR); - } else { - insertData.setString(15, newData.comment); - } - insertData.execute(); - try (ResultSet rs = insertData.getGeneratedKeys()) { - if (rs.next()) { - newData.idid = rs.getLong(1); - } else { - BanStick.getPlugin().severe("No IDID returned on IP Data insert?!"); - return null; // no bid? error. - } - } - } - - allIPDataID.put(newData.idid, newData); - return newData; - } catch (SQLException se) { - BanStick.getPlugin().severe("Failed to create a new ip data record: ", se); - } - return null; - } - - /** - * Saves the BSBan; only for internal use. Outside code must use Flush(); - */ - private void save() { - if (!dirty) { - return; - } - this.dirty = false; // don't let anyone else in! - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); - PreparedStatement save = connection.prepareStatement( - "UPDATE bs_ip_data SET valid = ?, proxy = ?, source = ?, comment = ? WHERE idid = ?");) { - saveToStatement(save); - int effects = save.executeUpdate(); - if (effects == 0) { - BanStick.getPlugin().severe("Failed to save BSIPData or no update? " + this.idid); - } - } catch (SQLException se) { - BanStick.getPlugin().severe("Save of BSIPData failed!: ", se); - } - } - - /** - * Internal helper to map this BSIPData to a PreparedStatement for upsert - * @param save the PreparedStatement to fill - * @throws SQLException if something goes wrong. - */ - private void saveToStatement(PreparedStatement save) throws SQLException { - save.setBoolean(1, this.valid); - save.setFloat(2, this.proxy); - if (this.source == null) { - save.setNull(3, Types.VARCHAR); - } else { - save.setString(3, this.source); - } - if (this.comment == null) { - save.setNull(4, Types.VARCHAR); - } else { - save.setString(4, this.comment); - } - save.setLong(5, this.idid); - } - - /** - * Cleanly saves this IPData if necessary, and removes it from the references lists. - */ - public void flush() { - if (dirty) { - save(); - } - allIPDataID.remove(this.idid); - this.deferIid = null; - this.iid = null; - } + public long getId() { + return this.idid; + } - /** - * Pulls from the dirty queue and commits updates to the backing DB in batches. - * Allows for high volume changes w/o swamping the DB with churn. - * - *

Note that inserts are direct, to ensure IDs and relationship consistency is upheld - */ - public static void saveDirty() { - int batchSize = 0; - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); - PreparedStatement save = connection.prepareStatement( - "UPDATE bs_ip_data SET valid = ?, proxy = ?, source = ?, comment = ? WHERE idid = ?");) { - while (!dirtyIPData.isEmpty()) { - WeakReference rdata = dirtyIPData.poll(); - BSIPData data = rdata.get(); - if (data != null && data.dirty) { - data.dirty = false; - data.saveToStatement(save); - save.addBatch(); - batchSize ++; - } - if (batchSize > 0 && batchSize % 100 == 0) { - int[] batchRun = save.executeBatch(); - if (batchRun.length != batchSize) { - BanStick.getPlugin().severe("Some elements of the dirty batch didn't save? " - + batchSize + " vs " + batchRun.length); - } else { - BanStick.getPlugin().debug("IP Data batch: {0} saves", batchRun.length); - } - batchSize = 0; - } - } - if (batchSize > 0 && batchSize % 100 > 0) { - int[] batchRun = save.executeBatch(); - if (batchRun.length != batchSize) { - BanStick.getPlugin().severe("Some elements of the dirty batch didn't save? " - + batchSize + " vs " + batchRun.length); - } else { - BanStick.getPlugin().debug("IP Data batch: {0} saves", batchRun.length); - } - } - } catch (SQLException se) { - BanStick.getPlugin().severe("Save of BSIPData dirty batch failed!: ", se); - } - } + /** + * Marks this proxy data as invalid, triggers that the backing data should be + * updated. + */ + public void invalidate() { + if (this.valid) { + this.valid = false; + dirtyIPData.offer(new WeakReference(this)); + } + } - /** - * Triggers a segmented preload of valid BSIPData segments. Items marked invalid are not loaded. - * Fills the cache with entries. - * - * @param offset Starting point - * @param limit How many to load - * @return The largest ID encountered during this load, or -1 if nothing loaded. - */ - public static long preload(long offset, int limit) { - long maxId = -1; - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); - PreparedStatement loadData = connection.prepareStatement( - "SELECT * FROM bs_ip_data WHERE valid = true AND idid > ? ORDER BY idid LIMIT ?");) { - loadData.setLong(1, offset); - loadData.setInt(2, limit); - try (ResultSet rs = loadData.executeQuery()) { - while (rs.next()) { - BSIPData data = extractData(rs); - if (!allIPDataID.containsKey(data.idid)) { - allIPDataID.put(data.idid, data); - } - if (data.idid > maxId) { - maxId = data.idid; - } - } - } - } catch (SQLException se) { - BanStick.getPlugin().severe("Failed during IPData preload, offset " + offset - + " limit " + limit, se); - } - return maxId; + public boolean isValid() { + return this.valid; + } - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append(ChatColor.WHITE).append(getIP().toString()).append(" - "); - if (!valid) { - sb.append(ChatColor.RED).append("[Invalid] ").append(ChatColor.WHITE); - } - if (continent != null || country != null || region != null || city != null - || postal != null || lat != null || lon != null) { - sb.append(ChatColor.AQUA).append("Location: ").append(ChatColor.WHITE); - } - if (continent != null) { - sb.append(continent).append(", "); - } - if (country != null) { - sb.append(country).append(", "); - } - if (region != null) { - sb.append(region).append(", "); - } - if (city != null) { - sb.append(city).append(", "); - } - if (postal != null) { - sb.append(postal).append(", "); - } - if (lat != null || lon != null) { - sb.append(ChatColor.GRAY).append("[").append(ChatColor.WHITE).append(lat) - .append(ChatColor.GRAY).append(',').append(ChatColor.WHITE).append(lon) - .append(ChatColor.GRAY).append("] ").append(ChatColor.WHITE); - } - if (connection != null) { - sb.append(ChatColor.GRAY).append("Connection: ").append(ChatColor.WHITE) - .append(connection).append(" "); - } - if (domain != null) { - sb.append("(").append(domain).append(") "); - } - if (provider != null) { - sb.append(ChatColor.GRAY).append("Provider: ").append(ChatColor.WHITE) - .append(provider).append(" "); - } - if (registeredAs != null) { - sb.append(ChatColor.GRAY).append("Reg. As: ").append(ChatColor.WHITE) - .append(registeredAs).append(" "); - } - if (source != null) { - sb.append(ChatColor.DARK_PURPLE).append("from ").append(ChatColor.WHITE) - .append(source).append(" "); - } - if (comment != null) { - sb.append(ChatColor.GRAY).append("Comments:").append(ChatColor.WHITE) - .append(comment).append(" "); - } - sb.append(ChatColor.DARK_AQUA).append("[pli: "); - if (proxy < 1.0) { - sb.append(ChatColor.GREEN); - } else if (proxy < 2.0) { - sb.append(ChatColor.GOLD); - } else if (proxy < 3.0) { - sb.append(ChatColor.YELLOW); - } else { - sb.append(ChatColor.RED); - } - sb.append(proxy).append(ChatColor.DARK_AQUA).append("]").append(ChatColor.RESET); - - return sb.toString(); - } + public Date getCreateTime() { + return this.createTime; + } - /** - * Generates a larger string of full details for this proxy - * @param showIPs indicate if IPs should be shown - * @return the String - */ - public String toFullString(boolean showIPs) { - if (showIPs) { - return toString(); - } - StringBuilder sb = new StringBuilder(); - sb.append(ChatColor.WHITE).append(getIP().toFullString(showIPs)).append(" - "); - if (!valid) { - sb.append(ChatColor.RED).append("[Invalid] ").append(ChatColor.WHITE); - } - sb.append("Proxy #").append(this.idid).append(" "); - if (source != null) { - sb.append(ChatColor.DARK_PURPLE).append("from ").append(ChatColor.WHITE).append(source).append(" "); - } - if (comment != null) { - sb.append(ChatColor.GRAY).append("Comments:").append(ChatColor.WHITE).append(comment).append(" "); - } - sb.append(ChatColor.DARK_AQUA).append("[pli: "); - if (proxy < 1.0) { - sb.append(ChatColor.GREEN); - } else if (proxy < 2.0) { - sb.append(ChatColor.GOLD); - } else if (proxy < 3.0) { - sb.append(ChatColor.YELLOW); - } else { - sb.append(ChatColor.RED); - } - sb.append(proxy).append(ChatColor.DARK_AQUA).append("]").append(ChatColor.RESET); - - return sb.toString(); - } + /** + * @return the BSIP associated with this Proxy (usually a CIDR address). + */ + public BSIP getIP() { + if (this.iid == null && this.deferIid != null) { + this.iid = BSIP.byId(this.deferIid); + } + return this.iid; + } + + public String getContinent() { + return this.continent; + } + + public String getCountry() { + return this.country; + } + + public String getRegion() { + return this.region; + } + + public String getCity() { + return this.city; + } + + public String getPostal() { + return this.postal; + } + + public Double getLat() { + return this.lat; + } + + public Double getLon() { + return this.lon; + } + + public String getDomain() { + return this.domain; + } + + public String getProvider() { + return this.provider; + } + + public String getRegisteredAs() { + return this.registeredAs; + } + + public String getConnection() { + return this.connection; + } + + public float getProxy() { + return this.proxy; + } + + /** + * Updates the proxy "level", based on threshold could trigger bans. + * Triggers a dirty flag update. + * + * @param proxy the new proxy value. + */ + public void setProxy(float proxy) { + this.proxy = proxy; + dirtyIPData.offer(new WeakReference(this)); + } + + public String getSource() { + return this.source; + } + + /** + * Sets the string-value "source" of this proxy. Can be updated using + * this method, triggers a dirty flag update. + * + * @param source The new source. + */ + public void setSource(String source) { + this.source = source; + dirtyIPData.offer(new WeakReference(this)); + + } + + public String getComment() { + return this.comment; + } + + /** + * Sets the string-value "comment" for this proxy. Can be updated using + * this method, triggers a dirty flag update. + * + * @param comment The new comment + */ + public void setComment(String comment) { + this.comment = comment; + dirtyIPData.offer(new WeakReference(this)); + } + + /** + * Retrieve a specific Proxy by its identifier. + * + * @param idid the ID of the Proxy to retrieve + * @return the BSIPData object with that ID if found, otherwise null. + */ + public static BSIPData byId(long idid) { + if (allIPDataID.containsKey(idid)) { + return allIPDataID.get(idid); + } + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); + PreparedStatement getId = connection.prepareStatement( + "SELECT * FROM bs_ip_data WHERE idid = ?");) { + getId.setLong(1, idid); + try (ResultSet rs = getId.executeQuery();) { + if (rs.next()) { + BSIPData data = extractData(rs); + allIPDataID.put(idid, data); + return data; + } else { + BanStick.getPlugin().warning("Failed to retrieve IP Data by id: " + idid + " - not found"); + } + } + } catch (SQLException se) { + BanStick.getPlugin().severe("Retrieval of IP Data by ID failed: " + idid, se); + } + return null; + } + + /** + * Internal tool to create a BSIPData object from a ResultSet + * + * @param rs the ResultSet to unpack + * @return a BSIPData from that ResultSet + * @throws SQLException if something goes wrong + */ + private static BSIPData extractData(ResultSet rs) throws SQLException { + BSIPData data = new BSIPData(); + data.idid = rs.getLong(1); + data.deferIid = rs.getLong(2); + //data.iid = BSIP.byId(rs.getLong(2)); + data.createTime = rs.getTimestamp(3); + data.valid = rs.getBoolean(4); + data.continent = rs.getString(5); + data.country = rs.getString(6); + data.region = rs.getString(7); + data.city = rs.getString(8); + data.postal = rs.getString(9); + data.lat = rs.getDouble(10); + if (rs.wasNull()) { + data.lat = null; + } + data.lon = rs.getDouble(11); + if (rs.wasNull()) { + data.lon = null; + } + data.domain = rs.getString(12); + data.provider = rs.getString(13); + data.registeredAs = rs.getString(14); + data.connection = rs.getString(15); + data.proxy = rs.getFloat(16); + data.source = rs.getString(17); + data.comment = rs.getString(18); + data.dirty = false; + return data; + } + + /** + * As described in method header; finds the other non-same IPData records that + * geolocate to the same country/region/city pairing. + * + * @param source The IPData to use to seed the search + * @return A list of IPDatas in the same region, or nothing if none found. + */ + public static List bySameCity(BSIPData source) { + List found = new ArrayList<>(); + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); + PreparedStatement getSame = connection.prepareStatement( + "SELECT * FROM bs_ip_data WHERE country = ? and region = ? and city = ? and idid != ? and valid = true ORDER BY create_time");) { + getSame.setString(1, source.getCountry()); + getSame.setString(2, source.getRegion()); + getSame.setString(3, source.getCity()); + getSame.setLong(4, source.getId()); + try (ResultSet rs = getSame.executeQuery();) { + while (rs.next()) { + if (allIPDataID.containsKey(rs.getLong(1))) { + found.add(allIPDataID.get(rs.getLong(1))); + } + BSIPData data = extractData(rs); + allIPDataID.put(data.idid, data); + found.add(data); + } + if (found.isEmpty()) { + BanStick.getPlugin().debug("Found no other IP Data in same city as {0}", source); + } + } + } catch (SQLException se) { + BanStick.getPlugin().severe("Retrieval of same-city IP Data by IP Data failed: " + source, se); + } + return found; + } + + /** + * Returns only the latest valid BSIPData records by exact match with the IP + * + * @param ip The BSIP record to use for IPData retrieval + * @return the matching BSIPData or null if no match + */ + public static BSIPData byExactIP(BSIP ip) { + if (ip == null) { + BanStick.getPlugin().warning("Weird failure, byExactIP with null IP"); + return null; + } + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); + PreparedStatement getId = connection.prepareStatement( + "SELECT * FROM bs_ip_data WHERE iid = ? and valid = true ORDER BY create_time DESC LIMIT 1");) { + getId.setLong(1, ip.getId()); + try (ResultSet rs = getId.executeQuery();) { + if (rs.next()) { + if (allIPDataID.containsKey(rs.getLong(1))) { + return allIPDataID.get(rs.getLong(1)); + } + BSIPData data = extractData(rs); + allIPDataID.put(data.idid, data); + return data; + } else { + BanStick.getPlugin().warning("Failed to retrieve IP Data by exact IP: {0} - not found", ip); + } + } + } catch (SQLException se) { + BanStick.getPlugin().severe("Retrieval of IP Data by exact IP failed: " + ip, se); + } + return null; + } + + /** + * @return the average proxy value for BSIPData entries having the same registeredAs. + */ + public double getAverageForRegistrar() { + if (this.registeredAs == null) { + return 0; + } + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); + PreparedStatement getSame = connection.prepareStatement( + "SELECT avg(proxy) FROM bs_ip_data WHERE registered_as = ?");) { + getSame.setString(1, this.registeredAs); + try (ResultSet rs = getSame.executeQuery();) { + rs.next(); + return rs.getDouble(1); //returns 0 for no matches + } + } catch (SQLException se) { + BanStick.getPlugin().severe("Failed to load average proxy score for registrar " + + this.registeredAs, se); + return 0; + } + } + + /** + * Finds the first subnet that fully contains the given BSIP's IP/CIDR, if any. + * + * @param ip The BSIP record to base the lookup on + * @return The BSIPData record that contains the IP/CIDR, or null if none found. + */ + public static BSIPData byContainsIP(BSIP ip) { + try { + if (ip == null) { + BanStick.getPlugin().warning("Weird failure, byContainsIP with null IP"); + return null; + } + IPAddress address = ip.getIPAddress(); + if (address == null) { + BanStick.getPlugin().warning("Weird failure, no ip _in_ {0}", ip.toString()); + return null; + } + Integer cidr = address.getNetworkPrefixLength(); + if (cidr == null) { + cidr = address.isIPv4() ? 32 : 128; + } + List knownContains = BSIP.allMatching(address, cidr); + + if (knownContains != null) { + for (BSIP maybe : knownContains) { + BSIPData data = byExactIP(maybe); + if (data != null) { + return data; + } + } + } + BanStick.getPlugin().warning("No IPData records contain IP {0}", ip); + } catch (Exception e) { + BanStick.getPlugin().warning("Failure during IPData retrieval", e); + } + return null; + } + + /** + * Returns all BSIPData that relate to or contain the given IP/CIDR. + * + * @param ip The BSIP to use for matching. + * @return a list; empty if nothing found. + */ + public static List allByIP(BSIP ip) { + List returns = new ArrayList<>(); + try { + if (ip == null) { + BanStick.getPlugin().warning("Weird failure, allByIP with null IP"); + return returns; + } + IPAddress address = ip.getIPAddress(); + if (address == null) { + BanStick.getPlugin().warning("Weird failure, no ip _in_ {0}", ip.toString()); + return returns; + } + Integer cidr = address.getNetworkPrefixLength(); + if (cidr == null) { + cidr = address.isIPv4() ? 32 : 128; + } + List knownContains = BSIP.allMatching(address, cidr); + + if (knownContains != null) { + for (BSIP maybe : knownContains) { + BSIPData data = byExactIP(maybe); + if (data != null) { + returns.add(data); + } + } + } + if (returns.isEmpty()) { + BanStick.getPlugin().warning("No IPData records contain IP {0}", ip); + } + } catch (Exception e) { + BanStick.getPlugin().warning("Failure during IPData retrieval", e); + } + return returns; + } + + /** + * This does NOT check for prior existence. Must be managed elsewhere. + * + * @param ip The BSIP record to bind to. Must not be null. + * @param continent The continent where this IP is registered to + * @param country The country where this IP is registered to + * @param region The region where this IP is registered to + * @param city The city where this IP is registered to + * @param postal The postal / zip code where this IP is registered to + * @param lat The latitude + * @param lon The longitude + * @param domain The domain that maps to this IP / range + * @param provider The provider for this IP / range + * @param registeredAs Any registration information for this IP / range + * @param connectionSource The connection source for this IP / range + * @param proxy The likelihood this is a proxy -- higher number for more likelihood. + * Assumes 0 - no, 3 - likely, 4 - definite + * @param source The source of this record (Cloud9? Tor? IP-API?) + * @param comment Any comments recorded against the BSIPData. + * @return The new BSIPData if successful + */ + public static BSIPData create(BSIP ip, String continent, String country, String region, + String city, String postal, Double lat, Double lon, String domain, String provider, + String registeredAs, String connectionSource, float proxy, String source, String comment) { + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection()) { + BSIPData newData = new BSIPData(); + newData.valid = true; + newData.dirty = false; + newData.continent = continent; + newData.deferIid = ip.getId(); + newData.iid = ip; + newData.country = country; + newData.region = region; + newData.city = city; + newData.postal = postal; + newData.lat = lat; + newData.lon = lon; + newData.domain = domain; + newData.provider = provider; + newData.registeredAs = registeredAs; + newData.connection = connectionSource; + newData.proxy = proxy; + newData.source = source; + newData.comment = comment; + + try (PreparedStatement insertData = connection.prepareStatement( + "INSERT INTO bs_ip_data(iid, continent, country, region, city, postal, lat, lon, domain, provider, registered_as, connection, proxy, source, comment) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);", + Statement.RETURN_GENERATED_KEYS)) { + insertData.setLong(1, newData.iid.getId()); + if (newData.continent == null) { + insertData.setNull(2, Types.VARCHAR); + } else { + insertData.setString(2, newData.continent); + } + if (newData.country == null) { + insertData.setNull(3, Types.VARCHAR); + } else { + insertData.setString(3, newData.country); + } + if (newData.region == null) { + insertData.setNull(4, Types.VARCHAR); + } else { + insertData.setString(4, newData.region); + } + if (newData.region == null) { + insertData.setNull(5, Types.VARCHAR); + } else { + insertData.setString(5, newData.city); + } + if (newData.postal == null) { + insertData.setNull(6, Types.VARCHAR); + } else { + insertData.setString(6, newData.postal); + } + if (newData.lat == null) { + insertData.setNull(7, Types.DOUBLE); + } else { + insertData.setDouble(7, newData.lat); + } + if (newData.lon == null) { + insertData.setNull(8, Types.DOUBLE); + } else { + insertData.setDouble(8, newData.lon); + } + if (newData.domain == null) { + insertData.setNull(9, Types.VARCHAR); + } else { + insertData.setString(9, newData.domain); + } + if (newData.domain == null) { + insertData.setNull(10, Types.VARCHAR); + } else { + insertData.setString(10, newData.provider); + } + if (newData.registeredAs == null) { + insertData.setNull(11, Types.VARCHAR); + } else { + insertData.setString(11, newData.registeredAs); + } + if (newData.connection == null) { + insertData.setNull(12, Types.VARCHAR); + } else { + insertData.setString(12, newData.connection); + } + insertData.setFloat(13, newData.proxy); + if (newData.source == null) { + insertData.setNull(14, Types.VARCHAR); + } else { + insertData.setString(14, newData.source); + } + if (newData.comment == null) { + insertData.setNull(15, Types.VARCHAR); + } else { + insertData.setString(15, newData.comment); + } + insertData.execute(); + try (ResultSet rs = insertData.getGeneratedKeys()) { + if (rs.next()) { + newData.idid = rs.getLong(1); + } else { + BanStick.getPlugin().severe("No IDID returned on IP Data insert?!"); + return null; // no bid? error. + } + } + } + + allIPDataID.put(newData.idid, newData); + return newData; + } catch (SQLException se) { + BanStick.getPlugin().severe("Failed to create a new ip data record: ", se); + } + return null; + } + + /** + * Saves the BSBan; only for internal use. Outside code must use Flush(); + */ + private void save() { + if (!dirty) { + return; + } + this.dirty = false; // don't let anyone else in! + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); + PreparedStatement save = connection.prepareStatement( + "UPDATE bs_ip_data SET valid = ?, proxy = ?, source = ?, comment = ? WHERE idid = ?");) { + saveToStatement(save); + int effects = save.executeUpdate(); + if (effects == 0) { + BanStick.getPlugin().severe("Failed to save BSIPData or no update? " + this.idid); + } + } catch (SQLException se) { + BanStick.getPlugin().severe("Save of BSIPData failed!: ", se); + } + } + + /** + * Internal helper to map this BSIPData to a PreparedStatement for upsert + * + * @param save the PreparedStatement to fill + * @throws SQLException if something goes wrong. + */ + private void saveToStatement(PreparedStatement save) throws SQLException { + save.setBoolean(1, this.valid); + save.setFloat(2, this.proxy); + if (this.source == null) { + save.setNull(3, Types.VARCHAR); + } else { + save.setString(3, this.source); + } + if (this.comment == null) { + save.setNull(4, Types.VARCHAR); + } else { + save.setString(4, this.comment); + } + save.setLong(5, this.idid); + } + + /** + * Cleanly saves this IPData if necessary, and removes it from the references lists. + */ + public void flush() { + if (dirty) { + save(); + } + allIPDataID.remove(this.idid); + this.deferIid = null; + this.iid = null; + } + + /** + * Pulls from the dirty queue and commits updates to the backing DB in batches. + * Allows for high volume changes w/o swamping the DB with churn. + * + *

Note that inserts are direct, to ensure IDs and relationship consistency is upheld + */ + public static void saveDirty() { + int batchSize = 0; + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); + PreparedStatement save = connection.prepareStatement( + "UPDATE bs_ip_data SET valid = ?, proxy = ?, source = ?, comment = ? WHERE idid = ?");) { + while (!dirtyIPData.isEmpty()) { + WeakReference rdata = dirtyIPData.poll(); + BSIPData data = rdata.get(); + if (data != null && data.dirty) { + data.dirty = false; + data.saveToStatement(save); + save.addBatch(); + batchSize++; + } + if (batchSize > 0 && batchSize % 100 == 0) { + int[] batchRun = save.executeBatch(); + if (batchRun.length != batchSize) { + BanStick.getPlugin().severe("Some elements of the dirty batch didn't save? " + + batchSize + " vs " + batchRun.length); + } else { + BanStick.getPlugin().debug("IP Data batch: {0} saves", batchRun.length); + } + batchSize = 0; + } + } + if (batchSize > 0 && batchSize % 100 > 0) { + int[] batchRun = save.executeBatch(); + if (batchRun.length != batchSize) { + BanStick.getPlugin().severe("Some elements of the dirty batch didn't save? " + + batchSize + " vs " + batchRun.length); + } else { + BanStick.getPlugin().debug("IP Data batch: {0} saves", batchRun.length); + } + } + } catch (SQLException se) { + BanStick.getPlugin().severe("Save of BSIPData dirty batch failed!: ", se); + } + } + + /** + * Triggers a segmented preload of valid BSIPData segments. Items marked invalid are not loaded. + * Fills the cache with entries. + * + * @param offset Starting point + * @param limit How many to load + * @return The largest ID encountered during this load, or -1 if nothing loaded. + */ + public static long preload(long offset, int limit) { + long maxId = -1; + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); + PreparedStatement loadData = connection.prepareStatement( + "SELECT * FROM bs_ip_data WHERE valid = true AND idid > ? ORDER BY idid LIMIT ?");) { + loadData.setLong(1, offset); + loadData.setInt(2, limit); + try (ResultSet rs = loadData.executeQuery()) { + while (rs.next()) { + BSIPData data = extractData(rs); + if (!allIPDataID.containsKey(data.idid)) { + allIPDataID.put(data.idid, data); + } + if (data.idid > maxId) { + maxId = data.idid; + } + } + } + } catch (SQLException se) { + BanStick.getPlugin().severe("Failed during IPData preload, offset " + offset + + " limit " + limit, se); + } + return maxId; + + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(ChatColor.WHITE).append(getIP().toString()).append(" - "); + if (!valid) { + sb.append(ChatColor.RED).append("[Invalid] ").append(ChatColor.WHITE); + } + if (continent != null || country != null || region != null || city != null + || postal != null || lat != null || lon != null) { + sb.append(ChatColor.AQUA).append("Location: ").append(ChatColor.WHITE); + } + if (continent != null) { + sb.append(continent).append(", "); + } + if (country != null) { + sb.append(country).append(", "); + } + if (region != null) { + sb.append(region).append(", "); + } + if (city != null) { + sb.append(city).append(", "); + } + if (postal != null) { + sb.append(postal).append(", "); + } + if (lat != null || lon != null) { + sb.append(ChatColor.GRAY).append("[").append(ChatColor.WHITE).append(lat) + .append(ChatColor.GRAY).append(',').append(ChatColor.WHITE).append(lon) + .append(ChatColor.GRAY).append("] ").append(ChatColor.WHITE); + } + if (connection != null) { + sb.append(ChatColor.GRAY).append("Connection: ").append(ChatColor.WHITE) + .append(connection).append(" "); + } + if (domain != null) { + sb.append("(").append(domain).append(") "); + } + if (provider != null) { + sb.append(ChatColor.GRAY).append("Provider: ").append(ChatColor.WHITE) + .append(provider).append(" "); + } + if (registeredAs != null) { + sb.append(ChatColor.GRAY).append("Reg. As: ").append(ChatColor.WHITE) + .append(registeredAs).append(" "); + } + if (source != null) { + sb.append(ChatColor.DARK_PURPLE).append("from ").append(ChatColor.WHITE) + .append(source).append(" "); + } + if (comment != null) { + sb.append(ChatColor.GRAY).append("Comments:").append(ChatColor.WHITE) + .append(comment).append(" "); + } + sb.append(ChatColor.DARK_AQUA).append("[pli: "); + if (proxy < 1.0) { + sb.append(ChatColor.GREEN); + } else if (proxy < 2.0) { + sb.append(ChatColor.GOLD); + } else if (proxy < 3.0) { + sb.append(ChatColor.YELLOW); + } else { + sb.append(ChatColor.RED); + } + sb.append(proxy).append(ChatColor.DARK_AQUA).append("]").append(ChatColor.RESET); + + return sb.toString(); + } + + /** + * Generates a larger string of full details for this proxy + * + * @param showIPs indicate if IPs should be shown + * @return the String + */ + public String toFullString(boolean showIPs) { + if (showIPs) { + return toString(); + } + StringBuilder sb = new StringBuilder(); + sb.append(ChatColor.WHITE).append(getIP().toFullString(showIPs)).append(" - "); + if (!valid) { + sb.append(ChatColor.RED).append("[Invalid] ").append(ChatColor.WHITE); + } + sb.append("Proxy #").append(this.idid).append(" "); + if (source != null) { + sb.append(ChatColor.DARK_PURPLE).append("from ").append(ChatColor.WHITE).append(source).append(" "); + } + if (comment != null) { + sb.append(ChatColor.GRAY).append("Comments:").append(ChatColor.WHITE).append(comment).append(" "); + } + sb.append(ChatColor.DARK_AQUA).append("[pli: "); + if (proxy < 1.0) { + sb.append(ChatColor.GREEN); + } else if (proxy < 2.0) { + sb.append(ChatColor.GOLD); + } else if (proxy < 3.0) { + sb.append(ChatColor.YELLOW); + } else { + sb.append(ChatColor.RED); + } + sb.append(proxy).append(ChatColor.DARK_AQUA).append("]").append(ChatColor.RESET); + + return sb.toString(); + } } diff --git a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/data/BSIPs.java b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/data/BSIPs.java index e9d0235b0..45a4a411f 100644 --- a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/data/BSIPs.java +++ b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/data/BSIPs.java @@ -13,130 +13,131 @@ import java.util.Set; /** * BSIPs management structure. Helper / support methods. - * - * @author ProgrammerDan * + * @author ProgrammerDan */ public final class BSIPs { - private BSPlayer forPlayer; - - private List ipList; - private Set ipSet; - - private BSIPs() { } - - /** - * Get a BSIPs for a specific player, which provides access to an IP list for a player. - * - * @param newPlayer - * @return - */ - public static BSIPs onlyFor(BSPlayer newPlayer) { - BSIPs bsips = new BSIPs(); - bsips.forPlayer = newPlayer; - bsips.ipList = null; - bsips.ipSet = null; - return bsips; - } - - /** - * Release (perhaps on logout) all the ips for a particular BSIPs object. - * @param bsips the BSIPs to release. - */ - public static void release(BSIPs bsips) { - if (bsips != null) { - if (bsips.ipList != null) { - bsips.ipList.clear(); - } - bsips.ipList = null; - if (bsips.ipSet != null) { - bsips.ipSet.clear(); - } - bsips.ipSet = null; - bsips.forPlayer = null; - } - } - - /** - * @return the latest BSIP from this BSIPs - */ - public BSIP getLatest() { - if (ipList == null) { - fill(); - } - if (ipList.isEmpty()) { - return null; - } - return BSIP.byId(ipList.get(ipList.size() - 1)); - } - - /** - * @return the full set of BSIP for a particular individual. - */ - public List getAll() { - if (ipList == null) { - fill(); - } - List ret = new ArrayList<>(ipList.size()); - for (Long iid : ipList) { - ret.add(BSIP.byId(iid)); - } - - return ret; - } - - /** - * Sets the given IP as latest; reorders if already exists in the list. - * - * @param ip The ip to set as latest. - */ - public void setLatest(BSIP ip) { - if (ipList == null) { - fill(); - } - if (ipSet.add(ip.getId())) { - ipList.add(ip.getId()); - } else { - // find and move. - int idp = ipList.indexOf(ip.getId()); - if (idp < ipList.size() - 1) { // not last elem already - ipList.add(ipList.remove(idp)); - } - } - } + private BSPlayer forPlayer; - /** - * Internal fill of BSIP for a particular player. - */ - private void fill() { - if (ipList == null) { - ipList = new ArrayList<>(); - } - if (ipSet == null) { - ipSet = new HashSet<>(); - } + private List ipList; + private Set ipSet; + + private BSIPs() { + } + + /** + * Get a BSIPs for a specific player, which provides access to an IP list for a player. + * + * @param newPlayer + * @return + */ + public static BSIPs onlyFor(BSPlayer newPlayer) { + BSIPs bsips = new BSIPs(); + bsips.forPlayer = newPlayer; + bsips.ipList = null; + bsips.ipSet = null; + return bsips; + } + + /** + * Release (perhaps on logout) all the ips for a particular BSIPs object. + * + * @param bsips the BSIPs to release. + */ + public static void release(BSIPs bsips) { + if (bsips != null) { + if (bsips.ipList != null) { + bsips.ipList.clear(); + } + bsips.ipList = null; + if (bsips.ipSet != null) { + bsips.ipSet.clear(); + } + bsips.ipSet = null; + bsips.forPlayer = null; + } + } + + /** + * @return the latest BSIP from this BSIPs + */ + public BSIP getLatest() { + if (ipList == null) { + fill(); + } + if (ipList.isEmpty()) { + return null; + } + return BSIP.byId(ipList.get(ipList.size() - 1)); + } + + /** + * @return the full set of BSIP for a particular individual. + */ + public List getAll() { + if (ipList == null) { + fill(); + } + List ret = new ArrayList<>(ipList.size()); + for (Long iid : ipList) { + ret.add(BSIP.byId(iid)); + } + + return ret; + } + + /** + * Sets the given IP as latest; reorders if already exists in the list. + * + * @param ip The ip to set as latest. + */ + public void setLatest(BSIP ip) { + if (ipList == null) { + fill(); + } + if (ipSet.add(ip.getId())) { + ipList.add(ip.getId()); + } else { + // find and move. + int idp = ipList.indexOf(ip.getId()); + if (idp < ipList.size() - 1) { // not last elem already + ipList.add(ipList.remove(idp)); + } + } + } + + /** + * Internal fill of BSIP for a particular player. + */ + private void fill() { + if (ipList == null) { + ipList = new ArrayList<>(); + } + if (ipSet == null) { + ipSet = new HashSet<>(); + } + + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); + PreparedStatement getIDs = connection.prepareStatement(// Get all ids only, order by join time. + "SELECT DISTINCT i.iid FROM bs_ip i JOIN bs_session s ON i.iid = s.iid WHERE s.pid = ? ORDER BY s.join_time;");) { + // TODO: replace statement w/ view. + getIDs.setLong(1, forPlayer.getId()); + BanStick.getPlugin().debug("Filling IPs for {0}", forPlayer.getUUID()); + try (ResultSet rs = getIDs.executeQuery()) { + while (rs.next()) { + Long id = rs.getLong(1); + if (ipSet.add(id)) { + ipList.add(rs.getLong(1)); + } + } + if (ipList.isEmpty() || ipSet.isEmpty()) { + BanStick.getPlugin().warning("No IPs for " + forPlayer.getName()); + } + } + } catch (SQLException se) { + BanStick.getPlugin().severe("Failed to get list of IP ids", se); + } + } - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); - PreparedStatement getIDs = connection.prepareStatement(// Get all ids only, order by join time. - "SELECT DISTINCT i.iid FROM bs_ip i JOIN bs_session s ON i.iid = s.iid WHERE s.pid = ? ORDER BY s.join_time;");) { - // TODO: replace statement w/ view. - getIDs.setLong(1, forPlayer.getId()); - BanStick.getPlugin().debug("Filling IPs for {0}", forPlayer.getUUID()); - try (ResultSet rs = getIDs.executeQuery()) { - while (rs.next()) { - Long id = rs.getLong(1); - if (ipSet.add(id)) { - ipList.add(rs.getLong(1)); - } - } - if (ipList.isEmpty() || ipSet.isEmpty()) { - BanStick.getPlugin().warning("No IPs for " + forPlayer.getName()); - } - } - } catch (SQLException se) { - BanStick.getPlugin().severe("Failed to get list of IP ids", se); - } - } - } diff --git a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/data/BSLog.java b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/data/BSLog.java index 3ab1a105b..710026edd 100644 --- a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/data/BSLog.java +++ b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/data/BSLog.java @@ -13,138 +13,138 @@ import org.bukkit.scheduler.BukkitRunnable; /** * TODO: Make accessors * - *

Currently a depositor log for changes to player ban status. - * Not all bans have internal tracking so this external log ensures + *

Currently a depositor log for changes to player ban status. + * Not all bans have internal tracking so this external log ensures * that all bans made or removed are tracked. * This ONLY works with player bans. - * - * @author ProgrammerDan * + * @author ProgrammerDan */ public class BSLog extends BukkitRunnable { - private static ConcurrentLinkedQueue toSave = new ConcurrentLinkedQueue<>(); + private static ConcurrentLinkedQueue toSave = new ConcurrentLinkedQueue<>(); - private int maxBatch = 100; - private long delay = 100L; - private long period = 1200L; - - public BSLog(FileConfiguration config) { - config(config.getConfigurationSection("log")); - } - - private void config(ConfigurationSection config) { - if (config == null) { - return; - } - maxBatch = config.getInt("maxBatch", maxBatch); - delay = config.getLong("delay", delay); - period = config.getLong("period", period); - } - - public long getDelay() { - return delay; - } - - public long getPeriod() { - return period; - } - - @Override - public void run() { - // drain the queue into the DB in batches - if (toSave.isEmpty()) { - return; - } - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); - PreparedStatement saveEm = connection.prepareStatement( - "INSERT INTO bs_ban_log (pid, bid, action) VALUES (?, ?, ?);");) { - int curBatch = 0; - while (curBatch < this.maxBatch && !toSave.isEmpty()) { - LogEntry nextCheck = toSave.poll(); - if (nextCheck == null) { - break; // we're somehow empty already - } - saveEm.setLong(1, nextCheck.player); - saveEm.setLong(2, nextCheck.ban); - saveEm.setString(3, nextCheck.action.toString()); - saveEm.addBatch(); - curBatch ++; - } - int[] batchRun = saveEm.executeBatch(); - if (batchRun.length != curBatch) { - BanStick.getPlugin().severe("Some elements of the log batch didn't save? " - + curBatch + " vs " + batchRun.length); - } else { - BanStick.getPlugin().debug("Log batch: {0} saves", batchRun.length); - } + private int maxBatch = 100; + private long delay = 100L; + private long period = 1200L; - } catch (Exception e) { - BanStick.getPlugin().severe("Warning, lost elements, some log entries failed to save!", e); - } - } + public BSLog(FileConfiguration config) { + config(config.getConfigurationSection("log")); + } - /** - * Register a new log entry to eventually be committed. - * - * @param action the nature of the log -- BAN/UNBAN/CHANGE - * @param bsPlayer the BSPlayer whose ban is being updated - * @param bid the Ban (BSBan) - */ - public static void register(Action action, BSPlayer bsPlayer, BSBan...bid) { - switch (action) { - case BAN: - case UNBAN: - if (bid.length > 0) { - toSave.offer(new LogEntry(action, bsPlayer, bid[0])); - } - break; - case CHANGE: - if (bid.length > 0) { - toSave.offer(new LogEntry(Action.UNBAN, bsPlayer, bid[0])); - } - if (bid.length > 1) { - toSave.offer(new LogEntry(Action.BAN, bsPlayer, bid[1])); - } - break; - default: - break; - } - } - - /** - * Attempts to shut down this log, but first attempts to force a clear of all - * logged entries. - */ - public void disable() { - while (!toSave.isEmpty()) { - run(); - } - } + private void config(ConfigurationSection config) { + if (config == null) { + return; + } + maxBatch = config.getInt("maxBatch", maxBatch); + delay = config.getLong("delay", delay); + period = config.getLong("period", period); + } - /** - * Internal enum for type of ban. - */ - enum Action { - BAN, - UNBAN, - CHANGE - } - - /** - * Internal LogEntry container. On creation just strips down to IDs. - */ - static class LogEntry { - Action action; - long ban; - long player; - Date time; - - LogEntry(Action action, BSPlayer player, BSBan ban) { - this.action = action; - this.ban = ban.getId(); - this.player = player.getId(); - this.time = new Date(); - } - } + public long getDelay() { + return delay; + } + + public long getPeriod() { + return period; + } + + @Override + public void run() { + // drain the queue into the DB in batches + if (toSave.isEmpty()) { + return; + } + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); + PreparedStatement saveEm = connection.prepareStatement( + "INSERT INTO bs_ban_log (pid, bid, action) VALUES (?, ?, ?);");) { + int curBatch = 0; + while (curBatch < this.maxBatch && !toSave.isEmpty()) { + LogEntry nextCheck = toSave.poll(); + if (nextCheck == null) { + break; // we're somehow empty already + } + saveEm.setLong(1, nextCheck.player); + saveEm.setLong(2, nextCheck.ban); + saveEm.setString(3, nextCheck.action.toString()); + saveEm.addBatch(); + curBatch++; + } + int[] batchRun = saveEm.executeBatch(); + if (batchRun.length != curBatch) { + BanStick.getPlugin().severe("Some elements of the log batch didn't save? " + + curBatch + " vs " + batchRun.length); + } else { + BanStick.getPlugin().debug("Log batch: {0} saves", batchRun.length); + } + + } catch (Exception e) { + BanStick.getPlugin().severe("Warning, lost elements, some log entries failed to save!", e); + } + } + + /** + * Register a new log entry to eventually be committed. + * + * @param action the nature of the log -- BAN/UNBAN/CHANGE + * @param bsPlayer the BSPlayer whose ban is being updated + * @param bid the Ban (BSBan) + */ + public static void register(Action action, BSPlayer bsPlayer, BSBan... bid) { + switch (action) { + case BAN: + case UNBAN: + if (bid.length > 0) { + toSave.offer(new LogEntry(action, bsPlayer, bid[0])); + } + break; + case CHANGE: + if (bid.length > 0) { + toSave.offer(new LogEntry(Action.UNBAN, bsPlayer, bid[0])); + } + if (bid.length > 1) { + toSave.offer(new LogEntry(Action.BAN, bsPlayer, bid[1])); + } + break; + default: + break; + } + } + + /** + * Attempts to shut down this log, but first attempts to force a clear of all + * logged entries. + */ + public void disable() { + while (!toSave.isEmpty()) { + run(); + } + } + + /** + * Internal enum for type of ban. + */ + enum Action { + BAN, + UNBAN, + CHANGE + } + + /** + * Internal LogEntry container. On creation just strips down to IDs. + */ + static class LogEntry { + + Action action; + long ban; + long player; + Date time; + + LogEntry(Action action, BSPlayer player, BSBan ban) { + this.action = action; + this.ban = ban.getId(); + this.player = player.getId(); + this.time = new Date(); + } + } } diff --git a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/data/BSPlayer.java b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/data/BSPlayer.java index 5e7dbcf22..89d064974 100644 --- a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/data/BSPlayer.java +++ b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/data/BSPlayer.java @@ -28,744 +28,745 @@ import org.bukkit.entity.Player; * Represents player DAO logic. * * @author ProgrammerDan - * */ public final class BSPlayer { - private static Map allPlayersID = new HashMap<>(); - private static Map allPlayersUUID = new HashMap<>(); - private static ConcurrentLinkedQueue> dirtyPlayers = new ConcurrentLinkedQueue<>(); + private static Map allPlayersID = new HashMap<>(); + private static Map allPlayersUUID = new HashMap<>(); + private static ConcurrentLinkedQueue> dirtyPlayers = new ConcurrentLinkedQueue<>(); - private long pid; - private String name; - private UUID uuid; - private Timestamp firstAdd; - private Long deferBid; - private BSBan bid; - private Timestamp ipPardonTime; - private Timestamp proxyPardonTime; - private Timestamp sharedPardonTime; - private boolean dirty; + private long pid; + private String name; + private UUID uuid; + private Timestamp firstAdd; + private Long deferBid; + private BSBan bid; + private Timestamp ipPardonTime; + private Timestamp proxyPardonTime; + private Timestamp sharedPardonTime; + private boolean dirty; - private transient BSSessions allSessions; - private transient BSIPs allIPs; - private transient BSShares allShares; - private transient BSExclusions allExclusions; + private transient BSSessions allSessions; + private transient BSIPs allIPs; + private transient BSShares allShares; + private transient BSExclusions allExclusions; - private BSPlayer() { } - - public long getId() { - return pid; - } + private BSPlayer() { + } - public String getName() { - return name; - } + public long getId() { + return pid; + } - /** - * Set the player name. Player names can change, so... sets this as dirty for an update task. - * @param name the new player name. - */ - public void setName(String name) { - this.name = name; - this.dirty = true; - dirtyPlayers.offer(new WeakReference<>(this)); - } + public String getName() { + return name; + } - public UUID getUUID() { - return uuid; - } + /** + * Set the player name. Player names can change, so... sets this as dirty for an update task. + * + * @param name the new player name. + */ + public void setName(String name) { + this.name = name; + this.dirty = true; + dirtyPlayers.offer(new WeakReference<>(this)); + } - public Date getFirstAdd() { - return firstAdd; - } + public UUID getUUID() { + return uuid; + } - public Date getIPPardonTime() { - return ipPardonTime; - } + public Date getFirstAdd() { + return firstAdd; + } - /** - * Updates the time where, after that time, all IP bans will expire. - * - * @param pardon Date for IP bans to expire, or null to remove the pardon. - */ - public void setIPPardonTime(Date pardon) { - this.ipPardonTime = pardon != null ? new Timestamp(pardon.getTime()) : null; - this.dirty = true; - dirtyPlayers.offer(new WeakReference<>(this)); - } + public Date getIPPardonTime() { + return ipPardonTime; + } - public Date getProxyPardonTime() { - return proxyPardonTime; - } + /** + * Updates the time where, after that time, all IP bans will expire. + * + * @param pardon Date for IP bans to expire, or null to remove the pardon. + */ + public void setIPPardonTime(Date pardon) { + this.ipPardonTime = pardon != null ? new Timestamp(pardon.getTime()) : null; + this.dirty = true; + dirtyPlayers.offer(new WeakReference<>(this)); + } - /** - * Updates the time where, after that time, all proxy bans will expire. - * - * @param pardon Date for Proxy bans to expire, or null to remove the pardon. - */ - public void setProxyPardonTime(Date pardon) { - this.proxyPardonTime = pardon != null ? new Timestamp(pardon.getTime()) : null; - this.dirty = true; - dirtyPlayers.offer(new WeakReference<>(this)); - } + public Date getProxyPardonTime() { + return proxyPardonTime; + } - public Date getSharedPardonTime() { - return sharedPardonTime; - } + /** + * Updates the time where, after that time, all proxy bans will expire. + * + * @param pardon Date for Proxy bans to expire, or null to remove the pardon. + */ + public void setProxyPardonTime(Date pardon) { + this.proxyPardonTime = pardon != null ? new Timestamp(pardon.getTime()) : null; + this.dirty = true; + dirtyPlayers.offer(new WeakReference<>(this)); + } - /** - * Updates the time where, after that time, all share bans will expire. - * - * @param pardon Date for Share bans to expire, or null to remove the pardon. - */ - public void setSharedPardonTime(Date pardon) { - this.sharedPardonTime = pardon != null ? new Timestamp(pardon.getTime()) : null; - this.dirty = true; - dirtyPlayers.offer(new WeakReference<>(this)); - } + public Date getSharedPardonTime() { + return sharedPardonTime; + } - /** - * Gets the principle active ban for this player. - * - * @return Current active BSBan, if any. - */ - public BSBan getBan() { - if (this.bid == null && this.deferBid != null) { - this.bid = BSBan.byId(this.deferBid); - } - return this.bid; - } + /** + * Updates the time where, after that time, all share bans will expire. + * + * @param pardon Date for Share bans to expire, or null to remove the pardon. + */ + public void setSharedPardonTime(Date pardon) { + this.sharedPardonTime = pardon != null ? new Timestamp(pardon.getTime()) : null; + this.dirty = true; + dirtyPlayers.offer(new WeakReference<>(this)); + } - /** - * Sets the principle active ban for this player. - * - * @param banId The new ban to apply, or null to clear. - */ - public void setBan(BSBan banId) { - if (banId == null && this.bid != null) { - BSLog.register(BSLog.Action.UNBAN, this, this.bid); - } else if (banId != null && this.bid == null) { - BSLog.register(BSLog.Action.BAN, this, banId); - } else if (banId != null && this.bid != null && banId.getId() != this.bid.getId()) { - BSLog.register(BSLog.Action.CHANGE, this, this.bid, banId); - } else if (banId != null && this.bid != null && banId.getId() == this.bid.getId()) { - return; // no change. - } - this.bid = banId; - this.deferBid = (banId == null ? null : banId.getId()); - this.dirty = true; - dirtyPlayers.offer(new WeakReference<>(this)); + /** + * Gets the principle active ban for this player. + * + * @return Current active BSBan, if any. + */ + public BSBan getBan() { + if (this.bid == null && this.deferBid != null) { + this.bid = BSBan.byId(this.deferBid); + } + return this.bid; + } - } + /** + * Sets the principle active ban for this player. + * + * @param banId The new ban to apply, or null to clear. + */ + public void setBan(BSBan banId) { + if (banId == null && this.bid != null) { + BSLog.register(BSLog.Action.UNBAN, this, this.bid); + } else if (banId != null && this.bid == null) { + BSLog.register(BSLog.Action.BAN, this, banId); + } else if (banId != null && this.bid != null && banId.getId() != this.bid.getId()) { + BSLog.register(BSLog.Action.CHANGE, this, this.bid, banId); + } else if (banId != null && this.bid != null && banId.getId() == this.bid.getId()) { + return; // no change. + } + this.bid = banId; + this.deferBid = (banId == null ? null : banId.getId()); + this.dirty = true; + dirtyPlayers.offer(new WeakReference<>(this)); - /** - * This is the heart of the tracking. If a session is already active, ends it; - * Starts a session for this player, associates that session with the current IP data, - * checks for new shares and any other stuff like that. - * - * @param player The player whose session to start - * @param sessionStart The Date that the session began - */ - public void startSession(final Player player, Date sessionStart) { - BSSession latest = this.allSessions.getLatest(); - if (latest != null && !latest.isEnded()) { - latest.setLeaveTime(sessionStart); - } - InetSocketAddress isa = player.getAddress(); - InetAddress ina = isa != null ? isa.getAddress() : null; - if (ina != null) { - BSIP ip = BanStickDatabaseHandler.getInstance().getOrCreateIP(ina); - this.allIPs.setLatest(ip); - latest = this.allSessions.startNew(ip, sessionStart); - this.allShares.check(latest); - } else { - BanStick.getPlugin().severe("Start session of BSPlayer failed, no IP retrievable! Player: " + player); - } - } + } - /** - * If session is active, end it. Starts a new session, when IP is known. - * Checks for new shares. - * - * @param ip The exact IP to use - * @param sessionStart the session start time - */ - public void startSession(BSIP ip, Date sessionStart) { - BSSession latest = this.allSessions.getLatest(); - if (latest != null && !latest.isEnded()) { - latest.setLeaveTime(sessionStart); - } - this.allIPs.setLatest(ip); - latest = this.allSessions.startNew(ip, sessionStart); - this.allShares.check(latest); - } + /** + * This is the heart of the tracking. If a session is already active, ends it; + * Starts a session for this player, associates that session with the current IP data, + * checks for new shares and any other stuff like that. + * + * @param player The player whose session to start + * @param sessionStart The Date that the session began + */ + public void startSession(final Player player, Date sessionStart) { + BSSession latest = this.allSessions.getLatest(); + if (latest != null && !latest.isEnded()) { + latest.setLeaveTime(sessionStart); + } + InetSocketAddress isa = player.getAddress(); + InetAddress ina = isa != null ? isa.getAddress() : null; + if (ina != null) { + BSIP ip = BanStickDatabaseHandler.getInstance().getOrCreateIP(ina); + this.allIPs.setLatest(ip); + latest = this.allSessions.startNew(ip, sessionStart); + this.allShares.check(latest); + } else { + BanStick.getPlugin().severe("Start session of BSPlayer failed, no IP retrievable! Player: " + player); + } + } - /** - * Ends the latest session for this player. Player-centric exposed focus for BSSessions's endLatest - * - * @param sessionEnd Date to end this player's current session. - */ - public void endSession(Date sessionEnd) { - this.allSessions.endLatest(sessionEnd); - } + /** + * If session is active, end it. Starts a new session, when IP is known. + * Checks for new shares. + * + * @param ip The exact IP to use + * @param sessionStart the session start time + */ + public void startSession(BSIP ip, Date sessionStart) { + BSSession latest = this.allSessions.getLatest(); + if (latest != null && !latest.isEnded()) { + latest.setLeaveTime(sessionStart); + } + this.allIPs.setLatest(ip); + latest = this.allSessions.startNew(ip, sessionStart); + this.allShares.check(latest); + } - /** - * Gets the latest session for this player. - * - * @return The latest BSSession object - */ - public BSSession getLatestSession() { - return this.allSessions.getLatest(); - } + /** + * Ends the latest session for this player. Player-centric exposed focus for BSSessions's endLatest + * + * @param sessionEnd Date to end this player's current session. + */ + public void endSession(Date sessionEnd) { + this.allSessions.endLatest(sessionEnd); + } - /** - * Gets all sessions for this player - * - * @return A list of all BSSessions for this player - */ - public List getAllSessions() { - return this.allSessions.getAll(); - } + /** + * Gets the latest session for this player. + * + * @return The latest BSSession object + */ + public BSSession getLatestSession() { + return this.allSessions.getLatest(); + } - /** - * This leverages a fun queue of WeakReferences, where if a player is forcibly flush()'d we don't care, - * or if a player is in the queue more then once we don't care, b/c we only save a dirty player once; - * and since we all store references and no copies, everything is nice and synchronized. - * - */ - public static void saveDirty() { - int batchSize = 0; - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); - PreparedStatement savePlayer = connection.prepareStatement( - "UPDATE bs_player SET ip_pardon_time = ?, proxy_pardon_time = ?, shared_pardon_time = ?, bid = ?, name = ? WHERE pid = ?");) { - while (!dirtyPlayers.isEmpty()) { - WeakReference rplayer = dirtyPlayers.poll(); - BSPlayer player = rplayer.get(); - if (player != null && player.dirty) { - player.dirty = false; - player.saveToStatement(savePlayer); - savePlayer.addBatch(); - batchSize ++; - } - if (batchSize > 0 && batchSize % 100 == 0) { - int[] batchRun = savePlayer.executeBatch(); - if (batchRun.length != batchSize) { - BanStick.getPlugin().severe("Some elements of the dirt batch didn't save? " - + batchSize + " vs " + batchRun.length); - } else { - BanStick.getPlugin().debug("Player batch: {0} saves", batchRun.length); - } - batchSize = 0; - } - } - if (batchSize > 0 && batchSize % 100 > 0) { - int[] batchRun = savePlayer.executeBatch(); - if (batchRun.length != batchSize) { - BanStick.getPlugin().severe("Some elements of the dirt batch didn't save? " - + batchSize + " vs " + batchRun.length); - } else { - BanStick.getPlugin().debug("Player batch: {0} saves", batchRun.length); - } - } - } catch (SQLException se) { - BanStick.getPlugin().severe("Save of BSPlayer dirty batch failed!: ", se); - } - } + /** + * Gets all sessions for this player + * + * @return A list of all BSSessions for this player + */ + public List getAllSessions() { + return this.allSessions.getAll(); + } - /** - * Saves the BSPlayer; only for internal use. Outside code must use Flush(); - */ - private void save() { - if (!dirty) { - return; - } - this.dirty = false; // don't let anyone else in! - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); - PreparedStatement savePlayer = connection.prepareStatement( - "UPDATE bs_player SET ip_pardon_time = ?, proxy_pardon_time = ?, shared_pardon_time = ?, bid = ?, name = ? WHERE pid = ?");) { - saveToStatement(savePlayer); - int effects = savePlayer.executeUpdate(); - if (effects == 0) { - BanStick.getPlugin().severe("Failed to save BSPlayer or no update? " + this.pid); - } - } catch (SQLException se) { - BanStick.getPlugin().severe("Save of BSPlayer failed!: ", se); - } - } + /** + * This leverages a fun queue of WeakReferences, where if a player is forcibly flush()'d we don't care, + * or if a player is in the queue more then once we don't care, b/c we only save a dirty player once; + * and since we all store references and no copies, everything is nice and synchronized. + */ + public static void saveDirty() { + int batchSize = 0; + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); + PreparedStatement savePlayer = connection.prepareStatement( + "UPDATE bs_player SET ip_pardon_time = ?, proxy_pardon_time = ?, shared_pardon_time = ?, bid = ?, name = ? WHERE pid = ?");) { + while (!dirtyPlayers.isEmpty()) { + WeakReference rplayer = dirtyPlayers.poll(); + BSPlayer player = rplayer.get(); + if (player != null && player.dirty) { + player.dirty = false; + player.saveToStatement(savePlayer); + savePlayer.addBatch(); + batchSize++; + } + if (batchSize > 0 && batchSize % 100 == 0) { + int[] batchRun = savePlayer.executeBatch(); + if (batchRun.length != batchSize) { + BanStick.getPlugin().severe("Some elements of the dirt batch didn't save? " + + batchSize + " vs " + batchRun.length); + } else { + BanStick.getPlugin().debug("Player batch: {0} saves", batchRun.length); + } + batchSize = 0; + } + } + if (batchSize > 0 && batchSize % 100 > 0) { + int[] batchRun = savePlayer.executeBatch(); + if (batchRun.length != batchSize) { + BanStick.getPlugin().severe("Some elements of the dirt batch didn't save? " + + batchSize + " vs " + batchRun.length); + } else { + BanStick.getPlugin().debug("Player batch: {0} saves", batchRun.length); + } + } + } catch (SQLException se) { + BanStick.getPlugin().severe("Save of BSPlayer dirty batch failed!: ", se); + } + } - private void saveToStatement(PreparedStatement savePlayer) throws SQLException { - if (this.ipPardonTime == null) { - savePlayer.setNull(1, Types.TIMESTAMP); - } else { - savePlayer.setTimestamp(1, this.ipPardonTime); - } - if (this.proxyPardonTime == null) { - savePlayer.setNull(2, Types.TIMESTAMP); - } else { - savePlayer.setTimestamp(2, this.proxyPardonTime); - } - if (this.sharedPardonTime == null) { - savePlayer.setNull(3, Types.TIMESTAMP); - } else { - savePlayer.setTimestamp(3, this.sharedPardonTime); - } - if (this.getBan() == null) { - savePlayer.setNull(4, Types.BIGINT); - } else { - savePlayer.setLong(4, this.bid.getId()); - } - if (this.name == null) { - savePlayer.setNull(5, Types.VARCHAR); - } else { - savePlayer.setString(5, this.name); - } - savePlayer.setLong(6, this.pid); - } + /** + * Saves the BSPlayer; only for internal use. Outside code must use Flush(); + */ + private void save() { + if (!dirty) { + return; + } + this.dirty = false; // don't let anyone else in! + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); + PreparedStatement savePlayer = connection.prepareStatement( + "UPDATE bs_player SET ip_pardon_time = ?, proxy_pardon_time = ?, shared_pardon_time = ?, bid = ?, name = ? WHERE pid = ?");) { + saveToStatement(savePlayer); + int effects = savePlayer.executeUpdate(); + if (effects == 0) { + BanStick.getPlugin().severe("Failed to save BSPlayer or no update? " + this.pid); + } + } catch (SQLException se) { + BanStick.getPlugin().severe("Save of BSPlayer failed!: ", se); + } + } - /** - * Cleanly saves this player if necessary, and removes it from the references lists. - */ - public void flush() { - if (dirty) { - save(); - } - BSSessions.release(this.allSessions); - BSIPs.release(this.allIPs); - BSShares.release(this.allShares); - allPlayersUUID.remove(this.uuid); - allPlayersID.remove(this.pid); - this.bid = null; - this.deferBid = null; - } + private void saveToStatement(PreparedStatement savePlayer) throws SQLException { + if (this.ipPardonTime == null) { + savePlayer.setNull(1, Types.TIMESTAMP); + } else { + savePlayer.setTimestamp(1, this.ipPardonTime); + } + if (this.proxyPardonTime == null) { + savePlayer.setNull(2, Types.TIMESTAMP); + } else { + savePlayer.setTimestamp(2, this.proxyPardonTime); + } + if (this.sharedPardonTime == null) { + savePlayer.setNull(3, Types.TIMESTAMP); + } else { + savePlayer.setTimestamp(3, this.sharedPardonTime); + } + if (this.getBan() == null) { + savePlayer.setNull(4, Types.BIGINT); + } else { + savePlayer.setLong(4, this.bid.getId()); + } + if (this.name == null) { + savePlayer.setNull(5, Types.VARCHAR); + } else { + savePlayer.setString(5, this.name); + } + savePlayer.setLong(6, this.pid); + } - /** - * Get player by UUID, pull from DB if not cached already. - * @param uuid Gets a BSPlayer record by uuid. - * @return BSPlayer matching the uuid or null if not found - */ - public static BSPlayer byUUID(final UUID uuid) { - if (allPlayersUUID.containsKey(uuid)) { - return allPlayersUUID.get(uuid); - } + /** + * Cleanly saves this player if necessary, and removes it from the references lists. + */ + public void flush() { + if (dirty) { + save(); + } + BSSessions.release(this.allSessions); + BSIPs.release(this.allIPs); + BSShares.release(this.allShares); + allPlayersUUID.remove(this.uuid); + allPlayersID.remove(this.pid); + this.bid = null; + this.deferBid = null; + } - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); - PreparedStatement getPlayer = connection.prepareStatement("SELECT * FROM bs_player WHERE uuid = ?");) { - getPlayer.setString(1, uuid.toString()); - try (ResultSet rs = getPlayer.executeQuery();) { - if (rs.next()) { - // found - long pid = rs.getLong(1); - BSPlayer player = null; - if (allPlayersID.containsKey(pid)) { - player = allPlayersID.get(pid); - return player; - } else { - player = new BSPlayer(); - player.pid = pid; - player.allSessions = BSSessions.onlyFor(player); - player.allExclusions = BSExclusions.onlyFor(player); - player.allIPs = BSIPs.onlyFor(player); - player.allShares = BSShares.onlyFor(player); - } - player.dirty = false; - player.name = rs.getString(2); - player.uuid = UUID.fromString(rs.getString(3)); - player.firstAdd = rs.getTimestamp(4); - long bid = rs.getLong(5); - if (!rs.wasNull()) { - player.deferBid = bid; - player.bid = null; - } - //player.bid = rs.wasNull() ? null : BSBan.byId(bid); - try { - player.ipPardonTime = rs.getTimestamp(6); - } catch (SQLException te) { - player.ipPardonTime = null; - } - try { - player.proxyPardonTime = rs.getTimestamp(7); - } catch (SQLException te) { - player.proxyPardonTime = null; - } - try { - player.sharedPardonTime = rs.getTimestamp(8); - } catch (SQLException te) { - player.sharedPardonTime = null; - } - allPlayersID.put(pid, player); - allPlayersUUID.put(player.uuid, player); - return player; - } else { - // not found - return null; // TODO: exception - } - } - } catch (SQLException se) { - BanStick.getPlugin().severe("Failed to execute query to get player: " + uuid.toString(), se); - } - return null; //TODO: exception - } + /** + * Get player by UUID, pull from DB if not cached already. + * + * @param uuid Gets a BSPlayer record by uuid. + * @return BSPlayer matching the uuid or null if not found + */ + public static BSPlayer byUUID(final UUID uuid) { + if (allPlayersUUID.containsKey(uuid)) { + return allPlayersUUID.get(uuid); + } - /** - * Direct lookup for a BSPlayer by database ID - * - * @param pid The Player ID to use in the lookup - * @return The Player found, or null if not found - */ - public static BSPlayer byId(final long pid) { - if (allPlayersID.containsKey(pid)) { - return allPlayersID.get(pid); - } + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); + PreparedStatement getPlayer = connection.prepareStatement("SELECT * FROM bs_player WHERE uuid = ?");) { + getPlayer.setString(1, uuid.toString()); + try (ResultSet rs = getPlayer.executeQuery();) { + if (rs.next()) { + // found + long pid = rs.getLong(1); + BSPlayer player = null; + if (allPlayersID.containsKey(pid)) { + player = allPlayersID.get(pid); + return player; + } else { + player = new BSPlayer(); + player.pid = pid; + player.allSessions = BSSessions.onlyFor(player); + player.allExclusions = BSExclusions.onlyFor(player); + player.allIPs = BSIPs.onlyFor(player); + player.allShares = BSShares.onlyFor(player); + } + player.dirty = false; + player.name = rs.getString(2); + player.uuid = UUID.fromString(rs.getString(3)); + player.firstAdd = rs.getTimestamp(4); + long bid = rs.getLong(5); + if (!rs.wasNull()) { + player.deferBid = bid; + player.bid = null; + } + //player.bid = rs.wasNull() ? null : BSBan.byId(bid); + try { + player.ipPardonTime = rs.getTimestamp(6); + } catch (SQLException te) { + player.ipPardonTime = null; + } + try { + player.proxyPardonTime = rs.getTimestamp(7); + } catch (SQLException te) { + player.proxyPardonTime = null; + } + try { + player.sharedPardonTime = rs.getTimestamp(8); + } catch (SQLException te) { + player.sharedPardonTime = null; + } + allPlayersID.put(pid, player); + allPlayersUUID.put(player.uuid, player); + return player; + } else { + // not found + return null; // TODO: exception + } + } + } catch (SQLException se) { + BanStick.getPlugin().severe("Failed to execute query to get player: " + uuid.toString(), se); + } + return null; //TODO: exception + } - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); - PreparedStatement getPlayer = connection.prepareStatement("SELECT * FROM bs_player WHERE pid = ?");) { - getPlayer.setLong(1, pid); - try (ResultSet rs = getPlayer.executeQuery();) { - if (rs.next()) { - // found - BSPlayer player = null; - player = new BSPlayer(); - player.dirty = false; - player.pid = pid; - player.allSessions = BSSessions.onlyFor(player); - player.allExclusions = BSExclusions.onlyFor(player); - player.allIPs = BSIPs.onlyFor(player); - player.allShares = BSShares.onlyFor(player); - player.name = rs.getString(2); - player.uuid = UUID.fromString(rs.getString(3)); - player.firstAdd = rs.getTimestamp(4); - long bid = rs.getLong(5); - if (!rs.wasNull()) { - player.deferBid = bid; - player.bid = null; - } - //player.bid = rs.wasNull() ? null : BSBan.byId(bid); - try { - player.ipPardonTime = rs.getTimestamp(6); - } catch (SQLException te) { - player.ipPardonTime = null; - } - try { - player.proxyPardonTime = rs.getTimestamp(7); - } catch (SQLException te) { - player.proxyPardonTime = null; - } - try { - player.sharedPardonTime = rs.getTimestamp(8); - } catch (SQLException te) { - player.sharedPardonTime = null; - } - allPlayersID.put(pid, player); - allPlayersUUID.put(player.uuid, player); - return player; - } else { - // not found - return null; // TODO: exception - } - } - } catch (SQLException se) { - BanStick.getPlugin().severe("Failed to execute query to get player: " + pid, se); - } - return null; // TODO: exception - } + /** + * Direct lookup for a BSPlayer by database ID + * + * @param pid The Player ID to use in the lookup + * @return The Player found, or null if not found + */ + public static BSPlayer byId(final long pid) { + if (allPlayersID.containsKey(pid)) { + return allPlayersID.get(pid); + } - /** - * Create a new player from the Bukkit object - * - * @param player The player object to use - * @return the BSPlayer created from the player, or null - */ - public static BSPlayer create(final Player player) { - if (allPlayersUUID.containsKey(player.getUniqueId())) { - return allPlayersUUID.get(player.getUniqueId()); - } - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection()) { - BSPlayer newPlayer = new BSPlayer(); - newPlayer.dirty = false; - newPlayer.name = player.getDisplayName(); - newPlayer.uuid = player.getUniqueId(); - newPlayer.firstAdd = new Timestamp(Calendar.getInstance().getTimeInMillis()); + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); + PreparedStatement getPlayer = connection.prepareStatement("SELECT * FROM bs_player WHERE pid = ?");) { + getPlayer.setLong(1, pid); + try (ResultSet rs = getPlayer.executeQuery();) { + if (rs.next()) { + // found + BSPlayer player = null; + player = new BSPlayer(); + player.dirty = false; + player.pid = pid; + player.allSessions = BSSessions.onlyFor(player); + player.allExclusions = BSExclusions.onlyFor(player); + player.allIPs = BSIPs.onlyFor(player); + player.allShares = BSShares.onlyFor(player); + player.name = rs.getString(2); + player.uuid = UUID.fromString(rs.getString(3)); + player.firstAdd = rs.getTimestamp(4); + long bid = rs.getLong(5); + if (!rs.wasNull()) { + player.deferBid = bid; + player.bid = null; + } + //player.bid = rs.wasNull() ? null : BSBan.byId(bid); + try { + player.ipPardonTime = rs.getTimestamp(6); + } catch (SQLException te) { + player.ipPardonTime = null; + } + try { + player.proxyPardonTime = rs.getTimestamp(7); + } catch (SQLException te) { + player.proxyPardonTime = null; + } + try { + player.sharedPardonTime = rs.getTimestamp(8); + } catch (SQLException te) { + player.sharedPardonTime = null; + } + allPlayersID.put(pid, player); + allPlayersUUID.put(player.uuid, player); + return player; + } else { + // not found + return null; // TODO: exception + } + } + } catch (SQLException se) { + BanStick.getPlugin().severe("Failed to execute query to get player: " + pid, se); + } + return null; // TODO: exception + } - try (PreparedStatement insertPlayer = connection.prepareStatement( - "INSERT INTO bs_player(name, uuid, first_add) VALUES (?, ?, ?);", - Statement.RETURN_GENERATED_KEYS)) { - insertPlayer.setString(1, newPlayer.name); - insertPlayer.setString(2, newPlayer.uuid.toString()); - insertPlayer.setTimestamp(3, newPlayer.firstAdd); - insertPlayer.execute(); - try (ResultSet rs = insertPlayer.getGeneratedKeys()) { - if (rs.next()) { - newPlayer.pid = rs.getLong(1); - } else { - BanStick.getPlugin().severe("No PID returned on player insert?!"); - return null; // no pid? error. - } - } - } + /** + * Create a new player from the Bukkit object + * + * @param player The player object to use + * @return the BSPlayer created from the player, or null + */ + public static BSPlayer create(final Player player) { + if (allPlayersUUID.containsKey(player.getUniqueId())) { + return allPlayersUUID.get(player.getUniqueId()); + } + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection()) { + BSPlayer newPlayer = new BSPlayer(); + newPlayer.dirty = false; + newPlayer.name = player.getDisplayName(); + newPlayer.uuid = player.getUniqueId(); + newPlayer.firstAdd = new Timestamp(Calendar.getInstance().getTimeInMillis()); - newPlayer.allSessions = BSSessions.onlyFor(newPlayer); - newPlayer.allIPs = BSIPs.onlyFor(newPlayer); - newPlayer.allShares = BSShares.onlyFor(newPlayer); - newPlayer.allExclusions = BSExclusions.onlyFor(newPlayer); + try (PreparedStatement insertPlayer = connection.prepareStatement( + "INSERT INTO bs_player(name, uuid, first_add) VALUES (?, ?, ?);", + Statement.RETURN_GENERATED_KEYS)) { + insertPlayer.setString(1, newPlayer.name); + insertPlayer.setString(2, newPlayer.uuid.toString()); + insertPlayer.setTimestamp(3, newPlayer.firstAdd); + insertPlayer.execute(); + try (ResultSet rs = insertPlayer.getGeneratedKeys()) { + if (rs.next()) { + newPlayer.pid = rs.getLong(1); + } else { + BanStick.getPlugin().severe("No PID returned on player insert?!"); + return null; // no pid? error. + } + } + } - allPlayersID.put(newPlayer.pid, newPlayer); - allPlayersUUID.put(newPlayer.uuid, newPlayer); - return newPlayer; - } catch (SQLException se) { - BanStick.getPlugin().severe("Failed to create a new player record: ", se); - return null; - } - } + newPlayer.allSessions = BSSessions.onlyFor(newPlayer); + newPlayer.allIPs = BSIPs.onlyFor(newPlayer); + newPlayer.allShares = BSShares.onlyFor(newPlayer); + newPlayer.allExclusions = BSExclusions.onlyFor(newPlayer); - /** - * TODO: this is empty. - * - * @param playerId The player's UUID to create. - * @return null; this is a NO-OP. Use different method, providing player name. - */ - public static BSPlayer create(UUID playerId) { - return null; - } + allPlayersID.put(newPlayer.pid, newPlayer); + allPlayersUUID.put(newPlayer.uuid, newPlayer); + return newPlayer; + } catch (SQLException se) { + BanStick.getPlugin().severe("Failed to create a new player record: ", se); + return null; + } + } - /** - * Creates, if needed, a new BSPlayer and inserts it into the database. Sets up related DAOs. - * - * @param playerId the Player's UUID to create - * @param name the Player's Name to create - * @return the new BSPlayer, or an existing player if they already exist, or null if failure. - */ - public static BSPlayer create(UUID playerId, String name) { - if (allPlayersUUID.containsKey(playerId)) { - return allPlayersUUID.get(playerId); - } - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection()) { - BSPlayer newPlayer = new BSPlayer(); - newPlayer.dirty = false; - newPlayer.name = name; - newPlayer.uuid = playerId; - newPlayer.firstAdd = new Timestamp(Calendar.getInstance().getTimeInMillis()); + /** + * TODO: this is empty. + * + * @param playerId The player's UUID to create. + * @return null; this is a NO-OP. Use different method, providing player name. + */ + public static BSPlayer create(UUID playerId) { + return null; + } - try (PreparedStatement insertPlayer = connection.prepareStatement( - "INSERT INTO bs_player(name, uuid, first_add) VALUES (?, ?, ?);", - Statement.RETURN_GENERATED_KEYS)) { - if (newPlayer.name == null) { - insertPlayer.setNull(1, Types.VARCHAR); - } else { - insertPlayer.setString(1, newPlayer.name); - } - insertPlayer.setString(2, newPlayer.uuid.toString()); - insertPlayer.setTimestamp(3, newPlayer.firstAdd); - insertPlayer.execute(); - try (ResultSet rs = insertPlayer.getGeneratedKeys()) { - if (rs.next()) { - newPlayer.pid = rs.getLong(1); - } else { - BanStick.getPlugin().severe("No PID returned on player insert?!"); - return null; // no pid? error. - } - } - } + /** + * Creates, if needed, a new BSPlayer and inserts it into the database. Sets up related DAOs. + * + * @param playerId the Player's UUID to create + * @param name the Player's Name to create + * @return the new BSPlayer, or an existing player if they already exist, or null if failure. + */ + public static BSPlayer create(UUID playerId, String name) { + if (allPlayersUUID.containsKey(playerId)) { + return allPlayersUUID.get(playerId); + } + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection()) { + BSPlayer newPlayer = new BSPlayer(); + newPlayer.dirty = false; + newPlayer.name = name; + newPlayer.uuid = playerId; + newPlayer.firstAdd = new Timestamp(Calendar.getInstance().getTimeInMillis()); - newPlayer.allSessions = BSSessions.onlyFor(newPlayer); - newPlayer.allIPs = BSIPs.onlyFor(newPlayer); - newPlayer.allShares = BSShares.onlyFor(newPlayer); - newPlayer.allExclusions = BSExclusions.onlyFor(newPlayer); + try (PreparedStatement insertPlayer = connection.prepareStatement( + "INSERT INTO bs_player(name, uuid, first_add) VALUES (?, ?, ?);", + Statement.RETURN_GENERATED_KEYS)) { + if (newPlayer.name == null) { + insertPlayer.setNull(1, Types.VARCHAR); + } else { + insertPlayer.setString(1, newPlayer.name); + } + insertPlayer.setString(2, newPlayer.uuid.toString()); + insertPlayer.setTimestamp(3, newPlayer.firstAdd); + insertPlayer.execute(); + try (ResultSet rs = insertPlayer.getGeneratedKeys()) { + if (rs.next()) { + newPlayer.pid = rs.getLong(1); + } else { + BanStick.getPlugin().severe("No PID returned on player insert?!"); + return null; // no pid? error. + } + } + } - allPlayersID.put(newPlayer.pid, newPlayer); - allPlayersUUID.put(newPlayer.uuid, newPlayer); - return newPlayer; - } catch (SQLException se) { - BanStick.getPlugin().severe("Failed to create a new player record: ", se); - return null; - } - } + newPlayer.allSessions = BSSessions.onlyFor(newPlayer); + newPlayer.allIPs = BSIPs.onlyFor(newPlayer); + newPlayer.allShares = BSShares.onlyFor(newPlayer); + newPlayer.allExclusions = BSExclusions.onlyFor(newPlayer); - /** - * Preloads a segment of player data. Offset indicates lowbound exclusive to begin, - * with limit constraining size of batch. - * - * @param offset (not included) low bound on ID of record to load. - * @param limit how many to load - * @return last ID encountered, or -1 is none/no more - */ - public static long preload(long offset, int limit) { - long maxId = -1; - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); - PreparedStatement loadPlayers = connection.prepareStatement( - "SELECT * FROM bs_player WHERE pid > ? ORDER BY pid LIMIT ?");) { - loadPlayers.setLong(1, offset); - loadPlayers.setInt(2, limit); - try (ResultSet rs = loadPlayers.executeQuery()) { - while (rs.next()) { - long numPid = rs.getLong(1); - if (numPid > maxId) { - maxId = numPid; - } - if (allPlayersID.containsKey(numPid)) { - continue; // skip those we know. - } - BSPlayer player = new BSPlayer(); - player.dirty = false; - player.pid = rs.getLong(1); - player.allSessions = BSSessions.onlyFor(player); - player.allIPs = BSIPs.onlyFor(player); - player.allShares = BSShares.onlyFor(player); - player.name = rs.getString(2); - player.uuid = UUID.fromString(rs.getString(3)); - player.firstAdd = rs.getTimestamp(4); - long bid = rs.getLong(5); - if (!rs.wasNull()) { - player.deferBid = bid; - player.bid = null; - } - //player.bid = rs.wasNull() ? null : BSBan.byId(bid); - try { - player.ipPardonTime = rs.getTimestamp(6); - } catch (SQLException te) { - player.ipPardonTime = null; - } - try { - player.proxyPardonTime = rs.getTimestamp(7); - } catch (SQLException te) { - player.proxyPardonTime = null; - } - try { - player.sharedPardonTime = rs.getTimestamp(8); - } catch (SQLException te) { - player.sharedPardonTime = null; - } + allPlayersID.put(newPlayer.pid, newPlayer); + allPlayersUUID.put(newPlayer.uuid, newPlayer); + return newPlayer; + } catch (SQLException se) { + BanStick.getPlugin().severe("Failed to create a new player record: ", se); + return null; + } + } - player.allSessions = BSSessions.onlyFor(player); - player.allIPs = BSIPs.onlyFor(player); - player.allShares = BSShares.onlyFor(player); - player.allExclusions = BSExclusions.onlyFor(player); + /** + * Preloads a segment of player data. Offset indicates lowbound exclusive to begin, + * with limit constraining size of batch. + * + * @param offset (not included) low bound on ID of record to load. + * @param limit how many to load + * @return last ID encountered, or -1 is none/no more + */ + public static long preload(long offset, int limit) { + long maxId = -1; + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); + PreparedStatement loadPlayers = connection.prepareStatement( + "SELECT * FROM bs_player WHERE pid > ? ORDER BY pid LIMIT ?");) { + loadPlayers.setLong(1, offset); + loadPlayers.setInt(2, limit); + try (ResultSet rs = loadPlayers.executeQuery()) { + while (rs.next()) { + long numPid = rs.getLong(1); + if (numPid > maxId) { + maxId = numPid; + } + if (allPlayersID.containsKey(numPid)) { + continue; // skip those we know. + } + BSPlayer player = new BSPlayer(); + player.dirty = false; + player.pid = rs.getLong(1); + player.allSessions = BSSessions.onlyFor(player); + player.allIPs = BSIPs.onlyFor(player); + player.allShares = BSShares.onlyFor(player); + player.name = rs.getString(2); + player.uuid = UUID.fromString(rs.getString(3)); + player.firstAdd = rs.getTimestamp(4); + long bid = rs.getLong(5); + if (!rs.wasNull()) { + player.deferBid = bid; + player.bid = null; + } + //player.bid = rs.wasNull() ? null : BSBan.byId(bid); + try { + player.ipPardonTime = rs.getTimestamp(6); + } catch (SQLException te) { + player.ipPardonTime = null; + } + try { + player.proxyPardonTime = rs.getTimestamp(7); + } catch (SQLException te) { + player.proxyPardonTime = null; + } + try { + player.sharedPardonTime = rs.getTimestamp(8); + } catch (SQLException te) { + player.sharedPardonTime = null; + } - if (!allPlayersID.containsKey(player.pid)) { - allPlayersID.put(player.pid, player); - } - if (!allPlayersUUID.containsKey(player.uuid)) { - allPlayersUUID.put(player.uuid, player); - } - } - } - } catch (SQLException se) { - BanStick.getPlugin().severe("Failed during Player preload, offset " + offset + " limit " + limit, se); - } - return maxId; - } + player.allSessions = BSSessions.onlyFor(player); + player.allIPs = BSIPs.onlyFor(player); + player.allShares = BSShares.onlyFor(player); + player.allExclusions = BSExclusions.onlyFor(player); - @Override - public String toString() { - StringBuffer sb = new StringBuffer(); - sb.append(this.name); - if (this.getBan() != null) { - sb.append(" [Banned]"); - } - if (this.ipPardonTime != null) { - sb.append(" [IP Pardoned]"); - } - if (this.proxyPardonTime != null) { - sb.append(" [Proxy Pardoned]"); - } - if (this.sharedPardonTime != null) { - sb.append(" [Share Pardoned]"); - } - return sb.toString(); - } + if (!allPlayersID.containsKey(player.pid)) { + allPlayersID.put(player.pid, player); + } + if (!allPlayersUUID.containsKey(player.uuid)) { + allPlayersUUID.put(player.uuid, player); + } + } + } + } catch (SQLException se) { + BanStick.getPlugin().severe("Failed during Player preload, offset " + offset + " limit " + limit, se); + } + return maxId; + } - public void pardonShare(BSShare share) { - this.allShares.markPardoned(share); - } + @Override + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append(this.name); + if (this.getBan() != null) { + sb.append(" [Banned]"); + } + if (this.ipPardonTime != null) { + sb.append(" [IP Pardoned]"); + } + if (this.proxyPardonTime != null) { + sb.append(" [Proxy Pardoned]"); + } + if (this.sharedPardonTime != null) { + sb.append(" [Share Pardoned]"); + } + return sb.toString(); + } - public void unpardonShare(BSShare share) { - this.allShares.markUnpardoned(share); - } + public void pardonShare(BSShare share) { + this.allShares.markPardoned(share); + } - public int getUnpardonedShareCardinality() { - return this.allShares.unpardonedOrdinality(); - } + public void unpardonShare(BSShare share) { + this.allShares.markUnpardoned(share); + } - public int getTotalShareCardinality() { - return this.allShares.shareOrdinality(); - } + public int getUnpardonedShareCardinality() { + return this.allShares.unpardonedOrdinality(); + } - public BSShare getLatestShare() { - return this.allShares.getLatest(); - } + public int getTotalShareCardinality() { + return this.allShares.shareOrdinality(); + } - public List getUnpardonedShares() { - return this.allShares.getUnpardoned(); - } + public BSShare getLatestShare() { + return this.allShares.getLatest(); + } - /** - * Gets all shares between this player and another player. - * - * @param player the BSPlayer to compare against. - * @return a list of BSShares between the two players, if any. - */ - public List sharesWith(BSPlayer player) { - if (this.allShares.doesShareWith(player.getId())) { - return this.allShares.getSharesWith(player); - } else { - return null; - } - } + public List getUnpardonedShares() { + return this.allShares.getUnpardoned(); + } - /** - * Recursively retrieves all other BSPlayers this one has a transitive IP connection to. - * For example if Player A uses IP X, Player B uses IP X & Y and Player C uses IP Y, - * the players A and C would not have a share. This function digs recursively through shares - * though to find connections like that one - * - * @param respectExclusions Whether player specific exclusions should be taken into account - * to ignore specific connections - * @return Set containing all BSPlayer this one has transitive ip association with - */ - public Set getTransitiveSharedPlayers(boolean respectExclusions) { - return getTransitiveSharedPlayersRecursive(new HashSet(), respectExclusions); - } + /** + * Gets all shares between this player and another player. + * + * @param player the BSPlayer to compare against. + * @return a list of BSShares between the two players, if any. + */ + public List sharesWith(BSPlayer player) { + if (this.allShares.doesShareWith(player.getId())) { + return this.allShares.getSharesWith(player); + } else { + return null; + } + } - private Set getTransitiveSharedPlayersRecursive(Set alts, boolean respectExclusions) { - alts.add(this); - for (BSShare share : getAllShares()) { - if (share.isPardoned()) { - continue; - } - if (!alts.contains(share.getFirstPlayer()) - && !(respectExclusions && allExclusions.hasExclusionWith(share.getFirstPlayer()))) { - share.getFirstPlayer().getTransitiveSharedPlayersRecursive(alts, respectExclusions); - } - if (!alts.contains(share.getSecondPlayer()) - && !(respectExclusions && allExclusions.hasExclusionWith(share.getSecondPlayer()))) { - share.getSecondPlayer().getTransitiveSharedPlayersRecursive(alts, respectExclusions); - } - } - return alts; - } + /** + * Recursively retrieves all other BSPlayers this one has a transitive IP connection to. + * For example if Player A uses IP X, Player B uses IP X & Y and Player C uses IP Y, + * the players A and C would not have a share. This function digs recursively through shares + * though to find connections like that one + * + * @param respectExclusions Whether player specific exclusions should be taken into account + * to ignore specific connections + * @return Set containing all BSPlayer this one has transitive ip association with + */ + public Set getTransitiveSharedPlayers(boolean respectExclusions) { + return getTransitiveSharedPlayersRecursive(new HashSet(), respectExclusions); + } - public List getAllShares() { - return this.allShares.getAll(); - } + private Set getTransitiveSharedPlayersRecursive(Set alts, boolean respectExclusions) { + alts.add(this); + for (BSShare share : getAllShares()) { + if (share.isPardoned()) { + continue; + } + if (!alts.contains(share.getFirstPlayer()) + && !(respectExclusions && allExclusions.hasExclusionWith(share.getFirstPlayer()))) { + share.getFirstPlayer().getTransitiveSharedPlayersRecursive(alts, respectExclusions); + } + if (!alts.contains(share.getSecondPlayer()) + && !(respectExclusions && allExclusions.hasExclusionWith(share.getSecondPlayer()))) { + share.getSecondPlayer().getTransitiveSharedPlayersRecursive(alts, respectExclusions); + } + } + return alts; + } - public void addShare(BSShare share, BSPlayer player) { - this.allShares.addNew(share, player); - } + public List getAllShares() { + return this.allShares.getAll(); + } - public void addExclusion(BSExclusion excl) { - this.allExclusions.addNew(excl); - } + public void addShare(BSShare share, BSPlayer player) { + this.allShares.addNew(share, player); + } - public void removeExclusion(BSExclusion excl) { - this.allExclusions.remove(excl); - } + public void addExclusion(BSExclusion excl) { + this.allExclusions.addNew(excl); + } - public BSExclusion getExclusionWith(BSPlayer player) { - return allExclusions.getExclusionWith(player); - } + public void removeExclusion(BSExclusion excl) { + this.allExclusions.remove(excl); + } - @Override + public BSExclusion getExclusionWith(BSPlayer player) { + return allExclusions.getExclusionWith(player); + } + + @Override public int hashCode() { - return Objects.hash(getId()); - } + return Objects.hash(getId()); + } } diff --git a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/data/BSRegistrars.java b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/data/BSRegistrars.java index 660c2809e..f1e9e00c9 100644 --- a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/data/BSRegistrars.java +++ b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/data/BSRegistrars.java @@ -19,113 +19,115 @@ import org.bukkit.entity.Player; */ public class BSRegistrars { - private Set registrars; + private Set registrars; - public BSRegistrars() { - registrars = loadRegistrarsFromDB(); - BanStick.getPlugin().getLogger().info("Loaded " + registrars + " banned registrars from database"); - } - - /** - * Checks if a particular Proxy's Registrar has been banned. - * - * @param data the Proxy to check - * @return true if banned, false if not banned. - */ - public boolean isBanned(BSIPData data) { - if (data == null) { - return false; - } - return registrars.contains(data.getRegisteredAs()); - } - - /** - * Ban the registrar of a particular Proxy. - * @param data the Proxy whose registrar to ban. - */ - public void banRegistrar(BSIPData data) { - if (registrars.contains(data.getRegisteredAs())) { - return; - } - if (data.getRegisteredAs() == null || data.getRegisteredAs().isEmpty()) { - return; - } - registrars.add(data.getRegisteredAs()); - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); - PreparedStatement insertRegistrar = connection - .prepareStatement("insert into bs_banned_registrars (registered_as) values(?);");) { - insertRegistrar.setString(1, data.getRegisteredAs()); - insertRegistrar.execute(); - } catch (SQLException se) { - BanStick.getPlugin().severe("Insertion of banned registrar failed", se); - } - } - - /** - * Given a particular Proxy, unban its registrar - * @param data the Proxy whose registrar to unban. - */ - public void unbanRegistrar(BSIPData data) { - if (data.getRegisteredAs() == null) { - return; - } - registrars.remove(data.getRegisteredAs()); - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); - PreparedStatement insertRegistrar = connection - .prepareStatement("delete from bs_banned_registrars where registered_as = ?");) { - insertRegistrar.setString(1, data.getRegisteredAs()); - insertRegistrar.execute(); - } catch (SQLException se) { - BanStick.getPlugin().severe("Deletion of banned registrar failed", se); - } - } - - /** - * After creating an IP data entry this method checks whether the - * registrar is banned and removes all active players with this registrar if neccessary - * - *

Note that this will create a unique UUID ban for online players, in addition to the - * Registrar ban, so if you're "undoing" this later, you'll have to manually unban players - * who use this Registrar. - * - * @param data IP data created just now - */ - public void checkAndCleanup(BSIPData data) { - if (!registrars.contains(data.getRegisteredAs())) { - return; - } - for (BSSession session : BSSession.byIP(data.getIP())) { - if (!session.isEnded()) { - //dont always reban people who logged in on a vpn once in the past - Player player = Bukkit.getPlayer(session.getPlayer().getUUID()); - if (player == null) { - BanStick.getPlugin().info("Session " + session.toFullString(true) + " was active, " - + "but did not have an active player"); - continue; - } - BanHandler.doUUIDBan(player.getUniqueId(), true); - BanStick.getPlugin().info("Banning " + player.getName() + " for " - + "blacklisted provider " + data.getRegisteredAs()); - BanStick.getPlugin().getEventHandler().doKickWithCheckup(player.getUniqueId(), - session.getPlayer().getBan()); - } - } - } + public BSRegistrars() { + registrars = loadRegistrarsFromDB(); + BanStick.getPlugin().getLogger().info("Loaded " + registrars + " banned registrars from database"); + } - private Set loadRegistrarsFromDB() { - Set result = new HashSet<>(); - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); - PreparedStatement loadSet = connection - .prepareStatement("SELECT registered_as FROM bs_banned_registrars;");) { - try (ResultSet rs = loadSet.executeQuery();) { - while (rs.next()) { - result.add(rs.getString(1)); - } - } - } catch (SQLException se) { - BanStick.getPlugin().severe("Retrieval of banned registrars failed", se); - } - return result; - } + /** + * Checks if a particular Proxy's Registrar has been banned. + * + * @param data the Proxy to check + * @return true if banned, false if not banned. + */ + public boolean isBanned(BSIPData data) { + if (data == null) { + return false; + } + return registrars.contains(data.getRegisteredAs()); + } + + /** + * Ban the registrar of a particular Proxy. + * + * @param data the Proxy whose registrar to ban. + */ + public void banRegistrar(BSIPData data) { + if (registrars.contains(data.getRegisteredAs())) { + return; + } + if (data.getRegisteredAs() == null || data.getRegisteredAs().isEmpty()) { + return; + } + registrars.add(data.getRegisteredAs()); + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); + PreparedStatement insertRegistrar = connection + .prepareStatement("insert into bs_banned_registrars (registered_as) values(?);");) { + insertRegistrar.setString(1, data.getRegisteredAs()); + insertRegistrar.execute(); + } catch (SQLException se) { + BanStick.getPlugin().severe("Insertion of banned registrar failed", se); + } + } + + /** + * Given a particular Proxy, unban its registrar + * + * @param data the Proxy whose registrar to unban. + */ + public void unbanRegistrar(BSIPData data) { + if (data.getRegisteredAs() == null) { + return; + } + registrars.remove(data.getRegisteredAs()); + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); + PreparedStatement insertRegistrar = connection + .prepareStatement("delete from bs_banned_registrars where registered_as = ?");) { + insertRegistrar.setString(1, data.getRegisteredAs()); + insertRegistrar.execute(); + } catch (SQLException se) { + BanStick.getPlugin().severe("Deletion of banned registrar failed", se); + } + } + + /** + * After creating an IP data entry this method checks whether the + * registrar is banned and removes all active players with this registrar if neccessary + * + *

Note that this will create a unique UUID ban for online players, in addition to the + * Registrar ban, so if you're "undoing" this later, you'll have to manually unban players + * who use this Registrar. + * + * @param data IP data created just now + */ + public void checkAndCleanup(BSIPData data) { + if (!registrars.contains(data.getRegisteredAs())) { + return; + } + for (BSSession session : BSSession.byIP(data.getIP())) { + if (!session.isEnded()) { + //dont always reban people who logged in on a vpn once in the past + Player player = Bukkit.getPlayer(session.getPlayer().getUUID()); + if (player == null) { + BanStick.getPlugin().info("Session " + session.toFullString(true) + " was active, " + + "but did not have an active player"); + continue; + } + BanHandler.doUUIDBan(player.getUniqueId(), true); + BanStick.getPlugin().info("Banning " + player.getName() + " for " + + "blacklisted provider " + data.getRegisteredAs()); + BanStick.getPlugin().getEventHandler().doKickWithCheckup(player.getUniqueId(), + session.getPlayer().getBan()); + } + } + } + + private Set loadRegistrarsFromDB() { + Set result = new HashSet<>(); + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); + PreparedStatement loadSet = connection + .prepareStatement("SELECT registered_as FROM bs_banned_registrars;");) { + try (ResultSet rs = loadSet.executeQuery();) { + while (rs.next()) { + result.add(rs.getString(1)); + } + } + } catch (SQLException se) { + BanStick.getPlugin().severe("Retrieval of banned registrars failed", se); + } + return result; + } } diff --git a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/data/BSSession.java b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/data/BSSession.java index 958ff0b79..de851baeb 100644 --- a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/data/BSSession.java +++ b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/data/BSSession.java @@ -19,378 +19,378 @@ import java.util.concurrent.ConcurrentLinkedQueue; import javax.annotation.Nonnull; /** - * Represents a single playtime of a player. - * + * Represents a single playtime of a player. + * *

Although technically connective tissue for IPs and Players, this also * does double duty by showing IP / geo movement over time. Investigating this * data can provide great insight into players using VPN or Proxy even without * the proxy datasets as their physical geolocation from IP will jump around * irregularly. It can also help prove out other common unban requests, for instance - * players frequently locate in multiple geographic / IP locations (for instance, + * players frequently locate in multiple geographic / IP locations (for instance, * separated parents, friend groups, school vs. home, work vs. home, etc.) - * - * @author ProgrammerDan * + * @author ProgrammerDan */ public final class BSSession { - private static Map allSessionID = new HashMap<>(); - private static ConcurrentLinkedQueue> dirtySessions = new ConcurrentLinkedQueue<>(); - private boolean dirty; - - private long sid; - private Long deferPid; - private BSPlayer pid; - private Timestamp joinTime; - private Timestamp leaveTime; - private Long deferIid; - private BSIP iid; - - private BSSession() { } + private static Map allSessionID = new HashMap<>(); + private static ConcurrentLinkedQueue> dirtySessions = new ConcurrentLinkedQueue<>(); + private boolean dirty; - public Date getJoinTime() { - return joinTime; - } - - public Date getLeaveTime() { - return leaveTime; - } - - /** - * If leave time was set incorrectly and needs to be cleared, use this method. - */ - public void clearLeaveTime() { - this.leaveTime = null; - this.dirty = true; - dirtySessions.offer(new WeakReference(this)); - } - - /** - * Java Date leaveTime setter. - * - * @param leaveTime the departure / end time of the session. - */ - public void setLeaveTime(@Nonnull Date leaveTime) { - setLeaveTime(new Timestamp(leaveTime.getTime())); - } - - /** - * SQL Date leaveTime setter. - * - * @param leaveTime the departure / end time of the session. - */ - public void setLeaveTime(@Nonnull Timestamp leaveTime) { - this.leaveTime = leaveTime; - this.dirty = true; - dirtySessions.offer(new WeakReference(this)); - } - - public boolean isEnded() { - return this.leaveTime != null; - } + private long sid; + private Long deferPid; + private BSPlayer pid; + private Timestamp joinTime; + private Timestamp leaveTime; + private Long deferIid; + private BSIP iid; - /** - * @return the BSPlayer related to this session. - */ - public BSPlayer getPlayer() { - if (pid == null && deferPid != null) { - pid = BSPlayer.byId(deferPid); - } - return pid; - } + private BSSession() { + } - /** - * @return the BSIP related to this session - */ - public BSIP getIP() { - if (iid == null && deferIid != null) { - iid = BSIP.byId(deferIid); - } - return iid; - } - - public long getId() { - return sid; - } - - /** - * This leverages a fun queue of WeakReferences, where if a session is forcibly flush()'d we don't care, - * or if a session is in the queue more then once we don't care b/c we only save a dirty session once; and - * since we all store references and no copies, everything is nice and synchronized. - * - */ - public static void saveDirty() { - int batchSize = 0; - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); - PreparedStatement save = connection.prepareStatement( - "UPDATE bs_session SET leave_time = ? WHERE sid = ?");) { - while (!dirtySessions.isEmpty()) { - WeakReference rsession = dirtySessions.poll(); - BSSession session = rsession.get(); - if (session != null && session.dirty) { - session.dirty = false; - session.saveToStatement(save); - save.addBatch(); - batchSize ++; - } - if (batchSize > 0 && batchSize % 100 == 0) { - int[] batchRun = save.executeBatch(); - if (batchRun.length != batchSize) { - BanStick.getPlugin().severe("Some elements of the dirty batch didn't save? " - + batchSize + " vs " + batchRun.length); - } else { - BanStick.getPlugin().debug("Session batch: {0} saves", batchRun.length); - } - batchSize = 0; - } - } - if (batchSize > 0 && batchSize % 100 > 0) { - int[] batchRun = save.executeBatch(); - if (batchRun.length != batchSize) { - BanStick.getPlugin().severe("Some elements of the dirty batch didn't save? " - + batchSize + " vs " + batchRun.length); - } else { - BanStick.getPlugin().debug("Session batch: {0} saves", batchRun.length); - } - } - } catch (SQLException se) { - BanStick.getPlugin().severe("Save of BSSession dirty batch failed!: ", se); - } - } - - /** - * Saves the BSSession; only for internal use. Outside code must use Flush(); - */ - private void save() { - if (!dirty) { - return; - } - this.dirty = false; // don't let anyone else in! - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); - PreparedStatement save = connection.prepareStatement( - "UPDATE bs_session SET leave_time = ? WHERE sid = ?");) { - saveToStatement(save); - int effects = save.executeUpdate(); - if (effects == 0) { - BanStick.getPlugin().severe("Failed to save BSSession or no update? " + this.sid); - } - } catch (SQLException se) { - BanStick.getPlugin().severe("Save of BSSession failed!: ", se); - } - } - - private void saveToStatement(PreparedStatement save) throws SQLException { - if (this.leaveTime == null) { - save.setNull(1, Types.TIMESTAMP); - } else { - save.setTimestamp(1, this.leaveTime); - } - save.setLong(2, this.sid); - } - - /** - * Cleanly saves this player if necessary, and removes it from the references lists. - */ - public void flush() { - if (dirty) { - save(); - } - allSessionID.remove(this.sid); - this.pid = null; - this.deferPid = null; - this.iid = null; - this.deferIid = null; - } - - /** - * Gets a BSSession directly by its database ID. - * @param sid the Session ID - * @return the BSSession if found in cache or loaded, otherwise null on failure to load or other failure. - */ - public static BSSession byId(long sid) { - if (allSessionID.containsKey(sid)) { - return allSessionID.get(sid); - } - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); - PreparedStatement getId = connection.prepareStatement("SELECT * FROM bs_session WHERE sid = ?");) { - getId.setLong(1, sid); - try (ResultSet rs = getId.executeQuery();) { - if (rs.next()) { - BSSession newS = internalGetSession(rs); - allSessionID.put(sid, newS); - return newS; - } else { - BanStick.getPlugin().warning("Failed to retrieve Session by id: " + sid + " - not found"); - } - } - } catch (SQLException se) { - BanStick.getPlugin().severe("Retrieval of session by ID failed: " + sid, se); - } - return null; - } + public Date getJoinTime() { + return joinTime; + } - private static BSSession internalGetSession(ResultSet rs) throws SQLException { - BSSession newS = new BSSession(); - newS.sid = rs.getLong(1); - newS.deferPid = rs.getLong(2); - //nS.pid = BSPlayer.byId(rs.getLong(2)); - newS.joinTime = rs.getTimestamp(3); - try { - newS.leaveTime = rs.getTimestamp(4); - } catch (SQLException se) { - newS.leaveTime = null; - } - newS.deferIid = rs.getLong(5); - //nS.iid = BSIP.byId(rs.getLong(5)); - newS.dirty = false; - return newS; - } - - /** - * Gets all sessions that have used a specific IP. Sessions returned may span multiple players. - * - * @param iid The IP to investigate - * @return a list of BSSessions related to this IP. The list may be empty. - */ - public static List byIP(BSIP iid) { - ArrayList sessions = new ArrayList<>(); - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); - PreparedStatement getIds = connection.prepareStatement("SELECT * FROM bs_session WHERE iid = ?");) { - getIds.setLong(1, iid.getId()); - try (ResultSet rs = getIds.executeQuery();) { - while (rs.next()) { - long sid = rs.getLong(1); - if (allSessionID.containsKey(sid)) { - sessions.add(allSessionID.get(sid)); - continue; - } - - BSSession internal = internalGetSession(rs); - sessions.add(internal); - allSessionID.put(internal.sid, internal); - } - } - } catch (SQLException se) { - BanStick.getPlugin().severe("Retrieval of sessions by IP failed: " + iid.toString(), se); - } - return sessions; - } + public Date getLeaveTime() { + return leaveTime; + } - /** - * Attempts to create a session from a player, session start time, and IP address - * - * @param pid the Player whose session we are starting - * @param sessionStart the Date of the session begin - * @param iid the IP address - * @return the newly created BSSession - */ - public static BSSession create(BSPlayer pid, Date sessionStart, BSIP iid) { - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); - PreparedStatement newSession = connection.prepareStatement( - "INSERT INTO bs_session(pid, join_time, iid) VALUES (?, ?, ?)", - Statement.RETURN_GENERATED_KEYS);) { - BSSession session = new BSSession(); - session.pid = pid; - session.deferPid = pid.getId(); - session.joinTime = new Timestamp(sessionStart.getTime()); - session.iid = iid; - session.deferIid = iid.getId(); - - newSession.setLong(1, pid.getId()); - newSession.setTimestamp(2, session.joinTime); - newSession.setLong(3, iid.getId()); - int ins = newSession.executeUpdate(); - if (ins < 1) { - BanStick.getPlugin().warning("Insert reported no session inserted?" + pid.getName()); - } - - try (ResultSet rs = newSession.getGeneratedKeys()) { - if (rs.next()) { - long sid = rs.getLong(1); - session.sid = sid; - session.dirty = false; - allSessionID.put(sid, session); - return session; - } else { - BanStick.getPlugin().severe("Failed to get ID from inserted session!? " + pid.getName()); - return null; - } - } - } catch (SQLException se) { - BanStick.getPlugin().severe("Failed to insert new session for " + pid.getName(), se); - } - return null; - } - - /** - * Preloads a block of session data. - * - * @param offset (not included) ID to retrieve after - * @param limit how many to retrieve - * @return last ID encountered or -1 if none. - */ - public static long preload(long offset, int limit) { - long maxId = -1; - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); - PreparedStatement loadSessions = connection.prepareStatement( - "SELECT * FROM bs_session WHERE sid > ? ORDER BY sid LIMIT ?");) { - loadSessions.setLong(1, offset); - loadSessions.setInt(2, limit); - try (ResultSet rs = loadSessions.executeQuery()) { - while (rs.next()) { - BSSession session = new BSSession(); - session.dirty = false; - session.sid = rs.getLong(1); - session.deferPid = rs.getLong(2); - //session.pid = BSPlayer.byId(rs.getLong(2)); - session.joinTime = rs.getTimestamp(3); - try { - session.leaveTime = rs.getTimestamp(4); - } catch (SQLException se) { - session.leaveTime = null; - } - session.deferIid = rs.getLong(5); - //session.iid = BSIP.byId(rs.getLong(5)); + /** + * If leave time was set incorrectly and needs to be cleared, use this method. + */ + public void clearLeaveTime() { + this.leaveTime = null; + this.dirty = true; + dirtySessions.offer(new WeakReference(this)); + } - if (!allSessionID.containsKey(session.sid)) { - allSessionID.put(session.sid, session); - } - - if (session.sid > maxId) { - maxId = session.sid; - } - } - } - } catch (SQLException se) { - BanStick.getPlugin().severe("Failed during Session preload, offset " + offset + " limit " + limit, se); - } - return maxId; - } - - @Override - public String toString() { - return toFullString(true); - } - - /** - * Shows Session details (player / start / stop / IP if set) - * - * @param showIP determines if to show IP or not - * @return the display string - */ - public String toFullString(boolean showIP) { - StringBuilder sb = new StringBuilder(); - sb.append(getPlayer().getName()).append(" ["); - if (showIP) { - sb.append(getIP().toString()); - } else { - sb.append(getIP().getId()); - } - sb.append("]: "); - sb.append(getJoinTime().toString()); - if (isEnded()) { - sb.append(" - ").append(getLeaveTime()); - } - return sb.toString(); - } + /** + * Java Date leaveTime setter. + * + * @param leaveTime the departure / end time of the session. + */ + public void setLeaveTime(@Nonnull Date leaveTime) { + setLeaveTime(new Timestamp(leaveTime.getTime())); + } + + /** + * SQL Date leaveTime setter. + * + * @param leaveTime the departure / end time of the session. + */ + public void setLeaveTime(@Nonnull Timestamp leaveTime) { + this.leaveTime = leaveTime; + this.dirty = true; + dirtySessions.offer(new WeakReference(this)); + } + + public boolean isEnded() { + return this.leaveTime != null; + } + + /** + * @return the BSPlayer related to this session. + */ + public BSPlayer getPlayer() { + if (pid == null && deferPid != null) { + pid = BSPlayer.byId(deferPid); + } + return pid; + } + + /** + * @return the BSIP related to this session + */ + public BSIP getIP() { + if (iid == null && deferIid != null) { + iid = BSIP.byId(deferIid); + } + return iid; + } + + public long getId() { + return sid; + } + + /** + * This leverages a fun queue of WeakReferences, where if a session is forcibly flush()'d we don't care, + * or if a session is in the queue more then once we don't care b/c we only save a dirty session once; and + * since we all store references and no copies, everything is nice and synchronized. + */ + public static void saveDirty() { + int batchSize = 0; + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); + PreparedStatement save = connection.prepareStatement( + "UPDATE bs_session SET leave_time = ? WHERE sid = ?");) { + while (!dirtySessions.isEmpty()) { + WeakReference rsession = dirtySessions.poll(); + BSSession session = rsession.get(); + if (session != null && session.dirty) { + session.dirty = false; + session.saveToStatement(save); + save.addBatch(); + batchSize++; + } + if (batchSize > 0 && batchSize % 100 == 0) { + int[] batchRun = save.executeBatch(); + if (batchRun.length != batchSize) { + BanStick.getPlugin().severe("Some elements of the dirty batch didn't save? " + + batchSize + " vs " + batchRun.length); + } else { + BanStick.getPlugin().debug("Session batch: {0} saves", batchRun.length); + } + batchSize = 0; + } + } + if (batchSize > 0 && batchSize % 100 > 0) { + int[] batchRun = save.executeBatch(); + if (batchRun.length != batchSize) { + BanStick.getPlugin().severe("Some elements of the dirty batch didn't save? " + + batchSize + " vs " + batchRun.length); + } else { + BanStick.getPlugin().debug("Session batch: {0} saves", batchRun.length); + } + } + } catch (SQLException se) { + BanStick.getPlugin().severe("Save of BSSession dirty batch failed!: ", se); + } + } + + /** + * Saves the BSSession; only for internal use. Outside code must use Flush(); + */ + private void save() { + if (!dirty) { + return; + } + this.dirty = false; // don't let anyone else in! + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); + PreparedStatement save = connection.prepareStatement( + "UPDATE bs_session SET leave_time = ? WHERE sid = ?");) { + saveToStatement(save); + int effects = save.executeUpdate(); + if (effects == 0) { + BanStick.getPlugin().severe("Failed to save BSSession or no update? " + this.sid); + } + } catch (SQLException se) { + BanStick.getPlugin().severe("Save of BSSession failed!: ", se); + } + } + + private void saveToStatement(PreparedStatement save) throws SQLException { + if (this.leaveTime == null) { + save.setNull(1, Types.TIMESTAMP); + } else { + save.setTimestamp(1, this.leaveTime); + } + save.setLong(2, this.sid); + } + + /** + * Cleanly saves this player if necessary, and removes it from the references lists. + */ + public void flush() { + if (dirty) { + save(); + } + allSessionID.remove(this.sid); + this.pid = null; + this.deferPid = null; + this.iid = null; + this.deferIid = null; + } + + /** + * Gets a BSSession directly by its database ID. + * + * @param sid the Session ID + * @return the BSSession if found in cache or loaded, otherwise null on failure to load or other failure. + */ + public static BSSession byId(long sid) { + if (allSessionID.containsKey(sid)) { + return allSessionID.get(sid); + } + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); + PreparedStatement getId = connection.prepareStatement("SELECT * FROM bs_session WHERE sid = ?");) { + getId.setLong(1, sid); + try (ResultSet rs = getId.executeQuery();) { + if (rs.next()) { + BSSession newS = internalGetSession(rs); + allSessionID.put(sid, newS); + return newS; + } else { + BanStick.getPlugin().warning("Failed to retrieve Session by id: " + sid + " - not found"); + } + } + } catch (SQLException se) { + BanStick.getPlugin().severe("Retrieval of session by ID failed: " + sid, se); + } + return null; + } + + private static BSSession internalGetSession(ResultSet rs) throws SQLException { + BSSession newS = new BSSession(); + newS.sid = rs.getLong(1); + newS.deferPid = rs.getLong(2); + //nS.pid = BSPlayer.byId(rs.getLong(2)); + newS.joinTime = rs.getTimestamp(3); + try { + newS.leaveTime = rs.getTimestamp(4); + } catch (SQLException se) { + newS.leaveTime = null; + } + newS.deferIid = rs.getLong(5); + //nS.iid = BSIP.byId(rs.getLong(5)); + newS.dirty = false; + return newS; + } + + /** + * Gets all sessions that have used a specific IP. Sessions returned may span multiple players. + * + * @param iid The IP to investigate + * @return a list of BSSessions related to this IP. The list may be empty. + */ + public static List byIP(BSIP iid) { + ArrayList sessions = new ArrayList<>(); + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); + PreparedStatement getIds = connection.prepareStatement("SELECT * FROM bs_session WHERE iid = ?");) { + getIds.setLong(1, iid.getId()); + try (ResultSet rs = getIds.executeQuery();) { + while (rs.next()) { + long sid = rs.getLong(1); + if (allSessionID.containsKey(sid)) { + sessions.add(allSessionID.get(sid)); + continue; + } + + BSSession internal = internalGetSession(rs); + sessions.add(internal); + allSessionID.put(internal.sid, internal); + } + } + } catch (SQLException se) { + BanStick.getPlugin().severe("Retrieval of sessions by IP failed: " + iid.toString(), se); + } + return sessions; + } + + /** + * Attempts to create a session from a player, session start time, and IP address + * + * @param pid the Player whose session we are starting + * @param sessionStart the Date of the session begin + * @param iid the IP address + * @return the newly created BSSession + */ + public static BSSession create(BSPlayer pid, Date sessionStart, BSIP iid) { + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); + PreparedStatement newSession = connection.prepareStatement( + "INSERT INTO bs_session(pid, join_time, iid) VALUES (?, ?, ?)", + Statement.RETURN_GENERATED_KEYS);) { + BSSession session = new BSSession(); + session.pid = pid; + session.deferPid = pid.getId(); + session.joinTime = new Timestamp(sessionStart.getTime()); + session.iid = iid; + session.deferIid = iid.getId(); + + newSession.setLong(1, pid.getId()); + newSession.setTimestamp(2, session.joinTime); + newSession.setLong(3, iid.getId()); + int ins = newSession.executeUpdate(); + if (ins < 1) { + BanStick.getPlugin().warning("Insert reported no session inserted?" + pid.getName()); + } + + try (ResultSet rs = newSession.getGeneratedKeys()) { + if (rs.next()) { + long sid = rs.getLong(1); + session.sid = sid; + session.dirty = false; + allSessionID.put(sid, session); + return session; + } else { + BanStick.getPlugin().severe("Failed to get ID from inserted session!? " + pid.getName()); + return null; + } + } + } catch (SQLException se) { + BanStick.getPlugin().severe("Failed to insert new session for " + pid.getName(), se); + } + return null; + } + + /** + * Preloads a block of session data. + * + * @param offset (not included) ID to retrieve after + * @param limit how many to retrieve + * @return last ID encountered or -1 if none. + */ + public static long preload(long offset, int limit) { + long maxId = -1; + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); + PreparedStatement loadSessions = connection.prepareStatement( + "SELECT * FROM bs_session WHERE sid > ? ORDER BY sid LIMIT ?");) { + loadSessions.setLong(1, offset); + loadSessions.setInt(2, limit); + try (ResultSet rs = loadSessions.executeQuery()) { + while (rs.next()) { + BSSession session = new BSSession(); + session.dirty = false; + session.sid = rs.getLong(1); + session.deferPid = rs.getLong(2); + //session.pid = BSPlayer.byId(rs.getLong(2)); + session.joinTime = rs.getTimestamp(3); + try { + session.leaveTime = rs.getTimestamp(4); + } catch (SQLException se) { + session.leaveTime = null; + } + session.deferIid = rs.getLong(5); + //session.iid = BSIP.byId(rs.getLong(5)); + + if (!allSessionID.containsKey(session.sid)) { + allSessionID.put(session.sid, session); + } + + if (session.sid > maxId) { + maxId = session.sid; + } + } + } + } catch (SQLException se) { + BanStick.getPlugin().severe("Failed during Session preload, offset " + offset + " limit " + limit, se); + } + return maxId; + } + + @Override + public String toString() { + return toFullString(true); + } + + /** + * Shows Session details (player / start / stop / IP if set) + * + * @param showIP determines if to show IP or not + * @return the display string + */ + public String toFullString(boolean showIP) { + StringBuilder sb = new StringBuilder(); + sb.append(getPlayer().getName()).append(" ["); + if (showIP) { + sb.append(getIP().toString()); + } else { + sb.append(getIP().getId()); + } + sb.append("]: "); + sb.append(getJoinTime().toString()); + if (isEnded()) { + sb.append(" - ").append(getLeaveTime()); + } + return sb.toString(); + } } diff --git a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/data/BSSessions.java b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/data/BSSessions.java index 0878055ae..9a7882f60 100644 --- a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/data/BSSessions.java +++ b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/data/BSSessions.java @@ -12,118 +12,119 @@ import java.util.List; /** * BSSessions management DAO for BSSession. - * + * * @author ProgrammerDan */ public final class BSSessions { - private BSPlayer forPlayer; - private List sessionList; - - private BSSessions() { } - - /** - * Get a BSSessions DAO for a specific player. - * - * @param newPlayer the player to get a Sessions DAO for. - * @return the BSessions. - */ - public static BSSessions onlyFor(BSPlayer newPlayer) { - BSSessions sessions = new BSSessions(); - sessions.forPlayer = newPlayer; - sessions.sessionList = null; - return sessions; - } - - /** - * @param session When called, releases this BSSessions DAO. - */ - public static void release(BSSessions session) { - if (session != null) { - session.sessionList.clear(); - session.sessionList = null; - session.forPlayer = null; - } - } - - /** - * @return the latest session in this BSSessions set. Null if no sessions. - */ - public BSSession getLatest() { - if (sessionList == null) { - fill(); - } - if (sessionList.isEmpty()) { - return null; - } - return BSSession.byId(sessionList.get(sessionList.size() - 1)); - } - - /** - * @return the list of sessions from this BSSession set. Empty List if no sessions. - */ - public List getAll() { - if (sessionList == null) { - fill(); - } - - List all = new ArrayList<>(); - - if (sessionList != null && !sessionList.isEmpty()) { - for (Long sid : sessionList) { - all.add(BSSession.byId(sid)); - } - } - - return all; - } - - private void fill() { - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); - PreparedStatement getIDs = connection.prepareStatement(// Get all ids only, order by join time. - "SELECT sid FROM bs_session WHERE pid = ? ORDER BY join_time;");) { - // TODO: replace statement w/ view. - getIDs.setLong(1, forPlayer.getId()); - try (ResultSet rs = getIDs.executeQuery()) { - sessionList = new ArrayList<>(); - while (rs.next()) { - sessionList.add(rs.getLong(1)); - } - if (sessionList.isEmpty()) { - BanStick.getPlugin().warning("No Sessions for " + forPlayer.getName()); - } - } - } catch (SQLException se) { - BanStick.getPlugin().severe("Failed to get list of Session ids", se); - } - } + private BSPlayer forPlayer; + private List sessionList; - /** - * We assume all prior sessions are ended; this method doesn't check. - * - * @param ip The IP in use for this session. - * @param sessionStart The start time of the session - * @return the new Session. - */ - public BSSession startNew(BSIP ip, Date sessionStart) { - BSSession session = BSSession.create(forPlayer, sessionStart, ip); - if (session != null) { - sessionList.add(session.getId()); - } // TODO: else throw exception - return session; - } + private BSSessions() { + } - /** - * Helper that safely ends the latest session if not already ended. - * - * @param sessionEnd the Date to use for ending the latest session. - */ - public void endLatest(Date sessionEnd) { - BSSession session = getLatest(); - if (session != null) { - session.setLeaveTime(sessionEnd); - } else { - BanStick.getPlugin().warning("Call to end a session, but no active session: " + forPlayer.getId()); - } - } + /** + * Get a BSSessions DAO for a specific player. + * + * @param newPlayer the player to get a Sessions DAO for. + * @return the BSessions. + */ + public static BSSessions onlyFor(BSPlayer newPlayer) { + BSSessions sessions = new BSSessions(); + sessions.forPlayer = newPlayer; + sessions.sessionList = null; + return sessions; + } + + /** + * @param session When called, releases this BSSessions DAO. + */ + public static void release(BSSessions session) { + if (session != null) { + session.sessionList.clear(); + session.sessionList = null; + session.forPlayer = null; + } + } + + /** + * @return the latest session in this BSSessions set. Null if no sessions. + */ + public BSSession getLatest() { + if (sessionList == null) { + fill(); + } + if (sessionList.isEmpty()) { + return null; + } + return BSSession.byId(sessionList.get(sessionList.size() - 1)); + } + + /** + * @return the list of sessions from this BSSession set. Empty List if no sessions. + */ + public List getAll() { + if (sessionList == null) { + fill(); + } + + List all = new ArrayList<>(); + + if (sessionList != null && !sessionList.isEmpty()) { + for (Long sid : sessionList) { + all.add(BSSession.byId(sid)); + } + } + + return all; + } + + private void fill() { + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); + PreparedStatement getIDs = connection.prepareStatement(// Get all ids only, order by join time. + "SELECT sid FROM bs_session WHERE pid = ? ORDER BY join_time;");) { + // TODO: replace statement w/ view. + getIDs.setLong(1, forPlayer.getId()); + try (ResultSet rs = getIDs.executeQuery()) { + sessionList = new ArrayList<>(); + while (rs.next()) { + sessionList.add(rs.getLong(1)); + } + if (sessionList.isEmpty()) { + BanStick.getPlugin().warning("No Sessions for " + forPlayer.getName()); + } + } + } catch (SQLException se) { + BanStick.getPlugin().severe("Failed to get list of Session ids", se); + } + } + + /** + * We assume all prior sessions are ended; this method doesn't check. + * + * @param ip The IP in use for this session. + * @param sessionStart The start time of the session + * @return the new Session. + */ + public BSSession startNew(BSIP ip, Date sessionStart) { + BSSession session = BSSession.create(forPlayer, sessionStart, ip); + if (session != null) { + sessionList.add(session.getId()); + } // TODO: else throw exception + return session; + } + + /** + * Helper that safely ends the latest session if not already ended. + * + * @param sessionEnd the Date to use for ending the latest session. + */ + public void endLatest(Date sessionEnd) { + BSSession session = getLatest(); + if (session != null) { + session.setLeaveTime(sessionEnd); + } else { + BanStick.getPlugin().warning("Call to end a session, but no active session: " + forPlayer.getId()); + } + } } diff --git a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/data/BSShare.java b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/data/BSShare.java index 6f668bf69..10cb41815 100644 --- a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/data/BSShare.java +++ b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/data/BSShare.java @@ -22,460 +22,461 @@ import org.bukkit.ChatColor; /** * Defines an explicit 1 to 1 relationship between two players - * @author ProgrammerDan * + * @author ProgrammerDan */ public final class BSShare { - private static Map allShareID = new HashMap<>(); - private static ConcurrentLinkedQueue> dirtyShares = new ConcurrentLinkedQueue<>(); - private boolean dirty; - - private long sid; - private Long deferFirstPlayer; - private BSPlayer firstPlayer; - private Long deferSecondPlayer; - private BSPlayer secondPlayer; - - private Long deferFirstSession; - private BSSession firstSession; - private Long deferSecondSession; - private BSSession secondSession; - - private Timestamp createTime; - private Timestamp pardonTime; - - private BSShare() { } - - public long getId() { - return this.sid; - } - - public Date getCreateTime() { - return createTime; - } - - public Date getPardonTime() { - return pardonTime; - } + private static Map allShareID = new HashMap<>(); + private static ConcurrentLinkedQueue> dirtyShares = new ConcurrentLinkedQueue<>(); + private boolean dirty; - /** - * If a pradon was granted incorrectly, this safely clears it. - */ - public void clearPardonTime() { - this.pardonTime = null; - this.dirty = true; - dirtyShares.offer(new WeakReference(this)); - firstPlayer.unpardonShare(this); - secondPlayer.unpardonShare(this); - } + private long sid; + private Long deferFirstPlayer; + private BSPlayer firstPlayer; + private Long deferSecondPlayer; + private BSPlayer secondPlayer; - /** - * Individual relationships can be pardoned. This sets the time of that pardon. - * - * @param pardonTime The Java Date to pardon on. - */ - public void setPardonTime(@Nonnull Date pardonTime) { - setPardonTime(new Timestamp(pardonTime.getTime())); - } - - /** - * Individual relationships can be pardoned. This sets the time of that pardon. - * - * @param pardonTime The SQL Date to pardon on. - */ - public void setPardonTime(@Nonnull Timestamp pardonTime) { - this.pardonTime = pardonTime; - this.dirty = true; - dirtyShares.offer(new WeakReference(this)); - if (isPardoned()) { - firstPlayer.pardonShare(this); - secondPlayer.pardonShare(this); - } else { - firstPlayer.unpardonShare(this); - secondPlayer.unpardonShare(this); - } - } - - public boolean isPardoned() { - return this.pardonTime != null && this.pardonTime.compareTo(new Date()) <= 0; - } - - /** - * @return the first player of this share. - */ - public BSPlayer getFirstPlayer() { - if (firstPlayer == null && deferFirstPlayer != null) { - firstPlayer = BSPlayer.byId(deferFirstPlayer); - } - return firstPlayer; - } - - /** - * @return the second player of this share. - */ - public BSPlayer getSecondPlayer() { - if (secondPlayer == null && deferSecondPlayer != null) { - secondPlayer = BSPlayer.byId(deferSecondPlayer); - } - return secondPlayer; - } + private Long deferFirstSession; + private BSSession firstSession; + private Long deferSecondSession; + private BSSession secondSession; - /** - * @return the first session of this share (generally for first player). - */ - public BSSession getFirstSession() { - if (firstSession == null && deferFirstSession != null) { - firstSession = BSSession.byId(deferFirstSession); - } - return firstSession; - } - - /** - * @return the second session of this share (generally for second player). - */ - public BSSession getSecondSession() { - if (secondSession == null && deferSecondSession != null) { - secondSession = BSSession.byId(deferSecondSession); - } - return secondSession; - } - - /** - * Gets a BSShare by database ID. - * - * @param sid the Share to retrieve's ID - * @return the BSShare if already loaded or found in DB, or null if not found. - */ - public static BSShare byId(long sid) { - if (allShareID.containsKey(sid)) { - return allShareID.get(sid); - } - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); - PreparedStatement getId = connection.prepareStatement("SELECT * FROM bs_share WHERE sid = ?");) { - getId.setLong(1, sid); - try (ResultSet rs = getId.executeQuery();) { - if (rs.next()) { - BSShare internal = internalGetShare(rs); - allShareID.put(sid, internal); - return internal; - } else { - BanStick.getPlugin().warning("Failed to retrieve Share by id: " + sid + " - not found"); - } - } - } catch (SQLException se) { - BanStick.getPlugin().severe("Retrieval of Share by ID failed: " + sid, se); - } + private Timestamp createTime; + private Timestamp pardonTime; - return null; - } + private BSShare() { + } - /** - * Gets all BSShares for a particular player. Does not matter if player is first or second on the share. - * - * @param player The BSPlayer to investigate - * @return a list of Shares for this player, could be empty if no shares found. - */ - public static List byPlayer(BSPlayer player) { - List shares = new ArrayList<>(); - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); - PreparedStatement getId = connection.prepareStatement( - "SELECT * FROM bs_share WHERE first_pid = ? OR second_pid = ?");) { - getId.setLong(1, player.getId()); - getId.setLong(2, player.getId()); - try (ResultSet rs = getId.executeQuery();) { - while (rs.next()) { - if (allShareID.containsKey(rs.getLong(1))) { - shares.add(allShareID.get(rs.getLong(1))); - continue; - } - BSShare internal = internalGetShare(rs); - allShareID.put(rs.getLong(1), internal); - shares.add(internal); - } - } - } catch (SQLException se) { - BanStick.getPlugin().severe("Retrieval of Shares by Player failed: " + player.toString(), se); - } - return shares; - } - - /** - * Gets all BSShares for a particular session. Gets all shares for all players involved in the session as - * either first or second session. - * - * @param session the BSSession to investigate - * @return a list of BSShare related to the session. List may be empty if no session are found. - */ - public static List bySession(BSSession session) { - List shares = new ArrayList<>(); - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); - PreparedStatement getId = connection.prepareStatement( - "SELECT * FROM bs_share WHERE first_sid = ? OR second_sid = ?");) { - getId.setLong(1, session.getId()); - getId.setLong(2, session.getId()); - try (ResultSet rs = getId.executeQuery();) { - while (rs.next()) { - if (allShareID.containsKey(rs.getLong(1))) { - shares.add(allShareID.get(rs.getLong(1))); - continue; - } - BSShare internal = internalGetShare(rs); - allShareID.put(rs.getLong(1), internal); - shares.add(internal); - } - } - } catch (SQLException se) { - BanStick.getPlugin().severe("Retrieval of Shares by Session failed: " + session.toString(), se); - } - return shares; - } - - private static BSShare internalGetShare(ResultSet rs) throws SQLException { - BSShare internal = new BSShare(); - internal.sid = rs.getLong(1); - internal.dirty = false; - internal.createTime = rs.getTimestamp(2); - internal.deferFirstPlayer = rs.getLong(3); - //nS.firstPlayer = BSPlayer.byId(rs.getLong(3)); - internal.deferSecondPlayer = rs.getLong(4); - //nS.secondPlayer = BSPlayer.byId(rs.getLong(4)); - internal.deferFirstSession = rs.getLong(5); - //nS.firstSession = BSSession.byId(rs.getLong(5)); - internal.deferSecondSession = rs.getLong(6); - //nS.secondSession = BSSession.byId(rs.getLong(6)); - if (rs.getBoolean(7)) { - try { - internal.pardonTime = rs.getTimestamp(8); - } catch (SQLException se) { - internal.pardonTime = null; // data is inconsistent. - internal.dirty = true; - dirtyShares.offer(new WeakReference(internal)); - } - } else { - internal.pardonTime = null; - } - return internal; - } - - /** - * Forces a save of all Shares marked dirty. - * - */ - public static void saveDirty() { - int batchSize = 0; - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); - PreparedStatement save = connection.prepareStatement( - "UPDATE bs_share SET pardon = ?, pardon_time = ? WHERE sid = ?");) { - while (!dirtyShares.isEmpty()) { - WeakReference rshare = dirtyShares.poll(); - BSShare share = rshare.get(); - if (share != null && share.dirty) { - share.dirty = false; - share.saveToStatement(save); - save.addBatch(); - batchSize ++; - } - if (batchSize > 0 && batchSize % 100 == 0) { - int[] batchRun = save.executeBatch(); - if (batchRun.length != batchSize) { - BanStick.getPlugin().severe("Some elements of the dirty batch didn't save? " - + batchSize + " vs " + batchRun.length); - } else { - BanStick.getPlugin().debug("Share batch: {0} saves", batchRun.length); - } - batchSize = 0; - } - } - if (batchSize > 0 && batchSize % 100 > 0) { - int[] batchRun = save.executeBatch(); - if (batchRun.length != batchSize) { - BanStick.getPlugin().severe("Some elements of the dirty batch didn't save? " - + batchSize + " vs " + batchRun.length); - } else { - BanStick.getPlugin().debug("Share batch: {0} saves", batchRun.length); - } - } - } catch (SQLException se) { - BanStick.getPlugin().severe("Save of BSShare dirty batch failed!: ", se); - } - } - - /** - * Saves the BSShare; only for internal use. Outside code must use Flush(); - */ - private void save() { - if (!dirty) { - return; - } - this.dirty = false; // don't let anyone else in! - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); - PreparedStatement save = connection.prepareStatement( - "UPDATE bs_share SET pardon = ?, pardon_time = ? WHERE sid = ?");) { - saveToStatement(save); - int effects = save.executeUpdate(); - if (effects == 0) { - BanStick.getPlugin().severe("Failed to save BSShare or no update? " + this.sid); - } - } catch (SQLException se) { - BanStick.getPlugin().severe("Save of BSShare failed!: ", se); - } - } - - private void saveToStatement(PreparedStatement save) throws SQLException { - if (this.pardonTime == null) { - save.setBoolean(1, false); - save.setNull(2, Types.TIMESTAMP); - } else { - save.setBoolean(1, true); - save.setTimestamp(2, this.pardonTime); - } - save.setLong(3, this.sid); - } - - /** - * Cleanly saves this player if necessary, and removes it from the references lists. - */ - public void flush() { - if (dirty) { - save(); - } - allShareID.remove(this.sid); - this.deferFirstPlayer = null; - this.firstPlayer = null; - this.deferSecondPlayer = null; - this.secondPlayer = null; - this.deferFirstSession = null; - this.firstSession = null; - this.deferSecondPlayer = null; - this.secondSession = null; - } + public long getId() { + return this.sid; + } - /** - * Preloads a segment of share data. Offset indicates lowbound exclusive to begin, - * with limit constraining size of batch. - * - * @param offset (not included) low bound on ID of record to load. - * @param limit how many to load - * @return last ID encountered, or -1 is none/no more - */ - public static long preload(long offset, int limit) { - long maxId = -1; - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); - PreparedStatement loadShares = connection.prepareStatement( - "SELECT * FROM bs_share WHERE sid > ? ORDER BY sid LIMIT ?");) { - loadShares.setLong(1, offset); - loadShares.setInt(2, limit); - try (ResultSet rs = loadShares.executeQuery()) { - while (rs.next()) { - if (rs.getLong(1) > maxId) { - maxId = rs.getLong(1); - } - if (allShareID.containsKey(rs.getLong(1))) { - continue; - } - - BSShare share = internalGetShare(rs); - allShareID.put(share.sid, share); - } - } - } catch (SQLException se) { - BanStick.getPlugin().severe("Failed during Share preload, offset " + offset + " limit " + limit, se); - } - return maxId; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - if (this.isPardoned()) { - sb.append(ChatColor.GREEN).append("[Pardoned] "); - } - sb.append(ChatColor.DARK_PURPLE).append("Share by ") - .append(ChatColor.WHITE).append(getFirstPlayer().getName()).append(ChatColor.DARK_PURPLE).append(" and ") - .append(ChatColor.WHITE).append(getSecondPlayer().getName()).append(ChatColor.DARK_PURPLE).append(" via ") - .append(ChatColor.WHITE).append(getFirstSession().toString()).append(ChatColor.DARK_PURPLE).append(" with ") - .append(ChatColor.WHITE).append(getSecondSession().toString()); - return sb.toString(); - } - - /** - * Print the full Share, and optionally show IPs - * @param showIPs true to show the IPs - * @return a Stirng with all the data. - */ - public String toFullString(boolean showIPs) { - if (showIPs) { - return toString(); - } else { - StringBuilder sb = new StringBuilder(); - if (this.isPardoned()) { - sb.append(ChatColor.GREEN).append("[Pardoned] "); - } - sb.append(ChatColor.DARK_PURPLE).append("Share by ") - .append(ChatColor.WHITE).append(getFirstPlayer().getName()) - .append(ChatColor.DARK_PURPLE).append(" and ") - .append(ChatColor.WHITE).append(getSecondPlayer().getName()) - .append(ChatColor.DARK_PURPLE).append(" via ") - .append(ChatColor.WHITE).append(getFirstSession().toFullString(showIPs)) - .append(ChatColor.DARK_PURPLE).append(" with ") - .append(ChatColor.WHITE).append(getSecondSession().toFullString(showIPs)); - return sb.toString(); - } - } + public Date getCreateTime() { + return createTime; + } - /** - * Create a new Share - * - * @param overlap First player's session - * @param session Second player's session - * @return a new BSShare linking these sessions - */ - public static BSShare create(BSSession overlap, BSSession session) { - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); - PreparedStatement newShare = connection.prepareStatement( - "INSERT INTO bs_share(create_time, first_pid, second_pid, first_sid, second_sid, pardon, pardon_time) VALUES (?, ?, ?, ?, ?, ?, ?)", Statement.RETURN_GENERATED_KEYS);) { - BSShare share = new BSShare(); - share.createTime = new Timestamp(Calendar.getInstance().getTimeInMillis()); - share.deferFirstPlayer = overlap.getPlayer().getId(); - share.firstPlayer = overlap.getPlayer(); - share.deferSecondPlayer = session.getPlayer().getId(); - share.secondPlayer = session.getPlayer(); - share.deferFirstSession = overlap.getId(); - share.firstSession = overlap; - share.deferSecondSession = session.getId(); - share.secondSession = session; - share.pardonTime = null; - - newShare.setTimestamp(1, share.createTime); - newShare.setLong(2, share.firstPlayer.getId()); - newShare.setLong(3, share.secondPlayer.getId()); - newShare.setLong(4, share.firstSession.getId()); - newShare.setLong(5, share.secondSession.getId()); - newShare.setBoolean(6, false); - newShare.setNull(7, Types.TIMESTAMP); - - int ins = newShare.executeUpdate(); - if (ins < 1) { - BanStick.getPlugin().warning("Insert reported no share inserted? " + share.getId()); - } - - try (ResultSet rs = newShare.getGeneratedKeys()) { - if (rs.next()) { - long sid = rs.getLong(1); - share.sid = sid; - share.dirty = false; - allShareID.put(sid, share); - return share; - } else { - BanStick.getPlugin().severe("Failed to get ID from inserted share!? " - + overlap.getId() + " - " + session.getId()); - return null; - } - } - } catch (SQLException se) { - BanStick.getPlugin().severe("Failed to insert new share for sessions!", se); - } - return null; - } + public Date getPardonTime() { + return pardonTime; + } + + /** + * If a pradon was granted incorrectly, this safely clears it. + */ + public void clearPardonTime() { + this.pardonTime = null; + this.dirty = true; + dirtyShares.offer(new WeakReference(this)); + firstPlayer.unpardonShare(this); + secondPlayer.unpardonShare(this); + } + + /** + * Individual relationships can be pardoned. This sets the time of that pardon. + * + * @param pardonTime The Java Date to pardon on. + */ + public void setPardonTime(@Nonnull Date pardonTime) { + setPardonTime(new Timestamp(pardonTime.getTime())); + } + + /** + * Individual relationships can be pardoned. This sets the time of that pardon. + * + * @param pardonTime The SQL Date to pardon on. + */ + public void setPardonTime(@Nonnull Timestamp pardonTime) { + this.pardonTime = pardonTime; + this.dirty = true; + dirtyShares.offer(new WeakReference(this)); + if (isPardoned()) { + firstPlayer.pardonShare(this); + secondPlayer.pardonShare(this); + } else { + firstPlayer.unpardonShare(this); + secondPlayer.unpardonShare(this); + } + } + + public boolean isPardoned() { + return this.pardonTime != null && this.pardonTime.compareTo(new Date()) <= 0; + } + + /** + * @return the first player of this share. + */ + public BSPlayer getFirstPlayer() { + if (firstPlayer == null && deferFirstPlayer != null) { + firstPlayer = BSPlayer.byId(deferFirstPlayer); + } + return firstPlayer; + } + + /** + * @return the second player of this share. + */ + public BSPlayer getSecondPlayer() { + if (secondPlayer == null && deferSecondPlayer != null) { + secondPlayer = BSPlayer.byId(deferSecondPlayer); + } + return secondPlayer; + } + + /** + * @return the first session of this share (generally for first player). + */ + public BSSession getFirstSession() { + if (firstSession == null && deferFirstSession != null) { + firstSession = BSSession.byId(deferFirstSession); + } + return firstSession; + } + + /** + * @return the second session of this share (generally for second player). + */ + public BSSession getSecondSession() { + if (secondSession == null && deferSecondSession != null) { + secondSession = BSSession.byId(deferSecondSession); + } + return secondSession; + } + + /** + * Gets a BSShare by database ID. + * + * @param sid the Share to retrieve's ID + * @return the BSShare if already loaded or found in DB, or null if not found. + */ + public static BSShare byId(long sid) { + if (allShareID.containsKey(sid)) { + return allShareID.get(sid); + } + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); + PreparedStatement getId = connection.prepareStatement("SELECT * FROM bs_share WHERE sid = ?");) { + getId.setLong(1, sid); + try (ResultSet rs = getId.executeQuery();) { + if (rs.next()) { + BSShare internal = internalGetShare(rs); + allShareID.put(sid, internal); + return internal; + } else { + BanStick.getPlugin().warning("Failed to retrieve Share by id: " + sid + " - not found"); + } + } + } catch (SQLException se) { + BanStick.getPlugin().severe("Retrieval of Share by ID failed: " + sid, se); + } + + return null; + } + + /** + * Gets all BSShares for a particular player. Does not matter if player is first or second on the share. + * + * @param player The BSPlayer to investigate + * @return a list of Shares for this player, could be empty if no shares found. + */ + public static List byPlayer(BSPlayer player) { + List shares = new ArrayList<>(); + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); + PreparedStatement getId = connection.prepareStatement( + "SELECT * FROM bs_share WHERE first_pid = ? OR second_pid = ?");) { + getId.setLong(1, player.getId()); + getId.setLong(2, player.getId()); + try (ResultSet rs = getId.executeQuery();) { + while (rs.next()) { + if (allShareID.containsKey(rs.getLong(1))) { + shares.add(allShareID.get(rs.getLong(1))); + continue; + } + BSShare internal = internalGetShare(rs); + allShareID.put(rs.getLong(1), internal); + shares.add(internal); + } + } + } catch (SQLException se) { + BanStick.getPlugin().severe("Retrieval of Shares by Player failed: " + player.toString(), se); + } + return shares; + } + + /** + * Gets all BSShares for a particular session. Gets all shares for all players involved in the session as + * either first or second session. + * + * @param session the BSSession to investigate + * @return a list of BSShare related to the session. List may be empty if no session are found. + */ + public static List bySession(BSSession session) { + List shares = new ArrayList<>(); + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); + PreparedStatement getId = connection.prepareStatement( + "SELECT * FROM bs_share WHERE first_sid = ? OR second_sid = ?");) { + getId.setLong(1, session.getId()); + getId.setLong(2, session.getId()); + try (ResultSet rs = getId.executeQuery();) { + while (rs.next()) { + if (allShareID.containsKey(rs.getLong(1))) { + shares.add(allShareID.get(rs.getLong(1))); + continue; + } + BSShare internal = internalGetShare(rs); + allShareID.put(rs.getLong(1), internal); + shares.add(internal); + } + } + } catch (SQLException se) { + BanStick.getPlugin().severe("Retrieval of Shares by Session failed: " + session.toString(), se); + } + return shares; + } + + private static BSShare internalGetShare(ResultSet rs) throws SQLException { + BSShare internal = new BSShare(); + internal.sid = rs.getLong(1); + internal.dirty = false; + internal.createTime = rs.getTimestamp(2); + internal.deferFirstPlayer = rs.getLong(3); + //nS.firstPlayer = BSPlayer.byId(rs.getLong(3)); + internal.deferSecondPlayer = rs.getLong(4); + //nS.secondPlayer = BSPlayer.byId(rs.getLong(4)); + internal.deferFirstSession = rs.getLong(5); + //nS.firstSession = BSSession.byId(rs.getLong(5)); + internal.deferSecondSession = rs.getLong(6); + //nS.secondSession = BSSession.byId(rs.getLong(6)); + if (rs.getBoolean(7)) { + try { + internal.pardonTime = rs.getTimestamp(8); + } catch (SQLException se) { + internal.pardonTime = null; // data is inconsistent. + internal.dirty = true; + dirtyShares.offer(new WeakReference(internal)); + } + } else { + internal.pardonTime = null; + } + return internal; + } + + /** + * Forces a save of all Shares marked dirty. + */ + public static void saveDirty() { + int batchSize = 0; + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); + PreparedStatement save = connection.prepareStatement( + "UPDATE bs_share SET pardon = ?, pardon_time = ? WHERE sid = ?");) { + while (!dirtyShares.isEmpty()) { + WeakReference rshare = dirtyShares.poll(); + BSShare share = rshare.get(); + if (share != null && share.dirty) { + share.dirty = false; + share.saveToStatement(save); + save.addBatch(); + batchSize++; + } + if (batchSize > 0 && batchSize % 100 == 0) { + int[] batchRun = save.executeBatch(); + if (batchRun.length != batchSize) { + BanStick.getPlugin().severe("Some elements of the dirty batch didn't save? " + + batchSize + " vs " + batchRun.length); + } else { + BanStick.getPlugin().debug("Share batch: {0} saves", batchRun.length); + } + batchSize = 0; + } + } + if (batchSize > 0 && batchSize % 100 > 0) { + int[] batchRun = save.executeBatch(); + if (batchRun.length != batchSize) { + BanStick.getPlugin().severe("Some elements of the dirty batch didn't save? " + + batchSize + " vs " + batchRun.length); + } else { + BanStick.getPlugin().debug("Share batch: {0} saves", batchRun.length); + } + } + } catch (SQLException se) { + BanStick.getPlugin().severe("Save of BSShare dirty batch failed!: ", se); + } + } + + /** + * Saves the BSShare; only for internal use. Outside code must use Flush(); + */ + private void save() { + if (!dirty) { + return; + } + this.dirty = false; // don't let anyone else in! + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); + PreparedStatement save = connection.prepareStatement( + "UPDATE bs_share SET pardon = ?, pardon_time = ? WHERE sid = ?");) { + saveToStatement(save); + int effects = save.executeUpdate(); + if (effects == 0) { + BanStick.getPlugin().severe("Failed to save BSShare or no update? " + this.sid); + } + } catch (SQLException se) { + BanStick.getPlugin().severe("Save of BSShare failed!: ", se); + } + } + + private void saveToStatement(PreparedStatement save) throws SQLException { + if (this.pardonTime == null) { + save.setBoolean(1, false); + save.setNull(2, Types.TIMESTAMP); + } else { + save.setBoolean(1, true); + save.setTimestamp(2, this.pardonTime); + } + save.setLong(3, this.sid); + } + + /** + * Cleanly saves this player if necessary, and removes it from the references lists. + */ + public void flush() { + if (dirty) { + save(); + } + allShareID.remove(this.sid); + this.deferFirstPlayer = null; + this.firstPlayer = null; + this.deferSecondPlayer = null; + this.secondPlayer = null; + this.deferFirstSession = null; + this.firstSession = null; + this.deferSecondPlayer = null; + this.secondSession = null; + } + + /** + * Preloads a segment of share data. Offset indicates lowbound exclusive to begin, + * with limit constraining size of batch. + * + * @param offset (not included) low bound on ID of record to load. + * @param limit how many to load + * @return last ID encountered, or -1 is none/no more + */ + public static long preload(long offset, int limit) { + long maxId = -1; + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); + PreparedStatement loadShares = connection.prepareStatement( + "SELECT * FROM bs_share WHERE sid > ? ORDER BY sid LIMIT ?");) { + loadShares.setLong(1, offset); + loadShares.setInt(2, limit); + try (ResultSet rs = loadShares.executeQuery()) { + while (rs.next()) { + if (rs.getLong(1) > maxId) { + maxId = rs.getLong(1); + } + if (allShareID.containsKey(rs.getLong(1))) { + continue; + } + + BSShare share = internalGetShare(rs); + allShareID.put(share.sid, share); + } + } + } catch (SQLException se) { + BanStick.getPlugin().severe("Failed during Share preload, offset " + offset + " limit " + limit, se); + } + return maxId; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + if (this.isPardoned()) { + sb.append(ChatColor.GREEN).append("[Pardoned] "); + } + sb.append(ChatColor.DARK_PURPLE).append("Share by ") + .append(ChatColor.WHITE).append(getFirstPlayer().getName()).append(ChatColor.DARK_PURPLE).append(" and ") + .append(ChatColor.WHITE).append(getSecondPlayer().getName()).append(ChatColor.DARK_PURPLE).append(" via ") + .append(ChatColor.WHITE).append(getFirstSession().toString()).append(ChatColor.DARK_PURPLE).append(" with ") + .append(ChatColor.WHITE).append(getSecondSession().toString()); + return sb.toString(); + } + + /** + * Print the full Share, and optionally show IPs + * + * @param showIPs true to show the IPs + * @return a Stirng with all the data. + */ + public String toFullString(boolean showIPs) { + if (showIPs) { + return toString(); + } else { + StringBuilder sb = new StringBuilder(); + if (this.isPardoned()) { + sb.append(ChatColor.GREEN).append("[Pardoned] "); + } + sb.append(ChatColor.DARK_PURPLE).append("Share by ") + .append(ChatColor.WHITE).append(getFirstPlayer().getName()) + .append(ChatColor.DARK_PURPLE).append(" and ") + .append(ChatColor.WHITE).append(getSecondPlayer().getName()) + .append(ChatColor.DARK_PURPLE).append(" via ") + .append(ChatColor.WHITE).append(getFirstSession().toFullString(showIPs)) + .append(ChatColor.DARK_PURPLE).append(" with ") + .append(ChatColor.WHITE).append(getSecondSession().toFullString(showIPs)); + return sb.toString(); + } + } + + /** + * Create a new Share + * + * @param overlap First player's session + * @param session Second player's session + * @return a new BSShare linking these sessions + */ + public static BSShare create(BSSession overlap, BSSession session) { + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); + PreparedStatement newShare = connection.prepareStatement( + "INSERT INTO bs_share(create_time, first_pid, second_pid, first_sid, second_sid, pardon, pardon_time) VALUES (?, ?, ?, ?, ?, ?, ?)", Statement.RETURN_GENERATED_KEYS);) { + BSShare share = new BSShare(); + share.createTime = new Timestamp(Calendar.getInstance().getTimeInMillis()); + share.deferFirstPlayer = overlap.getPlayer().getId(); + share.firstPlayer = overlap.getPlayer(); + share.deferSecondPlayer = session.getPlayer().getId(); + share.secondPlayer = session.getPlayer(); + share.deferFirstSession = overlap.getId(); + share.firstSession = overlap; + share.deferSecondSession = session.getId(); + share.secondSession = session; + share.pardonTime = null; + + newShare.setTimestamp(1, share.createTime); + newShare.setLong(2, share.firstPlayer.getId()); + newShare.setLong(3, share.secondPlayer.getId()); + newShare.setLong(4, share.firstSession.getId()); + newShare.setLong(5, share.secondSession.getId()); + newShare.setBoolean(6, false); + newShare.setNull(7, Types.TIMESTAMP); + + int ins = newShare.executeUpdate(); + if (ins < 1) { + BanStick.getPlugin().warning("Insert reported no share inserted? " + share.getId()); + } + + try (ResultSet rs = newShare.getGeneratedKeys()) { + if (rs.next()) { + long sid = rs.getLong(1); + share.sid = sid; + share.dirty = false; + allShareID.put(sid, share); + return share; + } else { + BanStick.getPlugin().severe("Failed to get ID from inserted share!? " + + overlap.getId() + " - " + session.getId()); + return null; + } + } + } catch (SQLException se) { + BanStick.getPlugin().severe("Failed to insert new share for sessions!", se); + } + return null; + } } diff --git a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/data/BSShares.java b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/data/BSShares.java index 47fc4f9a1..f9753dc2c 100644 --- a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/data/BSShares.java +++ b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/data/BSShares.java @@ -16,319 +16,320 @@ import static com.programmerdan.minecraft.banstick.handler.BanStickEventHandler. /** * BSShares DAO management object. - * - * @author ProgrammerDan * + * @author ProgrammerDan */ public final class BSShares { - - private BSPlayer forPlayer; - private List shareList; - private Set overlaps; - private Set unpardonedList; - private BSShares() { } - - /** - * Get BSShares DAO for a particular BSPlayer - * - * @param player the Player to look at - * @return the BSShares DAO for this player. - */ - public static BSShares onlyFor(BSPlayer player) { - BSShares shares = new BSShares(); - shares.forPlayer = player; - shares.shareList = null; - shares.overlaps = null; - shares.unpardonedList = null; - return shares; - } - - /** - * Release a BSShares DAO. - * - * @param shares the BSShares DAO to release. - */ - public static void release(BSShares shares) { - shares.forPlayer = null; - if (shares.shareList != null) { - shares.shareList.clear(); - } - if (shares.overlaps != null) { - shares.overlaps.clear(); - } - if (shares.unpardonedList != null) { - shares.unpardonedList.clear(); - } - shares.shareList = null; - } - - /** - * Get all Shares related to the configured player. - * - * @return a List of Shares, which could be empty if none are known. - */ - public List getAll() { - if (shareList == null) { - fill(); - } - - List all = new ArrayList<>(); - - if (shareList != null && !shareList.isEmpty()) { - for (Long sid : shareList) { - all.add(BSShare.byId(sid)); - } - } - - return all; - } - - /** - * Get all shares that are not pardoned. - * - * @return a List of Shares, which could be empty if all are pardoned. - */ - public List getUnpardoned() { - if (shareList == null) { - fill(); - } - - List unpardoned = new ArrayList<>(); - - if (unpardonedList != null && !unpardonedList.isEmpty()) { - for (Long sid : unpardonedList) { - unpardoned.add(BSShare.byId(sid)); - } - } - - return unpardoned; - } - - /** - * Get all players that have shares with the configured player. - * - * @return a List of Players, which could be empty if none are shared. - */ - public List getSharesWith() { - if (shareList == null) { - fill(); - } - - List players = new ArrayList<>(); - if (overlaps != null && !overlaps.isEmpty()) { - for (Long pid : overlaps) { - players.add(BSPlayer.byId(pid)); - } - } - - return players; - } - - /** - * Get all Shares between this player and the passed player. - * - * @param player the player to find shares with - * @return a list of shares, might be empty if no shares exist. - */ - public List getSharesWith(BSPlayer player) { - if (shareList == null) { - fill(); - } - List returns = new ArrayList<>(); - if (shareList == null || shareList.isEmpty()) { - return returns; - } - for (Long id : shareList) { - BSShare share = BSShare.byId(id); - if (share != null && (player.getId() == share.getFirstPlayer().getId() - || player.getId() == share.getSecondPlayer().getId())) { - returns.add(share); - } - } - return returns; - } + private BSPlayer forPlayer; + private List shareList; + private Set overlaps; + private Set unpardonedList; - /** - * Check if we have any overlap with a specific player. - * - * @param playerId The player to check - * @return true if any share overlaps, false otherwise. - */ - public boolean doesShareWith(Long playerId) { - if (shareList == null) { - fill(); - } - return overlaps.contains(playerId); - } - - private synchronized void fill() { - if (shareList != null) { - return; - } - try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); - PreparedStatement getIDs = connection.prepareStatement(// Get all ids only, order by create time. - "SELECT sid, first_pid, second_pid, pardon FROM bs_share WHERE first_pid = ? OR second_pid = ? ORDER BY create_time;");) { - getIDs.setLong(1, forPlayer.getId()); - getIDs.setLong(2, forPlayer.getId()); - try (ResultSet rs = getIDs.executeQuery()) { - List localShareList = new ArrayList<>(); - overlaps = new HashSet<>(); - unpardonedList = new HashSet<>(); - while (rs.next()) { - localShareList.add(rs.getLong(1)); - long fpid = rs.getLong(2); - long spid = rs.getLong(3); - boolean pardon = rs.getBoolean(4); - if (fpid == forPlayer.getId()) { - overlaps.add(spid); - } else { - overlaps.add(fpid); - } - if (!pardon) { - unpardonedList.add(rs.getLong(1)); - } - } - if (localShareList.isEmpty()) { - BanStick.getPlugin().info("No Shares for {0}", forPlayer.getName()); - } - shareList = localShareList; - } - } catch (SQLException se) { - BanStick.getPlugin().severe("Failed to get list of Share ids", se); - } - } - - /** - * Check if there's any overlap between this Shares and a given session. - * - * @param overlap The session to check against. - */ - public void check(BSSession overlap) { - if (shareList == null) { - fill(); - } - - // looks for all potential overlaps based on IP information - // Checks for existing overlaps - // If found, do nothing more. - // If new, create a new share. - List allSessions = BSSession.byIP(overlap.getIP()); - for (BSSession session : allSessions) { - if (forPlayer.getId() == session.getPlayer().getId() - || session.getId() == overlap.getId()) { - continue; - } - - if (!overlaps.contains(session.getPlayer().getId())) { // we know. We only record first overlap. - BSShare newOverlap = BSShare.create(overlap, session); - if (newOverlap != null) { - addNew(newOverlap, session.getPlayer()); - session.getPlayer().addShare(newOverlap, forPlayer); - } else { - BanStick.getPlugin().debug("Failed while generating share/overlap?"); - } - } - } - } - - /** - * Adds a new share / player to this BSShare. - * @param share the Share - * @param player the Player - */ - public void addNew(BSShare share, BSPlayer player) { - if (shareList == null) { - fill(); - } - - this.shareList.add(share.getId()); - this.overlaps.add(player.getId()); - this.unpardonedList.add(share.getId()); - // be sure it gets promoted to the opposing record - - BanStick.getPlugin().info("Found new overlap between {0} and {1}", forPlayer.getName(), player.getName()); + private BSShares() { + } - // this happens after the player has already logged in - // if the player has been associated with a banned share, kick them - BSBan ban1 = getActivePlayerBanOrTransitive(share.getFirstPlayer().getUUID()); - BSBan ban = ban1 != null ? ban1 : getActivePlayerBanOrTransitive(share.getSecondPlayer().getUUID()); - if (ban != null) { - BanStick.getPlugin().info("New overlap between {0} and {1} resulting in at least one ban; kicking...", forPlayer.getName(), player.getName()); - doKickWithCheckup(player.getUUID(), ban); - } - } - - /** - * @return Determine share ordinality. - */ - public int shareOrdinality() { - if (shareList == null) { - fill(); - } - return shareList.size(); - } + /** + * Get BSShares DAO for a particular BSPlayer + * + * @param player the Player to look at + * @return the BSShares DAO for this player. + */ + public static BSShares onlyFor(BSPlayer player) { + BSShares shares = new BSShares(); + shares.forPlayer = player; + shares.shareList = null; + shares.overlaps = null; + shares.unpardonedList = null; + return shares; + } - /** - * @return Determine the share unpardoned ordinality - */ - public int unpardonedOrdinality() { - if (shareList == null) { - fill(); - } - return unpardonedList.size(); - } - - /** - * @param share the Share to pardon. - */ - public void markPardoned(BSShare share) { - if (shareList == null) { - fill(); - } - // Check if a share of this Player - // Then check if the Share is actually marked pardoned - // Then shift out of unpardoned list if pardoned. - // Otherwise, correct. - if (shareList.contains(share.getId())) { - if (share.isPardoned()) { - unpardonedList.remove(share.getId()); - } else { - markUnpardoned(share); - } - } - } - - /** - * @param share the Share to unpardon - */ - public void markUnpardoned(BSShare share) { - if (shareList == null) { - fill(); - } - // Check if a share of this Player - // Then check if Share is actually unpardoned - // Then shift into the unpardoned list is unpardoned. - // Otherwise, correct. - if (shareList.contains(share.getId())) { - if (!share.isPardoned()) { - unpardonedList.add(share.getId()); - } else { - markPardoned(share); - } - } - } + /** + * Release a BSShares DAO. + * + * @param shares the BSShares DAO to release. + */ + public static void release(BSShares shares) { + shares.forPlayer = null; + if (shares.shareList != null) { + shares.shareList.clear(); + } + if (shares.overlaps != null) { + shares.overlaps.clear(); + } + if (shares.unpardonedList != null) { + shares.unpardonedList.clear(); + } + shares.shareList = null; + } - /** - * @return the latest Share - */ - public BSShare getLatest() { - if (shareList == null) { - fill(); - } - if (!shareList.isEmpty()) { - return BSShare.byId(shareList.get(shareList.size() - 1)); - } - return null; - } + /** + * Get all Shares related to the configured player. + * + * @return a List of Shares, which could be empty if none are known. + */ + public List getAll() { + if (shareList == null) { + fill(); + } + + List all = new ArrayList<>(); + + if (shareList != null && !shareList.isEmpty()) { + for (Long sid : shareList) { + all.add(BSShare.byId(sid)); + } + } + + return all; + } + + /** + * Get all shares that are not pardoned. + * + * @return a List of Shares, which could be empty if all are pardoned. + */ + public List getUnpardoned() { + if (shareList == null) { + fill(); + } + + List unpardoned = new ArrayList<>(); + + if (unpardonedList != null && !unpardonedList.isEmpty()) { + for (Long sid : unpardonedList) { + unpardoned.add(BSShare.byId(sid)); + } + } + + return unpardoned; + } + + /** + * Get all players that have shares with the configured player. + * + * @return a List of Players, which could be empty if none are shared. + */ + public List getSharesWith() { + if (shareList == null) { + fill(); + } + + List players = new ArrayList<>(); + if (overlaps != null && !overlaps.isEmpty()) { + for (Long pid : overlaps) { + players.add(BSPlayer.byId(pid)); + } + } + + return players; + } + + /** + * Get all Shares between this player and the passed player. + * + * @param player the player to find shares with + * @return a list of shares, might be empty if no shares exist. + */ + public List getSharesWith(BSPlayer player) { + if (shareList == null) { + fill(); + } + List returns = new ArrayList<>(); + if (shareList == null || shareList.isEmpty()) { + return returns; + } + for (Long id : shareList) { + BSShare share = BSShare.byId(id); + if (share != null && (player.getId() == share.getFirstPlayer().getId() + || player.getId() == share.getSecondPlayer().getId())) { + returns.add(share); + } + } + return returns; + } + + /** + * Check if we have any overlap with a specific player. + * + * @param playerId The player to check + * @return true if any share overlaps, false otherwise. + */ + public boolean doesShareWith(Long playerId) { + if (shareList == null) { + fill(); + } + return overlaps.contains(playerId); + } + + private synchronized void fill() { + if (shareList != null) { + return; + } + try (Connection connection = BanStickDatabaseHandler.getInstanceData().getConnection(); + PreparedStatement getIDs = connection.prepareStatement(// Get all ids only, order by create time. + "SELECT sid, first_pid, second_pid, pardon FROM bs_share WHERE first_pid = ? OR second_pid = ? ORDER BY create_time;");) { + getIDs.setLong(1, forPlayer.getId()); + getIDs.setLong(2, forPlayer.getId()); + try (ResultSet rs = getIDs.executeQuery()) { + List localShareList = new ArrayList<>(); + overlaps = new HashSet<>(); + unpardonedList = new HashSet<>(); + while (rs.next()) { + localShareList.add(rs.getLong(1)); + long fpid = rs.getLong(2); + long spid = rs.getLong(3); + boolean pardon = rs.getBoolean(4); + if (fpid == forPlayer.getId()) { + overlaps.add(spid); + } else { + overlaps.add(fpid); + } + if (!pardon) { + unpardonedList.add(rs.getLong(1)); + } + } + if (localShareList.isEmpty()) { + BanStick.getPlugin().info("No Shares for {0}", forPlayer.getName()); + } + shareList = localShareList; + } + } catch (SQLException se) { + BanStick.getPlugin().severe("Failed to get list of Share ids", se); + } + } + + /** + * Check if there's any overlap between this Shares and a given session. + * + * @param overlap The session to check against. + */ + public void check(BSSession overlap) { + if (shareList == null) { + fill(); + } + + // looks for all potential overlaps based on IP information + // Checks for existing overlaps + // If found, do nothing more. + // If new, create a new share. + List allSessions = BSSession.byIP(overlap.getIP()); + for (BSSession session : allSessions) { + if (forPlayer.getId() == session.getPlayer().getId() + || session.getId() == overlap.getId()) { + continue; + } + + if (!overlaps.contains(session.getPlayer().getId())) { // we know. We only record first overlap. + BSShare newOverlap = BSShare.create(overlap, session); + if (newOverlap != null) { + addNew(newOverlap, session.getPlayer()); + session.getPlayer().addShare(newOverlap, forPlayer); + } else { + BanStick.getPlugin().debug("Failed while generating share/overlap?"); + } + } + } + } + + /** + * Adds a new share / player to this BSShare. + * + * @param share the Share + * @param player the Player + */ + public void addNew(BSShare share, BSPlayer player) { + if (shareList == null) { + fill(); + } + + this.shareList.add(share.getId()); + this.overlaps.add(player.getId()); + this.unpardonedList.add(share.getId()); + // be sure it gets promoted to the opposing record + + BanStick.getPlugin().info("Found new overlap between {0} and {1}", forPlayer.getName(), player.getName()); + + // this happens after the player has already logged in + // if the player has been associated with a banned share, kick them + BSBan ban1 = getActivePlayerBanOrTransitive(share.getFirstPlayer().getUUID()); + BSBan ban = ban1 != null ? ban1 : getActivePlayerBanOrTransitive(share.getSecondPlayer().getUUID()); + if (ban != null) { + BanStick.getPlugin().info("New overlap between {0} and {1} resulting in at least one ban; kicking...", forPlayer.getName(), player.getName()); + doKickWithCheckup(player.getUUID(), ban); + } + } + + /** + * @return Determine share ordinality. + */ + public int shareOrdinality() { + if (shareList == null) { + fill(); + } + return shareList.size(); + } + + /** + * @return Determine the share unpardoned ordinality + */ + public int unpardonedOrdinality() { + if (shareList == null) { + fill(); + } + return unpardonedList.size(); + } + + /** + * @param share the Share to pardon. + */ + public void markPardoned(BSShare share) { + if (shareList == null) { + fill(); + } + // Check if a share of this Player + // Then check if the Share is actually marked pardoned + // Then shift out of unpardoned list if pardoned. + // Otherwise, correct. + if (shareList.contains(share.getId())) { + if (share.isPardoned()) { + unpardonedList.remove(share.getId()); + } else { + markUnpardoned(share); + } + } + } + + /** + * @param share the Share to unpardon + */ + public void markUnpardoned(BSShare share) { + if (shareList == null) { + fill(); + } + // Check if a share of this Player + // Then check if Share is actually unpardoned + // Then shift into the unpardoned list is unpardoned. + // Otherwise, correct. + if (shareList.contains(share.getId())) { + if (!share.isPardoned()) { + unpardonedList.add(share.getId()); + } else { + markPardoned(share); + } + } + } + + /** + * @return the latest Share + */ + public BSShare getLatest() { + if (shareList == null) { + fill(); + } + if (!shareList.isEmpty()) { + return BSShare.byId(shareList.get(shareList.size() - 1)); + } + return null; + } } diff --git a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/data/package-info.java b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/data/package-info.java index 16bf316aa..0f4c65cbf 100644 --- a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/data/package-info.java +++ b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/data/package-info.java @@ -1,6 +1,6 @@ /** * Data packages for BanStick; wrappers for DAO, etc. - * + * * @author ProgrammerDan */ package com.programmerdan.minecraft.banstick.data; diff --git a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/handler/BanHandler.java b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/handler/BanHandler.java index f6a851fef..b855431c0 100644 --- a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/handler/BanHandler.java +++ b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/handler/BanHandler.java @@ -17,356 +17,358 @@ import vg.civcraft.mc.namelayer.NameAPI; /** * A series of static utility classes to facilitate issuing bans. - * - * @author ProgrammerDan * + * @author ProgrammerDan */ public final class BanHandler { - private static final String AUTO_BAN = "Automatic Ban"; - private static final String ADMIN_BAN = "Administrative Ban"; + private static final String AUTO_BAN = "Automatic Ban"; + private static final String ADMIN_BAN = "Administrative Ban"; - private BanHandler() { } + private BanHandler() { + } - private static SimpleDateFormat getEndTimeFormat() { - return new SimpleDateFormat("MM/dd/yyyy HH:mms:ss"); - } - - /** - * Issues a ban against a specific UUID. - * - *

If the player is online, kicks them. - * - *

This uses the default message. See {@link #doUUIDBan(UUID, String, boolean)} for custom message, - * or {@link #doUUIDBan(UUID, Date, boolean)} for end time, or {@link #doUUIDBan(UUID, String, Date, boolean)} for - * both. - * - * @param playerId The UUID of the player to ban. - * @param adminBan Was this admin ban or automatic? - * @return A summary of who was banned. - */ - public static BanResult doUUIDBan(UUID playerId, boolean adminBan) { - return doUUIDBan(playerId, null, null, adminBan); - } - - /** - * Issues a ban against a specific UUID. - * - *

If the player is online, kicks them. - * - *

This uses the default message but a custom end time. - * - * @param playerId The UUID of the player to ban. - * @param banEnd The time the ban should end. - * @param adminBan Was this admin ban or automatic? - * @return A summary of who was banned. - */ - public static BanResult doUUIDBan(UUID playerId, Date banEnd, boolean adminBan) { - return doUUIDBan(playerId, null, banEnd, adminBan); - } - - /** - * Issues a ban against a specific UUID. - * - *

If the player is online, kicks them. - * - *

This uses a custom message. - * - * @param playerId The UUID of the player to ban. - * @param message The message to display when a player attempts to rejoin. - * @param adminBan Was this admin ban or automatic? - * @return A summary of who was banned. - */ - public static BanResult doUUIDBan(UUID playerId, String message, boolean adminBan) { - return doUUIDBan(playerId, message, null, adminBan); - } - - /** - * Issues a ban against a specific UUID. - * - *

If the player is online, kicks them. - * - *

This uses a custom message and end time. - * - * @param playerId The UUID of the player to ban. - * @param message The message to display when a player attempts to rejoin. - * @param banEnd The time the ban should end. - * @param adminBan Was this admin ban or automatic? - * @return A summary of who was banned. - */ - public static BanResult doUUIDBan(UUID playerId, String message, Date banEnd, boolean adminBan) { - try { - if (message == null || message.trim().equals("")) { - message = adminBan ? ADMIN_BAN : AUTO_BAN; // TODO: config! - } - Player spigotPlayer = Bukkit.getPlayer(playerId); - BSPlayer player = BSPlayer.byUUID(playerId); - if (player == null) { - if (spigotPlayer != null) { - player = BSPlayer.create(spigotPlayer); - } else { - String playerName = null; - try { - playerName = NameAPI.getCurrentName(playerId); - } catch (NoClassDefFoundError ncde) { } - - player = BSPlayer.create(playerId, playerName); - } - } - BSBan ban = BSBan.create(message, banEnd, adminBan); // general ban. - player.setBan(ban); - - if (spigotPlayer != null) { - if (banEnd != null) { - spigotPlayer.kickPlayer(message + ". Ends " + BanHandler.getEndTimeFormat().format(banEnd)); - } else { - spigotPlayer.kickPlayer(message); - } - } - - BanResult result = new BanResult(); - result.addPlayer(player); - return result; - } catch (Exception e) { - BanStick.getPlugin().warning("Failed to issue UUID ban: ", e); - return new BanResult(); - } - } + private static SimpleDateFormat getEndTimeFormat() { + return new SimpleDateFormat("MM/dd/yyyy HH:mms:ss"); + } - /** - * Issues a ban against an IP address. - * After the ban is created, finds all accounts that are using the IP address and bans them, unless - * already banned or pardoned. - * - * @param exactIP The IP address to ban. - * @param message The message to use as a ban message; is also sent to all players who are - * online and caught in the ban. - * @param banEnd When does the ban end? - * @param adminBan Was this an administrative ban? - * @param includeHistoric Ban everyone who has ever used this IP address? - * @return A BanResult object describing who was banned. - */ - public static BanResult doIPBan(BSIP exactIP, String message, Date banEnd, - boolean adminBan, boolean includeHistoric) { - try { - if (message == null || message.trim().equals("")) { - message = adminBan ? ADMIN_BAN : AUTO_BAN; // TODO: config! - } - // TODO: match with existing ban for this IP. - BSBan ban = BSBan.create(exactIP, message, banEnd, adminBan); // general ban. - BanResult result = new BanResult(); - result.addBan(ban); - - for (Player player : Bukkit.getOnlinePlayers()) { - BSPlayer banPlayer = BSPlayer.byUUID(player.getUniqueId()); - if (banPlayer.getIPPardonTime() != null) { - continue; // pardoned from IP match bans. - } - BSSession active = banPlayer.getLatestSession(); - if (active.getIP().getId() == exactIP.getId() && banPlayer.getBan() == null) { - // TODO replace with equality check. - banPlayer.setBan(ban); - result.addPlayer(banPlayer); - if (banEnd != null) { - player.kickPlayer(message + ". Ends " + BanHandler.getEndTimeFormat().format(banEnd)); - } else { - player.kickPlayer(message); - } - } - } - - if (includeHistoric) { - List sessions = BSSession.byIP(exactIP); - for (BSSession session : sessions) { - BSPlayer banPlayer = session.getPlayer(); - if (banPlayer.getIPPardonTime() != null) { - continue; // pardoned from IP match bans. - } - if (session.getPlayer().getBan() == null) { - banPlayer.setBan(ban); - result.addPlayer(banPlayer); - } - } - } - - return result; - } catch (Exception e) { - BanStick.getPlugin().warning("Failed to issue IP ban: ", e); - return new BanResult(); - } - } - - /** - * Does a ban against a CIDR range. - * - * @param cidrIP cidr IP range to ban - * @param message Message to record as ban reason - * @param banEnd The time to end the ban - * @param adminBan Is this an administrative ban? - * @param includeHistoric Should we include all historic occurrences of this IP in the ban? - * @return A BanResult with the bans issued, if any - */ - public static BanResult doCIDRBan(BSIP cidrIP, String message, Date banEnd, - boolean adminBan, boolean includeHistoric) { - try { - if (message == null || message.trim().equals("")) { - message = adminBan ? ADMIN_BAN : AUTO_BAN; // TODO: config! - } - BSBan ban = BSBan.create(cidrIP, message, banEnd, adminBan); // general ban. - BanResult result = new BanResult(); - result.addBan(ban); - - for (Player player : Bukkit.getOnlinePlayers()) { - BSPlayer banPlayer = BSPlayer.byUUID(player.getUniqueId()); - if (banPlayer.getBan() != null) { - continue; // already banned. - } - if (banPlayer.getIPPardonTime() != null) { - continue; // pardoned from IP match bans. - } - - BSSession active = banPlayer.getLatestSession(); - BSIP activeIP = active.getIP(); - boolean doBan = false; - if (cidrIP.getIPv4Address() != null && activeIP.getIPv4Address() != null) { - // check IPv4 - if (cidrIP.getIPv4Address().contains(activeIP.getIPv4Address())) { - doBan = true; - } - } else if (cidrIP.getIPv6Address() != null && activeIP.getIPv6Address() != null) { - if (cidrIP.getIPv6Address().contains(activeIP.getIPv6Address())) { - doBan = true; - } - } // if mismatched, don't ban. - - if (doBan) { - banPlayer.setBan(ban); - result.addPlayer(banPlayer); - if (banEnd != null) { - player.kickPlayer(message + ". Ends " + BanHandler.getEndTimeFormat().format(banEnd)); - } else { - player.kickPlayer(message); - } - } - } - - if (includeHistoric) { - List ipsIn = BSIP.allContained(cidrIP.getIPAddress().getLower(), - cidrIP.getIPAddress().getNetworkPrefixLength()); - for (BSIP exactIP : ipsIn) { - List sessions = BSSession.byIP(exactIP); - for (BSSession session : sessions) { - BSPlayer banPlayer = session.getPlayer(); - if (banPlayer.getIPPardonTime() != null) { - continue; // pardoned from IP match bans. - } - if (session.getPlayer().getBan() == null) { - banPlayer.setBan(ban); - result.addPlayer(banPlayer); - } - } - } - } - - return result; - } catch (Exception e) { - BanStick.getPlugin().warning("Failed to issue CIDR ban: ", e); - return new BanResult(); - } - } + /** + * Issues a ban against a specific UUID. + * + *

If the player is online, kicks them. + * + *

This uses the default message. See {@link #doUUIDBan(UUID, String, boolean)} for custom message, + * or {@link #doUUIDBan(UUID, Date, boolean)} for end time, or {@link #doUUIDBan(UUID, String, Date, boolean)} for + * both. + * + * @param playerId The UUID of the player to ban. + * @param adminBan Was this admin ban or automatic? + * @return A summary of who was banned. + */ + public static BanResult doUUIDBan(UUID playerId, boolean adminBan) { + return doUUIDBan(playerId, null, null, adminBan); + } - /** - * Given a share, ban both (or if limitBanTo is set, just one) with a specified message / end / admin flag - * @param share The share to ban - * @param limitBanTo optional player to limit to - * @param message the ban message - * @param banEnd the end of the ban - * @param adminBan is this an admin ban? - * @return the result of the ban as a BanResult - */ - public static BanResult doShareBan(BSShare share, BSPlayer limitBanTo, String message, - Date banEnd, boolean adminBan) { - try { - if (message == null || message.trim().equals("")) { - message = adminBan ? ADMIN_BAN : AUTO_BAN; // TODO: config! - } - BSBan ban = BSBan.create(share, message, banEnd, adminBan); // share ban - BanResult result = new BanResult(); - result.addBan(ban); - if (limitBanTo == null) { // do both - if (share.getFirstPlayer().getSharedPardonTime() == null && share.getFirstPlayer().getBan() == null) { - share.getFirstPlayer().setBan(ban); - result.addPlayer(share.getFirstPlayer()); - } - if (share.getSecondPlayer().getSharedPardonTime() == null && share.getSecondPlayer().getBan() == null) { - share.getSecondPlayer().setBan(ban); - result.addPlayer(share.getSecondPlayer()); - } - } else { - if (share.getFirstPlayer().getId() == limitBanTo.getId() - && share.getFirstPlayer().getSharedPardonTime() == null - && share.getFirstPlayer().getBan() == null) { - share.getFirstPlayer().setBan(ban); - result.addPlayer(share.getFirstPlayer()); - } - if (share.getSecondPlayer().getId() == limitBanTo.getId() - && share.getSecondPlayer().getSharedPardonTime() == null - && share.getSecondPlayer().getBan() == null) { - share.getSecondPlayer().setBan(ban); - result.addPlayer(share.getSecondPlayer()); - } - } - return result; - } catch (Exception e) { - BanStick.getPlugin().warning("Failed to issue Share ban: ", e); - return new BanResult(); - } - } + /** + * Issues a ban against a specific UUID. + * + *

If the player is online, kicks them. + * + *

This uses the default message but a custom end time. + * + * @param playerId The UUID of the player to ban. + * @param banEnd The time the ban should end. + * @param adminBan Was this admin ban or automatic? + * @return A summary of who was banned. + */ + public static BanResult doUUIDBan(UUID playerId, Date banEnd, boolean adminBan) { + return doUUIDBan(playerId, null, banEnd, adminBan); + } - /** - * Checks whether a player is banned. - * - * @param player The player to check if banned. - * @return Returns true if the player is banned. - */ - public static boolean isPlayerBanned(final Player player) { - return isPlayerBanned(player.getUniqueId()); - } + /** + * Issues a ban against a specific UUID. + * + *

If the player is online, kicks them. + * + *

This uses a custom message. + * + * @param playerId The UUID of the player to ban. + * @param message The message to display when a player attempts to rejoin. + * @param adminBan Was this admin ban or automatic? + * @return A summary of who was banned. + */ + public static BanResult doUUIDBan(UUID playerId, String message, boolean adminBan) { + return doUUIDBan(playerId, message, null, adminBan); + } - /** - * Checks whether a player is banned. - * - * @param puuid The player UUID to check if banned. - * @return Returns true if the player is banned. - */ - public static boolean isPlayerBanned(final UUID puuid) { - BSBan ban = getActivePlayerBanOrTransitive(puuid); - return ban != null; - } + /** + * Issues a ban against a specific UUID. + * + *

If the player is online, kicks them. + * + *

This uses a custom message and end time. + * + * @param playerId The UUID of the player to ban. + * @param message The message to display when a player attempts to rejoin. + * @param banEnd The time the ban should end. + * @param adminBan Was this admin ban or automatic? + * @return A summary of who was banned. + */ + public static BanResult doUUIDBan(UUID playerId, String message, Date banEnd, boolean adminBan) { + try { + if (message == null || message.trim().equals("")) { + message = adminBan ? ADMIN_BAN : AUTO_BAN; // TODO: config! + } + Player spigotPlayer = Bukkit.getPlayer(playerId); + BSPlayer player = BSPlayer.byUUID(playerId); + if (player == null) { + if (spigotPlayer != null) { + player = BSPlayer.create(spigotPlayer); + } else { + String playerName = null; + try { + playerName = NameAPI.getCurrentName(playerId); + } catch (NoClassDefFoundError ncde) { + } - /** - * Checks whether a player is banned, and returns the ban. - * - * @param puuid The player UUID to check if banned. - * @return Returns true if the player is banned. - */ - public static BSBan getActivePlayerBanOrTransitive(final UUID puuid) { - final BSPlayer bsPlayer = BSPlayer.byUUID(puuid); - if (bsPlayer == null) { - return null; - } - final BSBan bsBan = bsPlayer.getBan(); - if (bsBan != null && !bsBan.hasBanExpired()) { - return bsBan; - } - if (BanStick.getPlugin().getEventHandler().areTransitiveBansEnabled()) { - for (final BSPlayer alt : bsPlayer.getTransitiveSharedPlayers(true)) { - final BSBan bsAltBan = alt.getBan(); - if (bsAltBan != null && !bsAltBan.hasBanExpired()) { - return bsAltBan; - } - } - } - return null; - } + player = BSPlayer.create(playerId, playerName); + } + } + BSBan ban = BSBan.create(message, banEnd, adminBan); // general ban. + player.setBan(ban); + + if (spigotPlayer != null) { + if (banEnd != null) { + spigotPlayer.kickPlayer(message + ". Ends " + BanHandler.getEndTimeFormat().format(banEnd)); + } else { + spigotPlayer.kickPlayer(message); + } + } + + BanResult result = new BanResult(); + result.addPlayer(player); + return result; + } catch (Exception e) { + BanStick.getPlugin().warning("Failed to issue UUID ban: ", e); + return new BanResult(); + } + } + + /** + * Issues a ban against an IP address. + * After the ban is created, finds all accounts that are using the IP address and bans them, unless + * already banned or pardoned. + * + * @param exactIP The IP address to ban. + * @param message The message to use as a ban message; is also sent to all players who are + * online and caught in the ban. + * @param banEnd When does the ban end? + * @param adminBan Was this an administrative ban? + * @param includeHistoric Ban everyone who has ever used this IP address? + * @return A BanResult object describing who was banned. + */ + public static BanResult doIPBan(BSIP exactIP, String message, Date banEnd, + boolean adminBan, boolean includeHistoric) { + try { + if (message == null || message.trim().equals("")) { + message = adminBan ? ADMIN_BAN : AUTO_BAN; // TODO: config! + } + // TODO: match with existing ban for this IP. + BSBan ban = BSBan.create(exactIP, message, banEnd, adminBan); // general ban. + BanResult result = new BanResult(); + result.addBan(ban); + + for (Player player : Bukkit.getOnlinePlayers()) { + BSPlayer banPlayer = BSPlayer.byUUID(player.getUniqueId()); + if (banPlayer.getIPPardonTime() != null) { + continue; // pardoned from IP match bans. + } + BSSession active = banPlayer.getLatestSession(); + if (active.getIP().getId() == exactIP.getId() && banPlayer.getBan() == null) { + // TODO replace with equality check. + banPlayer.setBan(ban); + result.addPlayer(banPlayer); + if (banEnd != null) { + player.kickPlayer(message + ". Ends " + BanHandler.getEndTimeFormat().format(banEnd)); + } else { + player.kickPlayer(message); + } + } + } + + if (includeHistoric) { + List sessions = BSSession.byIP(exactIP); + for (BSSession session : sessions) { + BSPlayer banPlayer = session.getPlayer(); + if (banPlayer.getIPPardonTime() != null) { + continue; // pardoned from IP match bans. + } + if (session.getPlayer().getBan() == null) { + banPlayer.setBan(ban); + result.addPlayer(banPlayer); + } + } + } + + return result; + } catch (Exception e) { + BanStick.getPlugin().warning("Failed to issue IP ban: ", e); + return new BanResult(); + } + } + + /** + * Does a ban against a CIDR range. + * + * @param cidrIP cidr IP range to ban + * @param message Message to record as ban reason + * @param banEnd The time to end the ban + * @param adminBan Is this an administrative ban? + * @param includeHistoric Should we include all historic occurrences of this IP in the ban? + * @return A BanResult with the bans issued, if any + */ + public static BanResult doCIDRBan(BSIP cidrIP, String message, Date banEnd, + boolean adminBan, boolean includeHistoric) { + try { + if (message == null || message.trim().equals("")) { + message = adminBan ? ADMIN_BAN : AUTO_BAN; // TODO: config! + } + BSBan ban = BSBan.create(cidrIP, message, banEnd, adminBan); // general ban. + BanResult result = new BanResult(); + result.addBan(ban); + + for (Player player : Bukkit.getOnlinePlayers()) { + BSPlayer banPlayer = BSPlayer.byUUID(player.getUniqueId()); + if (banPlayer.getBan() != null) { + continue; // already banned. + } + if (banPlayer.getIPPardonTime() != null) { + continue; // pardoned from IP match bans. + } + + BSSession active = banPlayer.getLatestSession(); + BSIP activeIP = active.getIP(); + boolean doBan = false; + if (cidrIP.getIPv4Address() != null && activeIP.getIPv4Address() != null) { + // check IPv4 + if (cidrIP.getIPv4Address().contains(activeIP.getIPv4Address())) { + doBan = true; + } + } else if (cidrIP.getIPv6Address() != null && activeIP.getIPv6Address() != null) { + if (cidrIP.getIPv6Address().contains(activeIP.getIPv6Address())) { + doBan = true; + } + } // if mismatched, don't ban. + + if (doBan) { + banPlayer.setBan(ban); + result.addPlayer(banPlayer); + if (banEnd != null) { + player.kickPlayer(message + ". Ends " + BanHandler.getEndTimeFormat().format(banEnd)); + } else { + player.kickPlayer(message); + } + } + } + + if (includeHistoric) { + List ipsIn = BSIP.allContained(cidrIP.getIPAddress().getLower(), + cidrIP.getIPAddress().getNetworkPrefixLength()); + for (BSIP exactIP : ipsIn) { + List sessions = BSSession.byIP(exactIP); + for (BSSession session : sessions) { + BSPlayer banPlayer = session.getPlayer(); + if (banPlayer.getIPPardonTime() != null) { + continue; // pardoned from IP match bans. + } + if (session.getPlayer().getBan() == null) { + banPlayer.setBan(ban); + result.addPlayer(banPlayer); + } + } + } + } + + return result; + } catch (Exception e) { + BanStick.getPlugin().warning("Failed to issue CIDR ban: ", e); + return new BanResult(); + } + } + + /** + * Given a share, ban both (or if limitBanTo is set, just one) with a specified message / end / admin flag + * + * @param share The share to ban + * @param limitBanTo optional player to limit to + * @param message the ban message + * @param banEnd the end of the ban + * @param adminBan is this an admin ban? + * @return the result of the ban as a BanResult + */ + public static BanResult doShareBan(BSShare share, BSPlayer limitBanTo, String message, + Date banEnd, boolean adminBan) { + try { + if (message == null || message.trim().equals("")) { + message = adminBan ? ADMIN_BAN : AUTO_BAN; // TODO: config! + } + BSBan ban = BSBan.create(share, message, banEnd, adminBan); // share ban + BanResult result = new BanResult(); + result.addBan(ban); + if (limitBanTo == null) { // do both + if (share.getFirstPlayer().getSharedPardonTime() == null && share.getFirstPlayer().getBan() == null) { + share.getFirstPlayer().setBan(ban); + result.addPlayer(share.getFirstPlayer()); + } + if (share.getSecondPlayer().getSharedPardonTime() == null && share.getSecondPlayer().getBan() == null) { + share.getSecondPlayer().setBan(ban); + result.addPlayer(share.getSecondPlayer()); + } + } else { + if (share.getFirstPlayer().getId() == limitBanTo.getId() + && share.getFirstPlayer().getSharedPardonTime() == null + && share.getFirstPlayer().getBan() == null) { + share.getFirstPlayer().setBan(ban); + result.addPlayer(share.getFirstPlayer()); + } + if (share.getSecondPlayer().getId() == limitBanTo.getId() + && share.getSecondPlayer().getSharedPardonTime() == null + && share.getSecondPlayer().getBan() == null) { + share.getSecondPlayer().setBan(ban); + result.addPlayer(share.getSecondPlayer()); + } + } + return result; + } catch (Exception e) { + BanStick.getPlugin().warning("Failed to issue Share ban: ", e); + return new BanResult(); + } + } + + /** + * Checks whether a player is banned. + * + * @param player The player to check if banned. + * @return Returns true if the player is banned. + */ + public static boolean isPlayerBanned(final Player player) { + return isPlayerBanned(player.getUniqueId()); + } + + /** + * Checks whether a player is banned. + * + * @param puuid The player UUID to check if banned. + * @return Returns true if the player is banned. + */ + public static boolean isPlayerBanned(final UUID puuid) { + BSBan ban = getActivePlayerBanOrTransitive(puuid); + return ban != null; + } + + /** + * Checks whether a player is banned, and returns the ban. + * + * @param puuid The player UUID to check if banned. + * @return Returns true if the player is banned. + */ + public static BSBan getActivePlayerBanOrTransitive(final UUID puuid) { + final BSPlayer bsPlayer = BSPlayer.byUUID(puuid); + if (bsPlayer == null) { + return null; + } + final BSBan bsBan = bsPlayer.getBan(); + if (bsBan != null && !bsBan.hasBanExpired()) { + return bsBan; + } + if (BanStick.getPlugin().getEventHandler().areTransitiveBansEnabled()) { + for (final BSPlayer alt : bsPlayer.getTransitiveSharedPlayers(true)) { + final BSBan bsAltBan = alt.getBan(); + if (bsAltBan != null && !bsAltBan.hasBanExpired()) { + return bsAltBan; + } + } + } + return null; + } } diff --git a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/handler/BanStickCommandHandler.java b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/handler/BanStickCommandHandler.java index 98d4b79ab..6064cc057 100644 --- a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/handler/BanStickCommandHandler.java +++ b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/handler/BanStickCommandHandler.java @@ -20,35 +20,34 @@ import org.bukkit.configuration.file.FileConfiguration; * Handles Commands for this plugin. Check plugin.yml for details! * * @author ProgrammerDan - * */ public class BanStickCommandHandler { - public BanStickCommandHandler(FileConfiguration config) { - registerCommands(); - } + public BanStickCommandHandler(FileConfiguration config) { + registerCommands(); + } - private void registerCommands() { - safeRegisterCommand(BanStickCommand.name, new BanStickCommand()); - safeRegisterCommand(DoubleTapCommand.name, new DoubleTapCommand()); - safeRegisterCommand(ForgiveCommand.name, new ForgiveCommand()); - safeRegisterCommand(BanSaveCommand.name, new BanSaveCommand()); - safeRegisterCommand(LoveTapCommand.name, new LoveTapCommand()); - safeRegisterCommand(TakeItBackCommand.name, new TakeItBackCommand()); - safeRegisterCommand(DowsingRodCommand.name, new DowsingRodCommand()); - safeRegisterCommand(DrillDownCommand.name, new DrillDownCommand()); - safeRegisterCommand(UntangleCommand.name, new UntangleCommand()); - safeRegisterCommand(GetAltsCommand.name, new GetAltsCommand()); - safeRegisterCommand(BanRegistrarCommand.name, new BanRegistrarCommand()); - } - - private void safeRegisterCommand(String name, CommandExecutor executor) { - PluginCommand command = BanStick.getPlugin().getCommand(name); - if (command != null) { - command.setExecutor(executor); - } else { - BanStick.getPlugin().severe("Failed to register command: " + name); - } - } + private void registerCommands() { + safeRegisterCommand(BanStickCommand.name, new BanStickCommand()); + safeRegisterCommand(DoubleTapCommand.name, new DoubleTapCommand()); + safeRegisterCommand(ForgiveCommand.name, new ForgiveCommand()); + safeRegisterCommand(BanSaveCommand.name, new BanSaveCommand()); + safeRegisterCommand(LoveTapCommand.name, new LoveTapCommand()); + safeRegisterCommand(TakeItBackCommand.name, new TakeItBackCommand()); + safeRegisterCommand(DowsingRodCommand.name, new DowsingRodCommand()); + safeRegisterCommand(DrillDownCommand.name, new DrillDownCommand()); + safeRegisterCommand(UntangleCommand.name, new UntangleCommand()); + safeRegisterCommand(GetAltsCommand.name, new GetAltsCommand()); + safeRegisterCommand(BanRegistrarCommand.name, new BanRegistrarCommand()); + } + + private void safeRegisterCommand(String name, CommandExecutor executor) { + PluginCommand command = BanStick.getPlugin().getCommand(name); + if (command != null) { + command.setExecutor(executor); + } else { + BanStick.getPlugin().severe("Failed to register command: " + name); + } + } } diff --git a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/handler/BanStickDatabaseHandler.java b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/handler/BanStickDatabaseHandler.java index b0bb133cd..5b750fba8 100644 --- a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/handler/BanStickDatabaseHandler.java +++ b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/handler/BanStickDatabaseHandler.java @@ -23,436 +23,443 @@ import vg.civcraft.mc.civmodcore.dao.ManagedDatasource; * Ties into the managed datasource processes of the CivMod core plugin. * * @author ProgrammerDan - * */ public class BanStickDatabaseHandler { - private static BanStickDatabaseHandler instance; + private static BanStickDatabaseHandler instance; - private ManagedDatasource data; + private ManagedDatasource data; - /** - * Creates the core DAO handler from a config. - * - * @param config the config to use - * @throws RuntimeException if database config is missing or invalid. - */ - public BanStickDatabaseHandler(FileConfiguration config) { - ConfigurationSection internal = config.getConfigurationSection("database"); - if (internal == null || !configureData(internal)) { - throw new RuntimeException("Failed to configure Database for BanStick!"); - } - BanStickDatabaseHandler.instance = this; - } + /** + * Creates the core DAO handler from a config. + * + * @param config the config to use + * @throws RuntimeException if database config is missing or invalid. + */ + public BanStickDatabaseHandler(FileConfiguration config) { + ConfigurationSection internal = config.getConfigurationSection("database"); + if (internal == null || !configureData(internal)) { + throw new RuntimeException("Failed to configure Database for BanStick!"); + } + BanStickDatabaseHandler.instance = this; + } - public ManagedDatasource getData() { - return this.data; - } + public ManagedDatasource getData() { + return this.data; + } - public static BanStickDatabaseHandler getInstance() { - return BanStickDatabaseHandler.instance; - } + public static BanStickDatabaseHandler getInstance() { + return BanStickDatabaseHandler.instance; + } - public static ManagedDatasource getInstanceData() { - return BanStickDatabaseHandler.instance.data; - } + public static ManagedDatasource getInstanceData() { + return BanStickDatabaseHandler.instance.data; + } - private boolean configureData(ConfigurationSection config) { - String host = config.getString("host", "localhost"); - int port = config.getInt("port", 3306); - String dbname = config.getString("database", "banstick"); - String username = config.getString("user"); - String password = config.getString("password"); - int poolsize = config.getInt("poolsize", 5); - long connectionTimeout = config.getLong("connection_timeout", 10000L); - long idleTimeout = config.getLong("idle_timeout", 600000L); - long maxLifetime = config.getLong("max_lifetime", 7200000L); - try { - data = ManagedDatasource.construct(BanStick.getPlugin(), new DatabaseCredentials(username, password, host, port, "mysql", dbname, - poolsize, connectionTimeout, idleTimeout, maxLifetime)); - data.getConnection().close(); - } catch (Exception se) { - BanStick.getPlugin().info("Failed to initialize Database connection"); - se.printStackTrace(); - return false; - } + private boolean configureData(ConfigurationSection config) { + String host = config.getString("host", "localhost"); + int port = config.getInt("port", 3306); + String dbname = config.getString("database", "banstick"); + String username = config.getString("user"); + String password = config.getString("password"); + int poolsize = config.getInt("poolsize", 5); + long connectionTimeout = config.getLong("connection_timeout", 10000L); + long idleTimeout = config.getLong("idle_timeout", 600000L); + long maxLifetime = config.getLong("max_lifetime", 7200000L); + try { + data = ManagedDatasource.construct(BanStick.getPlugin(), new DatabaseCredentials(username, password, host, port, "mysql", dbname, + poolsize, connectionTimeout, idleTimeout, maxLifetime)); + data.getConnection().close(); + } catch (Exception se) { + BanStick.getPlugin().info("Failed to initialize Database connection"); + se.printStackTrace(); + return false; + } - initializeTables(); - stageUpdates(); + initializeTables(); + stageUpdates(); - long beginTime = System.currentTimeMillis(); + long beginTime = System.currentTimeMillis(); - try { - BanStick.getPlugin().info("Update prepared, starting database update."); - if (!data.updateDatabase()) { - BanStick.getPlugin().info("Update failed, disabling plugin."); - return false; - } - } catch (Exception e) { - BanStick.getPlugin().severe("Update failed, disabling plugin. Cause:", e); - return false; - } + try { + BanStick.getPlugin().info("Update prepared, starting database update."); + if (!data.updateDatabase()) { + BanStick.getPlugin().info("Update failed, disabling plugin."); + return false; + } + } catch (Exception e) { + BanStick.getPlugin().severe("Update failed, disabling plugin. Cause:", e); + return false; + } - BanStick.getPlugin().info(String.format("Database update took %d seconds", - (System.currentTimeMillis() - beginTime) / 1000)); + BanStick.getPlugin().info(String.format("Database update took %d seconds", + (System.currentTimeMillis() - beginTime) / 1000)); - activatePreload(config.getConfigurationSection("preload")); - activateDirtySave(config.getConfigurationSection("dirtysave")); - return true; - } + activatePreload(config.getConfigurationSection("preload")); + activateDirtySave(config.getConfigurationSection("dirtysave")); + return true; + } - private void activateDirtySave(ConfigurationSection config) { - long period = 5 * 60 * 50L; - long delay = 5 * 60 * 50L; - if (config != null) { - period = config.getLong("period", period); - delay = config.getLong("delay", delay); - } - BanStick.getPlugin().debug("DirtySave Period {0} Delay {1}", period, delay); + private void activateDirtySave(ConfigurationSection config) { + long period = 5 * 60 * 50L; + long delay = 5 * 60 * 50L; + if (config != null) { + period = config.getLong("period", period); + delay = config.getLong("delay", delay); + } + BanStick.getPlugin().debug("DirtySave Period {0} Delay {1}", period, delay); - Bukkit.getScheduler().runTaskTimerAsynchronously(BanStick.getPlugin(), new Runnable() { - @Override - public void run() { - BanStick.getPlugin().debug("Player dirty save"); - BSPlayer.saveDirty(); - } - }, delay, period); + Bukkit.getScheduler().runTaskTimerAsynchronously(BanStick.getPlugin(), new Runnable() { + @Override + public void run() { + BanStick.getPlugin().debug("Player dirty save"); + BSPlayer.saveDirty(); + } + }, delay, period); - Bukkit.getScheduler().runTaskTimerAsynchronously(BanStick.getPlugin(), new Runnable() { - @Override - public void run() { - BanStick.getPlugin().debug("Ban dirty save"); - BSBan.saveDirty(); - } - }, delay + (period / 5), period); + Bukkit.getScheduler().runTaskTimerAsynchronously(BanStick.getPlugin(), new Runnable() { + @Override + public void run() { + BanStick.getPlugin().debug("Ban dirty save"); + BSBan.saveDirty(); + } + }, delay + (period / 5), period); - Bukkit.getScheduler().runTaskTimerAsynchronously(BanStick.getPlugin(), new Runnable() { - @Override - public void run() { - BanStick.getPlugin().debug("Session dirty save"); - BSSession.saveDirty(); - } - }, delay + ((period * 2) / 5), period); + Bukkit.getScheduler().runTaskTimerAsynchronously(BanStick.getPlugin(), new Runnable() { + @Override + public void run() { + BanStick.getPlugin().debug("Session dirty save"); + BSSession.saveDirty(); + } + }, delay + ((period * 2) / 5), period); - Bukkit.getScheduler().runTaskTimerAsynchronously(BanStick.getPlugin(), new Runnable() { - @Override - public void run() { - BanStick.getPlugin().debug("Share dirty save"); - BSShare.saveDirty(); - } - }, delay + ((period * 3) / 5), period); + Bukkit.getScheduler().runTaskTimerAsynchronously(BanStick.getPlugin(), new Runnable() { + @Override + public void run() { + BanStick.getPlugin().debug("Share dirty save"); + BSShare.saveDirty(); + } + }, delay + ((period * 3) / 5), period); - Bukkit.getScheduler().runTaskTimerAsynchronously(BanStick.getPlugin(), new Runnable() { - @Override - public void run() { - BanStick.getPlugin().debug("Proxy dirty save"); - BSIPData.saveDirty(); - } - }, delay + ((period * 4) / 5), period); + Bukkit.getScheduler().runTaskTimerAsynchronously(BanStick.getPlugin(), new Runnable() { + @Override + public void run() { + BanStick.getPlugin().debug("Proxy dirty save"); + BSIPData.saveDirty(); + } + }, delay + ((period * 4) / 5), period); - BanStick.getPlugin().info("Dirty save tasks started."); - } + BanStick.getPlugin().info("Dirty save tasks started."); + } - private void activatePreload(ConfigurationSection config) { - if (config != null && config.getBoolean("enabled")) { - long period = 5 * 60 * 50L; - long delay = 5 * 60 * 50L; - period = config.getLong("period", period); - delay = config.getLong("delay", delay); - final int batchsize = config.getInt("batch", 100); + private void activatePreload(ConfigurationSection config) { + if (config != null && config.getBoolean("enabled")) { + long period = 5 * 60 * 50L; + long delay = 5 * 60 * 50L; + period = config.getLong("period", period); + delay = config.getLong("delay", delay); + final int batchsize = config.getInt("batch", 100); - BanStick.getPlugin().debug("Preload Period {0} Delay {1} batch {2}", period, delay, batchsize); + BanStick.getPlugin().debug("Preload Period {0} Delay {1} batch {2}", period, delay, batchsize); - new BukkitRunnable() { - private long lastId; - @Override - public void run() { - BanStick.getPlugin().debug("IP preload {0}, lim {1}", lastId, batchsize); - lastId = BSIP.preload(lastId, batchsize); - if (lastId < 0) { - this.cancel(); - } - } - }.runTaskTimerAsynchronously(BanStick.getPlugin(), delay, period); + new BukkitRunnable() { + private long lastId; - new BukkitRunnable() { - private long lastId; - @Override - public void run() { - BanStick.getPlugin().debug("Proxy preload {0}, lim {1}", lastId, batchsize); - lastId = BSIPData.preload(lastId, batchsize); - if (lastId < 0) { - this.cancel(); - } - } - }.runTaskTimerAsynchronously(BanStick.getPlugin(), delay + (period / 6), period); + @Override + public void run() { + BanStick.getPlugin().debug("IP preload {0}, lim {1}", lastId, batchsize); + lastId = BSIP.preload(lastId, batchsize); + if (lastId < 0) { + this.cancel(); + } + } + }.runTaskTimerAsynchronously(BanStick.getPlugin(), delay, period); - new BukkitRunnable() { - private long lastId; - @Override - public void run() { - BanStick.getPlugin().debug("Ban preload {0}, lim {1}", lastId, batchsize); - lastId = BSBan.preload(lastId, batchsize, false); - if (lastId < 0) { - this.cancel(); - } - } - }.runTaskTimerAsynchronously(BanStick.getPlugin(), delay + ((period * 2) / 6), period); + new BukkitRunnable() { + private long lastId; - new BukkitRunnable() { - private long lastId; - @Override - public void run() { - BanStick.getPlugin().debug("Player preload {0}, lim {1}", lastId, batchsize); - lastId = BSPlayer.preload(lastId, batchsize); - if (lastId < 0) { - this.cancel(); - } - } - }.runTaskTimerAsynchronously(BanStick.getPlugin(), delay + ((period * 3) / 6), period); + @Override + public void run() { + BanStick.getPlugin().debug("Proxy preload {0}, lim {1}", lastId, batchsize); + lastId = BSIPData.preload(lastId, batchsize); + if (lastId < 0) { + this.cancel(); + } + } + }.runTaskTimerAsynchronously(BanStick.getPlugin(), delay + (period / 6), period); - new BukkitRunnable() { - private long lastId; - @Override - public void run() { - BanStick.getPlugin().debug("Session preload {0}, lim {1}", lastId, batchsize); - lastId = BSSession.preload(lastId, batchsize); - if (lastId < 0) { - this.cancel(); - } - } - }.runTaskTimerAsynchronously(BanStick.getPlugin(), delay + ((period * 4) / 6), period); + new BukkitRunnable() { + private long lastId; - new BukkitRunnable() { - private long lastId; - @Override - public void run() { - BanStick.getPlugin().debug("Share preload {0}, lim {1}", lastId, batchsize); - lastId = BSShare.preload(lastId, batchsize); - if (lastId < 0) { - this.cancel(); - } - } - }.runTaskTimerAsynchronously(BanStick.getPlugin(), delay + ((period * 5) / 6), period); - } else { - BanStick.getPlugin().info("Preloading is disabled. Expect more lag on joins, lookups, and bans."); - } + @Override + public void run() { + BanStick.getPlugin().debug("Ban preload {0}, lim {1}", lastId, batchsize); + lastId = BSBan.preload(lastId, batchsize, false); + if (lastId < 0) { + this.cancel(); + } + } + }.runTaskTimerAsynchronously(BanStick.getPlugin(), delay + ((period * 2) / 6), period); - } + new BukkitRunnable() { + private long lastId; - /** - * Basic method to set up data model v1. - */ - private void initializeTables() { - data.registerMigration(0, false, - "CREATE TABLE IF NOT EXISTS bs_player (" + - " pid BIGINT AUTO_INCREMENT PRIMARY KEY," + - " name VARCHAR(16)," + - " uuid CHAR(36) NOT NULL UNIQUE," + - " first_add TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP," + - " bid BIGINT, " + - " ip_pardon_time TIMESTAMP NULL, " + - " proxy_pardon_time TIMESTAMP NULL," + - " shared_pardon_time TIMESTAMP NULL," + - " INDEX bs_player_name (name)," + - " INDEX bs_player_ip_pardons (ip_pardon_time)," + - " INDEX bs_player_proxy_pardons (proxy_pardon_time)," + - " INDEX bs_player_shared_pardons (shared_pardon_time)," + - " INDEX bs_player_join (first_add)" + - ");", + @Override + public void run() { + BanStick.getPlugin().debug("Player preload {0}, lim {1}", lastId, batchsize); + lastId = BSPlayer.preload(lastId, batchsize); + if (lastId < 0) { + this.cancel(); + } + } + }.runTaskTimerAsynchronously(BanStick.getPlugin(), delay + ((period * 3) / 6), period); - "CREATE TABLE IF NOT EXISTS bs_session (" + - " sid BIGINT AUTO_INCREMENT PRIMARY KEY," + - " pid BIGINT," + - " join_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP," + - " leave_time TIMESTAMP NULL," + - " iid BIGINT NOT NULL," + - " INDEX bs_session_pids (pid, join_time, leave_time)" + - ");", + new BukkitRunnable() { + private long lastId; - "CREATE TABLE IF NOT EXISTS bs_ban_log (" + - " lid BIGINT AUTO_INCREMENT PRIMARY KEY," + - " pid BIGINT NOT NULL," + - " bid BIGINT NOT NULL," + - " action_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP," + - " action VARCHAR(10) NOT NULL," + - " INDEX bs_ban_log_time (pid, action_time DESC)" + - ");", // TODO: Whenever a ban is given or removed from a player, record. + @Override + public void run() { + BanStick.getPlugin().debug("Session preload {0}, lim {1}", lastId, batchsize); + lastId = BSSession.preload(lastId, batchsize); + if (lastId < 0) { + this.cancel(); + } + } + }.runTaskTimerAsynchronously(BanStick.getPlugin(), delay + ((period * 4) / 6), period); - "CREATE TABLE IF NOT EXISTS bs_ban (" + - " bid BIGINT AUTO_INCREMENT PRIMARY KEY," + - " ban_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP," + - " ip_ban BIGINT," + - " proxy_ban BIGINT," + - " share_ban BIGINT," + - " admin_ban BOOLEAN DEFAULT FALSE," + - " message TEXT," + - " ban_end TIMESTAMP NULL," + - " INDEX bs_ban_time (ban_time)," + - " INDEX bs_ban_ip (ip_ban)," + - " INDEX bs_ban_proxy (proxy_ban)," + - " INDEX bs_ban_share (share_ban)," + - " INDEX bs_ban_end (ban_end)" + - ");", + new BukkitRunnable() { + private long lastId; - "CREATE TABLE IF NOT EXISTS bs_share (" + - " sid BIGINT AUTO_INCREMENT PRIMARY KEY," + - " create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP," + - " first_pid BIGINT NOT NULL REFERENCES bs_player(pid)," + - " second_pid BIGINT NOT NULL REFERENCES bs_player(pid)," + - " first_sid BIGINT NOT NULL REFERENCES bs_session(sid)," + - " second_sid BIGINT NOT NULL REFERENCES bs_session(sid)," + - " pardon BOOLEAN DEFAULT FALSE," + - " pardon_time TIMESTAMP NULL," + - " INDEX bs_share (first_pid, second_pid)," + - " INDEX bs_pardon (pardon_time)" + - ");", - "CREATE TABLE IF NOT EXISTS bs_ip (" + - " iid BIGINT AUTO_INCREMENT PRIMARY KEY," + - " create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP," + - " ip4 CHAR(15)," + - " ip4cidr SMALLINT," + - " ip6 CHAR(39)," + - " ip6cidr SMALLINT," + - " INDEX bs_session_ip4 (ip4, ip4cidr)," + - " INDEX bs_session_ip6 (ip6, ip6cidr)" + - ");", - "CREATE TABLE IF NOT EXISTS bs_ip_data (" + - " idid BIGINT AUTO_INCREMENT PRIMARY KEY," + - " iid BIGINT NOT NULL REFERENCES bs_ip(iid)," + - " create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP," + - " valid BOOLEAN DEFAULT TRUE," + - " continent TEXT," + - " country TEXT," + - " region TEXT," + - " city TEXT," + - " postal TEXT," + - " lat DOUBLE DEFAULT NULL," + - " lon DOUBLE DEFAULT NULL," + - " domain TEXT," + - " provider TEXT," + - " registered_as TEXT," + - " connection TEXT," + - " proxy FLOAT," + - " source TEXT," + - " comment TEXT," + - " INDEX bs_ip_data_iid (iid)," + - " INDEX bs_ip_data_valid (valid, create_time DESC)," + - " INDEX bs_ip_data_proxy (proxy)" + - ");", + @Override + public void run() { + BanStick.getPlugin().debug("Share preload {0}, lim {1}", lastId, batchsize); + lastId = BSShare.preload(lastId, batchsize); + if (lastId < 0) { + this.cancel(); + } + } + }.runTaskTimerAsynchronously(BanStick.getPlugin(), delay + ((period * 5) / 6), period); + } else { + BanStick.getPlugin().info("Preloading is disabled. Expect more lag on joins, lookups, and bans."); + } - "ALTER TABLE bs_player ADD CONSTRAINT fk_bs_player_ban " + - " FOREIGN KEY (bid) REFERENCES bs_ban (bid);", - "ALTER TABLE bs_session ADD CONSTRAINT fk_bs_session_player " + - " FOREIGN KEY (pid) REFERENCES bs_player (pid);", - "ALTER TABLE bs_session ADD CONSTRAINT fk_bs_session_iid " + - " FOREIGN KEY (iid) REFERENCES bs_ip (iid);", - - "ALTER TABLE bs_ban_log ADD CONSTRAINT fk_bs_ban_log_player " + - " FOREIGN KEY (pid) REFERENCES bs_player (pid);", - "ALTER TABLE bs_ban_log ADD CONSTRAINT fk_bs_ban_log_ban " + - " FOREIGN KEY (bid) REFERENCES bs_ban (bid);", + } - "ALTER TABLE bs_ban ADD CONSTRAINT fk_bs_ban_ip " + - " FOREIGN KEY (ip_ban) REFERENCES bs_ip (iid);", - "ALTER TABLE bs_ban ADD CONSTRAINT fk_bs_ban_ip_data " + - " FOREIGN KEY (proxy_ban) REFERENCES bs_ip_data (idid);", - "ALTER TABLE bs_ban ADD CONSTRAINT fk_bs_ban_share " + - " FOREIGN KEY (share_ban) REFERENCES bs_share (sid);" + /** + * Basic method to set up data model v1. + */ + private void initializeTables() { + data.registerMigration(0, false, + "CREATE TABLE IF NOT EXISTS bs_player (" + + " pid BIGINT AUTO_INCREMENT PRIMARY KEY," + + " name VARCHAR(16)," + + " uuid CHAR(36) NOT NULL UNIQUE," + + " first_add TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP," + + " bid BIGINT, " + + " ip_pardon_time TIMESTAMP NULL, " + + " proxy_pardon_time TIMESTAMP NULL," + + " shared_pardon_time TIMESTAMP NULL," + + " INDEX bs_player_name (name)," + + " INDEX bs_player_ip_pardons (ip_pardon_time)," + + " INDEX bs_player_proxy_pardons (proxy_pardon_time)," + + " INDEX bs_player_shared_pardons (shared_pardon_time)," + + " INDEX bs_player_join (first_add)" + + ");", - ); - data.registerMigration(1, false, "CREATE TABLE IF NOT EXISTS bs_exclusion (" - + "eid BIGINT AUTO_INCREMENT PRIMARY KEY," - + "create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP," - + "first_pid BIGINT NOT NULL REFERENCES bs_player(pid)," - + "second_pid BIGINT NOT NULL REFERENCES bs_player(pid)," - + " INDEX bs_exclusion_pid (first_pid, second_pid)" - + ");"); - data.registerMigration(2, false, "CREATE TABLE IF NOT EXISTS bs_banned_registrars (" - + "rid BIGINT AUTO_INCREMENT PRIMARY KEY," - + "create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP," - + "registered_as text" - + ");"); + "CREATE TABLE IF NOT EXISTS bs_session (" + + " sid BIGINT AUTO_INCREMENT PRIMARY KEY," + + " pid BIGINT," + + " join_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP," + + " leave_time TIMESTAMP NULL," + + " iid BIGINT NOT NULL," + + " INDEX bs_session_pids (pid, join_time, leave_time)" + + ");", - } + "CREATE TABLE IF NOT EXISTS bs_ban_log (" + + " lid BIGINT AUTO_INCREMENT PRIMARY KEY," + + " pid BIGINT NOT NULL," + + " bid BIGINT NOT NULL," + + " action_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP," + + " action VARCHAR(10) NOT NULL," + + " INDEX bs_ban_log_time (pid, action_time DESC)" + + ");", // TODO: Whenever a ban is given or removed from a player, record. - /** - * Add all new migrations here. - */ - private void stageUpdates() { + "CREATE TABLE IF NOT EXISTS bs_ban (" + + " bid BIGINT AUTO_INCREMENT PRIMARY KEY," + + " ban_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP," + + " ip_ban BIGINT," + + " proxy_ban BIGINT," + + " share_ban BIGINT," + + " admin_ban BOOLEAN DEFAULT FALSE," + + " message TEXT," + + " ban_end TIMESTAMP NULL," + + " INDEX bs_ban_time (ban_time)," + + " INDEX bs_ban_ip (ip_ban)," + + " INDEX bs_ban_proxy (proxy_ban)," + + " INDEX bs_ban_share (share_ban)," + + " INDEX bs_ban_end (ban_end)" + + ");", - } + "CREATE TABLE IF NOT EXISTS bs_share (" + + " sid BIGINT AUTO_INCREMENT PRIMARY KEY," + + " create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP," + + " first_pid BIGINT NOT NULL REFERENCES bs_player(pid)," + + " second_pid BIGINT NOT NULL REFERENCES bs_player(pid)," + + " first_sid BIGINT NOT NULL REFERENCES bs_session(sid)," + + " second_sid BIGINT NOT NULL REFERENCES bs_session(sid)," + + " pardon BOOLEAN DEFAULT FALSE," + + " pardon_time TIMESTAMP NULL," + + " INDEX bs_share (first_pid, second_pid)," + + " INDEX bs_pardon (pardon_time)" + + ");", + "CREATE TABLE IF NOT EXISTS bs_ip (" + + " iid BIGINT AUTO_INCREMENT PRIMARY KEY," + + " create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP," + + " ip4 CHAR(15)," + + " ip4cidr SMALLINT," + + " ip6 CHAR(39)," + + " ip6cidr SMALLINT," + + " INDEX bs_session_ip4 (ip4, ip4cidr)," + + " INDEX bs_session_ip6 (ip6, ip6cidr)" + + ");", + "CREATE TABLE IF NOT EXISTS bs_ip_data (" + + " idid BIGINT AUTO_INCREMENT PRIMARY KEY," + + " iid BIGINT NOT NULL REFERENCES bs_ip(iid)," + + " create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP," + + " valid BOOLEAN DEFAULT TRUE," + + " continent TEXT," + + " country TEXT," + + " region TEXT," + + " city TEXT," + + " postal TEXT," + + " lat DOUBLE DEFAULT NULL," + + " lon DOUBLE DEFAULT NULL," + + " domain TEXT," + + " provider TEXT," + + " registered_as TEXT," + + " connection TEXT," + + " proxy FLOAT," + + " source TEXT," + + " comment TEXT," + + " INDEX bs_ip_data_iid (iid)," + + " INDEX bs_ip_data_valid (valid, create_time DESC)," + + " INDEX bs_ip_data_proxy (proxy)" + + ");", - /** - * Handles shutdown and proper postprocess of dirty data. - */ - public void doShutdown() { + "ALTER TABLE bs_player ADD CONSTRAINT fk_bs_player_ban " + + " FOREIGN KEY (bid) REFERENCES bs_ban (bid);", + "ALTER TABLE bs_session ADD CONSTRAINT fk_bs_session_player " + + " FOREIGN KEY (pid) REFERENCES bs_player (pid);", + "ALTER TABLE bs_session ADD CONSTRAINT fk_bs_session_iid " + + " FOREIGN KEY (iid) REFERENCES bs_ip (iid);", - BanStick.getPlugin().info("Player dirty save"); - BSPlayer.saveDirty(); + "ALTER TABLE bs_ban_log ADD CONSTRAINT fk_bs_ban_log_player " + + " FOREIGN KEY (pid) REFERENCES bs_player (pid);", + "ALTER TABLE bs_ban_log ADD CONSTRAINT fk_bs_ban_log_ban " + + " FOREIGN KEY (bid) REFERENCES bs_ban (bid);", - BanStick.getPlugin().info("Ban dirty save"); - BSBan.saveDirty(); + "ALTER TABLE bs_ban ADD CONSTRAINT fk_bs_ban_ip " + + " FOREIGN KEY (ip_ban) REFERENCES bs_ip (iid);", + "ALTER TABLE bs_ban ADD CONSTRAINT fk_bs_ban_ip_data " + + " FOREIGN KEY (proxy_ban) REFERENCES bs_ip_data (idid);", + "ALTER TABLE bs_ban ADD CONSTRAINT fk_bs_ban_share " + + " FOREIGN KEY (share_ban) REFERENCES bs_share (sid);" - BanStick.getPlugin().info("Session dirty save"); - BSSession.saveDirty(); + ); + data.registerMigration(1, false, "CREATE TABLE IF NOT EXISTS bs_exclusion (" + + "eid BIGINT AUTO_INCREMENT PRIMARY KEY," + + "create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP," + + "first_pid BIGINT NOT NULL REFERENCES bs_player(pid)," + + "second_pid BIGINT NOT NULL REFERENCES bs_player(pid)," + + " INDEX bs_exclusion_pid (first_pid, second_pid)" + + ");"); + data.registerMigration(2, false, "CREATE TABLE IF NOT EXISTS bs_banned_registrars (" + + "rid BIGINT AUTO_INCREMENT PRIMARY KEY," + + "create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP," + + "registered_as text" + + ");"); - BanStick.getPlugin().info("Share dirty save"); - BSShare.saveDirty(); + } - BanStick.getPlugin().info("Proxy dirty save"); - BSIPData.saveDirty(); + /** + * Add all new migrations here. + */ + private void stageUpdates() { - BanStick.getPlugin().info("Ban Log save"); - BSLog log = BanStick.getPlugin().getLogHandler(); - if (log != null) { - log.disable(); - } - } + } - // ============ QUERIES ============= + /** + * Handles shutdown and proper postprocess of dirty data. + */ + public void doShutdown() { - /** - * For a given Bukkit player, get or create a BSPlayer for them. - * @param player the player - * @return the BSPlayer created or retrieved. Null on failure only. - */ - public BSPlayer getOrCreatePlayer(final Player player) { - // TODO: use exception - BSPlayer bsPlayer = getPlayer(player.getUniqueId()); - if (bsPlayer == null) { - bsPlayer = BSPlayer.create(player); - } + BanStick.getPlugin().info("Player dirty save"); + BSPlayer.saveDirty(); - return bsPlayer; - } + BanStick.getPlugin().info("Ban dirty save"); + BSBan.saveDirty(); - public BSPlayer getPlayer(final UUID uuid) { - return BSPlayer.byUUID(uuid); // TODO: exception - } + BanStick.getPlugin().info("Session dirty save"); + BSSession.saveDirty(); - /** - * For an Inet Address, get or create an IP for it. - * @param netAddress the InetAddress - * @return the BSIP created or retrieved. Null on failure only. - */ - public BSIP getOrCreateIP(final InetAddress netAddress) { - BSIP bsIP = getIP(netAddress); - if (bsIP == null) { - BanStick.getPlugin().debug("Creating IP address: {0}", netAddress); - bsIP = BSIP.create(netAddress); - } else { - BanStick.getPlugin().info("Registering future retrieval of IPData for {0}", bsIP.toString()); - BanStick.getPlugin().getIPDataHandler().offer(bsIP); - } - return bsIP; - } + BanStick.getPlugin().info("Share dirty save"); + BSShare.saveDirty(); - public BSIP getIP(final InetAddress netAddress) { - return BSIP.byInetAddress(netAddress); - } + BanStick.getPlugin().info("Proxy dirty save"); + BSIPData.saveDirty(); - public List getAllByIP(final InetAddress netAddress) { - return BSIP.allMatching(netAddress); - } + BanStick.getPlugin().info("Ban Log save"); + BSLog log = BanStick.getPlugin().getLogHandler(); + if (log != null) { + log.disable(); + } + } + + // ============ QUERIES ============= + + /** + * For a given Bukkit player, get or create a BSPlayer for them. + * + * @param player the player + * @return the BSPlayer created or retrieved. Null on failure only. + */ + public BSPlayer getOrCreatePlayer(final Player player) { + // TODO: use exception + BSPlayer bsPlayer = getPlayer(player.getUniqueId()); + if (bsPlayer == null) { + bsPlayer = BSPlayer.create(player); + } + + return bsPlayer; + } + + public BSPlayer getPlayer(final UUID uuid) { + return BSPlayer.byUUID(uuid); // TODO: exception + } + + /** + * For an Inet Address, get or create an IP for it. + * + * @param netAddress the InetAddress + * @return the BSIP created or retrieved. Null on failure only. + */ + public BSIP getOrCreateIP(final InetAddress netAddress) { + BSIP bsIP = getIP(netAddress); + if (bsIP == null) { + BanStick.getPlugin().debug("Creating IP address: {0}", netAddress); + bsIP = BSIP.create(netAddress); + } else { + BanStick.getPlugin().info("Registering future retrieval of IPData for {0}", bsIP.toString()); + BanStick.getPlugin().getIPDataHandler().offer(bsIP); + } + return bsIP; + } + + public BSIP getIP(final InetAddress netAddress) { + return BSIP.byInetAddress(netAddress); + } + + public List getAllByIP(final InetAddress netAddress) { + return BSIP.allMatching(netAddress); + } } diff --git a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/handler/BanStickEventHandler.java b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/handler/BanStickEventHandler.java index 828d511f1..068d67673 100644 --- a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/handler/BanStickEventHandler.java +++ b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/handler/BanStickEventHandler.java @@ -37,598 +37,598 @@ import vg.civcraft.mc.namelayer.NameAPI; * about to get BanSticked. * * @author ProgrammerDan - * */ public class BanStickEventHandler implements Listener { - private float proxyThreshold; - private boolean enableIPBans; - private boolean enableSubnetBans; - private boolean enableProxyKicks; - private boolean enableProxyBans; - private boolean enableNewProxyBans; - private boolean enableShareBans; - private String proxyBanMessage; - private int shareThreshold; - private String shareBanMessage; - private boolean transitiveBans; - private boolean loveTapNewJoins; - private boolean proxyCheckRegistrar; - /** - * Sets up a new EventHandler from a config. - * - * @param config the config to use - * @throws RuntimeException if the config is not found or is invalid. - */ - public BanStickEventHandler(FileConfiguration config) { - proxyThreshold = 2.0f; - enableIPBans = true; - enableSubnetBans = true; - enableProxyKicks = true; - enableProxyBans = false; - enableNewProxyBans = false; - enableShareBans = false; - proxyBanMessage = null; - shareThreshold = 0; - shareBanMessage = null; - transitiveBans = false; - loveTapNewJoins = true; - proxyCheckRegistrar = true; - // setup. - ConfigurationSection internal = config.getConfigurationSection("events"); - if (internal != null) { - configureEvents(internal); - registerEvents(); - } else { - throw new RuntimeException("Failed to set up Event Handler for BanStick, no events section in config."); - } - } + private float proxyThreshold; + private boolean enableIPBans; + private boolean enableSubnetBans; + private boolean enableProxyKicks; + private boolean enableProxyBans; + private boolean enableNewProxyBans; + private boolean enableShareBans; + private String proxyBanMessage; + private int shareThreshold; + private String shareBanMessage; + private boolean transitiveBans; + private boolean loveTapNewJoins; + private boolean proxyCheckRegistrar; - private void configureEvents(ConfigurationSection config) { - this.proxyThreshold = (float) config.getDouble("proxy.threshold", proxyThreshold); - this.enableIPBans = config.getBoolean("enable.ipBans", true); - this.enableSubnetBans = config.getBoolean("enable.subnetBans", true); - this.enableProxyKicks = config.getBoolean("enable.proxyKicks", true); - this.enableProxyBans = config.getBoolean("enable.proxyBans", false); - this.enableNewProxyBans = config.getBoolean("enable.newProxyBans", false); - this.enableShareBans = config.getBoolean("enable.shareBans", false); - this.proxyBanMessage = config.getString("proxy.banMessage", null); - this.shareThreshold = config.getInt("share.threshold", shareThreshold); - this.shareBanMessage = config.getString("share.banMessage", null); - this.transitiveBans = config.getBoolean("enable.transitiveBans"); - this.loveTapNewJoins = config.getBoolean("enable.lovetapOnJoin", loveTapNewJoins); - this.proxyCheckRegistrar = config.getBoolean("enable.proxyCheckRegistrar", proxyCheckRegistrar); - } + /** + * Sets up a new EventHandler from a config. + * + * @param config the config to use + * @throws RuntimeException if the config is not found or is invalid. + */ + public BanStickEventHandler(FileConfiguration config) { + proxyThreshold = 2.0f; + enableIPBans = true; + enableSubnetBans = true; + enableProxyKicks = true; + enableProxyBans = false; + enableNewProxyBans = false; + enableShareBans = false; + proxyBanMessage = null; + shareThreshold = 0; + shareBanMessage = null; + transitiveBans = false; + loveTapNewJoins = true; + proxyCheckRegistrar = true; + // setup. + ConfigurationSection internal = config.getConfigurationSection("events"); + if (internal != null) { + configureEvents(internal); + registerEvents(); + } else { + throw new RuntimeException("Failed to set up Event Handler for BanStick, no events section in config."); + } + } - private void registerEvents() { - Bukkit.getPluginManager().registerEvents(this, BanStick.getPlugin()); - } + private void configureEvents(ConfigurationSection config) { + this.proxyThreshold = (float) config.getDouble("proxy.threshold", proxyThreshold); + this.enableIPBans = config.getBoolean("enable.ipBans", true); + this.enableSubnetBans = config.getBoolean("enable.subnetBans", true); + this.enableProxyKicks = config.getBoolean("enable.proxyKicks", true); + this.enableProxyBans = config.getBoolean("enable.proxyBans", false); + this.enableNewProxyBans = config.getBoolean("enable.newProxyBans", false); + this.enableShareBans = config.getBoolean("enable.shareBans", false); + this.proxyBanMessage = config.getString("proxy.banMessage", null); + this.shareThreshold = config.getInt("share.threshold", shareThreshold); + this.shareBanMessage = config.getString("share.banMessage", null); + this.transitiveBans = config.getBoolean("enable.transitiveBans"); + this.loveTapNewJoins = config.getBoolean("enable.lovetapOnJoin", loveTapNewJoins); + this.proxyCheckRegistrar = config.getBoolean("enable.proxyCheckRegistrar", proxyCheckRegistrar); + } - /** - * Handles before a player has fully joined the server - * - * @param asyncEvent the event to process. - */ - @EventHandler(priority = EventPriority.LOWEST) - public void asyncPreJoinLowest(AsyncPlayerPreLoginEvent asyncEvent) { - final InetAddress preJoinAddress = asyncEvent.getAddress(); - final UUID preJoinUUID = asyncEvent.getUniqueId(); - final String preJoinName = asyncEvent.getName(); - // let other prejoins do their thing, we'll trigger a number of tasks now. + private void registerEvents() { + Bukkit.getPluginManager().registerEvents(this, BanStick.getPlugin()); + } - // First, trigger a UUID based lookup. TODO: Use Async Handler - BSPlayer player = BSPlayer.byUUID(preJoinUUID); - if (player == null) { // create and attempt to name -- review if this is safe. - String name = null; - try { - name = NameAPI.getCurrentName(preJoinUUID); - } catch (NoClassDefFoundError ncde) { - } // no namelayer - if (name == null) { - name = preJoinName; - } - BanStick.getPlugin().debug("New player {0}, creating record. Best guess at name: {1}", preJoinUUID, name); - player = BSPlayer.create(preJoinUUID, name); - } - BSIP ip = BanStickDatabaseHandler.getInstance().getOrCreateIP(preJoinAddress); - if (player != null) { - BSBan ban = player.getBan(); - if (ban != null) { - if (ban.getBanEndTime() != null && ban.getBanEndTime().before(new Date())) { // ban has ended. - player.setBan(null); - } else { - BanStick.getPlugin().info("Preventing login by " + player.getName() + " due to " + ban.toString()); - Bukkit.broadcast("Preventing login by " + player.getName() + " due to " + ban.toString(), - "banstick.ips"); - asyncEvent.disallow(Result.KICK_BANNED, ban.getMessage()); - return; - } - } - if (transitiveBans) { - for (BSPlayer alt : player.getTransitiveSharedPlayers(true)) { - ban = alt.getBan(); - if (ban != null) { - if (ban.getBanEndTime() != null && ban.getBanEndTime().before(new Date())) { // ban has ended. - alt.setBan(null); - } else { - BanStick.getPlugin().info("Preventing login by " + player.getName() + " due to " - + ban.toString() + " transitively applied from " + alt.getName()); - Bukkit.broadcast("Preventing login by " + player.getName() + " due to " + ban.toString() - + " on " + alt.getName(), "banstick.ips"); - asyncEvent.disallow(Result.KICK_BANNED, ban.getMessage()); - return; - } - } - } - } - if (player.getIPPardonTime() != null) { - BanStick.getPlugin().info("Skipping IP checks due to pardon for player " + player.getName()); - return; - } - } + /** + * Handles before a player has fully joined the server + * + * @param asyncEvent the event to process. + */ + @EventHandler(priority = EventPriority.LOWEST) + public void asyncPreJoinLowest(AsyncPlayerPreLoginEvent asyncEvent) { + final InetAddress preJoinAddress = asyncEvent.getAddress(); + final UUID preJoinUUID = asyncEvent.getUniqueId(); + final String preJoinName = asyncEvent.getName(); + // let other prejoins do their thing, we'll trigger a number of tasks now. - if (this.enableIPBans) { - // Second, trigger an exact IP based lookup. - if (ip != null) { - List ipBans = BSBan.byIP(ip, false); - for (int i = ipBans.size() - 1; i >= 0; i--) { - // TODO: Can I have better selectivity here? What are the rules? - BSBan pickOne = ipBans.get(i); - if (pickOne.getBanEndTime() != null && pickOne.getBanEndTime().before(new Date())) { - continue; // skip expired ban. - } - if (player != null) { - // associate! - player.setBan(pickOne); // get most recent matching IP ban and use it. + // First, trigger a UUID based lookup. TODO: Use Async Handler + BSPlayer player = BSPlayer.byUUID(preJoinUUID); + if (player == null) { // create and attempt to name -- review if this is safe. + String name = null; + try { + name = NameAPI.getCurrentName(preJoinUUID); + } catch (NoClassDefFoundError ncde) { + } // no namelayer + if (name == null) { + name = preJoinName; + } + BanStick.getPlugin().debug("New player {0}, creating record. Best guess at name: {1}", preJoinUUID, name); + player = BSPlayer.create(preJoinUUID, name); + } + BSIP ip = BanStickDatabaseHandler.getInstance().getOrCreateIP(preJoinAddress); + if (player != null) { + BSBan ban = player.getBan(); + if (ban != null) { + if (ban.getBanEndTime() != null && ban.getBanEndTime().before(new Date())) { // ban has ended. + player.setBan(null); + } else { + BanStick.getPlugin().info("Preventing login by " + player.getName() + " due to " + ban.toString()); + Bukkit.broadcast("Preventing login by " + player.getName() + " due to " + ban.toString(), + "banstick.ips"); + asyncEvent.disallow(Result.KICK_BANNED, ban.getMessage()); + return; + } + } + if (transitiveBans) { + for (BSPlayer alt : player.getTransitiveSharedPlayers(true)) { + ban = alt.getBan(); + if (ban != null) { + if (ban.getBanEndTime() != null && ban.getBanEndTime().before(new Date())) { // ban has ended. + alt.setBan(null); + } else { + BanStick.getPlugin().info("Preventing login by " + player.getName() + " due to " + + ban.toString() + " transitively applied from " + alt.getName()); + Bukkit.broadcast("Preventing login by " + player.getName() + " due to " + ban.toString() + + " on " + alt.getName(), "banstick.ips"); + asyncEvent.disallow(Result.KICK_BANNED, ban.getMessage()); + return; + } + } + } + } + if (player.getIPPardonTime() != null) { + BanStick.getPlugin().info("Skipping IP checks due to pardon for player " + player.getName()); + return; + } + } - BanStick.getPlugin() - .info("Preventing login by " + player.getName() + " due to " + pickOne.toString()); - Bukkit.broadcast("Preventing login by " + player.getName() + " due to " + pickOne.toString(), - "banstick.ips"); - } else { - BanStick.getPlugin().info("Preventing login due to " + pickOne.toString()); - Bukkit.broadcast("Preventing login due to " + pickOne.toString(), "banstick.ips"); - } - asyncEvent.disallow(Result.KICK_BANNED, pickOne.getMessage()); - return; - } - } - } + if (this.enableIPBans) { + // Second, trigger an exact IP based lookup. + if (ip != null) { + List ipBans = BSBan.byIP(ip, false); + for (int i = ipBans.size() - 1; i >= 0; i--) { + // TODO: Can I have better selectivity here? What are the rules? + BSBan pickOne = ipBans.get(i); + if (pickOne.getBanEndTime() != null && pickOne.getBanEndTime().before(new Date())) { + continue; // skip expired ban. + } + if (player != null) { + // associate! + player.setBan(pickOne); // get most recent matching IP ban and use it. - if (this.enableSubnetBans) { - // Third, trigger a CIDR lookup. This will continue until done; it does not tie - // into login or async join events. - List subnets = BSIP.allMatching(preJoinAddress); - for (BSIP sip : subnets) { - BanStick.getPlugin().debug("Check for bans on IP: {0}", sip.getId()); - List sipBans = BSBan.byIP(sip, false); - for (int i = sipBans.size() - 1; i >= 0; i--) { - // TODO: Can I have better selectivity here? What are the rules? - BSBan pickOne = sipBans.get(i); - if (pickOne.getBanEndTime() != null && pickOne.getBanEndTime().before(new Date())) { - continue; // skip expired ban. - } - if (player != null) { - // associate! - player.setBan(pickOne); // get most recent matching subnet ban and use it. - BanStick.getPlugin() - .info("Preventing login by " + player.getName() + " due to " + pickOne.toString()); - Bukkit.broadcast("Preventing login by " + player.getName() + " due to " + pickOne.toString(), - "banstick.ips"); - } else { - BanStick.getPlugin().info("Preventing login due to " + pickOne.toString()); - Bukkit.broadcast("Preventing login due to " + pickOne.toString(), "banstick.ips"); - } - asyncEvent.disallow(Result.KICK_BANNED, pickOne.getMessage()); - return; - } - } - } - } + BanStick.getPlugin() + .info("Preventing login by " + player.getName() + " due to " + pickOne.toString()); + Bukkit.broadcast("Preventing login by " + player.getName() + " due to " + pickOne.toString(), + "banstick.ips"); + } else { + BanStick.getPlugin().info("Preventing login due to " + pickOne.toString()); + Bukkit.broadcast("Preventing login due to " + pickOne.toString(), "banstick.ips"); + } + asyncEvent.disallow(Result.KICK_BANNED, pickOne.getMessage()); + return; + } + } + } - @EventHandler(priority = EventPriority.HIGHEST) - public void asyncPreJoinHighest(AsyncPlayerPreLoginEvent asyncEvent) { - // TODO: idea is we'd poll futures for results here - } + if (this.enableSubnetBans) { + // Third, trigger a CIDR lookup. This will continue until done; it does not tie + // into login or async join events. + List subnets = BSIP.allMatching(preJoinAddress); + for (BSIP sip : subnets) { + BanStick.getPlugin().debug("Check for bans on IP: {0}", sip.getId()); + List sipBans = BSBan.byIP(sip, false); + for (int i = sipBans.size() - 1; i >= 0; i--) { + // TODO: Can I have better selectivity here? What are the rules? + BSBan pickOne = sipBans.get(i); + if (pickOne.getBanEndTime() != null && pickOne.getBanEndTime().before(new Date())) { + continue; // skip expired ban. + } + if (player != null) { + // associate! + player.setBan(pickOne); // get most recent matching subnet ban and use it. + BanStick.getPlugin() + .info("Preventing login by " + player.getName() + " due to " + pickOne.toString()); + Bukkit.broadcast("Preventing login by " + player.getName() + " due to " + pickOne.toString(), + "banstick.ips"); + } else { + BanStick.getPlugin().info("Preventing login due to " + pickOne.toString()); + Bukkit.broadcast("Preventing login due to " + pickOne.toString(), "banstick.ips"); + } + asyncEvent.disallow(Result.KICK_BANNED, pickOne.getMessage()); + return; + } + } + } + } - @EventHandler(priority = EventPriority.HIGHEST) - public void loginHighest(PlayerLoginEvent loginEvent) { + @EventHandler(priority = EventPriority.HIGHEST) + public void asyncPreJoinHighest(AsyncPlayerPreLoginEvent asyncEvent) { + // TODO: idea is we'd poll futures for results here + } - } + @EventHandler(priority = EventPriority.HIGHEST) + public void loginHighest(PlayerLoginEvent loginEvent) { - /** - * This handler deals with registering the player if they are new, starting - * their session, and triggering session sharing and vpn warning checks. - * - * @param joinEvent The PlayerJoin event. - */ - @EventHandler(priority = EventPriority.MONITOR) - public void joinMonitor(PlayerJoinEvent joinEvent) { - final Player player = joinEvent.getPlayer(); - final Date playerNow = new Date(); - Bukkit.getScheduler().runTaskAsynchronously(BanStick.getPlugin(), new Runnable() { + } - @Override - public void run() { - // Get or create player. - if (player == null) { - BanStick.getPlugin().debug("A player check event was scheduled, but that player is already gone?"); - return; - } + /** + * This handler deals with registering the player if they are new, starting + * their session, and triggering session sharing and vpn warning checks. + * + * @param joinEvent The PlayerJoin event. + */ + @EventHandler(priority = EventPriority.MONITOR) + public void joinMonitor(PlayerJoinEvent joinEvent) { + final Player player = joinEvent.getPlayer(); + final Date playerNow = new Date(); + Bukkit.getScheduler().runTaskAsynchronously(BanStick.getPlugin(), new Runnable() { - BSPlayer bsPlayer = BSPlayer.byUUID(player.getUniqueId()); + @Override + public void run() { + // Get or create player. + if (player == null) { + BanStick.getPlugin().debug("A player check event was scheduled, but that player is already gone?"); + return; + } - String nowName = null; - try { - nowName = NameAPI.getCurrentName(player.getUniqueId()); - } catch (NoClassDefFoundError cnfe) { - } // no namelayer + BSPlayer bsPlayer = BSPlayer.byUUID(player.getUniqueId()); - if (nowName == null) { - nowName = player.getDisplayName(); - } - if (bsPlayer.getName() == null || !bsPlayer.getName().equals(nowName)) { - bsPlayer.setName(nowName); - } - bsPlayer.startSession(player, playerNow); - // The above does all the Shared Session checks, so check result here: - if (enableShareBans && bsPlayer.getSharedPardonTime() == null) { // no blank check - try { - // New approach: unpardoned shares count against your shareThreshold. If you're - // above shareThreshold, - // order accounts by join date and ban all unbanned accounts using Share Ban - // assignments that are newest - // and that exceed the shareThreshold. + String nowName = null; + try { + nowName = NameAPI.getCurrentName(player.getUniqueId()); + } catch (NoClassDefFoundError cnfe) { + } // no namelayer - // Don't apply share bans bidirectionally / automatically. - List shares = bsPlayer.getUnpardonedShares(); + if (nowName == null) { + nowName = player.getDisplayName(); + } + if (bsPlayer.getName() == null || !bsPlayer.getName().equals(nowName)) { + bsPlayer.setName(nowName); + } + bsPlayer.startSession(player, playerNow); + // The above does all the Shared Session checks, so check result here: + if (enableShareBans && bsPlayer.getSharedPardonTime() == null) { // no blank check + try { + // New approach: unpardoned shares count against your shareThreshold. If you're + // above shareThreshold, + // order accounts by join date and ban all unbanned accounts using Share Ban + // assignments that are newest + // and that exceed the shareThreshold. - int cardinality = shares.size(); - if (cardinality > shareThreshold && shareThreshold > -1) { - // are we multiaccount banning & are we above threshold? - // Find the Shares above the threshold for newest accounts by create age. Ban - // them (might be this one). - // For each you ban, check if online / kick. - BanStick.getPlugin().info( - "Player {0} has exceeding the shared account threshold. Banning the newest accounts that exceed the Threshold.", - bsPlayer.getName()); - int bansIssued = 0; + // Don't apply share bans bidirectionally / automatically. + List shares = bsPlayer.getUnpardonedShares(); - Set joinNoted = new HashSet<>(); - TreeMap joinTimes = new TreeMap<>(); - for (BSShare latest : shares) { - BSPlayer one = latest.getFirstPlayer(); - if (!joinNoted.contains(one.getId())) { - joinNoted.add(one.getId()); - joinTimes.put(one.getFirstAdd().getTime(), one); - } - BSPlayer two = latest.getSecondPlayer(); - if (!joinNoted.contains(two.getId())) { - joinNoted.add(two.getId()); - joinTimes.put(two.getFirstAdd().getTime(), two); - } + int cardinality = shares.size(); + if (cardinality > shareThreshold && shareThreshold > -1) { + // are we multiaccount banning & are we above threshold? + // Find the Shares above the threshold for newest accounts by create age. Ban + // them (might be this one). + // For each you ban, check if online / kick. + BanStick.getPlugin().info( + "Player {0} has exceeding the shared account threshold. Banning the newest accounts that exceed the Threshold.", + bsPlayer.getName()); + int bansIssued = 0; - } + Set joinNoted = new HashSet<>(); + TreeMap joinTimes = new TreeMap<>(); + for (BSShare latest : shares) { + BSPlayer one = latest.getFirstPlayer(); + if (!joinNoted.contains(one.getId())) { + joinNoted.add(one.getId()); + joinTimes.put(one.getFirstAdd().getTime(), one); + } + BSPlayer two = latest.getSecondPlayer(); + if (!joinNoted.contains(two.getId())) { + joinNoted.add(two.getId()); + joinTimes.put(two.getFirstAdd().getTime(), two); + } - // A shareThreshold of 0 means you can't Alt; so we ban all but the oldest - // account. - // Similarly a shareThreshold of 2 means you can have 2 alts; we ban all but the - // 3 oldest accounts. - // TreeMaps naturally order smallest to largest, so: - int skips = shareThreshold + 1; - for (BSPlayer banPlayer : joinTimes.values()) { - if (skips > 0) { - skips--; - continue; - } - if (banPlayer.getBan() != null || banPlayer.getSharedPardonTime() != null) { - continue; // already banned, or spared from Share bans. - } - // Bannerino using latest unpardoned. - BSShare useForBan = null; - if (banPlayer.getId() == bsPlayer.getId()) { // ban person joining. - useForBan = bsPlayer.getLatestShare(); - } else { - List banShares = bsPlayer.sharesWith(banPlayer); - if (banShares == null) { - continue; - } - Collections.reverse(banShares); // by default list is oldest to newest - for (BSShare testShare : banShares) { // we want newest to oldest - if (!testShare.isPardoned()) { - useForBan = testShare; - break; - } - } - if (useForBan == null) { - BanStick.getPlugin().warning( - "Something went wrong! Claim was that the connection of {0} shared with {1} unpardoned, yet only pardoned shares found.", - banPlayer.getName(), bsPlayer.getName()); - continue; - } - } - BSBan doTheBan = BSBan.create(useForBan, shareBanMessage, null, false); - banPlayer.setBan(doTheBan); - bansIssued++; + } - doKickWithCheckup(banPlayer.getUUID(), doTheBan); - } - BanStick.getPlugin().info( - "Player {0} exceeding the shared account threshold resulted in {1} bans.", - bsPlayer.getName(), bansIssued); - } - } catch (Exception e) { - BanStick.getPlugin().warning("Failure during Share checks: ", e); - } - } + // A shareThreshold of 0 means you can't Alt; so we ban all but the oldest + // account. + // Similarly a shareThreshold of 2 means you can have 2 alts; we ban all but the + // 3 oldest accounts. + // TreeMaps naturally order smallest to largest, so: + int skips = shareThreshold + 1; + for (BSPlayer banPlayer : joinTimes.values()) { + if (skips > 0) { + skips--; + continue; + } + if (banPlayer.getBan() != null || banPlayer.getSharedPardonTime() != null) { + continue; // already banned, or spared from Share bans. + } + // Bannerino using latest unpardoned. + BSShare useForBan = null; + if (banPlayer.getId() == bsPlayer.getId()) { // ban person joining. + useForBan = bsPlayer.getLatestShare(); + } else { + List banShares = bsPlayer.sharesWith(banPlayer); + if (banShares == null) { + continue; + } + Collections.reverse(banShares); // by default list is oldest to newest + for (BSShare testShare : banShares) { // we want newest to oldest + if (!testShare.isPardoned()) { + useForBan = testShare; + break; + } + } + if (useForBan == null) { + BanStick.getPlugin().warning( + "Something went wrong! Claim was that the connection of {0} shared with {1} unpardoned, yet only pardoned shares found.", + banPlayer.getName(), bsPlayer.getName()); + continue; + } + } + BSBan doTheBan = BSBan.create(useForBan, shareBanMessage, null, false); + banPlayer.setBan(doTheBan); + bansIssued++; - if (bsPlayer.getBan() != null) { - BanStick.getPlugin().debug("Player {0} is now banned, skipping proxy checks.", bsPlayer.getName()); - return; - } + doKickWithCheckup(banPlayer.getUUID(), doTheBan); + } + BanStick.getPlugin().info( + "Player {0} exceeding the shared account threshold resulted in {1} bans.", + bsPlayer.getName(), bansIssued); + } + } catch (Exception e) { + BanStick.getPlugin().warning("Failure during Share checks: ", e); + } + } - // Then do VPN checks - if (enableProxyBans || enableProxyKicks) { - // Inject IP Hub handler. - final BSSession latestSession = bsPlayer.getLatestSession(); - BanStick.getPlugin().getIPHubHandler().offer(latestSession.getIP()); + if (bsPlayer.getBan() != null) { + BanStick.getPlugin().debug("Player {0} is now banned, skipping proxy checks.", bsPlayer.getName()); + return; + } - try { - if (bsPlayer.getProxyPardonTime() == null) { - if (latestSession.getIP() == null) { - BanStick.getPlugin().warning("Weird failure, no ip for {0}", bsPlayer); - return; - } - if (latestSession.getIP().getIPAddress() == null) { - BanStick.getPlugin().warning("Weird failure, no ip address for {0}", bsPlayer); - return; - } - List proxyChecks = BSIPData.allByIP(latestSession.getIP()); - if (proxyChecks != null) { - for (BSIPData proxyCheck : proxyChecks) { - // check if entire provider is banned - if (BanStick.getPlugin().getRegistrarHandler().isBanned(proxyCheck)) { - BanHandler.doUUIDBan(player.getUniqueId(), true); - BanStick.getPlugin().info("Banning " + player.getName() + " for " - + "blacklisted provider " + proxyCheck.getRegisteredAs()); - doKickWithCheckup(player.getUniqueId(), bsPlayer.getBan()); - return; - } - BanStick.getPlugin().debug("Check for bans on Proxy: {0}", proxyCheck.getId()); - List proxyBans = BSBan.byProxy(proxyCheck, false); - for (int i = proxyBans.size() - 1; i >= 0; i--) { - BSBan pickOne = proxyBans.get(i); - if (pickOne.getBanEndTime() != null - && pickOne.getBanEndTime().before(new Date())) { - continue; // skip expired ban. - } + // Then do VPN checks + if (enableProxyBans || enableProxyKicks) { + // Inject IP Hub handler. + final BSSession latestSession = bsPlayer.getLatestSession(); + BanStick.getPlugin().getIPHubHandler().offer(latestSession.getIP()); - if (enableProxyBans) { - bsPlayer.setBan(pickOne); // get most recent matching proxy ban and use it. - } + try { + if (bsPlayer.getProxyPardonTime() == null) { + if (latestSession.getIP() == null) { + BanStick.getPlugin().warning("Weird failure, no ip for {0}", bsPlayer); + return; + } + if (latestSession.getIP().getIPAddress() == null) { + BanStick.getPlugin().warning("Weird failure, no ip address for {0}", bsPlayer); + return; + } + List proxyChecks = BSIPData.allByIP(latestSession.getIP()); + if (proxyChecks != null) { + for (BSIPData proxyCheck : proxyChecks) { + // check if entire provider is banned + if (BanStick.getPlugin().getRegistrarHandler().isBanned(proxyCheck)) { + BanHandler.doUUIDBan(player.getUniqueId(), true); + BanStick.getPlugin().info("Banning " + player.getName() + " for " + + "blacklisted provider " + proxyCheck.getRegisteredAs()); + doKickWithCheckup(player.getUniqueId(), bsPlayer.getBan()); + return; + } + BanStick.getPlugin().debug("Check for bans on Proxy: {0}", proxyCheck.getId()); + List proxyBans = BSBan.byProxy(proxyCheck, false); + for (int i = proxyBans.size() - 1; i >= 0; i--) { + BSBan pickOne = proxyBans.get(i); + if (pickOne.getBanEndTime() != null + && pickOne.getBanEndTime().before(new Date())) { + continue; // skip expired ban. + } - if (enableProxyKicks) { - doKickWithCheckup(player.getUniqueId(), pickOne); - } + if (enableProxyBans) { + bsPlayer.setBan(pickOne); // get most recent matching proxy ban and use it. + } - return; - } - // no ban yet; check if proxy meets /exceeds threshold for banning and new proxy - // bans are enabled. - if (proxyCheck.getProxy() >= proxyThreshold && enableNewProxyBans) { - BSBan newBan = BSBan.create(proxyCheck, proxyBanMessage, null, false); + if (enableProxyKicks) { + doKickWithCheckup(player.getUniqueId(), pickOne); + } - if (enableProxyBans) { - BanStick.getPlugin() - .info("Banning " + player.getName() + " for " + "proxy score " - + proxyCheck.getProxy() + " for registrar " - + proxyCheck.getRegisteredAs()); - bsPlayer.setBan(newBan); - } + return; + } + // no ban yet; check if proxy meets /exceeds threshold for banning and new proxy + // bans are enabled. + if (proxyCheck.getProxy() >= proxyThreshold && enableNewProxyBans) { + BSBan newBan = BSBan.create(proxyCheck, proxyBanMessage, null, false); - if (enableProxyKicks) { - doKickWithCheckup(player.getUniqueId(), newBan); - } + if (enableProxyBans) { + BanStick.getPlugin() + .info("Banning " + player.getName() + " for " + "proxy score " + + proxyCheck.getProxy() + " for registrar " + + proxyCheck.getRegisteredAs()); + bsPlayer.setBan(newBan); + } - return; - } - if (proxyCheckRegistrar) { - double registrarScore = proxyCheck.getAverageForRegistrar(); - if (registrarScore > proxyThreshold) { - BSBan newBan = BSBan.create(proxyCheck, proxyBanMessage, null, false); - bsPlayer.setBan(newBan); - if (enableProxyKicks) { - doKickWithCheckup(player.getUniqueId(), newBan); - } - BanStick.getPlugin() - .info("Banning " + player.getName() + " for " - + "proxy registrar score " + registrarScore - + " for registrar " + proxyCheck.getRegisteredAs()); - } - } - } - } - } - } catch (Exception e) { - BanStick.getPlugin().severe("Failed to check proxies: ", e); - } - } - // etc. - if (loveTapNewJoins && !joinEvent.getPlayer().hasPlayedBefore()) { - Bukkit.dispatchCommand(Bukkit.getServer().getConsoleSender(), - "lovetap " + joinEvent.getPlayer().getName()); - } - } + if (enableProxyKicks) { + doKickWithCheckup(player.getUniqueId(), newBan); + } - }); - } + return; + } + if (proxyCheckRegistrar) { + double registrarScore = proxyCheck.getAverageForRegistrar(); + if (registrarScore > proxyThreshold) { + BSBan newBan = BSBan.create(proxyCheck, proxyBanMessage, null, false); + bsPlayer.setBan(newBan); + if (enableProxyKicks) { + doKickWithCheckup(player.getUniqueId(), newBan); + } + BanStick.getPlugin() + .info("Banning " + player.getName() + " for " + + "proxy registrar score " + registrarScore + + " for registrar " + proxyCheck.getRegisteredAs()); + } + } + } + } + } + } catch (Exception e) { + BanStick.getPlugin().severe("Failed to check proxies: ", e); + } + } + // etc. + if (loveTapNewJoins && !joinEvent.getPlayer().hasPlayedBefore()) { + Bukkit.dispatchCommand(Bukkit.getServer().getConsoleSender(), + "lovetap " + joinEvent.getPlayer().getName()); + } + } - /** - * Given a particular IP and a proxy, check if anyone online needs a'kickin - * This is only really used in the deferred situation where a delayed task looks up - * deep IP information (the proxy) and we then want to identify bans that should be - * applied based on this new information. - * - * @param proxySource the IP address to check against - * @param proxyCheck the proxy to check against - */ - public void manageDeferredProxyKick(final BSIP proxySource, final BSIPData proxyCheck) { - BanStick.getPlugin().debug("Deferred check for bans on Proxy: {0}", proxyCheck.getId()); + }); + } - // check if proxy meets /exceeds threshold for banning and new proxy bans are enabled. - if (proxyCheck.getProxy() >= proxyThreshold && enableNewProxyBans) { - List proxyBans = BSBan.byProxy(proxyCheck, false); - BSBan newBan = null; - if (proxyBans != null && !proxyBans.isEmpty()) { - for (BSBan checkBan : proxyBans) { - if (checkBan.getBanEndTime() != null && checkBan.getBanEndTime().after(new Date())) { - newBan = checkBan; - break; - } - } - } - if (newBan == null && (proxyBans == null || proxyBans.isEmpty())) { - newBan = BSBan.create(proxyCheck, proxyBanMessage, null, false); - } + /** + * Given a particular IP and a proxy, check if anyone online needs a'kickin + * This is only really used in the deferred situation where a delayed task looks up + * deep IP information (the proxy) and we then want to identify bans that should be + * applied based on this new information. + * + * @param proxySource the IP address to check against + * @param proxyCheck the proxy to check against + */ + public void manageDeferredProxyKick(final BSIP proxySource, final BSIPData proxyCheck) { + BanStick.getPlugin().debug("Deferred check for bans on Proxy: {0}", proxyCheck.getId()); - // now look for online players that match, and kickban them. - for (Player player : Bukkit.getOnlinePlayers()) { - if (player != null) { - BSPlayer bsPlayer = BSPlayer.byUUID(player.getUniqueId()); + // check if proxy meets /exceeds threshold for banning and new proxy bans are enabled. + if (proxyCheck.getProxy() >= proxyThreshold && enableNewProxyBans) { + List proxyBans = BSBan.byProxy(proxyCheck, false); + BSBan newBan = null; + if (proxyBans != null && !proxyBans.isEmpty()) { + for (BSBan checkBan : proxyBans) { + if (checkBan.getBanEndTime() != null && checkBan.getBanEndTime().after(new Date())) { + newBan = checkBan; + break; + } + } + } + if (newBan == null && (proxyBans == null || proxyBans.isEmpty())) { + newBan = BSBan.create(proxyCheck, proxyBanMessage, null, false); + } - if (bsPlayer != null && bsPlayer.getProxyPardonTime() == null) { + // now look for online players that match, and kickban them. + for (Player player : Bukkit.getOnlinePlayers()) { + if (player != null) { + BSPlayer bsPlayer = BSPlayer.byUUID(player.getUniqueId()); - if (proxySource.getId() == bsPlayer.getLatestSession().getIP().getId()) { // match! - if (enableProxyBans) { - bsPlayer.setBan(newBan); - } - if (enableProxyKicks) { - doKickWithCheckup(player.getUniqueId(), newBan); - } - } - } - } - } + if (bsPlayer != null && bsPlayer.getProxyPardonTime() == null) { - } + if (proxySource.getId() == bsPlayer.getLatestSession().getIP().getId()) { // match! + if (enableProxyBans) { + bsPlayer.setBan(newBan); + } + if (enableProxyKicks) { + doKickWithCheckup(player.getUniqueId(), newBan); + } + } + } + } + } - } + } - /** - * This is an aggressive kick. It issues a kick, then starts a task to ensure - * that the individual in question is truly gone. Keeps checking until they are. - * - * @param puuid The person to kick - * @param picked The ban being applied - */ - public static void doKickWithCheckup(final UUID puuid, final BSBan picked) { - // now schedule a task to kick out the trash. - Bukkit.getScheduler().runTask(BanStick.getPlugin(), new Runnable() { + } - @Override - public void run() { - Player player = Bukkit.getPlayer(puuid); - if (player != null) { - player.kickPlayer(picked.getMessage()); - BanStick.getPlugin().info("Removing " + player.getDisplayName() + " due to " + picked.toString()); - Bukkit.broadcast("Removing " + player.getDisplayName() + " due to " + picked.toString(), - "banstick.ips"); + /** + * This is an aggressive kick. It issues a kick, then starts a task to ensure + * that the individual in question is truly gone. Keeps checking until they are. + * + * @param puuid The person to kick + * @param picked The ban being applied + */ + public static void doKickWithCheckup(final UUID puuid, final BSBan picked) { + // now schedule a task to kick out the trash. + Bukkit.getScheduler().runTask(BanStick.getPlugin(), new Runnable() { - new BukkitRunnable() { - private int recheck; + @Override + public void run() { + Player player = Bukkit.getPlayer(puuid); + if (player != null) { + player.kickPlayer(picked.getMessage()); + BanStick.getPlugin().info("Removing " + player.getDisplayName() + " due to " + picked.toString()); + Bukkit.broadcast("Removing " + player.getDisplayName() + " due to " + picked.toString(), + "banstick.ips"); - @Override - public void run() { - // let's keep checking to make sure they are gone - recheck++; - if (recheck % 10 == 9) { - BanStick.getPlugin().warning("Trying to kick {0} due to {1}, on {2}th retry.", puuid, - picked, recheck); - } - Player player = Bukkit.getPlayer(puuid); - if (player != null) { - player.kickPlayer(picked.getMessage()); - } else { - this.cancel(); - } - } - }.runTaskTimer(BanStick.getPlugin(), 10L, 10L); - } else { - BanStick.getPlugin().info("On return, banning " + puuid + " due to " + picked.toString()); - Bukkit.broadcast("On return, banning " + puuid + " due to " + picked.toString(), "banstick.ips"); - } - } + new BukkitRunnable() { + private int recheck; - }); - } + @Override + public void run() { + // let's keep checking to make sure they are gone + recheck++; + if (recheck % 10 == 9) { + BanStick.getPlugin().warning("Trying to kick {0} due to {1}, on {2}th retry.", puuid, + picked, recheck); + } + Player player = Bukkit.getPlayer(puuid); + if (player != null) { + player.kickPlayer(picked.getMessage()); + } else { + this.cancel(); + } + } + }.runTaskTimer(BanStick.getPlugin(), 10L, 10L); + } else { + BanStick.getPlugin().info("On return, banning " + puuid + " due to " + picked.toString()); + Bukkit.broadcast("On return, banning " + puuid + " due to " + picked.toString(), "banstick.ips"); + } + } - /** - * Calls {@link #disconnectEvent(Player)} - * - * @param quitEvent The PlayerQuitEvent - */ - @EventHandler(priority = EventPriority.MONITOR) - public void quitMonitor(PlayerQuitEvent quitEvent) { - disconnectEvent(quitEvent.getPlayer()); - } + }); + } - /** - * Calls {@link #disconnectEvent(Player)} - * - * @param kickEvent The PlayerKickEvent - */ - @EventHandler(priority = EventPriority.MONITOR) - public void kickMonitor(PlayerKickEvent kickEvent) { - disconnectEvent(kickEvent.getPlayer()); - } + /** + * Calls {@link #disconnectEvent(Player)} + * + * @param quitEvent The PlayerQuitEvent + */ + @EventHandler(priority = EventPriority.MONITOR) + public void quitMonitor(PlayerQuitEvent quitEvent) { + disconnectEvent(quitEvent.getPlayer()); + } - /** - * Special custom event handler for AltRequest from civmodcore. - * Uses transitive share data to determine the first in a cluster of - * alts to join the server, and sets that as "main" on the event. - * - * @param event the request event. - */ - @EventHandler - public void altRequest(AltRequestEvent event) { - BSPlayer bsPlayer = BSPlayer.byUUID(event.getAccountToGetMainFor()); - if (bsPlayer == null) { - return; - } - long minID = bsPlayer.getId(); - BSPlayer ogAcc = bsPlayer; - for (BSPlayer alt : bsPlayer.getTransitiveSharedPlayers(true)) { - if (alt.getId() < minID) { - minID = alt.getId(); - ogAcc = alt; - } - } - event.setMain(ogAcc.getUUID()); - } + /** + * Calls {@link #disconnectEvent(Player)} + * + * @param kickEvent The PlayerKickEvent + */ + @EventHandler(priority = EventPriority.MONITOR) + public void kickMonitor(PlayerKickEvent kickEvent) { + disconnectEvent(kickEvent.getPlayer()); + } - /** - * Ends the player's session. - * - * @param player - */ - private void disconnectEvent(final Player player) { - BSPlayer bsPlayer = BSPlayer.byUUID(player.getUniqueId()); - if (bsPlayer != null) { - bsPlayer.endSession(new Date()); - } - } + /** + * Special custom event handler for AltRequest from civmodcore. + * Uses transitive share data to determine the first in a cluster of + * alts to join the server, and sets that as "main" on the event. + * + * @param event the request event. + */ + @EventHandler + public void altRequest(AltRequestEvent event) { + BSPlayer bsPlayer = BSPlayer.byUUID(event.getAccountToGetMainFor()); + if (bsPlayer == null) { + return; + } + long minID = bsPlayer.getId(); + BSPlayer ogAcc = bsPlayer; + for (BSPlayer alt : bsPlayer.getTransitiveSharedPlayers(true)) { + if (alt.getId() < minID) { + minID = alt.getId(); + ogAcc = alt; + } + } + event.setMain(ogAcc.getUUID()); + } - /** - * Attempts to ensure that regardless of shutdown order, captures session end. - */ - public void shutdown() { - for (Player player : Bukkit.getOnlinePlayers()) { - disconnectEvent(player); // ensure some kind of session end is captured on orderly shutdown. - } - } + /** + * Ends the player's session. + * + * @param player + */ + private void disconnectEvent(final Player player) { + BSPlayer bsPlayer = BSPlayer.byUUID(player.getUniqueId()); + if (bsPlayer != null) { + bsPlayer.endSession(new Date()); + } + } - public boolean areTransitiveBansEnabled() { - return this.transitiveBans; - } + /** + * Attempts to ensure that regardless of shutdown order, captures session end. + */ + public void shutdown() { + for (Player player : Bukkit.getOnlinePlayers()) { + disconnectEvent(player); // ensure some kind of session end is captured on orderly shutdown. + } + } + + public boolean areTransitiveBansEnabled() { + return this.transitiveBans; + } } diff --git a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/handler/BanStickIPDataHandler.java b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/handler/BanStickIPDataHandler.java index d24cefbd1..d70a4efa0 100644 --- a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/handler/BanStickIPDataHandler.java +++ b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/handler/BanStickIPDataHandler.java @@ -30,390 +30,395 @@ import org.bukkit.scheduler.BukkitTask; /** * This class deals with scheduling a constrained lookup / update of data from IP data reporting service(s). - * + * *

Initially supports ip-api.com tl;dr free and decent request limits. - * + * *

Configurable, slightly. - * + * * @author ProgrammerDan */ public class BanStickIPDataHandler extends BukkitRunnable { - private BukkitTask selfTask; - private ConcurrentLinkedQueue> toCheck; - private boolean enabled; - - private int maxBatch; - private long period; - private int currentFailures; - private int disableOnFailures; - private long cooldownToReenable; - - private final String target = "http://ip-api.com/batch"; - /** - * Sets up an IPData handler from a config section. - * @param config the config - */ - public BanStickIPDataHandler(FileConfiguration config) { - if (!configure(config.getConfigurationSection("iplookup"))) { - BanStick.getPlugin().warning("IP Data lookup is disabled. This will reduce the quality of information on player's connections."); - return; - } - - begin(); - } - - private boolean configure(ConfigurationSection config) { - if (config != null && config.getBoolean("enable", false)) { - enabled = true; - } else { - return false; - } - - this.toCheck = new ConcurrentLinkedQueue<>(); - - this.maxBatch = config.getInt("maxBatch", 50); - this.period = config.getLong("period", 20); - this.disableOnFailures = config.getInt("failureCap", 10); - this.cooldownToReenable = config.getLong("cooldownTicks", 72000L); - this.currentFailures = 0; - - return true; - } - - private void begin() { - if (enabled) { - currentFailures = 0; - selfTask = this.runTaskTimerAsynchronously(BanStick.getPlugin(), period, period); - BanStick.getPlugin().warning("Dynamic IP Data lookup task started."); - } - } - - /** - * Shuts down this IPData Handler - */ - public void end() { - this.enabled = false; - if (this.selfTask == null) { - return; - } - this.selfTask.cancel(); - } - - /** - * Asks this IPData handler to check on a specific IP when possible. - * @param check the IP to check eventually. - */ - public void offer(BSIP check) { - if (enabled) { - this.toCheck.offer(new WeakReference(check)); - } - } - - @Override - public void run() { - if (!enabled) { - return; - } - if (disableOnFailures <= currentFailures) { - enabled = false; - if (this.cooldownToReenable > 0) { - BanStick.getPlugin().severe("Too many failures; temporarily disabling BanStickIPData updater."); - Bukkit.getScheduler().runTaskLater(BanStick.getPlugin(), new Runnable() { - @Override - public void run() { - currentFailures = 0; - enabled = true; - } - }, this.cooldownToReenable); - } else { - BanStick.getPlugin().severe("Too many failures; permanently disabling BanStickIPData updater."); - selfTask.cancel(); - } - return; - } - if (this.toCheck.isEmpty()) { - return; - } - try { - Set hardStaged = new HashSet<>(); - List> source = new ArrayList<>(); - - int curBatch = 0; - while (curBatch < this.maxBatch && !this.toCheck.isEmpty()) { - WeakReference nextCheck = this.toCheck.poll(); - if (nextCheck == null) { - break; // we're somehow empty already - } - BSIP nextIP = nextCheck.get(); - if (nextIP == null) { - continue; // it's not available anymore. - } - if (hardStaged.contains(nextIP.getId())) { - continue; // we've already staged it. - } - - IPAddress address = nextIP.getIPAddress(); - Integer mask = address.getNetworkPrefixLength(); - if (!(mask == null || mask == (address.isIPv4() ? 32 : 128))) { - continue; // only cidr-less ips allowed. - } - if (mask != null) { - address = address.getLower(); // strip cidr - } - - Map newEntry = new HashMap<>(); - newEntry.put("query", address.toString()); - source.add(newEntry); - curBatch ++; - } - - if (source.size() == 0) { - return; - } - - IpData[] replies = null; - - GsonBuilder builder = new com.google.gson.GsonBuilder(); - Gson gson = builder.create(); - String data = gson.toJson(source); - BanStick.getPlugin().debug("Requesting data from ip-data: {0}", data); - byte[] dataPrep = data.getBytes(StandardCharsets.UTF_8); - - URL url = new URL(target); - HttpURLConnection connection = (HttpURLConnection) url.openConnection(); - - connection.setRequestMethod("POST"); - connection.setDoOutput(true); - connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8"); - connection.setRequestProperty("Content-Length", String.valueOf(dataPrep.length)); - connection.setDoInput(true); - connection.connect(); - try (OutputStream dataSender = connection.getOutputStream()) { - dataSender.write(dataPrep); - } - try (InputStreamReader dataReply = new InputStreamReader(connection.getInputStream())) { - replies = gson.fromJson(dataReply, IpData[].class); - } - if (replies == null || replies.length == 0) { - BanStick.getPlugin().warning("IPData periodic batch updater failure, no data received"); - currentFailures ++; - return; - } - - for (IpData reply : replies) { - if (reply.getMessage() != null) { - BanStick.getPlugin().debug("Failure during IPData lookup for {0}: {1}", - reply.getQuery(), reply.getMessage()); - continue; - } - IPAddressString replyAddress = new IPAddressString(reply.getQuery()); - IPAddress address = replyAddress.getAddress(); - if (address == null) { - continue; - } - BSIP ipMatch = BSIP.byIPAddress(address); - if (ipMatch == null) { - continue; - } - BSIPData dataMatch = BSIPData.byExactIP(ipMatch); - String continent = null; - String domain = null; - String comment = null; - String sauce = "IP-API batch"; - float proxy = 0.0f; - if (dataMatch != null) { - if (reply.hasChanged(dataMatch)) { // is old outdated? - dataMatch.invalidate(); // mark that record and make a new one. - continent = dataMatch.getContinent(); - domain = dataMatch.getDomain(); - comment = dataMatch.getComment(); - proxy = dataMatch.getProxy(); - if (dataMatch.getSource() != null && dataMatch.getSource().contains(sauce)) { - sauce = dataMatch.getSource(); - } else { - sauce = dataMatch.getSource() != null ? dataMatch.getSource() + " aug. by IP-API batch" - : "IP-API batch"; - } - } else { - continue; // just move on, no changes. - } - } - dataMatch = BSIPData.create(ipMatch, continent, reply.getCountry(), reply.getRegionName(), - reply.getCity(), reply.getZip(), reply.getLat(), reply.getLon(), domain, - reply.getOrg(), reply.getAs(), reply.getIsp(), proxy, sauce, comment); - BanStick.getPlugin().getRegistrarHandler().checkAndCleanup(dataMatch); - } - } catch (MalformedURLException mue) { - enabled = false; - BanStick.getPlugin().severe("Failed to connect to malformed IPData check url", mue); - } catch (IOException ioe) { - currentFailures ++; - BanStick.getPlugin().warning("IO Error on IPData update: ", ioe); - } catch (ClassCastException cce) { - enabled = false; - BanStick.getPlugin().severe("Failed to identify connection as http; perm failure", cce); - } - } - - class IpData { - private String status; - private String message; - private String query; - private String country; - private String countryCode; - private String region; - private String regionName; - private String city; - private String zip; - private Double lat; - private Double lon; - private String timezone; - private String isp; - private String org; - private String as; - - IpData() { } + private BukkitTask selfTask; + private ConcurrentLinkedQueue> toCheck; + private boolean enabled; - public String getStatus() { - return status; - } + private int maxBatch; + private long period; + private int currentFailures; + private int disableOnFailures; + private long cooldownToReenable; - public void setStatus(String status) { - this.status = status; - } + private final String target = "http://ip-api.com/batch"; - public String getMessage() { - return message; - } + /** + * Sets up an IPData handler from a config section. + * + * @param config the config + */ + public BanStickIPDataHandler(FileConfiguration config) { + if (!configure(config.getConfigurationSection("iplookup"))) { + BanStick.getPlugin().warning("IP Data lookup is disabled. This will reduce the quality of information on player's connections."); + return; + } - public void setMessage(String message) { - this.message = message; - } + begin(); + } - public String getQuery() { - return query; - } + private boolean configure(ConfigurationSection config) { + if (config != null && config.getBoolean("enable", false)) { + enabled = true; + } else { + return false; + } - public void setQuery(String query) { - this.query = query; - } + this.toCheck = new ConcurrentLinkedQueue<>(); - public String getCountry() { - return country; - } + this.maxBatch = config.getInt("maxBatch", 50); + this.period = config.getLong("period", 20); + this.disableOnFailures = config.getInt("failureCap", 10); + this.cooldownToReenable = config.getLong("cooldownTicks", 72000L); + this.currentFailures = 0; - public void setCountry(String country) { - this.country = country; - } + return true; + } - public String getCountryCode() { - return countryCode; - } + private void begin() { + if (enabled) { + currentFailures = 0; + selfTask = this.runTaskTimerAsynchronously(BanStick.getPlugin(), period, period); + BanStick.getPlugin().warning("Dynamic IP Data lookup task started."); + } + } - public void setCountryCode(String countryCode) { - this.countryCode = countryCode; - } + /** + * Shuts down this IPData Handler + */ + public void end() { + this.enabled = false; + if (this.selfTask == null) { + return; + } + this.selfTask.cancel(); + } - public String getRegion() { - return region; - } + /** + * Asks this IPData handler to check on a specific IP when possible. + * + * @param check the IP to check eventually. + */ + public void offer(BSIP check) { + if (enabled) { + this.toCheck.offer(new WeakReference(check)); + } + } - public void setRegion(String region) { - this.region = region; - } + @Override + public void run() { + if (!enabled) { + return; + } + if (disableOnFailures <= currentFailures) { + enabled = false; + if (this.cooldownToReenable > 0) { + BanStick.getPlugin().severe("Too many failures; temporarily disabling BanStickIPData updater."); + Bukkit.getScheduler().runTaskLater(BanStick.getPlugin(), new Runnable() { + @Override + public void run() { + currentFailures = 0; + enabled = true; + } + }, this.cooldownToReenable); + } else { + BanStick.getPlugin().severe("Too many failures; permanently disabling BanStickIPData updater."); + selfTask.cancel(); + } + return; + } + if (this.toCheck.isEmpty()) { + return; + } + try { + Set hardStaged = new HashSet<>(); + List> source = new ArrayList<>(); - public String getRegionName() { - return regionName; - } + int curBatch = 0; + while (curBatch < this.maxBatch && !this.toCheck.isEmpty()) { + WeakReference nextCheck = this.toCheck.poll(); + if (nextCheck == null) { + break; // we're somehow empty already + } + BSIP nextIP = nextCheck.get(); + if (nextIP == null) { + continue; // it's not available anymore. + } + if (hardStaged.contains(nextIP.getId())) { + continue; // we've already staged it. + } - public void setRegionName(String regionName) { - this.regionName = regionName; - } + IPAddress address = nextIP.getIPAddress(); + Integer mask = address.getNetworkPrefixLength(); + if (!(mask == null || mask == (address.isIPv4() ? 32 : 128))) { + continue; // only cidr-less ips allowed. + } + if (mask != null) { + address = address.getLower(); // strip cidr + } - public String getCity() { - return city; - } + Map newEntry = new HashMap<>(); + newEntry.put("query", address.toString()); + source.add(newEntry); + curBatch++; + } - public void setCity(String city) { - this.city = city; - } + if (source.size() == 0) { + return; + } - public String getZip() { - return zip; - } + IpData[] replies = null; - public void setZip(String zip) { - this.zip = zip; - } + GsonBuilder builder = new com.google.gson.GsonBuilder(); + Gson gson = builder.create(); + String data = gson.toJson(source); + BanStick.getPlugin().debug("Requesting data from ip-data: {0}", data); + byte[] dataPrep = data.getBytes(StandardCharsets.UTF_8); - public Double getLat() { - return lat; - } + URL url = new URL(target); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); - public void setLat(Double lat) { - this.lat = lat; - } + connection.setRequestMethod("POST"); + connection.setDoOutput(true); + connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8"); + connection.setRequestProperty("Content-Length", String.valueOf(dataPrep.length)); + connection.setDoInput(true); + connection.connect(); + try (OutputStream dataSender = connection.getOutputStream()) { + dataSender.write(dataPrep); + } + try (InputStreamReader dataReply = new InputStreamReader(connection.getInputStream())) { + replies = gson.fromJson(dataReply, IpData[].class); + } + if (replies == null || replies.length == 0) { + BanStick.getPlugin().warning("IPData periodic batch updater failure, no data received"); + currentFailures++; + return; + } - public Double getLon() { - return lon; - } + for (IpData reply : replies) { + if (reply.getMessage() != null) { + BanStick.getPlugin().debug("Failure during IPData lookup for {0}: {1}", + reply.getQuery(), reply.getMessage()); + continue; + } + IPAddressString replyAddress = new IPAddressString(reply.getQuery()); + IPAddress address = replyAddress.getAddress(); + if (address == null) { + continue; + } + BSIP ipMatch = BSIP.byIPAddress(address); + if (ipMatch == null) { + continue; + } + BSIPData dataMatch = BSIPData.byExactIP(ipMatch); + String continent = null; + String domain = null; + String comment = null; + String sauce = "IP-API batch"; + float proxy = 0.0f; + if (dataMatch != null) { + if (reply.hasChanged(dataMatch)) { // is old outdated? + dataMatch.invalidate(); // mark that record and make a new one. + continent = dataMatch.getContinent(); + domain = dataMatch.getDomain(); + comment = dataMatch.getComment(); + proxy = dataMatch.getProxy(); + if (dataMatch.getSource() != null && dataMatch.getSource().contains(sauce)) { + sauce = dataMatch.getSource(); + } else { + sauce = dataMatch.getSource() != null ? dataMatch.getSource() + " aug. by IP-API batch" + : "IP-API batch"; + } + } else { + continue; // just move on, no changes. + } + } + dataMatch = BSIPData.create(ipMatch, continent, reply.getCountry(), reply.getRegionName(), + reply.getCity(), reply.getZip(), reply.getLat(), reply.getLon(), domain, + reply.getOrg(), reply.getAs(), reply.getIsp(), proxy, sauce, comment); + BanStick.getPlugin().getRegistrarHandler().checkAndCleanup(dataMatch); + } + } catch (MalformedURLException mue) { + enabled = false; + BanStick.getPlugin().severe("Failed to connect to malformed IPData check url", mue); + } catch (IOException ioe) { + currentFailures++; + BanStick.getPlugin().warning("IO Error on IPData update: ", ioe); + } catch (ClassCastException cce) { + enabled = false; + BanStick.getPlugin().severe("Failed to identify connection as http; perm failure", cce); + } + } - public void setLon(Double lon) { - this.lon = lon; - } + class IpData { - public String getTimezone() { - return timezone; - } + private String status; + private String message; + private String query; + private String country; + private String countryCode; + private String region; + private String regionName; + private String city; + private String zip; + private Double lat; + private Double lon; + private String timezone; + private String isp; + private String org; + private String as; - public void setTimezone(String timezone) { - this.timezone = timezone; - } + IpData() { + } - public String getIsp() { - return isp; - } + public String getStatus() { + return status; + } - public void setIsp(String isp) { - this.isp = isp; - } + public void setStatus(String status) { + this.status = status; + } - public String getOrg() { - return org; - } + public String getMessage() { + return message; + } - public void setOrg(String org) { - this.org = org; - } + public void setMessage(String message) { + this.message = message; + } - public String getAs() { - return as; - } + public String getQuery() { + return query; + } - public void setAs(String as) { - this.as = as; - } - - public boolean hasChanged(BSIPData data) { - if (isEqual(data.getCountry(), this.country) && isEqual(data.getRegion(), this.regionName) - && isEqual(data.getCity(), this.city) && isEqual(data.getPostal(), this.zip) - && isEqual(data.getLat(), this.lat) && isEqual(data.getLon(), this.lon) - && isEqual(data.getConnection(), this.isp) && isEqual(data.getProvider(), this.org) - && isEqual(data.getRegisteredAs(), this.as)) { - return false; - } - return true; - } - - private boolean isEqual(Object a, Object b) { - if (a == null && b == null) { - return true; - } - if (a != null) { - return a.equals(b); - } - return b.equals(a); - } - } + public void setQuery(String query) { + this.query = query; + } + + public String getCountry() { + return country; + } + + public void setCountry(String country) { + this.country = country; + } + + public String getCountryCode() { + return countryCode; + } + + public void setCountryCode(String countryCode) { + this.countryCode = countryCode; + } + + public String getRegion() { + return region; + } + + public void setRegion(String region) { + this.region = region; + } + + public String getRegionName() { + return regionName; + } + + public void setRegionName(String regionName) { + this.regionName = regionName; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getZip() { + return zip; + } + + public void setZip(String zip) { + this.zip = zip; + } + + public Double getLat() { + return lat; + } + + public void setLat(Double lat) { + this.lat = lat; + } + + public Double getLon() { + return lon; + } + + public void setLon(Double lon) { + this.lon = lon; + } + + public String getTimezone() { + return timezone; + } + + public void setTimezone(String timezone) { + this.timezone = timezone; + } + + public String getIsp() { + return isp; + } + + public void setIsp(String isp) { + this.isp = isp; + } + + public String getOrg() { + return org; + } + + public void setOrg(String org) { + this.org = org; + } + + public String getAs() { + return as; + } + + public void setAs(String as) { + this.as = as; + } + + public boolean hasChanged(BSIPData data) { + if (isEqual(data.getCountry(), this.country) && isEqual(data.getRegion(), this.regionName) + && isEqual(data.getCity(), this.city) && isEqual(data.getPostal(), this.zip) + && isEqual(data.getLat(), this.lat) && isEqual(data.getLon(), this.lon) + && isEqual(data.getConnection(), this.isp) && isEqual(data.getProvider(), this.org) + && isEqual(data.getRegisteredAs(), this.as)) { + return false; + } + return true; + } + + private boolean isEqual(Object a, Object b) { + if (a == null && b == null) { + return true; + } + if (a != null) { + return a.equals(b); + } + return b.equals(a); + } + } } diff --git a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/handler/BanStickIPHubHandler.java b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/handler/BanStickIPHubHandler.java index f8c54c385..718e72f55 100644 --- a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/handler/BanStickIPHubHandler.java +++ b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/handler/BanStickIPHubHandler.java @@ -22,346 +22,350 @@ import org.bukkit.scheduler.BukkitTask; /** * This class deals with scheduling a constrained lookup / update of data from IP proxy data key-locked services. - * - *

Initially supports iphub.info. Can be used for paid services. - * - *

Configurable, slightly. - * - * @author ProgrammerDan * + *

Initially supports iphub.info. Can be used for paid services. + * + *

Configurable, slightly. + * + * @author ProgrammerDan */ public class BanStickIPHubHandler extends BukkitRunnable { - private BukkitTask selfTask; - private ConcurrentLinkedQueue> toCheck; - private boolean enabled; - - private long period; - private int currentFailures; - private int disableOnFailures; - private long cooldownToReenable; - - private String key; - - private final String target = "http://v2.api.iphub.info/ip"; - - /** - * Sets up an IPHub info lookup task from a config - * @param config the config. - */ - public BanStickIPHubHandler(FileConfiguration config) { - if (!configure(config.getConfigurationSection("iphub"))) { - BanStick.getPlugin().warning("IP Hub Proxy (iphub.info) lookup is disabled. This will reduce the quality of information on player's connections."); - return; - } - - begin(); - } - - private boolean configure(ConfigurationSection config) { - if (config != null && config.getBoolean("enable", false)) { - enabled = true; - } else { - return false; - } - - this.toCheck = new ConcurrentLinkedQueue<>(); - - this.key = config.getString("key"); - this.period = config.getLong("period", 40); - this.disableOnFailures = config.getInt("failureCap", 5); - this.cooldownToReenable = config.getLong("cooldownTicks", 72000L); - this.currentFailures = 0; - - return true; - } - - private void begin() { - if (enabled) { - currentFailures = 0; - selfTask = this.runTaskTimerAsynchronously(BanStick.getPlugin(), period, period); - BanStick.getPlugin().warning("Dynamic IP Hub lookup task started."); - } - } - - /** - * Shuts down this IPHub handler. - */ - public void end() { - this.enabled = false; - if (this.selfTask == null) { - return; - } - this.selfTask.cancel(); - } - - /** - * Offers a specific IP to be checked later. - * @param check the IP - */ - public void offer(BSIP check) { - if (enabled) { - this.toCheck.offer(new WeakReference(check)); - } - } - - @Override - public void run() { - if (!enabled) { - return; - } - if (disableOnFailures <= currentFailures) { - enabled = false; - if (this.cooldownToReenable > 0) { - BanStick.getPlugin().severe("Too many failures; temporarily disabling BanStickIPHub updater."); - Bukkit.getScheduler().runTaskLater(BanStick.getPlugin(), new Runnable() { - @Override - public void run() { - currentFailures = 0; - enabled = true; - } - }, this.cooldownToReenable); - } else { - BanStick.getPlugin().severe("Too many failures; permanently disabling BanStickIPHub updater."); - selfTask.cancel(); - } - return; - } - if (this.toCheck.isEmpty()) { - return; - } - try { - WeakReference nextCheck = null; - BSIP nextIP = null; - IPAddress address = null; - while (address == null && !this.toCheck.isEmpty()) { - nextCheck = this.toCheck.poll(); - if (nextCheck != null) { - nextIP = nextCheck.get(); - } - if (nextIP != null) { - address = nextIP.getIPAddress(); - } - if (address != null) { - Integer mask = address.getNetworkPrefixLength(); - if (!(mask == null || mask == (address.isIPv4() ? 32 : 128))) { - address = null; - continue; // only cidr-less ips allowed. - } - if (mask != null) { - address = address.getLower(); // strip cidr - } - } - } // found - - if (address != null) { // sanity - URL url = new URL(target + "/" + address.toString()); - HttpURLConnection connection = (HttpURLConnection) url.openConnection(); - - connection.setRequestMethod("GET"); - connection.setDoOutput(true); - if (key != null) { - connection.setRequestProperty("X-Key", key); - } - connection.setDoInput(true); - connection.connect(); - IpData reply = null; - - GsonBuilder builder = new com.google.gson.GsonBuilder(); - Gson gson = builder.create(); + private BukkitTask selfTask; + private ConcurrentLinkedQueue> toCheck; + private boolean enabled; - try (InputStreamReader dataReply = new InputStreamReader(connection.getInputStream())) { - reply = gson.fromJson(dataReply, IpData.class); - } + private long period; + private int currentFailures; + private int disableOnFailures; + private long cooldownToReenable; - if (reply == null) { - BanStick.getPlugin().warning("IPHub periodic updater failure, no data received"); - currentFailures ++; - return; - } + private String key; - if (reply.getBlock() == null) { - BanStick.getPlugin().debug("Failure during IPHub lookup for {0}: {1}", - address.toString(), reply.toString()); - return; - } + private final String target = "http://v2.api.iphub.info/ip"; - IPAddressString replyAddress = new IPAddressString(reply.getIp()); - IPAddress naddress = replyAddress.getAddress(); - if (naddress == null) { - BanStick.getPlugin().debug("Failure during IPHub lookup for {0}: failed to parse {1} as IP?", - address.toString(), reply.getIp()); - return; - } - BSIP ipMatch = BSIP.byIPAddress(naddress); - if (ipMatch == null) { - BanStick.getPlugin().debug("Failure during IPHub lookup for {0}: returned {1} instead?", - address.toString(), reply.getIp()); - return; - } - BSIPData dataMatch = BSIPData.byExactIP(ipMatch); - String continent = null; - String domain = null; - String region = null; - String city = null; - String comment = null; - String postal = null; - Double lat = null; - Double lon = null; - String org = null; - String sauce = "IPHub.info"; - float proxy = reply.transformBlock(); - if (dataMatch != null) { - if (reply.hasChanged(dataMatch)) { // is old outdated? - dataMatch.invalidate(); // mark that record and make a new one. - continent = dataMatch.getContinent(); - domain = dataMatch.getDomain(); - comment = dataMatch.getComment(); - region = dataMatch.getRegion(); - city = dataMatch.getCity(); - proxy = Math.max(dataMatch.getProxy(), reply.transformBlock()); - // prefer highest resolved violation - postal = dataMatch.getPostal(); - lat = dataMatch.getLat(); - lon = dataMatch.getLon(); - org = dataMatch.getProvider(); - - if (dataMatch.getSource() != null && dataMatch.getSource().contains(sauce)) { - sauce = dataMatch.getSource(); - } else { - sauce = dataMatch.getSource() != null ? dataMatch.getSource() - + " aug. by IPHub.info" : "IPHub.info"; - } - } else { - return; // just move on, no changes. - } - } - dataMatch = BSIPData.create(ipMatch, continent, reply.getCountryName(), region, city, - postal, lat, lon, domain, org, reply.getAsn().toString(), reply.getIsp(), - proxy, sauce, comment); - - if (dataMatch != null) { - BanStick.getPlugin().getEventHandler().manageDeferredProxyKick(nextIP, dataMatch); - } + /** + * Sets up an IPHub info lookup task from a config + * + * @param config the config. + */ + public BanStickIPHubHandler(FileConfiguration config) { + if (!configure(config.getConfigurationSection("iphub"))) { + BanStick.getPlugin().warning("IP Hub Proxy (iphub.info) lookup is disabled. This will reduce the quality of information on player's connections."); + return; + } - } - } catch (MalformedURLException mue) { - enabled = false; - BanStick.getPlugin().severe("Failed to connect to malformed IPHub check url", mue); - } catch (IOException ioe) { - currentFailures ++; - BanStick.getPlugin().warning("IO Error on IPHub update: ", ioe); - } catch (ClassCastException cce) { - enabled = false; - BanStick.getPlugin().severe("Failed to identify connection as http; perm failure", cce); - } - } - - class IpData { - private String ip; - private String hostname; - private String countryCode; - private String countryName; - private Integer asn; - private String isp; - private Integer block; - - IpData() { } + begin(); + } - public String getIp() { - return ip; - } + private boolean configure(ConfigurationSection config) { + if (config != null && config.getBoolean("enable", false)) { + enabled = true; + } else { + return false; + } - public void setIp(String ip) { - this.ip = ip; - } + this.toCheck = new ConcurrentLinkedQueue<>(); - public String getHostname() { - return hostname; - } + this.key = config.getString("key"); + this.period = config.getLong("period", 40); + this.disableOnFailures = config.getInt("failureCap", 5); + this.cooldownToReenable = config.getLong("cooldownTicks", 72000L); + this.currentFailures = 0; - public void setHostname(String hostname) { - this.hostname = hostname; - } + return true; + } - public String getCountryName() { - return countryName; - } + private void begin() { + if (enabled) { + currentFailures = 0; + selfTask = this.runTaskTimerAsynchronously(BanStick.getPlugin(), period, period); + BanStick.getPlugin().warning("Dynamic IP Hub lookup task started."); + } + } - public void setCountryName(String countryName) { - this.countryName = countryName; - } + /** + * Shuts down this IPHub handler. + */ + public void end() { + this.enabled = false; + if (this.selfTask == null) { + return; + } + this.selfTask.cancel(); + } - public String getCountryCode() { - return countryCode; - } + /** + * Offers a specific IP to be checked later. + * + * @param check the IP + */ + public void offer(BSIP check) { + if (enabled) { + this.toCheck.offer(new WeakReference(check)); + } + } - public void setCountryCode(String countryCode) { - this.countryCode = countryCode; - } + @Override + public void run() { + if (!enabled) { + return; + } + if (disableOnFailures <= currentFailures) { + enabled = false; + if (this.cooldownToReenable > 0) { + BanStick.getPlugin().severe("Too many failures; temporarily disabling BanStickIPHub updater."); + Bukkit.getScheduler().runTaskLater(BanStick.getPlugin(), new Runnable() { + @Override + public void run() { + currentFailures = 0; + enabled = true; + } + }, this.cooldownToReenable); + } else { + BanStick.getPlugin().severe("Too many failures; permanently disabling BanStickIPHub updater."); + selfTask.cancel(); + } + return; + } + if (this.toCheck.isEmpty()) { + return; + } + try { + WeakReference nextCheck = null; + BSIP nextIP = null; + IPAddress address = null; + while (address == null && !this.toCheck.isEmpty()) { + nextCheck = this.toCheck.poll(); + if (nextCheck != null) { + nextIP = nextCheck.get(); + } + if (nextIP != null) { + address = nextIP.getIPAddress(); + } + if (address != null) { + Integer mask = address.getNetworkPrefixLength(); + if (!(mask == null || mask == (address.isIPv4() ? 32 : 128))) { + address = null; + continue; // only cidr-less ips allowed. + } + if (mask != null) { + address = address.getLower(); // strip cidr + } + } + } // found - public String getIsp() { - return isp; - } + if (address != null) { // sanity + URL url = new URL(target + "/" + address.toString()); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); - public void setIsp(String isp) { - this.isp = isp; - } + connection.setRequestMethod("GET"); + connection.setDoOutput(true); + if (key != null) { + connection.setRequestProperty("X-Key", key); + } + connection.setDoInput(true); + connection.connect(); - public Integer getBlock() { - return block; - } + IpData reply = null; - public void setBlock(Integer block) { - this.block = block; - } - - public float transformBlock() { - switch (block) { - case 0: - return 0.0f; // residential IP // safe - case 1: - return 3.0f; // non-residential IP / host / proxy / vpn - case 2: - return 1.5f; // non-residential AND residential IP - default: - break; - } - return 0.0f; - } + GsonBuilder builder = new com.google.gson.GsonBuilder(); + Gson gson = builder.create(); - public Integer getAsn() { - return asn; - } + try (InputStreamReader dataReply = new InputStreamReader(connection.getInputStream())) { + reply = gson.fromJson(dataReply, IpData.class); + } - public void setAsn(Integer asn) { - this.asn = asn; - } - - public boolean hasChanged(BSIPData data) { - if (isEqual(data.getCountry(), this.countryName) && isEqual(data.getRegisteredAs(), this.asn.toString()) - && isEqual(data.getConnection(), this.isp) && isEqual(data.getProxy(), this.transformBlock())) { - return false; - } - return true; - } - - private boolean isEqual(Object a, Object b) { - if (a == null && b == null) { - return true; - } - if (a != null) { - return a.equals(b); - } - return b.equals(a); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder("Reply: "); - sb.append(ip).append(" ").append(hostname).append(" ").append(countryCode).append(" ") - .append(countryName).append(" ").append(isp).append("-").append(asn).append(" = ").append(block); - return sb.toString(); - } - } + if (reply == null) { + BanStick.getPlugin().warning("IPHub periodic updater failure, no data received"); + currentFailures++; + return; + } + + if (reply.getBlock() == null) { + BanStick.getPlugin().debug("Failure during IPHub lookup for {0}: {1}", + address.toString(), reply.toString()); + return; + } + + IPAddressString replyAddress = new IPAddressString(reply.getIp()); + IPAddress naddress = replyAddress.getAddress(); + if (naddress == null) { + BanStick.getPlugin().debug("Failure during IPHub lookup for {0}: failed to parse {1} as IP?", + address.toString(), reply.getIp()); + return; + } + BSIP ipMatch = BSIP.byIPAddress(naddress); + if (ipMatch == null) { + BanStick.getPlugin().debug("Failure during IPHub lookup for {0}: returned {1} instead?", + address.toString(), reply.getIp()); + return; + } + BSIPData dataMatch = BSIPData.byExactIP(ipMatch); + String continent = null; + String domain = null; + String region = null; + String city = null; + String comment = null; + String postal = null; + Double lat = null; + Double lon = null; + String org = null; + String sauce = "IPHub.info"; + float proxy = reply.transformBlock(); + if (dataMatch != null) { + if (reply.hasChanged(dataMatch)) { // is old outdated? + dataMatch.invalidate(); // mark that record and make a new one. + continent = dataMatch.getContinent(); + domain = dataMatch.getDomain(); + comment = dataMatch.getComment(); + region = dataMatch.getRegion(); + city = dataMatch.getCity(); + proxy = Math.max(dataMatch.getProxy(), reply.transformBlock()); + // prefer highest resolved violation + postal = dataMatch.getPostal(); + lat = dataMatch.getLat(); + lon = dataMatch.getLon(); + org = dataMatch.getProvider(); + + if (dataMatch.getSource() != null && dataMatch.getSource().contains(sauce)) { + sauce = dataMatch.getSource(); + } else { + sauce = dataMatch.getSource() != null ? dataMatch.getSource() + + " aug. by IPHub.info" : "IPHub.info"; + } + } else { + return; // just move on, no changes. + } + } + dataMatch = BSIPData.create(ipMatch, continent, reply.getCountryName(), region, city, + postal, lat, lon, domain, org, reply.getAsn().toString(), reply.getIsp(), + proxy, sauce, comment); + + if (dataMatch != null) { + BanStick.getPlugin().getEventHandler().manageDeferredProxyKick(nextIP, dataMatch); + } + + } + } catch (MalformedURLException mue) { + enabled = false; + BanStick.getPlugin().severe("Failed to connect to malformed IPHub check url", mue); + } catch (IOException ioe) { + currentFailures++; + BanStick.getPlugin().warning("IO Error on IPHub update: ", ioe); + } catch (ClassCastException cce) { + enabled = false; + BanStick.getPlugin().severe("Failed to identify connection as http; perm failure", cce); + } + } + + class IpData { + + private String ip; + private String hostname; + private String countryCode; + private String countryName; + private Integer asn; + private String isp; + private Integer block; + + IpData() { + } + + public String getIp() { + return ip; + } + + public void setIp(String ip) { + this.ip = ip; + } + + public String getHostname() { + return hostname; + } + + public void setHostname(String hostname) { + this.hostname = hostname; + } + + public String getCountryName() { + return countryName; + } + + public void setCountryName(String countryName) { + this.countryName = countryName; + } + + public String getCountryCode() { + return countryCode; + } + + public void setCountryCode(String countryCode) { + this.countryCode = countryCode; + } + + public String getIsp() { + return isp; + } + + public void setIsp(String isp) { + this.isp = isp; + } + + public Integer getBlock() { + return block; + } + + public void setBlock(Integer block) { + this.block = block; + } + + public float transformBlock() { + switch (block) { + case 0: + return 0.0f; // residential IP // safe + case 1: + return 3.0f; // non-residential IP / host / proxy / vpn + case 2: + return 1.5f; // non-residential AND residential IP + default: + break; + } + return 0.0f; + } + + public Integer getAsn() { + return asn; + } + + public void setAsn(Integer asn) { + this.asn = asn; + } + + public boolean hasChanged(BSIPData data) { + if (isEqual(data.getCountry(), this.countryName) && isEqual(data.getRegisteredAs(), this.asn.toString()) + && isEqual(data.getConnection(), this.isp) && isEqual(data.getProxy(), this.transformBlock())) { + return false; + } + return true; + } + + private boolean isEqual(Object a, Object b) { + if (a == null && b == null) { + return true; + } + if (a != null) { + return a.equals(b); + } + return b.equals(a); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("Reply: "); + sb.append(ip).append(" ").append(hostname).append(" ").append(countryCode).append(" ") + .append(countryName).append(" ").append(isp).append("-").append(asn).append(" = ").append(block); + return sb.toString(); + } + } } diff --git a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/handler/BanStickImportHandler.java b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/handler/BanStickImportHandler.java index 033cf155e..2a4875d04 100644 --- a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/handler/BanStickImportHandler.java +++ b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/handler/BanStickImportHandler.java @@ -13,79 +13,79 @@ import org.bukkit.scheduler.BukkitTask; /** * Many folks might be migrating from an existing ban management system to BanStick; this is meant * to enable such migration easily. - * + * *

This is set up to be auto-loading modular like BanStickProxyHandler, so if you want to register * more importers just code 'm up and add them to the .importer package. Be sure they extend * {@link com.programmerdan.minecraft.banstick.handler.ImportWorker} class. - * - * @author ProgrammerDan * + * @author ProgrammerDan */ public class BanStickImportHandler { - ArrayList workers; - - public BanStickImportHandler(FileConfiguration config, ClassLoader classes) { - setup(config.getConfigurationSection("import"), classes); - } - - private void setup(ConfigurationSection config, ClassLoader classes) { - if (config == null || !config.getBoolean("enable", false)) { - BanStick.getPlugin().warning("All Import Workers disabled"); - return; - } - - workers = new ArrayList<>(); - - try { - ClassPath getSamplersPath = ClassPath.from(classes); + ArrayList workers; - for (ClassPath.ClassInfo clsInfo : getSamplersPath.getTopLevelClasses( - "com.programmerdan.minecraft.banstick.importer")) { - Class clazz = clsInfo.load(); - if (clazz != null && ImportWorker.class.isAssignableFrom(clazz)) { - BanStick.getPlugin().info("Found an import worker class {0}, attempting to find a " - + " suitable constructor", clazz.getName()); - ImportWorker loader = null; - try { - Constructor constructBasic = clazz.getConstructor(ConfigurationSection.class); - loader = (ImportWorker) constructBasic.newInstance(config); - BanStick.getPlugin().info("Created a new import worker of type {0}", clazz.getName()); - } catch (Exception e) { - BanStick.getPlugin().info("Failed to initialize an import worker of type {0}", clazz.getName()); - BanStick.getPlugin().warning(" Failure message: ", e.getMessage()); - } + public BanStickImportHandler(FileConfiguration config, ClassLoader classes) { + setup(config.getConfigurationSection("import"), classes); + } + + private void setup(ConfigurationSection config, ClassLoader classes) { + if (config == null || !config.getBoolean("enable", false)) { + BanStick.getPlugin().warning("All Import Workers disabled"); + return; + } + + workers = new ArrayList<>(); + + try { + ClassPath getSamplersPath = ClassPath.from(classes); + + for (ClassPath.ClassInfo clsInfo : getSamplersPath.getTopLevelClasses( + "com.programmerdan.minecraft.banstick.importer")) { + Class clazz = clsInfo.load(); + if (clazz != null && ImportWorker.class.isAssignableFrom(clazz)) { + BanStick.getPlugin().info("Found an import worker class {0}, attempting to find a " + + " suitable constructor", clazz.getName()); + ImportWorker loader = null; + try { + Constructor constructBasic = clazz.getConstructor(ConfigurationSection.class); + loader = (ImportWorker) constructBasic.newInstance(config); + BanStick.getPlugin().info("Created a new import worker of type {0}", clazz.getName()); + } catch (Exception e) { + BanStick.getPlugin().info("Failed to initialize an import worker of type {0}", clazz.getName()); + BanStick.getPlugin().warning(" Failure message: ", e.getMessage()); + } - if (loader != null) { - try { - BukkitTask task = Bukkit.getScheduler().runTaskLaterAsynchronously( - BanStick.getPlugin(), loader, loader.getDelay()); - loader.setTask(task); - } catch (Exception e) { - BanStick.getPlugin().warning("Failed to activate scraper worker of type {0}", - clazz.getName()); - BanStick.getPlugin().warning(" Failure message: ", e); - } - } - } - } - } catch (IOException ioe) { - BanStick.getPlugin().warning("Failed to load any scraper workers, due to IO error", ioe); - } - } - - /** - * Shuts this import handler down. - */ - public void shutdown() { - if (this.workers == null) { - return; - } - for (ImportWorker task : workers) { - try { - task.shutdown(); - } catch (Exception e) { } - } - } + if (loader != null) { + try { + BukkitTask task = Bukkit.getScheduler().runTaskLaterAsynchronously( + BanStick.getPlugin(), loader, loader.getDelay()); + loader.setTask(task); + } catch (Exception e) { + BanStick.getPlugin().warning("Failed to activate scraper worker of type {0}", + clazz.getName()); + BanStick.getPlugin().warning(" Failure message: ", e); + } + } + } + } + } catch (IOException ioe) { + BanStick.getPlugin().warning("Failed to load any scraper workers, due to IO error", ioe); + } + } + + /** + * Shuts this import handler down. + */ + public void shutdown() { + if (this.workers == null) { + return; + } + for (ImportWorker task : workers) { + try { + task.shutdown(); + } catch (Exception e) { + } + } + } } diff --git a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/handler/BanStickProxyHandler.java b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/handler/BanStickProxyHandler.java index dd4aa8615..94c07bc18 100644 --- a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/handler/BanStickProxyHandler.java +++ b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/handler/BanStickProxyHandler.java @@ -11,80 +11,81 @@ import org.bukkit.scheduler.BukkitTask; /** * Handles loading all proxy type workers. - * + * * @author ProgrammerDan */ public class BanStickProxyHandler { - ArrayList loaders; - ArrayList loaderTasks; - - public BanStickProxyHandler(FileConfiguration config, ClassLoader classes) { - setup(config.getConfigurationSection("proxy"), classes); - } - - private void setup(ConfigurationSection config, ClassLoader classes) { - if (config == null || !config.getBoolean("enable", false)) { - BanStick.getPlugin().warning("All Proxy List Loaders disabled"); - return; - } - - loaders = new ArrayList<>(); - loaderTasks = new ArrayList<>(); - - - // now load all configured proxy list loaders. - // Build using constructor then launch repeating task - // if no exception thrown. - try { - ClassPath getSamplersPath = ClassPath.from(classes); + ArrayList loaders; + ArrayList loaderTasks; - for (ClassPath.ClassInfo clsInfo : getSamplersPath.getTopLevelClasses( - "com.programmerdan.minecraft.banstick.proxy")) { - Class clazz = clsInfo.load(); - if (clazz != null && ProxyLoader.class.isAssignableFrom(clazz)) { - BanStick.getPlugin().info("Found a proxy loader class {0}, attempting to find" - + " a suitable constructor", clazz.getName()); - ProxyLoader loader = null; - try { - Constructor constructBasic = clazz.getConstructor(ConfigurationSection.class); - loader = (ProxyLoader) constructBasic.newInstance(config); - BanStick.getPlugin().info("Created a new proxy loader of type {0}", clazz.getName()); - } catch (Exception e) { - BanStick.getPlugin().info("Failed to initialize a proxy loader of type {0}", clazz.getName()); - BanStick.getPlugin().warning(" Failure message: ", e.getMessage()); - } + public BanStickProxyHandler(FileConfiguration config, ClassLoader classes) { + setup(config.getConfigurationSection("proxy"), classes); + } + + private void setup(ConfigurationSection config, ClassLoader classes) { + if (config == null || !config.getBoolean("enable", false)) { + BanStick.getPlugin().warning("All Proxy List Loaders disabled"); + return; + } + + loaders = new ArrayList<>(); + loaderTasks = new ArrayList<>(); - if (loader != null) { - try { - BukkitTask loaderTask = loader.runTaskTimerAsynchronously(BanStick.getPlugin(), - loader.getDelay(), loader.getPeriod()); - loaderTasks.add(loaderTask); - } catch (Exception e) { - BanStick.getPlugin().warning("Failed to activate proxy loader of type {0}", - clazz.getName()); - BanStick.getPlugin().warning(" Failure message: ", e); - } - } - } - } - } catch (IOException ioe) { - BanStick.getPlugin().warning("Failed to load any proxy loaders, due to IO error", ioe); - } - } - - /** - * Shuts down this proxy handler - */ - public void shutdown() { - if (loaderTasks == null) { - return; - } - for (BukkitTask task : loaderTasks) { - try { - task.cancel(); - } catch (Exception e) { } - } - } + // now load all configured proxy list loaders. + // Build using constructor then launch repeating task + // if no exception thrown. + try { + ClassPath getSamplersPath = ClassPath.from(classes); + + for (ClassPath.ClassInfo clsInfo : getSamplersPath.getTopLevelClasses( + "com.programmerdan.minecraft.banstick.proxy")) { + Class clazz = clsInfo.load(); + if (clazz != null && ProxyLoader.class.isAssignableFrom(clazz)) { + BanStick.getPlugin().info("Found a proxy loader class {0}, attempting to find" + + " a suitable constructor", clazz.getName()); + ProxyLoader loader = null; + try { + Constructor constructBasic = clazz.getConstructor(ConfigurationSection.class); + loader = (ProxyLoader) constructBasic.newInstance(config); + BanStick.getPlugin().info("Created a new proxy loader of type {0}", clazz.getName()); + } catch (Exception e) { + BanStick.getPlugin().info("Failed to initialize a proxy loader of type {0}", clazz.getName()); + BanStick.getPlugin().warning(" Failure message: ", e.getMessage()); + } + + + if (loader != null) { + try { + BukkitTask loaderTask = loader.runTaskTimerAsynchronously(BanStick.getPlugin(), + loader.getDelay(), loader.getPeriod()); + loaderTasks.add(loaderTask); + } catch (Exception e) { + BanStick.getPlugin().warning("Failed to activate proxy loader of type {0}", + clazz.getName()); + BanStick.getPlugin().warning(" Failure message: ", e); + } + } + } + } + } catch (IOException ioe) { + BanStick.getPlugin().warning("Failed to load any proxy loaders, due to IO error", ioe); + } + } + + /** + * Shuts down this proxy handler + */ + public void shutdown() { + if (loaderTasks == null) { + return; + } + for (BukkitTask task : loaderTasks) { + try { + task.cancel(); + } catch (Exception e) { + } + } + } } diff --git a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/handler/BanStickScrapeHandler.java b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/handler/BanStickScrapeHandler.java index 71fbbc72a..9568d44b1 100644 --- a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/handler/BanStickScrapeHandler.java +++ b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/handler/BanStickScrapeHandler.java @@ -15,82 +15,82 @@ import org.bukkit.scheduler.BukkitTask; * This framework allows the loading of many scrapers that will visit those sites, extract the proxies, * and add them to our banlists for a time; similar to Tor, but with more scraping magic instead of the * pretty lists that Tor publishes. - * + * *

This is set up to be auto-loading modular like BanStickProxyHandler, so if you want to register * more scrapers just code 'm up and add them to the .scraper package. Be sure they extend * {@link com.programmerdan.minecraft.banstick.handler.ScraperWorker} class. - * - * @author ProgrammerDan * + * @author ProgrammerDan */ public class BanStickScrapeHandler { - ArrayList workers; - - public BanStickScrapeHandler(FileConfiguration config, ClassLoader classes) { - setup(config.getConfigurationSection("scrapers"), classes); - } - - private void setup(ConfigurationSection config, ClassLoader classes) { - if (config == null || !config.getBoolean("enable", false)) { - BanStick.getPlugin().warning("All Scraper Workers disabled"); - return; - } - - workers = new ArrayList<>(); - - // now load all configured proxy list loaders. - // Build using constructor then launch repeating task - // if no exception thrown. - try { - ClassPath getSamplersPath = ClassPath.from(classes); + ArrayList workers; - for (ClassPath.ClassInfo clsInfo : getSamplersPath.getTopLevelClasses( - "com.programmerdan.minecraft.banstick.scraper")) { - Class clazz = clsInfo.load(); - if (clazz != null && ScraperWorker.class.isAssignableFrom(clazz)) { - BanStick.getPlugin().info("Found a scraper worker class {0}, attempting to find" - + " a suitable constructor", clazz.getName()); - ScraperWorker loader = null; - try { - Constructor constructBasic = clazz.getConstructor(ConfigurationSection.class); - loader = (ScraperWorker) constructBasic.newInstance(config); - BanStick.getPlugin().info("Created a new scraper worker of type {0}", clazz.getName()); - } catch (Exception e) { - BanStick.getPlugin().info("Failed to initialize a scraper worker of type {0}", clazz.getName()); - BanStick.getPlugin().warning(" Failure message: ", e.getMessage()); - } + public BanStickScrapeHandler(FileConfiguration config, ClassLoader classes) { + setup(config.getConfigurationSection("scrapers"), classes); + } + + private void setup(ConfigurationSection config, ClassLoader classes) { + if (config == null || !config.getBoolean("enable", false)) { + BanStick.getPlugin().warning("All Scraper Workers disabled"); + return; + } + + workers = new ArrayList<>(); + + // now load all configured proxy list loaders. + // Build using constructor then launch repeating task + // if no exception thrown. + try { + ClassPath getSamplersPath = ClassPath.from(classes); + + for (ClassPath.ClassInfo clsInfo : getSamplersPath.getTopLevelClasses( + "com.programmerdan.minecraft.banstick.scraper")) { + Class clazz = clsInfo.load(); + if (clazz != null && ScraperWorker.class.isAssignableFrom(clazz)) { + BanStick.getPlugin().info("Found a scraper worker class {0}, attempting to find" + + " a suitable constructor", clazz.getName()); + ScraperWorker loader = null; + try { + Constructor constructBasic = clazz.getConstructor(ConfigurationSection.class); + loader = (ScraperWorker) constructBasic.newInstance(config); + BanStick.getPlugin().info("Created a new scraper worker of type {0}", clazz.getName()); + } catch (Exception e) { + BanStick.getPlugin().info("Failed to initialize a scraper worker of type {0}", clazz.getName()); + BanStick.getPlugin().warning(" Failure message: ", e.getMessage()); + } - if (loader != null) { - try { - BukkitTask task = Bukkit.getScheduler().runTaskLaterAsynchronously(BanStick.getPlugin(), - loader, loader.getDelay()); - loader.setTask(task); - } catch (Exception e) { - BanStick.getPlugin().warning("Failed to activate scraper worker of type {0}", - clazz.getName()); - BanStick.getPlugin().warning(" Failure message: ", e); - } - } - } - } - } catch (IOException ioe) { - BanStick.getPlugin().warning("Failed to load any scraper workers, due to IO error", ioe); - } - } - - /** - * Shuts down this scrape manager. - */ - public void shutdown() { - if (this.workers == null) { - return; - } - for (ScraperWorker task : workers) { - try { - task.shutdown(); - } catch (Exception e) { } - } - } + if (loader != null) { + try { + BukkitTask task = Bukkit.getScheduler().runTaskLaterAsynchronously(BanStick.getPlugin(), + loader, loader.getDelay()); + loader.setTask(task); + } catch (Exception e) { + BanStick.getPlugin().warning("Failed to activate scraper worker of type {0}", + clazz.getName()); + BanStick.getPlugin().warning(" Failure message: ", e); + } + } + } + } + } catch (IOException ioe) { + BanStick.getPlugin().warning("Failed to load any scraper workers, due to IO error", ioe); + } + } + + /** + * Shuts down this scrape manager. + */ + public void shutdown() { + if (this.workers == null) { + return; + } + for (ScraperWorker task : workers) { + try { + task.shutdown(); + } catch (Exception e) { + } + } + } } diff --git a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/handler/BanStickTorUpdater.java b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/handler/BanStickTorUpdater.java index 540b154c6..ceae7b63e 100644 --- a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/handler/BanStickTorUpdater.java +++ b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/handler/BanStickTorUpdater.java @@ -21,7 +21,7 @@ import org.bukkit.scheduler.BukkitTask; /** * A handler for Tor-based scrapers, which is a bit specialized. Handles Tor Endpoint monitoring. - * + * * @author ProgrammerDan */ public class BanStickTorUpdater { @@ -42,185 +42,189 @@ tor: cidr: false */ - private boolean banNewNodes; - - private List torLists = new ArrayList<>(); - private List torListUpdaters = new ArrayList<>(); + private boolean banNewNodes; - /** - * Given a file config, sets up tor monitors. If no tor setion? no tor. - * @param config the tor config section. - */ - public BanStickTorUpdater(FileConfiguration config) { - if (!configureTor(config.getConfigurationSection("tor"))) { - return; - } - - activateTor(); - } - - private boolean configureTor(ConfigurationSection config) { - if (config == null || !config.getBoolean("check", false)) { - BanStick.getPlugin().info("TOR exit node checks disabled."); - return false; - } - - try { - banNewNodes = config.getBoolean("autoban", false); - ConfigurationSection lists = config.getConfigurationSection("lists"); - if (lists == null) { - return true; // all done quickly. - } - for (String listName : lists.getKeys(false)) { - ConfigurationSection list = lists.getConfigurationSection(listName); - if (list != null) { - torLists.add(new TorList( - list.getString("address"), - list.getLong("period"), - list.getLong("delay"), - list.getBoolean("cidr"), - list.getString("ban.message"), - list.getLong("ban.length") - )); - } - } - return true; - } catch (Exception e) { - BanStick.getPlugin().warning("Failed to load Tor nodes."); - return false; - } - } - - private void activateTor() { - for (TorList tor : torLists) { - BanStick.getPlugin().info("Preparing Tor runnable for " + tor.address); - BukkitRunnable run = new BukkitRunnable() { - final TorList torSave = tor; - @Override - public void run() { - try { - BanStick.getPlugin().info("Tor capture for " + torSave.address); - URL connection = new URL(torSave.address); - InputStream readIn = connection.openStream(); - BufferedReader in = new BufferedReader(new InputStreamReader(readIn)); - String line = in.readLine(); - long lines = 0L; - int errors = 0; - while (line != null) { - lines ++; - if (lines % 50 == 0) { - BanStick.getPlugin().info("Processed {0} records from {1} so far", - lines, torSave.address); - } - if (errors > 10) { - BanStick.getPlugin().warning("Cancelling this Tor capture run, too many errors."); - break; - } - try { - IPAddressString address = new IPAddressString(line); - address.validate(); - BSIP found = null; - if (torSave.cidr) { - found = BSIP.byCIDR(address.toAddress().getLower().toString(), - address.getNetworkPrefixLength()); - } else { - found = BSIP.byIPAddress(address.toAddress()); - } - if (found == null) { - if (torSave.cidr) { - found = BSIP.create(address.toAddress().getLower(), - address.getNetworkPrefixLength()); - } else { - found = BSIP.create(address.toAddress()); - } - // TODO: CREATE A VPN RECORD - BSIPData dataMatch = BSIPData.byExactIP(found); - if (dataMatch == null) { - dataMatch = BSIPData.create(found, null, null, null, null, - null, null, null, null, null, null, null, - 2.5f, torSave.address, "Tor exit node"); - } - } - - if (banNewNodes) { - boolean wasmatch = false; - List ban = BSBan.byIP(found, true); - - if (!(ban == null || ban.size() == 0)) { - // look for match; if unexpired, extend. - for (int i = ban.size() - 1 ; i >= 0; i--) { - BSBan pickOne = ban.get(i); - if (pickOne.isAdminBan()) { - continue; // skip admin entered bans. - } - if (pickOne.getBanEndTime() != null - && pickOne.getBanEndTime().after(new Date())) { - if (torSave.endlessBan) { - pickOne.clearBanEndTime(); // no end. - } else { - pickOne.setBanEndTime(new Date(System.currentTimeMillis() - + torSave.banLength)); - } - wasmatch = true; - break; - } - } - } - if (!wasmatch) { - BSBan.create(found, torSave.banMessage, - torSave.endlessBan ? null : new Date(System.currentTimeMillis() - + torSave.banLength), false); - } - } - - } catch (NullPointerException | IPAddressStringException e) { - // quiet. - errors ++; - } - line = in.readLine(); - } - } catch (IOException e) { - BanStick.getPlugin().debug("Failed reading from TOR list: " + torSave.address); - BanStick.getPlugin().warning(" Exception:", e); - } - } - }; - - torListUpdaters.add(run.runTaskTimerAsynchronously(BanStick.getPlugin(), tor.delay, tor.period)); - } - } - - /** - * Shuts down this TOR manager. - */ - public void shutdown() { - if (torListUpdaters == null) { - return; - } - for (BukkitTask task : torListUpdaters) { - try { - task.cancel(); - } catch (Exception e) { } - } - } + private List torLists = new ArrayList<>(); + private List torListUpdaters = new ArrayList<>(); - class TorList { - public String address; - public long period; - public long delay; - public boolean cidr; - public String banMessage; - public long banLength; - public boolean endlessBan; - - TorList(String address, long period, long delay, boolean cidr, String banMessage, long banLength) { - this.address = address; - this.period = period; - this.delay = delay; - this.cidr = cidr; - this.banMessage = banMessage; - this.banLength = banLength; - this.endlessBan = banLength == 0; - } - } + /** + * Given a file config, sets up tor monitors. If no tor setion? no tor. + * + * @param config the tor config section. + */ + public BanStickTorUpdater(FileConfiguration config) { + if (!configureTor(config.getConfigurationSection("tor"))) { + return; + } + + activateTor(); + } + + private boolean configureTor(ConfigurationSection config) { + if (config == null || !config.getBoolean("check", false)) { + BanStick.getPlugin().info("TOR exit node checks disabled."); + return false; + } + + try { + banNewNodes = config.getBoolean("autoban", false); + ConfigurationSection lists = config.getConfigurationSection("lists"); + if (lists == null) { + return true; // all done quickly. + } + for (String listName : lists.getKeys(false)) { + ConfigurationSection list = lists.getConfigurationSection(listName); + if (list != null) { + torLists.add(new TorList( + list.getString("address"), + list.getLong("period"), + list.getLong("delay"), + list.getBoolean("cidr"), + list.getString("ban.message"), + list.getLong("ban.length") + )); + } + } + return true; + } catch (Exception e) { + BanStick.getPlugin().warning("Failed to load Tor nodes."); + return false; + } + } + + private void activateTor() { + for (TorList tor : torLists) { + BanStick.getPlugin().info("Preparing Tor runnable for " + tor.address); + BukkitRunnable run = new BukkitRunnable() { + final TorList torSave = tor; + + @Override + public void run() { + try { + BanStick.getPlugin().info("Tor capture for " + torSave.address); + URL connection = new URL(torSave.address); + InputStream readIn = connection.openStream(); + BufferedReader in = new BufferedReader(new InputStreamReader(readIn)); + String line = in.readLine(); + long lines = 0L; + int errors = 0; + while (line != null) { + lines++; + if (lines % 50 == 0) { + BanStick.getPlugin().info("Processed {0} records from {1} so far", + lines, torSave.address); + } + if (errors > 10) { + BanStick.getPlugin().warning("Cancelling this Tor capture run, too many errors."); + break; + } + try { + IPAddressString address = new IPAddressString(line); + address.validate(); + BSIP found = null; + if (torSave.cidr) { + found = BSIP.byCIDR(address.toAddress().getLower().toString(), + address.getNetworkPrefixLength()); + } else { + found = BSIP.byIPAddress(address.toAddress()); + } + if (found == null) { + if (torSave.cidr) { + found = BSIP.create(address.toAddress().getLower(), + address.getNetworkPrefixLength()); + } else { + found = BSIP.create(address.toAddress()); + } + // TODO: CREATE A VPN RECORD + BSIPData dataMatch = BSIPData.byExactIP(found); + if (dataMatch == null) { + dataMatch = BSIPData.create(found, null, null, null, null, + null, null, null, null, null, null, null, + 2.5f, torSave.address, "Tor exit node"); + } + } + + if (banNewNodes) { + boolean wasmatch = false; + List ban = BSBan.byIP(found, true); + + if (!(ban == null || ban.size() == 0)) { + // look for match; if unexpired, extend. + for (int i = ban.size() - 1; i >= 0; i--) { + BSBan pickOne = ban.get(i); + if (pickOne.isAdminBan()) { + continue; // skip admin entered bans. + } + if (pickOne.getBanEndTime() != null + && pickOne.getBanEndTime().after(new Date())) { + if (torSave.endlessBan) { + pickOne.clearBanEndTime(); // no end. + } else { + pickOne.setBanEndTime(new Date(System.currentTimeMillis() + + torSave.banLength)); + } + wasmatch = true; + break; + } + } + } + if (!wasmatch) { + BSBan.create(found, torSave.banMessage, + torSave.endlessBan ? null : new Date(System.currentTimeMillis() + + torSave.banLength), false); + } + } + + } catch (NullPointerException | IPAddressStringException e) { + // quiet. + errors++; + } + line = in.readLine(); + } + } catch (IOException e) { + BanStick.getPlugin().debug("Failed reading from TOR list: " + torSave.address); + BanStick.getPlugin().warning(" Exception:", e); + } + } + }; + + torListUpdaters.add(run.runTaskTimerAsynchronously(BanStick.getPlugin(), tor.delay, tor.period)); + } + } + + /** + * Shuts down this TOR manager. + */ + public void shutdown() { + if (torListUpdaters == null) { + return; + } + for (BukkitTask task : torListUpdaters) { + try { + task.cancel(); + } catch (Exception e) { + } + } + } + + class TorList { + + public String address; + public long period; + public long delay; + public boolean cidr; + public String banMessage; + public long banLength; + public boolean endlessBan; + + TorList(String address, long period, long delay, boolean cidr, String banMessage, long banLength) { + this.address = address; + this.period = period; + this.delay = delay; + this.cidr = cidr; + this.banMessage = banMessage; + this.banLength = banLength; + this.endlessBan = banLength == 0; + } + } } diff --git a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/handler/ImportWorker.java b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/handler/ImportWorker.java index 98e58a497..6b8adbbc5 100644 --- a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/handler/ImportWorker.java +++ b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/handler/ImportWorker.java @@ -5,69 +5,68 @@ import org.bukkit.scheduler.BukkitTask; /** * ImportWorker definition, used elsewhere - * - * @author ProgrammerDan * + * @author ProgrammerDan */ public abstract class ImportWorker implements Runnable { - private BukkitTask importTask; - private long delay = 100L; - private boolean enable; - - /** - * Set up an import worker, using its name. - * - * @param config the config to load. - */ - public ImportWorker(ConfigurationSection config) { - if (config != null && setup(config.getConfigurationSection(name()))) { - enable = internalSetup(config.getConfigurationSection(name())); - } else { - enable = false; - } - } - - private boolean setup(ConfigurationSection config) { - if (config == null) { - return false; - } - delay = config.getLong("delay", delay); - return config.getBoolean("enable", enable); - } - - @Override - public void run() { - if (enable) { - doImport(); - } - } - - public abstract boolean internalSetup(ConfigurationSection config); + private BukkitTask importTask; + private long delay = 100L; + private boolean enable; - public abstract void doImport(); - - public abstract String name(); + /** + * Set up an import worker, using its name. + * + * @param config the config to load. + */ + public ImportWorker(ConfigurationSection config) { + if (config != null && setup(config.getConfigurationSection(name()))) { + enable = internalSetup(config.getConfigurationSection(name())); + } else { + enable = false; + } + } - public long getDelay() { - return 0; - } + private boolean setup(ConfigurationSection config) { + if (config == null) { + return false; + } + delay = config.getLong("delay", delay); + return config.getBoolean("enable", enable); + } - public void setTask(BukkitTask task) { - importTask = task; - } + @Override + public void run() { + if (enable) { + doImport(); + } + } - /** - * Attempt to shut this worker down. - */ - public void shutdown() { - try { - if (enable && importTask != null) { - importTask.cancel(); - } - } catch (Exception e) { - // shutdown? woops/ - } - } + public abstract boolean internalSetup(ConfigurationSection config); + + public abstract void doImport(); + + public abstract String name(); + + public long getDelay() { + return 0; + } + + public void setTask(BukkitTask task) { + importTask = task; + } + + /** + * Attempt to shut this worker down. + */ + public void shutdown() { + try { + if (enable && importTask != null) { + importTask.cancel(); + } + } catch (Exception e) { + // shutdown? woops/ + } + } } diff --git a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/handler/ProxyLoader.java b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/handler/ProxyLoader.java index c8f3be369..69a2cb862 100644 --- a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/handler/ProxyLoader.java +++ b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/handler/ProxyLoader.java @@ -6,71 +6,70 @@ import org.bukkit.scheduler.BukkitRunnable; /** * Lightweight wrapper. Put implementations into banstick.proxy classpath for autoloading. - * - * @author ProgrammerDan * + * @author ProgrammerDan */ public abstract class ProxyLoader extends BukkitRunnable { - private boolean enabled; - private long delay = 4200L; - private long period = 576000L; - - /** - * Basic constructor handles unified enabled/ disabled control, delay and period loading. - * - * @param config The configuration to use. - */ - public ProxyLoader(ConfigurationSection config) { - BanStick.getPlugin().info("ProxyLoader loading for: {0}", name()); - ConfigurationSection internalConfig = config.getConfigurationSection(name()); - if (internalConfig == null) { - throw new RuntimeException("ProxyLoader has no config; disabled"); - } - this.enabled = internalConfig.getBoolean("enable", false); - if (!this.enabled) { - throw new RuntimeException("ProxyLoader disabled"); - } - this.delay = internalConfig.getLong("delay", this.delay); - this.period = internalConfig.getLong("period", this.period); - - setup(internalConfig); - } - - /** - * Get delay before first pull of data / execution of proxy loader. - * - *

Default of 4200, or whatever is configured as delay. - * - * @return Number of ticks until first pull - */ - public long getDelay() { - return this.delay; - } - - /** - * Get period inbetween pulls. - * - *

Default of 576000 (8 hours). - * - * @return Number of ticks until next pull - */ - public long getPeriod() { - return this.period; - } - - /** - * Subclasses should use this in preference to overriding the constructor, use it to configure - * the instantiation. - * - * @param config The config to use to set up the proxy loader - */ - public abstract void setup(ConfigurationSection config); - - /** - * Give it a unique name / identity within the config.yml - * - * @return the unique name of this proxy loader; it is used to pick a branch along the config. - */ - public abstract String name(); + private boolean enabled; + private long delay = 4200L; + private long period = 576000L; + + /** + * Basic constructor handles unified enabled/ disabled control, delay and period loading. + * + * @param config The configuration to use. + */ + public ProxyLoader(ConfigurationSection config) { + BanStick.getPlugin().info("ProxyLoader loading for: {0}", name()); + ConfigurationSection internalConfig = config.getConfigurationSection(name()); + if (internalConfig == null) { + throw new RuntimeException("ProxyLoader has no config; disabled"); + } + this.enabled = internalConfig.getBoolean("enable", false); + if (!this.enabled) { + throw new RuntimeException("ProxyLoader disabled"); + } + this.delay = internalConfig.getLong("delay", this.delay); + this.period = internalConfig.getLong("period", this.period); + + setup(internalConfig); + } + + /** + * Get delay before first pull of data / execution of proxy loader. + * + *

Default of 4200, or whatever is configured as delay. + * + * @return Number of ticks until first pull + */ + public long getDelay() { + return this.delay; + } + + /** + * Get period inbetween pulls. + * + *

Default of 576000 (8 hours). + * + * @return Number of ticks until next pull + */ + public long getPeriod() { + return this.period; + } + + /** + * Subclasses should use this in preference to overriding the constructor, use it to configure + * the instantiation. + * + * @param config The config to use to set up the proxy loader + */ + public abstract void setup(ConfigurationSection config); + + /** + * Give it a unique name / identity within the config.yml + * + * @return the unique name of this proxy loader; it is used to pick a branch along the config. + */ + public abstract String name(); } diff --git a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/handler/ScraperWorker.java b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/handler/ScraperWorker.java index 1187e80b7..5bca6cc0e 100644 --- a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/handler/ScraperWorker.java +++ b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/handler/ScraperWorker.java @@ -7,200 +7,200 @@ import org.bukkit.scheduler.BukkitTask; /** * Middleweight wrapper. Put implementations into banstick.scraper classpath for autoloading. - * - *

Handles error tracking, scheduling, and cooldown on error max. - * - * @author ProgrammerDan * + *

Handles error tracking, scheduling, and cooldown on error max. + * + * @author ProgrammerDan */ public abstract class ScraperWorker implements Runnable { - private BukkitTask currentTask; - private boolean enabled; - private long delay; - private long period; - private long jitter; - private int maxErrors; - private long errorCooldown; - - private long lifetimeErrors; - private int currentErrors; - - /** - * Basic constructor handles unified enabled/ disabled control, delay and period and jitter loading. - * - *

Also pulls in max errors before shutdown and period until retry (if any) - * - * @param config The configuration to use. - */ - public ScraperWorker(ConfigurationSection config) { - currentTask = null; - enabled = false; - delay = 4200L; - period = 576000L; - jitter = 176000L; - maxErrors = 10; - errorCooldown = -1L; - lifetimeErrors = 0L; - currentErrors = 0; - - BanStick.getPlugin().info("ScraperWorker loading for: {0}", name()); - ConfigurationSection internalConfig = config.getConfigurationSection(name()); - if (internalConfig == null) { - throw new RuntimeException("ScraperWorker has no config; disabled"); - } - this.enabled = internalConfig.getBoolean("enable", false); - if (!this.enabled) { - throw new RuntimeException("ScraperWorker disabled"); - } - this.delay = internalConfig.getLong("delay", this.delay); - this.period = internalConfig.getLong("period", this.period); - this.jitter = internalConfig.getLong("jitter", this.jitter); - this.maxErrors = internalConfig.getInt("maxErrors", this.maxErrors); - this.errorCooldown = internalConfig.getLong("errorCooldown", this.errorCooldown); - - setup(internalConfig); - } - - /** - * Get delay before first pull of data / execution of scraper worker. - * - *

Default of 4200, or whatever is configured as delay. - * - * @return Number of ticks until first scrape - */ - public long getDelay() { - return this.delay; - } - - /** - * Get average period inbetween pulls. - * - *

Default of 576000 (8 hours). - * - * @return Number of ticks until next scrape, on average - */ - public long getPeriod() { - return this.period; - } - - /** - * Get +/- tick jitter inbetween executions, to disguise scrape - * - * @return Number of ticks +/- to randomly adjust runtime of next scrape. - */ - public long getJitter() { - return this.jitter; - } - - /** - * Gets the max errors before entering cooldown / shutdown. - * - * @return the max errors to tolerate - */ - public int getMaxErrors() { - return this.maxErrors; - } - - /** - * Returns the total errors encountered since this scraper began, ignore cooldown resets - * - * @return Total errors encountered - */ - public long getLifetimeErrors() { - return this.lifetimeErrors; - } - - /** - * Returns the errors encountered in this pre-cooldown segment. - * - * @return Errors since last start / cooldown end. - */ - public int getCurrentErrors() { - return this.currentErrors; - } - - public void registerError() { - this.currentErrors++; - this.lifetimeErrors++; - } - - /** - * Subclasses should use this in preference to overriding the constructor, use it to configure - * the instantiation. - * - * @param config The config to use to set up the scraper worker - */ - public abstract void setup(ConfigurationSection config); - - /** - * Give it a unique name / identity within the config.yml - * - * @return the unique name of this scraper worker; it is used to pick a branch along the config. - */ - public abstract String name(); - - /** - * Called on each run, should do the scraping - */ - public abstract void scrape(); - - /** - * Takes the base and jitters it randomly by +/- the jitter amount. If this goes below zero, - * instead produces a random number between [0,jitter) - * @param base The base amount to jitter - * @return A jittered base - */ - private long jitter(long base) { - long outcome = base + (long) (Math.random() * 2.0d * (double) this.jitter) - this.jitter; - if (outcome < 1L) { - outcome = (long) (Math.random() * (double) this.jitter); - } - return outcome; - } - - /** - * Base run, handles uncaught exceptions and cooldown/ error counting. - */ - @Override - public final void run() { - try { - BanStick.getPlugin().debug("Running Scraper Worker {0}", name()); - scrape(); - } catch (Exception e) { - BanStick.getPlugin().warning("Scraper Worker {0} uncaught failure during scrape", name()); - BanStick.getPlugin().warning("Exception: ", e); - registerError(); - } - - if (this.currentErrors > this.maxErrors) { - // enter cooldown. - this.currentErrors = 0; - - if (this.errorCooldown > 0) { - BanStick.getPlugin().warning("Error threshold exceeded; cooldown engaged for {0}.", name()); - this.currentTask = Bukkit.getScheduler().runTaskLaterAsynchronously(BanStick.getPlugin(), - this, jitter(this.errorCooldown)); - } else { - this.enabled = false; - BanStick.getPlugin().warning("Error threshold exceeded; {0} disabled.", name()); - } - } else { - this.currentTask = Bukkit.getScheduler().runTaskLaterAsynchronously(BanStick.getPlugin(), - this, jitter(this.delay)); - } - } - - /** - * Attempts to shut down this scraperworker - */ - public void shutdown() { - if (this.currentTask != null) { - this.currentTask.cancel(); - } - } - - public void setTask(BukkitTask task) { - this.currentTask = task; - } + private BukkitTask currentTask; + private boolean enabled; + private long delay; + private long period; + private long jitter; + private int maxErrors; + private long errorCooldown; + + private long lifetimeErrors; + private int currentErrors; + + /** + * Basic constructor handles unified enabled/ disabled control, delay and period and jitter loading. + * + *

Also pulls in max errors before shutdown and period until retry (if any) + * + * @param config The configuration to use. + */ + public ScraperWorker(ConfigurationSection config) { + currentTask = null; + enabled = false; + delay = 4200L; + period = 576000L; + jitter = 176000L; + maxErrors = 10; + errorCooldown = -1L; + lifetimeErrors = 0L; + currentErrors = 0; + + BanStick.getPlugin().info("ScraperWorker loading for: {0}", name()); + ConfigurationSection internalConfig = config.getConfigurationSection(name()); + if (internalConfig == null) { + throw new RuntimeException("ScraperWorker has no config; disabled"); + } + this.enabled = internalConfig.getBoolean("enable", false); + if (!this.enabled) { + throw new RuntimeException("ScraperWorker disabled"); + } + this.delay = internalConfig.getLong("delay", this.delay); + this.period = internalConfig.getLong("period", this.period); + this.jitter = internalConfig.getLong("jitter", this.jitter); + this.maxErrors = internalConfig.getInt("maxErrors", this.maxErrors); + this.errorCooldown = internalConfig.getLong("errorCooldown", this.errorCooldown); + + setup(internalConfig); + } + + /** + * Get delay before first pull of data / execution of scraper worker. + * + *

Default of 4200, or whatever is configured as delay. + * + * @return Number of ticks until first scrape + */ + public long getDelay() { + return this.delay; + } + + /** + * Get average period inbetween pulls. + * + *

Default of 576000 (8 hours). + * + * @return Number of ticks until next scrape, on average + */ + public long getPeriod() { + return this.period; + } + + /** + * Get +/- tick jitter inbetween executions, to disguise scrape + * + * @return Number of ticks +/- to randomly adjust runtime of next scrape. + */ + public long getJitter() { + return this.jitter; + } + + /** + * Gets the max errors before entering cooldown / shutdown. + * + * @return the max errors to tolerate + */ + public int getMaxErrors() { + return this.maxErrors; + } + + /** + * Returns the total errors encountered since this scraper began, ignore cooldown resets + * + * @return Total errors encountered + */ + public long getLifetimeErrors() { + return this.lifetimeErrors; + } + + /** + * Returns the errors encountered in this pre-cooldown segment. + * + * @return Errors since last start / cooldown end. + */ + public int getCurrentErrors() { + return this.currentErrors; + } + + public void registerError() { + this.currentErrors++; + this.lifetimeErrors++; + } + + /** + * Subclasses should use this in preference to overriding the constructor, use it to configure + * the instantiation. + * + * @param config The config to use to set up the scraper worker + */ + public abstract void setup(ConfigurationSection config); + + /** + * Give it a unique name / identity within the config.yml + * + * @return the unique name of this scraper worker; it is used to pick a branch along the config. + */ + public abstract String name(); + + /** + * Called on each run, should do the scraping + */ + public abstract void scrape(); + + /** + * Takes the base and jitters it randomly by +/- the jitter amount. If this goes below zero, + * instead produces a random number between [0,jitter) + * + * @param base The base amount to jitter + * @return A jittered base + */ + private long jitter(long base) { + long outcome = base + (long) (Math.random() * 2.0d * (double) this.jitter) - this.jitter; + if (outcome < 1L) { + outcome = (long) (Math.random() * (double) this.jitter); + } + return outcome; + } + + /** + * Base run, handles uncaught exceptions and cooldown/ error counting. + */ + @Override + public final void run() { + try { + BanStick.getPlugin().debug("Running Scraper Worker {0}", name()); + scrape(); + } catch (Exception e) { + BanStick.getPlugin().warning("Scraper Worker {0} uncaught failure during scrape", name()); + BanStick.getPlugin().warning("Exception: ", e); + registerError(); + } + + if (this.currentErrors > this.maxErrors) { + // enter cooldown. + this.currentErrors = 0; + + if (this.errorCooldown > 0) { + BanStick.getPlugin().warning("Error threshold exceeded; cooldown engaged for {0}.", name()); + this.currentTask = Bukkit.getScheduler().runTaskLaterAsynchronously(BanStick.getPlugin(), + this, jitter(this.errorCooldown)); + } else { + this.enabled = false; + BanStick.getPlugin().warning("Error threshold exceeded; {0} disabled.", name()); + } + } else { + this.currentTask = Bukkit.getScheduler().runTaskLaterAsynchronously(BanStick.getPlugin(), + this, jitter(this.delay)); + } + } + + /** + * Attempts to shut down this scraperworker + */ + public void shutdown() { + if (this.currentTask != null) { + this.currentTask.cancel(); + } + } + + public void setTask(BukkitTask task) { + this.currentTask = task; + } } diff --git a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/handler/package-info.java b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/handler/package-info.java index b2e49f983..ee73feeb8 100644 --- a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/handler/package-info.java +++ b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/handler/package-info.java @@ -1,9 +1,8 @@ /** * This package holds all the various handlers for behaviors, actions, and interactions. - * - *

CommandHandler; EventHandler; and CheckHandler. - * - * @author ProgrammerDan * + *

CommandHandler; EventHandler; and CheckHandler. + * + * @author ProgrammerDan */ package com.programmerdan.minecraft.banstick.handler; diff --git a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/importer/IpCheckImportWorker.java b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/importer/IpCheckImportWorker.java index 49ee90506..0709e2f40 100644 --- a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/importer/IpCheckImportWorker.java +++ b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/importer/IpCheckImportWorker.java @@ -23,84 +23,83 @@ import vg.civcraft.mc.namelayer.NameAPI; /** * Worker for IpCheck plugin's import. - * - * @author ProgrammerDan * + * @author ProgrammerDan */ public class IpCheckImportWorker extends ImportWorker { - private ManagedDatasource internalDatabase; - - public IpCheckImportWorker(ConfigurationSection config) { - super(config); - } + private ManagedDatasource internalDatabase; - @Override - public boolean internalSetup(ConfigurationSection config) { - if (config == null) { - return false; - } - ConfigurationSection internal = config.getConfigurationSection("database"); - if (internal != null) { - return provisionDatabase(internal); - } else { - return false; - } - } - - private boolean provisionDatabase(ConfigurationSection config) { - String host = config.getString("host", "localhost"); - int port = config.getInt("port", 3306); - String dbname = config.getString("database", "ipcheck"); - String username = config.getString("user"); - String password = config.getString("password"); - int poolsize = config.getInt("poolsize", 3); - long connectionTimeout = config.getLong("connection_timeout", 10000L); - long idleTimeout = config.getLong("idle_timeout", 600000L); - long maxLifetime = config.getLong("max_lifetime", 7200000L); - try { - internalDatabase = ManagedDatasource.construct(BanStick.getPlugin(), new DatabaseCredentials(username, password, host, port, "mysql", dbname, - poolsize, connectionTimeout, idleTimeout, maxLifetime)); - internalDatabase.getConnection().close(); - } catch (Exception se) { - BanStick.getPlugin().info("Failed to initialize Database connection"); - return false; - } - - return true; - } + public IpCheckImportWorker(ConfigurationSection config) { + super(config); + } - @Override - public void doImport() { - - // plan will be, create IP records; establish bans if ban is indicated. - // So, first, ipcheck_ip -- create any IP records not already known. If known, do nothing. - // If banned, make a ban record for that IP - // Second, ipcheck_user -- create any Users not already known. If known and not banned, - // but marked banned, ban w/ message. - // If exempted, rejoined exempted, or protected, provide pardons as appropriate - // Third, ipcheck_log -- create sessions for users + ips for the times given. - try { - doImportIPs(); - Thread.sleep(0); - doImportPlayers(); - Thread.sleep(0); - doImportSessions(); - Thread.sleep(0); - } catch (Exception e) { - BanStick.getPlugin().severe("Failed during IP-Check import, potentially incomplete import: ", e); - } - } + @Override + public boolean internalSetup(ConfigurationSection config) { + if (config == null) { + return false; + } + ConfigurationSection internal = config.getConfigurationSection("database"); + if (internal != null) { + return provisionDatabase(internal); + } else { + return false; + } + } - @Override - public String name() { - return "ipcheck"; - } - - private void doImportIPs() { - try (Connection connection = internalDatabase.getConnection(); - PreparedStatement getIPs = connection.prepareStatement( - "SELECT * FROM ipcheck_ip ORDER BY `timestamp` LIMIT ?, ?");) { + private boolean provisionDatabase(ConfigurationSection config) { + String host = config.getString("host", "localhost"); + int port = config.getInt("port", 3306); + String dbname = config.getString("database", "ipcheck"); + String username = config.getString("user"); + String password = config.getString("password"); + int poolsize = config.getInt("poolsize", 3); + long connectionTimeout = config.getLong("connection_timeout", 10000L); + long idleTimeout = config.getLong("idle_timeout", 600000L); + long maxLifetime = config.getLong("max_lifetime", 7200000L); + try { + internalDatabase = ManagedDatasource.construct(BanStick.getPlugin(), new DatabaseCredentials(username, password, host, port, "mysql", dbname, + poolsize, connectionTimeout, idleTimeout, maxLifetime)); + internalDatabase.getConnection().close(); + } catch (Exception se) { + BanStick.getPlugin().info("Failed to initialize Database connection"); + return false; + } + + return true; + } + + @Override + public void doImport() { + + // plan will be, create IP records; establish bans if ban is indicated. + // So, first, ipcheck_ip -- create any IP records not already known. If known, do nothing. + // If banned, make a ban record for that IP + // Second, ipcheck_user -- create any Users not already known. If known and not banned, + // but marked banned, ban w/ message. + // If exempted, rejoined exempted, or protected, provide pardons as appropriate + // Third, ipcheck_log -- create sessions for users + ips for the times given. + try { + doImportIPs(); + Thread.sleep(0); + doImportPlayers(); + Thread.sleep(0); + doImportSessions(); + Thread.sleep(0); + } catch (Exception e) { + BanStick.getPlugin().severe("Failed during IP-Check import, potentially incomplete import: ", e); + } + } + + @Override + public String name() { + return "ipcheck"; + } + + private void doImportIPs() { + try (Connection connection = internalDatabase.getConnection(); + PreparedStatement getIPs = connection.prepareStatement( + "SELECT * FROM ipcheck_ip ORDER BY `timestamp` LIMIT ?, ?");) { /* * CREATE TABLE `ipcheck_ip` ( `ip` varchar(15) NOT NULL, @@ -110,56 +109,56 @@ public class IpCheckImportWorker extends ImportWorker { `rejoinexempt` bit(1) NOT NULL DEFAULT b'0', PRIMARY KEY (`ip`) */ - long offset = 0; - int limit = 100; - boolean cont = true; - while (cont) { - getIPs.clearParameters(); - getIPs.setLong(1, offset); - getIPs.setInt(2, limit); - try (ResultSet rs = getIPs.executeQuery();) { - int thisCycle = 0; - while (rs.next()) { - // only ip and ban state is leveraged here. - String ip = rs.getString(1); - //Timestamp firstUse = rs.getTimestamp(2); - boolean isBanned = rs.getBoolean(3); - //boolean isJoinExempt = rs.getBoolean(4); - //boolean isWarnExempt = rs.getBoolean(5); - - try { - IPAddressString address = new IPAddressString(ip); - IPAddress exactAddress = address.toAddress(); - - BSIP exactIP = BSIP.byIPAddress(exactAddress); - if (exactIP == null) { - exactIP = BSIP.create(exactAddress); - } - if (isBanned) { - BSBan.create(exactIP, "Banned for Multiaccounting", null, true); - } - } catch (Exception e) { - BanStick.getPlugin().warning("Found invalid IP {0} in IP-Check database", ip); - } - thisCycle++; - } - if (thisCycle == 0) { // all done! - cont = false; - } else { - offset += limit; - } - } - Thread.sleep(0L); - } - } catch (SQLException | InterruptedException se) { - BanStick.getPlugin().severe("Failed to import IPs from IP-Check, potentially incomplete import: ", se); - } - } - - private void doImportPlayers() { - try (Connection connection = internalDatabase.getConnection(); - PreparedStatement getIPs = connection.prepareStatement( - "SELECT * FROM ipcheck_user ORDER BY `timestamp` LIMIT ?, ?");) { + long offset = 0; + int limit = 100; + boolean cont = true; + while (cont) { + getIPs.clearParameters(); + getIPs.setLong(1, offset); + getIPs.setInt(2, limit); + try (ResultSet rs = getIPs.executeQuery();) { + int thisCycle = 0; + while (rs.next()) { + // only ip and ban state is leveraged here. + String ip = rs.getString(1); + //Timestamp firstUse = rs.getTimestamp(2); + boolean isBanned = rs.getBoolean(3); + //boolean isJoinExempt = rs.getBoolean(4); + //boolean isWarnExempt = rs.getBoolean(5); + + try { + IPAddressString address = new IPAddressString(ip); + IPAddress exactAddress = address.toAddress(); + + BSIP exactIP = BSIP.byIPAddress(exactAddress); + if (exactIP == null) { + exactIP = BSIP.create(exactAddress); + } + if (isBanned) { + BSBan.create(exactIP, "Banned for Multiaccounting", null, true); + } + } catch (Exception e) { + BanStick.getPlugin().warning("Found invalid IP {0} in IP-Check database", ip); + } + thisCycle++; + } + if (thisCycle == 0) { // all done! + cont = false; + } else { + offset += limit; + } + } + Thread.sleep(0L); + } + } catch (SQLException | InterruptedException se) { + BanStick.getPlugin().severe("Failed to import IPs from IP-Check, potentially incomplete import: ", se); + } + } + + private void doImportPlayers() { + try (Connection connection = internalDatabase.getConnection(); + PreparedStatement getIPs = connection.prepareStatement( + "SELECT * FROM ipcheck_user ORDER BY `timestamp` LIMIT ?, ?");) { /* * CREATE TABLE `ipcheck_user` ( `username` varchar(255) NOT NULL, @@ -171,157 +170,159 @@ public class IpCheckImportWorker extends ImportWorker { `protected` bit(1) NOT NULL DEFAULT b'0', PRIMARY KEY (`username`) */ - long offset = 0; - int limit = 100; - boolean cont = true; - while (cont) { - getIPs.clearParameters(); - getIPs.setLong(1, offset); - getIPs.setInt(2, limit); - try (ResultSet rs = getIPs.executeQuery();) { - int thisCycle = 0; - while (rs.next()) { - // ignore fields not used in import. - String username = rs.getString(1); - //Timestamp firstJoin = rs.getTimestamp(2); - String banMessage = rs.getString(3); - //boolean isWarnExempt = rs.getBoolean(6); - - UUID uuid = null; - try { - uuid = NameAPI.getUUID(username); - } catch (NoClassDefFoundError ncde) { } - - if (uuid == null) { - Player bukkitPlayer = Bukkit.getPlayerExact(username); - if (bukkitPlayer != null) { - uuid = bukkitPlayer.getUniqueId(); - } - } - if (uuid == null) { - BanStick.getPlugin().warning( - "Unable to find UUID for player {0} while importing IPCheck", username); - continue; - } - BSPlayer player = BSPlayer.byUUID(uuid); - - if (player == null) { - player = BSPlayer.create(uuid, username); - } - - if (player == null) { - BanStick.getPlugin().warning( - "Failure making player with UUID {0} and name {1}", uuid, username); - } - - boolean isBanned = rs.getBoolean(4); - if (isBanned) { - BSBan ban = null; - if (banMessage != null && banMessage.length() > 0) { - ban = BSBan.create(banMessage, null, true); - } else { - ban = BSBan.create("Banned for Multiaccounting", null, true); - } - - player.setBan(ban); - } - - boolean isJoinExempt = rs.getBoolean(5); - if (isJoinExempt) { - player.setSharedPardonTime(new Date()); - } - boolean isProtected = rs.getBoolean(7); - if (isProtected) { - player.setIPPardonTime(new Date()); - player.setSharedPardonTime(new Date()); - } + long offset = 0; + int limit = 100; + boolean cont = true; + while (cont) { + getIPs.clearParameters(); + getIPs.setLong(1, offset); + getIPs.setInt(2, limit); + try (ResultSet rs = getIPs.executeQuery();) { + int thisCycle = 0; + while (rs.next()) { + // ignore fields not used in import. + String username = rs.getString(1); + //Timestamp firstJoin = rs.getTimestamp(2); + String banMessage = rs.getString(3); + //boolean isWarnExempt = rs.getBoolean(6); - thisCycle++; - } - if (thisCycle == 0) { // all done! - cont = false; - } else { - offset += limit; - } - } - Thread.sleep(0L); - } - } catch (SQLException | InterruptedException se) { - BanStick.getPlugin().severe("Failed to import Players from IP-Check, potentially incomplete import: ", se); - } - } - - private void doImportSessions() { - try (Connection connection = internalDatabase.getConnection(); - PreparedStatement getIPs = connection.prepareStatement( - "SELECT * FROM ipcheck_log ORDER BY `timestamp` LIMIT ?, ?");) { + UUID uuid = null; + try { + uuid = NameAPI.getUUID(username); + } catch (NoClassDefFoundError ncde) { + } + + if (uuid == null) { + Player bukkitPlayer = Bukkit.getPlayerExact(username); + if (bukkitPlayer != null) { + uuid = bukkitPlayer.getUniqueId(); + } + } + if (uuid == null) { + BanStick.getPlugin().warning( + "Unable to find UUID for player {0} while importing IPCheck", username); + continue; + } + BSPlayer player = BSPlayer.byUUID(uuid); + + if (player == null) { + player = BSPlayer.create(uuid, username); + } + + if (player == null) { + BanStick.getPlugin().warning( + "Failure making player with UUID {0} and name {1}", uuid, username); + } + + boolean isBanned = rs.getBoolean(4); + if (isBanned) { + BSBan ban = null; + if (banMessage != null && banMessage.length() > 0) { + ban = BSBan.create(banMessage, null, true); + } else { + ban = BSBan.create("Banned for Multiaccounting", null, true); + } + + player.setBan(ban); + } + + boolean isJoinExempt = rs.getBoolean(5); + if (isJoinExempt) { + player.setSharedPardonTime(new Date()); + } + boolean isProtected = rs.getBoolean(7); + if (isProtected) { + player.setIPPardonTime(new Date()); + player.setSharedPardonTime(new Date()); + } + + thisCycle++; + } + if (thisCycle == 0) { // all done! + cont = false; + } else { + offset += limit; + } + } + Thread.sleep(0L); + } + } catch (SQLException | InterruptedException se) { + BanStick.getPlugin().severe("Failed to import Players from IP-Check, potentially incomplete import: ", se); + } + } + + private void doImportSessions() { + try (Connection connection = internalDatabase.getConnection(); + PreparedStatement getIPs = connection.prepareStatement( + "SELECT * FROM ipcheck_log ORDER BY `timestamp` LIMIT ?, ?");) { /* * CREATE TABLE `ipcheck_log` ( `ip` varchar(15) NOT NULL, `username` varchar(255) NOT NULL, `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`ip`,`username`) - */ - long offset = 0; - int limit = 100; - boolean cont = true; - while (cont) { - getIPs.clearParameters(); - getIPs.setLong(1, offset); - getIPs.setInt(2, limit); - try (ResultSet rs = getIPs.executeQuery();) { - int thisCycle = 0; - while (rs.next()) { - String ip = rs.getString(1); - String username = rs.getString(2); - Timestamp sessionStart = rs.getTimestamp(3); - - try { - UUID uuid = null; - try { - uuid = NameAPI.getUUID(username); - } catch (NoClassDefFoundError ncde) { } - - if (uuid == null) { - Player bukkitPlayer = Bukkit.getPlayerExact(username); - if (bukkitPlayer != null) { - uuid = bukkitPlayer.getUniqueId(); - } - } - if (uuid == null) { - BanStick.getPlugin().warning( - "Unable to find UUID for player {0} while importing IPCheck", username); - continue; - } - BSPlayer player = BSPlayer.byUUID(uuid); - IPAddressString address = new IPAddressString(ip); - IPAddress exactAddress = address.toAddress(); - BSIP exactIP = BSIP.byIPAddress(exactAddress); - if (player == null || exactIP == null) { - BanStick.getPlugin().warning( - "Failed to find Player {0} or IP {1} from import, unable to import session time {2}", - username, ip, sessionStart); - } else { - player.startSession(exactIP, sessionStart); - player.endSession(new Date(sessionStart.getTime() + 1000L)); // default of 1 second. - } - } catch (Exception e) { - BanStick.getPlugin().warning("Found invalid data username {0} ip {1} in IP-Check database", - username, ip); - } - thisCycle++; - } - if (thisCycle == 0) { // all done! - cont = false; - } else { - offset += limit; - } - } - Thread.sleep(0L); - } - } catch (SQLException | InterruptedException se) { - BanStick.getPlugin().severe("Failed to import IPs from IP-Check, potentially incomplete import: ", se); - } - } + */ + long offset = 0; + int limit = 100; + boolean cont = true; + while (cont) { + getIPs.clearParameters(); + getIPs.setLong(1, offset); + getIPs.setInt(2, limit); + try (ResultSet rs = getIPs.executeQuery();) { + int thisCycle = 0; + while (rs.next()) { + String ip = rs.getString(1); + String username = rs.getString(2); + Timestamp sessionStart = rs.getTimestamp(3); + + try { + UUID uuid = null; + try { + uuid = NameAPI.getUUID(username); + } catch (NoClassDefFoundError ncde) { + } + + if (uuid == null) { + Player bukkitPlayer = Bukkit.getPlayerExact(username); + if (bukkitPlayer != null) { + uuid = bukkitPlayer.getUniqueId(); + } + } + if (uuid == null) { + BanStick.getPlugin().warning( + "Unable to find UUID for player {0} while importing IPCheck", username); + continue; + } + BSPlayer player = BSPlayer.byUUID(uuid); + IPAddressString address = new IPAddressString(ip); + IPAddress exactAddress = address.toAddress(); + BSIP exactIP = BSIP.byIPAddress(exactAddress); + if (player == null || exactIP == null) { + BanStick.getPlugin().warning( + "Failed to find Player {0} or IP {1} from import, unable to import session time {2}", + username, ip, sessionStart); + } else { + player.startSession(exactIP, sessionStart); + player.endSession(new Date(sessionStart.getTime() + 1000L)); // default of 1 second. + } + } catch (Exception e) { + BanStick.getPlugin().warning("Found invalid data username {0} ip {1} in IP-Check database", + username, ip); + } + thisCycle++; + } + if (thisCycle == 0) { // all done! + cont = false; + } else { + offset += limit; + } + } + Thread.sleep(0L); + } + } catch (SQLException | InterruptedException se) { + BanStick.getPlugin().severe("Failed to import IPs from IP-Check, potentially incomplete import: ", se); + } + } } diff --git a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/proxy/Cloud9ProxyLoader.java b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/proxy/Cloud9ProxyLoader.java index 3b6bed17f..63bfea9c7 100644 --- a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/proxy/Cloud9ProxyLoader.java +++ b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/proxy/Cloud9ProxyLoader.java @@ -24,173 +24,173 @@ import org.bukkit.configuration.ConfigurationSection; /** * Implementation of ProxyLoader, for Cloud9 data. Had been able to find some published * lists that were easy to implement at the time, so this captures that effort. - * + * * @author ProgrammerDan */ public final class Cloud9ProxyLoader extends ProxyLoader { - private String loadUrl; - private float proxyScore; - private boolean autoBan; - private long banLength; - private String banMessage; - - public Cloud9ProxyLoader(ConfigurationSection config) { - super(config); - } - - private BigInteger addressToLong(IPAddress convert) { - BigInteger output = BigInteger.ZERO; - int offset = 0; - String[] segments = convert.getSegmentStrings(); - for (int a = segments.length - 1; a >= 0; a --) { - BigInteger inject = BigInteger.valueOf(Long.valueOf(segments[a])); - output = output.add(inject.shiftLeft(offset)); - offset += convert.getBitsPerSegment(); - } - return output; - } + private String loadUrl; + private float proxyScore; + private boolean autoBan; + private long banLength; + private String banMessage; - @Override - public void run() { - try { - URL connection = new URL(this.loadUrl); - InputStream readIn = connection.openStream(); - BufferedReader in = new BufferedReader(new InputStreamReader(readIn)); - String line = in.readLine(); - int errors = 0; - long lines = 0; - while (line != null) { - lines ++; - if (lines % 50 == 0) { - BanStick.getPlugin().info("Checked {0} entries from Cloud9 so far", lines); - } - if (errors > 10) { - break; - } - try { - ArrayList cidrFromRange = new ArrayList<>(); - String[] fields = line.split(","); - IPAddressString lowbound = new IPAddressString(fields[0]); - IPAddressString highbound = new IPAddressString(fields[1]); - IPAddress lowboundAddr = lowbound.getAddress(); - IPAddress highboundAddr = highbound.getAddress(); - BanStick.getPlugin().debug("Starting with range: {0} vs {1}", lowboundAddr, highboundAddr); - BigInteger end = addressToLong(highboundAddr); - BigInteger start = addressToLong(lowboundAddr); - - // Borrowed wholesale from http://stackoverflow.com/a/5032908 - // Little hard to explain, but basically, finds the minimal set of CIDRs that fit the range, - // using bit math. - // TODO: Refactor into a utility. - while (end.compareTo(start) >= 0) { - try { - byte[] arr = start.toByteArray(); - if (arr[0] == 0) { - arr = Arrays.copyOfRange(arr, 1, arr.length); - } - lowboundAddr = IPAddress.from(arr); - } catch (IllegalArgumentException iae) { - BanStick.getPlugin().debug("Failed on byte array {0}", start.toByteArray()); - } + public Cloud9ProxyLoader(ConfigurationSection config) { + super(config); + } - int mask = lowboundAddr.isIPv4() ? 32 : 128; - while (mask > 0) { - IPAddress maskAddr = lowboundAddr.toSubnet(mask - 1); - if (maskAddr.getLower().compareTo(lowboundAddr) != 0) { - break; - } - mask --; - } - int x = BigIntegerMath.log2(end.subtract(start).add(BigInteger.ONE), RoundingMode.FLOOR); - int maxd = (lowboundAddr.isIPv4() ? 32 : 128) - x; - if (mask < maxd) { - mask = maxd; - } - - BanStick.getPlugin().debug(" Found sub-CIDR: {0}", - lowboundAddr.toSubnet(mask).toCanonicalString()); - cidrFromRange.add(lowboundAddr.toSubnet(mask)); - - BigInteger migrate = BigInteger.valueOf(2).pow((lowboundAddr.isIPv4() ? 32 : 128) - mask); - start = start.add(migrate); - } + private BigInteger addressToLong(IPAddress convert) { + BigInteger output = BigInteger.ZERO; + int offset = 0; + String[] segments = convert.getSegmentStrings(); + for (int a = segments.length - 1; a >= 0; a--) { + BigInteger inject = BigInteger.valueOf(Long.valueOf(segments[a])); + output = output.add(inject.shiftLeft(offset)); + offset += convert.getBitsPerSegment(); + } + return output; + } - String registeredAs = fields[2]; - String domain = (fields.length > 3) ? fields[3] : null; + @Override + public void run() { + try { + URL connection = new URL(this.loadUrl); + InputStream readIn = connection.openStream(); + BufferedReader in = new BufferedReader(new InputStreamReader(readIn)); + String line = in.readLine(); + int errors = 0; + long lines = 0; + while (line != null) { + lines++; + if (lines % 50 == 0) { + BanStick.getPlugin().info("Checked {0} entries from Cloud9 so far", lines); + } + if (errors > 10) { + break; + } + try { + ArrayList cidrFromRange = new ArrayList<>(); + String[] fields = line.split(","); + IPAddressString lowbound = new IPAddressString(fields[0]); + IPAddressString highbound = new IPAddressString(fields[1]); + IPAddress lowboundAddr = lowbound.getAddress(); + IPAddress highboundAddr = highbound.getAddress(); + BanStick.getPlugin().debug("Starting with range: {0} vs {1}", lowboundAddr, highboundAddr); + BigInteger end = addressToLong(highboundAddr); + BigInteger start = addressToLong(lowboundAddr); - for (IPAddress address : cidrFromRange) { - BSIP found = BSIP.byCIDR(address.getLower().toString(), address.getNetworkPrefixLength()); - if (found == null) { - found = BSIP.create(address.getLower(), address.getNetworkPrefixLength()); - } - - BSIPData data = BSIPData.byExactIP(found); - if (data == null) { - data = BSIPData.create(found, null, null, null, null, null, null, null, - domain, null, registeredAs, null, proxyScore, "Cloud9 Proxy Loader", null); - } - - if (autoBan) { - boolean wasmatch = false; - - List ban = BSBan.byProxy(data, true); - if (!(ban == null || ban.isEmpty())) { - // look for match; if unexpired, extend. - for (int i = ban.size() - 1 ; i >= 0; i--) { - BSBan pickOne = ban.get(i); - if (pickOne.isAdminBan()) { - continue; // skip admin entered bans. - } - if (pickOne.getBanEndTime() != null && pickOne.getBanEndTime().after(new Date())) { - if (this.banLength < 0) { // endless - pickOne.clearBanEndTime(); - } else { - pickOne.setBanEndTime(new Date(System.currentTimeMillis() - + this.banLength)); - } - wasmatch = true; - break; - } - } - } - if (!wasmatch) { - BSBan.create(data, this.banMessage, - this.banLength < 0 ? null : new Date(System.currentTimeMillis() - + this.banLength), false); - } - } - } - - } catch (Exception e) { - BanStick.getPlugin().debug("Failed to load: {0} due to {1}", line, e.getMessage()); - BanStick.getPlugin().warning(" Failure:", e); - e.printStackTrace(); - errors ++; - } - line = in.readLine(); - } - if (errors > 10) { - BanStick.getPlugin().warning("Cancelled cloud9 load due to too many errors."); - } - } catch (IOException e) { - BanStick.getPlugin().debug("Failed reading from Cloud9-style list: " + loadUrl); - } - } + // Borrowed wholesale from http://stackoverflow.com/a/5032908 + // Little hard to explain, but basically, finds the minimal set of CIDRs that fit the range, + // using bit math. + // TODO: Refactor into a utility. + while (end.compareTo(start) >= 0) { + try { + byte[] arr = start.toByteArray(); + if (arr[0] == 0) { + arr = Arrays.copyOfRange(arr, 1, arr.length); + } + lowboundAddr = IPAddress.from(arr); + } catch (IllegalArgumentException iae) { + BanStick.getPlugin().debug("Failed on byte array {0}", start.toByteArray()); + } - @Override - public void setup(ConfigurationSection config) { - this.loadUrl = config.getString("url"); - this.proxyScore = (float) config.getDouble("defaultScore", 3.0d); - this.autoBan = config.isConfigurationSection("ban"); - if (this.autoBan) { - this.banLength = config.getLong("ban.length", -1L); - this.banMessage = config.getString("ban.message", null); - } - } + int mask = lowboundAddr.isIPv4() ? 32 : 128; + while (mask > 0) { + IPAddress maskAddr = lowboundAddr.toSubnet(mask - 1); + if (maskAddr.getLower().compareTo(lowboundAddr) != 0) { + break; + } + mask--; + } + int x = BigIntegerMath.log2(end.subtract(start).add(BigInteger.ONE), RoundingMode.FLOOR); + int maxd = (lowboundAddr.isIPv4() ? 32 : 128) - x; + if (mask < maxd) { + mask = maxd; + } - @Override - public String name() { - return "cloud9"; - } + BanStick.getPlugin().debug(" Found sub-CIDR: {0}", + lowboundAddr.toSubnet(mask).toCanonicalString()); + cidrFromRange.add(lowboundAddr.toSubnet(mask)); + + BigInteger migrate = BigInteger.valueOf(2).pow((lowboundAddr.isIPv4() ? 32 : 128) - mask); + start = start.add(migrate); + } + + String registeredAs = fields[2]; + String domain = (fields.length > 3) ? fields[3] : null; + + for (IPAddress address : cidrFromRange) { + BSIP found = BSIP.byCIDR(address.getLower().toString(), address.getNetworkPrefixLength()); + if (found == null) { + found = BSIP.create(address.getLower(), address.getNetworkPrefixLength()); + } + + BSIPData data = BSIPData.byExactIP(found); + if (data == null) { + data = BSIPData.create(found, null, null, null, null, null, null, null, + domain, null, registeredAs, null, proxyScore, "Cloud9 Proxy Loader", null); + } + + if (autoBan) { + boolean wasmatch = false; + + List ban = BSBan.byProxy(data, true); + if (!(ban == null || ban.isEmpty())) { + // look for match; if unexpired, extend. + for (int i = ban.size() - 1; i >= 0; i--) { + BSBan pickOne = ban.get(i); + if (pickOne.isAdminBan()) { + continue; // skip admin entered bans. + } + if (pickOne.getBanEndTime() != null && pickOne.getBanEndTime().after(new Date())) { + if (this.banLength < 0) { // endless + pickOne.clearBanEndTime(); + } else { + pickOne.setBanEndTime(new Date(System.currentTimeMillis() + + this.banLength)); + } + wasmatch = true; + break; + } + } + } + if (!wasmatch) { + BSBan.create(data, this.banMessage, + this.banLength < 0 ? null : new Date(System.currentTimeMillis() + + this.banLength), false); + } + } + } + + } catch (Exception e) { + BanStick.getPlugin().debug("Failed to load: {0} due to {1}", line, e.getMessage()); + BanStick.getPlugin().warning(" Failure:", e); + e.printStackTrace(); + errors++; + } + line = in.readLine(); + } + if (errors > 10) { + BanStick.getPlugin().warning("Cancelled cloud9 load due to too many errors."); + } + } catch (IOException e) { + BanStick.getPlugin().debug("Failed reading from Cloud9-style list: " + loadUrl); + } + } + + @Override + public void setup(ConfigurationSection config) { + this.loadUrl = config.getString("url"); + this.proxyScore = (float) config.getDouble("defaultScore", 3.0d); + this.autoBan = config.isConfigurationSection("ban"); + if (this.autoBan) { + this.banLength = config.getLong("ban.length", -1L); + this.banMessage = config.getString("ban.message", null); + } + } + + @Override + public String name() { + return "cloud9"; + } } diff --git a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/scraper/ScrapeFreeProxyList.java b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/scraper/ScrapeFreeProxyList.java index 6f821b2c2..84fdbd829 100644 --- a/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/scraper/ScrapeFreeProxyList.java +++ b/plugins/banstick-paper/src/main/java/com/programmerdan/minecraft/banstick/scraper/ScrapeFreeProxyList.java @@ -20,130 +20,130 @@ import org.jsoup.select.Elements; /** * There are a number of free proxy lists we'd found. Some may no longer * be valid. This scrapes those. - * - * @author ProgrammerDan * + * @author ProgrammerDan */ public class ScrapeFreeProxyList extends ScraperWorker { - private String banMessage; - private long banLength; - - private String[] urls = new String[] { - "https://free-proxy-list.net", - "http://www.sslproxies.org/", - "http://www.us-proxy.org/", - "http://free-proxy-list.net/uk-proxy.html", - "http://www.socks-proxy.net/", - "http://free-proxy-list.net/anonymous-proxy.html" - }; - - public ScrapeFreeProxyList(ConfigurationSection config) { - super(config); - } + private String banMessage; + private long banLength; - @Override - public void setup(ConfigurationSection config) { - banMessage = config.getString("ban.message"); - banLength = config.getLong("ban.length"); - } + private String[] urls = new String[]{ + "https://free-proxy-list.net", + "http://www.sslproxies.org/", + "http://www.us-proxy.org/", + "http://free-proxy-list.net/uk-proxy.html", + "http://www.socks-proxy.net/", + "http://free-proxy-list.net/anonymous-proxy.html" + }; - @Override - public String name() { - return "freeproxylist"; - } + public ScrapeFreeProxyList(ConfigurationSection config) { + super(config); + } - @Override - public void scrape() { - for (String url : urls) { - scrapeOne(url); - } - } - - /** - * Does the work of "scraping" a single passed url. - * @param url - */ - public void scrapeOne(String url) { - try { - BanStick.getPlugin().debug("Scraping {0}", url); - Document doc = Jsoup.connect(url).userAgent( - "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0").get(); - Elements iptable = doc.select("table#proxylisttable"); - - Elements body = iptable.select("tbody"); - Elements trs = body.select("tr"); - BanStick.getPlugin().debug("Found {0} proxy IPs to scrape", trs.size()); - for (Element tr : trs) { - Elements tds = tr.select("td"); - String ip = null; - try { - ip = tds.first().text(); - } catch (Exception e) { - continue; - } - String country = null; - try { - country = tds.get(3).text(); - } catch (Exception e) { - // intentionally ignore errors. - } - String port = null; - try { - port = tds.get(1).text(); - } catch (Exception e) { - // intentionally ignore errors. - } - try { - IPAddressString addressS = new IPAddressString(ip); - addressS.validate(); - IPAddress address = addressS.toAddress(); - BSIP found = BSIP.byIPAddress(address); - if (found == null) { - found = BSIP.create(address); - } - BSIPData dataMatch = BSIPData.byExactIP(found); - if (dataMatch == null) { - dataMatch = BSIPData.create(found, null, country, null, null, - null, null, null, null, null, null, null, - 3.0f, name() + " " + url, "Anon Proxy on Port: " + port); - } - // autoban. - if (banLength > -1) { - boolean wasmatch = false; + @Override + public void setup(ConfigurationSection config) { + banMessage = config.getString("ban.message"); + banLength = config.getLong("ban.length"); + } - List ban = BSBan.byProxy(dataMatch, true); - if (!(ban == null || ban.isEmpty())) { - // look for match; if unexpired, extend. - for (int i = ban.size() - 1 ; i >= 0; i--) { - BSBan pickOne = ban.get(i); - if (pickOne.isAdminBan()) { - continue; // skip admin entered bans. - } - if (pickOne.getBanEndTime() != null && pickOne.getBanEndTime().after(new Date())) { - if (this.banLength < 0) { - pickOne.clearBanEndTime(); - } else { - pickOne.setBanEndTime(new Date(System.currentTimeMillis() + this.banLength)); - } - wasmatch = true; - break; - } - } - } - if (!wasmatch) { - BSBan.create(dataMatch, this.banMessage, this.banLength < 0 ? null - : new Date(System.currentTimeMillis() + this.banLength), false); - } - } - } catch (IPAddressStringException iase) { - continue; - } - } - } catch (IOException ioe) { - BanStick.getPlugin().warning("Failure during scrape of " + url, ioe); - this.registerError(); - } - } + @Override + public String name() { + return "freeproxylist"; + } + + @Override + public void scrape() { + for (String url : urls) { + scrapeOne(url); + } + } + + /** + * Does the work of "scraping" a single passed url. + * + * @param url + */ + public void scrapeOne(String url) { + try { + BanStick.getPlugin().debug("Scraping {0}", url); + Document doc = Jsoup.connect(url).userAgent( + "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0").get(); + Elements iptable = doc.select("table#proxylisttable"); + + Elements body = iptable.select("tbody"); + Elements trs = body.select("tr"); + BanStick.getPlugin().debug("Found {0} proxy IPs to scrape", trs.size()); + for (Element tr : trs) { + Elements tds = tr.select("td"); + String ip = null; + try { + ip = tds.first().text(); + } catch (Exception e) { + continue; + } + String country = null; + try { + country = tds.get(3).text(); + } catch (Exception e) { + // intentionally ignore errors. + } + String port = null; + try { + port = tds.get(1).text(); + } catch (Exception e) { + // intentionally ignore errors. + } + try { + IPAddressString addressS = new IPAddressString(ip); + addressS.validate(); + IPAddress address = addressS.toAddress(); + BSIP found = BSIP.byIPAddress(address); + if (found == null) { + found = BSIP.create(address); + } + BSIPData dataMatch = BSIPData.byExactIP(found); + if (dataMatch == null) { + dataMatch = BSIPData.create(found, null, country, null, null, + null, null, null, null, null, null, null, + 3.0f, name() + " " + url, "Anon Proxy on Port: " + port); + } + // autoban. + if (banLength > -1) { + boolean wasmatch = false; + + List ban = BSBan.byProxy(dataMatch, true); + if (!(ban == null || ban.isEmpty())) { + // look for match; if unexpired, extend. + for (int i = ban.size() - 1; i >= 0; i--) { + BSBan pickOne = ban.get(i); + if (pickOne.isAdminBan()) { + continue; // skip admin entered bans. + } + if (pickOne.getBanEndTime() != null && pickOne.getBanEndTime().after(new Date())) { + if (this.banLength < 0) { + pickOne.clearBanEndTime(); + } else { + pickOne.setBanEndTime(new Date(System.currentTimeMillis() + this.banLength)); + } + wasmatch = true; + break; + } + } + } + if (!wasmatch) { + BSBan.create(dataMatch, this.banMessage, this.banLength < 0 ? null + : new Date(System.currentTimeMillis() + this.banLength), false); + } + } + } catch (IPAddressStringException iase) { + continue; + } + } + } catch (IOException ioe) { + BanStick.getPlugin().warning("Failure during scrape of " + url, ioe); + this.registerError(); + } + } } diff --git a/plugins/banstick-paper/src/main/resources/plugin.yml b/plugins/banstick-paper/src/main/resources/plugin.yml index dd7eebe43..b21ad93b0 100644 --- a/plugins/banstick-paper/src/main/resources/plugin.yml +++ b/plugins/banstick-paper/src/main/resources/plugin.yml @@ -4,12 +4,12 @@ main: com.programmerdan.minecraft.banstick.BanStick author: ProgrammerDan description: A plugin focused on better IP / VPN / CIDR tracking and justice delivery api-version: 1.20 -depend: [CivModCore] -softdepend: [IP-Check, NameLayer] +depend: [ CivModCore ] +softdepend: [ IP-Check, NameLayer ] commands: banstick: description: Swing that banstick, send nerds flying. - aliases: [bst, stickofdoom, banhammer] + aliases: [ bst, stickofdoom, banhammer ] permission: banstick.ban usage: | / [ip] [banend: mm/dd/yyyy [hh:mm:ss]] [message] @@ -19,7 +19,7 @@ commands: For all, optionally include a date and time of unban using the format indicated, and optionally a message to display to player on ban doubletap: description: Handle unpardoning shares between two players; optionally ban one or both - aliases: [bdt, doublebladedaxe] + aliases: [ bdt, doublebladedaxe ] permission: banstick.ban usage: | / [+][ip] [banend: mm/dd/yyyy [hh:mm:ss]] [message] @@ -39,7 +39,7 @@ commands: / [ip]/[CIDR] [number of sessions] dowsingrod: description: Investigate breakdown of networks by up to three attributes - aliases: [bsdr, diviningrod] + aliases: [ bsdr, diviningrod ] permission: banstick.lovetap usage: | / [CONTINENT|COUNTRY|REGION|STATE|CITY|POSTAL|ZIP|DOMAIN|PROVIDER|REGISTEREDAS|CONNECTION] pagenum perpage @@ -49,7 +49,7 @@ commands: Use with care, can be Database intensive. drilldown: description: Investigate the IPs and IP Networks based on specific values (like, find all networks in China) - aliases: [bsdd, deepdive] + aliases: [ bsdd, deepdive ] permission: banstick.lovetap useage: | / SUMMARY|PLAYER|IP|IPDATA|IPDATASUMMARY [[CONTINENT|COUNTRY|REGION|STATE|CITY|POSTAL|ZIP|DOMAIN|PROVIDER|REGISTEREDAS|CONNECTION] "value"]x3 @@ -61,7 +61,7 @@ commands: IPDATASUMMARY shows all IPData records, all IPs in them, and all Players that use them. It will be slow probably. forgive: description: Remove specific IP / CIDR bans, unban specific individuals, or grant exemptions/ignores for a user - aliases: [bstf, showmercy] + aliases: [ bstf, showmercy ] permission: banstick.forgive usage: | / [ip] @@ -79,7 +79,7 @@ commands: Immediately pardons all shares between these two players. If ALL also expires all bans for all shares between these two players. takeitback: description: Remove exemptions/ignores with this command. - aliases: [unforgive, buryhim] + aliases: [ unforgive, buryhim ] permission: banstick.forgive usage: | / [name/uuid] [IP] [PROXY] [SHARED] diff --git a/plugins/bastion-paper/README.md b/plugins/bastion-paper/README.md index 46b1e7f39..5cb2379d9 100644 --- a/plugins/bastion-paper/README.md +++ b/plugins/bastion-paper/README.md @@ -1,71 +1,84 @@ Bastion ======= -A minecraft mod designed for use with [/r/civcraft](https://old.reddit.com/r/Civcraft/) and continually improved by [/r/devoted](https://old.reddit.com/r/devoted/). Currently in use on [/r/civclassics](https://old.reddit.com/r/Civclassics/) at mc.civclassic.com (1.16.5) +A minecraft mod designed for use with [/r/civcraft](https://old.reddit.com/r/Civcraft/) and continually improved +by [/r/devoted](https://old.reddit.com/r/devoted/). Currently in use +on [/r/civclassics](https://old.reddit.com/r/Civclassics/) at mc.civclassic.com (1.16.5) For a more extensive and updated list of features see https://github.com/CivClassic/Bastion/wiki Features: - * Destroys blocks placed in a cylinder or cuboid of configurable radius starting at or just above a reinforced target block (Bastion block) at the price of a configurable amount of reinforcement if the placer is not a member of the reinforcing group - * Prevents dispensers dispensing water, lava, and flint and steel if the owner of there reinforcement is not allowed to place blocks - * Prevents pistons pushing into the Bastion field (Area where block placement is restricted) if the owner of the reinforcement would not be allowed to place there. - * Prevents teleportation through the the Bastion field by non-members (Note this is highly experimental and may be better disabled) - * Multiple Bastion types with unique properties + +* Destroys blocks placed in a cylinder or cuboid of configurable radius starting at or just above a reinforced target + block (Bastion block) at the price of a configurable amount of reinforcement if the placer is not a member of the + reinforcing group +* Prevents dispensers dispensing water, lava, and flint and steel if the owner of there reinforcement is not allowed to + place blocks +* Prevents pistons pushing into the Bastion field (Area where block placement is restricted) if the owner of the + reinforcement would not be allowed to place there. +* Prevents teleportation through the the Bastion field by non-members (Note this is highly experimental and may be + better disabled) +* Multiple Bastion types with unique properties Modes: -* INFO - * When clicking a block inside a Bastion field tells you if you have access - * When clicking a bastion block gives some basic information on it -* DELETE - * When a Bastion block is clicked remove the bastion field while maintaing the reinforcement -* NORMAl - * Defualt clicking on blocks does nothing -* BASTION - * Any target block reinforced will become a Bastion Block -* CREATE - * Any reinforced target block clicked will becomea Bastion if you have access +* INFO + * When clicking a block inside a Bastion field tells you if you have access + * When clicking a bastion block gives some basic information on it +* DELETE + * When a Bastion block is clicked remove the bastion field while maintaing the reinforcement +* NORMAl + * Defualt clicking on blocks does nothing +* BASTION + * Any target block reinforced will become a Bastion Block +* CREATE + * Any reinforced target block clicked will becomea Bastion if you have access Commands: - * /bsi Puts the player into info mode - * /bsd Puts the player into delete mode - * /bso Puts the player into normal mode - * /bsc puts the player into create mode - * /bsb puts the player into bastion mode + +* /bsi Puts the player into info mode +* /bsd Puts the player into delete mode +* /bso Puts the player into normal mode +* /bsc puts the player into create mode +* /bsb puts the player into bastion mode Maturity: - * When a bastion is first created it starts much weaker - * While it matures any blocks placed within the field do much more damage - * Until mature ender pearls are not blocked. - * INFO mode gives some information on the time till maturity + +* When a bastion is first created it starts much weaker +* While it matures any blocks placed within the field do much more damage +* Until mature ender pearls are not blocked. +* INFO mode gives some information on the time till maturity Use: - * Place the "target block" and reinforce it - * Enter /bsb and click the block - * A bastion block has been created +* Place the "target block" and reinforce it +* Enter /bsb and click the block +* A bastion block has been created To install: - * Add Bastion.jar to the server /plugins directory - * Confirm that Citadel is also installed - * Launch the server or copy the default configuration file - * Create a Mysql database and account for the plugin - * Specify in the configuration file - * Relaunch the server + +* Add Bastion.jar to the server /plugins directory +* Confirm that Citadel is also installed +* Launch the server or copy the default configuration file +* Create a Mysql database and account for the plugin +* Specify in the configuration file +* Relaunch the server Permissions: - * Bastion.normal - * Ability to use basic set of commands - * Bastion.admin - * Gives access to /bsm to mature a bastion instantly - * sets Bastion.bypass to true - * Bastion.bypass - * Bastions should not effect you (not well tested) - * Bastion.dev - * /bsi gives extra info + +* Bastion.normal +* Ability to use basic set of commands +* Bastion.admin + * Gives access to /bsm to mature a bastion instantly + * sets Bastion.bypass to true +* Bastion.bypass + * Bastions should not effect you (not well tested) +* Bastion.dev + * /bsi gives extra info To compile: - * Download Paper - * Download Citadel - * Download Namelayer - * Download CivModCore - * Link to Paper, Citadel, Namelayer, and CivModCore then compile + +* Download Paper +* Download Citadel +* Download Namelayer +* Download CivModCore +* Link to Paper, Citadel, Namelayer, and CivModCore then compile diff --git a/plugins/bastion-paper/build.gradle.kts b/plugins/bastion-paper/build.gradle.kts index f28eaaff4..fc004ad99 100644 --- a/plugins/bastion-paper/build.gradle.kts +++ b/plugins/bastion-paper/build.gradle.kts @@ -1,15 +1,15 @@ plugins { - id("io.papermc.paperweight.userdev") + id("io.papermc.paperweight.userdev") } version = "3.0.1" dependencies { - paperweight { - paperDevBundle("1.20.4-R0.1-SNAPSHOT") - } + paperweight { + paperDevBundle("1.20.4-R0.1-SNAPSHOT") + } - compileOnly(project(":plugins:civmodcore-paper")) - compileOnly(project(":plugins:namelayer-paper")) - compileOnly(project(":plugins:citadel-paper")) + compileOnly(project(":plugins:civmodcore-paper")) + compileOnly(project(":plugins:namelayer-paper")) + compileOnly(project(":plugins:citadel-paper")) } diff --git a/plugins/bastion-paper/src/main/java/isaac/bastion/Bastion.java b/plugins/bastion-paper/src/main/java/isaac/bastion/Bastion.java index 07314e60f..a121c8288 100644 --- a/plugins/bastion-paper/src/main/java/isaac/bastion/Bastion.java +++ b/plugins/bastion-paper/src/main/java/isaac/bastion/Bastion.java @@ -25,141 +25,144 @@ import vg.civcraft.mc.namelayer.GroupManager.PlayerType; import vg.civcraft.mc.namelayer.permission.PermissionType; public final class Bastion extends ACivMod { - private static Bastion plugin; - private static BastionBlockStorage blockStorage; - private static BastionBlockManager blockManager; - private static BastionGroupStorage groupStorage; - private static BastionSettingManager settingManager; - private static CommonSettings commonSettings; - @Override - public void onEnable() { - super.onEnable(); - plugin = this; - saveDefaultConfig(); - reloadConfig(); - BastionType.loadBastionTypes(getConfig().getConfigurationSection("bastions")); - commonSettings = CommonSettings.load(getConfig().getConfigurationSection("commonSettings")); - setupDatabase(); - registerNameLayerPermissions(); - blockManager = new BastionBlockManager(); - settingManager = new BastionSettingManager(); - - if(!this.isEnabled()) //check that the plugin was not disabled in setting up any of the static variables - return; - - BastionType.startRegenAndErosionTasks(); - registerListeners(); - setupCommands(); - } - - @Override - public void onDisable() { - blockStorage.close(); - groupStorage.close(); - } - - public String getPluginName() { - return "Bastion"; - } - - private void registerListeners() { - getLogger().log(Level.INFO, "Registering Listeners"); - getServer().getPluginManager().registerEvents(new BastionDamageListener(), this); - getServer().getPluginManager().registerEvents(new BastionInteractListener(), this); - getServer().getPluginManager().registerEvents(new ElytraListener(), this); - getServer().getPluginManager().registerEvents(new BastionBreakListener(blockStorage, blockManager), this); - getServer().getPluginManager().registerEvents(new NameLayerListener(blockStorage), this); - getServer().getPluginManager().registerEvents(new CitadelListener(), this); - getServer().getPluginManager().registerEvents(new ModeListener(), this); - } + private static Bastion plugin; + private static BastionBlockStorage blockStorage; + private static BastionBlockManager blockManager; + private static BastionGroupStorage groupStorage; + private static BastionSettingManager settingManager; + private static CommonSettings commonSettings; - private void setupDatabase() { - ConfigurationSection config = getConfig().getConfigurationSection("mysql"); - String host = config.getString("host"); - int port = config.getInt("port"); - String user = config.getString("user"); - String pass = config.getString("password"); - String dbname = config.getString("database"); - int poolsize = config.getInt("poolsize"); - long connectionTimeout = config.getLong("connectionTimeout"); - long idleTimeout = config.getLong("idleTimeout"); - long maxLifetime = config.getLong("maxLifetime"); - ManagedDatasource db = null; - try { - db = ManagedDatasource.construct(this, new DatabaseCredentials(user, pass, host, port, "mysql", dbname, poolsize, connectionTimeout, idleTimeout, maxLifetime)); - db.getConnection().close(); - } catch(Exception e) { - warning("Could not connect to database, stopping bastion", e); - getServer().getPluginManager().disablePlugin(this); - return; - } + @Override + public void onEnable() { + super.onEnable(); + plugin = this; + saveDefaultConfig(); + reloadConfig(); + BastionType.loadBastionTypes(getConfig().getConfigurationSection("bastions")); + commonSettings = CommonSettings.load(getConfig().getConfigurationSection("commonSettings")); + setupDatabase(); + registerNameLayerPermissions(); + blockManager = new BastionBlockManager(); + settingManager = new BastionSettingManager(); - Database.registerMigrations(db); - if(!db.updateDatabase()) { - warning("Failed to update database, stopping bastion"); - getServer().getPluginManager().disablePlugin(this); - return; - } + if (!this.isEnabled()) //check that the plugin was not disabled in setting up any of the static variables + return; - blockStorage = new BastionBlockStorage(db, getLogger()); - blockStorage.loadBastions(); - getLogger().log(Level.INFO, "All Bastions loaded"); + BastionType.startRegenAndErosionTasks(); + registerListeners(); + setupCommands(); + } - groupStorage = new BastionGroupStorage(db, getLogger()); - groupStorage.loadGroups(); - } - - //Sets up the command managers - private void setupCommands(){ - getCommand("Bastion").setExecutor(new BastionCommandManager()); - getCommand("bsi").setExecutor(new ModeChangeCommand(Mode.INFO)); - getCommand("bsd").setExecutor(new ModeChangeCommand(Mode.DELETE)); - getCommand("bso").setExecutor(new ModeChangeCommand(Mode.NORMAL)); - getCommand("bsb").setExecutor(new ModeChangeCommand(Mode.BASTION)); - getCommand("bsf").setExecutor(new ModeChangeCommand(Mode.OFF)); - getCommand("bsm").setExecutor(new ModeChangeCommand(Mode.MATURE)); - } + @Override + public void onDisable() { + blockStorage.close(); + groupStorage.close(); + } - public static Bastion getPlugin() { - return plugin; - } - - public static BastionBlockManager getBastionManager() { - return blockManager; - } - - public static BastionBlockStorage getBastionStorage() { - return blockStorage; - } + public String getPluginName() { + return "Bastion"; + } - public static BastionSettingManager getSettingManager() { - return settingManager; - } + private void registerListeners() { + getLogger().log(Level.INFO, "Registering Listeners"); + getServer().getPluginManager().registerEvents(new BastionDamageListener(), this); + getServer().getPluginManager().registerEvents(new BastionInteractListener(), this); + getServer().getPluginManager().registerEvents(new ElytraListener(), this); + getServer().getPluginManager().registerEvents(new BastionBreakListener(blockStorage, blockManager), this); + getServer().getPluginManager().registerEvents(new NameLayerListener(blockStorage), this); + getServer().getPluginManager().registerEvents(new CitadelListener(), this); + getServer().getPluginManager().registerEvents(new ModeListener(), this); + } - public static CommonSettings getCommonSettings() { return commonSettings; } + private void setupDatabase() { + ConfigurationSection config = getConfig().getConfigurationSection("mysql"); + String host = config.getString("host"); + int port = config.getInt("port"); + String user = config.getString("user"); + String pass = config.getString("password"); + String dbname = config.getString("database"); + int poolsize = config.getInt("poolsize"); + long connectionTimeout = config.getLong("connectionTimeout"); + long idleTimeout = config.getLong("idleTimeout"); + long maxLifetime = config.getLong("maxLifetime"); + ManagedDatasource db = null; + try { + db = ManagedDatasource.construct(this, new DatabaseCredentials(user, pass, host, port, "mysql", dbname, poolsize, connectionTimeout, idleTimeout, maxLifetime)); + db.getConnection().close(); + } catch (Exception e) { + warning("Could not connect to database, stopping bastion", e); + getServer().getPluginManager().disablePlugin(this); + return; + } - private void registerNameLayerPermissions() { - LinkedList memberAndAbove = new LinkedList<>(); - memberAndAbove.add(PlayerType.MEMBERS); - memberAndAbove.add(PlayerType.MODS); - memberAndAbove.add(PlayerType.ADMINS); - memberAndAbove.add(PlayerType.OWNER); + Database.registerMigrations(db); + if (!db.updateDatabase()) { + warning("Failed to update database, stopping bastion"); + getServer().getPluginManager().disablePlugin(this); + return; + } - LinkedList modAndAbove = new LinkedList<>(); - modAndAbove.add(PlayerType.MODS); - modAndAbove.add(PlayerType.ADMINS); - modAndAbove.add(PlayerType.OWNER); + blockStorage = new BastionBlockStorage(db, getLogger()); + blockStorage.loadBastions(); + getLogger().log(Level.INFO, "All Bastions loaded"); - LinkedList adminAndAbove = new LinkedList<>(); - adminAndAbove.add(PlayerType.ADMINS); - adminAndAbove.add(PlayerType.OWNER); + groupStorage = new BastionGroupStorage(db, getLogger()); + groupStorage.loadGroups(); + } - PermissionType.registerPermission(Permissions.BASTION_PEARL, memberAndAbove, "Allows a player to throw a pearl into a bastion field."); - PermissionType.registerPermission(Permissions.BASTION_PLACE, modAndAbove, "Allows a player to place blocks within a bastion field.", false); - PermissionType.registerPermission(Permissions.BASTION_LIST, modAndAbove, "Allows a player to see all bastions under this group."); - PermissionType.registerPermission(Permissions.BASTION_MANAGE_GROUPS, adminAndAbove, "Allows linking bastion groups."); - PermissionType.registerPermission(Permissions.BASTION_ELYTRA, modAndAbove, "Permits elytra flight through a bastion."); - } + //Sets up the command managers + private void setupCommands() { + getCommand("Bastion").setExecutor(new BastionCommandManager()); + getCommand("bsi").setExecutor(new ModeChangeCommand(Mode.INFO)); + getCommand("bsd").setExecutor(new ModeChangeCommand(Mode.DELETE)); + getCommand("bso").setExecutor(new ModeChangeCommand(Mode.NORMAL)); + getCommand("bsb").setExecutor(new ModeChangeCommand(Mode.BASTION)); + getCommand("bsf").setExecutor(new ModeChangeCommand(Mode.OFF)); + getCommand("bsm").setExecutor(new ModeChangeCommand(Mode.MATURE)); + } + + public static Bastion getPlugin() { + return plugin; + } + + public static BastionBlockManager getBastionManager() { + return blockManager; + } + + public static BastionBlockStorage getBastionStorage() { + return blockStorage; + } + + public static BastionSettingManager getSettingManager() { + return settingManager; + } + + public static CommonSettings getCommonSettings() { + return commonSettings; + } + + private void registerNameLayerPermissions() { + LinkedList memberAndAbove = new LinkedList<>(); + memberAndAbove.add(PlayerType.MEMBERS); + memberAndAbove.add(PlayerType.MODS); + memberAndAbove.add(PlayerType.ADMINS); + memberAndAbove.add(PlayerType.OWNER); + + LinkedList modAndAbove = new LinkedList<>(); + modAndAbove.add(PlayerType.MODS); + modAndAbove.add(PlayerType.ADMINS); + modAndAbove.add(PlayerType.OWNER); + + LinkedList adminAndAbove = new LinkedList<>(); + adminAndAbove.add(PlayerType.ADMINS); + adminAndAbove.add(PlayerType.OWNER); + + PermissionType.registerPermission(Permissions.BASTION_PEARL, memberAndAbove, "Allows a player to throw a pearl into a bastion field."); + PermissionType.registerPermission(Permissions.BASTION_PLACE, modAndAbove, "Allows a player to place blocks within a bastion field.", false); + PermissionType.registerPermission(Permissions.BASTION_LIST, modAndAbove, "Allows a player to see all bastions under this group."); + PermissionType.registerPermission(Permissions.BASTION_MANAGE_GROUPS, adminAndAbove, "Allows linking bastion groups."); + PermissionType.registerPermission(Permissions.BASTION_ELYTRA, modAndAbove, "Permits elytra flight through a bastion."); + } } diff --git a/plugins/bastion-paper/src/main/java/isaac/bastion/BastionBlock.java b/plugins/bastion-paper/src/main/java/isaac/bastion/BastionBlock.java index dba98da62..e2b58c604 100644 --- a/plugins/bastion-paper/src/main/java/isaac/bastion/BastionBlock.java +++ b/plugins/bastion-paper/src/main/java/isaac/bastion/BastionBlock.java @@ -21,469 +21,479 @@ import vg.civcraft.mc.namelayer.group.Group; import vg.civcraft.mc.namelayer.permission.PermissionType; public class BastionBlock implements QTBox, Comparable { - private static final DecimalFormat formatter = new DecimalFormat("#.##"); - private Location location; - private int id = -1; - private long placed; //time when the bastion block was created - private BastionType type; - private Integer listGroupId; + private static final DecimalFormat formatter = new DecimalFormat("#.##"); - /** - * constructor for blocks loaded from database - * @param location - * @param placed - * @param id - * @param type - */ - public BastionBlock(Location location, long placed, int id, BastionType type) { - this.id = id; - this.location = location; - this.type = type; + private Location location; + private int id = -1; + private long placed; //time when the bastion block was created + private BastionType type; + private Integer listGroupId; - this.placed = placed; + /** + * constructor for blocks loaded from database + * + * @param location + * @param placed + * @param id + * @param type + */ + public BastionBlock(Location location, long placed, int id, BastionType type) { + this.id = id; + this.location = location; + this.type = type; - Reinforcement reinforcement = getReinforcement(); - if (reinforcement != null) { - this.listGroupId = reinforcement.getGroupId(); - } else{ - destroy(); - Bastion.getPlugin().severe("Reinforcement removed during BastionBlock instantiation, removing at " + location.toString()); - } + this.placed = placed; - } + Reinforcement reinforcement = getReinforcement(); + if (reinforcement != null) { + this.listGroupId = reinforcement.getGroupId(); + } else { + destroy(); + Bastion.getPlugin().severe("Reinforcement removed during BastionBlock instantiation, removing at " + location.toString()); + } - /** - * @return The amount to erode from the bastion for a block place - */ - public double getErosionFromBlock() { - double scaleStart = type.getStartScaleFactor(); - double scaleEnd = type.getFinalScaleFactor(); - - long time = System.currentTimeMillis() - placed; - - if(type.getWarmupTime() == 0) { - return scaleStart; - } else if(time < type.getWarmupTime()) { - return (((scaleEnd - scaleStart) / type.getWarmupTime()) * time + scaleStart); - } else { - return scaleEnd; - } - } + } - /** - * @return The amount to erode from the bastion for a pearl - */ - public double getErosionFromPearl() { - return getErosionFromBlock() * type.getPearlScaleFactor(); - } + /** + * @return The amount to erode from the bastion for a block place + */ + public double getErosionFromBlock() { + double scaleStart = type.getStartScaleFactor(); + double scaleEnd = type.getFinalScaleFactor(); - /** - * @return The amount to erode from the bastion for an elytra collision - */ - public double getErosionFromElytra() { - return getErosionFromBlock() * type.getElytraScale(); - } - - /** - * Checks if a location is inside this bastion field. - * - * @param loc The location to check - * @return true if in field - */ - public boolean inField(Location loc) { - return !(yLevelCheck(loc) || // don't add parens if you don't know why it wasn't there. - (type.isSquare() && - (Math.abs(loc.getBlockX() - location.getBlockX()) > type.getEffectRadius() || - Math.abs(loc.getBlockZ() - location.getBlockZ()) > type.getEffectRadius() ) ) || - (!type.isSquare() && - ((loc.getBlockX() - location.getX()) * (float)(loc.getBlockX() - location.getX()) + - (loc.getBlockZ() - location.getZ()) * (float)(loc.getBlockZ() - location.getZ()) >= type.getRadiusSquared() ) ) - ); - } - - public boolean yLevelCheck(Location loc) { - if(type.isIncludeY()) { - return loc.getBlockY() < location.getBlockY(); - } - return loc.getBlockY() <= location.getBlockY(); - } + long time = System.currentTimeMillis() - placed; - /** - * checks if a player would be allowed to remove the Bastion block - * @param player The player to check - * @return true if the player can remove the bastion - */ - public boolean canRemove(Player player){ + if (type.getWarmupTime() == 0) { + return scaleStart; + } else if (time < type.getWarmupTime()) { + return (((scaleEnd - scaleStart) / type.getWarmupTime()) * time + scaleStart); + } else { + return scaleEnd; + } + } - Reinforcement reinforcement = getReinforcement(); + /** + * @return The amount to erode from the bastion for a pearl + */ + public double getErosionFromPearl() { + return getErosionFromBlock() * type.getPearlScaleFactor(); + } - if(reinforcement!=null){ - return reinforcement.hasPermission(player, CitadelPermissionHandler.getBypass()); //should return true if founder or moderator, but I feel this is more consistant - } - return true; - } - - /** - * Check if a player is allowed to pearl in the bastion field - * @param player The player to check - * @return true if the player can pearl within the bastion - */ - public boolean canPearl(Player player) { - Reinforcement reinforcement = getReinforcement(); + /** + * @return The amount to erode from the bastion for an elytra collision + */ + public double getErosionFromElytra() { + return getErosionFromBlock() * type.getElytraScale(); + } - if(reinforcement!=null){ - return NameAPI.getGroupManager().hasAccess(reinforcement.getGroup(), player.getUniqueId(), PermissionType.getPermission(Permissions.BASTION_PEARL)); - } - return true; - } + /** + * Checks if a location is inside this bastion field. + * + * @param loc The location to check + * @return true if in field + */ + public boolean inField(Location loc) { + return !(yLevelCheck(loc) || // don't add parens if you don't know why it wasn't there. + (type.isSquare() && + (Math.abs(loc.getBlockX() - location.getBlockX()) > type.getEffectRadius() || + Math.abs(loc.getBlockZ() - location.getBlockZ()) > type.getEffectRadius())) || + (!type.isSquare() && + ((loc.getBlockX() - location.getX()) * (float) (loc.getBlockX() - location.getX()) + + (loc.getBlockZ() - location.getZ()) * (float) (loc.getBlockZ() - location.getZ()) >= type.getRadiusSquared())) + ); + } - /** - * Check if a player is allowed to place blocks in the bastion field - * @param player The player to check - * @return true if the player can place blocks within the bastion - */ - public boolean canPlace(Player player) { - Reinforcement reinforcement = getReinforcement(); + public boolean yLevelCheck(Location loc) { + if (type.isIncludeY()) { + return loc.getBlockY() < location.getBlockY(); + } + return loc.getBlockY() <= location.getBlockY(); + } - if (reinforcement == null) return true; - if (player == null) return false; + /** + * checks if a player would be allowed to remove the Bastion block + * + * @param player The player to check + * @return true if the player can remove the bastion + */ + public boolean canRemove(Player player) { - return NameAPI.getGroupManager().hasAccess(reinforcement.getGroup(), player.getUniqueId(), PermissionType.getPermission(Permissions.BASTION_PLACE)); - } - - /** - * Checks if a player has a permission for the bastion's group - * @param player The player to check - * @param perm The permission to check - * @return true if the player has the permission - */ - public boolean permAccess(Player player, PermissionType perm) { - Reinforcement rein = getReinforcement(); - if (rein == null) { - return true; - } - return NameAPI.getGroupManager().hasAccess(rein.getGroup(), player.getUniqueId(), perm); - } + Reinforcement reinforcement = getReinforcement(); - /** - * Checks if any of the players in the bastion field - * This is used mostly for checking if a dispenser can place things - * @param players the players to check - * @return true if any of the players can place blocks in this bastion - */ - public boolean oneCanPlace(Set players){ - Reinforcement reinforcement = getReinforcement(); - //the object will have been closed if null but we still don't want things to crash - if (reinforcement == null) { - return true; - } + if (reinforcement != null) { + return reinforcement.hasPermission(player, CitadelPermissionHandler.getBypass()); //should return true if founder or moderator, but I feel this is more consistant + } + return true; + } - for (UUID player: players){ - if (player != null) - if (NameAPI.getGroupManager().hasAccess(reinforcement.getGroup(), player, PermissionType.getPermission(Permissions.BASTION_PLACE))) - return true; - } + /** + * Check if a player is allowed to pearl in the bastion field + * + * @param player The player to check + * @return true if the player can pearl within the bastion + */ + public boolean canPearl(Player player) { + Reinforcement reinforcement = getReinforcement(); - return false; - } + if (reinforcement != null) { + return NameAPI.getGroupManager().hasAccess(reinforcement.getGroup(), player.getUniqueId(), PermissionType.getPermission(Permissions.BASTION_PEARL)); + } + return true; + } + + /** + * Check if a player is allowed to place blocks in the bastion field + * + * @param player The player to check + * @return true if the player can place blocks within the bastion + */ + public boolean canPlace(Player player) { + Reinforcement reinforcement = getReinforcement(); + + if (reinforcement == null) return true; + if (player == null) return false; + + return NameAPI.getGroupManager().hasAccess(reinforcement.getGroup(), player.getUniqueId(), PermissionType.getPermission(Permissions.BASTION_PLACE)); + } + + /** + * Checks if a player has a permission for the bastion's group + * + * @param player The player to check + * @param perm The permission to check + * @return true if the player has the permission + */ + public boolean permAccess(Player player, PermissionType perm) { + Reinforcement rein = getReinforcement(); + if (rein == null) { + return true; + } + return NameAPI.getGroupManager().hasAccess(rein.getGroup(), player.getUniqueId(), perm); + } + + /** + * Checks if any of the players in the bastion field + * This is used mostly for checking if a dispenser can place things + * + * @param players the players to check + * @return true if any of the players can place blocks in this bastion + */ + public boolean oneCanPlace(Set players) { + Reinforcement reinforcement = getReinforcement(); + //the object will have been closed if null but we still don't want things to crash + if (reinforcement == null) { + return true; + } + + for (UUID player : players) { + if (player != null) + if (NameAPI.getGroupManager().hasAccess(reinforcement.getGroup(), player, PermissionType.getPermission(Permissions.BASTION_PLACE))) + return true; + } + + return false; + } - /** - * @return true if the Bastion's strength is at zero and it should be removed - */ - public boolean shouldCull() { - return getReinforcement() == null || getReinforcement().getHealth() < 0; - } - - /** - * Regenerates one hp on the bastion up to the cap based on reinforcement - */ - public void regen() { - Reinforcement rein = getReinforcement(); - if(rein != null) { - ReinforcementLogic.damageReinforcement(rein, -1 , null); - } else { - destroy(); - Bastion.getPlugin().severe("Reinforcement removed without removing bastion, fixed at " + location); - } - } + /** + * @return true if the Bastion's strength is at zero and it should be removed + */ + public boolean shouldCull() { + return getReinforcement() == null || getReinforcement().getHealth() < 0; + } - /** - * removes a set amount of durability from the reinforcement - * @param amount The amount to remove - */ - public void erode(double amount) { - Reinforcement rein = getReinforcement(); - if (rein == null) { - return; - } - ReinforcementLogic.damageReinforcement(getReinforcement(), (float) amount , null); - if (shouldCull()) { - destroy(); - Bastion.getPlugin().severe("Reinforcement destroyed, removing bastion"); - } - } + /** + * Regenerates one hp on the bastion up to the cap based on reinforcement + */ + public void regen() { + Reinforcement rein = getReinforcement(); + if (rein != null) { + ReinforcementLogic.damageReinforcement(rein, -1, null); + } else { + destroy(); + Bastion.getPlugin().severe("Reinforcement removed without removing bastion, fixed at " + location); + } + } - /** - * Instantly matures the bastion - */ - public void mature() { - placed -= type.getWarmupTime(); - Bastion.getBastionStorage().updated(this); - } - - /** - * Checks if the bastion is mature - * @return true if the bastion is mature - */ - public boolean isMature() { - return System.currentTimeMillis() - placed >= type.getWarmupTime(); - } + /** + * removes a set amount of durability from the reinforcement + * + * @param amount The amount to remove + */ + public void erode(double amount) { + Reinforcement rein = getReinforcement(); + if (rein == null) { + return; + } + ReinforcementLogic.damageReinforcement(getReinforcement(), (float) amount, null); + if (shouldCull()) { + destroy(); + Bastion.getPlugin().severe("Reinforcement destroyed, removing bastion"); + } + } - /** - * Gets the reinforcement for this bastion - * @return The reinforcement for this bastion - */ - public Reinforcement getReinforcement() { - Reinforcement reinforcement = Citadel.getInstance().getReinforcementManager().getReinforcement(location); - if(reinforcement == null) { - destroy(); - Bastion.getPlugin().severe("Reinforcement no longer exists, but bastion not removed, fixed at " + location); - } - return reinforcement; - } + /** + * Instantly matures the bastion + */ + public void mature() { + placed -= type.getWarmupTime(); + Bastion.getBastionStorage().updated(this); + } - /** - * Gets the owner of the bastion's group - */ - public UUID getOwner() { - return getReinforcement().getGroup().getOwner(); - } + /** + * Checks if the bastion is mature + * + * @return true if the bastion is mature + */ + public boolean isMature() { + return System.currentTimeMillis() - placed >= type.getWarmupTime(); + } - /** - * Gets the location of the bastion - */ - public Location getLocation() { - return location; - } - - /** - * Gets the bastion's ID - */ - public int getId() { - return id; - } - - /** - * Gets the bastion's type - */ - public BastionType getType() { - return type; - } - - /** - * Gets how long the bastion has been in the world in ms - */ - public long getPlaced() { - return placed; - } + /** + * Gets the reinforcement for this bastion + * + * @return The reinforcement for this bastion + */ + public Reinforcement getReinforcement() { + Reinforcement reinforcement = Citadel.getInstance().getReinforcementManager().getReinforcement(location); + if (reinforcement == null) { + destroy(); + Bastion.getPlugin().severe("Reinforcement no longer exists, but bastion not removed, fixed at " + location); + } + return reinforcement; + } - /** - * Sets the id of this bastion - */ - public void setId(int id) { - this.id = id; - } + /** + * Gets the owner of the bastion's group + */ + public UUID getOwner() { + return getReinforcement().getGroup().getOwner(); + } - public Integer getListGroupId() { - return this.listGroupId; - } + /** + * Gets the location of the bastion + */ + public Location getLocation() { + return location; + } - public void setListGroupId(Integer groupId) { - this.listGroupId = groupId; - } + /** + * Gets the bastion's ID + */ + public int getId() { + return id; + } - // needed to use SparseQuadTree - @Override - public int qtXMin() { - return location.getBlockX()-type.getEffectRadius(); - } + /** + * Gets the bastion's type + */ + public BastionType getType() { + return type; + } - @Override - public int qtXMid() { - return location.getBlockX(); - } + /** + * Gets how long the bastion has been in the world in ms + */ + public long getPlaced() { + return placed; + } - @Override - public int qtXMax() { - return location.getBlockX()+type.getEffectRadius(); - } + /** + * Sets the id of this bastion + */ + public void setId(int id) { + this.id = id; + } - @Override - public int qtZMin() { - return location.getBlockZ()-type.getEffectRadius(); - } + public Integer getListGroupId() { + return this.listGroupId; + } - @Override - public int qtZMid() { - return location.getBlockZ(); - } + public void setListGroupId(Integer groupId) { + this.listGroupId = groupId; + } - @Override - public int qtZMax() { - return location.getBlockZ()+type.getEffectRadius(); - } + // needed to use SparseQuadTree + @Override + public int qtXMin() { + return location.getBlockX() - type.getEffectRadius(); + } - @Override - public String toString() { - SimpleDateFormat dateFormator = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); - StringBuilder result = new StringBuilder(ChatColor.GOLD + "" + ChatColor.BOLD + "Bastion Info" + ChatColor.AQUA + "\n"); + @Override + public int qtXMid() { + return location.getBlockX(); + } - result.append("Health: " + ChatColor.GOLD + "" + getStrengthText() + ChatColor.AQUA + "\n"); - if (!isMature()) { - result.append("Mature in: " + ChatColor.GOLD + "" + TextUtil.formatDuration(type.getWarmupTime()) + ChatColor.AQUA + "\n"); - } else { - result.append("Mature?: " + ChatColor.GOLD + "Yes" + ChatColor.AQUA + "\n"); - } - result.append("Placed: " + ChatColor.GOLD + "" + dateFormator.format(new Date(placed)) + ChatColor.AQUA + "\n"); - result.append("Group: " + ChatColor.GOLD + getGroupName() + ChatColor.AQUA + "\n"); - result.append("Location: " + ChatColor.GOLD + "" + this.location.getBlockX() + " " + this.location.getBlockY() + " " + this.location.getBlockZ()); - return result.toString(); - } + @Override + public int qtXMax() { + return location.getBlockX() + type.getEffectRadius(); + } - /** - * Creates an info message, adds more info if dev is true - * @param dev If the player is a dev - * @return An info message - */ - public String infoMessage(boolean dev) { - StringBuilder result = new StringBuilder(ChatColor.GREEN.toString()); - if (dev) { - return result.append( this.toString() ).toString(); - } + @Override + public int qtZMin() { + return location.getBlockZ() - type.getEffectRadius(); + } - String strength = getStrengthText(); + @Override + public int qtZMid() { + return location.getBlockZ(); + } - if(strength != null) { - result.append("Bastion: "); - result.append(strength); - } + @Override + public int qtZMax() { + return location.getBlockZ() + type.getEffectRadius(); + } - return result.toString(); - } + @Override + public String toString() { + SimpleDateFormat dateFormator = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); + StringBuilder result = new StringBuilder(ChatColor.GOLD + "" + ChatColor.BOLD + "Bastion Info" + ChatColor.AQUA + "\n"); - public String getHoverText() { - StringBuilder hoverText = new StringBuilder(); + result.append("Health: " + ChatColor.GOLD + "" + getStrengthText() + ChatColor.AQUA + "\n"); + if (!isMature()) { + result.append("Mature in: " + ChatColor.GOLD + "" + TextUtil.formatDuration(type.getWarmupTime()) + ChatColor.AQUA + "\n"); + } else { + result.append("Mature?: " + ChatColor.GOLD + "Yes" + ChatColor.AQUA + "\n"); + } + result.append("Placed: " + ChatColor.GOLD + "" + dateFormator.format(new Date(placed)) + ChatColor.AQUA + "\n"); + result.append("Group: " + ChatColor.GOLD + getGroupName() + ChatColor.AQUA + "\n"); + result.append("Location: " + ChatColor.GOLD + "" + this.location.getBlockX() + " " + this.location.getBlockY() + " " + this.location.getBlockZ()); + return result.toString(); + } - hoverText.append("Location: "); - hoverText.append(getLocationText()); - hoverText.append("\n"); + /** + * Creates an info message, adds more info if dev is true + * + * @param dev If the player is a dev + * @return An info message + */ + public String infoMessage(boolean dev) { + StringBuilder result = new StringBuilder(ChatColor.GREEN.toString()); + if (dev) { + return result.append(this.toString()).toString(); + } - hoverText.append("Group: "); - hoverText.append(getGroupName()); - hoverText.append("\n"); + String strength = getStrengthText(); - hoverText.append("Type: "); - hoverText.append(this.type.getItemName()); - hoverText.append("\n"); + if (strength != null) { + result.append("Bastion: "); + result.append(strength); + } - hoverText.append("Shape: "); - hoverText.append(this.type.isSquare() ? "Square" : "Circle"); - hoverText.append("\n"); + return result.toString(); + } - hoverText.append("Radius: "); - hoverText.append(this.type.getEffectRadius()); - hoverText.append("\n"); + public String getHoverText() { + StringBuilder hoverText = new StringBuilder(); - return hoverText.toString(); - } + hoverText.append("Location: "); + hoverText.append(getLocationText()); + hoverText.append("\n"); - public String getLocationText() { - String worldText = ""; + hoverText.append("Group: "); + hoverText.append(getGroupName()); + hoverText.append("\n"); - if (this.location != null - && this.location.getWorld() != null - && this.location.getWorld().getName() != null - ) - { - worldText = String.format("%s ", this.location.getWorld().getName()); - } + hoverText.append("Type: "); + hoverText.append(this.type.getItemName()); + hoverText.append("\n"); - return String.format("[%s%d %d %d]", worldText, this.location.getBlockX(), this.location.getBlockY(), this.location.getBlockZ()); - } + hoverText.append("Shape: "); + hoverText.append(this.type.isSquare() ? "Square" : "Circle"); + hoverText.append("\n"); - private String getGroupName() { - if(this.listGroupId == null) return ""; + hoverText.append("Radius: "); + hoverText.append(this.type.getEffectRadius()); + hoverText.append("\n"); - Group group = GroupManager.getGroup(this.listGroupId); + return hoverText.toString(); + } - return group != null ? group.getName() : ""; - } + public String getLocationText() { + String worldText = ""; - public Group getGroup () { - return GroupManager.getGroup(this.listGroupId); - } + if (this.location != null + && this.location.getWorld() != null + && this.location.getWorld().getName() != null + ) { + worldText = String.format("%s ", this.location.getWorld().getName()); + } - public String getStrengthText() { - return formatter.format(getReinforcement().getHealth()) + "/" + formatter.format(getReinforcement().getType().getHealth()); - } + return String.format("[%s%d %d %d]", worldText, this.location.getBlockX(), this.location.getBlockY(), this.location.getBlockZ()); + } - // TODO: Test world-aware comparison - @Override - public int compareTo(BastionBlock other) { - UUID thisWorld = location.getWorld().getUID(); - int thisX = location.getBlockX(); - int thisY = location.getBlockY(); - int thisZ = location.getBlockZ(); + private String getGroupName() { + if (this.listGroupId == null) return ""; - UUID otherWorld = location.getWorld().getUID(); - int otherX = other.location.getBlockX(); - int otherY = other.location.getBlockY(); - int otherZ = other.location.getBlockZ(); + Group group = GroupManager.getGroup(this.listGroupId); - int worldCompare = thisWorld.compareTo(otherWorld); - if (worldCompare != 0) { - return worldCompare; - } + return group != null ? group.getName() : ""; + } - if (thisX < otherX) { - return -1; - } - if (thisX > otherX) { - return 1; - } + public Group getGroup() { + return GroupManager.getGroup(this.listGroupId); + } - if (thisY < otherY) { - return -1; - } - if (thisY > otherY) { - return 1; - } - - if (thisZ < otherZ) { - return -1; - } - if (thisZ > otherZ) { - return 1; - } + public String getStrengthText() { + return formatter.format(getReinforcement().getHealth()) + "/" + formatter.format(getReinforcement().getType().getHealth()); + } - return 0; - } + // TODO: Test world-aware comparison + @Override + public int compareTo(BastionBlock other) { + UUID thisWorld = location.getWorld().getUID(); + int thisX = location.getBlockX(); + int thisY = location.getBlockY(); + int thisZ = location.getBlockZ(); - - /** - * removes Bastion from database and destroys the block at the location - */ - public void destroy() { - if (type.isDestroyOnRemove() || (type.isDestroyOnRemoveWhileImmature() && !isMature())) { - if (location.getChunk().isLoaded()) { - location.getBlock().setType(Material.AIR); - } - Bastion.getBastionStorage().deleteBastion(this); - } else { - Bastion.getBastionStorage().setBastionAsDead(this); - } - } + UUID otherWorld = location.getWorld().getUID(); + int otherX = other.location.getBlockX(); + int otherY = other.location.getBlockY(); + int otherZ = other.location.getBlockZ(); + + int worldCompare = thisWorld.compareTo(otherWorld); + if (worldCompare != 0) { + return worldCompare; + } + + if (thisX < otherX) { + return -1; + } + if (thisX > otherX) { + return 1; + } + + if (thisY < otherY) { + return -1; + } + if (thisY > otherY) { + return 1; + } + + if (thisZ < otherZ) { + return -1; + } + if (thisZ > otherZ) { + return 1; + } + + return 0; + } + + + /** + * removes Bastion from database and destroys the block at the location + */ + public void destroy() { + if (type.isDestroyOnRemove() || (type.isDestroyOnRemoveWhileImmature() && !isMature())) { + if (location.getChunk().isLoaded()) { + location.getBlock().setType(Material.AIR); + } + Bastion.getBastionStorage().deleteBastion(this); + } else { + Bastion.getBastionStorage().setBastionAsDead(this); + } + } } diff --git a/plugins/bastion-paper/src/main/java/isaac/bastion/BastionGroup.java b/plugins/bastion-paper/src/main/java/isaac/bastion/BastionGroup.java index 8472a38ac..0afb7240d 100644 --- a/plugins/bastion-paper/src/main/java/isaac/bastion/BastionGroup.java +++ b/plugins/bastion-paper/src/main/java/isaac/bastion/BastionGroup.java @@ -8,33 +8,34 @@ import java.util.HashSet; import java.util.Set; public class BastionGroup { - private int groupId; - private Set allowedGroupIds; - public BastionGroup(int groupId) { - this.groupId = groupId; - this.allowedGroupIds = new HashSet<>(); - } + private int groupId; + private Set allowedGroupIds; - public int getGroupId() { - return this.groupId; - } + public BastionGroup(int groupId) { + this.groupId = groupId; + this.allowedGroupIds = new HashSet<>(); + } - public void addAllowedGroup(int groupId) { - this.allowedGroupIds.add(groupId); - } + public int getGroupId() { + return this.groupId; + } - public boolean removeAllowedGroup(int groupId) { - this.allowedGroupIds.remove(groupId); + public void addAllowedGroup(int groupId) { + this.allowedGroupIds.add(groupId); + } - return this.allowedGroupIds.size() > 0; - } + public boolean removeAllowedGroup(int groupId) { + this.allowedGroupIds.remove(groupId); - public boolean isAllowedGroup(int groupId) { - return this.allowedGroupIds.contains(groupId); - } + return this.allowedGroupIds.size() > 0; + } - public Set getAllowedGroupIds() { - return this.allowedGroupIds; - } + public boolean isAllowedGroup(int groupId) { + return this.allowedGroupIds.contains(groupId); + } + + public Set getAllowedGroupIds() { + return this.allowedGroupIds; + } } diff --git a/plugins/bastion-paper/src/main/java/isaac/bastion/BastionType.java b/plugins/bastion-paper/src/main/java/isaac/bastion/BastionType.java index cf85be66b..37dd476bb 100644 --- a/plugins/bastion-paper/src/main/java/isaac/bastion/BastionType.java +++ b/plugins/bastion-paper/src/main/java/isaac/bastion/BastionType.java @@ -11,604 +11,579 @@ import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.scheduler.BukkitRunnable; public class BastionType { - - private static LinkedHashMap types = new LinkedHashMap<>(); - private static String defaultType; - private static int maxRadius = 0; - private String name; - private String itemName; - private List lore; - private String shortName; - private boolean square; - private int effectRadius; - private int radiusSquared; - private boolean includeY; - private int startScaleFactor; - private double finalScaleFactor; - private long warmupTime; - private int erosionTime; - private long placementCooldown; - private boolean destroyOnRemove; - private boolean onlyDirectDestruction; - private boolean blockPearls; - private boolean blockMidair; - private int pearlScale; - private boolean pearlRequireMature; - private boolean consumeOnBlock; - private int blocksToErode; - private boolean blockElytra; - private boolean destroyElytra; - private boolean damageElytra; - private int elytraScale; - private boolean elytraRequireMature; - private boolean explodeOnBlock; - private double explodeOnBlockStrength; - private boolean damageFirstBastion; - private int regenTime; - private boolean allowPearlingOut; - private boolean blockReinforcements; - private Material material; - private boolean destroyOnRemoveWhileImmature; - private int proximityDamageRange; - private double proximityDamageFactor; - - private String overLayName; - - public BastionType( - String name, - String itemName, - Material material, - List lore, - String shortName, - boolean square, - int effectRadius, - boolean includeY, - int startScaleFactor, - double finalScaleFactor, - long warmupTime, - int erosionTime, - long placementCooldown, - boolean destroyOnRemove, - boolean blockPearls, - boolean blockMidair, - int pearlScale, - boolean pearlRequireMature, - boolean consumeOnBlock, - int blocksToErode, - boolean blockElytra, - boolean destroyOnBlockElytra, - boolean damageElytra, - int elytraScale, - boolean elytraRequireMature, - boolean explodeOnBlock, - double explodeOnBlockStrength, - boolean damageFirstBastion, - int regenTime, - boolean onlyDirectDestruction, - boolean allowPearlingOut, - boolean blockReinforcements, - boolean destroyOnRemoveWhileImmature, - int proximityDamageRange, - double proximityDamageFactor, - String overLayName - ) { - this.name = name; - this.material = material; - this.itemName = itemName; - this.lore = lore; - this.shortName = shortName; - this.square = square; - this.effectRadius = effectRadius; - this.radiusSquared = effectRadius*effectRadius; - this.includeY = includeY; - this.startScaleFactor = startScaleFactor; - this.finalScaleFactor = finalScaleFactor; - this.warmupTime = warmupTime; - this.erosionTime = erosionTime; - this.placementCooldown = placementCooldown; - this.destroyOnRemove = destroyOnRemove; - this.onlyDirectDestruction = onlyDirectDestruction; - this.blockPearls = blockPearls; - this.blockMidair = blockMidair; - this.pearlScale = pearlScale; - this.pearlRequireMature = pearlRequireMature; - this.consumeOnBlock = consumeOnBlock; - this.blocksToErode = blocksToErode; - this.blockElytra = blockElytra; - this.destroyElytra = destroyOnBlockElytra; - this.damageElytra = damageElytra; - this.elytraScale = elytraScale; - this.elytraRequireMature = elytraRequireMature; - this.explodeOnBlock = explodeOnBlock; - this.explodeOnBlockStrength = explodeOnBlockStrength; - this.damageFirstBastion = damageFirstBastion; - this.regenTime = regenTime; - this.allowPearlingOut = allowPearlingOut; - this.blockReinforcements = blockReinforcements; - this.destroyOnRemoveWhileImmature = destroyOnRemoveWhileImmature; - this.proximityDamageFactor = proximityDamageFactor; - this.proximityDamageRange = proximityDamageRange; - this.overLayName = overLayName; - - maxRadius = effectRadius > maxRadius ? effectRadius : maxRadius; - } + private static LinkedHashMap types = new LinkedHashMap<>(); + private static String defaultType; + private static int maxRadius = 0; - /** - * @return The lore for this bastion type - */ - public List getLore() { - return lore; - } + private String name; + private String itemName; + private List lore; + private String shortName; + private boolean square; + private int effectRadius; + private int radiusSquared; + private boolean includeY; + private int startScaleFactor; + private double finalScaleFactor; + private long warmupTime; + private int erosionTime; + private long placementCooldown; + private boolean destroyOnRemove; + private boolean onlyDirectDestruction; + private boolean blockPearls; + private boolean blockMidair; + private int pearlScale; + private boolean pearlRequireMature; + private boolean consumeOnBlock; + private int blocksToErode; + private boolean blockElytra; + private boolean destroyElytra; + private boolean damageElytra; + private int elytraScale; + private boolean elytraRequireMature; + private boolean explodeOnBlock; + private double explodeOnBlockStrength; + private boolean damageFirstBastion; + private int regenTime; + private boolean allowPearlingOut; + private boolean blockReinforcements; + private Material material; + private boolean destroyOnRemoveWhileImmature; + private int proximityDamageRange; + private double proximityDamageFactor; - /** - * @return The item / display name for this Bastion type - */ - public String getItemName() { - return itemName; - } + private String overLayName; - /** - * @return Short name for this Bastion type. Used by /bsl command - */ - public String getShortName() { - return shortName; - } + public BastionType( + String name, + String itemName, + Material material, + List lore, + String shortName, + boolean square, + int effectRadius, + boolean includeY, + int startScaleFactor, + double finalScaleFactor, + long warmupTime, + int erosionTime, + long placementCooldown, + boolean destroyOnRemove, + boolean blockPearls, + boolean blockMidair, + int pearlScale, + boolean pearlRequireMature, + boolean consumeOnBlock, + int blocksToErode, + boolean blockElytra, + boolean destroyOnBlockElytra, + boolean damageElytra, + int elytraScale, + boolean elytraRequireMature, + boolean explodeOnBlock, + double explodeOnBlockStrength, + boolean damageFirstBastion, + int regenTime, + boolean onlyDirectDestruction, + boolean allowPearlingOut, + boolean blockReinforcements, + boolean destroyOnRemoveWhileImmature, + int proximityDamageRange, + double proximityDamageFactor, + String overLayName + ) { + this.name = name; + this.material = material; + this.itemName = itemName; + this.lore = lore; + this.shortName = shortName; + this.square = square; + this.effectRadius = effectRadius; + this.radiusSquared = effectRadius * effectRadius; + this.includeY = includeY; + this.startScaleFactor = startScaleFactor; + this.finalScaleFactor = finalScaleFactor; + this.warmupTime = warmupTime; + this.erosionTime = erosionTime; + this.placementCooldown = placementCooldown; + this.destroyOnRemove = destroyOnRemove; + this.onlyDirectDestruction = onlyDirectDestruction; + this.blockPearls = blockPearls; + this.blockMidair = blockMidair; + this.pearlScale = pearlScale; + this.pearlRequireMature = pearlRequireMature; + this.consumeOnBlock = consumeOnBlock; + this.blocksToErode = blocksToErode; + this.blockElytra = blockElytra; + this.destroyElytra = destroyOnBlockElytra; + this.damageElytra = damageElytra; + this.elytraScale = elytraScale; + this.elytraRequireMature = elytraRequireMature; + this.explodeOnBlock = explodeOnBlock; + this.explodeOnBlockStrength = explodeOnBlockStrength; + this.damageFirstBastion = damageFirstBastion; + this.regenTime = regenTime; + this.allowPearlingOut = allowPearlingOut; + this.blockReinforcements = blockReinforcements; + this.destroyOnRemoveWhileImmature = destroyOnRemoveWhileImmature; + this.proximityDamageFactor = proximityDamageFactor; + this.proximityDamageRange = proximityDamageRange; + this.overLayName = overLayName; - /** - * @return true if bastion is square - */ - public boolean isSquare() { - return square; - } + maxRadius = effectRadius > maxRadius ? effectRadius : maxRadius; + } - /** - * @return the radius of the bastion - */ - public int getEffectRadius() { - return effectRadius; - } + /** + * @return The lore for this bastion type + */ + public List getLore() { + return lore; + } - /** - * - * @return the radius of the bastion squared - */ - public int getRadiusSquared() { - return radiusSquared; - } - - /** - * - * @return true if the bastion blocks on it's own y level - */ - public boolean isIncludeY() { - return includeY; - } - - /** - * - * @return Whether players are allowed to pearl out of this field, - * meaning they are standing inside of the field, but their pearl landed in unbastioned territory - */ - public boolean canPearlOut() { - return allowPearlingOut; - } - - /** - * @return Name to use in HUD to describe type - */ - public String getOverlayName() { - return overLayName; - } + /** + * @return The item / display name for this Bastion type + */ + public String getItemName() { + return itemName; + } - /** - * - * @return The scale for amplifying damage when a bastion is first placed - */ - public int getStartScaleFactor() { - return startScaleFactor; - } + /** + * @return Short name for this Bastion type. Used by /bsl command + */ + public String getShortName() { + return shortName; + } - /** - * - * @return The scale for amplifying damage when a bastion is mature - */ - public double getFinalScaleFactor() { - return finalScaleFactor; - } + /** + * @return true if bastion is square + */ + public boolean isSquare() { + return square; + } - /** - * - * @return The time in ms it takes for a bastion to mature - */ - public long getWarmupTime() { - return warmupTime; - } - - /** - * - * @return The amount of time between erosions - */ - public int getErosionTime() { - return erosionTime; - } + /** + * @return the radius of the bastion + */ + public int getEffectRadius() { + return effectRadius; + } - /** - * - * @return true if the physical block should be destroyed when a bastion dies - */ - public boolean isDestroyOnRemove() { - return destroyOnRemove; - } - - /** - * - * @return true if a bastion can only be removed by destroying the block itself. - */ - public boolean isOnlyDirectDestruction() { - return onlyDirectDestruction; - } + /** + * @return the radius of the bastion squared + */ + public int getRadiusSquared() { + return radiusSquared; + } - /** - * - * @return true if the bastion blocks pearls - */ - public boolean isBlockPearls() { - return blockPearls; - } + /** + * @return true if the bastion blocks on it's own y level + */ + public boolean isIncludeY() { + return includeY; + } - /** - * - * @return true if the bastion blocks midair rather than when the pearl lands - */ - public boolean isBlockMidair() { - return blockMidair; - } + /** + * @return Whether players are allowed to pearl out of this field, + * meaning they are standing inside of the field, but their pearl landed in unbastioned territory + */ + public boolean canPearlOut() { + return allowPearlingOut; + } - /** - * - * @return The scale for increased bastion damage from pearls - */ - public int getPearlScaleFactor() { - return pearlScale; - } + /** + * @return Name to use in HUD to describe type + */ + public String getOverlayName() { + return overLayName; + } - /** - * - * @return true if the bastion must be mature to block pearls - */ - public boolean isRequireMaturity() { - return pearlRequireMature; - } + /** + * @return The scale for amplifying damage when a bastion is first placed + */ + public int getStartScaleFactor() { + return startScaleFactor; + } - /** - * - * @return true if pearls are consumed when blocked by bastion - */ - public boolean isConsumeOnBlock() { - return consumeOnBlock; - } - - /** - * - * @return The number of bastions that should be eroded from a block place - */ - public int getBlocksToErode() { - return blocksToErode; - } - - /** - * - * @return The cooldown for damaging a bastion - */ - public long getPlacementCooldown() { - return placementCooldown; - } - - /** - * - * @return true if the bastion blocks elytra - */ - public boolean isBlockElytra() { - return blockElytra; - } + /** + * @return The scale for amplifying damage when a bastion is mature + */ + public double getFinalScaleFactor() { + return finalScaleFactor; + } - /** - * - * @return true if the bastion destroys elytra - */ - public boolean isDestroyElytra() { - return destroyElytra; - } + /** + * @return The time in ms it takes for a bastion to mature + */ + public long getWarmupTime() { + return warmupTime; + } - /** - * - * @return true if the bastion just damages elytra - */ - public boolean isDamageElytra() { - return damageElytra; - } + /** + * @return The amount of time between erosions + */ + public int getErosionTime() { + return erosionTime; + } - /** - * - * @return The scale for increased damage from elytra collision - */ - public int getElytraScale() { - return elytraScale; - } + /** + * @return true if the physical block should be destroyed when a bastion dies + */ + public boolean isDestroyOnRemove() { + return destroyOnRemove; + } - /** - * - * @return true if bastion must be mature to block elytra - */ - public boolean isElytraRequireMature() { - return elytraRequireMature; - } - - /** - * - * @return true if there should be an explosion on elytra colision - */ - public boolean isExplodeOnBlock() { - return explodeOnBlock; - } - - /** - * - * @return the strength of the explosion on elytra collision - */ - public double getExplosionStrength() { - return explodeOnBlockStrength; - } - - /** - * - * @return true if only the first bastion hit should be damaged by pearls - */ - public boolean damageFirstBastion() { - return damageFirstBastion; - } - - /** - * - * @return The amount of time between regenerations - */ - public int getRegenTime() { - return regenTime; - } - - public Material getMaterial() { - return material; - } - - /** - * Gets the name of the bastion type - * This is used to reduce space in maps elsewhere - * @return The name of this bastion type - */ - public String getName() { - return name; - } - - /** - * @return true if the bastion should prevent citadel reinforcements - */ - public boolean isBlockReinforcements() { - return blockReinforcements; - } + /** + * @return true if a bastion can only be removed by destroying the block itself. + */ + public boolean isOnlyDirectDestruction() { + return onlyDirectDestruction; + } - @Override - public int hashCode() { - return name.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if(!(obj instanceof BastionType)) return false; - BastionType other = (BastionType) obj; - return other.getName().equals(name); - } - - /** - * Creates an item representation of the bastion type - * @return The bastion item - */ - public ItemStack getItemRepresentation() { - ItemStack is = new ItemStack(material); - if ((lore == null || lore.size() == 0) && itemName == null) return is; + /** + * @return true if the bastion blocks pearls + */ + public boolean isBlockPearls() { + return blockPearls; + } - ItemMeta im = is.hasItemMeta() ? is.getItemMeta() : Bukkit.getItemFactory().getItemMeta(material); - if (im == null) { - Bastion.getPlugin().getLogger().log(Level.WARNING, "Invalid Bastion configuration, unable to represent as an item for {0}", name); - return is; - } - if (lore != null) { - im.setLore(lore); - } - if (itemName != null) { - im.setDisplayName(itemName); - } - is.setItemMeta(im); - //Bastion.getPlugin().getLogger().log(Level.INFO, "Bastion {0} represented as {1}", new Object[] {name, is.toString()}); - return is; - } + /** + * @return true if the bastion blocks midair rather than when the pearl lands + */ + public boolean isBlockMidair() { + return blockMidair; + } - public static void loadBastionTypes(ConfigurationSection config) { - for(String key : config.getKeys(false)) { - Bastion.getPlugin().getLogger().log(Level.INFO, "Loading Bastion type {0}", key); - BastionType type = getBastionType(config.getConfigurationSection(key)); - if(type != null) { - if(defaultType == null) defaultType = key; - types.put(key, type); - Bastion.getPlugin().getLogger().log(Level.INFO, "Bastion type {0} loaded: {1}", new Object[]{key, type}); - } - } - } - - public static void startRegenAndErosionTasks() { - for(BastionType type : types.values()) { - if(type.erosionTime > 0) { - new BukkitRunnable() { - @Override - public void run() { - Bastion.getPlugin().getLogger().log(Level.INFO, "Erosion task begin, found " + - Bastion.getBastionStorage().getBastionsForType(type).size() + " to erode"); - for(BastionBlock bastion : Bastion.getBastionStorage().getBastionsForType(type)) { - bastion.erode(1); - } - Bastion.getPlugin().getLogger().log(Level.INFO, "Erosion task ended, after erosion " + - Bastion.getBastionStorage().getBastionsForType(type).size() + " remain"); - } - }.runTaskTimerAsynchronously(Bastion.getPlugin(), type.erosionTime, type.erosionTime); - } - if(type.regenTime > 0) { - new BukkitRunnable() { - @Override - public void run() { - Bastion.getPlugin().getLogger().log(Level.INFO, "Regen task begin, found " + - Bastion.getBastionStorage().getBastionsForType(type).size() + " to regen"); - for(BastionBlock bastion : Bastion.getBastionStorage().getBastionsForType(type)) { - bastion.regen(); - } - Bastion.getPlugin().getLogger().log(Level.INFO, "Regen task ended, after regen " + - Bastion.getBastionStorage().getBastionsForType(type).size() + " remain"); + /** + * @return The scale for increased bastion damage from pearls + */ + public int getPearlScaleFactor() { + return pearlScale; + } - } - }.runTaskTimerAsynchronously(Bastion.getPlugin(), type.regenTime, type.regenTime); - } - } - } - - public static BastionType getBastionType(String name) { - return types.get(name); - } - - public static BastionType getBastionType(Material mat, String itemName, List lore) { - if (lore != null && lore.size() == 0) lore = null; - for (BastionType type : types.values()) { - //StringBuilder sb = new StringBuilder(); - boolean test = type.material.equals(mat); - //sb.append(type.getName()).append(" is").append(test ? " " : "n't ").append(mat); - test &= ((itemName == null && type.itemName == null) || (type.itemName != null && type.itemName.equals(itemName))); - //sb.append(" name is ").append(itemName).append(test ? " = " : " not ").append(type.itemName); - test &= ((lore == null && (type.lore == null || type.lore.size() == 0)) || (type.lore != null && type.lore.equals(lore))); - //sb.append(" lore is ").append(lore).append(test ? " = " : " not ").append(type.lore); - //Bastion.getPlugin().getLogger().log(Level.INFO, "BastionType check {0}", sb); - if (test) return type; - } - return null; - } - - /** - * - * @return The radius of the largest bastion type - */ - public static int getMaxRadius() { - return maxRadius; - } - - public boolean isDestroyOnRemoveWhileImmature() { - return destroyOnRemoveWhileImmature; - } - - /** - * - * @return The default bastion type - */ - public static String getDefaultType() { - return defaultType; - } - - public int getProximityDamageRange() { - return proximityDamageRange; - } - - public double getProximityDamageFactor() { - return proximityDamageFactor; - } - - public static BastionType getBastionType(ConfigurationSection config) { - String name = config.getName(); - Material material = Material.getMaterial(config.getString("block.material")); - if(!material.isBlock()) { - return null; - } - String itemName = config.getString("block.name"); - List lore = config.getStringList("block.lore"); - String shortName = config.getString("shortName"); - boolean square = config.getBoolean("squarefield"); - int effectRadius = config.getInt("effectRadius"); - boolean includeY = config.getBoolean("includeY"); - int startScaleFactor = config.getInt("startScaleFactor"); - double finalScaleFactor = config.getDouble("finalScaleFactor"); - long warmupTime = config.getLong("warmupTime"); - int erosionTime = config.getInt("erosionPerDay"); - if(erosionTime > 0) { - erosionTime = 1728000 / erosionTime; - } else if(erosionTime < 0) { - erosionTime = 0; - } - long placementCooldown = config.getLong("placementCooldown"); - boolean destroyOnRemove = config.getBoolean("destroyOnRemove"); - boolean onlyDirectDestroy = config.getBoolean("onlyDirectDestroy"); - boolean blockReinforcements = config.getBoolean("blockReinforcements"); - boolean blockPearls = config.getBoolean("pearls.block"); - boolean blockMidair = config.getBoolean("pearls.blockMidair"); - boolean allowPearlingOut = config.getBoolean("pearls.allowPearlingOut"); - int scaleFactor = config.getInt("pearls.scaleFactor"); - boolean requireMaturity = config.getBoolean("pearls.requireMaturity"); - boolean consumeOnBlock = config.getBoolean("pearls.consumeOnBlock"); - boolean damageFirstBastion = config.getBoolean("pearls.damageFirstBastion"); - int blocksToErode = config.getInt("blocksToErode"); - boolean blockElytra = config.getBoolean("elytra.block"); - boolean destroyElytra = config.getBoolean("elytra.destroyOnBlock"); - boolean damageElytra = config.getBoolean("elytra.damageOnBlock"); - int elytraScale = config.getInt("elytra.scaleFactor"); - boolean elytraRequireMature = config.getBoolean("elytra.requireMaturity"); - int regenTime = config.getInt("regenPerDay"); - int proximityDamageRange = config.getInt("proximityDamageRange", 0); - double proximityDamageFactor = config.getDouble("proximityDamageFactor", 0.5); - if(regenTime > 0) { - regenTime = 1728000 / regenTime; - } else if(regenTime < 0) { - regenTime = 0; - } - boolean explodeOnBlock = config.getBoolean("elytra.explodeOnBlock"); - double explodeOnBlockStrength = config.getDouble("elytra.explodeOnBlockStrength"); - boolean destroyOnRemoveWhileImmature = config.getBoolean("destroyOnRemoveWhileImmature", true); - String overlayName = config.getString("overlay_name"); - return new BastionType(name, itemName, material, lore, shortName, square, effectRadius, includeY, startScaleFactor, finalScaleFactor, warmupTime, - erosionTime, placementCooldown, destroyOnRemove, blockPearls, blockMidair, scaleFactor, requireMaturity, consumeOnBlock, - blocksToErode, blockElytra, destroyElytra, damageElytra, elytraScale, elytraRequireMature, explodeOnBlock, - explodeOnBlockStrength, damageFirstBastion, regenTime, onlyDirectDestroy, allowPearlingOut, blockReinforcements, destroyOnRemoveWhileImmature, - proximityDamageRange, proximityDamageFactor, overlayName); - } + /** + * @return true if the bastion must be mature to block pearls + */ + public boolean isRequireMaturity() { + return pearlRequireMature; + } - @Override - public String toString() { - StringBuilder sb = new StringBuilder(this.name); - sb.append(": ").append(material) - .append(" name:").append(itemName) - .append(" lore[").append(lore != null ? lore.size() : 0).append("]: ").append(lore) - .append(" scale[").append(this.startScaleFactor).append("->").append(this.finalScaleFactor) - .append(" ").append(this.effectRadius).append(this.square ? "cb": "r") - .append(" wm").append(this.warmupTime).append(" cd").append(this.placementCooldown) - .append(" ed").append(this.erosionTime).append(" rd").append(this.regenTime) - .append(" iY").append(this.includeY).append(" bte").append(this.blocksToErode) - .append(" doR").append(this.destroyOnRemove).append(" oDD").append(this.onlyDirectDestruction) - .append(" pearls[").append(this.blockPearls); - if (this.blockPearls) { - sb.append(": mid").append(this.blockMidair).append(" rM").append(this.pearlRequireMature) - .append(" sc").append(this.pearlScale).append(" cob").append(this.consumeOnBlock) - .append(" dfB").append(this.damageFirstBastion).append(" apo").append(allowPearlingOut); - } - sb.append("] elytra[").append(this.blockElytra); - if (this.blockElytra) { - sb.append(": rM").append(this.elytraRequireMature).append(" sc").append(this.elytraScale) - .append(" dob").append(this.damageElytra).append(" Dob").append(this.destroyElytra) - .append(" eob").append(this.explodeOnBlock).append(" eos").append(this.explodeOnBlockStrength); - } - sb.append("]"); - return sb.toString(); - } + /** + * @return true if pearls are consumed when blocked by bastion + */ + public boolean isConsumeOnBlock() { + return consumeOnBlock; + } + + /** + * @return The number of bastions that should be eroded from a block place + */ + public int getBlocksToErode() { + return blocksToErode; + } + + /** + * @return The cooldown for damaging a bastion + */ + public long getPlacementCooldown() { + return placementCooldown; + } + + /** + * @return true if the bastion blocks elytra + */ + public boolean isBlockElytra() { + return blockElytra; + } + + /** + * @return true if the bastion destroys elytra + */ + public boolean isDestroyElytra() { + return destroyElytra; + } + + /** + * @return true if the bastion just damages elytra + */ + public boolean isDamageElytra() { + return damageElytra; + } + + /** + * @return The scale for increased damage from elytra collision + */ + public int getElytraScale() { + return elytraScale; + } + + /** + * @return true if bastion must be mature to block elytra + */ + public boolean isElytraRequireMature() { + return elytraRequireMature; + } + + /** + * @return true if there should be an explosion on elytra colision + */ + public boolean isExplodeOnBlock() { + return explodeOnBlock; + } + + /** + * @return the strength of the explosion on elytra collision + */ + public double getExplosionStrength() { + return explodeOnBlockStrength; + } + + /** + * @return true if only the first bastion hit should be damaged by pearls + */ + public boolean damageFirstBastion() { + return damageFirstBastion; + } + + /** + * @return The amount of time between regenerations + */ + public int getRegenTime() { + return regenTime; + } + + public Material getMaterial() { + return material; + } + + /** + * Gets the name of the bastion type + * This is used to reduce space in maps elsewhere + * + * @return The name of this bastion type + */ + public String getName() { + return name; + } + + /** + * @return true if the bastion should prevent citadel reinforcements + */ + public boolean isBlockReinforcements() { + return blockReinforcements; + } + + @Override + public int hashCode() { + return name.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof BastionType)) return false; + BastionType other = (BastionType) obj; + return other.getName().equals(name); + } + + /** + * Creates an item representation of the bastion type + * + * @return The bastion item + */ + public ItemStack getItemRepresentation() { + ItemStack is = new ItemStack(material); + if ((lore == null || lore.size() == 0) && itemName == null) return is; + + ItemMeta im = is.hasItemMeta() ? is.getItemMeta() : Bukkit.getItemFactory().getItemMeta(material); + if (im == null) { + Bastion.getPlugin().getLogger().log(Level.WARNING, "Invalid Bastion configuration, unable to represent as an item for {0}", name); + return is; + } + if (lore != null) { + im.setLore(lore); + } + if (itemName != null) { + im.setDisplayName(itemName); + } + is.setItemMeta(im); + //Bastion.getPlugin().getLogger().log(Level.INFO, "Bastion {0} represented as {1}", new Object[] {name, is.toString()}); + return is; + } + + public static void loadBastionTypes(ConfigurationSection config) { + for (String key : config.getKeys(false)) { + Bastion.getPlugin().getLogger().log(Level.INFO, "Loading Bastion type {0}", key); + BastionType type = getBastionType(config.getConfigurationSection(key)); + if (type != null) { + if (defaultType == null) defaultType = key; + types.put(key, type); + Bastion.getPlugin().getLogger().log(Level.INFO, "Bastion type {0} loaded: {1}", new Object[]{key, type}); + } + } + } + + public static void startRegenAndErosionTasks() { + for (BastionType type : types.values()) { + if (type.erosionTime > 0) { + new BukkitRunnable() { + @Override + public void run() { + Bastion.getPlugin().getLogger().log(Level.INFO, "Erosion task begin, found " + + Bastion.getBastionStorage().getBastionsForType(type).size() + " to erode"); + for (BastionBlock bastion : Bastion.getBastionStorage().getBastionsForType(type)) { + bastion.erode(1); + } + Bastion.getPlugin().getLogger().log(Level.INFO, "Erosion task ended, after erosion " + + Bastion.getBastionStorage().getBastionsForType(type).size() + " remain"); + } + }.runTaskTimerAsynchronously(Bastion.getPlugin(), type.erosionTime, type.erosionTime); + } + if (type.regenTime > 0) { + new BukkitRunnable() { + @Override + public void run() { + Bastion.getPlugin().getLogger().log(Level.INFO, "Regen task begin, found " + + Bastion.getBastionStorage().getBastionsForType(type).size() + " to regen"); + for (BastionBlock bastion : Bastion.getBastionStorage().getBastionsForType(type)) { + bastion.regen(); + } + Bastion.getPlugin().getLogger().log(Level.INFO, "Regen task ended, after regen " + + Bastion.getBastionStorage().getBastionsForType(type).size() + " remain"); + + } + }.runTaskTimerAsynchronously(Bastion.getPlugin(), type.regenTime, type.regenTime); + } + } + } + + public static BastionType getBastionType(String name) { + return types.get(name); + } + + public static BastionType getBastionType(Material mat, String itemName, List lore) { + if (lore != null && lore.size() == 0) lore = null; + for (BastionType type : types.values()) { + //StringBuilder sb = new StringBuilder(); + boolean test = type.material.equals(mat); + //sb.append(type.getName()).append(" is").append(test ? " " : "n't ").append(mat); + test &= ((itemName == null && type.itemName == null) || (type.itemName != null && type.itemName.equals(itemName))); + //sb.append(" name is ").append(itemName).append(test ? " = " : " not ").append(type.itemName); + test &= ((lore == null && (type.lore == null || type.lore.size() == 0)) || (type.lore != null && type.lore.equals(lore))); + //sb.append(" lore is ").append(lore).append(test ? " = " : " not ").append(type.lore); + //Bastion.getPlugin().getLogger().log(Level.INFO, "BastionType check {0}", sb); + if (test) return type; + } + return null; + } + + /** + * @return The radius of the largest bastion type + */ + public static int getMaxRadius() { + return maxRadius; + } + + public boolean isDestroyOnRemoveWhileImmature() { + return destroyOnRemoveWhileImmature; + } + + /** + * @return The default bastion type + */ + public static String getDefaultType() { + return defaultType; + } + + public int getProximityDamageRange() { + return proximityDamageRange; + } + + public double getProximityDamageFactor() { + return proximityDamageFactor; + } + + public static BastionType getBastionType(ConfigurationSection config) { + String name = config.getName(); + Material material = Material.getMaterial(config.getString("block.material")); + if (!material.isBlock()) { + return null; + } + String itemName = config.getString("block.name"); + List lore = config.getStringList("block.lore"); + String shortName = config.getString("shortName"); + boolean square = config.getBoolean("squarefield"); + int effectRadius = config.getInt("effectRadius"); + boolean includeY = config.getBoolean("includeY"); + int startScaleFactor = config.getInt("startScaleFactor"); + double finalScaleFactor = config.getDouble("finalScaleFactor"); + long warmupTime = config.getLong("warmupTime"); + int erosionTime = config.getInt("erosionPerDay"); + if (erosionTime > 0) { + erosionTime = 1728000 / erosionTime; + } else if (erosionTime < 0) { + erosionTime = 0; + } + long placementCooldown = config.getLong("placementCooldown"); + boolean destroyOnRemove = config.getBoolean("destroyOnRemove"); + boolean onlyDirectDestroy = config.getBoolean("onlyDirectDestroy"); + boolean blockReinforcements = config.getBoolean("blockReinforcements"); + boolean blockPearls = config.getBoolean("pearls.block"); + boolean blockMidair = config.getBoolean("pearls.blockMidair"); + boolean allowPearlingOut = config.getBoolean("pearls.allowPearlingOut"); + int scaleFactor = config.getInt("pearls.scaleFactor"); + boolean requireMaturity = config.getBoolean("pearls.requireMaturity"); + boolean consumeOnBlock = config.getBoolean("pearls.consumeOnBlock"); + boolean damageFirstBastion = config.getBoolean("pearls.damageFirstBastion"); + int blocksToErode = config.getInt("blocksToErode"); + boolean blockElytra = config.getBoolean("elytra.block"); + boolean destroyElytra = config.getBoolean("elytra.destroyOnBlock"); + boolean damageElytra = config.getBoolean("elytra.damageOnBlock"); + int elytraScale = config.getInt("elytra.scaleFactor"); + boolean elytraRequireMature = config.getBoolean("elytra.requireMaturity"); + int regenTime = config.getInt("regenPerDay"); + int proximityDamageRange = config.getInt("proximityDamageRange", 0); + double proximityDamageFactor = config.getDouble("proximityDamageFactor", 0.5); + if (regenTime > 0) { + regenTime = 1728000 / regenTime; + } else if (regenTime < 0) { + regenTime = 0; + } + boolean explodeOnBlock = config.getBoolean("elytra.explodeOnBlock"); + double explodeOnBlockStrength = config.getDouble("elytra.explodeOnBlockStrength"); + boolean destroyOnRemoveWhileImmature = config.getBoolean("destroyOnRemoveWhileImmature", true); + String overlayName = config.getString("overlay_name"); + return new BastionType(name, itemName, material, lore, shortName, square, effectRadius, includeY, startScaleFactor, finalScaleFactor, warmupTime, + erosionTime, placementCooldown, destroyOnRemove, blockPearls, blockMidair, scaleFactor, requireMaturity, consumeOnBlock, + blocksToErode, blockElytra, destroyElytra, damageElytra, elytraScale, elytraRequireMature, explodeOnBlock, + explodeOnBlockStrength, damageFirstBastion, regenTime, onlyDirectDestroy, allowPearlingOut, blockReinforcements, destroyOnRemoveWhileImmature, + proximityDamageRange, proximityDamageFactor, overlayName); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(this.name); + sb.append(": ").append(material) + .append(" name:").append(itemName) + .append(" lore[").append(lore != null ? lore.size() : 0).append("]: ").append(lore) + .append(" scale[").append(this.startScaleFactor).append("->").append(this.finalScaleFactor) + .append(" ").append(this.effectRadius).append(this.square ? "cb" : "r") + .append(" wm").append(this.warmupTime).append(" cd").append(this.placementCooldown) + .append(" ed").append(this.erosionTime).append(" rd").append(this.regenTime) + .append(" iY").append(this.includeY).append(" bte").append(this.blocksToErode) + .append(" doR").append(this.destroyOnRemove).append(" oDD").append(this.onlyDirectDestruction) + .append(" pearls[").append(this.blockPearls); + if (this.blockPearls) { + sb.append(": mid").append(this.blockMidair).append(" rM").append(this.pearlRequireMature) + .append(" sc").append(this.pearlScale).append(" cob").append(this.consumeOnBlock) + .append(" dfB").append(this.damageFirstBastion).append(" apo").append(allowPearlingOut); + } + sb.append("] elytra[").append(this.blockElytra); + if (this.blockElytra) { + sb.append(": rM").append(this.elytraRequireMature).append(" sc").append(this.elytraScale) + .append(" dob").append(this.damageElytra).append(" Dob").append(this.destroyElytra) + .append(" eob").append(this.explodeOnBlock).append(" eos").append(this.explodeOnBlockStrength); + } + sb.append("]"); + return sb.toString(); + } } diff --git a/plugins/bastion-paper/src/main/java/isaac/bastion/CommonSettings.java b/plugins/bastion-paper/src/main/java/isaac/bastion/CommonSettings.java index 851bcd7fb..f6ccffd31 100644 --- a/plugins/bastion-paper/src/main/java/isaac/bastion/CommonSettings.java +++ b/plugins/bastion-paper/src/main/java/isaac/bastion/CommonSettings.java @@ -11,34 +11,35 @@ import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; public class CommonSettings { - private boolean cancelReinforcementModeInBastionField; - private int listBastionTimeout; - private Set cancelPlacementAndDamage; - public boolean isCancelReinforcementModeInBastionField() { - return this.cancelReinforcementModeInBastionField; - } + private boolean cancelReinforcementModeInBastionField; + private int listBastionTimeout; + private Set cancelPlacementAndDamage; - public int getListBastionTimeout() { - return this.listBastionTimeout; - } + public boolean isCancelReinforcementModeInBastionField() { + return this.cancelReinforcementModeInBastionField; + } - public Set getCancelPlacementAndDamage() { - return this.cancelPlacementAndDamage; - } + public int getListBastionTimeout() { + return this.listBastionTimeout; + } - public static CommonSettings load(ConfigurationSection config) { - CommonSettings settings = new CommonSettings(); - settings.cancelReinforcementModeInBastionField = config.getBoolean("cancelReinforcementModeInBastionField", false); - settings.listBastionTimeout = config.getInt("listBastionTimeout", 2000); - List materialNames = config.getStringList("cancelPlacementAndDamage"); - settings.cancelPlacementAndDamage = new HashSet<>(); - for (String name : materialNames) { - Material m = Material.matchMaterial(name); - if (m != null) { - settings.cancelPlacementAndDamage.add(m); - } - } - return settings; - } + public Set getCancelPlacementAndDamage() { + return this.cancelPlacementAndDamage; + } + + public static CommonSettings load(ConfigurationSection config) { + CommonSettings settings = new CommonSettings(); + settings.cancelReinforcementModeInBastionField = config.getBoolean("cancelReinforcementModeInBastionField", false); + settings.listBastionTimeout = config.getInt("listBastionTimeout", 2000); + List materialNames = config.getStringList("cancelPlacementAndDamage"); + settings.cancelPlacementAndDamage = new HashSet<>(); + for (String name : materialNames) { + Material m = Material.matchMaterial(name); + if (m != null) { + settings.cancelPlacementAndDamage.add(m); + } + } + return settings; + } } diff --git a/plugins/bastion-paper/src/main/java/isaac/bastion/Permissions.java b/plugins/bastion-paper/src/main/java/isaac/bastion/Permissions.java index abf1be929..c3356b9db 100644 --- a/plugins/bastion-paper/src/main/java/isaac/bastion/Permissions.java +++ b/plugins/bastion-paper/src/main/java/isaac/bastion/Permissions.java @@ -5,9 +5,10 @@ package isaac.bastion; public class Permissions { - public static final String BASTION_PEARL = "BASTION_PEARL"; - public static final String BASTION_PLACE = "BASTION_PLACE"; - public static final String BASTION_LIST = "BASTION_LIST"; - public static final String BASTION_MANAGE_GROUPS = "BASTION_MANAGE_GROUPS"; - public static final String BASTION_ELYTRA = "BASTION_ELYTRA"; + + public static final String BASTION_PEARL = "BASTION_PEARL"; + public static final String BASTION_PLACE = "BASTION_PLACE"; + public static final String BASTION_LIST = "BASTION_LIST"; + public static final String BASTION_MANAGE_GROUPS = "BASTION_MANAGE_GROUPS"; + public static final String BASTION_ELYTRA = "BASTION_ELYTRA"; } diff --git a/plugins/bastion-paper/src/main/java/isaac/bastion/commands/BastionCommandManager.java b/plugins/bastion-paper/src/main/java/isaac/bastion/commands/BastionCommandManager.java index a02c6d797..405a858d5 100644 --- a/plugins/bastion-paper/src/main/java/isaac/bastion/commands/BastionCommandManager.java +++ b/plugins/bastion-paper/src/main/java/isaac/bastion/commands/BastionCommandManager.java @@ -10,37 +10,37 @@ import org.bukkit.command.CommandSender; public class BastionCommandManager implements CommandExecutor { - @Override - public boolean onCommand(CommandSender sender, Command command, - String label, String[] args) { - if(args.length>0){ - if(args[0].equalsIgnoreCase("License")){ - InputStream input = getClass().getResourceAsStream("/License.txt"); - sender.sendMessage(convertStreamToString(input)); - return true; - } else if(args[0].equalsIgnoreCase("about")){ - sender.sendMessage(ChatColor.GREEN+"Bastion version "+Bastion.getPlugin().getDescription().getVersion()); - return true; - } - } - return false; - } - - @SuppressWarnings("resource") - public static String convertStreamToString(InputStream is) { - if (is == null) { - return ""; - } - Scanner s = new Scanner(is).useDelimiter("\\A"); - String ret = ""; - try { - ret = s.hasNext() ? s.next() : ""; - } catch (IllegalStateException ise) { - ret = ""; - } finally { - s.close(); - ret = ""; - } - return ret; - } + @Override + public boolean onCommand(CommandSender sender, Command command, + String label, String[] args) { + if (args.length > 0) { + if (args[0].equalsIgnoreCase("License")) { + InputStream input = getClass().getResourceAsStream("/License.txt"); + sender.sendMessage(convertStreamToString(input)); + return true; + } else if (args[0].equalsIgnoreCase("about")) { + sender.sendMessage(ChatColor.GREEN + "Bastion version " + Bastion.getPlugin().getDescription().getVersion()); + return true; + } + } + return false; + } + + @SuppressWarnings("resource") + public static String convertStreamToString(InputStream is) { + if (is == null) { + return ""; + } + Scanner s = new Scanner(is).useDelimiter("\\A"); + String ret = ""; + try { + ret = s.hasNext() ? s.next() : ""; + } catch (IllegalStateException ise) { + ret = ""; + } finally { + s.close(); + ret = ""; + } + return ret; + } } diff --git a/plugins/bastion-paper/src/main/java/isaac/bastion/commands/ModeChangeCommand.java b/plugins/bastion-paper/src/main/java/isaac/bastion/commands/ModeChangeCommand.java index fb9e403c8..dce281075 100644 --- a/plugins/bastion-paper/src/main/java/isaac/bastion/commands/ModeChangeCommand.java +++ b/plugins/bastion-paper/src/main/java/isaac/bastion/commands/ModeChangeCommand.java @@ -11,41 +11,41 @@ import org.bukkit.event.block.Action; import org.bukkit.event.player.PlayerInteractEvent; public class ModeChangeCommand implements CommandExecutor { - - PlayersStates.Mode mode; - - public ModeChangeCommand(PlayersStates.Mode mode){ - this.mode = mode; - } - // TODO: Add World Aware. - @Override - public boolean onCommand(CommandSender sender, Command command, String arg2, - String[] arguments) { - if (!(sender instanceof Player)) { - return false; - } - - PlayersStates.toggleModeForPlayer((Player) sender, mode); - - if (sender.hasPermission("Bastion.dev")) { - if (arguments.length >= 3) { - try { - Integer x = Integer.parseInt(arguments[0]); - Integer y = Integer.parseInt(arguments[1]); - Integer z = Integer.parseInt(arguments[2]); - Player player = (Player) sender; - Bukkit.getServer().getPluginManager().callEvent( - new PlayerInteractEvent(player, Action.RIGHT_CLICK_BLOCK, - player.getInventory().getItemInMainHand(), new Location(player.getLocation().getWorld(), - x, y - 1, z).getBlock(), BlockFace.UP )); - } catch (NumberFormatException e) { - sender.sendMessage("One of the arguments you provided was not a number"); - } - } - } - - return true; - } + PlayersStates.Mode mode; + + public ModeChangeCommand(PlayersStates.Mode mode) { + this.mode = mode; + } + + // TODO: Add World Aware. + @Override + public boolean onCommand(CommandSender sender, Command command, String arg2, + String[] arguments) { + if (!(sender instanceof Player)) { + return false; + } + + PlayersStates.toggleModeForPlayer((Player) sender, mode); + + if (sender.hasPermission("Bastion.dev")) { + if (arguments.length >= 3) { + try { + Integer x = Integer.parseInt(arguments[0]); + Integer y = Integer.parseInt(arguments[1]); + Integer z = Integer.parseInt(arguments[2]); + Player player = (Player) sender; + Bukkit.getServer().getPluginManager().callEvent( + new PlayerInteractEvent(player, Action.RIGHT_CLICK_BLOCK, + player.getInventory().getItemInMainHand(), new Location(player.getLocation().getWorld(), + x, y - 1, z).getBlock(), BlockFace.UP)); + } catch (NumberFormatException e) { + sender.sendMessage("One of the arguments you provided was not a number"); + } + } + } + + return true; + } } diff --git a/plugins/bastion-paper/src/main/java/isaac/bastion/commands/PlayersStates.java b/plugins/bastion-paper/src/main/java/isaac/bastion/commands/PlayersStates.java index ef2a5af1a..c5f4801a8 100644 --- a/plugins/bastion-paper/src/main/java/isaac/bastion/commands/PlayersStates.java +++ b/plugins/bastion-paper/src/main/java/isaac/bastion/commands/PlayersStates.java @@ -8,57 +8,61 @@ import org.bukkit.ChatColor; import org.bukkit.entity.Player; public class PlayersStates { - static public enum Mode { - NORMAL,INFO,DELETE,OFF,BASTION,MATURE - } - static private Map playersModes = new HashMap<>(); - static private Map playersCallback = new HashMap<>(); - static public boolean playerInMode(Player player, Mode mode){ - Mode result = playersModes.get(player.getUniqueId()); - return result == mode; - } + static public enum Mode { + NORMAL, INFO, DELETE, OFF, BASTION, MATURE + } - static private class CallBack implements Runnable{ - private UUID forPlayer; - private Mode forMode; - public CallBack(UUID player,Mode mode){ - forPlayer = player; - forMode = mode; - } + static private Map playersModes = new HashMap<>(); + static private Map playersCallback = new HashMap<>(); - @Override - public void run() { - try { - PlayersStates.setModeForPlayer(Bastion.getPlugin().getServer().getPlayer(forPlayer), forMode); - } catch (NullPointerException e) { - // TODO: player offline perhaps? do something here. - } - } - } + static public boolean playerInMode(Player player, Mode mode) { + Mode result = playersModes.get(player.getUniqueId()); + return result == mode; + } - public static void setModeForPlayer(Player player, Mode mode){ - if (mode==null) { - mode = Mode.NORMAL; - } - - UUID pid = player.getUniqueId(); - - Mode old = playersModes.get(pid); - - if (old != null && old != mode && old != Mode.NORMAL) { - player.sendMessage(ChatColor.YELLOW + "Bastion " + old.name() + " mode off"); - } - player.sendMessage(ChatColor.GREEN + "Bastion " + mode.name() + " mode on"); + static private class CallBack implements Runnable { - playersModes.put(pid, mode); - } - - public static void toggleModeForPlayer(Player player, Mode mode) { - Mode old = playersModes.get(player.getUniqueId()); - if (old == mode) { - mode = Mode.NORMAL; - } - setModeForPlayer(player, mode); - } + private UUID forPlayer; + private Mode forMode; + + public CallBack(UUID player, Mode mode) { + forPlayer = player; + forMode = mode; + } + + @Override + public void run() { + try { + PlayersStates.setModeForPlayer(Bastion.getPlugin().getServer().getPlayer(forPlayer), forMode); + } catch (NullPointerException e) { + // TODO: player offline perhaps? do something here. + } + } + } + + public static void setModeForPlayer(Player player, Mode mode) { + if (mode == null) { + mode = Mode.NORMAL; + } + + UUID pid = player.getUniqueId(); + + Mode old = playersModes.get(pid); + + if (old != null && old != mode && old != Mode.NORMAL) { + player.sendMessage(ChatColor.YELLOW + "Bastion " + old.name() + " mode off"); + } + player.sendMessage(ChatColor.GREEN + "Bastion " + mode.name() + " mode on"); + + playersModes.put(pid, mode); + } + + public static void toggleModeForPlayer(Player player, Mode mode) { + Mode old = playersModes.get(player.getUniqueId()); + if (old == mode) { + mode = Mode.NORMAL; + } + setModeForPlayer(player, mode); + } } diff --git a/plugins/bastion-paper/src/main/java/isaac/bastion/event/BastionCreateEvent.java b/plugins/bastion-paper/src/main/java/isaac/bastion/event/BastionCreateEvent.java index 49ddcf18a..d2aaf3fde 100644 --- a/plugins/bastion-paper/src/main/java/isaac/bastion/event/BastionCreateEvent.java +++ b/plugins/bastion-paper/src/main/java/isaac/bastion/event/BastionCreateEvent.java @@ -8,59 +8,64 @@ import org.bukkit.event.player.PlayerEvent; /** * Event that gets fired when a bastion is created + * * @author Gordon */ public class BastionCreateEvent extends PlayerEvent implements Cancellable { - - private final BastionBlock bastion; - - private boolean cancelled; - - // Handler list for spigot events - private static final HandlerList handlers = new HandlerList(); - - /** - * Creates a new BastionCreateEvent instance - * @param bastion The bastion instance - * @param player The player creating the bastion - */ - public BastionCreateEvent(final BastionBlock bastion, final Player player) { - super(player); - this.bastion = bastion; - } - - /** - * Gets the created bastion - * @return The created bastion - */ - public BastionBlock getBastion() { - return bastion; - } - - /** - * Gets whether the event is cancelled - * @return true if the event is cancelled - */ - @Override - public boolean isCancelled() { - return cancelled; - } - - /** - * Sets whether the event is cancelled - * @param cancelled whether the event is cancelled - */ - @Override - public void setCancelled(boolean cancelled) { - this.cancelled = cancelled; - } - - @Override - public HandlerList getHandlers() { - return handlers; - } - - public static HandlerList getHandlerList() { - return handlers; - } + + private final BastionBlock bastion; + + private boolean cancelled; + + // Handler list for spigot events + private static final HandlerList handlers = new HandlerList(); + + /** + * Creates a new BastionCreateEvent instance + * + * @param bastion The bastion instance + * @param player The player creating the bastion + */ + public BastionCreateEvent(final BastionBlock bastion, final Player player) { + super(player); + this.bastion = bastion; + } + + /** + * Gets the created bastion + * + * @return The created bastion + */ + public BastionBlock getBastion() { + return bastion; + } + + /** + * Gets whether the event is cancelled + * + * @return true if the event is cancelled + */ + @Override + public boolean isCancelled() { + return cancelled; + } + + /** + * Sets whether the event is cancelled + * + * @param cancelled whether the event is cancelled + */ + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } } diff --git a/plugins/bastion-paper/src/main/java/isaac/bastion/event/BastionDamageEvent.java b/plugins/bastion-paper/src/main/java/isaac/bastion/event/BastionDamageEvent.java index 2451a05ef..78dea79c8 100644 --- a/plugins/bastion-paper/src/main/java/isaac/bastion/event/BastionDamageEvent.java +++ b/plugins/bastion-paper/src/main/java/isaac/bastion/event/BastionDamageEvent.java @@ -8,81 +8,89 @@ import org.bukkit.event.player.PlayerEvent; /** * Event that gets fired when a bastion is damaged + * * @author Gordon */ public class BastionDamageEvent extends PlayerEvent implements Cancellable { - public enum Cause { BLOCK_PLACED, PEARL, ELYTRA } - - private final BastionBlock bastion; - private final Cause cause; - private final double damage; - - private boolean cancelled; - - // Handler list for spigot events - private static final HandlerList handlers = new HandlerList(); - - /** - * Creates a new BastionDamageEvent instance - * @param bastion The damaged bastion instance - * @param player The damaging player - * @param cause The damage cause - */ - public BastionDamageEvent(final BastionBlock bastion, final Player player, final Cause cause, final double damage) { - super(player); - this.bastion = bastion; - this.cause = cause; - this.damage = damage; - } - - /** - * Gets the damaged bastion - * @return The damaged bastion - */ - public BastionBlock getBastion() { - return bastion; - } - - /** - * Gets the damage cause - * @return The damage cause - */ - public Cause getCause() { - return cause; - } - - /** - * Gets the amount of damage to the bastion - * @return The amount of damage - */ - public double getDamage() { - return damage; - } - - /** - * Gets whether the event is cancelled - * @return true if the event is cancelled - */ - @Override - public boolean isCancelled() { - return cancelled; - } - - /** - * Sets whether the event is cancelled - * @param cancelled whether the event is cancelled - */ - @Override - public void setCancelled(boolean cancelled) { - this.cancelled = cancelled; - } - - @Override - public HandlerList getHandlers() { - return handlers; - } - - public static HandlerList getHandlerList() { - return handlers; - } + + public enum Cause {BLOCK_PLACED, PEARL, ELYTRA} + + private final BastionBlock bastion; + private final Cause cause; + private final double damage; + + private boolean cancelled; + + // Handler list for spigot events + private static final HandlerList handlers = new HandlerList(); + + /** + * Creates a new BastionDamageEvent instance + * + * @param bastion The damaged bastion instance + * @param player The damaging player + * @param cause The damage cause + */ + public BastionDamageEvent(final BastionBlock bastion, final Player player, final Cause cause, final double damage) { + super(player); + this.bastion = bastion; + this.cause = cause; + this.damage = damage; + } + + /** + * Gets the damaged bastion + * + * @return The damaged bastion + */ + public BastionBlock getBastion() { + return bastion; + } + + /** + * Gets the damage cause + * + * @return The damage cause + */ + public Cause getCause() { + return cause; + } + + /** + * Gets the amount of damage to the bastion + * + * @return The amount of damage + */ + public double getDamage() { + return damage; + } + + /** + * Gets whether the event is cancelled + * + * @return true if the event is cancelled + */ + @Override + public boolean isCancelled() { + return cancelled; + } + + /** + * Sets whether the event is cancelled + * + * @param cancelled whether the event is cancelled + */ + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } } diff --git a/plugins/bastion-paper/src/main/java/isaac/bastion/event/BastionDestroyedEvent.java b/plugins/bastion-paper/src/main/java/isaac/bastion/event/BastionDestroyedEvent.java index c55106237..daeb169ab 100644 --- a/plugins/bastion-paper/src/main/java/isaac/bastion/event/BastionDestroyedEvent.java +++ b/plugins/bastion-paper/src/main/java/isaac/bastion/event/BastionDestroyedEvent.java @@ -7,39 +7,42 @@ import org.bukkit.event.player.PlayerEvent; /** * Event that gets fired when a bastion is broken + * * @author biggestnerd */ public class BastionDestroyedEvent extends PlayerEvent { - - private final BastionBlock bastion; - - //Handler list for spigot events - private static final HandlerList handlers = new HandlerList(); - - /** - * Created a new BastionDestroyedEvent instance - * @param bastion The destroyed bastion - * @param player The destroying player - */ - public BastionDestroyedEvent(BastionBlock bastion, Player player) { - super(player); - this.bastion = bastion; - } - - /** - * Gets the destroyed bastion - * @return The destroyed bastion - */ - public BastionBlock getBastion() { - return bastion; - } - - @Override - public HandlerList getHandlers() { - return handlers; - } - public static HandlerList getHandlerList() { - return handlers; - } + private final BastionBlock bastion; + + //Handler list for spigot events + private static final HandlerList handlers = new HandlerList(); + + /** + * Created a new BastionDestroyedEvent instance + * + * @param bastion The destroyed bastion + * @param player The destroying player + */ + public BastionDestroyedEvent(BastionBlock bastion, Player player) { + super(player); + this.bastion = bastion; + } + + /** + * Gets the destroyed bastion + * + * @return The destroyed bastion + */ + public BastionBlock getBastion() { + return bastion; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } } diff --git a/plugins/bastion-paper/src/main/java/isaac/bastion/listeners/BastionBreakListener.java b/plugins/bastion-paper/src/main/java/isaac/bastion/listeners/BastionBreakListener.java index 9fa944568..2af0080a9 100644 --- a/plugins/bastion-paper/src/main/java/isaac/bastion/listeners/BastionBreakListener.java +++ b/plugins/bastion-paper/src/main/java/isaac/bastion/listeners/BastionBreakListener.java @@ -29,152 +29,153 @@ import org.bukkit.util.Vector; public class BastionBreakListener implements Listener { - private BastionBlockStorage storage; - private BastionBlockManager manager; - - public BastionBreakListener(BastionBlockStorage storage, BastionBlockManager manager) { - this.storage = storage; - this.manager = manager; - } - - private void dropBastionItem(Location loc, BastionType type, Player player, TextComponent chatMessage) { - ItemStack item = type.getItemRepresentation(); - new BukkitRunnable() { - @Override - public void run() { - loc.getWorld().dropItem(loc.add(0.5, 0.5, 0.5), item).setVelocity(new Vector(0, 0.05, 0));; + private BastionBlockStorage storage; + private BastionBlockManager manager; - if(player != null && chatMessage != null) { - player.spigot().sendMessage(chatMessage); - } - } - }.runTaskLater(Bastion.getPlugin(), 1); - storage.deleteDeadBastion(loc); // just in case. - } - - @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) - public void onBlockBreak(BlockBreakEvent event) { - // we will only reach this is allowed by Citadel -- e.g. is not cancelled. - Block block = event.getBlock(); - BastionType type = storage.getTypeAtLocation(block.getLocation()); - if (type == null) { - type = storage.getAndRemovePendingBastion(block.getLocation()); - } - if(type != null) { - Bastion.getPlugin().getLogger().log(Level.INFO, "BastionType broken {0}", type.toString()); + public BastionBreakListener(BastionBlockStorage storage, BastionBlockManager manager) { + this.storage = storage; + this.manager = manager; + } - TextComponent chatMessage = null; - BastionBlock bastion = storage.getBastionBlock(block.getLocation()); - if (bastion != null) { - if(this.manager.canListBastionsForGroup(event.getPlayer(), bastion.getListGroupId())) { - chatMessage = this.manager.bastionDeletedMessageComponent(bastion); - } + private void dropBastionItem(Location loc, BastionType type, Player player, TextComponent chatMessage) { + ItemStack item = type.getItemRepresentation(); + new BukkitRunnable() { + @Override + public void run() { + loc.getWorld().dropItem(loc.add(0.5, 0.5, 0.5), item).setVelocity(new Vector(0, 0.05, 0)); + ; - bastion.destroy(); - } - event.setCancelled(true); - block.setType(Material.AIR); - dropBastionItem(block.getLocation(), type, event.getPlayer(), chatMessage); - } - } - - @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) - public void onEntityExplode(EntityExplodeEvent event) { - Iterator iterator = event.blockList().iterator(); - HashSet blocks = new HashSet<>(); - while(iterator.hasNext()) { - Block block = iterator.next(); - BastionType type = storage.getTypeAtLocation(block.getLocation()); - if (type == null) { - type = storage.getAndRemovePendingBastion(block.getLocation()); - } - if( type != null) { - if(blocks.contains(block)) { - continue; - } - blocks.add(block); - block.setType(Material.AIR); - dropBastionItem(block.getLocation(), type, null, null); - iterator.remove(); // don't explode it, we've got it covered now. - } - } - } + if (player != null && chatMessage != null) { + player.spigot().sendMessage(chatMessage); + } + } + }.runTaskLater(Bastion.getPlugin(), 1); + storage.deleteDeadBastion(loc); // just in case. + } - @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) - public void onBlockExplode(BlockExplodeEvent event) { - Iterator iterator = event.blockList().iterator(); - HashSet blocks = new HashSet<>(); - while(iterator.hasNext()) { - Block block = iterator.next(); - BastionType type = storage.getTypeAtLocation(block.getLocation()); - if (type == null) { - type = storage.getAndRemovePendingBastion(block.getLocation()); - } - if( type != null) { - if(blocks.contains(block)) { - continue; - } - blocks.add(block); - block.setType(Material.AIR); - dropBastionItem(block.getLocation(), type, null, null); - iterator.remove(); // don't explode it, we've got it covered now. - } - } - } + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onBlockBreak(BlockBreakEvent event) { + // we will only reach this is allowed by Citadel -- e.g. is not cancelled. + Block block = event.getBlock(); + BastionType type = storage.getTypeAtLocation(block.getLocation()); + if (type == null) { + type = storage.getAndRemovePendingBastion(block.getLocation()); + } + if (type != null) { + Bastion.getPlugin().getLogger().log(Level.INFO, "BastionType broken {0}", type.toString()); - @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) - public void onPistonExtend(BlockPistonExtendEvent event) { - // we will only reach this if citadel allows - for(Block block : event.getBlocks()) { - BastionType type = storage.getTypeAtLocation(block.getLocation()); - if (type == null) { - type = storage.getAndRemovePendingBastion(block.getLocation()); - } - if(type != null) { - if(block.getPistonMoveReaction() == PistonMoveReaction.BREAK) { - dropBastionItem(block.getLocation(), type, null, null); - block.setType(Material.AIR); - } else if(block.getPistonMoveReaction() == PistonMoveReaction.MOVE) { - Block toBlock = block.getRelative(event.getDirection()); - storage.moveDeadBastion(block.getLocation(), toBlock.getLocation()); - // TODO might need special handling if was pending previously - } - } - } - } - - @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) - public void onPistonRetract(BlockPistonRetractEvent event) { - if(!event.isSticky()) return; - for(Block block : event.getBlocks()) { - BastionType type = storage.getTypeAtLocation(block.getLocation()); - if (type == null) { - type = storage.getAndRemovePendingBastion(block.getLocation()); - } - if(type != null) { - if(block.getPistonMoveReaction() == PistonMoveReaction.BREAK) { - dropBastionItem(block.getLocation(), type, null, null); - block.setType(Material.AIR); - } else if(block.getPistonMoveReaction() == PistonMoveReaction.MOVE) { - Block toBlock = block.getRelative(event.getDirection()); - storage.moveDeadBastion(block.getLocation(), toBlock.getLocation()); - // TODO might need special handling if pending previously - } - } - } - } - - @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) - public void onBlockBurn(BlockBurnEvent event) { - Block block = event.getBlock(); - BastionType type = storage.getTypeAtLocation(block.getLocation()); - if (type == null) { - type = storage.getAndRemovePendingBastion(block.getLocation()); - } - if(type != null) { - block.setType(Material.AIR); - dropBastionItem(block.getLocation(), type, null, null); - event.setCancelled(true); - } - } + TextComponent chatMessage = null; + BastionBlock bastion = storage.getBastionBlock(block.getLocation()); + if (bastion != null) { + if (this.manager.canListBastionsForGroup(event.getPlayer(), bastion.getListGroupId())) { + chatMessage = this.manager.bastionDeletedMessageComponent(bastion); + } + + bastion.destroy(); + } + event.setCancelled(true); + block.setType(Material.AIR); + dropBastionItem(block.getLocation(), type, event.getPlayer(), chatMessage); + } + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onEntityExplode(EntityExplodeEvent event) { + Iterator iterator = event.blockList().iterator(); + HashSet blocks = new HashSet<>(); + while (iterator.hasNext()) { + Block block = iterator.next(); + BastionType type = storage.getTypeAtLocation(block.getLocation()); + if (type == null) { + type = storage.getAndRemovePendingBastion(block.getLocation()); + } + if (type != null) { + if (blocks.contains(block)) { + continue; + } + blocks.add(block); + block.setType(Material.AIR); + dropBastionItem(block.getLocation(), type, null, null); + iterator.remove(); // don't explode it, we've got it covered now. + } + } + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onBlockExplode(BlockExplodeEvent event) { + Iterator iterator = event.blockList().iterator(); + HashSet blocks = new HashSet<>(); + while (iterator.hasNext()) { + Block block = iterator.next(); + BastionType type = storage.getTypeAtLocation(block.getLocation()); + if (type == null) { + type = storage.getAndRemovePendingBastion(block.getLocation()); + } + if (type != null) { + if (blocks.contains(block)) { + continue; + } + blocks.add(block); + block.setType(Material.AIR); + dropBastionItem(block.getLocation(), type, null, null); + iterator.remove(); // don't explode it, we've got it covered now. + } + } + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onPistonExtend(BlockPistonExtendEvent event) { + // we will only reach this if citadel allows + for (Block block : event.getBlocks()) { + BastionType type = storage.getTypeAtLocation(block.getLocation()); + if (type == null) { + type = storage.getAndRemovePendingBastion(block.getLocation()); + } + if (type != null) { + if (block.getPistonMoveReaction() == PistonMoveReaction.BREAK) { + dropBastionItem(block.getLocation(), type, null, null); + block.setType(Material.AIR); + } else if (block.getPistonMoveReaction() == PistonMoveReaction.MOVE) { + Block toBlock = block.getRelative(event.getDirection()); + storage.moveDeadBastion(block.getLocation(), toBlock.getLocation()); + // TODO might need special handling if was pending previously + } + } + } + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onPistonRetract(BlockPistonRetractEvent event) { + if (!event.isSticky()) return; + for (Block block : event.getBlocks()) { + BastionType type = storage.getTypeAtLocation(block.getLocation()); + if (type == null) { + type = storage.getAndRemovePendingBastion(block.getLocation()); + } + if (type != null) { + if (block.getPistonMoveReaction() == PistonMoveReaction.BREAK) { + dropBastionItem(block.getLocation(), type, null, null); + block.setType(Material.AIR); + } else if (block.getPistonMoveReaction() == PistonMoveReaction.MOVE) { + Block toBlock = block.getRelative(event.getDirection()); + storage.moveDeadBastion(block.getLocation(), toBlock.getLocation()); + // TODO might need special handling if pending previously + } + } + } + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onBlockBurn(BlockBurnEvent event) { + Block block = event.getBlock(); + BastionType type = storage.getTypeAtLocation(block.getLocation()); + if (type == null) { + type = storage.getAndRemovePendingBastion(block.getLocation()); + } + if (type != null) { + block.setType(Material.AIR); + dropBastionItem(block.getLocation(), type, null, null); + event.setCancelled(true); + } + } } diff --git a/plugins/bastion-paper/src/main/java/isaac/bastion/listeners/BastionDamageListener.java b/plugins/bastion-paper/src/main/java/isaac/bastion/listeners/BastionDamageListener.java index 68ee12b56..d1827bae0 100644 --- a/plugins/bastion-paper/src/main/java/isaac/bastion/listeners/BastionDamageListener.java +++ b/plugins/bastion-paper/src/main/java/isaac/bastion/listeners/BastionDamageListener.java @@ -39,187 +39,188 @@ import vg.civcraft.mc.namelayer.group.Group; import vg.civcraft.mc.namelayer.permission.PermissionType; public final class BastionDamageListener implements Listener { - private BastionBlockManager blockManager; - private EnderPearlManager pearlManager; - public BastionDamageListener() { - blockManager = Bastion.getBastionManager(); - pearlManager = new EnderPearlManager(); - } + private BastionBlockManager blockManager; + private EnderPearlManager pearlManager; - @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) - public void onBlockPlace(BlockPlaceEvent event) { - Set blocks = new CopyOnWriteArraySet<>(); - blocks.add(event.getBlock()); - Set blocking = blockManager.getBlockingBastionsWithoutPermission(event.getBlock().getLocation(), - event.getPlayer().getUniqueId(), PermissionType.getPermission(Permissions.BASTION_PLACE)); - for(BastionBlock bastion : blocking) { - if (!bastion.getType().isOnlyDirectDestruction()) { - event.setCancelled(true); - if (!Bastion.getSettingManager().getIgnorePlacementMessages(event.getPlayer().getUniqueId())) { - event.getPlayer().sendMessage(ChatColor.RED + "Bastion removed block"); - } - Material mat = event.getBlock().getType(); - if (!Bastion.getCommonSettings().getCancelPlacementAndDamage().contains(mat)) { - blockManager.erodeFromPlace(event.getPlayer(), blocking); - } else { - event.getPlayer().sendMessage(String.format("%s%s cannot be used to damage bastions", ChatColor.RED, - ItemUtils.getItemName(mat))); - } - return; - } - } - } + public BastionDamageListener() { + blockManager = Bastion.getBastionManager(); + pearlManager = new EnderPearlManager(); + } - @EventHandler(ignoreCancelled = true) - public void onWaterFlow(BlockFromToEvent event) { - Set blocks = new HashSet<>(); - blocks.add(event.getToBlock().getLocation()); - if (stopBlockEvent(event.getBlock().getLocation(), blocks)) { - event.setCancelled(true); - } - } + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void onBlockPlace(BlockPlaceEvent event) { + Set blocks = new CopyOnWriteArraySet<>(); + blocks.add(event.getBlock()); + Set blocking = blockManager.getBlockingBastionsWithoutPermission(event.getBlock().getLocation(), + event.getPlayer().getUniqueId(), PermissionType.getPermission(Permissions.BASTION_PLACE)); + for (BastionBlock bastion : blocking) { + if (!bastion.getType().isOnlyDirectDestruction()) { + event.setCancelled(true); + if (!Bastion.getSettingManager().getIgnorePlacementMessages(event.getPlayer().getUniqueId())) { + event.getPlayer().sendMessage(ChatColor.RED + "Bastion removed block"); + } + Material mat = event.getBlock().getType(); + if (!Bastion.getCommonSettings().getCancelPlacementAndDamage().contains(mat)) { + blockManager.erodeFromPlace(event.getPlayer(), blocking); + } else { + event.getPlayer().sendMessage(String.format("%s%s cannot be used to damage bastions", ChatColor.RED, + ItemUtils.getItemName(mat))); + } + return; + } + } + } - @EventHandler(ignoreCancelled = true) - public void onTreeGrow(StructureGrowEvent event) { - List blocks = new ArrayList<>(); - for (BlockState state : event.getBlocks()) { - blocks.add(state.getLocation()); - } - if (stopBlockEvent(event.getLocation(), blocks)) { - event.setCancelled(true); - } - } + @EventHandler(ignoreCancelled = true) + public void onWaterFlow(BlockFromToEvent event) { + Set blocks = new HashSet<>(); + blocks.add(event.getToBlock().getLocation()); + if (stopBlockEvent(event.getBlock().getLocation(), blocks)) { + event.setCancelled(true); + } + } - @EventHandler(ignoreCancelled = true) - public void onPistonExtend(BlockPistonExtendEvent event) { - handlePistonEvent(event, event.getBlocks()); - } + @EventHandler(ignoreCancelled = true) + public void onTreeGrow(StructureGrowEvent event) { + List blocks = new ArrayList<>(); + for (BlockState state : event.getBlocks()) { + blocks.add(state.getLocation()); + } + if (stopBlockEvent(event.getLocation(), blocks)) { + event.setCancelled(true); + } + } - @EventHandler(ignoreCancelled = true) - public void onPistonRetract(BlockPistonRetractEvent event) { - handlePistonEvent(event, event.getBlocks()); - } - - private void handlePistonEvent(BlockPistonEvent event, List blocks) { - Set involved = new HashSet<>(); - blocks.forEach(b -> { - involved.add(b.getLocation()); - involved.add(b.getRelative(event.getDirection()).getLocation()); - }); - involved.add(event.getBlock().getRelative(event.getDirection()).getLocation()); - if (stopBlockEvent(event.getBlock().getLocation(), involved)) { - event.setCancelled(true); - } - } + @EventHandler(ignoreCancelled = true) + public void onPistonExtend(BlockPistonExtendEvent event) { + handlePistonEvent(event, event.getBlocks()); + } - @EventHandler(ignoreCancelled = true) - public void onBucketEmpty(PlayerBucketEmptyEvent event) { - Set blocking = blockManager.getBlockingBastionsWithoutPermission(event.getBlock().getLocation(), - event.getPlayer().getUniqueId(), PermissionType.getPermission(Permissions.BASTION_PLACE)); - if (!blocking.isEmpty()) { - event.setCancelled(true); - if (!Bastion.getSettingManager().getIgnorePlacementMessages(event.getPlayer().getUniqueId())) { - event.getPlayer().sendMessage(ChatColor.RED + "Emptying bucket prevented by Bastion"); - } - } - } + @EventHandler(ignoreCancelled = true) + public void onPistonRetract(BlockPistonRetractEvent event) { + handlePistonEvent(event, event.getBlocks()); + } - private boolean stopBlockEvent(Location source, Collection locations) { - Set blocking = blockManager.getEnteredGroupFields(source, locations); - return !blocking.isEmpty(); - } + private void handlePistonEvent(BlockPistonEvent event, List blocks) { + Set involved = new HashSet<>(); + blocks.forEach(b -> { + involved.add(b.getLocation()); + involved.add(b.getRelative(event.getDirection()).getLocation()); + }); + involved.add(event.getBlock().getRelative(event.getDirection()).getLocation()); + if (stopBlockEvent(event.getBlock().getLocation(), involved)) { + event.setCancelled(true); + } + } - @EventHandler(ignoreCancelled = true) - public void onDispense(BlockDispenseEvent event) { - Material material = event.getItem().getType(); - if (!(material == Material.WATER_BUCKET || material == Material.LAVA_BUCKET - || material == Material.FLINT_AND_STEEL || material == Material.POWDER_SNOW_BUCKET - || material == Material.TROPICAL_FISH_BUCKET || material == Material.AXOLOTL_BUCKET - || material == Material.COD_BUCKET || material == Material.PUFFERFISH_BUCKET - || material == Material.SALMON_SPAWN_EGG || material == Material.BUCKET)) { - return; - } - Set blocks = new HashSet<>(); - blocks.add(event.getBlock().getRelative(((Dispenser) event.getBlock().getBlockData()).getFacing()).getLocation()); - if (stopBlockEvent(event.getBlock().getLocation(), blocks)) { - event.setCancelled(true); - } - } + @EventHandler(ignoreCancelled = true) + public void onBucketEmpty(PlayerBucketEmptyEvent event) { + Set blocking = blockManager.getBlockingBastionsWithoutPermission(event.getBlock().getLocation(), + event.getPlayer().getUniqueId(), PermissionType.getPermission(Permissions.BASTION_PLACE)); + if (!blocking.isEmpty()) { + event.setCancelled(true); + if (!Bastion.getSettingManager().getIgnorePlacementMessages(event.getPlayer().getUniqueId())) { + event.getPlayer().sendMessage(ChatColor.RED + "Emptying bucket prevented by Bastion"); + } + } + } - @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) - public void handleEnderPearlLanded(PlayerTeleportEvent event) { - if (event.getCause() != TeleportCause.ENDER_PEARL) { - return; // Only handle enderpearl cases - } - if (event.getPlayer().hasPermission("Bastion.bypass")) { - return; - } + private boolean stopBlockEvent(Location source, Collection locations) { + Set blocking = blockManager.getEnteredGroupFields(source, locations); + return !blocking.isEmpty(); + } - Set blocking = blockManager.getBlockingBastionsWithoutPermission(event.getTo(), event.getPlayer().getUniqueId(), - PermissionType.getPermission(Permissions.BASTION_PEARL)); + @EventHandler(ignoreCancelled = true) + public void onDispense(BlockDispenseEvent event) { + Material material = event.getItem().getType(); + if (!(material == Material.WATER_BUCKET || material == Material.LAVA_BUCKET + || material == Material.FLINT_AND_STEEL || material == Material.POWDER_SNOW_BUCKET + || material == Material.TROPICAL_FISH_BUCKET || material == Material.AXOLOTL_BUCKET + || material == Material.COD_BUCKET || material == Material.PUFFERFISH_BUCKET + || material == Material.SALMON_SPAWN_EGG || material == Material.BUCKET)) { + return; + } + Set blocks = new HashSet<>(); + blocks.add(event.getBlock().getRelative(((Dispenser) event.getBlock().getBlockData()).getFacing()).getLocation()); + if (stopBlockEvent(event.getBlock().getLocation(), blocks)) { + event.setCancelled(true); + } + } - Iterator i = blocking.iterator(); + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void handleEnderPearlLanded(PlayerTeleportEvent event) { + if (event.getCause() != TeleportCause.ENDER_PEARL) { + return; // Only handle enderpearl cases + } + if (event.getPlayer().hasPermission("Bastion.bypass")) { + return; + } - while (i.hasNext()) { - BastionBlock bastion = i.next(); - if (bastion.getType().isOnlyDirectDestruction() || !bastion.getType().isBlockPearls() - || (bastion.getType().isRequireMaturity() && !bastion.isMature())) { - i.remove(); - } - } + Set blocking = blockManager.getBlockingBastionsWithoutPermission(event.getTo(), event.getPlayer().getUniqueId(), + PermissionType.getPermission(Permissions.BASTION_PEARL)); - if (!blocking.isEmpty()) { - blockManager.erodeFromTeleport(event.getPlayer(), blocking); - event.getPlayer().sendMessage(ChatColor.RED + "Ender pearl blocked by Bastion Block"); - boolean consume = false; - for (BastionBlock block : blocking) { - if (block.getType().isConsumeOnBlock()) { - consume = true; - } - } - if (!consume) { - event.getPlayer().getInventory().addItem(new ItemStack(Material.ENDER_PEARL)); - } - event.setCancelled(true); - return; - } + Iterator i = blocking.iterator(); - blocking = blockManager.getBlockingBastionsWithoutPermission(event.getFrom(), event.getPlayer().getUniqueId(), - PermissionType.getPermission(Permissions.BASTION_PEARL)); + while (i.hasNext()) { + BastionBlock bastion = i.next(); + if (bastion.getType().isOnlyDirectDestruction() || !bastion.getType().isBlockPearls() + || (bastion.getType().isRequireMaturity() && !bastion.isMature())) { + i.remove(); + } + } - i = blocking.iterator(); + if (!blocking.isEmpty()) { + blockManager.erodeFromTeleport(event.getPlayer(), blocking); + event.getPlayer().sendMessage(ChatColor.RED + "Ender pearl blocked by Bastion Block"); + boolean consume = false; + for (BastionBlock block : blocking) { + if (block.getType().isConsumeOnBlock()) { + consume = true; + } + } + if (!consume) { + event.getPlayer().getInventory().addItem(new ItemStack(Material.ENDER_PEARL)); + } + event.setCancelled(true); + return; + } - while (i.hasNext()) { - BastionBlock bastion = i.next(); - if (bastion.getType().canPearlOut() || bastion.getType().isOnlyDirectDestruction() - || !bastion.getType().isBlockPearls() - || (bastion.getType().isRequireMaturity() && !bastion.isMature())) { - i.remove(); - } - } + blocking = blockManager.getBlockingBastionsWithoutPermission(event.getFrom(), event.getPlayer().getUniqueId(), + PermissionType.getPermission(Permissions.BASTION_PEARL)); - if (!blocking.isEmpty()) { - blockManager.erodeFromTeleport(event.getPlayer(), blocking); - event.getPlayer().sendMessage(ChatColor.RED + "Ender pearl blocked by Bastion Block"); - boolean consume = false; - for (BastionBlock block : blocking) { - if (block.getType().isConsumeOnBlock()) { - consume = true; - } - } - if (!consume) { - event.getPlayer().getInventory().addItem(new ItemStack(Material.ENDER_PEARL)); - } - event.setCancelled(true); - } - } + i = blocking.iterator(); - @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) - public void onProjectileThrownEvent(ProjectileLaunchEvent event) { - if (event.getEntity() instanceof EnderPearl) { - EnderPearl pearl = (EnderPearl) event.getEntity(); - pearlManager.handlePearlLaunched(pearl); - } - } + while (i.hasNext()) { + BastionBlock bastion = i.next(); + if (bastion.getType().canPearlOut() || bastion.getType().isOnlyDirectDestruction() + || !bastion.getType().isBlockPearls() + || (bastion.getType().isRequireMaturity() && !bastion.isMature())) { + i.remove(); + } + } + + if (!blocking.isEmpty()) { + blockManager.erodeFromTeleport(event.getPlayer(), blocking); + event.getPlayer().sendMessage(ChatColor.RED + "Ender pearl blocked by Bastion Block"); + boolean consume = false; + for (BastionBlock block : blocking) { + if (block.getType().isConsumeOnBlock()) { + consume = true; + } + } + if (!consume) { + event.getPlayer().getInventory().addItem(new ItemStack(Material.ENDER_PEARL)); + } + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void onProjectileThrownEvent(ProjectileLaunchEvent event) { + if (event.getEntity() instanceof EnderPearl) { + EnderPearl pearl = (EnderPearl) event.getEntity(); + pearlManager.handlePearlLaunched(pearl); + } + } } diff --git a/plugins/bastion-paper/src/main/java/isaac/bastion/listeners/BastionInteractListener.java b/plugins/bastion-paper/src/main/java/isaac/bastion/listeners/BastionInteractListener.java index 0551c104a..70074316c 100644 --- a/plugins/bastion-paper/src/main/java/isaac/bastion/listeners/BastionInteractListener.java +++ b/plugins/bastion-paper/src/main/java/isaac/bastion/listeners/BastionInteractListener.java @@ -37,166 +37,166 @@ import vg.civcraft.mc.namelayer.permission.PermissionType; public class BastionInteractListener implements Listener { - private BastionBlockManager blockManager; - private BastionBlockStorage blockStorage; + private BastionBlockManager blockManager; + private BastionBlockStorage blockStorage; - public BastionInteractListener() { - blockManager = Bastion.getBastionManager(); - blockStorage = Bastion.getBastionStorage(); - } + public BastionInteractListener() { + blockManager = Bastion.getBastionManager(); + blockStorage = Bastion.getBastionStorage(); + } - @EventHandler(ignoreCancelled=true) - public void onBlockClicked(PlayerInteractEvent event) { - if (event.getAction() != Action.RIGHT_CLICK_BLOCK && event.getAction() != Action.RIGHT_CLICK_AIR) { - return; - } + @EventHandler(ignoreCancelled = true) + public void onBlockClicked(PlayerInteractEvent event) { + if (event.getAction() != Action.RIGHT_CLICK_BLOCK && event.getAction() != Action.RIGHT_CLICK_AIR) { + return; + } - final Player player = event.getPlayer(); + final Player player = event.getPlayer(); - //Stop boat places in bastions - Material isBoat = player.getInventory().getItemInMainHand().getType(); - Material offhand = player.getInventory().getItemInOffHand().getType(); - if(Tag.ITEMS_BOATS.isTagged(isBoat) || Tag.ITEMS_BOATS.isTagged(offhand) && event.getClickedBlock() != null) { - Set blocks = new CopyOnWriteArraySet<>(); - blocks.add(event.getClickedBlock()); - Set blocking = blockManager.getBlockingBastionsWithoutPermission(event.getClickedBlock().getLocation(), - event.getPlayer().getUniqueId(), PermissionType.getPermission(Permissions.BASTION_PLACE)); - if (!blocking.isEmpty()) { - event.setCancelled(true); - player.sendMessage(ChatColor.RED+"Boat blocked by bastion"); - return; - } - } + //Stop boat places in bastions + Material isBoat = player.getInventory().getItemInMainHand().getType(); + Material offhand = player.getInventory().getItemInOffHand().getType(); + if (Tag.ITEMS_BOATS.isTagged(isBoat) || Tag.ITEMS_BOATS.isTagged(offhand) && event.getClickedBlock() != null) { + Set blocks = new CopyOnWriteArraySet<>(); + blocks.add(event.getClickedBlock()); + Set blocking = blockManager.getBlockingBastionsWithoutPermission(event.getClickedBlock().getLocation(), + event.getPlayer().getUniqueId(), PermissionType.getPermission(Permissions.BASTION_PLACE)); + if (!blocking.isEmpty()) { + event.setCancelled(true); + player.sendMessage(ChatColor.RED + "Boat blocked by bastion"); + return; + } + } - if (PlayersStates.playerInMode(player, Mode.NORMAL)) { - return; - } - - if (event.getAction() != Action.RIGHT_CLICK_BLOCK || event.getHand() != EquipmentSlot.HAND) { - return; - } + if (PlayersStates.playerInMode(player, Mode.NORMAL)) { + return; + } - Block block = event.getClickedBlock(); + if (event.getAction() != Action.RIGHT_CLICK_BLOCK || event.getHand() != EquipmentSlot.HAND) { + return; + } - if (PlayersStates.playerInMode(player, Mode.INFO)) { - boolean dev = player.hasPermission("Bastion.dev"); - TextComponent toSend = blockManager.infoMessageComponent(dev, block.getRelative(event.getBlockFace()), block, player); + Block block = event.getClickedBlock(); - player.spigot().sendMessage(toSend); - } else if (PlayersStates.playerInMode(player, Mode.DELETE)) { - BastionBlock bastionBlock = blockStorage.getBastionBlock(block.getLocation()); + if (PlayersStates.playerInMode(player, Mode.INFO)) { + boolean dev = player.hasPermission("Bastion.dev"); + TextComponent toSend = blockManager.infoMessageComponent(dev, block.getRelative(event.getBlockFace()), block, player); - if (bastionBlock == null) { - return; - } + player.spigot().sendMessage(toSend); + } else if (PlayersStates.playerInMode(player, Mode.DELETE)) { + BastionBlock bastionBlock = blockStorage.getBastionBlock(block.getLocation()); - if (bastionBlock.canRemove(player)) { - TextComponent toSend = blockManager.bastionDeletedMessageComponent(bastionBlock); - bastionBlock.destroy(); - player.spigot().sendMessage(toSend); - event.setCancelled(true); - } - } else if (PlayersStates.playerInMode(player, Mode.MATURE)) { - BastionBlock bastionBlock= blockStorage.getBastionBlock(block.getLocation()); + if (bastionBlock == null) { + return; + } - if (bastionBlock == null) { - return; - } - bastionBlock.mature(); - player.sendMessage(ChatColor.GREEN + "Matured"); - } else if (PlayersStates.playerInMode(player, Mode.BASTION)) { - final BastionType type = blockStorage.getAndRemovePendingBastion(block.getLocation()); - if(type == null) return; //if it wasnt stored it cant have been a bastion - Reinforcement reinforcement = Citadel.getInstance().getReinforcementManager().getReinforcement(block.getLocation()); + if (bastionBlock.canRemove(player)) { + TextComponent toSend = blockManager.bastionDeletedMessageComponent(bastionBlock); + bastionBlock.destroy(); + player.spigot().sendMessage(toSend); + event.setCancelled(true); + } + } else if (PlayersStates.playerInMode(player, Mode.MATURE)) { + BastionBlock bastionBlock = blockStorage.getBastionBlock(block.getLocation()); - if (NameAPI.getGroupManager().hasAccess(reinforcement.getGroup(), player.getUniqueId(), PermissionType.getPermission(Permissions.BASTION_PLACE))) { - final Location loc = block.getLocation().clone(); - new BukkitRunnable() { - @Override - public void run() { - if(blockStorage.createBastion(loc, type, player)) { - TextComponent toSend = blockManager.bastionCreatedMessageComponent(loc); - player.spigot().sendMessage(toSend); - } else { - blockStorage.addPendingBastion(loc, type); - player.sendMessage(ChatColor.RED + "Failed to create bastion"); - } - } - }.runTask(Bastion.getPlugin()); - } else{ - player.sendMessage(ChatColor.RED + "You don't have the right permission"); - } - } - } + if (bastionBlock == null) { + return; + } + bastionBlock.mature(); + player.sendMessage(ChatColor.GREEN + "Matured"); + } else if (PlayersStates.playerInMode(player, Mode.BASTION)) { + final BastionType type = blockStorage.getAndRemovePendingBastion(block.getLocation()); + if (type == null) return; //if it wasnt stored it cant have been a bastion + Reinforcement reinforcement = Citadel.getInstance().getReinforcementManager().getReinforcement(block.getLocation()); - @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) - public void onBlockPlace(BlockPlaceEvent event) { - ItemStack inHand = event.getItemInHand(); - if (inHand == null) { - return; - } + if (NameAPI.getGroupManager().hasAccess(reinforcement.getGroup(), player.getUniqueId(), PermissionType.getPermission(Permissions.BASTION_PLACE))) { + final Location loc = block.getLocation().clone(); + new BukkitRunnable() { + @Override + public void run() { + if (blockStorage.createBastion(loc, type, player)) { + TextComponent toSend = blockManager.bastionCreatedMessageComponent(loc); + player.spigot().sendMessage(toSend); + } else { + blockStorage.addPendingBastion(loc, type); + player.sendMessage(ChatColor.RED + "Failed to create bastion"); + } + } + }.runTask(Bastion.getPlugin()); + } else { + player.sendMessage(ChatColor.RED + "You don't have the right permission"); + } + } + } - BastionType type = blockToType(event.getBlock(), inHand); - if(type != null) { - Bastion.getPlugin().getLogger().log(Level.INFO, "Pending a bastion at {0}", event.getBlock().getLocation()); - blockStorage.addPendingBastion(event.getBlock().getLocation(), type); - } - } + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void onBlockPlace(BlockPlaceEvent event) { + ItemStack inHand = event.getItemInHand(); + if (inHand == null) { + return; + } - @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) - public void onReinforcement(ReinforcementCreationEvent event) { - Block block = event.getReinforcement().getLocation().getBlock(); + BastionType type = blockToType(event.getBlock(), inHand); + if (type != null) { + Bastion.getPlugin().getLogger().log(Level.INFO, "Pending a bastion at {0}", event.getBlock().getLocation()); + blockStorage.addPendingBastion(event.getBlock().getLocation(), type); + } + } - final BastionType type = blockStorage.getAndRemovePendingBastion(block.getLocation()); - if (type != null && !PlayersStates.playerInMode(event.getPlayer(), Mode.OFF)) { - // Check Permissions.BASTION_PLACE; Citadel handles the canBypass() check... - Reinforcement reinforcement = event.getReinforcement(); - final Player player = event.getPlayer(); - if (!NameAPI.getGroupManager().hasAccess(reinforcement.getGroup(), player.getUniqueId(), PermissionType.getPermission(Permissions.BASTION_PLACE))) { - event.setCancelled(true); - event.getPlayer().sendMessage(ChatColor.RED + "You lack permission to create a Bastion on this group"); - blockStorage.addPendingBastion(block.getLocation(), type); - return; - } - // end Check Permissions.BASTION_PLACE - - Bastion.getPlugin().getLogger().log(Level.INFO, "Registering to create a {0} bastion", type); - final Location loc = block.getLocation().clone(); - // Can't do it immediately, as the reinforcement doesn't exist _during_ the create event. - new BukkitRunnable() { - @Override - public void run() { - if (blockStorage.createBastion(loc, type, player)) { - TextComponent toSend = blockManager.bastionCreatedMessageComponent(loc); - player.spigot().sendMessage(toSend); - } else { - blockStorage.addPendingBastion(loc, type); - player.sendMessage(ChatColor.RED + "Failed to create bastion"); - } - } - }.runTask(Bastion.getPlugin()); - } else { - if (blockManager.changeBastionGroup(event.getPlayer(), event.getReinforcement(), block.getLocation()) == Boolean.FALSE) { - event.setCancelled(true); - event.getPlayer().sendMessage(ChatColor.RED + "You lack permission to alter a Bastion with this group"); - } - } - } + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onReinforcement(ReinforcementCreationEvent event) { + Block block = event.getReinforcement().getLocation().getBlock(); - public BastionType blockToType(Block block, ItemStack inHand) { - Material mat = block.getType(); //, block.getData()); -- again, we can't differentiate based on this? - String displayName = null; - List lore = null; - if (inHand != null) { - ItemMeta im = inHand.getItemMeta(); - if (im != null && im.hasLore()) { - lore = im.getLore(); - } - if (im != null && im.hasDisplayName()) { - displayName = im.getDisplayName(); - } - } - BastionType type = BastionType.getBastionType(mat, displayName, lore); - return type; - } + final BastionType type = blockStorage.getAndRemovePendingBastion(block.getLocation()); + if (type != null && !PlayersStates.playerInMode(event.getPlayer(), Mode.OFF)) { + // Check Permissions.BASTION_PLACE; Citadel handles the canBypass() check... + Reinforcement reinforcement = event.getReinforcement(); + final Player player = event.getPlayer(); + if (!NameAPI.getGroupManager().hasAccess(reinforcement.getGroup(), player.getUniqueId(), PermissionType.getPermission(Permissions.BASTION_PLACE))) { + event.setCancelled(true); + event.getPlayer().sendMessage(ChatColor.RED + "You lack permission to create a Bastion on this group"); + blockStorage.addPendingBastion(block.getLocation(), type); + return; + } + // end Check Permissions.BASTION_PLACE + + Bastion.getPlugin().getLogger().log(Level.INFO, "Registering to create a {0} bastion", type); + final Location loc = block.getLocation().clone(); + // Can't do it immediately, as the reinforcement doesn't exist _during_ the create event. + new BukkitRunnable() { + @Override + public void run() { + if (blockStorage.createBastion(loc, type, player)) { + TextComponent toSend = blockManager.bastionCreatedMessageComponent(loc); + player.spigot().sendMessage(toSend); + } else { + blockStorage.addPendingBastion(loc, type); + player.sendMessage(ChatColor.RED + "Failed to create bastion"); + } + } + }.runTask(Bastion.getPlugin()); + } else { + if (blockManager.changeBastionGroup(event.getPlayer(), event.getReinforcement(), block.getLocation()) == Boolean.FALSE) { + event.setCancelled(true); + event.getPlayer().sendMessage(ChatColor.RED + "You lack permission to alter a Bastion with this group"); + } + } + } + + public BastionType blockToType(Block block, ItemStack inHand) { + Material mat = block.getType(); //, block.getData()); -- again, we can't differentiate based on this? + String displayName = null; + List lore = null; + if (inHand != null) { + ItemMeta im = inHand.getItemMeta(); + if (im != null && im.hasLore()) { + lore = im.getLore(); + } + if (im != null && im.hasDisplayName()) { + displayName = im.getDisplayName(); + } + } + BastionType type = BastionType.getBastionType(mat, displayName, lore); + return type; + } } diff --git a/plugins/bastion-paper/src/main/java/isaac/bastion/listeners/CitadelListener.java b/plugins/bastion-paper/src/main/java/isaac/bastion/listeners/CitadelListener.java index 0f2cc2550..137cc3da6 100644 --- a/plugins/bastion-paper/src/main/java/isaac/bastion/listeners/CitadelListener.java +++ b/plugins/bastion-paper/src/main/java/isaac/bastion/listeners/CitadelListener.java @@ -13,27 +13,27 @@ import vg.civcraft.mc.citadel.events.ReinforcementCreationEvent; import vg.civcraft.mc.namelayer.permission.PermissionType; public class CitadelListener implements Listener { - - private BastionBlockManager blockManager; - - public CitadelListener() { - this.blockManager = Bastion.getBastionManager(); - } - @EventHandler(ignoreCancelled = true) - public void onReinforcementCreation(ReinforcementCreationEvent event) { - Set preblocking = blockManager.getBlockingBastionsWithoutPermission(event.getReinforcement().getLocation(), - event.getPlayer().getUniqueId(), PermissionType.getPermission(Permissions.BASTION_PLACE)); - for(BastionBlock bastion : preblocking) { - BastionType type = bastion.getType(); - if(type.isBlockReinforcements()) { - event.setCancelled(true); - if (!Bastion.getSettingManager().getIgnorePlacementMessages(event.getPlayer().getUniqueId())) { - event.getPlayer().sendMessage(ChatColor.RED + "Bastion prevented reinforcement"); - } - blockManager.erodeFromPlace(event.getPlayer(), preblocking); - return; - } - } - } + private BastionBlockManager blockManager; + + public CitadelListener() { + this.blockManager = Bastion.getBastionManager(); + } + + @EventHandler(ignoreCancelled = true) + public void onReinforcementCreation(ReinforcementCreationEvent event) { + Set preblocking = blockManager.getBlockingBastionsWithoutPermission(event.getReinforcement().getLocation(), + event.getPlayer().getUniqueId(), PermissionType.getPermission(Permissions.BASTION_PLACE)); + for (BastionBlock bastion : preblocking) { + BastionType type = bastion.getType(); + if (type.isBlockReinforcements()) { + event.setCancelled(true); + if (!Bastion.getSettingManager().getIgnorePlacementMessages(event.getPlayer().getUniqueId())) { + event.getPlayer().sendMessage(ChatColor.RED + "Bastion prevented reinforcement"); + } + blockManager.erodeFromPlace(event.getPlayer(), preblocking); + return; + } + } + } } diff --git a/plugins/bastion-paper/src/main/java/isaac/bastion/listeners/ElytraListener.java b/plugins/bastion-paper/src/main/java/isaac/bastion/listeners/ElytraListener.java index 5f45c1eba..017a6648b 100644 --- a/plugins/bastion-paper/src/main/java/isaac/bastion/listeners/ElytraListener.java +++ b/plugins/bastion-paper/src/main/java/isaac/bastion/listeners/ElytraListener.java @@ -14,43 +14,43 @@ import org.bukkit.inventory.PlayerInventory; public class ElytraListener implements Listener { - private ElytraManager manager; - - public ElytraListener() { - manager = new ElytraManager(); - } - - @EventHandler(ignoreCancelled=true) - public void onElytraGlide(PlayerMoveEvent event) { - Player p = event.getPlayer(); - if(!p.isGliding()) return; - - //Bastion.getPlugin().getLogger().info("Gliding"); - - PlayerInventory inv = p.getInventory(); - if(inv.getChestplate() != null && inv.getChestplate().getType() != Material.ELYTRA) return; - - //Bastion.getPlugin().getLogger().info("Via elytra"); - - if (manager.handleElytraMovement(p, event.getTo())) { - Bastion.getPlugin().getLogger().info("Blocked."); - event.setCancelled(true); - } - } - - @EventHandler(ignoreCancelled=true) - public void onPlayerDepart(PlayerQuitEvent event) { - unwatchPlayer(event); - } - - @EventHandler(ignoreCancelled=true) - public void onPlayerKick(PlayerKickEvent event) { - unwatchPlayer(event); - } - - private void unwatchPlayer(PlayerEvent event) { - Player p = event.getPlayer(); - if (p == null) return; - manager.clearThrottle(p.getUniqueId()); - } + private ElytraManager manager; + + public ElytraListener() { + manager = new ElytraManager(); + } + + @EventHandler(ignoreCancelled = true) + public void onElytraGlide(PlayerMoveEvent event) { + Player p = event.getPlayer(); + if (!p.isGliding()) return; + + //Bastion.getPlugin().getLogger().info("Gliding"); + + PlayerInventory inv = p.getInventory(); + if (inv.getChestplate() != null && inv.getChestplate().getType() != Material.ELYTRA) return; + + //Bastion.getPlugin().getLogger().info("Via elytra"); + + if (manager.handleElytraMovement(p, event.getTo())) { + Bastion.getPlugin().getLogger().info("Blocked."); + event.setCancelled(true); + } + } + + @EventHandler(ignoreCancelled = true) + public void onPlayerDepart(PlayerQuitEvent event) { + unwatchPlayer(event); + } + + @EventHandler(ignoreCancelled = true) + public void onPlayerKick(PlayerKickEvent event) { + unwatchPlayer(event); + } + + private void unwatchPlayer(PlayerEvent event) { + Player p = event.getPlayer(); + if (p == null) return; + manager.clearThrottle(p.getUniqueId()); + } } diff --git a/plugins/bastion-paper/src/main/java/isaac/bastion/listeners/ModeListener.java b/plugins/bastion-paper/src/main/java/isaac/bastion/listeners/ModeListener.java index 4d00943ac..da5fd3016 100644 --- a/plugins/bastion-paper/src/main/java/isaac/bastion/listeners/ModeListener.java +++ b/plugins/bastion-paper/src/main/java/isaac/bastion/listeners/ModeListener.java @@ -32,135 +32,135 @@ import vg.civcraft.mc.namelayer.permission.PermissionType; public class ModeListener implements Listener { - private BottomLine bsiBottomLine; - private CivScoreBoard bsiBoard; - private BastionSettingManager settingMan; + private BottomLine bsiBottomLine; + private CivScoreBoard bsiBoard; + private BastionSettingManager settingMan; - private PermissionType placePerm; + private PermissionType placePerm; - public ModeListener() { - this.bsiBoard = ScoreBoardAPI.createBoard("bsiDisplay"); - this.bsiBottomLine = BottomLineAPI.createBottomLine("bsiDisplay", 3); - this.settingMan = Bastion.getSettingManager(); - settingMan.getBsiOverlay().registerListener(new SettingChangeListener() { - @Override - public void handle(UUID player, PlayerSetting setting, Boolean oldValue, Boolean newValue) { - if (newValue) { - updateDisplayedInformation(Bukkit.getPlayer(player), Bukkit.getPlayer(player).getLocation()); - return; - } - Player p = Bukkit.getPlayer(player); - if (p != null) { - hideAll(p); - } - } - }); - settingMan.getBsiLocation().registerListener(new SettingChangeListener() { - @Override - public void handle(UUID player, PlayerSetting setting, String oldValue, String newValue) { - updateDisplayedInformation(Bukkit.getPlayer(player), Bukkit.getPlayer(player).getLocation()); - } - }); - this.placePerm = PermissionType.getPermission(Permissions.BASTION_PLACE); - } + public ModeListener() { + this.bsiBoard = ScoreBoardAPI.createBoard("bsiDisplay"); + this.bsiBottomLine = BottomLineAPI.createBottomLine("bsiDisplay", 3); + this.settingMan = Bastion.getSettingManager(); + settingMan.getBsiOverlay().registerListener(new SettingChangeListener() { + @Override + public void handle(UUID player, PlayerSetting setting, Boolean oldValue, Boolean newValue) { + if (newValue) { + updateDisplayedInformation(Bukkit.getPlayer(player), Bukkit.getPlayer(player).getLocation()); + return; + } + Player p = Bukkit.getPlayer(player); + if (p != null) { + hideAll(p); + } + } + }); + settingMan.getBsiLocation().registerListener(new SettingChangeListener() { + @Override + public void handle(UUID player, PlayerSetting setting, String oldValue, String newValue) { + updateDisplayedInformation(Bukkit.getPlayer(player), Bukkit.getPlayer(player).getLocation()); + } + }); + this.placePerm = PermissionType.getPermission(Permissions.BASTION_PLACE); + } - @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) - public void onPlayerJoin(PlayerJoinEvent pje) { - updateDisplayedInformation(pje.getPlayer(), pje.getPlayer().getLocation()); - } + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onPlayerJoin(PlayerJoinEvent pje) { + updateDisplayedInformation(pje.getPlayer(), pje.getPlayer().getLocation()); + } - @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) - public void onPlayerMove(PlayerMoveEvent pme) { - Location to = pme.getTo(); - if (to == null) { - return; - } - Location from = pme.getFrom(); - if (from.getBlockX() == to.getBlockX() && from.getBlockY() == to.getBlockY() - && from.getBlockZ() == to.getBlockZ() && from.getWorld().equals(to.getWorld())) { - return; - } - updateDisplayedInformation(pme.getPlayer(), to); - } + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onPlayerMove(PlayerMoveEvent pme) { + Location to = pme.getTo(); + if (to == null) { + return; + } + Location from = pme.getFrom(); + if (from.getBlockX() == to.getBlockX() && from.getBlockY() == to.getBlockY() + && from.getBlockZ() == to.getBlockZ() && from.getWorld().equals(to.getWorld())) { + return; + } + updateDisplayedInformation(pme.getPlayer(), to); + } - /** - * This method handles the updating of the scoreboard/action bar as to whether - * the player is in a bastion field or not. - * - * @param player to update bastion status to - * @param location to check for bastions - */ - private void updateDisplayedInformation(Player player, Location location) { - if (player == null || location == null) { - return; - } - if (!settingMan.getBsiOverlay().getValue(player.getUniqueId())) { - hideAll(player); - return; - } - Set bastionBlocks = Bastion.getBastionManager().getBlockingBastions(location); - if (bastionBlocks.isEmpty()) { - if (settingMan.getShowNoBastion(player.getUniqueId())) { - updateDisplaySetting(player, ChatColor.WHITE + "No Bastion"); - } else { - hideAll(player); - } - return; - } - Set alliedBastions = new HashSet<>(); - Set enemyBastions = new HashSet<>(); - for (BastionBlock bastion : bastionBlocks) { - if (NameAPI.getGroupManager().hasAccess(bastion.getGroup(), player.getUniqueId(), placePerm)) { - alliedBastions.add(bastion.getType()); - } else { - enemyBastions.add(bastion.getType()); - } - } - if (!alliedBastions.isEmpty() && !enemyBastions.isEmpty()) { - updateDisplaySetting(player, - String.format("%s%sConflict Bastion %s[%s] %s[%s]", ChatColor.YELLOW, ChatColor.BOLD, - ChatColor.GREEN, buildBastionTypeList(alliedBastions), ChatColor.RED, - buildBastionTypeList(enemyBastions))); - return; - } - if (!alliedBastions.isEmpty()) { - updateDisplaySetting(player, - String.format("%sAlly Bastion [%s]", ChatColor.GREEN, buildBastionTypeList(alliedBastions))); - return; - } - updateDisplaySetting(player, String.format("%s%sEnemy Bastion [%s]", ChatColor.RED, ChatColor.BOLD, - buildBastionTypeList(enemyBastions))); - } + /** + * This method handles the updating of the scoreboard/action bar as to whether + * the player is in a bastion field or not. + * + * @param player to update bastion status to + * @param location to check for bastions + */ + private void updateDisplayedInformation(Player player, Location location) { + if (player == null || location == null) { + return; + } + if (!settingMan.getBsiOverlay().getValue(player.getUniqueId())) { + hideAll(player); + return; + } + Set bastionBlocks = Bastion.getBastionManager().getBlockingBastions(location); + if (bastionBlocks.isEmpty()) { + if (settingMan.getShowNoBastion(player.getUniqueId())) { + updateDisplaySetting(player, ChatColor.WHITE + "No Bastion"); + } else { + hideAll(player); + } + return; + } + Set alliedBastions = new HashSet<>(); + Set enemyBastions = new HashSet<>(); + for (BastionBlock bastion : bastionBlocks) { + if (NameAPI.getGroupManager().hasAccess(bastion.getGroup(), player.getUniqueId(), placePerm)) { + alliedBastions.add(bastion.getType()); + } else { + enemyBastions.add(bastion.getType()); + } + } + if (!alliedBastions.isEmpty() && !enemyBastions.isEmpty()) { + updateDisplaySetting(player, + String.format("%s%sConflict Bastion %s[%s] %s[%s]", ChatColor.YELLOW, ChatColor.BOLD, + ChatColor.GREEN, buildBastionTypeList(alliedBastions), ChatColor.RED, + buildBastionTypeList(enemyBastions))); + return; + } + if (!alliedBastions.isEmpty()) { + updateDisplaySetting(player, + String.format("%sAlly Bastion [%s]", ChatColor.GREEN, buildBastionTypeList(alliedBastions))); + return; + } + updateDisplaySetting(player, String.format("%s%sEnemy Bastion [%s]", ChatColor.RED, ChatColor.BOLD, + buildBastionTypeList(enemyBastions))); + } - private String buildBastionTypeList(Set types) { - List identifiers = new ArrayList<>(); - for (BastionType type : types) { - identifiers.add(type.getOverlayName()); - } - Collections.sort(identifiers); - return String.join(",", identifiers); - } + private String buildBastionTypeList(Set types) { + List identifiers = new ArrayList<>(); + for (BastionType type : types) { + identifiers.add(type.getOverlayName()); + } + Collections.sort(identifiers); + return String.join(",", identifiers); + } - /** - * This method simply updates the players information - * - * @param player to update scoreboard/action bar on - * @param locSetting PlayerSetting of where to display information - * @param state Value of the PlayerSetting - * @param text Text to display - */ - private void updateDisplaySetting(Player player, String text) { - DisplayLocationSetting locSetting = settingMan.getBsiLocation(); - if (locSetting.showOnActionbar(player.getUniqueId())) { - bsiBottomLine.updatePlayer(player, text); - } - if (locSetting.showOnSidebar(player.getUniqueId())) { - bsiBoard.set(player, text); - } - } + /** + * This method simply updates the players information + * + * @param player to update scoreboard/action bar on + * @param locSetting PlayerSetting of where to display information + * @param state Value of the PlayerSetting + * @param text Text to display + */ + private void updateDisplaySetting(Player player, String text) { + DisplayLocationSetting locSetting = settingMan.getBsiLocation(); + if (locSetting.showOnActionbar(player.getUniqueId())) { + bsiBottomLine.updatePlayer(player, text); + } + if (locSetting.showOnSidebar(player.getUniqueId())) { + bsiBoard.set(player, text); + } + } - private void hideAll(Player player) { - bsiBottomLine.removePlayer(player); - bsiBoard.hide(player); - } + private void hideAll(Player player) { + bsiBottomLine.removePlayer(player); + bsiBoard.hide(player); + } } diff --git a/plugins/bastion-paper/src/main/java/isaac/bastion/listeners/NameLayerListener.java b/plugins/bastion-paper/src/main/java/isaac/bastion/listeners/NameLayerListener.java index 2d346b9d3..3d901d404 100644 --- a/plugins/bastion-paper/src/main/java/isaac/bastion/listeners/NameLayerListener.java +++ b/plugins/bastion-paper/src/main/java/isaac/bastion/listeners/NameLayerListener.java @@ -13,24 +13,25 @@ import vg.civcraft.mc.namelayer.events.GroupDeleteEvent; import vg.civcraft.mc.namelayer.events.GroupMergeEvent; public class NameLayerListener implements Listener { - private BastionBlockStorage storage; - public NameLayerListener(BastionBlockStorage storage) { - this.storage = storage; - } + private BastionBlockStorage storage; - @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) - public void onGroupMergeEvent(GroupMergeEvent event) { - int toGroupId = event.getMergingInto().getGroupId(); - List fromGroupIds = event.getToBeMerged().getGroupIds(); + public NameLayerListener(BastionBlockStorage storage) { + this.storage = storage; + } - this.storage.mergeGroups(toGroupId, fromGroupIds); - } + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onGroupMergeEvent(GroupMergeEvent event) { + int toGroupId = event.getMergingInto().getGroupId(); + List fromGroupIds = event.getToBeMerged().getGroupIds(); - @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) - public void onGroupDeleteEvent(GroupDeleteEvent event) { - List groupIds = event.getGroup().getGroupIds(); + this.storage.mergeGroups(toGroupId, fromGroupIds); + } - this.storage.removeGroups(groupIds); - } + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onGroupDeleteEvent(GroupDeleteEvent event) { + List groupIds = event.getGroup().getGroupIds(); + + this.storage.removeGroups(groupIds); + } } diff --git a/plugins/bastion-paper/src/main/java/isaac/bastion/manager/BastionBlockManager.java b/plugins/bastion-paper/src/main/java/isaac/bastion/manager/BastionBlockManager.java index 791d4ff78..194d553f3 100644 --- a/plugins/bastion-paper/src/main/java/isaac/bastion/manager/BastionBlockManager.java +++ b/plugins/bastion-paper/src/main/java/isaac/bastion/manager/BastionBlockManager.java @@ -34,310 +34,308 @@ import vg.civcraft.mc.namelayer.group.Group; import vg.civcraft.mc.namelayer.permission.PermissionType; public class BastionBlockManager { - private static Random rng = new Random(); - private HashMap> cooldowns = new HashMap<>(); - private BastionBlockStorage storage; + private static Random rng = new Random(); - public BastionBlockManager() { - storage = Bastion.getBastionStorage(); - } + private HashMap> cooldowns = new HashMap<>(); + private BastionBlockStorage storage; - // For block places - public void erodeFromPlace(Player player, Set blocking) { - erodeFromAction(player, blocking, Cause.BLOCK_PLACED, PermissionType.getPermission(Permissions.BASTION_PLACE)); - } + public BastionBlockManager() { + storage = Bastion.getBastionStorage(); + } - // For pearls - public void erodeFromTeleport(Player player, Set blocking) { - erodeFromAction(player, blocking, Cause.PEARL, PermissionType.getPermission(Permissions.BASTION_PEARL)); - } + // For block places + public void erodeFromPlace(Player player, Set blocking) { + erodeFromAction(player, blocking, Cause.BLOCK_PLACED, PermissionType.getPermission(Permissions.BASTION_PLACE)); + } - /** - * Common handler for erosion. - */ - private void erodeFromAction(Player player, Set blocking, Cause cause, PermissionType perm) { - HashMap> typeMap = new HashMap<>(); - for (BastionBlock block : blocking) { - if (cause == Cause.PEARL && !block.getType().isBlockPearls()) { - continue; - } - Set set = typeMap.get(block.getType()); - if (set == null) { - set = new HashSet<>(); - typeMap.put(block.getType(), set); - } - set.add(block); - } + // For pearls + public void erodeFromTeleport(Player player, Set blocking) { + erodeFromAction(player, blocking, Cause.PEARL, PermissionType.getPermission(Permissions.BASTION_PEARL)); + } - for (BastionType type : typeMap.keySet()) { - if (onCooldown(player.getUniqueId(), type)) { - continue; - } - Set bastions = typeMap.get(type); - Set otherNearby = getBlockingBastionsWithoutPermission( - bastions.stream().map(b -> b.getLocation()).collect(Collectors.toSet()), - player.getUniqueId(), perm); - // dont damage those already directly damaged - otherNearby.removeAll(bastions); - for (BastionBlock bastion : otherNearby) { - if (bastion.getType() != type) { - continue; - } - boolean closeEnough = false; - for (BastionBlock comparesBas : bastions) { - if (Math.abs(comparesBas.getLocation().getBlockX() - bastion.getLocation().getBlockX()) > type - .getProximityDamageRange()) { - continue; - } - if (Math.abs(comparesBas.getLocation().getBlockZ() - bastion.getLocation().getBlockZ()) > type - .getProximityDamageRange()) { - continue; - } - closeEnough = true; - break; - } - if (closeEnough) { - double damage = cause == Cause.BLOCK_PLACED ? bastion.getErosionFromBlock() - : bastion.getErosionFromPearl(); - damage *= type.getProximityDamageFactor(); - BastionDamageEvent event = new BastionDamageEvent(bastion, player, cause, damage); - Bukkit.getPluginManager().callEvent(event); - if (event.isCancelled()) { - continue; - } - bastion.erode(damage); - } - } + /** + * Common handler for erosion. + */ + private void erodeFromAction(Player player, Set blocking, Cause cause, PermissionType perm) { + HashMap> typeMap = new HashMap<>(); + for (BastionBlock block : blocking) { + if (cause == Cause.PEARL && !block.getType().isBlockPearls()) { + continue; + } + Set set = typeMap.get(block.getType()); + if (set == null) { + set = new HashSet<>(); + typeMap.put(block.getType(), set); + } + set.add(block); + } - if (type.getBlocksToErode() < 0) { // erode all - for (BastionBlock bastion : bastions) { - double damage = cause == Cause.BLOCK_PLACED ? bastion.getErosionFromBlock() - : bastion.getErosionFromPearl(); - BastionDamageEvent event = new BastionDamageEvent(bastion, player, cause, damage); - Bukkit.getPluginManager().callEvent(event); - if (event.isCancelled()) { - continue; - } - bastion.erode(damage); - } - } else if (type.getBlocksToErode() > 0) { // erode some - List ordered = new LinkedList<>(bastions); - for (int i = 0; i < ordered.size() && i < type.getBlocksToErode(); i++) { - int erode = rng.nextInt(ordered.size()); - BastionBlock bastion = ordered.get(erode); - double damage = cause == Cause.BLOCK_PLACED ? bastion.getErosionFromBlock() - : bastion.getErosionFromPearl(); - BastionDamageEvent event = new BastionDamageEvent(bastion, player, cause, damage); - Bukkit.getPluginManager().callEvent(event); - if (event.isCancelled()) { - continue; - } - bastion.erode(damage); - ordered.remove(erode); - } - } - } - } + for (BastionType type : typeMap.keySet()) { + if (onCooldown(player.getUniqueId(), type)) { + continue; + } + Set bastions = typeMap.get(type); + Set otherNearby = getBlockingBastionsWithoutPermission( + bastions.stream().map(b -> b.getLocation()).collect(Collectors.toSet()), + player.getUniqueId(), perm); + // dont damage those already directly damaged + otherNearby.removeAll(bastions); + for (BastionBlock bastion : otherNearby) { + if (bastion.getType() != type) { + continue; + } + boolean closeEnough = false; + for (BastionBlock comparesBas : bastions) { + if (Math.abs(comparesBas.getLocation().getBlockX() - bastion.getLocation().getBlockX()) > type + .getProximityDamageRange()) { + continue; + } + if (Math.abs(comparesBas.getLocation().getBlockZ() - bastion.getLocation().getBlockZ()) > type + .getProximityDamageRange()) { + continue; + } + closeEnough = true; + break; + } + if (closeEnough) { + double damage = cause == Cause.BLOCK_PLACED ? bastion.getErosionFromBlock() + : bastion.getErosionFromPearl(); + damage *= type.getProximityDamageFactor(); + BastionDamageEvent event = new BastionDamageEvent(bastion, player, cause, damage); + Bukkit.getPluginManager().callEvent(event); + if (event.isCancelled()) { + continue; + } + bastion.erode(damage); + } + } - public boolean onCooldown(UUID player, BastionType type) { - if (!cooldowns.containsKey(player)) { - cooldowns.put(player, new HashMap()); - return false; - } - if (!cooldowns.get(player).containsKey(type.getName())) { - cooldowns.get(player).put(type.getName(), System.currentTimeMillis()); - return false; - } - long lastPlaced = cooldowns.get(player).get(type.getName()); + if (type.getBlocksToErode() < 0) { // erode all + for (BastionBlock bastion : bastions) { + double damage = cause == Cause.BLOCK_PLACED ? bastion.getErosionFromBlock() + : bastion.getErosionFromPearl(); + BastionDamageEvent event = new BastionDamageEvent(bastion, player, cause, damage); + Bukkit.getPluginManager().callEvent(event); + if (event.isCancelled()) { + continue; + } + bastion.erode(damage); + } + } else if (type.getBlocksToErode() > 0) { // erode some + List ordered = new LinkedList<>(bastions); + for (int i = 0; i < ordered.size() && i < type.getBlocksToErode(); i++) { + int erode = rng.nextInt(ordered.size()); + BastionBlock bastion = ordered.get(erode); + double damage = cause == Cause.BLOCK_PLACED ? bastion.getErosionFromBlock() + : bastion.getErosionFromPearl(); + BastionDamageEvent event = new BastionDamageEvent(bastion, player, cause, damage); + Bukkit.getPluginManager().callEvent(event); + if (event.isCancelled()) { + continue; + } + bastion.erode(damage); + ordered.remove(erode); + } + } + } + } - if ((System.currentTimeMillis() - lastPlaced) < type.getPlacementCooldown()) { - return true; - } else { - cooldowns.get(player).put(type.getName(), System.currentTimeMillis()); - } + public boolean onCooldown(UUID player, BastionType type) { + if (!cooldowns.containsKey(player)) { + cooldowns.put(player, new HashMap()); + return false; + } + if (!cooldowns.get(player).containsKey(type.getName())) { + cooldowns.get(player).put(type.getName(), System.currentTimeMillis()); + return false; + } + long lastPlaced = cooldowns.get(player).get(type.getName()); - return false; - } + if ((System.currentTimeMillis() - lastPlaced) < type.getPlacementCooldown()) { + return true; + } else { + cooldowns.get(player).put(type.getName(), System.currentTimeMillis()); + } - public Set getBlockingBastions(Location loc) { - return getBlockingBastions(loc, null); - } - - public Set getEnteredGroupFields(Location source, Collection target) { - Set result = new HashSet<>(); - for(Location loc : target) { - for(BastionBlock b : getBlockingBastions(loc)) { - result.add(b.getGroup()); - } - } - for(BastionBlock b : getBlockingBastions(source)) { - result.remove(b.getGroup()); - } + return false; + } - return result; - } - - public Set getBlockingBastions(Set locs) { - Set result = new HashSet<>(); - for(Location loc : locs) { - result.addAll(getBlockingBastions(loc)); - } - return result; - } - - public Set getBlockingBastionsWithoutPermission(Set locs, UUID player, - PermissionType permission) { - Set result = new HashSet<>(); - for(Location loc : locs) { - result.addAll(getBlockingBastionsWithoutPermission(loc, player, permission)); - } - return result; - } + public Set getBlockingBastions(Location loc) { + return getBlockingBastions(loc, null); + } - public Set getBlockingBastionsWithoutPermission(Location loc, UUID player, - PermissionType permission) { - return getBlockingBastions(loc, b -> !NameAPI.getGroupManager().hasAccess(b.getGroup(), player, permission)); - } + public Set getEnteredGroupFields(Location source, Collection target) { + Set result = new HashSet<>(); + for (Location loc : target) { + for (BastionBlock b : getBlockingBastions(loc)) { + result.add(b.getGroup()); + } + } + for (BastionBlock b : getBlockingBastions(source)) { + result.remove(b.getGroup()); + } - public Set getBlockingBastions(Location loc, Predicate filter) { - Set boxes = storage.forLocation(loc); - if (CollectionUtils.isEmpty(boxes)) { - return Collections.emptySet(); - } - Set result = new HashSet<>(); - for (BastionBlock bastion : boxes) { - if (filter != null && !filter.test(bastion)) { - continue; - } - if (bastion.inField(loc)) { - result.add(bastion); - } + return result; + } - } - return result; - } + public Set getBlockingBastions(Set locs) { + Set result = new HashSet<>(); + for (Location loc : locs) { + result.addAll(getBlockingBastions(loc)); + } + return result; + } - public boolean canListBastionsForGroup(Player player, Integer groupId) { - if (player == null || groupId == null) { - return false; - } - Group group = GroupManager.getGroup(groupId); - if (group == null) { - return false; - } - PermissionType permission = PermissionType.getPermission(Permissions.BASTION_LIST); - return NameAPI.getGroupManager().hasAccess(group, player.getUniqueId(), permission); - } + public Set getBlockingBastionsWithoutPermission(Set locs, UUID player, + PermissionType permission) { + Set result = new HashSet<>(); + for (Location loc : locs) { + result.addAll(getBlockingBastionsWithoutPermission(loc, player, permission)); + } + return result; + } - public TextComponent bastionDeletedMessageComponent(BastionBlock bastion) { - TextComponent component = new TextComponent(ChatColor.GREEN + "Bastion deleted"); + public Set getBlockingBastionsWithoutPermission(Location loc, UUID player, + PermissionType permission) { + return getBlockingBastions(loc, b -> !NameAPI.getGroupManager().hasAccess(b.getGroup(), player, permission)); + } - String hoverText = bastion.getHoverText(); - component.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(hoverText))); + public Set getBlockingBastions(Location loc, Predicate filter) { + Set boxes = storage.forLocation(loc); + if (CollectionUtils.isEmpty(boxes)) { + return Collections.emptySet(); + } + Set result = new HashSet<>(); + for (BastionBlock bastion : boxes) { + if (filter != null && !filter.test(bastion)) { + continue; + } + if (bastion.inField(loc)) { + result.add(bastion); + } - return component; - } + } + return result; + } - public TextComponent bastionCreatedMessageComponent(Location location) { - BastionBlock bastion = storage.getBastionBlock(location); + public boolean canListBastionsForGroup(Player player, Integer groupId) { + if (player == null || groupId == null) { + return false; + } + Group group = GroupManager.getGroup(groupId); + if (group == null) { + return false; + } + PermissionType permission = PermissionType.getPermission(Permissions.BASTION_LIST); + return NameAPI.getGroupManager().hasAccess(group, player.getUniqueId(), permission); + } - TextComponent component = new TextComponent(ChatColor.GREEN + "Bastion block created"); + public TextComponent bastionDeletedMessageComponent(BastionBlock bastion) { + TextComponent component = new TextComponent(ChatColor.GREEN + "Bastion deleted"); - String hoverText = bastion.getHoverText(); - component.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(hoverText))); + String hoverText = bastion.getHoverText(); + component.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(hoverText))); - return component; - } + return component; + } - public TextComponent infoMessageComponent(boolean dev, Block block, Block clicked, Player player) { - BastionBlock bastion = storage.getBastionBlock(clicked.getLocation()); // Get the bastion at the location - // clicked. + public TextComponent bastionCreatedMessageComponent(Location location) { + BastionBlock bastion = storage.getBastionBlock(location); - if (bastion == null) - return new TextComponent(infoMessage(dev, block, clicked, player)); + TextComponent component = new TextComponent(ChatColor.GREEN + "Bastion block created"); - TextComponent component = new TextComponent(bastion.infoMessage(dev)); + String hoverText = bastion.getHoverText(); + component.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(hoverText))); - if (canListBastionsForGroup(player, bastion.getListGroupId())) { - String hoverText = bastion.getHoverText(); - component.setHoverEvent( - new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(hoverText))); - } + return component; + } - return component; - } + public TextComponent infoMessageComponent(boolean dev, Block block, Block clicked, Player player) { + BastionBlock bastion = storage.getBastionBlock(clicked.getLocation()); // Get the bastion at the location + // clicked. - public String infoMessage(boolean dev, Block block, Block clicked, Player player) { - BastionBlock bastion = storage.getBastionBlock(clicked.getLocation()); // Get the bastion at the location - // clicked. + if (bastion == null) + return new TextComponent(infoMessage(dev, block, clicked, player)); - if (bastion != null) { // See if anything was found - return bastion.infoMessage(dev); // If there is actually something there tell the player about it. - } + TextComponent component = new TextComponent(bastion.infoMessage(dev)); - StringBuilder sb = new StringBuilder(); + if (canListBastionsForGroup(player, bastion.getListGroupId())) { + String hoverText = bastion.getHoverText(); + component.setHoverEvent( + new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(hoverText))); + } - Set bastions = getBlockingBastions(block.getLocation()); - if (bastions.isEmpty()) { - sb.append(ChatColor.YELLOW).append("No Bastion Block"); - } - else { - Set alliedBastions = new HashSet<>(); - Set enemyBastions = new HashSet<>(); - for (BastionBlock bas : bastions) { - if (NameAPI.getGroupManager().hasAccess(bas.getGroup(), player.getUniqueId(), PermissionType.getPermission(Permissions.BASTION_PLACE))) { - alliedBastions.add(bas.getType()); - } else { - enemyBastions.add(bas.getType()); - } - } - if (alliedBastions.isEmpty()) { - sb.append(ChatColor.RED).append(String.format("Enemy %s prevent you from building", - String.join(" ", enemyBastions.stream().map(BastionType::getName).collect(Collectors.toList())))); - } - else { - if (enemyBastions.isEmpty()) { - sb.append(ChatColor.GREEN).append(String.format("Allied %s prevent others from building", - String.join(" ", alliedBastions.stream().map(BastionType::getName).collect(Collectors.toList())))); - } - else { - sb.append(ChatColor.RED).append(String.format("Enemy %s prevent you from building and allied %s prevent others from building", - String.join(" ", enemyBastions.stream().map(BastionType::getName).collect(Collectors.toList())), - String.join(" ", alliedBastions.stream().map(BastionType::getName).collect(Collectors.toList())))); - } - } - } + return component; + } - if (dev) { - for(BastionBlock bas : bastions) { - sb.append('\n' + bas.toString() ); - } - } - return sb.toString(); - } + public String infoMessage(boolean dev, Block block, Block clicked, Player player) { + BastionBlock bastion = storage.getBastionBlock(clicked.getLocation()); // Get the bastion at the location + // clicked. - public Boolean changeBastionGroup(Player player, Reinforcement reinforcement, Location location) { - BastionBlock bastion = storage.getBastionBlock(location); + if (bastion != null) { // See if anything was found + return bastion.infoMessage(dev); // If there is actually something there tell the player about it. + } - if (bastion == null) { - return null; - } + StringBuilder sb = new StringBuilder(); - Reinforcement oldReinf = bastion.getReinforcement(); + Set bastions = getBlockingBastions(block.getLocation()); + if (bastions.isEmpty()) { + sb.append(ChatColor.YELLOW).append("No Bastion Block"); + } else { + Set alliedBastions = new HashSet<>(); + Set enemyBastions = new HashSet<>(); + for (BastionBlock bas : bastions) { + if (NameAPI.getGroupManager().hasAccess(bas.getGroup(), player.getUniqueId(), PermissionType.getPermission(Permissions.BASTION_PLACE))) { + alliedBastions.add(bas.getType()); + } else { + enemyBastions.add(bas.getType()); + } + } + if (alliedBastions.isEmpty()) { + sb.append(ChatColor.RED).append(String.format("Enemy %s prevent you from building", + String.join(" ", enemyBastions.stream().map(BastionType::getName).collect(Collectors.toList())))); + } else { + if (enemyBastions.isEmpty()) { + sb.append(ChatColor.GREEN).append(String.format("Allied %s prevent others from building", + String.join(" ", alliedBastions.stream().map(BastionType::getName).collect(Collectors.toList())))); + } else { + sb.append(ChatColor.RED).append(String.format("Enemy %s prevent you from building and allied %s prevent others from building", + String.join(" ", enemyBastions.stream().map(BastionType::getName).collect(Collectors.toList())), + String.join(" ", alliedBastions.stream().map(BastionType::getName).collect(Collectors.toList())))); + } + } + } - if (NameAPI.getGroupManager().hasAccess(reinforcement.getGroup(), player.getUniqueId(), - PermissionType.getPermission(Permissions.BASTION_PLACE)) - && NameAPI.getGroupManager().hasAccess(oldReinf.getGroup(), player.getUniqueId(), - PermissionType.getPermission(Permissions.BASTION_PLACE))) { - storage.changeBastionGroup(bastion); - return Boolean.TRUE; - } else { - return Boolean.FALSE; - } - } + if (dev) { + for (BastionBlock bas : bastions) { + sb.append('\n' + bas.toString()); + } + } + return sb.toString(); + } - public void getBastionsByGroupIds(List groupIds, List result) { - storage.getBastionsByGroupIds(groupIds, result); - } + public Boolean changeBastionGroup(Player player, Reinforcement reinforcement, Location location) { + BastionBlock bastion = storage.getBastionBlock(location); + + if (bastion == null) { + return null; + } + + Reinforcement oldReinf = bastion.getReinforcement(); + + if (NameAPI.getGroupManager().hasAccess(reinforcement.getGroup(), player.getUniqueId(), + PermissionType.getPermission(Permissions.BASTION_PLACE)) + && NameAPI.getGroupManager().hasAccess(oldReinf.getGroup(), player.getUniqueId(), + PermissionType.getPermission(Permissions.BASTION_PLACE))) { + storage.changeBastionGroup(bastion); + return Boolean.TRUE; + } else { + return Boolean.FALSE; + } + } + + public void getBastionsByGroupIds(List groupIds, List result) { + storage.getBastionsByGroupIds(groupIds, result); + } } diff --git a/plugins/bastion-paper/src/main/java/isaac/bastion/manager/ElytraManager.java b/plugins/bastion-paper/src/main/java/isaac/bastion/manager/ElytraManager.java index a130e1855..828d342b2 100644 --- a/plugins/bastion-paper/src/main/java/isaac/bastion/manager/ElytraManager.java +++ b/plugins/bastion-paper/src/main/java/isaac/bastion/manager/ElytraManager.java @@ -33,249 +33,249 @@ import vg.civcraft.mc.namelayer.permission.PermissionType; public class ElytraManager { - private BastionBlockStorage storage; - private Map throttle; - private Map lastMoves; - - public ElytraManager() { - storage = Bastion.getBastionStorage(); - throttle = new ConcurrentHashMap<>(); - lastMoves = new ConcurrentHashMap<>(); - } - - public void clearThrottle(UUID player) { - throttle.remove(player); - } - - public void cleanLastMove(UUID player) { - lastMoves.remove(player); - } - - public boolean handleElytraMovement(Player player, Location to) { - // We use movement data plus vector data to form correct movement projection vectors. - Long lastMove = lastMoves.get(player.getUniqueId()); - Long nowMove = System.currentTimeMillis(); - lastMoves.put(player.getUniqueId(), nowMove); - if (lastMove == null) lastMove = nowMove - 50l; // assume 20/sec + private BastionBlockStorage storage; + private Map throttle; + private Map lastMoves; - // Throttle checks to no more then 10 a second. - Long lastCheck = throttle.get(player.getUniqueId()); - if (lastCheck != null && nowMove - lastCheck.longValue() < 100l){ + public ElytraManager() { + storage = Bastion.getBastionStorage(); + throttle = new ConcurrentHashMap<>(); + lastMoves = new ConcurrentHashMap<>(); + } + + public void clearThrottle(UUID player) { + throttle.remove(player); + } + + public void cleanLastMove(UUID player) { + lastMoves.remove(player); + } + + public boolean handleElytraMovement(Player player, Location to) { + // We use movement data plus vector data to form correct movement projection vectors. + Long lastMove = lastMoves.get(player.getUniqueId()); + Long nowMove = System.currentTimeMillis(); + lastMoves.put(player.getUniqueId(), nowMove); + if (lastMove == null) lastMove = nowMove - 50l; // assume 20/sec + + // Throttle checks to no more then 10 a second. + Long lastCheck = throttle.get(player.getUniqueId()); + if (lastCheck != null && nowMove - lastCheck.longValue() < 100l) { /*Bastion.getPlugin().getLogger().log(Level.INFO, "Throttled: {0} vs. {1}", new Object[] {lastCheck, System.currentTimeMillis()});*/ - return false; - } - throttle.put(player.getUniqueId(), System.currentTimeMillis()); - //Bastion.getPlugin().getLogger().info("Not throttled"); - - // collect to/from - Location from = player.getLocation(); - if (to == null) { - to = player.getLocation(); - } - - // fix vector - Vector pVec = player.getVelocity(); - if (pVec == null || pVec.lengthSquared() == 0.0d) { - pVec = new Vector(to.getX() - from.getX(), - to.getY() - from.getY(), - to.getZ() - from.getZ()); - } - - // We target 100ms between updates. We want to "project out" past the next movement. - // So for whatever time _actually_ passed between move packets, map to 200ms - pVec.multiply( (double) (200l / (nowMove-lastMove) ) ); + return false; + } + throttle.put(player.getUniqueId(), System.currentTimeMillis()); + //Bastion.getPlugin().getLogger().info("Not throttled"); - // We doubledown; project the vector out another movement cycle. - Location newTo = from.clone().add(pVec); + // collect to/from + Location from = player.getLocation(); + if (to == null) { + to = player.getLocation(); + } + + // fix vector + Vector pVec = player.getVelocity(); + if (pVec == null || pVec.lengthSquared() == 0.0d) { + pVec = new Vector(to.getX() - from.getX(), + to.getY() - from.getY(), + to.getZ() - from.getZ()); + } + + // We target 100ms between updates. We want to "project out" past the next movement. + // So for whatever time _actually_ passed between move packets, map to 200ms + pVec.multiply((double) (200l / (nowMove - lastMove))); + + // We doubledown; project the vector out another movement cycle. + Location newTo = from.clone().add(pVec); /*Bastion.getPlugin().getLogger().log(Level.INFO, " from: {0}, to: {1}, speed {2}", new Object[] {from, newTo, pVec});*/ - - // find maxset of bastions - Set possible = storage.getPossibleFlightBlocking( - BastionType.getMaxRadius() * 2, - from, newTo ); - if (possible == null || possible.isEmpty()) { - //Bastion.getPlugin().getLogger().info("No interations"); - return false; - } - - // find actual collisions - Set definiteCollide = simpleCollide(possible, pVec, from, newTo, player); //EnderPearlManager.staticSimpleCollide(possible, from, newTo, p); - if (definiteCollide == null || definiteCollide.isEmpty()) { - //Bastion.getPlugin().getLogger().info("No definite collisions"); - return false; - } - - // only allocate if we're going to use it. - Set impact = new TreeSet<>(); - BastionType noImpact = null; - boolean breakElytra = false; - boolean damageElytra = false; - double explosionStrength = -1; - - // look through bastions - for(BastionBlock bastion : definiteCollide) { - BastionType type = bastion.getType(); - breakElytra = breakElytra || type.isDestroyElytra(); - damageElytra = damageElytra || type.isDamageElytra(); - if(type.isExplodeOnBlock()) { - explosionStrength = Math.max(explosionStrength, type.getExplosionStrength()); - } - Location bLoc = bastion.getLocation(); - double testY = bLoc.getY() + ( type.isIncludeY() ? 0 : 1); - - // Are we fully below the bastion? - if (testY > Math.max(from.getY(), newTo.getY())) continue; - - boolean hit = false; - // Are we fully above the bastion? - if (testY <= Math.min(from.getY(), newTo.getY())) { - hit = true; // definite hit. - } else { // Are we inbetween? - // We'll use simple interpolation. We know they are not equal so no div by zero possible. - double s = (newTo.getY() - testY) / (newTo.getY() - from.getY()); - Location midpoint = from.clone(); - midpoint.add((newTo.getX() - from.getX()) * s, - (newTo.getY() - from.getY()) * s, - (newTo.getZ() - from.getZ()) * s); - hit = bastion.inField(midpoint); - } - - // We're going to clip this bastion field. - if (hit) { - //Bastion.getPlugin().getLogger().log(Level.INFO, " hit bastion at {0}", bLoc); - if (type.getElytraScale() > 0 && type.getBlocksToErode() != 0) { // we do no damage so just impact. - impact.add(bastion); - } else if(noImpact == null) { - noImpact = bastion.getType(); - } - } - } - - // Found a few hits, figure out who gets damaged. - if (impact != null && impact.size() > 0) { - doImpact(player, breakElytra, damageElytra, explosionStrength); - // handle breaking/damage to elytra - - HashMap> typeMap = new HashMap>(); - for(BastionBlock block : impact) { - if(!block.getType().isDamageElytra()) continue; - if(!typeMap.containsKey(block.getType())) { - typeMap.put(block.getType(), new HashSet()); - } - typeMap.get(block.getType()).add(block); - } - - for(BastionType type : typeMap.keySet()) { - if(Bastion.getBastionManager().onCooldown(player.getUniqueId(), type)) continue; - int breakCount = type.getBlocksToErode(); - if(breakCount < 0 || impact.size() >= breakCount) { - for(BastionBlock bastion : typeMap.get(type)) { - double damage = bastion.getErosionFromElytra(); - BastionDamageEvent event = new BastionDamageEvent(bastion, player, Cause.ELYTRA, damage); - Bukkit.getPluginManager().callEvent(event); - if(event.isCancelled()) continue; - bastion.erode(damage); - } - } else if (breakCount > 0) { - Random rng = new Random(); - List ordered = new LinkedList(typeMap.get(type)); - for(int i = 0; i < ordered.size() && (i < breakCount); i++) { - int erode = rng.nextInt(ordered.size()); - BastionBlock toErode = ordered.get(erode); - double damage = toErode.getErosionFromElytra(); - BastionDamageEvent event = new BastionDamageEvent(toErode, player, Cause.ELYTRA, damage); - Bukkit.getPluginManager().callEvent(event); - if(event.isCancelled()) continue; - toErode.erode(damage); - ordered.remove(erode); - } - } - } - return true; - } else if (noImpact != null) { - return true; - } - - return false; - } - - private Set simpleCollide(Set possible, Vector velocity, Location start, Location end, Player player) { - Set couldCollide = new TreeSet<>(); - for (BastionBlock bastion : possible) { - Location loc = bastion.getLocation().clone(); - loc.setY(0); - //check player flight permission. - if (NameAPI.getGroupManager().hasAccess(bastion.getGroup(), player.getUniqueId(), PermissionType.getPermission(Permissions.BASTION_ELYTRA))) { - continue; - } - if (bastion.getType().isSquare()) { - if (hasCollisionPointsSquare(start, end, bastion.getLocation(), bastion.getType().getEffectRadius())) { - couldCollide.add(bastion); - } - } else { - if (hasCollisionPointsCircle(velocity, start, bastion.getLocation(), bastion.getType().getEffectRadius())) { - couldCollide.add(bastion); - } - } - } - return couldCollide; - } - - private boolean hasCollisionPointsCircle(Vector d, Location start, Location circleLoc, double radius) { - Vector f = start.toVector().subtract(circleLoc.toVector()); - double a = d.dot(d); - double b = 2.0d * f.dot(d); - double c = f.dot(f) - radius * radius; - - double descrim = b*b - 4*a*c; - if (descrim >= 0.0d || a == 0) { - descrim = Math.sqrt(descrim); - - double t1 = (-b - descrim) / (2*a); - double t2 = (-b + descrim) / (2*a); - - if ((t1 >= 0 && t1 <= 1) || (t2 >= 0 && t2 <= 1) || (t1 < 0 && t2 > 1 )) { - return true; - } - } - return false; - } - + // find maxset of bastions + Set possible = storage.getPossibleFlightBlocking( + BastionType.getMaxRadius() * 2, + from, newTo); + if (possible == null || possible.isEmpty()) { + //Bastion.getPlugin().getLogger().info("No interations"); + return false; + } + + // find actual collisions + Set definiteCollide = simpleCollide(possible, pVec, from, newTo, player); //EnderPearlManager.staticSimpleCollide(possible, from, newTo, p); + if (definiteCollide == null || definiteCollide.isEmpty()) { + //Bastion.getPlugin().getLogger().info("No definite collisions"); + return false; + } + + // only allocate if we're going to use it. + Set impact = new TreeSet<>(); + BastionType noImpact = null; + boolean breakElytra = false; + boolean damageElytra = false; + double explosionStrength = -1; + + // look through bastions + for (BastionBlock bastion : definiteCollide) { + BastionType type = bastion.getType(); + breakElytra = breakElytra || type.isDestroyElytra(); + damageElytra = damageElytra || type.isDamageElytra(); + if (type.isExplodeOnBlock()) { + explosionStrength = Math.max(explosionStrength, type.getExplosionStrength()); + } + Location bLoc = bastion.getLocation(); + double testY = bLoc.getY() + (type.isIncludeY() ? 0 : 1); + + // Are we fully below the bastion? + if (testY > Math.max(from.getY(), newTo.getY())) continue; + + boolean hit = false; + // Are we fully above the bastion? + if (testY <= Math.min(from.getY(), newTo.getY())) { + hit = true; // definite hit. + } else { // Are we inbetween? + // We'll use simple interpolation. We know they are not equal so no div by zero possible. + double s = (newTo.getY() - testY) / (newTo.getY() - from.getY()); + Location midpoint = from.clone(); + midpoint.add((newTo.getX() - from.getX()) * s, + (newTo.getY() - from.getY()) * s, + (newTo.getZ() - from.getZ()) * s); + hit = bastion.inField(midpoint); + } + + // We're going to clip this bastion field. + if (hit) { + //Bastion.getPlugin().getLogger().log(Level.INFO, " hit bastion at {0}", bLoc); + if (type.getElytraScale() > 0 && type.getBlocksToErode() != 0) { // we do no damage so just impact. + impact.add(bastion); + } else if (noImpact == null) { + noImpact = bastion.getType(); + } + } + } + + // Found a few hits, figure out who gets damaged. + if (impact != null && impact.size() > 0) { + doImpact(player, breakElytra, damageElytra, explosionStrength); + // handle breaking/damage to elytra + + HashMap> typeMap = new HashMap>(); + for (BastionBlock block : impact) { + if (!block.getType().isDamageElytra()) continue; + if (!typeMap.containsKey(block.getType())) { + typeMap.put(block.getType(), new HashSet()); + } + typeMap.get(block.getType()).add(block); + } + + for (BastionType type : typeMap.keySet()) { + if (Bastion.getBastionManager().onCooldown(player.getUniqueId(), type)) continue; + int breakCount = type.getBlocksToErode(); + if (breakCount < 0 || impact.size() >= breakCount) { + for (BastionBlock bastion : typeMap.get(type)) { + double damage = bastion.getErosionFromElytra(); + BastionDamageEvent event = new BastionDamageEvent(bastion, player, Cause.ELYTRA, damage); + Bukkit.getPluginManager().callEvent(event); + if (event.isCancelled()) continue; + bastion.erode(damage); + } + } else if (breakCount > 0) { + Random rng = new Random(); + List ordered = new LinkedList(typeMap.get(type)); + for (int i = 0; i < ordered.size() && (i < breakCount); i++) { + int erode = rng.nextInt(ordered.size()); + BastionBlock toErode = ordered.get(erode); + double damage = toErode.getErosionFromElytra(); + BastionDamageEvent event = new BastionDamageEvent(toErode, player, Cause.ELYTRA, damage); + Bukkit.getPluginManager().callEvent(event); + if (event.isCancelled()) continue; + toErode.erode(damage); + ordered.remove(erode); + } + } + } + return true; + } else if (noImpact != null) { + return true; + } + + return false; + } + + private Set simpleCollide(Set possible, Vector velocity, Location start, Location end, Player player) { + Set couldCollide = new TreeSet<>(); + for (BastionBlock bastion : possible) { + Location loc = bastion.getLocation().clone(); + loc.setY(0); + + //check player flight permission. + if (NameAPI.getGroupManager().hasAccess(bastion.getGroup(), player.getUniqueId(), PermissionType.getPermission(Permissions.BASTION_ELYTRA))) { + continue; + } + if (bastion.getType().isSquare()) { + if (hasCollisionPointsSquare(start, end, bastion.getLocation(), bastion.getType().getEffectRadius())) { + couldCollide.add(bastion); + } + } else { + if (hasCollisionPointsCircle(velocity, start, bastion.getLocation(), bastion.getType().getEffectRadius())) { + couldCollide.add(bastion); + } + } + } + return couldCollide; + } + + private boolean hasCollisionPointsCircle(Vector d, Location start, Location circleLoc, double radius) { + Vector f = start.toVector().subtract(circleLoc.toVector()); + double a = d.dot(d); + double b = 2.0d * f.dot(d); + double c = f.dot(f) - radius * radius; + + double descrim = b * b - 4 * a * c; + if (descrim >= 0.0d || a == 0) { + descrim = Math.sqrt(descrim); + + double t1 = (-b - descrim) / (2 * a); + double t2 = (-b + descrim) / (2 * a); + + if ((t1 >= 0 && t1 <= 1) || (t2 >= 0 && t2 <= 1) || (t1 < 0 && t2 > 1)) { + return true; + } + } + return false; + } + private boolean hasCollisionPointsSquare(Location startLoc, Location endLoc, Location squareLoc, double radius) { double zl = (endLoc.getZ() - startLoc.getZ()); double xl = (endLoc.getX() - startLoc.getX()); double r2 = radius * 2.0; double ba = squareLoc.getX() - startLoc.getX(); double bb = squareLoc.getZ() - startLoc.getZ(); - + double s = 0.0d; double t = 0.0d; - if (xl != 0){ - s = zl * (ba + radius) / ( xl * r2 ) - bb / r2 + .5d; //bottom + if (xl != 0) { + s = zl * (ba + radius) / (xl * r2) - bb / r2 + .5d; //bottom t = (ba + radius) / xl; if (s >= 0.0 && s <= 1.0 && t >= 0.0 && t <= 1.0) { return true; } - - s = zl * (ba - radius) / ( xl * r2 ) - bb / r2 + .5d; //top + + s = zl * (ba - radius) / (xl * r2) - bb / r2 + .5d; //top t = (ba - radius) / xl; if (s >= 0.0 && s <= 1.0 && t >= 0.0 && t <= 1.0) { return true; } } - - if (zl != 0){ - s = xl * (bb + radius) / ( zl * r2 ) - ba / r2 + .5d; //right + + if (zl != 0) { + s = xl * (bb + radius) / (zl * r2) - ba / r2 + .5d; //right t = (bb + radius) / zl; if (s >= 0.0 && s <= 1.0 && t >= 0.0 && t <= 1.0) { return true; } - - s = xl * (bb - radius) / ( zl * r2 ) - ba / r2 + .5d; //leftt + + s = xl * (bb - radius) / (zl * r2) - ba / r2 + .5d; //leftt t = (bb - radius) / zl; if (s >= 0.0 && s <= 1.0 && t >= 0.0 && t <= 1.0) { return true; @@ -283,22 +283,22 @@ public class ElytraManager { } return false; } - - private void doImpact(Player p, boolean breakElytra, boolean damageElytra, double explosionStrength) { - p.sendMessage(ChatColor.RED+"Elytra flight blocked by Bastion Block"); - p.setVelocity(new Vector(0, 0, 0)); - PlayerInventory inv = p.getInventory(); - if (breakElytra) { - inv.setChestplate(new ItemStack(Material.AIR)); - } else if (damageElytra){ - ItemStack elytra = inv.getChestplate(); - Damageable dmgable = ItemUtils.getDamageable(elytra); - dmgable.setDamage(432); - elytra.setItemMeta((ItemMeta) dmgable); - inv.setChestplate(elytra); - } - if(explosionStrength >= 0) { - p.getWorld().createExplosion(p.getLocation(), (float) explosionStrength); - } - } + + private void doImpact(Player p, boolean breakElytra, boolean damageElytra, double explosionStrength) { + p.sendMessage(ChatColor.RED + "Elytra flight blocked by Bastion Block"); + p.setVelocity(new Vector(0, 0, 0)); + PlayerInventory inv = p.getInventory(); + if (breakElytra) { + inv.setChestplate(new ItemStack(Material.AIR)); + } else if (damageElytra) { + ItemStack elytra = inv.getChestplate(); + Damageable dmgable = ItemUtils.getDamageable(elytra); + dmgable.setDamage(432); + elytra.setItemMeta((ItemMeta) dmgable); + inv.setChestplate(elytra); + } + if (explosionStrength >= 0) { + p.getWorld().createExplosion(p.getLocation(), (float) explosionStrength); + } + } } diff --git a/plugins/bastion-paper/src/main/java/isaac/bastion/manager/EnderPearlManager.java b/plugins/bastion-paper/src/main/java/isaac/bastion/manager/EnderPearlManager.java index 692f3e734..4998643e0 100644 --- a/plugins/bastion-paper/src/main/java/isaac/bastion/manager/EnderPearlManager.java +++ b/plugins/bastion-paper/src/main/java/isaac/bastion/manager/EnderPearlManager.java @@ -22,454 +22,459 @@ import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.util.Vector; public class EnderPearlManager { - public static final int MAX_TELEPORT = 800; - private BastionBlockStorage storage; - - private FlightTask task; - - public EnderPearlManager() { - storage = Bastion.getBastionStorage(); - task = new FlightTask(); - } - public void handlePearlLaunched(EnderPearl pearl) { - getBlocking(pearl); - } + public static final int MAX_TELEPORT = 800; + private BastionBlockStorage storage; - private void getBlocking(EnderPearl pearl) { - double gravity = 0.03F; + private FlightTask task; - Vector speed = pearl.getVelocity(); - Vector twoDSpeed = speed.clone(); - twoDSpeed.setY(0); + public EnderPearlManager() { + storage = Bastion.getBastionStorage(); + task = new FlightTask(); + } - double horizontalSpeed = getLengthSigned(twoDSpeed); - double verticalSpeed = speed.getY(); + public void handlePearlLaunched(EnderPearl pearl) { + getBlocking(pearl); + } - Location loc = pearl.getLocation(); + private void getBlocking(EnderPearl pearl) { + double gravity = 0.03F; - double maxTicks = getMaxTicks(verticalSpeed, loc.getY(), -gravity); - double maxDistance = getMaxDistance(horizontalSpeed, maxTicks); + Vector speed = pearl.getVelocity(); + Vector twoDSpeed = speed.clone(); + twoDSpeed.setY(0); - //check if it has any possibility of going through a bastion + double horizontalSpeed = getLengthSigned(twoDSpeed); + double verticalSpeed = speed.getY(); + + Location loc = pearl.getLocation(); + + double maxTicks = getMaxTicks(verticalSpeed, loc.getY(), -gravity); + double maxDistance = getMaxDistance(horizontalSpeed, maxTicks); + + //check if it has any possibility of going through a bastion /*if (!(maxDistance > BastionType.getMaxRadius() / 2 || maxDistance < -1)) { return; }*/ - - Player threw = null; - if (pearl.getShooter() instanceof Player) { - threw = (Player) pearl.getShooter(); - } - Set possible = storage.getPossibleTeleportBlocking(pearl.getLocation(), maxDistance); //all the bastion blocks within range of the pearl + Player threw = null; + if (pearl.getShooter() instanceof Player) { + threw = (Player) pearl.getShooter(); + } - // no need to do anything if there aren't any bastions to run into. - if (possible.isEmpty()) { - return; - } + Set possible = storage.getPossibleTeleportBlocking(pearl.getLocation(), maxDistance); //all the bastion blocks within range of the pearl - Location start = pearl.getLocation(); - Location end = start.clone(); - end.add(twoDSpeed.multiply(maxTicks)); + // no need to do anything if there aren't any bastions to run into. + if (possible.isEmpty()) { + return; + } - Set couldCollide = simpleCollide(possible, start.clone(), end.clone(), threw); //all the bastions where the pearl passes over or under their shadow + Location start = pearl.getLocation(); + Location end = start.clone(); + end.add(twoDSpeed.multiply(maxTicks)); - if (couldCollide.isEmpty()) { - return; - } + Set couldCollide = simpleCollide(possible, start.clone(), end.clone(), threw); //all the bastions where the pearl passes over or under their shadow + + if (couldCollide.isEmpty()) { + return; + } - BastionBlock firstCollision = null; - long firstCollisionTime = -1; - for (BastionBlock bastion : couldCollide) { - long currentCollidesBy = (long) collidesBy(bastion, start.clone(), end.clone(), speed, gravity, horizontalSpeed); - if (currentCollidesBy != -1 && (firstCollision == null || currentCollidesBy < firstCollisionTime)) { - firstCollisionTime = currentCollidesBy; - firstCollision = bastion; - } - } + BastionBlock firstCollision = null; + long firstCollisionTime = -1; + for (BastionBlock bastion : couldCollide) { + long currentCollidesBy = (long) collidesBy(bastion, start.clone(), end.clone(), speed, gravity, horizontalSpeed); + if (currentCollidesBy != -1 && (firstCollision == null || currentCollidesBy < firstCollisionTime)) { + firstCollisionTime = currentCollidesBy; + firstCollision = bastion; + } + } - if (firstCollisionTime != -1) { //if we found something add it - task.manage(new Flight(pearl, firstCollisionTime, firstCollision)); - return; - } - } - - private Set simpleCollide(Set possible, Location start, Location end, Player player) { - Set couldCollide = new TreeSet(); - for (BastionBlock bastion : possible) { - Location loc = bastion.getLocation().clone(); - loc.setY(0); - - if (bastion.canPearl(player)) { // not blocked, continue - continue; - } - - if (bastion.getType().isSquare()) { - if (!getCollisionPointsSquare(start, end, loc, bastion.getType().getEffectRadius()).isEmpty() ) { // TODO: reuse is good, doing the same thing twice is bad - couldCollide.add(bastion); - } - } else { - if (circleLineCollide(start, end, loc, bastion.getType().getRadiusSquared())) { - couldCollide.add(bastion); - } - } - } + if (firstCollisionTime != -1) { //if we found something add it + task.manage(new Flight(pearl, firstCollisionTime, firstCollision)); + return; + } + } - return couldCollide; - } + private Set simpleCollide(Set possible, Location start, Location end, Player player) { + Set couldCollide = new TreeSet(); + for (BastionBlock bastion : possible) { + Location loc = bastion.getLocation().clone(); + loc.setY(0); - double collidesBy(BastionBlock bastion, Location startLoc, Location endLoc, Vector speed, double gravity, double horizontalSpeed) { - //Get the points were our line crosses the circle - List collision_points = null; - if (bastion.getType().isSquare()) { - collision_points = getCollisionPointsSquare(startLoc, endLoc, bastion.getLocation(), bastion.getType().getEffectRadius()); - } else { - collision_points = getCollisionPoints(startLoc, endLoc, bastion.getLocation(), bastion.getType().getRadiusSquared()); - } - - if (collision_points.isEmpty()) { - return -1; - } - - //solve the quadratic equation for the equation governing the pearls y height. See if it ever reaches (bastion.getLocation().getY()+1 - List solutions = getSolutions(-gravity/2, speed.getY(), startLoc.getY() - (bastion.getLocation().getY() + (bastion.getType().isIncludeY() ? 0 : 1) )); - - //If there aren't any results we no there are no intersections - if (solutions.isEmpty()) { - return -1; - } - - Location temp = startLoc.clone(); - temp.setY(0); + if (bastion.canPearl(player)) { // not blocked, continue + continue; + } - //Solutions held the time at which the collision would happen lets change it to a position - for(int i = 0; i < solutions.size(); ++i) { - solutions.set(i, solutions.get(i) * horizontalSpeed); - } + if (bastion.getType().isSquare()) { + if (!getCollisionPointsSquare(start, end, loc, bastion.getType().getEffectRadius()).isEmpty()) { // TODO: reuse is good, doing the same thing twice is bad + couldCollide.add(bastion); + } + } else { + if (circleLineCollide(start, end, loc, bastion.getType().getRadiusSquared())) { + couldCollide.add(bastion); + } + } + } - List oneDCollisions = new ArrayList(); + return couldCollide; + } - //turn those points into scalers along the line of the pearl - for(Location collision_point : collision_points){ - Location twoDStart = startLoc.clone(); - twoDStart.setY(0); - collision_point.setY(0); - oneDCollisions.add(collision_point.subtract(twoDStart).length()); - } + double collidesBy(BastionBlock bastion, Location startLoc, Location endLoc, Vector speed, double gravity, double horizontalSpeed) { + //Get the points were our line crosses the circle + List collision_points = null; + if (bastion.getType().isSquare()) { + collision_points = getCollisionPointsSquare(startLoc, endLoc, bastion.getLocation(), bastion.getType().getEffectRadius()); + } else { + collision_points = getCollisionPoints(startLoc, endLoc, bastion.getLocation(), bastion.getType().getRadiusSquared()); + } - for(Double collisionPoint : oneDCollisions){ - //if this is the solution lets convert it to a tick - //check if the collision point is inside between the solutions if so we know there will be a collision - if ((solutions.get(0) > collisionPoint && solutions.get(1) < collisionPoint) || (solutions.get(1) > collisionPoint && solutions.get(0) < collisionPoint)) { - //solution 1 is between the two collision points - if (!(oneDCollisions.get(0) > solutions.get(1) && oneDCollisions.get(1) < solutions.get(0) || - oneDCollisions.get(1) > solutions.get(1) && oneDCollisions.get(0) < solutions.get(0))) { - return (solutions.get(1)) / horizontalSpeed + startLoc.getWorld().getFullTime(); - } else{ - if (oneDCollisions.get(0) < oneDCollisions.get(1)) { - return (oneDCollisions.get(0)) / horizontalSpeed + startLoc.getWorld().getFullTime(); - }else{ - return (oneDCollisions.get(1)) / horizontalSpeed + startLoc.getWorld().getFullTime(); - } - } - } - } + if (collision_points.isEmpty()) { + return -1; + } - return -1; - } - - //returns the solutions to the quadratic equation - private List getSolutions(double a, double b, double c){ - double toTakeSquareRoot=b*b-4*a*c; - if(toTakeSquareRoot<0||a==0) - return Collections.emptyList(); + //solve the quadratic equation for the equation governing the pearls y height. See if it ever reaches (bastion.getLocation().getY()+1 + List solutions = getSolutions(-gravity / 2, speed.getY(), startLoc.getY() - (bastion.getLocation().getY() + (bastion.getType().isIncludeY() ? 0 : 1))); - double squareRooted=Math.sqrt(toTakeSquareRoot); + //If there aren't any results we no there are no intersections + if (solutions.isEmpty()) { + return -1; + } - double s1=(-b-squareRooted)/(2*a); + Location temp = startLoc.clone(); + temp.setY(0); - double s2=(-b+squareRooted)/(2*a); + //Solutions held the time at which the collision would happen lets change it to a position + for (int i = 0; i < solutions.size(); ++i) { + solutions.set(i, solutions.get(i) * horizontalSpeed); + } - return Arrays.asList(s1, s2); - } - - /** - * Finds points on a line extending infinitely through the points startLoc and endLoc interesting a square centered at squareLoc. - * @param startLoc - * @param endLoc - * @param squareLoc - * @param radius - * @return - */ - private List getCollisionPointsSquare (Location startLoc, Location endLoc, Location squareLoc, double radius) { - double zl = (endLoc.getZ() - startLoc.getZ()); - double xl = (endLoc.getX() - startLoc.getX()); - double r2 = radius * 2.0; - double ba = squareLoc.getX() - startLoc.getX(); - double bb = squareLoc.getZ() - startLoc.getZ(); - - List results=new ArrayList<>(); - Location so = null; - double s = 0.0d; - if (xl != 0){ - s = zl * (ba + radius) / ( xl * r2 ) - bb / r2 + .5d; //bottom - if (s >= 0.0 && s <= 1.0) { - so = squareLoc.clone().add(radius, 0, -radius + s*r2); - results.add(so); - } - - s = zl * (ba - radius) / ( xl * r2 ) - bb / r2 + .5d; //top - if (s >= 0.0 && s <= 1.0) { - so = squareLoc.clone().add(-radius, 0, -radius + s*r2); - results.add(so); - } - } - - if (zl != 0){ - s = xl * (bb + radius) / ( zl * r2 ) - ba / r2 + .5d; //right - if (s >= 0.0 && s <= 1.0) { - so = squareLoc.clone().add(-radius + s*r2, 0, radius); - results.add(so); - } - - s = xl * (bb - radius) / ( zl * r2 ) - ba / r2 + .5d; //leftt - if (s >= 0.0 && s <= 1.0) { - so = squareLoc.clone().add(-radius + s*r2, 0, -radius); - results.add(so); - } - } - return results; - } - - /** - * Finds points on a line extending infinitely through the points startLoc and endLoc intersecting a circle centered at circleLoc - * @param startLoc - * @param endLoc - * @param circleLoc - * @param radiusSquared - * @return - */ - private List getCollisionPoints (Location startLoc, Location endLoc, Location circleLoc, double radiusSquared) { - Vector delta = vectorFromLocations(startLoc, endLoc); - Vector circleLocInTermsOfStart = vectorFromLocations(startLoc, circleLoc); - - boolean flipped = false; - if(delta.getX() == 0){ - flipped = true; - flipXZ(delta); - flipXZ(circleLocInTermsOfStart); - } - circleLocInTermsOfStart.add(new Vector(0.5,0,0.5)); - - double slope = delta.getZ()/delta.getX(); - - double circleX = circleLocInTermsOfStart.getX(); - double circleZ = circleLocInTermsOfStart.getZ(); - - double circleXSquared = circleX*circleX; - double circleZSquared = circleZ*circleZ; + List oneDCollisions = new ArrayList(); - - List xs = getSolutions(slope*slope+1,-(2*circleZ*slope+2*circleX),circleXSquared+circleZSquared-radiusSquared); - List results = new ArrayList(); - for (double x : xs) { - Vector offset = new Vector(x, 0, x*slope); - if(flipped) { - flipXZ(offset); - } - results.add(startLoc.clone().add(offset)); - } - - - return results; - } + //turn those points into scalers along the line of the pearl + for (Location collision_point : collision_points) { + Location twoDStart = startLoc.clone(); + twoDStart.setY(0); + collision_point.setY(0); + oneDCollisions.add(collision_point.subtract(twoDStart).length()); + } - private double getMaxDistance(double horizontalSpeed, double maxTicks) { - return horizontalSpeed*maxTicks; - } + for (Double collisionPoint : oneDCollisions) { + //if this is the solution lets convert it to a tick + //check if the collision point is inside between the solutions if so we know there will be a collision + if ((solutions.get(0) > collisionPoint && solutions.get(1) < collisionPoint) || (solutions.get(1) > collisionPoint && solutions.get(0) < collisionPoint)) { + //solution 1 is between the two collision points + if (!(oneDCollisions.get(0) > solutions.get(1) && oneDCollisions.get(1) < solutions.get(0) || + oneDCollisions.get(1) > solutions.get(1) && oneDCollisions.get(0) < solutions.get(0))) { + return (solutions.get(1)) / horizontalSpeed + startLoc.getWorld().getFullTime(); + } else { + if (oneDCollisions.get(0) < oneDCollisions.get(1)) { + return (oneDCollisions.get(0)) / horizontalSpeed + startLoc.getWorld().getFullTime(); + } else { + return (oneDCollisions.get(1)) / horizontalSpeed + startLoc.getWorld().getFullTime(); + } + } + } + } - private double getMaxTicks(double verticalSpeed, double y, double deltaY) { - return ((-verticalSpeed) - Math.sqrt(verticalSpeed*verticalSpeed - 2*deltaY*y)) / deltaY; - } + return -1; + } - // TODO evaluate this vs. getCollisonPoints. Which is more efficient? Prefer it, or find a way to re-use the result once captured. - private boolean circleLineCollide(Location startLoc, Location endLoc, Location circleLoc, double radiusSquared) { - Location lineStart = startLoc.clone(); - Location lineEnd = endLoc.clone(); - Location circleCenter = circleLoc.clone(); + //returns the solutions to the quadratic equation + private List getSolutions(double a, double b, double c) { + double toTakeSquareRoot = b * b - 4 * a * c; + if (toTakeSquareRoot < 0 || a == 0) + return Collections.emptyList(); - Vector direction = vectorFromLocations(lineStart,lineEnd); + double squareRooted = Math.sqrt(toTakeSquareRoot); - if (direction.getZ() == 0) { - if (direction.getBlockX() == 0) { - return false; - } - flipXZ(lineStart); - flipXZ(lineEnd); - flipXZ(circleCenter); - flipXZ(direction); - } + double s1 = (-b - squareRooted) / (2 * a); - Vector start = lineStart.toVector(); - Vector end = lineEnd.toVector(); + double s2 = (-b + squareRooted) / (2 * a); - Vector circle = circleCenter.toVector(); + return Arrays.asList(s1, s2); + } - double slope = direction.getZ() / direction.getX(); - double perpSlope = -1/slope; + /** + * Finds points on a line extending infinitely through the points startLoc and endLoc interesting a square centered at squareLoc. + * + * @param startLoc + * @param endLoc + * @param squareLoc + * @param radius + * @return + */ + private List getCollisionPointsSquare(Location startLoc, Location endLoc, Location squareLoc, double radius) { + double zl = (endLoc.getZ() - startLoc.getZ()); + double xl = (endLoc.getX() - startLoc.getX()); + double r2 = radius * 2.0; + double ba = squareLoc.getX() - startLoc.getX(); + double bb = squareLoc.getZ() - startLoc.getZ(); - //This is the closest x if this line segment was extended for ever - double closestX = (slope*start.getX() - perpSlope*circle.getX() + circle.getBlockZ() - start.getZ()) / - (slope - perpSlope); + List results = new ArrayList<>(); + Location so = null; + double s = 0.0d; + if (xl != 0) { + s = zl * (ba + radius) / (xl * r2) - bb / r2 + .5d; //bottom + if (s >= 0.0 && s <= 1.0) { + so = squareLoc.clone().add(radius, 0, -radius + s * r2); + results.add(so); + } - //Getting the Z from the x is easy - double closestZ = slope*(closestX - start.getX()) + start.getZ(); + s = zl * (ba - radius) / (xl * r2) - bb / r2 + .5d; //top + if (s >= 0.0 && s <= 1.0) { + so = squareLoc.clone().add(-radius, 0, -radius + s * r2); + results.add(so); + } + } - Vector closest = new Vector(closestX, 0, closestZ); + if (zl != 0) { + s = xl * (bb + radius) / (zl * r2) - ba / r2 + .5d; //right + if (s >= 0.0 && s <= 1.0) { + so = squareLoc.clone().add(-radius + s * r2, 0, radius); + results.add(so); + } - double distanceSquared = closest.clone().subtract(circle).lengthSquared(); + s = xl * (bb - radius) / (zl * r2) - ba / r2 + .5d; //leftt + if (s >= 0.0 && s <= 1.0) { + so = squareLoc.clone().add(-radius + s * r2, 0, -radius); + results.add(so); + } + } + return results; + } - if (distanceSquared > radiusSquared) { - return false; - } + /** + * Finds points on a line extending infinitely through the points startLoc and endLoc intersecting a circle centered at circleLoc + * + * @param startLoc + * @param endLoc + * @param circleLoc + * @param radiusSquared + * @return + */ + private List getCollisionPoints(Location startLoc, Location endLoc, Location circleLoc, double radiusSquared) { + Vector delta = vectorFromLocations(startLoc, endLoc); + Vector circleLocInTermsOfStart = vectorFromLocations(startLoc, circleLoc); - if ( ((closest.getX() > lineStart.getX() && closest.getX() > lineEnd.getX()) || - (closest.getZ() > lineStart.getZ() && closest.getZ() > lineEnd.getZ()))|| - ((closest.getX() < lineStart.getX() && closest.getX() < lineEnd.getX()) || - (closest.getZ() < lineStart.getZ() && closest.getZ() < lineEnd.getZ()))) { - if (closest.clone().subtract(end).lengthSquared() < closest.clone().subtract(start).lengthSquared()) { - closest=end; - } else { - closest=start; - } - } + boolean flipped = false; + if (delta.getX() == 0) { + flipped = true; + flipXZ(delta); + flipXZ(circleLocInTermsOfStart); + } + circleLocInTermsOfStart.add(new Vector(0.5, 0, 0.5)); - distanceSquared = closest.subtract(circle).lengthSquared(); + double slope = delta.getZ() / delta.getX(); - if (distanceSquared > radiusSquared) { - return false; - } + double circleX = circleLocInTermsOfStart.getX(); + double circleZ = circleLocInTermsOfStart.getZ(); - return true; - } - - private double getLengthSigned(Vector vec) { - double length = vec.length(); - - return length; - } + double circleXSquared = circleX * circleX; + double circleZSquared = circleZ * circleZ; - private void flipXZ(Location a) { - double tempX = a.getX(); - a.setX(a.getZ()); - a.setZ(tempX); - } - private void flipXZ(Vector a) { - double tempX = a.getX(); - a.setX(a.getZ()); - a.setZ(tempX); - } + List xs = getSolutions(slope * slope + 1, -(2 * circleZ * slope + 2 * circleX), circleXSquared + circleZSquared - radiusSquared); + List results = new ArrayList(); + for (double x : xs) { + Vector offset = new Vector(x, 0, x * slope); + if (flipped) { + flipXZ(offset); + } + results.add(startLoc.clone().add(offset)); + } - private Vector vectorFromLocations(Location start, Location end) { - return new Vector(end.getX()-start.getX(),end.getY()-start.getY(),end.getZ()-start.getZ()); - } - - private class FlightTask{ - PriorityQueue inFlight = new PriorityQueue(); - Flight onTask = null; - int currentTask = -1; - - void manage(Flight flight) { - inFlight.add(flight); - if (onTask == null){ - next(); - return; - } - if (onTask.compareTo(flight) == 1 || onTask == null) { - this.next(); - } - } - private void next() { - if(currentTask != -1) { - Bukkit.getScheduler().cancelTask(currentTask); - } - - if (onTask != null) { - inFlight.add(onTask); - } - - onTask = inFlight.poll(); - if (onTask == null) { - return; - } - - if (onTask.timeToEnd() <= 0) { - onTask.cancel(); - currentTask = -1; - onTask = null; - next(); - return; - } - - currentTask = new BukkitRunnable(){ - @Override - public void run() { - onTask.cancel(); - onTask = null; - currentTask = -1; - next(); - } - }.runTaskLater(Bastion.getPlugin(), onTask.timeToEnd()).getTaskId(); - } - } - - - private class Flight implements Comparable { - private EnderPearl pearl; - private Long endTime; - private BastionBlock blocking; - - public Flight(EnderPearl pearl, long endTime, BastionBlock blocking) { - this.pearl = pearl; - this.endTime = endTime; - this.blocking = blocking; - } - - - public void cancel() { - if (pearl.getShooter() instanceof Player) { - Player player = (Player) pearl.getShooter(); - - if (blocking.getType().damageFirstBastion() && !Bastion.getBastionManager().onCooldown(player.getUniqueId(), blocking.getType())) { - blocking.erode(blocking.getErosionFromPearl()); - pearl.getWorld().playEffect(pearl.getLocation(), Effect.ENDEREYE_LAUNCH, 1); - } - - if (blocking.getType().isBlockMidair()) { - player.sendMessage(ChatColor.RED+"Ender pearl blocked by Bastion Block"); - if (!blocking.getType().isConsumeOnBlock()) { - player.getInventory().addItem(new ItemStack(Material.ENDER_PEARL)); - player.updateInventory(); - } - } - } - if (blocking.getType().isBlockMidair()) { - pearl.remove(); - } - - } - - public long timeToEnd() { - return endTime - pearl.getWorld().getFullTime(); - } + return results; + } - @Override - public int compareTo(Flight o) { - return (int) Math.signum(o.endTime - endTime); - } - } + private double getMaxDistance(double horizontalSpeed, double maxTicks) { + return horizontalSpeed * maxTicks; + } + + private double getMaxTicks(double verticalSpeed, double y, double deltaY) { + return ((-verticalSpeed) - Math.sqrt(verticalSpeed * verticalSpeed - 2 * deltaY * y)) / deltaY; + } + + // TODO evaluate this vs. getCollisonPoints. Which is more efficient? Prefer it, or find a way to re-use the result once captured. + private boolean circleLineCollide(Location startLoc, Location endLoc, Location circleLoc, double radiusSquared) { + Location lineStart = startLoc.clone(); + Location lineEnd = endLoc.clone(); + Location circleCenter = circleLoc.clone(); + + Vector direction = vectorFromLocations(lineStart, lineEnd); + + if (direction.getZ() == 0) { + if (direction.getBlockX() == 0) { + return false; + } + flipXZ(lineStart); + flipXZ(lineEnd); + flipXZ(circleCenter); + flipXZ(direction); + } + + Vector start = lineStart.toVector(); + Vector end = lineEnd.toVector(); + + Vector circle = circleCenter.toVector(); + + double slope = direction.getZ() / direction.getX(); + double perpSlope = -1 / slope; + + //This is the closest x if this line segment was extended for ever + double closestX = (slope * start.getX() - perpSlope * circle.getX() + circle.getBlockZ() - start.getZ()) / + (slope - perpSlope); + + //Getting the Z from the x is easy + double closestZ = slope * (closestX - start.getX()) + start.getZ(); + + Vector closest = new Vector(closestX, 0, closestZ); + + double distanceSquared = closest.clone().subtract(circle).lengthSquared(); + + if (distanceSquared > radiusSquared) { + return false; + } + + if (((closest.getX() > lineStart.getX() && closest.getX() > lineEnd.getX()) || + (closest.getZ() > lineStart.getZ() && closest.getZ() > lineEnd.getZ())) || + ((closest.getX() < lineStart.getX() && closest.getX() < lineEnd.getX()) || + (closest.getZ() < lineStart.getZ() && closest.getZ() < lineEnd.getZ()))) { + if (closest.clone().subtract(end).lengthSquared() < closest.clone().subtract(start).lengthSquared()) { + closest = end; + } else { + closest = start; + } + } + + distanceSquared = closest.subtract(circle).lengthSquared(); + + if (distanceSquared > radiusSquared) { + return false; + } + + return true; + } + + private double getLengthSigned(Vector vec) { + double length = vec.length(); + + return length; + } + + private void flipXZ(Location a) { + double tempX = a.getX(); + a.setX(a.getZ()); + a.setZ(tempX); + } + + private void flipXZ(Vector a) { + double tempX = a.getX(); + a.setX(a.getZ()); + a.setZ(tempX); + } + + private Vector vectorFromLocations(Location start, Location end) { + return new Vector(end.getX() - start.getX(), end.getY() - start.getY(), end.getZ() - start.getZ()); + } + + private class FlightTask { + + PriorityQueue inFlight = new PriorityQueue(); + Flight onTask = null; + int currentTask = -1; + + void manage(Flight flight) { + inFlight.add(flight); + if (onTask == null) { + next(); + return; + } + if (onTask.compareTo(flight) == 1 || onTask == null) { + this.next(); + } + } + + private void next() { + if (currentTask != -1) { + Bukkit.getScheduler().cancelTask(currentTask); + } + + if (onTask != null) { + inFlight.add(onTask); + } + + onTask = inFlight.poll(); + if (onTask == null) { + return; + } + + if (onTask.timeToEnd() <= 0) { + onTask.cancel(); + currentTask = -1; + onTask = null; + next(); + return; + } + + currentTask = new BukkitRunnable() { + @Override + public void run() { + onTask.cancel(); + onTask = null; + currentTask = -1; + next(); + } + }.runTaskLater(Bastion.getPlugin(), onTask.timeToEnd()).getTaskId(); + } + } + + + private class Flight implements Comparable { + + private EnderPearl pearl; + private Long endTime; + private BastionBlock blocking; + + public Flight(EnderPearl pearl, long endTime, BastionBlock blocking) { + this.pearl = pearl; + this.endTime = endTime; + this.blocking = blocking; + } + + + public void cancel() { + if (pearl.getShooter() instanceof Player) { + Player player = (Player) pearl.getShooter(); + + if (blocking.getType().damageFirstBastion() && !Bastion.getBastionManager().onCooldown(player.getUniqueId(), blocking.getType())) { + blocking.erode(blocking.getErosionFromPearl()); + pearl.getWorld().playEffect(pearl.getLocation(), Effect.ENDEREYE_LAUNCH, 1); + } + + if (blocking.getType().isBlockMidair()) { + player.sendMessage(ChatColor.RED + "Ender pearl blocked by Bastion Block"); + if (!blocking.getType().isConsumeOnBlock()) { + player.getInventory().addItem(new ItemStack(Material.ENDER_PEARL)); + player.updateInventory(); + } + } + } + if (blocking.getType().isBlockMidair()) { + pearl.remove(); + } + + } + + public long timeToEnd() { + return endTime - pearl.getWorld().getFullTime(); + } + + @Override + public int compareTo(Flight o) { + return (int) Math.signum(o.endTime - endTime); + } + } } diff --git a/plugins/bastion-paper/src/main/java/isaac/bastion/storage/BastionBlockStorage.java b/plugins/bastion-paper/src/main/java/isaac/bastion/storage/BastionBlockStorage.java index c9b264395..b4a41e92c 100644 --- a/plugins/bastion-paper/src/main/java/isaac/bastion/storage/BastionBlockStorage.java +++ b/plugins/bastion-paper/src/main/java/isaac/bastion/storage/BastionBlockStorage.java @@ -31,518 +31,530 @@ import vg.civcraft.mc.civmodcore.world.locations.QTBox; import vg.civcraft.mc.civmodcore.world.locations.SparseQuadTree; public class BastionBlockStorage { - - private ManagedDatasource db; - private Logger log; - - private Map> blocks; - private Set changed; - private Set bastions; - private Map> groups; - private Map dead; - private int taskId; - - private HashMap pendingBastions; - - private static final String addBastion = "insert into bastion_blocks (bastion_type, loc_x, loc_y, loc_z, loc_world, placed) values (?,?,?,?,?,?);"; - private static final String updateBastion = "update bastion_blocks set placed=? where bastion_id=?;"; - private static final String deleteBastion = "delete from bastion_blocks where bastion_id=?;"; - private static final String setDead = "update bastion_blocks set dead=1 where bastion_id=?;"; - private static final String deleteDead = "delete from bastion_blocks where loc_world=? and loc_x=? and loc_y=? and loc_z=?;"; - private static final String moveDead = "update bastion_blocks set loc_world=?, loc_x=?, loc_y=?, loc_z=? where loc_world=? and loc_x=? and loc_y=? and loc_z=?;"; - - public BastionBlockStorage(ManagedDatasource db, Logger log) { - blocks = new HashMap<>(); - changed = new TreeSet<>(); - bastions = new TreeSet<>(); - groups = new HashMap<>(); - dead = new HashMap<>(); - pendingBastions = new HashMap<>(); - this.db = db; - this.log = log; - long saveDelay = 86400000 / Bastion.getPlugin().getConfig().getLong("mysql.savesPerDay", 64); - taskId = new BukkitRunnable(){ - @Override - public void run(){ - update(); - } - }.runTaskTimer(Bastion.getPlugin(),saveDelay,saveDelay).getTaskId(); - } - - /** - * Updates all remaining bastions and cancels the update task - */ - public void close() { - Bukkit.getScheduler().cancelTask(taskId); - update(); - } - - /** - * Creates a new bastion and adds it to the database - * @param loc The location of the bastion - * @param type The type of bastion - * @return Whether or not the bastion was created successfully - */ - public boolean createBastion(Location loc, BastionType type, Player owner) { - long placed = System.currentTimeMillis(); - BastionBlock bastion = new BastionBlock(loc, placed, -1, type); - BastionCreateEvent event = new BastionCreateEvent(bastion, owner); - Bukkit.getPluginManager().callEvent(event); - if(event.isCancelled()) return false; - try(Connection conn = db.getConnection(); - PreparedStatement ps = conn.prepareStatement(addBastion, Statement.RETURN_GENERATED_KEYS);) { - ps.setString(1, type.getName()); - ps.setInt(2, loc.getBlockX()); - ps.setInt(3, loc.getBlockY()); - ps.setInt(4, loc.getBlockZ()); - ps.setString(5, loc.getWorld().getName()); - ps.setLong(6, placed); - ps.executeUpdate(); - int id = -1; - try (ResultSet nid = ps.getGeneratedKeys();) { - if (nid.next()) { - id = nid.getInt(1); - } - } - if (id < 0) { - log.log(Level.WARNING, "Failed to get ID of bastion during insert at {0}, rolling back", loc); - dead.put(loc, bastion.getType().getName()); - deleteDeadBastion(loc); - return false; - } - bastion.setId(id); - addBastion(bastion); - } catch (SQLException e) { - log.log(Level.WARNING, "Problem saving bastion at " + bastion.getLocation().toString(), e); - return false; - } - return true; - } - - /** - * Deletes a bastion from the database - * @param bastion The bastion to delete - */ - public void deleteBastion(BastionBlock bastion) { - try (Connection conn = db.getConnection(); - PreparedStatement ps = conn.prepareStatement(deleteBastion)) { - ps.setInt(1, bastion.getId()); - ps.executeUpdate(); - try { - removeBastion(bastion); - } catch (NullPointerException npe) { - log.log(Level.WARNING, "Bastion wasn't in cache, or failed to remove from cache: " + bastion.getLocation().toString(), npe); - } - } catch (SQLException e) { - log.log(Level.WARNING, "Failed to delete a bastion at " + bastion.getLocation().toString(), e); - } - } - - /** - * Sets a bastion as dead but still in the world - * @param bastion The bastion that died - */ - public void setBastionAsDead(BastionBlock bastion) { - try (Connection conn = db.getConnection(); - PreparedStatement ps = conn.prepareStatement(setDead)) { - ps.setInt(1, bastion.getId()); - ps.executeUpdate(); - removeBastion(bastion); - dead.put(bastion.getLocation(), bastion.getType().getName()); - } catch (SQLException e) { - log.log(Level.WARNING, "Failed to set bastion as dead at " + bastion.getLocation().toString(), e); - } - } - - public void deleteDeadBastion(Location loc) { - if(!dead.containsKey(loc)) return; - try (Connection conn = db.getConnection(); - PreparedStatement ps = conn.prepareStatement(deleteDead)) { - ps.setString(1, loc.getWorld().getName()); - ps.setInt(2, loc.getBlockX()); - ps.setInt(3, loc.getBlockY()); - ps.setInt(4, loc.getBlockZ()); - ps.executeUpdate(); - dead.remove(loc); - } catch (SQLException e) { - log.log(Level.WARNING, "Failed to delete dead bastion at " + loc.toString(), e); - } - } - - public void moveDeadBastion(Location from, Location to) { - try (Connection conn = db.getConnection(); - PreparedStatement ps = conn.prepareStatement(moveDead)) { - ps.setString(1, to.getWorld().getName()); - ps.setInt(2, to.getBlockX()); - ps.setInt(3, to.getBlockY()); - ps.setInt(4, to.getBlockZ()); - ps.setString(5, from.getWorld().getName()); - ps.setInt(6, from.getBlockX()); - ps.setInt(7, from.getBlockY()); - ps.setInt(8, from.getBlockZ()); - ps.executeUpdate(); - dead.put(to, dead.remove(from)); - } catch (SQLException e) { - log.log(Level.WARNING, "Failed to move bastion at " + from.toString() + " to " + to.toString(), e); - } - } - /** - * Updates a bastion in the database - * @param bastion The bastion to update - */ - private void updateBastion(BastionBlock bastion) { - try (Connection conn = db.getConnection(); - PreparedStatement ps = conn.prepareStatement(updateBastion)) { - ps.setLong(1, bastion.getPlaced()); - ps.setInt(2, bastion.getId()); - ps.executeUpdate(); - } catch (SQLException e) { - log.log(Level.WARNING, "Failed to update bastion at " + bastion.getLocation().toString(), e); - } - } - - /** - * Adds this bastion to a set of bastions to be updated - * @param bastion The bastion to be updated - */ - public void updated(BastionBlock bastion) { - changed.add(bastion); - } - - /** - * Find bastions that intersect a location - * @param loc The location to check - * @return A set of QTBoxes (bastions) that overlap with the location - */ - public Set forLocation(Location loc) { - return blocks.get(loc.getWorld()).find(loc.getBlockX(), loc.getBlockZ()); - } - - /** - * Retrieve possible blocking bastions for a thrown pearl - * @param loc The location of the pearl - * @param maxDistance The max distance the pearl could be from a bastion without collision - * @return A set of bastions a pearl could collide with - */ - public Set getPossibleTeleportBlocking(Location loc, double maxDistance) { - Set boxes = blocks.get(loc.getWorld()).find(loc.getBlockX(), loc.getBlockY(), true); - - double maxDistanceSquared = maxDistance * maxDistance; - double maxBoxDistanceSquared = maxDistanceSquared * 2.0; - - Set result = new TreeSet<>(); - - for(QTBox box : boxes) { - if(box instanceof BastionBlock) { - BastionBlock bastion = (BastionBlock) box; - BastionType type = bastion.getType(); - // Skip bastions who don't do midair blocking. - if (!type.isBlockPearls() || !type.isBlockMidair()) continue; - // Check on other conditions. - if (((type.isSquare() && bastion.getLocation().distanceSquared(loc) <= maxBoxDistanceSquared) || - (!type.isSquare() && bastion.getLocation().distanceSquared(loc) <= maxDistanceSquared)) && - (!type.isRequireMaturity() || bastion.isMature())) { - result.add(bastion); - } - } - } - return result; - } - - /** - * Retrieve possible blocking bastions for elytra flight - * @param maxDistance The max distance you could be without collision - * @param locs The locations the player is at while flying - * @return A set of bastions a flying player could collide with - */ - public Set getPossibleFlightBlocking(double maxDistance, Location...locs) { - Set boxes = null; - Set result = new TreeSet<>(); - double maxDistanceSquared = maxDistance * maxDistance; - double maxBoxDistanceSquared = maxDistanceSquared * 2.0; - - for (Location loc: locs) { + private ManagedDatasource db; + private Logger log; + + private Map> blocks; + private Set changed; + private Set bastions; + private Map> groups; + private Map dead; + private int taskId; + + private HashMap pendingBastions; + + private static final String addBastion = "insert into bastion_blocks (bastion_type, loc_x, loc_y, loc_z, loc_world, placed) values (?,?,?,?,?,?);"; + private static final String updateBastion = "update bastion_blocks set placed=? where bastion_id=?;"; + private static final String deleteBastion = "delete from bastion_blocks where bastion_id=?;"; + private static final String setDead = "update bastion_blocks set dead=1 where bastion_id=?;"; + private static final String deleteDead = "delete from bastion_blocks where loc_world=? and loc_x=? and loc_y=? and loc_z=?;"; + private static final String moveDead = "update bastion_blocks set loc_world=?, loc_x=?, loc_y=?, loc_z=? where loc_world=? and loc_x=? and loc_y=? and loc_z=?;"; + + public BastionBlockStorage(ManagedDatasource db, Logger log) { + blocks = new HashMap<>(); + changed = new TreeSet<>(); + bastions = new TreeSet<>(); + groups = new HashMap<>(); + dead = new HashMap<>(); + pendingBastions = new HashMap<>(); + this.db = db; + this.log = log; + long saveDelay = 86400000 / Bastion.getPlugin().getConfig().getLong("mysql.savesPerDay", 64); + taskId = new BukkitRunnable() { + @Override + public void run() { + update(); + } + }.runTaskTimer(Bastion.getPlugin(), saveDelay, saveDelay).getTaskId(); + } + + /** + * Updates all remaining bastions and cancels the update task + */ + public void close() { + Bukkit.getScheduler().cancelTask(taskId); + update(); + } + + /** + * Creates a new bastion and adds it to the database + * + * @param loc The location of the bastion + * @param type The type of bastion + * @return Whether or not the bastion was created successfully + */ + public boolean createBastion(Location loc, BastionType type, Player owner) { + long placed = System.currentTimeMillis(); + BastionBlock bastion = new BastionBlock(loc, placed, -1, type); + BastionCreateEvent event = new BastionCreateEvent(bastion, owner); + Bukkit.getPluginManager().callEvent(event); + if (event.isCancelled()) return false; + try (Connection conn = db.getConnection(); + PreparedStatement ps = conn.prepareStatement(addBastion, Statement.RETURN_GENERATED_KEYS);) { + ps.setString(1, type.getName()); + ps.setInt(2, loc.getBlockX()); + ps.setInt(3, loc.getBlockY()); + ps.setInt(4, loc.getBlockZ()); + ps.setString(5, loc.getWorld().getName()); + ps.setLong(6, placed); + ps.executeUpdate(); + int id = -1; + try (ResultSet nid = ps.getGeneratedKeys();) { + if (nid.next()) { + id = nid.getInt(1); + } + } + if (id < 0) { + log.log(Level.WARNING, "Failed to get ID of bastion during insert at {0}, rolling back", loc); + dead.put(loc, bastion.getType().getName()); + deleteDeadBastion(loc); + return false; + } + bastion.setId(id); + addBastion(bastion); + } catch (SQLException e) { + log.log(Level.WARNING, "Problem saving bastion at " + bastion.getLocation().toString(), e); + return false; + } + return true; + } + + /** + * Deletes a bastion from the database + * + * @param bastion The bastion to delete + */ + public void deleteBastion(BastionBlock bastion) { + try (Connection conn = db.getConnection(); + PreparedStatement ps = conn.prepareStatement(deleteBastion)) { + ps.setInt(1, bastion.getId()); + ps.executeUpdate(); + try { + removeBastion(bastion); + } catch (NullPointerException npe) { + log.log(Level.WARNING, "Bastion wasn't in cache, or failed to remove from cache: " + bastion.getLocation().toString(), npe); + } + } catch (SQLException e) { + log.log(Level.WARNING, "Failed to delete a bastion at " + bastion.getLocation().toString(), e); + } + } + + /** + * Sets a bastion as dead but still in the world + * + * @param bastion The bastion that died + */ + public void setBastionAsDead(BastionBlock bastion) { + try (Connection conn = db.getConnection(); + PreparedStatement ps = conn.prepareStatement(setDead)) { + ps.setInt(1, bastion.getId()); + ps.executeUpdate(); + removeBastion(bastion); + dead.put(bastion.getLocation(), bastion.getType().getName()); + } catch (SQLException e) { + log.log(Level.WARNING, "Failed to set bastion as dead at " + bastion.getLocation().toString(), e); + } + } + + public void deleteDeadBastion(Location loc) { + if (!dead.containsKey(loc)) return; + try (Connection conn = db.getConnection(); + PreparedStatement ps = conn.prepareStatement(deleteDead)) { + ps.setString(1, loc.getWorld().getName()); + ps.setInt(2, loc.getBlockX()); + ps.setInt(3, loc.getBlockY()); + ps.setInt(4, loc.getBlockZ()); + ps.executeUpdate(); + dead.remove(loc); + } catch (SQLException e) { + log.log(Level.WARNING, "Failed to delete dead bastion at " + loc.toString(), e); + } + } + + public void moveDeadBastion(Location from, Location to) { + try (Connection conn = db.getConnection(); + PreparedStatement ps = conn.prepareStatement(moveDead)) { + ps.setString(1, to.getWorld().getName()); + ps.setInt(2, to.getBlockX()); + ps.setInt(3, to.getBlockY()); + ps.setInt(4, to.getBlockZ()); + ps.setString(5, from.getWorld().getName()); + ps.setInt(6, from.getBlockX()); + ps.setInt(7, from.getBlockY()); + ps.setInt(8, from.getBlockZ()); + ps.executeUpdate(); + dead.put(to, dead.remove(from)); + } catch (SQLException e) { + log.log(Level.WARNING, "Failed to move bastion at " + from.toString() + " to " + to.toString(), e); + } + } + + /** + * Updates a bastion in the database + * + * @param bastion The bastion to update + */ + private void updateBastion(BastionBlock bastion) { + try (Connection conn = db.getConnection(); + PreparedStatement ps = conn.prepareStatement(updateBastion)) { + ps.setLong(1, bastion.getPlaced()); + ps.setInt(2, bastion.getId()); + ps.executeUpdate(); + } catch (SQLException e) { + log.log(Level.WARNING, "Failed to update bastion at " + bastion.getLocation().toString(), e); + } + } + + /** + * Adds this bastion to a set of bastions to be updated + * + * @param bastion The bastion to be updated + */ + public void updated(BastionBlock bastion) { + changed.add(bastion); + } + + /** + * Find bastions that intersect a location + * + * @param loc The location to check + * @return A set of QTBoxes (bastions) that overlap with the location + */ + public Set forLocation(Location loc) { + return blocks.get(loc.getWorld()).find(loc.getBlockX(), loc.getBlockZ()); + } + + /** + * Retrieve possible blocking bastions for a thrown pearl + * + * @param loc The location of the pearl + * @param maxDistance The max distance the pearl could be from a bastion without collision + * @return A set of bastions a pearl could collide with + */ + public Set getPossibleTeleportBlocking(Location loc, double maxDistance) { + Set boxes = blocks.get(loc.getWorld()).find(loc.getBlockX(), loc.getBlockY(), true); + + double maxDistanceSquared = maxDistance * maxDistance; + double maxBoxDistanceSquared = maxDistanceSquared * 2.0; + + Set result = new TreeSet<>(); + + for (QTBox box : boxes) { + if (box instanceof BastionBlock) { + BastionBlock bastion = (BastionBlock) box; + BastionType type = bastion.getType(); + // Skip bastions who don't do midair blocking. + if (!type.isBlockPearls() || !type.isBlockMidair()) continue; + // Check on other conditions. + if (((type.isSquare() && bastion.getLocation().distanceSquared(loc) <= maxBoxDistanceSquared) || + (!type.isSquare() && bastion.getLocation().distanceSquared(loc) <= maxDistanceSquared)) && + (!type.isRequireMaturity() || bastion.isMature())) { + result.add(bastion); + } + } + } + return result; + } + + /** + * Retrieve possible blocking bastions for elytra flight + * + * @param maxDistance The max distance you could be without collision + * @param locs The locations the player is at while flying + * @return A set of bastions a flying player could collide with + */ + public Set getPossibleFlightBlocking(double maxDistance, Location... locs) { + Set boxes = null; + Set result = new TreeSet<>(); + double maxDistanceSquared = maxDistance * maxDistance; + double maxBoxDistanceSquared = maxDistanceSquared * 2.0; + + for (Location loc : locs) { boxes = blocks.get(loc.getWorld()).find(loc.getBlockX(), loc.getBlockZ(), true); Location yLoc = loc.clone(); - + for (QTBox box : boxes) { if (box instanceof BastionBlock) { - BastionBlock bastion = (BastionBlock)box; + BastionBlock bastion = (BastionBlock) box; BastionType type = bastion.getType(); // Don't add bastions that don't block flight if (!type.isBlockElytra()) continue; yLoc.setY(bastion.getLocation().getY()); // Fixed for square field nearness, using diagonal distance as max -- (radius * sqrt(2)) ^ 2 - if (((type.isSquare() && bastion.getLocation().distanceSquared(yLoc) <= maxBoxDistanceSquared) || - (!type.isSquare() && bastion.getLocation().distanceSquared(yLoc) <= maxDistanceSquared)) && - (!type.isElytraRequireMature() || bastion.isMature())) { + if (((type.isSquare() && bastion.getLocation().distanceSquared(yLoc) <= maxBoxDistanceSquared) || + (!type.isSquare() && bastion.getLocation().distanceSquared(yLoc) <= maxDistanceSquared)) && + (!type.isElytraRequireMature() || bastion.isMature())) { result.add(bastion); } } } } - return result; - } - - /** - * Retrieves a bastion at a given location - * @param loc Location of the bastion block - * @return The bastion block, can be null - */ - public BastionBlock getBastionBlock(Location loc) { - Set possible = forLocation(loc); - for(QTBox box : possible) { - BastionBlock bastion = (BastionBlock) box; - if(bastion.getLocation().equals(loc)) { - return bastion; - } - } - return null; - } - - /** - * Gets the type of the bastion, dead or alive, at a location - * @param loc Location of the bastion - * @return The type of bastion, can be null - */ - public BastionType getTypeAtLocation(Location loc) { - BastionBlock bastion = getBastionBlock(loc); - if(bastion != null) { - return bastion.getType(); - } - String type = dead.get(loc); - if(type != null) { - return BastionType.getBastionType(type); - } - return null; - } - - /** - * Loads all bastions from the database - */ - //@SuppressWarnings("deprecation") - public void loadBastions() { - int enderSearchRadius = EnderPearlManager.MAX_TELEPORT + 100; - for(World world : Bukkit.getWorlds()) { - SparseQuadTree bastionsForWorld = new SparseQuadTree<>(enderSearchRadius); - blocks.put(world, bastionsForWorld); - try (Connection conn = db.getConnection(); - PreparedStatement ps = conn.prepareStatement("select * from bastion_blocks where loc_world=?;")) { - ps.setString(1, world.getName()); - ResultSet result = ps.executeQuery(); - while(result.next()) { - int x = result.getInt("loc_x"); - int y = result.getInt("loc_y"); - int z = result.getInt("loc_z"); - int id = result.getInt("bastion_id"); - long placed = result.getLong("placed"); - BastionType type = BastionType.getBastionType(result.getString("bastion_type")); - boolean died = result.getBoolean("dead"); - Location loc = new Location(world, x, y, z); - BastionBlock block = new BastionBlock(loc, placed, id, type); - if (died) { - dead.put(loc, block.getType().getName()); - } else { - addBastion(block, bastionsForWorld); - } - } - } catch (SQLException e) { - log.log(Level.SEVERE, ChatColor.RED + "===== Error loading bastions from database, shutting down =====", e); - Bukkit.getServer().getPluginManager().disablePlugin(Bastion.getPlugin()); - } - } - } + return result; + } - private void update() { - int count = changed.size(); - for(BastionBlock block : changed) { - updateBastion(block); - } - changed.clear(); - log.info("Updated " + count + " bastions"); - } + /** + * Retrieves a bastion at a given location + * + * @param loc Location of the bastion block + * @return The bastion block, can be null + */ + public BastionBlock getBastionBlock(Location loc) { + Set possible = forLocation(loc); + for (QTBox box : possible) { + BastionBlock bastion = (BastionBlock) box; + if (bastion.getLocation().equals(loc)) { + return bastion; + } + } + return null; + } - /** - * List groups methods - **/ + /** + * Gets the type of the bastion, dead or alive, at a location + * + * @param loc Location of the bastion + * @return The type of bastion, can be null + */ + public BastionType getTypeAtLocation(Location loc) { + BastionBlock bastion = getBastionBlock(loc); + if (bastion != null) { + return bastion.getType(); + } + String type = dead.get(loc); + if (type != null) { + return BastionType.getBastionType(type); + } + return null; + } - public void changeBastionGroup(BastionBlock bastion) { - if(bastion.getListGroupId() != null) { - List oldGroupBastions = groups.get(bastion.getListGroupId()); + /** + * Loads all bastions from the database + */ + //@SuppressWarnings("deprecation") + public void loadBastions() { + int enderSearchRadius = EnderPearlManager.MAX_TELEPORT + 100; + for (World world : Bukkit.getWorlds()) { + SparseQuadTree bastionsForWorld = new SparseQuadTree<>(enderSearchRadius); + blocks.put(world, bastionsForWorld); + try (Connection conn = db.getConnection(); + PreparedStatement ps = conn.prepareStatement("select * from bastion_blocks where loc_world=?;")) { + ps.setString(1, world.getName()); + ResultSet result = ps.executeQuery(); + while (result.next()) { + int x = result.getInt("loc_x"); + int y = result.getInt("loc_y"); + int z = result.getInt("loc_z"); + int id = result.getInt("bastion_id"); + long placed = result.getLong("placed"); + BastionType type = BastionType.getBastionType(result.getString("bastion_type")); + boolean died = result.getBoolean("dead"); + Location loc = new Location(world, x, y, z); + BastionBlock block = new BastionBlock(loc, placed, id, type); + if (died) { + dead.put(loc, block.getType().getName()); + } else { + addBastion(block, bastionsForWorld); + } + } + } catch (SQLException e) { + log.log(Level.SEVERE, ChatColor.RED + "===== Error loading bastions from database, shutting down =====", e); + Bukkit.getServer().getPluginManager().disablePlugin(Bastion.getPlugin()); + } + } + } - if (oldGroupBastions != null) { - oldGroupBastions.remove(bastion); - } - } + private void update() { + int count = changed.size(); + for (BastionBlock block : changed) { + updateBastion(block); + } + changed.clear(); + log.info("Updated " + count + " bastions"); + } - Reinforcement rein = bastion.getReinforcement(); + /** + * List groups methods + **/ - if(rein != null) { - bastion.setListGroupId(rein.getGroupId()); + public void changeBastionGroup(BastionBlock bastion) { + if (bastion.getListGroupId() != null) { + List oldGroupBastions = groups.get(bastion.getListGroupId()); - List groupBastions = groups.get(rein.getGroupId()); + if (oldGroupBastions != null) { + oldGroupBastions.remove(bastion); + } + } - if(groupBastions == null) { - groups.put(rein.getGroupId(), groupBastions = new ArrayList<>()); - } + Reinforcement rein = bastion.getReinforcement(); - groupBastions.add(bastion); - } else { - bastion.setListGroupId(null); - } - } + if (rein != null) { + bastion.setListGroupId(rein.getGroupId()); - public void getBastionsByGroupIds(List groupIds, List result) { - synchronized (groups) { - for(Integer groupId : groupIds) { - List groupBastions = groups.get(groupId); + List groupBastions = groups.get(rein.getGroupId()); - if (groupBastions != null) { - for(BastionBlock bastion : groupBastions) { - result.add(bastion); - } - } - } - } - } + if (groupBastions == null) { + groups.put(rein.getGroupId(), groupBastions = new ArrayList<>()); + } - public void mergeGroups(int toGroupId, List fromGroupIds) { - synchronized (groups) { - List toGroupBastions = null; + groupBastions.add(bastion); + } else { + bastion.setListGroupId(null); + } + } - for(int fromGroupId : fromGroupIds) { - List fromGroupBastions = groups.get(fromGroupId); + public void getBastionsByGroupIds(List groupIds, List result) { + synchronized (groups) { + for (Integer groupId : groupIds) { + List groupBastions = groups.get(groupId); - if(fromGroupBastions == null) continue; + if (groupBastions != null) { + for (BastionBlock bastion : groupBastions) { + result.add(bastion); + } + } + } + } + } - if(toGroupBastions == null) { - toGroupBastions = groups.get(toGroupId); + public void mergeGroups(int toGroupId, List fromGroupIds) { + synchronized (groups) { + List toGroupBastions = null; - if(toGroupBastions == null) { - groups.put(toGroupId, toGroupBastions = new ArrayList<>()); - } - } + for (int fromGroupId : fromGroupIds) { + List fromGroupBastions = groups.get(fromGroupId); - toGroupBastions.addAll(fromGroupBastions); + if (fromGroupBastions == null) continue; - groups.remove(fromGroupId); - } - } - } + if (toGroupBastions == null) { + toGroupBastions = groups.get(toGroupId); - public void removeGroups(List groupIds) { - synchronized (groups) { - for(int groupId : groupIds) { - groups.remove(groupId); - } - } - } + if (toGroupBastions == null) { + groups.put(toGroupId, toGroupBastions = new ArrayList<>()); + } + } - private void addBastion(BastionBlock bastion) { - addBastion(bastion, blocks.get(bastion.getLocation().getWorld())); - } + toGroupBastions.addAll(fromGroupBastions); - private void addBastion(BastionBlock bastion, SparseQuadTree bastionsForWorld) { - bastions.add(bastion); - bastionsForWorld.add(bastion); + groups.remove(fromGroupId); + } + } + } - if(bastion.getListGroupId() != null) { - synchronized (groups) { - List groupBastions = groups.get(bastion.getListGroupId()); + public void removeGroups(List groupIds) { + synchronized (groups) { + for (int groupId : groupIds) { + groups.remove(groupId); + } + } + } - if (groupBastions == null) { - groups.put(bastion.getListGroupId(), groupBastions = new ArrayList<>()); - } + private void addBastion(BastionBlock bastion) { + addBastion(bastion, blocks.get(bastion.getLocation().getWorld())); + } - groupBastions.add(bastion); - } - } - } + private void addBastion(BastionBlock bastion, SparseQuadTree bastionsForWorld) { + bastions.add(bastion); + bastionsForWorld.add(bastion); - private void removeBastion(BastionBlock bastion) { - if(bastion.getListGroupId() != null) { - synchronized (groups) { - List groupBastions = groups.get(bastion.getListGroupId()); + if (bastion.getListGroupId() != null) { + synchronized (groups) { + List groupBastions = groups.get(bastion.getListGroupId()); - if (groupBastions != null) { - groupBastions.remove(bastion); - } - } - } + if (groupBastions == null) { + groups.put(bastion.getListGroupId(), groupBastions = new ArrayList<>()); + } - bastions.remove(bastion); - blocks.get(bastion.getLocation().getWorld()).remove(bastion); - } + groupBastions.add(bastion); + } + } + } - /** - * Gets a set of all bastion blocks across all worlds - * @return All the bastion blocks - */ - public Set getAllBastions() { - return bastions; - } - - /** - * Gets all bastions of a certain type - * @param type The type of bastion you want - * @return A set of bastions of that type - */ - public Set getBastionsForType(BastionType type) { - Set forType = new HashSet(); - for(BastionBlock bastion : bastions) { - if(bastion.getType().equals(type)) { - forType.add(bastion); - } - } - return forType; - } - - /** - * Allows the Break Listener to properly handle unreinforced bastions, at least - * until restart. - * - * TODO: Add persistence of "pending" bastions. - * - * @param loc The location to check for a pending bastion - * @return True if a bastion was pending there. - */ - public boolean isPendingBastion(Location loc) { - return pendingBastions.containsKey(loc); - } - - /** - * Remove from pending and return the type removed. - * Used by external break handlers. - * - * @param loc The location to get and return a pending bastion - * @return The type of the bastion that was pended. - */ - public BastionType getAndRemovePendingBastion(Location loc) { - return pendingBastions.remove(loc); - } - - /** - * Get from pending and return the type. - * Used by external break handlers. - * - * @param loc The location to get and return a pending bastion - * @return The type of the bastion that is pended. - */ - public BastionType getPendingBastion(Location loc) { - return pendingBastions.get(loc); - } - - /** - * Allows the Interact listener to register that a bastion block has been - * placed but is of yet unreinforced and not persisted by the database. - * - * TODO: Add persistence. - * - * @param loc The location to record a pended bastion - * @param type The type of the bastion pended - */ - public void addPendingBastion(Location loc, BastionType type) { - pendingBastions.put(loc, type); - } + private void removeBastion(BastionBlock bastion) { + if (bastion.getListGroupId() != null) { + synchronized (groups) { + List groupBastions = groups.get(bastion.getListGroupId()); + + if (groupBastions != null) { + groupBastions.remove(bastion); + } + } + } + + bastions.remove(bastion); + blocks.get(bastion.getLocation().getWorld()).remove(bastion); + } + + /** + * Gets a set of all bastion blocks across all worlds + * + * @return All the bastion blocks + */ + public Set getAllBastions() { + return bastions; + } + + /** + * Gets all bastions of a certain type + * + * @param type The type of bastion you want + * @return A set of bastions of that type + */ + public Set getBastionsForType(BastionType type) { + Set forType = new HashSet(); + for (BastionBlock bastion : bastions) { + if (bastion.getType().equals(type)) { + forType.add(bastion); + } + } + return forType; + } + + /** + * Allows the Break Listener to properly handle unreinforced bastions, at least + * until restart. + *

+ * TODO: Add persistence of "pending" bastions. + * + * @param loc The location to check for a pending bastion + * @return True if a bastion was pending there. + */ + public boolean isPendingBastion(Location loc) { + return pendingBastions.containsKey(loc); + } + + /** + * Remove from pending and return the type removed. + * Used by external break handlers. + * + * @param loc The location to get and return a pending bastion + * @return The type of the bastion that was pended. + */ + public BastionType getAndRemovePendingBastion(Location loc) { + return pendingBastions.remove(loc); + } + + /** + * Get from pending and return the type. + * Used by external break handlers. + * + * @param loc The location to get and return a pending bastion + * @return The type of the bastion that is pended. + */ + public BastionType getPendingBastion(Location loc) { + return pendingBastions.get(loc); + } + + /** + * Allows the Interact listener to register that a bastion block has been + * placed but is of yet unreinforced and not persisted by the database. + *

+ * TODO: Add persistence. + * + * @param loc The location to record a pended bastion + * @param type The type of the bastion pended + */ + public void addPendingBastion(Location loc, BastionType type) { + pendingBastions.put(loc, type); + } } diff --git a/plugins/bastion-paper/src/main/java/isaac/bastion/storage/BastionGroupStorage.java b/plugins/bastion-paper/src/main/java/isaac/bastion/storage/BastionGroupStorage.java index ce2625494..e2b37072e 100644 --- a/plugins/bastion-paper/src/main/java/isaac/bastion/storage/BastionGroupStorage.java +++ b/plugins/bastion-paper/src/main/java/isaac/bastion/storage/BastionGroupStorage.java @@ -26,274 +26,279 @@ import vg.civcraft.mc.namelayer.GroupManager; import vg.civcraft.mc.namelayer.group.Group; public class BastionGroupStorage { - private static class Operation { - public int groupId; - public int allowedGroupId; - public boolean isAdded; - } - private static class BastionGroupAndAllowed { - public BastionGroup bastionGroup; - public Integer allowedGroupId; - } + private static class Operation { - private static final int saveDelay = 60 * 20; //once per 1 minute + public int groupId; + public int allowedGroupId; + public boolean isAdded; + } - private ManagedDatasource db; - private Logger log; + private static class BastionGroupAndAllowed { - private List changed; - private Queue localChanged = new ArrayDeque<>(); + public BastionGroup bastionGroup; + public Integer allowedGroupId; + } - private Map groups; - private int taskId; + private static final int saveDelay = 60 * 20; //once per 1 minute - private static final String selectAllGroups = "select * from bastion_groups order by bastion_group_id;"; - private static final String selectGroup = "select * from bastion_groups where bastion_group_id = ? and allowed_group_id = ?;"; - private static final String addGroup = "insert into bastion_groups (bastion_group_id, allowed_group_id) values (?, ?);"; - private static final String deleteGroup = "delete from bastion_groups where bastion_group_id = ? and allowed_group_id = ?;"; + private ManagedDatasource db; + private Logger log; - public BastionGroupStorage(ManagedDatasource db, Logger log) { - this.changed = new ArrayList<>(); - this.groups = new HashMap<>(); - this.db = db; - this.log = log; + private List changed; + private Queue localChanged = new ArrayDeque<>(); - this.taskId = new BukkitRunnable(){ - @Override - public void run(){ - updateChanged(); - } - }.runTaskTimerAsynchronously(Bastion.getPlugin(), saveDelay, saveDelay).getTaskId(); - } + private Map groups; + private int taskId; - /** - * Updates all remaining bastions and cancels the update task - */ - public void close() { - Bukkit.getScheduler().cancelTask(this.taskId); - updateChanged(); - } + private static final String selectAllGroups = "select * from bastion_groups order by bastion_group_id;"; + private static final String selectGroup = "select * from bastion_groups where bastion_group_id = ? and allowed_group_id = ?;"; + private static final String addGroup = "insert into bastion_groups (bastion_group_id, allowed_group_id) values (?, ?);"; + private static final String deleteGroup = "delete from bastion_groups where bastion_group_id = ? and allowed_group_id = ?;"; - /** - * Data manipulations methods - */ + public BastionGroupStorage(ManagedDatasource db, Logger log) { + this.changed = new ArrayList<>(); + this.groups = new HashMap<>(); + this.db = db; + this.log = log; - /** - * Adds bastion group - * @param group Bastion's group - * @param allowedGroup Allowed group - * @return True is group was added, False - if it already exist - */ - public boolean addAllowedGroup(Group group, Group allowedGroup) { - List bastionGroups = getBastionGroups(group); + this.taskId = new BukkitRunnable() { + @Override + public void run() { + updateChanged(); + } + }.runTaskTimerAsynchronously(Bastion.getPlugin(), saveDelay, saveDelay).getTaskId(); + } - if(findBastionGroupAndAllowed(bastionGroups, allowedGroup) != null) return false; + /** + * Updates all remaining bastions and cancels the update task + */ + public void close() { + Bukkit.getScheduler().cancelTask(this.taskId); + updateChanged(); + } - BastionGroup bastionGroup; + /** + * Data manipulations methods + */ - if(bastionGroups.size() > 0) { - bastionGroup = bastionGroups.get(0); - } else { - this.groups.put(group.getGroupId(), bastionGroup = new BastionGroup(group.getGroupId())); - } + /** + * Adds bastion group + * + * @param group Bastion's group + * @param allowedGroup Allowed group + * @return True is group was added, False - if it already exist + */ + public boolean addAllowedGroup(Group group, Group allowedGroup) { + List bastionGroups = getBastionGroups(group); - bastionGroup.addAllowedGroup(allowedGroup.getGroupId()); - addChanged(bastionGroup.getGroupId(), allowedGroup.getGroupId(), true); + if (findBastionGroupAndAllowed(bastionGroups, allowedGroup) != null) return false; - return true; - } + BastionGroup bastionGroup; - /** - * Deletes a bastion group - * @param group The bastion's group - * @param allowedGroup The allowed group name to delete - * @return True is group was deleted, False - if group doesn't exist - */ - public boolean deleteAllowedGroup(Group group, Group allowedGroup) { - boolean isDeleted = false; - BastionGroupAndAllowed bastionGroupAndAllowed; + if (bastionGroups.size() > 0) { + bastionGroup = bastionGroups.get(0); + } else { + this.groups.put(group.getGroupId(), bastionGroup = new BastionGroup(group.getGroupId())); + } - while((bastionGroupAndAllowed = getBastionGroupByAllowed(group, allowedGroup)) != null) { - if (!bastionGroupAndAllowed.bastionGroup.removeAllowedGroup(bastionGroupAndAllowed.allowedGroupId)) { - this.groups.remove(bastionGroupAndAllowed.bastionGroup.getGroupId()); - } + bastionGroup.addAllowedGroup(allowedGroup.getGroupId()); + addChanged(bastionGroup.getGroupId(), allowedGroup.getGroupId(), true); - addChanged(bastionGroupAndAllowed.bastionGroup.getGroupId(), bastionGroupAndAllowed.allowedGroupId, false); + return true; + } - isDeleted = true; - } + /** + * Deletes a bastion group + * + * @param group The bastion's group + * @param allowedGroup The allowed group name to delete + * @return True is group was deleted, False - if group doesn't exist + */ + public boolean deleteAllowedGroup(Group group, Group allowedGroup) { + boolean isDeleted = false; + BastionGroupAndAllowed bastionGroupAndAllowed; - return isDeleted; - } + while ((bastionGroupAndAllowed = getBastionGroupByAllowed(group, allowedGroup)) != null) { + if (!bastionGroupAndAllowed.bastionGroup.removeAllowedGroup(bastionGroupAndAllowed.allowedGroupId)) { + this.groups.remove(bastionGroupAndAllowed.bastionGroup.getGroupId()); + } - public boolean isAllowedGroup(Group group, Group allowedGroup) { - return group.equals(allowedGroup) || getBastionGroupByAllowed(group, allowedGroup) != null; - } + addChanged(bastionGroupAndAllowed.bastionGroup.getGroupId(), bastionGroupAndAllowed.allowedGroupId, false); - public List getBastionGroups(Group group) { - List bastionGroups = new ArrayList(); + isDeleted = true; + } - for(int groupId : group.getGroupIds()) { - BastionGroup bastionGroup = this.groups.get(groupId); + return isDeleted; + } - if(bastionGroup != null) { - bastionGroups.add(bastionGroup); - } - } + public boolean isAllowedGroup(Group group, Group allowedGroup) { + return group.equals(allowedGroup) || getBastionGroupByAllowed(group, allowedGroup) != null; + } - return bastionGroups; - } + public List getBastionGroups(Group group) { + List bastionGroups = new ArrayList(); + + for (int groupId : group.getGroupIds()) { + BastionGroup bastionGroup = this.groups.get(groupId); + + if (bastionGroup != null) { + bastionGroups.add(bastionGroup); + } + } + + return bastionGroups; + } - /** - * Loads all bastion groups from the database - */ - public void loadGroups() { - try ( - Connection conn = this.db.getConnection(); - PreparedStatement ps = conn.prepareStatement(selectAllGroups) - ) { - int validCount = 0; - int invalidCount = 0; - ResultSet result = ps.executeQuery(); + /** + * Loads all bastion groups from the database + */ + public void loadGroups() { + try ( + Connection conn = this.db.getConnection(); + PreparedStatement ps = conn.prepareStatement(selectAllGroups) + ) { + int validCount = 0; + int invalidCount = 0; + ResultSet result = ps.executeQuery(); - while(result.next()) { - int groupId = result.getInt("bastion_group_id"); - int allowedGroupId = result.getInt("allowed_group_id"); - Group group = GroupManager.getGroup(groupId); - Group allowedGroup = GroupManager.getGroup(allowedGroupId); + while (result.next()) { + int groupId = result.getInt("bastion_group_id"); + int allowedGroupId = result.getInt("allowed_group_id"); + Group group = GroupManager.getGroup(groupId); + Group allowedGroup = GroupManager.getGroup(allowedGroupId); - if(group == null || allowedGroup == null) { - addChanged(groupId, allowedGroupId, false); - invalidCount++; - } else { - BastionGroup bastionGroup = this.groups.get(groupId); + if (group == null || allowedGroup == null) { + addChanged(groupId, allowedGroupId, false); + invalidCount++; + } else { + BastionGroup bastionGroup = this.groups.get(groupId); - if(bastionGroup == null) { - this.groups.put(groupId, bastionGroup = new BastionGroup(groupId)); - } + if (bastionGroup == null) { + this.groups.put(groupId, bastionGroup = new BastionGroup(groupId)); + } - bastionGroup.addAllowedGroup(allowedGroupId); + bastionGroup.addAllowedGroup(allowedGroupId); - validCount++; - } - } + validCount++; + } + } - log.info("Loaded " + this.groups.size() + " bastion groups with " + validCount + " allowed groups."); + log.info("Loaded " + this.groups.size() + " bastion groups with " + validCount + " allowed groups."); - if(invalidCount > 0) { - log.info(" Marked to delete " + invalidCount + " records for non-existent groups."); - } - } catch (SQLException e) { - e.printStackTrace(); - log.log(Level.SEVERE, ChatColor.RED + "===== Error loading bastion groups from database, shutting down =====", e); - Bukkit.getServer().getPluginManager().disablePlugin(Bastion.getPlugin()); - } - } + if (invalidCount > 0) { + log.info(" Marked to delete " + invalidCount + " records for non-existent groups."); + } + } catch (SQLException e) { + e.printStackTrace(); + log.log(Level.SEVERE, ChatColor.RED + "===== Error loading bastion groups from database, shutting down =====", e); + Bukkit.getServer().getPluginManager().disablePlugin(Bastion.getPlugin()); + } + } - /** - * Scheduled task methods - */ + /** + * Scheduled task methods + */ - private void updateChanged() { - try { - synchronized (this.changed) { - if (this.changed.size() != 0) { - this.localChanged.addAll(this.changed); - this.changed.clear(); - } - } + private void updateChanged() { + try { + synchronized (this.changed) { + if (this.changed.size() != 0) { + this.localChanged.addAll(this.changed); + this.changed.clear(); + } + } - this.log.info("'Update bastion groups' task begin, found " + this.localChanged.size() + " operations to proceed"); + this.log.info("'Update bastion groups' task begin, found " + this.localChanged.size() + " operations to proceed"); - int count = 0; + int count = 0; - try { - Operation operation; + try { + Operation operation; - while ((operation = this.localChanged.poll()) != null) { - update(operation); - count++; - } - } finally { - this.log.info("'Update bastion groups' task ended, " + count + " operations proceeded"); - } - } catch (Exception e) { - e.printStackTrace(); - } - } + while ((operation = this.localChanged.poll()) != null) { + update(operation); + count++; + } + } finally { + this.log.info("'Update bastion groups' task ended, " + count + " operations proceeded"); + } + } catch (Exception e) { + e.printStackTrace(); + } + } - private void update(Operation operation) { - try (Connection conn = db.getConnection()) { - if(operation.isAdded) { - try (PreparedStatement ps = conn.prepareStatement(selectGroup)) { - ps.setInt(1, operation.groupId); - ps.setInt(2, operation.allowedGroupId); + private void update(Operation operation) { + try (Connection conn = db.getConnection()) { + if (operation.isAdded) { + try (PreparedStatement ps = conn.prepareStatement(selectGroup)) { + ps.setInt(1, operation.groupId); + ps.setInt(2, operation.allowedGroupId); - try (ResultSet result = ps.executeQuery()) { - boolean hasData = result.next(); + try (ResultSet result = ps.executeQuery()) { + boolean hasData = result.next(); - if (hasData) return; - } catch (SQLException e2) { - e2.printStackTrace(); - return; - } - } catch (SQLException e1) { - e1.printStackTrace(); - return; - } - } + if (hasData) return; + } catch (SQLException e2) { + e2.printStackTrace(); + return; + } + } catch (SQLException e1) { + e1.printStackTrace(); + return; + } + } - String sql = operation.isAdded ? addGroup : deleteGroup; + String sql = operation.isAdded ? addGroup : deleteGroup; - try (PreparedStatement ps = conn.prepareStatement(sql)) { - ps.setInt(1, operation.groupId); - ps.setInt(2, operation.allowedGroupId); - ps.executeUpdate(); - } catch (SQLException e1) { - e1.printStackTrace(); - } - } catch (SQLException e2) { - e2.printStackTrace(); - } - } + try (PreparedStatement ps = conn.prepareStatement(sql)) { + ps.setInt(1, operation.groupId); + ps.setInt(2, operation.allowedGroupId); + ps.executeUpdate(); + } catch (SQLException e1) { + e1.printStackTrace(); + } + } catch (SQLException e2) { + e2.printStackTrace(); + } + } - /** - * Helper methods - */ + /** + * Helper methods + */ - private void addChanged(int groupId, int allowedGroupId, boolean isAdded) { - Operation operation = new Operation(); - operation.groupId = groupId; - operation.allowedGroupId = allowedGroupId; - operation.isAdded = isAdded; + private void addChanged(int groupId, int allowedGroupId, boolean isAdded) { + Operation operation = new Operation(); + operation.groupId = groupId; + operation.allowedGroupId = allowedGroupId; + operation.isAdded = isAdded; - synchronized (this.changed) { - this.changed.add(operation); - } - } + synchronized (this.changed) { + this.changed.add(operation); + } + } - private BastionGroupAndAllowed getBastionGroupByAllowed(Group group, Group allowedGroup) { - List bastionGroups = getBastionGroups(group); - return bastionGroups.size() > 0 ? findBastionGroupAndAllowed(bastionGroups, allowedGroup) : null; - } + private BastionGroupAndAllowed getBastionGroupByAllowed(Group group, Group allowedGroup) { + List bastionGroups = getBastionGroups(group); + return bastionGroups.size() > 0 ? findBastionGroupAndAllowed(bastionGroups, allowedGroup) : null; + } - private BastionGroupAndAllowed findBastionGroupAndAllowed(List bastionGroups, Group allowedGroup) { - List allowedGroupIds = allowedGroup.getGroupIds(); + private BastionGroupAndAllowed findBastionGroupAndAllowed(List bastionGroups, Group allowedGroup) { + List allowedGroupIds = allowedGroup.getGroupIds(); - for(BastionGroup bastionGroup : bastionGroups) { - for(int allowedGroupId : allowedGroupIds) { - if(bastionGroup.isAllowedGroup(allowedGroupId)) { - BastionGroupAndAllowed result = new BastionGroupAndAllowed(); - result.bastionGroup = bastionGroup; - result.allowedGroupId = allowedGroupId; + for (BastionGroup bastionGroup : bastionGroups) { + for (int allowedGroupId : allowedGroupIds) { + if (bastionGroup.isAllowedGroup(allowedGroupId)) { + BastionGroupAndAllowed result = new BastionGroupAndAllowed(); + result.bastionGroup = bastionGroup; + result.allowedGroupId = allowedGroupId; - return result; - } - } - } + return result; + } + } + } - return null; - } + return null; + } } diff --git a/plugins/bastion-paper/src/main/java/isaac/bastion/storage/Database.java b/plugins/bastion-paper/src/main/java/isaac/bastion/storage/Database.java index c67bf429d..744af5bf2 100644 --- a/plugins/bastion-paper/src/main/java/isaac/bastion/storage/Database.java +++ b/plugins/bastion-paper/src/main/java/isaac/bastion/storage/Database.java @@ -8,30 +8,31 @@ import isaac.bastion.BastionType; import vg.civcraft.mc.civmodcore.dao.ManagedDatasource; public class Database { - public static void registerMigrations(ManagedDatasource db) { - db.registerMigration(0, false, - "create table if not exists `bastion_blocks`(" - + "bastion_id int(10) unsigned NOT NULL AUTO_INCREMENT," - + "bastion_type varchar(40) DEFAULT '" + BastionType.getDefaultType() + "'," - + "loc_x int(10)," - + "loc_y int(10)," - + "loc_z int(10)," - + "loc_world varchar(40) NOT NULL," - + "placed bigint(20) Unsigned," - + "fraction float(20) Unsigned," - + "PRIMARY KEY (`bastion_id`));"); - db.registerMigration(1, false, - "ALTER TABLE bastion_blocks ADD COLUMN IF NOT EXISTS bastion_type VARCHAR(40) DEFAULT '" - + BastionType.getDefaultType() + "';"); + public static void registerMigrations(ManagedDatasource db) { + db.registerMigration(0, false, + "create table if not exists `bastion_blocks`(" + + "bastion_id int(10) unsigned NOT NULL AUTO_INCREMENT," + + "bastion_type varchar(40) DEFAULT '" + BastionType.getDefaultType() + "'," + + "loc_x int(10)," + + "loc_y int(10)," + + "loc_z int(10)," + + "loc_world varchar(40) NOT NULL," + + "placed bigint(20) Unsigned," + + "fraction float(20) Unsigned," + + "PRIMARY KEY (`bastion_id`));"); - db.registerMigration(2, false, - "ALTER TABLE bastion_blocks ADD COLUMN IF NOT EXISTS dead TINYINT(1) DEFAULT 0;"); + db.registerMigration(1, false, + "ALTER TABLE bastion_blocks ADD COLUMN IF NOT EXISTS bastion_type VARCHAR(40) DEFAULT '" + + BastionType.getDefaultType() + "';"); - db.registerMigration(3, false, - "create table if not exists `bastion_groups`(" - + "bastion_group_id int not null," - + "allowed_group_id int not null," - + "PRIMARY KEY (bastion_group_id, allowed_group_id));"); - } + db.registerMigration(2, false, + "ALTER TABLE bastion_blocks ADD COLUMN IF NOT EXISTS dead TINYINT(1) DEFAULT 0;"); + + db.registerMigration(3, false, + "create table if not exists `bastion_groups`(" + + "bastion_group_id int not null," + + "allowed_group_id int not null," + + "PRIMARY KEY (bastion_group_id, allowed_group_id));"); + } } diff --git a/plugins/bastion-paper/src/main/java/isaac/bastion/utils/BastionSettingManager.java b/plugins/bastion-paper/src/main/java/isaac/bastion/utils/BastionSettingManager.java index c4c04b7fc..f947b13e9 100644 --- a/plugins/bastion-paper/src/main/java/isaac/bastion/utils/BastionSettingManager.java +++ b/plugins/bastion-paper/src/main/java/isaac/bastion/utils/BastionSettingManager.java @@ -12,44 +12,44 @@ import vg.civcraft.mc.civmodcore.players.settings.impl.DisplayLocationSetting; public class BastionSettingManager { - private BooleanSetting bsiOverlay; - private BooleanSetting showNoBastion; - private DisplayLocationSetting bsiLocation; - private BooleanSetting ignorePlacementWarnings; + private BooleanSetting bsiOverlay; + private BooleanSetting showNoBastion; + private DisplayLocationSetting bsiLocation; + private BooleanSetting ignorePlacementWarnings; - public BastionSettingManager() { - initSettings(); - } + public BastionSettingManager() { + initSettings(); + } - private void initSettings() { - MenuSection menu = new MenuSection("Bastion", "All settings related to Bastion", PlayerSettingAPI.getMainMenu(), - new ItemStack(BastionType.getBastionType(BastionType.getDefaultType()).getMaterial())); + private void initSettings() { + MenuSection menu = new MenuSection("Bastion", "All settings related to Bastion", PlayerSettingAPI.getMainMenu(), + new ItemStack(BastionType.getBastionType(BastionType.getDefaultType()).getMaterial())); - bsiOverlay = new BooleanSetting(Bastion.getPlugin(), true, "Display Bastion Information", "bsiOverlay", "Shows if the block you're standing on is bastioned territory."); - showNoBastion = new BooleanSetting(Bastion.getPlugin(), false, "Display if you are not in a bastion field", "showNoBastion", "If enabled, will display Bastion status, even if you are not currently in a bastion field"); - bsiLocation = new DisplayLocationSetting(Bastion.getPlugin(), DisplayLocationSetting.DisplayLocation.SIDEBAR, "BSI Location", "bsiLocation", new ItemStack(Material.ARROW), "BSI"); - ignorePlacementWarnings = new BooleanSetting(Bastion.getPlugin(), false, "Ignore placement warnings", "ignorePlacementWarnings", "Show placements warning in chat when placing in a bastion field"); + bsiOverlay = new BooleanSetting(Bastion.getPlugin(), true, "Display Bastion Information", "bsiOverlay", "Shows if the block you're standing on is bastioned territory."); + showNoBastion = new BooleanSetting(Bastion.getPlugin(), false, "Display if you are not in a bastion field", "showNoBastion", "If enabled, will display Bastion status, even if you are not currently in a bastion field"); + bsiLocation = new DisplayLocationSetting(Bastion.getPlugin(), DisplayLocationSetting.DisplayLocation.SIDEBAR, "BSI Location", "bsiLocation", new ItemStack(Material.ARROW), "BSI"); + ignorePlacementWarnings = new BooleanSetting(Bastion.getPlugin(), false, "Ignore placement warnings", "ignorePlacementWarnings", "Show placements warning in chat when placing in a bastion field"); - menu.registerToParentMenu(); - menu.registerSetting(bsiOverlay); - menu.registerSetting(showNoBastion); - menu.registerSetting(bsiLocation); - menu.registerSetting(ignorePlacementWarnings); - } + menu.registerToParentMenu(); + menu.registerSetting(bsiOverlay); + menu.registerSetting(showNoBastion); + menu.registerSetting(bsiLocation); + menu.registerSetting(ignorePlacementWarnings); + } - public BooleanSetting getBsiOverlay() { - return bsiOverlay; - } + public BooleanSetting getBsiOverlay() { + return bsiOverlay; + } - public DisplayLocationSetting getBsiLocation() { - return bsiLocation; - } + public DisplayLocationSetting getBsiLocation() { + return bsiLocation; + } - public boolean getShowNoBastion(UUID uuid) { - return showNoBastion.getValue(uuid); - } + public boolean getShowNoBastion(UUID uuid) { + return showNoBastion.getValue(uuid); + } - public boolean getIgnorePlacementMessages(UUID uuid) { - return ignorePlacementWarnings.getValue(uuid); - } + public boolean getIgnorePlacementMessages(UUID uuid) { + return ignorePlacementWarnings.getValue(uuid); + } } diff --git a/plugins/bastion-paper/src/main/java/isaac/bastion/utils/ChatFiller.java b/plugins/bastion-paper/src/main/java/isaac/bastion/utils/ChatFiller.java index c2a6d8a61..9064020e8 100644 --- a/plugins/bastion-paper/src/main/java/isaac/bastion/utils/ChatFiller.java +++ b/plugins/bastion-paper/src/main/java/isaac/bastion/utils/ChatFiller.java @@ -11,246 +11,250 @@ import java.util.Set; import org.bukkit.ChatColor; public class ChatFiller { - /** - * Default character length. - */ - public final static Double DEFAULT_LENGTH = 3.0 / 2.0; - /** - * Maximum character length. - */ - public final static Double MAX_LENGTH = 3.0 / 2.0; + /** + * Default character length. + */ + public final static Double DEFAULT_LENGTH = 3.0 / 2.0; - /** - * Gap fill string maximum size. - */ - private final static Double MAX_GAP = 1.25; + /** + * Maximum character length. + */ + public final static Double MAX_LENGTH = 3.0 / 2.0; - /** - * Chat width. - */ - public final static Double CHAT_WIDTH = 80.0; + /** + * Gap fill string maximum size. + */ + private final static Double MAX_GAP = 1.25; - /** - * Size map. - */ - private final static HashMap SIZE_MAP = new HashMap() { + /** + * Chat width. + */ + public final static Double CHAT_WIDTH = 80.0; - /** - * Serial version UID. - */ - private static final long serialVersionUID = 1L; + /** + * Size map. + */ + private final static HashMap SIZE_MAP = new HashMap() { - { - put('i', 0.5); - put('k', 5.0 / 4.0); - put('t', 1.0); - put('f', 5.0 / 4.0); - put('(', 5.0 / 4.0); - put(')', 5.0 / 4.0); - put('<', 5.0 / 4.0); - put('>', 5.0 / 4.0); - put('{', 5.0 / 4.0); - put('}', 5.0 / 4.0); - put(',', 1.0 / 2.0); - put('.', 1.0 / 2.0); - put('[', 1.0); - put(']', 1.0); - put('I', 1.0); - put('|', 1.0 / 2.0); - put('*', 5.0 / 4.0); - put('"', 5.0 / 4.0); - put('|', 0.5); - put('!', 0.5); - put(':', 0.5); - put('l', 3.0 / 4.0); - put('.', 1.0 / 2.0); - put('\'', 3.0 / 4.0); - put(' ', 1.0 / 1.0); - put('\"', 5.0 / 4.0); - put('`', 0.5); - put('\0', 0.0); + /** + * Serial version UID. + */ + private static final long serialVersionUID = 1L; - put(' ', 1.0); + { + put('i', 0.5); + put('k', 5.0 / 4.0); + put('t', 1.0); + put('f', 5.0 / 4.0); + put('(', 5.0 / 4.0); + put(')', 5.0 / 4.0); + put('<', 5.0 / 4.0); + put('>', 5.0 / 4.0); + put('{', 5.0 / 4.0); + put('}', 5.0 / 4.0); + put(',', 1.0 / 2.0); + put('.', 1.0 / 2.0); + put('[', 1.0); + put(']', 1.0); + put('I', 1.0); + put('|', 1.0 / 2.0); + put('*', 5.0 / 4.0); + put('"', 5.0 / 4.0); + put('|', 0.5); + put('!', 0.5); + put(':', 0.5); + put('l', 3.0 / 4.0); + put('.', 1.0 / 2.0); + put('\'', 3.0 / 4.0); + put(' ', 1.0 / 1.0); + put('\"', 5.0 / 4.0); + put('`', 0.5); + put('\0', 0.0); - put('\u2500', 5.0 / 4.0); - put('\u2502', 1.0 / 4.0); - put('\u250C', 3.0 / 4.0); - put('\u2510', 3.0 / 4.0); - put('\u2514', 3.0 / 4.0); - put('\u2518', 3.0 / 4.0); + put(' ', 1.0); - put('\u2550', 5.0 / 4.0); - put('\u2551', 1.0 / 2.0); + put('\u2500', 5.0 / 4.0); + put('\u2502', 1.0 / 4.0); + put('\u250C', 3.0 / 4.0); + put('\u2510', 3.0 / 4.0); + put('\u2514', 3.0 / 4.0); + put('\u2518', 3.0 / 4.0); - put('\u2554', 3.0 / 4.0); - put('\u2560', 3.0 / 4.0); - put('\u255A', 3.0 / 4.0); + put('\u2550', 5.0 / 4.0); + put('\u2551', 1.0 / 2.0); - put('\u2557', 4.0 / 4.0); - put('\u2563', 4.0 / 4.0); - put('\u255D', 4.0 / 4.0); + put('\u2554', 3.0 / 4.0); + put('\u2560', 3.0 / 4.0); + put('\u255A', 3.0 / 4.0); - put('\u2591', 2.0); - } - }; + put('\u2557', 4.0 / 4.0); + put('\u2563', 4.0 / 4.0); + put('\u255D', 4.0 / 4.0); - /** - * Gap fill chars. - */ - private final static HashSet FILL_CHARS = new HashSet() { + put('\u2591', 2.0); + } + }; - private static final long serialVersionUID = 1L; - { - add(' '); - } - }; + /** + * Gap fill chars. + */ + private final static HashSet FILL_CHARS = new HashSet() { - /** - * Trims and/or fills a string to be as close to the required length without exceeding it. - * If the string is trimmed, the supplied suffix is added (provided that won't exceed reqLength) - * @param str string to trim/fill - * @param reqLength required length - * @return the trimmed/filled string - */ - public static String fillString(String str, Double reqLength, String suffix) { + private static final long serialVersionUID = 1L; - double suffixLength = calcLength(suffix); - char[] chars = str.toCharArray(); - StringBuffer result = new StringBuffer(); - StringBuffer suffixResult = new StringBuffer(); - Double length = 0.0; + { + add(' '); + } + }; - // Cut size and add suffix if necessary - boolean suffixFilled = false; - for (int i = 0; i < chars.length; i++) { - Double charLength = SIZE_MAP.get(chars[i]); - if (charLength == null) { - charLength = DEFAULT_LENGTH; - } + /** + * Trims and/or fills a string to be as close to the required length without exceeding it. + * If the string is trimmed, the supplied suffix is added (provided that won't exceed reqLength) + * + * @param str string to trim/fill + * @param reqLength required length + * @return the trimmed/filled string + */ + public static String fillString(String str, Double reqLength, String suffix) { - if (!suffixFilled && length + charLength + suffixLength > reqLength) { - suffixFilled = true; - suffixResult.append(suffix); - } + double suffixLength = calcLength(suffix); + char[] chars = str.toCharArray(); + StringBuffer result = new StringBuffer(); + StringBuffer suffixResult = new StringBuffer(); + Double length = 0.0; - if (length + charLength > reqLength) { - result = suffixResult; - break; - } + // Cut size and add suffix if necessary + boolean suffixFilled = false; + for (int i = 0; i < chars.length; i++) { + Double charLength = SIZE_MAP.get(chars[i]); + if (charLength == null) { + charLength = DEFAULT_LENGTH; + } - result.append(chars[i]); - if (!suffixFilled) { - suffixResult.append(chars[i]); - } + if (!suffixFilled && length + charLength + suffixLength > reqLength) { + suffixFilled = true; + suffixResult.append(suffix); + } - if (!(chars[i] == ChatColor.COLOR_CHAR || (i > 0 && chars[i - 1] == ChatColor.COLOR_CHAR))) { - length += charLength; - } - } + if (length + charLength > reqLength) { + result = suffixResult; + break; + } - // Add spaces: - Character fillChar = ' '; - Double fillLength = 1.0; - while (true) { - Double gapLength = reqLength - length; + result.append(chars[i]); + if (!suffixFilled) { + suffixResult.append(chars[i]); + } - // Gap filled: - if (gapLength <= 0) { - break; - } + if (!(chars[i] == ChatColor.COLOR_CHAR || (i > 0 && chars[i - 1] == ChatColor.COLOR_CHAR))) { + length += charLength; + } + } - // Add custom fillers: - if (gapLength <= MAX_GAP) { + // Add spaces: + Character fillChar = ' '; + Double fillLength = 1.0; + while (true) { + Double gapLength = reqLength - length; - fillChar = findCustom(gapLength, reqLength); - if (fillChar != null) { - result.append(fillChar); - fillLength = SIZE_MAP.get(fillChar); - } - break; - } - result.append(fillChar); - length += fillLength; - } - return result.toString(); - } + // Gap filled: + if (gapLength <= 0) { + break; + } - /** - * Trims and/or fills a string to be as close to the required length without exceeding it. - * If the string is trimmed, no suffix is added - * @param str string to trim/fill - * @param reqLength required length - * @return the trimmed/filled string equal to or bigger the required length - */ - public static String fillString(String str, Double reqLength) { + // Add custom fillers: + if (gapLength <= MAX_GAP) { - return fillString(str, reqLength, ""); - } + fillChar = findCustom(gapLength, reqLength); + if (fillChar != null) { + result.append(fillChar); + fillLength = SIZE_MAP.get(fillChar); + } + break; + } + result.append(fillChar); + length += fillLength; + } + return result.toString(); + } - /** - * Finds a custom character with the best fit. - * - * @param gapLen gap length - * @param reqLength required length - * @return char that best fits the gap, null if none - */ - private static Character findCustom(Double gapLen, Double reqLength) { + /** + * Trims and/or fills a string to be as close to the required length without exceeding it. + * If the string is trimmed, no suffix is added + * + * @param str string to trim/fill + * @param reqLength required length + * @return the trimmed/filled string equal to or bigger the required length + */ + public static String fillString(String str, Double reqLength) { - Set gapStrs = new HashSet(FILL_CHARS); - Double bestFitLen = -1.0; - Character bestFitStr = null; + return fillString(str, reqLength, ""); + } - for (Character gapStr : gapStrs) { + /** + * Finds a custom character with the best fit. + * + * @param gapLen gap length + * @param reqLength required length + * @return char that best fits the gap, null if none + */ + private static Character findCustom(Double gapLen, Double reqLength) { - Double gapStrLen = SIZE_MAP.get(gapStr); + Set gapStrs = new HashSet(FILL_CHARS); + Double bestFitLen = -1.0; + Character bestFitStr = null; - if (gapLen - gapStrLen >= 0 && gapStrLen > bestFitLen) { - bestFitLen = gapStrLen; - bestFitStr = gapStr; - } - } - return bestFitStr; - } + for (Character gapStr : gapStrs) { - /** - * Calculates the length of a string. - * - * @param str string - * @return string length - */ - public static Double calcLength(String str) { + Double gapStrLen = SIZE_MAP.get(gapStr); - char[] chars = str.toCharArray(); + if (gapLen - gapStrLen >= 0 && gapStrLen > bestFitLen) { + bestFitLen = gapStrLen; + bestFitStr = gapStr; + } + } + return bestFitStr; + } - Double length = 0.0; + /** + * Calculates the length of a string. + * + * @param str string + * @return string length + */ + public static Double calcLength(String str) { - for (int i = 0; i < chars.length; i++) { - Double charLength = SIZE_MAP.get(chars[i]); - if (charLength == null) { - charLength = DEFAULT_LENGTH; - } + char[] chars = str.toCharArray(); - if (!(chars[i] == ChatColor.COLOR_CHAR || (i > 0 && chars[i - 1] == ChatColor.COLOR_CHAR))) { - length += charLength; - } - } - return length; - } + Double length = 0.0; - /** - * Adjusts filler characters. - * - * @param str string - * @return adjusted string - */ - public static String adjustFillers(String str) { + for (int i = 0; i < chars.length; i++) { + Double charLength = SIZE_MAP.get(chars[i]); + if (charLength == null) { + charLength = DEFAULT_LENGTH; + } - str = str.replace("\u278A", ChatColor.DARK_GRAY + "`"); + if (!(chars[i] == ChatColor.COLOR_CHAR || (i > 0 && chars[i - 1] == ChatColor.COLOR_CHAR))) { + length += charLength; + } + } + return length; + } - str = str.replace("\u278B", ChatColor.DARK_GRAY + "" + ChatColor.BOLD + "`"); - str = str.replace("\u278C", ChatColor.DARK_GRAY + "" + ChatColor.BOLD + " "); + /** + * Adjusts filler characters. + * + * @param str string + * @return adjusted string + */ + public static String adjustFillers(String str) { - return str; - } + str = str.replace("\u278A", ChatColor.DARK_GRAY + "`"); + + str = str.replace("\u278B", ChatColor.DARK_GRAY + "" + ChatColor.BOLD + "`"); + str = str.replace("\u278C", ChatColor.DARK_GRAY + "" + ChatColor.BOLD + " "); + + return str; + } } diff --git a/plugins/bastion-paper/src/main/resources/config.yml b/plugins/bastion-paper/src/main/resources/config.yml index b34d634c2..1dc8f0340 100644 --- a/plugins/bastion-paper/src/main/resources/config.yml +++ b/plugins/bastion-paper/src/main/resources/config.yml @@ -15,15 +15,15 @@ commonSettings: cancelPlacementAndDamage: - SCAFFOLDING bastions: -#The first bastion in this list will be used as the default type -#This only really matters the first time your start it up when converting from old bastion -#All bastions in the db will be flagged as, in this instance, citybastion + #The first bastion in this list will be used as the default type + #This only really matters the first time your start it up when converting from old bastion + #All bastions in the db will be flagged as, in this instance, citybastion citybastion: block: material: NETHER_WART_BLOCK durability: 0 name: City Bastion - lore: + lore: - This bastion will protect your plot shortName: City squarefield: true @@ -59,7 +59,7 @@ bastions: material: BONE_BLOCK durability: 0 name: Claim Bastion - lore: + lore: - This bastion will protect your claims squarefield: false effectRadius: 300 @@ -94,7 +94,7 @@ bastions: material: SPONGE durability: 0 name: Bastion - lore: + lore: - this one is hellaz squarefield: false effectRadius: 10 diff --git a/plugins/bastion-paper/src/main/resources/plugin.yml b/plugins/bastion-paper/src/main/resources/plugin.yml index 767709cab..ddc063557 100644 --- a/plugins/bastion-paper/src/main/resources/plugin.yml +++ b/plugins/bastion-paper/src/main/resources/plugin.yml @@ -2,54 +2,54 @@ name: Bastion version: ${version} main: isaac.bastion.Bastion author: spaceFountain -authors: [Rourke750, ProgrammerDan, Maxopoly, TealNerd, Aleksey-Terzi] -depend: [CivModCore, Citadel, NameLayer] +authors: [ Rourke750, ProgrammerDan, Maxopoly, TealNerd, Aleksey-Terzi ] +depend: [ CivModCore, Citadel, NameLayer ] api-version: 1.20 commands: - Bastion: - description: Base command for Bastion - usage: /Bastion - permission: Bastion.normal - bsi: - description: Gives info on blocks that are clicked - usage: /bsi and right click a block - permission: Bastion.normal - bsd: - description: Removes Bastion Block when clicked - usage: /bsd and right click a block - permission: Bastion.normal - bso: - description: Returns to normal - usage: /bso set the mode back to normal - permission: Bastion.normal - bsb: - description: Turns mode to BASTION mode - usage: /bsb set the mode to BASTION. When clicking a reinforced target block it becomes a Bastion - permission: Bastion.normal - bsf: - description: Changes mode to OFF mode where reinforcing the target block does not create a Bastion - usage: /bsb set the mode OFF. When a target block is reinforced it does not create a bastion - permission: Bastion.normal - bsm: - description: Insta matures any bastion left clicked - usage: /bsm - permission: Bastion.admin + Bastion: + description: Base command for Bastion + usage: /Bastion + permission: Bastion.normal + bsi: + description: Gives info on blocks that are clicked + usage: /bsi and right click a block + permission: Bastion.normal + bsd: + description: Removes Bastion Block when clicked + usage: /bsd and right click a block + permission: Bastion.normal + bso: + description: Returns to normal + usage: /bso set the mode back to normal + permission: Bastion.normal + bsb: + description: Turns mode to BASTION mode + usage: /bsb set the mode to BASTION. When clicking a reinforced target block it becomes a Bastion + permission: Bastion.normal + bsf: + description: Changes mode to OFF mode where reinforcing the target block does not create a Bastion + usage: /bsb set the mode OFF. When a target block is reinforced it does not create a bastion + permission: Bastion.normal + bsm: + description: Insta matures any bastion left clicked + usage: /bsm + permission: Bastion.admin permissions: - Bastion.*: - description: Gives access to all Bastion commands - default: false - Bastion.normal: - description: All a normal player should ever need - default: true - Bastion.admin: - description: Special power for admins - default: false - children: - Bastion.bypass: true - Bastion.dev: true - Bastion.bypass: - description: Bastions do not effect members - default: false - Bastion.dev: - description: Special debug commands and different responses to existing commands - default: op + Bastion.*: + description: Gives access to all Bastion commands + default: false + Bastion.normal: + description: All a normal player should ever need + default: true + Bastion.admin: + description: Special power for admins + default: false + children: + Bastion.bypass: true + Bastion.dev: true + Bastion.bypass: + description: Bastions do not effect members + default: false + Bastion.dev: + description: Special debug commands and different responses to existing commands + default: op diff --git a/plugins/castlegates-paper/README.md b/plugins/castlegates-paper/README.md index 12c278832..5bc42dbc4 100644 --- a/plugins/castlegates-paper/README.md +++ b/plugins/castlegates-paper/README.md @@ -4,6 +4,7 @@ Allows to create retractable bridges and gates. Supports Citadel, Bastion and Orebfuscator plugins. ### Requirements: + - Java 1.6 / 1.7 / 1.8 - Spigot/PaperSpigot and any other fork of CraftBukkit diff --git a/plugins/castlegates-paper/build.gradle.kts b/plugins/castlegates-paper/build.gradle.kts index 0039e305a..f823ece5d 100644 --- a/plugins/castlegates-paper/build.gradle.kts +++ b/plugins/castlegates-paper/build.gradle.kts @@ -1,17 +1,17 @@ plugins { - id("io.papermc.paperweight.userdev") + id("io.papermc.paperweight.userdev") } version = "2.0.2" dependencies { - paperweight { - paperDevBundle("1.20.4-R0.1-SNAPSHOT") - } + paperweight { + paperDevBundle("1.20.4-R0.1-SNAPSHOT") + } - compileOnly(project(":plugins:civmodcore-paper")) - compileOnly(project(":plugins:namelayer-paper")) - compileOnly(project(":plugins:citadel-paper")) - compileOnly(project(":plugins:bastion-paper")) - compileOnly(project(":plugins:jukealert-paper")) + compileOnly(project(":plugins:civmodcore-paper")) + compileOnly(project(":plugins:namelayer-paper")) + compileOnly(project(":plugins:citadel-paper")) + compileOnly(project(":plugins:bastion-paper")) + compileOnly(project(":plugins:jukealert-paper")) } diff --git a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/CastleGates.java b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/CastleGates.java index 70b6d38b7..3c44cbe40 100644 --- a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/CastleGates.java +++ b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/CastleGates.java @@ -1,6 +1,5 @@ /** * @author Aleksey Terzi - * */ package com.aleksey.castlegates; @@ -29,43 +28,50 @@ import com.aleksey.castlegates.listener.EntityListener; import com.aleksey.castlegates.config.ConfigManager; public class CastleGates extends JavaPlugin { + private static CastleGates _instance; + public static CastleGates getInstance() { - return _instance; + return _instance; } private static CastleGatesManager _manager; + public static CastleGatesManager getManager() { - return _manager; + return _manager; } private static ConfigManager _configManager; + public static ConfigManager getConfigManager() { - return _configManager; + return _configManager; } private static ICitadelManager _citadelManager; + public static ICitadelManager getCitadelManager() { - return _citadelManager; + return _citadelManager; } private static IBastionManager _bastionManager; + public static IBastionManager getBastionManager() { - return _bastionManager; + return _bastionManager; } private static IJukeAlertManager _jukeAlertManager; + public static IJukeAlertManager getJukeAlertManager() { - return _jukeAlertManager; + return _jukeAlertManager; } public static Logger getPluginLogger() { - return _instance.getLogger(); + return _instance.getLogger(); } @Override public void onEnable() { - _instance = this; + _instance = this; _manager = new CastleGatesManager(); _configManager = new ConfigManager(getLogger()); @@ -77,9 +83,9 @@ public class CastleGates extends JavaPlugin { SqlDatabase db = initDatabase(); - if(db == null) return; + if (db == null) return; - if(!_manager.init(db)) + if (!_manager.init(db)) return; _citadelManager.init(); @@ -90,7 +96,7 @@ public class CastleGates extends JavaPlugin { } private void enableCivPlugins() { - if(getServer().getPluginManager().getPlugin("Citadel") != null) { + if (getServer().getPluginManager().getPlugin("Citadel") != null) { _citadelManager = new CitadelManager(); getLogger().log(Level.INFO, "Citadel plugin found."); } else { @@ -98,7 +104,7 @@ public class CastleGates extends JavaPlugin { getLogger().log(Level.INFO, "Citadel plugin NOT found."); } - if(getServer().getPluginManager().getPlugin("JukeAlert") != null) { + if (getServer().getPluginManager().getPlugin("JukeAlert") != null) { _jukeAlertManager = new JukeAlertManager(); getLogger().log(Level.INFO, "JukeAlert plugin found."); } else { @@ -106,7 +112,7 @@ public class CastleGates extends JavaPlugin { getLogger().log(Level.INFO, "JukeAlert plugin NOT found."); } - if(getServer().getPluginManager().getPlugin("Bastion") != null) { + if (getServer().getPluginManager().getPlugin("Bastion") != null) { _bastionManager = new BastionManager(); _bastionManager.init(); getLogger().log(Level.INFO, "Bastion plugin found."); @@ -117,23 +123,23 @@ public class CastleGates extends JavaPlugin { } private SqlDatabase initDatabase() { - SqlDatabase db = new SqlDatabase( - _configManager.getDatabase().host, - _configManager.getDatabase().port, - _configManager.getDatabase().db, - _configManager.getDatabase().user, - _configManager.getDatabase().password, - getLogger() - ); + SqlDatabase db = new SqlDatabase( + _configManager.getDatabase().host, + _configManager.getDatabase().port, + _configManager.getDatabase().db, + _configManager.getDatabase().user, + _configManager.getDatabase().password, + getLogger() + ); - if(!db.connect()) return null; + if (!db.connect()) return null; - if(!db.initDb()) { - db.close(); - return null; - } + if (!db.initDb()) { + db.close(); + return null; + } - return db; + return db; } @Override diff --git a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/command/CastleGatesCommand.java b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/command/CastleGatesCommand.java index e03703af7..f0974eb23 100644 --- a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/command/CastleGatesCommand.java +++ b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/command/CastleGatesCommand.java @@ -1,6 +1,5 @@ /** * @author Aleksey Terzi - * */ package com.aleksey.castlegates.command; @@ -17,125 +16,124 @@ import com.aleksey.castlegates.types.TimerOperation; import com.aleksey.castlegates.utils.Helper; public class CastleGatesCommand { - public static boolean onCommand(CommandSender sender, Command command, String label, String[] args) { - if (!(sender instanceof Player player)) { - if(args.length != 1 || !args[0].equalsIgnoreCase("reload")) return false; - CastleGates.getManager().reinit(); - return true; - } + + public static boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (!(sender instanceof Player player)) { + if (args.length != 1 || !args[0].equalsIgnoreCase("reload")) return false; + CastleGates.getManager().reinit(); + return true; + } CommandMode mode; - if(command.getName().equalsIgnoreCase("gear")) { - mode = CommandMode.CREATE; - } else if(command.getName().equalsIgnoreCase("link")) { - mode = CommandMode.LINK; - } else if(args.length == 0){ - return false; + if (command.getName().equalsIgnoreCase("gear")) { + mode = CommandMode.CREATE; + } else if (command.getName().equalsIgnoreCase("link")) { + mode = CommandMode.LINK; + } else if (args.length == 0) { + return false; } else { - switch(args[0].toLowerCase()) { - case "timer": - return setTimeMode(player, args); - case "normal": - mode = CommandMode.NORMAL; - break; - case "create": - mode = CommandMode.CREATE; - break; - case "link": - mode = CommandMode.LINK; - break; - case "info": - mode = CommandMode.INFO; - break; - default: - return false; - } + switch (args[0].toLowerCase()) { + case "timer": + return setTimeMode(player, args); + case "normal": + mode = CommandMode.NORMAL; + break; + case "create": + mode = CommandMode.CREATE; + break; + case "link": + mode = CommandMode.LINK; + break; + case "info": + mode = CommandMode.INFO; + break; + default: + return false; + } - if (args.length != 1) return false; - } + if (args.length != 1) return false; + } - CastleGates.getManager().setPlayerMode(player, mode, null, null, null); + CastleGates.getManager().setPlayerMode(player, mode, null, null, null); - return true; - } + return true; + } - private static boolean setTimeMode(Player player, String[] args) { - if(args.length > 4) return false; + private static boolean setTimeMode(Player player, String[] args) { + if (args.length > 4) return false; - Integer timer; - TimerOperation timerOperation; - TimerMode timerMode; + Integer timer; + TimerOperation timerOperation; + TimerMode timerMode; - if(args.length == 2 && args[1].equalsIgnoreCase("door")) { - timer = 1; - timerOperation = TimerOperation.UNDRAW; - timerMode = TimerMode.DOOR; - } else { - timer = args.length > 1 - ? parseTimerTimeout(args[1], player) - : (Integer) CastleGates.getConfigManager().getTimerDefault(); + if (args.length == 2 && args[1].equalsIgnoreCase("door")) { + timer = 1; + timerOperation = TimerOperation.UNDRAW; + timerMode = TimerMode.DOOR; + } else { + timer = args.length > 1 + ? parseTimerTimeout(args[1], player) + : (Integer) CastleGates.getConfigManager().getTimerDefault(); - if (timer == null) return true; + if (timer == null) return true; - timerOperation = CastleGates.getConfigManager().getTimerDefaultOperation(); - timerMode = TimerMode.DEFAULT; + timerOperation = CastleGates.getConfigManager().getTimerDefaultOperation(); + timerMode = TimerMode.DEFAULT; - if(args.length > 2) { - if(args.length == 4 || !args[2].equalsIgnoreCase("door")) { - timerOperation = Helper.parseTimerOperation(args[2]); + if (args.length > 2) { + if (args.length == 4 || !args[2].equalsIgnoreCase("door")) { + timerOperation = Helper.parseTimerOperation(args[2]); - if (timerOperation == null) { - player.sendMessage(ChatColor.RED + "Allowed timer operations are draw, undraw and revert."); - return true; - } - } + if (timerOperation == null) { + player.sendMessage(ChatColor.RED + "Allowed timer operations are draw, undraw and revert."); + return true; + } + } - if(args.length == 4 || args[2].equalsIgnoreCase("door")) { - if(args.length == 4) { - if(!args[3].equalsIgnoreCase("door")) { - player.sendMessage(ChatColor.RED + "Allowed timer mode is door."); - return true; - } - } else { - timerOperation = TimerOperation.UNDRAW; - } + if (args.length == 4 || args[2].equalsIgnoreCase("door")) { + if (args.length == 4) { + if (!args[3].equalsIgnoreCase("door")) { + player.sendMessage(ChatColor.RED + "Allowed timer mode is door."); + return true; + } + } else { + timerOperation = TimerOperation.UNDRAW; + } - timerMode = TimerMode.DOOR; - } - } - } + timerMode = TimerMode.DOOR; + } + } + } - CastleGates.getManager().setPlayerMode(player, CommandMode.TIMER, timer, timerOperation, timerMode); + CastleGates.getManager().setPlayerMode(player, CommandMode.TIMER, timer, timerOperation, timerMode); - return true; - } + return true; + } - private static Integer parseTimerTimeout(String text, Player player) { - int timer; + private static Integer parseTimerTimeout(String text, Player player) { + int timer; - try { - timer = Integer.parseInt(text); - } - catch(NumberFormatException ex) { - return null; - } + try { + timer = Integer.parseInt(text); + } catch (NumberFormatException ex) { + return null; + } - if(timer < CastleGates.getConfigManager().getTimerMin() - || timer > CastleGates.getConfigManager().getTimerMax() - ) - { - String errorMessage = "Timer interval is limited to the value between " - + CastleGates.getConfigManager().getTimerMin() - + " and " - + CastleGates.getConfigManager().getTimerMax() - + " sec"; + if (timer < CastleGates.getConfigManager().getTimerMin() + || timer > CastleGates.getConfigManager().getTimerMax() + ) { + String errorMessage = "Timer interval is limited to the value between " + + CastleGates.getConfigManager().getTimerMin() + + " and " + + CastleGates.getConfigManager().getTimerMax() + + " sec"; - player.sendMessage(ChatColor.RED + errorMessage); + player.sendMessage(ChatColor.RED + errorMessage); - return null; - } + return null; + } - return timer; - } + return timer; + } } diff --git a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/config/ConfigDefaults.java b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/config/ConfigDefaults.java index c416c2ef9..32a085ec4 100644 --- a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/config/ConfigDefaults.java +++ b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/config/ConfigDefaults.java @@ -1,6 +1,5 @@ /** * @author Aleksey Terzi - * */ package com.aleksey.castlegates.config; @@ -8,233 +7,234 @@ package com.aleksey.castlegates.config; import org.bukkit.Material; public class ConfigDefaults { - public static final String[] gearMaterials = new String[] { - Material.STONE.name(), - Material.GRASS_BLOCK.name(), - Material.DIRT.name(), - Material.COBBLESTONE.name(), - Material.OAK_WOOD.name(), - Material.OAK_LOG.name(), - Material.OAK_PLANKS.name(), - Material.OAK_STAIRS.name(), - Material.OAK_FENCE.name(), - Material.OAK_SLAB.name(), - Material.STRIPPED_OAK_LOG.name(), - Material.STRIPPED_OAK_WOOD.name(), + public static final String[] gearMaterials = new String[]{ + Material.STONE.name(), + Material.GRASS_BLOCK.name(), + Material.DIRT.name(), + Material.COBBLESTONE.name(), - Material.SPRUCE_WOOD.name(), - Material.SPRUCE_LOG.name(), - Material.SPRUCE_PLANKS.name(), - Material.SPRUCE_STAIRS.name(), - Material.SPRUCE_FENCE.name(), - Material.SPRUCE_SLAB.name(), - Material.STRIPPED_SPRUCE_LOG.name(), - Material.STRIPPED_SPRUCE_WOOD.name(), + Material.OAK_WOOD.name(), + Material.OAK_LOG.name(), + Material.OAK_PLANKS.name(), + Material.OAK_STAIRS.name(), + Material.OAK_FENCE.name(), + Material.OAK_SLAB.name(), + Material.STRIPPED_OAK_LOG.name(), + Material.STRIPPED_OAK_WOOD.name(), - Material.BIRCH_WOOD.name(), - Material.BIRCH_LOG.name(), - Material.BIRCH_PLANKS.name(), - Material.BIRCH_STAIRS.name(), - Material.BIRCH_FENCE.name(), - Material.BIRCH_SLAB.name(), - Material.STRIPPED_BIRCH_LOG.name(), - Material.STRIPPED_BIRCH_WOOD.name(), + Material.SPRUCE_WOOD.name(), + Material.SPRUCE_LOG.name(), + Material.SPRUCE_PLANKS.name(), + Material.SPRUCE_STAIRS.name(), + Material.SPRUCE_FENCE.name(), + Material.SPRUCE_SLAB.name(), + Material.STRIPPED_SPRUCE_LOG.name(), + Material.STRIPPED_SPRUCE_WOOD.name(), - Material.JUNGLE_WOOD.name(), - Material.JUNGLE_LOG.name(), - Material.JUNGLE_PLANKS.name(), - Material.JUNGLE_STAIRS.name(), - Material.JUNGLE_FENCE.name(), - Material.JUNGLE_SLAB.name(), - Material.STRIPPED_JUNGLE_LOG.name(), - Material.STRIPPED_JUNGLE_WOOD.name(), + Material.BIRCH_WOOD.name(), + Material.BIRCH_LOG.name(), + Material.BIRCH_PLANKS.name(), + Material.BIRCH_STAIRS.name(), + Material.BIRCH_FENCE.name(), + Material.BIRCH_SLAB.name(), + Material.STRIPPED_BIRCH_LOG.name(), + Material.STRIPPED_BIRCH_WOOD.name(), - Material.ACACIA_WOOD.name(), - Material.ACACIA_LOG.name(), - Material.ACACIA_PLANKS.name(), - Material.ACACIA_STAIRS.name(), - Material.ACACIA_FENCE.name(), - Material.ACACIA_SLAB.name(), - Material.STRIPPED_ACACIA_LOG.name(), - Material.STRIPPED_ACACIA_WOOD.name(), + Material.JUNGLE_WOOD.name(), + Material.JUNGLE_LOG.name(), + Material.JUNGLE_PLANKS.name(), + Material.JUNGLE_STAIRS.name(), + Material.JUNGLE_FENCE.name(), + Material.JUNGLE_SLAB.name(), + Material.STRIPPED_JUNGLE_LOG.name(), + Material.STRIPPED_JUNGLE_WOOD.name(), - Material.DARK_OAK_WOOD.name(), - Material.DARK_OAK_LOG.name(), - Material.DARK_OAK_PLANKS.name(), - Material.DARK_OAK_STAIRS.name(), - Material.DARK_OAK_FENCE.name(), - Material.DARK_OAK_SLAB.name(), - Material.STRIPPED_DARK_OAK_LOG.name(), - Material.STRIPPED_DARK_OAK_WOOD.name(), + Material.ACACIA_WOOD.name(), + Material.ACACIA_LOG.name(), + Material.ACACIA_PLANKS.name(), + Material.ACACIA_STAIRS.name(), + Material.ACACIA_FENCE.name(), + Material.ACACIA_SLAB.name(), + Material.STRIPPED_ACACIA_LOG.name(), + Material.STRIPPED_ACACIA_WOOD.name(), - Material.GLASS.name(), - Material.LAPIS_BLOCK.name(), - Material.SANDSTONE.name(), + Material.DARK_OAK_WOOD.name(), + Material.DARK_OAK_LOG.name(), + Material.DARK_OAK_PLANKS.name(), + Material.DARK_OAK_STAIRS.name(), + Material.DARK_OAK_FENCE.name(), + Material.DARK_OAK_SLAB.name(), + Material.STRIPPED_DARK_OAK_LOG.name(), + Material.STRIPPED_DARK_OAK_WOOD.name(), - Material.WHITE_WOOL.name(), - Material.ORANGE_WOOL.name(), - Material.MAGENTA_WOOL.name(), - Material.LIGHT_BLUE_WOOL.name(), - Material.YELLOW_WOOL.name(), - Material.LIME_WOOL.name(), - Material.PINK_WOOL.name(), - Material.GRAY_WOOL.name(), - Material.LIGHT_GRAY_WOOL.name(), - Material.CYAN_WOOL.name(), - Material.PURPLE_WOOL.name(), - Material.BLUE_WOOL.name(), - Material.BROWN_WOOL.name(), - Material.GREEN_WOOL.name(), - Material.RED_WOOL.name(), - Material.BLACK_WOOL.name(), + Material.GLASS.name(), + Material.LAPIS_BLOCK.name(), + Material.SANDSTONE.name(), - Material.GOLD_BLOCK.name(), - Material.IRON_BLOCK.name(), - Material.BRICK.name(), - Material.MOSSY_COBBLESTONE.name(), - Material.MOSSY_COBBLESTONE_SLAB.name(), - Material.OBSIDIAN.name(), - Material.DIAMOND_BLOCK.name(), - Material.COBBLESTONE_STAIRS.name(), - Material.COBBLESTONE_SLAB.name(), - Material.ICE.name(), - Material.SNOW_BLOCK.name(), - Material.CLAY.name(), - Material.NETHERRACK.name(), - Material.GLOWSTONE.name(), - Material.SMOOTH_STONE.name(), - Material.IRON_BARS.name(), - Material.BRICK_STAIRS.name(), - Material.NETHER_BRICK.name(), - Material.NETHER_BRICK_STAIRS.name(), - Material.SANDSTONE_STAIRS.name(), - Material.EMERALD_BLOCK.name(), - Material.REDSTONE_BLOCK.name(), - Material.QUARTZ_BLOCK.name(), - Material.QUARTZ_STAIRS.name(), - Material.ACACIA_STAIRS.name(), - Material.DARK_OAK_STAIRS.name(), - Material.HAY_BLOCK.name(), - Material.COAL_BLOCK.name(), - Material.PACKED_ICE.name(), - Material.RED_SANDSTONE.name(), - Material.RED_SANDSTONE_STAIRS.name(), - Material.SPRUCE_FENCE.name(), - Material.BIRCH_FENCE.name(), - Material.JUNGLE_FENCE.name(), - Material.DARK_OAK_FENCE.name(), - Material.ACACIA_FENCE.name(), - Material.PURPUR_BLOCK.name(), - Material.PURPUR_STAIRS.name(), - Material.PURPUR_SLAB.name(), - Material.MAGMA_BLOCK.name(), - Material.NETHER_WART_BLOCK.name(), - Material.RED_NETHER_BRICKS.name(), - Material.BONE_BLOCK.name() - }; + Material.WHITE_WOOL.name(), + Material.ORANGE_WOOL.name(), + Material.MAGENTA_WOOL.name(), + Material.LIGHT_BLUE_WOOL.name(), + Material.YELLOW_WOOL.name(), + Material.LIME_WOOL.name(), + Material.PINK_WOOL.name(), + Material.GRAY_WOOL.name(), + Material.LIGHT_GRAY_WOOL.name(), + Material.CYAN_WOOL.name(), + Material.PURPLE_WOOL.name(), + Material.BLUE_WOOL.name(), + Material.BROWN_WOOL.name(), + Material.GREEN_WOOL.name(), + Material.RED_WOOL.name(), + Material.BLACK_WOOL.name(), - public static final String[] bridgeMaterials = new String[] { - Material.STONE.name(), - Material.DIRT.name(), - Material.COBBLESTONE.name(), + Material.GOLD_BLOCK.name(), + Material.IRON_BLOCK.name(), + Material.BRICK.name(), + Material.MOSSY_COBBLESTONE.name(), + Material.MOSSY_COBBLESTONE_SLAB.name(), + Material.OBSIDIAN.name(), + Material.DIAMOND_BLOCK.name(), + Material.COBBLESTONE_STAIRS.name(), + Material.COBBLESTONE_SLAB.name(), + Material.ICE.name(), + Material.SNOW_BLOCK.name(), + Material.CLAY.name(), + Material.NETHERRACK.name(), + Material.GLOWSTONE.name(), + Material.SMOOTH_STONE.name(), + Material.IRON_BARS.name(), + Material.BRICK_STAIRS.name(), + Material.NETHER_BRICK.name(), + Material.NETHER_BRICK_STAIRS.name(), + Material.SANDSTONE_STAIRS.name(), + Material.EMERALD_BLOCK.name(), + Material.REDSTONE_BLOCK.name(), + Material.QUARTZ_BLOCK.name(), + Material.QUARTZ_STAIRS.name(), + Material.ACACIA_STAIRS.name(), + Material.DARK_OAK_STAIRS.name(), + Material.HAY_BLOCK.name(), + Material.COAL_BLOCK.name(), + Material.PACKED_ICE.name(), + Material.RED_SANDSTONE.name(), + Material.RED_SANDSTONE_STAIRS.name(), + Material.SPRUCE_FENCE.name(), + Material.BIRCH_FENCE.name(), + Material.JUNGLE_FENCE.name(), + Material.DARK_OAK_FENCE.name(), + Material.ACACIA_FENCE.name(), + Material.PURPUR_BLOCK.name(), + Material.PURPUR_STAIRS.name(), + Material.PURPUR_SLAB.name(), + Material.MAGMA_BLOCK.name(), + Material.NETHER_WART_BLOCK.name(), + Material.RED_NETHER_BRICKS.name(), + Material.BONE_BLOCK.name() + }; - Material.OAK_WOOD.name(), - Material.OAK_LOG.name(), - Material.OAK_PLANKS.name(), - Material.OAK_FENCE.name(), - Material.STRIPPED_OAK_LOG.name(), - Material.STRIPPED_OAK_WOOD.name(), + public static final String[] bridgeMaterials = new String[]{ + Material.STONE.name(), + Material.DIRT.name(), + Material.COBBLESTONE.name(), - Material.SPRUCE_WOOD.name(), - Material.SPRUCE_LOG.name(), - Material.SPRUCE_PLANKS.name(), - Material.SPRUCE_FENCE.name(), - Material.STRIPPED_SPRUCE_LOG.name(), - Material.STRIPPED_SPRUCE_WOOD.name(), + Material.OAK_WOOD.name(), + Material.OAK_LOG.name(), + Material.OAK_PLANKS.name(), + Material.OAK_FENCE.name(), + Material.STRIPPED_OAK_LOG.name(), + Material.STRIPPED_OAK_WOOD.name(), - Material.BIRCH_WOOD.name(), - Material.BIRCH_LOG.name(), - Material.BIRCH_PLANKS.name(), - Material.BIRCH_FENCE.name(), - Material.STRIPPED_BIRCH_LOG.name(), - Material.STRIPPED_BIRCH_WOOD.name(), + Material.SPRUCE_WOOD.name(), + Material.SPRUCE_LOG.name(), + Material.SPRUCE_PLANKS.name(), + Material.SPRUCE_FENCE.name(), + Material.STRIPPED_SPRUCE_LOG.name(), + Material.STRIPPED_SPRUCE_WOOD.name(), - Material.JUNGLE_WOOD.name(), - Material.JUNGLE_LOG.name(), - Material.JUNGLE_PLANKS.name(), - Material.JUNGLE_FENCE.name(), - Material.STRIPPED_JUNGLE_LOG.name(), - Material.STRIPPED_JUNGLE_WOOD.name(), + Material.BIRCH_WOOD.name(), + Material.BIRCH_LOG.name(), + Material.BIRCH_PLANKS.name(), + Material.BIRCH_FENCE.name(), + Material.STRIPPED_BIRCH_LOG.name(), + Material.STRIPPED_BIRCH_WOOD.name(), - Material.ACACIA_WOOD.name(), - Material.ACACIA_LOG.name(), - Material.ACACIA_PLANKS.name(), - Material.ACACIA_FENCE.name(), - Material.STRIPPED_ACACIA_LOG.name(), - Material.STRIPPED_ACACIA_WOOD.name(), + Material.JUNGLE_WOOD.name(), + Material.JUNGLE_LOG.name(), + Material.JUNGLE_PLANKS.name(), + Material.JUNGLE_FENCE.name(), + Material.STRIPPED_JUNGLE_LOG.name(), + Material.STRIPPED_JUNGLE_WOOD.name(), - Material.DARK_OAK_WOOD.name(), - Material.DARK_OAK_LOG.name(), - Material.DARK_OAK_PLANKS.name(), - Material.DARK_OAK_FENCE.name(), - Material.STRIPPED_DARK_OAK_LOG.name(), - Material.STRIPPED_DARK_OAK_WOOD.name(), + Material.ACACIA_WOOD.name(), + Material.ACACIA_LOG.name(), + Material.ACACIA_PLANKS.name(), + Material.ACACIA_FENCE.name(), + Material.STRIPPED_ACACIA_LOG.name(), + Material.STRIPPED_ACACIA_WOOD.name(), - Material.GLASS.name(), - Material.LAPIS_BLOCK.name(), - Material.SANDSTONE.name(), + Material.DARK_OAK_WOOD.name(), + Material.DARK_OAK_LOG.name(), + Material.DARK_OAK_PLANKS.name(), + Material.DARK_OAK_FENCE.name(), + Material.STRIPPED_DARK_OAK_LOG.name(), + Material.STRIPPED_DARK_OAK_WOOD.name(), - Material.WHITE_WOOL.name(), - Material.ORANGE_WOOL.name(), - Material.MAGENTA_WOOL.name(), - Material.LIGHT_BLUE_WOOL.name(), - Material.YELLOW_WOOL.name(), - Material.LIME_WOOL.name(), - Material.PINK_WOOL.name(), - Material.GRAY_WOOL.name(), - Material.LIGHT_GRAY_WOOL.name(), - Material.CYAN_WOOL.name(), - Material.PURPLE_WOOL.name(), - Material.BLUE_WOOL.name(), - Material.BROWN_WOOL.name(), - Material.GREEN_WOOL.name(), - Material.RED_WOOL.name(), - Material.BLACK_WOOL.name(), + Material.GLASS.name(), + Material.LAPIS_BLOCK.name(), + Material.SANDSTONE.name(), - Material.GOLD_BLOCK.name(), - Material.IRON_BLOCK.name(), - Material.BRICK.name(), - Material.MOSSY_COBBLESTONE.name(), - Material.DIAMOND_BLOCK.name(), - Material.COBBLESTONE_STAIRS.name(), - Material.ICE.name(), - Material.SNOW_BLOCK.name(), - Material.CLAY.name(), - Material.NETHERRACK.name(), - Material.GLOWSTONE.name(), - Material.BRICK_STAIRS.name(), - Material.NETHER_BRICK.name(), - Material.NETHER_BRICK_STAIRS.name(), - Material.SANDSTONE_STAIRS.name(), - Material.EMERALD_BLOCK.name(), - Material.REDSTONE_BLOCK.name(), - Material.QUARTZ_BLOCK.name(), - Material.QUARTZ_STAIRS.name(), - Material.ACACIA_STAIRS.name(), - Material.DARK_OAK_STAIRS.name(), - Material.HAY_BLOCK.name(), - Material.COAL_BLOCK.name(), - Material.PACKED_ICE.name(), - Material.RED_SANDSTONE.name(), - Material.RED_SANDSTONE_STAIRS.name(), - Material.SPRUCE_FENCE.name(), - Material.BIRCH_FENCE.name(), - Material.JUNGLE_FENCE.name(), - Material.DARK_OAK_FENCE.name(), - Material.ACACIA_FENCE.name(), - Material.PURPUR_BLOCK.name(), - Material.PURPUR_STAIRS.name(), - Material.PURPUR_SLAB.name(), - }; + Material.WHITE_WOOL.name(), + Material.ORANGE_WOOL.name(), + Material.MAGENTA_WOOL.name(), + Material.LIGHT_BLUE_WOOL.name(), + Material.YELLOW_WOOL.name(), + Material.LIME_WOOL.name(), + Material.PINK_WOOL.name(), + Material.GRAY_WOOL.name(), + Material.LIGHT_GRAY_WOOL.name(), + Material.CYAN_WOOL.name(), + Material.PURPLE_WOOL.name(), + Material.BLUE_WOOL.name(), + Material.BROWN_WOOL.name(), + Material.GREEN_WOOL.name(), + Material.RED_WOOL.name(), + Material.BLACK_WOOL.name(), + + Material.GOLD_BLOCK.name(), + Material.IRON_BLOCK.name(), + Material.BRICK.name(), + Material.MOSSY_COBBLESTONE.name(), + Material.DIAMOND_BLOCK.name(), + Material.COBBLESTONE_STAIRS.name(), + Material.ICE.name(), + Material.SNOW_BLOCK.name(), + Material.CLAY.name(), + Material.NETHERRACK.name(), + Material.GLOWSTONE.name(), + Material.BRICK_STAIRS.name(), + Material.NETHER_BRICK.name(), + Material.NETHER_BRICK_STAIRS.name(), + Material.SANDSTONE_STAIRS.name(), + Material.EMERALD_BLOCK.name(), + Material.REDSTONE_BLOCK.name(), + Material.QUARTZ_BLOCK.name(), + Material.QUARTZ_STAIRS.name(), + Material.ACACIA_STAIRS.name(), + Material.DARK_OAK_STAIRS.name(), + Material.HAY_BLOCK.name(), + Material.COAL_BLOCK.name(), + Material.PACKED_ICE.name(), + Material.RED_SANDSTONE.name(), + Material.RED_SANDSTONE_STAIRS.name(), + Material.SPRUCE_FENCE.name(), + Material.BIRCH_FENCE.name(), + Material.JUNGLE_FENCE.name(), + Material.DARK_OAK_FENCE.name(), + Material.ACACIA_FENCE.name(), + Material.PURPUR_BLOCK.name(), + Material.PURPUR_STAIRS.name(), + Material.PURPUR_SLAB.name(), + }; } diff --git a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/config/ConfigManager.java b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/config/ConfigManager.java index 17f982b1c..08981863d 100644 --- a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/config/ConfigManager.java +++ b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/config/ConfigManager.java @@ -1,6 +1,5 @@ /** * @author Aleksey Terzi - * */ package com.aleksey.castlegates.config; @@ -22,240 +21,245 @@ import com.aleksey.castlegates.types.TimerOperation; import com.aleksey.castlegates.utils.Helper; public class ConfigManager { - public static class Database { - public String host; - public int port; - public String db; - public String user; - public String password; - } - private static class ItemMaterial { - public Material material; - public Short damage; - public Integer amount; - public String lore; + public static class Database { - public ItemMaterial(Material material, Short damage, Integer amount, String lore) { - this.material = material; - this.damage = damage; - this.amount = amount; - this.lore = lore; + public String host; + public int port; + public String db; + public String user; + public String password; + } - if(Objects.equals(this.lore, "")) { - this.lore = null; - } - } - } + private static class ItemMaterial { - private final Logger _logger; - private FileConfiguration _file; - private Database _database; - private HashSet _gearMaterials; - private HashSet _bridgeMaterials; - private ItemMaterial _stickItem; - private ItemMaterial _creationConsumeItem; - private int _maxPowerTransfers; - private int _maxBridgeLength; - private int _playerStateResetInSeconds; - private int _switchTimeout; - private int _maxRedstoneDistance; - private boolean _allowAutoCreate; - private boolean _interactWithSnitches; - private boolean _timerEnabled; - private int _timerMin; - private int _timerMax; - private int _timerDefault; - private TimerOperation _timerDefaultOperation; - private boolean _gearblockMustBeReinforced; - private boolean _horizontalLinkDisabled; + public Material material; + public Short damage; + public Integer amount; + public String lore; - public ConfigManager(Logger logger) { - _logger = logger; - } + public ItemMaterial(Material material, Short damage, Integer amount, String lore) { + this.material = material; + this.damage = damage; + this.amount = amount; + this.lore = lore; - public void load(FileConfiguration file) { - _file = file; + if (Objects.equals(this.lore, "")) { + this.lore = null; + } + } + } - _database = new Database(); - _database.host = getString("Database.Host", "localhost"); - _database.port = getInt("Database.Port", 3306); - _database.db = getString("Database.Schema", "castle_gates"); - _database.user = getString("Database.User", ""); - _database.password = getString("Database.Password", ""); + private final Logger _logger; + private FileConfiguration _file; + private Database _database; + private HashSet _gearMaterials; + private HashSet _bridgeMaterials; + private ItemMaterial _stickItem; + private ItemMaterial _creationConsumeItem; + private int _maxPowerTransfers; + private int _maxBridgeLength; + private int _playerStateResetInSeconds; + private int _switchTimeout; + private int _maxRedstoneDistance; + private boolean _allowAutoCreate; + private boolean _interactWithSnitches; + private boolean _timerEnabled; + private int _timerMin; + private int _timerMax; + private int _timerDefault; + private TimerOperation _timerDefaultOperation; + private boolean _gearblockMustBeReinforced; + private boolean _horizontalLinkDisabled; - _allowAutoCreate = getBoolean("Settings.AllowAutoCreate", true); - _interactWithSnitches = getBoolean("Settings.InteractWithSnitches", true); - _maxPowerTransfers = getInt("Settings.MaxPowerTransfers", 8, 0, 10); - _maxBridgeLength = getInt("Settings.MaxBridgeLength", 16, 1, 40); - _playerStateResetInSeconds = getInt("Settings.PlayerStateResetInSeconds", 5 * 60); - _switchTimeout = getInt("Settings.SwitchTimeout", 1000, 500, 100000); - _maxRedstoneDistance = getInt("Settings.MaxRedstoneDistance", 7); - _timerEnabled = getBoolean("Settings.Timer.Enabled", true); - _timerMin = getInt("Settings.Timer.Min", 1); - _timerMax = getInt("Settings.Timer.Max", 60); - _timerDefault = getInt("Settings.Timer.DefaultInterval", 5); - _timerDefaultOperation = getTimerOperation(); - _gearblockMustBeReinforced = getBoolean("Settings.GearblockMustBeReinforced", false); - _horizontalLinkDisabled = getBoolean("Settings.HorizontalLinkDisabled", false); + public ConfigManager(Logger logger) { + _logger = logger; + } - _gearMaterials = getBlockMaterials("Blocks.GearMaterials", ConfigDefaults.gearMaterials); - _bridgeMaterials = getBlockMaterials("Blocks.BridgeMaterials", ConfigDefaults.bridgeMaterials); + public void load(FileConfiguration file) { + _file = file; - _stickItem = getItemMaterial("Items.Tool", Material.STICK, null); + _database = new Database(); + _database.host = getString("Database.Host", "localhost"); + _database.port = getInt("Database.Port", 3306); + _database.db = getString("Database.Schema", "castle_gates"); + _database.user = getString("Database.User", ""); + _database.password = getString("Database.Password", ""); - _creationConsumeItem = getItemMaterial("Items.CreationConsume", Material.GOLD_INGOT, 1); + _allowAutoCreate = getBoolean("Settings.AllowAutoCreate", true); + _interactWithSnitches = getBoolean("Settings.InteractWithSnitches", true); + _maxPowerTransfers = getInt("Settings.MaxPowerTransfers", 8, 0, 10); + _maxBridgeLength = getInt("Settings.MaxBridgeLength", 16, 1, 40); + _playerStateResetInSeconds = getInt("Settings.PlayerStateResetInSeconds", 5 * 60); + _switchTimeout = getInt("Settings.SwitchTimeout", 1000, 500, 100000); + _maxRedstoneDistance = getInt("Settings.MaxRedstoneDistance", 7); + _timerEnabled = getBoolean("Settings.Timer.Enabled", true); + _timerMin = getInt("Settings.Timer.Min", 1); + _timerMax = getInt("Settings.Timer.Max", 60); + _timerDefault = getInt("Settings.Timer.DefaultInterval", 5); + _timerDefaultOperation = getTimerOperation(); + _gearblockMustBeReinforced = getBoolean("Settings.GearblockMustBeReinforced", false); + _horizontalLinkDisabled = getBoolean("Settings.HorizontalLinkDisabled", false); - if(_creationConsumeItem.amount == null) { - _creationConsumeItem.amount = 1; - } + _gearMaterials = getBlockMaterials("Blocks.GearMaterials", ConfigDefaults.gearMaterials); + _bridgeMaterials = getBlockMaterials("Blocks.BridgeMaterials", ConfigDefaults.bridgeMaterials); - if(_creationConsumeItem.damage == null) { - _creationConsumeItem.damage = 0; - } - } + _stickItem = getItemMaterial("Items.Tool", Material.STICK, null); - public boolean isTimerEnabled() { - return _timerEnabled; - } + _creationConsumeItem = getItemMaterial("Items.CreationConsume", Material.GOLD_INGOT, 1); - public int getTimerMin() { - return _timerMin; - } + if (_creationConsumeItem.amount == null) { + _creationConsumeItem.amount = 1; + } - public int getTimerMax() { - return _timerMax; - } + if (_creationConsumeItem.damage == null) { + _creationConsumeItem.damage = 0; + } + } - public int getTimerDefault() { - return _timerDefault; - } + public boolean isTimerEnabled() { + return _timerEnabled; + } - public TimerOperation getTimerDefaultOperation() { - return _timerDefaultOperation; - } + public int getTimerMin() { + return _timerMin; + } - public boolean isGearblockMustBeReinforced() { return _gearblockMustBeReinforced; } + public int getTimerMax() { + return _timerMax; + } - public boolean isHorizontalLinkDisabled() { return _horizontalLinkDisabled; } + public int getTimerDefault() { + return _timerDefault; + } - public Database getDatabase() { - return _database; - } + public TimerOperation getTimerDefaultOperation() { + return _timerDefaultOperation; + } - public boolean isGearBlockType(Block block) { - return _gearMaterials.contains(block.getType()); - } + public boolean isGearblockMustBeReinforced() { + return _gearblockMustBeReinforced; + } - public boolean isStickItem(ItemStack item) { - if(item == null - || item.getType() != _stickItem.material - || _stickItem.damage != null && Helper.getItemDamage(item) != _stickItem.damage - || _stickItem.amount != null && item.getAmount() != _stickItem.amount - ) - { - return false; - } + public boolean isHorizontalLinkDisabled() { + return _horizontalLinkDisabled; + } - String lore = Helper.getLore(item); + public Database getDatabase() { + return _database; + } - if(Objects.equals(lore, "")) { - lore = null; - } + public boolean isGearBlockType(Block block) { + return _gearMaterials.contains(block.getType()); + } - return Objects.equals(lore, _stickItem.lore); - } + public boolean isStickItem(ItemStack item) { + if (item == null + || item.getType() != _stickItem.material + || _stickItem.damage != null && Helper.getItemDamage(item) != _stickItem.damage + || _stickItem.amount != null && item.getAmount() != _stickItem.amount + ) { + return false; + } - public boolean isBridgeMaterial(Block block) { - return _bridgeMaterials.contains(block.getType()); - } + String lore = Helper.getLore(item); - public boolean isCreationConsumeItem(ItemStack item) { - if(item == null - || item.getType() != _creationConsumeItem.material - || _creationConsumeItem.damage != null && Helper.getItemDamage(item) != _creationConsumeItem.damage - ) - { - return false; - } + if (Objects.equals(lore, "")) { + lore = null; + } - String lore = Helper.getLore(item); + return Objects.equals(lore, _stickItem.lore); + } - if(Objects.equals(lore, "")) { - lore = null; - } + public boolean isBridgeMaterial(Block block) { + return _bridgeMaterials.contains(block.getType()); + } - return Objects.equals(lore, _creationConsumeItem.lore); - } + public boolean isCreationConsumeItem(ItemStack item) { + if (item == null + || item.getType() != _creationConsumeItem.material + || _creationConsumeItem.damage != null && Helper.getItemDamage(item) != _creationConsumeItem.damage + ) { + return false; + } - public ItemStack getCreationConsumeItem() { - ItemStack item = new ItemStack(_creationConsumeItem.material, _creationConsumeItem.amount); + String lore = Helper.getLore(item); - if (_creationConsumeItem.damage != null) - ((Damageable)item.getItemMeta()).setDamage(_creationConsumeItem.damage); + if (Objects.equals(lore, "")) { + lore = null; + } - Helper.setLore(item, _creationConsumeItem.lore); + return Objects.equals(lore, _creationConsumeItem.lore); + } - return item; - } + public ItemStack getCreationConsumeItem() { + ItemStack item = new ItemStack(_creationConsumeItem.material, _creationConsumeItem.amount); - public int getDataWorkerRate() { - return 500; - } + if (_creationConsumeItem.damage != null) + ((Damageable) item.getItemMeta()).setDamage(_creationConsumeItem.damage); - public int getTimerWorkerRate() { - return 500; - } + Helper.setLore(item, _creationConsumeItem.lore); - public int getMaxPowerTransfers() { - return _maxPowerTransfers; - } + return item; + } - public int getMaxBridgeLength() { - return _maxBridgeLength; - } + public int getDataWorkerRate() { + return 500; + } - public int getPlayerStateResetInSeconds() { - return _playerStateResetInSeconds; - } + public int getTimerWorkerRate() { + return 500; + } - public int getSwitchTimeout() { - return _switchTimeout; - } + public int getMaxPowerTransfers() { + return _maxPowerTransfers; + } - public double getMaxRedstoneDistance() { - return _maxRedstoneDistance; - } + public int getMaxBridgeLength() { + return _maxBridgeLength; + } - public boolean getAllowAutoCreate() { - return _allowAutoCreate; - } + public int getPlayerStateResetInSeconds() { + return _playerStateResetInSeconds; + } - public boolean getInteractWithSnitches() { - return _interactWithSnitches; - } + public int getSwitchTimeout() { + return _switchTimeout; + } - private TimerOperation getTimerOperation() { - final String path = "Settings.Timer.DefaultOperation"; - final TimerOperation defaultData = TimerOperation.UNDRAW; + public double getMaxRedstoneDistance() { + return _maxRedstoneDistance; + } + + public boolean getAllowAutoCreate() { + return _allowAutoCreate; + } + + public boolean getInteractWithSnitches() { + return _interactWithSnitches; + } + + private TimerOperation getTimerOperation() { + final String path = "Settings.Timer.DefaultOperation"; + final TimerOperation defaultData = TimerOperation.UNDRAW; if (_file.get(path) == null) - _file.set(path, defaultData.name()); + _file.set(path, defaultData.name()); String name = _file.getString(path, defaultData.name()); TimerOperation result = Helper.parseTimerOperation(name); - if(result == null) { - _logger.log(Level.WARNING, "'" + name + "' is an invalid timer operation, '" + defaultData.name() + "'" + " will be used instead."); - result = defaultData; + if (result == null) { + _logger.log(Level.WARNING, "'" + name + "' is an invalid timer operation, '" + defaultData.name() + "'" + " will be used instead."); + result = defaultData; } return result; - } + } - private String getString(String path, String defaultData) { + private String getString(String path, String defaultData) { if (_file.get(path) == null) - _file.set(path, defaultData); + _file.set(path, defaultData); return _file.getString(path, defaultData); } @@ -273,11 +277,10 @@ public class ConfigManager { int value = _file.getInt(path, defaultData); - if(value < min) { - value = min; - } - else if(value > max) { - value = max; + if (value < min) { + value = min; + } else if (value > max) { + value = max; } return value; @@ -285,78 +288,78 @@ public class ConfigManager { private boolean getBoolean(String path, boolean defaultData) { if (_file.get(path) == null) - _file.set(path, defaultData); + _file.set(path, defaultData); return _file.getBoolean(path, defaultData); } private HashSet getBlockMaterials(String path, String[] materials) { - List list; + List list; - if(_file.get(path) != null) { - list = _file.getStringList(path); - } else { - _file.set(path, materials); - list = Arrays.asList(materials); - } + if (_file.get(path) != null) { + list = _file.getStringList(path); + } else { + _file.set(path, materials); + list = Arrays.asList(materials); + } - HashSet result = new HashSet<>(); + HashSet result = new HashSet<>(); - for(String materialName : list) { - if(materialName != null && materialName.length() > 0) { - var material = Material.getMaterial(materialName.toUpperCase()); + for (String materialName : list) { + if (materialName != null && materialName.length() > 0) { + var material = Material.getMaterial(materialName.toUpperCase()); - if (material == null) - throw new IllegalArgumentException("Material " + materialName + " is not found"); + if (material == null) + throw new IllegalArgumentException("Material " + materialName + " is not found"); - result.add(material); - } - } + result.add(material); + } + } - return result; + return result; } private ItemMaterial getItemMaterial(String path, Material defaultMaterial, Integer defaultAmount) { - String material = _file.getString(path + ".material"); - Short damage; - Integer amount; - String lore; + String material = _file.getString(path + ".material"); + Short damage; + Integer amount; + String lore; - if(material == null) { - material = defaultMaterial.name(); - damage = null; - amount = defaultAmount; - lore = ""; + if (material == null) { + material = defaultMaterial.name(); + damage = null; + amount = defaultAmount; + lore = ""; - _file.set(path + ".material", material); - _file.set(path + ".damage", damage); - _file.set(path + ".amount", amount); - _file.set(path + ".lore", lore); - } else { - if(_file.get(path + ".damage") != null) { - damage = (short)_file.getInt(path + ".damage"); - } else { - damage = null; - _file.set(path + ".damage", damage); - } + _file.set(path + ".material", material); + _file.set(path + ".damage", damage); + _file.set(path + ".amount", amount); + _file.set(path + ".lore", lore); + } else { + if (_file.get(path + ".damage") != null) { + damage = (short) _file.getInt(path + ".damage"); + } else { + damage = null; + _file.set(path + ".damage", damage); + } - if(_file.get(path + ".amount") != null) { - amount = _file.getInt(path + ".amount"); - } else { - amount = defaultAmount; - _file.set(path + ".amount", amount); - } + if (_file.get(path + ".amount") != null) { + amount = _file.getInt(path + ".amount"); + } else { + amount = defaultAmount; + _file.set(path + ".amount", amount); + } - if(_file.get(path + ".lore") != null) { - lore = _file.getString(path + ".lore"); - } else { - lore = ""; - _file.set(path + ".lore", lore); - } - } + if (_file.get(path + ".lore") != null) { + lore = _file.getString(path + ".lore"); + } else { + lore = ""; + _file.set(path + ".lore", lore); + } + } - Material materialObj = Material.getMaterial(material); + Material materialObj = Material.getMaterial(material); - return new ItemMaterial(materialObj, damage, amount, lore); + return new ItemMaterial(materialObj, damage, amount, lore); } } diff --git a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/database/GearblockInfo.java b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/database/GearblockInfo.java index 54bf440ed..791fd114a 100644 --- a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/database/GearblockInfo.java +++ b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/database/GearblockInfo.java @@ -1,16 +1,16 @@ /** * @author Aleksey Terzi - * */ package com.aleksey.castlegates.database; public class GearblockInfo { - public int GearblockId; - public String WorldId; - public int X; - public int Y; - public int Z; - public Integer Timer; - public Integer TimerOperation; + + public int GearblockId; + public String WorldId; + public int X; + public int Y; + public int Z; + public Integer Timer; + public Integer TimerOperation; } diff --git a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/database/GearblockSource.java b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/database/GearblockSource.java index 2c2ddfa80..6200718d1 100644 --- a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/database/GearblockSource.java +++ b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/database/GearblockSource.java @@ -1,6 +1,5 @@ /** * @author Aleksey Terzi - * */ package com.aleksey.castlegates.database; @@ -13,110 +12,111 @@ import java.util.ArrayList; import java.util.List; public class GearblockSource { - private static final String countAllScript = "SELECT COUNT(*) FROM cg_gearblock"; - private static final String selectAllScript = "SELECT * FROM cg_gearblock ORDER BY GearblockId"; - private static final String insertScript = "INSERT INTO cg_gearblock (WorldId, X, Y, Z, Timer, TimerOperation) VALUES (?, ?, ?, ?, ?, ?)"; - private static final String updateScript = "UPDATE cg_gearblock SET WorldId = ?, X = ?, Y = ?, Z = ?, Timer = ?, TimerOperation = ? WHERE GearblockId = ?"; - private static final String deleteScript = "DELETE FROM cg_gearblock WHERE GearblockId = ?"; - private final SqlDatabase _db; + private static final String countAllScript = "SELECT COUNT(*) FROM cg_gearblock"; + private static final String selectAllScript = "SELECT * FROM cg_gearblock ORDER BY GearblockId"; + private static final String insertScript = "INSERT INTO cg_gearblock (WorldId, X, Y, Z, Timer, TimerOperation) VALUES (?, ?, ?, ?, ?, ?)"; + private static final String updateScript = "UPDATE cg_gearblock SET WorldId = ?, X = ?, Y = ?, Z = ?, Timer = ?, TimerOperation = ? WHERE GearblockId = ?"; + private static final String deleteScript = "DELETE FROM cg_gearblock WHERE GearblockId = ?"; - public GearblockSource(SqlDatabase db) { - _db = db; - } + private final SqlDatabase _db; - public int countAll() throws SQLException { - try (PreparedStatement sql = _db.prepareStatement(countAllScript)) { - try (ResultSet rs = sql.executeQuery()) { - if (rs.next()) return rs.getInt(1); - } - } + public GearblockSource(SqlDatabase db) { + _db = db; + } - return 0; - } + public int countAll() throws SQLException { + try (PreparedStatement sql = _db.prepareStatement(countAllScript)) { + try (ResultSet rs = sql.executeQuery()) { + if (rs.next()) return rs.getInt(1); + } + } - public List selectAll() throws SQLException { - ArrayList list = new ArrayList<>(); + return 0; + } - try (PreparedStatement sql = _db.prepareStatement(selectAllScript)) { - try (ResultSet rs = sql.executeQuery()) { - while (rs.next()) { - GearblockInfo info = new GearblockInfo(); + public List selectAll() throws SQLException { + ArrayList list = new ArrayList<>(); - info.GearblockId = rs.getInt("GearblockId"); - info.WorldId = rs.getString("WorldId"); - info.X = rs.getInt("X"); - info.Y = rs.getInt("Y"); - info.Z = rs.getInt("Z"); + try (PreparedStatement sql = _db.prepareStatement(selectAllScript)) { + try (ResultSet rs = sql.executeQuery()) { + while (rs.next()) { + GearblockInfo info = new GearblockInfo(); - info.Timer = rs.getInt("Timer"); - if (rs.wasNull()) info.Timer = null; + info.GearblockId = rs.getInt("GearblockId"); + info.WorldId = rs.getString("WorldId"); + info.X = rs.getInt("X"); + info.Y = rs.getInt("Y"); + info.Z = rs.getInt("Z"); - info.TimerOperation = rs.getInt("TimerOperation"); - if (rs.wasNull()) info.TimerOperation = null; + info.Timer = rs.getInt("Timer"); + if (rs.wasNull()) info.Timer = null; - list.add(info); - } - } - } + info.TimerOperation = rs.getInt("TimerOperation"); + if (rs.wasNull()) info.TimerOperation = null; - return list; - } + list.add(info); + } + } + } - public void insert(GearblockInfo info) throws SQLException { - try (PreparedStatement sql = _db.prepareStatementWithReturn(insertScript)) { - sql.setString(1, info.WorldId); - sql.setInt(2, info.X); - sql.setInt(3, info.Y); - sql.setInt(4, info.Z); + return list; + } - if (info.Timer != null) - sql.setInt(5, info.Timer); - else - sql.setNull(5, Types.INTEGER); + public void insert(GearblockInfo info) throws SQLException { + try (PreparedStatement sql = _db.prepareStatementWithReturn(insertScript)) { + sql.setString(1, info.WorldId); + sql.setInt(2, info.X); + sql.setInt(3, info.Y); + sql.setInt(4, info.Z); - if (info.TimerOperation != null) - sql.setInt(6, info.TimerOperation); - else - sql.setNull(6, Types.INTEGER); + if (info.Timer != null) + sql.setInt(5, info.Timer); + else + sql.setNull(5, Types.INTEGER); - sql.executeUpdate(); + if (info.TimerOperation != null) + sql.setInt(6, info.TimerOperation); + else + sql.setNull(6, Types.INTEGER); - try (ResultSet rs = sql.getGeneratedKeys()) { - rs.next(); - info.GearblockId = rs.getInt(1); - } - } - } + sql.executeUpdate(); - public void update(GearblockInfo info) throws SQLException { - try (PreparedStatement sql = _db.prepareStatement(updateScript)) { - sql.setString(1, info.WorldId); - sql.setInt(2, info.X); - sql.setInt(3, info.Y); - sql.setInt(4, info.Z); + try (ResultSet rs = sql.getGeneratedKeys()) { + rs.next(); + info.GearblockId = rs.getInt(1); + } + } + } - if (info.Timer != null) - sql.setInt(5, info.Timer); - else - sql.setNull(5, Types.INTEGER); + public void update(GearblockInfo info) throws SQLException { + try (PreparedStatement sql = _db.prepareStatement(updateScript)) { + sql.setString(1, info.WorldId); + sql.setInt(2, info.X); + sql.setInt(3, info.Y); + sql.setInt(4, info.Z); - if (info.TimerOperation != null) - sql.setInt(6, info.TimerOperation); - else - sql.setNull(6, Types.INTEGER); + if (info.Timer != null) + sql.setInt(5, info.Timer); + else + sql.setNull(5, Types.INTEGER); - sql.setInt(7, info.GearblockId); + if (info.TimerOperation != null) + sql.setInt(6, info.TimerOperation); + else + sql.setNull(6, Types.INTEGER); - sql.executeUpdate(); - } - } + sql.setInt(7, info.GearblockId); - public void delete(int gear_id) throws SQLException { - try (PreparedStatement sql = _db.prepareStatement(deleteScript)) { - sql.setInt(1, gear_id); + sql.executeUpdate(); + } + } - sql.executeUpdate(); - } - } + public void delete(int gear_id) throws SQLException { + try (PreparedStatement sql = _db.prepareStatement(deleteScript)) { + sql.setInt(1, gear_id); + + sql.executeUpdate(); + } + } } diff --git a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/database/LinkInfo.java b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/database/LinkInfo.java index 1b2cdd94a..8f830ab47 100644 --- a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/database/LinkInfo.java +++ b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/database/LinkInfo.java @@ -1,13 +1,13 @@ /** * @author Aleksey Terzi - * */ package com.aleksey.castlegates.database; public class LinkInfo { - public int LinkId; - public Integer StartGearblockId; - public Integer EndGearblockId; - public String Blocks; + + public int LinkId; + public Integer StartGearblockId; + public Integer EndGearblockId; + public String Blocks; } diff --git a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/database/LinkSource.java b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/database/LinkSource.java index 111624ea7..e7dfe7c29 100644 --- a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/database/LinkSource.java +++ b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/database/LinkSource.java @@ -1,6 +1,5 @@ /** * @author Aleksey Terzi - * */ package com.aleksey.castlegates.database; @@ -13,113 +12,114 @@ import java.util.ArrayList; import java.util.List; public class LinkSource { - private static final String countAllScript = "SELECT COUNT(*) FROM cg_link"; - private static final String selectAllScript = "SELECT * FROM cg_link ORDER BY LinkId"; - private static final String insertScript = "INSERT INTO cg_link (StartGearblockId, EndGearblockId, Blocks) VALUES (?, ?, ?)"; - private static final String updateScript = "UPDATE cg_link SET StartGearblockId = ?, EndGearblockId = ?, Blocks = ? WHERE LinkId = ?"; - private static final String deleteScript = "DELETE FROM cg_link WHERE LinkId = ?"; - private final SqlDatabase _db; + private static final String countAllScript = "SELECT COUNT(*) FROM cg_link"; + private static final String selectAllScript = "SELECT * FROM cg_link ORDER BY LinkId"; + private static final String insertScript = "INSERT INTO cg_link (StartGearblockId, EndGearblockId, Blocks) VALUES (?, ?, ?)"; + private static final String updateScript = "UPDATE cg_link SET StartGearblockId = ?, EndGearblockId = ?, Blocks = ? WHERE LinkId = ?"; + private static final String deleteScript = "DELETE FROM cg_link WHERE LinkId = ?"; - public LinkSource(SqlDatabase db) { - _db = db; - } + private final SqlDatabase _db; - public int countAll() throws SQLException { - try (PreparedStatement sql = _db.prepareStatement(countAllScript)) { - try (ResultSet rs = sql.executeQuery()) { - if (rs.next()) return rs.getInt(1); - } - } + public LinkSource(SqlDatabase db) { + _db = db; + } - return 0; - } + public int countAll() throws SQLException { + try (PreparedStatement sql = _db.prepareStatement(countAllScript)) { + try (ResultSet rs = sql.executeQuery()) { + if (rs.next()) return rs.getInt(1); + } + } - public List selectAll() throws SQLException { - ArrayList list = new ArrayList<>(); + return 0; + } - try (PreparedStatement sql = _db.prepareStatement(selectAllScript)) { - try (ResultSet rs = sql.executeQuery()) { - while (rs.next()) { - LinkInfo info = new LinkInfo(); - info.LinkId = rs.getInt("LinkId"); + public List selectAll() throws SQLException { + ArrayList list = new ArrayList<>(); - info.StartGearblockId = rs.getInt("StartGearblockId"); - if (rs.wasNull()) info.StartGearblockId = null; + try (PreparedStatement sql = _db.prepareStatement(selectAllScript)) { + try (ResultSet rs = sql.executeQuery()) { + while (rs.next()) { + LinkInfo info = new LinkInfo(); + info.LinkId = rs.getInt("LinkId"); - info.EndGearblockId = rs.getInt("EndGearblockId"); - if (rs.wasNull()) info.EndGearblockId = null; + info.StartGearblockId = rs.getInt("StartGearblockId"); + if (rs.wasNull()) info.StartGearblockId = null; - info.Blocks = rs.getString("Blocks"); + info.EndGearblockId = rs.getInt("EndGearblockId"); + if (rs.wasNull()) info.EndGearblockId = null; - list.add(info); - } - } - } + info.Blocks = rs.getString("Blocks"); - return list; - } + list.add(info); + } + } + } - public void insert(LinkInfo info) throws SQLException { - try (PreparedStatement sql = _db.prepareStatementWithReturn(insertScript)) { - if (info.StartGearblockId != null) { - sql.setInt(1, info.StartGearblockId); - } else { - sql.setNull(1, Types.INTEGER); - } + return list; + } - if (info.EndGearblockId != null) { - sql.setInt(2, info.EndGearblockId); - } else { - sql.setNull(2, Types.INTEGER); - } + public void insert(LinkInfo info) throws SQLException { + try (PreparedStatement sql = _db.prepareStatementWithReturn(insertScript)) { + if (info.StartGearblockId != null) { + sql.setInt(1, info.StartGearblockId); + } else { + sql.setNull(1, Types.INTEGER); + } - if (info.Blocks != null) { - sql.setString(3, info.Blocks); - } else { - sql.setNull(3, Types.VARCHAR); - } + if (info.EndGearblockId != null) { + sql.setInt(2, info.EndGearblockId); + } else { + sql.setNull(2, Types.INTEGER); + } - sql.executeUpdate(); + if (info.Blocks != null) { + sql.setString(3, info.Blocks); + } else { + sql.setNull(3, Types.VARCHAR); + } - try (ResultSet rs = sql.getGeneratedKeys()) { - rs.next(); - info.LinkId = rs.getInt(1); - } - } - } + sql.executeUpdate(); - public void update(LinkInfo info) throws SQLException { - try (PreparedStatement sql = _db.prepareStatement(updateScript)) { - if (info.StartGearblockId != null) { - sql.setInt(1, info.StartGearblockId); - } else { - sql.setNull(1, Types.INTEGER); - } + try (ResultSet rs = sql.getGeneratedKeys()) { + rs.next(); + info.LinkId = rs.getInt(1); + } + } + } - if (info.EndGearblockId != null) { - sql.setInt(2, info.EndGearblockId); - } else { - sql.setNull(2, Types.INTEGER); - } + public void update(LinkInfo info) throws SQLException { + try (PreparedStatement sql = _db.prepareStatement(updateScript)) { + if (info.StartGearblockId != null) { + sql.setInt(1, info.StartGearblockId); + } else { + sql.setNull(1, Types.INTEGER); + } - if (info.Blocks != null) { - sql.setString(3, info.Blocks); - } else { - sql.setNull(3, Types.VARCHAR); - } + if (info.EndGearblockId != null) { + sql.setInt(2, info.EndGearblockId); + } else { + sql.setNull(2, Types.INTEGER); + } - sql.setInt(4, info.LinkId); + if (info.Blocks != null) { + sql.setString(3, info.Blocks); + } else { + sql.setNull(3, Types.VARCHAR); + } - sql.executeUpdate(); - } - } + sql.setInt(4, info.LinkId); - public void delete(int link_id) throws SQLException { - try (PreparedStatement sql = _db.prepareStatement(deleteScript)) { - sql.setInt(1, link_id); + sql.executeUpdate(); + } + } - sql.executeUpdate(); - } - } + public void delete(int link_id) throws SQLException { + try (PreparedStatement sql = _db.prepareStatement(deleteScript)) { + sql.setInt(1, link_id); + + sql.executeUpdate(); + } + } } diff --git a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/database/ReinforcementInfo.java b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/database/ReinforcementInfo.java index 9935a5eb9..655056b61 100644 --- a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/database/ReinforcementInfo.java +++ b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/database/ReinforcementInfo.java @@ -1,16 +1,16 @@ /** * @author Aleksey Terzi - * */ package com.aleksey.castlegates.database; public class ReinforcementInfo { - public int LinkId; - public int BlockSequence; - public long CreationTime; - public short TypeId; - public float Health; - public int GroupId; - public boolean Insecure; + + public int LinkId; + public int BlockSequence; + public long CreationTime; + public short TypeId; + public float Health; + public int GroupId; + public boolean Insecure; } diff --git a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/database/ReinforcementSource.java b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/database/ReinforcementSource.java index 3eb30fbdc..7068f76e4 100644 --- a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/database/ReinforcementSource.java +++ b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/database/ReinforcementSource.java @@ -1,6 +1,5 @@ /** * @author Aleksey Terzi - * */ package com.aleksey.castlegates.database; @@ -12,59 +11,60 @@ import java.util.ArrayList; import java.util.List; public class ReinforcementSource { - private static final String selectAllScript = "SELECT * FROM cg_reinforcement ORDER BY LinkId, BlockSequence"; - private static final String insertScript = "INSERT INTO cg_reinforcement (LinkId, BlockSequence, CreationTime, TypeId, Health, GroupId, Insecure) VALUES (?, ?, ?, ?, ?, ?, ?)"; - private static final String deleteScript = "DELETE FROM cg_reinforcement WHERE LinkId = ?"; - private final SqlDatabase _db; + private static final String selectAllScript = "SELECT * FROM cg_reinforcement ORDER BY LinkId, BlockSequence"; + private static final String insertScript = "INSERT INTO cg_reinforcement (LinkId, BlockSequence, CreationTime, TypeId, Health, GroupId, Insecure) VALUES (?, ?, ?, ?, ?, ?, ?)"; + private static final String deleteScript = "DELETE FROM cg_reinforcement WHERE LinkId = ?"; - public ReinforcementSource(SqlDatabase db) { - _db = db; - } + private final SqlDatabase _db; - public List selectAll() throws SQLException { - ArrayList list = new ArrayList<>(); + public ReinforcementSource(SqlDatabase db) { + _db = db; + } - try (PreparedStatement sql = _db.prepareStatement(selectAllScript)) { + public List selectAll() throws SQLException { + ArrayList list = new ArrayList<>(); - try (ResultSet rs = sql.executeQuery()) { - while (rs.next()) { - ReinforcementInfo info = new ReinforcementInfo(); - info.LinkId = rs.getInt("LinkId"); - info.BlockSequence = rs.getInt("BlockSequence"); - info.CreationTime = rs.getLong("CreationTime"); - info.TypeId = rs.getShort("TypeId"); - info.Health = rs.getFloat("Health"); - info.GroupId = rs.getInt("GroupId"); - info.Insecure = rs.getBoolean("Insecure"); + try (PreparedStatement sql = _db.prepareStatement(selectAllScript)) { - list.add(info); - } - } - } + try (ResultSet rs = sql.executeQuery()) { + while (rs.next()) { + ReinforcementInfo info = new ReinforcementInfo(); + info.LinkId = rs.getInt("LinkId"); + info.BlockSequence = rs.getInt("BlockSequence"); + info.CreationTime = rs.getLong("CreationTime"); + info.TypeId = rs.getShort("TypeId"); + info.Health = rs.getFloat("Health"); + info.GroupId = rs.getInt("GroupId"); + info.Insecure = rs.getBoolean("Insecure"); - return list; - } + list.add(info); + } + } + } - public void insert(ReinforcementInfo info) throws SQLException { - try (PreparedStatement sql = _db.prepareStatement(insertScript)) { - sql.setInt(1, info.LinkId); - sql.setInt(2, info.BlockSequence); - sql.setLong(3, info.CreationTime); - sql.setShort(4, info.TypeId); - sql.setFloat(5, info.Health); - sql.setInt(6, info.GroupId); - sql.setBoolean(7, info.Insecure); + return list; + } - sql.executeUpdate(); - } - } + public void insert(ReinforcementInfo info) throws SQLException { + try (PreparedStatement sql = _db.prepareStatement(insertScript)) { + sql.setInt(1, info.LinkId); + sql.setInt(2, info.BlockSequence); + sql.setLong(3, info.CreationTime); + sql.setShort(4, info.TypeId); + sql.setFloat(5, info.Health); + sql.setInt(6, info.GroupId); + sql.setBoolean(7, info.Insecure); - public void deleteByLinkId(int link_id) throws SQLException { - try (PreparedStatement sql = _db.prepareStatement(deleteScript)) { - sql.setInt(1, link_id); + sql.executeUpdate(); + } + } - sql.executeUpdate(); - } - } + public void deleteByLinkId(int link_id) throws SQLException { + try (PreparedStatement sql = _db.prepareStatement(deleteScript)) { + sql.setInt(1, link_id); + + sql.executeUpdate(); + } + } } diff --git a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/database/SqlDatabase.java b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/database/SqlDatabase.java index f41f905a6..ed3bd873f 100644 --- a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/database/SqlDatabase.java +++ b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/database/SqlDatabase.java @@ -1,6 +1,5 @@ /** * @author Aleksey Terzi - * */ package com.aleksey.castlegates.database; @@ -17,7 +16,8 @@ import java.util.logging.Logger; import com.aleksey.castlegates.utils.ResourceHelper; public class SqlDatabase { - private final String _host; + + private final String _host; private final int _port; private final String _db; private final String _user; @@ -72,11 +72,11 @@ public class SqlDatabase { } public boolean checkConnection() { - if(isConnected()) return true; + if (isConnected()) return true; - _logger.log(Level.INFO, "Database went away, reconnecting."); + _logger.log(Level.INFO, "Database went away, reconnecting."); - return connect(); + return connect(); } public PreparedStatement prepareStatement(String sqlStatement) throws SQLException { @@ -88,28 +88,28 @@ public class SqlDatabase { } public boolean initDb() { - _logger.log(Level.INFO, "Database initialization started..."); + _logger.log(Level.INFO, "Database initialization started..."); - ArrayList list = ResourceHelper.readScriptList("/create_db.txt"); + ArrayList list = ResourceHelper.readScriptList("/create_db.txt"); if (list == null) { _logger.log(Level.SEVERE, "Resource create_db.txt is not found."); return false; } - for(String script : list) { - try (PreparedStatement statement = prepareStatement(script)) { - statement.execute(); - } catch (SQLException e) { - _logger.log(Level.SEVERE, "Database is NOT initialized."); - _logger.log(Level.SEVERE, "Failed script: \n" + script); - e.printStackTrace(); - return false; - } - } + for (String script : list) { + try (PreparedStatement statement = prepareStatement(script)) { + statement.execute(); + } catch (SQLException e) { + _logger.log(Level.SEVERE, "Database is NOT initialized."); + _logger.log(Level.SEVERE, "Failed script: \n" + script); + e.printStackTrace(); + return false; + } + } - _logger.log(Level.INFO, "Database initialized."); + _logger.log(Level.INFO, "Database initialized."); - return true; + return true; } } diff --git a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/engine/CastleGatesManager.java b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/engine/CastleGatesManager.java index 1a03a18cc..afdbd1da6 100644 --- a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/engine/CastleGatesManager.java +++ b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/engine/CastleGatesManager.java @@ -1,6 +1,5 @@ /** * @author Aleksey Terzi - * */ package com.aleksey.castlegates.engine; @@ -28,104 +27,107 @@ import java.util.List; import java.util.logging.Level; public class CastleGatesManager { - private SqlDatabase _db; - private StorageManager _storage; - private BridgeManager _bridgeManager; - private BridgeEventHandler _bridgeEventHandler; - private PlayerStateManager _stateManager; - public boolean init(SqlDatabase db) { - _db = db; + private SqlDatabase _db; + private StorageManager _storage; + private BridgeManager _bridgeManager; + private BridgeEventHandler _bridgeEventHandler; + private PlayerStateManager _stateManager; - try { - _storage = new StorageManager(); - _storage.init(db); - } catch (SQLException e) { - e.printStackTrace(); - return false; - } + public boolean init(SqlDatabase db) { + _db = db; - _bridgeManager = new BridgeManager(); - _bridgeManager.init(_storage); + try { + _storage = new StorageManager(); + _storage.init(db); + } catch (SQLException e) { + e.printStackTrace(); + return false; + } - _bridgeEventHandler = new BridgeEventHandler(_storage, _bridgeManager); + _bridgeManager = new BridgeManager(); + _bridgeManager.init(_storage); - _stateManager = new PlayerStateManager(); + _bridgeEventHandler = new BridgeEventHandler(_storage, _bridgeManager); - return true; - } + _stateManager = new PlayerStateManager(); - public void reinit() { - CastleGates.getPluginLogger().log(Level.INFO, "Start reload process..."); + return true; + } - _bridgeManager.close(); + public void reinit() { + CastleGates.getPluginLogger().log(Level.INFO, "Start reload process..."); - try { - _storage.close(); - _storage.init(_db); - } catch (SQLException e) { - e.printStackTrace(); - return; - } + _bridgeManager.close(); - _bridgeManager.init(_storage); + try { + _storage.close(); + _storage.init(_db); + } catch (SQLException e) { + e.printStackTrace(); + return; + } - CastleGates.getPluginLogger().log(Level.INFO, "Reload process completed."); - } + _bridgeManager.init(_storage); - public void close() { - if(_bridgeManager != null) { - _bridgeManager.close(); - } + CastleGates.getPluginLogger().log(Level.INFO, "Reload process completed."); + } - if(_storage != null) { - _storage.close(); - } + public void close() { + if (_bridgeManager != null) { + _bridgeManager.close(); + } - if(_db != null) { - _db.close(); - } - } + if (_storage != null) { + _storage.close(); + } - public void setPlayerMode(Player player, CommandMode mode, Integer timer, TimerOperation timerOperation, TimerMode timerMode) { - _stateManager.setPlayerMode(player, mode, timer, timerOperation, timerMode); - } + if (_db != null) { + _db.close(); + } + } - public void handlePlayerJoin(PlayerJoinEvent event) { - _stateManager.clearPlayerMode(event.getPlayer()); - } + public void setPlayerMode(Player player, CommandMode mode, Integer timer, TimerOperation timerOperation, TimerMode timerMode) { + _stateManager.setPlayerMode(player, mode, timer, timerOperation, timerMode); + } - public void handlePlayerQuit(PlayerQuitEvent event) { - _stateManager.clearPlayerMode(event.getPlayer()); - } + public void handlePlayerJoin(PlayerJoinEvent event) { + _stateManager.clearPlayerMode(event.getPlayer()); + } - public void handleBlockClicked(PlayerInteractEvent event) { - boolean interacted = _bridgeEventHandler.handleBlockClicked(event, _stateManager.getPlayerState(event.getPlayer())); + public void handlePlayerQuit(PlayerQuitEvent event) { + _stateManager.clearPlayerMode(event.getPlayer()); + } - if(interacted) { - _stateManager.interact(event.getPlayer()); - } - } + public void handleBlockClicked(PlayerInteractEvent event) { + boolean interacted = _bridgeEventHandler.handleBlockClicked(event, _stateManager.getPlayerState(event.getPlayer())); - public void handleBlockBreak(BlockBreakEvent event) { - _bridgeEventHandler.handleBlockBreak(event); - } + if (interacted) { + _stateManager.interact(event.getPlayer()); + } + } - public void handleBlockRedstone(BlockRedstoneEvent event) { + public void handleBlockBreak(BlockBreakEvent event) { + _bridgeEventHandler.handleBlockBreak(event); + } + + public void handleBlockRedstone(BlockRedstoneEvent event) { _bridgeEventHandler.handleBlockRedstone(event); - } + } - public void handleBlockPhysics(BlockPhysicsEvent event) { - _bridgeEventHandler.handleBlockPhysics(event); - } + public void handleBlockPhysics(BlockPhysicsEvent event) { + _bridgeEventHandler.handleBlockPhysics(event); + } - public void handleEntityExplode(EntityExplodeEvent event) { - _bridgeEventHandler.handleEntityExplode(event); - } + public void handleEntityExplode(EntityExplodeEvent event) { + _bridgeEventHandler.handleEntityExplode(event); + } - public void handleEntityChangeBlock(EntityChangeBlockEvent event) { _bridgeEventHandler.handleEntityChangeBlock(event); } + public void handleEntityChangeBlock(EntityChangeBlockEvent event) { + _bridgeEventHandler.handleEntityChangeBlock(event); + } - public void handlePistonEvent(List blocks) { - _bridgeEventHandler.handlePistonEvent(blocks); - } + public void handlePistonEvent(List blocks) { + _bridgeEventHandler.handlePistonEvent(blocks); + } } diff --git a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/engine/PlayerStateManager.java b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/engine/PlayerStateManager.java index 5b5b513fb..219869c3a 100644 --- a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/engine/PlayerStateManager.java +++ b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/engine/PlayerStateManager.java @@ -1,6 +1,5 @@ /** * @author Aleksey Terzi - * */ package com.aleksey.castlegates.engine; @@ -18,100 +17,101 @@ import com.aleksey.castlegates.types.CommandMode; import com.aleksey.castlegates.types.TimerOperation; public class PlayerStateManager { - public static class PlayerState { - public CommandMode mode; - public Integer timer; - public TimerOperation timerOperation; - public TimerMode timerMode; - public long lastInteracted; - } - private final Map _states = new HashMap<>(); - private final Map _tasks = new HashMap<>(); + public static class PlayerState { - public void clearPlayerMode(Player player) { - Integer taskId = _tasks.get(player); + public CommandMode mode; + public Integer timer; + public TimerOperation timerOperation; + public TimerMode timerMode; + public long lastInteracted; + } - if(taskId != null) { - Bukkit.getScheduler().cancelTask(taskId); - } + private final Map _states = new HashMap<>(); + private final Map _tasks = new HashMap<>(); - PlayerState state = _states.get(player); + public void clearPlayerMode(Player player) { + Integer taskId = _tasks.get(player); - if(state == null) return; + if (taskId != null) { + Bukkit.getScheduler().cancelTask(taskId); + } - _states.remove(player); + PlayerState state = _states.get(player); - if(player.isOnline()) { - player.sendMessage(ChatColor.YELLOW + "Castle Gates " + state.mode.name() + " mode off"); - } - } + if (state == null) return; - public PlayerState getPlayerState(Player player) { - return _states.get(player); - } + _states.remove(player); - public void setPlayerMode(Player player, CommandMode mode, Integer timer, TimerOperation timerOperation, TimerMode timerMode) { - if(mode == CommandMode.OFF) { - clearPlayerMode(player); - return; - } + if (player.isOnline()) { + player.sendMessage(ChatColor.YELLOW + "Castle Gates " + state.mode.name() + " mode off"); + } + } - PlayerState state = _states.get(player); + public PlayerState getPlayerState(Player player) { + return _states.get(player); + } - if(state == null) { - if(mode == CommandMode.NORMAL) { - player.sendMessage(ChatColor.GREEN + "Castle Gates " + mode.name() + " mode on"); - return; - } + public void setPlayerMode(Player player, CommandMode mode, Integer timer, TimerOperation timerOperation, TimerMode timerMode) { + if (mode == CommandMode.OFF) { + clearPlayerMode(player); + return; + } - _states.put(player, state = new PlayerState()); - } - else if(state.mode == mode) { - clearPlayerMode(player); - return; - } + PlayerState state = _states.get(player); - state.mode = mode; - state.timer = timer; - state.timerOperation = timerOperation; - state.timerMode = timerMode; - state.lastInteracted = System.currentTimeMillis(); + if (state == null) { + if (mode == CommandMode.NORMAL) { + player.sendMessage(ChatColor.GREEN + "Castle Gates " + mode.name() + " mode on"); + return; + } - addTask(player); + _states.put(player, state = new PlayerState()); + } else if (state.mode == mode) { + clearPlayerMode(player); + return; + } - player.sendMessage(ChatColor.GREEN + "Castle Gates " + mode.name() + " mode on"); - } + state.mode = mode; + state.timer = timer; + state.timerOperation = timerOperation; + state.timerMode = timerMode; + state.lastInteracted = System.currentTimeMillis(); - public void interact(Player player) { - PlayerState state = _states.get(player); + addTask(player); - if(state != null) { - state.lastInteracted = System.currentTimeMillis(); - } - } + player.sendMessage(ChatColor.GREEN + "Castle Gates " + mode.name() + " mode on"); + } - private void addTask(final Player player) { - if(_tasks.containsKey(player)) return; + public void interact(Player player) { + PlayerState state = _states.get(player); - final PlayerStateManager stateManager = this; + if (state != null) { + state.lastInteracted = System.currentTimeMillis(); + } + } - int taskId = Bukkit.getScheduler().runTaskTimer( - CastleGates.getInstance(), - () -> { - PlayerState state = stateManager._states.get(player); - if(state != null) { - long offTime = state.lastInteracted + 1000L * CastleGates.getConfigManager().getPlayerStateResetInSeconds(); + private void addTask(final Player player) { + if (_tasks.containsKey(player)) return; - if(offTime < System.currentTimeMillis()) { - clearPlayerMode(player); - } - } - }, - 20L * 30, - 20L * 30 - ).getTaskId(); + final PlayerStateManager stateManager = this; - _tasks.put(player, taskId); - } + int taskId = Bukkit.getScheduler().runTaskTimer( + CastleGates.getInstance(), + () -> { + PlayerState state = stateManager._states.get(player); + if (state != null) { + long offTime = state.lastInteracted + 1000L * CastleGates.getConfigManager().getPlayerStateResetInSeconds(); + + if (offTime < System.currentTimeMillis()) { + clearPlayerMode(player); + } + } + }, + 20L * 30, + 20L * 30 + ).getTaskId(); + + _tasks.put(player, taskId); + } } diff --git a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/engine/StorageManager.java b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/engine/StorageManager.java index 67416ff22..b75887b8c 100644 --- a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/engine/StorageManager.java +++ b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/engine/StorageManager.java @@ -13,6 +13,7 @@ import java.util.List; import java.util.Map; public class StorageManager { + private Map _gearblocks; private DataWorker _dataWorker; @@ -25,7 +26,7 @@ public class StorageManager { } public void close() { - if(_dataWorker != null) { + if (_dataWorker != null) { _dataWorker.close(); _dataWorker = null; } @@ -58,15 +59,13 @@ public class StorageManager { public void addLink(Gearblock gearblock1, Gearblock gearblock2) { GearblockLink link; - if(gearblock1.getBrokenLink() != null) { + if (gearblock1.getBrokenLink() != null) { link = gearblock1.getBrokenLink(); link.setRestored(gearblock2); - } - else if(gearblock2.getBrokenLink() != null) { + } else if (gearblock2.getBrokenLink() != null) { link = gearblock2.getBrokenLink(); link.setRestored(gearblock1); - } - else { + } else { link = new GearblockLink(gearblock1, gearblock2); } @@ -79,11 +78,11 @@ public class StorageManager { public void removeLink(GearblockLink link) { link.setRemoved(); - if(link.getGearblock1() != null) { + if (link.getGearblock1() != null) { link.getGearblock1().setLink(null); } - if(link.getGearblock2() != null) { + if (link.getGearblock2() != null) { link.getGearblock2().setLink(null); } @@ -111,4 +110,4 @@ public class StorageManager { _dataWorker.addChangedGearblock(gearblock); } -} \ No newline at end of file +} diff --git a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/engine/bridge/BridgeEventHandler.java b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/engine/bridge/BridgeEventHandler.java index 69b1afd13..0f4fd64fe 100644 --- a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/engine/bridge/BridgeEventHandler.java +++ b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/engine/bridge/BridgeEventHandler.java @@ -32,7 +32,9 @@ import java.util.List; import java.util.UUID; public class BridgeEventHandler { + private static class FindGearResult { + public Gearblock gearblock; public int distance; @@ -53,30 +55,27 @@ public class BridgeEventHandler { } public boolean handleBlockClicked(PlayerInteractEvent event, PlayerStateManager.PlayerState state) { - if(event.getAction() == Action.RIGHT_CLICK_BLOCK && event.getHand() == EquipmentSlot.HAND) { + if (event.getAction() == Action.RIGHT_CLICK_BLOCK && event.getHand() == EquipmentSlot.HAND) { simpleActivate(event); return false; } - if(event.getAction() != Action.LEFT_CLICK_BLOCK) + if (event.getAction() != Action.LEFT_CLICK_BLOCK) return false; boolean interacted = false; ConfigManager configManager = CastleGates.getConfigManager(); - CommandMode mode = state != null ? state.mode: CommandMode.OFF; + CommandMode mode = state != null ? state.mode : CommandMode.OFF; - if(configManager.getAllowAutoCreate() && configManager.isCreationConsumeItem(event.getItem())) { + if (configManager.getAllowAutoCreate() && configManager.isCreationConsumeItem(event.getItem())) { interacted = createGearblockAndLink(event); - } - else if(mode == CommandMode.INFO) { + } else if (mode == CommandMode.INFO) { showGearInfo(event); interacted = true; - } - else if(mode == CommandMode.TIMER) { + } else if (mode == CommandMode.TIMER) { interacted = setGearblockTimer(event, state); - } - else if(configManager.isStickItem(event.getItem())) { - interacted = switch(mode) { + } else if (configManager.isStickItem(event.getItem())) { + interacted = switch (mode) { case CREATE -> createGearblock(event); case LINK -> linkGearblocks(event); default -> false; @@ -90,7 +89,7 @@ public class BridgeEventHandler { Block block = event.getBlock(); BridgeManager.RemoveResult result = _bridgeManager.removeGear(new BlockCoord(block)); - if(result == BridgeManager.RemoveResult.Removed || result == BridgeManager.RemoveResult.RemovedWithLink) { + if (result == BridgeManager.RemoveResult.Removed || result == BridgeManager.RemoveResult.RemovedWithLink) { Helper.putItemToInventoryOrDrop(event.getPlayer(), block.getLocation(), CastleGates.getConfigManager().getCreationConsumeItem()); } } @@ -103,7 +102,7 @@ public class BridgeEventHandler { for (BlockFace face : BridgeManager.faces) { Block faceBlock = block.getRelative(face); - if(_storage.getGearblock(new BlockCoord(faceBlock)) != null) { + if (_storage.getGearblock(new BlockCoord(faceBlock)) != null) { _waitingBlocks.add(faceBlock); } } @@ -112,7 +111,7 @@ public class BridgeEventHandler { public void handleBlockPhysics(BlockPhysicsEvent event) { Block block = event.getBlock(); - if(_waitingBlocks.remove(block)) { + if (_waitingBlocks.remove(block)) { processBlock(block, block.isBlockPowered()); } } @@ -133,16 +132,16 @@ public class BridgeEventHandler { for (Block block : blocks) { BridgeManager.RemoveResult result = _bridgeManager.removeGear(new BlockCoord(block)); - if(result == BridgeManager.RemoveResult.Removed || result == BridgeManager.RemoveResult.RemovedWithLink) { + if (result == BridgeManager.RemoveResult.Removed || result == BridgeManager.RemoveResult.RemovedWithLink) { Helper.putItemToInventoryOrDrop(null, block.getLocation(), dropItem); } } } private boolean createGearblockAndLink(PlayerInteractEvent event) { - if(event.getClickedBlock() == null - || CastleGates.getCitadelManager().isReinforcingStateActive(event.getPlayer()) - || !createGearblock(event) + if (event.getClickedBlock() == null + || CastleGates.getCitadelManager().isReinforcingStateActive(event.getPlayer()) + || !createGearblock(event) ) { return false; } @@ -150,17 +149,16 @@ public class BridgeEventHandler { Block block = event.getClickedBlock(); Gearblock gearblock1 = _storage.getGearblock(new BlockCoord(block)); - if(gearblock1.getLink() != null) + if (gearblock1.getLink() != null) return true; - for(BlockFace face : BridgeManager.faces) { + for (BlockFace face : BridgeManager.faces) { FindGearResult result = findEndGear(block, face); - if(result != null - && result.gearblock.getLink() == null - && linkGearblocks(event.getPlayer(), gearblock1, result, false) - ) - { + if (result != null + && result.gearblock.getLink() == null + && linkGearblocks(event.getPlayer(), gearblock1, result, false) + ) { break; } } @@ -177,14 +175,13 @@ public class BridgeEventHandler { Location location = block.getLocation(); - if(CastleGates.getConfigManager().isGearblockMustBeReinforced() - && !CastleGates.getCitadelManager().isReinforced(location)) - { + if (CastleGates.getConfigManager().isGearblockMustBeReinforced() + && !CastleGates.getCitadelManager().isReinforced(location)) { player.sendMessage(ChatColor.RED + "Block must be reinforced to create a gearblock."); return false; } - if(!CastleGates.getCitadelManager().canBypass(player, location)) { + if (!CastleGates.getCitadelManager().canBypass(player, location)) { player.sendMessage(ChatColor.RED + "Citadel has prevented the creation of a gearblock."); return false; } @@ -192,17 +189,17 @@ public class BridgeEventHandler { ItemStack consumeItem = CastleGates.getConfigManager().getCreationConsumeItem(); List consumeSlots = Helper.getConsumeSlots(player, consumeItem); - if(consumeSlots == null && consumeItem != null) { + if (consumeSlots == null && consumeItem != null) { player.sendMessage(ChatColor.RED + "Not enough material left to create a gearblock."); return false; } BridgeManager.CreateResult result = _bridgeManager.createGear(block); - if(result == BridgeManager.CreateResult.NotCreated) { + if (result == BridgeManager.CreateResult.NotCreated) { player.sendMessage(ChatColor.RED + block.getType().toString() + " cannot be used as a gearblock."); return false; - } else if(result == BridgeManager.CreateResult.AlreadyExist) { + } else if (result == BridgeManager.CreateResult.AlreadyExist) { player.sendMessage(ChatColor.RED + "That block is already a gearblock."); return true; } @@ -225,16 +222,16 @@ public class BridgeEventHandler { Gearblock gearblock1 = _storage.getGearblock(new BlockCoord(block)); - if(gearblock1 == null) + if (gearblock1 == null) return false; - if(!CastleGates.getCitadelManager().canBypass(player, block.getLocation())) { + if (!CastleGates.getCitadelManager().canBypass(player, block.getLocation())) { player.sendMessage(ChatColor.RED + "Citadel has prevented the creation of a link."); return false; } - if(gearblock1.getLink() != null) { - if(gearblock1.getLink().isDrawn()) { + if (gearblock1.getLink() != null) { + if (gearblock1.getLink().isDrawn()) { player.sendMessage(ChatColor.RED + "Cannot unlink gearblocks in a drawn bridge/gate."); } else { _bridgeManager.removeLink(gearblock1.getLink()); @@ -246,7 +243,7 @@ public class BridgeEventHandler { FindGearResult result = findEndGear(block, event.getBlockFace()); - if(result == null) { + if (result == null) { event.getPlayer().sendMessage(ChatColor.RED + "End gearblock not found. Link distance is limited to " + CastleGates.getConfigManager().getMaxBridgeLength() + " blocks."); } else { linkGearblocks(player, gearblock1, result, true); @@ -258,16 +255,16 @@ public class BridgeEventHandler { private boolean linkGearblocks(Player player, Gearblock gearblock1, FindGearResult result, boolean showError) { Location loc = new Location(player.getWorld(), result.gearblock.getCoord().getX(), result.gearblock.getCoord().getY(), result.gearblock.getCoord().getZ()); - if(!CastleGates.getCitadelManager().canBypass(player, loc)) { - if(showError) { + if (!CastleGates.getCitadelManager().canBypass(player, loc)) { + if (showError) { player.sendMessage(ChatColor.RED + "Citadel has prevented the creation of a link."); } return false; } - if(result.gearblock.getLink() != null) { - if(showError) { + if (result.gearblock.getLink() != null) { + if (showError) { player.sendMessage(ChatColor.RED + "The gearblock at [" + result.gearblock.getCoord().getX() + " " + result.gearblock.getCoord().getY() + " " + result.gearblock.getCoord().getZ() + "] already has a link. Remove it before creating a new one."); ParticleHelper.spawn(player, result.gearblock, ParticleHelper.Type.Warning); } @@ -275,14 +272,14 @@ public class BridgeEventHandler { return false; } - if(_bridgeManager.createLink(gearblock1, result.gearblock, result.distance)) { + if (_bridgeManager.createLink(gearblock1, result.gearblock, result.distance)) { player.sendMessage(ChatColor.GREEN + "The gearblock has been linked with the gearblock at [" + result.gearblock.getCoord().getX() + " " + result.gearblock.getCoord().getY() + " " + result.gearblock.getCoord().getZ() + "]."); ParticleHelper.spawn(player, gearblock1, ParticleHelper.Type.Info); ParticleHelper.spawn(player, result.gearblock, ParticleHelper.Type.Info); return true; } - if(showError) { + if (showError) { player.sendMessage(ChatColor.RED + "The gearblock at [" + result.gearblock.getCoord().getX() + " " + result.gearblock.getCoord().getY() + " " + result.gearblock.getCoord().getZ() + "] has a broken link which cannot be restored by using the clicked block. Click the block where the other gearblock used to be."); ParticleHelper.spawn(player, result.gearblock, ParticleHelper.Type.Warning); } @@ -298,10 +295,10 @@ public class BridgeEventHandler { int maxBridgeLength = CastleGates.getConfigManager().getMaxBridgeLength(); boolean isNonSimpleDisabled = CastleGates.getConfigManager().isHorizontalLinkDisabled() - && blockFace != BlockFace.UP - && blockFace != BlockFace.DOWN; + && blockFace != BlockFace.UP + && blockFace != BlockFace.DOWN; - for(int i = 0; i < maxBridgeLength; i++) { + for (int i = 0; i < maxBridgeLength; i++) { x += blockFace.getModX(); y += blockFace.getModY(); z += blockFace.getModZ(); @@ -309,14 +306,14 @@ public class BridgeEventHandler { BlockCoord location = new BlockCoord(worldUID, x, y, z); Gearblock gearblock = _storage.getGearblock(location); - if(gearblock != null) { + if (gearblock != null) { if (i == 0 || i > 1 && isNonSimpleDisabled) return null; if (isNonSimpleDisabled && ( - hasAdjacentGearblocks(worldUID, startGearBlock.getX(), startGearBlock.getY(), startGearBlock.getZ()) + hasAdjacentGearblocks(worldUID, startGearBlock.getX(), startGearBlock.getY(), startGearBlock.getZ()) || hasAdjacentGearblocks(worldUID, x, y, z) - ) + ) ) { return null; } @@ -330,11 +327,11 @@ public class BridgeEventHandler { private boolean hasAdjacentGearblocks(UUID worldUID, int x, int y, int z) { return _storage.hasGearblock(new BlockCoord(worldUID, x + 1, y, z)) - || _storage.hasGearblock(new BlockCoord(worldUID, x - 1, y, z)) - || _storage.hasGearblock(new BlockCoord(worldUID, x, y + 1, z)) - || _storage.hasGearblock(new BlockCoord(worldUID, x, y - 1, z)) - || _storage.hasGearblock(new BlockCoord(worldUID, x, y, z + 1)) - || _storage.hasGearblock(new BlockCoord(worldUID, x, y, z - 1)); + || _storage.hasGearblock(new BlockCoord(worldUID, x - 1, y, z)) + || _storage.hasGearblock(new BlockCoord(worldUID, x, y + 1, z)) + || _storage.hasGearblock(new BlockCoord(worldUID, x, y - 1, z)) + || _storage.hasGearblock(new BlockCoord(worldUID, x, y, z + 1)) + || _storage.hasGearblock(new BlockCoord(worldUID, x, y, z - 1)); } private void showGearInfo(PlayerInteractEvent event) { @@ -347,10 +344,10 @@ public class BridgeEventHandler { BlockCoord blockCoord = new BlockCoord(block); Gearblock gearblock = _storage.getGearblock(blockCoord); - if(gearblock == null) { + if (gearblock == null) { BridgeManager.SearchBridgeBlockResult searchResult = _bridgeManager.searchBridgeBlock(blockCoord); - switch(searchResult) { + switch (searchResult) { case Bridge -> player.sendMessage("Bridge block"); case Gates -> player.sendMessage("Gate block"); } @@ -358,62 +355,59 @@ public class BridgeEventHandler { return; } - if(!CastleGates.getCitadelManager().canViewInformation(player, block.getLocation())) { + if (!CastleGates.getCitadelManager().canViewInformation(player, block.getLocation())) { player.sendMessage(ChatColor.RED + "Gearblock"); - } - else { - if(gearblock.getLink() == null) { + } else { + if (gearblock.getLink() == null) { player.sendMessage(ChatColor.GREEN + "The gearblock is not linked."); - if(gearblock.getBrokenLink() != null) { + if (gearblock.getBrokenLink() != null) { player.sendMessage(ChatColor.GREEN + "But contains " + gearblock.getBrokenLink().getBlocks().size() + " drawn blocks."); } - } - else { - Gearblock gearblock2 = gearblock.getLink().getGearblock1() == gearblock ? gearblock.getLink().getGearblock2(): gearblock.getLink().getGearblock1(); + } else { + Gearblock gearblock2 = gearblock.getLink().getGearblock1() == gearblock ? gearblock.getLink().getGearblock2() : gearblock.getLink().getGearblock1(); player.sendMessage(ChatColor.GREEN + "The gearblock has been linked to the gearblock at [" + gearblock2.getCoord().getX() + " " + gearblock2.getCoord().getY() + " " + gearblock2.getCoord().getZ() + "]."); - if(gearblock.getLink().isDrawn()) { + if (gearblock.getLink().isDrawn()) { player.sendMessage(ChatColor.GREEN + "The bridge/gate is drawn."); } ParticleHelper.spawn(player, gearblock2, ParticleHelper.Type.Info); } - if(gearblock.getTimer() != null) { + if (gearblock.getTimer() != null) { String message = "Timer: " + gearblock.getTimer() + " sec to process operation " + gearblock.getTimerOperation() + " in " + gearblock.getTimerMode() + " mode."; player.sendMessage(ChatColor.GREEN + message); } - if(gearblock.getLockedGearblocks() != null || gearblock.getLockGearblock() != null) { + if (gearblock.getLockedGearblocks() != null || gearblock.getLockGearblock() != null) { player.sendMessage(ChatColor.YELLOW + "Locked"); } } } private void processBlock(Block block, boolean isPowered) { - if(_processingBlocks.contains(block)) + if (_processingBlocks.contains(block)) return; Gearblock gearblock = _storage.getGearblock(new BlockCoord(block)); - if(gearblock == null || gearblock.isPowered() == isPowered) + if (gearblock == null || gearblock.isPowered() == isPowered) return; _processingBlocks.add(block); - try - { + try { List players = Helper.getNearbyPlayers(block.getLocation()); PowerResult result = _bridgeManager.processGearblock( - block.getWorld(), - gearblock, - isPowered, - players + block.getWorld(), + gearblock, + isPowered, + players ); - if(result.status == PowerResult.Status.Locked && gearblock.getTimerMode() == TimerMode.DOOR) { + if (result.status == PowerResult.Status.Locked && gearblock.getTimerMode() == TimerMode.DOOR) { result = PowerResult.Unchanged; } @@ -430,7 +424,7 @@ public class BridgeEventHandler { if (block == null) return true; - if(!CastleGates.getConfigManager().isTimerEnabled()) { + if (!CastleGates.getConfigManager().isTimerEnabled()) { player.sendMessage(ChatColor.RED + "The timer function is disabled on this server."); return true; } @@ -438,19 +432,19 @@ public class BridgeEventHandler { BlockCoord blockCoord = new BlockCoord(block); Gearblock gearblock = _storage.getGearblock(blockCoord); - if(gearblock == null) { + if (gearblock == null) { player.sendMessage(ChatColor.RED + "That block is not a gearblock."); return true; } - if(!CastleGates.getCitadelManager().canBypass(player, block.getLocation())) { + if (!CastleGates.getCitadelManager().canBypass(player, block.getLocation())) { player.sendMessage(ChatColor.RED + "Citadel has prevented that operation."); return true; } String message; - if(gearblock.getTimer() == null) { + if (gearblock.getTimer() == null) { _storage.setGearblockTimer(gearblock, state.timer, state.timerOperation, state.timerMode); String modeText = state.timerMode == TimerMode.DEFAULT ? "DEFAULT" : "DOOR"; message = ChatColor.GREEN + "The gearblock's timer has been set to " + state.timer + " sec to process operation " + state.timerOperation + " in " + modeText + " mode."; @@ -475,30 +469,28 @@ public class BridgeEventHandler { BlockCoord blockCoord = new BlockCoord(block); Gearblock gearblock = _storage.getGearblock(blockCoord); - if(gearblock != null) + if (gearblock != null) return; GearblockLink link; - if((link = getLink(blockCoord.getForward(), blockCoord.getBackward())) == null - && (link = getLink(blockCoord.getRight(), blockCoord.getLeft())) == null - && (link = getLink(blockCoord.getTop(), blockCoord.getBottom())) == null - ) - { + if ((link = getLink(blockCoord.getForward(), blockCoord.getBackward())) == null + && (link = getLink(blockCoord.getRight(), blockCoord.getLeft())) == null + && (link = getLink(blockCoord.getTop(), blockCoord.getBottom())) == null + ) { return; } - if(_bridgeManager.isNotSimpleGearblock(link.getGearblock1(), event.getPlayer()) - || _bridgeManager.isNotSimpleGearblock(link.getGearblock2(), event.getPlayer()) - ) - { + if (_bridgeManager.isNotSimpleGearblock(link.getGearblock1(), event.getPlayer()) + || _bridgeManager.isNotSimpleGearblock(link.getGearblock2(), event.getPlayer()) + ) { return; } BlockCoord processCoord = link.getGearblock1().getCoord(); Block processBlock = block.getWorld().getBlockAt(processCoord.getX(), processCoord.getY(), processCoord.getZ()); - if(_waitingBlocks.contains(processBlock)) + if (_waitingBlocks.contains(processBlock)) return; processBlock(processBlock, true); @@ -509,16 +501,15 @@ public class BridgeEventHandler { Gearblock gearblock = _storage.getGearblock(start); GearblockLink link = gearblock != null ? gearblock.getLink() : null; - if(link != null && - ( - link.getGearblock1().getCoord().equals(start) && link.getGearblock2().getCoord().equals(end) + if (link != null && + ( + link.getGearblock1().getCoord().equals(start) && link.getGearblock2().getCoord().equals(end) || link.getGearblock1().getCoord().equals(end) && link.getGearblock2().getCoord().equals(start) - ) ) - { + ) { return link; } return null; } -} \ No newline at end of file +} diff --git a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/engine/bridge/BridgeManager.java b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/engine/bridge/BridgeManager.java index 65eebb185..d60f55489 100644 --- a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/engine/bridge/BridgeManager.java +++ b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/engine/bridge/BridgeManager.java @@ -1,6 +1,5 @@ /** * @author Aleksey Terzi - * */ package com.aleksey.castlegates.engine.bridge; @@ -30,725 +29,724 @@ import com.aleksey.castlegates.utils.Helper; import com.aleksey.castlegates.utils.TimerWorker; public class BridgeManager { - public static final BlockFace[] faces = new BlockFace[] { - BlockFace.EAST, - BlockFace.WEST, - BlockFace.UP, - BlockFace.DOWN, - BlockFace.SOUTH, - BlockFace.NORTH - }; - - public enum CreateResult { NotCreated, AlreadyExist, Created } - public enum RemoveResult { NotExist, Removed, RemovedWithLink } - public enum SearchBridgeBlockResult { NotFound, Bridge, Gates } - public enum DoorAccess { None, Partial, Full } - - private StorageManager _storage; - private Map _pendingTimerBatches; - private TimerWorker _timerWorker; - - public void init(StorageManager storage) { - _storage = storage; - _pendingTimerBatches = new HashMap<>(); - - _timerWorker = new TimerWorker(this); - _timerWorker.startThread(); - } - - public void close() { - if(_timerWorker != null) { - _timerWorker.terminateThread(); - _timerWorker = null; - } - } - - public SearchBridgeBlockResult searchBridgeBlock(BlockCoord coord) { - int maxLen = CastleGates.getConfigManager().getMaxBridgeLength(); - - for(BlockFace face : faces) { - BlockCoord current = coord.clone(); - - for(int i = 0; i < maxLen; i++) { - current.increment(face); - - Gearblock gearblock = _storage.getGearblock(current); - - if(gearblock != null) { - if(isBridgeBlock(gearblock, face)) { - return face == BlockFace.UP || face == BlockFace.DOWN - ? SearchBridgeBlockResult.Gates - : SearchBridgeBlockResult.Bridge; - } - - break; - } - } - } - - return SearchBridgeBlockResult.NotFound; - } - - private static boolean isBridgeBlock(Gearblock gearblock, BlockFace face) { - GearblockLink link = gearblock.getLink(); - - if(link == null || link.isDrawn()) return false; - - BlockCoord coord1 = link.getGearblock1().getCoord(); - BlockCoord coord2 = link.getGearblock2().getCoord(); - - return switch(face) { - case EAST -> coord1.getX() < gearblock.getCoord().getX() || coord2.getX() < gearblock.getCoord().getX(); - case WEST -> coord1.getX() > gearblock.getCoord().getX() || coord2.getX() > gearblock.getCoord().getX(); - case UP -> coord1.getY() < gearblock.getCoord().getY() || coord2.getY() < gearblock.getCoord().getY(); - case DOWN -> coord1.getY() > gearblock.getCoord().getY() || coord2.getY() > gearblock.getCoord().getY(); - case SOUTH -> coord1.getZ() < gearblock.getCoord().getZ() || coord2.getZ() < gearblock.getCoord().getZ(); - case NORTH -> coord1.getZ() > gearblock.getCoord().getZ() || coord2.getZ() > gearblock.getCoord().getZ(); - default -> false; - }; - } - - public CreateResult createGear(Block block) { - BlockCoord location = new BlockCoord(block); - - if(!CastleGates.getConfigManager().isGearBlockType(block)) return CreateResult.NotCreated; - if(_storage.hasGearblock(location)) return CreateResult.AlreadyExist; - - _storage.addGearblock(location); - - return CreateResult.Created; - } - - public RemoveResult removeGear(BlockCoord location) { - Gearblock gear = _storage.getGearblock(location); - - if(gear == null) return RemoveResult.NotExist; - - RemoveResult result = RemoveResult.Removed; - - if(gear.getLockGearblock() != null) { - unlock(gear.getLockGearblock()); - } else { - unlock(gear); - } - - if(gear.getBrokenLink() != null) { - removeLink(gear.getBrokenLink()); - result = RemoveResult.RemovedWithLink; - } - else if (gear.getLink() != null) { - if(gear.getLink().isDrawn()) { - _storage.setLinkBroken(gear); - } else { - removeLink(gear.getLink()); - result = RemoveResult.RemovedWithLink; - } - } - _storage.removeGearblock(gear); + public static final BlockFace[] faces = new BlockFace[]{ + BlockFace.EAST, + BlockFace.WEST, + BlockFace.UP, + BlockFace.DOWN, + BlockFace.SOUTH, + BlockFace.NORTH + }; - return result; - } + public enum CreateResult {NotCreated, AlreadyExist, Created} - public void removeLink(GearblockLink link) { - if(link == null) - return; + public enum RemoveResult {NotExist, Removed, RemovedWithLink} - Gearblock gearblock1 = link.getGearblock1(); + public enum SearchBridgeBlockResult {NotFound, Bridge, Gates} - if(gearblock1 != null) { - if(gearblock1.getLockGearblock() != null) { - unlock(gearblock1.getLockGearblock()); - } else { - unlock(gearblock1); - } - } + public enum DoorAccess {None, Partial, Full} - Gearblock gearblock2 = link.getGearblock2(); + private StorageManager _storage; + private Map _pendingTimerBatches; + private TimerWorker _timerWorker; - if(gearblock2 != null) { - if(gearblock2.getLockGearblock() != null) { - unlock(gearblock2.getLockGearblock()); - } else { - unlock(gearblock2); - } - } + public void init(StorageManager storage) { + _storage = storage; + _pendingTimerBatches = new HashMap<>(); - _storage.removeLink(link); - } + _timerWorker = new TimerWorker(this); + _timerWorker.startThread(); + } - public boolean createLink(Gearblock gearblock1, Gearblock gearblock2, int distance) { - if(!removeGearblocksLinks(gearblock1, gearblock2, distance)) return false; + public void close() { + if (_timerWorker != null) { + _timerWorker.terminateThread(); + _timerWorker = null; + } + } - if(gearblock1.getLink() != null) return true; + public SearchBridgeBlockResult searchBridgeBlock(BlockCoord coord) { + int maxLen = CastleGates.getConfigManager().getMaxBridgeLength(); - _storage.addLink(gearblock1, gearblock2); + for (BlockFace face : faces) { + BlockCoord current = coord.clone(); - return true; - } + for (int i = 0; i < maxLen; i++) { + current.increment(face); - private boolean removeGearblocksLinks(Gearblock gearblock1, Gearblock gearblock2, int distance) { - if(gearblock1.getBrokenLink() != null && gearblock2.getBrokenLink() != null - || gearblock1.getBrokenLink() != null && distance != gearblock1.getBrokenLink().getBlocks().size() - || gearblock2.getBrokenLink() != null && distance != gearblock2.getBrokenLink().getBlocks().size() - ) - { - return false; - } + Gearblock gearblock = _storage.getGearblock(current); - GearblockLink link1 = gearblock1.getLink(); - GearblockLink link2 = gearblock2.getLink(); + if (gearblock != null) { + if (isBridgeBlock(gearblock, face)) { + return face == BlockFace.UP || face == BlockFace.DOWN + ? SearchBridgeBlockResult.Gates + : SearchBridgeBlockResult.Bridge; + } - if(link1 != null && link1.equals(link2)) return true; + break; + } + } + } - if(link1 != null && link1.isDrawn() || link2 != null && link2.isDrawn()) return false; + return SearchBridgeBlockResult.NotFound; + } - if(link1 != null) { - _storage.removeLink(link1); - } + private static boolean isBridgeBlock(Gearblock gearblock, BlockFace face) { + GearblockLink link = gearblock.getLink(); - if(link2 != null) { - _storage.removeLink(link2); - } + if (link == null || link.isDrawn()) return false; - return true; - } + BlockCoord coord1 = link.getGearblock1().getCoord(); + BlockCoord coord2 = link.getGearblock2().getCoord(); - public PowerResult processGearblock(World world, Gearblock gearblock, boolean isPowered, List players) { - if(gearblock.isPowered() == isPowered) - return PowerResult.Unchanged; + return switch (face) { + case EAST -> coord1.getX() < gearblock.getCoord().getX() || coord2.getX() < gearblock.getCoord().getX(); + case WEST -> coord1.getX() > gearblock.getCoord().getX() || coord2.getX() > gearblock.getCoord().getX(); + case UP -> coord1.getY() < gearblock.getCoord().getY() || coord2.getY() < gearblock.getCoord().getY(); + case DOWN -> coord1.getY() > gearblock.getCoord().getY() || coord2.getY() > gearblock.getCoord().getY(); + case SOUTH -> coord1.getZ() < gearblock.getCoord().getZ() || coord2.getZ() < gearblock.getCoord().getZ(); + case NORTH -> coord1.getZ() > gearblock.getCoord().getZ() || coord2.getZ() > gearblock.getCoord().getZ(); + default -> false; + }; + } - if(!isPowered) { - unlock(gearblock); - gearblock.setPowered(false); - addPendingTimerBatch(gearblock); - return PowerResult.Unpowered; - } + public CreateResult createGear(Block block) { + BlockCoord location = new BlockCoord(block); - if(System.currentTimeMillis() - gearblock.getLastSwitchTime() < CastleGates.getConfigManager().getSwitchTimeout()) { - return PowerResult.Unchanged; - } + if (!CastleGates.getConfigManager().isGearBlockType(block)) return CreateResult.NotCreated; + if (_storage.hasGearblock(location)) return CreateResult.AlreadyExist; - ICitadel citadel = getCitadel(world, gearblock, players); - DoorAccess doorAccess = canAccessDoors(world, gearblock, citadel); + _storage.addGearblock(location); - switch(doorAccess) { - case None: return PowerResult.NotInCitadelGroup; - case Partial: return PowerResult.DifferentCitadelGroup; - } + return CreateResult.Created; + } - if(extendDoorTimerBatch(gearblock)) - return PowerResult.Unchanged; + public RemoveResult removeGear(BlockCoord location) { + Gearblock gear = _storage.getGearblock(location); - if(!unlock(gearblock)) - return PowerResult.Locked; + if (gear == null) return RemoveResult.NotExist; - gearblock.setPowered(true); + RemoveResult result = RemoveResult.Removed; - if(gearblock.getLink() != null) - { - PowerResult result = !gearblock.getLink().isDrawn() - ? canDraw(world, gearblock.getLink(), citadel) - : canUndraw(world, gearblock.getLink(), players, citadel); + if (gear.getLockGearblock() != null) { + unlock(gear.getLockGearblock()); + } else { + unlock(gear); + } - if(result != PowerResult.Allowed) - return result; - } + if (gear.getBrokenLink() != null) { + removeLink(gear.getBrokenLink()); + result = RemoveResult.RemovedWithLink; + } else if (gear.getLink() != null) { + if (gear.getLink().isDrawn()) { + _storage.setLinkBroken(gear); + } else { + removeLink(gear.getLink()); + result = RemoveResult.RemovedWithLink; + } + } - PowerResult result = powerGear(world, gearblock, players, citadel); + _storage.removeGearblock(gear); - gearblock.setLastSwitchTime(); + return result; + } - return result; - } + public void removeLink(GearblockLink link) { + if (link == null) + return; - private void addPendingTimerBatch(Gearblock gearblock) { - TimerBatch timerBatch = _pendingTimerBatches.get(gearblock); + Gearblock gearblock1 = link.getGearblock1(); - if(timerBatch != null && timerBatch.resetRunTime() && !timerBatch.isInvalid()) { - _timerWorker.addBatch(timerBatch); - } - } + if (gearblock1 != null) { + if (gearblock1.getLockGearblock() != null) { + unlock(gearblock1.getLockGearblock()); + } else { + unlock(gearblock1); + } + } - private PowerResult powerGear(World world, Gearblock gearblock, List players, ICitadel citadel) { - HashSet gearblocks = new HashSet<>(); - gearblocks.add(gearblock); + Gearblock gearblock2 = link.getGearblock2(); - PowerResult transferResult = transferPower(world, gearblock, true, players, citadel, gearblocks); + if (gearblock2 != null) { + if (gearblock2.getLockGearblock() != null) { + unlock(gearblock2.getLockGearblock()); + } else { + unlock(gearblock2); + } + } - if(transferResult != PowerResult.Allowed) - return transferResult; + _storage.removeLink(link); + } - if(isLocked(gearblocks)) - return PowerResult.Locked; + public boolean createLink(Gearblock gearblock1, Gearblock gearblock2, int distance) { + if (!removeGearblocksLinks(gearblock1, gearblock2, distance)) return false; - TimerBatch timerBatch = gearblock.getTimer() != null ? new TimerBatch(world, gearblock, gearblocks) : null; - Boolean draw = powerGearList(world, gearblocks, timerBatch); + if (gearblock1.getLink() != null) return true; - lock(gearblock, gearblocks); + _storage.addLink(gearblock1, gearblock2); - if(draw == null) - return PowerResult.Unchanged; + return true; + } - PowerResult result = draw ? PowerResult.Drawn : PowerResult.Undrawn; + private boolean removeGearblocksLinks(Gearblock gearblock1, Gearblock gearblock2, int distance) { + if (gearblock1.getBrokenLink() != null && gearblock2.getBrokenLink() != null + || gearblock1.getBrokenLink() != null && distance != gearblock1.getBrokenLink().getBlocks().size() + || gearblock2.getBrokenLink() != null && distance != gearblock2.getBrokenLink().getBlocks().size() + ) { + return false; + } - if(timerBatch != null) { - timerBatch.setProcessStatus(result.status); + GearblockLink link1 = gearblock1.getLink(); + GearblockLink link2 = gearblock2.getLink(); - if(gearblock.getTimerMode() == TimerMode.DEFAULT) { - _timerWorker.addBatch(timerBatch); - } else { - _pendingTimerBatches.put(gearblock, timerBatch); - } - } + if (link1 != null && link1.equals(link2)) return true; - return result; - } + if (link1 != null && link1.isDrawn() || link2 != null && link2.isDrawn()) return false; - private Boolean powerGearList(World world, HashSet gearblocks, TimerBatch timerBatch) { - Boolean draw = null; - - for(Gearblock gearFromList : gearblocks) { - GearblockLink linkFromList = gearFromList.getLink(); - - if(linkFromList == null) continue; - - if(draw == null) { - draw = !linkFromList.isDrawn(); - } - - if(!linkFromList.isDrawn()) { - draw(world, linkFromList); - } else { - undraw(world, linkFromList); - } + if (link1 != null) { + _storage.removeLink(link1); + } - if(timerBatch != null) { - timerBatch.addLink(linkFromList); - } - } + if (link2 != null) { + _storage.removeLink(link2); + } - return draw; - } + return true; + } - private boolean unlock(Gearblock gearblock) { - if(gearblock.getLockGearblock() != null) { - return false; - } + public PowerResult processGearblock(World world, Gearblock gearblock, boolean isPowered, List players) { + if (gearblock.isPowered() == isPowered) + return PowerResult.Unchanged; - if(gearblock.getLockedGearblocks() == null) { - return true; - } + if (!isPowered) { + unlock(gearblock); + gearblock.setPowered(false); + addPendingTimerBatch(gearblock); + return PowerResult.Unpowered; + } - for(Gearblock lockedGearblock : gearblock.getLockedGearblocks()) { - lockedGearblock.setLockGearblock(null); - } + if (System.currentTimeMillis() - gearblock.getLastSwitchTime() < CastleGates.getConfigManager().getSwitchTimeout()) { + return PowerResult.Unchanged; + } - gearblock.setLockedGearblocks(null); - - return true; - } + ICitadel citadel = getCitadel(world, gearblock, players); + DoorAccess doorAccess = canAccessDoors(world, gearblock, citadel); - private void lock(Gearblock gearblock, HashSet gearblocks) { - List lockedGearblocks = new ArrayList<>(); + switch (doorAccess) { + case None: + return PowerResult.NotInCitadelGroup; + case Partial: + return PowerResult.DifferentCitadelGroup; + } - for(Gearblock lockedGearblock : gearblocks) { - GearblockLink link = lockedGearblock.getLink(); + if (extendDoorTimerBatch(gearblock)) + return PowerResult.Unchanged; - if(lockedGearblock != gearblock) { - if(link != null) { - lockedGearblocks.add(link.getGearblock1()); - lockedGearblocks.add(link.getGearblock2()); - - link.getGearblock1().setLockGearblock(gearblock); - link.getGearblock2().setLockGearblock(gearblock); - } else { - lockedGearblocks.add(lockedGearblock); - lockedGearblock.setLockGearblock(gearblock); - } - } else if(link != null) { - if(link.getGearblock1() != lockedGearblock) { - lockedGearblocks.add(link.getGearblock1()); - link.getGearblock1().setLockGearblock(gearblock); - } else { - lockedGearblocks.add(link.getGearblock2()); - link.getGearblock2().setLockGearblock(gearblock); - } - } - } - - gearblock.setLockedGearblocks(lockedGearblocks); - } - - private boolean isLocked(HashSet gearblocks) { - for(Gearblock lockedGearblock : gearblocks) { - if(lockedGearblock.getLockGearblock() != null) { - return true; - } - } - - return false; - } - - private boolean extendDoorTimerBatch(Gearblock gearblock) { - if(gearblock.getTimer() == null - || gearblock.getTimerMode() != TimerMode.DOOR - || gearblock.getTimerBatch() == null - || gearblock.getTimerBatch().getTimerMode() != TimerMode.DOOR - || gearblock.getTimerBatch().isInvalid() - ) - { - return false; - } - - TimerBatch originalTimerBatch = gearblock.getTimerBatch(); - boolean canLock = true; - - for(Gearblock current : originalTimerBatch.getAllGearblocks()) { - if(current.getLockedGearblocks() != null && current != originalTimerBatch.getGearblock() - || current.getLockGearblock() != null && current.getLockGearblock() != originalTimerBatch.getGearblock() - ) - { - canLock = false; - break; - } - } - - if(canLock) { - gearblock.setPowered(true); - - originalTimerBatch.invalidate(); - - unlock(originalTimerBatch.getGearblock()); - lock(gearblock, originalTimerBatch.getAllGearblocks()); - - _pendingTimerBatches.put(gearblock, originalTimerBatch.clone(gearblock)); - } - - return true; - } - - public boolean processTimerBatch(TimerBatch timerBatch) { - timerBatch.clearTimerBatchForAllGearblocks(); - - boolean result = false; - World world = timerBatch.getWorld(); - - for(TimerLink timerLink : timerBatch.getLinks()) { - GearblockLink link = timerLink.getLink(); - - if(link.isRemoved() || link.isBroken() || link.isDrawn() == timerLink.isMustDraw()) { - continue; - } - - if(!link.isDrawn()) { - draw(world, link); - } else { - undraw(world, link); - } - - result = true; - } - - return result; - } - - private PowerResult transferPower( - World world, - Gearblock gearblock, - boolean isPowered, - List players, - ICitadel citadel, - HashSet gearblocks - ) - { - ConfigManager configManager = CastleGates.getConfigManager(); - BlockCoord gearLoc = gearblock.getCoord(); - - for(int i = 0; i < faces.length && gearblocks.size() <= configManager.getMaxPowerTransfers(); i++) { - BlockFace face = faces[i]; - BlockCoord loc = new BlockCoord(world.getUID(), gearLoc.getX() + face.getModX(), gearLoc.getY() + face.getModY(), gearLoc.getZ() + face.getModZ()); - Gearblock to = _storage.getGearblock(loc); - - if(to == null || to.isPowered() == isPowered || gearblocks.contains(to)) continue; + if (!unlock(gearblock)) + return PowerResult.Locked; - DoorAccess access = canAccessDoors(world, to, citadel); + gearblock.setPowered(true); - if(access == DoorAccess.Partial) { - return PowerResult.DifferentCitadelGroup; - } else if(access == DoorAccess.None) { - continue; - } + if (gearblock.getLink() != null) { + PowerResult result = !gearblock.getLink().isDrawn() + ? canDraw(world, gearblock.getLink(), citadel) + : canUndraw(world, gearblock.getLink(), players, citadel); - if(isPowered) { - GearblockLink link = to.getLink(); + if (result != PowerResult.Allowed) + return result; + } - if(link != null) { - PowerResult result; + PowerResult result = powerGear(world, gearblock, players, citadel); - if(!link.isDrawn()) { - result = canDraw(world, link, citadel); - } else { - result = canUndraw(world, link, players, citadel); - } + gearblock.setLastSwitchTime(); - if(result != PowerResult.Allowed) return result; - } + return result; + } - gearblocks.add(to); - } + private void addPendingTimerBatch(Gearblock gearblock) { + TimerBatch timerBatch = _pendingTimerBatches.get(gearblock); - PowerResult result = transferPower(world, to, isPowered, players, citadel, gearblocks); + if (timerBatch != null && timerBatch.resetRunTime() && !timerBatch.isInvalid()) { + _timerWorker.addBatch(timerBatch); + } + } - if(result != PowerResult.Allowed) return result; - } + private PowerResult powerGear(World world, Gearblock gearblock, List players, ICitadel citadel) { + HashSet gearblocks = new HashSet<>(); + gearblocks.add(gearblock); - return PowerResult.Allowed; - } + PowerResult transferResult = transferPower(world, gearblock, true, players, citadel, gearblocks); - private BlockFace getLinkFace(GearblockLink link) { - BlockCoord loc1 = link.getGearblock1().getCoord(); - BlockCoord loc2 = link.getGearblock2().getCoord(); + if (transferResult != PowerResult.Allowed) + return transferResult; - if(loc1.getX() != loc2.getX()) { - return loc1.getX() < loc2.getX() ? BlockFace.EAST: BlockFace.WEST; - } - else if(loc1.getY() != loc2.getY()) { - return loc1.getY() < loc2.getY() ? BlockFace.UP: BlockFace.DOWN; - } - else if(loc1.getZ() != loc2.getZ()) { - return loc1.getZ() < loc2.getZ() ? BlockFace.SOUTH: BlockFace.NORTH; - } + if (isLocked(gearblocks)) + return PowerResult.Locked; - return null; - } + TimerBatch timerBatch = gearblock.getTimer() != null ? new TimerBatch(world, gearblock, gearblocks) : null; + Boolean draw = powerGearList(world, gearblocks, timerBatch); - private PowerResult canDraw(World world, GearblockLink link, ICitadel citadel) { - ConfigManager configManager = CastleGates.getConfigManager(); + lock(gearblock, gearblocks); - BlockFace blockFace = getLinkFace(link); - if (blockFace == null) - return PowerResult.Locked; + if (draw == null) + return PowerResult.Unchanged; - BlockCoord loc1 = link.getGearblock1().getCoord(); - BlockCoord loc2 = link.getGearblock2().getCoord(); + PowerResult result = draw ? PowerResult.Drawn : PowerResult.Undrawn; - int x1 = loc1.getX(), y1 = loc1.getY(), z1 = loc1.getZ(); - int x2 = loc2.getX(), y2 = loc2.getY(), z2 = loc2.getZ(); + if (timerBatch != null) { + timerBatch.setProcessStatus(result.status); - x1 += blockFace.getModX(); - y1 += blockFace.getModY(); - z1 += blockFace.getModZ(); + if (gearblock.getTimerMode() == TimerMode.DEFAULT) { + _timerWorker.addBatch(timerBatch); + } else { + _pendingTimerBatches.put(gearblock, timerBatch); + } + } - while(x1 != x2 || y1 != y2 || z1 != z2) { - Block block = world.getBlockAt(x1, y1, z1); + return result; + } - if(!configManager.isBridgeMaterial(block)) return new PowerResult(PowerResult.Status.Broken, block); + private Boolean powerGearList(World world, HashSet gearblocks, TimerBatch timerBatch) { + Boolean draw = null; + + for (Gearblock gearFromList : gearblocks) { + GearblockLink linkFromList = gearFromList.getLink(); + + if (linkFromList == null) continue; + + if (draw == null) { + draw = !linkFromList.isDrawn(); + } - if(_storage.hasGearblock(new BlockCoord(block))) return new PowerResult(PowerResult.Status.CannotDrawGear, block); + if (!linkFromList.isDrawn()) { + draw(world, linkFromList); + } else { + undraw(world, linkFromList); + } - if(!citadel.canAccessDoors(block.getLocation())) return PowerResult.DifferentCitadelGroup; + if (timerBatch != null) { + timerBatch.addLink(linkFromList); + } + } - x1 += blockFace.getModX(); - y1 += blockFace.getModY(); - z1 += blockFace.getModZ(); - } + return draw; + } - return PowerResult.Allowed; - } + private boolean unlock(Gearblock gearblock) { + if (gearblock.getLockGearblock() != null) { + return false; + } - private void draw(World world, GearblockLink link) { - BlockFace blockFace = getLinkFace(link); - if (blockFace == null) - return; + if (gearblock.getLockedGearblocks() == null) { + return true; + } - BlockCoord loc1 = link.getGearblock1().getCoord(); - BlockCoord loc2 = link.getGearblock2().getCoord(); + for (Gearblock lockedGearblock : gearblock.getLockedGearblocks()) { + lockedGearblock.setLockGearblock(null); + } - int x1 = loc1.getX(), y1 = loc1.getY(), z1 = loc1.getZ(); - int x2 = loc2.getX(), y2 = loc2.getY(), z2 = loc2.getZ(); + gearblock.setLockedGearblocks(null); - x1 += blockFace.getModX(); - y1 += blockFace.getModY(); - z1 += blockFace.getModZ(); + return true; + } - ICitadelManager citadelManager = CastleGates.getCitadelManager(); - ArrayList blockStates = new ArrayList<>(); - ArrayList locations = new ArrayList<>(); - ArrayList states = new ArrayList<>(); + private void lock(Gearblock gearblock, HashSet gearblocks) { + List lockedGearblocks = new ArrayList<>(); - while(x1 != x2 || y1 != y2 || z1 != z2) { - Block block = world.getBlockAt(x1, y1, z1); - Location location = block.getLocation(); + for (Gearblock lockedGearblock : gearblocks) { + GearblockLink link = lockedGearblock.getLink(); - locations.add(location); + if (lockedGearblock != gearblock) { + if (link != null) { + lockedGearblocks.add(link.getGearblock1()); + lockedGearblocks.add(link.getGearblock2()); + + link.getGearblock1().setLockGearblock(gearblock); + link.getGearblock2().setLockGearblock(gearblock); + } else { + lockedGearblocks.add(lockedGearblock); + lockedGearblock.setLockGearblock(gearblock); + } + } else if (link != null) { + if (link.getGearblock1() != lockedGearblock) { + lockedGearblocks.add(link.getGearblock1()); + link.getGearblock1().setLockGearblock(gearblock); + } else { + lockedGearblocks.add(link.getGearblock2()); + link.getGearblock2().setLockGearblock(gearblock); + } + } + } + + gearblock.setLockedGearblocks(lockedGearblocks); + } + + private boolean isLocked(HashSet gearblocks) { + for (Gearblock lockedGearblock : gearblocks) { + if (lockedGearblock.getLockGearblock() != null) { + return true; + } + } + + return false; + } + + private boolean extendDoorTimerBatch(Gearblock gearblock) { + if (gearblock.getTimer() == null + || gearblock.getTimerMode() != TimerMode.DOOR + || gearblock.getTimerBatch() == null + || gearblock.getTimerBatch().getTimerMode() != TimerMode.DOOR + || gearblock.getTimerBatch().isInvalid() + ) { + return false; + } + + TimerBatch originalTimerBatch = gearblock.getTimerBatch(); + boolean canLock = true; + + for (Gearblock current : originalTimerBatch.getAllGearblocks()) { + if (current.getLockedGearblocks() != null && current != originalTimerBatch.getGearblock() + || current.getLockGearblock() != null && current.getLockGearblock() != originalTimerBatch.getGearblock() + ) { + canLock = false; + break; + } + } + + if (canLock) { + gearblock.setPowered(true); + + originalTimerBatch.invalidate(); + + unlock(originalTimerBatch.getGearblock()); + lock(gearblock, originalTimerBatch.getAllGearblocks()); + + _pendingTimerBatches.put(gearblock, originalTimerBatch.clone(gearblock)); + } + + return true; + } + + public boolean processTimerBatch(TimerBatch timerBatch) { + timerBatch.clearTimerBatchForAllGearblocks(); + + boolean result = false; + World world = timerBatch.getWorld(); + + for (TimerLink timerLink : timerBatch.getLinks()) { + GearblockLink link = timerLink.getLink(); + + if (link.isRemoved() || link.isBroken() || link.isDrawn() == timerLink.isMustDraw()) { + continue; + } + + if (!link.isDrawn()) { + draw(world, link); + } else { + undraw(world, link); + } + + result = true; + } + + return result; + } + + private PowerResult transferPower( + World world, + Gearblock gearblock, + boolean isPowered, + List players, + ICitadel citadel, + HashSet gearblocks + ) { + ConfigManager configManager = CastleGates.getConfigManager(); + BlockCoord gearLoc = gearblock.getCoord(); + + for (int i = 0; i < faces.length && gearblocks.size() <= configManager.getMaxPowerTransfers(); i++) { + BlockFace face = faces[i]; + BlockCoord loc = new BlockCoord(world.getUID(), gearLoc.getX() + face.getModX(), gearLoc.getY() + face.getModY(), gearLoc.getZ() + face.getModZ()); + Gearblock to = _storage.getGearblock(loc); + + if (to == null || to.isPowered() == isPowered || gearblocks.contains(to)) continue; - ReinforcementInfo reinforcement = citadelManager.removeReinforcement(location); - BlockState blockState = new BlockState(block, reinforcement); + DoorAccess access = canAccessDoors(world, to, citadel); - blockStates.add(blockState); + if (access == DoorAccess.Partial) { + return PowerResult.DifferentCitadelGroup; + } else if (access == DoorAccess.None) { + continue; + } - org.bukkit.block.BlockState state = block.getState(); + if (isPowered) { + GearblockLink link = to.getLink(); - state.setType(Material.AIR); - states.add(state); + if (link != null) { + PowerResult result; - x1 += blockFace.getModX(); - y1 += blockFace.getModY(); - z1 += blockFace.getModZ(); - } + if (!link.isDrawn()) { + result = canDraw(world, link, citadel); + } else { + result = canUndraw(world, link, players, citadel); + } - // Call our event before committing world changes. - Bukkit.getPluginManager().callEvent(new CastleGatesDrawGateEvent(locations)); + if (result != PowerResult.Allowed) return result; + } - // commit world changes - for (org.bukkit.block.BlockState state : states) { - state.update(true, true); - } - - _storage.setLinkBlocks(link, blockStates); - } + gearblocks.add(to); + } - private PowerResult canUndraw(World world, GearblockLink link, List players, ICitadel citadel) { - BlockFace blockFace = getLinkFace(link); - if (blockFace == null) - return PowerResult.Locked; + PowerResult result = transferPower(world, to, isPowered, players, citadel, gearblocks); - BlockCoord loc1 = link.getGearblock1().getCoord(); - BlockCoord loc2 = link.getGearblock2().getCoord(); + if (result != PowerResult.Allowed) return result; + } - int x1 = loc1.getX(), y1 = loc1.getY(), z1 = loc1.getZ(); - int x2 = loc2.getX(), y2 = loc2.getY(), z2 = loc2.getZ(); + return PowerResult.Allowed; + } - x1 += blockFace.getModX(); - y1 += blockFace.getModY(); - z1 += blockFace.getModZ(); + private BlockFace getLinkFace(GearblockLink link) { + BlockCoord loc1 = link.getGearblock1().getCoord(); + BlockCoord loc2 = link.getGearblock2().getCoord(); - List bridgeBlocks = new ArrayList<>(); + if (loc1.getX() != loc2.getX()) { + return loc1.getX() < loc2.getX() ? BlockFace.EAST : BlockFace.WEST; + } else if (loc1.getY() != loc2.getY()) { + return loc1.getY() < loc2.getY() ? BlockFace.UP : BlockFace.DOWN; + } else if (loc1.getZ() != loc2.getZ()) { + return loc1.getZ() < loc2.getZ() ? BlockFace.SOUTH : BlockFace.NORTH; + } - while(x1 != x2 || y1 != y2 || z1 != z2) { - Block block = world.getBlockAt(x1, y1, z1); + return null; + } - if(!Helper.isEmptyBlock(block)) - return new PowerResult(PowerResult.Status.Blocked, block); + private PowerResult canDraw(World world, GearblockLink link, ICitadel citadel) { + ConfigManager configManager = CastleGates.getConfigManager(); - bridgeBlocks.add(block); + BlockFace blockFace = getLinkFace(link); + if (blockFace == null) + return PowerResult.Locked; - x1 += blockFace.getModX(); - y1 += blockFace.getModY(); - z1 += blockFace.getModZ(); - } + BlockCoord loc1 = link.getGearblock1().getCoord(); + BlockCoord loc2 = link.getGearblock2().getCoord(); - return CastleGates.getBastionManager().canUndraw(players, bridgeBlocks, citadel) - ? PowerResult.Allowed - : PowerResult.BastionBlocked; - } + int x1 = loc1.getX(), y1 = loc1.getY(), z1 = loc1.getZ(); + int x2 = loc2.getX(), y2 = loc2.getY(), z2 = loc2.getZ(); - private void undraw(World world, GearblockLink link) { - BlockFace blockFace = getLinkFace(link); + x1 += blockFace.getModX(); + y1 += blockFace.getModY(); + z1 += blockFace.getModZ(); - if (blockFace == null) - return; + while (x1 != x2 || y1 != y2 || z1 != z2) { + Block block = world.getBlockAt(x1, y1, z1); - BlockCoord loc1 = link.getGearblock1().getCoord(); - BlockCoord loc2 = link.getGearblock2().getCoord(); + if (!configManager.isBridgeMaterial(block)) return new PowerResult(PowerResult.Status.Broken, block); - int x1 = loc1.getX(), y1 = loc1.getY(), z1 = loc1.getZ(); - int x2 = loc2.getX(), y2 = loc2.getY(), z2 = loc2.getZ(); + if (_storage.hasGearblock(new BlockCoord(block))) + return new PowerResult(PowerResult.Status.CannotDrawGear, block); - x1 += blockFace.getModX(); - y1 += blockFace.getModY(); - z1 += blockFace.getModZ(); + if (!citadel.canAccessDoors(block.getLocation())) return PowerResult.DifferentCitadelGroup; - ICitadelManager citadelManager = CastleGates.getCitadelManager(); - List linkBlocks = link.getBlocks(); - List worldBlocks = new ArrayList<>(); - ArrayList locations = new ArrayList<>(); + x1 += blockFace.getModX(); + y1 += blockFace.getModY(); + z1 += blockFace.getModZ(); + } - while(x1 != x2 || y1 != y2 || z1 != z2) { - Block block = world.getBlockAt(x1, y1, z1); - worldBlocks.add(block); + return PowerResult.Allowed; + } - Location location = block.getLocation(); - locations.add(location); + private void draw(World world, GearblockLink link) { + BlockFace blockFace = getLinkFace(link); + if (blockFace == null) + return; - x1 += blockFace.getModX(); - y1 += blockFace.getModY(); - z1 += blockFace.getModZ(); - } + BlockCoord loc1 = link.getGearblock1().getCoord(); + BlockCoord loc2 = link.getGearblock2().getCoord(); - Bukkit.getPluginManager().callEvent(new CastleGatesUndrawGateEvent(locations)); + int x1 = loc1.getX(), y1 = loc1.getY(), z1 = loc1.getZ(); + int x2 = loc2.getX(), y2 = loc2.getY(), z2 = loc2.getZ(); - for (int i = 0; i < linkBlocks.size(); i++) { - BlockState blockState = linkBlocks.get(i); - BlockData blockData = Bukkit.createBlockData(blockState.getBlockData()); - Block block = worldBlocks.get(i); + x1 += blockFace.getModX(); + y1 += blockFace.getModY(); + z1 += blockFace.getModZ(); - block.setBlockData(blockData, false); + ICitadelManager citadelManager = CastleGates.getCitadelManager(); + ArrayList blockStates = new ArrayList<>(); + ArrayList locations = new ArrayList<>(); + ArrayList states = new ArrayList<>(); - citadelManager.createReinforcement(blockState.getReinforcement(), block.getLocation()); - } + while (x1 != x2 || y1 != y2 || z1 != z2) { + Block block = world.getBlockAt(x1, y1, z1); + Location location = block.getLocation(); - // Apply physics - for (Block block : worldBlocks) - block.setBlockData(block.getBlockData(), true); + locations.add(location); - _storage.setLinkBlocks(link, null); - } + ReinforcementInfo reinforcement = citadelManager.removeReinforcement(location); + BlockState blockState = new BlockState(block, reinforcement); - private static DoorAccess canAccessDoors(World world, Gearblock gearblock, ICitadel citadel) { - boolean hasAccess = citadel.canAccessDoors(getLocation(world, gearblock.getCoord())); + blockStates.add(blockState); - if(!hasAccess) return DoorAccess.None; + org.bukkit.block.BlockState state = block.getState(); - GearblockLink link = gearblock.getLink(); + state.setType(Material.AIR); + states.add(state); - if(link == null) return DoorAccess.Full; + x1 += blockFace.getModX(); + y1 += blockFace.getModY(); + z1 += blockFace.getModZ(); + } - Gearblock secondGearblock = link.getGearblock1() == gearblock - ? link.getGearblock2() - : link.getGearblock1(); + // Call our event before committing world changes. + Bukkit.getPluginManager().callEvent(new CastleGatesDrawGateEvent(locations)); - return citadel.canAccessDoors(getLocation(world, secondGearblock.getCoord())) ? DoorAccess.Full : DoorAccess.Partial; - } + // commit world changes + for (org.bukkit.block.BlockState state : states) { + state.update(true, true); + } - private static Location getLocation(World world, BlockCoord coord) { - return new Location(world, coord.getX(), coord.getY(), coord.getZ()); - } + _storage.setLinkBlocks(link, blockStates); + } - private static ICitadel getCitadel(World world, Gearblock gearblock, List players) { - BlockCoord coord = gearblock.getCoord(); - Location location = new Location(world, coord.getX(), coord.getY(), coord.getZ()); + private PowerResult canUndraw(World world, GearblockLink link, List players, ICitadel citadel) { + BlockFace blockFace = getLinkFace(link); + if (blockFace == null) + return PowerResult.Locked; - return CastleGates.getCitadelManager().getCitadel(players, location); - } + BlockCoord loc1 = link.getGearblock1().getCoord(); + BlockCoord loc2 = link.getGearblock2().getCoord(); - public boolean isNotSimpleGearblock(Gearblock gearblock, Player player) { - World world = player.getWorld(); - BlockCoord coord = gearblock.getCoord(); - List players = new ArrayList<>(); + int x1 = loc1.getX(), y1 = loc1.getY(), z1 = loc1.getZ(); + int x2 = loc2.getX(), y2 = loc2.getY(), z2 = loc2.getZ(); - players.add(player); + x1 += blockFace.getModX(); + y1 += blockFace.getModY(); + z1 += blockFace.getModZ(); - ICitadel citadel = getCitadel(world, gearblock, players); + List bridgeBlocks = new ArrayList<>(); - return hasAccessibleGearblock(world, coord.getForward(), players, citadel) - || hasAccessibleGearblock(world, coord.getBackward(), players, citadel) - || hasAccessibleGearblock(world, coord.getRight(), players, citadel) - || hasAccessibleGearblock(world, coord.getLeft(), players, citadel) - || hasAccessibleGearblock(world, coord.getTop(), players, citadel) - || hasAccessibleGearblock(world, coord.getBottom(), players, citadel); - } + while (x1 != x2 || y1 != y2 || z1 != z2) { + Block block = world.getBlockAt(x1, y1, z1); - private boolean hasAccessibleGearblock(World world, BlockCoord coord, List players, ICitadel originalCitadel) { - Gearblock gearblock = _storage.getGearblock(coord); - if(gearblock == null) - return false; + if (!Helper.isEmptyBlock(block)) + return new PowerResult(PowerResult.Status.Blocked, block); - ICitadel citadel = getCitadel(world, gearblock, players); + bridgeBlocks.add(block); - return originalCitadel.getGroupName() == null - ? citadel.getGroupName() == null - : originalCitadel.getGroupName().equalsIgnoreCase(citadel.getGroupName()); - } -} \ No newline at end of file + x1 += blockFace.getModX(); + y1 += blockFace.getModY(); + z1 += blockFace.getModZ(); + } + + return CastleGates.getBastionManager().canUndraw(players, bridgeBlocks, citadel) + ? PowerResult.Allowed + : PowerResult.BastionBlocked; + } + + private void undraw(World world, GearblockLink link) { + BlockFace blockFace = getLinkFace(link); + + if (blockFace == null) + return; + + BlockCoord loc1 = link.getGearblock1().getCoord(); + BlockCoord loc2 = link.getGearblock2().getCoord(); + + int x1 = loc1.getX(), y1 = loc1.getY(), z1 = loc1.getZ(); + int x2 = loc2.getX(), y2 = loc2.getY(), z2 = loc2.getZ(); + + x1 += blockFace.getModX(); + y1 += blockFace.getModY(); + z1 += blockFace.getModZ(); + + ICitadelManager citadelManager = CastleGates.getCitadelManager(); + List linkBlocks = link.getBlocks(); + List worldBlocks = new ArrayList<>(); + ArrayList locations = new ArrayList<>(); + + while (x1 != x2 || y1 != y2 || z1 != z2) { + Block block = world.getBlockAt(x1, y1, z1); + worldBlocks.add(block); + + Location location = block.getLocation(); + locations.add(location); + + x1 += blockFace.getModX(); + y1 += blockFace.getModY(); + z1 += blockFace.getModZ(); + } + + Bukkit.getPluginManager().callEvent(new CastleGatesUndrawGateEvent(locations)); + + for (int i = 0; i < linkBlocks.size(); i++) { + BlockState blockState = linkBlocks.get(i); + BlockData blockData = Bukkit.createBlockData(blockState.getBlockData()); + Block block = worldBlocks.get(i); + + block.setBlockData(blockData, false); + + citadelManager.createReinforcement(blockState.getReinforcement(), block.getLocation()); + } + + // Apply physics + for (Block block : worldBlocks) + block.setBlockData(block.getBlockData(), true); + + _storage.setLinkBlocks(link, null); + } + + private static DoorAccess canAccessDoors(World world, Gearblock gearblock, ICitadel citadel) { + boolean hasAccess = citadel.canAccessDoors(getLocation(world, gearblock.getCoord())); + + if (!hasAccess) return DoorAccess.None; + + GearblockLink link = gearblock.getLink(); + + if (link == null) return DoorAccess.Full; + + Gearblock secondGearblock = link.getGearblock1() == gearblock + ? link.getGearblock2() + : link.getGearblock1(); + + return citadel.canAccessDoors(getLocation(world, secondGearblock.getCoord())) ? DoorAccess.Full : DoorAccess.Partial; + } + + private static Location getLocation(World world, BlockCoord coord) { + return new Location(world, coord.getX(), coord.getY(), coord.getZ()); + } + + private static ICitadel getCitadel(World world, Gearblock gearblock, List players) { + BlockCoord coord = gearblock.getCoord(); + Location location = new Location(world, coord.getX(), coord.getY(), coord.getZ()); + + return CastleGates.getCitadelManager().getCitadel(players, location); + } + + public boolean isNotSimpleGearblock(Gearblock gearblock, Player player) { + World world = player.getWorld(); + BlockCoord coord = gearblock.getCoord(); + List players = new ArrayList<>(); + + players.add(player); + + ICitadel citadel = getCitadel(world, gearblock, players); + + return hasAccessibleGearblock(world, coord.getForward(), players, citadel) + || hasAccessibleGearblock(world, coord.getBackward(), players, citadel) + || hasAccessibleGearblock(world, coord.getRight(), players, citadel) + || hasAccessibleGearblock(world, coord.getLeft(), players, citadel) + || hasAccessibleGearblock(world, coord.getTop(), players, citadel) + || hasAccessibleGearblock(world, coord.getBottom(), players, citadel); + } + + private boolean hasAccessibleGearblock(World world, BlockCoord coord, List players, ICitadel originalCitadel) { + Gearblock gearblock = _storage.getGearblock(coord); + if (gearblock == null) + return false; + + ICitadel citadel = getCitadel(world, gearblock, players); + + return originalCitadel.getGroupName() == null + ? citadel.getGroupName() == null + : originalCitadel.getGroupName().equalsIgnoreCase(citadel.getGroupName()); + } +} diff --git a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/events/CastleGatesDrawGateEvent.java b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/events/CastleGatesDrawGateEvent.java index 3a991621d..75c1eb2f6 100644 --- a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/events/CastleGatesDrawGateEvent.java +++ b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/events/CastleGatesDrawGateEvent.java @@ -8,29 +8,29 @@ import org.bukkit.event.HandlerList; /** * Called after the Gear is fully drawn (withdrawn). Lets other plugins update themselves based on the blocks changed. - * - * @author ProgrammerDan * + * @author ProgrammerDan */ public class CastleGatesDrawGateEvent extends Event { - private static final HandlerList _handlers = new HandlerList(); - - private final List _impacted; - - public CastleGatesDrawGateEvent(final List impacted) { - this._impacted = impacted; - } - public List getImpacted() { - return this._impacted; - } + private static final HandlerList _handlers = new HandlerList(); - @Override - public HandlerList getHandlers() { - return CastleGatesDrawGateEvent._handlers; - } + private final List _impacted; - public static HandlerList getHandlerList() { - return _handlers; - } + public CastleGatesDrawGateEvent(final List impacted) { + this._impacted = impacted; + } + + public List getImpacted() { + return this._impacted; + } + + @Override + public HandlerList getHandlers() { + return CastleGatesDrawGateEvent._handlers; + } + + public static HandlerList getHandlerList() { + return _handlers; + } } diff --git a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/events/CastleGatesUndrawGateEvent.java b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/events/CastleGatesUndrawGateEvent.java index fa8a19198..1b7f3dfb7 100644 --- a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/events/CastleGatesUndrawGateEvent.java +++ b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/events/CastleGatesUndrawGateEvent.java @@ -8,29 +8,29 @@ import org.bukkit.event.HandlerList; /** * Called after the Gear is fully drawn (withdrawn). Lets other plugins update themselves based on the blocks changed. - * - * @author ProgrammerDan * + * @author ProgrammerDan */ public class CastleGatesUndrawGateEvent extends Event { - private static final HandlerList _handlers = new HandlerList(); - - private final List _impacted; - - public CastleGatesUndrawGateEvent(final List impacted) { - this._impacted = impacted; - } - - public List getImpacted() { - return this._impacted; - } - - @Override - public HandlerList getHandlers() { - return CastleGatesUndrawGateEvent._handlers; - } - public static HandlerList getHandlerList() { - return _handlers; - } + private static final HandlerList _handlers = new HandlerList(); + + private final List _impacted; + + public CastleGatesUndrawGateEvent(final List impacted) { + this._impacted = impacted; + } + + public List getImpacted() { + return this._impacted; + } + + @Override + public HandlerList getHandlers() { + return CastleGatesUndrawGateEvent._handlers; + } + + public static HandlerList getHandlerList() { + return _handlers; + } } diff --git a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/events/package-info.java b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/events/package-info.java index ac8b1bf76..6c5e0c82d 100644 --- a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/events/package-info.java +++ b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/events/package-info.java @@ -1,8 +1,10 @@ /** * Augments for CastleGates to broadcast gate open / close events and pre-events. + * + * @author ProgrammerDan */ /** * @author ProgrammerDan * */ -package com.aleksey.castlegates.events; \ No newline at end of file +package com.aleksey.castlegates.events; diff --git a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/listener/BlockListener.java b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/listener/BlockListener.java index d495f0f78..aed964869 100644 --- a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/listener/BlockListener.java +++ b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/listener/BlockListener.java @@ -1,6 +1,5 @@ /** * @author Aleksey Terzi - * */ package com.aleksey.castlegates.listener; @@ -17,28 +16,29 @@ import org.bukkit.event.block.BlockRedstoneEvent; import com.aleksey.castlegates.CastleGates; public class BlockListener implements Listener { - @EventHandler(priority=EventPriority.NORMAL, ignoreCancelled=true) - public void onBlockBreak(BlockBreakEvent event) { - CastleGates.getManager().handleBlockBreak(event); - } - @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled=true) + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void onBlockBreak(BlockBreakEvent event) { + CastleGates.getManager().handleBlockBreak(event); + } + + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onBlockRedstone(BlockRedstoneEvent event) { - CastleGates.getManager().handleBlockRedstone(event); - } + CastleGates.getManager().handleBlockRedstone(event); + } - @EventHandler(priority=EventPriority.NORMAL, ignoreCancelled=true) - public void onBlockPhysics(BlockPhysicsEvent event) { - CastleGates.getManager().handleBlockPhysics(event); - } + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void onBlockPhysics(BlockPhysicsEvent event) { + CastleGates.getManager().handleBlockPhysics(event); + } - @EventHandler(priority=EventPriority.HIGH, ignoreCancelled=true) - public void onBlockPistonExtend(BlockPistonExtendEvent event) { - CastleGates.getManager().handlePistonEvent(event.getBlocks()); - } + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void onBlockPistonExtend(BlockPistonExtendEvent event) { + CastleGates.getManager().handlePistonEvent(event.getBlocks()); + } - @EventHandler(priority=EventPriority.HIGH, ignoreCancelled=true) - public void onBlockPistonRetract(BlockPistonRetractEvent event) { - CastleGates.getManager().handlePistonEvent(event.getBlocks()); - } + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void onBlockPistonRetract(BlockPistonRetractEvent event) { + CastleGates.getManager().handlePistonEvent(event.getBlocks()); + } } diff --git a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/listener/EntityListener.java b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/listener/EntityListener.java index 796f15c9b..b41832d88 100644 --- a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/listener/EntityListener.java +++ b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/listener/EntityListener.java @@ -1,6 +1,5 @@ /** * @author Aleksey Terzi - * */ package com.aleksey.castlegates.listener; @@ -17,30 +16,31 @@ import org.bukkit.event.player.PlayerQuitEvent; import com.aleksey.castlegates.CastleGates; public class EntityListener implements Listener { + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onPlayerJoin(PlayerJoinEvent event) { - CastleGates.getManager().handlePlayerJoin(event); + CastleGates.getManager().handlePlayerJoin(event); } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onPlayerQuit(PlayerQuitEvent event) { - CastleGates.getManager().handlePlayerQuit(event); + CastleGates.getManager().handlePlayerQuit(event); } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onPlayerInteract(PlayerInteractEvent event) { - if(event.getClickedBlock() != null) { - CastleGates.getManager().handleBlockClicked(event); - } + if (event.getClickedBlock() != null) { + CastleGates.getManager().handleBlockClicked(event); + } } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) - public void onEntityExplode(EntityExplodeEvent event) { - CastleGates.getManager().handleEntityExplode(event); - } + public void onEntityExplode(EntityExplodeEvent event) { + CastleGates.getManager().handleEntityExplode(event); + } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) - public void onEntityChangeBlock(EntityChangeBlockEvent event) { - CastleGates.getManager().handleEntityChangeBlock(event); - } + public void onEntityChangeBlock(EntityChangeBlockEvent event) { + CastleGates.getManager().handleEntityChangeBlock(event); + } } diff --git a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/plugins/bastion/BastionManager.java b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/plugins/bastion/BastionManager.java index a7fcae2ff..34a626eca 100644 --- a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/plugins/bastion/BastionManager.java +++ b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/plugins/bastion/BastionManager.java @@ -1,6 +1,5 @@ /** * @author Aleksey Terzi - * */ package com.aleksey.castlegates.plugins.bastion; @@ -27,77 +26,78 @@ import vg.civcraft.mc.namelayer.GroupManager.PlayerType; import vg.civcraft.mc.namelayer.permission.PermissionType; public class BastionManager implements IBastionManager { - private static final String PERMISSION_UNDRAW = "BASTION_BRIDGE_UNDRAW"; - private BastionBlockManager _blockManager; + private static final String PERMISSION_UNDRAW = "BASTION_BRIDGE_UNDRAW"; - public void init() { - _blockManager = Bastion.getBastionManager(); + private BastionBlockManager _blockManager; - LinkedList memberAndAbove = new LinkedList<>(); - memberAndAbove.add(PlayerType.MEMBERS); - memberAndAbove.add(PlayerType.MODS); - memberAndAbove.add(PlayerType.ADMINS); - memberAndAbove.add(PlayerType.OWNER); - PermissionType.registerPermission(PERMISSION_UNDRAW, memberAndAbove, "Allows undrawing bridges/gates above bastions"); - } + public void init() { + _blockManager = Bastion.getBastionManager(); - public boolean canUndraw(List players, List bridgeBlocks, ICitadel citadel) { - if (players != null) { - for(Player player : players) { - if(player.hasPermission("Bastion.bypass")) { - return true; - } - } - } + LinkedList memberAndAbove = new LinkedList<>(); + memberAndAbove.add(PlayerType.MEMBERS); + memberAndAbove.add(PlayerType.MODS); + memberAndAbove.add(PlayerType.ADMINS); + memberAndAbove.add(PlayerType.OWNER); + PermissionType.registerPermission(PERMISSION_UNDRAW, memberAndAbove, "Allows undrawing bridges/gates above bastions"); + } - for(Block block : bridgeBlocks) { - if(!hasBastionAccess(players, block, citadel)) { - return false; - } - } + public boolean canUndraw(List players, List bridgeBlocks, ICitadel citadel) { + if (players != null) { + for (Player player : players) { + if (player.hasPermission("Bastion.bypass")) { + return true; + } + } + } - return true; - } + for (Block block : bridgeBlocks) { + if (!hasBastionAccess(players, block, citadel)) { + return false; + } + } - private boolean hasBastionAccess(List players, Block block, ICitadel citadel) { - PermissionType perm = PermissionType.getPermission(PERMISSION_UNDRAW); - Location loc = block.getLocation(); - Set bastions = _blockManager.getBlockingBastions(loc); + return true; + } - if (bastions == null) - return true; + private boolean hasBastionAccess(List players, Block block, ICitadel citadel) { + PermissionType perm = PermissionType.getPermission(PERMISSION_UNDRAW); + Location loc = block.getLocation(); + Set bastions = _blockManager.getBlockingBastions(loc); - ReinforcementManager reinManager = Citadel.getInstance().getReinforcementManager(); + if (bastions == null) + return true; - for(BastionBlock bastion : bastions) { - if(bastion.getType().isOnlyDirectDestruction() || !bastion.inField(loc)) - continue; + ReinforcementManager reinManager = Citadel.getInstance().getReinforcementManager(); - Reinforcement rein = reinManager.getReinforcement(bastion.getLocation()); + for (BastionBlock bastion : bastions) { + if (bastion.getType().isOnlyDirectDestruction() || !bastion.inField(loc)) + continue; - if(rein == null) - continue; + Reinforcement rein = reinManager.getReinforcement(bastion.getLocation()); - if(players == null) - return false; + if (rein == null) + continue; - if(citadel.useJukeAlert() && !rein.getGroup().getName().equalsIgnoreCase(citadel.getGroupName())) - return false; + if (players == null) + return false; - boolean hasAccess = false; + if (citadel.useJukeAlert() && !rein.getGroup().getName().equalsIgnoreCase(citadel.getGroupName())) + return false; - for (Player player : players) { - if (bastion.permAccess(player, perm)) { - hasAccess = true; - break; - } - } + boolean hasAccess = false; - if (!hasAccess) - return false; - } + for (Player player : players) { + if (bastion.permAccess(player, perm)) { + hasAccess = true; + break; + } + } - return true; - } -} \ No newline at end of file + if (!hasAccess) + return false; + } + + return true; + } +} diff --git a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/plugins/bastion/IBastionManager.java b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/plugins/bastion/IBastionManager.java index 28ddab4f9..56229dfb8 100644 --- a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/plugins/bastion/IBastionManager.java +++ b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/plugins/bastion/IBastionManager.java @@ -1,6 +1,5 @@ /** * @author Aleksey Terzi - * */ package com.aleksey.castlegates.plugins.bastion; @@ -12,6 +11,8 @@ import org.bukkit.block.Block; import org.bukkit.entity.Player; public interface IBastionManager { - void init(); - boolean canUndraw(List players, List bridgeBlocks, ICitadel jukeAlertCitadel); + + void init(); + + boolean canUndraw(List players, List bridgeBlocks, ICitadel jukeAlertCitadel); } diff --git a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/plugins/bastion/NoBastionManager.java b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/plugins/bastion/NoBastionManager.java index af38eb0ab..c345f949c 100644 --- a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/plugins/bastion/NoBastionManager.java +++ b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/plugins/bastion/NoBastionManager.java @@ -1,6 +1,5 @@ /** * @author Aleksey Terzi - * */ package com.aleksey.castlegates.plugins.bastion; @@ -12,10 +11,11 @@ import org.bukkit.block.Block; import org.bukkit.entity.Player; public class NoBastionManager implements IBastionManager { - public void init() { - } - public boolean canUndraw(List players, List bridgeBlocks, ICitadel jukeAlertCitadel) { - return true; - } + public void init() { + } + + public boolean canUndraw(List players, List bridgeBlocks, ICitadel jukeAlertCitadel) { + return true; + } } diff --git a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/plugins/citadel/Citadel.java b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/plugins/citadel/Citadel.java index 3f7377430..eeadfa395 100644 --- a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/plugins/citadel/Citadel.java +++ b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/plugins/citadel/Citadel.java @@ -11,6 +11,7 @@ import vg.civcraft.mc.citadel.model.Reinforcement; import java.util.List; public class Citadel implements ICitadel { + private String _groupName; private boolean _hasAccess; private boolean _useJukeAlert; @@ -21,22 +22,24 @@ public class Citadel implements ICitadel { _useJukeAlert = useJukeAlert; } - public boolean useJukeAlert() { return _useJukeAlert; } + public boolean useJukeAlert() { + return _useJukeAlert; + } public String getGroupName() { return _groupName; } public boolean canAccessDoors(Location location) { - if(!_hasAccess) return false; + if (!_hasAccess) return false; Reinforcement rein = vg.civcraft.mc.citadel.Citadel - .getInstance() - .getReinforcementManager() - .getReinforcement(location); + .getInstance() + .getReinforcementManager() + .getReinforcement(location); return rein == null ? _groupName == null : _groupName != null && _groupName.equalsIgnoreCase(rein.getGroup().getName()); } -} \ No newline at end of file +} diff --git a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/plugins/citadel/CitadelManager.java b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/plugins/citadel/CitadelManager.java index f0af7c06d..b4c73c60e 100644 --- a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/plugins/citadel/CitadelManager.java +++ b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/plugins/citadel/CitadelManager.java @@ -1,6 +1,5 @@ /** * @author Aleksey Terzi - * */ package com.aleksey.castlegates.plugins.citadel; @@ -26,145 +25,147 @@ import vg.civcraft.mc.citadel.playerstate.PlayerStateManager; import vg.civcraft.mc.citadel.playerstate.ReinforcingState; public class CitadelManager extends Thread implements ICitadelManager, Runnable { - private static class UpdatedReinforcement { - public Reinforcement rein; - public boolean deleted; - public UpdatedReinforcement(Reinforcement rein, boolean deleted) { - this.rein = rein; - this.deleted = deleted; - } - } + private static class UpdatedReinforcement { - private long _lastExecute = System.currentTimeMillis(); + public Reinforcement rein; + public boolean deleted; + + public UpdatedReinforcement(Reinforcement rein, boolean deleted) { + this.rein = rein; + this.deleted = deleted; + } + } + + private long _lastExecute = System.currentTimeMillis(); private AtomicBoolean _kill = new AtomicBoolean(false); - private AtomicBoolean _run = new AtomicBoolean(false); + private AtomicBoolean _run = new AtomicBoolean(false); private List _updatedReinforcements = new ArrayList(); - private Queue _localUpdatedReinforcements = new ArrayDeque(); + private Queue _localUpdatedReinforcements = new ArrayDeque(); - @Override + @Override public void init() { - startThread(); + startThread(); } - @Override + @Override public void close() { - terminateThread(); + terminateThread(); } - @Override - public double getMaxRedstoneDistance() { - return CastleGates.getConfigManager().getMaxRedstoneDistance(); - } + @Override + public double getMaxRedstoneDistance() { + return CastleGates.getConfigManager().getMaxRedstoneDistance(); + } - @Override - public ICitadel getCitadel(List players, Location loc) { - Reinforcement rein = Citadel.getInstance().getReinforcementManager().getReinforcement(loc); + @Override + public ICitadel getCitadel(List players, Location loc) { + Reinforcement rein = Citadel.getInstance().getReinforcementManager().getReinforcement(loc); - boolean hasAccess = rein == null; - boolean useJukeAlert = false; + boolean hasAccess = rein == null; + boolean useJukeAlert = false; - if(!hasAccess) { - var doorsPermission= CitadelPermissionHandler.getDoors(); + if (!hasAccess) { + var doorsPermission = CitadelPermissionHandler.getDoors(); - if (players != null && players.size() > 0) { - for (Player player : players) { - if (rein.hasPermission(player, doorsPermission) || player.hasPermission("citadel.admin")) { - hasAccess = true; - break; - } - } - } + if (players != null && players.size() > 0) { + for (Player player : players) { + if (rein.hasPermission(player, doorsPermission) || player.hasPermission("citadel.admin")) { + hasAccess = true; + break; + } + } + } - if(!hasAccess) { - if(CastleGates.getJukeAlertManager().hasJukeAlertAccess(loc, rein.getGroup().getName())) { - hasAccess = true; - useJukeAlert = true; - } - } - } + if (!hasAccess) { + if (CastleGates.getJukeAlertManager().hasJukeAlertAccess(loc, rein.getGroup().getName())) { + hasAccess = true; + useJukeAlert = true; + } + } + } - return new com.aleksey.castlegates.plugins.citadel.Citadel(rein, hasAccess, useJukeAlert); - } + return new com.aleksey.castlegates.plugins.citadel.Citadel(rein, hasAccess, useJukeAlert); + } - @Override - public boolean isReinforced(Location loc) { - Reinforcement rein = Citadel.getInstance().getReinforcementManager().getReinforcement(loc); - return rein != null; - } + @Override + public boolean isReinforced(Location loc) { + Reinforcement rein = Citadel.getInstance().getReinforcementManager().getReinforcement(loc); + return rein != null; + } - @Override - public boolean canBypass(Player player, Location loc) { - Reinforcement rein = Citadel.getInstance().getReinforcementManager().getReinforcement(loc); + @Override + public boolean canBypass(Player player, Location loc) { + Reinforcement rein = Citadel.getInstance().getReinforcementManager().getReinforcement(loc); - if(rein == null) - return true; + if (rein == null) + return true; - if(player == null) - return false; + if (player == null) + return false; - return rein.hasPermission(player, CitadelPermissionHandler.getBypass()) - || player.hasPermission("citadel.admin"); - } + return rein.hasPermission(player, CitadelPermissionHandler.getBypass()) + || player.hasPermission("citadel.admin"); + } - @Override - public boolean canViewInformation(Player player, Location loc) { - Reinforcement rein = Citadel.getInstance().getReinforcementManager().getReinforcement(loc); + @Override + public boolean canViewInformation(Player player, Location loc) { + Reinforcement rein = Citadel.getInstance().getReinforcementManager().getReinforcement(loc); - if(rein == null) - return true; + if (rein == null) + return true; - if(player == null) - return false; + if (player == null) + return false; - return rein.hasPermission(player, CitadelPermissionHandler.getInfo()) - || player.hasPermission("citadel.admin"); - } + return rein.hasPermission(player, CitadelPermissionHandler.getInfo()) + || player.hasPermission("citadel.admin"); + } - @Override - public ReinforcementInfo removeReinforcement(Location loc) { - Reinforcement rein = Citadel.getInstance().getReinforcementManager().getReinforcement(loc); + @Override + public ReinforcementInfo removeReinforcement(Location loc) { + Reinforcement rein = Citadel.getInstance().getReinforcementManager().getReinforcement(loc); - if(rein == null) - return null; + if (rein == null) + return null; - ReinforcementInfo info = new ReinforcementInfo(); - info.CreationTime = rein.getCreationTime(); - info.TypeId = rein.getType().getID(); - info.Health = rein.getHealth(); - info.GroupId = rein.getGroupId(); - info.Insecure = rein.isInsecure(); + ReinforcementInfo info = new ReinforcementInfo(); + info.CreationTime = rein.getCreationTime(); + info.TypeId = rein.getType().getID(); + info.Health = rein.getHealth(); + info.GroupId = rein.getGroupId(); + info.Insecure = rein.isInsecure(); - synchronized(this._updatedReinforcements) { - this._updatedReinforcements.add(new UpdatedReinforcement(rein, true)); - } + synchronized (this._updatedReinforcements) { + this._updatedReinforcements.add(new UpdatedReinforcement(rein, true)); + } - return info; - } + return info; + } - @Override - public boolean createReinforcement(ReinforcementInfo info, Location loc) { - if(info == null) - return false; + @Override + public boolean createReinforcement(ReinforcementInfo info, Location loc) { + if (info == null) + return false; - var type = Citadel.getInstance().getReinforcementTypeManager().getById(info.TypeId); - var rein = new Reinforcement(loc, type, info.GroupId, info.CreationTime, info.Health, info.Insecure, true); + var type = Citadel.getInstance().getReinforcementTypeManager().getById(info.TypeId); + var rein = new Reinforcement(loc, type, info.GroupId, info.CreationTime, info.Health, info.Insecure, true); - synchronized(this._updatedReinforcements) { - this._updatedReinforcements.add(new UpdatedReinforcement(rein, false)); - } + synchronized (this._updatedReinforcements) { + this._updatedReinforcements.add(new UpdatedReinforcement(rein, false)); + } - return true; - } + return true; + } - @Override - public boolean isReinforcingStateActive(Player player) { - PlayerStateManager stateManager = Citadel.getInstance().getStateManager(); - AbstractPlayerState currentState = stateManager.getState(player); + @Override + public boolean isReinforcingStateActive(Player player) { + PlayerStateManager stateManager = Citadel.getInstance().getStateManager(); + AbstractPlayerState currentState = stateManager.getState(player); - return currentState instanceof ReinforcingState; - } + return currentState instanceof ReinforcingState; + } public void startThread() { setName("CastleGates CitadelManager Thread"); @@ -174,64 +175,64 @@ public class CitadelManager extends Thread implements ICitadelManager, Runnable CastleGates.getPluginLogger().log(Level.INFO, "CitadelManager thread started"); } - public void terminateThread() { - this._kill.set(true); + public void terminateThread() { + this._kill.set(true); - while (this._run.get()) { - try { - Thread.sleep(100); - } catch (Exception e) { - e.printStackTrace(); - } - } + while (this._run.get()) { + try { + Thread.sleep(100); + } catch (Exception e) { + e.printStackTrace(); + } + } - saveData(); + saveData(); - CastleGates.getPluginLogger().log(Level.INFO, "CitadelManager thread stopped"); - } + CastleGates.getPluginLogger().log(Level.INFO, "CitadelManager thread stopped"); + } @Override public void run() { - this._run.set(true); + this._run.set(true); - try { - while (!this.isInterrupted() && !this._kill.get()) { - try { - long timeWait = _lastExecute + CastleGates.getConfigManager().getDataWorkerRate() - System.currentTimeMillis(); - _lastExecute = System.currentTimeMillis(); - if (timeWait > 0) { - Thread.sleep(timeWait); - } + try { + while (!this.isInterrupted() && !this._kill.get()) { + try { + long timeWait = _lastExecute + CastleGates.getConfigManager().getDataWorkerRate() - System.currentTimeMillis(); + _lastExecute = System.currentTimeMillis(); + if (timeWait > 0) { + Thread.sleep(timeWait); + } - saveData(); - } catch (Exception e) { - e.printStackTrace(); - } - } - } finally { - this._run.set(false); - } - } + saveData(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } finally { + this._run.set(false); + } + } - private void saveData() { - try { - synchronized (this._updatedReinforcements) { - if (this._updatedReinforcements.size() == 0) return; + private void saveData() { + try { + synchronized (this._updatedReinforcements) { + if (this._updatedReinforcements.size() == 0) return; - this._localUpdatedReinforcements.addAll(this._updatedReinforcements); - this._updatedReinforcements.clear(); - } + this._localUpdatedReinforcements.addAll(this._updatedReinforcements); + this._updatedReinforcements.clear(); + } - UpdatedReinforcement updated; + UpdatedReinforcement updated; - while ((updated = this._localUpdatedReinforcements.poll()) != null) { - if (updated.deleted) - updated.rein.setHealth(-1); - else - Citadel.getInstance().getReinforcementManager().putReinforcement(updated.rein); - } - } catch (Exception e) { - e.printStackTrace(); - } - } + while ((updated = this._localUpdatedReinforcements.poll()) != null) { + if (updated.deleted) + updated.rein.setHealth(-1); + else + Citadel.getInstance().getReinforcementManager().putReinforcement(updated.rein); + } + } catch (Exception e) { + e.printStackTrace(); + } + } } diff --git a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/plugins/citadel/ICitadel.java b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/plugins/citadel/ICitadel.java index c42e30bdf..551b2d787 100644 --- a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/plugins/citadel/ICitadel.java +++ b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/plugins/citadel/ICitadel.java @@ -7,7 +7,10 @@ package com.aleksey.castlegates.plugins.citadel; import org.bukkit.Location; public interface ICitadel { + boolean useJukeAlert(); + String getGroupName(); + boolean canAccessDoors(Location location); } diff --git a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/plugins/citadel/ICitadelManager.java b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/plugins/citadel/ICitadelManager.java index af3dd07bf..14cba97b5 100644 --- a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/plugins/citadel/ICitadelManager.java +++ b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/plugins/citadel/ICitadelManager.java @@ -1,6 +1,5 @@ /** * @author Aleksey Terzi - * */ package com.aleksey.castlegates.plugins.citadel; @@ -13,14 +12,24 @@ import org.bukkit.entity.Player; import com.aleksey.castlegates.database.ReinforcementInfo; public interface ICitadelManager { - void init(); - void close(); - double getMaxRedstoneDistance(); - ICitadel getCitadel(List players, Location loc); - boolean isReinforced(Location loc); - boolean canBypass(Player player, Location loc); - boolean canViewInformation(Player player, Location loc); - ReinforcementInfo removeReinforcement(Location loc); - boolean createReinforcement(ReinforcementInfo info, Location loc); - boolean isReinforcingStateActive(Player player); + + void init(); + + void close(); + + double getMaxRedstoneDistance(); + + ICitadel getCitadel(List players, Location loc); + + boolean isReinforced(Location loc); + + boolean canBypass(Player player, Location loc); + + boolean canViewInformation(Player player, Location loc); + + ReinforcementInfo removeReinforcement(Location loc); + + boolean createReinforcement(ReinforcementInfo info, Location loc); + + boolean isReinforcingStateActive(Player player); } diff --git a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/plugins/citadel/NoCitadel.java b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/plugins/citadel/NoCitadel.java index 4a517e255..240bca970 100644 --- a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/plugins/citadel/NoCitadel.java +++ b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/plugins/citadel/NoCitadel.java @@ -7,7 +7,16 @@ package com.aleksey.castlegates.plugins.citadel; import org.bukkit.Location; public class NoCitadel implements ICitadel { - public boolean useJukeAlert() { return false; } - public String getGroupName() { return null; } - public boolean canAccessDoors(Location location) { return true; } + + public boolean useJukeAlert() { + return false; + } + + public String getGroupName() { + return null; + } + + public boolean canAccessDoors(Location location) { + return true; + } } diff --git a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/plugins/citadel/NoCitadelManager.java b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/plugins/citadel/NoCitadelManager.java index 0f4af0c05..27af70dac 100644 --- a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/plugins/citadel/NoCitadelManager.java +++ b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/plugins/citadel/NoCitadelManager.java @@ -1,6 +1,5 @@ /** * @author Aleksey Terzi - * */ package com.aleksey.castlegates.plugins.citadel; @@ -14,49 +13,54 @@ import com.aleksey.castlegates.CastleGates; import com.aleksey.castlegates.database.ReinforcementInfo; public class NoCitadelManager implements ICitadelManager { - @Override - public void init() { - } + @Override + public void init() { - @Override - public void close() { + } - } + @Override + public void close() { - @Override - public double getMaxRedstoneDistance() { - return CastleGates.getConfigManager().getMaxRedstoneDistance(); - } + } - @Override - public ICitadel getCitadel(List players, Location loc) { return new NoCitadel(); } + @Override + public double getMaxRedstoneDistance() { + return CastleGates.getConfigManager().getMaxRedstoneDistance(); + } - @Override - public boolean isReinforced(Location loc) { return false; } + @Override + public ICitadel getCitadel(List players, Location loc) { + return new NoCitadel(); + } - @Override - public boolean canBypass(Player player, Location loc) { - return true; - } + @Override + public boolean isReinforced(Location loc) { + return false; + } - @Override - public boolean canViewInformation(Player player, Location loc) { - return true; - } + @Override + public boolean canBypass(Player player, Location loc) { + return true; + } - @Override - public ReinforcementInfo removeReinforcement(Location loc) { - return null; - } + @Override + public boolean canViewInformation(Player player, Location loc) { + return true; + } - @Override - public boolean createReinforcement(ReinforcementInfo info, Location loc) { - return false; - } + @Override + public ReinforcementInfo removeReinforcement(Location loc) { + return null; + } - @Override - public boolean isReinforcingStateActive(Player player) { - return false; - } + @Override + public boolean createReinforcement(ReinforcementInfo info, Location loc) { + return false; + } + + @Override + public boolean isReinforcingStateActive(Player player) { + return false; + } } diff --git a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/plugins/jukealert/IJukeAlertManager.java b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/plugins/jukealert/IJukeAlertManager.java index f50a07dbb..7b4bd0c47 100644 --- a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/plugins/jukealert/IJukeAlertManager.java +++ b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/plugins/jukealert/IJukeAlertManager.java @@ -3,5 +3,6 @@ package com.aleksey.castlegates.plugins.jukealert; import org.bukkit.Location; public interface IJukeAlertManager { - boolean hasJukeAlertAccess(Location location, String groupName); -} \ No newline at end of file + + boolean hasJukeAlertAccess(Location location, String groupName); +} diff --git a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/plugins/jukealert/JukeAlertManager.java b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/plugins/jukealert/JukeAlertManager.java index e2727466a..7e49888d1 100644 --- a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/plugins/jukealert/JukeAlertManager.java +++ b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/plugins/jukealert/JukeAlertManager.java @@ -11,31 +11,31 @@ import com.untamedears.jukealert.SnitchManager; import java.util.Set; public class JukeAlertManager implements IJukeAlertManager { + private final SnitchManager _snitchManager = JukeAlert.getInstance().getSnitchManager(); - public boolean hasJukeAlertAccess(Location location, String groupName) { - if(!CastleGates.getConfigManager().getInteractWithSnitches()) return false; + public boolean hasJukeAlertAccess(Location location, String groupName) { + if (!CastleGates.getConfigManager().getInteractWithSnitches()) return false; - Set snitches = _snitchManager.getSnitchesCovering(location); + Set snitches = _snitchManager.getSnitchesCovering(location); - if (snitches.size() > 0) { - double distance = CastleGates.getCitadelManager().getMaxRedstoneDistance(); + if (snitches.size() > 0) { + double distance = CastleGates.getCitadelManager().getMaxRedstoneDistance(); - for (Snitch snitch : snitches) { - if (snitch.getGroup().getName().equalsIgnoreCase(groupName) - && snitch.getLocation().distance(location) <= distance - ) - { - LeverToggleAppender toggleAppender = snitch.getAppender(LeverToggleAppender.class); - if (toggleAppender == null) { - continue; - } - if (toggleAppender.shouldToggle()) - return true; - } - } - } + for (Snitch snitch : snitches) { + if (snitch.getGroup().getName().equalsIgnoreCase(groupName) + && snitch.getLocation().distance(location) <= distance + ) { + LeverToggleAppender toggleAppender = snitch.getAppender(LeverToggleAppender.class); + if (toggleAppender == null) { + continue; + } + if (toggleAppender.shouldToggle()) + return true; + } + } + } - return false; - } + return false; + } } diff --git a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/plugins/jukealert/NoJukeAlertManager.java b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/plugins/jukealert/NoJukeAlertManager.java index d446ff1a1..0c1dbafb3 100644 --- a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/plugins/jukealert/NoJukeAlertManager.java +++ b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/plugins/jukealert/NoJukeAlertManager.java @@ -4,5 +4,8 @@ import com.aleksey.castlegates.plugins.citadel.ICitadel; import org.bukkit.Location; public class NoJukeAlertManager implements IJukeAlertManager { - public boolean hasJukeAlertAccess(Location location, String groupName) { return false; } + + public boolean hasJukeAlertAccess(Location location, String groupName) { + return false; + } } diff --git a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/types/BlockCoord.java b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/types/BlockCoord.java index 68b498d95..83c5bef15 100644 --- a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/types/BlockCoord.java +++ b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/types/BlockCoord.java @@ -1,6 +1,5 @@ /** * @author Aleksey Terzi - * */ package com.aleksey.castlegates.types; @@ -11,70 +10,96 @@ import org.bukkit.block.Block; import org.bukkit.block.BlockFace; public class BlockCoord { - private final UUID _world; - private int _x; - private int _y; - private int _z; - public BlockCoord(Block block) { - _world = block.getWorld().getUID(); - _x = block.getX(); - _y = block.getY(); - _z = block.getZ(); - } + private final UUID _world; + private int _x; + private int _y; + private int _z; - public BlockCoord(UUID world, int x, int y, int z) { - _world = world; - _x = x; - _y = y; - _z = z; - } + public BlockCoord(Block block) { + _world = block.getWorld().getUID(); + _x = block.getX(); + _y = block.getY(); + _z = block.getZ(); + } - @Override - public BlockCoord clone() { - return new BlockCoord(_world, _x, _y, _z); - } + public BlockCoord(UUID world, int x, int y, int z) { + _world = world; + _x = x; + _y = y; + _z = z; + } - public UUID getWorldUID() { return _world; } + @Override + public BlockCoord clone() { + return new BlockCoord(_world, _x, _y, _z); + } - public int getX() { return _x; } + public UUID getWorldUID() { + return _world; + } - public int getY() { return _y; } + public int getX() { + return _x; + } - public int getZ() { return _z; } + public int getY() { + return _y; + } - public void increment(BlockFace face) { - _x += face.getModX(); - _y += face.getModY(); - _z += face.getModZ(); - } + public int getZ() { + return _z; + } - public BlockCoord getForward() { return new BlockCoord(_world, _x, _y, _z - 1); } - public BlockCoord getBackward() { return new BlockCoord(_world, _x, _y, _z + 1); } - public BlockCoord getRight() { return new BlockCoord(_world, _x - 1, _y, _z); } - public BlockCoord getLeft() { return new BlockCoord(_world, _x + 1, _y, _z); } - public BlockCoord getTop() { return new BlockCoord(_world, _x, _y + 1, _z); } - public BlockCoord getBottom() { return new BlockCoord(_world, _x, _y - 1, _z); } + public void increment(BlockFace face) { + _x += face.getModX(); + _y += face.getModY(); + _z += face.getModZ(); + } - @Override - public boolean equals(Object other) { - if (!(other instanceof BlockCoord object)) - return false; + public BlockCoord getForward() { + return new BlockCoord(_world, _x, _y, _z - 1); + } - return _world.equals(object._world) - && _x == object._x - && _y == object._y - && _z == object._z - ; - } + public BlockCoord getBackward() { + return new BlockCoord(_world, _x, _y, _z + 1); + } - @Override - public int hashCode() { - return _world.hashCode() ^ _x ^ _y ^ _z; - } + public BlockCoord getRight() { + return new BlockCoord(_world, _x - 1, _y, _z); + } - @Override - public String toString() { - return "World UUID = " + _world + ", [" + _x + " " + _y + " " + _z + "]"; - } + public BlockCoord getLeft() { + return new BlockCoord(_world, _x + 1, _y, _z); + } + + public BlockCoord getTop() { + return new BlockCoord(_world, _x, _y + 1, _z); + } + + public BlockCoord getBottom() { + return new BlockCoord(_world, _x, _y - 1, _z); + } + + @Override + public boolean equals(Object other) { + if (!(other instanceof BlockCoord object)) + return false; + + return _world.equals(object._world) + && _x == object._x + && _y == object._y + && _z == object._z + ; + } + + @Override + public int hashCode() { + return _world.hashCode() ^ _x ^ _y ^ _z; + } + + @Override + public String toString() { + return "World UUID = " + _world + ", [" + _x + " " + _y + " " + _z + "]"; + } } diff --git a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/types/BlockState.java b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/types/BlockState.java index 8a590ee6e..5e0bc9ad4 100644 --- a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/types/BlockState.java +++ b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/types/BlockState.java @@ -1,6 +1,5 @@ /** * @author Aleksey Terzi - * */ package com.aleksey.castlegates.types; @@ -10,30 +9,44 @@ import org.bukkit.block.Block; import com.aleksey.castlegates.database.ReinforcementInfo; public class BlockState { - public static final char Separator = '\n'; - private String _blockData; - public String getBlockData() { return _blockData; } - public int getBlockDataLen() { return _blockData.length() + 1; } + public static final char Separator = '\n'; - private ReinforcementInfo _reinforcement; - public void setReinforcement(ReinforcementInfo reinforcement) { _reinforcement = reinforcement; } - public ReinforcementInfo getReinforcement() { return _reinforcement; } + private String _blockData; - public BlockState(Block block, ReinforcementInfo reinforcement) { - _blockData = block.getBlockData().getAsString(); - _reinforcement = reinforcement; - } + public String getBlockData() { + return _blockData; + } - private BlockState(String blockData) { - _blockData = blockData; - } - public void serialize(StringBuilder data) { - data.append(_blockData); - data.append(Separator); - } + public int getBlockDataLen() { + return _blockData.length() + 1; + } - public static BlockState deserialize(String blockData) { - return new BlockState(blockData); - } + private ReinforcementInfo _reinforcement; + + public void setReinforcement(ReinforcementInfo reinforcement) { + _reinforcement = reinforcement; + } + + public ReinforcementInfo getReinforcement() { + return _reinforcement; + } + + public BlockState(Block block, ReinforcementInfo reinforcement) { + _blockData = block.getBlockData().getAsString(); + _reinforcement = reinforcement; + } + + private BlockState(String blockData) { + _blockData = blockData; + } + + public void serialize(StringBuilder data) { + data.append(_blockData); + data.append(Separator); + } + + public static BlockState deserialize(String blockData) { + return new BlockState(blockData); + } } diff --git a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/types/CommandMode.java b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/types/CommandMode.java index d4bb60655..d24db7b29 100644 --- a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/types/CommandMode.java +++ b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/types/CommandMode.java @@ -1,15 +1,14 @@ /** * @author Aleksey Terzi - * */ package com.aleksey.castlegates.types; public enum CommandMode { - OFF, - NORMAL, - CREATE, - LINK, - INFO, - TIMER + OFF, + NORMAL, + CREATE, + LINK, + INFO, + TIMER } diff --git a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/types/Gearblock.java b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/types/Gearblock.java index 420861b90..f42212f3d 100644 --- a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/types/Gearblock.java +++ b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/types/Gearblock.java @@ -1,6 +1,5 @@ /** * @author Aleksey Terzi - * */ package com.aleksey.castlegates.types; @@ -9,74 +8,129 @@ import java.util.List; public class Gearblock { - private int _id; - private final BlockCoord _coord; - private boolean _powered; - private boolean _removed; - private GearblockLink _link; - private Integer _timer; - private TimerOperation _timerOperation; - private TimerMode _timerMode; - private TimerBatch _timerBatch; - private long _lastSwitchTime; - private Gearblock _lockGearblock; - private List _lockedGearblocks; - public Gearblock(BlockCoord coord) { - _coord = coord; - } + private int _id; + private final BlockCoord _coord; + private boolean _powered; + private boolean _removed; + private GearblockLink _link; + private Integer _timer; + private TimerOperation _timerOperation; + private TimerMode _timerMode; + private TimerBatch _timerBatch; + private long _lastSwitchTime; + private Gearblock _lockGearblock; + private List _lockedGearblocks; - public int getId() { return _id; } - public void setId(int value) { _id = value; } + public Gearblock(BlockCoord coord) { + _coord = coord; + } - public BlockCoord getCoord() { return _coord; } + public int getId() { + return _id; + } - public boolean isRemoved() { return _removed; } - public void setRemoved() { _removed = true; } + public void setId(int value) { + _id = value; + } - public boolean isPowered() { return _powered; } - public void setPowered(boolean value) { _powered = value; } + public BlockCoord getCoord() { + return _coord; + } - public GearblockLink getLink() { return _link != null && !_link.isBroken() ? _link : null; } - public GearblockLink getBrokenLink() { return _link != null && _link.isBroken() ? _link : null; } - public void setLink(GearblockLink link) { _link = link; } + public boolean isRemoved() { + return _removed; + } - public Integer getTimer() { return _timer; } - public TimerOperation getTimerOperation() { return _timerOperation; } - public TimerMode getTimerMode() { return _timerMode; } - public void setTimer(Integer timer, TimerOperation timerOperation, TimerMode timerMode) { - _timer = timer; - _timerOperation = timerOperation; - _timerMode = timerMode; - } + public void setRemoved() { + _removed = true; + } - public TimerBatch getTimerBatch() { return _timerBatch; } - public void setTimerBatch(TimerBatch timerBatch) { _timerBatch = timerBatch; } + public boolean isPowered() { + return _powered; + } - public long getLastSwitchTime() { return _lastSwitchTime; } - public void setLastSwitchTime() { _lastSwitchTime = System.currentTimeMillis(); } + public void setPowered(boolean value) { + _powered = value; + } - public void setLockGearblock(Gearblock lockGearblock) { _lockGearblock = lockGearblock; } - public Gearblock getLockGearblock() { return _lockGearblock; } + public GearblockLink getLink() { + return _link != null && !_link.isBroken() ? _link : null; + } - public void setLockedGearblocks(List lockedGearblocks) { _lockedGearblocks = lockedGearblocks; } - public List getLockedGearblocks() { return _lockedGearblocks; } + public GearblockLink getBrokenLink() { + return _link != null && _link.isBroken() ? _link : null; + } - @Override - public boolean equals(Object other) { - if (!(other instanceof Gearblock object)) - return false; + public void setLink(GearblockLink link) { + _link = link; + } - return _coord.equals(object._coord); - } + public Integer getTimer() { + return _timer; + } - @Override - public int hashCode() { - return _coord.hashCode(); - } + public TimerOperation getTimerOperation() { + return _timerOperation; + } - @Override - public String toString() { - return _coord.toString(); - } + public TimerMode getTimerMode() { + return _timerMode; + } + + public void setTimer(Integer timer, TimerOperation timerOperation, TimerMode timerMode) { + _timer = timer; + _timerOperation = timerOperation; + _timerMode = timerMode; + } + + public TimerBatch getTimerBatch() { + return _timerBatch; + } + + public void setTimerBatch(TimerBatch timerBatch) { + _timerBatch = timerBatch; + } + + public long getLastSwitchTime() { + return _lastSwitchTime; + } + + public void setLastSwitchTime() { + _lastSwitchTime = System.currentTimeMillis(); + } + + public void setLockGearblock(Gearblock lockGearblock) { + _lockGearblock = lockGearblock; + } + + public Gearblock getLockGearblock() { + return _lockGearblock; + } + + public void setLockedGearblocks(List lockedGearblocks) { + _lockedGearblocks = lockedGearblocks; + } + + public List getLockedGearblocks() { + return _lockedGearblocks; + } + + @Override + public boolean equals(Object other) { + if (!(other instanceof Gearblock object)) + return false; + + return _coord.equals(object._coord); + } + + @Override + public int hashCode() { + return _coord.hashCode(); + } + + @Override + public String toString() { + return _coord.toString(); + } } diff --git a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/types/GearblockForUpdate.java b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/types/GearblockForUpdate.java index 649266f02..9a3778b4b 100644 --- a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/types/GearblockForUpdate.java +++ b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/types/GearblockForUpdate.java @@ -3,6 +3,7 @@ package com.aleksey.castlegates.types; import com.aleksey.castlegates.database.GearblockInfo; public class GearblockForUpdate { - public Gearblock original; - public GearblockInfo info; + + public Gearblock original; + public GearblockInfo info; } diff --git a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/types/GearblockLink.java b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/types/GearblockLink.java index 85252209b..91d72dbe3 100644 --- a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/types/GearblockLink.java +++ b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/types/GearblockLink.java @@ -1,6 +1,5 @@ /** * @author Aleksey Terzi - * */ package com.aleksey.castlegates.types; @@ -8,46 +7,71 @@ package com.aleksey.castlegates.types; import java.util.List; public class GearblockLink { - private int _id; - private Gearblock _gearblock1; - private Gearblock _gearblock2; - private boolean _removed; - private List _blocks; - public GearblockLink(Gearblock gearblock1, Gearblock gearblock2) { - _gearblock1 = gearblock1; - _gearblock2 = gearblock2; - } + private int _id; + private Gearblock _gearblock1; + private Gearblock _gearblock2; + private boolean _removed; + private List _blocks; - public int getId() { return _id; } - public void setId(int value) { _id = value; } + public GearblockLink(Gearblock gearblock1, Gearblock gearblock2) { + _gearblock1 = gearblock1; + _gearblock2 = gearblock2; + } - public Gearblock getGearblock1() { return _gearblock1; } + public int getId() { + return _id; + } - public Gearblock getGearblock2() { return _gearblock2; } + public void setId(int value) { + _id = value; + } - public boolean isBroken() { return _gearblock1 == null || _gearblock2 == null; } + public Gearblock getGearblock1() { + return _gearblock1; + } - public void setBroken(Gearblock removedGear) { - if(_gearblock1 == removedGear) { - _gearblock1 = null; - } else { - _gearblock2 = null; - } - } + public Gearblock getGearblock2() { + return _gearblock2; + } - public void setRestored(Gearblock addedGearblock) { - if(_gearblock1 == null) { - _gearblock1 = addedGearblock; - } else { - _gearblock2 = addedGearblock; - } - } + public boolean isBroken() { + return _gearblock1 == null || _gearblock2 == null; + } - public boolean isRemoved() { return _removed; } - public void setRemoved() { _removed = true; } + public void setBroken(Gearblock removedGear) { + if (_gearblock1 == removedGear) { + _gearblock1 = null; + } else { + _gearblock2 = null; + } + } - public boolean isDrawn() { return _blocks != null; } - public List getBlocks() { return _blocks; } - public void setBlocks(List blocks) { _blocks = blocks; } + public void setRestored(Gearblock addedGearblock) { + if (_gearblock1 == null) { + _gearblock1 = addedGearblock; + } else { + _gearblock2 = addedGearblock; + } + } + + public boolean isRemoved() { + return _removed; + } + + public void setRemoved() { + _removed = true; + } + + public boolean isDrawn() { + return _blocks != null; + } + + public List getBlocks() { + return _blocks; + } + + public void setBlocks(List blocks) { + _blocks = blocks; + } } diff --git a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/types/LinkForUpdate.java b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/types/LinkForUpdate.java index 0fadfb9f4..086845b78 100644 --- a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/types/LinkForUpdate.java +++ b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/types/LinkForUpdate.java @@ -5,9 +5,10 @@ import java.util.List; import com.aleksey.castlegates.database.ReinforcementInfo; public class LinkForUpdate { - public GearblockLink original; - public Gearblock gearblock1; - public Gearblock gearblock2; - public String blocks; - public List reinforcements; + + public GearblockLink original; + public Gearblock gearblock1; + public Gearblock gearblock2; + public String blocks; + public List reinforcements; } diff --git a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/types/PowerResult.java b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/types/PowerResult.java index ac6d43bd7..9560726b4 100644 --- a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/types/PowerResult.java +++ b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/types/PowerResult.java @@ -3,36 +3,37 @@ package com.aleksey.castlegates.types; import org.bukkit.block.Block; public class PowerResult { - public enum Status { - Unchanged, - Unpowered, - Blocked, - Broken, - Drawn, - Undrawn, - CannotDrawGear, - NotInCitadelGroup, - DifferentCitadelGroup, - BastionBlocked, - Locked, - Allowed - } - public Status status; - public Block block; + public enum Status { + Unchanged, + Unpowered, + Blocked, + Broken, + Drawn, + Undrawn, + CannotDrawGear, + NotInCitadelGroup, + DifferentCitadelGroup, + BastionBlocked, + Locked, + Allowed + } - public PowerResult(Status status, Block block) { - this.status = status; - this.block = block; - } + public Status status; + public Block block; - public static final PowerResult Unchanged = new PowerResult(Status.Unchanged, null); - public static final PowerResult Unpowered = new PowerResult(Status.Unpowered, null); - public static final PowerResult Drawn = new PowerResult(Status.Drawn, null); - public static final PowerResult Undrawn = new PowerResult(Status.Undrawn, null); - public static final PowerResult NotInCitadelGroup = new PowerResult(Status.NotInCitadelGroup, null); - public static final PowerResult DifferentCitadelGroup = new PowerResult(Status.DifferentCitadelGroup, null); - public static final PowerResult BastionBlocked = new PowerResult(Status.BastionBlocked, null); - public static final PowerResult Allowed = new PowerResult(Status.Allowed, null); - public static final PowerResult Locked = new PowerResult(Status.Locked, null); + public PowerResult(Status status, Block block) { + this.status = status; + this.block = block; + } + + public static final PowerResult Unchanged = new PowerResult(Status.Unchanged, null); + public static final PowerResult Unpowered = new PowerResult(Status.Unpowered, null); + public static final PowerResult Drawn = new PowerResult(Status.Drawn, null); + public static final PowerResult Undrawn = new PowerResult(Status.Undrawn, null); + public static final PowerResult NotInCitadelGroup = new PowerResult(Status.NotInCitadelGroup, null); + public static final PowerResult DifferentCitadelGroup = new PowerResult(Status.DifferentCitadelGroup, null); + public static final PowerResult BastionBlocked = new PowerResult(Status.BastionBlocked, null); + public static final PowerResult Allowed = new PowerResult(Status.Allowed, null); + public static final PowerResult Locked = new PowerResult(Status.Locked, null); } diff --git a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/types/TimerBatch.java b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/types/TimerBatch.java index bb8e8ccf7..5c2f48f4a 100644 --- a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/types/TimerBatch.java +++ b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/types/TimerBatch.java @@ -7,98 +7,109 @@ import java.util.List; import org.bukkit.World; public class TimerBatch { - private World _world; - private Gearblock _gearblock; - private HashSet _allGearblocks; - private long _runTimeMillis; - private PowerResult.Status _processStatus; - private TimerOperation _timerOperation; - private TimerMode _timerMode; - private boolean _isInvalid; - private List _links = new ArrayList<>(); - public World getWorld() { - return _world; - } + private World _world; + private Gearblock _gearblock; + private HashSet _allGearblocks; + private long _runTimeMillis; + private PowerResult.Status _processStatus; + private TimerOperation _timerOperation; + private TimerMode _timerMode; + private boolean _isInvalid; + private List _links = new ArrayList<>(); - public Gearblock getGearblock() { - return _gearblock; - } + public World getWorld() { + return _world; + } - public TimerMode getTimerMode() { return _timerMode; } + public Gearblock getGearblock() { + return _gearblock; + } - public HashSet getAllGearblocks() { return _allGearblocks; } - public void clearTimerBatchForAllGearblocks() { - for(Gearblock gearblock : _allGearblocks) { - gearblock.setTimerBatch(null); - } - } + public TimerMode getTimerMode() { + return _timerMode; + } - public List getLinks() { - return _links; - } + public HashSet getAllGearblocks() { + return _allGearblocks; + } - public long getRunTimeMillis() { - return _runTimeMillis; - } + public void clearTimerBatchForAllGearblocks() { + for (Gearblock gearblock : _allGearblocks) { + gearblock.setTimerBatch(null); + } + } - public boolean resetRunTime() { - if(_gearblock.getTimer() == null) return false; + public List getLinks() { + return _links; + } - _runTimeMillis = System.currentTimeMillis() + _gearblock.getTimer() * 1000; + public long getRunTimeMillis() { + return _runTimeMillis; + } - return true; - } + public boolean resetRunTime() { + if (_gearblock.getTimer() == null) return false; - public void setProcessStatus(PowerResult.Status processStatus) { - _processStatus = processStatus; - } + _runTimeMillis = System.currentTimeMillis() + _gearblock.getTimer() * 1000; - public PowerResult.Status getProcessStatus() { - return _processStatus; - } + return true; + } - public boolean isInvalid() { return _isInvalid; } - public void invalidate() { _isInvalid = true; } + public void setProcessStatus(PowerResult.Status processStatus) { + _processStatus = processStatus; + } - public TimerBatch(World world, Gearblock gearblock, HashSet allGearblocks) { - _world = world; - _gearblock = gearblock; - _timerOperation = gearblock.getTimerOperation(); - _timerMode = gearblock.getTimerMode(); - _allGearblocks = allGearblocks; + public PowerResult.Status getProcessStatus() { + return _processStatus; + } - for(Gearblock current : _allGearblocks) { - if(current.getTimerBatch() != null) { - current.getTimerBatch().invalidate(); - } + public boolean isInvalid() { + return _isInvalid; + } - current.setTimerBatch(this); - } + public void invalidate() { + _isInvalid = true; + } - resetRunTime(); - } + public TimerBatch(World world, Gearblock gearblock, HashSet allGearblocks) { + _world = world; + _gearblock = gearblock; + _timerOperation = gearblock.getTimerOperation(); + _timerMode = gearblock.getTimerMode(); + _allGearblocks = allGearblocks; - public void addLink(GearblockLink link) { - boolean mustDraw = _timerOperation == TimerOperation.DRAW - || _timerOperation == TimerOperation.REVERT && !link.isDrawn(); + for (Gearblock current : _allGearblocks) { + if (current.getTimerBatch() != null) { + current.getTimerBatch().invalidate(); + } - _links.add(new TimerLink(link, mustDraw)); - } + current.setTimerBatch(this); + } - public TimerBatch clone(Gearblock newGearblock) { - TimerBatch clone = new TimerBatch(_world, newGearblock, _allGearblocks); + resetRunTime(); + } - clone._world = _world; - clone._gearblock = newGearblock; - clone._allGearblocks = _allGearblocks; - clone._runTimeMillis = _runTimeMillis; - clone._processStatus = _processStatus; - clone._timerOperation = _timerOperation; - clone._timerMode = _timerMode; - clone._isInvalid = false; - clone._links = _links; + public void addLink(GearblockLink link) { + boolean mustDraw = _timerOperation == TimerOperation.DRAW + || _timerOperation == TimerOperation.REVERT && !link.isDrawn(); - return clone; - } + _links.add(new TimerLink(link, mustDraw)); + } + + public TimerBatch clone(Gearblock newGearblock) { + TimerBatch clone = new TimerBatch(_world, newGearblock, _allGearblocks); + + clone._world = _world; + clone._gearblock = newGearblock; + clone._allGearblocks = _allGearblocks; + clone._runTimeMillis = _runTimeMillis; + clone._processStatus = _processStatus; + clone._timerOperation = _timerOperation; + clone._timerMode = _timerMode; + clone._isInvalid = false; + clone._links = _links; + + return clone; + } } diff --git a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/types/TimerLink.java b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/types/TimerLink.java index 798f4f2fc..d47ed1772 100644 --- a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/types/TimerLink.java +++ b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/types/TimerLink.java @@ -1,19 +1,20 @@ package com.aleksey.castlegates.types; public class TimerLink { - private final GearblockLink _link; - private final boolean _mustDraw; - public GearblockLink getLink() { - return _link; - } + private final GearblockLink _link; + private final boolean _mustDraw; - public boolean isMustDraw() { - return _mustDraw; - } + public GearblockLink getLink() { + return _link; + } - public TimerLink(GearblockLink link, boolean mustDraw) { - _link = link; - _mustDraw = mustDraw; - } + public boolean isMustDraw() { + return _mustDraw; + } + + public TimerLink(GearblockLink link, boolean mustDraw) { + _link = link; + _mustDraw = mustDraw; + } } diff --git a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/types/TimerOperation.java b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/types/TimerOperation.java index be27241d6..e26280843 100644 --- a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/types/TimerOperation.java +++ b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/types/TimerOperation.java @@ -1,7 +1,7 @@ package com.aleksey.castlegates.types; public enum TimerOperation { - DRAW, - UNDRAW, - REVERT + DRAW, + UNDRAW, + REVERT } diff --git a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/utils/DataWorker.java b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/utils/DataWorker.java index 94592d817..0d5950dbe 100644 --- a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/utils/DataWorker.java +++ b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/utils/DataWorker.java @@ -1,6 +1,5 @@ /** * @author Aleksey Terzi - * */ package com.aleksey.castlegates.utils; @@ -25,166 +24,167 @@ import com.aleksey.castlegates.database.SqlDatabase; import com.aleksey.castlegates.types.*; public class DataWorker extends Thread implements Runnable { - private static final int DRAW_CODE = 0; - private static final int UNDRAW_CODE = 1; - private static final int REVERT_CODE = 2; - private static final int OPERATION_MASK = 3; - private static final int MODE_MASK = 4; - private final SqlDatabase _db; - private final GearblockSource _gearblockSource; - private final LinkSource _linkSource; - private final ReinforcementSource _reinforcementSource; + private static final int DRAW_CODE = 0; + private static final int UNDRAW_CODE = 1; + private static final int REVERT_CODE = 2; + private static final int OPERATION_MASK = 3; + private static final int MODE_MASK = 4; - private final Map _changedGearblocks = new HashMap<>(); - private final Map _changedLinks = new HashMap<>(); + private final SqlDatabase _db; + private final GearblockSource _gearblockSource; + private final LinkSource _linkSource; + private final ReinforcementSource _reinforcementSource; - private final ArrayList _localChangedGearblocks = new ArrayList<>(); - private final ArrayList _localChangedLinks = new ArrayList<>(); + private final Map _changedGearblocks = new HashMap<>(); + private final Map _changedLinks = new HashMap<>(); - private long _lastExecute = System.currentTimeMillis(); + private final ArrayList _localChangedGearblocks = new ArrayList<>(); + private final ArrayList _localChangedLinks = new ArrayList<>(); + + private long _lastExecute = System.currentTimeMillis(); private final AtomicBoolean _kill = new AtomicBoolean(false); - private final AtomicBoolean _run = new AtomicBoolean(false); + private final AtomicBoolean _run = new AtomicBoolean(false); public DataWorker(SqlDatabase db) { - _db = db; - _gearblockSource = new GearblockSource(db); - _linkSource = new LinkSource(db); - _reinforcementSource = new ReinforcementSource(db); - } + _db = db; + _gearblockSource = new GearblockSource(db); + _linkSource = new LinkSource(db); + _reinforcementSource = new ReinforcementSource(db); + } - public void close() { - terminateThread(); - } + public void close() { + terminateThread(); + } - public Map load() throws SQLException { - Map gearblocks = new HashMap<>(); - Map gearblocksById = new HashMap<>(); - Map linksById = new HashMap<>(); + public Map load() throws SQLException { + Map gearblocks = new HashMap<>(); + Map gearblocksById = new HashMap<>(); + Map linksById = new HashMap<>(); - loadGears(gearblocks, gearblocksById); - loadLinks(linksById, gearblocksById); - loadReinforcements(linksById); + loadGears(gearblocks, gearblocksById); + loadLinks(linksById, gearblocksById); + loadReinforcements(linksById); - return gearblocks; - } + return gearblocks; + } - private void loadGears(Map gearblocks, Map gearblocksById) throws SQLException { - int gearblockCount = _gearblockSource.countAll(); + private void loadGears(Map gearblocks, Map gearblocksById) throws SQLException { + int gearblockCount = _gearblockSource.countAll(); - CastleGates.getPluginLogger().log(Level.INFO, "Gearblock count: " + gearblockCount); + CastleGates.getPluginLogger().log(Level.INFO, "Gearblock count: " + gearblockCount); - List gearData = _gearblockSource.selectAll(); - int timerCount = 0; + List gearData = _gearblockSource.selectAll(); + int timerCount = 0; - for(GearblockInfo info : gearData) { - UUID world = UUID.fromString(info.WorldId); - BlockCoord location = new BlockCoord(world, info.X, info.Y, info.Z); - Gearblock gearblock = new Gearblock(location); + for (GearblockInfo info : gearData) { + UUID world = UUID.fromString(info.WorldId); + BlockCoord location = new BlockCoord(world, info.X, info.Y, info.Z); + Gearblock gearblock = new Gearblock(location); - TimerOperation timerOperation = null; - TimerMode timerMode = null; + TimerOperation timerOperation = null; + TimerMode timerMode = null; - if(info.TimerOperation != null) { - timerMode = (info.TimerOperation & MODE_MASK) != 0 ? TimerMode.DOOR : TimerMode.DEFAULT; + if (info.TimerOperation != null) { + timerMode = (info.TimerOperation & MODE_MASK) != 0 ? TimerMode.DOOR : TimerMode.DEFAULT; - switch(info.TimerOperation & OPERATION_MASK) { - case DRAW_CODE -> timerOperation = TimerOperation.DRAW; - case UNDRAW_CODE -> timerOperation = TimerOperation.UNDRAW; - case REVERT_CODE -> timerOperation = TimerOperation.REVERT; - } + switch (info.TimerOperation & OPERATION_MASK) { + case DRAW_CODE -> timerOperation = TimerOperation.DRAW; + case UNDRAW_CODE -> timerOperation = TimerOperation.UNDRAW; + case REVERT_CODE -> timerOperation = TimerOperation.REVERT; + } - timerCount++; - } + timerCount++; + } - gearblock.setId(info.GearblockId); - gearblock.setTimer(info.Timer, timerOperation, timerMode); + gearblock.setId(info.GearblockId); + gearblock.setTimer(info.Timer, timerOperation, timerMode); - gearblocks.put(location, gearblock); - gearblocksById.put(info.GearblockId, gearblock); - } + gearblocks.put(location, gearblock); + gearblocksById.put(info.GearblockId, gearblock); + } - CastleGates.getPluginLogger().log(Level.INFO, "Loaded gearblocks: " + gearblocks.size()); - CastleGates.getPluginLogger().log(Level.INFO, "Loaded gearblocksById: " + gearblocksById.size()); - CastleGates.getPluginLogger().log(Level.INFO, "Timers: " + timerCount); - } + CastleGates.getPluginLogger().log(Level.INFO, "Loaded gearblocks: " + gearblocks.size()); + CastleGates.getPluginLogger().log(Level.INFO, "Loaded gearblocksById: " + gearblocksById.size()); + CastleGates.getPluginLogger().log(Level.INFO, "Timers: " + timerCount); + } - private void loadLinks(Map linksById, Map gearblocksById) throws SQLException { - int linkCount = _linkSource.countAll(); + private void loadLinks(Map linksById, Map gearblocksById) throws SQLException { + int linkCount = _linkSource.countAll(); - CastleGates.getPluginLogger().log(Level.INFO, "Link count: " + linkCount); + CastleGates.getPluginLogger().log(Level.INFO, "Link count: " + linkCount); - List linkData = _linkSource.selectAll(); - List invalidLinks = new ArrayList<>(); - int drawnLinkCount = 0, brokenLinkCount = 0; + List linkData = _linkSource.selectAll(); + List invalidLinks = new ArrayList<>(); + int drawnLinkCount = 0, brokenLinkCount = 0; - for(LinkInfo info : linkData) { - Gearblock gearblock1 = info.StartGearblockId != null ? gearblocksById.get(info.StartGearblockId) : null; - Gearblock gearblock2 = info.EndGearblockId != null ? gearblocksById.get(info.EndGearblockId) : null; - List blocks = deserializeBlocks(info.Blocks); - GearblockLink link = new GearblockLink(gearblock1, gearblock2); + for (LinkInfo info : linkData) { + Gearblock gearblock1 = info.StartGearblockId != null ? gearblocksById.get(info.StartGearblockId) : null; + Gearblock gearblock2 = info.EndGearblockId != null ? gearblocksById.get(info.EndGearblockId) : null; + List blocks = deserializeBlocks(info.Blocks); + GearblockLink link = new GearblockLink(gearblock1, gearblock2); - link.setId(info.LinkId); - link.setBlocks(blocks); + link.setId(info.LinkId); + link.setBlocks(blocks); - if(gearblock1 != null) { - gearblock1.setLink(link); - } + if (gearblock1 != null) { + gearblock1.setLink(link); + } - if(gearblock2 != null) { - gearblock2.setLink(link); - } + if (gearblock2 != null) { + gearblock2.setLink(link); + } - linksById.put(link.getId(), link); + linksById.put(link.getId(), link); - if(gearblock1 == null && gearblock2 == null) { - invalidLinks.add(info); - } + if (gearblock1 == null && gearblock2 == null) { + invalidLinks.add(info); + } - if(link.isDrawn()) { - drawnLinkCount++; - } + if (link.isDrawn()) { + drawnLinkCount++; + } - if(link.isBroken()) { - brokenLinkCount++; - } - } + if (link.isBroken()) { + brokenLinkCount++; + } + } - CastleGates.getPluginLogger().log(Level.INFO, "Loaded links: " + linkData.size()); + CastleGates.getPluginLogger().log(Level.INFO, "Loaded links: " + linkData.size()); - if(drawnLinkCount > 0) { - CastleGates.getPluginLogger().log(Level.INFO, "Links in DRAWN state: " + drawnLinkCount); - } + if (drawnLinkCount > 0) { + CastleGates.getPluginLogger().log(Level.INFO, "Links in DRAWN state: " + drawnLinkCount); + } - if(brokenLinkCount > 0) { - CastleGates.getPluginLogger().log(Level.INFO, "Links in BROKEN state: " + brokenLinkCount); - } + if (brokenLinkCount > 0) { + CastleGates.getPluginLogger().log(Level.INFO, "Links in BROKEN state: " + brokenLinkCount); + } - if(invalidLinks.size() > 0) { - CastleGates.getPluginLogger().log(Level.WARNING, "Invalid links (i.e. BUG): " + invalidLinks.size()); + if (invalidLinks.size() > 0) { + CastleGates.getPluginLogger().log(Level.WARNING, "Invalid links (i.e. BUG): " + invalidLinks.size()); - String filePath = new InvalidLinkLogger().write(invalidLinks); + String filePath = new InvalidLinkLogger().write(invalidLinks); - CastleGates.getPluginLogger().log(Level.INFO, "List of invalid links saved to: " + filePath); - } - } + CastleGates.getPluginLogger().log(Level.INFO, "List of invalid links saved to: " + filePath); + } + } - private void loadReinforcements(Map linksById) throws SQLException { - List reinforcementData = _reinforcementSource.selectAll(); - GearblockLink link = null; + private void loadReinforcements(Map linksById) throws SQLException { + List reinforcementData = _reinforcementSource.selectAll(); + GearblockLink link = null; - for(ReinforcementInfo info : reinforcementData) { - if(link == null || link.getId() != info.LinkId) { - link = linksById.get(info.LinkId); - } + for (ReinforcementInfo info : reinforcementData) { + if (link == null || link.getId() != info.LinkId) { + link = linksById.get(info.LinkId); + } - BlockState blockState = link.getBlocks().get(info.BlockSequence); - blockState.setReinforcement(info); - } - } + BlockState blockState = link.getBlocks().get(info.BlockSequence); + blockState.setReinforcement(info); + } + } public void startThread() { - _kill.set(false); + _kill.set(false); setName("CastleGates DataWorker Thread"); setPriority(Thread.MIN_PRIORITY); @@ -196,227 +196,225 @@ public class DataWorker extends Thread implements Runnable { public void terminateThread() { _kill.set(true); - while (_run.get()) { - try { - Thread.sleep(100); - } catch (Exception e) { - e.printStackTrace(); - } - } + while (_run.get()) { + try { + Thread.sleep(100); + } catch (Exception e) { + e.printStackTrace(); + } + } - saveData(); + saveData(); - CastleGates.getPluginLogger().log(Level.INFO, "DataWorker thread stopped"); + CastleGates.getPluginLogger().log(Level.INFO, "DataWorker thread stopped"); } public void run() { - _run.set(true); + _run.set(true); - try { - while (!isInterrupted() && !_kill.get()) { - try { - long timeWait = _lastExecute + CastleGates.getConfigManager().getDataWorkerRate() - System.currentTimeMillis(); - _lastExecute = System.currentTimeMillis(); - if (timeWait > 0) { - Thread.sleep(timeWait); - } + try { + while (!isInterrupted() && !_kill.get()) { + try { + long timeWait = _lastExecute + CastleGates.getConfigManager().getDataWorkerRate() - System.currentTimeMillis(); + _lastExecute = System.currentTimeMillis(); + if (timeWait > 0) { + Thread.sleep(timeWait); + } - saveData(); - } catch (Exception e) { - e.printStackTrace(); - } - } - } finally { - _run.set(false); - } + saveData(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } finally { + _run.set(false); + } } private void saveData() { - try { - synchronized (_changedGearblocks) { - _localChangedGearblocks.addAll(_changedGearblocks.values()); - _changedGearblocks.clear(); - } + try { + synchronized (_changedGearblocks) { + _localChangedGearblocks.addAll(_changedGearblocks.values()); + _changedGearblocks.clear(); + } - synchronized (_changedLinks) { - _localChangedLinks.addAll(_changedLinks.values()); - _changedLinks.clear(); - } + synchronized (_changedLinks) { + _localChangedLinks.addAll(_changedLinks.values()); + _changedLinks.clear(); + } - if (_localChangedGearblocks.size() > 0 || _localChangedLinks.size() > 0) { - if (_db.checkConnection()) { - try { - updateGears(); - updateLinks(); - } finally { - _localChangedGearblocks.clear(); - _localChangedLinks.clear(); - } - } - } - } catch (Exception e) { - e.printStackTrace(); - } - } + if (_localChangedGearblocks.size() > 0 || _localChangedLinks.size() > 0) { + if (_db.checkConnection()) { + try { + updateGears(); + updateLinks(); + } finally { + _localChangedGearblocks.clear(); + _localChangedLinks.clear(); + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } private void updateGears() throws SQLException { - for(GearblockForUpdate gearForUpdate : _localChangedGearblocks) { - if(gearForUpdate.original.isRemoved()) { - if(gearForUpdate.original.getId() != 0) { - _gearblockSource.delete(gearForUpdate.original.getId()); - } - } - else if(gearForUpdate.original.getId() != 0) { - _gearblockSource.update(gearForUpdate.info); - } - else { - _gearblockSource.insert(gearForUpdate.info); - gearForUpdate.original.setId(gearForUpdate.info.GearblockId); - } - } + for (GearblockForUpdate gearForUpdate : _localChangedGearblocks) { + if (gearForUpdate.original.isRemoved()) { + if (gearForUpdate.original.getId() != 0) { + _gearblockSource.delete(gearForUpdate.original.getId()); + } + } else if (gearForUpdate.original.getId() != 0) { + _gearblockSource.update(gearForUpdate.info); + } else { + _gearblockSource.insert(gearForUpdate.info); + gearForUpdate.original.setId(gearForUpdate.info.GearblockId); + } + } } private void updateLinks() throws SQLException { - for(LinkForUpdate linkForUpdate : _localChangedLinks) { - if(linkForUpdate.original.isRemoved()) { - if(linkForUpdate.original.getId() != 0) { - _reinforcementSource.deleteByLinkId(linkForUpdate.original.getId()); - _linkSource.delete(linkForUpdate.original.getId()); - } - } else { - LinkInfo info = new LinkInfo(); - info.LinkId = linkForUpdate.original.getId(); - info.StartGearblockId = linkForUpdate.gearblock1 != null ? linkForUpdate.gearblock1.getId(): null; - info.EndGearblockId = linkForUpdate.gearblock2 != null ? linkForUpdate.gearblock2.getId(): null; - info.Blocks = linkForUpdate.blocks; + for (LinkForUpdate linkForUpdate : _localChangedLinks) { + if (linkForUpdate.original.isRemoved()) { + if (linkForUpdate.original.getId() != 0) { + _reinforcementSource.deleteByLinkId(linkForUpdate.original.getId()); + _linkSource.delete(linkForUpdate.original.getId()); + } + } else { + LinkInfo info = new LinkInfo(); + info.LinkId = linkForUpdate.original.getId(); + info.StartGearblockId = linkForUpdate.gearblock1 != null ? linkForUpdate.gearblock1.getId() : null; + info.EndGearblockId = linkForUpdate.gearblock2 != null ? linkForUpdate.gearblock2.getId() : null; + info.Blocks = linkForUpdate.blocks; - if(info.LinkId != 0) { - _linkSource.update(info); + if (info.LinkId != 0) { + _linkSource.update(info); - if(info.Blocks == null) { - _reinforcementSource.deleteByLinkId(info.LinkId); - } - } else { - _linkSource.insert(info); - linkForUpdate.original.setId(info.LinkId); - } + if (info.Blocks == null) { + _reinforcementSource.deleteByLinkId(info.LinkId); + } + } else { + _linkSource.insert(info); + linkForUpdate.original.setId(info.LinkId); + } - if(linkForUpdate.reinforcements != null) { - for(ReinforcementInfo reinforcement : linkForUpdate.reinforcements) { - if(reinforcement.LinkId != 0) continue; + if (linkForUpdate.reinforcements != null) { + for (ReinforcementInfo reinforcement : linkForUpdate.reinforcements) { + if (reinforcement.LinkId != 0) continue; - reinforcement.LinkId = info.LinkId; + reinforcement.LinkId = info.LinkId; - _reinforcementSource.insert(reinforcement); - } - } - } - } + _reinforcementSource.insert(reinforcement); + } + } + } + } } public void addChangedGearblock(Gearblock gearblock) { - GearblockInfo info; + GearblockInfo info; - if(gearblock.isRemoved()) { - info = null; - } else { - info = new GearblockInfo(); + if (gearblock.isRemoved()) { + info = null; + } else { + info = new GearblockInfo(); - BlockCoord location = gearblock.getCoord(); - info.GearblockId = gearblock.getId(); - info.WorldId = location.getWorldUID().toString(); - info.X = location.getX(); - info.Y = location.getY(); - info.Z = location.getZ(); - info.Timer = gearblock.getTimer(); + BlockCoord location = gearblock.getCoord(); + info.GearblockId = gearblock.getId(); + info.WorldId = location.getWorldUID().toString(); + info.X = location.getX(); + info.Y = location.getY(); + info.Z = location.getZ(); + info.Timer = gearblock.getTimer(); - if(gearblock.getTimerOperation() != null) { - switch(gearblock.getTimerOperation()) { - case DRAW -> info.TimerOperation = DRAW_CODE; - case UNDRAW -> info.TimerOperation = UNDRAW_CODE; - case REVERT -> info.TimerOperation = REVERT_CODE; - } + if (gearblock.getTimerOperation() != null) { + switch (gearblock.getTimerOperation()) { + case DRAW -> info.TimerOperation = DRAW_CODE; + case UNDRAW -> info.TimerOperation = UNDRAW_CODE; + case REVERT -> info.TimerOperation = REVERT_CODE; + } - if(gearblock.getTimerMode() == TimerMode.DOOR) { - info.TimerOperation |= MODE_MASK; - } - } - } + if (gearblock.getTimerMode() == TimerMode.DOOR) { + info.TimerOperation |= MODE_MASK; + } + } + } - GearblockForUpdate gearForUpdate = new GearblockForUpdate(); - gearForUpdate.original = gearblock; - gearForUpdate.info = info; + GearblockForUpdate gearForUpdate = new GearblockForUpdate(); + gearForUpdate.original = gearblock; + gearForUpdate.info = info; - synchronized(_changedGearblocks) { - _changedGearblocks.put(gearblock, gearForUpdate); - } - } + synchronized (_changedGearblocks) { + _changedGearblocks.put(gearblock, gearForUpdate); + } + } - public void addChangedLink(GearblockLink link) { - LinkForUpdate linkForUpdate = new LinkForUpdate(); - linkForUpdate.original = link; + public void addChangedLink(GearblockLink link) { + LinkForUpdate linkForUpdate = new LinkForUpdate(); + linkForUpdate.original = link; - if(!link.isRemoved()) { - linkForUpdate.gearblock1 = link.getGearblock1(); - linkForUpdate.gearblock2 = link.getGearblock2(); - linkForUpdate.blocks = serializeBlocks(link); + if (!link.isRemoved()) { + linkForUpdate.gearblock1 = link.getGearblock1(); + linkForUpdate.gearblock2 = link.getGearblock2(); + linkForUpdate.blocks = serializeBlocks(link); - if(link.getBlocks() != null) { - linkForUpdate.reinforcements = new ArrayList<>(); + if (link.getBlocks() != null) { + linkForUpdate.reinforcements = new ArrayList<>(); - for(int i = 0; i < link.getBlocks().size(); i++) { - ReinforcementInfo reinforcement = link.getBlocks().get(i).getReinforcement(); + for (int i = 0; i < link.getBlocks().size(); i++) { + ReinforcementInfo reinforcement = link.getBlocks().get(i).getReinforcement(); - if(reinforcement != null && reinforcement.LinkId == 0) { - reinforcement.BlockSequence = i; - linkForUpdate.reinforcements.add(reinforcement); - } - } - } - } + if (reinforcement != null && reinforcement.LinkId == 0) { + reinforcement.BlockSequence = i; + linkForUpdate.reinforcements.add(reinforcement); + } + } + } + } - synchronized(_changedLinks) { - _changedLinks.put(link, linkForUpdate); - } - } + synchronized (_changedLinks) { + _changedLinks.put(link, linkForUpdate); + } + } - private static String serializeBlocks(GearblockLink link) { - if(link.getBlocks() == null) - return null; + private static String serializeBlocks(GearblockLink link) { + if (link.getBlocks() == null) + return null; - int length = 0; - for(BlockState block : link.getBlocks()) - length += block.getBlockDataLen(); + int length = 0; + for (BlockState block : link.getBlocks()) + length += block.getBlockDataLen(); - StringBuilder blockSerialized = new StringBuilder(length); - for(BlockState block : link.getBlocks()) - block.serialize(blockSerialized); + StringBuilder blockSerialized = new StringBuilder(length); + for (BlockState block : link.getBlocks()) + block.serialize(blockSerialized); - return blockSerialized.toString(); - } + return blockSerialized.toString(); + } - public static List deserializeBlocks(String blockDataList) { - if(blockDataList == null || blockDataList.length() == 0) - return null; + public static List deserializeBlocks(String blockDataList) { + if (blockDataList == null || blockDataList.length() == 0) + return null; - List blocks = new ArrayList<>(); - int len = blockDataList.length(); - int startIndex = 0; - int index = 0; + List blocks = new ArrayList<>(); + int len = blockDataList.length(); + int startIndex = 0; + int index = 0; - while (index < len) { - if (blockDataList.charAt(index) == BlockState.Separator) { - String blockData = blockDataList.substring(startIndex, index); - BlockState block = BlockState.deserialize(blockData); + while (index < len) { + if (blockDataList.charAt(index) == BlockState.Separator) { + String blockData = blockDataList.substring(startIndex, index); + BlockState block = BlockState.deserialize(blockData); - blocks.add(block); + blocks.add(block); - startIndex = index + 1; - } + startIndex = index + 1; + } - index++; - } + index++; + } - return blocks; - } + return blocks; + } } diff --git a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/utils/Helper.java b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/utils/Helper.java index e24359cf0..2c3ad728d 100644 --- a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/utils/Helper.java +++ b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/utils/Helper.java @@ -1,6 +1,5 @@ /** * @author Aleksey Terzi - * */ package com.aleksey.castlegates.utils; @@ -26,69 +25,70 @@ import com.aleksey.castlegates.CastleGates; import com.aleksey.castlegates.types.TimerOperation; public class Helper { - public static int getItemDamage(ItemStack item) { - ItemMeta meta = item.getItemMeta(); - return meta == null ? 0 : ((Damageable) meta).getDamage(); - } - public static boolean isEmptyBlock(Block block) { - Material material = block.getType(); + public static int getItemDamage(ItemStack item) { + ItemMeta meta = item.getItemMeta(); + return meta == null ? 0 : ((Damageable) meta).getDamage(); + } - return material == Material.AIR - || material == Material.WATER - || material == Material.LAVA - ; - } + public static boolean isEmptyBlock(Block block) { + Material material = block.getType(); - public static TimerOperation parseTimerOperation(String name) { - if(name == null) { - return null; - } + return material == Material.AIR + || material == Material.WATER + || material == Material.LAVA + ; + } - return switch(name.toLowerCase()) { - case "draw" -> TimerOperation.DRAW; - case "undraw" -> TimerOperation.UNDRAW; - case "revert" -> TimerOperation.REVERT; - default -> null; - }; - } + public static TimerOperation parseTimerOperation(String name) { + if (name == null) { + return null; + } - public static String getLore(ItemStack item) { - ItemMeta meta = item.getItemMeta(); + return switch (name.toLowerCase()) { + case "draw" -> TimerOperation.DRAW; + case "undraw" -> TimerOperation.UNDRAW; + case "revert" -> TimerOperation.REVERT; + default -> null; + }; + } - if(meta == null || !meta.hasLore()) - return null; + public static String getLore(ItemStack item) { + ItemMeta meta = item.getItemMeta(); - StringBuilder lore = new StringBuilder(); + if (meta == null || !meta.hasLore()) + return null; - for (Component line: meta.lore()) { - if(lore.length() > 0) { - lore.append("\n"); - } + StringBuilder lore = new StringBuilder(); - lore.append(line); - } + for (Component line : meta.lore()) { + if (lore.length() > 0) { + lore.append("\n"); + } - return lore.toString(); - } + lore.append(line); + } - public static void setLore(ItemStack item, String lore) { - if (lore == null || lore.length() == 0) - return; + return lore.toString(); + } - String[] textList = lore.split("\n"); - List loreList = new ArrayList<>(); + public static void setLore(ItemStack item, String lore) { + if (lore == null || lore.length() == 0) + return; - for (String loreText : textList) - loreList.add(Component.text(loreText)); + String[] textList = lore.split("\n"); + List loreList = new ArrayList<>(); - ItemMeta meta = item.getItemMeta(); - meta.lore(loreList); - item.setItemMeta(meta); - } + for (String loreText : textList) + loreList.add(Component.text(loreText)); - public static List getNearbyPlayers(Location location) { - double distance = CastleGates.getCitadelManager().getMaxRedstoneDistance(); + ItemMeta meta = item.getItemMeta(); + meta.lore(loreList); + item.setItemMeta(meta); + } + + public static List getNearbyPlayers(Location location) { + double distance = CastleGates.getCitadelManager().getMaxRedstoneDistance(); double minX = location.getX() - distance; double minZ = location.getZ() - distance; double maxX = location.getX() + distance; @@ -97,18 +97,17 @@ public class Helper { List players = new ArrayList<>(); for (Player player : Bukkit.getOnlinePlayers()) { - if (player.isDead()) continue; + if (player.isDead()) continue; Location playerLocation = player.getLocation(); - if(!playerLocation.getWorld().equals(location.getWorld())) continue; + if (!playerLocation.getWorld().equals(location.getWorld())) continue; double playerX = playerLocation.getX(); double playerZ = playerLocation.getZ(); if (playerX < minX || playerX > maxX - || playerZ < minZ || playerZ > maxZ) - { + || playerZ < minZ || playerZ > maxZ) { continue; } @@ -120,78 +119,77 @@ public class Helper { } return players; - } + } - public static List getConsumeSlots(Player player, ItemStack consumeItem) { - if(consumeItem == null) return null; + public static List getConsumeSlots(Player player, ItemStack consumeItem) { + if (consumeItem == null) return null; - List list = new ArrayList<>(); - PlayerInventory inventory = player.getInventory(); - int inventorySize = inventory.getSize(); - int requiredAmount = consumeItem.getAmount(); + List list = new ArrayList<>(); + PlayerInventory inventory = player.getInventory(); + int inventorySize = inventory.getSize(); + int requiredAmount = consumeItem.getAmount(); - try { - for(int i = 0; i < inventorySize && requiredAmount > 0; i++) { - ItemStack item = inventory.getItem(i); + try { + for (int i = 0; i < inventorySize && requiredAmount > 0; i++) { + ItemStack item = inventory.getItem(i); - if(item == null || !consumeItem.isSimilar(item)) { - continue; - } + if (item == null || !consumeItem.isSimilar(item)) { + continue; + } - list.add(i); + list.add(i); - requiredAmount -= item.getAmount(); - } + requiredAmount -= item.getAmount(); + } } catch (Exception ex) { } - return requiredAmount > 0 ? null :list; - } + return requiredAmount > 0 ? null : list; + } - public static void consumeItem(Player player, ItemStack consumeItem, List list) { - if(list == null) - return; + public static void consumeItem(Player player, ItemStack consumeItem, List list) { + if (list == null) + return; - PlayerInventory inventory = player.getInventory(); - int requiredAmount = consumeItem.getAmount(); + PlayerInventory inventory = player.getInventory(); + int requiredAmount = consumeItem.getAmount(); - for(int i = 0; i < list.size() && requiredAmount > 0; i++) { - int slot = list.get(i); - ItemStack item = inventory.getItem(slot); - int itemAmount = item.getAmount(); - int amountToRemove = Math.min(itemAmount, requiredAmount); + for (int i = 0; i < list.size() && requiredAmount > 0; i++) { + int slot = list.get(i); + ItemStack item = inventory.getItem(slot); + int itemAmount = item.getAmount(); + int amountToRemove = Math.min(itemAmount, requiredAmount); - if(itemAmount > amountToRemove) { - item.setAmount(itemAmount - amountToRemove); - } else { - inventory.clear(slot); - } + if (itemAmount > amountToRemove) { + item.setAmount(itemAmount - amountToRemove); + } else { + inventory.clear(slot); + } - requiredAmount -= amountToRemove; - } - } + requiredAmount -= amountToRemove; + } + } - public static void putItemToInventoryOrDrop(Player player, Location dropLocation, ItemStack dropItem) { - if (player != null){ + public static void putItemToInventoryOrDrop(Player player, Location dropLocation, ItemStack dropItem) { + if (player != null) { Inventory inv = player.getInventory(); - for(ItemStack leftover : inv.addItem(dropItem).values()) { - dropItemAtLocation(dropLocation, leftover); + for (ItemStack leftover : inv.addItem(dropItem).values()) { + dropItemAtLocation(dropLocation, leftover); } + } else { + dropItemAtLocation(dropLocation, dropItem); } - else { - dropItemAtLocation(dropLocation, dropItem); - } - } + } - private static void dropItemAtLocation(final Location dropLocation, final ItemStack dropItem) { - Bukkit.getScheduler().scheduleSyncDelayedTask(CastleGates.getInstance(), () -> { - try { - Location newDropLocation = dropLocation.add(0.5, 0.5, 0.5); - dropLocation.getWorld().dropItem(newDropLocation, dropItem).setVelocity(new Vector(0, 0.05, 0)); - } catch (Exception e) { - CastleGates.getPluginLogger().log(Level.WARNING, "dropItemAtLocation called but errored: ", e); - } - }, 1); - } + private static void dropItemAtLocation(final Location dropLocation, final ItemStack dropItem) { + Bukkit.getScheduler().scheduleSyncDelayedTask(CastleGates.getInstance(), () -> { + try { + Location newDropLocation = dropLocation.add(0.5, 0.5, 0.5); + dropLocation.getWorld().dropItem(newDropLocation, dropItem).setVelocity(new Vector(0, 0.05, 0)); + } catch (Exception e) { + CastleGates.getPluginLogger().log(Level.WARNING, "dropItemAtLocation called but errored: ", e); + } + }, 1); + } } diff --git a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/utils/InvalidLinkLogger.java b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/utils/InvalidLinkLogger.java index 901c501fb..35a45324b 100644 --- a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/utils/InvalidLinkLogger.java +++ b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/utils/InvalidLinkLogger.java @@ -16,6 +16,7 @@ import java.util.Date; import java.util.List; public class InvalidLinkLogger { + private static final DateFormat fileDateFormat = new SimpleDateFormat("yyyy_MM_dd_HHmmss"); private static final String folderName = "castlegates_logs"; @@ -26,13 +27,12 @@ public class InvalidLinkLogger { PrintWriter writer = getWriter(); try { - for(LinkInfo link : links) { + for (LinkInfo link : links) { writeLink(link, writer); } } catch (Exception e) { e.printStackTrace(); - } - finally { + } finally { writer.flush(); writer.close(); } @@ -59,7 +59,7 @@ public class InvalidLinkLogger { private PrintWriter getWriter() throws FileNotFoundException { File folder = new File(folderName); - if(!folder.exists()) + if (!folder.exists()) folder.mkdirs(); _filePath = folder + "/InvalidLinks_" + fileDateFormat.format(new Date()) + ".txt"; @@ -67,7 +67,7 @@ public class InvalidLinkLogger { File file = new File(_filePath); return file.exists() - ? new PrintWriter(new FileOutputStream(file, true)) - : new PrintWriter(_filePath); + ? new PrintWriter(new FileOutputStream(file, true)) + : new PrintWriter(_filePath); } } diff --git a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/utils/ParticleHelper.java b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/utils/ParticleHelper.java index 1aa7662ac..6ad581b54 100644 --- a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/utils/ParticleHelper.java +++ b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/utils/ParticleHelper.java @@ -9,29 +9,30 @@ import com.aleksey.castlegates.types.BlockCoord; import com.aleksey.castlegates.types.Gearblock; public class ParticleHelper { - public enum Type { Info, Warning } - public static void spawn(Player player, Gearblock gearblock, Type type) { - BlockCoord coord = gearblock.getCoord(); - Location location = new Location(player.getWorld(), 0.5 + coord.getX(), 0.5 + coord.getY(), 0.5 + coord.getZ()); + public enum Type {Info, Warning} - spawn(location, type); - } + public static void spawn(Player player, Gearblock gearblock, Type type) { + BlockCoord coord = gearblock.getCoord(); + Location location = new Location(player.getWorld(), 0.5 + coord.getX(), 0.5 + coord.getY(), 0.5 + coord.getZ()); - public static void spawn(Block block, Type type) { - Location location = new Location(block.getWorld(), 0.5 + block.getX(), 0.5 + block.getY(), 0.5 + block.getZ()); + spawn(location, type); + } - spawn(location, type); - } + public static void spawn(Block block, Type type) { + Location location = new Location(block.getWorld(), 0.5 + block.getX(), 0.5 + block.getY(), 0.5 + block.getZ()); - public static void spawn(Location location, Type type) { - final Particle particle = type == Type.Info ? Particle.ENCHANTMENT_TABLE: Particle.EXPLOSION_NORMAL; - final float offsetX = 0; - final float offsetY = 0; - final float offsetZ = 0; - final float speed = 0.5f; - final int particleCount = 80; + spawn(location, type); + } - location.getWorld().spawnParticle(particle, location, particleCount, offsetX, offsetY, offsetZ, speed, null); - } + public static void spawn(Location location, Type type) { + final Particle particle = type == Type.Info ? Particle.ENCHANTMENT_TABLE : Particle.EXPLOSION_NORMAL; + final float offsetX = 0; + final float offsetY = 0; + final float offsetZ = 0; + final float speed = 0.5f; + final int particleCount = 80; + + location.getWorld().spawnParticle(particle, location, particleCount, offsetX, offsetY, offsetZ, speed, null); + } } diff --git a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/utils/PowerResultHelper.java b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/utils/PowerResultHelper.java index 9a37c7136..97382d01a 100644 --- a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/utils/PowerResultHelper.java +++ b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/utils/PowerResultHelper.java @@ -11,79 +11,79 @@ import org.bukkit.entity.Player; import com.aleksey.castlegates.types.PowerResult; public class PowerResultHelper { - public static void showStatus(Location location, List players, PowerResult result) { - String message = switch(result.status) { - case Blocked -> getBlockedMessage(result); - case Broken -> getBrokenMessage(result); - case CannotDrawGear -> getCannotDrawGearMessage(result); - case NotInCitadelGroup -> ChatColor.RED + "Citadel has prevented that operation."; - case DifferentCitadelGroup -> ChatColor.RED + "All blocks must be reinforced by the same group."; - case BastionBlocked -> ChatColor.RED + "A bastion has prevented the bridge/gate from undrawing."; - case Locked -> ChatColor.RED + "The gearblock is locked."; - default -> null; - }; - if(message != null) { - for(Player player : players) { - player.sendMessage(message); - } - } - else if(result.status == PowerResult.Status.Drawn || result.status == PowerResult.Status.Undrawn){ - playSound(location, result.status); - } + public static void showStatus(Location location, List players, PowerResult result) { + String message = switch (result.status) { + case Blocked -> getBlockedMessage(result); + case Broken -> getBrokenMessage(result); + case CannotDrawGear -> getCannotDrawGearMessage(result); + case NotInCitadelGroup -> ChatColor.RED + "Citadel has prevented that operation."; + case DifferentCitadelGroup -> ChatColor.RED + "All blocks must be reinforced by the same group."; + case BastionBlocked -> ChatColor.RED + "A bastion has prevented the bridge/gate from undrawing."; + case Locked -> ChatColor.RED + "The gearblock is locked."; + default -> null; + }; - if(result.block != null) { - ParticleHelper.spawn(result.block, ParticleHelper.Type.Warning); - } - } + if (message != null) { + for (Player player : players) { + player.sendMessage(message); + } + } else if (result.status == PowerResult.Status.Drawn || result.status == PowerResult.Status.Undrawn) { + playSound(location, result.status); + } - public static void playSound(Location location, PowerResult.Status status) { - Sound sound = status == PowerResult.Status.Drawn - ? Sound.BLOCK_PISTON_CONTRACT - : Sound.BLOCK_PISTON_EXTEND; + if (result.block != null) { + ParticleHelper.spawn(result.block, ParticleHelper.Type.Warning); + } + } - location.getWorld().playSound(location, sound, 0.7f, 1); - } + public static void playSound(Location location, PowerResult.Status status) { + Sound sound = status == PowerResult.Status.Drawn + ? Sound.BLOCK_PISTON_CONTRACT + : Sound.BLOCK_PISTON_EXTEND; - private static String getBlockedMessage(PowerResult result) { - Location location = result.block.getLocation(); + location.getWorld().playSound(location, sound, 0.7f, 1); + } - return ChatColor.RED + - "The bridge/gate undraw path is blocked at [" + location.getBlockX() + - " " + location.getBlockY() + - " " + location.getBlockZ() + - "]." - ; - } + private static String getBlockedMessage(PowerResult result) { + Location location = result.block.getLocation(); - private static String getBrokenMessage(PowerResult result) { - Location location = result.block.getLocation(); + return ChatColor.RED + + "The bridge/gate undraw path is blocked at [" + location.getBlockX() + + " " + location.getBlockY() + + " " + location.getBlockZ() + + "]." + ; + } - if(result.block.getType() == Material.AIR) { - return ChatColor.RED + - "The bridge/gate is broken at [" + location.getBlockX() + - " " + location.getBlockY() + - " " + location.getBlockZ() + - "]." - ; - } + private static String getBrokenMessage(PowerResult result) { + Location location = result.block.getLocation(); - return ChatColor.RED + - "The " + result.block.getType() + " block at [" + location.getBlockX() + - " " + location.getBlockY() + - " " + location.getBlockZ() + - "] is not allowed to be used as a part of bridges/gates." - ; - } + if (result.block.getType() == Material.AIR) { + return ChatColor.RED + + "The bridge/gate is broken at [" + location.getBlockX() + + " " + location.getBlockY() + + " " + location.getBlockZ() + + "]." + ; + } - private static String getCannotDrawGearMessage(PowerResult result) { - Location location = result.block.getLocation(); + return ChatColor.RED + + "The " + result.block.getType() + " block at [" + location.getBlockX() + + " " + location.getBlockY() + + " " + location.getBlockZ() + + "] is not allowed to be used as a part of bridges/gates." + ; + } - return ChatColor.RED + - "The gearblock at [" + location.getBlockX() + - " " + location.getBlockY() + - " " + location.getBlockZ() + - "] is not allowed to be used as a part of bridges/gates." - ; - } + private static String getCannotDrawGearMessage(PowerResult result) { + Location location = result.block.getLocation(); + + return ChatColor.RED + + "The gearblock at [" + location.getBlockX() + + " " + location.getBlockY() + + " " + location.getBlockZ() + + "] is not allowed to be used as a part of bridges/gates." + ; + } } diff --git a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/utils/ResourceHelper.java b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/utils/ResourceHelper.java index 597b37a4d..470c9837e 100644 --- a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/utils/ResourceHelper.java +++ b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/utils/ResourceHelper.java @@ -1,6 +1,5 @@ /** * @author Aleksey Terzi - * */ package com.aleksey.castlegates.utils; @@ -14,38 +13,38 @@ import java.util.ArrayList; import com.aleksey.castlegates.CastleGates; public class ResourceHelper { - public static ArrayList readScriptList(String resourcePath) { - InputStream stream = CastleGates.class.getResourceAsStream(resourcePath); - if(stream == null) - return null; + public static ArrayList readScriptList(String resourcePath) { + InputStream stream = CastleGates.class.getResourceAsStream(resourcePath); - StringBuilder script = new StringBuilder(); - ArrayList list = new ArrayList<>(); + if (stream == null) + return null; - try { - BufferedReader reader = new BufferedReader(new InputStreamReader(stream)); - String line; + StringBuilder script = new StringBuilder(); + ArrayList list = new ArrayList<>(); + + try { + BufferedReader reader = new BufferedReader(new InputStreamReader(stream)); + String line; while ((line = reader.readLine()) != null) { - if(line.endsWith(";")) { - script.append(line); - list.add(script.toString()); - script.delete(0, script.length()); - } - else { - script.append(line); - script.append("\n"); - } + if (line.endsWith(";")) { + script.append(line); + list.add(script.toString()); + script.delete(0, script.length()); + } else { + script.append(line); + script.append("\n"); + } } - if(script.length() > 0) { - list.add(script.toString()); + if (script.length() > 0) { + list.add(script.toString()); } - } catch (IOException e) { - e.printStackTrace(); - } + } catch (IOException e) { + e.printStackTrace(); + } - return list; - } + return list; + } } diff --git a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/utils/TimerWorker.java b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/utils/TimerWorker.java index a6427e3c6..2a05b98fd 100644 --- a/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/utils/TimerWorker.java +++ b/plugins/castlegates-paper/src/main/java/com/aleksey/castlegates/utils/TimerWorker.java @@ -1,6 +1,5 @@ /** * @author Aleksey Terzi - * */ package com.aleksey.castlegates.utils; @@ -18,17 +17,18 @@ import com.aleksey.castlegates.types.Gearblock; import com.aleksey.castlegates.types.TimerBatch; public class TimerWorker extends Thread implements Runnable { - private BridgeManager _bridgeManager; - private List _batches; - private long _lastExecute = System.currentTimeMillis(); + private BridgeManager _bridgeManager; + private List _batches; + + private long _lastExecute = System.currentTimeMillis(); private AtomicBoolean _kill = new AtomicBoolean(false); private AtomicBoolean _run = new AtomicBoolean(false); public TimerWorker(BridgeManager bridgeManager) { - _bridgeManager = bridgeManager; - _batches = new ArrayList(); - } + _bridgeManager = bridgeManager; + _batches = new ArrayList(); + } public void startThread() { _kill.set(false); @@ -111,23 +111,23 @@ public class TimerWorker extends Thread implements Runnable { } private void runBatch(final TimerBatch batch) { - final BridgeManager bridgeManager = _bridgeManager; + final BridgeManager bridgeManager = _bridgeManager; - CastleGates.runTask(new Runnable() { + CastleGates.runTask(new Runnable() { public void run() { - if(!batch.isInvalid() && bridgeManager.processTimerBatch(batch)) { - BlockCoord blockCoord = batch.getGearblock().getCoord(); - Location location = new Location(batch.getWorld(), blockCoord.getX(), blockCoord.getY(), blockCoord.getZ()); + if (!batch.isInvalid() && bridgeManager.processTimerBatch(batch)) { + BlockCoord blockCoord = batch.getGearblock().getCoord(); + Location location = new Location(batch.getWorld(), blockCoord.getX(), blockCoord.getY(), blockCoord.getZ()); - PowerResultHelper.playSound(location, batch.getProcessStatus()); - } + PowerResultHelper.playSound(location, batch.getProcessStatus()); + } } }); } public void addBatch(TimerBatch batch) { - synchronized(_batches) { - _batches.add(batch); - } - } + synchronized (_batches) { + _batches.add(batch); + } + } } diff --git a/plugins/castlegates-paper/src/main/resources/plugin.yml b/plugins/castlegates-paper/src/main/resources/plugin.yml index a645bd745..eeeb5cce5 100644 --- a/plugins/castlegates-paper/src/main/resources/plugin.yml +++ b/plugins/castlegates-paper/src/main/resources/plugin.yml @@ -4,17 +4,17 @@ version: ${version} author: Aleksey-Terzi description: 'Drawable gates and bridges' api-version: 1.17 -softdepend: [NameLayer, Citadel, Bastion, JukeAlert] +softdepend: [ NameLayer, Citadel, Bastion, JukeAlert ] commands: - cg: - description: Manage Castle Gates. - usage: | - / normal - Normal mode - / create - Create gear block mode - / link - Link gears mode - / timer [ []] [door] - Set timer mode - / info - Information mode - gear: - description: Create gear block mode - link: - description: Create link block mode \ No newline at end of file + cg: + description: Manage Castle Gates. + usage: | + / normal - Normal mode + / create - Create gear block mode + / link - Link gears mode + / timer [ []] [door] - Set timer mode + / info - Information mode + gear: + description: Create gear block mode + link: + description: Create link block mode diff --git a/plugins/citadel-paper/build.gradle.kts b/plugins/citadel-paper/build.gradle.kts index ddc80c1a7..a142cd607 100644 --- a/plugins/citadel-paper/build.gradle.kts +++ b/plugins/citadel-paper/build.gradle.kts @@ -1,15 +1,15 @@ plugins { - id("io.papermc.paperweight.userdev") + id("io.papermc.paperweight.userdev") } version = "5.2.4" dependencies { - paperweight { - paperDevBundle("1.20.4-R0.1-SNAPSHOT") - } + paperweight { + paperDevBundle("1.20.4-R0.1-SNAPSHOT") + } - compileOnly(project(":plugins:civmodcore-paper")) - compileOnly(project(":plugins:namelayer-paper")) - compileOnly("com.gmail.filoghost.holographicdisplays:holographicdisplays-api:2.4.9") + compileOnly(project(":plugins:civmodcore-paper")) + compileOnly(project(":plugins:namelayer-paper")) + compileOnly("com.gmail.filoghost.holographicdisplays:holographicdisplays-api:2.4.9") } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/Citadel.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/Citadel.java index 10f758b74..2f48d8461 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/Citadel.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/Citadel.java @@ -29,148 +29,148 @@ import vg.civcraft.mc.civmodcore.world.locations.chunkmeta.block.table.TableStor public class Citadel extends ACivMod { - private static Citadel instance; + private static Citadel instance; - public static Citadel getInstance() { - return instance; - } + public static Citadel getInstance() { + return instance; + } - private Logger logger; - private ReinforcementManager reinManager; - private CitadelConfigManager config; - private AcidManager acidManager; - private ReinforcementTypeManager typeManager; - private HologramManager holoManager; - private CitadelSettingManager settingManager; - private CitadelDAO dao; - private ActivityMap activityMap; - private CitadelCommandManager commandManager; + private Logger logger; + private ReinforcementManager reinManager; + private CitadelConfigManager config; + private AcidManager acidManager; + private ReinforcementTypeManager typeManager; + private HologramManager holoManager; + private CitadelSettingManager settingManager; + private CitadelDAO dao; + private ActivityMap activityMap; + private CitadelCommandManager commandManager; - private PlayerStateManager stateManager; + private PlayerStateManager stateManager; - /** - * @return Acid block manager - */ - public AcidManager getAcidManager() { - return acidManager; - } + /** + * @return Acid block manager + */ + public AcidManager getAcidManager() { + return acidManager; + } - public CitadelConfigManager getConfigManager() { - return config; - } + public CitadelConfigManager getConfigManager() { + return config; + } - public ReinforcementManager getReinforcementManager() { - return reinManager; - } + public ReinforcementManager getReinforcementManager() { + return reinManager; + } - public ReinforcementTypeManager getReinforcementTypeManager() { - return typeManager; - } + public ReinforcementTypeManager getReinforcementTypeManager() { + return typeManager; + } - public CitadelSettingManager getSettingManager() { - return settingManager; - } + public CitadelSettingManager getSettingManager() { + return settingManager; + } - public PlayerStateManager getStateManager() { - return stateManager; - } + public PlayerStateManager getStateManager() { + return stateManager; + } - public HologramManager getHologramManager() { - return holoManager; - } + public HologramManager getHologramManager() { + return holoManager; + } - public ActivityMap getActivityMap() { - return activityMap; - } - - CitadelDAO getDAO() { - return dao; - } + public ActivityMap getActivityMap() { + return activityMap; + } - @Override - public void onDisable() { - activityMap.disable(); - dao.setBatchMode(true); - reinManager.shutDown(); - dao.cleanupBatches(); - HandlerList.unregisterAll(this); - Bukkit.getScheduler().cancelTasks(this); - } + CitadelDAO getDAO() { + return dao; + } - public void reload() { - onDisable(); - onEnable(); - } + @Override + public void onDisable() { + activityMap.disable(); + dao.setBatchMode(true); + reinManager.shutDown(); + dao.cleanupBatches(); + HandlerList.unregisterAll(this); + Bukkit.getScheduler().cancelTasks(this); + } - @Override - public void onEnable() { - super.onEnable(); - instance = this; - logger = getLogger(); - if (!Bukkit.getPluginManager().isPluginEnabled("NameLayer")) { - logger.info("Citadel is shutting down because it could not find NameLayer"); - Bukkit.shutdown(); - return; - } - config = new CitadelConfigManager(this); - if (!config.parse()) { - logger.severe("Errors in config file, shutting down"); - Bukkit.shutdown(); - return; - } - typeManager = new ReinforcementTypeManager(); - config.getReinforcementTypes().forEach(t -> - { - if (!typeManager.register(t)) { - logger.severe("Errors in the config file, shutting down"); - Bukkit.shutdown(); - return; - } - }); - dao = new CitadelDAO(this.logger, config.getDatabase()); - if (!dao.updateDatabase()) { - logger.severe("Errors setting up database, shutting down"); - Bukkit.shutdown(); - return; - } + public void reload() { + onDisable(); + onEnable(); + } - activityMap = new ActivityMap(this.logger, config.getDatabase()); - activityMap.enable(); + @Override + public void onEnable() { + super.onEnable(); + instance = this; + logger = getLogger(); + if (!Bukkit.getPluginManager().isPluginEnabled("NameLayer")) { + logger.info("Citadel is shutting down because it could not find NameLayer"); + Bukkit.shutdown(); + return; + } + config = new CitadelConfigManager(this); + if (!config.parse()) { + logger.severe("Errors in config file, shutting down"); + Bukkit.shutdown(); + return; + } + typeManager = new ReinforcementTypeManager(); + config.getReinforcementTypes().forEach(t -> + { + if (!typeManager.register(t)) { + logger.severe("Errors in the config file, shutting down"); + Bukkit.shutdown(); + return; + } + }); + dao = new CitadelDAO(this.logger, config.getDatabase()); + if (!dao.updateDatabase()) { + logger.severe("Errors setting up database, shutting down"); + Bukkit.shutdown(); + return; + } - BlockBasedChunkMetaView> chunkMetaData = - ChunkMetaAPI.registerBlockBasedPlugin(this, () -> new CitadelChunkData(false, dao),dao, true); - if (chunkMetaData == null) { - logger.severe("Errors setting up chunk metadata API, shutting down"); - Bukkit.shutdown(); - return; - } - reinManager = new ReinforcementManager(chunkMetaData); - stateManager = new PlayerStateManager(); - acidManager = new AcidManager(config.getAcidTypes()); - settingManager = new CitadelSettingManager(); - Bukkit.getScheduler().scheduleSyncDelayedTask(this, () -> { - if (Bukkit.getPluginManager().isPluginEnabled("HolographicDisplays")) { - holoManager = new HologramManager(settingManager); - logger.info("HolographicDisplays is loaded, holograms available"); - } - else { - logger.info("HolographicDisplays is not loaded, no holograms available"); - }}); - commandManager = new CitadelCommandManager(this); - CitadelPermissionHandler.setup(); - registerListeners(); - } + activityMap = new ActivityMap(this.logger, config.getDatabase()); + activityMap.enable(); - /** - * Registers the listeners for Citadel. - */ - private void registerListeners() { - getServer().getPluginManager().registerEvents(new BlockListener(this), this); - getServer().getPluginManager().registerEvents(new EntityListener(), this); - getServer().getPluginManager().registerEvents(new InventoryListener(), this); - getServer().getPluginManager().registerEvents(new ModeListener(this), this); - getServer().getPluginManager().registerEvents(new RedstoneListener(config.getMaxRedstoneDistance()), this); - getServer().getPluginManager().registerEvents(new ActivityListener(activityMap), this); - getServer().getPluginManager().registerEvents(new WorldBorderListener(), this); - } + BlockBasedChunkMetaView> chunkMetaData = + ChunkMetaAPI.registerBlockBasedPlugin(this, () -> new CitadelChunkData(false, dao), dao, true); + if (chunkMetaData == null) { + logger.severe("Errors setting up chunk metadata API, shutting down"); + Bukkit.shutdown(); + return; + } + reinManager = new ReinforcementManager(chunkMetaData); + stateManager = new PlayerStateManager(); + acidManager = new AcidManager(config.getAcidTypes()); + settingManager = new CitadelSettingManager(); + Bukkit.getScheduler().scheduleSyncDelayedTask(this, () -> { + if (Bukkit.getPluginManager().isPluginEnabled("HolographicDisplays")) { + holoManager = new HologramManager(settingManager); + logger.info("HolographicDisplays is loaded, holograms available"); + } else { + logger.info("HolographicDisplays is not loaded, no holograms available"); + } + }); + commandManager = new CitadelCommandManager(this); + CitadelPermissionHandler.setup(); + registerListeners(); + } + + /** + * Registers the listeners for Citadel. + */ + private void registerListeners() { + getServer().getPluginManager().registerEvents(new BlockListener(this), this); + getServer().getPluginManager().registerEvents(new EntityListener(), this); + getServer().getPluginManager().registerEvents(new InventoryListener(), this); + getServer().getPluginManager().registerEvents(new ModeListener(this), this); + getServer().getPluginManager().registerEvents(new RedstoneListener(config.getMaxRedstoneDistance()), this); + getServer().getPluginManager().registerEvents(new ActivityListener(activityMap), this); + getServer().getPluginManager().registerEvents(new WorldBorderListener(), this); + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/CitadelConfigManager.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/CitadelConfigManager.java index f4a579a0a..8de07f66e 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/CitadelConfigManager.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/CitadelConfigManager.java @@ -30,300 +30,300 @@ import vg.civcraft.mc.civmodcore.utilities.TextUtil; public class CitadelConfigManager extends ConfigParser { - private ManagedDatasource database; - private List reinforcementTypes; - private List acidTypes; + private ManagedDatasource database; + private List reinforcementTypes; + private List acidTypes; - private List globalBlackList; + private List globalBlackList; - private boolean logHostileBreaks; - private boolean logFriendlyBreaks; - private boolean logDamage; - private boolean logCreation; - private boolean logMessages; + private boolean logHostileBreaks; + private boolean logFriendlyBreaks; + private boolean logDamage; + private boolean logCreation; + private boolean logMessages; - private long globalDecayTimer; - private double globalDecayMultiplier; + private long globalDecayTimer; + private double globalDecayMultiplier; - private double redstoneRange; + private double redstoneRange; - private boolean hangersInheritReinforcements; + private boolean hangersInheritReinforcements; - private int activityMapResolution; - private int activityMapRadius; - private long activityEntryRefreshAfterMs; - private long activityRadiusRefreshAfterMs; + private int activityMapResolution; + private int activityMapRadius; + private long activityEntryRefreshAfterMs; + private long activityRadiusRefreshAfterMs; - private long activityDefault; - private List activityWorlds; + private long activityDefault; + private List activityWorlds; - private Map buffers; + private Map buffers; - public CitadelConfigManager(ACivMod plugin) { - super(plugin); - } + public CitadelConfigManager(ACivMod plugin) { + super(plugin); + } - public int getActivityMapRadius() { - return activityMapRadius; - } + public int getActivityMapRadius() { + return activityMapRadius; + } - public int getActivityMapResolution() { - return activityMapResolution; - } + public int getActivityMapResolution() { + return activityMapResolution; + } - public long getActivityEntryRefreshAfterMs() { - return activityEntryRefreshAfterMs; - } + public long getActivityEntryRefreshAfterMs() { + return activityEntryRefreshAfterMs; + } - public long getActivityRadiusRefreshAfterMs() { - return activityRadiusRefreshAfterMs; - } + public long getActivityRadiusRefreshAfterMs() { + return activityRadiusRefreshAfterMs; + } - public long getActivityDefault() { - return activityDefault; - } + public long getActivityDefault() { + return activityDefault; + } - public List getActivityWorlds() { - return activityWorlds; - } + public List getActivityWorlds() { + return activityWorlds; + } - public List getBlacklistedMaterials() { - return globalBlackList; - } + public List getBlacklistedMaterials() { + return globalBlackList; + } - public ManagedDatasource getDatabase() { - return database; - } + public ManagedDatasource getDatabase() { + return database; + } - public double getMaxRedstoneDistance() { - return redstoneRange; - } + public double getMaxRedstoneDistance() { + return redstoneRange; + } - public boolean doHangersInheritReinforcements() { - return hangersInheritReinforcements; - } + public boolean doHangersInheritReinforcements() { + return hangersInheritReinforcements; + } - public Map getWorldBorderBuffers() { - return Collections.unmodifiableMap(this.buffers); - } + public Map getWorldBorderBuffers() { + return Collections.unmodifiableMap(this.buffers); + } - private ReinforcementEffect getReinforcementEffect(ConfigurationSection config) { - if (config == null) { - return null; - } - Particle effect; - try { - String effectName = config.getString("type"); - effect = Particle.valueOf(effectName); - } catch (IllegalArgumentException e) { - logger.warning("Invalid effect at: " + config.getCurrentPath()); - return null; - } - float offSet = (float) config.getDouble("offset", 0); - float offsetX = (float) config.getDouble("offsetX", offSet); - float offsetY = (float) config.getDouble("offsetY", offSet); - float offsetZ = (float) config.getDouble("offsetZ", offSet); - float speed = (float) config.getDouble("speed", 1); - int amount = config.getInt("particleCount", 50); - return new ReinforcementEffect(effect, offsetX, offsetY, offsetZ, speed, amount); - } + private ReinforcementEffect getReinforcementEffect(ConfigurationSection config) { + if (config == null) { + return null; + } + Particle effect; + try { + String effectName = config.getString("type"); + effect = Particle.valueOf(effectName); + } catch (IllegalArgumentException e) { + logger.warning("Invalid effect at: " + config.getCurrentPath()); + return null; + } + float offSet = (float) config.getDouble("offset", 0); + float offsetX = (float) config.getDouble("offsetX", offSet); + float offsetY = (float) config.getDouble("offsetY", offSet); + float offsetZ = (float) config.getDouble("offsetZ", offSet); + float speed = (float) config.getDouble("speed", 1); + int amount = config.getInt("particleCount", 50); + return new ReinforcementEffect(effect, offsetX, offsetY, offsetZ, speed, amount); + } - public List getReinforcementTypes() { - return reinforcementTypes; - } + public List getReinforcementTypes() { + return reinforcementTypes; + } - public List getAcidTypes() { - return acidTypes; - } + public List getAcidTypes() { + return acidTypes; + } - public boolean logCreation() { - return logCreation; - } + public boolean logCreation() { + return logCreation; + } - public boolean logDamage() { - return logDamage; - } + public boolean logDamage() { + return logDamage; + } - public boolean logFriendlyBreaks() { - return logFriendlyBreaks; - } + public boolean logFriendlyBreaks() { + return logFriendlyBreaks; + } - public boolean logHostileBreaks() { - return logHostileBreaks; - } + public boolean logHostileBreaks() { + return logHostileBreaks; + } - public boolean logMessages() { - return logMessages; - } + public boolean logMessages() { + return logMessages; + } - @Override - protected boolean parseInternal(ConfigurationSection config) { - database = ManagedDatasource.construct((ACivMod) plugin, (DatabaseCredentials) config.get("database")); - globalBlackList = ConfigHelper.parseMaterialList(config, "non_reinforceables"); - logHostileBreaks = config.getBoolean("logHostileBreaks", true); - logFriendlyBreaks = config.getBoolean("logFriendlyBreaks", true); - logDamage = config.getBoolean("logDamage", false); - logCreation = config.getBoolean("logCreation", true); - logMessages = config.getBoolean("logMessages", true); - redstoneRange = config.getDouble("redstoneDistance", 3); - globalDecayMultiplier = config.getDouble("global_decay_multiplier", 2.0); - globalDecayTimer = ConfigHelper.parseTime(config.getString("global_decay_timer", "0")); - parseReinforcementTypes(config.getConfigurationSection("reinforcements")); - parseAcidTypes(config.getConfigurationSection("acids")); - hangersInheritReinforcements = config.getBoolean("hangers_inherit_reinforcement", false); + @Override + protected boolean parseInternal(ConfigurationSection config) { + database = ManagedDatasource.construct((ACivMod) plugin, (DatabaseCredentials) config.get("database")); + globalBlackList = ConfigHelper.parseMaterialList(config, "non_reinforceables"); + logHostileBreaks = config.getBoolean("logHostileBreaks", true); + logFriendlyBreaks = config.getBoolean("logFriendlyBreaks", true); + logDamage = config.getBoolean("logDamage", false); + logCreation = config.getBoolean("logCreation", true); + logMessages = config.getBoolean("logMessages", true); + redstoneRange = config.getDouble("redstoneDistance", 3); + globalDecayMultiplier = config.getDouble("global_decay_multiplier", 2.0); + globalDecayTimer = ConfigHelper.parseTime(config.getString("global_decay_timer", "0")); + parseReinforcementTypes(config.getConfigurationSection("reinforcements")); + parseAcidTypes(config.getConfigurationSection("acids")); + hangersInheritReinforcements = config.getBoolean("hangers_inherit_reinforcement", false); - activityMapRadius = config.getInt("activity-map-radius", 1); - activityMapResolution = config.getInt("activity-map-resolution", 512); - activityEntryRefreshAfterMs = config.getLong("activity-entry-refresh-after-ms", 3 * 60L * 60L * 1000L); - activityRadiusRefreshAfterMs = config.getLong("activity-radius-refresh-after-ms", 3 * 60L * 60L * 1000L); - activityDefault = config.getLong("activity-default", System.currentTimeMillis()); - activityWorlds = config.getStringList("activity-map-worlds"); + activityMapRadius = config.getInt("activity-map-radius", 1); + activityMapResolution = config.getInt("activity-map-resolution", 512); + activityEntryRefreshAfterMs = config.getLong("activity-entry-refresh-after-ms", 3 * 60L * 60L * 1000L); + activityRadiusRefreshAfterMs = config.getLong("activity-radius-refresh-after-ms", 3 * 60L * 60L * 1000L); + activityDefault = config.getLong("activity-default", System.currentTimeMillis()); + activityWorlds = config.getStringList("activity-map-worlds"); - parseWorldBorderBuffers(config.getConfigurationSection("world-border-buffers")); + parseWorldBorderBuffers(config.getConfigurationSection("world-border-buffers")); - return true; - } + return true; + } - private ReinforcementType parseReinforcementType(ConfigurationSection config) { - if (!config.isItemStack("item")) { - logger.warning( - "Reinforcement config at " + config.getCurrentPath() + " had no valid item entry, it was ignored"); - return null; - } - ItemStack item = config.getItemStack("item"); - ReinforcementEffect creationEffect = getReinforcementEffect(config.getConfigurationSection("creation_effect")); - ReinforcementEffect damageEffect = getReinforcementEffect(config.getConfigurationSection("damage_effect")); - ReinforcementEffect destructionEffect = getReinforcementEffect( - config.getConfigurationSection("destruction_effect")); - long gracePeriod = ConfigHelper.parseTime(config.getString("grace_period", "0"), TimeUnit.MILLISECONDS); - long maturationTime = ConfigHelper.parseTime(config.getString("mature_time", "0"), TimeUnit.MILLISECONDS); - long acidTime = ConfigHelper.parseTime(config.getString("acid_time", "-1"), TimeUnit.MILLISECONDS); - int acidPriority = config.getInt("acid_priority", 0); - String name = config.getString("name"); - double maturationScale = config.getInt("scale_amount", 1); - float health = (float) config.getDouble("hit_points", 100); - double returnChance = config.getDouble("return_chance", 1.0); - List reinforceables = ConfigHelper.parseMaterialList(config, "reinforceables"); - List nonReinforceables = ConfigHelper.parseMaterialList(config, "non_reinforceables"); - short id = (short) config.getInt("id", -1); - long decayTimer = ConfigHelper - .parseTime(config.getString("decay_timer", String.valueOf(globalDecayTimer / 1000L) + "s")); - double decayMultiplier = config.getDouble("decay_multiplier", globalDecayMultiplier); - double multiplerOnDeletedGroup = config.getDouble("deleted_group_multipler", 4); - int legacyId = config.getInt("legacy_id", -1); - List allowedWorlds = ConfigHelper.getStringList(config, "allowed_worlds"); - if (name == null) { - logger.warning("No name specified for reinforcement type at " + config.getCurrentPath()); - name = item.getType().name(); - } - if (id == -1) { - logger.warning("Reinforcement type at " + config.getCurrentPath() + " had no id, it was ignored"); - return null; - } - if (!reinforceables.isEmpty() && !nonReinforceables.isEmpty()) { - logger.warning("Both blacklist and whitelist specified for reinforcement type at " + config.getCurrentPath() - + ". This does not make sense and the type will be ignored"); - return null; - } - //TODO Should really be replaced with a toString() method - logger.info("Parsed reinforcement type " + name + " for item " + item.toString() + ", returnChance: " - + returnChance + ", maturationTime: " + TextUtil.formatDuration(maturationTime, TimeUnit.MILLISECONDS) - + ", acidTime: " + TextUtil.formatDuration(acidTime, TimeUnit.MILLISECONDS) + ", gracePeriod: " - + gracePeriod + ", id: " + id + ", allowedWorlds: " + StringUtils.join(allowedWorlds, ", ")); - return new ReinforcementType(health, returnChance, item, maturationTime, acidTime, acidPriority, maturationScale, gracePeriod, - creationEffect, damageEffect, destructionEffect, reinforceables, nonReinforceables, id, name, - globalBlackList, decayTimer, decayMultiplier, multiplerOnDeletedGroup, legacyId, allowedWorlds); - } + private ReinforcementType parseReinforcementType(ConfigurationSection config) { + if (!config.isItemStack("item")) { + logger.warning( + "Reinforcement config at " + config.getCurrentPath() + " had no valid item entry, it was ignored"); + return null; + } + ItemStack item = config.getItemStack("item"); + ReinforcementEffect creationEffect = getReinforcementEffect(config.getConfigurationSection("creation_effect")); + ReinforcementEffect damageEffect = getReinforcementEffect(config.getConfigurationSection("damage_effect")); + ReinforcementEffect destructionEffect = getReinforcementEffect( + config.getConfigurationSection("destruction_effect")); + long gracePeriod = ConfigHelper.parseTime(config.getString("grace_period", "0"), TimeUnit.MILLISECONDS); + long maturationTime = ConfigHelper.parseTime(config.getString("mature_time", "0"), TimeUnit.MILLISECONDS); + long acidTime = ConfigHelper.parseTime(config.getString("acid_time", "-1"), TimeUnit.MILLISECONDS); + int acidPriority = config.getInt("acid_priority", 0); + String name = config.getString("name"); + double maturationScale = config.getInt("scale_amount", 1); + float health = (float) config.getDouble("hit_points", 100); + double returnChance = config.getDouble("return_chance", 1.0); + List reinforceables = ConfigHelper.parseMaterialList(config, "reinforceables"); + List nonReinforceables = ConfigHelper.parseMaterialList(config, "non_reinforceables"); + short id = (short) config.getInt("id", -1); + long decayTimer = ConfigHelper + .parseTime(config.getString("decay_timer", String.valueOf(globalDecayTimer / 1000L) + "s")); + double decayMultiplier = config.getDouble("decay_multiplier", globalDecayMultiplier); + double multiplerOnDeletedGroup = config.getDouble("deleted_group_multipler", 4); + int legacyId = config.getInt("legacy_id", -1); + List allowedWorlds = ConfigHelper.getStringList(config, "allowed_worlds"); + if (name == null) { + logger.warning("No name specified for reinforcement type at " + config.getCurrentPath()); + name = item.getType().name(); + } + if (id == -1) { + logger.warning("Reinforcement type at " + config.getCurrentPath() + " had no id, it was ignored"); + return null; + } + if (!reinforceables.isEmpty() && !nonReinforceables.isEmpty()) { + logger.warning("Both blacklist and whitelist specified for reinforcement type at " + config.getCurrentPath() + + ". This does not make sense and the type will be ignored"); + return null; + } + //TODO Should really be replaced with a toString() method + logger.info("Parsed reinforcement type " + name + " for item " + item.toString() + ", returnChance: " + + returnChance + ", maturationTime: " + TextUtil.formatDuration(maturationTime, TimeUnit.MILLISECONDS) + + ", acidTime: " + TextUtil.formatDuration(acidTime, TimeUnit.MILLISECONDS) + ", gracePeriod: " + + gracePeriod + ", id: " + id + ", allowedWorlds: " + StringUtils.join(allowedWorlds, ", ")); + return new ReinforcementType(health, returnChance, item, maturationTime, acidTime, acidPriority, maturationScale, gracePeriod, + creationEffect, damageEffect, destructionEffect, reinforceables, nonReinforceables, id, name, + globalBlackList, decayTimer, decayMultiplier, multiplerOnDeletedGroup, legacyId, allowedWorlds); + } - private void parseReinforcementTypes(ConfigurationSection config) { - reinforcementTypes = new LinkedList<>(); - if (config == null) { - logger.info("No reinforcement types found in config"); - return; - } - for (String key : config.getKeys(false)) { - if (!config.isConfigurationSection(key)) { - logger.warning("Ignoring invalid entry " + key + " at " + config.getCurrentPath()); - continue; - } - ReinforcementType type = parseReinforcementType(config.getConfigurationSection(key)); - if (type != null) { - reinforcementTypes.add(type); - } - } - } + private void parseReinforcementTypes(ConfigurationSection config) { + reinforcementTypes = new LinkedList<>(); + if (config == null) { + logger.info("No reinforcement types found in config"); + return; + } + for (String key : config.getKeys(false)) { + if (!config.isConfigurationSection(key)) { + logger.warning("Ignoring invalid entry " + key + " at " + config.getCurrentPath()); + continue; + } + ReinforcementType type = parseReinforcementType(config.getConfigurationSection(key)); + if (type != null) { + reinforcementTypes.add(type); + } + } + } - @Nullable - private AcidType parseAcidType(ConfigurationSection config) { - String materialName = config.getString("material"); - if (materialName == null) { - logger.info("Ignoring invalid acid material"); - return null; - } - double multiplier = config.getDouble("maturation_time_multiplier"); + @Nullable + private AcidType parseAcidType(ConfigurationSection config) { + String materialName = config.getString("material"); + if (materialName == null) { + logger.info("Ignoring invalid acid material"); + return null; + } + double multiplier = config.getDouble("maturation_time_multiplier"); - Material material = Material.getMaterial(materialName); + Material material = Material.getMaterial(materialName); - List blockFaces = config.getStringList("faces").stream().map(BlockFace::valueOf).toList(); + List blockFaces = config.getStringList("faces").stream().map(BlockFace::valueOf).toList(); - return new AcidType(material, multiplier, blockFaces); - } + return new AcidType(material, multiplier, blockFaces); + } - private void parseAcidTypes(ConfigurationSection config) { - acidTypes = new ArrayList<>(); + private void parseAcidTypes(ConfigurationSection config) { + acidTypes = new ArrayList<>(); - if (config == null) { - logger.info("No acid types found in config"); - return; - } + if (config == null) { + logger.info("No acid types found in config"); + return; + } - for (String key: config.getKeys(false)) { - if (!config.isConfigurationSection(key)) { - logger.warning("Ignoring invalid entry " + key + " at " + config.getCurrentPath()); - continue; - } - AcidType type = parseAcidType(config.getConfigurationSection(key)); - if (type != null) { - acidTypes.add(type); - } - } - } + for (String key : config.getKeys(false)) { + if (!config.isConfigurationSection(key)) { + logger.warning("Ignoring invalid entry " + key + " at " + config.getCurrentPath()); + continue; + } + AcidType type = parseAcidType(config.getConfigurationSection(key)); + if (type != null) { + acidTypes.add(type); + } + } + } - private void parseWorldBorderBuffers(ConfigurationSection config) { - buffers = new HashMap<>(); - if (config == null) { - logger.info("No Buffers zones found in config"); - return; - } - for (String key : config.getKeys(false)) { - World world = Bukkit.getWorld(key); - if (world == null) { - logger.warning("WorldBuffer at " + config.getCurrentPath() + " couldn't find a world with this name: " + key); - continue; - } - ConfigurationSection insideWorld = config.getConfigurationSection(key); - if (insideWorld == null) { - logger.warning("Couldn't loop inside a world buffer config section"); - continue; - } - WorldBorderBuffers.Shape worldBorderShape; - try { - worldBorderShape = WorldBorderBuffers.Shape.valueOf(insideWorld.getString("shape", "square").toUpperCase()); - } catch (IllegalArgumentException exception) { - logger.warning("Shape at " + insideWorld.getCurrentPath() + " was not a valid input"); - continue; - } - double worldBorderBufferSize = insideWorld.getDouble("starting_radius", 100D); - ConfigurationSection insideCenter = insideWorld.getConfigurationSection("center"); - if (insideCenter == null) { - logger.info("No center for world border buffer found at " + insideWorld.getCurrentPath()); - continue; - } - double centerX = insideCenter.getDouble("x", 0.0); - double centerZ = insideCenter.getDouble("z", 0.0); - logger.info("Parsed World Border Buffer zone for world " + world.getName() + " with radius " + worldBorderBufferSize + " in shape " + worldBorderShape + " centered at " + centerX + ", " + centerZ); - buffers.put(world.getUID(), new WorldBorderBuffers(centerX, centerZ, worldBorderShape, worldBorderBufferSize)); - } + private void parseWorldBorderBuffers(ConfigurationSection config) { + buffers = new HashMap<>(); + if (config == null) { + logger.info("No Buffers zones found in config"); + return; + } + for (String key : config.getKeys(false)) { + World world = Bukkit.getWorld(key); + if (world == null) { + logger.warning("WorldBuffer at " + config.getCurrentPath() + " couldn't find a world with this name: " + key); + continue; + } + ConfigurationSection insideWorld = config.getConfigurationSection(key); + if (insideWorld == null) { + logger.warning("Couldn't loop inside a world buffer config section"); + continue; + } + WorldBorderBuffers.Shape worldBorderShape; + try { + worldBorderShape = WorldBorderBuffers.Shape.valueOf(insideWorld.getString("shape", "square").toUpperCase()); + } catch (IllegalArgumentException exception) { + logger.warning("Shape at " + insideWorld.getCurrentPath() + " was not a valid input"); + continue; + } + double worldBorderBufferSize = insideWorld.getDouble("starting_radius", 100D); + ConfigurationSection insideCenter = insideWorld.getConfigurationSection("center"); + if (insideCenter == null) { + logger.info("No center for world border buffer found at " + insideWorld.getCurrentPath()); + continue; + } + double centerX = insideCenter.getDouble("x", 0.0); + double centerZ = insideCenter.getDouble("z", 0.0); + logger.info("Parsed World Border Buffer zone for world " + world.getName() + " with radius " + worldBorderBufferSize + " in shape " + worldBorderShape + " centered at " + centerX + ", " + centerZ); + buffers.put(world.getUID(), new WorldBorderBuffers(centerX, centerZ, worldBorderShape, worldBorderBufferSize)); + } - } + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/CitadelPermissionHandler.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/CitadelPermissionHandler.java index a5283ddc6..59304b7f4 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/CitadelPermissionHandler.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/CitadelPermissionHandler.java @@ -8,112 +8,112 @@ import vg.civcraft.mc.namelayer.permission.PermissionType; public class CitadelPermissionHandler { - private CitadelPermissionHandler() { - } + private CitadelPermissionHandler() { + } - private static PermissionType chestPerm; - private static PermissionType bypassPerm; - private static PermissionType cropsPerm; - private static PermissionType insecurePerm; - private static PermissionType reinforcePerm; - private static PermissionType doorPerm; - private static PermissionType acidPerm; - private static PermissionType infoPerm; - private static PermissionType repairPerm; - private static PermissionType modifyBlockPerm; - private static PermissionType beaconPerm; - private static PermissionType hangingPlaceBreak; - private static PermissionType itemFramePutTake; - private static PermissionType itemFrameRotate; + private static PermissionType chestPerm; + private static PermissionType bypassPerm; + private static PermissionType cropsPerm; + private static PermissionType insecurePerm; + private static PermissionType reinforcePerm; + private static PermissionType doorPerm; + private static PermissionType acidPerm; + private static PermissionType infoPerm; + private static PermissionType repairPerm; + private static PermissionType modifyBlockPerm; + private static PermissionType beaconPerm; + private static PermissionType hangingPlaceBreak; + private static PermissionType itemFramePutTake; + private static PermissionType itemFrameRotate; - public static void setup() { - List membersAndAbove = Arrays.asList(PlayerType.MEMBERS, PlayerType.MODS, PlayerType.ADMINS, - PlayerType.OWNER); - List modAndAbove = Arrays.asList(PlayerType.MODS, PlayerType.ADMINS, PlayerType.OWNER); - reinforcePerm = PermissionType.registerPermission("REINFORCE", new ArrayList<>(modAndAbove), - "Allows reinforcing blocks on this group"); - acidPerm = PermissionType.registerPermission("ACIDBLOCK", new ArrayList<>(modAndAbove), - "Allows activating acid blocks reinforced on this group"); - infoPerm = PermissionType.registerPermission("REINFORCEMENT_INFO", new ArrayList<>(membersAndAbove), - "Allows viewing information on reinforcements reinforced on this group"); - bypassPerm = PermissionType.registerPermission("BYPASS_REINFORCEMENT", new ArrayList<>(modAndAbove), - "Allows bypassing reinforcements reinforced on this group"); - repairPerm = PermissionType.registerPermission("REPAIR_REINFORCEMENT", new ArrayList<>(modAndAbove), - "Allows repairing reinforcements reinforced on this group"); - doorPerm = PermissionType.registerPermission("DOORS", new ArrayList<>(membersAndAbove), - "Allows opening doors reinforced on this group"); - chestPerm = PermissionType.registerPermission("CHESTS", new ArrayList<>(membersAndAbove), - "Allows opening containers like chests reinforced on this group"); - cropsPerm = PermissionType.registerPermission("CROPS", new ArrayList<>(membersAndAbove), - "Allows harvesting crops growing on soil reinforced on this group"); - insecurePerm = PermissionType.registerPermission("INSECURE_REINFORCEMENT", new ArrayList<>(membersAndAbove), - "Allows toggling the insecure flag on reinforcements"); - modifyBlockPerm = PermissionType.registerPermission("MODIFY_BLOCK", new ArrayList<>(modAndAbove), - "Allows modifying reinforced blocks like flipping levers, stripping logs etc."); - beaconPerm = PermissionType.registerPermission("BEACONS", new ArrayList<>(membersAndAbove), - "Allow changing beacon effects"); - hangingPlaceBreak = PermissionType.registerPermission("HANGING_PLACE_BREAK", new ArrayList<>(membersAndAbove), - "Allows placing/breaking hanging entities on reinforced blocks."); - itemFramePutTake = PermissionType.registerPermission("ITEM_FRAME_PUT_TAKE", new ArrayList<>(membersAndAbove), - "Allows the placing/removal of items into/from Item Frames."); - itemFrameRotate = PermissionType.registerPermission("ITEM_FRAME_ROTATE", new ArrayList<>(membersAndAbove), - "Allows the rotation of items placed within Item Frames."); - } - - public static PermissionType getModifyBlocks() { - return modifyBlockPerm; - } + public static void setup() { + List membersAndAbove = Arrays.asList(PlayerType.MEMBERS, PlayerType.MODS, PlayerType.ADMINS, + PlayerType.OWNER); + List modAndAbove = Arrays.asList(PlayerType.MODS, PlayerType.ADMINS, PlayerType.OWNER); + reinforcePerm = PermissionType.registerPermission("REINFORCE", new ArrayList<>(modAndAbove), + "Allows reinforcing blocks on this group"); + acidPerm = PermissionType.registerPermission("ACIDBLOCK", new ArrayList<>(modAndAbove), + "Allows activating acid blocks reinforced on this group"); + infoPerm = PermissionType.registerPermission("REINFORCEMENT_INFO", new ArrayList<>(membersAndAbove), + "Allows viewing information on reinforcements reinforced on this group"); + bypassPerm = PermissionType.registerPermission("BYPASS_REINFORCEMENT", new ArrayList<>(modAndAbove), + "Allows bypassing reinforcements reinforced on this group"); + repairPerm = PermissionType.registerPermission("REPAIR_REINFORCEMENT", new ArrayList<>(modAndAbove), + "Allows repairing reinforcements reinforced on this group"); + doorPerm = PermissionType.registerPermission("DOORS", new ArrayList<>(membersAndAbove), + "Allows opening doors reinforced on this group"); + chestPerm = PermissionType.registerPermission("CHESTS", new ArrayList<>(membersAndAbove), + "Allows opening containers like chests reinforced on this group"); + cropsPerm = PermissionType.registerPermission("CROPS", new ArrayList<>(membersAndAbove), + "Allows harvesting crops growing on soil reinforced on this group"); + insecurePerm = PermissionType.registerPermission("INSECURE_REINFORCEMENT", new ArrayList<>(membersAndAbove), + "Allows toggling the insecure flag on reinforcements"); + modifyBlockPerm = PermissionType.registerPermission("MODIFY_BLOCK", new ArrayList<>(modAndAbove), + "Allows modifying reinforced blocks like flipping levers, stripping logs etc."); + beaconPerm = PermissionType.registerPermission("BEACONS", new ArrayList<>(membersAndAbove), + "Allow changing beacon effects"); + hangingPlaceBreak = PermissionType.registerPermission("HANGING_PLACE_BREAK", new ArrayList<>(membersAndAbove), + "Allows placing/breaking hanging entities on reinforced blocks."); + itemFramePutTake = PermissionType.registerPermission("ITEM_FRAME_PUT_TAKE", new ArrayList<>(membersAndAbove), + "Allows the placing/removal of items into/from Item Frames."); + itemFrameRotate = PermissionType.registerPermission("ITEM_FRAME_ROTATE", new ArrayList<>(membersAndAbove), + "Allows the rotation of items placed within Item Frames."); + } - public static PermissionType getChests() { - return chestPerm; - } + public static PermissionType getModifyBlocks() { + return modifyBlockPerm; + } - public static PermissionType getDoors() { - return doorPerm; - } + public static PermissionType getChests() { + return chestPerm; + } - public static PermissionType getBypass() { - return bypassPerm; - } + public static PermissionType getDoors() { + return doorPerm; + } - public static PermissionType getReinforce() { - return reinforcePerm; - } + public static PermissionType getBypass() { + return bypassPerm; + } - public static PermissionType getAcidblock() { - return acidPerm; - } + public static PermissionType getReinforce() { + return reinforcePerm; + } - public static PermissionType getCrops() { - return cropsPerm; - } + public static PermissionType getAcidblock() { + return acidPerm; + } - public static PermissionType getInsecure() { - return insecurePerm; - } + public static PermissionType getCrops() { + return cropsPerm; + } - public static PermissionType getInfo() { - return infoPerm; - } + public static PermissionType getInsecure() { + return insecurePerm; + } - public static PermissionType getRepair() { - return repairPerm; - } + public static PermissionType getInfo() { + return infoPerm; + } - public static PermissionType getBeacon() { - return beaconPerm; - } + public static PermissionType getRepair() { + return repairPerm; + } - public static PermissionType getHangingPlaceBreak() { - return hangingPlaceBreak; - } + public static PermissionType getBeacon() { + return beaconPerm; + } - public static PermissionType getItemFramePutTake() { - return itemFramePutTake; - } + public static PermissionType getHangingPlaceBreak() { + return hangingPlaceBreak; + } - public static PermissionType getItemFrameRotate() { - return itemFrameRotate; - } + public static PermissionType getItemFramePutTake() { + return itemFramePutTake; + } + + public static PermissionType getItemFrameRotate() { + return itemFrameRotate; + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/CitadelUtility.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/CitadelUtility.java index 49c7af5a8..a9abf4485 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/CitadelUtility.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/CitadelUtility.java @@ -23,197 +23,196 @@ import vg.civcraft.mc.namelayer.group.Group; */ public class CitadelUtility { - private CitadelUtility() { - } + private CitadelUtility() { + } - public static boolean isPlant(Block plant) { - switch (plant.getType()) { - case DANDELION: - case POPPY: - case BLUE_ORCHID: - case ALLIUM: - case AZURE_BLUET: - case ORANGE_TULIP: - case RED_TULIP: - case PINK_TULIP: - case WHITE_TULIP: - case OXEYE_DAISY: - case ACACIA_SAPLING: - case BIRCH_SAPLING: - case DARK_OAK_SAPLING: - case JUNGLE_SAPLING: - case OAK_SAPLING: - case SPRUCE_SAPLING: - case FLOWERING_AZALEA: - case WHEAT: - case CARROTS: - case POTATOES: - case BEETROOTS: - case MELON_STEM: - case PUMPKIN_STEM: - case ATTACHED_MELON_STEM: - case ATTACHED_PUMPKIN_STEM: - case NETHER_WART: - case SUGAR_CANE: - case CACTUS: - case SUNFLOWER: - case LILAC: - case PEONY: - case TALL_GRASS: - case SHORT_GRASS: - case TWISTING_VINES: - case TWISTING_VINES_PLANT: - case WEEPING_VINES: - case WEEPING_VINES_PLANT: - case KELP: - case KELP_PLANT: - case BIG_DRIPLEAF: - case BIG_DRIPLEAF_STEM: - case CAVE_VINES: - case CAVE_VINES_PLANT: - case SMALL_DRIPLEAF: - case SWEET_BERRY_BUSH: - case BAMBOO: - case BAMBOO_SAPLING: - case SEA_PICKLE: - case POINTED_DRIPSTONE: - return true; - default: - return false; - } - } + public static boolean isPlant(Block plant) { + switch (plant.getType()) { + case DANDELION: + case POPPY: + case BLUE_ORCHID: + case ALLIUM: + case AZURE_BLUET: + case ORANGE_TULIP: + case RED_TULIP: + case PINK_TULIP: + case WHITE_TULIP: + case OXEYE_DAISY: + case ACACIA_SAPLING: + case BIRCH_SAPLING: + case DARK_OAK_SAPLING: + case JUNGLE_SAPLING: + case OAK_SAPLING: + case SPRUCE_SAPLING: + case FLOWERING_AZALEA: + case WHEAT: + case CARROTS: + case POTATOES: + case BEETROOTS: + case MELON_STEM: + case PUMPKIN_STEM: + case ATTACHED_MELON_STEM: + case ATTACHED_PUMPKIN_STEM: + case NETHER_WART: + case SUGAR_CANE: + case CACTUS: + case SUNFLOWER: + case LILAC: + case PEONY: + case TALL_GRASS: + case SHORT_GRASS: + case TWISTING_VINES: + case TWISTING_VINES_PLANT: + case WEEPING_VINES: + case WEEPING_VINES_PLANT: + case KELP: + case KELP_PLANT: + case BIG_DRIPLEAF: + case BIG_DRIPLEAF_STEM: + case CAVE_VINES: + case CAVE_VINES_PLANT: + case SMALL_DRIPLEAF: + case SWEET_BERRY_BUSH: + case BAMBOO: + case BAMBOO_SAPLING: + case SEA_PICKLE: + case POINTED_DRIPSTONE: + return true; + default: + return false; + } + } - public static void sendAndLog(CommandSender receiver, ChatColor color, String message) { - receiver.sendMessage(color + message); - if (Citadel.getInstance().getConfigManager().logMessages()) { - Citadel.getInstance().getLogger().log(Level.INFO, "Sent {0} reply {1}", - new Object[]{receiver.getName(), message}); - } - } + public static void sendAndLog(CommandSender receiver, ChatColor color, String message) { + receiver.sendMessage(color + message); + if (Citadel.getInstance().getConfigManager().logMessages()) { + Citadel.getInstance().getLogger().log(Level.INFO, "Sent {0} reply {1}", + new Object[]{receiver.getName(), message}); + } + } - public static void sendAndLog(CommandSender receiver, ChatColor color, String message, Location location) { - final TextComponent component = new TextComponent(color + message); - addCoordsHoverComponent(component, location); - receiver.spigot().sendMessage(component); - if (Citadel.getInstance().getConfigManager().logMessages()) { - Citadel.getInstance().getLogger().log(Level.INFO, "Sent {0} reply {1}", - new Object[]{receiver.getName(), message}); - } - } + public static void sendAndLog(CommandSender receiver, ChatColor color, String message, Location location) { + final TextComponent component = new TextComponent(color + message); + addCoordsHoverComponent(component, location); + receiver.spigot().sendMessage(component); + if (Citadel.getInstance().getConfigManager().logMessages()) { + Citadel.getInstance().getLogger().log(Level.INFO, "Sent {0} reply {1}", + new Object[]{receiver.getName(), message}); + } + } - private static BaseComponent addCoordsHoverComponent(BaseComponent component, Location location) { - String hoverText = String.format("Location: %s %s %s", - location.getBlockX(), - location.getBlockY(), - location.getBlockZ()); - component.setHoverEvent(new HoverEvent( - HoverEvent.Action.SHOW_TEXT, - new Text(hoverText))); - return component; - } + private static BaseComponent addCoordsHoverComponent(BaseComponent component, Location location) { + String hoverText = String.format("Location: %s %s %s", + location.getBlockX(), + location.getBlockY(), + location.getBlockZ()); + component.setHoverEvent(new HoverEvent( + HoverEvent.Action.SHOW_TEXT, + new Text(hoverText))); + return component; + } - public static void debugLog(String msg) { - if (Citadel.getInstance().getConfigManager().isDebugEnabled()) { - Citadel.getInstance().getLogger().info(msg); - } - } + public static void debugLog(String msg) { + if (Citadel.getInstance().getConfigManager().isDebugEnabled()) { + Citadel.getInstance().getLogger().info(msg); + } + } - public static boolean consumeReinforcementItems(Player player, ReinforcementType type, boolean consumeExtra) { - ItemMap toRemove = new ItemMap(type.getItem()); - if (consumeExtra) { - toRemove.addItemAmount(type.getItem(), 1); - } - if (!toRemove.removeSafelyFrom(player.getInventory())) { - CitadelUtility.sendAndLog(player, ChatColor.RED, - "Failed to remove items needed for " + type.getName() + " reinforcement from your inventory"); - Citadel.getInstance().getStateManager().setState(player, null); - return false; - } - return true; - } + public static boolean consumeReinforcementItems(Player player, ReinforcementType type, boolean consumeExtra) { + ItemMap toRemove = new ItemMap(type.getItem()); + if (consumeExtra) { + toRemove.addItemAmount(type.getItem(), 1); + } + if (!toRemove.removeSafelyFrom(player.getInventory())) { + CitadelUtility.sendAndLog(player, ChatColor.RED, + "Failed to remove items needed for " + type.getName() + " reinforcement from your inventory"); + Citadel.getInstance().getStateManager().setState(player, null); + return false; + } + return true; + } - public static boolean attemptReinforcementCreation(Block block, ReinforcementType type, Group group, - Player player) { - // check if group still exists - if (!group.isValid()) { - CitadelUtility.sendAndLog(player, ChatColor.RED, - "The group " + group.getName() + " seems to have been deleted in the mean time", - block.getLocation()); - Citadel.getInstance().getStateManager().setState(player, null); - return true; - } - // check if player still has permission - if (!NameAPI.getGroupManager().hasAccess(group, player.getUniqueId(), - CitadelPermissionHandler.getReinforce())) { - CitadelUtility.sendAndLog(player, ChatColor.RED, - "You seem to have lost permission to reinforce on " + group.getName(), - block.getLocation()); - Citadel.getInstance().getStateManager().setState(player, null); - return true; - } - block = ReinforcementLogic.getResponsibleBlock(block); - // check if reinforcement already exists - Reinforcement existingRein = Citadel.getInstance().getReinforcementManager().getReinforcement(block); - if (existingRein != null) { - // something like a slab, we just ignore this - return false; - } - // check if reinforcement can reinforce that block - if (!type.canBeReinforced(block.getType())) { - CitadelUtility.sendAndLog(player, ChatColor.RED, - type.getName() + " can not reinforce " + block.getType(), - block.getLocation()); - return true; - } - // check if reinforcement is allowed in the current world - if (!type.isAllowedInWorld(block.getWorld().getName())) - { - CitadelUtility.sendAndLog(player, ChatColor.RED, - type.getName() + " can not reinforce in this dimension", block.getLocation()); - return true; - } - ItemMap playerItems = new ItemMap(player.getInventory()); - // check inventory - int available = playerItems.getAmount(type.getItem()); - int required = type.getItem().getAmount(); - // special handling if the reinforcement material is also the block being placed - // consuming the reinforcement material once will count the block being placed as reinforcing itself - // so detect that and consume an extra one - boolean consumeExtra = false; - //We do this over a material check to keep lore/name support intact etc - ItemStack offfhandStack = player.getInventory().getItemInOffHand().clone(); - offfhandStack.setAmount(1); + public static boolean attemptReinforcementCreation(Block block, ReinforcementType type, Group group, + Player player) { + // check if group still exists + if (!group.isValid()) { + CitadelUtility.sendAndLog(player, ChatColor.RED, + "The group " + group.getName() + " seems to have been deleted in the mean time", + block.getLocation()); + Citadel.getInstance().getStateManager().setState(player, null); + return true; + } + // check if player still has permission + if (!NameAPI.getGroupManager().hasAccess(group, player.getUniqueId(), + CitadelPermissionHandler.getReinforce())) { + CitadelUtility.sendAndLog(player, ChatColor.RED, + "You seem to have lost permission to reinforce on " + group.getName(), + block.getLocation()); + Citadel.getInstance().getStateManager().setState(player, null); + return true; + } + block = ReinforcementLogic.getResponsibleBlock(block); + // check if reinforcement already exists + Reinforcement existingRein = Citadel.getInstance().getReinforcementManager().getReinforcement(block); + if (existingRein != null) { + // something like a slab, we just ignore this + return false; + } + // check if reinforcement can reinforce that block + if (!type.canBeReinforced(block.getType())) { + CitadelUtility.sendAndLog(player, ChatColor.RED, + type.getName() + " can not reinforce " + block.getType(), + block.getLocation()); + return true; + } + // check if reinforcement is allowed in the current world + if (!type.isAllowedInWorld(block.getWorld().getName())) { + CitadelUtility.sendAndLog(player, ChatColor.RED, + type.getName() + " can not reinforce in this dimension", block.getLocation()); + return true; + } + ItemMap playerItems = new ItemMap(player.getInventory()); + // check inventory + int available = playerItems.getAmount(type.getItem()); + int required = type.getItem().getAmount(); + // special handling if the reinforcement material is also the block being placed + // consuming the reinforcement material once will count the block being placed as reinforcing itself + // so detect that and consume an extra one + boolean consumeExtra = false; + //We do this over a material check to keep lore/name support intact etc + ItemStack offfhandStack = player.getInventory().getItemInOffHand().clone(); + offfhandStack.setAmount(1); - boolean blockIsAlsoReinforcement = block.getType() == type.getItem().getType(); - if (blockIsAlsoReinforcement) { - boolean placingFromReinforcementStack = (player.getInventory().getHeldItemSlot() == player.getInventory().first(block.getType())) || - (offfhandStack.equals(type.getItem())); - if (placingFromReinforcementStack) { - consumeExtra = true; - required++; - } - } - if (available < required) { - Citadel.getInstance().getStateManager().setState(player, null); - CitadelUtility.sendAndLog(player, ChatColor.RED, - "You have no items left to reinforce with " + type.getName(), - block.getLocation()); - return true; - } - Reinforcement newRein = ReinforcementLogic.callReinforcementCreationEvent(player, block, type, group); - if (newRein == null) { - return true; - } - // remove from inventory - if (!CitadelUtility.consumeReinforcementItems(player, type, consumeExtra)) { - return true; - } - // create reinforcement - if (Citadel.getInstance().getConfigManager().logCreation()) { - Citadel.getInstance().getLogger().info(player.getName() + " created reinforcement with " + type.getName() - + " for " + block.getType().toString() + " at " + block.getLocation().toString()); - } - ReinforcementLogic.createReinforcement(newRein); - return false; - } + boolean blockIsAlsoReinforcement = block.getType() == type.getItem().getType(); + if (blockIsAlsoReinforcement) { + boolean placingFromReinforcementStack = (player.getInventory().getHeldItemSlot() == player.getInventory().first(block.getType())) || + (offfhandStack.equals(type.getItem())); + if (placingFromReinforcementStack) { + consumeExtra = true; + required++; + } + } + if (available < required) { + Citadel.getInstance().getStateManager().setState(player, null); + CitadelUtility.sendAndLog(player, ChatColor.RED, + "You have no items left to reinforce with " + type.getName(), + block.getLocation()); + return true; + } + Reinforcement newRein = ReinforcementLogic.callReinforcementCreationEvent(player, block, type, group); + if (newRein == null) { + return true; + } + // remove from inventory + if (!CitadelUtility.consumeReinforcementItems(player, type, consumeExtra)) { + return true; + } + // create reinforcement + if (Citadel.getInstance().getConfigManager().logCreation()) { + Citadel.getInstance().getLogger().info(player.getName() + " created reinforcement with " + type.getName() + + " for " + block.getType().toString() + " at " + block.getLocation().toString()); + } + ReinforcementLogic.createReinforcement(newRein); + return false; + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/ReinforcementLogic.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/ReinforcementLogic.java index da85736de..a9f86f0f0 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/ReinforcementLogic.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/ReinforcementLogic.java @@ -25,361 +25,361 @@ import vg.civcraft.mc.namelayer.group.Group; public final class ReinforcementLogic { - private ReinforcementLogic() { - } + private ReinforcementLogic() { + } - /** - * Inserts a new reinforcements into the cache, queues it for persistence and - * plays particle effects for creation - * - * @param rein Reinforcement just created - */ - public static void createReinforcement(Reinforcement rein) { - Citadel.getInstance().getReinforcementManager().putReinforcement(rein); - if (rein.getType().getCreationEffect() != null) { - rein.getType().getCreationEffect().playEffect(rein); - } - } + /** + * Inserts a new reinforcements into the cache, queues it for persistence and + * plays particle effects for creation + * + * @param rein Reinforcement just created + */ + public static void createReinforcement(Reinforcement rein) { + Citadel.getInstance().getReinforcementManager().putReinforcement(rein); + if (rein.getType().getCreationEffect() != null) { + rein.getType().getCreationEffect().playEffect(rein); + } + } - public static Reinforcement callReinforcementCreationEvent(Player player, Block block, ReinforcementType type, - Group group) { - Reinforcement rein = new Reinforcement(block.getLocation(), type, group); - ReinforcementCreationEvent event = new ReinforcementCreationEvent(player, rein); - Bukkit.getPluginManager().callEvent(event); - if (event.isCancelled()) { - return null; - } - return rein; - } + public static Reinforcement callReinforcementCreationEvent(Player player, Block block, ReinforcementType type, + Group group) { + Reinforcement rein = new Reinforcement(block.getLocation(), type, group); + ReinforcementCreationEvent event = new ReinforcementCreationEvent(player, rein); + Bukkit.getPluginManager().callEvent(event); + if (event.isCancelled()) { + return null; + } + return rein; + } - public static void damageReinforcement(Reinforcement rein, float damage, Entity source) { - float futureHealth = rein.getHealth() - damage; - if (futureHealth <= 0) { - ReinforcementDestructionEvent event = new ReinforcementDestructionEvent(rein, damage, source); - Bukkit.getPluginManager().callEvent(event); - if (event.isCancelled()) { - return; - } - } - futureHealth = Math.min(futureHealth, rein.getType().getHealth()); - rein.setHealth(futureHealth); - if (rein.isBroken()) { - if (rein.getType().getDestructionEffect() != null) { - rein.getType().getDestructionEffect().playEffect(rein); - } - } else { - if (rein.getType().getDamageEffect() != null) { - rein.getType().getDamageEffect().playEffect(rein); - } - } - } + public static void damageReinforcement(Reinforcement rein, float damage, Entity source) { + float futureHealth = rein.getHealth() - damage; + if (futureHealth <= 0) { + ReinforcementDestructionEvent event = new ReinforcementDestructionEvent(rein, damage, source); + Bukkit.getPluginManager().callEvent(event); + if (event.isCancelled()) { + return; + } + } + futureHealth = Math.min(futureHealth, rein.getType().getHealth()); + rein.setHealth(futureHealth); + if (rein.isBroken()) { + if (rein.getType().getDestructionEffect() != null) { + rein.getType().getDestructionEffect().playEffect(rein); + } + } else { + if (rein.getType().getDamageEffect() != null) { + rein.getType().getDamageEffect().playEffect(rein); + } + } + } - public static float getDamageApplied(Reinforcement reinforcement) { - float damageAmount = 1.0F; - if (!reinforcement.isMature()) { - double timeExisted = System.currentTimeMillis() - reinforcement.getCreationTime(); - double progress = timeExisted / reinforcement.getType().getMaturationTime(); - damageAmount /= progress; - damageAmount *= reinforcement.getType().getMaturationScale(); - } - damageAmount *= getDecayDamage(reinforcement); - return damageAmount; - } + public static float getDamageApplied(Reinforcement reinforcement) { + float damageAmount = 1.0F; + if (!reinforcement.isMature()) { + double timeExisted = System.currentTimeMillis() - reinforcement.getCreationTime(); + double progress = timeExisted / reinforcement.getType().getMaturationTime(); + damageAmount /= progress; + damageAmount *= reinforcement.getType().getMaturationScale(); + } + damageAmount *= getDecayDamage(reinforcement); + return damageAmount; + } - public static double getDecayDamage(Reinforcement reinforcement) { - if (reinforcement.getGroup() != null) { - //long lastRefresh = reinforcement.getGroup().getActivityTimeStamp(); - ActivityMap map = Citadel.getInstance().getActivityMap(); - return map.getLastActivityTime(reinforcement.getGroup(), reinforcement.getLocation()) - .map(Instant::toEpochMilli) - .map(lastRefresh -> reinforcement.getType().getDecayDamageMultipler(lastRefresh)) - .orElse(1d); - } else { - return reinforcement.getType().getDeletedGroupMultiplier(); - } - } + public static double getDecayDamage(Reinforcement reinforcement) { + if (reinforcement.getGroup() != null) { + //long lastRefresh = reinforcement.getGroup().getActivityTimeStamp(); + ActivityMap map = Citadel.getInstance().getActivityMap(); + return map.getLastActivityTime(reinforcement.getGroup(), reinforcement.getLocation()) + .map(Instant::toEpochMilli) + .map(lastRefresh -> reinforcement.getType().getDecayDamageMultipler(lastRefresh)) + .orElse(1d); + } else { + return reinforcement.getType().getDeletedGroupMultiplier(); + } + } - public static Reinforcement getReinforcementAt(Location location) { - return Citadel.getInstance().getReinforcementManager().getReinforcement(location); - } + public static Reinforcement getReinforcementAt(Location location) { + return Citadel.getInstance().getReinforcementManager().getReinforcement(location); + } - public static Reinforcement getReinforcementProtecting(Block block) { - if (!WorldUtils.isValidBlock(block)) { - return null; - } - Reinforcement reinforcement = getReinforcementAt(block.getLocation()); - if (reinforcement != null) { - return reinforcement; - } - switch (block.getType()) { - // Chests are awkward since you can place both sides of a double chest - // independently, which isn't true for - // beds, plants, or doors, so this needs to be accounted for and - // "getResponsibleBlock()" isn't appropriate - // for the following logic: that both sides protect each other; that if either - // block is reinforced, then - // the chest as a whole remains protected. - case CHEST: - case TRAPPED_CHEST: { - Chest chest = (Chest) block.getBlockData(); - BlockFace facing = chest.getFacing(); - switch (chest.getType()) { - case LEFT: { - BlockFace face = WorldUtils.turnClockwise(facing); - return getReinforcementAt(block.getLocation().add(face.getDirection())); - } - case RIGHT: { - BlockFace face = WorldUtils.turnAntiClockwise(facing); - return getReinforcementAt(block.getLocation().add(face.getDirection())); - } - default: { - return null; - } - } - } - default: { - Block responsible = getResponsibleBlock(block); - if (Objects.equals(block, responsible)) { - return null; - } - return getReinforcementAt(responsible.getLocation()); - } - } - } + public static Reinforcement getReinforcementProtecting(Block block) { + if (!WorldUtils.isValidBlock(block)) { + return null; + } + Reinforcement reinforcement = getReinforcementAt(block.getLocation()); + if (reinforcement != null) { + return reinforcement; + } + switch (block.getType()) { + // Chests are awkward since you can place both sides of a double chest + // independently, which isn't true for + // beds, plants, or doors, so this needs to be accounted for and + // "getResponsibleBlock()" isn't appropriate + // for the following logic: that both sides protect each other; that if either + // block is reinforced, then + // the chest as a whole remains protected. + case CHEST: + case TRAPPED_CHEST: { + Chest chest = (Chest) block.getBlockData(); + BlockFace facing = chest.getFacing(); + switch (chest.getType()) { + case LEFT: { + BlockFace face = WorldUtils.turnClockwise(facing); + return getReinforcementAt(block.getLocation().add(face.getDirection())); + } + case RIGHT: { + BlockFace face = WorldUtils.turnAntiClockwise(facing); + return getReinforcementAt(block.getLocation().add(face.getDirection())); + } + default: { + return null; + } + } + } + default: { + Block responsible = getResponsibleBlock(block); + if (Objects.equals(block, responsible)) { + return null; + } + return getReinforcementAt(responsible.getLocation()); + } + } + } - /** - * Some blocks, crops in particular, can not be reinforced but instead have - * their reinforcement behavior tied to a source block. This method will get - * that source block, which may be the given block itself. It does not look at - * reinforcement data at all, it merely applies logic based on block type and - * physics checks - * - * @param block Block to get responsible block for - * @return Block which reinforcement would protect the given block - */ + /** + * Some blocks, crops in particular, can not be reinforced but instead have + * their reinforcement behavior tied to a source block. This method will get + * that source block, which may be the given block itself. It does not look at + * reinforcement data at all, it merely applies logic based on block type and + * physics checks + * + * @param block Block to get responsible block for + * @return Block which reinforcement would protect the given block + */ - public static Block getResponsibleBlock(Block block) { - // Do not put [double] chests in here. - switch (block.getType()) { - case DANDELION: - case POPPY: - case BLUE_ORCHID: - case ALLIUM: - case AZURE_BLUET: - case ORANGE_TULIP: - case RED_TULIP: - case PINK_TULIP: - case WHITE_TULIP: - case OXEYE_DAISY: - case ACACIA_SAPLING: - case BIRCH_SAPLING: - case DARK_OAK_SAPLING: - case JUNGLE_SAPLING: - case OAK_SAPLING: - case SPRUCE_SAPLING: - case WARPED_FUNGUS: - case CRIMSON_FUNGUS: - case BAMBOO_SAPLING: - case FLOWERING_AZALEA: - case WHEAT: - case CARROTS: - case POTATOES: - case BEETROOTS: - case SWEET_BERRY_BUSH: - case MELON_STEM: - case PUMPKIN_STEM: - case ATTACHED_MELON_STEM: - case ATTACHED_PUMPKIN_STEM: - case WARPED_ROOTS: - case CRIMSON_ROOTS: - case NETHER_SPROUTS: - case WITHER_ROSE: - case LILY_OF_THE_VALLEY: - case CORNFLOWER: - case SEA_PICKLE: - case FERN: - case KELP: - case SHORT_GRASS: - case SEAGRASS: - case TUBE_CORAL: - case TUBE_CORAL_FAN: - case BRAIN_CORAL: - case BRAIN_CORAL_FAN: - case BUBBLE_CORAL: - case BUBBLE_CORAL_FAN: - case FIRE_CORAL: - case FIRE_CORAL_FAN: - case HORN_CORAL: - case HORN_CORAL_FAN: - case DEAD_TUBE_CORAL: - case DEAD_TUBE_CORAL_FAN: - case DEAD_BRAIN_CORAL: - case DEAD_BRAIN_CORAL_FAN: - case DEAD_BUBBLE_CORAL: - case DEAD_BUBBLE_CORAL_FAN: - case DEAD_FIRE_CORAL: - case DEAD_FIRE_CORAL_FAN: - case DEAD_HORN_CORAL: - case DEAD_HORN_CORAL_FAN: - case SMALL_DRIPLEAF: - case NETHER_WART: { - return block.getRelative(BlockFace.DOWN); - } - case SUGAR_CANE: - case BAMBOO: - case ROSE_BUSH: - case TWISTING_VINES_PLANT: - case BIG_DRIPLEAF_STEM: - case CACTUS: - case SUNFLOWER: - case LILAC: - case TALL_GRASS: - case LARGE_FERN: - case TALL_SEAGRASS: - case KELP_PLANT: - case PEONY: { - // scan downwards for first different block - Block below = block.getRelative(BlockFace.DOWN); - while (below.getType() == block.getType()) { - below = below.getRelative(BlockFace.DOWN); - } - return below; - } - case SPORE_BLOSSOM: - case HANGING_ROOTS: { - return block.getRelative(BlockFace.UP); - } - case ACACIA_DOOR: - case BIRCH_DOOR: - case DARK_OAK_DOOR: - case IRON_DOOR: - case SPRUCE_DOOR: - case JUNGLE_DOOR: - case WARPED_DOOR: - case CRIMSON_DOOR: - case OAK_DOOR: { - if (block.getRelative(BlockFace.UP).getType() != block.getType()) { - // block is upper half of a door - return block.getRelative(BlockFace.DOWN); - } - return block; - } - case BLACK_BED: - case BLUE_BED: - case BROWN_BED: - case CYAN_BED: - case GRAY_BED: - case GREEN_BED: - case MAGENTA_BED: - case LIME_BED: - case ORANGE_BED: - case PURPLE_BED: - case PINK_BED: - case WHITE_BED: - case LIGHT_GRAY_BED: - case LIGHT_BLUE_BED: - case RED_BED: - case YELLOW_BED: { - Bed bed = (Bed) block.getBlockData(); - if (bed.getPart() == Bed.Part.HEAD) { - return block.getRelative(bed.getFacing().getOppositeFace()); - } - return block; - } - case TUBE_CORAL_WALL_FAN: - case BRAIN_CORAL_WALL_FAN: - case BUBBLE_CORAL_WALL_FAN: - case FIRE_CORAL_WALL_FAN: - case HORN_CORAL_WALL_FAN: - case DEAD_TUBE_CORAL_WALL_FAN: - case DEAD_BRAIN_CORAL_WALL_FAN: - case DEAD_BUBBLE_CORAL_WALL_FAN: - case DEAD_FIRE_CORAL_WALL_FAN: - case DEAD_HORN_CORAL_WALL_FAN: { - CoralWallFan cwf = (CoralWallFan) block.getBlockData(); - return block.getRelative(cwf.getFacing().getOppositeFace()); - } - case SMALL_AMETHYST_BUD: - case MEDIUM_AMETHYST_BUD: - case LARGE_AMETHYST_BUD: { - AmethystCluster amethyst = (AmethystCluster) block.getBlockData(); - return block.getRelative(amethyst.getFacing().getOppositeFace()); - } - case WEEPING_VINES: { - // scan upwards - Block above = block.getRelative(BlockFace.UP); - while (above.getType() == block.getType() || above.getType() == Material.WEEPING_VINES_PLANT) { - above = above.getRelative(BlockFace.UP); - } - return above; - } - case CAVE_VINES: { - // scan upwards for first different block - Block above = block.getRelative(BlockFace.UP); - while (above.getType() == block.getType() || above.getType() == Material.CAVE_VINES_PLANT) { - above = above.getRelative(BlockFace.UP); - } - return above; - } - case CAVE_VINES_PLANT: - case WEEPING_VINES_PLANT: { - // scan upwards for first different block - Block above = block.getRelative(BlockFace.UP); - while (above.getType() == block.getType()) { - above = above.getRelative(BlockFace.UP); - } - return above; - } - case TWISTING_VINES: { - // scan downwards for first different block - Block below = block.getRelative(BlockFace.DOWN); - while (below.getType() == block.getType() || below.getType() == Material.TWISTING_VINES_PLANT) { - below = below.getRelative(BlockFace.DOWN); - } - return below; - } - case BIG_DRIPLEAF: { - // scan downwards for first different block - Block below = block.getRelative(BlockFace.DOWN); - while (below.getType() == block.getType() || below.getType() == Material.BIG_DRIPLEAF_STEM) { - below = below.getRelative(BlockFace.DOWN); - } - return below; - } - case POINTED_DRIPSTONE: - PointedDripstone dripstone = (PointedDripstone) block.getBlockData(); - Block direction = block.getRelative(dripstone.getVerticalDirection().getOppositeFace()); - while (direction.getType() == block.getType()) { - direction = direction.getRelative(dripstone.getVerticalDirection().getOppositeFace()); - } - return direction; - default: { - return block; - } - } - } + public static Block getResponsibleBlock(Block block) { + // Do not put [double] chests in here. + switch (block.getType()) { + case DANDELION: + case POPPY: + case BLUE_ORCHID: + case ALLIUM: + case AZURE_BLUET: + case ORANGE_TULIP: + case RED_TULIP: + case PINK_TULIP: + case WHITE_TULIP: + case OXEYE_DAISY: + case ACACIA_SAPLING: + case BIRCH_SAPLING: + case DARK_OAK_SAPLING: + case JUNGLE_SAPLING: + case OAK_SAPLING: + case SPRUCE_SAPLING: + case WARPED_FUNGUS: + case CRIMSON_FUNGUS: + case BAMBOO_SAPLING: + case FLOWERING_AZALEA: + case WHEAT: + case CARROTS: + case POTATOES: + case BEETROOTS: + case SWEET_BERRY_BUSH: + case MELON_STEM: + case PUMPKIN_STEM: + case ATTACHED_MELON_STEM: + case ATTACHED_PUMPKIN_STEM: + case WARPED_ROOTS: + case CRIMSON_ROOTS: + case NETHER_SPROUTS: + case WITHER_ROSE: + case LILY_OF_THE_VALLEY: + case CORNFLOWER: + case SEA_PICKLE: + case FERN: + case KELP: + case SHORT_GRASS: + case SEAGRASS: + case TUBE_CORAL: + case TUBE_CORAL_FAN: + case BRAIN_CORAL: + case BRAIN_CORAL_FAN: + case BUBBLE_CORAL: + case BUBBLE_CORAL_FAN: + case FIRE_CORAL: + case FIRE_CORAL_FAN: + case HORN_CORAL: + case HORN_CORAL_FAN: + case DEAD_TUBE_CORAL: + case DEAD_TUBE_CORAL_FAN: + case DEAD_BRAIN_CORAL: + case DEAD_BRAIN_CORAL_FAN: + case DEAD_BUBBLE_CORAL: + case DEAD_BUBBLE_CORAL_FAN: + case DEAD_FIRE_CORAL: + case DEAD_FIRE_CORAL_FAN: + case DEAD_HORN_CORAL: + case DEAD_HORN_CORAL_FAN: + case SMALL_DRIPLEAF: + case NETHER_WART: { + return block.getRelative(BlockFace.DOWN); + } + case SUGAR_CANE: + case BAMBOO: + case ROSE_BUSH: + case TWISTING_VINES_PLANT: + case BIG_DRIPLEAF_STEM: + case CACTUS: + case SUNFLOWER: + case LILAC: + case TALL_GRASS: + case LARGE_FERN: + case TALL_SEAGRASS: + case KELP_PLANT: + case PEONY: { + // scan downwards for first different block + Block below = block.getRelative(BlockFace.DOWN); + while (below.getType() == block.getType()) { + below = below.getRelative(BlockFace.DOWN); + } + return below; + } + case SPORE_BLOSSOM: + case HANGING_ROOTS: { + return block.getRelative(BlockFace.UP); + } + case ACACIA_DOOR: + case BIRCH_DOOR: + case DARK_OAK_DOOR: + case IRON_DOOR: + case SPRUCE_DOOR: + case JUNGLE_DOOR: + case WARPED_DOOR: + case CRIMSON_DOOR: + case OAK_DOOR: { + if (block.getRelative(BlockFace.UP).getType() != block.getType()) { + // block is upper half of a door + return block.getRelative(BlockFace.DOWN); + } + return block; + } + case BLACK_BED: + case BLUE_BED: + case BROWN_BED: + case CYAN_BED: + case GRAY_BED: + case GREEN_BED: + case MAGENTA_BED: + case LIME_BED: + case ORANGE_BED: + case PURPLE_BED: + case PINK_BED: + case WHITE_BED: + case LIGHT_GRAY_BED: + case LIGHT_BLUE_BED: + case RED_BED: + case YELLOW_BED: { + Bed bed = (Bed) block.getBlockData(); + if (bed.getPart() == Bed.Part.HEAD) { + return block.getRelative(bed.getFacing().getOppositeFace()); + } + return block; + } + case TUBE_CORAL_WALL_FAN: + case BRAIN_CORAL_WALL_FAN: + case BUBBLE_CORAL_WALL_FAN: + case FIRE_CORAL_WALL_FAN: + case HORN_CORAL_WALL_FAN: + case DEAD_TUBE_CORAL_WALL_FAN: + case DEAD_BRAIN_CORAL_WALL_FAN: + case DEAD_BUBBLE_CORAL_WALL_FAN: + case DEAD_FIRE_CORAL_WALL_FAN: + case DEAD_HORN_CORAL_WALL_FAN: { + CoralWallFan cwf = (CoralWallFan) block.getBlockData(); + return block.getRelative(cwf.getFacing().getOppositeFace()); + } + case SMALL_AMETHYST_BUD: + case MEDIUM_AMETHYST_BUD: + case LARGE_AMETHYST_BUD: { + AmethystCluster amethyst = (AmethystCluster) block.getBlockData(); + return block.getRelative(amethyst.getFacing().getOppositeFace()); + } + case WEEPING_VINES: { + // scan upwards + Block above = block.getRelative(BlockFace.UP); + while (above.getType() == block.getType() || above.getType() == Material.WEEPING_VINES_PLANT) { + above = above.getRelative(BlockFace.UP); + } + return above; + } + case CAVE_VINES: { + // scan upwards for first different block + Block above = block.getRelative(BlockFace.UP); + while (above.getType() == block.getType() || above.getType() == Material.CAVE_VINES_PLANT) { + above = above.getRelative(BlockFace.UP); + } + return above; + } + case CAVE_VINES_PLANT: + case WEEPING_VINES_PLANT: { + // scan upwards for first different block + Block above = block.getRelative(BlockFace.UP); + while (above.getType() == block.getType()) { + above = above.getRelative(BlockFace.UP); + } + return above; + } + case TWISTING_VINES: { + // scan downwards for first different block + Block below = block.getRelative(BlockFace.DOWN); + while (below.getType() == block.getType() || below.getType() == Material.TWISTING_VINES_PLANT) { + below = below.getRelative(BlockFace.DOWN); + } + return below; + } + case BIG_DRIPLEAF: { + // scan downwards for first different block + Block below = block.getRelative(BlockFace.DOWN); + while (below.getType() == block.getType() || below.getType() == Material.BIG_DRIPLEAF_STEM) { + below = below.getRelative(BlockFace.DOWN); + } + return below; + } + case POINTED_DRIPSTONE: + PointedDripstone dripstone = (PointedDripstone) block.getBlockData(); + Block direction = block.getRelative(dripstone.getVerticalDirection().getOppositeFace()); + while (direction.getType() == block.getType()) { + direction = direction.getRelative(dripstone.getVerticalDirection().getOppositeFace()); + } + return direction; + default: { + return block; + } + } + } - /** - * Checks if at the given block is a container, which is not insecure and which - * the player can not access due to missing perms - * - * @param player the player attempting to access stuff - * @param block Block to check for - * @return True if the player can not do something like placing an adjacent - * chest or comparator, false otherwise - */ - public static boolean isPreventingBlockAccess(Player player, Block block) { - if (block == null) { - return false; - } - if (block.getState() instanceof InventoryHolder) { - Reinforcement rein = getReinforcementProtecting(block); - if (rein == null || rein.isInsecure()) { - return false; - } - return !rein.hasPermission(player, CitadelPermissionHandler.getChests()); - } - return false; - } + /** + * Checks if at the given block is a container, which is not insecure and which + * the player can not access due to missing perms + * + * @param player the player attempting to access stuff + * @param block Block to check for + * @return True if the player can not do something like placing an adjacent + * chest or comparator, false otherwise + */ + public static boolean isPreventingBlockAccess(Player player, Block block) { + if (block == null) { + return false; + } + if (block.getState() instanceof InventoryHolder) { + Reinforcement rein = getReinforcementProtecting(block); + if (rein == null || rein.isInsecure()) { + return false; + } + return !rein.hasPermission(player, CitadelPermissionHandler.getChests()); + } + return false; + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/ReinforcementManager.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/ReinforcementManager.java index 6d5e50bb6..5899cf306 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/ReinforcementManager.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/ReinforcementManager.java @@ -10,45 +10,45 @@ import vg.civcraft.mc.civmodcore.world.locations.chunkmeta.block.table.TableStor public class ReinforcementManager { - private BlockBasedChunkMetaView> chunkMetaData; + private BlockBasedChunkMetaView> chunkMetaData; - ReinforcementManager( - BlockBasedChunkMetaView> chunkMetaData) { - this.chunkMetaData = chunkMetaData; - } + ReinforcementManager( + BlockBasedChunkMetaView> chunkMetaData) { + this.chunkMetaData = chunkMetaData; + } - /** - * Gets the reinforcement at the given location if one exists - * - * @param location Location to get reinforcement for - * @return Reinforcement at the location or null if no reinforcement exists - * there - */ - public Reinforcement getReinforcement(Location location) { - return (Reinforcement) chunkMetaData.get(location); - } + /** + * Gets the reinforcement at the given location if one exists + * + * @param location Location to get reinforcement for + * @return Reinforcement at the location or null if no reinforcement exists + * there + */ + public Reinforcement getReinforcement(Location location) { + return (Reinforcement) chunkMetaData.get(location); + } - /** - * Gets the reinforcement for the given block if one exists - * - * @param block Block to get reinforcement for - * @return Reinforcement for the block or null if no reinforcement exists there - */ - public Reinforcement getReinforcement(Block block) { - return getReinforcement(block.getLocation()); - } + /** + * Gets the reinforcement for the given block if one exists + * + * @param block Block to get reinforcement for + * @return Reinforcement for the block or null if no reinforcement exists there + */ + public Reinforcement getReinforcement(Block block) { + return getReinforcement(block.getLocation()); + } - /** - * Inserts the given reinforcement into the tracking. If a reinforcement already - * exists at the same location it will be replaced. - * - * @param reinforcement Reinforcement to insert - */ - public void putReinforcement(Reinforcement reinforcement) { - chunkMetaData.put(reinforcement); - } + /** + * Inserts the given reinforcement into the tracking. If a reinforcement already + * exists at the same location it will be replaced. + * + * @param reinforcement Reinforcement to insert + */ + public void putReinforcement(Reinforcement reinforcement) { + chunkMetaData.put(reinforcement); + } - void shutDown() { - chunkMetaData.disable(); - } + void shutDown() { + chunkMetaData.disable(); + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/acidtypes/AcidType.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/acidtypes/AcidType.java index fde351eb2..3ba646ec3 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/acidtypes/AcidType.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/acidtypes/AcidType.java @@ -6,7 +6,9 @@ import org.bukkit.block.BlockFace; import java.util.List; public record AcidType( - Material material, - double modifier, - List blockFaces -) { } + Material material, + double modifier, + List blockFaces +) { + +} diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/activity/ActivityMap.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/activity/ActivityMap.java index 3b57bead7..0e3351d20 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/activity/ActivityMap.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/activity/ActivityMap.java @@ -37,483 +37,483 @@ import vg.civcraft.mc.namelayer.group.Group; public class ActivityMap { - private static final long SAVE_CHANGES_INTERVAL_MS = 60L * 1000L; // 1 min - private static final long UNLOAD_INTERVAL_MS = 60L * 1000L; // 1 min - - private final Logger logger; - private final ActivityDB activityDB; - private final ScheduledExecutorService scheduler; - private AtomicBoolean loadChunkDisabled; - private Thread loadChunkThread; - private final WorldIDManager worldIdManager; - private final Map> data; // world, xz, group, activity/entry - private final ConcurrentLinkedQueue playerUpdates; - private final LinkedBlockingQueue chunkLoadQueue; - private final ConcurrentLinkedQueue chunkUnloadQueue; - private final ActivityMapTimePoll timePoll; - private final AtomicInteger unloadCount; - - private final Set worlds; - private final int resolution; - private final int radius; - private final long entryRefreshAfterMs; - private final long radiusRefreshAfterMs; - private final Instant defaultActivity; - - private boolean enabled; - - public ActivityMap(Logger logger, ManagedDatasource source) { - this.logger = logger; - this.activityDB = new ActivityDB(source); - this.scheduler = Executors.newScheduledThreadPool(2); - this.worldIdManager = CivModCorePlugin.getInstance().getWorldIdManager(); - this.data = new ConcurrentHashMap<>(); - this.playerUpdates = new ConcurrentLinkedQueue<>(); - this.chunkLoadQueue = new LinkedBlockingQueue<>(); - this.chunkUnloadQueue = new ConcurrentLinkedQueue<>(); - this.timePoll = new ActivityMapTimePoll(); - this.unloadCount = new AtomicInteger(); - - int resolution = 16 * (Citadel.getInstance().getConfigManager().getActivityMapResolution() / 16); - this.resolution = resolution <= 0 ? 1 : resolution; - - this.radius = Citadel.getInstance().getConfigManager().getActivityMapRadius(); - this.entryRefreshAfterMs = Citadel.getInstance().getConfigManager().getActivityEntryRefreshAfterMs(); - this.radiusRefreshAfterMs = Citadel.getInstance().getConfigManager().getActivityRadiusRefreshAfterMs(); - this.worlds = new HashSet<>(); - this.defaultActivity = Instant - .ofEpochSecond(Citadel.getInstance().getConfigManager().getActivityDefault()); - - this.enabled = false; - } - - public void enable() { - if (!activityDB.enable()) { - logger.severe("ActivityMap cannot be enabled"); - return; - } - - for (String world : Citadel.getInstance().getConfigManager().getActivityWorlds()) { - World bukkitWorld = Bukkit.getWorld(world); - if (bukkitWorld == null) { - Citadel.getInstance().getLogger().warning("World not found: " + world); - } else { - worlds.add(bukkitWorld.getUID()); - } - } - - scheduler.scheduleWithFixedDelay(() -> { - saveChangesToDB(); - }, SAVE_CHANGES_INTERVAL_MS, SAVE_CHANGES_INTERVAL_MS, TimeUnit.MILLISECONDS); - - scheduler.scheduleWithFixedDelay(() -> { - unloadChunkTask(); - }, UNLOAD_INTERVAL_MS, UNLOAD_INTERVAL_MS, TimeUnit.MILLISECONDS); - - startLoadChunkThread(); - - timePoll.startPolling(); - - enabled = true; - } - - private void startLoadChunkThread() { - loadChunkDisabled = new AtomicBoolean(false); - - final String threadName = "citadel-activity-map-chunk-loading"; - loadChunkThread = new Thread(() -> loadChunkThreadTask(threadName, loadChunkDisabled), threadName); - loadChunkThread.start(); - } - - public void disable() { - if (!enabled) { - return; - } - - loadChunkDisabled.set(true); - loadChunkThread.interrupt(); - - scheduler.shutdown(); - - try { - if (!scheduler.awaitTermination(60, TimeUnit.SECONDS)) - scheduler.shutdownNow(); - } catch (InterruptedException ex) { - ex.printStackTrace(); - } - - timePoll.stopPolling(); - - logger.info("ActivityMap scheduler and its tasks are shutdown."); - - saveChangesToDB(); - - logger.info("ActivityMap changes are saved."); - } - - private Instant getActivity(RegionCoord regionCoord, int groupId) { - RegionData regionData = getRegion(regionCoord, true); - - synchronized (regionData) { - GroupData groupData = regionData.get(groupId); - Instant activity = groupData != null ? groupData.activity : null; - return activity; - } - } - - private RegionData getRegion(RegionCoord regionCoord, boolean loadIfNotLoaded) { - Map worldData = data.computeIfAbsent(regionCoord.worldId(), a -> new ConcurrentHashMap<>()); - XZKey regionKey = new XZKey(regionCoord.x(), regionCoord.z()); - RegionData regionData = worldData.computeIfAbsent(regionKey, a -> new RegionData()); - - if (regionData.isLoaded() || !loadIfNotLoaded) { - return regionData; - } - - synchronized (regionData) { - if (regionData.isLoaded()) { - return regionData; - } - - long start = System.nanoTime(); - - activityDB.select(regionCoord.worldId(), regionCoord.x(), regionCoord.z(), resolution, activityItem -> { - GroupData groupData = new GroupData(activityItem.activity()); - regionData.put(activityItem.group(), groupData); - }); - - timePoll.pushTimeNano(System.nanoTime() - start); - - regionData.setLoaded(); - - return regionData; - } - } - - private void saveChangesToDB() { - Map> regions = getUpdatedRegions(); - if (regions == null || regions.size() == 0) { - return; - } - - Map> extendedRegions = getExtendedRegions(regions); - List activities = new ArrayList<>(); - - for (Map.Entry> regionEntry : extendedRegions.entrySet()) { - RegionCoord regionCoord = regionEntry.getKey(); - Set groups = regionEntry.getValue(); - Instant activity = Instant.now(); - - getUpdatedActivities(activities, regionCoord, groups, activity); - - boolean updateEntry = regions.containsKey(regionCoord); - RegionData regionData = getRegion(regionCoord, false); - - if (!regionData.isLoaded()) { - continue; - } - - synchronized (regionData) { - for (int groupId : groups) { - GroupData groupData = regionData.get(groupId); - groupData.activity = activity; - - if (updateEntry) { - groupData.entry = activity; - } - } - } - } - - activityDB.update(activities); - } - - private Map> getUpdatedRegions() { - GroupManager groupManager = NameAPI.getGroupManager(); - Map> regions = null; - - PlayerUpdate playerUpdate; - while ((playerUpdate = playerUpdates.poll()) != null) { - if (regions == null) { - regions = new HashMap<>(); - } - - Set groups = regions.computeIfAbsent(playerUpdate.regionCoord(), a -> new HashSet<>()); - - List groupNames = groupManager.getAllGroupNames(playerUpdate.playerId()); - for (String groupName : groupNames) { - Group group = GroupManager.getGroup(groupName); - if (groupManager.hasAccess(group, playerUpdate.playerId(), CitadelPermissionHandler.getBypass())) { - groups.add(group.getGroupId()); - } - } - } - - return regions; - } - - private Map> getExtendedRegions(Map> regions) { - Map> extendedRegions = new HashMap<>(); - - for (Map.Entry> regionEntry : regions.entrySet()) { - RegionCoord regionCoord = regionEntry.getKey(); - Set groups = regionEntry.getValue(); - - if (isRegionEntryValid(regionCoord, groups)) { - continue; - } - - for (int xOffset = -radius; xOffset <= radius; xOffset++) { - int x = regionCoord.x() + xOffset; - for (int zOffset = -radius; zOffset <= radius; zOffset++) { - int z = regionCoord.z() + zOffset; - RegionCoord extendedRegionCoord = new RegionCoord(regionCoord.worldId(), x, z); - boolean updateEntry = regionCoord.equals(extendedRegionCoord); - - if (isRegionRadiusValid(extendedRegionCoord, groups, updateEntry)) { - continue; - } - - Set extendedGroups = extendedRegions.get(extendedRegionCoord); - if (extendedGroups == null) { - extendedRegions.put(extendedRegionCoord, groups); - } else { - extendedGroups.addAll(groups); - } - } - } - } - - return extendedRegions; - } - - private boolean isRegionEntryValid(RegionCoord regionCoord, Set groups) { - RegionData regionData = getRegion(regionCoord, false); - if (!regionData.isLoaded()) { - return false; - } - - Instant enteredPoint = Instant.now().minusMillis(entryRefreshAfterMs); - - synchronized (regionData) { - for (int groupId : groups) { - Instant entry = regionData.get(groupId).entry; - if (entry == null || entry.compareTo(enteredPoint) < 0) { - return false; - } - } - } - - return true; - } - - private boolean isRegionRadiusValid(RegionCoord regionCoord, Set groups, boolean updateEntry) { - RegionData regionData = getRegion(regionCoord, false); - if (!regionData.isLoaded()) { - return false; - } - - Instant activePoint = Instant.now().minusMillis(radiusRefreshAfterMs); - - synchronized (regionData) { - for (int groupId : groups) { - GroupData groupData = regionData.get(groupId); - if (groupData.activity == null || groupData.activity.compareTo(activePoint) < 0) { - return false; - } - if (updateEntry) { - groupData.entry = Instant.now(); - } - } - } - - return true; - } - - private void getUpdatedActivities(List activities, RegionCoord regionCoord, Set groups, Instant activity) { - for (int groupId : groups) { - var activityItem = new ActivityItem( - regionCoord.worldId(), - groupId, - regionCoord.x(), - regionCoord.z(), - activity, - resolution - ); - - activities.add(activityItem); - } - } - - private void loadChunkThreadTask(String threadName, AtomicBoolean disabled) { - this.logger.info("Thread " + threadName + " is started."); - - while (!disabled.get()) { - try { - ChunkCoord chunkCoord = chunkLoadQueue.take(); - - chunkUnloadQueue.remove(chunkCoord); - - RegionCoord regionCoord = getRegionCoordByChunk(chunkCoord); - RegionData regionData = getRegion(regionCoord, true); - - synchronized (regionData) { - regionData.addChunk(chunkCoord); - } - } catch (InterruptedException e) { - if(!disabled.get()) { - e.printStackTrace(); - } - } - } - - this.logger.info("Thread " + threadName + " is stopped."); - } - - private void unloadChunkTask() { - ChunkCoord chunkCoord; - while ((chunkCoord = chunkUnloadQueue.poll()) != null) { - RegionCoord regionCoord = getRegionCoordByChunk(chunkCoord); - Map worldData = data.get(regionCoord.worldId()); - if (worldData == null) { - continue; - } - - XZKey regionKey = new XZKey(regionCoord.x(), regionCoord.z()); - RegionData regionData = worldData.get(regionKey); - if (regionData == null) { - continue; - } - - synchronized (regionData) { - if (regionData.removeChunk(chunkCoord)) { - worldData.remove(regionKey); - unloadCount.incrementAndGet(); - } - } - } - } - - private RegionCoord getRegionCoord(Location location) { - short worldId = worldIdManager.getInternalWorldId(location.getWorld()); - int regionX = Math.floorDiv(location.getBlockX(), resolution); - int regionZ = Math.floorDiv(location.getBlockZ(), resolution); - - return new RegionCoord(worldId, regionX, regionZ); - } - - private RegionCoord getRegionCoordByChunk(ChunkCoord chunkCoord) { - short worldId = chunkCoord.worldId(); - int regionX = Math.floorDiv(chunkCoord.x() << 4, resolution); - int regionZ = Math.floorDiv(chunkCoord.z() << 4, resolution); - - return new RegionCoord(worldId, regionX, regionZ); - } - - private boolean isEnabled(World world) { - return enabled && world != null && this.worlds.contains(world.getUID()); - } - - public void loadChunk(Chunk chunk) { - if (!isEnabled(chunk.getWorld())) { - return; - } - - short worldId = worldIdManager.getInternalWorldId(chunk.getWorld()); - ChunkCoord chunkCoord = new ChunkCoord(worldId, chunk.getX(), chunk.getZ()); - - chunkLoadQueue.add(chunkCoord); - } - - public void unloadChunk(Chunk chunk) { - if (!isEnabled(chunk.getWorld())) { - return; - } - - short worldId = worldIdManager.getInternalWorldId(chunk.getWorld()); - ChunkCoord chunkCoord = new ChunkCoord(worldId, chunk.getX(), chunk.getZ()); - chunkUnloadQueue.add(chunkCoord); - } - - public Optional getLastActivityTime(Group group, Location location) { - if (!isEnabled(location.getWorld())) { - return Optional.of(Instant.ofEpochMilli(group.getActivityTimeStamp())); - } - - RegionCoord regionCoord = getRegionCoord(location); - int groupId = group.getGroupId(); - - Instant activity = getActivity(regionCoord, groupId); - if (activity == null) { - activity = Instant.ofEpochMilli(group.getActivityTimeStamp()); - if (activity.compareTo(defaultActivity) > 0) { - activity = defaultActivity; - } - } - - return Optional.of(activity); - } - - public void savePlayerActivity(Location from, Location to, Player player) { - if (!isEnabled(to.getWorld())) { - return; - } - - RegionCoord regionFrom = getRegionCoord(from); - RegionCoord regionTo = getRegionCoord(to); - - if (!regionFrom.equals(regionTo)) - playerUpdates.add(new PlayerUpdate(regionTo, player.getUniqueId())); - } - - public void savePlayerActivity(Location location, Player player) { - if (!isEnabled(location.getWorld())) { - return; - } - - RegionCoord regionCoord = getRegionCoord(location); - playerUpdates.add(new PlayerUpdate(regionCoord, player.getUniqueId())); - } - - public ActivityMapStat getStat() { - if (!enabled) { - return null; - } - - int worlds = data.size(); - int loadedRegions = 0; - int notLoadedRegions = 0; - Set uniqueGroups = new HashSet<>(); - int loadedActivities = 0; - - for (Map world : data.values()) { - for (RegionData regionData : world.values()) { - synchronized (regionData) { - if (regionData.isLoaded()) { - loadedRegions++; - } else { - notLoadedRegions++; - } - - Set groups = regionData.getGroups(); - - uniqueGroups.addAll(regionData.getGroups()); - - loadedActivities += groups.size(); - } - } - } - - var stat = new ActivityMapStat(); - stat.worlds = worlds; - stat.loadedRegions = loadedRegions; - stat.notLoadedRegions = notLoadedRegions; - stat.uniqueGroups = uniqueGroups.size(); - stat.loadedActivities = loadedActivities; - stat.regionUnloadCount = unloadCount.get(); - - timePoll.getStat(stat); - - return stat; - } + private static final long SAVE_CHANGES_INTERVAL_MS = 60L * 1000L; // 1 min + private static final long UNLOAD_INTERVAL_MS = 60L * 1000L; // 1 min + + private final Logger logger; + private final ActivityDB activityDB; + private final ScheduledExecutorService scheduler; + private AtomicBoolean loadChunkDisabled; + private Thread loadChunkThread; + private final WorldIDManager worldIdManager; + private final Map> data; // world, xz, group, activity/entry + private final ConcurrentLinkedQueue playerUpdates; + private final LinkedBlockingQueue chunkLoadQueue; + private final ConcurrentLinkedQueue chunkUnloadQueue; + private final ActivityMapTimePoll timePoll; + private final AtomicInteger unloadCount; + + private final Set worlds; + private final int resolution; + private final int radius; + private final long entryRefreshAfterMs; + private final long radiusRefreshAfterMs; + private final Instant defaultActivity; + + private boolean enabled; + + public ActivityMap(Logger logger, ManagedDatasource source) { + this.logger = logger; + this.activityDB = new ActivityDB(source); + this.scheduler = Executors.newScheduledThreadPool(2); + this.worldIdManager = CivModCorePlugin.getInstance().getWorldIdManager(); + this.data = new ConcurrentHashMap<>(); + this.playerUpdates = new ConcurrentLinkedQueue<>(); + this.chunkLoadQueue = new LinkedBlockingQueue<>(); + this.chunkUnloadQueue = new ConcurrentLinkedQueue<>(); + this.timePoll = new ActivityMapTimePoll(); + this.unloadCount = new AtomicInteger(); + + int resolution = 16 * (Citadel.getInstance().getConfigManager().getActivityMapResolution() / 16); + this.resolution = resolution <= 0 ? 1 : resolution; + + this.radius = Citadel.getInstance().getConfigManager().getActivityMapRadius(); + this.entryRefreshAfterMs = Citadel.getInstance().getConfigManager().getActivityEntryRefreshAfterMs(); + this.radiusRefreshAfterMs = Citadel.getInstance().getConfigManager().getActivityRadiusRefreshAfterMs(); + this.worlds = new HashSet<>(); + this.defaultActivity = Instant + .ofEpochSecond(Citadel.getInstance().getConfigManager().getActivityDefault()); + + this.enabled = false; + } + + public void enable() { + if (!activityDB.enable()) { + logger.severe("ActivityMap cannot be enabled"); + return; + } + + for (String world : Citadel.getInstance().getConfigManager().getActivityWorlds()) { + World bukkitWorld = Bukkit.getWorld(world); + if (bukkitWorld == null) { + Citadel.getInstance().getLogger().warning("World not found: " + world); + } else { + worlds.add(bukkitWorld.getUID()); + } + } + + scheduler.scheduleWithFixedDelay(() -> { + saveChangesToDB(); + }, SAVE_CHANGES_INTERVAL_MS, SAVE_CHANGES_INTERVAL_MS, TimeUnit.MILLISECONDS); + + scheduler.scheduleWithFixedDelay(() -> { + unloadChunkTask(); + }, UNLOAD_INTERVAL_MS, UNLOAD_INTERVAL_MS, TimeUnit.MILLISECONDS); + + startLoadChunkThread(); + + timePoll.startPolling(); + + enabled = true; + } + + private void startLoadChunkThread() { + loadChunkDisabled = new AtomicBoolean(false); + + final String threadName = "citadel-activity-map-chunk-loading"; + loadChunkThread = new Thread(() -> loadChunkThreadTask(threadName, loadChunkDisabled), threadName); + loadChunkThread.start(); + } + + public void disable() { + if (!enabled) { + return; + } + + loadChunkDisabled.set(true); + loadChunkThread.interrupt(); + + scheduler.shutdown(); + + try { + if (!scheduler.awaitTermination(60, TimeUnit.SECONDS)) + scheduler.shutdownNow(); + } catch (InterruptedException ex) { + ex.printStackTrace(); + } + + timePoll.stopPolling(); + + logger.info("ActivityMap scheduler and its tasks are shutdown."); + + saveChangesToDB(); + + logger.info("ActivityMap changes are saved."); + } + + private Instant getActivity(RegionCoord regionCoord, int groupId) { + RegionData regionData = getRegion(regionCoord, true); + + synchronized (regionData) { + GroupData groupData = regionData.get(groupId); + Instant activity = groupData != null ? groupData.activity : null; + return activity; + } + } + + private RegionData getRegion(RegionCoord regionCoord, boolean loadIfNotLoaded) { + Map worldData = data.computeIfAbsent(regionCoord.worldId(), a -> new ConcurrentHashMap<>()); + XZKey regionKey = new XZKey(regionCoord.x(), regionCoord.z()); + RegionData regionData = worldData.computeIfAbsent(regionKey, a -> new RegionData()); + + if (regionData.isLoaded() || !loadIfNotLoaded) { + return regionData; + } + + synchronized (regionData) { + if (regionData.isLoaded()) { + return regionData; + } + + long start = System.nanoTime(); + + activityDB.select(regionCoord.worldId(), regionCoord.x(), regionCoord.z(), resolution, activityItem -> { + GroupData groupData = new GroupData(activityItem.activity()); + regionData.put(activityItem.group(), groupData); + }); + + timePoll.pushTimeNano(System.nanoTime() - start); + + regionData.setLoaded(); + + return regionData; + } + } + + private void saveChangesToDB() { + Map> regions = getUpdatedRegions(); + if (regions == null || regions.size() == 0) { + return; + } + + Map> extendedRegions = getExtendedRegions(regions); + List activities = new ArrayList<>(); + + for (Map.Entry> regionEntry : extendedRegions.entrySet()) { + RegionCoord regionCoord = regionEntry.getKey(); + Set groups = regionEntry.getValue(); + Instant activity = Instant.now(); + + getUpdatedActivities(activities, regionCoord, groups, activity); + + boolean updateEntry = regions.containsKey(regionCoord); + RegionData regionData = getRegion(regionCoord, false); + + if (!regionData.isLoaded()) { + continue; + } + + synchronized (regionData) { + for (int groupId : groups) { + GroupData groupData = regionData.get(groupId); + groupData.activity = activity; + + if (updateEntry) { + groupData.entry = activity; + } + } + } + } + + activityDB.update(activities); + } + + private Map> getUpdatedRegions() { + GroupManager groupManager = NameAPI.getGroupManager(); + Map> regions = null; + + PlayerUpdate playerUpdate; + while ((playerUpdate = playerUpdates.poll()) != null) { + if (regions == null) { + regions = new HashMap<>(); + } + + Set groups = regions.computeIfAbsent(playerUpdate.regionCoord(), a -> new HashSet<>()); + + List groupNames = groupManager.getAllGroupNames(playerUpdate.playerId()); + for (String groupName : groupNames) { + Group group = GroupManager.getGroup(groupName); + if (groupManager.hasAccess(group, playerUpdate.playerId(), CitadelPermissionHandler.getBypass())) { + groups.add(group.getGroupId()); + } + } + } + + return regions; + } + + private Map> getExtendedRegions(Map> regions) { + Map> extendedRegions = new HashMap<>(); + + for (Map.Entry> regionEntry : regions.entrySet()) { + RegionCoord regionCoord = regionEntry.getKey(); + Set groups = regionEntry.getValue(); + + if (isRegionEntryValid(regionCoord, groups)) { + continue; + } + + for (int xOffset = -radius; xOffset <= radius; xOffset++) { + int x = regionCoord.x() + xOffset; + for (int zOffset = -radius; zOffset <= radius; zOffset++) { + int z = regionCoord.z() + zOffset; + RegionCoord extendedRegionCoord = new RegionCoord(regionCoord.worldId(), x, z); + boolean updateEntry = regionCoord.equals(extendedRegionCoord); + + if (isRegionRadiusValid(extendedRegionCoord, groups, updateEntry)) { + continue; + } + + Set extendedGroups = extendedRegions.get(extendedRegionCoord); + if (extendedGroups == null) { + extendedRegions.put(extendedRegionCoord, groups); + } else { + extendedGroups.addAll(groups); + } + } + } + } + + return extendedRegions; + } + + private boolean isRegionEntryValid(RegionCoord regionCoord, Set groups) { + RegionData regionData = getRegion(regionCoord, false); + if (!regionData.isLoaded()) { + return false; + } + + Instant enteredPoint = Instant.now().minusMillis(entryRefreshAfterMs); + + synchronized (regionData) { + for (int groupId : groups) { + Instant entry = regionData.get(groupId).entry; + if (entry == null || entry.compareTo(enteredPoint) < 0) { + return false; + } + } + } + + return true; + } + + private boolean isRegionRadiusValid(RegionCoord regionCoord, Set groups, boolean updateEntry) { + RegionData regionData = getRegion(regionCoord, false); + if (!regionData.isLoaded()) { + return false; + } + + Instant activePoint = Instant.now().minusMillis(radiusRefreshAfterMs); + + synchronized (regionData) { + for (int groupId : groups) { + GroupData groupData = regionData.get(groupId); + if (groupData.activity == null || groupData.activity.compareTo(activePoint) < 0) { + return false; + } + if (updateEntry) { + groupData.entry = Instant.now(); + } + } + } + + return true; + } + + private void getUpdatedActivities(List activities, RegionCoord regionCoord, Set groups, Instant activity) { + for (int groupId : groups) { + var activityItem = new ActivityItem( + regionCoord.worldId(), + groupId, + regionCoord.x(), + regionCoord.z(), + activity, + resolution + ); + + activities.add(activityItem); + } + } + + private void loadChunkThreadTask(String threadName, AtomicBoolean disabled) { + this.logger.info("Thread " + threadName + " is started."); + + while (!disabled.get()) { + try { + ChunkCoord chunkCoord = chunkLoadQueue.take(); + + chunkUnloadQueue.remove(chunkCoord); + + RegionCoord regionCoord = getRegionCoordByChunk(chunkCoord); + RegionData regionData = getRegion(regionCoord, true); + + synchronized (regionData) { + regionData.addChunk(chunkCoord); + } + } catch (InterruptedException e) { + if (!disabled.get()) { + e.printStackTrace(); + } + } + } + + this.logger.info("Thread " + threadName + " is stopped."); + } + + private void unloadChunkTask() { + ChunkCoord chunkCoord; + while ((chunkCoord = chunkUnloadQueue.poll()) != null) { + RegionCoord regionCoord = getRegionCoordByChunk(chunkCoord); + Map worldData = data.get(regionCoord.worldId()); + if (worldData == null) { + continue; + } + + XZKey regionKey = new XZKey(regionCoord.x(), regionCoord.z()); + RegionData regionData = worldData.get(regionKey); + if (regionData == null) { + continue; + } + + synchronized (regionData) { + if (regionData.removeChunk(chunkCoord)) { + worldData.remove(regionKey); + unloadCount.incrementAndGet(); + } + } + } + } + + private RegionCoord getRegionCoord(Location location) { + short worldId = worldIdManager.getInternalWorldId(location.getWorld()); + int regionX = Math.floorDiv(location.getBlockX(), resolution); + int regionZ = Math.floorDiv(location.getBlockZ(), resolution); + + return new RegionCoord(worldId, regionX, regionZ); + } + + private RegionCoord getRegionCoordByChunk(ChunkCoord chunkCoord) { + short worldId = chunkCoord.worldId(); + int regionX = Math.floorDiv(chunkCoord.x() << 4, resolution); + int regionZ = Math.floorDiv(chunkCoord.z() << 4, resolution); + + return new RegionCoord(worldId, regionX, regionZ); + } + + private boolean isEnabled(World world) { + return enabled && world != null && this.worlds.contains(world.getUID()); + } + + public void loadChunk(Chunk chunk) { + if (!isEnabled(chunk.getWorld())) { + return; + } + + short worldId = worldIdManager.getInternalWorldId(chunk.getWorld()); + ChunkCoord chunkCoord = new ChunkCoord(worldId, chunk.getX(), chunk.getZ()); + + chunkLoadQueue.add(chunkCoord); + } + + public void unloadChunk(Chunk chunk) { + if (!isEnabled(chunk.getWorld())) { + return; + } + + short worldId = worldIdManager.getInternalWorldId(chunk.getWorld()); + ChunkCoord chunkCoord = new ChunkCoord(worldId, chunk.getX(), chunk.getZ()); + chunkUnloadQueue.add(chunkCoord); + } + + public Optional getLastActivityTime(Group group, Location location) { + if (!isEnabled(location.getWorld())) { + return Optional.of(Instant.ofEpochMilli(group.getActivityTimeStamp())); + } + + RegionCoord regionCoord = getRegionCoord(location); + int groupId = group.getGroupId(); + + Instant activity = getActivity(regionCoord, groupId); + if (activity == null) { + activity = Instant.ofEpochMilli(group.getActivityTimeStamp()); + if (activity.compareTo(defaultActivity) > 0) { + activity = defaultActivity; + } + } + + return Optional.of(activity); + } + + public void savePlayerActivity(Location from, Location to, Player player) { + if (!isEnabled(to.getWorld())) { + return; + } + + RegionCoord regionFrom = getRegionCoord(from); + RegionCoord regionTo = getRegionCoord(to); + + if (!regionFrom.equals(regionTo)) + playerUpdates.add(new PlayerUpdate(regionTo, player.getUniqueId())); + } + + public void savePlayerActivity(Location location, Player player) { + if (!isEnabled(location.getWorld())) { + return; + } + + RegionCoord regionCoord = getRegionCoord(location); + playerUpdates.add(new PlayerUpdate(regionCoord, player.getUniqueId())); + } + + public ActivityMapStat getStat() { + if (!enabled) { + return null; + } + + int worlds = data.size(); + int loadedRegions = 0; + int notLoadedRegions = 0; + Set uniqueGroups = new HashSet<>(); + int loadedActivities = 0; + + for (Map world : data.values()) { + for (RegionData regionData : world.values()) { + synchronized (regionData) { + if (regionData.isLoaded()) { + loadedRegions++; + } else { + notLoadedRegions++; + } + + Set groups = regionData.getGroups(); + + uniqueGroups.addAll(regionData.getGroups()); + + loadedActivities += groups.size(); + } + } + } + + var stat = new ActivityMapStat(); + stat.worlds = worlds; + stat.loadedRegions = loadedRegions; + stat.notLoadedRegions = notLoadedRegions; + stat.uniqueGroups = uniqueGroups.size(); + stat.loadedActivities = loadedActivities; + stat.regionUnloadCount = unloadCount.get(); + + timePoll.getStat(stat); + + return stat; + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/activity/ActivityMapStat.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/activity/ActivityMapStat.java index b4b613dee..4e097e7f6 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/activity/ActivityMapStat.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/activity/ActivityMapStat.java @@ -1,14 +1,15 @@ package vg.civcraft.mc.citadel.activity; public class ActivityMapStat { - public int worlds; - public int loadedRegions; - public int notLoadedRegions; - public int uniqueGroups; - public int loadedActivities; - public long regionUnloadCount; - public long regionLoadCount; - public long regionLoadSumNano; - public long regionLoadMinTimeNano; - public long regionLoadMaxTimeNano; + + public int worlds; + public int loadedRegions; + public int notLoadedRegions; + public int uniqueGroups; + public int loadedActivities; + public long regionUnloadCount; + public long regionLoadCount; + public long regionLoadSumNano; + public long regionLoadMinTimeNano; + public long regionLoadMaxTimeNano; } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/activity/ActivityMapTimePoll.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/activity/ActivityMapTimePoll.java index c6b37d210..8c59b4ef0 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/activity/ActivityMapTimePoll.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/activity/ActivityMapTimePoll.java @@ -6,92 +6,93 @@ import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; class ActivityMapTimePoll { - private static final long POLL_INTERVAL_MS = 1000L; - private final ConcurrentLinkedQueue nanoTimes = new ConcurrentLinkedQueue<>(); - private final ScheduledExecutorService scheduler = new ScheduledThreadPoolExecutor(1); - private final Object syncRoot = new Object(); + private static final long POLL_INTERVAL_MS = 1000L; - private long regionLoadCount; - private long regionLoadSumNano; - private long regionLoadMinTimeNano; - private long regionLoadMaxTimeNano; + private final ConcurrentLinkedQueue nanoTimes = new ConcurrentLinkedQueue<>(); + private final ScheduledExecutorService scheduler = new ScheduledThreadPoolExecutor(1); + private final Object syncRoot = new Object(); - private void poll() { - long currentRegionLoadCount = 0; - long currentRegionLoadSumNano = 0; - long currentRegionLoadMinTimeNano = Long.MAX_VALUE; - long currentRegionLoadMaxTimeNano = Long.MIN_VALUE; + private long regionLoadCount; + private long regionLoadSumNano; + private long regionLoadMinTimeNano; + private long regionLoadMaxTimeNano; - Long current; - while ((current = nanoTimes.poll()) != null) { - if (currentRegionLoadCount > 0) { - if (current < currentRegionLoadMinTimeNano) { - currentRegionLoadMinTimeNano = current; - } - if (current > currentRegionLoadMaxTimeNano) { - currentRegionLoadMaxTimeNano = current; - } - } else { - currentRegionLoadMinTimeNano = current; - currentRegionLoadMaxTimeNano = current; - } + private void poll() { + long currentRegionLoadCount = 0; + long currentRegionLoadSumNano = 0; + long currentRegionLoadMinTimeNano = Long.MAX_VALUE; + long currentRegionLoadMaxTimeNano = Long.MIN_VALUE; - currentRegionLoadCount++; - currentRegionLoadSumNano += current; - } + Long current; + while ((current = nanoTimes.poll()) != null) { + if (currentRegionLoadCount > 0) { + if (current < currentRegionLoadMinTimeNano) { + currentRegionLoadMinTimeNano = current; + } + if (current > currentRegionLoadMaxTimeNano) { + currentRegionLoadMaxTimeNano = current; + } + } else { + currentRegionLoadMinTimeNano = current; + currentRegionLoadMaxTimeNano = current; + } - if (currentRegionLoadCount == 0) { - return; - } + currentRegionLoadCount++; + currentRegionLoadSumNano += current; + } - synchronized (syncRoot) { - if (regionLoadCount > 0) { - if (currentRegionLoadMinTimeNano < regionLoadMinTimeNano) { - regionLoadMinTimeNano = currentRegionLoadMinTimeNano; - } - if (currentRegionLoadMaxTimeNano > regionLoadMaxTimeNano) { - regionLoadMaxTimeNano = currentRegionLoadMaxTimeNano; - } - } else { - regionLoadMinTimeNano = currentRegionLoadMinTimeNano; - regionLoadMaxTimeNano = currentRegionLoadMaxTimeNano; - } + if (currentRegionLoadCount == 0) { + return; + } - regionLoadCount += currentRegionLoadCount; - regionLoadSumNano += currentRegionLoadSumNano; - } - } + synchronized (syncRoot) { + if (regionLoadCount > 0) { + if (currentRegionLoadMinTimeNano < regionLoadMinTimeNano) { + regionLoadMinTimeNano = currentRegionLoadMinTimeNano; + } + if (currentRegionLoadMaxTimeNano > regionLoadMaxTimeNano) { + regionLoadMaxTimeNano = currentRegionLoadMaxTimeNano; + } + } else { + regionLoadMinTimeNano = currentRegionLoadMinTimeNano; + regionLoadMaxTimeNano = currentRegionLoadMaxTimeNano; + } - void startPolling() { - scheduler.scheduleWithFixedDelay(() -> { - poll(); - }, POLL_INTERVAL_MS, POLL_INTERVAL_MS, TimeUnit.MILLISECONDS); - } + regionLoadCount += currentRegionLoadCount; + regionLoadSumNano += currentRegionLoadSumNano; + } + } - void stopPolling() { - this.scheduler.shutdown(); + void startPolling() { + scheduler.scheduleWithFixedDelay(() -> { + poll(); + }, POLL_INTERVAL_MS, POLL_INTERVAL_MS, TimeUnit.MILLISECONDS); + } - try { - if (!this.scheduler.awaitTermination(5, TimeUnit.SECONDS)) - this.scheduler.shutdownNow(); - } catch (InterruptedException ex) { - ex.printStackTrace(); - } - } + void stopPolling() { + this.scheduler.shutdown(); - void pushTimeNano(long nano) { - nanoTimes.add(nano); - } + try { + if (!this.scheduler.awaitTermination(5, TimeUnit.SECONDS)) + this.scheduler.shutdownNow(); + } catch (InterruptedException ex) { + ex.printStackTrace(); + } + } - void getStat(ActivityMapStat stat) { - poll(); + void pushTimeNano(long nano) { + nanoTimes.add(nano); + } - synchronized (syncRoot) { - stat.regionLoadCount = regionLoadCount; - stat.regionLoadSumNano = regionLoadSumNano; - stat.regionLoadMinTimeNano = regionLoadMinTimeNano; - stat.regionLoadMaxTimeNano = regionLoadMaxTimeNano; - } - } + void getStat(ActivityMapStat stat) { + poll(); + + synchronized (syncRoot) { + stat.regionLoadCount = regionLoadCount; + stat.regionLoadSumNano = regionLoadSumNano; + stat.regionLoadMinTimeNano = regionLoadMinTimeNano; + stat.regionLoadMaxTimeNano = regionLoadMaxTimeNano; + } + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/activity/ChunkCoord.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/activity/ChunkCoord.java index cb3410879..966e8b695 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/activity/ChunkCoord.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/activity/ChunkCoord.java @@ -1,8 +1,9 @@ package vg.civcraft.mc.citadel.activity; -record ChunkCoord (short worldId, int x, int z) { - @Override - public int hashCode() { - return (int)worldId & 0xffff | (x << 4) | (z << 18); - } +record ChunkCoord(short worldId, int x, int z) { + + @Override + public int hashCode() { + return (int) worldId & 0xffff | (x << 4) | (z << 18); + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/activity/GroupData.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/activity/GroupData.java index bc6914fa4..02ec4559a 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/activity/GroupData.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/activity/GroupData.java @@ -3,10 +3,11 @@ package vg.civcraft.mc.citadel.activity; import java.time.Instant; class GroupData { - public Instant activity; - public Instant entry; - public GroupData(Instant activity) { - this.activity = activity; - } + public Instant activity; + public Instant entry; + + public GroupData(Instant activity) { + this.activity = activity; + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/activity/PlayerUpdate.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/activity/PlayerUpdate.java index b576e3d99..b82f867a9 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/activity/PlayerUpdate.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/activity/PlayerUpdate.java @@ -2,5 +2,6 @@ package vg.civcraft.mc.citadel.activity; import java.util.UUID; -record PlayerUpdate (RegionCoord regionCoord, UUID playerId) { +record PlayerUpdate(RegionCoord regionCoord, UUID playerId) { + } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/activity/RegionCoord.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/activity/RegionCoord.java index 0bc875875..17ef6af43 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/activity/RegionCoord.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/activity/RegionCoord.java @@ -1,8 +1,9 @@ package vg.civcraft.mc.citadel.activity; -record RegionCoord (short worldId, int x, int z) { - @Override - public int hashCode() { - return (int)worldId & 0xffff | (x << 8) | (z << 16); - } +record RegionCoord(short worldId, int x, int z) { + + @Override + public int hashCode() { + return (int) worldId & 0xffff | (x << 8) | (z << 16); + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/activity/RegionData.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/activity/RegionData.java index d415b6269..817a9dcc5 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/activity/RegionData.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/activity/RegionData.java @@ -7,36 +7,37 @@ import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; class RegionData { - private final Map data = new HashMap<>(); - private final AtomicBoolean isLoaded = new AtomicBoolean(); - private final Set chunks = new HashSet<>(); - public void put(int groupId, GroupData groupData) { - data.put(groupId, groupData); - } + private final Map data = new HashMap<>(); + private final AtomicBoolean isLoaded = new AtomicBoolean(); + private final Set chunks = new HashSet<>(); - public GroupData get(int groupId) { - return data.computeIfAbsent(groupId, a -> new GroupData(null)); - } + public void put(int groupId, GroupData groupData) { + data.put(groupId, groupData); + } - public void addChunk(ChunkCoord chunkCoord) { - chunks.add(chunkCoord); - } + public GroupData get(int groupId) { + return data.computeIfAbsent(groupId, a -> new GroupData(null)); + } - public boolean removeChunk(ChunkCoord chunkCoord) { - chunks.remove(chunkCoord); - return chunks.size() == 0; - } + public void addChunk(ChunkCoord chunkCoord) { + chunks.add(chunkCoord); + } - public boolean isLoaded() { - return isLoaded.get(); - } + public boolean removeChunk(ChunkCoord chunkCoord) { + chunks.remove(chunkCoord); + return chunks.size() == 0; + } - public void setLoaded() { - isLoaded.set(true); - } + public boolean isLoaded() { + return isLoaded.get(); + } - public Set getGroups() { - return data.keySet(); - } + public void setLoaded() { + isLoaded.set(true); + } + + public Set getGroups() { + return data.keySet(); + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/activity/XZKey.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/activity/XZKey.java index 038e8cefc..c931cf5b7 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/activity/XZKey.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/activity/XZKey.java @@ -1,8 +1,9 @@ package vg.civcraft.mc.citadel.activity; -record XZKey (int x, int z) { - @Override - public int hashCode() { - return x | (z << 8); - } +record XZKey(int x, int z) { + + @Override + public int hashCode() { + return x | (z << 8); + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/Acid.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/Acid.java index 8984c8278..e2ff43d9b 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/Acid.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/Acid.java @@ -27,100 +27,100 @@ import vg.civcraft.mc.civmodcore.utilities.TextUtil; public class Acid extends BaseCommand { - @CommandAlias("ctacid|acid") - @Description("Removes the block above it if used on an acid block") - public void execute(Player p) { - Iterator itr = new BlockIterator(p, 40); // Within 2.5 chunks - AcidManager acidMan = Citadel.getInstance().getAcidManager(); - boolean foundAny = false; - while (itr.hasNext()) { - Block block = itr.next(); - if (MaterialUtils.isAir(block.getType()) || !(block.getType().isSolid()) || !(block.getType().isOccluding())) { - continue; - } - if (!acidMan.isPossibleAcidBlock(block)) { - if (!foundAny) { - CitadelUtility.sendAndLog(p, ChatColor.RED, "That block is not a valid acid block"); - } - return; - } - Reinforcement reinforcement = ReinforcementLogic.getReinforcementAt(block.getLocation()); - if (reinforcement == null) { - CitadelUtility.sendAndLog(p, ChatColor.RED, "That block is not reinforced."); - return; - } - if (!reinforcement.hasPermission(p, CitadelPermissionHandler.getAcidblock())) { - CitadelUtility.sendAndLog(p, ChatColor.RED, - "You do not have sufficient permission to use acid blocks on this group."); - return; - } - long neededTime = acidMan.getRemainingAcidMaturationTime(reinforcement); - if (neededTime > 0) { - CitadelUtility.sendAndLog(p, ChatColor.RED, "That acid block will be mature in " - + TextUtil.formatDuration(neededTime, TimeUnit.MILLISECONDS)); - return; - } + @CommandAlias("ctacid|acid") + @Description("Removes the block above it if used on an acid block") + public void execute(Player p) { + Iterator itr = new BlockIterator(p, 40); // Within 2.5 chunks + AcidManager acidMan = Citadel.getInstance().getAcidManager(); + boolean foundAny = false; + while (itr.hasNext()) { + Block block = itr.next(); + if (MaterialUtils.isAir(block.getType()) || !(block.getType().isSolid()) || !(block.getType().isOccluding())) { + continue; + } + if (!acidMan.isPossibleAcidBlock(block)) { + if (!foundAny) { + CitadelUtility.sendAndLog(p, ChatColor.RED, "That block is not a valid acid block"); + } + return; + } + Reinforcement reinforcement = ReinforcementLogic.getReinforcementAt(block.getLocation()); + if (reinforcement == null) { + CitadelUtility.sendAndLog(p, ChatColor.RED, "That block is not reinforced."); + return; + } + if (!reinforcement.hasPermission(p, CitadelPermissionHandler.getAcidblock())) { + CitadelUtility.sendAndLog(p, ChatColor.RED, + "You do not have sufficient permission to use acid blocks on this group."); + return; + } + long neededTime = acidMan.getRemainingAcidMaturationTime(reinforcement); + if (neededTime > 0) { + CitadelUtility.sendAndLog(p, ChatColor.RED, "That acid block will be mature in " + + TextUtil.formatDuration(neededTime, TimeUnit.MILLISECONDS)); + return; + } - AcidType acidType = acidMan.getAcidTypeFromMaterial(block.getType()); + AcidType acidType = acidMan.getAcidTypeFromMaterial(block.getType()); - for (BlockFace blockFace : acidType.blockFaces()) { - Block relativeBlock = block.getRelative(blockFace); + for (BlockFace blockFace : acidType.blockFaces()) { + Block relativeBlock = block.getRelative(blockFace); - Reinforcement relativeReinforcement = ReinforcementLogic.getReinforcementProtecting(relativeBlock); - if ( - relativeReinforcement == null - || !relativeReinforcement.getType().canBeReinforced(relativeBlock.getType()) - || !acidMan.canAcidBlock(reinforcement.getType(), relativeReinforcement.getType()) - || acidMan.isPossibleAcidBlock(relativeBlock) - ) { - continue; - } + Reinforcement relativeReinforcement = ReinforcementLogic.getReinforcementProtecting(relativeBlock); + if ( + relativeReinforcement == null + || !relativeReinforcement.getType().canBeReinforced(relativeBlock.getType()) + || !acidMan.canAcidBlock(reinforcement.getType(), relativeReinforcement.getType()) + || acidMan.isPossibleAcidBlock(relativeBlock) + ) { + continue; + } - ReinforcementAcidBlockedEvent event = new ReinforcementAcidBlockedEvent(p, reinforcement, relativeReinforcement); - Bukkit.getPluginManager().callEvent(event); - if (event.isCancelled()) { - if (Citadel.getInstance().getConfigManager().isDebugEnabled()) { - Citadel.getInstance().getLogger().log(Level.INFO, - "Acid block event cancelled for acid at " + reinforcement.getLocation()); - } - return; - } + ReinforcementAcidBlockedEvent event = new ReinforcementAcidBlockedEvent(p, reinforcement, relativeReinforcement); + Bukkit.getPluginManager().callEvent(event); + if (event.isCancelled()) { + if (Citadel.getInstance().getConfigManager().isDebugEnabled()) { + Citadel.getInstance().getLogger().log(Level.INFO, + "Acid block event cancelled for acid at " + reinforcement.getLocation()); + } + return; + } - if (Citadel.getInstance().getConfigManager().logHostileBreaks()) { - Citadel.getInstance().getLogger().log(Level.INFO, "Acid at {0} broke {1} at {2}, activated by {3}", - new Object[]{block.getLocation(), relativeBlock.getType(), relativeBlock.getLocation(), p.getName()}); - } + if (Citadel.getInstance().getConfigManager().logHostileBreaks()) { + Citadel.getInstance().getLogger().log(Level.INFO, "Acid at {0} broke {1} at {2}, activated by {3}", + new Object[]{block.getLocation(), relativeBlock.getType(), relativeBlock.getLocation(), p.getName()}); + } - foundAny = true; - ReinforcementLogic.damageReinforcement(relativeReinforcement, relativeReinforcement.getHealth() + 1, p); - if (!acidContainerBlock(relativeBlock)) { - relativeBlock.breakNaturally(); - } - } + foundAny = true; + ReinforcementLogic.damageReinforcement(relativeReinforcement, relativeReinforcement.getHealth() + 1, p); + if (!acidContainerBlock(relativeBlock)) { + relativeBlock.breakNaturally(); + } + } - reinforcement.setHealth(-1); - block.breakNaturally(); - p.getWorld().dropItemNaturally(reinforcement.getLocation(), reinforcement.getType().getItem()); - } - } + reinforcement.setHealth(-1); + block.breakNaturally(); + p.getWorld().dropItemNaturally(reinforcement.getLocation(), reinforcement.getType().getItem()); + } + } - /** - * Checks if a containers contents can be dropped - * - * @param block Container being acid blocked - * @return true if contents have been successfully dropped - */ + /** + * Checks if a containers contents can be dropped + * + * @param block Container being acid blocked + * @return true if contents have been successfully dropped + */ - public boolean acidContainerBlock(Block block) { - if (!(block instanceof Container)) { - return false; - } - Container container = (Container) block.getBlockData(); - ItemStack[] items = container.getInventory().getContents(); - container.getInventory().clear(); - for (ItemStack item : items) { - block.getWorld().dropItemNaturally(block.getLocation(), item); - } - return true; - } + public boolean acidContainerBlock(Block block) { + if (!(block instanceof Container)) { + return false; + } + Container container = (Container) block.getBlockData(); + ItemStack[] items = container.getInventory().getContents(); + container.getInventory().clear(); + for (ItemStack item : items) { + block.getWorld().dropItemNaturally(block.getLocation(), item); + } + return true; + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/Activity.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/Activity.java index ffd71b2b5..830e6eebf 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/Activity.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/Activity.java @@ -13,38 +13,39 @@ import vg.civcraft.mc.citadel.activity.ActivityMapStat; @CommandAlias("am") public class Activity extends BaseCommand { - @CommandAlias("stat") - @Description("Shows ActivityMap statistics.") - @CommandPermission("citadel.admin") - public void execute(CommandSender sender) { - ActivityMapStat stat = Citadel.getInstance().getActivityMap().getStat(); - if (stat == null) { - sender.sendMessage(Component.text("ActivityMap is disabled").color(NamedTextColor.RED)); - return; - } - sender.sendMessage(Component.text("[ActivityMap] object statistics:").color(NamedTextColor.YELLOW)); - sender.sendMessage("World count: " + stat.worlds); - sender.sendMessage("In-memory loaded regions: " + longToStr(stat.loadedRegions)); - sender.sendMessage("In-memory NOT loaded regions: " + longToStr(stat.notLoadedRegions)); - sender.sendMessage("In-memory groups: " + longToStr(stat.uniqueGroups)); - sender.sendMessage("In-memory activities: " + longToStr(stat.loadedActivities)); + @CommandAlias("stat") + @Description("Shows ActivityMap statistics.") + @CommandPermission("citadel.admin") + public void execute(CommandSender sender) { + ActivityMapStat stat = Citadel.getInstance().getActivityMap().getStat(); + if (stat == null) { + sender.sendMessage(Component.text("ActivityMap is disabled").color(NamedTextColor.RED)); + return; + } - sender.sendMessage(Component.text("[ActivityMap] region load statistics:").color(NamedTextColor.YELLOW)); - sender.sendMessage("Regions loaded: " + longToStr(stat.regionLoadCount)); - sender.sendMessage("Regions un-loaded: " + longToStr(stat.regionUnloadCount)); - sender.sendMessage("Total load time: " + nanoToMsStr(stat.regionLoadSumNano)); - sender.sendMessage("Min load time: " + nanoToMsStr(stat.regionLoadMinTimeNano)); - sender.sendMessage("Max load time: " + nanoToMsStr(stat.regionLoadMaxTimeNano)); - sender.sendMessage("Avg load time: " + nanoToMsStr(stat.regionLoadSumNano / stat.regionLoadCount)); - } + sender.sendMessage(Component.text("[ActivityMap] object statistics:").color(NamedTextColor.YELLOW)); + sender.sendMessage("World count: " + stat.worlds); + sender.sendMessage("In-memory loaded regions: " + longToStr(stat.loadedRegions)); + sender.sendMessage("In-memory NOT loaded regions: " + longToStr(stat.notLoadedRegions)); + sender.sendMessage("In-memory groups: " + longToStr(stat.uniqueGroups)); + sender.sendMessage("In-memory activities: " + longToStr(stat.loadedActivities)); - private static String longToStr(long i) { - return String.format("%,d", i); - } + sender.sendMessage(Component.text("[ActivityMap] region load statistics:").color(NamedTextColor.YELLOW)); + sender.sendMessage("Regions loaded: " + longToStr(stat.regionLoadCount)); + sender.sendMessage("Regions un-loaded: " + longToStr(stat.regionUnloadCount)); + sender.sendMessage("Total load time: " + nanoToMsStr(stat.regionLoadSumNano)); + sender.sendMessage("Min load time: " + nanoToMsStr(stat.regionLoadMinTimeNano)); + sender.sendMessage("Max load time: " + nanoToMsStr(stat.regionLoadMaxTimeNano)); + sender.sendMessage("Avg load time: " + nanoToMsStr(stat.regionLoadSumNano / stat.regionLoadCount)); + } - private static String nanoToMsStr(long nano) { - double ms = (double)Math.round(nano / 10000L) / 100.0; - return String.format("%,.2f ms", ms); - } + private static String longToStr(long i) { + return String.format("%,d", i); + } + + private static String nanoToMsStr(long nano) { + double ms = (double) Math.round(nano / 10000L) / 100.0; + return String.format("%,.2f ms", ms); + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/AdvancedFortification.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/AdvancedFortification.java index f4b357cfb..7687d710c 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/AdvancedFortification.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/AdvancedFortification.java @@ -23,70 +23,70 @@ import vg.civcraft.mc.namelayer.group.Group; public class AdvancedFortification extends BaseCommand { - @CommandAlias("cta|advfort") - @Syntax("") - @Description("Enters advanced fortification mode or adds configurations to it. Advanced configuration mode allows you to place on different groups with different reinforcement types at once") - @CommandCompletion("@CT_Groups") - public void execute(Player player, @Optional String targetGroup) { - PlayerStateManager stateManager = Citadel.getInstance().getStateManager(); - AbstractPlayerState currentState = stateManager.getState(player); - AdvancedFortificationState advFortState = null; - if (currentState instanceof AdvancedFortificationState) { - advFortState = (AdvancedFortificationState) currentState; - if (targetGroup == null || targetGroup.isEmpty()) { - stateManager.setState(player, null); - return; - } - } - ItemStack mainHand = player.getInventory().getItemInMainHand(); - if (mainHand.getType() == Material.AIR) { - CitadelUtility.sendAndLog(player, ChatColor.RED, - "You need to hold an item in your main hand to specify the block type to reinforce"); - return; - } - ItemStack offHand = player.getInventory().getItemInOffHand(); - if (offHand.getType() == Material.AIR) { - CitadelUtility.sendAndLog(player, ChatColor.RED, "You need to hold a reinforcement item in your off hand"); - return; - } - ReinforcementType type = Citadel.getInstance().getReinforcementTypeManager().getByItemStack(offHand, player.getWorld().getName()); - if (type == null) { - CitadelUtility.sendAndLog(player, ChatColor.RED, "You can not reinforce with the item in your off hand"); - return; - } - if (!type.canBeReinforced(mainHand.getType())) { - CitadelUtility.sendAndLog(player, ChatColor.AQUA, - type.getName() + ChatColor.RED + " can not reinforce " + mainHand.getType().name()); - return; - } - String groupName = null; - if (targetGroup == null ||targetGroup.isEmpty()) { - groupName = NameAPI.getGroupManager().getDefaultGroup(player.getUniqueId()); - if (groupName == null) { - CitadelUtility.sendAndLog(player, ChatColor.RED, - "You don't have a default group and can thus not use this command without specifying a group"); - return; - } - } else { - groupName = targetGroup; - } + @CommandAlias("cta|advfort") + @Syntax("") + @Description("Enters advanced fortification mode or adds configurations to it. Advanced configuration mode allows you to place on different groups with different reinforcement types at once") + @CommandCompletion("@CT_Groups") + public void execute(Player player, @Optional String targetGroup) { + PlayerStateManager stateManager = Citadel.getInstance().getStateManager(); + AbstractPlayerState currentState = stateManager.getState(player); + AdvancedFortificationState advFortState = null; + if (currentState instanceof AdvancedFortificationState) { + advFortState = (AdvancedFortificationState) currentState; + if (targetGroup == null || targetGroup.isEmpty()) { + stateManager.setState(player, null); + return; + } + } + ItemStack mainHand = player.getInventory().getItemInMainHand(); + if (mainHand.getType() == Material.AIR) { + CitadelUtility.sendAndLog(player, ChatColor.RED, + "You need to hold an item in your main hand to specify the block type to reinforce"); + return; + } + ItemStack offHand = player.getInventory().getItemInOffHand(); + if (offHand.getType() == Material.AIR) { + CitadelUtility.sendAndLog(player, ChatColor.RED, "You need to hold a reinforcement item in your off hand"); + return; + } + ReinforcementType type = Citadel.getInstance().getReinforcementTypeManager().getByItemStack(offHand, player.getWorld().getName()); + if (type == null) { + CitadelUtility.sendAndLog(player, ChatColor.RED, "You can not reinforce with the item in your off hand"); + return; + } + if (!type.canBeReinforced(mainHand.getType())) { + CitadelUtility.sendAndLog(player, ChatColor.AQUA, + type.getName() + ChatColor.RED + " can not reinforce " + mainHand.getType().name()); + return; + } + String groupName = null; + if (targetGroup == null || targetGroup.isEmpty()) { + groupName = NameAPI.getGroupManager().getDefaultGroup(player.getUniqueId()); + if (groupName == null) { + CitadelUtility.sendAndLog(player, ChatColor.RED, + "You don't have a default group and can thus not use this command without specifying a group"); + return; + } + } else { + groupName = targetGroup; + } - Group group = GroupManager.getGroup(groupName); - if (group == null) { - CitadelUtility.sendAndLog(player, ChatColor.RED, "The group " + groupName + " does not exist."); - return; - } - boolean hasAccess = NameAPI.getGroupManager().hasAccess(group.getName(), player.getUniqueId(), - CitadelPermissionHandler.getReinforce()); - if (!hasAccess) { - CitadelUtility - .sendAndLog(player, ChatColor.RED, "You do not have permission to reinforce on " + group.getName()); - return; - } - if (advFortState == null) { - advFortState = new AdvancedFortificationState(player); - stateManager.setState(player, advFortState); - } - advFortState.addSetup(mainHand, type, group); - } + Group group = GroupManager.getGroup(groupName); + if (group == null) { + CitadelUtility.sendAndLog(player, ChatColor.RED, "The group " + groupName + " does not exist."); + return; + } + boolean hasAccess = NameAPI.getGroupManager().hasAccess(group.getName(), player.getUniqueId(), + CitadelPermissionHandler.getReinforce()); + if (!hasAccess) { + CitadelUtility + .sendAndLog(player, ChatColor.RED, "You do not have permission to reinforce on " + group.getName()); + return; + } + if (advFortState == null) { + advFortState = new AdvancedFortificationState(player); + stateManager.setState(player, advFortState); + } + advFortState.addSetup(mainHand, type, group); + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/AreaReinforce.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/AreaReinforce.java index d8adb7aad..f780d1ef1 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/AreaReinforce.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/AreaReinforce.java @@ -17,85 +17,85 @@ import vg.civcraft.mc.namelayer.group.Group; public class AreaReinforce extends BaseCommand { - @CommandAlias("ctar") - @Syntax(" ") - @Description("Using the reinforcement item in your main hand, reinforces an area to your default or a target group.") - @CommandCompletion("@CT_Groups @nothing @nothing @nothing @nothing @nothing @nothing true") - @CommandPermission("citadel.admin") - public void execute(Player p, @Optional String targetGroup, String minX, String minY, String minZ, String maxX, String maxY, String maxZ, @Optional String skipReinforcements) { - UUID uuid = NameAPI.getUUID(p.getName()); - ReinforcementType reinType = Citadel.getInstance().getReinforcementTypeManager() - .getByItemStack(p.getInventory().getItemInMainHand(), p.getWorld().getName()); - if (reinType == null) { - CitadelUtility.sendAndLog(p, ChatColor.RED, "The item you are holding is not a possible reinforcement"); - return; - } - String groupName = null; - if (targetGroup == null) { - groupName = NameAPI.getGroupManager().getDefaultGroup(uuid); - if (groupName == null) { - CitadelUtility.sendAndLog(p, ChatColor.RED, "You need to set a default group \n Use /nlsdg to do so"); - return; - } - } else { - groupName = targetGroup; - } - Group group = GroupManager.getGroup(groupName); - if (group == null) { - CitadelUtility.sendAndLog(p, ChatColor.RED, "That group does not exist."); - return; - } - // no additional group permission check here because the player is - // admin/op anyway - int xMin, yMin, zMin, xMax, yMax, zMax; - try { - int x1 = Integer.parseInt(minX); - int y1 = Integer.parseInt(minY); - int z1 = Integer.parseInt(minZ); - int x2 = Integer.parseInt(maxX); - int y2 = Integer.parseInt(maxY); - int z2 = Integer.parseInt(maxZ); - xMin = Math.min(x1, x2); - yMin = Math.min(y1, y2); - zMin = Math.min(z1, z2); - xMax = Math.max(x1, x2); - yMax = Math.max(y1, y2); - zMax = Math.max(z1, z2); - } catch (NumberFormatException e) { - CitadelUtility.sendAndLog(p, ChatColor.RED, "One of the arguments you provided was not a number"); - return; - } - boolean skipReins = skipReinforcements.equalsIgnoreCase("true"); - int count = 0; - for (int x = xMin; x <= xMax; x++) { - for (int y = yMin; y <= yMax; y++) { - for (int z = zMin; z <= zMax; z++) { - Block current = p.getWorld().getBlockAt(x, y, z); - if (!reinType.canBeReinforced(current.getType())) { - continue; - } - Reinforcement reinforcement = ReinforcementLogic.getReinforcementAt(current.getLocation()); - if (reinforcement != null) { - if (skipReins) { - continue; - } - } - Block protecting = ReinforcementLogic.getResponsibleBlock(current); - if (!current.getLocation().equals(protecting.getLocation())) { - continue; - } - if (current.getType().isAir()) { - continue; - } - count++; - Reinforcement rein = ReinforcementLogic.callReinforcementCreationEvent(p, current, reinType, group); - if (rein != null) { - ReinforcementLogic.createReinforcement(rein); - } - } - } - } + @CommandAlias("ctar") + @Syntax(" ") + @Description("Using the reinforcement item in your main hand, reinforces an area to your default or a target group.") + @CommandCompletion("@CT_Groups @nothing @nothing @nothing @nothing @nothing @nothing true") + @CommandPermission("citadel.admin") + public void execute(Player p, @Optional String targetGroup, String minX, String minY, String minZ, String maxX, String maxY, String maxZ, @Optional String skipReinforcements) { + UUID uuid = NameAPI.getUUID(p.getName()); + ReinforcementType reinType = Citadel.getInstance().getReinforcementTypeManager() + .getByItemStack(p.getInventory().getItemInMainHand(), p.getWorld().getName()); + if (reinType == null) { + CitadelUtility.sendAndLog(p, ChatColor.RED, "The item you are holding is not a possible reinforcement"); + return; + } + String groupName = null; + if (targetGroup == null) { + groupName = NameAPI.getGroupManager().getDefaultGroup(uuid); + if (groupName == null) { + CitadelUtility.sendAndLog(p, ChatColor.RED, "You need to set a default group \n Use /nlsdg to do so"); + return; + } + } else { + groupName = targetGroup; + } + Group group = GroupManager.getGroup(groupName); + if (group == null) { + CitadelUtility.sendAndLog(p, ChatColor.RED, "That group does not exist."); + return; + } + // no additional group permission check here because the player is + // admin/op anyway + int xMin, yMin, zMin, xMax, yMax, zMax; + try { + int x1 = Integer.parseInt(minX); + int y1 = Integer.parseInt(minY); + int z1 = Integer.parseInt(minZ); + int x2 = Integer.parseInt(maxX); + int y2 = Integer.parseInt(maxY); + int z2 = Integer.parseInt(maxZ); + xMin = Math.min(x1, x2); + yMin = Math.min(y1, y2); + zMin = Math.min(z1, z2); + xMax = Math.max(x1, x2); + yMax = Math.max(y1, y2); + zMax = Math.max(z1, z2); + } catch (NumberFormatException e) { + CitadelUtility.sendAndLog(p, ChatColor.RED, "One of the arguments you provided was not a number"); + return; + } + boolean skipReins = skipReinforcements.equalsIgnoreCase("true"); + int count = 0; + for (int x = xMin; x <= xMax; x++) { + for (int y = yMin; y <= yMax; y++) { + for (int z = zMin; z <= zMax; z++) { + Block current = p.getWorld().getBlockAt(x, y, z); + if (!reinType.canBeReinforced(current.getType())) { + continue; + } + Reinforcement reinforcement = ReinforcementLogic.getReinforcementAt(current.getLocation()); + if (reinforcement != null) { + if (skipReins) { + continue; + } + } + Block protecting = ReinforcementLogic.getResponsibleBlock(current); + if (!current.getLocation().equals(protecting.getLocation())) { + continue; + } + if (current.getType().isAir()) { + continue; + } + count++; + Reinforcement rein = ReinforcementLogic.callReinforcementCreationEvent(p, current, reinType, group); + if (rein != null) { + ReinforcementLogic.createReinforcement(rein); + } + } + } + } - CitadelUtility.sendAndLog(p, ChatColor.GREEN, "Successfully created " + count + " reinforcements"); - } + CitadelUtility.sendAndLog(p, ChatColor.GREEN, "Successfully created " + count + " reinforcements"); + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/Bypass.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/Bypass.java index 165b733ec..58396937a 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/Bypass.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/Bypass.java @@ -11,17 +11,17 @@ import vg.civcraft.mc.civmodcore.players.settings.impl.BooleanSetting; public class Bypass extends BaseCommand { - @CommandAlias("ctb|bypass") - @Description("Toggles bypass state. In bypass state you can break blocks reinforced on groups you have access to in a single break") - public void execute(Player player) { - BooleanSetting setting = Citadel.getInstance().getSettingManager().getBypass(); - boolean enabled = setting.getValue(player); - if (enabled) { - CitadelUtility.sendAndLog(player, ChatColor.GREEN, "Bypass mode has been disabled."); - } else { - CitadelUtility.sendAndLog(player, ChatColor.GREEN, - "Bypass mode has been enabled. You will be able to break reinforced blocks if you are on the group."); - } - setting.toggleValue(player.getUniqueId()); - } + @CommandAlias("ctb|bypass") + @Description("Toggles bypass state. In bypass state you can break blocks reinforced on groups you have access to in a single break") + public void execute(Player player) { + BooleanSetting setting = Citadel.getInstance().getSettingManager().getBypass(); + boolean enabled = setting.getValue(player); + if (enabled) { + CitadelUtility.sendAndLog(player, ChatColor.GREEN, "Bypass mode has been disabled."); + } else { + CitadelUtility.sendAndLog(player, ChatColor.GREEN, + "Bypass mode has been enabled. You will be able to break reinforced blocks if you are on the group."); + } + setting.toggleValue(player.getUniqueId()); + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/CitadelCommandManager.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/CitadelCommandManager.java index 02df64383..127d01b62 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/CitadelCommandManager.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/CitadelCommandManager.java @@ -9,32 +9,32 @@ import vg.civcraft.mc.namelayer.command.TabCompleters.GroupTabCompleter; public class CitadelCommandManager extends CommandManager { - public CitadelCommandManager(Plugin plugin) { - super(plugin); - init(); - } + public CitadelCommandManager(Plugin plugin) { + super(plugin); + init(); + } - @Override - public void registerCommands() { - registerCommand(new Acid()); - registerCommand(new Activity()); - registerCommand(new AdvancedFortification()); - registerCommand(new AreaReinforce()); - registerCommand(new Bypass()); - registerCommand(new EasyMode()); - registerCommand(new Fortification()); - registerCommand(new Information()); - registerCommand(new Insecure()); - registerCommand(new Off()); - registerCommand(new PatchMode()); - registerCommand(new Reinforce()); - registerCommand(new ReinforcementsGUI()); - registerCommand(new Reload()); - } + @Override + public void registerCommands() { + registerCommand(new Acid()); + registerCommand(new Activity()); + registerCommand(new AdvancedFortification()); + registerCommand(new AreaReinforce()); + registerCommand(new Bypass()); + registerCommand(new EasyMode()); + registerCommand(new Fortification()); + registerCommand(new Information()); + registerCommand(new Insecure()); + registerCommand(new Off()); + registerCommand(new PatchMode()); + registerCommand(new Reinforce()); + registerCommand(new ReinforcementsGUI()); + registerCommand(new Reload()); + } - @Override - public void registerCompletions(@Nonnull CommandCompletions completions) { - super.registerCompletions(completions); - completions.registerCompletion("CT_Groups", (context) -> GroupTabCompleter.complete(context.getInput(), null, context.getPlayer())); - } + @Override + public void registerCompletions(@Nonnull CommandCompletions completions) { + super.registerCompletions(completions); + completions.registerCompletion("CT_Groups", (context) -> GroupTabCompleter.complete(context.getInput(), null, context.getPlayer())); + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/EasyMode.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/EasyMode.java index becefda3c..f94d38469 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/EasyMode.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/EasyMode.java @@ -11,17 +11,17 @@ import vg.civcraft.mc.civmodcore.players.settings.impl.BooleanSetting; public class EasyMode extends BaseCommand { - @CommandAlias("cte|easymode") - @Description("Reinforces to your default group using materials from your offhand.") - public void execute(Player player) { - BooleanSetting setting = Citadel.getInstance().getSettingManager().getEasyMode(); - boolean enabled = setting.getValue(player); - if (enabled) { - CitadelUtility.sendAndLog(player, ChatColor.GREEN, "Easy reinforcing mode has been disabled."); - } else { - CitadelUtility.sendAndLog(player, ChatColor.GREEN, - "Easy reinforcing mode has been enabled. You will be able to reinforce to your default group by placing blocks while having a reinforcement material in your off hand."); - } - setting.toggleValue(player.getUniqueId()); - } + @CommandAlias("cte|easymode") + @Description("Reinforces to your default group using materials from your offhand.") + public void execute(Player player) { + BooleanSetting setting = Citadel.getInstance().getSettingManager().getEasyMode(); + boolean enabled = setting.getValue(player); + if (enabled) { + CitadelUtility.sendAndLog(player, ChatColor.GREEN, "Easy reinforcing mode has been disabled."); + } else { + CitadelUtility.sendAndLog(player, ChatColor.GREEN, + "Easy reinforcing mode has been enabled. You will be able to reinforce to your default group by placing blocks while having a reinforcement material in your off hand."); + } + setting.toggleValue(player.getUniqueId()); + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/Fortification.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/Fortification.java index 10c9ea515..5cb2d301b 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/Fortification.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/Fortification.java @@ -21,57 +21,57 @@ import vg.civcraft.mc.namelayer.group.Group; public class Fortification extends BaseCommand { - @CommandAlias("ctf|reinforce|fortify") - @Syntax("") - @Description("Enters fortification mode. All blocks placed in fortification mode will automatically be reinforced. If no group is given, your default group will be used") - @CommandCompletion("@CT_Groups") - public void execute(Player player, @Optional String targetGroup) { - PlayerStateManager stateManager = Citadel.getInstance().getStateManager(); - AbstractPlayerState currentState = stateManager.getState(player); - if (targetGroup == null && currentState instanceof FortificationState) { - stateManager.setState(player, null); - return; - } - ReinforcementType type = Citadel.getInstance().getReinforcementTypeManager() - .getByItemStack(player.getInventory().getItemInMainHand(), player.getWorld().getName()); - if (type == null) { - CitadelUtility.sendAndLog(player, ChatColor.RED, "You can not reinforce with this item"); - stateManager.setState(player, null); - return; - } - - String groupName = null; - if (targetGroup == null) { - groupName = NameAPI.getGroupManager().getDefaultGroup(player.getUniqueId()); - if (groupName == null) { - CitadelUtility.sendAndLog(player, ChatColor.RED, - "You need to fortify to a group! Try /fortify groupname. \n Or use /create groupname if you don't have a group yet."); - return; - } - } else { - groupName = targetGroup; - } - - Group group = GroupManager.getGroup(groupName); - if (group == null) { - CitadelUtility.sendAndLog(player, ChatColor.RED, "The group " + groupName + " does not exist."); - stateManager.setState(player, null); - return; - } - boolean hasAccess = NameAPI.getGroupManager().hasAccess(group.getName(), player.getUniqueId(), - CitadelPermissionHandler.getReinforce()); - if (!hasAccess) { - CitadelUtility.sendAndLog(player, ChatColor.RED, "You do not have permission to reinforce on " + group.getName()); - stateManager.setState(player, null); - return; - } - if (currentState instanceof FortificationState) { - FortificationState fortState = (FortificationState) currentState; - if (fortState.getGroup() == group && fortState.getType() == type) { - stateManager.setState(player, null); - return; - } - } - stateManager.setState(player, new FortificationState(player, type, group)); - } + @CommandAlias("ctf|reinforce|fortify") + @Syntax("") + @Description("Enters fortification mode. All blocks placed in fortification mode will automatically be reinforced. If no group is given, your default group will be used") + @CommandCompletion("@CT_Groups") + public void execute(Player player, @Optional String targetGroup) { + PlayerStateManager stateManager = Citadel.getInstance().getStateManager(); + AbstractPlayerState currentState = stateManager.getState(player); + if (targetGroup == null && currentState instanceof FortificationState) { + stateManager.setState(player, null); + return; + } + ReinforcementType type = Citadel.getInstance().getReinforcementTypeManager() + .getByItemStack(player.getInventory().getItemInMainHand(), player.getWorld().getName()); + if (type == null) { + CitadelUtility.sendAndLog(player, ChatColor.RED, "You can not reinforce with this item"); + stateManager.setState(player, null); + return; + } + + String groupName = null; + if (targetGroup == null) { + groupName = NameAPI.getGroupManager().getDefaultGroup(player.getUniqueId()); + if (groupName == null) { + CitadelUtility.sendAndLog(player, ChatColor.RED, + "You need to fortify to a group! Try /fortify groupname. \n Or use /create groupname if you don't have a group yet."); + return; + } + } else { + groupName = targetGroup; + } + + Group group = GroupManager.getGroup(groupName); + if (group == null) { + CitadelUtility.sendAndLog(player, ChatColor.RED, "The group " + groupName + " does not exist."); + stateManager.setState(player, null); + return; + } + boolean hasAccess = NameAPI.getGroupManager().hasAccess(group.getName(), player.getUniqueId(), + CitadelPermissionHandler.getReinforce()); + if (!hasAccess) { + CitadelUtility.sendAndLog(player, ChatColor.RED, "You do not have permission to reinforce on " + group.getName()); + stateManager.setState(player, null); + return; + } + if (currentState instanceof FortificationState) { + FortificationState fortState = (FortificationState) currentState; + if (fortState.getGroup() == group && fortState.getType() == type) { + stateManager.setState(player, null); + return; + } + } + stateManager.setState(player, new FortificationState(player, type, group)); + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/Information.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/Information.java index de5ee8490..a8608b619 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/Information.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/Information.java @@ -10,12 +10,12 @@ import vg.civcraft.mc.civmodcore.players.settings.impl.BooleanSetting; public class Information extends BaseCommand { - @CommandAlias("cti|ctinfo|info") - @Description("Enters information mode. Interacting with blocks in information mode will show information on their reinforcement") - public void execute(Player player) { - BooleanSetting ctiSetting = Citadel.getInstance().getSettingManager().getInformationMode(); - ctiSetting.toggleValue(player.getUniqueId()); - player.sendMessage(ChatColor.GREEN + "Toggled reinforcement information mode " + ChatColor.YELLOW - + (ctiSetting.getValue(player.getUniqueId()) ? "on" : "off")); - } + @CommandAlias("cti|ctinfo|info") + @Description("Enters information mode. Interacting with blocks in information mode will show information on their reinforcement") + public void execute(Player player) { + BooleanSetting ctiSetting = Citadel.getInstance().getSettingManager().getInformationMode(); + ctiSetting.toggleValue(player.getUniqueId()); + player.sendMessage(ChatColor.GREEN + "Toggled reinforcement information mode " + ChatColor.YELLOW + + (ctiSetting.getValue(player.getUniqueId()) ? "on" : "off")); + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/Insecure.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/Insecure.java index 75d0cb3d9..3a00b782d 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/Insecure.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/Insecure.java @@ -11,15 +11,15 @@ import vg.civcraft.mc.citadel.playerstate.PlayerStateManager; public class Insecure extends BaseCommand { - @CommandAlias("ctin|insecure") - @Description("Enters insecure mode. Interacting with containers in insecure mode will switch their insecure flag. Insecure containers can interact with hoppers reinforced on a different group. All containers are secure by default") - public void execute(Player player) { - PlayerStateManager stateManager = Citadel.getInstance().getStateManager(); - AbstractPlayerState currentState = Citadel.getInstance().getStateManager().getState(player); - if (currentState instanceof InsecureState) { - stateManager.setState(player, null); - } else { - stateManager.setState(player, new InsecureState(player)); - } - } + @CommandAlias("ctin|insecure") + @Description("Enters insecure mode. Interacting with containers in insecure mode will switch their insecure flag. Insecure containers can interact with hoppers reinforced on a different group. All containers are secure by default") + public void execute(Player player) { + PlayerStateManager stateManager = Citadel.getInstance().getStateManager(); + AbstractPlayerState currentState = Citadel.getInstance().getStateManager().getState(player); + if (currentState instanceof InsecureState) { + stateManager.setState(player, null); + } else { + stateManager.setState(player, new InsecureState(player)); + } + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/Off.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/Off.java index cab93ced1..39afcd2fe 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/Off.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/Off.java @@ -10,17 +10,17 @@ import vg.civcraft.mc.citadel.model.CitadelSettingManager; public class Off extends BaseCommand { - @CommandAlias("cto") - @Description("Leaves all reinforcement modes") - public void execute(Player sender) { - Citadel.getInstance().getStateManager().setState(sender, null); - CitadelSettingManager settings = Citadel.getInstance().getSettingManager(); - UUID uuid = sender.getUniqueId(); - if (settings.getInformationMode().getValue(uuid) && settings.shouldCtoDisableCti(uuid)) { - settings.getInformationMode().setValue(uuid, false); - } - if (settings.getBypass().getValue(uuid) && settings.shouldCtoDisableCtb(uuid)) { - settings.getBypass().setValue(uuid, false); - } - } + @CommandAlias("cto") + @Description("Leaves all reinforcement modes") + public void execute(Player sender) { + Citadel.getInstance().getStateManager().setState(sender, null); + CitadelSettingManager settings = Citadel.getInstance().getSettingManager(); + UUID uuid = sender.getUniqueId(); + if (settings.getInformationMode().getValue(uuid) && settings.shouldCtoDisableCti(uuid)) { + settings.getInformationMode().setValue(uuid, false); + } + if (settings.getBypass().getValue(uuid) && settings.shouldCtoDisableCtb(uuid)) { + settings.getBypass().setValue(uuid, false); + } + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/PatchMode.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/PatchMode.java index 367b0715a..e49fa67c6 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/PatchMode.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/PatchMode.java @@ -12,16 +12,16 @@ import vg.civcraft.mc.citadel.playerstate.PlayerStateManager; public class PatchMode extends BaseCommand { - @CommandAlias("ctp|patchmode|patch") - @Description("Enters patch mode, which allows you to repair reinforcements. Note that repairing reinforcements will also reset their maturation cycle") - @CommandCompletion("@CT_Groups") - public void execute(Player player) { - PlayerStateManager stateManager = Citadel.getInstance().getStateManager(); - AbstractPlayerState currentState = Citadel.getInstance().getStateManager().getState(player); - if (currentState instanceof PatchState) { - stateManager.setState(player, null); - } else { - stateManager.setState(player, new PatchState(player)); - } - } + @CommandAlias("ctp|patchmode|patch") + @Description("Enters patch mode, which allows you to repair reinforcements. Note that repairing reinforcements will also reset their maturation cycle") + @CommandCompletion("@CT_Groups") + public void execute(Player player) { + PlayerStateManager stateManager = Citadel.getInstance().getStateManager(); + AbstractPlayerState currentState = Citadel.getInstance().getStateManager().getState(player); + if (currentState instanceof PatchState) { + stateManager.setState(player, null); + } else { + stateManager.setState(player, new PatchState(player)); + } + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/Reinforce.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/Reinforce.java index 53863f3a6..51a73eddc 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/Reinforce.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/Reinforce.java @@ -21,45 +21,45 @@ import vg.civcraft.mc.namelayer.group.Group; public class Reinforce extends BaseCommand { - @CommandAlias("ctr") - @Syntax("") - @Description("Enters reinforcing mode. Interacting with blocks in reinforcing mode will reinforce them or modify their reinforcement") - @CommandCompletion("@CT_Groups") - public void execute(Player player, @Optional String targetGroup) { - UUID uuid = NameAPI.getUUID(player.getName()); - String groupName = null; - if (targetGroup == null) { - groupName = NameAPI.getGroupManager().getDefaultGroup(uuid); - if (groupName == null) { - CitadelUtility.sendAndLog(player, ChatColor.RED, - "You need to reinforce to a group! Try /reinforce groupname. \n Or use /create groupname if you don't have a group yet."); - return; - } - } else { - groupName = targetGroup; - } - PlayerStateManager stateManager = Citadel.getInstance().getStateManager(); - Group group = GroupManager.getGroup(groupName); - if (group == null) { - CitadelUtility.sendAndLog(player, ChatColor.RED, "The group " + groupName + " does not exist."); - stateManager.setState(player, null); - return; - } - boolean hasAccess = NameAPI.getGroupManager().hasAccess(group.getName(), player.getUniqueId(), - CitadelPermissionHandler.getReinforce()); - if (!hasAccess) { - CitadelUtility.sendAndLog(player, ChatColor.RED, "You do not have permission to reinforce on " + group.getName()); - stateManager.setState(player, null); - return; - } - AbstractPlayerState currentState = Citadel.getInstance().getStateManager().getState(player); - if (currentState instanceof ReinforcingState) { - ReinforcingState reinState = (ReinforcingState) currentState; - if (reinState.getGroup() == group) { - stateManager.setState(player, null); - return; - } - } - stateManager.setState(player, new ReinforcingState(player, group)); - } + @CommandAlias("ctr") + @Syntax("") + @Description("Enters reinforcing mode. Interacting with blocks in reinforcing mode will reinforce them or modify their reinforcement") + @CommandCompletion("@CT_Groups") + public void execute(Player player, @Optional String targetGroup) { + UUID uuid = NameAPI.getUUID(player.getName()); + String groupName = null; + if (targetGroup == null) { + groupName = NameAPI.getGroupManager().getDefaultGroup(uuid); + if (groupName == null) { + CitadelUtility.sendAndLog(player, ChatColor.RED, + "You need to reinforce to a group! Try /reinforce groupname. \n Or use /create groupname if you don't have a group yet."); + return; + } + } else { + groupName = targetGroup; + } + PlayerStateManager stateManager = Citadel.getInstance().getStateManager(); + Group group = GroupManager.getGroup(groupName); + if (group == null) { + CitadelUtility.sendAndLog(player, ChatColor.RED, "The group " + groupName + " does not exist."); + stateManager.setState(player, null); + return; + } + boolean hasAccess = NameAPI.getGroupManager().hasAccess(group.getName(), player.getUniqueId(), + CitadelPermissionHandler.getReinforce()); + if (!hasAccess) { + CitadelUtility.sendAndLog(player, ChatColor.RED, "You do not have permission to reinforce on " + group.getName()); + stateManager.setState(player, null); + return; + } + AbstractPlayerState currentState = Citadel.getInstance().getStateManager().getState(player); + if (currentState instanceof ReinforcingState) { + ReinforcingState reinState = (ReinforcingState) currentState; + if (reinState.getGroup() == group) { + stateManager.setState(player, null); + return; + } + } + stateManager.setState(player, new ReinforcingState(player, group)); + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/ReinforcementsGUI.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/ReinforcementsGUI.java index aa684c6c4..b343ecc75 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/ReinforcementsGUI.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/ReinforcementsGUI.java @@ -28,69 +28,68 @@ import static java.util.stream.Collectors.partitioningBy; public class ReinforcementsGUI extends BaseCommand { - private DecimalFormat format = new DecimalFormat("##.##"); + private DecimalFormat format = new DecimalFormat("##.##"); - @CommandAlias("ctdl|reinforcements") - @Description("Opens a GUI displaying all reinforcement materials") - public void execute(Player sender) { + @CommandAlias("ctdl|reinforcements") + @Description("Opens a GUI displaying all reinforcement materials") + public void execute(Player sender) { - Map> allowedOrNot = Citadel.getInstance().getReinforcementTypeManager().getAllTypes() - .stream().collect(partitioningBy(i -> - i.isAllowedInWorld(sender.getWorld().getName()))); + Map> allowedOrNot = Citadel.getInstance().getReinforcementTypeManager().getAllTypes() + .stream().collect(partitioningBy(i -> + i.isAllowedInWorld(sender.getWorld().getName()))); - List allowedTypes = allowedOrNot.get(true); - List disallowedTypes = allowedOrNot.get(false); + List allowedTypes = allowedOrNot.get(true); + List disallowedTypes = allowedOrNot.get(false); - // sort ascending by health - Collections.sort(allowedTypes, (o1, o2) -> Double.compare(o1.getHealth(), o2.getHealth())); - Collections.sort(disallowedTypes, (o1, o2) -> Double.compare(o1.getHealth(), o2.getHealth())); - List clicks = new LinkedList<>(); + // sort ascending by health + Collections.sort(allowedTypes, (o1, o2) -> Double.compare(o1.getHealth(), o2.getHealth())); + Collections.sort(disallowedTypes, (o1, o2) -> Double.compare(o1.getHealth(), o2.getHealth())); + List clicks = new LinkedList<>(); - clicks.addAll(getClicks(allowedTypes, true)); + clicks.addAll(getClicks(allowedTypes, true)); - if (disallowedTypes.size() > 0) { - for (int i = 0; i < 18 - (allowedTypes.size() % 9); i++) { - clicks.add(new DecorationStack(Material.AIR)); - } - } - clicks.addAll(getClicks(disallowedTypes, false)); + if (disallowedTypes.size() > 0) { + for (int i = 0; i < 18 - (allowedTypes.size() % 9); i++) { + clicks.add(new DecorationStack(Material.AIR)); + } + } + clicks.addAll(getClicks(disallowedTypes, false)); - MultiPageView pageView = new MultiPageView(sender, clicks, ChatColor.BLUE + "Reinforcements", true); - pageView.showScreen(); - } + MultiPageView pageView = new MultiPageView(sender, clicks, ChatColor.BLUE + "Reinforcements", true); + pageView.showScreen(); + } - private List getClicks(List types, boolean allowed) - { - List clickables = new LinkedList<>(); + private List getClicks(List types, boolean allowed) { + List clickables = new LinkedList<>(); - for (ReinforcementType type : types) { - ItemStack is = type.getItem().clone(); - ItemUtils.setComponentDisplayName(is, Component.text(ChatColor.AQUA + type.getName() + (allowed ? ChatColor.GREEN + " (Allowed in current dimension)" : ChatColor.RED + " (Not allowed in current dimension)"))); - ItemUtils.addLore(is, ChatColor.GREEN + "Health: " + format.format(type.getHealth())); - ItemUtils.addLore(is, ChatColor.GOLD + "Maturation time: " - + TextUtil.formatDuration(type.getMaturationTime(), TimeUnit.MILLISECONDS)); - if (type.getAcidTime() > 0) { - ItemUtils.addLore(is, ChatColor.GOLD + "Acid maturation time: " - + TextUtil.formatDuration(type.getAcidTime(), TimeUnit.MILLISECONDS)); - } else { - ItemUtils.addLore(is, ChatColor.GOLD + "Can not be used for acid"); - } - ItemUtils.addLore(is, - ChatColor.WHITE + "Return chance: " + format.format(type.getReturnChance() * 100.0) + " %"); + for (ReinforcementType type : types) { + ItemStack is = type.getItem().clone(); + ItemUtils.setComponentDisplayName(is, Component.text(ChatColor.AQUA + type.getName() + (allowed ? ChatColor.GREEN + " (Allowed in current dimension)" : ChatColor.RED + " (Not allowed in current dimension)"))); + ItemUtils.addLore(is, ChatColor.GREEN + "Health: " + format.format(type.getHealth())); + ItemUtils.addLore(is, ChatColor.GOLD + "Maturation time: " + + TextUtil.formatDuration(type.getMaturationTime(), TimeUnit.MILLISECONDS)); + if (type.getAcidTime() > 0) { + ItemUtils.addLore(is, ChatColor.GOLD + "Acid maturation time: " + + TextUtil.formatDuration(type.getAcidTime(), TimeUnit.MILLISECONDS)); + } else { + ItemUtils.addLore(is, ChatColor.GOLD + "Can not be used for acid"); + } + ItemUtils.addLore(is, + ChatColor.WHITE + "Return chance: " + format.format(type.getReturnChance() * 100.0) + " %"); - ItemUtils.addComponentLore(is, Component.text(ChatColor.GOLD + "Allowed dimensions:")); - List allowedDimensionComponents = type.getAllowedWorlds().stream().map(e -> - Component.text(ChatColor.GREEN + " - " + e)).collect(Collectors.toList()); + ItemUtils.addComponentLore(is, Component.text(ChatColor.GOLD + "Allowed dimensions:")); + List allowedDimensionComponents = type.getAllowedWorlds().stream().map(e -> + Component.text(ChatColor.GREEN + " - " + e)).collect(Collectors.toList()); - if (allowedDimensionComponents.isEmpty()) { - ItemUtils.addComponentLore(is, Component.text(ChatColor.DARK_GREEN + " * Everywhere")); - } else { - ItemUtils.addComponentLore(is, allowedDimensionComponents); - } - IClickable click = new DecorationStack(is); - clickables.add(click); - } + if (allowedDimensionComponents.isEmpty()) { + ItemUtils.addComponentLore(is, Component.text(ChatColor.DARK_GREEN + " * Everywhere")); + } else { + ItemUtils.addComponentLore(is, allowedDimensionComponents); + } + IClickable click = new DecorationStack(is); + clickables.add(click); + } - return clickables; - } + return clickables; + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/Reload.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/Reload.java index 9cc350185..940b96a38 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/Reload.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/command/Reload.java @@ -10,11 +10,11 @@ import vg.civcraft.mc.citadel.Citadel; public class Reload extends BaseCommand { - @CommandAlias("citadelreload") - @CommandPermission("citadel.admin") - @Description("Reloads Citadel entirely") - public void execute(CommandSender sender) { - Citadel.getInstance().reload(); - sender.sendMessage(ChatColor.GREEN + "Reloaded Citadel"); - } + @CommandAlias("citadelreload") + @CommandPermission("citadel.admin") + @Description("Reloads Citadel entirely") + public void execute(CommandSender sender) { + Citadel.getInstance().reload(); + sender.sendMessage(ChatColor.GREEN + "Reloaded Citadel"); + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/events/ReinforcedBlockBreak.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/events/ReinforcedBlockBreak.java index 98a84c086..64a078c66 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/events/ReinforcedBlockBreak.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/events/ReinforcedBlockBreak.java @@ -7,33 +7,32 @@ import vg.civcraft.mc.citadel.model.Reinforcement; /** * Called when a reinforcement is destroyed and the block reinforced is going to drop - * */ public class ReinforcedBlockBreak extends ReinforcementEvent { - - private static final HandlerList handlers = new HandlerList(); - public static HandlerList getHandlerList() { - return handlers; - } - - private BlockBreakEvent blockEvent; + private static final HandlerList handlers = new HandlerList(); - public ReinforcedBlockBreak(Player who, Reinforcement reinforcement, BlockBreakEvent event) { - super(who, reinforcement); - this.blockEvent = event; - } - - /** - * @return The BlockBreakEvent which caused the destrution of the reinforcement - */ - public BlockBreakEvent getWrappedBlockBreakEvent() { - return blockEvent; - } + public static HandlerList getHandlerList() { + return handlers; + } - @Override - public HandlerList getHandlers() { - return handlers; - } + private BlockBreakEvent blockEvent; + + public ReinforcedBlockBreak(Player who, Reinforcement reinforcement, BlockBreakEvent event) { + super(who, reinforcement); + this.blockEvent = event; + } + + /** + * @return The BlockBreakEvent which caused the destrution of the reinforcement + */ + public BlockBreakEvent getWrappedBlockBreakEvent() { + return blockEvent; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/events/ReinforcementAcidBlockedEvent.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/events/ReinforcementAcidBlockedEvent.java index bb97d64a7..eb3d148cf 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/events/ReinforcementAcidBlockedEvent.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/events/ReinforcementAcidBlockedEvent.java @@ -6,33 +6,33 @@ import vg.civcraft.mc.citadel.model.Reinforcement; /** * Called when a block is destroyed by an acid block - * */ public class ReinforcementAcidBlockedEvent extends ReinforcementEvent { - private static final HandlerList handlers = new HandlerList(); - public static HandlerList getHandlerList() { - return handlers; - } + private static final HandlerList handlers = new HandlerList(); - private Reinforcement acidBlock; + public static HandlerList getHandlerList() { + return handlers; + } - public ReinforcementAcidBlockedEvent(Player player, Reinforcement acidBlock, Reinforcement destroyedBlock) { - super(player, destroyedBlock); - this.acidBlock = acidBlock; - } + private Reinforcement acidBlock; - /** - * Gets the reinforcement of the acid block. - * - * @return Acid block reinforcement - */ - public Reinforcement getAcidBlockReinforcement() { - return acidBlock; - } + public ReinforcementAcidBlockedEvent(Player player, Reinforcement acidBlock, Reinforcement destroyedBlock) { + super(player, destroyedBlock); + this.acidBlock = acidBlock; + } - @Override - public HandlerList getHandlers() { - return handlers; - } + /** + * Gets the reinforcement of the acid block. + * + * @return Acid block reinforcement + */ + public Reinforcement getAcidBlockReinforcement() { + return acidBlock; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/events/ReinforcementBypassEvent.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/events/ReinforcementBypassEvent.java index d7e607e14..129b829d4 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/events/ReinforcementBypassEvent.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/events/ReinforcementBypassEvent.java @@ -6,23 +6,22 @@ import vg.civcraft.mc.citadel.model.Reinforcement; /** * Called when a player bypasses a reinforcement they have access to - * */ public class ReinforcementBypassEvent extends ReinforcementEvent { - private static final HandlerList handlers = new HandlerList(); + private static final HandlerList handlers = new HandlerList(); - public static HandlerList getHandlerList() { - return handlers; - } + public static HandlerList getHandlerList() { + return handlers; + } - public ReinforcementBypassEvent(Player who, Reinforcement reinforcement) { - super(who, reinforcement); - } + public ReinforcementBypassEvent(Player who, Reinforcement reinforcement) { + super(who, reinforcement); + } - @Override - public HandlerList getHandlers() { - return handlers; - } + @Override + public HandlerList getHandlers() { + return handlers; + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/events/ReinforcementChangeTypeEvent.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/events/ReinforcementChangeTypeEvent.java index e38d1e5b3..a54187659 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/events/ReinforcementChangeTypeEvent.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/events/ReinforcementChangeTypeEvent.java @@ -7,33 +7,31 @@ import vg.civcraft.mc.citadel.reinforcementtypes.ReinforcementType; /** * Called when a reinforcements type is changed - * */ public class ReinforcementChangeTypeEvent extends ReinforcementEvent { - private static final HandlerList handlers = new HandlerList(); + private static final HandlerList handlers = new HandlerList(); - public static HandlerList getHandlerList() { - return handlers; - } + public static HandlerList getHandlerList() { + return handlers; + } - private ReinforcementType newType; + private ReinforcementType newType; - public ReinforcementChangeTypeEvent(Player p, Reinforcement rein, ReinforcementType newType) { - super(p, rein); - this.newType = newType; - } + public ReinforcementChangeTypeEvent(Player p, Reinforcement rein, ReinforcementType newType) { + super(p, rein); + this.newType = newType; + } - @Override - public HandlerList getHandlers() { - return handlers; - } + @Override + public HandlerList getHandlers() { + return handlers; + } - /** - * - * @return Future reinforcement type - */ - public ReinforcementType getNewType() { - return newType; - } + /** + * @return Future reinforcement type + */ + public ReinforcementType getNewType() { + return newType; + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/events/ReinforcementCreationEvent.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/events/ReinforcementCreationEvent.java index 54ed98b9e..af393b156 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/events/ReinforcementCreationEvent.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/events/ReinforcementCreationEvent.java @@ -6,22 +6,21 @@ import vg.civcraft.mc.citadel.model.Reinforcement; /** * Called when a new reinforcement is created - * */ public class ReinforcementCreationEvent extends ReinforcementEvent { - private static final HandlerList handlers = new HandlerList(); + private static final HandlerList handlers = new HandlerList(); - public static HandlerList getHandlerList() { - return handlers; - } + public static HandlerList getHandlerList() { + return handlers; + } - public ReinforcementCreationEvent(Player p, Reinforcement rein) { - super(p, rein); - } + public ReinforcementCreationEvent(Player p, Reinforcement rein) { + super(p, rein); + } - @Override - public HandlerList getHandlers() { - return handlers; - } + @Override + public HandlerList getHandlers() { + return handlers; + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/events/ReinforcementDamageEvent.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/events/ReinforcementDamageEvent.java index 8bd80de6c..e62fdefc8 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/events/ReinforcementDamageEvent.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/events/ReinforcementDamageEvent.java @@ -6,43 +6,42 @@ import vg.civcraft.mc.citadel.model.Reinforcement; /** * Called when a reinforcement is damaged by a player, but not when it is damaged by other entities or natural causes - * */ public class ReinforcementDamageEvent extends ReinforcementEvent { - private static final HandlerList handlers = new HandlerList(); + private static final HandlerList handlers = new HandlerList(); - public static HandlerList getHandlerList() { - return handlers; - } + public static HandlerList getHandlerList() { + return handlers; + } - private float damageDone; + private float damageDone; - public ReinforcementDamageEvent(Player player, Reinforcement rein, float damageDone) { - super(player, rein); - this.damageDone = damageDone; - } + public ReinforcementDamageEvent(Player player, Reinforcement rein, float damageDone) { + super(player, rein); + this.damageDone = damageDone; + } - /** - * Gets the total damage done by this damaging event - * - * @return Total damage - */ - public float getDamageDone() { - return damageDone; - } + /** + * Gets the total damage done by this damaging event + * + * @return Total damage + */ + public float getDamageDone() { + return damageDone; + } - @Override - public HandlerList getHandlers() { - return handlers; - } + @Override + public HandlerList getHandlers() { + return handlers; + } - /** - * Sets the total damage done - * - * @param damageDone Damage to do - */ - public void setDamageDone(float damageDone) { - this.damageDone = damageDone; - } + /** + * Sets the total damage done + * + * @param damageDone Damage to do + */ + public void setDamageDone(float damageDone) { + this.damageDone = damageDone; + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/events/ReinforcementDestructionEvent.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/events/ReinforcementDestructionEvent.java index a0fece6db..0f11663df 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/events/ReinforcementDestructionEvent.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/events/ReinforcementDestructionEvent.java @@ -9,62 +9,61 @@ import vg.civcraft.mc.citadel.model.Reinforcement; /** * Called when a reinforcement is forcefully destroyed, meaning it is removed * and was not bypassed - * */ public class ReinforcementDestructionEvent extends Event implements Cancellable { - private static final HandlerList handlers = new HandlerList(); + private static final HandlerList handlers = new HandlerList(); - public static HandlerList getHandlerList() { - return handlers; - } + public static HandlerList getHandlerList() { + return handlers; + } - private boolean isCancelled; - private Reinforcement reinforcement; - private float finalDamage; - private Entity source; + private boolean isCancelled; + private Reinforcement reinforcement; + private float finalDamage; + private Entity source; - public ReinforcementDestructionEvent(Reinforcement reinforcement, float finalDamage, Entity source) { - this.finalDamage = finalDamage; - this.reinforcement = reinforcement; - this.source = source; - } + public ReinforcementDestructionEvent(Reinforcement reinforcement, float finalDamage, Entity source) { + this.finalDamage = finalDamage; + this.reinforcement = reinforcement; + this.source = source; + } - /** - * @return Source of the final damage dealt to the reinforcement. May be a - * player, creeper, fireball etc. or possibly null - */ - public Entity getSource() { - return source; - } + /** + * @return Source of the final damage dealt to the reinforcement. May be a + * player, creeper, fireball etc. or possibly null + */ + public Entity getSource() { + return source; + } - /** - * @return Reinforcement destroyed - */ - public Reinforcement getReinforcement() { - return reinforcement; - } + /** + * @return Reinforcement destroyed + */ + public Reinforcement getReinforcement() { + return reinforcement; + } - /** - * @return How much damage was dealt in the killing blow to the reinforcement - */ - public float getFinalDamage() { - return finalDamage; - } + /** + * @return How much damage was dealt in the killing blow to the reinforcement + */ + public float getFinalDamage() { + return finalDamage; + } - @Override - public HandlerList getHandlers() { - return handlers; - } + @Override + public HandlerList getHandlers() { + return handlers; + } - @Override - public boolean isCancelled() { - return isCancelled; - } + @Override + public boolean isCancelled() { + return isCancelled; + } - @Override - public void setCancelled(boolean value) { - isCancelled = value; - } + @Override + public void setCancelled(boolean value) { + isCancelled = value; + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/events/ReinforcementEvent.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/events/ReinforcementEvent.java index 42c2f9aab..e57f548f2 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/events/ReinforcementEvent.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/events/ReinforcementEvent.java @@ -7,29 +7,29 @@ import vg.civcraft.mc.citadel.model.Reinforcement; public abstract class ReinforcementEvent extends PlayerEvent implements Cancellable { - protected Reinforcement reinforcement; - protected boolean isCancelled; + protected Reinforcement reinforcement; + protected boolean isCancelled; - public ReinforcementEvent(Player who, Reinforcement reinforcement) { - super(who); - this.reinforcement = reinforcement; - isCancelled = false; - } + public ReinforcementEvent(Player who, Reinforcement reinforcement) { + super(who); + this.reinforcement = reinforcement; + isCancelled = false; + } - /** - * @return Reinforcement involved in this event - */ - public Reinforcement getReinforcement() { - return reinforcement; - } + /** + * @return Reinforcement involved in this event + */ + public Reinforcement getReinforcement() { + return reinforcement; + } - @Override - public boolean isCancelled() { - return isCancelled; - } + @Override + public boolean isCancelled() { + return isCancelled; + } - @Override - public void setCancelled(boolean value) { - isCancelled = value; - } + @Override + public void setCancelled(boolean value) { + isCancelled = value; + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/events/ReinforcementGroupChangeEvent.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/events/ReinforcementGroupChangeEvent.java index 1f18a3d32..127dabdcc 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/events/ReinforcementGroupChangeEvent.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/events/ReinforcementGroupChangeEvent.java @@ -7,30 +7,29 @@ import vg.civcraft.mc.namelayer.group.Group; /** * Called when the group a reinforcement is on is changed - * */ public class ReinforcementGroupChangeEvent extends ReinforcementEvent { - private static final HandlerList handlers = new HandlerList(); + private static final HandlerList handlers = new HandlerList(); - public static HandlerList getHandlerList() { - return handlers; - } + public static HandlerList getHandlerList() { + return handlers; + } - private Group newGroup; + private Group newGroup; - public ReinforcementGroupChangeEvent(Player who, Reinforcement reinforcement, Group newGroup) { - super(who, reinforcement); - this.newGroup = newGroup; - } + public ReinforcementGroupChangeEvent(Player who, Reinforcement reinforcement, Group newGroup) { + super(who, reinforcement); + this.newGroup = newGroup; + } - @Override - public HandlerList getHandlers() { - return handlers; - } + @Override + public HandlerList getHandlers() { + return handlers; + } - public Group getNewGroup() { - return newGroup; - } + public Group getNewGroup() { + return newGroup; + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/events/ReinforcementModeSwitchEvent.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/events/ReinforcementModeSwitchEvent.java index 5a89ae416..1c69d65d8 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/events/ReinforcementModeSwitchEvent.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/events/ReinforcementModeSwitchEvent.java @@ -9,53 +9,52 @@ import vg.civcraft.mc.citadel.playerstate.AbstractPlayerState; /** * Called when a player changes his reinforcement mode. Not called when the * player attempt to switch, but stays in the same mode - * */ public class ReinforcementModeSwitchEvent extends PlayerEvent implements Cancellable { - private static final HandlerList handlers = new HandlerList(); + private static final HandlerList handlers = new HandlerList(); - public static HandlerList getHandlerList() { - return handlers; - } + public static HandlerList getHandlerList() { + return handlers; + } - private AbstractPlayerState oldState; - private AbstractPlayerState newState; - private boolean isCancelled; + private AbstractPlayerState oldState; + private AbstractPlayerState newState; + private boolean isCancelled; - public ReinforcementModeSwitchEvent(Player who, AbstractPlayerState oldState, AbstractPlayerState newState) { - super(who); - this.oldState = oldState; - this.newState = newState; - isCancelled = false; - } + public ReinforcementModeSwitchEvent(Player who, AbstractPlayerState oldState, AbstractPlayerState newState) { + super(who); + this.oldState = oldState; + this.newState = newState; + isCancelled = false; + } - /** - * @return Reinforcement mode before the change - */ - public AbstractPlayerState getOldMode() { - return oldState; - } + /** + * @return Reinforcement mode before the change + */ + public AbstractPlayerState getOldMode() { + return oldState; + } - /** - * @return Reinforcement mode after the change - */ - public AbstractPlayerState getNewMode() { - return newState; - } + /** + * @return Reinforcement mode after the change + */ + public AbstractPlayerState getNewMode() { + return newState; + } - @Override - public boolean isCancelled() { - return isCancelled; - } + @Override + public boolean isCancelled() { + return isCancelled; + } - @Override - public void setCancelled(boolean value) { - isCancelled = value; - } + @Override + public void setCancelled(boolean value) { + isCancelled = value; + } - @Override - public HandlerList getHandlers() { - return handlers; - } + @Override + public HandlerList getHandlers() { + return handlers; + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/events/ReinforcementRepairEvent.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/events/ReinforcementRepairEvent.java index 872989087..7db664a5f 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/events/ReinforcementRepairEvent.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/events/ReinforcementRepairEvent.java @@ -6,23 +6,22 @@ import vg.civcraft.mc.citadel.model.Reinforcement; /** * Called when a reinforcement is repaired in patch mode - * */ public class ReinforcementRepairEvent extends ReinforcementEvent { - - private static final HandlerList handlers = new HandlerList(); - public static HandlerList getHandlerList() { - return handlers; - } + private static final HandlerList handlers = new HandlerList(); - public ReinforcementRepairEvent(Player who, Reinforcement reinforcement) { - super(who, reinforcement); - } + public static HandlerList getHandlerList() { + return handlers; + } - @Override - public HandlerList getHandlers() { - return handlers; - } + public ReinforcementRepairEvent(Player who, Reinforcement reinforcement) { + super(who, reinforcement); + } + + @Override + public HandlerList getHandlers() { + return handlers; + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/listener/ActivityListener.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/listener/ActivityListener.java index 5f5d87d6c..a2c2dc993 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/listener/ActivityListener.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/listener/ActivityListener.java @@ -12,37 +12,37 @@ import vg.civcraft.mc.citadel.activity.ActivityMap; public class ActivityListener implements Listener { - private final ActivityMap map; + private final ActivityMap map; - public ActivityListener(ActivityMap map) { - this.map = map; - } + public ActivityListener(ActivityMap map) { + this.map = map; + } - @EventHandler - public void onPlayerMove(PlayerMoveEvent event) { - Location from = event.getFrom(); - Location to = event.getTo(); + @EventHandler + public void onPlayerMove(PlayerMoveEvent event) { + Location from = event.getFrom(); + Location to = event.getTo(); - if (to == null || from == null || !event.hasChangedBlock()) { - return; - } + if (to == null || from == null || !event.hasChangedBlock()) { + return; + } - map.savePlayerActivity(from, to, event.getPlayer()); - } + map.savePlayerActivity(from, to, event.getPlayer()); + } - @EventHandler - public void onPlayerJoin(PlayerJoinEvent event) { - Location location = event.getPlayer().getLocation(); - map.savePlayerActivity(location, event.getPlayer()); - } + @EventHandler + public void onPlayerJoin(PlayerJoinEvent event) { + Location location = event.getPlayer().getLocation(); + map.savePlayerActivity(location, event.getPlayer()); + } - @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) - public void onChunkLoad(ChunkLoadEvent e) { - map.loadChunk(e.getChunk()); - } + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onChunkLoad(ChunkLoadEvent e) { + map.loadChunk(e.getChunk()); + } - @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) - public void onChunkUnload(ChunkUnloadEvent e) { - map.unloadChunk(e.getChunk()); - } + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onChunkUnload(ChunkUnloadEvent e) { + map.unloadChunk(e.getChunk()); + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/listener/BlockListener.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/listener/BlockListener.java index ce2d64827..3e9fca9bd 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/listener/BlockListener.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/listener/BlockListener.java @@ -63,752 +63,752 @@ import java.util.Map; public class BlockListener implements Listener { - private static final Material matfire = Material.FIRE; - private final Map mossSpreadingDispensers = new HashMap<>(); + private static final Material matfire = Material.FIRE; + private final Map mossSpreadingDispensers = new HashMap<>(); - private DoubleInteractFixer interactFixer; + private DoubleInteractFixer interactFixer; - public BlockListener(Citadel plugin) { - this.interactFixer = new DoubleInteractFixer(plugin); - } + public BlockListener(Citadel plugin) { + this.interactFixer = new DoubleInteractFixer(plugin); + } - @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) - public void blockBreakEvent(BlockBreakEvent event) { - Citadel.getInstance().getStateManager().getState(event.getPlayer()).handleBreakBlock(event); - } + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void blockBreakEvent(BlockBreakEvent event) { + Citadel.getInstance().getStateManager().getState(event.getPlayer()).handleBreakBlock(event); + } - @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) - public void blockPlaceEvent(BlockPlaceEvent event) { - Citadel.getInstance().getStateManager().getState(event.getPlayer()).handleBlockPlace(event); - } + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void blockPlaceEvent(BlockPlaceEvent event) { + Citadel.getInstance().getStateManager().getState(event.getPlayer()).handleBlockPlace(event); + } - @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) - public void plantExploitFix(BlockPlaceEvent event) { - Block placed = event.getBlockPlaced(); - Block placedAgainst = event.getBlockAgainst(); + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void plantExploitFix(BlockPlaceEvent event) { + Block placed = event.getBlockPlaced(); + Block placedAgainst = event.getBlockAgainst(); - Reinforcement reinforcement = ReinforcementLogic.getReinforcementProtecting(placed); - if (reinforcement == null) { - return; - } - if (reinforcement.hasPermission(event.getPlayer(), CitadelPermissionHandler.getCrops())) { - return; - } - event.setCancelled(true); - event.getPlayer().sendMessage(Component.text("You cannot place this without the permission " + CitadelPermissionHandler.getCrops().getName() + " on it's group!", NamedTextColor.RED)); - } - - @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) - public void blockBurn(BlockBurnEvent bbe) { - Reinforcement reinforcement = ReinforcementLogic.getReinforcementProtecting(bbe.getBlock()); - if (reinforcement == null) { - return; - } - bbe.setCancelled(true); - Block block = bbe.getBlock(); - // Basic essential fire protection - if (block.getRelative(0, 1, 0).getType() == matfire) { - block.getRelative(0, 1, 0).setType(Material.AIR); - } // Essential - // Extended fire protection (recommend) - if (block.getRelative(1, 0, 0).getType() == matfire) { - block.getRelative(1, 0, 0).setType(Material.AIR); - } - if (block.getRelative(-1, 0, 0).getType() == matfire) { - block.getRelative(-1, 0, 0).setType(Material.AIR); - } - if (block.getRelative(0, -1, 0).getType() == matfire) { - block.getRelative(0, -1, 0).setType(Material.AIR); - } - if (block.getRelative(0, 0, 1).getType() == matfire) { - block.getRelative(0, 0, 1).setType(Material.AIR); - } - if (block.getRelative(0, 0, -1).getType() == matfire) { - block.getRelative(0, 0, -1).setType(Material.AIR); - } - } - - @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) - public void onEntityChangeBlock(EntityChangeBlockEvent event) { - if (event.getEntityType() != EntityType.FALLING_BLOCK) { - return; - } - - Block block = event.getBlock(); - Reinforcement rein = ReinforcementLogic.getReinforcementProtecting(block); - - if (rein != null) { - event.setCancelled(true); - } - } - - // Stop comparators from being placed unless the reinforcement is insecure - @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) - public void comparatorPlaceCheck(BlockPlaceEvent event) { - // We only care if they are placing a comparator - if (event.getBlockPlaced().getType() != Material.COMPARATOR) { - return; - } - Comparator comparator = (Comparator) event.getBlockPlaced().getBlockData(); - Block block = event.getBlockPlaced().getRelative(comparator.getFacing().getOppositeFace()); - // Check if the comparator is placed against something with an inventory - if (ReinforcementLogic.isPreventingBlockAccess(event.getPlayer(), block)) { - event.setCancelled(true); - CitadelUtility.sendAndLog(event.getPlayer(), ChatColor.RED, - "You can not place this because it'd allow bypassing a nearby reinforcement", - block.getLocation()); - return; - } - // Comparators can also read through a single opaque block - if (block.getType().isOccluding()) { - if (ReinforcementLogic.isPreventingBlockAccess(event.getPlayer(), - block.getRelative(comparator.getFacing().getOppositeFace()))) { - event.setCancelled(true); - CitadelUtility.sendAndLog(event.getPlayer(), ChatColor.RED, - "You can not place this because it'd allow bypassing a nearby reinforcement", - block.getLocation()); - } - } - } - - @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) - public void interact(PlayerInteractEvent pie) { - if (pie.getAction() == Action.RIGHT_CLICK_BLOCK) { - if (interactFixer.checkInteracted(pie.getPlayer(), pie.getClickedBlock())) { - return; - } - } else if (pie.getAction() != Action.LEFT_CLICK_BLOCK) { - return; - } - Citadel.getInstance().getStateManager().getState(pie.getPlayer()).handleInteractBlock(pie); - } - - // prevent placing water inside of reinforced blocks - @EventHandler(priority = EventPriority.LOW) - public void liquidDumpEvent(PlayerBucketEmptyEvent event) { - Block block = event.getBlockClicked().getRelative(event.getBlockFace()); - if (block.getType() == Material.AIR || block.getType().isSolid()) { - return; - } - Reinforcement rein = ReinforcementLogic.getReinforcementProtecting(block); - if (rein != null) { - event.setCancelled(true); - } - } - - @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) - public void onBlockFromToEvent(BlockFromToEvent event) { - // prevent water/lava from spilling reinforced blocks away - if (event.getToBlock().getY() < event.getToBlock().getWorld().getMinHeight()) { - return; - } - Reinforcement rein = ReinforcementLogic.getReinforcementProtecting(event.getToBlock()); - if (rein != null) { - event.setCancelled(true); - } - } - - // prevent "enemy" grass spreading to reinforced dirt - @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) - public void onGrassSpread(BlockSpreadEvent event) { - if (event.getSource().getType() != Material.GRASS_BLOCK) return; - - Reinforcement destRein = ReinforcementLogic.getReinforcementProtecting(event.getBlock()); - if (destRein == null) { - return; - } - - Reinforcement sourceRein = ReinforcementLogic.getReinforcementProtecting(event.getSource()); - if (sourceRein == null || sourceRein.getGroupId() != destRein.getGroupId()) { - event.setCancelled(true); - } - } - - // prevent breaking reinforced blocks through plant growth - @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) - public void onStructureGrow(StructureGrowEvent event) { - for (BlockState block_state : event.getBlocks()) { - if (ReinforcementLogic.getReinforcementProtecting(block_state.getBlock()) != null) { - event.setCancelled(true); - return; - } - } - } - - // prevent sculk spread if block is reinforced - @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) - public void onSculkSpread(BlockSpreadEvent event) { - if (event.getSource().getType() != Material.SCULK_CATALYST) return; - - if (ReinforcementLogic.getReinforcementProtecting(event.getBlock()) != null) { - event.setCancelled(true); + Reinforcement reinforcement = ReinforcementLogic.getReinforcementProtecting(placed); + if (reinforcement == null) { + return; } - } + if (reinforcement.hasPermission(event.getPlayer(), CitadelPermissionHandler.getCrops())) { + return; + } + event.setCancelled(true); + event.getPlayer().sendMessage(Component.text("You cannot place this without the permission " + CitadelPermissionHandler.getCrops().getName() + " on it's group!", NamedTextColor.RED)); + } - // prevent drying mud to clay if the mud is reinforced - @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) - public void onMudDry(BlockFormEvent event) { - if (event.getNewState().getType() != Material.CLAY && - event.getBlock().getType() != Material.MUD) return; + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void blockBurn(BlockBurnEvent bbe) { + Reinforcement reinforcement = ReinforcementLogic.getReinforcementProtecting(bbe.getBlock()); + if (reinforcement == null) { + return; + } + bbe.setCancelled(true); + Block block = bbe.getBlock(); + // Basic essential fire protection + if (block.getRelative(0, 1, 0).getType() == matfire) { + block.getRelative(0, 1, 0).setType(Material.AIR); + } // Essential + // Extended fire protection (recommend) + if (block.getRelative(1, 0, 0).getType() == matfire) { + block.getRelative(1, 0, 0).setType(Material.AIR); + } + if (block.getRelative(-1, 0, 0).getType() == matfire) { + block.getRelative(-1, 0, 0).setType(Material.AIR); + } + if (block.getRelative(0, -1, 0).getType() == matfire) { + block.getRelative(0, -1, 0).setType(Material.AIR); + } + if (block.getRelative(0, 0, 1).getType() == matfire) { + block.getRelative(0, 0, 1).setType(Material.AIR); + } + if (block.getRelative(0, 0, -1).getType() == matfire) { + block.getRelative(0, 0, -1).setType(Material.AIR); + } + } - if (ReinforcementLogic.getReinforcementProtecting(event.getBlock()) != null) { - event.setCancelled(true); - } - } + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void onEntityChangeBlock(EntityChangeBlockEvent event) { + if (event.getEntityType() != EntityType.FALLING_BLOCK) { + return; + } - // prevent dirt to mud if dirt is reinforced - @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) - public void onMudCreated(EntityChangeBlockEvent event) { - if (!Tag.CONVERTABLE_TO_MUD.isTagged(event.getBlock().getType()) || - event.getTo() != Material.MUD) return; + Block block = event.getBlock(); + Reinforcement rein = ReinforcementLogic.getReinforcementProtecting(block); - Reinforcement reinforcement = Citadel.getInstance().getReinforcementManager().getReinforcement(event.getBlock().getLocation()); - if (reinforcement == null) return; + if (rein != null) { + event.setCancelled(true); + } + } - Entity eventEntity = event.getEntity(); + // Stop comparators from being placed unless the reinforcement is insecure + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void comparatorPlaceCheck(BlockPlaceEvent event) { + // We only care if they are placing a comparator + if (event.getBlockPlaced().getType() != Material.COMPARATOR) { + return; + } + Comparator comparator = (Comparator) event.getBlockPlaced().getBlockData(); + Block block = event.getBlockPlaced().getRelative(comparator.getFacing().getOppositeFace()); + // Check if the comparator is placed against something with an inventory + if (ReinforcementLogic.isPreventingBlockAccess(event.getPlayer(), block)) { + event.setCancelled(true); + CitadelUtility.sendAndLog(event.getPlayer(), ChatColor.RED, + "You can not place this because it'd allow bypassing a nearby reinforcement", + block.getLocation()); + return; + } + // Comparators can also read through a single opaque block + if (block.getType().isOccluding()) { + if (ReinforcementLogic.isPreventingBlockAccess(event.getPlayer(), + block.getRelative(comparator.getFacing().getOppositeFace()))) { + event.setCancelled(true); + CitadelUtility.sendAndLog(event.getPlayer(), ChatColor.RED, + "You can not place this because it'd allow bypassing a nearby reinforcement", + block.getLocation()); + } + } + } - if (!(eventEntity instanceof Player player)) return; + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void interact(PlayerInteractEvent pie) { + if (pie.getAction() == Action.RIGHT_CLICK_BLOCK) { + if (interactFixer.checkInteracted(pie.getPlayer(), pie.getClickedBlock())) { + return; + } + } else if (pie.getAction() != Action.LEFT_CLICK_BLOCK) { + return; + } + Citadel.getInstance().getStateManager().getState(pie.getPlayer()).handleInteractBlock(pie); + } + + // prevent placing water inside of reinforced blocks + @EventHandler(priority = EventPriority.LOW) + public void liquidDumpEvent(PlayerBucketEmptyEvent event) { + Block block = event.getBlockClicked().getRelative(event.getBlockFace()); + if (block.getType() == Material.AIR || block.getType().isSolid()) { + return; + } + Reinforcement rein = ReinforcementLogic.getReinforcementProtecting(block); + if (rein != null) { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void onBlockFromToEvent(BlockFromToEvent event) { + // prevent water/lava from spilling reinforced blocks away + if (event.getToBlock().getY() < event.getToBlock().getWorld().getMinHeight()) { + return; + } + Reinforcement rein = ReinforcementLogic.getReinforcementProtecting(event.getToBlock()); + if (rein != null) { + event.setCancelled(true); + } + } + + // prevent "enemy" grass spreading to reinforced dirt + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void onGrassSpread(BlockSpreadEvent event) { + if (event.getSource().getType() != Material.GRASS_BLOCK) return; + + Reinforcement destRein = ReinforcementLogic.getReinforcementProtecting(event.getBlock()); + if (destRein == null) { + return; + } + + Reinforcement sourceRein = ReinforcementLogic.getReinforcementProtecting(event.getSource()); + if (sourceRein == null || sourceRein.getGroupId() != destRein.getGroupId()) { + event.setCancelled(true); + } + } + + // prevent breaking reinforced blocks through plant growth + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void onStructureGrow(StructureGrowEvent event) { + for (BlockState block_state : event.getBlocks()) { + if (ReinforcementLogic.getReinforcementProtecting(block_state.getBlock()) != null) { + event.setCancelled(true); + return; + } + } + } + + // prevent sculk spread if block is reinforced + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void onSculkSpread(BlockSpreadEvent event) { + if (event.getSource().getType() != Material.SCULK_CATALYST) return; + + if (ReinforcementLogic.getReinforcementProtecting(event.getBlock()) != null) { + event.setCancelled(true); + } + } + + // prevent drying mud to clay if the mud is reinforced + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void onMudDry(BlockFormEvent event) { + if (event.getNewState().getType() != Material.CLAY && + event.getBlock().getType() != Material.MUD) return; + + if (ReinforcementLogic.getReinforcementProtecting(event.getBlock()) != null) { + event.setCancelled(true); + } + } + + // prevent dirt to mud if dirt is reinforced + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void onMudCreated(EntityChangeBlockEvent event) { + if (!Tag.CONVERTABLE_TO_MUD.isTagged(event.getBlock().getType()) || + event.getTo() != Material.MUD) return; + + Reinforcement reinforcement = Citadel.getInstance().getReinforcementManager().getReinforcement(event.getBlock().getLocation()); + if (reinforcement == null) return; + + Entity eventEntity = event.getEntity(); + + if (!(eventEntity instanceof Player player)) return; if (!reinforcement.hasPermission(player, CitadelPermissionHandler.getModifyBlocks())) { - player.sendMessage(ChatColor.RED + "You do not have permission to modify this block"); - event.setCancelled(true); - } - } + player.sendMessage(ChatColor.RED + "You do not have permission to modify this block"); + event.setCancelled(true); + } + } - // prevent opening reinforced things - @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) - public void openContainer(PlayerInteractEvent e) { - if (!e.hasBlock()) { - return; - } - if (e.getAction() != Action.RIGHT_CLICK_BLOCK) { - return; - } - Reinforcement rein = ReinforcementLogic.getReinforcementProtecting(e.getClickedBlock()); - if (rein == null) { - return; - } - Player player = e.getPlayer(); + // prevent opening reinforced things + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void openContainer(PlayerInteractEvent e) { + if (!e.hasBlock()) { + return; + } + if (e.getAction() != Action.RIGHT_CLICK_BLOCK) { + return; + } + Reinforcement rein = ReinforcementLogic.getReinforcementProtecting(e.getClickedBlock()); + if (rein == null) { + return; + } + Player player = e.getPlayer(); - // Logic copied from ServerPlayerGameMode#useItemOn - // This will let the event happen if the player is not going to actually open/interact with the block - boolean flag = player.getInventory().getItemInMainHand().getType() != Material.AIR || player.getInventory().getItemInOffHand().getType() != Material.AIR; - if (player.isSneaking() && flag) { - return; - } + // Logic copied from ServerPlayerGameMode#useItemOn + // This will let the event happen if the player is not going to actually open/interact with the block + boolean flag = player.getInventory().getItemInMainHand().getType() != Material.AIR || player.getInventory().getItemInOffHand().getType() != Material.AIR; + if (player.isSneaking() && flag) { + return; + } - // Iron trapdoors and doors cannot be opened by right clicking on them - if (e.getClickedBlock().getType() == Material.IRON_TRAPDOOR || e.getClickedBlock().getType() == Material.IRON_DOOR) { - return; - } + // Iron trapdoors and doors cannot be opened by right clicking on them + if (e.getClickedBlock().getType() == Material.IRON_TRAPDOOR || e.getClickedBlock().getType() == Material.IRON_DOOR) { + return; + } - if (e.getClickedBlock().getState() instanceof Container) { - if (!rein.hasPermission(player, CitadelPermissionHandler.getChests())) { - e.setCancelled(true); - String msg = String.format("%s is locked with %s%s", e.getClickedBlock().getType().name(), - ChatColor.AQUA, rein.getType().getName()); - CitadelUtility.sendAndLog(player, ChatColor.RED, msg, e.getClickedBlock().getLocation()); - } - return; - } - if (e.getClickedBlock().getBlockData() instanceof Openable) { - if (!rein.hasPermission(player, CitadelPermissionHandler.getDoors())) { - e.setCancelled(true); - String msg = String.format("%s is locked with %s%s", e.getClickedBlock().getType().name(), - ChatColor.AQUA, rein.getType().getName()); - CitadelUtility.sendAndLog(player, ChatColor.RED, msg, e.getClickedBlock().getLocation()); - } - } - } + if (e.getClickedBlock().getState() instanceof Container) { + if (!rein.hasPermission(player, CitadelPermissionHandler.getChests())) { + e.setCancelled(true); + String msg = String.format("%s is locked with %s%s", e.getClickedBlock().getType().name(), + ChatColor.AQUA, rein.getType().getName()); + CitadelUtility.sendAndLog(player, ChatColor.RED, msg, e.getClickedBlock().getLocation()); + } + return; + } + if (e.getClickedBlock().getBlockData() instanceof Openable) { + if (!rein.hasPermission(player, CitadelPermissionHandler.getDoors())) { + e.setCancelled(true); + String msg = String.format("%s is locked with %s%s", e.getClickedBlock().getType().name(), + ChatColor.AQUA, rein.getType().getName()); + CitadelUtility.sendAndLog(player, ChatColor.RED, msg, e.getClickedBlock().getLocation()); + } + } + } - // prevent players from upgrading a chest into a double chest to bypass the - // single chests reinforcement - @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) - public void preventBypassChestAccess(BlockPlaceEvent e) { - Material mat = e.getBlock().getType(); - if (mat != Material.CHEST && mat != Material.TRAPPED_CHEST) { - return; - } - for (Block rel : WorldUtils.getPlanarBlockSides(e.getBlock(), true)) { - if (rel.getType() == mat && ReinforcementLogic.isPreventingBlockAccess(e.getPlayer(), rel)) { - e.setCancelled(true); - CitadelUtility.sendAndLog(e.getPlayer(), ChatColor.RED, - "You can not place this because it'd allow bypassing a nearby reinforcement", rel.getLocation()); - break; - } - } - } + // prevent players from upgrading a chest into a double chest to bypass the + // single chests reinforcement + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void preventBypassChestAccess(BlockPlaceEvent e) { + Material mat = e.getBlock().getType(); + if (mat != Material.CHEST && mat != Material.TRAPPED_CHEST) { + return; + } + for (Block rel : WorldUtils.getPlanarBlockSides(e.getBlock(), true)) { + if (rel.getType() == mat && ReinforcementLogic.isPreventingBlockAccess(e.getPlayer(), rel)) { + e.setCancelled(true); + CitadelUtility.sendAndLog(e.getPlayer(), ChatColor.RED, + "You can not place this because it'd allow bypassing a nearby reinforcement", rel.getLocation()); + break; + } + } + } - @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) - public void removeReinforcedAir(BlockPlaceEvent e) { - if (!MaterialUtils.isAir(e.getBlockReplacedState().getType())) { - return; - } - Reinforcement rein = Citadel.getInstance().getReinforcementManager().getReinforcement(e.getBlock()); - if (rein != null) { - rein.setHealth(-1); - } - } + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void removeReinforcedAir(BlockPlaceEvent e) { + if (!MaterialUtils.isAir(e.getBlockReplacedState().getType())) { + return; + } + Reinforcement rein = Citadel.getInstance().getReinforcementManager().getReinforcement(e.getBlock()); + if (rein != null) { + rein.setHealth(-1); + } + } - @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) - public void preventStrippingLogs(PlayerInteractEvent pie) { - if (!pie.hasBlock()) { - return; - } - if (pie.getAction() != Action.RIGHT_CLICK_BLOCK) { - return; - } - Block block = pie.getClickedBlock(); - if (!MoreTags.LOGS.isTagged(block.getType())) { - return; - } - EquipmentSlot hand = pie.getHand(); - if (hand != EquipmentSlot.HAND && hand != EquipmentSlot.OFF_HAND) { - return; - } - ItemStack relevant; - Player p = pie.getPlayer(); - if (hand == EquipmentSlot.HAND) { - relevant = p.getInventory().getItemInMainHand(); - } else { - relevant = p.getInventory().getItemInOffHand(); - } - if (!MaterialTags.AXES.isTagged(relevant.getType())) { - return; - } - Reinforcement rein = Citadel.getInstance().getReinforcementManager().getReinforcement(block); - if (rein == null) { - return; - } - if (!rein.hasPermission(p, CitadelPermissionHandler.getModifyBlocks())) { - p.sendMessage(ChatColor.RED + "You do not have permission to modify this block"); - pie.setCancelled(true); - } - } + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void preventStrippingLogs(PlayerInteractEvent pie) { + if (!pie.hasBlock()) { + return; + } + if (pie.getAction() != Action.RIGHT_CLICK_BLOCK) { + return; + } + Block block = pie.getClickedBlock(); + if (!MoreTags.LOGS.isTagged(block.getType())) { + return; + } + EquipmentSlot hand = pie.getHand(); + if (hand != EquipmentSlot.HAND && hand != EquipmentSlot.OFF_HAND) { + return; + } + ItemStack relevant; + Player p = pie.getPlayer(); + if (hand == EquipmentSlot.HAND) { + relevant = p.getInventory().getItemInMainHand(); + } else { + relevant = p.getInventory().getItemInOffHand(); + } + if (!MaterialTags.AXES.isTagged(relevant.getType())) { + return; + } + Reinforcement rein = Citadel.getInstance().getReinforcementManager().getReinforcement(block); + if (rein == null) { + return; + } + if (!rein.hasPermission(p, CitadelPermissionHandler.getModifyBlocks())) { + p.sendMessage(ChatColor.RED + "You do not have permission to modify this block"); + pie.setCancelled(true); + } + } - @EventHandler(priority = EventPriority.NORMAL) - public void rightClickCaveVines(PlayerHarvestBlockEvent event) { - Block harvestedBlock = event.getHarvestedBlock(); - Reinforcement reinforcement = ReinforcementLogic.getReinforcementProtecting(harvestedBlock); - if (reinforcement == null) { - return; - } - if (!reinforcement.hasPermission(event.getPlayer(), CitadelPermissionHandler.getCrops())) { - event.getPlayer().sendMessage(Component.text("You do not have permission to harvest this crop").color(NamedTextColor.RED)); - event.setCancelled(true); - } - } + @EventHandler(priority = EventPriority.NORMAL) + public void rightClickCaveVines(PlayerHarvestBlockEvent event) { + Block harvestedBlock = event.getHarvestedBlock(); + Reinforcement reinforcement = ReinforcementLogic.getReinforcementProtecting(harvestedBlock); + if (reinforcement == null) { + return; + } + if (!reinforcement.hasPermission(event.getPlayer(), CitadelPermissionHandler.getCrops())) { + event.getPlayer().sendMessage(Component.text("You do not have permission to harvest this crop").color(NamedTextColor.RED)); + event.setCancelled(true); + } + } - /* - For some stupid reason, Waxing / Stripping copper blocks calls a BlockPlaceEvent instead of PlayerInteractEvent, - this obviously might change in future so heres a warning note - Reminder: This is retarded - */ - @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) - public void preventWaxingCopper(BlockPlaceEvent event) { - if (!MoreTags.COPPER_BLOCKS.isTagged(event.getBlockPlaced().getType())) { - return; - } - Reinforcement reinforcement = Citadel.getInstance().getReinforcementManager().getReinforcement(event.getBlockPlaced()); - if (reinforcement == null) { - return; - } - Player player = event.getPlayer(); - if (!reinforcement.hasPermission(player, CitadelPermissionHandler.getModifyBlocks())) { - player.sendMessage(ChatColor.RED + "You do not have permission to modify this block"); - event.setCancelled(true); - } - } + /* + For some stupid reason, Waxing / Stripping copper blocks calls a BlockPlaceEvent instead of PlayerInteractEvent, + this obviously might change in future so heres a warning note + Reminder: This is retarded + */ + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void preventWaxingCopper(BlockPlaceEvent event) { + if (!MoreTags.COPPER_BLOCKS.isTagged(event.getBlockPlaced().getType())) { + return; + } + Reinforcement reinforcement = Citadel.getInstance().getReinforcementManager().getReinforcement(event.getBlockPlaced()); + if (reinforcement == null) { + return; + } + Player player = event.getPlayer(); + if (!reinforcement.hasPermission(player, CitadelPermissionHandler.getModifyBlocks())) { + player.sendMessage(ChatColor.RED + "You do not have permission to modify this block"); + event.setCancelled(true); + } + } - @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) - public void preventTilingGrass(PlayerInteractEvent pie) { - if (!pie.hasBlock()) { - return; - } - if (pie.getAction() != Action.RIGHT_CLICK_BLOCK) { - return; - } - Block block = pie.getClickedBlock(); - if (block.getType() != Material.GRASS_BLOCK) { - return; - } - EquipmentSlot hand = pie.getHand(); - if (hand != EquipmentSlot.HAND && hand != EquipmentSlot.OFF_HAND) { - return; - } - ItemStack relevant; - Player p = pie.getPlayer(); - if (hand == EquipmentSlot.HAND) { - relevant = p.getInventory().getItemInMainHand(); - } else { - relevant = p.getInventory().getItemInOffHand(); - } - if (!MaterialTags.SHOVELS.isTagged(relevant.getType())) { - return; - } - Reinforcement rein = Citadel.getInstance().getReinforcementManager().getReinforcement(block); - if (rein == null) { - return; - } - if (!rein.hasPermission(p, CitadelPermissionHandler.getModifyBlocks())) { - p.sendMessage(ChatColor.RED + "You do not have permission to modify this block"); - pie.setCancelled(true); - } - } + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void preventTilingGrass(PlayerInteractEvent pie) { + if (!pie.hasBlock()) { + return; + } + if (pie.getAction() != Action.RIGHT_CLICK_BLOCK) { + return; + } + Block block = pie.getClickedBlock(); + if (block.getType() != Material.GRASS_BLOCK) { + return; + } + EquipmentSlot hand = pie.getHand(); + if (hand != EquipmentSlot.HAND && hand != EquipmentSlot.OFF_HAND) { + return; + } + ItemStack relevant; + Player p = pie.getPlayer(); + if (hand == EquipmentSlot.HAND) { + relevant = p.getInventory().getItemInMainHand(); + } else { + relevant = p.getInventory().getItemInOffHand(); + } + if (!MaterialTags.SHOVELS.isTagged(relevant.getType())) { + return; + } + Reinforcement rein = Citadel.getInstance().getReinforcementManager().getReinforcement(block); + if (rein == null) { + return; + } + if (!rein.hasPermission(p, CitadelPermissionHandler.getModifyBlocks())) { + p.sendMessage(ChatColor.RED + "You do not have permission to modify this block"); + pie.setCancelled(true); + } + } - @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) - public void preventTillingDirtIntoFarmland(PlayerInteractEvent pie) { - if (!pie.hasBlock()) { - return; - } - if (pie.getAction() != Action.RIGHT_CLICK_BLOCK) { - return; - } - Block block = pie.getClickedBlock(); - Material type = block.getType(); - if (type != Material.GRASS_BLOCK && type != Material.DIRT && type != Material.COARSE_DIRT - && type != Material.DIRT_PATH) { - return; - } - EquipmentSlot hand = pie.getHand(); - if (hand != EquipmentSlot.HAND && hand != EquipmentSlot.OFF_HAND) { - return; - } - ItemStack relevant; - Player p = pie.getPlayer(); - if (hand == EquipmentSlot.HAND) { - relevant = p.getInventory().getItemInMainHand(); - } else { - relevant = p.getInventory().getItemInOffHand(); - } - if (!MaterialTags.HOES.isTagged(relevant.getType())) { - return; - } - Reinforcement rein = Citadel.getInstance().getReinforcementManager().getReinforcement(block); - if (rein == null) { - return; - } - if (!rein.hasPermission(p, CitadelPermissionHandler.getModifyBlocks())) { - p.sendMessage(ChatColor.RED + "You do not have permission to modify this block"); - pie.setCancelled(true); - } - } + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void preventTillingDirtIntoFarmland(PlayerInteractEvent pie) { + if (!pie.hasBlock()) { + return; + } + if (pie.getAction() != Action.RIGHT_CLICK_BLOCK) { + return; + } + Block block = pie.getClickedBlock(); + Material type = block.getType(); + if (type != Material.GRASS_BLOCK && type != Material.DIRT && type != Material.COARSE_DIRT + && type != Material.DIRT_PATH) { + return; + } + EquipmentSlot hand = pie.getHand(); + if (hand != EquipmentSlot.HAND && hand != EquipmentSlot.OFF_HAND) { + return; + } + ItemStack relevant; + Player p = pie.getPlayer(); + if (hand == EquipmentSlot.HAND) { + relevant = p.getInventory().getItemInMainHand(); + } else { + relevant = p.getInventory().getItemInOffHand(); + } + if (!MaterialTags.HOES.isTagged(relevant.getType())) { + return; + } + Reinforcement rein = Citadel.getInstance().getReinforcementManager().getReinforcement(block); + if (rein == null) { + return; + } + if (!rein.hasPermission(p, CitadelPermissionHandler.getModifyBlocks())) { + p.sendMessage(ChatColor.RED + "You do not have permission to modify this block"); + pie.setCancelled(true); + } + } - @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) - public void preventHarvestingHoney(PlayerInteractEvent pie) { - if (!pie.hasBlock()) { - return; - } - if (pie.getAction() != Action.RIGHT_CLICK_BLOCK) { - return; - } - Block block = pie.getClickedBlock(); - Material type = block.getType(); - if (type != Material.BEE_NEST && type != Material.BEEHIVE) { - return; - } - EquipmentSlot hand = pie.getHand(); - if (hand != EquipmentSlot.HAND && hand != EquipmentSlot.OFF_HAND) { - return; - } - ItemStack relevant; - Player p = pie.getPlayer(); - if (hand == EquipmentSlot.HAND) { - relevant = p.getInventory().getItemInMainHand(); - } else { - relevant = p.getInventory().getItemInOffHand(); - } - if (relevant.getType() != Material.SHEARS && relevant.getType() != Material.GLASS_BOTTLE) { - return; - } - Reinforcement rein = Citadel.getInstance().getReinforcementManager().getReinforcement(block); - if (rein == null) { - return; - } - if (!rein.hasPermission(p, CitadelPermissionHandler.getModifyBlocks())) { - p.sendMessage(ChatColor.RED + "You do not have permission to harvest this block"); - pie.setCancelled(true); - } - } + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void preventHarvestingHoney(PlayerInteractEvent pie) { + if (!pie.hasBlock()) { + return; + } + if (pie.getAction() != Action.RIGHT_CLICK_BLOCK) { + return; + } + Block block = pie.getClickedBlock(); + Material type = block.getType(); + if (type != Material.BEE_NEST && type != Material.BEEHIVE) { + return; + } + EquipmentSlot hand = pie.getHand(); + if (hand != EquipmentSlot.HAND && hand != EquipmentSlot.OFF_HAND) { + return; + } + ItemStack relevant; + Player p = pie.getPlayer(); + if (hand == EquipmentSlot.HAND) { + relevant = p.getInventory().getItemInMainHand(); + } else { + relevant = p.getInventory().getItemInOffHand(); + } + if (relevant.getType() != Material.SHEARS && relevant.getType() != Material.GLASS_BOTTLE) { + return; + } + Reinforcement rein = Citadel.getInstance().getReinforcementManager().getReinforcement(block); + if (rein == null) { + return; + } + if (!rein.hasPermission(p, CitadelPermissionHandler.getModifyBlocks())) { + p.sendMessage(ChatColor.RED + "You do not have permission to harvest this block"); + pie.setCancelled(true); + } + } - @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) - public void preventLightingCandles(PlayerInteractEvent pie) { - if (!pie.hasBlock()) { - return; - } - if (pie.getAction() != Action.RIGHT_CLICK_BLOCK) { - return; - } - Block block = pie.getClickedBlock(); - Material type = block.getType(); - if (!MoreTags.LIGHTABLE_CANDLES.isTagged(type)) { - return; - } - if (!pie.hasItem()) { - Lightable candles = (Lightable) block.getBlockData(); - if (candles.isLit()) { - Reinforcement rein = Citadel.getInstance().getReinforcementManager().getReinforcement(block); - if (rein == null) { - return; - } - if (!rein.hasPermission(pie.getPlayer(), CitadelPermissionHandler.getModifyBlocks())) { - pie.getPlayer().sendMessage(ChatColor.RED + "You do not have permission to modify this block"); - pie.setCancelled(true); - return; - } - } - } - EquipmentSlot hand = pie.getHand(); - if (hand != EquipmentSlot.HAND && hand != EquipmentSlot.OFF_HAND) { - return; - } - ItemStack relevant; - Player p = pie.getPlayer(); - if (hand == EquipmentSlot.HAND) { - relevant = p.getInventory().getItemInMainHand(); - } else { - relevant = p.getInventory().getItemInOffHand(); - } - if (relevant.getType() != Material.FLINT_AND_STEEL) { - return; - } - Reinforcement rein = Citadel.getInstance().getReinforcementManager().getReinforcement(block); - if (rein == null) { - return; - } - if (!rein.hasPermission(p, CitadelPermissionHandler.getModifyBlocks())) { - p.sendMessage(ChatColor.RED + "You do not have permission to modify this block"); - pie.setCancelled(true); - } - } + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void preventLightingCandles(PlayerInteractEvent pie) { + if (!pie.hasBlock()) { + return; + } + if (pie.getAction() != Action.RIGHT_CLICK_BLOCK) { + return; + } + Block block = pie.getClickedBlock(); + Material type = block.getType(); + if (!MoreTags.LIGHTABLE_CANDLES.isTagged(type)) { + return; + } + if (!pie.hasItem()) { + Lightable candles = (Lightable) block.getBlockData(); + if (candles.isLit()) { + Reinforcement rein = Citadel.getInstance().getReinforcementManager().getReinforcement(block); + if (rein == null) { + return; + } + if (!rein.hasPermission(pie.getPlayer(), CitadelPermissionHandler.getModifyBlocks())) { + pie.getPlayer().sendMessage(ChatColor.RED + "You do not have permission to modify this block"); + pie.setCancelled(true); + return; + } + } + } + EquipmentSlot hand = pie.getHand(); + if (hand != EquipmentSlot.HAND && hand != EquipmentSlot.OFF_HAND) { + return; + } + ItemStack relevant; + Player p = pie.getPlayer(); + if (hand == EquipmentSlot.HAND) { + relevant = p.getInventory().getItemInMainHand(); + } else { + relevant = p.getInventory().getItemInOffHand(); + } + if (relevant.getType() != Material.FLINT_AND_STEEL) { + return; + } + Reinforcement rein = Citadel.getInstance().getReinforcementManager().getReinforcement(block); + if (rein == null) { + return; + } + if (!rein.hasPermission(p, CitadelPermissionHandler.getModifyBlocks())) { + p.sendMessage(ChatColor.RED + "You do not have permission to modify this block"); + pie.setCancelled(true); + } + } - @EventHandler(priority = EventPriority.LOW, ignoreCancelled = false) - public void openBeacon(PlayerInteractEvent pie) { - if (!pie.hasBlock()) { - return; - } - if (pie.getAction() != Action.RIGHT_CLICK_BLOCK) { - return; - } - if (pie.getClickedBlock().getType() != Material.BEACON) { - return; - } - Reinforcement rein = ReinforcementLogic.getReinforcementProtecting(pie.getClickedBlock()); - if (rein == null) { - return; - } - if (!rein.hasPermission(pie.getPlayer(), CitadelPermissionHandler.getBeacon())) { - pie.setCancelled(true); - String msg = String.format("%s is locked with %s%s", pie.getClickedBlock().getType().name(), ChatColor.AQUA, - rein.getType().getName()); - CitadelUtility.sendAndLog(pie.getPlayer(), ChatColor.RED, msg, pie.getClickedBlock().getLocation()); - } - } + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = false) + public void openBeacon(PlayerInteractEvent pie) { + if (!pie.hasBlock()) { + return; + } + if (pie.getAction() != Action.RIGHT_CLICK_BLOCK) { + return; + } + if (pie.getClickedBlock().getType() != Material.BEACON) { + return; + } + Reinforcement rein = ReinforcementLogic.getReinforcementProtecting(pie.getClickedBlock()); + if (rein == null) { + return; + } + if (!rein.hasPermission(pie.getPlayer(), CitadelPermissionHandler.getBeacon())) { + pie.setCancelled(true); + String msg = String.format("%s is locked with %s%s", pie.getClickedBlock().getType().name(), ChatColor.AQUA, + rein.getType().getName()); + CitadelUtility.sendAndLog(pie.getPlayer(), ChatColor.RED, msg, pie.getClickedBlock().getLocation()); + } + } - // ------------------------------------------------------------ - // Lecterns - // ------------------------------------------------------------ + // ------------------------------------------------------------ + // Lecterns + // ------------------------------------------------------------ - @EventHandler(ignoreCancelled = true) - public void preventLecternPutBook(final PlayerInteractEvent event) { - if (event.getAction() != Action.RIGHT_CLICK_BLOCK) { - return; - } - final var clickedBlock = event.getClickedBlock(); - if (clickedBlock == null || clickedBlock.getType() != Material.LECTERN) { - return; - } - // if the lectern has a book, then the person is right clicking to read that book, not place in a new book - final var clickedBlockData = (Lectern) clickedBlock.getBlockData(); - if (clickedBlockData.hasBook()) { - return; - } - INTERNAL_checkLecternModificationPermission(event, event.getPlayer(), clickedBlock.getLocation()); - } + @EventHandler(ignoreCancelled = true) + public void preventLecternPutBook(final PlayerInteractEvent event) { + if (event.getAction() != Action.RIGHT_CLICK_BLOCK) { + return; + } + final var clickedBlock = event.getClickedBlock(); + if (clickedBlock == null || clickedBlock.getType() != Material.LECTERN) { + return; + } + // if the lectern has a book, then the person is right clicking to read that book, not place in a new book + final var clickedBlockData = (Lectern) clickedBlock.getBlockData(); + if (clickedBlockData.hasBook()) { + return; + } + INTERNAL_checkLecternModificationPermission(event, event.getPlayer(), clickedBlock.getLocation()); + } - @EventHandler(ignoreCancelled = true) - public void preventLecternTakeBook(final PlayerTakeLecternBookEvent event) { - INTERNAL_checkLecternModificationPermission(event, event.getPlayer(), event.getLectern().getLocation()); - } + @EventHandler(ignoreCancelled = true) + public void preventLecternTakeBook(final PlayerTakeLecternBookEvent event) { + INTERNAL_checkLecternModificationPermission(event, event.getPlayer(), event.getLectern().getLocation()); + } - private void INTERNAL_checkLecternModificationPermission(final Cancellable event, - final Player clicker, - final Location lecternLocation) { - // We already know that a lectern is a single block, thus the additional logic - // of ReinforcementLogic.getReinforcementProtecting(block) is unnecessary - final var reinforcement = ReinforcementLogic.getReinforcementAt(lecternLocation); - if (reinforcement == null - || reinforcement.isInsecure() - || reinforcement.hasPermission(clicker.getUniqueId(), CitadelPermissionHandler.getChests())) { - return; - } - event.setCancelled(true); - CitadelUtility.sendAndLog(clicker, ChatColor.RED, "You cannot modify that lectern.", lecternLocation); - } + private void INTERNAL_checkLecternModificationPermission(final Cancellable event, + final Player clicker, + final Location lecternLocation) { + // We already know that a lectern is a single block, thus the additional logic + // of ReinforcementLogic.getReinforcementProtecting(block) is unnecessary + final var reinforcement = ReinforcementLogic.getReinforcementAt(lecternLocation); + if (reinforcement == null + || reinforcement.isInsecure() + || reinforcement.hasPermission(clicker.getUniqueId(), CitadelPermissionHandler.getChests())) { + return; + } + event.setCancelled(true); + CitadelUtility.sendAndLog(clicker, ChatColor.RED, "You cannot modify that lectern.", lecternLocation); + } - @EventHandler(ignoreCancelled = true) - public void onMossSpread(BlockFertilizeEvent event) { - Player player = event.getPlayer(); - Iterator iterator = event.getBlocks().iterator(); - Block dispenser = mossSpreadingDispensers.remove(event.getBlock()); - Reinforcement dispenserRein = dispenser == null ? null - : Citadel.getInstance() - .getReinforcementManager() - .getReinforcement(dispenser); - Group dispenserGroup = dispenserRein == null ? null : - dispenserRein.getGroup(); - while (iterator.hasNext()) { - BlockState block = iterator.next(); - Reinforcement reinforcement = Citadel.getInstance() - .getReinforcementManager() - .getReinforcement(block.getBlock()); - if (reinforcement == null) { - continue; - } - if (player != null && reinforcement.hasPermission(player, CitadelPermissionHandler.getCrops())) { - continue; - } - if (dispenserGroup != null && dispenserGroup == reinforcement.getGroup()) { - continue; - } - iterator.remove(); - } - } + @EventHandler(ignoreCancelled = true) + public void onMossSpread(BlockFertilizeEvent event) { + Player player = event.getPlayer(); + Iterator iterator = event.getBlocks().iterator(); + Block dispenser = mossSpreadingDispensers.remove(event.getBlock()); + Reinforcement dispenserRein = dispenser == null ? null + : Citadel.getInstance() + .getReinforcementManager() + .getReinforcement(dispenser); + Group dispenserGroup = dispenserRein == null ? null : + dispenserRein.getGroup(); + while (iterator.hasNext()) { + BlockState block = iterator.next(); + Reinforcement reinforcement = Citadel.getInstance() + .getReinforcementManager() + .getReinforcement(block.getBlock()); + if (reinforcement == null) { + continue; + } + if (player != null && reinforcement.hasPermission(player, CitadelPermissionHandler.getCrops())) { + continue; + } + if (dispenserGroup != null && dispenserGroup == reinforcement.getGroup()) { + continue; + } + iterator.remove(); + } + } - @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGH) - public void onDispenserGrowMoss(BlockDispenseEvent event) { - Block dispenserBlock = event.getBlock(); - ItemStack bonemeal = event.getItem(); - Dispenser dispenser = (Dispenser) event.getBlock().getBlockData(); - if (bonemeal.getType() != Material.BONE_MEAL) { - return; - } - Block moss = dispenserBlock.getRelative(dispenser.getFacing()); - if (moss.getType() != Material.MOSS_BLOCK) { - return; - } - mossSpreadingDispensers.put(moss, dispenserBlock); - } + @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGH) + public void onDispenserGrowMoss(BlockDispenseEvent event) { + Block dispenserBlock = event.getBlock(); + ItemStack bonemeal = event.getItem(); + Dispenser dispenser = (Dispenser) event.getBlock().getBlockData(); + if (bonemeal.getType() != Material.BONE_MEAL) { + return; + } + Block moss = dispenserBlock.getRelative(dispenser.getFacing()); + if (moss.getType() != Material.MOSS_BLOCK) { + return; + } + mossSpreadingDispensers.put(moss, dispenserBlock); + } - @EventHandler(ignoreCancelled = true) - public void preventHostileAnvilUsage( - final PlayerInteractEvent event - ) { - if (event.getAction() != Action.RIGHT_CLICK_BLOCK) { - return; - } - final Block clickedBlock = event.getClickedBlock(); - if (clickedBlock == null || !Tag.ANVIL.isTagged(clickedBlock.getType())) { - return; - } - final Player clicker = event.getPlayer(); - // We already know that an anvil is a single block, thus the additional logic - // of ReinforcementLogic.getReinforcementProtecting(block) is unnecessary - final Reinforcement reinforcement = ReinforcementLogic.getReinforcementAt(clickedBlock.getLocation()); - if (reinforcement == null - || reinforcement.isInsecure() - || reinforcement.hasPermission(clicker.getUniqueId(), CitadelPermissionHandler.getChests())) { - return; - } - event.setCancelled(true); - CitadelUtility.sendAndLog(clicker, ChatColor.RED, "You cannot use that anvil.", clickedBlock.getLocation()); - } + @EventHandler(ignoreCancelled = true) + public void preventHostileAnvilUsage( + final PlayerInteractEvent event + ) { + if (event.getAction() != Action.RIGHT_CLICK_BLOCK) { + return; + } + final Block clickedBlock = event.getClickedBlock(); + if (clickedBlock == null || !Tag.ANVIL.isTagged(clickedBlock.getType())) { + return; + } + final Player clicker = event.getPlayer(); + // We already know that an anvil is a single block, thus the additional logic + // of ReinforcementLogic.getReinforcementProtecting(block) is unnecessary + final Reinforcement reinforcement = ReinforcementLogic.getReinforcementAt(clickedBlock.getLocation()); + if (reinforcement == null + || reinforcement.isInsecure() + || reinforcement.hasPermission(clicker.getUniqueId(), CitadelPermissionHandler.getChests())) { + return; + } + event.setCancelled(true); + CitadelUtility.sendAndLog(clicker, ChatColor.RED, "You cannot use that anvil.", clickedBlock.getLocation()); + } - @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) - public void preventTakingBooks(PlayerInteractEvent pie) { - if (!pie.hasBlock()) { - return; - } - if (pie.getAction() != Action.RIGHT_CLICK_BLOCK) { - return; - } - Block block = pie.getClickedBlock(); - Material type = block.getType(); - if (type != Material.CHISELED_BOOKSHELF) { - return; - } - EquipmentSlot hand = pie.getHand(); - if (hand != EquipmentSlot.HAND && hand != EquipmentSlot.OFF_HAND) { - return; - } - ItemStack relevant; - Player p = pie.getPlayer(); - if (hand == EquipmentSlot.HAND) { - relevant = p.getInventory().getItemInMainHand(); - } else { - relevant = p.getInventory().getItemInOffHand(); - } - if (relevant.getType() != Material.AIR && !Tag.ITEMS_BOOKSHELF_BOOKS.isTagged(relevant.getType())) { - return; - } - Reinforcement rein = Citadel.getInstance().getReinforcementManager().getReinforcement(block); - if (rein == null) { - return; - } - if (!rein.hasPermission(p, CitadelPermissionHandler.getModifyBlocks())) { - p.sendMessage(ChatColor.RED + "You do not have permission to " + - (Tag.ITEMS_BOOKSHELF_BOOKS.isTagged(relevant.getType()) ? "place books in this shelf" : "take books from this shelf")); - pie.setCancelled(true); - } - } + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void preventTakingBooks(PlayerInteractEvent pie) { + if (!pie.hasBlock()) { + return; + } + if (pie.getAction() != Action.RIGHT_CLICK_BLOCK) { + return; + } + Block block = pie.getClickedBlock(); + Material type = block.getType(); + if (type != Material.CHISELED_BOOKSHELF) { + return; + } + EquipmentSlot hand = pie.getHand(); + if (hand != EquipmentSlot.HAND && hand != EquipmentSlot.OFF_HAND) { + return; + } + ItemStack relevant; + Player p = pie.getPlayer(); + if (hand == EquipmentSlot.HAND) { + relevant = p.getInventory().getItemInMainHand(); + } else { + relevant = p.getInventory().getItemInOffHand(); + } + if (relevant.getType() != Material.AIR && !Tag.ITEMS_BOOKSHELF_BOOKS.isTagged(relevant.getType())) { + return; + } + Reinforcement rein = Citadel.getInstance().getReinforcementManager().getReinforcement(block); + if (rein == null) { + return; + } + if (!rein.hasPermission(p, CitadelPermissionHandler.getModifyBlocks())) { + p.sendMessage(ChatColor.RED + "You do not have permission to " + + (Tag.ITEMS_BOOKSHELF_BOOKS.isTagged(relevant.getType()) ? "place books in this shelf" : "take books from this shelf")); + pie.setCancelled(true); + } + } - @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) - public void preventDusting(PlayerInteractEvent pie) { // Maybe this should be changed to brushing? The two terms seem to be used interchangeably. - if (!pie.hasBlock()) { - return; - } - if (pie.getAction() != Action.RIGHT_CLICK_BLOCK) { - return; - } - Block block = pie.getClickedBlock(); - Material type = block.getType(); - if (!MoreTags.DUSTABLE.isTagged(type)) { - return; - } - EquipmentSlot hand = pie.getHand(); - if (hand != EquipmentSlot.HAND && hand != EquipmentSlot.OFF_HAND) { - return; - } - ItemStack relevant; - Player p = pie.getPlayer(); - if (hand == EquipmentSlot.HAND) { - relevant = p.getInventory().getItemInMainHand(); - } else { - relevant = p.getInventory().getItemInOffHand(); - } - if (relevant.getType() != Material.BRUSH) { - return; - } - Reinforcement rein = Citadel.getInstance().getReinforcementManager().getReinforcement(block); - if (rein == null) { - return; - } - if (!rein.hasPermission(p, CitadelPermissionHandler.getModifyBlocks())) { - p.sendMessage(ChatColor.RED + "You do not have permission to dust this block"); - pie.setCancelled(true); - } - } + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void preventDusting(PlayerInteractEvent pie) { // Maybe this should be changed to brushing? The two terms seem to be used interchangeably. + if (!pie.hasBlock()) { + return; + } + if (pie.getAction() != Action.RIGHT_CLICK_BLOCK) { + return; + } + Block block = pie.getClickedBlock(); + Material type = block.getType(); + if (!MoreTags.DUSTABLE.isTagged(type)) { + return; + } + EquipmentSlot hand = pie.getHand(); + if (hand != EquipmentSlot.HAND && hand != EquipmentSlot.OFF_HAND) { + return; + } + ItemStack relevant; + Player p = pie.getPlayer(); + if (hand == EquipmentSlot.HAND) { + relevant = p.getInventory().getItemInMainHand(); + } else { + relevant = p.getInventory().getItemInOffHand(); + } + if (relevant.getType() != Material.BRUSH) { + return; + } + Reinforcement rein = Citadel.getInstance().getReinforcementManager().getReinforcement(block); + if (rein == null) { + return; + } + if (!rein.hasPermission(p, CitadelPermissionHandler.getModifyBlocks())) { + p.sendMessage(ChatColor.RED + "You do not have permission to dust this block"); + pie.setCancelled(true); + } + } - @EventHandler(ignoreCancelled = true) - public void preventFlowerTheft(PlayerInteractEvent event) { - if (event.getAction() != Action.RIGHT_CLICK_BLOCK) { - return; - } - Block block = event.getClickedBlock(); - if (block == null || !Tag.FLOWER_POTS.isTagged(block.getType())) { - return; - } - Player player = event.getPlayer(); + @EventHandler(ignoreCancelled = true) + public void preventFlowerTheft(PlayerInteractEvent event) { + if (event.getAction() != Action.RIGHT_CLICK_BLOCK) { + return; + } + Block block = event.getClickedBlock(); + if (block == null || !Tag.FLOWER_POTS.isTagged(block.getType())) { + return; + } + Player player = event.getPlayer(); - Reinforcement reinforcement = Citadel.getInstance().getReinforcementManager().getReinforcement(block); + Reinforcement reinforcement = Citadel.getInstance().getReinforcementManager().getReinforcement(block); - if (reinforcement == null - || reinforcement.isInsecure() - || reinforcement.hasPermission(player.getUniqueId(), CitadelPermissionHandler.getModifyBlocks())) { - return; - } - event.setCancelled(true); - player.sendMessage(ChatColor.RED + "You do not have permission to modify this block"); - } + if (reinforcement == null + || reinforcement.isInsecure() + || reinforcement.hasPermission(player.getUniqueId(), CitadelPermissionHandler.getModifyBlocks())) { + return; + } + event.setCancelled(true); + player.sendMessage(ChatColor.RED + "You do not have permission to modify this block"); + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/listener/EntityListener.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/listener/EntityListener.java index d2c545d53..1f031cb7e 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/listener/EntityListener.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/listener/EntityListener.java @@ -51,19 +51,19 @@ import vg.civcraft.mc.namelayer.database.GroupManagerDao; public class EntityListener implements Listener { - protected GroupManager gm = NameAPI.getGroupManager(); + protected GroupManager gm = NameAPI.getGroupManager(); - // prevent zombies from breaking reinforced doors - @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) - public void breakDoor(EntityBreakDoorEvent ebde) { - Reinforcement rein = ReinforcementLogic.getReinforcementProtecting(ebde.getBlock()); - if (rein != null) { - ReinforcementLogic.damageReinforcement(rein, ReinforcementLogic.getDamageApplied(rein), ebde.getEntity()); - if (!rein.isBroken()) { - ebde.setCancelled(true); - } - } - } + // prevent zombies from breaking reinforced doors + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void breakDoor(EntityBreakDoorEvent ebde) { + Reinforcement rein = ReinforcementLogic.getReinforcementProtecting(ebde.getBlock()); + if (rein != null) { + ReinforcementLogic.damageReinforcement(rein, ReinforcementLogic.getDamageApplied(rein), ebde.getEntity()); + if (!rein.isBroken()) { + ebde.setCancelled(true); + } + } + } // Prevent Piglins and other "smart" mobs from opening reinforced doors, trapdoors, and fence gates @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) @@ -83,304 +83,304 @@ public class EntityListener implements Listener { } } - // For some ungodly reason, when you break a block below a block with gravity, it spawns a FallingBlock entity - // that then attempts to change the block. To prevent this change from ticking damage and creating a ghost block - // the entity needs to have its gravity disabled so it immediately lands. - @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) - public void onFallingBlockSpawn(EntitySpawnEvent event) { - if (event.getEntityType() != EntityType.FALLING_BLOCK) { - return; - } - Block block = event.getLocation().getBlock(); - Reinforcement rein = ReinforcementLogic.getReinforcementProtecting(block); - if (rein == null) { - return; - } - Entity entity = event.getEntity(); - entity.setGravity(false); - event.setCancelled(true); - } + // For some ungodly reason, when you break a block below a block with gravity, it spawns a FallingBlock entity + // that then attempts to change the block. To prevent this change from ticking damage and creating a ghost block + // the entity needs to have its gravity disabled so it immediately lands. + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void onFallingBlockSpawn(EntitySpawnEvent event) { + if (event.getEntityType() != EntityType.FALLING_BLOCK) { + return; + } + Block block = event.getLocation().getBlock(); + Reinforcement rein = ReinforcementLogic.getReinforcementProtecting(block); + if (rein == null) { + return; + } + Entity entity = event.getEntity(); + entity.setGravity(false); + event.setCancelled(true); + } - @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) - public void changeBlock(EntityChangeBlockEvent ecbe) { - Block block = ecbe.getBlock(); - Reinforcement rein = ReinforcementLogic.getReinforcementProtecting(block); - // Do not allow a falling block entity to damage reinforcements. - if (rein == null || ecbe.getEntityType() == EntityType.FALLING_BLOCK) { - return; - } - if (ecbe.getBlock().getType() == Material.BIG_DRIPLEAF) { - return; - } - if (ecbe.getBlock().getType() == Material.CAVE_VINES || ecbe.getBlock().getType() == Material.CAVE_VINES_PLANT) { - return; - } - ReinforcementLogic.damageReinforcement(rein, ReinforcementLogic.getDamageApplied(rein), ecbe.getEntity()); - if (rein.isBroken()) { - return; - } - ecbe.setCancelled(true); - } + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void changeBlock(EntityChangeBlockEvent ecbe) { + Block block = ecbe.getBlock(); + Reinforcement rein = ReinforcementLogic.getReinforcementProtecting(block); + // Do not allow a falling block entity to damage reinforcements. + if (rein == null || ecbe.getEntityType() == EntityType.FALLING_BLOCK) { + return; + } + if (ecbe.getBlock().getType() == Material.BIG_DRIPLEAF) { + return; + } + if (ecbe.getBlock().getType() == Material.CAVE_VINES || ecbe.getBlock().getType() == Material.CAVE_VINES_PLANT) { + return; + } + ReinforcementLogic.damageReinforcement(rein, ReinforcementLogic.getDamageApplied(rein), ecbe.getEntity()); + if (rein.isBroken()) { + return; + } + ecbe.setCancelled(true); + } - // apply explosion damage to reinforcements - @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) - public void explode(EntityExplodeEvent eee) { - Iterator iterator = eee.blockList().iterator(); - // we can edit the result by removing blocks from the list - while (iterator.hasNext()) { - Block block = iterator.next(); - Reinforcement rein = ReinforcementLogic.getReinforcementProtecting(block); - if (rein == null) { - continue; - } - ReinforcementLogic.damageReinforcement(rein, ReinforcementLogic.getDamageApplied(rein), eee.getEntity()); - if (!rein.isBroken()) { - iterator.remove(); - } - } - } + // apply explosion damage to reinforcements + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void explode(EntityExplodeEvent eee) { + Iterator iterator = eee.blockList().iterator(); + // we can edit the result by removing blocks from the list + while (iterator.hasNext()) { + Block block = iterator.next(); + Reinforcement rein = ReinforcementLogic.getReinforcementProtecting(block); + if (rein == null) { + continue; + } + ReinforcementLogic.damageReinforcement(rein, ReinforcementLogic.getDamageApplied(rein), eee.getEntity()); + if (!rein.isBroken()) { + iterator.remove(); + } + } + } - private List getGolemBlocks(EntityType type, Block base) { - ArrayList blocks = new ArrayList<>(); - blocks.add(base); - base = base.getRelative(BlockFace.UP); - blocks.add(base); - if (type == EntityType.IRON_GOLEM) { - for (BlockFace face : new BlockFace[] { BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST, - BlockFace.WEST }) { - Block arm = base.getRelative(face); - if (arm.getType() == Material.IRON_BLOCK) - blocks.add(arm); - } - } - base = base.getRelative(BlockFace.UP); - blocks.add(base); - return blocks; - } + private List getGolemBlocks(EntityType type, Block base) { + ArrayList blocks = new ArrayList<>(); + blocks.add(base); + base = base.getRelative(BlockFace.UP); + blocks.add(base); + if (type == EntityType.IRON_GOLEM) { + for (BlockFace face : new BlockFace[]{BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST, + BlockFace.WEST}) { + Block arm = base.getRelative(face); + if (arm.getType() == Material.IRON_BLOCK) + blocks.add(arm); + } + } + base = base.getRelative(BlockFace.UP); + blocks.add(base); + return blocks; + } - @EventHandler(priority = EventPriority.HIGHEST) - public void playerJoinEvent(PlayerJoinEvent event) { - Player p = event.getPlayer(); - final UUID uuid = p.getUniqueId(); + @EventHandler(priority = EventPriority.HIGHEST) + public void playerJoinEvent(PlayerJoinEvent event) { + Player p = event.getPlayer(); + final UUID uuid = p.getUniqueId(); - new BukkitRunnable() { - @Override - public void run() { - GroupManagerDao db = NameLayerPlugin.getGroupManagerDao(); - for (String groupName : db.getGroupNames(uuid)) { - if (NameAPI.getGroupManager().hasAccess(groupName, uuid, - CitadelPermissionHandler.getBypass())) { - GroupManager.getGroup(groupName).updateActivityTimeStamp(); - } - } - } - }.runTaskAsynchronously(Citadel.getInstance()); - } + new BukkitRunnable() { + @Override + public void run() { + GroupManagerDao db = NameLayerPlugin.getGroupManagerDao(); + for (String groupName : db.getGroupNames(uuid)) { + if (NameAPI.getGroupManager().hasAccess(groupName, uuid, + CitadelPermissionHandler.getBypass())) { + GroupManager.getGroup(groupName).updateActivityTimeStamp(); + } + } + } + }.runTaskAsynchronously(Citadel.getInstance()); + } - @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) - public void powderedSnowPickup(PlayerBucketFillEvent event) { - if (event.getBlockClicked().getType() != Material.POWDER_SNOW) { - return; - } + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void powderedSnowPickup(PlayerBucketFillEvent event) { + if (event.getBlockClicked().getType() != Material.POWDER_SNOW) { + return; + } - Block clickedBlock = event.getBlockClicked(); - Reinforcement reinforcement = Citadel.getInstance().getReinforcementManager().getReinforcement(clickedBlock); - if (reinforcement == null) { - return; - } - Player player = event.getPlayer(); - if (!reinforcement.hasPermission(player, CitadelPermissionHandler.getBypass())) { - player.sendMessage(Component.text("You do not have permission to bypass this block!").color(NamedTextColor.RED)); - event.setCancelled(true); - return; - } - ReinforcementBypassEvent bypassEvent = new ReinforcementBypassEvent(player, reinforcement); - Bukkit.getPluginManager().callEvent(bypassEvent); - if (event.isCancelled()) { - event.setCancelled(true); - return; - } - reinforcement.setHealth(-1); - } + Block clickedBlock = event.getBlockClicked(); + Reinforcement reinforcement = Citadel.getInstance().getReinforcementManager().getReinforcement(clickedBlock); + if (reinforcement == null) { + return; + } + Player player = event.getPlayer(); + if (!reinforcement.hasPermission(player, CitadelPermissionHandler.getBypass())) { + player.sendMessage(Component.text("You do not have permission to bypass this block!").color(NamedTextColor.RED)); + event.setCancelled(true); + return; + } + ReinforcementBypassEvent bypassEvent = new ReinforcementBypassEvent(player, reinforcement); + Bukkit.getPluginManager().callEvent(bypassEvent); + if (event.isCancelled()) { + event.setCancelled(true); + return; + } + reinforcement.setHealth(-1); + } - // prevent creating golems from reinforced blocks - @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) - public void spawn(CreatureSpawnEvent cse) { - EntityType type = cse.getEntityType(); - if (type != EntityType.IRON_GOLEM && type != EntityType.SNOWMAN && type != EntityType.WITHER - && type != EntityType.SILVERFISH) { - return; - } - for (Block block : getGolemBlocks(type, cse.getLocation().getBlock())) { - Reinforcement reinforcement = Citadel.getInstance().getReinforcementManager().getReinforcement(block); - if (reinforcement != null) { - cse.setCancelled(true); - } - } - } + // prevent creating golems from reinforced blocks + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void spawn(CreatureSpawnEvent cse) { + EntityType type = cse.getEntityType(); + if (type != EntityType.IRON_GOLEM && type != EntityType.SNOWMAN && type != EntityType.WITHER + && type != EntityType.SILVERFISH) { + return; + } + for (Block block : getGolemBlocks(type, cse.getLocation().getBlock())) { + Reinforcement reinforcement = Citadel.getInstance().getReinforcementManager().getReinforcement(block); + if (reinforcement != null) { + cse.setCancelled(true); + } + } + } - // ------------------------------------------------------------ - // Hanging Entities - // ------------------------------------------------------------ + // ------------------------------------------------------------ + // Hanging Entities + // ------------------------------------------------------------ - @EventHandler(priority = EventPriority.HIGHEST) - public void hangingPlaceEvent(HangingPlaceEvent event) { - if (!Citadel.getInstance().getConfigManager().doHangersInheritReinforcements()) { - return; - } - Player player = event.getPlayer(); - if (player == null) { - return; - } - Reinforcement reinforcement = ReinforcementLogic.getReinforcementProtecting(event.getBlock()); - if (reinforcement == null) { - return; - } - if (reinforcement.isInsecure()) { - return; - } - if (reinforcement.hasPermission(player, CitadelPermissionHandler.getHangingPlaceBreak())) { - return; - } - player.sendMessage(ChatColor.RED + "You cannot place those on blocks you don't have permissions for."); - event.setCancelled(true); - Bukkit.getScheduler().runTaskLater(Citadel.getInstance(), player::updateInventory, 1L); - } + @EventHandler(priority = EventPriority.HIGHEST) + public void hangingPlaceEvent(HangingPlaceEvent event) { + if (!Citadel.getInstance().getConfigManager().doHangersInheritReinforcements()) { + return; + } + Player player = event.getPlayer(); + if (player == null) { + return; + } + Reinforcement reinforcement = ReinforcementLogic.getReinforcementProtecting(event.getBlock()); + if (reinforcement == null) { + return; + } + if (reinforcement.isInsecure()) { + return; + } + if (reinforcement.hasPermission(player, CitadelPermissionHandler.getHangingPlaceBreak())) { + return; + } + player.sendMessage(ChatColor.RED + "You cannot place those on blocks you don't have permissions for."); + event.setCancelled(true); + Bukkit.getScheduler().runTaskLater(Citadel.getInstance(), player::updateInventory, 1L); + } - @EventHandler(priority = EventPriority.HIGHEST) - public void hangingEntityBreakEvent(HangingBreakByEntityEvent event) { - if (!Citadel.getInstance().getConfigManager().doHangersInheritReinforcements()) { - return; - } - switch (event.getCause()) { - // Allow it to break if: - // 1) The host block broke - // 2) A block was placed over it - // 3) A plugin broke it - case OBSTRUCTION: - case PHYSICS: - case DEFAULT: - case EXPLOSION: - return; - case ENTITY: { - if (!(event.getRemover() instanceof final Player player)) { - break; - } - Hanging entity = event.getEntity(); - Block host = entity.getLocation().getBlock().getRelative(entity.getAttachedFace()); - Reinforcement reinforcement = ReinforcementLogic.getReinforcementProtecting(host); - if (reinforcement == null) { - return; - } - if (reinforcement.isInsecure()) { - return; - } - if (reinforcement.hasPermission(player, CitadelPermissionHandler.getHangingPlaceBreak())) { - return; - } - player.sendMessage(ChatColor.RED + "The host block is protecting this."); - //break; - } - } - event.setCancelled(true); - } + @EventHandler(priority = EventPriority.HIGHEST) + public void hangingEntityBreakEvent(HangingBreakByEntityEvent event) { + if (!Citadel.getInstance().getConfigManager().doHangersInheritReinforcements()) { + return; + } + switch (event.getCause()) { + // Allow it to break if: + // 1) The host block broke + // 2) A block was placed over it + // 3) A plugin broke it + case OBSTRUCTION: + case PHYSICS: + case DEFAULT: + case EXPLOSION: + return; + case ENTITY: { + if (!(event.getRemover() instanceof final Player player)) { + break; + } + Hanging entity = event.getEntity(); + Block host = entity.getLocation().getBlock().getRelative(entity.getAttachedFace()); + Reinforcement reinforcement = ReinforcementLogic.getReinforcementProtecting(host); + if (reinforcement == null) { + return; + } + if (reinforcement.isInsecure()) { + return; + } + if (reinforcement.hasPermission(player, CitadelPermissionHandler.getHangingPlaceBreak())) { + return; + } + player.sendMessage(ChatColor.RED + "The host block is protecting this."); + //break; + } + } + event.setCancelled(true); + } - @EventHandler(priority = EventPriority.HIGHEST) - public void HangingBreakEvent(HangingBreakEvent event) { - if (!Citadel.getInstance().getConfigManager().doHangersInheritReinforcements()) { - return; - } - if (event.getCause() != HangingBreakEvent.RemoveCause.EXPLOSION){ - return; - } - Hanging entity = event.getEntity(); - Block host = entity.getLocation().getBlock().getRelative(entity.getAttachedFace()); - Reinforcement reinforcement = ReinforcementLogic.getReinforcementProtecting(host); - if (reinforcement == null) { - return; - } - if (reinforcement.isInsecure()) { - return; - } - event.setCancelled(true); - } + @EventHandler(priority = EventPriority.HIGHEST) + public void HangingBreakEvent(HangingBreakEvent event) { + if (!Citadel.getInstance().getConfigManager().doHangersInheritReinforcements()) { + return; + } + if (event.getCause() != HangingBreakEvent.RemoveCause.EXPLOSION) { + return; + } + Hanging entity = event.getEntity(); + Block host = entity.getLocation().getBlock().getRelative(entity.getAttachedFace()); + Reinforcement reinforcement = ReinforcementLogic.getReinforcementProtecting(host); + if (reinforcement == null) { + return; + } + if (reinforcement.isInsecure()) { + return; + } + event.setCancelled(true); + } - @EventHandler(priority = EventPriority.HIGHEST) - public void entityDamageEvent(EntityDamageByEntityEvent event) { - if (!Citadel.getInstance().getConfigManager().doHangersInheritReinforcements()) { - return; - } - if (!(event.getEntity() instanceof final Hanging entity)) { - return; - } - if (!(event.getDamager() instanceof final Player player)) { - event.setCancelled(true); - return; - } - Block host = entity.getLocation().getBlock().getRelative(entity.getAttachedFace()); - Reinforcement reinforcement = ReinforcementLogic.getReinforcementProtecting(host); - if (reinforcement == null) { - return; - } - if (entity instanceof ItemFrame) { - if (ItemUtils.isValidItem(((ItemFrame) entity).getItem())) { - if (reinforcement.isInsecure()) { - return; - } - if (reinforcement.hasPermission(player, CitadelPermissionHandler.getItemFramePutTake())) { - return; - } - } - } - player.sendMessage(ChatColor.RED + "The host block is protecting this."); - event.setCancelled(true); - } + @EventHandler(priority = EventPriority.HIGHEST) + public void entityDamageEvent(EntityDamageByEntityEvent event) { + if (!Citadel.getInstance().getConfigManager().doHangersInheritReinforcements()) { + return; + } + if (!(event.getEntity() instanceof final Hanging entity)) { + return; + } + if (!(event.getDamager() instanceof final Player player)) { + event.setCancelled(true); + return; + } + Block host = entity.getLocation().getBlock().getRelative(entity.getAttachedFace()); + Reinforcement reinforcement = ReinforcementLogic.getReinforcementProtecting(host); + if (reinforcement == null) { + return; + } + if (entity instanceof ItemFrame) { + if (ItemUtils.isValidItem(((ItemFrame) entity).getItem())) { + if (reinforcement.isInsecure()) { + return; + } + if (reinforcement.hasPermission(player, CitadelPermissionHandler.getItemFramePutTake())) { + return; + } + } + } + player.sendMessage(ChatColor.RED + "The host block is protecting this."); + event.setCancelled(true); + } - @EventHandler(priority = EventPriority.HIGHEST) - public void playerEntityInteractEvent(PlayerInteractEntityEvent event) { - if (!Citadel.getInstance().getConfigManager().doHangersInheritReinforcements()) { - return; - } - if (!(event.getRightClicked() instanceof final Hanging entity)) { - return; - } - Block host = entity.getLocation().getBlock().getRelative(entity.getAttachedFace()); - Reinforcement reinforcement = ReinforcementLogic.getReinforcementProtecting(host); - if (reinforcement == null) { - return; - } - Player player = event.getPlayer(); - if (entity instanceof ItemFrame) { - if (reinforcement.isInsecure()) { - return; - } - // If the Item Frame already has an item, then the only possible action is rotation - if (ItemUtils.isValidItem(((ItemFrame) entity).getItem())) { - if (reinforcement.hasPermission(player, CitadelPermissionHandler.getItemFrameRotate())) { - return; - } - } - // If the Item Frame is empty, then the only possible action is placement - if (reinforcement.hasPermission(player, CitadelPermissionHandler.getItemFramePutTake())) { - return; - } - } - player.sendMessage(ChatColor.RED + "You do not have permission to alter that."); - event.setCancelled(true); - } + @EventHandler(priority = EventPriority.HIGHEST) + public void playerEntityInteractEvent(PlayerInteractEntityEvent event) { + if (!Citadel.getInstance().getConfigManager().doHangersInheritReinforcements()) { + return; + } + if (!(event.getRightClicked() instanceof final Hanging entity)) { + return; + } + Block host = entity.getLocation().getBlock().getRelative(entity.getAttachedFace()); + Reinforcement reinforcement = ReinforcementLogic.getReinforcementProtecting(host); + if (reinforcement == null) { + return; + } + Player player = event.getPlayer(); + if (entity instanceof ItemFrame) { + if (reinforcement.isInsecure()) { + return; + } + // If the Item Frame already has an item, then the only possible action is rotation + if (ItemUtils.isValidItem(((ItemFrame) entity).getItem())) { + if (reinforcement.hasPermission(player, CitadelPermissionHandler.getItemFrameRotate())) { + return; + } + } + // If the Item Frame is empty, then the only possible action is placement + if (reinforcement.hasPermission(player, CitadelPermissionHandler.getItemFramePutTake())) { + return; + } + } + player.sendMessage(ChatColor.RED + "You do not have permission to alter that."); + event.setCancelled(true); + } - // prevent editing signs without permission - @EventHandler(priority = EventPriority.HIGHEST) - public void playerEditSign(PlayerOpenSignEvent event) { - Player player = event.getPlayer(); + // prevent editing signs without permission + @EventHandler(priority = EventPriority.HIGHEST) + public void playerEditSign(PlayerOpenSignEvent event) { + Player player = event.getPlayer(); - Reinforcement reinforcement = Citadel.getInstance().getReinforcementManager().getReinforcement(event.getSign().getBlock()); - if (reinforcement == null) return; + Reinforcement reinforcement = Citadel.getInstance().getReinforcementManager().getReinforcement(event.getSign().getBlock()); + if (reinforcement == null) return; - if (!reinforcement.hasPermission(player, CitadelPermissionHandler.getModifyBlocks())) { - player.sendMessage(ChatColor.RED + "You do not have permission to modify this block"); - event.setCancelled(true); - } - } + if (!reinforcement.hasPermission(player, CitadelPermissionHandler.getModifyBlocks())) { + player.sendMessage(ChatColor.RED + "You do not have permission to modify this block"); + event.setCancelled(true); + } + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/listener/InventoryListener.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/listener/InventoryListener.java index 5534f5914..ee24a917c 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/listener/InventoryListener.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/listener/InventoryListener.java @@ -17,114 +17,114 @@ import vg.civcraft.mc.civmodcore.world.WorldUtils; public class InventoryListener implements Listener { - @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) - public void onInventoryMoveItemEvent(InventoryMoveItemEvent event) { - Inventory fromInventory = event.getSource(); - InventoryHolder fromHolder = fromInventory.getHolder(false); - boolean isFromBlock = fromHolder instanceof BlockInventoryHolder || fromHolder instanceof DoubleChest; - boolean fromAtChunkBorder = false; - Location fromLocation = null; - if (isFromBlock) { - fromLocation = fromInventory.getLocation(); - fromAtChunkBorder = isAtChunkBorder(fromLocation); - if (fromAtChunkBorder && !WorldUtils.isBlockLoaded(fromLocation)) { - event.setCancelled(true); - return; - } - } + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void onInventoryMoveItemEvent(InventoryMoveItemEvent event) { + Inventory fromInventory = event.getSource(); + InventoryHolder fromHolder = fromInventory.getHolder(false); + boolean isFromBlock = fromHolder instanceof BlockInventoryHolder || fromHolder instanceof DoubleChest; + boolean fromAtChunkBorder = false; + Location fromLocation = null; + if (isFromBlock) { + fromLocation = fromInventory.getLocation(); + fromAtChunkBorder = isAtChunkBorder(fromLocation); + if (fromAtChunkBorder && !WorldUtils.isBlockLoaded(fromLocation)) { + event.setCancelled(true); + return; + } + } - Inventory destInventory = event.getDestination(); - InventoryHolder destHolder = destInventory.getHolder(false); - boolean isDestBlock = destHolder instanceof BlockInventoryHolder || destHolder instanceof DoubleChest; - boolean destAtChunkBorder = false; - Location destLocation = null; - if (isDestBlock) { - destLocation = destInventory.getLocation(); - destAtChunkBorder = isAtChunkBorder(destLocation); - if (destAtChunkBorder && !WorldUtils.isBlockLoaded(destLocation)) { - event.setCancelled(true); - return; - } - } else { - if (!isFromBlock) { - // neither is a block, just ignore entirely - return; - } - } + Inventory destInventory = event.getDestination(); + InventoryHolder destHolder = destInventory.getHolder(false); + boolean isDestBlock = destHolder instanceof BlockInventoryHolder || destHolder instanceof DoubleChest; + boolean destAtChunkBorder = false; + Location destLocation = null; + if (isDestBlock) { + destLocation = destInventory.getLocation(); + destAtChunkBorder = isAtChunkBorder(destLocation); + if (destAtChunkBorder && !WorldUtils.isBlockLoaded(destLocation)) { + event.setCancelled(true); + return; + } + } else { + if (!isFromBlock) { + // neither is a block, just ignore entirely + return; + } + } - // Determine the reinforcement of the source - Reinforcement fromReinforcement = null; - if (isFromBlock) { - if (fromAtChunkBorder && fromHolder instanceof DoubleChest) { - DoubleChest doubleChest = (DoubleChest) fromHolder; - Location chestLocation = ((Chest) doubleChest.getLeftSide(false)).getLocation(); - Location otherLocation = ((Chest) doubleChest.getRightSide(false)).getLocation(); - // [LagFix] If either side of the double chest is not loaded then the - // reinforcement cannot be retrieved - // [LagFix] without necessarily loading the chunk to check against reinforcement - // logic, therefore this - // [LagFix] should err on the side of caution and prevent the transfer. - if (!WorldUtils.isBlockLoaded(chestLocation) || !WorldUtils.isBlockLoaded(otherLocation)) { - event.setCancelled(true); - return; - } - } - fromReinforcement = ReinforcementLogic.getReinforcementProtecting(fromLocation.getBlock()); - } - // Determine the reinforcement of the destination - Reinforcement destReinforcement = null; - if (isDestBlock) { - if (destAtChunkBorder && destHolder instanceof DoubleChest) { - DoubleChest doubleChest = (DoubleChest) destHolder; - Location chestLocation = ((Chest) doubleChest.getLeftSide(false)).getLocation(); - Location otherLocation = ((Chest) doubleChest.getRightSide(false)).getLocation(); - // [LagFix] If either side of the double chest is not loaded then the - // reinforcement cannot be retrieved - // [LagFix] without necessarily loading the chunk to check against reinforcement - // logic, therefore this - // [LagFix] should err on the side of caution and prevent the transfer. - if (!WorldUtils.isBlockLoaded(chestLocation) || !WorldUtils.isBlockLoaded(otherLocation)) { - event.setCancelled(true); - return; - } - } - destReinforcement = ReinforcementLogic.getReinforcementProtecting(destLocation.getBlock()); - } - // Allow the transfer if neither are reinforced - if (fromReinforcement == null && destReinforcement == null) { - return; - } - // Allow the transfer if the destination is un-reinforced and the source is - // insecure - if (destReinforcement == null) { - if (!fromReinforcement.isInsecure()) { - event.setCancelled(true); - } - return; - } - // Allow the transfer if the source is un-reinforced and the destination is - // insecure - if (fromReinforcement == null) { - if (!destReinforcement.isInsecure()) { - event.setCancelled(true); - } - return; - } - // Allow the transfer if both the source and destination are insecure - if (fromReinforcement.isInsecure() && destReinforcement.isInsecure()) { - return; - } - // Allow the transfer if both the source and destination are on the same group - if (fromReinforcement.getGroupId() == destReinforcement.getGroupId()) { - return; - } - event.setCancelled(true); - } - - private static boolean isAtChunkBorder(Location location) { - int xShif = location.getBlockX() & 15; - int zShif = location.getBlockZ() & 15; - return xShif == 0 || xShif == 15 || zShif == 0 || zShif == 15; - } + // Determine the reinforcement of the source + Reinforcement fromReinforcement = null; + if (isFromBlock) { + if (fromAtChunkBorder && fromHolder instanceof DoubleChest) { + DoubleChest doubleChest = (DoubleChest) fromHolder; + Location chestLocation = ((Chest) doubleChest.getLeftSide(false)).getLocation(); + Location otherLocation = ((Chest) doubleChest.getRightSide(false)).getLocation(); + // [LagFix] If either side of the double chest is not loaded then the + // reinforcement cannot be retrieved + // [LagFix] without necessarily loading the chunk to check against reinforcement + // logic, therefore this + // [LagFix] should err on the side of caution and prevent the transfer. + if (!WorldUtils.isBlockLoaded(chestLocation) || !WorldUtils.isBlockLoaded(otherLocation)) { + event.setCancelled(true); + return; + } + } + fromReinforcement = ReinforcementLogic.getReinforcementProtecting(fromLocation.getBlock()); + } + // Determine the reinforcement of the destination + Reinforcement destReinforcement = null; + if (isDestBlock) { + if (destAtChunkBorder && destHolder instanceof DoubleChest) { + DoubleChest doubleChest = (DoubleChest) destHolder; + Location chestLocation = ((Chest) doubleChest.getLeftSide(false)).getLocation(); + Location otherLocation = ((Chest) doubleChest.getRightSide(false)).getLocation(); + // [LagFix] If either side of the double chest is not loaded then the + // reinforcement cannot be retrieved + // [LagFix] without necessarily loading the chunk to check against reinforcement + // logic, therefore this + // [LagFix] should err on the side of caution and prevent the transfer. + if (!WorldUtils.isBlockLoaded(chestLocation) || !WorldUtils.isBlockLoaded(otherLocation)) { + event.setCancelled(true); + return; + } + } + destReinforcement = ReinforcementLogic.getReinforcementProtecting(destLocation.getBlock()); + } + // Allow the transfer if neither are reinforced + if (fromReinforcement == null && destReinforcement == null) { + return; + } + // Allow the transfer if the destination is un-reinforced and the source is + // insecure + if (destReinforcement == null) { + if (!fromReinforcement.isInsecure()) { + event.setCancelled(true); + } + return; + } + // Allow the transfer if the source is un-reinforced and the destination is + // insecure + if (fromReinforcement == null) { + if (!destReinforcement.isInsecure()) { + event.setCancelled(true); + } + return; + } + // Allow the transfer if both the source and destination are insecure + if (fromReinforcement.isInsecure() && destReinforcement.isInsecure()) { + return; + } + // Allow the transfer if both the source and destination are on the same group + if (fromReinforcement.getGroupId() == destReinforcement.getGroupId()) { + return; + } + event.setCancelled(true); + } + + private static boolean isAtChunkBorder(Location location) { + int xShif = location.getBlockX() & 15; + int zShif = location.getBlockZ() & 15; + return xShif == 0 || xShif == 15 || zShif == 0 || zShif == 15; + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/listener/ModeListener.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/listener/ModeListener.java index 0e107b6af..4e25aa255 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/listener/ModeListener.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/listener/ModeListener.java @@ -37,248 +37,248 @@ import vg.civcraft.mc.civmodcore.utilities.TextUtil; public class ModeListener implements Listener { - private static final DecimalFormat commaFormat = new DecimalFormat("#.##"); - private static final DecimalFormat roundingFormat = new DecimalFormat("0"); + private static final DecimalFormat commaFormat = new DecimalFormat("#.##"); + private static final DecimalFormat roundingFormat = new DecimalFormat("0"); - private DoubleInteractFixer interactFixer; - private BottomLine ctiBottomLine; - private CivScoreBoard ctiBoard; - private BottomLine ctbBottomLine; - private CivScoreBoard ctbBoard; - private BottomLine reinBottomLine; - private CivScoreBoard reinBoard; - private CitadelSettingManager settingMan; - private PlayerStateManager stateMan; + private DoubleInteractFixer interactFixer; + private BottomLine ctiBottomLine; + private CivScoreBoard ctiBoard; + private BottomLine ctbBottomLine; + private CivScoreBoard ctbBoard; + private BottomLine reinBottomLine; + private CivScoreBoard reinBoard; + private CitadelSettingManager settingMan; + private PlayerStateManager stateMan; - public ModeListener(Citadel citadel) { - interactFixer = new DoubleInteractFixer(citadel); - this.stateMan = citadel.getStateManager(); - this.ctiBottomLine = BottomLineAPI.createBottomLine("ctiDisplay", 3); - this.ctiBoard = ScoreBoardAPI.createBoard("ctiDisplay"); - this.ctbBottomLine = BottomLineAPI.createBottomLine("ctbDisplay", 3); - this.ctbBoard = ScoreBoardAPI.createBoard("ctbDisplay"); - this.reinBottomLine = BottomLineAPI.createBottomLine("ctreinDisplay", 3); - this.reinBoard = ScoreBoardAPI.createBoard("ctreinDisplay"); - this.settingMan = Citadel.getInstance().getSettingManager(); - settingMan.getInformationMode().registerListener(new SettingChangeListener() { - @Override - public void handle(UUID player, PlayerSetting setting, Boolean oldValue, Boolean newValue) { - setCtiOverlay(Bukkit.getPlayer(player), newValue); - } - }); - settingMan.getInformationLocationSetting().registerListener(new SettingChangeListener() { - @Override - public void handle(UUID player, PlayerSetting setting, String oldValue, String newValue) { - setCtiOverlay(Bukkit.getPlayer(player), settingMan.getInformationMode().getValue(player)); - } - }); - settingMan.getBypass().registerListener(new SettingChangeListener() { - @Override - public void handle(UUID player, PlayerSetting setting, Boolean oldValue, Boolean newValue) { - setCtbOverlay(Bukkit.getPlayer(player), newValue); - } - }); - settingMan.getBypassLocationSetting().registerListener(new SettingChangeListener() { - @Override - public void handle(UUID player, PlayerSetting setting, String oldValue, String newValue) { - setCtbOverlay(Bukkit.getPlayer(player), settingMan.getBypass().getValue(player)); - } - }); - settingMan.getModeLocationSetting().registerListener(new SettingChangeListener() { + public ModeListener(Citadel citadel) { + interactFixer = new DoubleInteractFixer(citadel); + this.stateMan = citadel.getStateManager(); + this.ctiBottomLine = BottomLineAPI.createBottomLine("ctiDisplay", 3); + this.ctiBoard = ScoreBoardAPI.createBoard("ctiDisplay"); + this.ctbBottomLine = BottomLineAPI.createBottomLine("ctbDisplay", 3); + this.ctbBoard = ScoreBoardAPI.createBoard("ctbDisplay"); + this.reinBottomLine = BottomLineAPI.createBottomLine("ctreinDisplay", 3); + this.reinBoard = ScoreBoardAPI.createBoard("ctreinDisplay"); + this.settingMan = Citadel.getInstance().getSettingManager(); + settingMan.getInformationMode().registerListener(new SettingChangeListener() { + @Override + public void handle(UUID player, PlayerSetting setting, Boolean oldValue, Boolean newValue) { + setCtiOverlay(Bukkit.getPlayer(player), newValue); + } + }); + settingMan.getInformationLocationSetting().registerListener(new SettingChangeListener() { + @Override + public void handle(UUID player, PlayerSetting setting, String oldValue, String newValue) { + setCtiOverlay(Bukkit.getPlayer(player), settingMan.getInformationMode().getValue(player)); + } + }); + settingMan.getBypass().registerListener(new SettingChangeListener() { + @Override + public void handle(UUID player, PlayerSetting setting, Boolean oldValue, Boolean newValue) { + setCtbOverlay(Bukkit.getPlayer(player), newValue); + } + }); + settingMan.getBypassLocationSetting().registerListener(new SettingChangeListener() { + @Override + public void handle(UUID player, PlayerSetting setting, String oldValue, String newValue) { + setCtbOverlay(Bukkit.getPlayer(player), settingMan.getBypass().getValue(player)); + } + }); + settingMan.getModeLocationSetting().registerListener(new SettingChangeListener() { - @Override - public void handle(UUID player, PlayerSetting setting, String oldValue, String newValue) { - setReinModeOverlay(Bukkit.getPlayer(player), stateMan.getState(Bukkit.getPlayer(player))); - } - }); - } + @Override + public void handle(UUID player, PlayerSetting setting, String oldValue, String newValue) { + setReinModeOverlay(Bukkit.getPlayer(player), stateMan.getState(Bukkit.getPlayer(player))); + } + }); + } - @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) - public void modeChange(ReinforcementModeSwitchEvent event) { - setReinModeOverlay(event.getPlayer(), event.getNewMode()); - } + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void modeChange(ReinforcementModeSwitchEvent event) { + setReinModeOverlay(event.getPlayer(), event.getNewMode()); + } - @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) - public void playerLogin(PlayerJoinEvent e) { - setCtiOverlay(e.getPlayer(), settingMan.getInformationMode().getValue(e.getPlayer())); - setCtbOverlay(e.getPlayer(), settingMan.getBypass().getValue(e.getPlayer())); - setReinModeOverlay(e.getPlayer(), stateMan.getState(e.getPlayer())); - } + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void playerLogin(PlayerJoinEvent e) { + setCtiOverlay(e.getPlayer(), settingMan.getInformationMode().getValue(e.getPlayer())); + setCtbOverlay(e.getPlayer(), settingMan.getBypass().getValue(e.getPlayer())); + setReinModeOverlay(e.getPlayer(), stateMan.getState(e.getPlayer())); + } - private void setCtiOverlay(Player player, boolean state) { - updateDisplaySetting(player, settingMan.getInformationLocationSetting(), state, ChatColor.GOLD + "CTI", - ctiBottomLine, ctiBoard); - } + private void setCtiOverlay(Player player, boolean state) { + updateDisplaySetting(player, settingMan.getInformationLocationSetting(), state, ChatColor.GOLD + "CTI", + ctiBottomLine, ctiBoard); + } - private void setCtbOverlay(Player player, boolean state) { - updateDisplaySetting(player, settingMan.getBypassLocationSetting(), state, ChatColor.AQUA + "CTB", - ctbBottomLine, ctbBoard); - } + private void setCtbOverlay(Player player, boolean state) { + updateDisplaySetting(player, settingMan.getBypassLocationSetting(), state, ChatColor.AQUA + "CTB", + ctbBottomLine, ctbBoard); + } - private void setReinModeOverlay(Player player, AbstractPlayerState state) { - if (state == null) { - return; - } - updateDisplaySetting(player, settingMan.getModeLocationSetting(), true, state.getOverlayText(), reinBottomLine, - reinBoard); - } + private void setReinModeOverlay(Player player, AbstractPlayerState state) { + if (state == null) { + return; + } + updateDisplaySetting(player, settingMan.getModeLocationSetting(), true, state.getOverlayText(), reinBottomLine, + reinBoard); + } - private static void updateDisplaySetting(Player player, DisplayLocationSetting locSetting, boolean state, String text, - BottomLine bottomLine, CivScoreBoard scoreBoard) { - if (player == null) { - return; - } - if (text == null) { - state = false; - } - if (!state) { - // always clean up, value might have been changed - bottomLine.removePlayer(player); - scoreBoard.hide(player); - } else { - if (locSetting.showOnActionbar(player.getUniqueId())) { - bottomLine.updatePlayer(player, text); - } - if (locSetting.showOnSidebar(player.getUniqueId())) { - scoreBoard.set(player, text); - } - } - } + private static void updateDisplaySetting(Player player, DisplayLocationSetting locSetting, boolean state, String text, + BottomLine bottomLine, CivScoreBoard scoreBoard) { + if (player == null) { + return; + } + if (text == null) { + state = false; + } + if (!state) { + // always clean up, value might have been changed + bottomLine.removePlayer(player); + scoreBoard.hide(player); + } else { + if (locSetting.showOnActionbar(player.getUniqueId())) { + bottomLine.updatePlayer(player, text); + } + if (locSetting.showOnSidebar(player.getUniqueId())) { + scoreBoard.set(player, text); + } + } + } - public static ChatColor getDamageColor(double relativeHealth) { - if (relativeHealth >= 1.0) { - return ChatColor.GREEN; - } else if (relativeHealth >= 0.75) { - return ChatColor.DARK_GREEN; - } else if (relativeHealth >= 0.5) { - return ChatColor.YELLOW; - } else if (relativeHealth >= 0.25) { - return ChatColor.RED; - } else { - return ChatColor.DARK_RED; - } - } + public static ChatColor getDamageColor(double relativeHealth) { + if (relativeHealth >= 1.0) { + return ChatColor.GREEN; + } else if (relativeHealth >= 0.75) { + return ChatColor.DARK_GREEN; + } else if (relativeHealth >= 0.5) { + return ChatColor.YELLOW; + } else if (relativeHealth >= 0.25) { + return ChatColor.RED; + } else { + return ChatColor.DARK_RED; + } + } - public static String formatHealth(Reinforcement rein) { - double broken = rein.getHealth() / rein.getType().getHealth(); - ChatColor color; - if (broken >= 1.0) { - color = ChatColor.GREEN; - } else if (broken >= 0.75) { - color = ChatColor.DARK_GREEN; - } else if (broken >= 0.5) { - color = ChatColor.YELLOW; - } else if (broken >= 0.25) { - color = ChatColor.RED; - } else { - color = ChatColor.DARK_RED; - } - return String.format("%s%s%% (%s/%s)", color.toString(), - commaFormat.format(rein.getHealth() / rein.getType().getHealth() * 100), - roundingFormat.format(rein.getHealth()), roundingFormat.format(rein.getType().getHealth())); - } + public static String formatHealth(Reinforcement rein) { + double broken = rein.getHealth() / rein.getType().getHealth(); + ChatColor color; + if (broken >= 1.0) { + color = ChatColor.GREEN; + } else if (broken >= 0.75) { + color = ChatColor.DARK_GREEN; + } else if (broken >= 0.5) { + color = ChatColor.YELLOW; + } else if (broken >= 0.25) { + color = ChatColor.RED; + } else { + color = ChatColor.DARK_RED; + } + return String.format("%s%s%% (%s/%s)", color.toString(), + commaFormat.format(rein.getHealth() / rein.getType().getHealth() * 100), + roundingFormat.format(rein.getHealth()), roundingFormat.format(rein.getType().getHealth())); + } - public static String formatProgress(long start, long timeNeeded, String text) { - long timeTaken = System.currentTimeMillis() - start; - timeTaken = Math.min(timeTaken, timeNeeded); - double progress = Math.min(1.0, ((double) timeTaken) / ((double) timeNeeded)); - return String.format("%s%% %s %s", commaFormat.format(progress * 100), text, - TextUtil.formatDuration(timeNeeded - timeTaken, TimeUnit.MILLISECONDS)); - } + public static String formatProgress(long start, long timeNeeded, String text) { + long timeTaken = System.currentTimeMillis() - start; + timeTaken = Math.min(timeTaken, timeNeeded); + double progress = Math.min(1.0, ((double) timeTaken) / ((double) timeNeeded)); + return String.format("%s%% %s %s", commaFormat.format(progress * 100), text, + TextUtil.formatDuration(timeNeeded - timeTaken, TimeUnit.MILLISECONDS)); + } - @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) - public void handleInteractBlock(PlayerInteractEvent e) { - if (e.getAction() == Action.RIGHT_CLICK_BLOCK) { - if (interactFixer.checkInteracted(e.getPlayer(), e.getClickedBlock())) { - return; - } - } else if (e.getAction() != Action.LEFT_CLICK_BLOCK) { - return; - } - if (!settingMan.getInformationMode().getValue(e.getPlayer())) { - return; - } - Reinforcement rein = ReinforcementLogic.getReinforcementProtecting(e.getClickedBlock()); - Player player = e.getPlayer(); - boolean showChat = settingMan.shouldShowChatInCti(player.getUniqueId()); - if (rein == null) { - if (showChat) { - CitadelUtility.sendAndLog(e.getPlayer(), ChatColor.YELLOW, "Not reinforced", e.getClickedBlock().getLocation()); - } - return; - } - if (player.getGameMode() == GameMode.CREATIVE && e.getAction() == Action.LEFT_CLICK_BLOCK) { - e.setCancelled(true); - } - boolean showHolo = settingMan.shouldShowHologramInCti(player.getUniqueId()); - if (!rein.hasPermission(player, CitadelPermissionHandler.getInfo())) { - if (showChat) { - Citadel.getInstance().getSettingManager().sendCtiEnemyMessage(player, rein, e.getClickedBlock().getLocation()); - } - if (showHolo) { - showHolo(rein, player); - } - return; - } - if (showChat) { - StringBuilder sb = new StringBuilder(); - sb.append(String.format("Reinforced at %s%s health with %s%s %son %s%s ", formatHealth(rein), - ChatColor.GREEN, ChatColor.AQUA, rein.getType().getName(), ChatColor.GREEN, ChatColor.LIGHT_PURPLE, - rein.getGroup().getName())); - if (!rein.isMature()) { - sb.append(ChatColor.GOLD); - sb.append(formatProgress(rein.getCreationTime(), rein.getType().getMaturationTime(), "mature")); - sb.append(" "); - } - if (rein.isInsecure()) { - sb.append(ChatColor.AQUA); - sb.append("(Insecure) "); - } - if (ReinforcementLogic.getDecayDamage(rein) != 1) { - String ctiDecayAmountFormat = commaFormat.format(ReinforcementLogic.getDecayDamage(rein)); - sb.append(String.format("%s(Decayed x%s) ", ChatColor.LIGHT_PURPLE, ctiDecayAmountFormat)); - } - AcidManager acidMan = Citadel.getInstance().getAcidManager(); - if (acidMan.isPossibleAcidBlock(e.getClickedBlock())) { - sb.append(ChatColor.GOLD); - long remainingTime = acidMan.getRemainingAcidMaturationTime(rein); - if (remainingTime == 0) { - sb.append("Acid ready"); - } else { - sb.append(String.format("%sAcid block mature in %s", ChatColor.YELLOW, TextUtil.formatDuration(remainingTime, TimeUnit.MILLISECONDS))); - } - } - if (e.getPlayer().hasPermission("citadel.admin")) { - sb.append(String.format("\n%sActivityMap.Activity = %s", - ChatColor.WHITE, - Citadel.getInstance().getActivityMap().getLastActivityTime(rein.getGroup(), rein.getLocation()))); - } - CitadelUtility.sendAndLog(player, ChatColor.GREEN, sb.toString().trim(), e.getClickedBlock().getLocation()); - } - if (showHolo) { - showHolo(rein, player); - } - } + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void handleInteractBlock(PlayerInteractEvent e) { + if (e.getAction() == Action.RIGHT_CLICK_BLOCK) { + if (interactFixer.checkInteracted(e.getPlayer(), e.getClickedBlock())) { + return; + } + } else if (e.getAction() != Action.LEFT_CLICK_BLOCK) { + return; + } + if (!settingMan.getInformationMode().getValue(e.getPlayer())) { + return; + } + Reinforcement rein = ReinforcementLogic.getReinforcementProtecting(e.getClickedBlock()); + Player player = e.getPlayer(); + boolean showChat = settingMan.shouldShowChatInCti(player.getUniqueId()); + if (rein == null) { + if (showChat) { + CitadelUtility.sendAndLog(e.getPlayer(), ChatColor.YELLOW, "Not reinforced", e.getClickedBlock().getLocation()); + } + return; + } + if (player.getGameMode() == GameMode.CREATIVE && e.getAction() == Action.LEFT_CLICK_BLOCK) { + e.setCancelled(true); + } + boolean showHolo = settingMan.shouldShowHologramInCti(player.getUniqueId()); + if (!rein.hasPermission(player, CitadelPermissionHandler.getInfo())) { + if (showChat) { + Citadel.getInstance().getSettingManager().sendCtiEnemyMessage(player, rein, e.getClickedBlock().getLocation()); + } + if (showHolo) { + showHolo(rein, player); + } + return; + } + if (showChat) { + StringBuilder sb = new StringBuilder(); + sb.append(String.format("Reinforced at %s%s health with %s%s %son %s%s ", formatHealth(rein), + ChatColor.GREEN, ChatColor.AQUA, rein.getType().getName(), ChatColor.GREEN, ChatColor.LIGHT_PURPLE, + rein.getGroup().getName())); + if (!rein.isMature()) { + sb.append(ChatColor.GOLD); + sb.append(formatProgress(rein.getCreationTime(), rein.getType().getMaturationTime(), "mature")); + sb.append(" "); + } + if (rein.isInsecure()) { + sb.append(ChatColor.AQUA); + sb.append("(Insecure) "); + } + if (ReinforcementLogic.getDecayDamage(rein) != 1) { + String ctiDecayAmountFormat = commaFormat.format(ReinforcementLogic.getDecayDamage(rein)); + sb.append(String.format("%s(Decayed x%s) ", ChatColor.LIGHT_PURPLE, ctiDecayAmountFormat)); + } + AcidManager acidMan = Citadel.getInstance().getAcidManager(); + if (acidMan.isPossibleAcidBlock(e.getClickedBlock())) { + sb.append(ChatColor.GOLD); + long remainingTime = acidMan.getRemainingAcidMaturationTime(rein); + if (remainingTime == 0) { + sb.append("Acid ready"); + } else { + sb.append(String.format("%sAcid block mature in %s", ChatColor.YELLOW, TextUtil.formatDuration(remainingTime, TimeUnit.MILLISECONDS))); + } + } + if (e.getPlayer().hasPermission("citadel.admin")) { + sb.append(String.format("\n%sActivityMap.Activity = %s", + ChatColor.WHITE, + Citadel.getInstance().getActivityMap().getLastActivityTime(rein.getGroup(), rein.getLocation()))); + } + CitadelUtility.sendAndLog(player, ChatColor.GREEN, sb.toString().trim(), e.getClickedBlock().getLocation()); + } + if (showHolo) { + showHolo(rein, player); + } + } - @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = false) - public void onBlockBreak(BlockBreakEvent event) { - // refresh hologram - Reinforcement rein = ReinforcementLogic.getReinforcementProtecting(event.getBlock()); - if (rein == null) { - return; - } - Player player = event.getPlayer(); - boolean showHolo = Citadel.getInstance().getSettingManager().shouldShowHologramInCti(player.getUniqueId()); - if (!showHolo) { - return; - } - showHolo(rein, player); - } + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = false) + public void onBlockBreak(BlockBreakEvent event) { + // refresh hologram + Reinforcement rein = ReinforcementLogic.getReinforcementProtecting(event.getBlock()); + if (rein == null) { + return; + } + Player player = event.getPlayer(); + boolean showHolo = Citadel.getInstance().getSettingManager().shouldShowHologramInCti(player.getUniqueId()); + if (!showHolo) { + return; + } + showHolo(rein, player); + } - private static void showHolo(Reinforcement rein, Player player) { - HologramManager holoManager = Citadel.getInstance().getHologramManager(); - if (holoManager != null) { - holoManager.showInfoHolo(rein, player); - } - } + private static void showHolo(Reinforcement rein, Player player) { + HologramManager holoManager = Citadel.getInstance().getHologramManager(); + if (holoManager != null) { + holoManager.showInfoHolo(rein, player); + } + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/listener/RedstoneListener.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/listener/RedstoneListener.java index c14958448..29e565892 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/listener/RedstoneListener.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/listener/RedstoneListener.java @@ -38,196 +38,196 @@ import vg.civcraft.mc.civmodcore.world.WorldUtils; public class RedstoneListener implements Listener { - private static boolean isAuthorizedPlayerNear(Reinforcement reinforcement, double distance) { - Location reinLocation = reinforcement.getLocation(); + private static boolean isAuthorizedPlayerNear(Reinforcement reinforcement, double distance) { + Location reinLocation = reinforcement.getLocation(); - if (reinLocation.getWorld() == null) { - return false; - } + if (reinLocation.getWorld() == null) { + return false; + } - // distance is radius, not diameter - double diameter = distance * 2; - Collection entities = reinLocation.getWorld().getNearbyEntities(reinLocation, diameter, diameter, - diameter, - e -> e instanceof Player && !e.isDead() - && reinforcement.hasPermission(e.getUniqueId(), CitadelPermissionHandler.getDoors()) - && e.getLocation().distanceSquared(reinLocation) <= diameter * diameter); - return !entities.isEmpty(); - } + // distance is radius, not diameter + double diameter = distance * 2; + Collection entities = reinLocation.getWorld().getNearbyEntities(reinLocation, diameter, diameter, + diameter, + e -> e instanceof Player && !e.isDead() + && reinforcement.hasPermission(e.getUniqueId(), CitadelPermissionHandler.getDoors()) + && e.getLocation().distanceSquared(reinLocation) <= diameter * diameter); + return !entities.isEmpty(); + } - private double maxRedstoneDistance; + private double maxRedstoneDistance; - private Map> authorizations; + private Map> authorizations; - public RedstoneListener(double maxRedstoneDistance) { - this.maxRedstoneDistance = maxRedstoneDistance; - this.authorizations = new HashMap<>(); - Bukkit.getScheduler().scheduleSyncRepeatingTask(Citadel.getInstance(), () -> authorizations.clear(), 1, 1); - } + public RedstoneListener(double maxRedstoneDistance) { + this.maxRedstoneDistance = maxRedstoneDistance; + this.authorizations = new HashMap<>(); + Bukkit.getScheduler().scheduleSyncRepeatingTask(Citadel.getInstance(), () -> authorizations.clear(), 1, 1); + } - @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) - public void pistonExtend(BlockPistonExtendEvent bpee) { - for (Block block : bpee.getBlocks()) { - Reinforcement reinforcement = ReinforcementLogic.getReinforcementProtecting(block); - if (reinforcement != null) { - bpee.setCancelled(true); - break; - } - } - } + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void pistonExtend(BlockPistonExtendEvent bpee) { + for (Block block : bpee.getBlocks()) { + Reinforcement reinforcement = ReinforcementLogic.getReinforcementProtecting(block); + if (reinforcement != null) { + bpee.setCancelled(true); + break; + } + } + } - @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) - public void pistonRetract(BlockPistonRetractEvent bpre) { - for (Block block : bpre.getBlocks()) { - Reinforcement reinforcement = ReinforcementLogic.getReinforcementProtecting(block); - if (reinforcement != null) { - bpre.setCancelled(true); - break; - } - } - } + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void pistonRetract(BlockPistonRetractEvent bpre) { + for (Block block : bpre.getBlocks()) { + Reinforcement reinforcement = ReinforcementLogic.getReinforcementProtecting(block); + if (reinforcement != null) { + bpre.setCancelled(true); + break; + } + } + } - @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) - public void pressButton(PlayerInteractEvent e) { - if (e.getAction() != Action.RIGHT_CLICK_BLOCK) { - return; - } - if (!(e.getClickedBlock().getBlockData() instanceof Switch)) { - return; - } - Switch button = (Switch) (e.getClickedBlock().getBlockData()); - Block buttonBlock = e.getClickedBlock(); - Block attachedBlock; - BlockFace skip = button.getFacing().getOppositeFace(); - // needs special handling because buttons attached to ceiling and ground can be - // turned in which case the facing direction indicates this direction - switch (button.getAttachedFace()) { - case CEILING: - attachedBlock = e.getClickedBlock().getRelative(BlockFace.UP); - skip = BlockFace.UP; - break; - case FLOOR: - attachedBlock = e.getClickedBlock().getRelative(BlockFace.DOWN); - skip = BlockFace.DOWN; - break; - case WALL: - attachedBlock = e.getClickedBlock().getRelative(button.getFacing().getOppositeFace()); - break; - default: - Citadel.getInstance().getLogger().warning("Could not handle button face " + button.getAttachedFace()); - return; - } - // prepare all sides of button itself - setupAdjacentDoors(e.getPlayer(), buttonBlock, skip); - // prepare all sides of the block attached to - setupAdjacentDoors(e.getPlayer(), attachedBlock, button.getFacing()); - } + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void pressButton(PlayerInteractEvent e) { + if (e.getAction() != Action.RIGHT_CLICK_BLOCK) { + return; + } + if (!(e.getClickedBlock().getBlockData() instanceof Switch)) { + return; + } + Switch button = (Switch) (e.getClickedBlock().getBlockData()); + Block buttonBlock = e.getClickedBlock(); + Block attachedBlock; + BlockFace skip = button.getFacing().getOppositeFace(); + // needs special handling because buttons attached to ceiling and ground can be + // turned in which case the facing direction indicates this direction + switch (button.getAttachedFace()) { + case CEILING: + attachedBlock = e.getClickedBlock().getRelative(BlockFace.UP); + skip = BlockFace.UP; + break; + case FLOOR: + attachedBlock = e.getClickedBlock().getRelative(BlockFace.DOWN); + skip = BlockFace.DOWN; + break; + case WALL: + attachedBlock = e.getClickedBlock().getRelative(button.getFacing().getOppositeFace()); + break; + default: + Citadel.getInstance().getLogger().warning("Could not handle button face " + button.getAttachedFace()); + return; + } + // prepare all sides of button itself + setupAdjacentDoors(e.getPlayer(), buttonBlock, skip); + // prepare all sides of the block attached to + setupAdjacentDoors(e.getPlayer(), attachedBlock, button.getFacing()); + } - @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) - public void redstonePower(BlockRedstoneEvent bre) { - // prevent doors from being opened by redstone - if (bre.getNewCurrent() <= 0 || bre.getOldCurrent() > 0) { - return; - } - Block block = bre.getBlock(); - BlockData blockData = block.getBlockData(); - if (!(blockData instanceof Openable)) { - return; - } - Openable openable = (Openable) blockData; - if (openable.isOpen()) { - return; - } - if (blockData instanceof Door) { - // we always store the activation for the lower half of a door - Door door = (Door) blockData; - if (door.getHalf() == Bisected.Half.TOP) { - block = block.getRelative(BlockFace.DOWN); - } - } - Reinforcement rein = ReinforcementLogic.getReinforcementProtecting(block); - if (rein == null) { - return; - } - if (rein.isInsecure()) { - boolean playerNearby = isAuthorizedPlayerNear(rein, maxRedstoneDistance); - if (!playerNearby) { - bre.setNewCurrent(bre.getOldCurrent()); - } - return; - } - List playersActivating = authorizations.get(block.getLocation()); - if (playersActivating == null) { - bre.setNewCurrent(bre.getOldCurrent()); - return; - } - for (UUID uuid : playersActivating) { - if (rein.hasPermission(uuid, CitadelPermissionHandler.getDoors())) { - // single valid perm is enough to open - return; - } - } - // noone valid found nearby, so deny - bre.setNewCurrent(bre.getOldCurrent()); - } + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void redstonePower(BlockRedstoneEvent bre) { + // prevent doors from being opened by redstone + if (bre.getNewCurrent() <= 0 || bre.getOldCurrent() > 0) { + return; + } + Block block = bre.getBlock(); + BlockData blockData = block.getBlockData(); + if (!(blockData instanceof Openable)) { + return; + } + Openable openable = (Openable) blockData; + if (openable.isOpen()) { + return; + } + if (blockData instanceof Door) { + // we always store the activation for the lower half of a door + Door door = (Door) blockData; + if (door.getHalf() == Bisected.Half.TOP) { + block = block.getRelative(BlockFace.DOWN); + } + } + Reinforcement rein = ReinforcementLogic.getReinforcementProtecting(block); + if (rein == null) { + return; + } + if (rein.isInsecure()) { + boolean playerNearby = isAuthorizedPlayerNear(rein, maxRedstoneDistance); + if (!playerNearby) { + bre.setNewCurrent(bre.getOldCurrent()); + } + return; + } + List playersActivating = authorizations.get(block.getLocation()); + if (playersActivating == null) { + bre.setNewCurrent(bre.getOldCurrent()); + return; + } + for (UUID uuid : playersActivating) { + if (rein.hasPermission(uuid, CitadelPermissionHandler.getDoors())) { + // single valid perm is enough to open + return; + } + } + // noone valid found nearby, so deny + bre.setNewCurrent(bre.getOldCurrent()); + } - private void setupAdjacentDoors(Player player, Block block, BlockFace skip) { - for (Entry entry : WorldUtils.getAllBlockSidesMapped(block, true).entrySet()) { - if (entry.getKey() == skip) { - continue; - } - Block rel = entry.getValue(); - BlockData blockData = rel.getBlockData(); - if (!(blockData instanceof Openable)) { - continue; - } - Location locationToSave; - if (blockData instanceof Door) { - Door door = (Door) blockData; - if (door.getHalf() == Bisected.Half.TOP) { - // block is upper half of a door - locationToSave = rel.getRelative(BlockFace.DOWN).getLocation(); - } else { - // already the lower half of the door - locationToSave = rel.getLocation(); - } - } else { - locationToSave = rel.getLocation(); - } - List existingAuths = authorizations.computeIfAbsent(locationToSave, k -> new LinkedList<>()); - existingAuths.add(player.getUniqueId()); - } - } + private void setupAdjacentDoors(Player player, Block block, BlockFace skip) { + for (Entry entry : WorldUtils.getAllBlockSidesMapped(block, true).entrySet()) { + if (entry.getKey() == skip) { + continue; + } + Block rel = entry.getValue(); + BlockData blockData = rel.getBlockData(); + if (!(blockData instanceof Openable)) { + continue; + } + Location locationToSave; + if (blockData instanceof Door) { + Door door = (Door) blockData; + if (door.getHalf() == Bisected.Half.TOP) { + // block is upper half of a door + locationToSave = rel.getRelative(BlockFace.DOWN).getLocation(); + } else { + // already the lower half of the door + locationToSave = rel.getLocation(); + } + } else { + locationToSave = rel.getLocation(); + } + List existingAuths = authorizations.computeIfAbsent(locationToSave, k -> new LinkedList<>()); + existingAuths.add(player.getUniqueId()); + } + } - @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) - public void playerStepPressurePlate(PlayerInteractEvent e) { - if (e.getAction() != Action.PHYSICAL) { - return; - } - Material mat = e.getClickedBlock().getType(); - if (!Tag.PRESSURE_PLATES.isTagged(mat)) { - return; - } - setupAdjacentDoors(e.getPlayer(), e.getClickedBlock(), BlockFace.EAST_SOUTH_EAST); - setupAdjacentDoors(e.getPlayer(), e.getClickedBlock().getRelative(BlockFace.DOWN), BlockFace.UP); - } + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void playerStepPressurePlate(PlayerInteractEvent e) { + if (e.getAction() != Action.PHYSICAL) { + return; + } + Material mat = e.getClickedBlock().getType(); + if (!Tag.PRESSURE_PLATES.isTagged(mat)) { + return; + } + setupAdjacentDoors(e.getPlayer(), e.getClickedBlock(), BlockFace.EAST_SOUTH_EAST); + setupAdjacentDoors(e.getPlayer(), e.getClickedBlock().getRelative(BlockFace.DOWN), BlockFace.UP); + } - @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) - public void entityStepPressurePlate(EntityInteractEvent e) { - if (!(e.getEntity() instanceof Vehicle)){ - return; - } - Material mat = e.getBlock().getType(); - if (!Tag.PRESSURE_PLATES.isTagged(mat)) { - return; - } - for (Entity p : e.getEntity().getPassengers()) { - if (p instanceof Player) { - setupAdjacentDoors((Player) p, e.getBlock(), BlockFace.EAST_SOUTH_EAST); - setupAdjacentDoors((Player) p, e.getBlock().getRelative(BlockFace.DOWN), BlockFace.UP); - } - } - } + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void entityStepPressurePlate(EntityInteractEvent e) { + if (!(e.getEntity() instanceof Vehicle)) { + return; + } + Material mat = e.getBlock().getType(); + if (!Tag.PRESSURE_PLATES.isTagged(mat)) { + return; + } + for (Entity p : e.getEntity().getPassengers()) { + if (p instanceof Player) { + setupAdjacentDoors((Player) p, e.getBlock(), BlockFace.EAST_SOUTH_EAST); + setupAdjacentDoors((Player) p, e.getBlock().getRelative(BlockFace.DOWN), BlockFace.UP); + } + } + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/listener/WorldBorderListener.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/listener/WorldBorderListener.java index b4e80cba4..d74b35b13 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/listener/WorldBorderListener.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/listener/WorldBorderListener.java @@ -14,23 +14,23 @@ import vg.civcraft.mc.citadel.model.WorldBorderBuffers; public class WorldBorderListener implements Listener { - private Map buffers; + private Map buffers; - public WorldBorderListener() { - this.buffers = Citadel.getInstance().getConfigManager().getWorldBorderBuffers(); - } + public WorldBorderListener() { + this.buffers = Citadel.getInstance().getConfigManager().getWorldBorderBuffers(); + } - @EventHandler - public void onReinCreation (ReinforcementCreationEvent event) { - World world = event.getReinforcement().getLocation().getWorld(); - if (!buffers.containsKey(world.getUID())) { - return; - } - WorldBorderBuffers buffer = buffers.get(world.getUID()); - Location reinforcementLocation = event.getReinforcement().getLocation(); - if (buffer.checkIfOutside(reinforcementLocation.getX(), reinforcementLocation.getZ())) { - event.getPlayer().sendMessage(Component.text("You cannot reinforce this close to the border!").color(NamedTextColor.RED)); - event.setCancelled(true); - } - } + @EventHandler + public void onReinCreation(ReinforcementCreationEvent event) { + World world = event.getReinforcement().getLocation().getWorld(); + if (!buffers.containsKey(world.getUID())) { + return; + } + WorldBorderBuffers buffer = buffers.get(world.getUID()); + Location reinforcementLocation = event.getReinforcement().getLocation(); + if (buffer.checkIfOutside(reinforcementLocation.getX(), reinforcementLocation.getZ())) { + event.getPlayer().sendMessage(Component.text("You cannot reinforce this close to the border!").color(NamedTextColor.RED)); + event.setCancelled(true); + } + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/model/AcidManager.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/model/AcidManager.java index 58efbffc1..9a07e31b7 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/model/AcidManager.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/model/AcidManager.java @@ -13,70 +13,70 @@ import vg.civcraft.mc.civmodcore.inventory.items.MaterialUtils; public class AcidManager { - private List acidTypes; + private List acidTypes; - public AcidManager(Collection acidTypes) { - this.acidTypes = new ArrayList<>(acidTypes); - } + public AcidManager(Collection acidTypes) { + this.acidTypes = new ArrayList<>(acidTypes); + } - /** - * Checks if acid blocking is enabled for this reinforcement type - * - * @param acidBlock acid Reinforcement type to check for - * @param victim victim block Reinforcement type - * @return True if the reinforcement type can acid block other reinforcements - * and has an acid timer configured - */ - public boolean canAcidBlock(ReinforcementType acidBlock, ReinforcementType victim) { - return acidBlock.getAcidPriority() >= victim.getAcidPriority(); - } + /** + * Checks if acid blocking is enabled for this reinforcement type + * + * @param acidBlock acid Reinforcement type to check for + * @param victim victim block Reinforcement type + * @return True if the reinforcement type can acid block other reinforcements + * and has an acid timer configured + */ + public boolean canAcidBlock(ReinforcementType acidBlock, ReinforcementType victim) { + return acidBlock.getAcidPriority() >= victim.getAcidPriority(); + } - /** - * Gets remaining time needed to mature acid block in milli seconds. If the acid - * is ready 0 will be returned - * - * @param rein Reinforcement to check for - * @return Remaining time in milli seconds or 0 if the acid is ready - */ - public long getRemainingAcidMaturationTime(Reinforcement rein) { - Block acidBlock = rein.getLocation().getBlock(); - Block targetBlock = acidBlock.getRelative(BlockFace.UP); + /** + * Gets remaining time needed to mature acid block in milli seconds. If the acid + * is ready 0 will be returned + * + * @param rein Reinforcement to check for + * @return Remaining time in milli seconds or 0 if the acid is ready + */ + public long getRemainingAcidMaturationTime(Reinforcement rein) { + Block acidBlock = rein.getLocation().getBlock(); + Block targetBlock = acidBlock.getRelative(BlockFace.UP); - double acidMultiplier = acidTypes.stream() - .filter(acidType -> acidType.material() == acidBlock.getType()) - .findFirst() - .map(AcidType::modifier) - .orElse(1D); + double acidMultiplier = acidTypes.stream() + .filter(acidType -> acidType.material() == acidBlock.getType()) + .findFirst() + .map(AcidType::modifier) + .orElse(1D); - double decayMultiplier = 1; - if (!MaterialUtils.isAir(targetBlock.getType())) { - Reinforcement targetBlockRein = ReinforcementLogic.getReinforcementAt(targetBlock.getLocation()); - if (targetBlockRein != null) { - decayMultiplier = ReinforcementLogic.getDecayDamage(targetBlockRein); - } - } - long totalTime = Math.round(rein.getType().getAcidTime() / decayMultiplier * acidMultiplier); - return Math.max(0, totalTime - rein.getAge()); - } + double decayMultiplier = 1; + if (!MaterialUtils.isAir(targetBlock.getType())) { + Reinforcement targetBlockRein = ReinforcementLogic.getReinforcementAt(targetBlock.getLocation()); + if (targetBlockRein != null) { + decayMultiplier = ReinforcementLogic.getDecayDamage(targetBlockRein); + } + } + long totalTime = Math.round(rein.getType().getAcidTime() / decayMultiplier * acidMultiplier); + return Math.max(0, totalTime - rein.getAge()); + } - /** - * Checks if the given valid is of a material registered as valid acid material - * - * @param b Block to check for - * @return True if the block material is suited for being an acid block - */ - public boolean isPossibleAcidBlock(Block b) { - if (b == null) { - return false; - } - return acidTypes.stream() - .anyMatch(acidType -> acidType.material() == b.getType()); - } + /** + * Checks if the given valid is of a material registered as valid acid material + * + * @param b Block to check for + * @return True if the block material is suited for being an acid block + */ + public boolean isPossibleAcidBlock(Block b) { + if (b == null) { + return false; + } + return acidTypes.stream() + .anyMatch(acidType -> acidType.material() == b.getType()); + } - public AcidType getAcidTypeFromMaterial(Material material) { - return acidTypes.stream() - .filter(acidType -> acidType.material() == material) - .findFirst() - .orElseThrow(); - } + public AcidType getAcidTypeFromMaterial(Material material) { + return acidTypes.stream() + .filter(acidType -> acidType.material() == material) + .findFirst() + .orElseThrow(); + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/model/ActivityDB.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/model/ActivityDB.java index 181cbc9ae..e28f1cd40 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/model/ActivityDB.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/model/ActivityDB.java @@ -12,95 +12,96 @@ import java.util.List; import java.util.function.Consumer; public class ActivityDB { - private static final String CREATE_TABLE = "CREATE TABLE IF NOT EXISTS ctdl_activity_map (" - + "group_id INT, " - + "world SMALLINT, " - + "x INT, " - + "z INT, " - + "resolution SMALLINT UNSIGNED, " - + "activity TIMESTAMP, " - + "PRIMARY KEY(group_id, world, x, z, resolution))"; - private static final String EXISTS_INDEX = "SELECT * FROM information_schema.statistics WHERE table_name = 'ctdl_activity_map' AND table_schema = database() AND index_name = 'PRIMARY' AND seq_in_index = 1 AND column_name = 'resolution' LIMIT 0, 1"; - private static final String CREATE_INDEX = "ALTER TABLE ctdl_activity_map DROP PRIMARY KEY, ADD PRIMARY KEY (resolution, world, x, z, group_id)"; - private static final String GET_REGION_ACTIVITIES = "SELECT group_id, activity FROM ctdl_activity_map WHERE world = ? AND x = ? AND z = ? AND resolution = ?"; - private static final String UPDATE_ACTIVITY = "INSERT INTO ctdl_activity_map (group_id, world, x, z, resolution, activity) VALUES (?, ?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE activity = ?"; + private static final String CREATE_TABLE = "CREATE TABLE IF NOT EXISTS ctdl_activity_map (" + + "group_id INT, " + + "world SMALLINT, " + + "x INT, " + + "z INT, " + + "resolution SMALLINT UNSIGNED, " + + "activity TIMESTAMP, " + + "PRIMARY KEY(group_id, world, x, z, resolution))"; - private final ManagedDatasource datasource; + private static final String EXISTS_INDEX = "SELECT * FROM information_schema.statistics WHERE table_name = 'ctdl_activity_map' AND table_schema = database() AND index_name = 'PRIMARY' AND seq_in_index = 1 AND column_name = 'resolution' LIMIT 0, 1"; + private static final String CREATE_INDEX = "ALTER TABLE ctdl_activity_map DROP PRIMARY KEY, ADD PRIMARY KEY (resolution, world, x, z, group_id)"; + private static final String GET_REGION_ACTIVITIES = "SELECT group_id, activity FROM ctdl_activity_map WHERE world = ? AND x = ? AND z = ? AND resolution = ?"; + private static final String UPDATE_ACTIVITY = "INSERT INTO ctdl_activity_map (group_id, world, x, z, resolution, activity) VALUES (?, ?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE activity = ?"; - public ActivityDB(ManagedDatasource datasource) { - this.datasource = datasource; - } + private final ManagedDatasource datasource; - public boolean enable() { - try (Connection connection = datasource.getConnection()) { - connection.createStatement().executeUpdate(CREATE_TABLE); + public ActivityDB(ManagedDatasource datasource) { + this.datasource = datasource; + } - boolean indexExists = false; + public boolean enable() { + try (Connection connection = datasource.getConnection()) { + connection.createStatement().executeUpdate(CREATE_TABLE); - try (PreparedStatement statement = connection.prepareStatement(EXISTS_INDEX)) { - try (ResultSet resultSet = statement.executeQuery()) { - while (resultSet.next()) { - indexExists = true; - } - } - } + boolean indexExists = false; - if (!indexExists) { - connection.createStatement().executeUpdate(CREATE_INDEX); - } - } catch (SQLException ex) { - ex.printStackTrace(); - return false; - } + try (PreparedStatement statement = connection.prepareStatement(EXISTS_INDEX)) { + try (ResultSet resultSet = statement.executeQuery()) { + while (resultSet.next()) { + indexExists = true; + } + } + } - return true; - } + if (!indexExists) { + connection.createStatement().executeUpdate(CREATE_INDEX); + } + } catch (SQLException ex) { + ex.printStackTrace(); + return false; + } - public void update(List activities) { - try (Connection connection = datasource.getConnection()) { - try (PreparedStatement statement = connection.prepareStatement(UPDATE_ACTIVITY)) { - for (ActivityItem activityItem : activities) { - statement.setInt(1, activityItem.group()); - statement.setShort(2, activityItem.world()); - statement.setInt(3, activityItem.x()); - statement.setInt(4, activityItem.z()); - statement.setInt(5, activityItem.resolution()); - statement.setTimestamp(6, Timestamp.from(activityItem.activity())); - statement.setTimestamp(7, Timestamp.from(activityItem.activity())); - statement.addBatch(); - } + return true; + } - statement.executeBatch(); - } - } catch (SQLException ex) { - ex.printStackTrace(); - } - } + public void update(List activities) { + try (Connection connection = datasource.getConnection()) { + try (PreparedStatement statement = connection.prepareStatement(UPDATE_ACTIVITY)) { + for (ActivityItem activityItem : activities) { + statement.setInt(1, activityItem.group()); + statement.setShort(2, activityItem.world()); + statement.setInt(3, activityItem.x()); + statement.setInt(4, activityItem.z()); + statement.setInt(5, activityItem.resolution()); + statement.setTimestamp(6, Timestamp.from(activityItem.activity())); + statement.setTimestamp(7, Timestamp.from(activityItem.activity())); + statement.addBatch(); + } - public void select(short worldId, int x, int z, int resolution, Consumer process) { - try (Connection connection = datasource.getConnection()) { - connection.setAutoCommit(false); - try (PreparedStatement statement = connection.prepareStatement(GET_REGION_ACTIVITIES, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY)) { - statement.setFetchSize(Integer.MIN_VALUE); - statement.setShort(1, worldId); - statement.setInt(2, x); - statement.setInt(3, z); - statement.setInt(4, resolution); + statement.executeBatch(); + } + } catch (SQLException ex) { + ex.printStackTrace(); + } + } - try (ResultSet resultSet = statement.executeQuery()) { - while (resultSet.next()) { - int groupId = resultSet.getShort("group_id"); - Instant activity = resultSet.getTimestamp("activity").toInstant(); + public void select(short worldId, int x, int z, int resolution, Consumer process) { + try (Connection connection = datasource.getConnection()) { + connection.setAutoCommit(false); + try (PreparedStatement statement = connection.prepareStatement(GET_REGION_ACTIVITIES, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY)) { + statement.setFetchSize(Integer.MIN_VALUE); + statement.setShort(1, worldId); + statement.setInt(2, x); + statement.setInt(3, z); + statement.setInt(4, resolution); - var activityItem = new ActivityItem(worldId, groupId, x, z, activity, resolution); + try (ResultSet resultSet = statement.executeQuery()) { + while (resultSet.next()) { + int groupId = resultSet.getShort("group_id"); + Instant activity = resultSet.getTimestamp("activity").toInstant(); - process.accept(activityItem); - } - } - } - } catch (SQLException ex) { - ex.printStackTrace(); - } - } + var activityItem = new ActivityItem(worldId, groupId, x, z, activity, resolution); + + process.accept(activityItem); + } + } + } + } catch (SQLException ex) { + ex.printStackTrace(); + } + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/model/ActivityItem.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/model/ActivityItem.java index 95c99981b..fcde66ce9 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/model/ActivityItem.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/model/ActivityItem.java @@ -2,12 +2,12 @@ package vg.civcraft.mc.citadel.model; import java.time.Instant; -public record ActivityItem ( - short world, - int group, - int x, - int z, - Instant activity, - int resolution) -{ +public record ActivityItem( + short world, + int group, + int x, + int z, + Instant activity, + int resolution) { + } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/model/CitadelChunkData.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/model/CitadelChunkData.java index 8e871cc0e..bb8924687 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/model/CitadelChunkData.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/model/CitadelChunkData.java @@ -5,8 +5,8 @@ import vg.civcraft.mc.civmodcore.world.locations.chunkmeta.block.table.TableBase public class CitadelChunkData extends TableBasedBlockChunkMeta { - public CitadelChunkData(boolean isNew, CitadelDAO storage) { - super(isNew, storage); - } + public CitadelChunkData(boolean isNew, CitadelDAO storage) { + super(isNew, storage); + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/model/CitadelDAO.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/model/CitadelDAO.java index 676e96564..6e3f77c30 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/model/CitadelDAO.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/model/CitadelDAO.java @@ -31,401 +31,402 @@ import vg.civcraft.mc.civmodcore.world.locations.global.WorldIDManager; public class CitadelDAO extends TableStorageEngine { - private boolean batchMode; - private List> batches; + private boolean batchMode; + private List> batches; - public CitadelDAO(Logger logger, ManagedDatasource db) { - super(logger, db); - this.batchMode = false; - } + public CitadelDAO(Logger logger, ManagedDatasource db) { + super(logger, db); + this.batchMode = false; + } - public void setBatchMode(boolean batch) { - this.batchMode = batch; - batches = new ArrayList<>(); - for (int i = 0; i < 3; i++) { - batches.add(new ArrayList<>()); - } - } + public void setBatchMode(boolean batch) { + this.batchMode = batch; + batches = new ArrayList<>(); + for (int i = 0; i < 3; i++) { + batches.add(new ArrayList<>()); + } + } - public void cleanupBatches() { - long currentTime = System.currentTimeMillis(); - try (Connection conn = db.getConnection(); - PreparedStatement deleteRein = conn.prepareStatement( - "delete from ctdl_reinforcements where chunk_x = ? and chunk_z = ? and world_id = ? and " - + "x_offset = ? and y = ? and z_offset = ?;");) { - conn.setAutoCommit(false); - for (ReinforcementTuple rein : batches.get(2)) { - setDeleteDataStatement(deleteRein, rein.rein, rein.coord); - deleteRein.addBatch(); - } - logger.info("Batch 2: " + (System.currentTimeMillis() - currentTime) + " ms"); - logger.info("Batch 2 Size: " + batches.get(2).size()); - batches.get(2).clear(); - deleteRein.executeBatch(); - conn.setAutoCommit(true); - logger.info("Batch 2 Finish: " + (System.currentTimeMillis() - currentTime) + " ms"); - } catch (SQLException e) { - logger.log(Level.SEVERE, "Failed to delete reinforcement from db: ", e); - } - try (Connection conn = db.getConnection(); - PreparedStatement insertRein = conn.prepareStatement( - "insert into ctdl_reinforcements (chunk_x, chunk_z, world_id, x_offset, y, z_offset, type_id, " - + "health, group_id, insecure, creation_time) values(?,?,?, ?,?,?, ?,?,?,?,?);");) { - conn.setAutoCommit(false); - for (ReinforcementTuple rein : batches.get(0)) { - setInsertDataStatement(insertRein, rein.rein, rein.coord); - insertRein.addBatch(); - } - logger.info("Batch 0: " + (System.currentTimeMillis() - currentTime) + " ms"); - logger.info("Batch 0 Size: " + batches.get(0).size()); - batches.get(0).clear(); - insertRein.executeBatch(); - conn.setAutoCommit(true); - logger.info("Batch 0 Finish: " + (System.currentTimeMillis() - currentTime) + " ms"); - } catch (SQLException e) { - logger.log(Level.SEVERE, "Failed to insert reinforcement into db: ", e); - } - try (Connection conn = db.getConnection(); - PreparedStatement updateRein = conn.prepareStatement("update ctdl_reinforcements set type_id = ?, health = ?, group_id = ?, insecure = ?, creation_time = ? where " - + "chunk_x = ? and chunk_z = ? and world_id = ? and x_offset = ? and y = ? and z_offset = ?;");) { - conn.setAutoCommit(false); - for (ReinforcementTuple rein : batches.get(1)) { - setUpdateDataStatement(updateRein, rein.rein, rein.coord); - updateRein.addBatch(); - } - logger.info("Batch 1: " + (System.currentTimeMillis() - currentTime) + " ms"); - logger.info("Batch 1 Size: " + batches.get(1).size()); - batches.get(1).clear(); - updateRein.executeBatch(); - conn.setAutoCommit(true); - logger.info("Batch 1 Finish: " + (System.currentTimeMillis() - currentTime) + " ms"); - } catch (SQLException e) { - logger.log(Level.SEVERE, "Failed to update reinforcement in db: ", e); - } - } + public void cleanupBatches() { + long currentTime = System.currentTimeMillis(); + try (Connection conn = db.getConnection(); + PreparedStatement deleteRein = conn.prepareStatement( + "delete from ctdl_reinforcements where chunk_x = ? and chunk_z = ? and world_id = ? and " + + "x_offset = ? and y = ? and z_offset = ?;");) { + conn.setAutoCommit(false); + for (ReinforcementTuple rein : batches.get(2)) { + setDeleteDataStatement(deleteRein, rein.rein, rein.coord); + deleteRein.addBatch(); + } + logger.info("Batch 2: " + (System.currentTimeMillis() - currentTime) + " ms"); + logger.info("Batch 2 Size: " + batches.get(2).size()); + batches.get(2).clear(); + deleteRein.executeBatch(); + conn.setAutoCommit(true); + logger.info("Batch 2 Finish: " + (System.currentTimeMillis() - currentTime) + " ms"); + } catch (SQLException e) { + logger.log(Level.SEVERE, "Failed to delete reinforcement from db: ", e); + } + try (Connection conn = db.getConnection(); + PreparedStatement insertRein = conn.prepareStatement( + "insert into ctdl_reinforcements (chunk_x, chunk_z, world_id, x_offset, y, z_offset, type_id, " + + "health, group_id, insecure, creation_time) values(?,?,?, ?,?,?, ?,?,?,?,?);");) { + conn.setAutoCommit(false); + for (ReinforcementTuple rein : batches.get(0)) { + setInsertDataStatement(insertRein, rein.rein, rein.coord); + insertRein.addBatch(); + } + logger.info("Batch 0: " + (System.currentTimeMillis() - currentTime) + " ms"); + logger.info("Batch 0 Size: " + batches.get(0).size()); + batches.get(0).clear(); + insertRein.executeBatch(); + conn.setAutoCommit(true); + logger.info("Batch 0 Finish: " + (System.currentTimeMillis() - currentTime) + " ms"); + } catch (SQLException e) { + logger.log(Level.SEVERE, "Failed to insert reinforcement into db: ", e); + } + try (Connection conn = db.getConnection(); + PreparedStatement updateRein = conn.prepareStatement("update ctdl_reinforcements set type_id = ?, health = ?, group_id = ?, insecure = ?, creation_time = ? where " + + "chunk_x = ? and chunk_z = ? and world_id = ? and x_offset = ? and y = ? and z_offset = ?;");) { + conn.setAutoCommit(false); + for (ReinforcementTuple rein : batches.get(1)) { + setUpdateDataStatement(updateRein, rein.rein, rein.coord); + updateRein.addBatch(); + } + logger.info("Batch 1: " + (System.currentTimeMillis() - currentTime) + " ms"); + logger.info("Batch 1 Size: " + batches.get(1).size()); + batches.get(1).clear(); + updateRein.executeBatch(); + conn.setAutoCommit(true); + logger.info("Batch 1 Finish: " + (System.currentTimeMillis() - currentTime) + " ms"); + } catch (SQLException e) { + logger.log(Level.SEVERE, "Failed to update reinforcement in db: ", e); + } + } - @Override - public void registerMigrations() { - db.registerMigration(15, false, - "CREATE TABLE IF NOT EXISTS reinforcement (rein_id int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY," - + "x int(11) NOT NULL, y int(11) NOT NULL, z int(11) NOT NULL, chunk_x int(11) NOT NULL, chunk_z int(11) NOT NULL," - + "world varchar(255) NOT NULL, material_id int(11) NOT NULL, durability varchar(10) NOT NULL, insecure tinyint(1) NOT NULL," - + "group_id int(11) NOT NULL, maturation_time int(11) NOT NULL, rein_type_id int(11) NOT NULL, lore varchar(255) DEFAULT NULL," - + "acid_time int(11) NOT NULL)"); - db.registerMigration(16, false, new Callable() { + @Override + public void registerMigrations() { + db.registerMigration(15, false, + "CREATE TABLE IF NOT EXISTS reinforcement (rein_id int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY," + + "x int(11) NOT NULL, y int(11) NOT NULL, z int(11) NOT NULL, chunk_x int(11) NOT NULL, chunk_z int(11) NOT NULL," + + "world varchar(255) NOT NULL, material_id int(11) NOT NULL, durability varchar(10) NOT NULL, insecure tinyint(1) NOT NULL," + + "group_id int(11) NOT NULL, maturation_time int(11) NOT NULL, rein_type_id int(11) NOT NULL, lore varchar(255) DEFAULT NULL," + + "acid_time int(11) NOT NULL)"); + db.registerMigration(16, false, new Callable() { - @Override - public Boolean call() throws Exception { - try (Connection insertConn = db.getConnection(); - PreparedStatement selectRein = insertConn.prepareStatement( - "select x,y,z,chunk_x,chunk_z,world,material_id,durability,insecure,group_id,maturation_time,lore from reinforcement order by rein_id asc"); - ResultSet rs = selectRein.executeQuery()) { - PreparedStatement insertRein = insertConn.prepareStatement( - "insert into ctdl_reinforcements (chunk_x, chunk_z, world_id, x_offset, y, z_offset, type_id, " - + "health, group_id, insecure, creation_time) values(?,?,?, ?,?,?, ?,?,?,?,?);"); - try (PreparedStatement deleteExisting = insertConn - .prepareStatement("delete from ctdl_reinforcements")) { - // in case this migration failed before some of the data might already have - // migrated, which we want to undo - deleteExisting.execute(); - } + @Override + public Boolean call() throws Exception { + try (Connection insertConn = db.getConnection(); + PreparedStatement selectRein = insertConn.prepareStatement( + "select x,y,z,chunk_x,chunk_z,world,material_id,durability,insecure,group_id,maturation_time,lore from reinforcement order by rein_id asc"); + ResultSet rs = selectRein.executeQuery()) { + PreparedStatement insertRein = insertConn.prepareStatement( + "insert into ctdl_reinforcements (chunk_x, chunk_z, world_id, x_offset, y, z_offset, type_id, " + + "health, group_id, insecure, creation_time) values(?,?,?, ?,?,?, ?,?,?,?,?);"); + try (PreparedStatement deleteExisting = insertConn + .prepareStatement("delete from ctdl_reinforcements")) { + // in case this migration failed before some of the data might already have + // migrated, which we want to undo + deleteExisting.execute(); + } - WorldIDManager worldMan = CivModCorePlugin.getInstance().getWorldIdManager(); - Map> reinTypes = new TreeMap<>(); - for (ReinforcementType type : Citadel.getInstance().getReinforcementTypeManager().getAllTypes()) { - List withType = reinTypes.computeIfAbsent(type.getLegacyId(), - s -> new ArrayList<>()); - withType.add(type); - } - int batchCounter = 0; - while (rs.next()) { - byte x = (byte) BlockBasedChunkMeta.modulo(rs.getInt(1)); - short y = (short) rs.getInt(2); - byte z = (byte) BlockBasedChunkMeta.modulo(rs.getInt(3)); - int chunkX = rs.getInt(4); - int chunkZ = rs.getInt(5); - String worldName = rs.getString(6); - int materialId = rs.getInt(7); - String durability = rs.getString(8); - boolean insecure = rs.getBoolean(9); - int groupId = rs.getInt(10); - int maturationTime = rs.getInt(11); - String lore = rs.getString(12); + WorldIDManager worldMan = CivModCorePlugin.getInstance().getWorldIdManager(); + Map> reinTypes = new TreeMap<>(); + for (ReinforcementType type : Citadel.getInstance().getReinforcementTypeManager().getAllTypes()) { + List withType = reinTypes.computeIfAbsent(type.getLegacyId(), + s -> new ArrayList<>()); + withType.add(type); + } + int batchCounter = 0; + while (rs.next()) { + byte x = (byte) BlockBasedChunkMeta.modulo(rs.getInt(1)); + short y = (short) rs.getInt(2); + byte z = (byte) BlockBasedChunkMeta.modulo(rs.getInt(3)); + int chunkX = rs.getInt(4); + int chunkZ = rs.getInt(5); + String worldName = rs.getString(6); + int materialId = rs.getInt(7); + String durability = rs.getString(8); + boolean insecure = rs.getBoolean(9); + int groupId = rs.getInt(10); + int maturationTime = rs.getInt(11); + String lore = rs.getString(12); - short worldID = worldMan.getInternalWorldId(Bukkit.getWorld(worldName)); - if (worldID == -1) { - logger.severe("Failed to find world id for world with name " + worldName); - return false; - } - float healthFloat = Float.parseFloat(durability); - List withType = reinTypes.get(materialId); - if (withType == null) { - logger.severe( - "Failed to find material mapping for reinforcement with material id " + materialId); - return false; - } - ReinforcementType type = null; - if (withType.size() == 1) { - type = withType.get(0); - } else { - boolean hasLore = lore != null; - for (ReinforcementType compType : withType) { - ItemMeta meta = compType.getItem().getItemMeta(); - if (hasLore == meta.hasLore()) { - if (!hasLore || meta.getLore().get(0).equals(lore)) { - type = compType; - break; - } - } - } - if (type == null) { - logger.severe("Failed to find material mapping for reinforcement with material id " - + materialId + " and lore " + lore); - return false; - } - } - // previously we stored the timestamp at which the reinforcement will be mature - // in minutes since unix epoch - // No, I do not know why - long creationTime = maturationTime - (type.getMaturationTime() / 60_000); - // some rows have a maturation time of 0, no idea why - creationTime = Math.max(creationTime, 1); - creationTime *= 60_000; + short worldID = worldMan.getInternalWorldId(Bukkit.getWorld(worldName)); + if (worldID == -1) { + logger.severe("Failed to find world id for world with name " + worldName); + return false; + } + float healthFloat = Float.parseFloat(durability); + List withType = reinTypes.get(materialId); + if (withType == null) { + logger.severe( + "Failed to find material mapping for reinforcement with material id " + materialId); + return false; + } + ReinforcementType type = null; + if (withType.size() == 1) { + type = withType.get(0); + } else { + boolean hasLore = lore != null; + for (ReinforcementType compType : withType) { + ItemMeta meta = compType.getItem().getItemMeta(); + if (hasLore == meta.hasLore()) { + if (!hasLore || meta.getLore().get(0).equals(lore)) { + type = compType; + break; + } + } + } + if (type == null) { + logger.severe("Failed to find material mapping for reinforcement with material id " + + materialId + " and lore " + lore); + return false; + } + } + // previously we stored the timestamp at which the reinforcement will be mature + // in minutes since unix epoch + // No, I do not know why + long creationTime = maturationTime - (type.getMaturationTime() / 60_000); + // some rows have a maturation time of 0, no idea why + creationTime = Math.max(creationTime, 1); + creationTime *= 60_000; - insertRein.setInt(1, chunkX); - insertRein.setInt(2, chunkZ); - insertRein.setShort(3, worldID); - insertRein.setByte(4, x); - insertRein.setShort(5, y); - insertRein.setByte(6, z); - insertRein.setShort(7, type.getID()); - insertRein.setFloat(8, healthFloat); - insertRein.setInt(9, groupId); - insertRein.setBoolean(10, insecure); - insertRein.setTimestamp(11, new Timestamp(creationTime)); - insertRein.addBatch(); - if (batchCounter > 10000) { - batchCounter = 0; - insertRein.executeBatch(); - } - batchCounter++; - } - insertRein.executeBatch(); - } - return true; - } - }, "create table if not exists ctdl_reinforcements (chunk_x int not null, chunk_z int not null, world_id smallint unsigned not null, " - + "x_offset tinyint unsigned not null, y smallint not null, z_offset tinyint unsigned not null, " - + "type_id smallint unsigned not null, health float not null, group_id int not null, insecure boolean not null default false," - + "creation_time timestamp not null default now(), index reinChunkLookUp(chunk_x, chunk_z, world_id), primary key " - + "(chunk_x, chunk_z, world_id, x_offset, y ,z_offset))"); - } + insertRein.setInt(1, chunkX); + insertRein.setInt(2, chunkZ); + insertRein.setShort(3, worldID); + insertRein.setByte(4, x); + insertRein.setShort(5, y); + insertRein.setByte(6, z); + insertRein.setShort(7, type.getID()); + insertRein.setFloat(8, healthFloat); + insertRein.setInt(9, groupId); + insertRein.setBoolean(10, insecure); + insertRein.setTimestamp(11, new Timestamp(creationTime)); + insertRein.addBatch(); + if (batchCounter > 10000) { + batchCounter = 0; + insertRein.executeBatch(); + } + batchCounter++; + } + insertRein.executeBatch(); + } + return true; + } + }, "create table if not exists ctdl_reinforcements (chunk_x int not null, chunk_z int not null, world_id smallint unsigned not null, " + + "x_offset tinyint unsigned not null, y smallint not null, z_offset tinyint unsigned not null, " + + "type_id smallint unsigned not null, health float not null, group_id int not null, insecure boolean not null default false," + + "creation_time timestamp not null default now(), index reinChunkLookUp(chunk_x, chunk_z, world_id), primary key " + + "(chunk_x, chunk_z, world_id, x_offset, y ,z_offset))"); + } - /** - * Gets a single reinforcement at the given location without inserting it into - * the tracking - * - * @return Reinforcement loaded from the database - */ - @Override - public Reinforcement getForLocation(int x, int y, int z, short worldID, short pluginID) { - int chunkX = BlockBasedChunkMeta.toChunkCoord(x); - int chunkZ = BlockBasedChunkMeta.toChunkCoord(z); - ReinforcementTypeManager typeMan = Citadel.getInstance().getReinforcementTypeManager(); - try (Connection insertConn = db.getConnection(); - PreparedStatement selectRein = insertConn - .prepareStatement("select type_id, group_id, creation_time, health, insecure " - + "from ctdl_reinforcements where chunk_x = ? and chunk_z = ? and world_id = ? and x_offset = ? and y = ? and z_offset = ?;");) { - selectRein.setInt(1, chunkX); - selectRein.setInt(2, chunkZ); - selectRein.setShort(3, worldID); - selectRein.setByte(4, (byte) BlockBasedChunkMeta.modulo(x)); - selectRein.setShort(5, (short) y); - selectRein.setByte(6, (byte) BlockBasedChunkMeta.modulo(z)); - try (ResultSet rs = selectRein.executeQuery()) { - if (!rs.next()) { - return null; - } - short typeID = rs.getShort(1); - ReinforcementType type = typeMan.getById(typeID); - if (type == null) { - logger.log(Level.SEVERE, "Failed to load reinforcement with type id " + typeID); - return null; - } - int groupID = rs.getInt(2); - long creationTime = rs.getTimestamp(3).getTime(); - float health = rs.getFloat(4); - boolean insecure = rs.getBoolean(5); - World world = CivModCorePlugin.getInstance().getWorldIdManager().getWorldByInternalID(worldID); - Location loc = new Location(world, x, y, z); - return new Reinforcement(loc, type, groupID, creationTime, health, insecure, false); - } - } catch (SQLException e) { - logger.log(Level.SEVERE, "Failed to load reinforcement from db: ", e); - return null; - } - } + /** + * Gets a single reinforcement at the given location without inserting it into + * the tracking + * + * @return Reinforcement loaded from the database + */ + @Override + public Reinforcement getForLocation(int x, int y, int z, short worldID, short pluginID) { + int chunkX = BlockBasedChunkMeta.toChunkCoord(x); + int chunkZ = BlockBasedChunkMeta.toChunkCoord(z); + ReinforcementTypeManager typeMan = Citadel.getInstance().getReinforcementTypeManager(); + try (Connection insertConn = db.getConnection(); + PreparedStatement selectRein = insertConn + .prepareStatement("select type_id, group_id, creation_time, health, insecure " + + "from ctdl_reinforcements where chunk_x = ? and chunk_z = ? and world_id = ? and x_offset = ? and y = ? and z_offset = ?;");) { + selectRein.setInt(1, chunkX); + selectRein.setInt(2, chunkZ); + selectRein.setShort(3, worldID); + selectRein.setByte(4, (byte) BlockBasedChunkMeta.modulo(x)); + selectRein.setShort(5, (short) y); + selectRein.setByte(6, (byte) BlockBasedChunkMeta.modulo(z)); + try (ResultSet rs = selectRein.executeQuery()) { + if (!rs.next()) { + return null; + } + short typeID = rs.getShort(1); + ReinforcementType type = typeMan.getById(typeID); + if (type == null) { + logger.log(Level.SEVERE, "Failed to load reinforcement with type id " + typeID); + return null; + } + int groupID = rs.getInt(2); + long creationTime = rs.getTimestamp(3).getTime(); + float health = rs.getFloat(4); + boolean insecure = rs.getBoolean(5); + World world = CivModCorePlugin.getInstance().getWorldIdManager().getWorldByInternalID(worldID); + Location loc = new Location(world, x, y, z); + return new Reinforcement(loc, type, groupID, creationTime, health, insecure, false); + } + } catch (SQLException e) { + logger.log(Level.SEVERE, "Failed to load reinforcement from db: ", e); + return null; + } + } - @Override - public void insert(Reinforcement data, XZWCoord coord) { - if (batchMode) { - batches.get(0).add(new ReinforcementTuple(data, coord)); - return; - } - try (Connection insertConn = db.getConnection(); - PreparedStatement insertRein = insertConn.prepareStatement( - "insert into ctdl_reinforcements (chunk_x, chunk_z, world_id, x_offset, y, z_offset, type_id, " - + "health, group_id, insecure, creation_time) values(?,?,?, ?,?,?, ?,?,?,?,?);");) { - setInsertDataStatement(insertRein, data, coord); - insertRein.execute(); - } catch (SQLException e) { - logger.log(Level.SEVERE, "Failed to insert reinforcement into db: ", e); - } - } + @Override + public void insert(Reinforcement data, XZWCoord coord) { + if (batchMode) { + batches.get(0).add(new ReinforcementTuple(data, coord)); + return; + } + try (Connection insertConn = db.getConnection(); + PreparedStatement insertRein = insertConn.prepareStatement( + "insert into ctdl_reinforcements (chunk_x, chunk_z, world_id, x_offset, y, z_offset, type_id, " + + "health, group_id, insecure, creation_time) values(?,?,?, ?,?,?, ?,?,?,?,?);");) { + setInsertDataStatement(insertRein, data, coord); + insertRein.execute(); + } catch (SQLException e) { + logger.log(Level.SEVERE, "Failed to insert reinforcement into db: ", e); + } + } - private static void setInsertDataStatement(PreparedStatement insertRein, Reinforcement data, XZWCoord coord) throws SQLException { - insertRein.setInt(1, coord.getX()); - insertRein.setInt(2, coord.getZ()); - insertRein.setShort(3, coord.getWorldID()); - insertRein.setByte(4, (byte) BlockBasedChunkMeta.modulo(data.getLocation().getBlockX())); - insertRein.setShort(5, (short) data.getLocation().getBlockY()); - insertRein.setByte(6, (byte) BlockBasedChunkMeta.modulo(data.getLocation().getBlockZ())); - insertRein.setShort(7, data.getType().getID()); - insertRein.setFloat(8, data.getHealth()); - insertRein.setInt(9, data.getGroupId()); - insertRein.setBoolean(10, data.isInsecure()); - insertRein.setTimestamp(11, new Timestamp(data.getCreationTime())); - } + private static void setInsertDataStatement(PreparedStatement insertRein, Reinforcement data, XZWCoord coord) throws SQLException { + insertRein.setInt(1, coord.getX()); + insertRein.setInt(2, coord.getZ()); + insertRein.setShort(3, coord.getWorldID()); + insertRein.setByte(4, (byte) BlockBasedChunkMeta.modulo(data.getLocation().getBlockX())); + insertRein.setShort(5, (short) data.getLocation().getBlockY()); + insertRein.setByte(6, (byte) BlockBasedChunkMeta.modulo(data.getLocation().getBlockZ())); + insertRein.setShort(7, data.getType().getID()); + insertRein.setFloat(8, data.getHealth()); + insertRein.setInt(9, data.getGroupId()); + insertRein.setBoolean(10, data.isInsecure()); + insertRein.setTimestamp(11, new Timestamp(data.getCreationTime())); + } - @Override - public void update(Reinforcement data, XZWCoord coord) { - if (batchMode) { - batches.get(1).add(new ReinforcementTuple(data, coord)); - return; - } - try (Connection insertConn = db.getConnection(); - PreparedStatement updateRein = insertConn.prepareStatement( - "update ctdl_reinforcements set type_id = ?, health = ?, group_id = ?, insecure = ?, creation_time = ? where " - + "chunk_x = ? and chunk_z = ? and world_id = ? and x_offset = ? and y = ? and z_offset = ?;");) { - setUpdateDataStatement(updateRein, data, coord); - updateRein.execute(); - } catch (SQLException e) { - logger.log(Level.SEVERE, "Failed to update reinforcement in db: ", e); - } - } + @Override + public void update(Reinforcement data, XZWCoord coord) { + if (batchMode) { + batches.get(1).add(new ReinforcementTuple(data, coord)); + return; + } + try (Connection insertConn = db.getConnection(); + PreparedStatement updateRein = insertConn.prepareStatement( + "update ctdl_reinforcements set type_id = ?, health = ?, group_id = ?, insecure = ?, creation_time = ? where " + + "chunk_x = ? and chunk_z = ? and world_id = ? and x_offset = ? and y = ? and z_offset = ?;");) { + setUpdateDataStatement(updateRein, data, coord); + updateRein.execute(); + } catch (SQLException e) { + logger.log(Level.SEVERE, "Failed to update reinforcement in db: ", e); + } + } - private static void setUpdateDataStatement(PreparedStatement updateRein, Reinforcement data, XZWCoord coord) throws SQLException { - updateRein.setShort(1, data.getType().getID()); - updateRein.setFloat(2, data.getHealth()); - updateRein.setInt(3, data.getGroupId()); - updateRein.setBoolean(4, data.isInsecure()); - updateRein.setTimestamp(5, new Timestamp(data.getCreationTime())); - updateRein.setInt(6, coord.getX()); - updateRein.setInt(7, coord.getZ()); - updateRein.setShort(8, coord.getWorldID()); - updateRein.setByte(9, (byte) BlockBasedChunkMeta.modulo(data.getLocation().getBlockX())); - updateRein.setShort(10, (short) data.getLocation().getBlockY()); - updateRein.setByte(11, (byte) BlockBasedChunkMeta.modulo(data.getLocation().getBlockZ())); - } + private static void setUpdateDataStatement(PreparedStatement updateRein, Reinforcement data, XZWCoord coord) throws SQLException { + updateRein.setShort(1, data.getType().getID()); + updateRein.setFloat(2, data.getHealth()); + updateRein.setInt(3, data.getGroupId()); + updateRein.setBoolean(4, data.isInsecure()); + updateRein.setTimestamp(5, new Timestamp(data.getCreationTime())); + updateRein.setInt(6, coord.getX()); + updateRein.setInt(7, coord.getZ()); + updateRein.setShort(8, coord.getWorldID()); + updateRein.setByte(9, (byte) BlockBasedChunkMeta.modulo(data.getLocation().getBlockX())); + updateRein.setShort(10, (short) data.getLocation().getBlockY()); + updateRein.setByte(11, (byte) BlockBasedChunkMeta.modulo(data.getLocation().getBlockZ())); + } - @Override - public void delete(Reinforcement data, XZWCoord coord) { - if (batchMode) { - batches.get(2).add(new ReinforcementTuple(data, coord)); - return; - } - try (Connection insertConn = db.getConnection(); - PreparedStatement deleteRein = insertConn.prepareStatement( - "delete from ctdl_reinforcements where chunk_x = ? and chunk_z = ? and world_id = ? and " - + "x_offset = ? and y = ? and z_offset = ?;");) { - setDeleteDataStatement(deleteRein, data, coord); - deleteRein.execute(); - } catch (SQLException e) { - logger.log(Level.SEVERE, "Failed to delete reinforcement from db: ", e); - } - } + @Override + public void delete(Reinforcement data, XZWCoord coord) { + if (batchMode) { + batches.get(2).add(new ReinforcementTuple(data, coord)); + return; + } + try (Connection insertConn = db.getConnection(); + PreparedStatement deleteRein = insertConn.prepareStatement( + "delete from ctdl_reinforcements where chunk_x = ? and chunk_z = ? and world_id = ? and " + + "x_offset = ? and y = ? and z_offset = ?;");) { + setDeleteDataStatement(deleteRein, data, coord); + deleteRein.execute(); + } catch (SQLException e) { + logger.log(Level.SEVERE, "Failed to delete reinforcement from db: ", e); + } + } - private static void setDeleteDataStatement(PreparedStatement deleteRein, Reinforcement data, XZWCoord coord) throws SQLException { - deleteRein.setInt(1, coord.getX()); - deleteRein.setInt(2, coord.getZ()); - deleteRein.setShort(3, coord.getWorldID()); - deleteRein.setByte(4, (byte) BlockBasedChunkMeta.modulo(data.getLocation().getBlockX())); - deleteRein.setShort(5, (short) data.getLocation().getBlockY()); - deleteRein.setByte(6, (byte) BlockBasedChunkMeta.modulo(data.getLocation().getBlockZ())); - } + private static void setDeleteDataStatement(PreparedStatement deleteRein, Reinforcement data, XZWCoord coord) throws SQLException { + deleteRein.setInt(1, coord.getX()); + deleteRein.setInt(2, coord.getZ()); + deleteRein.setShort(3, coord.getWorldID()); + deleteRein.setByte(4, (byte) BlockBasedChunkMeta.modulo(data.getLocation().getBlockX())); + deleteRein.setShort(5, (short) data.getLocation().getBlockY()); + deleteRein.setByte(6, (byte) BlockBasedChunkMeta.modulo(data.getLocation().getBlockZ())); + } - @Override - public void fill(TableBasedBlockChunkMeta chunkData, Consumer insertFunction) { - int preMultipliedX = chunkData.getChunkCoord().getX() * 16; - int preMultipliedZ = chunkData.getChunkCoord().getZ() * 16; - ReinforcementTypeManager typeMan = Citadel.getInstance().getReinforcementTypeManager(); - World world = chunkData.getChunkCoord().getWorld(); - try (Connection insertConn = db.getConnection(); - PreparedStatement selectRein = insertConn.prepareStatement( - "select x_offset, y, z_offset, type_id, group_id, creation_time, health, insecure " - + "from ctdl_reinforcements where chunk_x = ? and chunk_z = ? and world_id = ?;");) { - selectRein.setInt(1, chunkData.getChunkCoord().getX()); - selectRein.setInt(2, chunkData.getChunkCoord().getZ()); - selectRein.setShort(3, chunkData.getChunkCoord().getWorldID()); - try (ResultSet rs = selectRein.executeQuery()) { - while (rs.next()) { - int xOffset = rs.getByte(1); - int x = xOffset + preMultipliedX; - int y = rs.getShort(2); - int zOffset = rs.getByte(3); - int z = zOffset + preMultipliedZ; - Location location = new Location(world, x, y, z); - short typeID = rs.getShort(4); - ReinforcementType type = typeMan.getById(typeID); - if (type == null) { - logger.log(Level.SEVERE, "Failed to load reinforcement with type id " + typeID); - continue; - } - int groupID = rs.getInt(5); - long creationTime = rs.getTimestamp(6).getTime(); - float health = rs.getFloat(7); - boolean insecure = rs.getBoolean(8); - Reinforcement rein = new Reinforcement(location, type, groupID, creationTime, health, insecure, - false); - insertFunction.accept(rein); - } - } - } catch (SQLException e) { - logger.log(Level.SEVERE, "Failed to load reinforcement from db: ", e); - } - } + @Override + public void fill(TableBasedBlockChunkMeta chunkData, Consumer insertFunction) { + int preMultipliedX = chunkData.getChunkCoord().getX() * 16; + int preMultipliedZ = chunkData.getChunkCoord().getZ() * 16; + ReinforcementTypeManager typeMan = Citadel.getInstance().getReinforcementTypeManager(); + World world = chunkData.getChunkCoord().getWorld(); + try (Connection insertConn = db.getConnection(); + PreparedStatement selectRein = insertConn.prepareStatement( + "select x_offset, y, z_offset, type_id, group_id, creation_time, health, insecure " + + "from ctdl_reinforcements where chunk_x = ? and chunk_z = ? and world_id = ?;");) { + selectRein.setInt(1, chunkData.getChunkCoord().getX()); + selectRein.setInt(2, chunkData.getChunkCoord().getZ()); + selectRein.setShort(3, chunkData.getChunkCoord().getWorldID()); + try (ResultSet rs = selectRein.executeQuery()) { + while (rs.next()) { + int xOffset = rs.getByte(1); + int x = xOffset + preMultipliedX; + int y = rs.getShort(2); + int zOffset = rs.getByte(3); + int z = zOffset + preMultipliedZ; + Location location = new Location(world, x, y, z); + short typeID = rs.getShort(4); + ReinforcementType type = typeMan.getById(typeID); + if (type == null) { + logger.log(Level.SEVERE, "Failed to load reinforcement with type id " + typeID); + continue; + } + int groupID = rs.getInt(5); + long creationTime = rs.getTimestamp(6).getTime(); + float health = rs.getFloat(7); + boolean insecure = rs.getBoolean(8); + Reinforcement rein = new Reinforcement(location, type, groupID, creationTime, health, insecure, + false); + insertFunction.accept(rein); + } + } + } catch (SQLException e) { + logger.log(Level.SEVERE, "Failed to load reinforcement from db: ", e); + } + } - @Override - public Collection getAllDataChunks() { - List result = new ArrayList<>(); - try (Connection insertConn = db.getConnection(); - PreparedStatement selectChunks = insertConn.prepareStatement( - "select chunk_x, chunk_z, world_id from ctdl_reinforcements group by chunk_x, chunk_z, world_id"); - ResultSet rs = selectChunks.executeQuery()) { - while (rs.next()) { - int chunkX = rs.getInt(1); - int chunkZ = rs.getInt(2); - short worldID = rs.getShort(3); - result.add(new XZWCoord(chunkX, chunkZ, worldID)); - } - } catch (SQLException e) { - logger.log(Level.SEVERE, "Failed to select populated chunks from db: ", e); - } - return result; - } + @Override + public Collection getAllDataChunks() { + List result = new ArrayList<>(); + try (Connection insertConn = db.getConnection(); + PreparedStatement selectChunks = insertConn.prepareStatement( + "select chunk_x, chunk_z, world_id from ctdl_reinforcements group by chunk_x, chunk_z, world_id"); + ResultSet rs = selectChunks.executeQuery()) { + while (rs.next()) { + int chunkX = rs.getInt(1); + int chunkZ = rs.getInt(2); + short worldID = rs.getShort(3); + result.add(new XZWCoord(chunkX, chunkZ, worldID)); + } + } catch (SQLException e) { + logger.log(Level.SEVERE, "Failed to select populated chunks from db: ", e); + } + return result; + } - @Override - public boolean stayLoaded() { - return false; - } + @Override + public boolean stayLoaded() { + return false; + } - private class ReinforcementTuple { - private Reinforcement rein; - private XZWCoord coord; + private class ReinforcementTuple { - ReinforcementTuple(Reinforcement rein, XZWCoord coord) { - this.rein = rein; - this.coord = coord; - } - } + private Reinforcement rein; + private XZWCoord coord; + + ReinforcementTuple(Reinforcement rein, XZWCoord coord) { + this.rein = rein; + this.coord = coord; + } + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/model/CitadelSettingManager.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/model/CitadelSettingManager.java index 48f06d603..8ada33284 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/model/CitadelSettingManager.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/model/CitadelSettingManager.java @@ -25,193 +25,193 @@ import vg.civcraft.mc.civmodcore.players.settings.impl.StringSetting; public class CitadelSettingManager { - private BooleanSetting byPass; - private BooleanSetting informationMode; - private BooleanSetting showChatMsgInCti; - private BooleanSetting showHologramInCti; - private BooleanSetting easyMode; - private BooleanSetting ctoDisableCti; - private BooleanSetting ctoDisableCtb; + private BooleanSetting byPass; + private BooleanSetting informationMode; + private BooleanSetting showChatMsgInCti; + private BooleanSetting showHologramInCti; + private BooleanSetting easyMode; + private BooleanSetting ctoDisableCti; + private BooleanSetting ctoDisableCtb; - private BoundedIntegerSetting hologramDuration; + private BoundedIntegerSetting hologramDuration; - private CommandReplySetting ctiNotReinforced; - // private CommandReplySetting ctiAllied; - private CommandReplySetting ctiEnemy; - // private CommandReplySetting modeSwitch; - private DecimalFormatSetting ctiPercentageHealth; - private DecimalFormatSetting ctiReinforcementHealth; - private DecimalFormatSetting ctiDecayMultiplier; - private StringSetting ctiDecay; - private DisplayLocationSetting ctbLocationSetting; - private DisplayLocationSetting modeLocationSetting; - private DisplayLocationSetting ctiLocationSetting; + private CommandReplySetting ctiNotReinforced; + // private CommandReplySetting ctiAllied; + private CommandReplySetting ctiEnemy; + // private CommandReplySetting modeSwitch; + private DecimalFormatSetting ctiPercentageHealth; + private DecimalFormatSetting ctiReinforcementHealth; + private DecimalFormatSetting ctiDecayMultiplier; + private StringSetting ctiDecay; + private DisplayLocationSetting ctbLocationSetting; + private DisplayLocationSetting modeLocationSetting; + private DisplayLocationSetting ctiLocationSetting; - public CitadelSettingManager() { - initSettings(); - } + public CitadelSettingManager() { + initSettings(); + } - public DisplayLocationSetting getBypassLocationSetting() { - return ctbLocationSetting; - } + public DisplayLocationSetting getBypassLocationSetting() { + return ctbLocationSetting; + } - public DisplayLocationSetting getModeLocationSetting() { - return modeLocationSetting; - } + public DisplayLocationSetting getModeLocationSetting() { + return modeLocationSetting; + } - public DisplayLocationSetting getInformationLocationSetting() { - return ctiLocationSetting; - } + public DisplayLocationSetting getInformationLocationSetting() { + return ctiLocationSetting; + } - public BooleanSetting getBypass() { - return byPass; - } + public BooleanSetting getBypass() { + return byPass; + } - public BooleanSetting getInformationMode() { - return informationMode; - } + public BooleanSetting getInformationMode() { + return informationMode; + } - public BooleanSetting getEasyMode() { - return easyMode; - } + public BooleanSetting getEasyMode() { + return easyMode; + } - public boolean shouldShowChatInCti(UUID uuid) { - return showChatMsgInCti.getValue(uuid); - } + public boolean shouldShowChatInCti(UUID uuid) { + return showChatMsgInCti.getValue(uuid); + } - public boolean shouldCtoDisableCti(UUID uuid) { - return ctoDisableCti.getValue(uuid); - } + public boolean shouldCtoDisableCti(UUID uuid) { + return ctoDisableCti.getValue(uuid); + } - public boolean shouldCtoDisableCtb(UUID uuid) { - return ctoDisableCtb.getValue(uuid); - } + public boolean shouldCtoDisableCtb(UUID uuid) { + return ctoDisableCtb.getValue(uuid); + } - public boolean shouldShowHologramInCti(UUID uuid) { - return showHologramInCti.getValue(uuid); - } + public boolean shouldShowHologramInCti(UUID uuid) { + return showHologramInCti.getValue(uuid); + } - public boolean isInEasyMode(UUID uuid) { - return easyMode.getValue(uuid); - } + public boolean isInEasyMode(UUID uuid) { + return easyMode.getValue(uuid); + } - public int getHologramDuration(UUID uuid) { - return hologramDuration.getValue(uuid); - } + public int getHologramDuration(UUID uuid) { + return hologramDuration.getValue(uuid); + } - void initSettings() { - MenuSection menu = PlayerSettingAPI.getMainMenu().createMenuSection("Citadel", - "Citadel and reinforcement related settings", new ItemStack(Material.IRON_INGOT)); - byPass = new BooleanSetting(Citadel.getInstance(), true, "Bypass", "citadelBypass", - "Allows you to bypass reinforcements you have permission for and break them in a single break"); - PlayerSettingAPI.registerSetting(byPass, menu); + void initSettings() { + MenuSection menu = PlayerSettingAPI.getMainMenu().createMenuSection("Citadel", + "Citadel and reinforcement related settings", new ItemStack(Material.IRON_INGOT)); + byPass = new BooleanSetting(Citadel.getInstance(), true, "Bypass", "citadelBypass", + "Allows you to bypass reinforcements you have permission for and break them in a single break"); + PlayerSettingAPI.registerSetting(byPass, menu); - informationMode = new BooleanSetting(Citadel.getInstance(), false, "Information mode", "citadelInformationMode", - "Displays information about reinforced blocks when interacting with them"); - PlayerSettingAPI.registerSetting(informationMode, menu); + informationMode = new BooleanSetting(Citadel.getInstance(), false, "Information mode", "citadelInformationMode", + "Displays information about reinforced blocks when interacting with them"); + PlayerSettingAPI.registerSetting(informationMode, menu); - easyMode = new BooleanSetting(Citadel.getInstance(), false, "Easy reinforcing mode", "citadelEasyMode", - "Allows automatically reinforcing to your default group with reinforcement materials from your off hand"); - PlayerSettingAPI.registerSetting(easyMode, menu); + easyMode = new BooleanSetting(Citadel.getInstance(), false, "Easy reinforcing mode", "citadelEasyMode", + "Allows automatically reinforcing to your default group with reinforcement materials from your off hand"); + PlayerSettingAPI.registerSetting(easyMode, menu); - showChatMsgInCti = new BooleanSetting(Citadel.getInstance(), true, "Show chat message in information mode", - "citadelCtiShowChatMsg", "Should chat messages be shown in reinforcement information mode"); - PlayerSettingAPI.registerSetting(showChatMsgInCti, menu); + showChatMsgInCti = new BooleanSetting(Citadel.getInstance(), true, "Show chat message in information mode", + "citadelCtiShowChatMsg", "Should chat messages be shown in reinforcement information mode"); + PlayerSettingAPI.registerSetting(showChatMsgInCti, menu); - showHologramInCti = new BooleanSetting(Citadel.getInstance(), true, "Show holograms in information mode", - "citadelCtiShowHologram", "Should holograms be shown in reinforcement information mode"); - PlayerSettingAPI.registerSetting(showHologramInCti, menu); + showHologramInCti = new BooleanSetting(Citadel.getInstance(), true, "Show holograms in information mode", + "citadelCtiShowHologram", "Should holograms be shown in reinforcement information mode"); + PlayerSettingAPI.registerSetting(showHologramInCti, menu); - hologramDuration = new BoundedIntegerSetting(Citadel.getInstance(), 5000, "Hologram visibility duration", - "citadelHologramCullTimer", new ItemStack(Material.CLOCK), - "How long should holograms in information mode remain visible, measured in milli seconds", false, 1000, - 30000); - PlayerSettingAPI.registerSetting(hologramDuration, menu); - - ctbLocationSetting = new DisplayLocationSetting(Citadel.getInstance(), DisplayLocationSetting.DisplayLocation.NONE, "Bypass display location" - , "citadelBypassDisplayLocation", new ItemStack(Material.GOLDEN_PICKAXE), "bypass"); - PlayerSettingAPI.registerSetting(ctbLocationSetting, menu); - - ctiLocationSetting = new DisplayLocationSetting(Citadel.getInstance(), DisplayLocationSetting.DisplayLocation.SIDEBAR, "Information mode display location" - , "citadelInfoModeDisplayLocation", new ItemStack(Material.BOOKSHELF), "reinforcement info mode"); - PlayerSettingAPI.registerSetting(ctiLocationSetting, menu); - - modeLocationSetting = new DisplayLocationSetting(Citadel.getInstance(), DisplayLocationSetting.DisplayLocation.SIDEBAR, "Citadel mode display location" - , "citadelReinModeDisplayLocation", new ItemStack(Material.NETHER_STAR), "Citadel mode"); - PlayerSettingAPI.registerSetting(modeLocationSetting, menu); + hologramDuration = new BoundedIntegerSetting(Citadel.getInstance(), 5000, "Hologram visibility duration", + "citadelHologramCullTimer", new ItemStack(Material.CLOCK), + "How long should holograms in information mode remain visible, measured in milli seconds", false, 1000, + 30000); + PlayerSettingAPI.registerSetting(hologramDuration, menu); - ctoDisableCtb = new BooleanSetting(Citadel.getInstance(), false, "/cto disable /ctb", - "citadelCtoDisableCtb", "Should /cto disable Bypass mode (/ctb)"); - PlayerSettingAPI.registerSetting(ctoDisableCtb, menu); + ctbLocationSetting = new DisplayLocationSetting(Citadel.getInstance(), DisplayLocationSetting.DisplayLocation.NONE, "Bypass display location" + , "citadelBypassDisplayLocation", new ItemStack(Material.GOLDEN_PICKAXE), "bypass"); + PlayerSettingAPI.registerSetting(ctbLocationSetting, menu); - ctoDisableCti = new BooleanSetting(Citadel.getInstance(), true, "/cto disable /cti", - "citadelCtoDisableCti", "Should /cto disable Information mode (/cti)"); - PlayerSettingAPI.registerSetting(ctoDisableCti, menu); + ctiLocationSetting = new DisplayLocationSetting(Citadel.getInstance(), DisplayLocationSetting.DisplayLocation.SIDEBAR, "Information mode display location" + , "citadelInfoModeDisplayLocation", new ItemStack(Material.BOOKSHELF), "reinforcement info mode"); + PlayerSettingAPI.registerSetting(ctiLocationSetting, menu); - MenuSection commandSection = menu.createMenuSection("Command replies", - "Configures replies of reinforcements or Citadel commands"); + modeLocationSetting = new DisplayLocationSetting(Citadel.getInstance(), DisplayLocationSetting.DisplayLocation.SIDEBAR, "Citadel mode display location" + , "citadelReinModeDisplayLocation", new ItemStack(Material.NETHER_STAR), "Citadel mode"); + PlayerSettingAPI.registerSetting(modeLocationSetting, menu); - ctiNotReinforced = new CommandReplySetting(Citadel.getInstance(), ChatColor.YELLOW + "Not reinforced", - "CTI Message Unreinforced", "citadel_cti_unreinforced", new ItemStack(Material.YELLOW_TERRACOTTA), - "The message received when interacting with an unreinforced block in Information Mode"); - PlayerSettingAPI.registerSetting(ctiNotReinforced, commandSection); + ctoDisableCtb = new BooleanSetting(Citadel.getInstance(), false, "/cto disable /ctb", + "citadelCtoDisableCtb", "Should /cto disable Bypass mode (/ctb)"); + PlayerSettingAPI.registerSetting(ctoDisableCtb, menu); - ctiPercentageHealth = new DecimalFormatSetting(Citadel.getInstance(), new DecimalFormat("#.##"), - "Reinforcement Percentage Health Format", "citadel_cti_percentage_health", - new ItemStack(Material.KNOWLEDGE_BOOK), - "Decimal format used for displaying a percentage value for reinforcement health", 100.0 / 3); - PlayerSettingAPI.registerSetting(ctiPercentageHealth, commandSection); + ctoDisableCti = new BooleanSetting(Citadel.getInstance(), true, "/cto disable /cti", + "citadelCtoDisableCti", "Should /cto disable Information mode (/cti)"); + PlayerSettingAPI.registerSetting(ctoDisableCti, menu); - ctiReinforcementHealth = new DecimalFormatSetting(Citadel.getInstance(), new DecimalFormat("0"), - "Reinforcement Health Format", "citadel_cti_health", new ItemStack(Material.KNOWLEDGE_BOOK), - "Decimal format used for displaying a reinforcements health", 100.0 / 3); - PlayerSettingAPI.registerSetting(ctiReinforcementHealth, commandSection); + MenuSection commandSection = menu.createMenuSection("Command replies", + "Configures replies of reinforcements or Citadel commands"); - ctiDecayMultiplier = new DecimalFormatSetting(Citadel.getInstance(), new DecimalFormat("#.##"), - "Reinforcement Decay Multiplier Format", "citadel_cti_decay_multiplier", - new ItemStack(Material.KNOWLEDGE_BOOK), - "Decimal format used for displaying the decay multiplier of a reinforcement", 100.0 / 3); - PlayerSettingAPI.registerSetting(ctiDecayMultiplier, commandSection); + ctiNotReinforced = new CommandReplySetting(Citadel.getInstance(), ChatColor.YELLOW + "Not reinforced", + "CTI Message Unreinforced", "citadel_cti_unreinforced", new ItemStack(Material.YELLOW_TERRACOTTA), + "The message received when interacting with an unreinforced block in Information Mode"); + PlayerSettingAPI.registerSetting(ctiNotReinforced, commandSection); - ctiDecay = new StringSetting(Citadel.getInstance(), " (Decayed x%%decay%%)", - "Reinforcement Decay Format", "citadel_cti_decay", new ItemStack(Material.KNOWLEDGE_BOOK), - "String format used for displaying the decay of a reinforcement"); - PlayerSettingAPI.registerSetting(ctiDecay, commandSection); + ctiPercentageHealth = new DecimalFormatSetting(Citadel.getInstance(), new DecimalFormat("#.##"), + "Reinforcement Percentage Health Format", "citadel_cti_percentage_health", + new ItemStack(Material.KNOWLEDGE_BOOK), + "Decimal format used for displaying a percentage value for reinforcement health", 100.0 / 3); + PlayerSettingAPI.registerSetting(ctiPercentageHealth, commandSection); - ctiEnemy = new CommandReplySetting(Citadel.getInstance(), - ChatColor.RED + "Reinforced at %%health_color%%%%perc_health%%% (%%health%%/%%max_health%%)" - + ChatColor.RED + " health with " + ChatColor.AQUA + "%%type%%" + ChatColor.LIGHT_PURPLE + "%%decay_string%%", - "CTI Message Enemy", "citadel_cti_enemy", new ItemStack(Material.RED_TERRACOTTA), - "The message received when interacting with enemy reinforcements"); - ctiEnemy.registerArgument("perc_health", "33.33", "the percentage health of the reinforcement"); - ctiEnemy.registerArgument("max_health", "50", "the maximum health of the reinforcement"); - ctiEnemy.registerArgument("health", "25", "the current health of the reinforcement"); - ctiEnemy.registerArgument("type", "Stone", "the type of the reinforcement"); - ctiEnemy.registerArgument("health_color", ModeListener.getDamageColor(0.5).toString(), - "a color representing the reinforcement health"); - ctiEnemy.registerArgument("decay_string", "", "the decay of the reinforcement"); - PlayerSettingAPI.registerSetting(ctiEnemy, commandSection); - } + ctiReinforcementHealth = new DecimalFormatSetting(Citadel.getInstance(), new DecimalFormat("0"), + "Reinforcement Health Format", "citadel_cti_health", new ItemStack(Material.KNOWLEDGE_BOOK), + "Decimal format used for displaying a reinforcements health", 100.0 / 3); + PlayerSettingAPI.registerSetting(ctiReinforcementHealth, commandSection); - public void sendCtiEnemyMessage(Player player, Reinforcement reinforcement, Location location) { - Map args = new TreeMap<>(); - ReinforcementType type = reinforcement.getType(); - String percFormat = ctiPercentageHealth.getValue(player) - .format(reinforcement.getHealth() / type.getHealth() * 100); - args.put("perc_health", percFormat); - DecimalFormat reinHealthFormatter = ctiReinforcementHealth.getValue(player); - args.put("health", reinHealthFormatter.format(reinforcement.getHealth())); - args.put("max_health", reinHealthFormatter.format(type.getHealth())); - args.put("type", type.getName()); - args.put("health_color", - ModeListener.getDamageColor(reinforcement.getHealth() / type.getHealth()).toString()); - if (ReinforcementLogic.getDecayDamage(reinforcement) != 1) { - String ctiDecayAmountFormat = ctiDecayMultiplier.getValue(player).format(ReinforcementLogic.getDecayDamage(reinforcement)); - String ctiDecayFormat = ctiDecay.getValue(player).replaceAll("%%decay%%", ctiDecayAmountFormat); - args.put("decay_string", ctiDecayFormat); - } else { - args.put("decay_string", ""); - } - CitadelUtility.sendAndLog(player, ChatColor.RESET, ctiEnemy.formatReply(player.getUniqueId(), args), location); - } + ctiDecayMultiplier = new DecimalFormatSetting(Citadel.getInstance(), new DecimalFormat("#.##"), + "Reinforcement Decay Multiplier Format", "citadel_cti_decay_multiplier", + new ItemStack(Material.KNOWLEDGE_BOOK), + "Decimal format used for displaying the decay multiplier of a reinforcement", 100.0 / 3); + PlayerSettingAPI.registerSetting(ctiDecayMultiplier, commandSection); + + ctiDecay = new StringSetting(Citadel.getInstance(), " (Decayed x%%decay%%)", + "Reinforcement Decay Format", "citadel_cti_decay", new ItemStack(Material.KNOWLEDGE_BOOK), + "String format used for displaying the decay of a reinforcement"); + PlayerSettingAPI.registerSetting(ctiDecay, commandSection); + + ctiEnemy = new CommandReplySetting(Citadel.getInstance(), + ChatColor.RED + "Reinforced at %%health_color%%%%perc_health%%% (%%health%%/%%max_health%%)" + + ChatColor.RED + " health with " + ChatColor.AQUA + "%%type%%" + ChatColor.LIGHT_PURPLE + "%%decay_string%%", + "CTI Message Enemy", "citadel_cti_enemy", new ItemStack(Material.RED_TERRACOTTA), + "The message received when interacting with enemy reinforcements"); + ctiEnemy.registerArgument("perc_health", "33.33", "the percentage health of the reinforcement"); + ctiEnemy.registerArgument("max_health", "50", "the maximum health of the reinforcement"); + ctiEnemy.registerArgument("health", "25", "the current health of the reinforcement"); + ctiEnemy.registerArgument("type", "Stone", "the type of the reinforcement"); + ctiEnemy.registerArgument("health_color", ModeListener.getDamageColor(0.5).toString(), + "a color representing the reinforcement health"); + ctiEnemy.registerArgument("decay_string", "", "the decay of the reinforcement"); + PlayerSettingAPI.registerSetting(ctiEnemy, commandSection); + } + + public void sendCtiEnemyMessage(Player player, Reinforcement reinforcement, Location location) { + Map args = new TreeMap<>(); + ReinforcementType type = reinforcement.getType(); + String percFormat = ctiPercentageHealth.getValue(player) + .format(reinforcement.getHealth() / type.getHealth() * 100); + args.put("perc_health", percFormat); + DecimalFormat reinHealthFormatter = ctiReinforcementHealth.getValue(player); + args.put("health", reinHealthFormatter.format(reinforcement.getHealth())); + args.put("max_health", reinHealthFormatter.format(type.getHealth())); + args.put("type", type.getName()); + args.put("health_color", + ModeListener.getDamageColor(reinforcement.getHealth() / type.getHealth()).toString()); + if (ReinforcementLogic.getDecayDamage(reinforcement) != 1) { + String ctiDecayAmountFormat = ctiDecayMultiplier.getValue(player).format(ReinforcementLogic.getDecayDamage(reinforcement)); + String ctiDecayFormat = ctiDecay.getValue(player).replaceAll("%%decay%%", ctiDecayAmountFormat); + args.put("decay_string", ctiDecayFormat); + } else { + args.put("decay_string", ""); + } + CitadelUtility.sendAndLog(player, ChatColor.RESET, ctiEnemy.formatReply(player.getUniqueId(), args), location); + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/model/HologramManager.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/model/HologramManager.java index a6c190801..29bf3c582 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/model/HologramManager.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/model/HologramManager.java @@ -17,162 +17,163 @@ import org.bukkit.util.Vector; import vg.civcraft.mc.citadel.Citadel; import vg.civcraft.mc.citadel.CitadelPermissionHandler; import vg.civcraft.mc.citadel.listener.ModeListener; + public class HologramManager { - // distance from center to diagonal corner is 0.5 * sqrt(2) and we add 10 % for - // good measure - private static final double HOLOOFFSET = 0.55 * Math.sqrt(2); + // distance from center to diagonal corner is 0.5 * sqrt(2) and we add 10 % for + // good measure + private static final double HOLOOFFSET = 0.55 * Math.sqrt(2); - private Map> holograms; - private Set activeHolos; - private CitadelSettingManager settingMan; + private Map> holograms; + private Set activeHolos; + private CitadelSettingManager settingMan; - public HologramManager(CitadelSettingManager settingMan) { - this.holograms = new HashMap<>(); - this.activeHolos = new HashSet<>(); - this.settingMan = settingMan; - new BukkitRunnable() { + public HologramManager(CitadelSettingManager settingMan) { + this.holograms = new HashMap<>(); + this.activeHolos = new HashSet<>(); + this.settingMan = settingMan; + new BukkitRunnable() { - @Override - public void run() { - updateHolograms(); - } + @Override + public void run() { + updateHolograms(); + } - }.runTaskTimer(Citadel.getInstance(), 2L, 2L); - } + }.runTaskTimer(Citadel.getInstance(), 2L, 2L); + } - public void showInfoHolo(Reinforcement rein, Player player) { - Map locationSpecificHolos = holograms.get(rein.getLocation()); - if (locationSpecificHolos == null) { - locationSpecificHolos = new TreeMap<>(); - holograms.put(rein.getLocation(), locationSpecificHolos); - } - PlayerHolo holo = locationSpecificHolos.get(player.getUniqueId()); - if (holo == null) { - holo = new PlayerHolo(player, rein); - locationSpecificHolos.put(player.getUniqueId(), holo); - } - activeHolos.add(holo); - holo.show(); - } + public void showInfoHolo(Reinforcement rein, Player player) { + Map locationSpecificHolos = holograms.get(rein.getLocation()); + if (locationSpecificHolos == null) { + locationSpecificHolos = new TreeMap<>(); + holograms.put(rein.getLocation(), locationSpecificHolos); + } + PlayerHolo holo = locationSpecificHolos.get(player.getUniqueId()); + if (holo == null) { + holo = new PlayerHolo(player, rein); + locationSpecificHolos.put(player.getUniqueId(), holo); + } + activeHolos.add(holo); + holo.show(); + } - private static Location getHoloLocation(Reinforcement rein, Player player) { - Location baseLoc = rein.getBlockCenter(); - baseLoc = baseLoc.add(0, 0.5, 0); - Vector vector = player.getEyeLocation().toVector(); - vector.subtract(baseLoc.toVector()); - // vector is now the offset from the reinforcement to the player and we now move - // towards the player so the hologram isn't inside the block - vector.normalize(); - // holoOffSet is a good distance to ensure we fully move the hologram out of the - // block - vector.multiply(HOLOOFFSET); - baseLoc.add(vector); - return baseLoc; - } + private static Location getHoloLocation(Reinforcement rein, Player player) { + Location baseLoc = rein.getBlockCenter(); + baseLoc = baseLoc.add(0, 0.5, 0); + Vector vector = player.getEyeLocation().toVector(); + vector.subtract(baseLoc.toVector()); + // vector is now the offset from the reinforcement to the player and we now move + // towards the player so the hologram isn't inside the block + vector.normalize(); + // holoOffSet is a good distance to ensure we fully move the hologram out of the + // block + vector.multiply(HOLOOFFSET); + baseLoc.add(vector); + return baseLoc; + } - private void updateHolograms() { - for (Iterator iter = activeHolos.iterator(); iter.hasNext();) { - PlayerHolo holo = iter.next(); - if (!holo.update()) { - iter.remove(); - } - } - } + private void updateHolograms() { + for (Iterator iter = activeHolos.iterator(); iter.hasNext(); ) { + PlayerHolo holo = iter.next(); + if (!holo.update()) { + iter.remove(); + } + } + } - private class PlayerHolo { + private class PlayerHolo { - private Player player; - private Hologram hologram; - private Reinforcement reinforcement; - private long timeStamp; - private boolean hasPermission; - private Location cachedPlayerLocation; - private double cachedHealth; - private long cullDelay; + private Player player; + private Hologram hologram; + private Reinforcement reinforcement; + private long timeStamp; + private boolean hasPermission; + private Location cachedPlayerLocation; + private double cachedHealth; + private long cullDelay; - public PlayerHolo(Player player, Reinforcement reinforcement) { - this.player = player; - this.reinforcement = reinforcement; - this.timeStamp = System.currentTimeMillis(); - this.cullDelay = settingMan.getHologramDuration(player.getUniqueId()); - // we intentionally cache permission to avoid having to look it up often - // showing a bit too much information if the player gets kicked while a holo is - // already visible does not matter - this.hasPermission = reinforcement.hasPermission(player, CitadelPermissionHandler.getInfo()); - } + public PlayerHolo(Player player, Reinforcement reinforcement) { + this.player = player; + this.reinforcement = reinforcement; + this.timeStamp = System.currentTimeMillis(); + this.cullDelay = settingMan.getHologramDuration(player.getUniqueId()); + // we intentionally cache permission to avoid having to look it up often + // showing a bit too much information if the player gets kicked while a holo is + // already visible does not matter + this.hasPermission = reinforcement.hasPermission(player, CitadelPermissionHandler.getInfo()); + } - void show() { - refreshTimestamp(); - if (hologram != null) { - return; - } - hologram = HologramsAPI.createHologram(Citadel.getInstance(), getHoloLocation(reinforcement, player)); - cachedPlayerLocation = player.getLocation(); - hologram.getVisibilityManager().setVisibleByDefault(false); - hologram.getVisibilityManager().showTo(player); - updateText(); - } + void show() { + refreshTimestamp(); + if (hologram != null) { + return; + } + hologram = HologramsAPI.createHologram(Citadel.getInstance(), getHoloLocation(reinforcement, player)); + cachedPlayerLocation = player.getLocation(); + hologram.getVisibilityManager().setVisibleByDefault(false); + hologram.getVisibilityManager().showTo(player); + updateText(); + } - boolean update() { - if (System.currentTimeMillis() - timeStamp > cullDelay) { - delete(); - return false; - } - if (reinforcement.isBroken()) { - delete(); - return false; - } - updateLocation(); - updateText(); - return true; - } + boolean update() { + if (System.currentTimeMillis() - timeStamp > cullDelay) { + delete(); + return false; + } + if (reinforcement.isBroken()) { + delete(); + return false; + } + updateLocation(); + updateText(); + return true; + } - void updateLocation() { - Location current = player.getLocation(); - // Location.equals would also check pitch/yaw - if (current.getBlockX() == cachedPlayerLocation.getBlockX() && current.getBlockY() == cachedPlayerLocation.getBlockY() - && current.getBlockZ() == cachedPlayerLocation.getBlockZ()) { - return; - } - Location updated = getHoloLocation(reinforcement, player); - hologram.teleport(updated); - } + void updateLocation() { + Location current = player.getLocation(); + // Location.equals would also check pitch/yaw + if (current.getBlockX() == cachedPlayerLocation.getBlockX() && current.getBlockY() == cachedPlayerLocation.getBlockY() + && current.getBlockZ() == cachedPlayerLocation.getBlockZ()) { + return; + } + Location updated = getHoloLocation(reinforcement, player); + hologram.teleport(updated); + } - void refreshTimestamp() { - this.timeStamp = System.currentTimeMillis(); - } + void refreshTimestamp() { + this.timeStamp = System.currentTimeMillis(); + } - void updateText() { - if (reinforcement.getHealth() != cachedHealth || hologram.size() == 0) { - if (hologram.size() > 0) { - hologram.removeLine(0); - } - hologram.insertTextLine(0, ModeListener.formatHealth(reinforcement)); - cachedHealth = reinforcement.getHealth(); - } - if (!hasPermission) { - return; - } - if (hologram.size() == 1) { - // not initialized yet - hologram.insertTextLine(1, ChatColor.LIGHT_PURPLE + reinforcement.getGroup().getName()); - hologram.insertTextLine(2, ChatColor.AQUA + reinforcement.getType().getName()); - } - if (hologram.size() == 4) { - hologram.removeLine(3); - } - if (!reinforcement.isMature()) { - hologram.insertTextLine(3, ModeListener.formatProgress(reinforcement.getCreationTime(), - reinforcement.getType().getMaturationTime(), "")); - } - } + void updateText() { + if (reinforcement.getHealth() != cachedHealth || hologram.size() == 0) { + if (hologram.size() > 0) { + hologram.removeLine(0); + } + hologram.insertTextLine(0, ModeListener.formatHealth(reinforcement)); + cachedHealth = reinforcement.getHealth(); + } + if (!hasPermission) { + return; + } + if (hologram.size() == 1) { + // not initialized yet + hologram.insertTextLine(1, ChatColor.LIGHT_PURPLE + reinforcement.getGroup().getName()); + hologram.insertTextLine(2, ChatColor.AQUA + reinforcement.getType().getName()); + } + if (hologram.size() == 4) { + hologram.removeLine(3); + } + if (!reinforcement.isMature()) { + hologram.insertTextLine(3, ModeListener.formatProgress(reinforcement.getCreationTime(), + reinforcement.getType().getMaturationTime(), "")); + } + } - void delete() { - hologram.delete(); - hologram = null; - } + void delete() { + hologram.delete(); + hologram = null; + } - } + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/model/Reinforcement.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/model/Reinforcement.java index bc7024a2a..b0901314c 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/model/Reinforcement.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/model/Reinforcement.java @@ -13,197 +13,198 @@ import vg.civcraft.mc.namelayer.permission.PermissionType; public class Reinforcement extends TableBasedDataObject { - private static Random rng = new Random(); + private static Random rng = new Random(); - private long creationTime; - private ReinforcementType type; - private float health; - private int groupId; - private boolean insecure; + private long creationTime; + private ReinforcementType type; + private float health; + private int groupId; + private boolean insecure; - public Reinforcement(Location loc, ReinforcementType type, Group group) { - this(loc, type, group.getGroupId(), System.currentTimeMillis(), type.getHealth(), false, true); - } + public Reinforcement(Location loc, ReinforcementType type, Group group) { + this(loc, type, group.getGroupId(), System.currentTimeMillis(), type.getHealth(), false, true); + } - public Reinforcement(Location loc, ReinforcementType type, int groupID, long creationTime, float health, - boolean insecure, boolean isNew) { - super(loc, isNew); - if (type == null) { - throw new IllegalArgumentException("Reinforcement type for reinforcement can not be null"); - } - this.type = type; - this.creationTime = creationTime; - this.health = health; - this.groupId = groupID; - this.insecure = insecure; - } + public Reinforcement(Location loc, ReinforcementType type, int groupID, long creationTime, float health, + boolean insecure, boolean isNew) { + super(loc, isNew); + if (type == null) { + throw new IllegalArgumentException("Reinforcement type for reinforcement can not be null"); + } + this.type = type; + this.creationTime = creationTime; + this.health = health; + this.groupId = groupID; + this.insecure = insecure; + } - /** - * @return Age of this reinforcement in milli seconds - */ - public long getAge() { - return System.currentTimeMillis() - creationTime; - } + /** + * @return Age of this reinforcement in milli seconds + */ + public long getAge() { + return System.currentTimeMillis() - creationTime; + } - /** - * @return Unix time in ms when the reinforcement was created - */ - public long getCreationTime() { - return creationTime; - } + /** + * @return Unix time in ms when the reinforcement was created + */ + public long getCreationTime() { + return creationTime; + } - /** - * @return Group this reinforcement is under - */ - public Group getGroup() { - return GroupManager.getGroup(groupId); - } + /** + * @return Group this reinforcement is under + */ + public Group getGroup() { + return GroupManager.getGroup(groupId); + } - /** - * @return Id of the group this reinforcement is under - */ - public int getGroupId() { - return groupId; - } + /** + * @return Id of the group this reinforcement is under + */ + public int getGroupId() { + return groupId; + } - /** - * @return Current health - */ - public float getHealth() { - return health; - } + /** + * @return Current health + */ + public float getHealth() { + return health; + } - /** - * Gets the center of the block at the location of this reinforcement. - * getLocation() will return the integer coordinates of the reinforcement while - * this location is offset by 0.5 to the center - * - * @return Center of the block - */ - public Location getBlockCenter() { - Location copy = location.clone(); - copy.add(0.5, 0.5, 0.5); - return copy; - } + /** + * Gets the center of the block at the location of this reinforcement. + * getLocation() will return the integer coordinates of the reinforcement while + * this location is offset by 0.5 to the center + * + * @return Center of the block + */ + public Location getBlockCenter() { + Location copy = location.clone(); + copy.add(0.5, 0.5, 0.5); + return copy; + } - /** - * @return Type of this reinforcement - */ - public ReinforcementType getType() { - return type; - } - - /** - * Checks whether the player with the given UUID has the given permission on the group this reinforcement belongs to - * @param uuid UUID of the player to check permissions for, not null - * @param permission Permission to check, not null - * @return True if the player has the given permission on this reinforcements group, false otherwise - */ - public boolean hasPermission(UUID uuid, PermissionType permission) { - if (permission == null) { - throw new IllegalArgumentException("PermissionType may not be null"); - } - Group g = getGroup(); - if (g == null) { - return false; - } - return NameAPI.getGroupManager().hasAccess(g, uuid, permission); - } - - /** - * Checks whether the given player has the given permission on the group this reinforcement belongs to - * @param player Player to check permissions for, not null - * @param permission Permission to check, not null - * @return True if the player has the given permission on this reinforcements group, false otherwise - */ - public boolean hasPermission(Player player, PermissionType permission) { - return hasPermission(player.getUniqueId(), permission); - } + /** + * @return Type of this reinforcement + */ + public ReinforcementType getType() { + return type; + } - /** - * After being broken reinforcements will no longer be accessible via lookup, - * but may still persist in the cache until their deletion is persisted into the - * database - * - * @return True if the reinforcements health is equal to or less than 0 - */ - public boolean isBroken() { - return health <= 0; - } + /** + * Checks whether the player with the given UUID has the given permission on the group this reinforcement belongs to + * + * @param uuid UUID of the player to check permissions for, not null + * @param permission Permission to check, not null + * @return True if the player has the given permission on this reinforcements group, false otherwise + */ + public boolean hasPermission(UUID uuid, PermissionType permission) { + if (permission == null) { + throw new IllegalArgumentException("PermissionType may not be null"); + } + Group g = getGroup(); + if (g == null) { + return false; + } + return NameAPI.getGroupManager().hasAccess(g, uuid, permission); + } - /** - * @return Whether the reinforcement is insecure, meaning it ignores Citadel - * restrictions on hoppers etc. - */ - public boolean isInsecure() { - return insecure; - } + /** + * Checks whether the given player has the given permission on the group this reinforcement belongs to + * + * @param player Player to check permissions for, not null + * @param permission Permission to check, not null + * @return True if the player has the given permission on this reinforcements group, false otherwise + */ + public boolean hasPermission(Player player, PermissionType permission) { + return hasPermission(player.getUniqueId(), permission); + } - /** - * @return Whether reinforcement is mature, meaning the maturation time - * configured for this reinforcements type has passed since the - * reinforcements creation - */ - public boolean isMature() { - return System.currentTimeMillis() - creationTime > type.getMaturationTime(); - } + /** + * After being broken reinforcements will no longer be accessible via lookup, + * but may still persist in the cache until their deletion is persisted into the + * database + * + * @return True if the reinforcements health is equal to or less than 0 + */ + public boolean isBroken() { + return health <= 0; + } - public void setGroup(Group group) { - if (group == null) { - throw new IllegalArgumentException("Group can not be set to null for a reinforcement"); - } - this.groupId = group.getGroupId(); - setDirty(); - } + /** + * @return Whether the reinforcement is insecure, meaning it ignores Citadel + * restrictions on hoppers etc. + */ + public boolean isInsecure() { + return insecure; + } - /** - * Sets the health of a reinforcement. - * - * @param health new health value - */ - public void setHealth(float health) { - this.health = health; - if (health <= 0) { - if (getOwningCache() != null) { - getOwningCache().remove(this); - } - } - else { - setDirty(); - } - } + /** + * @return Whether reinforcement is mature, meaning the maturation time + * configured for this reinforcements type has passed since the + * reinforcements creation + */ + public boolean isMature() { + return System.currentTimeMillis() - creationTime > type.getMaturationTime(); + } - public void setType(ReinforcementType type) { - this.type = type; - setDirty(); - } + public void setGroup(Group group) { + if (group == null) { + throw new IllegalArgumentException("Group can not be set to null for a reinforcement"); + } + this.groupId = group.getGroupId(); + setDirty(); + } - /** - * Switches the insecure flag of the reinforcement - */ - public void toggleInsecure() { - insecure = !insecure; - setDirty(); - } - - /** - * Resets the timestamp at which the reinforcement was created to the current one - */ - public void resetCreationTime() { - this.creationTime = System.currentTimeMillis(); - } + /** + * Sets the health of a reinforcement. + * + * @param health new health value + */ + public void setHealth(float health) { + this.health = health; + if (health <= 0) { + if (getOwningCache() != null) { + getOwningCache().remove(this); + } + } else { + setDirty(); + } + } - /** - * Does a randomness check based on current reinforcement health and - * reinforcement type to decide whether the reinforcement item should be - * returned - * - * @return Whether to return the reinforcement item or not - */ - public boolean rollForItemReturn() { - double baseChance = type.getReturnChance(); - double relativeHealth = health / type.getHealth(); - baseChance *= relativeHealth; - return rng.nextDouble() <= baseChance; - } + public void setType(ReinforcementType type) { + this.type = type; + setDirty(); + } + + /** + * Switches the insecure flag of the reinforcement + */ + public void toggleInsecure() { + insecure = !insecure; + setDirty(); + } + + /** + * Resets the timestamp at which the reinforcement was created to the current one + */ + public void resetCreationTime() { + this.creationTime = System.currentTimeMillis(); + } + + /** + * Does a randomness check based on current reinforcement health and + * reinforcement type to decide whether the reinforcement item should be + * returned + * + * @return Whether to return the reinforcement item or not + */ + public boolean rollForItemReturn() { + double baseChance = type.getReturnChance(); + double relativeHealth = health / type.getHealth(); + baseChance *= relativeHealth; + return rng.nextDouble() <= baseChance; + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/model/WorldBorderBuffers.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/model/WorldBorderBuffers.java index 384e7403f..6ec4b1665 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/model/WorldBorderBuffers.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/model/WorldBorderBuffers.java @@ -1,30 +1,31 @@ package vg.civcraft.mc.citadel.model; public record WorldBorderBuffers(double centerX, double centerZ, Shape borderShape, double bufferSize) { - public enum Shape { - CIRCLE, - SQUARE; - } - private boolean checkIfOutsideCircle(double x,double z) { - return (x - centerX) * (x - centerX) + (z - centerZ) * (z - centerZ) > bufferSize * bufferSize; - } + public enum Shape { + CIRCLE, + SQUARE; + } - private boolean checkIfOutsideSquare(double x, double z) { - return Math.abs(x) > (centerX + bufferSize) || Math.abs(z) > (centerZ + bufferSize); - } + private boolean checkIfOutsideCircle(double x, double z) { + return (x - centerX) * (x - centerX) + (z - centerZ) * (z - centerZ) > bufferSize * bufferSize; + } - public boolean checkIfOutside(double x, double z) { - switch (this.borderShape) { - case CIRCLE -> { - return checkIfOutsideCircle(x, z); - } - case SQUARE -> { - return checkIfOutsideSquare(x, z); - } - } - return false; - } + private boolean checkIfOutsideSquare(double x, double z) { + return Math.abs(x) > (centerX + bufferSize) || Math.abs(z) > (centerZ + bufferSize); + } + + public boolean checkIfOutside(double x, double z) { + switch (this.borderShape) { + case CIRCLE -> { + return checkIfOutsideCircle(x, z); + } + case SQUARE -> { + return checkIfOutsideSquare(x, z); + } + } + return false; + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/playerstate/AbstractPlayerState.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/playerstate/AbstractPlayerState.java index 425e7a6db..147b737df 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/playerstate/AbstractPlayerState.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/playerstate/AbstractPlayerState.java @@ -24,86 +24,86 @@ import vg.civcraft.mc.civmodcore.utilities.DelayedItemDrop; public abstract class AbstractPlayerState { - protected UUID uuid; + protected UUID uuid; - public AbstractPlayerState(Player p) { - if (p == null) { - throw new IllegalArgumentException("Player for player state can not be null"); - } - this.uuid = p.getUniqueId(); - } + public AbstractPlayerState(Player p) { + if (p == null) { + throw new IllegalArgumentException("Player for player state can not be null"); + } + this.uuid = p.getUniqueId(); + } - public abstract String getName(); + public abstract String getName(); - public abstract void handleBlockPlace(BlockPlaceEvent e); + public abstract void handleBlockPlace(BlockPlaceEvent e); - public void handleBreakBlock(BlockBreakEvent e) { - Reinforcement rein = ReinforcementLogic.getReinforcementProtecting(e.getBlock()); - if (rein == null) { - // no reinforcement, normal break which we dont care about - return; - } - if (CitadelUtility.isPlant(e.getBlock())) { - if (rein.hasPermission(e.getPlayer(), CitadelPermissionHandler.getCrops()) - && !e.getBlock().getLocation().equals(rein.getLocation())) { - // allow, because player has crop permission and the only reinforcement - // protecting is in the soil - return; - } - } - boolean hasAccess = rein.hasPermission(e.getPlayer(), CitadelPermissionHandler.getBypass()); - BooleanSetting setting = (BooleanSetting) PlayerSettingAPI.getSetting("citadelBypass"); - boolean hasByPass = setting.getValue(e.getPlayer()); - if (hasAccess && hasByPass) { - ReinforcementBypassEvent bypassEvent = new ReinforcementBypassEvent(e.getPlayer(), rein); - Bukkit.getPluginManager().callEvent(bypassEvent); - if (bypassEvent.isCancelled()) { - e.setCancelled(true); - return; - } - if (rein.rollForItemReturn()) { - giveReinforcement(e.getBlock().getLocation().clone().add(0.5, 0.5, 0.5), e.getPlayer(), rein.getType()); - } - rein.setHealth(-1); - return; - } - if (hasAccess) { - CitadelUtility.sendAndLog(e.getPlayer(), ChatColor.GREEN, - "You could bypass this reinforcement if you turn bypass mode on with '/ctb'", - e.getBlock().getLocation()); - } - e.setCancelled(true); - float damage = ReinforcementLogic.getDamageApplied(rein); - ReinforcementDamageEvent dre = new ReinforcementDamageEvent(e.getPlayer(), rein, damage); - Bukkit.getPluginManager().callEvent(dre); - if (dre.isCancelled()) { - return; - } - damage = dre.getDamageDone(); - ReinforcementLogic.damageReinforcement(rein, damage, e.getPlayer()); - if (rein.getHealth() <= 0) { - // in the case of double chests or similar there might now be another rein - // protecting this block - Reinforcement backupRein = ReinforcementLogic.getReinforcementProtecting(e.getBlock()); - if (backupRein == null) { - e.setCancelled(false); - ReinforcedBlockBreak rbbe = new ReinforcedBlockBreak(e.getPlayer(), rein, e); - Bukkit.getPluginManager().callEvent(rbbe); - } - } - } + public void handleBreakBlock(BlockBreakEvent e) { + Reinforcement rein = ReinforcementLogic.getReinforcementProtecting(e.getBlock()); + if (rein == null) { + // no reinforcement, normal break which we dont care about + return; + } + if (CitadelUtility.isPlant(e.getBlock())) { + if (rein.hasPermission(e.getPlayer(), CitadelPermissionHandler.getCrops()) + && !e.getBlock().getLocation().equals(rein.getLocation())) { + // allow, because player has crop permission and the only reinforcement + // protecting is in the soil + return; + } + } + boolean hasAccess = rein.hasPermission(e.getPlayer(), CitadelPermissionHandler.getBypass()); + BooleanSetting setting = (BooleanSetting) PlayerSettingAPI.getSetting("citadelBypass"); + boolean hasByPass = setting.getValue(e.getPlayer()); + if (hasAccess && hasByPass) { + ReinforcementBypassEvent bypassEvent = new ReinforcementBypassEvent(e.getPlayer(), rein); + Bukkit.getPluginManager().callEvent(bypassEvent); + if (bypassEvent.isCancelled()) { + e.setCancelled(true); + return; + } + if (rein.rollForItemReturn()) { + giveReinforcement(e.getBlock().getLocation().clone().add(0.5, 0.5, 0.5), e.getPlayer(), rein.getType()); + } + rein.setHealth(-1); + return; + } + if (hasAccess) { + CitadelUtility.sendAndLog(e.getPlayer(), ChatColor.GREEN, + "You could bypass this reinforcement if you turn bypass mode on with '/ctb'", + e.getBlock().getLocation()); + } + e.setCancelled(true); + float damage = ReinforcementLogic.getDamageApplied(rein); + ReinforcementDamageEvent dre = new ReinforcementDamageEvent(e.getPlayer(), rein, damage); + Bukkit.getPluginManager().callEvent(dre); + if (dre.isCancelled()) { + return; + } + damage = dre.getDamageDone(); + ReinforcementLogic.damageReinforcement(rein, damage, e.getPlayer()); + if (rein.getHealth() <= 0) { + // in the case of double chests or similar there might now be another rein + // protecting this block + Reinforcement backupRein = ReinforcementLogic.getReinforcementProtecting(e.getBlock()); + if (backupRein == null) { + e.setCancelled(false); + ReinforcedBlockBreak rbbe = new ReinforcedBlockBreak(e.getPlayer(), rein, e); + Bukkit.getPluginManager().callEvent(rbbe); + } + } + } - public abstract void handleInteractBlock(PlayerInteractEvent e); + public abstract void handleInteractBlock(PlayerInteractEvent e); - protected static void giveReinforcement(Location location, Player p, ReinforcementType type) { - HashMap notAdded = p.getInventory().addItem(type.getItem().clone()); - if (!notAdded.isEmpty()) { - DelayedItemDrop.dropAt(location, type.getItem().clone()); - } - } + protected static void giveReinforcement(Location location, Player p, ReinforcementType type) { + HashMap notAdded = p.getInventory().addItem(type.getItem().clone()); + if (!notAdded.isEmpty()) { + DelayedItemDrop.dropAt(location, type.getItem().clone()); + } + } - public abstract String getOverlayText(); + public abstract String getOverlayText(); - @Override - public abstract boolean equals(Object o); + @Override + public abstract boolean equals(Object o); } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/playerstate/AdvancedFortificationState.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/playerstate/AdvancedFortificationState.java index 1432c5dbe..408ba32bc 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/playerstate/AdvancedFortificationState.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/playerstate/AdvancedFortificationState.java @@ -15,85 +15,85 @@ import vg.civcraft.mc.namelayer.group.Group; public class AdvancedFortificationState extends AbstractPlayerState { - private Map setups; + private Map setups; - public AdvancedFortificationState(Player p) { - super(p); - setups = new HashMap<>(); - } + public AdvancedFortificationState(Player p) { + super(p); + setups = new HashMap<>(); + } - @Override - public String getName() { - return "Advanced fortification mode"; - } + @Override + public String getName() { + return "Advanced fortification mode"; + } - @Override - public void handleBlockPlace(BlockPlaceEvent e) { - ItemStack placed = e.getItemInHand(); - Player player = e.getPlayer(); - // check if we have a setup for this block, we need a copy for lookup so we can - // set amount to 1 - ItemStack lookUpCopy = placed.clone(); - lookUpCopy.setAmount(1); - ReinforcingSetup setup = setups.get(lookUpCopy); - if (setup == null) { - CitadelUtility.sendAndLog(player, ChatColor.RED, - "No setup configured for this block type, no reinforcement was applied"); - return; - } - boolean hadError = CitadelUtility.attemptReinforcementCreation(e.getBlock(), setup.type, setup.group, e.getPlayer()); - if (hadError) { - e.setCancelled(true); - Citadel.getInstance().getStateManager().setState(e.getPlayer(), null); - } - } + @Override + public void handleBlockPlace(BlockPlaceEvent e) { + ItemStack placed = e.getItemInHand(); + Player player = e.getPlayer(); + // check if we have a setup for this block, we need a copy for lookup so we can + // set amount to 1 + ItemStack lookUpCopy = placed.clone(); + lookUpCopy.setAmount(1); + ReinforcingSetup setup = setups.get(lookUpCopy); + if (setup == null) { + CitadelUtility.sendAndLog(player, ChatColor.RED, + "No setup configured for this block type, no reinforcement was applied"); + return; + } + boolean hadError = CitadelUtility.attemptReinforcementCreation(e.getBlock(), setup.type, setup.group, e.getPlayer()); + if (hadError) { + e.setCancelled(true); + Citadel.getInstance().getStateManager().setState(e.getPlayer(), null); + } + } - public void addSetup(ItemStack forBlock, ReinforcementType type, Group group) { - ItemStack copy = forBlock.clone(); - copy.setAmount(1); - ReinforcingSetup existing = setups.get(copy); - setups.put(copy, new ReinforcingSetup(type, group)); - Player player = Bukkit.getPlayer(uuid); - if (player != null) { - if (existing != null) { - CitadelUtility.sendAndLog(player, ChatColor.GOLD, - "Replaced existing setup with " + ChatColor.AQUA + existing.type.getName() + ChatColor.GOLD - + " on " + ChatColor.LIGHT_PURPLE + existing.group.getName() + ChatColor.GOLD + "for " - + copy.getType() + " with " + ChatColor.AQUA + type.getName() + ChatColor.GOLD + " on " - + ChatColor.LIGHT_PURPLE + group.getName()); - } else { - CitadelUtility.sendAndLog(player, ChatColor.GOLD, copy.getType() + " will be reinforced with " + ChatColor.AQUA - + type.getName() + ChatColor.GOLD + " on " + ChatColor.LIGHT_PURPLE + group.getName()); - } - } - } + public void addSetup(ItemStack forBlock, ReinforcementType type, Group group) { + ItemStack copy = forBlock.clone(); + copy.setAmount(1); + ReinforcingSetup existing = setups.get(copy); + setups.put(copy, new ReinforcingSetup(type, group)); + Player player = Bukkit.getPlayer(uuid); + if (player != null) { + if (existing != null) { + CitadelUtility.sendAndLog(player, ChatColor.GOLD, + "Replaced existing setup with " + ChatColor.AQUA + existing.type.getName() + ChatColor.GOLD + + " on " + ChatColor.LIGHT_PURPLE + existing.group.getName() + ChatColor.GOLD + "for " + + copy.getType() + " with " + ChatColor.AQUA + type.getName() + ChatColor.GOLD + " on " + + ChatColor.LIGHT_PURPLE + group.getName()); + } else { + CitadelUtility.sendAndLog(player, ChatColor.GOLD, copy.getType() + " will be reinforced with " + ChatColor.AQUA + + type.getName() + ChatColor.GOLD + " on " + ChatColor.LIGHT_PURPLE + group.getName()); + } + } + } - @Override - public void handleInteractBlock(PlayerInteractEvent e) { + @Override + public void handleInteractBlock(PlayerInteractEvent e) { - } + } - private class ReinforcingSetup { + private class ReinforcingSetup { - ReinforcementType type; - Group group; + ReinforcementType type; + Group group; - ReinforcingSetup(ReinforcementType type, Group group) { - this.type = type; - this.group = group; - } + ReinforcingSetup(ReinforcementType type, Group group) { + this.type = type; + this.group = group; + } - } + } - @Override - public boolean equals(Object o) { - //just always make a new state for this one - return false; - } + @Override + public boolean equals(Object o) { + //just always make a new state for this one + return false; + } - @Override - public String getOverlayText() { - return ChatColor.GOLD + "CTAF"; - } + @Override + public String getOverlayText() { + return ChatColor.GOLD + "CTAF"; + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/playerstate/FortificationState.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/playerstate/FortificationState.java index 3aa6f8098..9b52ebc3f 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/playerstate/FortificationState.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/playerstate/FortificationState.java @@ -13,59 +13,60 @@ import vg.civcraft.mc.namelayer.group.Group; public class FortificationState extends AbstractPlayerState { - private final ReinforcementType type; - private final Group group; + private final ReinforcementType type; + private final Group group; - public FortificationState(Player player, ReinforcementType type, Group group) { - super(player); - this.type = type; - this.group = group; - } + public FortificationState(Player player, ReinforcementType type, Group group) { + super(player); + this.type = type; + this.group = group; + } - public Group getGroup() { - return group; - } + public Group getGroup() { + return group; + } - @Override - public String getName() { - return "Fortifying mode with " + ChatColor.AQUA + type.getName() + ChatColor.YELLOW + " on " - + ChatColor.LIGHT_PURPLE + group.getName(); - } + @Override + public String getName() { + return "Fortifying mode with " + ChatColor.AQUA + type.getName() + ChatColor.YELLOW + " on " + + ChatColor.LIGHT_PURPLE + group.getName(); + } - public ReinforcementType getType() { - return type; - } + public ReinforcementType getType() { + return type; + } - @Override - public void handleBlockPlace(BlockPlaceEvent event) { - Player player = event.getPlayer(); - Block block = event.getBlock(); - // Prevent double reinforcement (slabs) - if (ReinforcementLogic.getReinforcementAt(block.getLocation()) != null) { - return; - } - if (CitadelUtility.attemptReinforcementCreation(block, type, group, player)) { // true == fail - Citadel.getInstance().getStateManager().setState(player, null); - event.setCancelled(true); - //return; - } - } + @Override + public void handleBlockPlace(BlockPlaceEvent event) { + Player player = event.getPlayer(); + Block block = event.getBlock(); + // Prevent double reinforcement (slabs) + if (ReinforcementLogic.getReinforcementAt(block.getLocation()) != null) { + return; + } + if (CitadelUtility.attemptReinforcementCreation(block, type, group, player)) { // true == fail + Citadel.getInstance().getStateManager().setState(player, null); + event.setCancelled(true); + //return; + } + } - @Override - public void handleInteractBlock(PlayerInteractEvent event) { } + @Override + public void handleInteractBlock(PlayerInteractEvent event) { + } - @Override - public boolean equals(Object other) { - if (!(other instanceof FortificationState)) { - return false; - } - FortificationState fort = (FortificationState) other; - return fort.type == this.type && fort.group.getName().equals(this.getGroup().getName()); - } + @Override + public boolean equals(Object other) { + if (!(other instanceof FortificationState)) { + return false; + } + FortificationState fort = (FortificationState) other; + return fort.type == this.type && fort.group.getName().equals(this.getGroup().getName()); + } - @Override - public String getOverlayText() { - return String.format("%sCTF %s%s %s%s", ChatColor.GOLD, ChatColor.LIGHT_PURPLE, group.getName(), ChatColor.AQUA, - type.getName()); - } + @Override + public String getOverlayText() { + return String.format("%sCTF %s%s %s%s", ChatColor.GOLD, ChatColor.LIGHT_PURPLE, group.getName(), ChatColor.AQUA, + type.getName()); + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/playerstate/InsecureState.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/playerstate/InsecureState.java index 948b41b4c..4eea6f466 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/playerstate/InsecureState.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/playerstate/InsecureState.java @@ -11,51 +11,51 @@ import vg.civcraft.mc.citadel.model.Reinforcement; public class InsecureState extends AbstractPlayerState { - public InsecureState(Player p) { - super(p); - } + public InsecureState(Player p) { + super(p); + } - @Override - public String getName() { - return "Insecure mode"; - } + @Override + public String getName() { + return "Insecure mode"; + } - @Override - public void handleBlockPlace(BlockPlaceEvent e) { - } + @Override + public void handleBlockPlace(BlockPlaceEvent e) { + } - @Override - public void handleInteractBlock(PlayerInteractEvent e) { - Reinforcement rein = ReinforcementLogic.getReinforcementProtecting(e.getClickedBlock()); - if (rein == null) { - return; - } - e.setCancelled(true); - if (rein.hasPermission(e.getPlayer(), CitadelPermissionHandler.getInsecure())) { - rein.toggleInsecure(); - if (rein.isInsecure()) { - CitadelUtility.sendAndLog(e.getPlayer(), ChatColor.YELLOW, - e.getClickedBlock().getType().name() + " is now insecure", - e.getClickedBlock().getLocation()); - } else { - CitadelUtility.sendAndLog(e.getPlayer(), ChatColor.GREEN, - e.getClickedBlock().getType().name() + " is now secure", - e.getClickedBlock().getLocation()); - } - } else { - CitadelUtility.sendAndLog(e.getPlayer(), ChatColor.RED, - "You are not allowed to make this reinforcement insecure", - e.getClickedBlock().getLocation()); - } - } + @Override + public void handleInteractBlock(PlayerInteractEvent e) { + Reinforcement rein = ReinforcementLogic.getReinforcementProtecting(e.getClickedBlock()); + if (rein == null) { + return; + } + e.setCancelled(true); + if (rein.hasPermission(e.getPlayer(), CitadelPermissionHandler.getInsecure())) { + rein.toggleInsecure(); + if (rein.isInsecure()) { + CitadelUtility.sendAndLog(e.getPlayer(), ChatColor.YELLOW, + e.getClickedBlock().getType().name() + " is now insecure", + e.getClickedBlock().getLocation()); + } else { + CitadelUtility.sendAndLog(e.getPlayer(), ChatColor.GREEN, + e.getClickedBlock().getType().name() + " is now secure", + e.getClickedBlock().getLocation()); + } + } else { + CitadelUtility.sendAndLog(e.getPlayer(), ChatColor.RED, + "You are not allowed to make this reinforcement insecure", + e.getClickedBlock().getLocation()); + } + } - @Override - public boolean equals(Object o) { - return o instanceof InsecureState; - } + @Override + public boolean equals(Object o) { + return o instanceof InsecureState; + } - @Override - public String getOverlayText() { - return ChatColor.GREEN + "CTIN"; - } + @Override + public String getOverlayText() { + return ChatColor.GREEN + "CTIN"; + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/playerstate/NormalState.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/playerstate/NormalState.java index 50d36bbc5..f131a4bfa 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/playerstate/NormalState.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/playerstate/NormalState.java @@ -15,64 +15,64 @@ import vg.civcraft.mc.namelayer.group.Group; public class NormalState extends AbstractPlayerState { - public NormalState(Player p) { - super(p); - } + public NormalState(Player p) { + super(p); + } - @Override - public String getName() { - return ChatColor.GREEN + "Normal mode"; - } + @Override + public String getName() { + return ChatColor.GREEN + "Normal mode"; + } - @Override - public void handleBlockPlace(BlockPlaceEvent e) { - Player player = e.getPlayer(); - if (!Citadel.getInstance().getSettingManager().isInEasyMode(player.getUniqueId())) { - return; - } - ItemStack offHand = player.getInventory().getItemInOffHand(); - ReinforcementType type = Citadel.getInstance().getReinforcementTypeManager().getByItemStack(offHand, player.getWorld().getName()); - if (type == null) { - return; - } - String defaultGroupName = NameAPI.getGroupManager().getDefaultGroup(player.getUniqueId()); - Group defaultGroup = GroupManager.getGroup(defaultGroupName); - if (defaultGroup == null) { - return; - } - CitadelUtility.attemptReinforcementCreation(e.getBlock(), type, defaultGroup, player); - } + @Override + public void handleBlockPlace(BlockPlaceEvent e) { + Player player = e.getPlayer(); + if (!Citadel.getInstance().getSettingManager().isInEasyMode(player.getUniqueId())) { + return; + } + ItemStack offHand = player.getInventory().getItemInOffHand(); + ReinforcementType type = Citadel.getInstance().getReinforcementTypeManager().getByItemStack(offHand, player.getWorld().getName()); + if (type == null) { + return; + } + String defaultGroupName = NameAPI.getGroupManager().getDefaultGroup(player.getUniqueId()); + Group defaultGroup = GroupManager.getGroup(defaultGroupName); + if (defaultGroup == null) { + return; + } + CitadelUtility.attemptReinforcementCreation(e.getBlock(), type, defaultGroup, player); + } - @Override - public void handleInteractBlock(PlayerInteractEvent e) { - if (e.getAction() != Action.LEFT_CLICK_BLOCK) { - return; - } - Player player = e.getPlayer(); - if (!Citadel.getInstance().getSettingManager().isInEasyMode(player.getUniqueId())) { - return; - } - ItemStack hand = player.getInventory().getItemInMainHand(); - ReinforcementType type = Citadel.getInstance().getReinforcementTypeManager().getByItemStack(hand, player.getWorld().getName()); - if (type == null) { - return; - } - String defaultGroupName = NameAPI.getGroupManager().getDefaultGroup(player.getUniqueId()); - Group defaultGroup = GroupManager.getGroup(defaultGroupName); - if (defaultGroup == null) { - return; - } - CitadelUtility.attemptReinforcementCreation(e.getClickedBlock(), type, defaultGroup, player); - } + @Override + public void handleInteractBlock(PlayerInteractEvent e) { + if (e.getAction() != Action.LEFT_CLICK_BLOCK) { + return; + } + Player player = e.getPlayer(); + if (!Citadel.getInstance().getSettingManager().isInEasyMode(player.getUniqueId())) { + return; + } + ItemStack hand = player.getInventory().getItemInMainHand(); + ReinforcementType type = Citadel.getInstance().getReinforcementTypeManager().getByItemStack(hand, player.getWorld().getName()); + if (type == null) { + return; + } + String defaultGroupName = NameAPI.getGroupManager().getDefaultGroup(player.getUniqueId()); + Group defaultGroup = GroupManager.getGroup(defaultGroupName); + if (defaultGroup == null) { + return; + } + CitadelUtility.attemptReinforcementCreation(e.getClickedBlock(), type, defaultGroup, player); + } - @Override - public boolean equals(Object o) { - return o instanceof NormalState; - } + @Override + public boolean equals(Object o) { + return o instanceof NormalState; + } - @Override - public String getOverlayText() { - return null; - } + @Override + public String getOverlayText() { + return null; + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/playerstate/PatchState.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/playerstate/PatchState.java index 686b46ec8..3d04017f4 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/playerstate/PatchState.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/playerstate/PatchState.java @@ -16,91 +16,91 @@ import vg.civcraft.mc.civmodcore.inventory.items.ItemMap; public class PatchState extends AbstractPlayerState { - public PatchState(Player p) { - super(p); - } + public PatchState(Player p) { + super(p); + } - @Override - public String getName() { - return "Patch mode"; - } + @Override + public String getName() { + return "Patch mode"; + } - @Override - public void handleBlockPlace(BlockPlaceEvent e) { + @Override + public void handleBlockPlace(BlockPlaceEvent e) { - } + } - @Override - public void handleInteractBlock(PlayerInteractEvent e) { - Reinforcement rein = ReinforcementLogic.getReinforcementProtecting(e.getClickedBlock()); - Player player = e.getPlayer(); - if (rein == null) { - CitadelUtility.sendAndLog(player, ChatColor.RED, - "This block is not reinforced", - e.getClickedBlock().getLocation()); - return; - } - if (!rein.hasPermission(player, CitadelPermissionHandler.getRepair())) { - CitadelUtility.sendAndLog(player, ChatColor.RED, - "You do not have permission to repair reinforcements on this group", - e.getClickedBlock().getLocation()); - return; - } - if (rein.getHealth() >= rein.getType().getHealth()) { - if (rein.hasPermission(player, CitadelPermissionHandler.getRepair())) { - CitadelUtility.sendAndLog(player, ChatColor.GOLD, - "Reinforcement is already at " + ModeListener.formatHealth(rein) + ChatColor.GOLD - + " health with " + ChatColor.AQUA + rein.getType().getName() + ChatColor.GOLD - + " on " + ChatColor.LIGHT_PURPLE + rein.getGroup().getName(), - e.getClickedBlock().getLocation()); - } else { - CitadelUtility.sendAndLog(player, ChatColor.GOLD, - "Reinforcement is already at " + ModeListener.formatHealth(rein) + ChatColor.GOLD + " health", - e.getClickedBlock().getLocation()); - } - return; - } - ItemMap playerMap = new ItemMap(player.getInventory()); - if (playerMap.getAmount(rein.getType().getItem()) <= 0) { - CitadelUtility.sendAndLog(player, ChatColor.RED, - "You don't have the item required to repair " + ChatColor.AQUA - + rein.getType().getName() + ChatColor.GOLD + " reinforcements", - e.getClickedBlock().getLocation()); - return; - } - ReinforcementRepairEvent repairEvent = new ReinforcementRepairEvent(e.getPlayer(), rein); - Bukkit.getPluginManager().callEvent(repairEvent); - if (repairEvent.isCancelled()) { - return; - } - if (!rein.rollForItemReturn()) { - if (!CitadelUtility.consumeReinforcementItems(player, rein.getType(), false)) { - return; - } - } + @Override + public void handleInteractBlock(PlayerInteractEvent e) { + Reinforcement rein = ReinforcementLogic.getReinforcementProtecting(e.getClickedBlock()); + Player player = e.getPlayer(); + if (rein == null) { + CitadelUtility.sendAndLog(player, ChatColor.RED, + "This block is not reinforced", + e.getClickedBlock().getLocation()); + return; + } + if (!rein.hasPermission(player, CitadelPermissionHandler.getRepair())) { + CitadelUtility.sendAndLog(player, ChatColor.RED, + "You do not have permission to repair reinforcements on this group", + e.getClickedBlock().getLocation()); + return; + } + if (rein.getHealth() >= rein.getType().getHealth()) { + if (rein.hasPermission(player, CitadelPermissionHandler.getRepair())) { + CitadelUtility.sendAndLog(player, ChatColor.GOLD, + "Reinforcement is already at " + ModeListener.formatHealth(rein) + ChatColor.GOLD + + " health with " + ChatColor.AQUA + rein.getType().getName() + ChatColor.GOLD + + " on " + ChatColor.LIGHT_PURPLE + rein.getGroup().getName(), + e.getClickedBlock().getLocation()); + } else { + CitadelUtility.sendAndLog(player, ChatColor.GOLD, + "Reinforcement is already at " + ModeListener.formatHealth(rein) + ChatColor.GOLD + " health", + e.getClickedBlock().getLocation()); + } + return; + } + ItemMap playerMap = new ItemMap(player.getInventory()); + if (playerMap.getAmount(rein.getType().getItem()) <= 0) { + CitadelUtility.sendAndLog(player, ChatColor.RED, + "You don't have the item required to repair " + ChatColor.AQUA + + rein.getType().getName() + ChatColor.GOLD + " reinforcements", + e.getClickedBlock().getLocation()); + return; + } + ReinforcementRepairEvent repairEvent = new ReinforcementRepairEvent(e.getPlayer(), rein); + Bukkit.getPluginManager().callEvent(repairEvent); + if (repairEvent.isCancelled()) { + return; + } + if (!rein.rollForItemReturn()) { + if (!CitadelUtility.consumeReinforcementItems(player, rein.getType(), false)) { + return; + } + } - CitadelUtility.sendAndLog( - player, - ChatColor.GOLD, "Patching " - + ChatColor.AQUA + rein.getType().getName() - + ChatColor.GOLD + " reinforcement owned by " - + ChatColor.LIGHT_PURPLE + rein.getGroup().getName() - + ChatColor.GOLD + " from " - + ModeListener.formatHealth(rein), - e.getClickedBlock().getLocation() - ); + CitadelUtility.sendAndLog( + player, + ChatColor.GOLD, "Patching " + + ChatColor.AQUA + rein.getType().getName() + + ChatColor.GOLD + " reinforcement owned by " + + ChatColor.LIGHT_PURPLE + rein.getGroup().getName() + + ChatColor.GOLD + " from " + + ModeListener.formatHealth(rein), + e.getClickedBlock().getLocation() + ); - rein.setHealth(rein.getType().getHealth()); - rein.resetCreationTime(); - } + rein.setHealth(rein.getType().getHealth()); + rein.resetCreationTime(); + } - @Override - public boolean equals(Object o) { - return o instanceof PatchMode; - } + @Override + public boolean equals(Object o) { + return o instanceof PatchMode; + } - @Override - public String getOverlayText() { - return ChatColor.GREEN + "CTP"; - } + @Override + public String getOverlayText() { + return ChatColor.GREEN + "CTP"; + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/playerstate/PlayerStateManager.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/playerstate/PlayerStateManager.java index 133cbefc4..3c2555c12 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/playerstate/PlayerStateManager.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/playerstate/PlayerStateManager.java @@ -11,48 +11,48 @@ import vg.civcraft.mc.citadel.events.ReinforcementModeSwitchEvent; public class PlayerStateManager { - private Map playerStateMap; + private Map playerStateMap; - public PlayerStateManager() { - this.playerStateMap = new TreeMap<>(); - } + public PlayerStateManager() { + this.playerStateMap = new TreeMap<>(); + } - public AbstractPlayerState getState(Player player) { - if (player == null) { - throw new IllegalArgumentException("Can not get state for null player"); - } - AbstractPlayerState state = playerStateMap.get(player.getUniqueId()); - if (state == null) { - state = new NormalState(player); - playerStateMap.put(player.getUniqueId(), state); - } - return state; - } + public AbstractPlayerState getState(Player player) { + if (player == null) { + throw new IllegalArgumentException("Can not get state for null player"); + } + AbstractPlayerState state = playerStateMap.get(player.getUniqueId()); + if (state == null) { + state = new NormalState(player); + playerStateMap.put(player.getUniqueId(), state); + } + return state; + } - public void setState(Player player, AbstractPlayerState state) { - if (player == null) { - throw new IllegalArgumentException("Can not set state for null player"); - } - AbstractPlayerState existingState = getState(player); - if (existingState == null) { - existingState = new NormalState(player); - } - // null state is allowed, it just resets the state - if (state == null) { - state = new NormalState(player); - } - if (existingState.equals(state)) { - CitadelUtility.sendAndLog(player, ChatColor.GOLD, "You are still in " + ChatColor.YELLOW + state.getName()); - return; - } - ReinforcementModeSwitchEvent switchEvent = new ReinforcementModeSwitchEvent(player, existingState, state); - Bukkit.getPluginManager().callEvent(switchEvent); - if (switchEvent.isCancelled()) { - return; - } - playerStateMap.put(player.getUniqueId(), state); - CitadelUtility.sendAndLog(player, ChatColor.GOLD, "Switched Citadel mode to " + ChatColor.YELLOW - + state.getName() + ChatColor.GOLD + " from " + ChatColor.YELLOW + existingState.getName()); - } + public void setState(Player player, AbstractPlayerState state) { + if (player == null) { + throw new IllegalArgumentException("Can not set state for null player"); + } + AbstractPlayerState existingState = getState(player); + if (existingState == null) { + existingState = new NormalState(player); + } + // null state is allowed, it just resets the state + if (state == null) { + state = new NormalState(player); + } + if (existingState.equals(state)) { + CitadelUtility.sendAndLog(player, ChatColor.GOLD, "You are still in " + ChatColor.YELLOW + state.getName()); + return; + } + ReinforcementModeSwitchEvent switchEvent = new ReinforcementModeSwitchEvent(player, existingState, state); + Bukkit.getPluginManager().callEvent(switchEvent); + if (switchEvent.isCancelled()) { + return; + } + playerStateMap.put(player.getUniqueId(), state); + CitadelUtility.sendAndLog(player, ChatColor.GOLD, "Switched Citadel mode to " + ChatColor.YELLOW + + state.getName() + ChatColor.GOLD + " from " + ChatColor.YELLOW + existingState.getName()); + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/playerstate/ReinforcingState.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/playerstate/ReinforcingState.java index fd7800be2..8e7e9c2f9 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/playerstate/ReinforcingState.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/playerstate/ReinforcingState.java @@ -20,168 +20,168 @@ import vg.civcraft.mc.namelayer.group.Group; public class ReinforcingState extends AbstractPlayerState { - private Group group; + private Group group; - public ReinforcingState(Player p, Group group) { - super(p); - this.group = group; - } + public ReinforcingState(Player p, Group group) { + super(p); + this.group = group; + } - public Group getGroup() { - return group; - } + public Group getGroup() { + return group; + } - @Override - public String getName() { - return "Reinforcing mode on " + ChatColor.LIGHT_PURPLE + group.getName(); - } + @Override + public String getName() { + return "Reinforcing mode on " + ChatColor.LIGHT_PURPLE + group.getName(); + } - @Override - public void handleBlockPlace(BlockPlaceEvent e) { - } + @Override + public void handleBlockPlace(BlockPlaceEvent e) { + } - @Override - public void handleInteractBlock(PlayerInteractEvent e) { - // always cancel - e.setCancelled(true); - // does group still exist? - if (!group.isValid()) { - CitadelUtility.sendAndLog(e.getPlayer(), ChatColor.RED, - "The group " + group.getName() + " seems to have been deleted in the mean time"); - Citadel.getInstance().getStateManager().setState(e.getPlayer(), null); - return; - } - Player player = e.getPlayer(); - // does the player have an item? - if (e.getItem() == null) { - CitadelUtility.sendAndLog(player, ChatColor.RED, "You have nothing in your hand to reinforce with", - e.getClickedBlock().getLocation()); - return; - } - ReinforcementType type = Citadel.getInstance().getReinforcementTypeManager().getByItemStack(e.getItem(), player.getWorld().getName()); - // is it a valid item to reinforce with - if (type == null) { - CitadelUtility.sendAndLog(player, ChatColor.RED, "You can not reinforce with this item", - e.getClickedBlock().getLocation()); - return; - } - Block block = ReinforcementLogic.getResponsibleBlock(e.getClickedBlock()); - // can the item reinforce the clicked block - if (!type.canBeReinforced(block.getType())) { - CitadelUtility.sendAndLog(player, ChatColor.RED, - type.getName() + " can not reinforce " + block.getType(), - block.getLocation()); - return; - } - // is the reinforcement item allowed in the current world - if (!type.isAllowedInWorld(block.getWorld().getName())) { - CitadelUtility.sendAndLog(player, ChatColor.RED, - type.getName() + " cannot reinforce in this dimension", block.getLocation()); - return; - } - // does the player have permission to reinforce on that group - if (!NameAPI.getGroupManager().hasAccess(group, e.getPlayer().getUniqueId(), - CitadelPermissionHandler.getReinforce())) { - CitadelUtility.sendAndLog(e.getPlayer(), ChatColor.RED, - "You seem to have lost permission to reinforce on " + group.getName(), - e.getClickedBlock().getLocation()); - Citadel.getInstance().getStateManager().setState(e.getPlayer(), null); - return; - } - Reinforcement rein = ReinforcementLogic.getReinforcementProtecting(block); - // if reinforcement exists, check if player has permission to edit it - if (rein != null) { - if (!rein.hasPermission(e.getPlayer(), CitadelPermissionHandler.getBypass())) { - CitadelUtility.sendAndLog(e.getPlayer(), ChatColor.RED, - "You do not have permission to bypass this reinforcement", - e.getClickedBlock().getLocation()); - return; - } - } - Reinforcement newRein = null; - if (rein == null || rein.getType() != type) { - // check inventory for reinforcement item - ItemMap toConsume = new ItemMap(type.getItem()); - if (!toConsume.isContainedIn(player.getInventory())) { - CitadelUtility.sendAndLog(e.getPlayer(), ChatColor.RED, "No reinforcing item found in your inventory?", - e.getClickedBlock().getLocation()); - return; - } - if (rein == null) { - newRein = ReinforcementLogic.callReinforcementCreationEvent(player, block, type, group); - if (newRein == null) { - //event was cancelled, error message is up to whoever cancelled it - return; - } - } - // consume item from inventory - if (!toConsume.removeSafelyFrom(player.getInventory())) { - CitadelUtility.sendAndLog(e.getPlayer(), ChatColor.RED, - "Failed to remove reinforcement item from your inventory", - e.getClickedBlock().getLocation()); - return; - } - } + @Override + public void handleInteractBlock(PlayerInteractEvent e) { + // always cancel + e.setCancelled(true); + // does group still exist? + if (!group.isValid()) { + CitadelUtility.sendAndLog(e.getPlayer(), ChatColor.RED, + "The group " + group.getName() + " seems to have been deleted in the mean time"); + Citadel.getInstance().getStateManager().setState(e.getPlayer(), null); + return; + } + Player player = e.getPlayer(); + // does the player have an item? + if (e.getItem() == null) { + CitadelUtility.sendAndLog(player, ChatColor.RED, "You have nothing in your hand to reinforce with", + e.getClickedBlock().getLocation()); + return; + } + ReinforcementType type = Citadel.getInstance().getReinforcementTypeManager().getByItemStack(e.getItem(), player.getWorld().getName()); + // is it a valid item to reinforce with + if (type == null) { + CitadelUtility.sendAndLog(player, ChatColor.RED, "You can not reinforce with this item", + e.getClickedBlock().getLocation()); + return; + } + Block block = ReinforcementLogic.getResponsibleBlock(e.getClickedBlock()); + // can the item reinforce the clicked block + if (!type.canBeReinforced(block.getType())) { + CitadelUtility.sendAndLog(player, ChatColor.RED, + type.getName() + " can not reinforce " + block.getType(), + block.getLocation()); + return; + } + // is the reinforcement item allowed in the current world + if (!type.isAllowedInWorld(block.getWorld().getName())) { + CitadelUtility.sendAndLog(player, ChatColor.RED, + type.getName() + " cannot reinforce in this dimension", block.getLocation()); + return; + } + // does the player have permission to reinforce on that group + if (!NameAPI.getGroupManager().hasAccess(group, e.getPlayer().getUniqueId(), + CitadelPermissionHandler.getReinforce())) { + CitadelUtility.sendAndLog(e.getPlayer(), ChatColor.RED, + "You seem to have lost permission to reinforce on " + group.getName(), + e.getClickedBlock().getLocation()); + Citadel.getInstance().getStateManager().setState(e.getPlayer(), null); + return; + } + Reinforcement rein = ReinforcementLogic.getReinforcementProtecting(block); + // if reinforcement exists, check if player has permission to edit it + if (rein != null) { + if (!rein.hasPermission(e.getPlayer(), CitadelPermissionHandler.getBypass())) { + CitadelUtility.sendAndLog(e.getPlayer(), ChatColor.RED, + "You do not have permission to bypass this reinforcement", + e.getClickedBlock().getLocation()); + return; + } + } + Reinforcement newRein = null; + if (rein == null || rein.getType() != type) { + // check inventory for reinforcement item + ItemMap toConsume = new ItemMap(type.getItem()); + if (!toConsume.isContainedIn(player.getInventory())) { + CitadelUtility.sendAndLog(e.getPlayer(), ChatColor.RED, "No reinforcing item found in your inventory?", + e.getClickedBlock().getLocation()); + return; + } + if (rein == null) { + newRein = ReinforcementLogic.callReinforcementCreationEvent(player, block, type, group); + if (newRein == null) { + //event was cancelled, error message is up to whoever cancelled it + return; + } + } + // consume item from inventory + if (!toConsume.removeSafelyFrom(player.getInventory())) { + CitadelUtility.sendAndLog(e.getPlayer(), ChatColor.RED, + "Failed to remove reinforcement item from your inventory", + e.getClickedBlock().getLocation()); + return; + } + } - if (rein == null) { - if (Citadel.getInstance().getConfigManager().logCreation()) { - Citadel.getInstance().getLogger() - .info(player.getName() + " created reinforcement with " + type.getName() + " for " - + block.getType().toString() + " at " - + block.getLocation().toString()); - } - // just create new reinforcement - ReinforcementLogic.createReinforcement(newRein); - } else { - // replace existing one - boolean changedGroup = false; - if (group.getGroupId() != rein.getGroup().getGroupId()) { - // switch group - ReinforcementGroupChangeEvent rgce = new ReinforcementGroupChangeEvent(player, rein, group); - Bukkit.getPluginManager().callEvent(rgce); - if (!rgce.isCancelled()) { - rein.setGroup(group); - changedGroup = true; - } - // informing the user is up to whoever cancelled it - } - if (type != rein.getType()) { - // switch type - ReinforcementChangeTypeEvent rcte = new ReinforcementChangeTypeEvent(player, rein, type); - Bukkit.getPluginManager().callEvent(rcte); - if (!rcte.isCancelled()) { - if (rein.rollForItemReturn()) { - giveReinforcement(rein.getLocation().clone().add(0.5, 0.5, 0.5), e.getPlayer(), rein.getType()); - } - rein.setType(type); - rein.setHealth(type.getHealth()); - rein.resetCreationTime(); - CitadelUtility.sendAndLog(player, ChatColor.GREEN, - "Updated reinforcement to " + rein.getType().getName() + " on " + group.getName(), - e.getClickedBlock().getLocation()); - } else if (changedGroup) { - CitadelUtility.sendAndLog(player, ChatColor.GREEN, - "Updated group to " + ChatColor.LIGHT_PURPLE + group.getName(), - e.getClickedBlock().getLocation()); - } - } else if (changedGroup) { - CitadelUtility.sendAndLog(player, ChatColor.GREEN, - "Updated group to " + ChatColor.LIGHT_PURPLE + group.getName(), - e.getClickedBlock().getLocation()); - } - } - } + if (rein == null) { + if (Citadel.getInstance().getConfigManager().logCreation()) { + Citadel.getInstance().getLogger() + .info(player.getName() + " created reinforcement with " + type.getName() + " for " + + block.getType().toString() + " at " + + block.getLocation().toString()); + } + // just create new reinforcement + ReinforcementLogic.createReinforcement(newRein); + } else { + // replace existing one + boolean changedGroup = false; + if (group.getGroupId() != rein.getGroup().getGroupId()) { + // switch group + ReinforcementGroupChangeEvent rgce = new ReinforcementGroupChangeEvent(player, rein, group); + Bukkit.getPluginManager().callEvent(rgce); + if (!rgce.isCancelled()) { + rein.setGroup(group); + changedGroup = true; + } + // informing the user is up to whoever cancelled it + } + if (type != rein.getType()) { + // switch type + ReinforcementChangeTypeEvent rcte = new ReinforcementChangeTypeEvent(player, rein, type); + Bukkit.getPluginManager().callEvent(rcte); + if (!rcte.isCancelled()) { + if (rein.rollForItemReturn()) { + giveReinforcement(rein.getLocation().clone().add(0.5, 0.5, 0.5), e.getPlayer(), rein.getType()); + } + rein.setType(type); + rein.setHealth(type.getHealth()); + rein.resetCreationTime(); + CitadelUtility.sendAndLog(player, ChatColor.GREEN, + "Updated reinforcement to " + rein.getType().getName() + " on " + group.getName(), + e.getClickedBlock().getLocation()); + } else if (changedGroup) { + CitadelUtility.sendAndLog(player, ChatColor.GREEN, + "Updated group to " + ChatColor.LIGHT_PURPLE + group.getName(), + e.getClickedBlock().getLocation()); + } + } else if (changedGroup) { + CitadelUtility.sendAndLog(player, ChatColor.GREEN, + "Updated group to " + ChatColor.LIGHT_PURPLE + group.getName(), + e.getClickedBlock().getLocation()); + } + } + } - @Override - public boolean equals(Object o) { - if (!(o instanceof ReinforcingState)) { - return false; - } - return ((ReinforcingState) o).group.getName().equals(this.getGroup().getName()); - } + @Override + public boolean equals(Object o) { + if (!(o instanceof ReinforcingState)) { + return false; + } + return ((ReinforcingState) o).group.getName().equals(this.getGroup().getName()); + } - @Override - public String getOverlayText() { - return String.format("%sCTR %s%s", ChatColor.GOLD, ChatColor.LIGHT_PURPLE, group.getName()); - } + @Override + public String getOverlayText() { + return String.format("%sCTR %s%s", ChatColor.GOLD, ChatColor.LIGHT_PURPLE, group.getName()); + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/reinforcementtypes/ReinforcementEffect.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/reinforcementtypes/ReinforcementEffect.java index 6fdcdec4a..17f393164 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/reinforcementtypes/ReinforcementEffect.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/reinforcementtypes/ReinforcementEffect.java @@ -5,93 +5,88 @@ import org.bukkit.Particle; import vg.civcraft.mc.citadel.model.Reinforcement; public class ReinforcementEffect { - private Particle particle; - private float offsetX; - private float offsetY; - private float offsetZ; - private float speed; - private int particleCount; - public ReinforcementEffect(Particle particle, float offsetX, float offsetY, float offsetZ, float speed, - int particleCount) { - this.particle = particle; - this.offsetX = offsetX; - this.offsetY = offsetY; - this.offsetZ = offsetZ; - this.speed = speed; - this.particleCount = particleCount; - } + private Particle particle; + private float offsetX; + private float offsetY; + private float offsetZ; + private float speed; + private int particleCount; - /** - * - * @return the amount to be randomly offset by in the X axis - */ - public float getOffsetX() { - return offsetX; - } + public ReinforcementEffect(Particle particle, float offsetX, float offsetY, float offsetZ, float speed, + int particleCount) { + this.particle = particle; + this.offsetX = offsetX; + this.offsetY = offsetY; + this.offsetZ = offsetZ; + this.speed = speed; + this.particleCount = particleCount; + } - /** - * - * @return the amount to be randomly offset by in the Y axis - */ - public float getOffsetY() { - return offsetY; - } + /** + * @return the amount to be randomly offset by in the X axis + */ + public float getOffsetX() { + return offsetX; + } - /** - * - * @return the amount to be randomly offset by in the Z axis - */ - public float getOffsetZ() { - return offsetZ; - } + /** + * @return the amount to be randomly offset by in the Y axis + */ + public float getOffsetY() { + return offsetY; + } - /** - * - * @return the type of particle used in this effect - */ - public Particle getParticle() { - return particle; - } + /** + * @return the amount to be randomly offset by in the Z axis + */ + public float getOffsetZ() { + return offsetZ; + } - /** - * - * @return the amount of particle to display. - */ - public int getParticleCount() { - return particleCount; - } + /** + * @return the type of particle used in this effect + */ + public Particle getParticle() { + return particle; + } - /** - * - * @return the speed of the particles - */ - public float getSpeed() { - return speed; - } + /** + * @return the amount of particle to display. + */ + public int getParticleCount() { + return particleCount; + } - /** - * Display an effect defined in the config around a reinforcement. - * - * @param location the location of the reinforcement. - */ - public void playEffect(Location location) { - location.getWorld().spawnParticle(particle, location, particleCount, offsetX, offsetY, offsetZ, speed, null); - } - - /** - * Display an effect defined in the config around a reinforcement. - * - * @param reinforcement Reinforcement to play effect around - */ - public void playEffect(Reinforcement reinforcement) { - playEffect(reinforcement.getBlockCenter()); - } + /** + * @return the speed of the particles + */ + public float getSpeed() { + return speed; + } - @Override - public String toString() { - return String.format( - " type: %s \n offsetX: %f \n offsetY: %f \n offsetZ: %f \n speed: %f \n particleCount: %d", - particle, offsetX, offsetY, offsetZ, speed, particleCount); - } + /** + * Display an effect defined in the config around a reinforcement. + * + * @param location the location of the reinforcement. + */ + public void playEffect(Location location) { + location.getWorld().spawnParticle(particle, location, particleCount, offsetX, offsetY, offsetZ, speed, null); + } + + /** + * Display an effect defined in the config around a reinforcement. + * + * @param reinforcement Reinforcement to play effect around + */ + public void playEffect(Reinforcement reinforcement) { + playEffect(reinforcement.getBlockCenter()); + } + + @Override + public String toString() { + return String.format( + " type: %s \n offsetX: %f \n offsetY: %f \n offsetZ: %f \n speed: %f \n particleCount: %d", + particle, offsetX, offsetY, offsetZ, speed, particleCount); + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/reinforcementtypes/ReinforcementType.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/reinforcementtypes/ReinforcementType.java index 53c50910a..7fcb110eb 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/reinforcementtypes/ReinforcementType.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/reinforcementtypes/ReinforcementType.java @@ -8,218 +8,215 @@ import org.bukkit.inventory.ItemStack; public class ReinforcementType { - private float health; - private double returnChance; - private ItemStack item; - private long maturationTime; - private int acidPriority; - private long acidTime; - private double scale; - private long gracePeriod; - private ReinforcementEffect creationEffect; - private ReinforcementEffect damageEffect; - private ReinforcementEffect destructionEffect; - private Set allowedReinforceables; - private Set disallowedReinforceables; - private Set globalBlackList; - private short id; - private String name; - private long decayTimer; - private double decayMultiplier; - private double deletedGroupMulitplier; - private int legacyId; - private Set allowedWorlds; + private float health; + private double returnChance; + private ItemStack item; + private long maturationTime; + private int acidPriority; + private long acidTime; + private double scale; + private long gracePeriod; + private ReinforcementEffect creationEffect; + private ReinforcementEffect damageEffect; + private ReinforcementEffect destructionEffect; + private Set allowedReinforceables; + private Set disallowedReinforceables; + private Set globalBlackList; + private short id; + private String name; + private long decayTimer; + private double decayMultiplier; + private double deletedGroupMulitplier; + private int legacyId; + private Set allowedWorlds; - public ReinforcementType(float health, double returnChance, ItemStack item, long maturationTime, long acidTime, int acidPriority, - double scale, long gracePeriod, ReinforcementEffect creationEffect, ReinforcementEffect damageEffect, - ReinforcementEffect destructionEffect, Collection allowsReinforceables, - Collection disallowedReinforceables, short id, String name, Collection globalBlackList, - long decayTimer, double decayMultiplier, double deletedGroupMulitplier, int legacyId, Collection allowedWorlds) { - this.health = health; - this.name = name; - this.returnChance = returnChance; - this.item = item; - this.maturationTime = maturationTime; - this.acidTime = acidTime; - this.acidPriority = acidPriority; - this.scale = scale; - this.creationEffect = creationEffect; - this.damageEffect = damageEffect; - this.destructionEffect = destructionEffect; - this.gracePeriod = gracePeriod; - this.deletedGroupMulitplier = deletedGroupMulitplier; - if (!allowsReinforceables.isEmpty()) { - this.allowedReinforceables = new TreeSet<>(allowsReinforceables); - } else { - // can only black list OR white list - if (!disallowedReinforceables.isEmpty()) { - this.disallowedReinforceables = new TreeSet<>(disallowedReinforceables); - } - } - this.globalBlackList = new TreeSet<>(); - if (!globalBlackList.isEmpty()) { - this.globalBlackList.addAll(globalBlackList); - } - this.allowedWorlds = new TreeSet<>(); - if (!allowedWorlds.isEmpty()) - { - this.allowedWorlds.addAll(allowedWorlds); - } - this.id = id; - this.decayMultiplier = decayMultiplier; - this.decayTimer = decayTimer; - this.legacyId = legacyId; - } + public ReinforcementType(float health, double returnChance, ItemStack item, long maturationTime, long acidTime, int acidPriority, + double scale, long gracePeriod, ReinforcementEffect creationEffect, ReinforcementEffect damageEffect, + ReinforcementEffect destructionEffect, Collection allowsReinforceables, + Collection disallowedReinforceables, short id, String name, Collection globalBlackList, + long decayTimer, double decayMultiplier, double deletedGroupMulitplier, int legacyId, Collection allowedWorlds) { + this.health = health; + this.name = name; + this.returnChance = returnChance; + this.item = item; + this.maturationTime = maturationTime; + this.acidTime = acidTime; + this.acidPriority = acidPriority; + this.scale = scale; + this.creationEffect = creationEffect; + this.damageEffect = damageEffect; + this.destructionEffect = destructionEffect; + this.gracePeriod = gracePeriod; + this.deletedGroupMulitplier = deletedGroupMulitplier; + if (!allowsReinforceables.isEmpty()) { + this.allowedReinforceables = new TreeSet<>(allowsReinforceables); + } else { + // can only black list OR white list + if (!disallowedReinforceables.isEmpty()) { + this.disallowedReinforceables = new TreeSet<>(disallowedReinforceables); + } + } + this.globalBlackList = new TreeSet<>(); + if (!globalBlackList.isEmpty()) { + this.globalBlackList.addAll(globalBlackList); + } + this.allowedWorlds = new TreeSet<>(); + if (!allowedWorlds.isEmpty()) { + this.allowedWorlds.addAll(allowedWorlds); + } + this.id = id; + this.decayMultiplier = decayMultiplier; + this.decayTimer = decayTimer; + this.legacyId = legacyId; + } - public boolean canBeReinforced(Material mat) { - if (globalBlackList.contains(mat)) { - return false; - } - if (allowedReinforceables == null) { - return disallowedReinforceables == null || !disallowedReinforceables.contains(mat); - } - return allowedReinforceables.contains(mat); - } + public boolean canBeReinforced(Material mat) { + if (globalBlackList.contains(mat)) { + return false; + } + if (allowedReinforceables == null) { + return disallowedReinforceables == null || !disallowedReinforceables.contains(mat); + } + return allowedReinforceables.contains(mat); + } - public Set getAllowedWorlds() - { - return allowedWorlds; - } + public Set getAllowedWorlds() { + return allowedWorlds; + } - public boolean isAllowedInWorld(String worldName) - { - if (allowedWorlds.contains(worldName) || allowedWorlds.isEmpty()) - { - return true; - } + public boolean isAllowedInWorld(String worldName) { + if (allowedWorlds.contains(worldName) || allowedWorlds.isEmpty()) { + return true; + } - return false; - } + return false; + } - /** - * @return Returns the acid maturation time needed until this acid block is - * ready. - */ - public long getAcidTime() { - return acidTime; - } + /** + * @return Returns the acid maturation time needed until this acid block is + * ready. + */ + public long getAcidTime() { + return acidTime; + } - /** - * @return the time in milli seconds to "forgive" reinforcements and apply 100% - * return rate. Set to 0 to disable. - */ - public long getGracePeriod() { - return this.gracePeriod; - } + /** + * @return the time in milli seconds to "forgive" reinforcements and apply 100% + * return rate. Set to 0 to disable. + */ + public long getGracePeriod() { + return this.gracePeriod; + } - /** - * @return Maximum health - */ - public float getHealth() { - return health; - } + /** + * @return Maximum health + */ + public float getHealth() { + return health; + } - /** - * @return The unique id identifying this config - */ - public short getID() { - return id; - } - - /** - * @return Damage multiplier applied if the owning group was deleted - */ - public double getDeletedGroupMultiplier() { - return deletedGroupMulitplier; - } + /** + * @return The unique id identifying this config + */ + public short getID() { + return id; + } - /** - * @return Item used to create instance of this item - */ - public ItemStack getItem() { - return item; - } - - /** - * @return Acid priority of this type. Acid blocks can only remove blocks of lower or equal priority - */ - public int getAcidPriority() { - return acidPriority; - } + /** + * @return Damage multiplier applied if the owning group was deleted + */ + public double getDeletedGroupMultiplier() { + return deletedGroupMulitplier; + } - /** - * @return Get the scale of amount of damage a block should take when it is not - * fully mature. - */ - public double getMaturationScale() { - return scale; - } + /** + * @return Item used to create instance of this item + */ + public ItemStack getItem() { + return item; + } - /** - * @return Returns the Maturation time needed until this block is mature in - * milliseconds - */ - public long getMaturationTime() { - return maturationTime; - } + /** + * @return Acid priority of this type. Acid blocks can only remove blocks of lower or equal priority + */ + public int getAcidPriority() { + return acidPriority; + } - /** - * @return Nice name to use for messages - */ - public String getName() { - return name; - } + /** + * @return Get the scale of amount of damage a block should take when it is not + * fully mature. + */ + public double getMaturationScale() { + return scale; + } - /** - * @return Get the effect to spawn around this type of reinforcement when it is - * created - */ - public ReinforcementEffect getCreationEffect() { - return creationEffect; - } + /** + * @return Returns the Maturation time needed until this block is mature in + * milliseconds + */ + public long getMaturationTime() { + return maturationTime; + } - /** - * @return Get the effect to spawn around this type of reinforcement when it is - * damaged - */ - public ReinforcementEffect getDamageEffect() { - return damageEffect; - } + /** + * @return Nice name to use for messages + */ + public String getName() { + return name; + } - /** - * @return Get the effect to spawn around this type of reinforcement when it is - * destroyed - */ - public ReinforcementEffect getDestructionEffect() { - return destructionEffect; - } + /** + * @return Get the effect to spawn around this type of reinforcement when it is + * created + */ + public ReinforcementEffect getCreationEffect() { + return creationEffect; + } - /** - * @return The percent chance that a block will return the reinforcements. - * Scales with damage. 1 means it is 100% and .5 means 50% - */ - public double getReturnChance() { - return returnChance; - } - - /** - * Material id the material used for the reinforcement had pre-flattening (1.12.2 or earlier). Needed once for - * proper migration of reinforcements to higher versions - * @return Old item id of the reinforcement item - */ - public int getLegacyId() { - return legacyId; - } - - public double getDecayDamageMultipler(long since) { - if (decayTimer <= 0 || decayMultiplier == 1) { - return 1; - } - long timePassed = System.currentTimeMillis() - since; - if (timePassed <= decayTimer) { - return 1; - } - double timeExponent = ((double) timePassed / (double) decayTimer); - return Math.pow(decayMultiplier, timeExponent); - } + /** + * @return Get the effect to spawn around this type of reinforcement when it is + * damaged + */ + public ReinforcementEffect getDamageEffect() { + return damageEffect; + } + + /** + * @return Get the effect to spawn around this type of reinforcement when it is + * destroyed + */ + public ReinforcementEffect getDestructionEffect() { + return destructionEffect; + } + + /** + * @return The percent chance that a block will return the reinforcements. + * Scales with damage. 1 means it is 100% and .5 means 50% + */ + public double getReturnChance() { + return returnChance; + } + + /** + * Material id the material used for the reinforcement had pre-flattening (1.12.2 or earlier). Needed once for + * proper migration of reinforcements to higher versions + * + * @return Old item id of the reinforcement item + */ + public int getLegacyId() { + return legacyId; + } + + public double getDecayDamageMultipler(long since) { + if (decayTimer <= 0 || decayMultiplier == 1) { + return 1; + } + long timePassed = System.currentTimeMillis() - since; + if (timePassed <= decayTimer) { + return 1; + } + double timeExponent = ((double) timePassed / (double) decayTimer); + return Math.pow(decayMultiplier, timeExponent); + } } diff --git a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/reinforcementtypes/ReinforcementTypeManager.java b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/reinforcementtypes/ReinforcementTypeManager.java index 42a44f45f..4c3b0438d 100644 --- a/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/reinforcementtypes/ReinforcementTypeManager.java +++ b/plugins/citadel-paper/src/main/java/vg/civcraft/mc/citadel/reinforcementtypes/ReinforcementTypeManager.java @@ -9,82 +9,82 @@ import org.bukkit.inventory.ItemStack; public class ReinforcementTypeManager { - private Map globalTypesByItem; - private Map> localTypesByItem; - private Map typesById; + private Map globalTypesByItem; + private Map> localTypesByItem; + private Map typesById; - public ReinforcementTypeManager() { - globalTypesByItem = new HashMap<>(); - localTypesByItem = new HashMap<>(); - typesById = new TreeMap<>(); - } + public ReinforcementTypeManager() { + globalTypesByItem = new HashMap<>(); + localTypesByItem = new HashMap<>(); + typesById = new TreeMap<>(); + } - public Collection getAllTypes() { - return typesById.values(); - } + public Collection getAllTypes() { + return typesById.values(); + } - public ReinforcementType getById(short id) { - return typesById.get(id); - } + public ReinforcementType getById(short id) { + return typesById.get(id); + } - public ReinforcementType getByItemStack(ItemStack is, String worldName) { - ItemStack copy = is.clone(); - copy.setAmount(1); + public ReinforcementType getByItemStack(ItemStack is, String worldName) { + ItemStack copy = is.clone(); + copy.setAmount(1); - ReinforcementType foundType = globalTypesByItem.get(copy); + ReinforcementType foundType = globalTypesByItem.get(copy); - if (foundType == null) { // Reinforcement type is not global, aka local - if (localTypesByItem.get(copy) == null) { // The item type is not registered at all, so it can't have any allowed worlds - return null; - } + if (foundType == null) { // Reinforcement type is not global, aka local + if (localTypesByItem.get(copy) == null) { // The item type is not registered at all, so it can't have any allowed worlds + return null; + } - foundType = localTypesByItem.get(copy).get(worldName); + foundType = localTypesByItem.get(copy).get(worldName); - if (foundType == null) { - foundType = localTypesByItem.get(copy).values().stream().filter(Objects::nonNull).findAny().orElse(null); - } + if (foundType == null) { + foundType = localTypesByItem.get(copy).values().stream().filter(Objects::nonNull).findAny().orElse(null); + } - return foundType; - } else { // Reinforcement type is global, and has been found - return foundType; - } - } + return foundType; + } else { // Reinforcement type is global, and has been found + return foundType; + } + } - public boolean register(ReinforcementType type) { - typesById.put(type.getID(), type); + public boolean register(ReinforcementType type) { + typesById.put(type.getID(), type); - if (type.getAllowedWorlds().isEmpty()) { // Registering a global reinforcement - if (localTypesByItem.get(type.getItem()) != null) { - // Problem because there is already a local reinforcement for the item type - return false; - } + if (type.getAllowedWorlds().isEmpty()) { // Registering a global reinforcement + if (localTypesByItem.get(type.getItem()) != null) { + // Problem because there is already a local reinforcement for the item type + return false; + } - if (globalTypesByItem.put(type.getItem(), type) != null) { - // Problem because there is already a global reinforcement for the item type registered - return false; - } + if (globalTypesByItem.put(type.getItem(), type) != null) { + // Problem because there is already a global reinforcement for the item type registered + return false; + } - globalTypesByItem.put(type.getItem(), type); // Types with no allowed worlds are global and able to be used everywhere + globalTypesByItem.put(type.getItem(), type); // Types with no allowed worlds are global and able to be used everywhere - return true; - } else { // Registering a local reinforcement - if (globalTypesByItem.get(type.getItem()) != null) { - // Problem because there is already a global reinforcement for the item type - return false; - } + return true; + } else { // Registering a local reinforcement + if (globalTypesByItem.get(type.getItem()) != null) { + // Problem because there is already a global reinforcement for the item type + return false; + } - // At this point we have verified there is not already a global reinforcement, so the local reinforcement can go ahead + // At this point we have verified there is not already a global reinforcement, so the local reinforcement can go ahead - for (String allowedWorld : type.getAllowedWorlds()) { // For all the allowed worlds + for (String allowedWorld : type.getAllowedWorlds()) { // For all the allowed worlds - if (localTypesByItem.computeIfAbsent(type.getItem(), k -> new HashMap<>()) // Put the item in the map and create a sub-map if it doesn't already exist, if so there should not be any conflicting local-items - .put(allowedWorld, type) != null) { // Put the allowed world, if a value is returned, there was previously something associated with the world, therefore there are two local reinforcements attempting to exist locally in a world - return false; - } - } + if (localTypesByItem.computeIfAbsent(type.getItem(), k -> new HashMap<>()) // Put the item in the map and create a sub-map if it doesn't already exist, if so there should not be any conflicting local-items + .put(allowedWorld, type) != null) { // Put the allowed world, if a value is returned, there was previously something associated with the world, therefore there are two local reinforcements attempting to exist locally in a world + return false; + } + } - return true; - } - } + return true; + } + } } diff --git a/plugins/citadel-paper/src/main/resources/config.yml b/plugins/citadel-paper/src/main/resources/config.yml index 7d2c73e4a..d7a107460 100644 --- a/plugins/citadel-paper/src/main/resources/config.yml +++ b/plugins/citadel-paper/src/main/resources/config.yml @@ -80,140 +80,140 @@ acids: material: GOLD_BLOCK maturation_time_multiplier: 1 faces: - - UP + - UP diamond: material: DIAMOND_BLOCK maturation_time_multiplier: 2 faces: - - UP - - DOWN + - UP + - DOWN netherite: material: NETHERITE_BLOCK maturation_time_multiplier: 4 faces: - - UP - - DOWN - - NORTH - - SOUTH - - EAST - - WEST - + - UP + - DOWN + - NORTH + - SOUTH + - EAST + - WEST + non_reinforceables: - - BEDROCK - - END_PORTAL - - END_PORTAL_FRAME - - OAK_SAPLING - - BIRCH_SAPLING - - SPRUCE_SAPLING - - JUNGLE_SAPLING - - DARK_OAK_SAPLING - - ACACIA_SAPLING - - BAMBOO_SAPLING - - TALL_GRASS - - DEAD_BUSH - - PISTON - - MOVING_PISTON - - PISTON_HEAD - - POPPY - - DANDELION - - BLUE_ORCHID - - ALLIUM - - RED_TULIP - - ORANGE_TULIP - - WHITE_TULIP - - PINK_TULIP - - OXEYE_DAISY - - CORNFLOWER - - LILY_OF_THE_VALLEY - - SUNFLOWER - - SEA_PICKLE - - LILAC - - PEONY - - ROSE_BUSH - - BROWN_MUSHROOM - - RED_MUSHROOM - - CRIMSON_FUNGUS - - WARPED_FUNGUS - - CRIMSON_ROOTS - - WARPED_ROOTS - - NETHER_SPROUTS - - WEEPING_VINES - - TWISTING_VINES - - TWISTING_VINES_PLANT - - WEEPING_VINES_PLANT - - TNT - - WHEAT - - BEETROOTS - - POTATOES - - CARROTS - - FERN - - LARGE_FERN - - SHORT_GRASS - - SEAGRASS - - TALL_SEAGRASS - - BAMBOO - - SUGAR_CANE - - SWEET_BERRIES - - BROWN_MUSHROOM - - RED_MUSHROOM - - KELP - - SEA_PICKLE - - NETHER_WART - - CHORUS_FRUIT - - FIRE - - SOUL_FIRE - - SNOW - - ICE - - CACTUS - - KELP_PLANT - - NETHER_PORTAL - - CAKE - - PUMPKIN_STEM - - MELON_STEM - - VINE - - BRAIN_CORAL - - BRAIN_CORAL_BLOCK - - BRAIN_CORAL_FAN - - BRAIN_CORAL_WALL_FAN - - BUBBLE_CORAL - - BUBBLE_CORAL_BLOCK - - BUBBLE_CORAL_FAN - - BUBBLE_CORAL_WALL_FAN - - FIRE_CORAL - - FIRE_CORAL_BLOCK - - FIRE_CORAL_FAN - - FIRE_CORAL_WALL_FAN - - HORN_CORAL - - HORN_CORAL_BLOCK - - HORN_CORAL_FAN - - HORN_CORAL_WALL_FAN - - TUBE_CORAL - - TUBE_CORAL_BLOCK - - TUBE_CORAL_FAN - - TUBE_CORAL_WALL_FAN - - DEAD_BRAIN_CORAL - - DEAD_BRAIN_CORAL_BLOCK - - DEAD_BRAIN_CORAL_FAN - - DEAD_BRAIN_CORAL_WALL_FAN - - DEAD_BUBBLE_CORAL - - DEAD_BUBBLE_CORAL_BLOCK - - DEAD_BUBBLE_CORAL_FAN - - DEAD_BUBBLE_CORAL_WALL_FAN - - DEAD_FIRE_CORAL - - DEAD_FIRE_CORAL_BLOCK - - DEAD_FIRE_CORAL_FAN - - DEAD_FIRE_CORAL_WALL_FAN - - DEAD_HORN_CORAL - - DEAD_HORN_CORAL_BLOCK - - DEAD_HORN_CORAL_FAN - - DEAD_HORN_CORAL_WALL_FAN - - DEAD_TUBE_CORAL - - DEAD_TUBE_CORAL_BLOCK - - DEAD_TUBE_CORAL_FAN - - DEAD_TUBE_CORAL_WALL_FAN - - SCAFFOLDING + - BEDROCK + - END_PORTAL + - END_PORTAL_FRAME + - OAK_SAPLING + - BIRCH_SAPLING + - SPRUCE_SAPLING + - JUNGLE_SAPLING + - DARK_OAK_SAPLING + - ACACIA_SAPLING + - BAMBOO_SAPLING + - TALL_GRASS + - DEAD_BUSH + - PISTON + - MOVING_PISTON + - PISTON_HEAD + - POPPY + - DANDELION + - BLUE_ORCHID + - ALLIUM + - RED_TULIP + - ORANGE_TULIP + - WHITE_TULIP + - PINK_TULIP + - OXEYE_DAISY + - CORNFLOWER + - LILY_OF_THE_VALLEY + - SUNFLOWER + - SEA_PICKLE + - LILAC + - PEONY + - ROSE_BUSH + - BROWN_MUSHROOM + - RED_MUSHROOM + - CRIMSON_FUNGUS + - WARPED_FUNGUS + - CRIMSON_ROOTS + - WARPED_ROOTS + - NETHER_SPROUTS + - WEEPING_VINES + - TWISTING_VINES + - TWISTING_VINES_PLANT + - WEEPING_VINES_PLANT + - TNT + - WHEAT + - BEETROOTS + - POTATOES + - CARROTS + - FERN + - LARGE_FERN + - SHORT_GRASS + - SEAGRASS + - TALL_SEAGRASS + - BAMBOO + - SUGAR_CANE + - SWEET_BERRIES + - BROWN_MUSHROOM + - RED_MUSHROOM + - KELP + - SEA_PICKLE + - NETHER_WART + - CHORUS_FRUIT + - FIRE + - SOUL_FIRE + - SNOW + - ICE + - CACTUS + - KELP_PLANT + - NETHER_PORTAL + - CAKE + - PUMPKIN_STEM + - MELON_STEM + - VINE + - BRAIN_CORAL + - BRAIN_CORAL_BLOCK + - BRAIN_CORAL_FAN + - BRAIN_CORAL_WALL_FAN + - BUBBLE_CORAL + - BUBBLE_CORAL_BLOCK + - BUBBLE_CORAL_FAN + - BUBBLE_CORAL_WALL_FAN + - FIRE_CORAL + - FIRE_CORAL_BLOCK + - FIRE_CORAL_FAN + - FIRE_CORAL_WALL_FAN + - HORN_CORAL + - HORN_CORAL_BLOCK + - HORN_CORAL_FAN + - HORN_CORAL_WALL_FAN + - TUBE_CORAL + - TUBE_CORAL_BLOCK + - TUBE_CORAL_FAN + - TUBE_CORAL_WALL_FAN + - DEAD_BRAIN_CORAL + - DEAD_BRAIN_CORAL_BLOCK + - DEAD_BRAIN_CORAL_FAN + - DEAD_BRAIN_CORAL_WALL_FAN + - DEAD_BUBBLE_CORAL + - DEAD_BUBBLE_CORAL_BLOCK + - DEAD_BUBBLE_CORAL_FAN + - DEAD_BUBBLE_CORAL_WALL_FAN + - DEAD_FIRE_CORAL + - DEAD_FIRE_CORAL_BLOCK + - DEAD_FIRE_CORAL_FAN + - DEAD_FIRE_CORAL_WALL_FAN + - DEAD_HORN_CORAL + - DEAD_HORN_CORAL_BLOCK + - DEAD_HORN_CORAL_FAN + - DEAD_HORN_CORAL_WALL_FAN + - DEAD_TUBE_CORAL + - DEAD_TUBE_CORAL_BLOCK + - DEAD_TUBE_CORAL_FAN + - DEAD_TUBE_CORAL_WALL_FAN + - SCAFFOLDING acidblock_material: - - GOLD_BLOCK + - GOLD_BLOCK # Determines whether hanging entities (such as Item Frames) can be protected by their host block hangers_inherit_reinforcement: false diff --git a/plugins/citadel-paper/src/main/resources/plugin.yml b/plugins/citadel-paper/src/main/resources/plugin.yml index 9754f680a..f86a049d6 100644 --- a/plugins/citadel-paper/src/main/resources/plugin.yml +++ b/plugins/citadel-paper/src/main/resources/plugin.yml @@ -2,20 +2,20 @@ name: Citadel main: vg.civcraft.mc.citadel.Citadel version: ${version} authors: -- Rourke750 -- Maxopoly -- ProgrammerDan -- okx-code -- Cranite -- FeatherCrown -- Lazersmoke -- TealNerd -- Scuwr + - Rourke750 + - Maxopoly + - ProgrammerDan + - okx-code + - Cranite + - FeatherCrown + - Lazersmoke + - TealNerd + - Scuwr depend: -- NameLayer -- CivModCore + - NameLayer + - CivModCore softdepend: -- HolographicDisplays + - HolographicDisplays description: Citadel allows you to make blocks difficult to break. When a block is reinforced, it must be broken many times before it is destroyed. api-version: 1.20 permissions: diff --git a/plugins/civchat2-paper/build.gradle.kts b/plugins/civchat2-paper/build.gradle.kts index e55268d00..bd5b61b8e 100644 --- a/plugins/civchat2-paper/build.gradle.kts +++ b/plugins/civchat2-paper/build.gradle.kts @@ -1,14 +1,14 @@ plugins { - id("io.papermc.paperweight.userdev") + id("io.papermc.paperweight.userdev") } version = "2.2.2" dependencies { - paperweight { - paperDevBundle("1.20.4-R0.1-SNAPSHOT") - } + paperweight { + paperDevBundle("1.20.4-R0.1-SNAPSHOT") + } - compileOnly(project(":plugins:civmodcore-paper")) - compileOnly(project(":plugins:namelayer-paper")) + compileOnly(project(":plugins:civmodcore-paper")) + compileOnly(project(":plugins:namelayer-paper")) } diff --git a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/ChatStrings.java b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/ChatStrings.java index c0b6da9a4..76300ba46 100644 --- a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/ChatStrings.java +++ b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/ChatStrings.java @@ -4,53 +4,53 @@ import org.bukkit.ChatColor; public class ChatStrings { - public final static String localChatFormat = "<%1$s> %2$s"; + public final static String localChatFormat = "<%1$s> %2$s"; - public final static String chatPlayerIsOffline = ChatColor.YELLOW + "That player is offline."; + public final static String chatPlayerIsOffline = ChatColor.YELLOW + "That player is offline."; - public final static String chatNoOneToReplyTo = ChatColor.YELLOW + "You have no one to reply to."; + public final static String chatNoOneToReplyTo = ChatColor.YELLOW + "You have no one to reply to."; - public final static String chatCantMessageSelf = ChatColor.YELLOW + "You can't message yourself."; + public final static String chatCantMessageSelf = ChatColor.YELLOW + "You can't message yourself."; - public final static String chatCantIgnoreSelf = ChatColor.YELLOW + "You can't ignore yourself."; + public final static String chatCantIgnoreSelf = ChatColor.YELLOW + "You can't ignore yourself."; - public final static String chatNowChattingWith = ChatColor.GREEN + "You are now chatting with %s."; + public final static String chatNowChattingWith = ChatColor.GREEN + "You are now chatting with %s."; - public final static String chatMovedToGlobal = ChatColor.YELLOW + "You are now in local chat."; //previously global chat, changed to prevent confusing with global ! chat group + public final static String chatMovedToGlobal = ChatColor.YELLOW + "You are now in local chat."; //previously global chat, changed to prevent confusing with global ! chat group - public final static String chatGroupNotFound = ChatColor.RED + "There is no group with that name."; + public final static String chatGroupNotFound = ChatColor.RED + "There is no group with that name."; - public final static String chatGroupAlreadyChatting = ChatColor.YELLOW + "You are already chatting in that group."; + public final static String chatGroupAlreadyChatting = ChatColor.YELLOW + "You are already chatting in that group."; - public final static String chatGroupNowChattingIn = ChatColor.GREEN + "You are now chatting in group %s."; + public final static String chatGroupNowChattingIn = ChatColor.GREEN + "You are now chatting in group %s."; - public final static String chatGroupNoPerms = ChatColor.RED + "You don't have permission to chat in this group."; + public final static String chatGroupNoPerms = ChatColor.RED + "You don't have permission to chat in this group."; - public final static String chatNeedToUnignore = ChatColor.YELLOW + "You need to unignore %s."; + public final static String chatNeedToUnignore = ChatColor.YELLOW + "You need to unignore %s."; - public final static String chatPlayerNotFound = ChatColor.RED + "No player exists with that name."; + public final static String chatPlayerNotFound = ChatColor.RED + "No player exists with that name."; - public final static String chatNowIgnoring = ChatColor.GREEN + "You are now ignoring %s"; + public final static String chatNowIgnoring = ChatColor.GREEN + "You are now ignoring %s"; - public final static String chatStoppedIgnoring = ChatColor.GREEN + "You stopped ignoring %s."; + public final static String chatStoppedIgnoring = ChatColor.GREEN + "You stopped ignoring %s."; - public final static String chatNotIgnoringAnyPlayers = ChatColor.GOLD + "You are not ignoring any players."; + public final static String chatNotIgnoringAnyPlayers = ChatColor.GOLD + "You are not ignoring any players."; - public final static String chatNotIgnoringAnyGroups = ChatColor.GOLD + "You are not ignoring any groups."; + public final static String chatNotIgnoringAnyGroups = ChatColor.GOLD + "You are not ignoring any groups."; - public final static String chatPlayerIgnoringYou = ChatColor.YELLOW + "That player is ignoring you."; + public final static String chatPlayerIgnoringYou = ChatColor.YELLOW + "That player is ignoring you."; - public final static String chatRemovedFromChat = ChatColor.GREEN + "You left private chat."; + public final static String chatRemovedFromChat = ChatColor.GREEN + "You left private chat."; - public final static String chatNotInPrivateChat = ChatColor.YELLOW + "You aren't in private chat."; + public final static String chatNotInPrivateChat = ChatColor.YELLOW + "You aren't in private chat."; - public final static String chatAfk = ChatColor.BLUE + "You are now AFK, type /afk to remove AFK status."; + public final static String chatAfk = ChatColor.BLUE + "You are now AFK, type /afk to remove AFK status."; - public final static String chatNotAfk = ChatColor.BLUE + "You are no longer AFK."; + public final static String chatNotAfk = ChatColor.BLUE + "You are no longer AFK."; - public final static String chatPlayerAfk = ChatColor.AQUA + "That player is currently AFK."; + public final static String chatPlayerAfk = ChatColor.AQUA + "That player is currently AFK."; - public final static String chatGroupMessage = ChatColor.GRAY + "[%s] %s: " + ChatColor.WHITE + "%s"; - - public final static String globalMuted = ChatColor.RED + "You are muted from global and local chat for %s"; + public final static String chatGroupMessage = ChatColor.GRAY + "[%s] %s: " + ChatColor.WHITE + "%s"; + + public final static String globalMuted = ChatColor.RED + "You are muted from global and local chat for %s"; } diff --git a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/CivChat2.java b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/CivChat2.java index a661be467..a6f63135a 100644 --- a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/CivChat2.java +++ b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/CivChat2.java @@ -17,89 +17,88 @@ import vg.civcraft.mc.namelayer.permission.PermissionType; /** * @author jjj5311 - * */ public class CivChat2 extends ACivMod { - private static CivChat2 instance; + private static CivChat2 instance; - private CivChat2Log log; - private CivChat2Config config; - private CivChat2Manager chatMan; - private CivChat2SettingsManager settingsManager; - private CivChat2FileLogger fileLog; - private CivChatDAO databaseManager; - private CivChatCommandManager commandManager; + private CivChat2Log log; + private CivChat2Config config; + private CivChat2Manager chatMan; + private CivChat2SettingsManager settingsManager; + private CivChat2FileLogger fileLog; + private CivChatDAO databaseManager; + private CivChatCommandManager commandManager; - @Override - public void onEnable() { - super.onEnable(); - instance = this; - saveDefaultConfig(); - reloadConfig(); - config = new CivChat2Config(getConfig()); - log = new CivChat2Log(); - log.initializeLogger(instance); - fileLog = new CivChat2FileLogger(); - databaseManager = new CivChatDAO(); - settingsManager = new CivChat2SettingsManager(); - chatMan = new CivChat2Manager(instance); - log.debug("Debug Enabled"); - commandManager = new CivChatCommandManager(this); - registerNameLayerPermissions(); - registerCivChatEvents(); - } + @Override + public void onEnable() { + super.onEnable(); + instance = this; + saveDefaultConfig(); + reloadConfig(); + config = new CivChat2Config(getConfig()); + log = new CivChat2Log(); + log.initializeLogger(instance); + fileLog = new CivChat2FileLogger(); + databaseManager = new CivChatDAO(); + settingsManager = new CivChat2SettingsManager(); + chatMan = new CivChat2Manager(instance); + log.debug("Debug Enabled"); + commandManager = new CivChatCommandManager(this); + registerNameLayerPermissions(); + registerCivChatEvents(); + } - @Override - public void onDisable() { - } + @Override + public void onDisable() { + } - public CivChat2Manager getCivChat2Manager() { - return chatMan; - } + public CivChat2Manager getCivChat2Manager() { + return chatMan; + } - public boolean debugEnabled() { - return config.getDebug(); - } + public boolean debugEnabled() { + return config.getDebug(); + } - public CivChat2Log getCivChat2Log() { - return log; - } + public CivChat2Log getCivChat2Log() { + return log; + } - private void registerCivChatEvents() { - getServer().getPluginManager().registerEvents(new CivChat2Listener(chatMan), this); - getServer().getPluginManager().registerEvents(new KillListener(config, databaseManager, settingsManager), this); - } + private void registerCivChatEvents() { + getServer().getPluginManager().registerEvents(new CivChat2Listener(chatMan), this); + getServer().getPluginManager().registerEvents(new KillListener(config, databaseManager, settingsManager), this); + } - public void registerNameLayerPermissions() { - List memberAndAbove = Arrays.asList(PlayerType.MEMBERS, PlayerType.MODS, PlayerType.ADMINS , PlayerType.OWNER); - PermissionType.registerPermission("READ_CHAT", new ArrayList<>(memberAndAbove), - "Allows receiving messages sent in the group chat"); - PermissionType.registerPermission("WRITE_CHAT", new ArrayList<>(memberAndAbove), - "Allows sending messages to the group chat"); - } + public void registerNameLayerPermissions() { + List memberAndAbove = Arrays.asList(PlayerType.MEMBERS, PlayerType.MODS, PlayerType.ADMINS, PlayerType.OWNER); + PermissionType.registerPermission("READ_CHAT", new ArrayList<>(memberAndAbove), + "Allows receiving messages sent in the group chat"); + PermissionType.registerPermission("WRITE_CHAT", new ArrayList<>(memberAndAbove), + "Allows sending messages to the group chat"); + } - private void registerCompletions() { + private void registerCompletions() { - } + } - public static CivChat2 getInstance() { - return instance; - } + public static CivChat2 getInstance() { + return instance; + } - public CivChat2SettingsManager getCivChat2SettingsManager(){ - return settingsManager; - } + public CivChat2SettingsManager getCivChat2SettingsManager() { + return settingsManager; + } - public CivChat2Config getPluginConfig() { - return config; - } + public CivChat2Config getPluginConfig() { + return config; + } - public CivChat2FileLogger getCivChat2FileLogger() { - return fileLog; - } + public CivChat2FileLogger getCivChat2FileLogger() { + return fileLog; + } - public CivChatDAO getDatabaseManager() { - return this.databaseManager; - } + public CivChatDAO getDatabaseManager() { + return this.databaseManager; + } } diff --git a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/CivChat2Manager.java b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/CivChat2Manager.java index 65e1b1148..6103ea3de 100644 --- a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/CivChat2Manager.java +++ b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/CivChat2Manager.java @@ -31,408 +31,406 @@ import vg.civcraft.mc.namelayer.permission.PermissionType; public class CivChat2Manager { - private CivChat2Config config; + private CivChat2Config config; - private CivChat2FileLogger chatLog; - - private CivChat2 instance; - - private CivChatDAO DBM; - - // chatChannels in hashmap with (Player 1 name, player 2 name) - private HashMap chatChannels; - - // groupChatChannels have (Player, Group) - private final HashMap groupChatChannels; - - // replyList has (playerName, whotoreplyto) - private final HashMap replyList; - - private final Set afkPlayers; - - private ScoreboardHUD scoreboardHUD; - - protected static final GroupManager GM = NameAPI.getGroupManager(); - - private String defaultColor; - - private static Map customNames = new HashMap<>(); - - public CivChat2Manager(CivChat2 pluginInstance) { - - instance = pluginInstance; - config = instance.getPluginConfig(); - chatLog = instance.getCivChat2FileLogger(); - DBM = instance.getDatabaseManager(); - defaultColor = config.getDefaultColor(); - chatChannels = new HashMap<>(); - groupChatChannels = new HashMap<>(); - replyList = new HashMap<>(); - afkPlayers = new HashSet<>(); - scoreboardHUD = new ScoreboardHUD(); - } - - /** - * Gets the channel for player to player chat - * - * @param player Player name of the channel - * @return Returns a String of channel name, null if doesn't exist - */ - public UUID getChannel(Player player) { - - Preconditions.checkNotNull(player, "player"); - - return chatChannels.get(player.getUniqueId()); - } - - /** - * Removes the channel from the channel storage - * - * @param player Player Name of the channel - * - */ - public void removeChannel(Player player) { - - Preconditions.checkNotNull(player, "player"); - - chatChannels.remove(player.getUniqueId()); - scoreboardHUD.updateScoreboardHUD(player); - } - - /** - * Adds a channel for player to player chat, if player1 is currently in a - * chatChannel this will overwrite it - * - * @param player1 Sender's name - * @param player2 Receiver's name - */ - public void addChatChannel(Player player1, Player player2) { - - Preconditions.checkNotNull(player1, "player1"); - Preconditions.checkNotNull(player2, "player2"); - - if (getChannel(player1) != null) { - chatChannels.put(player1.getUniqueId(), player2.getUniqueId()); - } else { - chatChannels.put(player1.getUniqueId(), player2.getUniqueId()); - } - scoreboardHUD.updateScoreboardHUD(player1); - } - - /** - * Method to Send private message between to players - * - * @param sender Player sending the message - * @param receiver Player Receiving the message - * @param chatMessage Message to send from sender to receive - */ - public void sendPrivateMsg(Player sender, Player receiver, String chatMessage) { - - PrivateMessageEvent event = new PrivateMessageEvent(sender, receiver, chatMessage); - Bukkit.getPluginManager().callEvent(event); - - if (event.isCancelled()) { - return; - } - StringBuilder sb = new StringBuilder(); - String senderName = customNames.containsKey(sender.getUniqueId()) ? customNames.get(sender.getUniqueId()) - : sender.getDisplayName(); - String receiverName = customNames.containsKey(receiver.getUniqueId()) ? customNames.get(receiver.getUniqueId()) - : receiver.getDisplayName(); - - String senderMessage = sb.append(ChatColor.LIGHT_PURPLE).append("To ").append(receiverName) - .append(ChatColor.LIGHT_PURPLE).append(": ").append(chatMessage).toString(); - sb = new StringBuilder(); - String receiverMessage = sb.append(ChatColor.LIGHT_PURPLE).append("From ").append(senderName) - .append(ChatColor.LIGHT_PURPLE).append(": ").append(chatMessage).toString(); - - if (isPlayerAfk(receiver)) { - receiver.sendMessage(receiverMessage); - sender.sendMessage(parse(ChatStrings.chatPlayerAfk)); - return; - // Player is ignoring the sender - } else if (DBM.isIgnoringPlayer(receiver.getUniqueId(), sender.getUniqueId())) { - sender.sendMessage(parse(ChatStrings.chatPlayerIgnoringYou)); - return; - } else if (DBM.isIgnoringPlayer(sender.getUniqueId(), receiver.getUniqueId())) { - sender.sendMessage(parse(ChatStrings.chatNeedToUnignore, receiverName)); - return; - } - chatLog.logPrivateMessage(sender, chatMessage, receiver.getName()); - replyList.put(receiver.getUniqueId(), sender.getUniqueId()); - replyList.put(sender.getUniqueId(), receiver.getUniqueId()); - sender.sendMessage(senderMessage); - receiver.sendMessage(receiverMessage); - } - - /** - * Method to broadcast a message in global chat - * - * @param sender Player who sent the message - * @param chatMessage Message to send - * @param recipients Players in range to receive the message - */ - public void broadcastMessage(Player sender, String chatMessage, String messageFormat, Set recipients) { - - Preconditions.checkNotNull(sender, "sender"); - Preconditions.checkNotNull(chatMessage, "chatMessage"); - Preconditions.checkArgument(!Strings.isNullOrEmpty(messageFormat), "messageFormat"); - Preconditions.checkNotNull(recipients, "recipients"); - - GlobalChatEvent event = new GlobalChatEvent(sender, chatMessage, messageFormat); - Bukkit.getPluginManager().callEvent(event); - - if (event.isCancelled()) { - return; - } - - long mutedUntil = instance.getCivChat2SettingsManager().getGlobalChatMuteSetting().getValue(sender); - Group targetChatGroup = groupChatChannels.get(sender.getUniqueId()); - if (mutedUntil > System.currentTimeMillis()) { - if (targetChatGroup == null || targetChatGroup.getName().equals(instance.getPluginConfig().getGlobalChatGroupName())) { - sender.sendMessage(String.format(ChatStrings.globalMuted, TextUtil.formatDuration(mutedUntil - System.currentTimeMillis()))); - return; - } - } - - int range = config.getChatRange(); - int height = config.getYInc(); - Location location = sender.getLocation(); - int y = location.getBlockY(); - double scale = (config.getYScale()) / 1000; - - StringBuilder sb = new StringBuilder(); - - // Do height check - // Player is above chat increase range - if (y > height) { - int above = y - height; - int newRange = (int) (range + (range * (scale * above))); - range = newRange; - sb.delete(0, sb.length()); - } - - Set receivers = new HashSet<>(); - // Loop through players and send to those that are close enough - for (Player receiver : recipients) { - if (!DBM.isIgnoringPlayer(receiver.getUniqueId(), sender.getUniqueId())) { - if (receiver.getWorld().equals(sender.getWorld())) { - double receiverDistance = location.distance(receiver.getLocation()); - if (receiverDistance <= range) { - net.md_5.bungee.api.ChatColor newColor; - if (config.useDynamicRangeColoring()) { - int comp = (int) (255 - (128.0 * receiverDistance) / range); - newColor = net.md_5.bungee.api.ChatColor.of(new Color(comp, comp, comp)); - } - else { - newColor = net.md_5.bungee.api.ChatColor.of(config.getColorAtDistance(receiverDistance)); - } - newColor = newColor != null ? newColor : net.md_5.bungee.api.ChatColor.of(defaultColor); - - String senderName = customNames.containsKey(sender.getUniqueId()) - ? customNames.get(sender.getUniqueId()) - : sender.getDisplayName(); - TextComponent text = new TextComponent(String.format(messageFormat, senderName + ChatColor.RESET, "")); - TextComponent msgPart = new TextComponent(chatMessage); - msgPart.setColor(newColor); - receiver.spigot().sendMessage(text, msgPart); - receivers.add(receiver.getName()); - } - } - } - } - receivers.remove(sender.getName()); - chatLog.logGlobalMessage(sender, chatMessage, receivers); - } - - /** - * Gets whether a player is AFK - * - * @param player The player to check - * @return true if the player is AFK - */ - public boolean isPlayerAfk(Player player) { - Preconditions.checkNotNull(player, "player"); - return afkPlayers.contains(player.getUniqueId()); - } - - /** - * Sets the AFK status of a player - * - * @param player The player to change - * @return The player AFK status - */ - public boolean setPlayerAfk(Player player, boolean afkStatus) { - Preconditions.checkNotNull(player, "player"); - - if (afkStatus) { - afkPlayers.add(player.getUniqueId()); - } else { - afkPlayers.remove(player.getUniqueId()); - } - return afkStatus; - } - - /** - * Toggles the AFK status of a player - * - * @param player Player to toggle state for - * @return Whether afk is turned on afterwards - */ - public boolean togglePlayerAfk(Player player) { - Preconditions.checkNotNull(player, "player"); - if (afkPlayers.contains(player.getUniqueId())) { - afkPlayers.remove(player.getUniqueId()); - return false; - } - afkPlayers.add(player.getUniqueId()); - return true; - } - - /** - * Gets the player to send reply to - * - * @param sender the person sending reply command - * @return the UUID of the person to reply to, null if none - */ - public UUID getPlayerReply(Player sender) { - Preconditions.checkNotNull(sender, "sender"); - return replyList.get(sender.getUniqueId()); - } - - /** - * Add a player to the replyList - * - * @param player The player using the reply command. - * @param replyPlayer The the player that will receive the reply - */ - public void addPlayerReply(Player player, Player replyPlayer) { - - Preconditions.checkNotNull(player, "player"); - Preconditions.checkNotNull(replyPlayer, "replyPlayer"); - - replyList.put(player.getUniqueId(), replyPlayer.getUniqueId()); - } - - /** - * Method to add a group chat channel - * - * @param player Player sending the message - * @param group Group sending the message to - */ - public void addGroupChat(Player player, Group group) { - - Preconditions.checkNotNull(player, "player"); - Preconditions.checkNotNull(group, "group"); - - groupChatChannels.put(player.getUniqueId(), group); - scoreboardHUD.updateScoreboardHUD(player); - } - - /** - * Method to send a message to a group - * - * @param sender sender sending the message - * @param group Group to send the message too - * @param message Message to send to the group - */ - public void sendGroupMsg(Player sender, Group group, String message) { - - Preconditions.checkNotNull(sender, "sender"); - Preconditions.checkNotNull(group, "group"); - Preconditions.checkArgument(!Strings.isNullOrEmpty(message), "message"); - - if (group.getName().equals(config.getGlobalChatGroupName())) { - long mutedUntil = instance.getCivChat2SettingsManager().getGlobalChatMuteSetting().getValue(sender); - if (mutedUntil > System.currentTimeMillis()) { - sender.sendMessage(String.format(ChatStrings.globalMuted, TextUtil.formatDuration(mutedUntil - System.currentTimeMillis()))); - return; - } - } - GroupChatEvent event = new GroupChatEvent(sender, group.getName(), message); - Bukkit.getPluginManager().callEvent(event); - - if (event.isCancelled()) { - return; - } - List members = new ArrayList<>(); - List membersUUID = group.getAllMembers(); - for (UUID uuid : membersUUID) { - // Only add online players to members - Player toAdd = Bukkit.getPlayer(uuid); - if (toAdd != null && toAdd.isOnline() && NameAPI.getGroupManager().hasAccess(group, toAdd.getUniqueId(), - PermissionType.getPermission("READ_CHAT"))) { - members.add(toAdd); - } - } - - String senderName = customNames.containsKey(sender.getUniqueId()) ? customNames.get(sender.getUniqueId()) - : sender.getDisplayName(); - String formatted = parse(ChatStrings.chatGroupMessage, group.getName(), senderName, message); - - for (Player receiver : members) { - if (DBM.isIgnoringGroup(receiver.getUniqueId(), group.getName())) { - continue; - } - if (DBM.isIgnoringPlayer(receiver.getUniqueId(), sender.getUniqueId())) { - continue; - } - receiver.sendMessage(formatted); - } - - Set players = new HashSet<>(); - for (Player player : members) { - players.add(NameAPI.getCurrentName(player.getUniqueId())); - } - players.remove(senderName); - chatLog.logGroupMessage(sender, message, group.getName(), players); - } - - /** - * Method to remove player from a group chat - * - * @param player The player to remove from chat - */ - public void removeGroupChat(Player player) { - - Preconditions.checkNotNull(player, "player"); - - groupChatChannels.remove(player.getUniqueId()); - scoreboardHUD.updateScoreboardHUD(player); - } - - /** - * Method to get the group player is currently chatting in - * - * @param player Players name - * @return Group they are currently chatting in - */ - public Group getGroupChatting(Player player) { - - Preconditions.checkNotNull(player, "player"); - - return groupChatChannels.get(player.getUniqueId()); - } - - public String parse(String text) { - - return ChatUtils.parseColor(text); - } - - public String parse(String text, Object... args) { - - return String.format(ChatUtils.parseColor(text), args); - } - - public void setCustomName(UUID player, String name) { - customNames.put(player, name); - } - - public void removeCustomName(UUID player) { - customNames.remove(player); - } - - public ScoreboardHUD getScoreboardHUD() { - return scoreboardHUD; - } + private CivChat2FileLogger chatLog; + + private CivChat2 instance; + + private CivChatDAO DBM; + + // chatChannels in hashmap with (Player 1 name, player 2 name) + private HashMap chatChannels; + + // groupChatChannels have (Player, Group) + private final HashMap groupChatChannels; + + // replyList has (playerName, whotoreplyto) + private final HashMap replyList; + + private final Set afkPlayers; + + private ScoreboardHUD scoreboardHUD; + + protected static final GroupManager GM = NameAPI.getGroupManager(); + + private String defaultColor; + + private static Map customNames = new HashMap<>(); + + public CivChat2Manager(CivChat2 pluginInstance) { + + instance = pluginInstance; + config = instance.getPluginConfig(); + chatLog = instance.getCivChat2FileLogger(); + DBM = instance.getDatabaseManager(); + defaultColor = config.getDefaultColor(); + chatChannels = new HashMap<>(); + groupChatChannels = new HashMap<>(); + replyList = new HashMap<>(); + afkPlayers = new HashSet<>(); + scoreboardHUD = new ScoreboardHUD(); + } + + /** + * Gets the channel for player to player chat + * + * @param player Player name of the channel + * @return Returns a String of channel name, null if doesn't exist + */ + public UUID getChannel(Player player) { + + Preconditions.checkNotNull(player, "player"); + + return chatChannels.get(player.getUniqueId()); + } + + /** + * Removes the channel from the channel storage + * + * @param player Player Name of the channel + */ + public void removeChannel(Player player) { + + Preconditions.checkNotNull(player, "player"); + + chatChannels.remove(player.getUniqueId()); + scoreboardHUD.updateScoreboardHUD(player); + } + + /** + * Adds a channel for player to player chat, if player1 is currently in a + * chatChannel this will overwrite it + * + * @param player1 Sender's name + * @param player2 Receiver's name + */ + public void addChatChannel(Player player1, Player player2) { + + Preconditions.checkNotNull(player1, "player1"); + Preconditions.checkNotNull(player2, "player2"); + + if (getChannel(player1) != null) { + chatChannels.put(player1.getUniqueId(), player2.getUniqueId()); + } else { + chatChannels.put(player1.getUniqueId(), player2.getUniqueId()); + } + scoreboardHUD.updateScoreboardHUD(player1); + } + + /** + * Method to Send private message between to players + * + * @param sender Player sending the message + * @param receiver Player Receiving the message + * @param chatMessage Message to send from sender to receive + */ + public void sendPrivateMsg(Player sender, Player receiver, String chatMessage) { + + PrivateMessageEvent event = new PrivateMessageEvent(sender, receiver, chatMessage); + Bukkit.getPluginManager().callEvent(event); + + if (event.isCancelled()) { + return; + } + StringBuilder sb = new StringBuilder(); + String senderName = customNames.containsKey(sender.getUniqueId()) ? customNames.get(sender.getUniqueId()) + : sender.getDisplayName(); + String receiverName = customNames.containsKey(receiver.getUniqueId()) ? customNames.get(receiver.getUniqueId()) + : receiver.getDisplayName(); + + String senderMessage = sb.append(ChatColor.LIGHT_PURPLE).append("To ").append(receiverName) + .append(ChatColor.LIGHT_PURPLE).append(": ").append(chatMessage).toString(); + sb = new StringBuilder(); + String receiverMessage = sb.append(ChatColor.LIGHT_PURPLE).append("From ").append(senderName) + .append(ChatColor.LIGHT_PURPLE).append(": ").append(chatMessage).toString(); + + if (isPlayerAfk(receiver)) { + receiver.sendMessage(receiverMessage); + sender.sendMessage(parse(ChatStrings.chatPlayerAfk)); + return; + // Player is ignoring the sender + } else if (DBM.isIgnoringPlayer(receiver.getUniqueId(), sender.getUniqueId())) { + sender.sendMessage(parse(ChatStrings.chatPlayerIgnoringYou)); + return; + } else if (DBM.isIgnoringPlayer(sender.getUniqueId(), receiver.getUniqueId())) { + sender.sendMessage(parse(ChatStrings.chatNeedToUnignore, receiverName)); + return; + } + chatLog.logPrivateMessage(sender, chatMessage, receiver.getName()); + replyList.put(receiver.getUniqueId(), sender.getUniqueId()); + replyList.put(sender.getUniqueId(), receiver.getUniqueId()); + sender.sendMessage(senderMessage); + receiver.sendMessage(receiverMessage); + } + + /** + * Method to broadcast a message in global chat + * + * @param sender Player who sent the message + * @param chatMessage Message to send + * @param recipients Players in range to receive the message + */ + public void broadcastMessage(Player sender, String chatMessage, String messageFormat, Set recipients) { + + Preconditions.checkNotNull(sender, "sender"); + Preconditions.checkNotNull(chatMessage, "chatMessage"); + Preconditions.checkArgument(!Strings.isNullOrEmpty(messageFormat), "messageFormat"); + Preconditions.checkNotNull(recipients, "recipients"); + + GlobalChatEvent event = new GlobalChatEvent(sender, chatMessage, messageFormat); + Bukkit.getPluginManager().callEvent(event); + + if (event.isCancelled()) { + return; + } + + long mutedUntil = instance.getCivChat2SettingsManager().getGlobalChatMuteSetting().getValue(sender); + Group targetChatGroup = groupChatChannels.get(sender.getUniqueId()); + if (mutedUntil > System.currentTimeMillis()) { + if (targetChatGroup == null || targetChatGroup.getName().equals(instance.getPluginConfig().getGlobalChatGroupName())) { + sender.sendMessage(String.format(ChatStrings.globalMuted, TextUtil.formatDuration(mutedUntil - System.currentTimeMillis()))); + return; + } + } + + int range = config.getChatRange(); + int height = config.getYInc(); + Location location = sender.getLocation(); + int y = location.getBlockY(); + double scale = (config.getYScale()) / 1000; + + StringBuilder sb = new StringBuilder(); + + // Do height check + // Player is above chat increase range + if (y > height) { + int above = y - height; + int newRange = (int) (range + (range * (scale * above))); + range = newRange; + sb.delete(0, sb.length()); + } + + Set receivers = new HashSet<>(); + // Loop through players and send to those that are close enough + for (Player receiver : recipients) { + if (!DBM.isIgnoringPlayer(receiver.getUniqueId(), sender.getUniqueId())) { + if (receiver.getWorld().equals(sender.getWorld())) { + double receiverDistance = location.distance(receiver.getLocation()); + if (receiverDistance <= range) { + net.md_5.bungee.api.ChatColor newColor; + if (config.useDynamicRangeColoring()) { + int comp = (int) (255 - (128.0 * receiverDistance) / range); + newColor = net.md_5.bungee.api.ChatColor.of(new Color(comp, comp, comp)); + } else { + newColor = net.md_5.bungee.api.ChatColor.of(config.getColorAtDistance(receiverDistance)); + } + newColor = newColor != null ? newColor : net.md_5.bungee.api.ChatColor.of(defaultColor); + + String senderName = customNames.containsKey(sender.getUniqueId()) + ? customNames.get(sender.getUniqueId()) + : sender.getDisplayName(); + TextComponent text = new TextComponent(String.format(messageFormat, senderName + ChatColor.RESET, "")); + TextComponent msgPart = new TextComponent(chatMessage); + msgPart.setColor(newColor); + receiver.spigot().sendMessage(text, msgPart); + receivers.add(receiver.getName()); + } + } + } + } + receivers.remove(sender.getName()); + chatLog.logGlobalMessage(sender, chatMessage, receivers); + } + + /** + * Gets whether a player is AFK + * + * @param player The player to check + * @return true if the player is AFK + */ + public boolean isPlayerAfk(Player player) { + Preconditions.checkNotNull(player, "player"); + return afkPlayers.contains(player.getUniqueId()); + } + + /** + * Sets the AFK status of a player + * + * @param player The player to change + * @return The player AFK status + */ + public boolean setPlayerAfk(Player player, boolean afkStatus) { + Preconditions.checkNotNull(player, "player"); + + if (afkStatus) { + afkPlayers.add(player.getUniqueId()); + } else { + afkPlayers.remove(player.getUniqueId()); + } + return afkStatus; + } + + /** + * Toggles the AFK status of a player + * + * @param player Player to toggle state for + * @return Whether afk is turned on afterwards + */ + public boolean togglePlayerAfk(Player player) { + Preconditions.checkNotNull(player, "player"); + if (afkPlayers.contains(player.getUniqueId())) { + afkPlayers.remove(player.getUniqueId()); + return false; + } + afkPlayers.add(player.getUniqueId()); + return true; + } + + /** + * Gets the player to send reply to + * + * @param sender the person sending reply command + * @return the UUID of the person to reply to, null if none + */ + public UUID getPlayerReply(Player sender) { + Preconditions.checkNotNull(sender, "sender"); + return replyList.get(sender.getUniqueId()); + } + + /** + * Add a player to the replyList + * + * @param player The player using the reply command. + * @param replyPlayer The the player that will receive the reply + */ + public void addPlayerReply(Player player, Player replyPlayer) { + + Preconditions.checkNotNull(player, "player"); + Preconditions.checkNotNull(replyPlayer, "replyPlayer"); + + replyList.put(player.getUniqueId(), replyPlayer.getUniqueId()); + } + + /** + * Method to add a group chat channel + * + * @param player Player sending the message + * @param group Group sending the message to + */ + public void addGroupChat(Player player, Group group) { + + Preconditions.checkNotNull(player, "player"); + Preconditions.checkNotNull(group, "group"); + + groupChatChannels.put(player.getUniqueId(), group); + scoreboardHUD.updateScoreboardHUD(player); + } + + /** + * Method to send a message to a group + * + * @param sender sender sending the message + * @param group Group to send the message too + * @param message Message to send to the group + */ + public void sendGroupMsg(Player sender, Group group, String message) { + + Preconditions.checkNotNull(sender, "sender"); + Preconditions.checkNotNull(group, "group"); + Preconditions.checkArgument(!Strings.isNullOrEmpty(message), "message"); + + if (group.getName().equals(config.getGlobalChatGroupName())) { + long mutedUntil = instance.getCivChat2SettingsManager().getGlobalChatMuteSetting().getValue(sender); + if (mutedUntil > System.currentTimeMillis()) { + sender.sendMessage(String.format(ChatStrings.globalMuted, TextUtil.formatDuration(mutedUntil - System.currentTimeMillis()))); + return; + } + } + GroupChatEvent event = new GroupChatEvent(sender, group.getName(), message); + Bukkit.getPluginManager().callEvent(event); + + if (event.isCancelled()) { + return; + } + List members = new ArrayList<>(); + List membersUUID = group.getAllMembers(); + for (UUID uuid : membersUUID) { + // Only add online players to members + Player toAdd = Bukkit.getPlayer(uuid); + if (toAdd != null && toAdd.isOnline() && NameAPI.getGroupManager().hasAccess(group, toAdd.getUniqueId(), + PermissionType.getPermission("READ_CHAT"))) { + members.add(toAdd); + } + } + + String senderName = customNames.containsKey(sender.getUniqueId()) ? customNames.get(sender.getUniqueId()) + : sender.getDisplayName(); + String formatted = parse(ChatStrings.chatGroupMessage, group.getName(), senderName, message); + + for (Player receiver : members) { + if (DBM.isIgnoringGroup(receiver.getUniqueId(), group.getName())) { + continue; + } + if (DBM.isIgnoringPlayer(receiver.getUniqueId(), sender.getUniqueId())) { + continue; + } + receiver.sendMessage(formatted); + } + + Set players = new HashSet<>(); + for (Player player : members) { + players.add(NameAPI.getCurrentName(player.getUniqueId())); + } + players.remove(senderName); + chatLog.logGroupMessage(sender, message, group.getName(), players); + } + + /** + * Method to remove player from a group chat + * + * @param player The player to remove from chat + */ + public void removeGroupChat(Player player) { + + Preconditions.checkNotNull(player, "player"); + + groupChatChannels.remove(player.getUniqueId()); + scoreboardHUD.updateScoreboardHUD(player); + } + + /** + * Method to get the group player is currently chatting in + * + * @param player Players name + * @return Group they are currently chatting in + */ + public Group getGroupChatting(Player player) { + + Preconditions.checkNotNull(player, "player"); + + return groupChatChannels.get(player.getUniqueId()); + } + + public String parse(String text) { + + return ChatUtils.parseColor(text); + } + + public String parse(String text, Object... args) { + + return String.format(ChatUtils.parseColor(text), args); + } + + public void setCustomName(UUID player, String name) { + customNames.put(player, name); + } + + public void removeCustomName(UUID player) { + customNames.remove(player); + } + + public ScoreboardHUD getScoreboardHUD() { + return scoreboardHUD; + } } diff --git a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/commands/Afk.java b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/commands/Afk.java index 6b69ffd45..75dfd92b1 100644 --- a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/commands/Afk.java +++ b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/commands/Afk.java @@ -9,14 +9,14 @@ import vg.civcraft.mc.civchat2.CivChat2; public class Afk extends BaseCommand { - @CommandAlias("afk") - @Description("Toggle afk status") - public void execute(Player player) { - boolean isAfk = CivChat2.getInstance().getCivChat2Manager().togglePlayerAfk(player); - if (isAfk) { - player.sendMessage(ChatStrings.chatAfk); - } else { - player.sendMessage(ChatStrings.chatNotAfk); - } - } + @CommandAlias("afk") + @Description("Toggle afk status") + public void execute(Player player) { + boolean isAfk = CivChat2.getInstance().getCivChat2Manager().togglePlayerAfk(player); + if (isAfk) { + player.sendMessage(ChatStrings.chatAfk); + } else { + player.sendMessage(ChatStrings.chatNotAfk); + } + } } diff --git a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/commands/CivChatCommandManager.java b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/commands/CivChatCommandManager.java index c1479177c..90af6f404 100644 --- a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/commands/CivChatCommandManager.java +++ b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/commands/CivChatCommandManager.java @@ -9,31 +9,31 @@ import vg.civcraft.mc.namelayer.command.TabCompleters.GroupTabCompleter; public class CivChatCommandManager extends CommandManager { - public CivChatCommandManager(Plugin plugin) { - super(plugin); - init(); - } + public CivChatCommandManager(Plugin plugin) { + super(plugin); + init(); + } - @Override - public void registerCommands() { - registerCommand(new Afk()); - registerCommand(new Exit()); - registerCommand(new GlobalChat()); - registerCommand(new GlobalMute()); - registerCommand(new GroupChat()); - registerCommand(new Ignore()); - registerCommand(new IgnoreGroup()); - registerCommand(new IgnoreList()); - registerCommand(new LocalChat()); - registerCommand(new Reply()); - registerCommand(new Tell()); - registerCommand(new WhoAmI()); - } + @Override + public void registerCommands() { + registerCommand(new Afk()); + registerCommand(new Exit()); + registerCommand(new GlobalChat()); + registerCommand(new GlobalMute()); + registerCommand(new GroupChat()); + registerCommand(new Ignore()); + registerCommand(new IgnoreGroup()); + registerCommand(new IgnoreList()); + registerCommand(new LocalChat()); + registerCommand(new Reply()); + registerCommand(new Tell()); + registerCommand(new WhoAmI()); + } - @Override - public void registerCompletions(@Nonnull CommandCompletions completions) { - super.registerCompletions(completions); - completions.registerCompletion("CC_Groups", (context) -> GroupTabCompleter - .complete(context.getInput(), null, context.getPlayer())); - } + @Override + public void registerCompletions(@Nonnull CommandCompletions completions) { + super.registerCompletions(completions); + completions.registerCompletion("CC_Groups", (context) -> GroupTabCompleter + .complete(context.getInput(), null, context.getPlayer())); + } } diff --git a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/commands/Exit.java b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/commands/Exit.java index 90782a0f8..1b8211350 100644 --- a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/commands/Exit.java +++ b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/commands/Exit.java @@ -16,19 +16,19 @@ import vg.civcraft.mc.civchat2.CivChat2Manager; public class Exit extends BaseCommand { - @CommandAlias("exit") - @Description("Exit private or group chats") - public void execute(Player player, @Optional String message) { - CivChat2Manager chatMan = CivChat2.getInstance().getCivChat2Manager(); - if (message == null) { - chatMan.removeChannel(player); - chatMan.removeGroupChat(player); - player.sendMessage(ChatStrings.chatMovedToGlobal); - return; - } - StringBuilder chatMsg = new StringBuilder(); - chatMsg.append(message); - Set players = new HashSet<>(CivChat2.getInstance().getServer().getOnlinePlayers()); - chatMan.broadcastMessage(player, chatMsg.toString(), localChatFormat, players); - } + @CommandAlias("exit") + @Description("Exit private or group chats") + public void execute(Player player, @Optional String message) { + CivChat2Manager chatMan = CivChat2.getInstance().getCivChat2Manager(); + if (message == null) { + chatMan.removeChannel(player); + chatMan.removeGroupChat(player); + player.sendMessage(ChatStrings.chatMovedToGlobal); + return; + } + StringBuilder chatMsg = new StringBuilder(); + chatMsg.append(message); + Set players = new HashSet<>(CivChat2.getInstance().getServer().getOnlinePlayers()); + chatMan.broadcastMessage(player, chatMsg.toString(), localChatFormat, players); + } } diff --git a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/commands/GlobalChat.java b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/commands/GlobalChat.java index f79617779..6b060fbf7 100644 --- a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/commands/GlobalChat.java +++ b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/commands/GlobalChat.java @@ -16,58 +16,59 @@ import vg.civcraft.mc.namelayer.group.Group; import vg.civcraft.mc.namelayer.permission.PermissionType; public class GlobalChat extends BaseCommand { - @CommandAlias("global|globalchat") - @Syntax("[message]") - @Description("Enters global group chat or sends a message to global group chat") - @CommandCompletion("@CC_Groups @nothing") - public void execute(Player player, @Optional String chatMessage) { - String globalGroupName = CivChat2.getInstance().getPluginConfig().getGlobalChatGroupName(); - if (globalGroupName == null) { - return; - } - Group globalGroup = GroupManager.getGroup(globalGroupName); - CivChat2Manager chatMan = CivChat2.getInstance().getCivChat2Manager(); - Group currentGroup = chatMan.getGroupChatting(player); + @CommandAlias("global|globalchat") + @Syntax("[message]") + @Description("Enters global group chat or sends a message to global group chat") + @CommandCompletion("@CC_Groups @nothing") - if (globalGroup == null) { - player.sendMessage(ChatStrings.chatGroupNotFound); - return; - } - if (!NameAPI.getGroupManager().hasAccess(globalGroup, player.getUniqueId(), - PermissionType.getPermission("WRITE_CHAT"))) { - player.sendMessage(ChatStrings.chatGroupNoPerms); - return; - } - if (CivChat2.getInstance().getDatabaseManager().isIgnoringGroup(player.getUniqueId(), globalGroupName)) { - player.sendMessage(String.format(ChatStrings.chatNeedToUnignore, globalGroupName)); - return; - } - if (chatMessage == null) { - if (currentGroup != null) { // Check if currently in group - if (currentGroup == globalGroup) { // Check if current group global - player.sendMessage(ChatStrings.chatGroupAlreadyChatting); - } else { // Switch to global group from current group - player.sendMessage(String.format(ChatStrings.chatGroupNowChattingIn, globalGroupName)); - chatMan.removeGroupChat(player); - chatMan.addGroupChat(player, globalGroup); - } - } else { // Switch to global group - player.sendMessage(String.format(ChatStrings.chatGroupNowChattingIn, globalGroupName)); - if (chatMan.getChannel(player) != null) { - chatMan.removeChannel(player); - } - chatMan.addGroupChat(player, globalGroup); - } - } else { // Send message to global group - if (currentGroup != null) { - chatMan.sendGroupMsg(player, globalGroup, chatMessage); - } else { - if (chatMan.getChannel(player) != null) { - chatMan.removeChannel(player); - } - chatMan.sendGroupMsg(player, globalGroup, chatMessage); - } - } - } + public void execute(Player player, @Optional String chatMessage) { + String globalGroupName = CivChat2.getInstance().getPluginConfig().getGlobalChatGroupName(); + if (globalGroupName == null) { + return; + } + Group globalGroup = GroupManager.getGroup(globalGroupName); + CivChat2Manager chatMan = CivChat2.getInstance().getCivChat2Manager(); + Group currentGroup = chatMan.getGroupChatting(player); + + if (globalGroup == null) { + player.sendMessage(ChatStrings.chatGroupNotFound); + return; + } + if (!NameAPI.getGroupManager().hasAccess(globalGroup, player.getUniqueId(), + PermissionType.getPermission("WRITE_CHAT"))) { + player.sendMessage(ChatStrings.chatGroupNoPerms); + return; + } + if (CivChat2.getInstance().getDatabaseManager().isIgnoringGroup(player.getUniqueId(), globalGroupName)) { + player.sendMessage(String.format(ChatStrings.chatNeedToUnignore, globalGroupName)); + return; + } + if (chatMessage == null) { + if (currentGroup != null) { // Check if currently in group + if (currentGroup == globalGroup) { // Check if current group global + player.sendMessage(ChatStrings.chatGroupAlreadyChatting); + } else { // Switch to global group from current group + player.sendMessage(String.format(ChatStrings.chatGroupNowChattingIn, globalGroupName)); + chatMan.removeGroupChat(player); + chatMan.addGroupChat(player, globalGroup); + } + } else { // Switch to global group + player.sendMessage(String.format(ChatStrings.chatGroupNowChattingIn, globalGroupName)); + if (chatMan.getChannel(player) != null) { + chatMan.removeChannel(player); + } + chatMan.addGroupChat(player, globalGroup); + } + } else { // Send message to global group + if (currentGroup != null) { + chatMan.sendGroupMsg(player, globalGroup, chatMessage); + } else { + if (chatMan.getChannel(player) != null) { + chatMan.removeChannel(player); + } + chatMan.sendGroupMsg(player, globalGroup, chatMessage); + } + } + } } diff --git a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/commands/GlobalMute.java b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/commands/GlobalMute.java index 8330ce6da..690b0dca4 100644 --- a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/commands/GlobalMute.java +++ b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/commands/GlobalMute.java @@ -21,49 +21,49 @@ import vg.civcraft.mc.namelayer.NameAPI; public class GlobalMute extends BaseCommand { - @CommandAlias("globalmute") - @CommandPermission("civchat2.globalmute") - @Syntax(" [time]") - @Description("Applies, checks or removes a players global mute timer") - @CommandCompletion("set|check|remove @allplayers @nothing") - public void execute(CommandSender sender, String getSetOrCheck, String targetPlayer, @Optional String muteTime) { - UUID player = NameAPI.getUUID(targetPlayer); - if (player == null) { - sender.sendMessage(ChatColor.RED + "The player " + targetPlayer + " does not exist"); - return; - } - LongSetting banSetting = CivChat2.getInstance().getCivChat2SettingsManager().getGlobalChatMuteSetting(); - switch (getSetOrCheck.toLowerCase()) { - case "set": - if (muteTime == null) { - sender.sendMessage(ChatColor.RED + "You need to supply a ban timer"); - return; - } - long time = ConfigHelper.parseTime(muteTime); - if (time <= 0) { - sender.sendMessage(ChatColor.RED + "Invalid ban time frame"); - return; - } - banSetting.setValue(player, System.currentTimeMillis() + time); - sender.sendMessage(ChatColor.GREEN + targetPlayer + " will be banned for " + TextUtil - .formatDuration(time, TimeUnit.MILLISECONDS)); - return; - case "remove": - banSetting.setValue(player, 0L); - sender.sendMessage(Component.text("You have unmuted the player " + targetPlayer, NamedTextColor.GREEN)); - return; - case "check": - case "get": - long timeForUnban = banSetting.getValue(player); - timeForUnban -= System.currentTimeMillis(); - if (timeForUnban <= 0) { - sender.sendMessage(ChatColor.GREEN + targetPlayer + " is not chat muted"); - return; - } - sender.sendMessage(ChatColor.GREEN + targetPlayer + " is banned for another " + TextUtil.formatDuration(timeForUnban, TimeUnit.MILLISECONDS)); - return; - default: - sender.sendMessage(ChatColor.RED + getSetOrCheck + " is not a valid action"); - } - } + @CommandAlias("globalmute") + @CommandPermission("civchat2.globalmute") + @Syntax(" [time]") + @Description("Applies, checks or removes a players global mute timer") + @CommandCompletion("set|check|remove @allplayers @nothing") + public void execute(CommandSender sender, String getSetOrCheck, String targetPlayer, @Optional String muteTime) { + UUID player = NameAPI.getUUID(targetPlayer); + if (player == null) { + sender.sendMessage(ChatColor.RED + "The player " + targetPlayer + " does not exist"); + return; + } + LongSetting banSetting = CivChat2.getInstance().getCivChat2SettingsManager().getGlobalChatMuteSetting(); + switch (getSetOrCheck.toLowerCase()) { + case "set": + if (muteTime == null) { + sender.sendMessage(ChatColor.RED + "You need to supply a ban timer"); + return; + } + long time = ConfigHelper.parseTime(muteTime); + if (time <= 0) { + sender.sendMessage(ChatColor.RED + "Invalid ban time frame"); + return; + } + banSetting.setValue(player, System.currentTimeMillis() + time); + sender.sendMessage(ChatColor.GREEN + targetPlayer + " will be banned for " + TextUtil + .formatDuration(time, TimeUnit.MILLISECONDS)); + return; + case "remove": + banSetting.setValue(player, 0L); + sender.sendMessage(Component.text("You have unmuted the player " + targetPlayer, NamedTextColor.GREEN)); + return; + case "check": + case "get": + long timeForUnban = banSetting.getValue(player); + timeForUnban -= System.currentTimeMillis(); + if (timeForUnban <= 0) { + sender.sendMessage(ChatColor.GREEN + targetPlayer + " is not chat muted"); + return; + } + sender.sendMessage(ChatColor.GREEN + targetPlayer + " is banned for another " + TextUtil.formatDuration(timeForUnban, TimeUnit.MILLISECONDS)); + return; + default: + sender.sendMessage(ChatColor.RED + getSetOrCheck + " is not a valid action"); + } + } } diff --git a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/commands/GroupChat.java b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/commands/GroupChat.java index f86c23031..af4c475a3 100644 --- a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/commands/GroupChat.java +++ b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/commands/GroupChat.java @@ -17,84 +17,84 @@ import vg.civcraft.mc.namelayer.permission.PermissionType; public class GroupChat extends BaseCommand { - @CommandAlias("groupc|groupchat|gchat|g|gc") - @Syntax("[group] [message]") - @Description("Enters a group chat or sends a message to a group chat") - @CommandCompletion("@CC_Groups @nothing") - public void execute(Player player, @Optional String targetGroup, @Optional String chatMessage) { - CivChat2Manager chatMan = CivChat2.getInstance().getCivChat2Manager(); - GroupManager gm = NameAPI.getGroupManager(); - boolean isGroupChatting = chatMan.getGroupChatting(player) != null; - Group group; - boolean defGroup = false; - if (targetGroup == null && chatMessage == null) { - // Check if player is in groupchat and move them to normal chat - if (isGroupChatting) { - player.sendMessage(ChatStrings.chatMovedToGlobal); - chatMan.removeGroupChat(player); - return; - } else { - String defGroupName = gm.getDefaultGroup(player.getUniqueId()); - if (defGroupName != null) { - group = GroupManager.getGroup(defGroupName); - defGroup = true; - } else { - return; - } - } - } - if (targetGroup == null) { - return; - } - group = GroupManager.getGroup(targetGroup); - if (group == null) { - player.sendMessage(ChatStrings.chatGroupNotFound); - return; - } - if (!NameAPI.getGroupManager().hasAccess(group, player.getUniqueId(), - PermissionType.getPermission("WRITE_CHAT"))) { - player.sendMessage(ChatStrings.chatGroupNoPerms); - return; - } - if (CivChat2.getInstance().getDatabaseManager().isIgnoringGroup(player.getUniqueId(), group.getName())) { - player.sendMessage(String.format(ChatStrings.chatNeedToUnignore, group.getName())); - return; - } - if (chatMessage == null) { - if (isGroupChatting) { - // Player already groupchatting check if it's this group - Group curGroup = chatMan.getGroupChatting(player); - if (curGroup == group) { - player.sendMessage(ChatStrings.chatGroupAlreadyChatting); - } else { - player.sendMessage(String.format(ChatStrings.chatGroupNowChattingIn, group.getName())); - chatMan.removeGroupChat(player); - chatMan.addGroupChat(player, group); - } - } else { - player.sendMessage(String.format(ChatStrings.chatGroupNowChattingIn, group.getName())); - if (chatMan.getChannel(player) != null) { - chatMan.removeChannel(player); - } - chatMan.addGroupChat(player, group); - } - } else { - StringBuilder chatMsg = new StringBuilder(); - chatMsg.append(chatMessage); - if (isGroupChatting) { - // Player already groupchatting check if it's this group - Group curGroup = chatMan.getGroupChatting(player); - if (curGroup == group) { - chatMan.sendGroupMsg(player, group, chatMsg.toString()); - } else { - chatMan.sendGroupMsg(player, group, chatMsg.toString()); - } - } else { - if (chatMan.getChannel(player) != null) { - chatMan.removeChannel(player); - } - chatMan.sendGroupMsg(player, group, chatMsg.toString()); - } - } - } + @CommandAlias("groupc|groupchat|gchat|g|gc") + @Syntax("[group] [message]") + @Description("Enters a group chat or sends a message to a group chat") + @CommandCompletion("@CC_Groups @nothing") + public void execute(Player player, @Optional String targetGroup, @Optional String chatMessage) { + CivChat2Manager chatMan = CivChat2.getInstance().getCivChat2Manager(); + GroupManager gm = NameAPI.getGroupManager(); + boolean isGroupChatting = chatMan.getGroupChatting(player) != null; + Group group; + boolean defGroup = false; + if (targetGroup == null && chatMessage == null) { + // Check if player is in groupchat and move them to normal chat + if (isGroupChatting) { + player.sendMessage(ChatStrings.chatMovedToGlobal); + chatMan.removeGroupChat(player); + return; + } else { + String defGroupName = gm.getDefaultGroup(player.getUniqueId()); + if (defGroupName != null) { + group = GroupManager.getGroup(defGroupName); + defGroup = true; + } else { + return; + } + } + } + if (targetGroup == null) { + return; + } + group = GroupManager.getGroup(targetGroup); + if (group == null) { + player.sendMessage(ChatStrings.chatGroupNotFound); + return; + } + if (!NameAPI.getGroupManager().hasAccess(group, player.getUniqueId(), + PermissionType.getPermission("WRITE_CHAT"))) { + player.sendMessage(ChatStrings.chatGroupNoPerms); + return; + } + if (CivChat2.getInstance().getDatabaseManager().isIgnoringGroup(player.getUniqueId(), group.getName())) { + player.sendMessage(String.format(ChatStrings.chatNeedToUnignore, group.getName())); + return; + } + if (chatMessage == null) { + if (isGroupChatting) { + // Player already groupchatting check if it's this group + Group curGroup = chatMan.getGroupChatting(player); + if (curGroup == group) { + player.sendMessage(ChatStrings.chatGroupAlreadyChatting); + } else { + player.sendMessage(String.format(ChatStrings.chatGroupNowChattingIn, group.getName())); + chatMan.removeGroupChat(player); + chatMan.addGroupChat(player, group); + } + } else { + player.sendMessage(String.format(ChatStrings.chatGroupNowChattingIn, group.getName())); + if (chatMan.getChannel(player) != null) { + chatMan.removeChannel(player); + } + chatMan.addGroupChat(player, group); + } + } else { + StringBuilder chatMsg = new StringBuilder(); + chatMsg.append(chatMessage); + if (isGroupChatting) { + // Player already groupchatting check if it's this group + Group curGroup = chatMan.getGroupChatting(player); + if (curGroup == group) { + chatMan.sendGroupMsg(player, group, chatMsg.toString()); + } else { + chatMan.sendGroupMsg(player, group, chatMsg.toString()); + } + } else { + if (chatMan.getChannel(player) != null) { + chatMan.removeChannel(player); + } + chatMan.sendGroupMsg(player, group, chatMsg.toString()); + } + } + } } diff --git a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/commands/Ignore.java b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/commands/Ignore.java index 5c69df103..61ef78f1b 100644 --- a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/commands/Ignore.java +++ b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/commands/Ignore.java @@ -13,31 +13,31 @@ import vg.civcraft.mc.civchat2.database.CivChatDAO; public class Ignore extends BaseCommand { - @CommandAlias("ignore") - @Syntax("") - @Description("Toggles ignoring a player") - @CommandCompletion("@allplayers") - public void execute(Player player, String targetPlayer) { - Player ignoredPlayer = Bukkit.getServer().getPlayer(targetPlayer); - if (ignoredPlayer == null) { - player.sendMessage(ChatStrings.chatPlayerNotFound); - return; - } - if (player == ignoredPlayer) { - player.sendMessage(ChatStrings.chatCantIgnoreSelf); - return; - } - CivChatDAO db = CivChat2.getInstance().getDatabaseManager(); - if (!db.isIgnoringPlayer(player.getUniqueId(), ignoredPlayer.getUniqueId())) { - // Player added to the list - db.addIgnoredPlayer(player.getUniqueId(), ignoredPlayer.getUniqueId()); - player.sendMessage(String.format(ChatStrings.chatNowIgnoring, ignoredPlayer.getDisplayName())); - return; - } else { - // Player removed from the list - db.removeIgnoredPlayer(player.getUniqueId(), ignoredPlayer.getUniqueId()); - player.sendMessage(String.format(ChatStrings.chatStoppedIgnoring, ignoredPlayer.getDisplayName())); - return; - } - } + @CommandAlias("ignore") + @Syntax("") + @Description("Toggles ignoring a player") + @CommandCompletion("@allplayers") + public void execute(Player player, String targetPlayer) { + Player ignoredPlayer = Bukkit.getServer().getPlayer(targetPlayer); + if (ignoredPlayer == null) { + player.sendMessage(ChatStrings.chatPlayerNotFound); + return; + } + if (player == ignoredPlayer) { + player.sendMessage(ChatStrings.chatCantIgnoreSelf); + return; + } + CivChatDAO db = CivChat2.getInstance().getDatabaseManager(); + if (!db.isIgnoringPlayer(player.getUniqueId(), ignoredPlayer.getUniqueId())) { + // Player added to the list + db.addIgnoredPlayer(player.getUniqueId(), ignoredPlayer.getUniqueId()); + player.sendMessage(String.format(ChatStrings.chatNowIgnoring, ignoredPlayer.getDisplayName())); + return; + } else { + // Player removed from the list + db.removeIgnoredPlayer(player.getUniqueId(), ignoredPlayer.getUniqueId()); + player.sendMessage(String.format(ChatStrings.chatStoppedIgnoring, ignoredPlayer.getDisplayName())); + return; + } + } } diff --git a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/commands/IgnoreGroup.java b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/commands/IgnoreGroup.java index cb44d2c1e..05b35fe06 100644 --- a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/commands/IgnoreGroup.java +++ b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/commands/IgnoreGroup.java @@ -14,29 +14,29 @@ import vg.civcraft.mc.namelayer.group.Group; public class IgnoreGroup extends BaseCommand { - @CommandAlias("ignoregroup") - @Syntax("") - @Description("Toggles ignoring a group") - public void execute(Player player, String targetGroup) { - Group group = GroupManager.getGroup(targetGroup); - if (group == null) { - player.sendMessage(ChatStrings.chatGroupNotFound); - return; - } - String ignore = group.getName(); - CivChatDAO db = CivChat2.getInstance().getDatabaseManager(); - if (!db.isIgnoringGroup(player.getUniqueId(), ignore)) { - db.addIgnoredGroup(player.getUniqueId(), ignore); - CivChat2Manager chatMan = CivChat2.getInstance().getCivChat2Manager(); - player.sendMessage(String.format(ChatStrings.chatNowIgnoring, ignore)); - if (group.equals(chatMan.getGroupChatting(player))) { - chatMan.removeGroupChat(player); - player.sendMessage(ChatStrings.chatMovedToGlobal); - } - return; - } else { - db.removeIgnoredGroup(player.getUniqueId(), ignore); - player.sendMessage(String.format(ChatStrings.chatStoppedIgnoring, ignore)); - } - } + @CommandAlias("ignoregroup") + @Syntax("") + @Description("Toggles ignoring a group") + public void execute(Player player, String targetGroup) { + Group group = GroupManager.getGroup(targetGroup); + if (group == null) { + player.sendMessage(ChatStrings.chatGroupNotFound); + return; + } + String ignore = group.getName(); + CivChatDAO db = CivChat2.getInstance().getDatabaseManager(); + if (!db.isIgnoringGroup(player.getUniqueId(), ignore)) { + db.addIgnoredGroup(player.getUniqueId(), ignore); + CivChat2Manager chatMan = CivChat2.getInstance().getCivChat2Manager(); + player.sendMessage(String.format(ChatStrings.chatNowIgnoring, ignore)); + if (group.equals(chatMan.getGroupChatting(player))) { + chatMan.removeGroupChat(player); + player.sendMessage(ChatStrings.chatMovedToGlobal); + } + return; + } else { + db.removeIgnoredGroup(player.getUniqueId(), ignore); + player.sendMessage(String.format(ChatStrings.chatStoppedIgnoring, ignore)); + } + } } diff --git a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/commands/IgnoreList.java b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/commands/IgnoreList.java index bbcc9e329..4e4c36c4c 100644 --- a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/commands/IgnoreList.java +++ b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/commands/IgnoreList.java @@ -19,67 +19,67 @@ import vg.civcraft.mc.civchat2.database.CivChatDAO; import vg.civcraft.mc.namelayer.NameAPI; public final class IgnoreList extends BaseCommand { - @CommandAlias("ignorelist") - @Description("Lists the players and groups you are ignoring") - private void execute( - final @NotNull Player sender - ) { - final CivChatDAO db = CivChat2.getInstance().getDatabaseManager(); - // Ignored players - sender.sendMessage( - Component.text() - .content("Ignored players: [") - .append( - db.getIgnoredPlayers(sender.getUniqueId()) - .stream() - .map(NameAPI::getCurrentName) - .filter(Objects::nonNull) - .flatMap(commaSeparatedClickableNames("/ignore %s")) - .toList() - ) - .append(Component.text("]")) - ); + @CommandAlias("ignorelist") + @Description("Lists the players and groups you are ignoring") + private void execute( + final @NotNull Player sender + ) { + final CivChatDAO db = CivChat2.getInstance().getDatabaseManager(); - // Ignored groups - sender.sendMessage( - Component.text() - .content("Ignored groups: [") - .append( - db.getIgnoredGroups(sender.getUniqueId()) - .stream() - .flatMap(commaSeparatedClickableNames("/ignoregroup %s")) - .toList() - ) - .append(Component.text("]")) - ); - } + // Ignored players + sender.sendMessage( + Component.text() + .content("Ignored players: [") + .append( + db.getIgnoredPlayers(sender.getUniqueId()) + .stream() + .map(NameAPI::getCurrentName) + .filter(Objects::nonNull) + .flatMap(commaSeparatedClickableNames("/ignore %s")) + .toList() + ) + .append(Component.text("]")) + ); - private static @NotNull Function> commaSeparatedClickableNames( - final @NotNull String formattedCommand - ) { - final var hasPreviousName = new AtomicBoolean(false); - return (name) -> { - final Component clickableName = Component.text() - .content(name) - .color(NamedTextColor.YELLOW) - .decoration(TextDecoration.UNDERLINED, TextDecoration.State.TRUE) - .clickEvent(ClickEvent.clickEvent( - ClickEvent.Action.COPY_TO_CLIPBOARD, - formattedCommand.formatted(name) - )) - .hoverEvent(HoverEvent.showText(Component.text("Click to copy un-ignore command"))) - .build(); - if (hasPreviousName.get()) { - return Stream.of( - Component.text(", "), - clickableName - ); - } - else { - hasPreviousName.set(true); - return Stream.of(clickableName); - } - }; - } + // Ignored groups + sender.sendMessage( + Component.text() + .content("Ignored groups: [") + .append( + db.getIgnoredGroups(sender.getUniqueId()) + .stream() + .flatMap(commaSeparatedClickableNames("/ignoregroup %s")) + .toList() + ) + .append(Component.text("]")) + ); + } + + private static @NotNull Function> commaSeparatedClickableNames( + final @NotNull String formattedCommand + ) { + final var hasPreviousName = new AtomicBoolean(false); + return (name) -> { + final Component clickableName = Component.text() + .content(name) + .color(NamedTextColor.YELLOW) + .decoration(TextDecoration.UNDERLINED, TextDecoration.State.TRUE) + .clickEvent(ClickEvent.clickEvent( + ClickEvent.Action.COPY_TO_CLIPBOARD, + formattedCommand.formatted(name) + )) + .hoverEvent(HoverEvent.showText(Component.text("Click to copy un-ignore command"))) + .build(); + if (hasPreviousName.get()) { + return Stream.of( + Component.text(", "), + clickableName + ); + } else { + hasPreviousName.set(true); + return Stream.of(clickableName); + } + }; + } } diff --git a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/commands/LocalChat.java b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/commands/LocalChat.java index 07e97e78a..67cb31d34 100644 --- a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/commands/LocalChat.java +++ b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/commands/LocalChat.java @@ -14,19 +14,20 @@ import vg.civcraft.mc.civchat2.CivChat2; import vg.civcraft.mc.civchat2.CivChat2Manager; public class LocalChat extends BaseCommand { - @CommandAlias("local|localchat") - @Description("Enter local chat") - public void execute(Player player, @Optional String chatMessage) { - CivChat2Manager chatMan = CivChat2.getInstance().getCivChat2Manager(); - Set players = new HashSet<>(CivChat2.getInstance().getServer().getOnlinePlayers()); + @CommandAlias("local|localchat") + @Description("Enter local chat") - if (chatMessage == null) { - chatMan.removeChannel(player); - chatMan.removeGroupChat(player); - player.sendMessage(ChatStrings.chatMovedToGlobal); - return; - } - chatMan.broadcastMessage(player, chatMessage, localChatFormat, players); - } + public void execute(Player player, @Optional String chatMessage) { + CivChat2Manager chatMan = CivChat2.getInstance().getCivChat2Manager(); + Set players = new HashSet<>(CivChat2.getInstance().getServer().getOnlinePlayers()); + + if (chatMessage == null) { + chatMan.removeChannel(player); + chatMan.removeGroupChat(player); + player.sendMessage(ChatStrings.chatMovedToGlobal); + return; + } + chatMan.broadcastMessage(player, chatMessage, localChatFormat, players); + } } diff --git a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/commands/Reply.java b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/commands/Reply.java index 0c7229bfe..75f4d44c9 100644 --- a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/commands/Reply.java +++ b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/commands/Reply.java @@ -14,36 +14,36 @@ import vg.civcraft.mc.civchat2.CivChat2Manager; public class Reply extends BaseCommand { - @CommandAlias("reply|r") - @Syntax("[message]") - @Description("Replies to the last person you sent a message to or received one from") - public void execute(Player player, @Optional String chatMessage) { - CivChat2Manager chatMan = CivChat2.getInstance().getCivChat2Manager(); - UUID receiverUUID = chatMan.getPlayerReply(player); + @CommandAlias("reply|r") + @Syntax("[message]") + @Description("Replies to the last person you sent a message to or received one from") + public void execute(Player player, @Optional String chatMessage) { + CivChat2Manager chatMan = CivChat2.getInstance().getCivChat2Manager(); + UUID receiverUUID = chatMan.getPlayerReply(player); - Player receiver = Bukkit.getPlayer(receiverUUID); - if (receiver == null) { - player.sendMessage(ChatStrings.chatNoOneToReplyTo); - return; - } + Player receiver = Bukkit.getPlayer(receiverUUID); + if (receiver == null) { + player.sendMessage(ChatStrings.chatNoOneToReplyTo); + return; + } - if (!(receiver.isOnline())) { - player.sendMessage(ChatStrings.chatPlayerIsOffline); - return; - } + if (!(receiver.isOnline())) { + player.sendMessage(ChatStrings.chatPlayerIsOffline); + return; + } - if (player.getUniqueId().equals(receiver.getUniqueId())) { - player.sendMessage(ChatStrings.chatCantMessageSelf); - return; - } + if (player.getUniqueId().equals(receiver.getUniqueId())) { + player.sendMessage(ChatStrings.chatCantMessageSelf); + return; + } - if (!(chatMessage == null)) { - chatMan.sendPrivateMsg(player, receiver, chatMessage); - return; - } - // Player to chat with reply user - chatMan.removeChannel(player); - chatMan.addChatChannel(player, receiver); - player.sendMessage(String.format(ChatStrings.chatNowChattingWith, receiver.getName())); - } + if (!(chatMessage == null)) { + chatMan.sendPrivateMsg(player, receiver, chatMessage); + return; + } + // Player to chat with reply user + chatMan.removeChannel(player); + chatMan.addChatChannel(player, receiver); + player.sendMessage(String.format(ChatStrings.chatNowChattingWith, receiver.getName())); + } } diff --git a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/commands/Tell.java b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/commands/Tell.java index ce7e2263c..eca9004d9 100644 --- a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/commands/Tell.java +++ b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/commands/Tell.java @@ -17,55 +17,55 @@ import vg.civcraft.mc.civchat2.database.CivChatDAO; public class Tell extends BaseCommand { - @CommandAlias("tell|message|m|pm|msg") - @Syntax("[player] [message]") - @Description("Sends a private message to someone or enters a private chat with them") - @CommandCompletion("@allplayers @nothing") - public void execute(Player player, @Optional String targetPlayer, @Optional String chatMessage) { - CivChat2Manager chatMan = CivChat2.getInstance().getCivChat2Manager(); - if (targetPlayer == null && chatMessage == null) { - UUID chattingWith = chatMan.getChannel(player); - if (chattingWith != null) { - chatMan.removeChannel(player); - player.sendMessage(ChatStrings.chatRemovedFromChat); - } else { - player.sendMessage(ChatStrings.chatNotInPrivateChat); - } - return; - } + @CommandAlias("tell|message|m|pm|msg") + @Syntax("[player] [message]") + @Description("Sends a private message to someone or enters a private chat with them") + @CommandCompletion("@allplayers @nothing") + public void execute(Player player, @Optional String targetPlayer, @Optional String chatMessage) { + CivChat2Manager chatMan = CivChat2.getInstance().getCivChat2Manager(); + if (targetPlayer == null && chatMessage == null) { + UUID chattingWith = chatMan.getChannel(player); + if (chattingWith != null) { + chatMan.removeChannel(player); + player.sendMessage(ChatStrings.chatRemovedFromChat); + } else { + player.sendMessage(ChatStrings.chatNotInPrivateChat); + } + return; + } - Player receiver = Bukkit.getPlayer(targetPlayer); - if (receiver == null) { - player.sendMessage(ChatStrings.chatPlayerNotFound); - return; - } + Player receiver = Bukkit.getPlayer(targetPlayer); + if (receiver == null) { + player.sendMessage(ChatStrings.chatPlayerNotFound); + return; + } - if (!(receiver.isOnline())) { - player.sendMessage(ChatStrings.chatPlayerIsOffline); - return; - } + if (!(receiver.isOnline())) { + player.sendMessage(ChatStrings.chatPlayerIsOffline); + return; + } - if (player == receiver) { - player.sendMessage(ChatStrings.chatCantMessageSelf); - return; - } + if (player == receiver) { + player.sendMessage(ChatStrings.chatCantMessageSelf); + return; + } - if (!(chatMessage == null)) { - chatMan.sendPrivateMsg(player, receiver, chatMessage); - return; - } else { - CivChatDAO db = CivChat2.getInstance().getDatabaseManager(); - if (db.isIgnoringPlayer(player.getUniqueId(), receiver.getUniqueId())) { - player.sendMessage(String.format(ChatStrings.chatNeedToUnignore, receiver.getDisplayName())); - return; - } + if (!(chatMessage == null)) { + chatMan.sendPrivateMsg(player, receiver, chatMessage); + return; + } else { + CivChatDAO db = CivChat2.getInstance().getDatabaseManager(); + if (db.isIgnoringPlayer(player.getUniqueId(), receiver.getUniqueId())) { + player.sendMessage(String.format(ChatStrings.chatNeedToUnignore, receiver.getDisplayName())); + return; + } - if (db.isIgnoringPlayer(receiver.getUniqueId(), player.getUniqueId())) { - player.sendMessage(ChatStrings.chatPlayerIgnoringYou); - return; - } - chatMan.addChatChannel(player, receiver); - player.sendMessage(String.format(ChatStrings.chatNowChattingWith, receiver.getDisplayName())); - } - } + if (db.isIgnoringPlayer(receiver.getUniqueId(), player.getUniqueId())) { + player.sendMessage(ChatStrings.chatPlayerIgnoringYou); + return; + } + chatMan.addChatChannel(player, receiver); + player.sendMessage(String.format(ChatStrings.chatNowChattingWith, receiver.getDisplayName())); + } + } } diff --git a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/commands/WhoAmI.java b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/commands/WhoAmI.java index c1b4eebdd..6f3d13284 100644 --- a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/commands/WhoAmI.java +++ b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/commands/WhoAmI.java @@ -11,18 +11,18 @@ import vg.civcraft.mc.namelayer.NameAPI; public class WhoAmI extends BaseCommand { - @CommandAlias("whoami") - @Description("Tells you who you are") - public void execute(CommandSender sender) { - final String response = ChatColor.YELLOW + "You are: " + ChatColor.RESET; - if (sender instanceof Player) { - final Player player = (Player) sender; - final String name = NameAPI.getCurrentName(player.getUniqueId()); - if (!Strings.isNullOrEmpty(name)) { - player.sendMessage(response + name); - return; - } - } - sender.sendMessage(response + sender.getName()); - } + @CommandAlias("whoami") + @Description("Tells you who you are") + public void execute(CommandSender sender) { + final String response = ChatColor.YELLOW + "You are: " + ChatColor.RESET; + if (sender instanceof Player) { + final Player player = (Player) sender; + final String name = NameAPI.getCurrentName(player.getUniqueId()); + if (!Strings.isNullOrEmpty(name)) { + player.sendMessage(response + name); + return; + } + } + sender.sendMessage(response + sender.getName()); + } } diff --git a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/database/CivChatDAO.java b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/database/CivChatDAO.java index 09426e765..7c806a90f 100644 --- a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/database/CivChatDAO.java +++ b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/database/CivChatDAO.java @@ -13,275 +13,275 @@ import vg.civcraft.mc.civchat2.utility.CivChat2Config; public class CivChatDAO { - private CivChat2 plugin = CivChat2.getInstance(); + private CivChat2 plugin = CivChat2.getInstance(); - private CivChat2Config config = plugin.getPluginConfig(); + private CivChat2Config config = plugin.getPluginConfig(); - private Database db; + private Database db; - private HashMap> ignoredPlayers = new HashMap<>(); + private HashMap> ignoredPlayers = new HashMap<>(); - private HashMap> ignoredGroups = new HashMap<>(); + private HashMap> ignoredGroups = new HashMap<>(); - private String addIgnoredPlayer; + private String addIgnoredPlayer; - private String getIgnoredPlayers; + private String getIgnoredPlayers; - private String removeIgnoredPlayer; + private String removeIgnoredPlayer; - private String addIgnoredGroup; + private String addIgnoredGroup; - private String getIgnoredGroups; + private String getIgnoredGroups; - private String removeIgnoredGroup; + private String removeIgnoredGroup; - private String loadIgnoredPlayersList; + private String loadIgnoredPlayersList; - private String loadIgnoredGroupsList; + private String loadIgnoredGroupsList; - public CivChatDAO() { + public CivChatDAO() { - if (!isValidConnection()) { - return; - } - executeDatabaseStatements(); - loadPreparedStatements(); - loadIgnoredPlayersList(); - loadIgnoredGroupsList(); - } + if (!isValidConnection()) { + return; + } + executeDatabaseStatements(); + loadPreparedStatements(); + loadIgnoredPlayersList(); + loadIgnoredGroupsList(); + } - public boolean isValidConnection() { + public boolean isValidConnection() { - String username = config.getMysqlUsername(); - String host = config.getMysqlHost(); - int port = config.getMysqlPort(); - String password = config.getMysqlPassword(); - String dbname = config.getMysqlDBname(); - db = new Database(host, port, dbname, username, password, plugin.getLogger()); - return db.connect(); - } + String username = config.getMysqlUsername(); + String host = config.getMysqlHost(); + int port = config.getMysqlPort(); + String password = config.getMysqlPassword(); + String dbname = config.getMysqlDBname(); + db = new Database(host, port, dbname, username, password, plugin.getLogger()); + return db.connect(); + } - private void executeDatabaseStatements() { + private void executeDatabaseStatements() { - db.execute("create table if not exists PlayersIgnoreList(" + "player varchar(36) not null," - + "ignoredPlayer varchar(36) not null);"); - db.execute("create table if not exists GroupsIgnoreList(" + "player varchar(36) not null," - + "ignoredGroup varchar(255) not null);"); - } + db.execute("create table if not exists PlayersIgnoreList(" + "player varchar(36) not null," + + "ignoredPlayer varchar(36) not null);"); + db.execute("create table if not exists GroupsIgnoreList(" + "player varchar(36) not null," + + "ignoredGroup varchar(255) not null);"); + } - public boolean isConnected() { + public boolean isConnected() { - return db.isConnected(); - } + return db.isConnected(); + } - private void loadPreparedStatements() { + private void loadPreparedStatements() { - addIgnoredPlayer = "insert into PlayersIgnoreList(player, ignoredPlayer) values(?,?);"; - getIgnoredPlayers = "select * from PlayersIgnoreList where player = ?;"; - removeIgnoredPlayer = "delete from PlayersIgnoreList where player = ? and ignoredPlayer = ?;"; + addIgnoredPlayer = "insert into PlayersIgnoreList(player, ignoredPlayer) values(?,?);"; + getIgnoredPlayers = "select * from PlayersIgnoreList where player = ?;"; + removeIgnoredPlayer = "delete from PlayersIgnoreList where player = ? and ignoredPlayer = ?;"; - addIgnoredGroup = "insert into GroupsIgnoreList(player, ignoredGroup) values(?,?);"; - getIgnoredGroups = "select * from GroupsIgnoreList where player = ?;"; - removeIgnoredGroup = "delete from GroupsIgnoreList where player = ? and ignoredGroup = ?;"; + addIgnoredGroup = "insert into GroupsIgnoreList(player, ignoredGroup) values(?,?);"; + getIgnoredGroups = "select * from GroupsIgnoreList where player = ?;"; + removeIgnoredGroup = "delete from GroupsIgnoreList where player = ? and ignoredGroup = ?;"; - loadIgnoredPlayersList = "select * from PlayersIgnoreList"; - loadIgnoredGroupsList = "select * from GroupsIgnoreList"; - } + loadIgnoredPlayersList = "select * from PlayersIgnoreList"; + loadIgnoredGroupsList = "select * from GroupsIgnoreList"; + } - private boolean addIgnoredPlayerToMap(UUID playerUUID, UUID ignoredPlayerUUID) { + private boolean addIgnoredPlayerToMap(UUID playerUUID, UUID ignoredPlayerUUID) { - if (ignoredPlayers.containsKey(playerUUID)) { - if (ignoredPlayers.get(playerUUID).contains(ignoredPlayerUUID)) { - return false; - } - ignoredPlayers.get(playerUUID).add(ignoredPlayerUUID); - } else { - List ignoredPlayersList = new ArrayList<>(); - ignoredPlayersList.add(ignoredPlayerUUID); - ignoredPlayers.put(playerUUID, ignoredPlayersList); - } - return true; - } + if (ignoredPlayers.containsKey(playerUUID)) { + if (ignoredPlayers.get(playerUUID).contains(ignoredPlayerUUID)) { + return false; + } + ignoredPlayers.get(playerUUID).add(ignoredPlayerUUID); + } else { + List ignoredPlayersList = new ArrayList<>(); + ignoredPlayersList.add(ignoredPlayerUUID); + ignoredPlayers.put(playerUUID, ignoredPlayersList); + } + return true; + } - private boolean removeIgnoredPlayerFromMap(UUID playerUUID, UUID ignoredPlayerUUID) { + private boolean removeIgnoredPlayerFromMap(UUID playerUUID, UUID ignoredPlayerUUID) { - if (ignoredPlayers.containsKey(playerUUID)) { - ignoredPlayers.get(playerUUID).remove(ignoredPlayerUUID); - if (ignoredPlayers.get(playerUUID).isEmpty()) { - ignoredPlayers.remove(playerUUID); - } - return true; - } - return false; - } + if (ignoredPlayers.containsKey(playerUUID)) { + ignoredPlayers.get(playerUUID).remove(ignoredPlayerUUID); + if (ignoredPlayers.get(playerUUID).isEmpty()) { + ignoredPlayers.remove(playerUUID); + } + return true; + } + return false; + } - public void loadIgnoredPlayersList() { + public void loadIgnoredPlayersList() { - PreparedStatement loadIgnoredPlayersList = db.prepareStatement(this.loadIgnoredPlayersList); - try { - ResultSet rs = loadIgnoredPlayersList.executeQuery(); - while (rs.next()) { - addIgnoredPlayerToMap(UUID.fromString(rs.getString("player")), - UUID.fromString(rs.getString("ignoredPlayer"))); - } - } catch (SQLException e) { - e.printStackTrace(); - } - } + PreparedStatement loadIgnoredPlayersList = db.prepareStatement(this.loadIgnoredPlayersList); + try { + ResultSet rs = loadIgnoredPlayersList.executeQuery(); + while (rs.next()) { + addIgnoredPlayerToMap(UUID.fromString(rs.getString("player")), + UUID.fromString(rs.getString("ignoredPlayer"))); + } + } catch (SQLException e) { + e.printStackTrace(); + } + } - private boolean addIgnoredGroupToMap(UUID playerUUID, String group) { + private boolean addIgnoredGroupToMap(UUID playerUUID, String group) { - if (ignoredGroups.containsKey(playerUUID)) { - if (ignoredGroups.get(playerUUID).contains(group)) { - return false; - } - ignoredGroups.get(playerUUID).add(group); - } else { - List ignoredGroupList = new ArrayList(); - ignoredGroupList.add(group); - ignoredGroups.put(playerUUID, ignoredGroupList); - } - return true; - } + if (ignoredGroups.containsKey(playerUUID)) { + if (ignoredGroups.get(playerUUID).contains(group)) { + return false; + } + ignoredGroups.get(playerUUID).add(group); + } else { + List ignoredGroupList = new ArrayList(); + ignoredGroupList.add(group); + ignoredGroups.put(playerUUID, ignoredGroupList); + } + return true; + } - private boolean removeIgnoredGroupFromMap(UUID playerUUID, String group) { + private boolean removeIgnoredGroupFromMap(UUID playerUUID, String group) { - if (ignoredGroups.containsKey(playerUUID)) { - ignoredGroups.get(playerUUID).remove(group); - if (ignoredGroups.get(playerUUID).isEmpty()) { - ignoredGroups.remove(playerUUID); - } - return true; - } - return false; - } + if (ignoredGroups.containsKey(playerUUID)) { + ignoredGroups.get(playerUUID).remove(group); + if (ignoredGroups.get(playerUUID).isEmpty()) { + ignoredGroups.remove(playerUUID); + } + return true; + } + return false; + } - public void loadIgnoredGroupsList() { + public void loadIgnoredGroupsList() { - PreparedStatement loadIgnoredGroupsList = db.prepareStatement(this.loadIgnoredGroupsList); - try { - ResultSet rs = loadIgnoredGroupsList.executeQuery(); - while (rs.next()) { - addIgnoredGroupToMap(UUID.fromString(rs.getString("player")), rs.getString("ignoredGroup")); - } - } catch (SQLException e) { - e.printStackTrace(); - } - } + PreparedStatement loadIgnoredGroupsList = db.prepareStatement(this.loadIgnoredGroupsList); + try { + ResultSet rs = loadIgnoredGroupsList.executeQuery(); + while (rs.next()) { + addIgnoredGroupToMap(UUID.fromString(rs.getString("player")), rs.getString("ignoredGroup")); + } + } catch (SQLException e) { + e.printStackTrace(); + } + } - public boolean addIgnoredPlayer(UUID playerUUID, UUID ignoredPlayerUUID) { + public boolean addIgnoredPlayer(UUID playerUUID, UUID ignoredPlayerUUID) { - if (!addIgnoredPlayerToMap(playerUUID, ignoredPlayerUUID)) { - return false; - } - PreparedStatement addIgnoredPlayer = db.prepareStatement(this.addIgnoredPlayer); - try { - addIgnoredPlayer.setString(1, playerUUID.toString()); - addIgnoredPlayer.setString(2, ignoredPlayerUUID.toString()); - addIgnoredPlayer.execute(); - } catch (SQLException e) { - e.printStackTrace(); - } - return true; - } + if (!addIgnoredPlayerToMap(playerUUID, ignoredPlayerUUID)) { + return false; + } + PreparedStatement addIgnoredPlayer = db.prepareStatement(this.addIgnoredPlayer); + try { + addIgnoredPlayer.setString(1, playerUUID.toString()); + addIgnoredPlayer.setString(2, ignoredPlayerUUID.toString()); + addIgnoredPlayer.execute(); + } catch (SQLException e) { + e.printStackTrace(); + } + return true; + } - public List getIgnoredPlayers(UUID playerUUID) { + public List getIgnoredPlayers(UUID playerUUID) { - if (ignoredPlayers.containsKey(playerUUID)) { - return ignoredPlayers.get(playerUUID); - } - List ignoredPlayersList = new LinkedList<>(); - PreparedStatement getIgnoredPlayers = db.prepareStatement(this.getIgnoredPlayers); - try { - getIgnoredPlayers.setString(1, playerUUID.toString()); - ResultSet rs = getIgnoredPlayers.executeQuery(); - while (rs.next()) { - ignoredPlayersList.add(UUID.fromString(rs.getString("ignoredPlayer"))); - } - ignoredPlayers.put(playerUUID, ignoredPlayersList); - return ignoredPlayersList; - } catch (SQLException e) { - e.printStackTrace(); - } - return null; - } + if (ignoredPlayers.containsKey(playerUUID)) { + return ignoredPlayers.get(playerUUID); + } + List ignoredPlayersList = new LinkedList<>(); + PreparedStatement getIgnoredPlayers = db.prepareStatement(this.getIgnoredPlayers); + try { + getIgnoredPlayers.setString(1, playerUUID.toString()); + ResultSet rs = getIgnoredPlayers.executeQuery(); + while (rs.next()) { + ignoredPlayersList.add(UUID.fromString(rs.getString("ignoredPlayer"))); + } + ignoredPlayers.put(playerUUID, ignoredPlayersList); + return ignoredPlayersList; + } catch (SQLException e) { + e.printStackTrace(); + } + return null; + } - public boolean removeIgnoredPlayer(UUID playerUUID, UUID ignoredPlayerUUID) { + public boolean removeIgnoredPlayer(UUID playerUUID, UUID ignoredPlayerUUID) { - if (!removeIgnoredPlayerFromMap(playerUUID, ignoredPlayerUUID)) { - return false; - } - PreparedStatement removeIgnoredPlayer = db.prepareStatement(this.removeIgnoredPlayer); - try { - removeIgnoredPlayer.setString(1, playerUUID.toString()); - removeIgnoredPlayer.setString(2, ignoredPlayerUUID.toString()); - removeIgnoredPlayer.execute(); - } catch (SQLException e) { - e.printStackTrace(); - } - return true; - } - - public boolean addIgnoredGroup(UUID playerUUID, String group) { + if (!removeIgnoredPlayerFromMap(playerUUID, ignoredPlayerUUID)) { + return false; + } + PreparedStatement removeIgnoredPlayer = db.prepareStatement(this.removeIgnoredPlayer); + try { + removeIgnoredPlayer.setString(1, playerUUID.toString()); + removeIgnoredPlayer.setString(2, ignoredPlayerUUID.toString()); + removeIgnoredPlayer.execute(); + } catch (SQLException e) { + e.printStackTrace(); + } + return true; + } - if (!addIgnoredGroupToMap(playerUUID, group)) { - return false; - } - PreparedStatement addIgnoredGroup = db.prepareStatement(this.addIgnoredGroup); - try { - addIgnoredGroup.setString(1, playerUUID.toString()); - addIgnoredGroup.setString(2, group); - addIgnoredGroup.execute(); - } catch (SQLException e) { - e.printStackTrace(); - } - return true; - } + public boolean addIgnoredGroup(UUID playerUUID, String group) { - public List getIgnoredGroups(UUID playerUUID) { + if (!addIgnoredGroupToMap(playerUUID, group)) { + return false; + } + PreparedStatement addIgnoredGroup = db.prepareStatement(this.addIgnoredGroup); + try { + addIgnoredGroup.setString(1, playerUUID.toString()); + addIgnoredGroup.setString(2, group); + addIgnoredGroup.execute(); + } catch (SQLException e) { + e.printStackTrace(); + } + return true; + } - if (ignoredGroups.containsKey(playerUUID)) { - return ignoredGroups.get(playerUUID); - } - List ignoredGroupsList = new LinkedList(); - PreparedStatement getIgnoredGroups = db.prepareStatement(this.getIgnoredGroups); - try { - getIgnoredGroups.setString(1, playerUUID.toString()); - ResultSet rs = getIgnoredGroups.executeQuery(); - while (rs.next()) { - ignoredGroupsList.add(rs.getString("group")); - } - ignoredGroups.put(playerUUID, ignoredGroupsList); - return ignoredGroupsList; - } catch (SQLException e) { - e.printStackTrace(); - } - return null; - } + public List getIgnoredGroups(UUID playerUUID) { - public boolean removeIgnoredGroup(UUID playerUUID, String group) { + if (ignoredGroups.containsKey(playerUUID)) { + return ignoredGroups.get(playerUUID); + } + List ignoredGroupsList = new LinkedList(); + PreparedStatement getIgnoredGroups = db.prepareStatement(this.getIgnoredGroups); + try { + getIgnoredGroups.setString(1, playerUUID.toString()); + ResultSet rs = getIgnoredGroups.executeQuery(); + while (rs.next()) { + ignoredGroupsList.add(rs.getString("group")); + } + ignoredGroups.put(playerUUID, ignoredGroupsList); + return ignoredGroupsList; + } catch (SQLException e) { + e.printStackTrace(); + } + return null; + } - if (!removeIgnoredGroupFromMap(playerUUID, group)) { - return false; - } - PreparedStatement removeIgnoredGroup = db.prepareStatement(this.removeIgnoredGroup); - try { - removeIgnoredGroup.setString(1, playerUUID.toString()); - removeIgnoredGroup.setString(2, group); - removeIgnoredGroup.execute(); - } catch (SQLException e) { - e.printStackTrace(); - } - return true; - } + public boolean removeIgnoredGroup(UUID playerUUID, String group) { - public boolean isIgnoringPlayer(UUID playerUUID, UUID ignoredPlayerUUID) { + if (!removeIgnoredGroupFromMap(playerUUID, group)) { + return false; + } + PreparedStatement removeIgnoredGroup = db.prepareStatement(this.removeIgnoredGroup); + try { + removeIgnoredGroup.setString(1, playerUUID.toString()); + removeIgnoredGroup.setString(2, group); + removeIgnoredGroup.execute(); + } catch (SQLException e) { + e.printStackTrace(); + } + return true; + } - return getIgnoredPlayers(playerUUID).contains(ignoredPlayerUUID); - } + public boolean isIgnoringPlayer(UUID playerUUID, UUID ignoredPlayerUUID) { - public boolean isIgnoringGroup(UUID playerUUID, String group) { + return getIgnoredPlayers(playerUUID).contains(ignoredPlayerUUID); + } - return getIgnoredGroups(playerUUID).contains(group); - } + public boolean isIgnoringGroup(UUID playerUUID, String group) { + + return getIgnoredGroups(playerUUID).contains(group); + } } diff --git a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/database/Database.java b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/database/Database.java index 8d9ecf722..92c5781ea 100644 --- a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/database/Database.java +++ b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/database/Database.java @@ -9,131 +9,131 @@ import java.util.logging.Logger; public class Database { - private String host; + private String host; - private int port; + private int port; - private String db; + private String db; - private String user; + private String user; - private String password; + private String password; - private Logger logger; + private Logger logger; - private Connection connection; + private Connection connection; - public Database(String host, int port, String db, String user, String password, Logger logger) { + public Database(String host, int port, String db, String user, String password, Logger logger) { - this.host = host; - this.port = port; - this.db = db; - this.user = user; - this.password = password; - this.logger = logger; - } + this.host = host; + this.port = port; + this.db = db; + this.user = user; + this.password = password; + this.logger = logger; + } - public String getDb() { + public String getDb() { - return db; - } + return db; + } - public String getHost() { + public String getHost() { - return host; - } + return host; + } - public String getPassword() { + public String getPassword() { - return password; - } + return password; + } - public String getUser() { + public String getUser() { - return user; - } + return user; + } - /** - * Connects to the database. - * - * @since 0.1 - */ - public boolean connect() { + /** + * Connects to the database. + * + * @since 0.1 + */ + public boolean connect() { - String jdbc = "jdbc:mysql://" + host + ":" + port + "/" + db + "?user=" + user + "&password=" + password; - try { - Class.forName("com.mysql.cj.jdbc.Driver").getConstructor().newInstance(); - } catch (Exception ex) { - throw new RuntimeException("Failed to initialize JDBC driver."); - } - try { - connection = DriverManager.getConnection(jdbc); - this.logger.log(Level.INFO, "Connected to database!"); - return true; - } catch (SQLException ex) { - this.logger.log(Level.SEVERE, "Could not connnect to the database!", ex); - return false; - } - } + String jdbc = "jdbc:mysql://" + host + ":" + port + "/" + db + "?user=" + user + "&password=" + password; + try { + Class.forName("com.mysql.cj.jdbc.Driver").getConstructor().newInstance(); + } catch (Exception ex) { + throw new RuntimeException("Failed to initialize JDBC driver."); + } + try { + connection = DriverManager.getConnection(jdbc); + this.logger.log(Level.INFO, "Connected to database!"); + return true; + } catch (SQLException ex) { + this.logger.log(Level.SEVERE, "Could not connnect to the database!", ex); + return false; + } + } - /** - * Closes the database connection. - * - * @since 0.1 - */ - public void close() { + /** + * Closes the database connection. + * + * @since 0.1 + */ + public void close() { - try { - connection.close(); - } catch (SQLException ex) { - this.logger.log(Level.SEVERE, "An error occured while closing the connection.", ex); - } - } + try { + connection.close(); + } catch (SQLException ex) { + this.logger.log(Level.SEVERE, "An error occured while closing the connection.", ex); + } + } - /** - * Are we connected to the database? - * - * @return Connected - */ - public boolean isConnected() { + /** + * Are we connected to the database? + * + * @return Connected + */ + public boolean isConnected() { - try { - return connection.isValid(5); - } catch (SQLException ex) { - this.logger.log(Level.SEVERE, "isConnected error!", ex); - } - return false; - } + try { + return connection.isValid(5); + } catch (SQLException ex) { + this.logger.log(Level.SEVERE, "isConnected error!", ex); + } + return false; + } - /** - * Prepare the SQL statements - * - * @return PreparedStatement - */ - public PreparedStatement prepareStatement(String sqlStatement) { + /** + * Prepare the SQL statements + * + * @return PreparedStatement + */ + public PreparedStatement prepareStatement(String sqlStatement) { - try { - if (!isConnected()) { - connect(); - } - return connection.prepareStatement(sqlStatement); - } catch (SQLException ex) { - this.logger.log(Level.SEVERE, "Failed to prepare statement! " + sqlStatement, ex); - } - return null; - } + try { + if (!isConnected()) { + connect(); + } + return connection.prepareStatement(sqlStatement); + } catch (SQLException ex) { + this.logger.log(Level.SEVERE, "Failed to prepare statement! " + sqlStatement, ex); + } + return null; + } - public void execute(String sql) { + public void execute(String sql) { - try { - if (isConnected()) { - connection.prepareStatement(sql).executeUpdate(); - } else { - connect(); - execute(sql); - } - } catch (SQLException ex) { - this.logger.log(Level.SEVERE, "Could not execute SQL statement!", ex); - } - } + try { + if (isConnected()) { + connection.prepareStatement(sql).executeUpdate(); + } else { + connect(); + execute(sql); + } + } catch (SQLException ex) { + this.logger.log(Level.SEVERE, "Could not execute SQL statement!", ex); + } + } } diff --git a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/event/GlobalChatEvent.java b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/event/GlobalChatEvent.java index 7c859e44b..12a59794c 100644 --- a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/event/GlobalChatEvent.java +++ b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/event/GlobalChatEvent.java @@ -7,63 +7,63 @@ import org.bukkit.event.player.PlayerEvent; public class GlobalChatEvent extends PlayerEvent implements Cancellable { - private final String message; + private final String message; - private final String format; + private final String format; - private boolean cancelled; + private boolean cancelled; - // Handler list for spigot events - private static final HandlerList handlers = new HandlerList(); + // Handler list for spigot events + private static final HandlerList handlers = new HandlerList(); - public GlobalChatEvent(final Player player, final String message, final String format) { + public GlobalChatEvent(final Player player, final String message, final String format) { - super(player); + super(player); - this.message = message; - this.format = format; - } + this.message = message; + this.format = format; + } - /** - * Gets the chat message - * - * @return The chat message - */ - public String getMessage() { + /** + * Gets the chat message + * + * @return The chat message + */ + public String getMessage() { - return message; - } + return message; + } - @Override - public HandlerList getHandlers() { + @Override + public HandlerList getHandlers() { - return handlers; - } + return handlers; + } - public static HandlerList getHandlerList() { + public static HandlerList getHandlerList() { - return handlers; - } + return handlers; + } - @Override - public boolean isCancelled() { + @Override + public boolean isCancelled() { - return cancelled; - } + return cancelled; + } - @Override - public void setCancelled(boolean cancelled) { + @Override + public void setCancelled(boolean cancelled) { - this.cancelled = cancelled; - } + this.cancelled = cancelled; + } - /** - * Gets the format to use to display this chat message. - * - * @return The message format - */ - public String getFormat() { + /** + * Gets the format to use to display this chat message. + * + * @return The message format + */ + public String getFormat() { - return format; - } + return format; + } } diff --git a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/event/GroupChatEvent.java b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/event/GroupChatEvent.java index 950d5747a..4c86c0173 100644 --- a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/event/GroupChatEvent.java +++ b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/event/GroupChatEvent.java @@ -7,62 +7,62 @@ import org.bukkit.event.player.PlayerEvent; public class GroupChatEvent extends PlayerEvent implements Cancellable { - private final String groupName; + private final String groupName; - private final String message; + private final String message; - private boolean cancelled; + private boolean cancelled; - // Handler list for spigot events - private static final HandlerList handlers = new HandlerList(); + // Handler list for spigot events + private static final HandlerList handlers = new HandlerList(); - public GroupChatEvent(final Player player, final String groupName, final String message) { - super(player); + public GroupChatEvent(final Player player, final String groupName, final String message) { + super(player); - this.groupName = groupName; - this.message = message; - } + this.groupName = groupName; + this.message = message; + } - /** - * Gets the group name - * - * @return The group name - */ - public String getGroup() { + /** + * Gets the group name + * + * @return The group name + */ + public String getGroup() { - return groupName; - } + return groupName; + } - /** - * Gets the chat message - * - * @return The chat message - */ - public String getMessage() { + /** + * Gets the chat message + * + * @return The chat message + */ + public String getMessage() { - return message; - } + return message; + } - @Override - public HandlerList getHandlers() { + @Override + public HandlerList getHandlers() { - return handlers; - } + return handlers; + } - public static HandlerList getHandlerList() { + public static HandlerList getHandlerList() { - return handlers; - } + return handlers; + } - @Override - public boolean isCancelled() { + @Override + public boolean isCancelled() { - return cancelled; - } + return cancelled; + } - @Override - public void setCancelled(boolean cancelled) { + @Override + public void setCancelled(boolean cancelled) { - this.cancelled = cancelled; - } + this.cancelled = cancelled; + } } diff --git a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/event/PrivateMessageEvent.java b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/event/PrivateMessageEvent.java index 721e785d2..78084d23b 100644 --- a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/event/PrivateMessageEvent.java +++ b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/event/PrivateMessageEvent.java @@ -7,62 +7,62 @@ import org.bukkit.event.player.PlayerEvent; public class PrivateMessageEvent extends PlayerEvent implements Cancellable { - private final Player receiver; + private final Player receiver; - private final String message; + private final String message; - private boolean cancelled; + private boolean cancelled; - // Handler list for spigot events - private static final HandlerList handlers = new HandlerList(); + // Handler list for spigot events + private static final HandlerList handlers = new HandlerList(); - public PrivateMessageEvent(final Player player, final Player receiver, final String message) { - super(player); + public PrivateMessageEvent(final Player player, final Player receiver, final String message) { + super(player); - this.receiver = receiver; - this.message = message; - } + this.receiver = receiver; + this.message = message; + } - /** - * Gets the message receiver - * - * @return The message receiver - */ - public Player getReceiver() { + /** + * Gets the message receiver + * + * @return The message receiver + */ + public Player getReceiver() { - return receiver; - } + return receiver; + } - /** - * Gets the chat message - * - * @return The chat message - */ - public String getMessage() { + /** + * Gets the chat message + * + * @return The chat message + */ + public String getMessage() { - return message; - } + return message; + } - @Override - public HandlerList getHandlers() { + @Override + public HandlerList getHandlers() { - return handlers; - } + return handlers; + } - public static HandlerList getHandlerList() { + public static HandlerList getHandlerList() { - return handlers; - } + return handlers; + } - @Override - public boolean isCancelled() { + @Override + public boolean isCancelled() { - return cancelled; - } + return cancelled; + } - @Override - public void setCancelled(boolean cancelled) { + @Override + public void setCancelled(boolean cancelled) { - this.cancelled = cancelled; - } + this.cancelled = cancelled; + } } diff --git a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/listeners/CivChat2Listener.java b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/listeners/CivChat2Listener.java index 433250d92..d163bedf1 100644 --- a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/listeners/CivChat2Listener.java +++ b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/listeners/CivChat2Listener.java @@ -33,137 +33,137 @@ import java.util.UUID; */ public class CivChat2Listener implements Listener { - private CivChat2Manager chatman; - private CivChatDAO db; - private CivChat2SettingsManager settings; - private Set localWarn; + private CivChat2Manager chatman; + private CivChatDAO db; + private CivChat2SettingsManager settings; + private Set localWarn; - public CivChat2Listener(CivChat2Manager instance) { - chatman = instance; - db = CivChat2.getInstance().getDatabaseManager(); - settings = CivChat2.getInstance().getCivChat2SettingsManager(); - localWarn = new HashSet<>(); - } + public CivChat2Listener(CivChat2Manager instance) { + chatman = instance; + db = CivChat2.getInstance().getDatabaseManager(); + settings = CivChat2.getInstance().getCivChat2SettingsManager(); + localWarn = new HashSet<>(); + } - @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) - public void onPlayerDeath(PlayerDeathEvent playerDeathEvent) { - playerDeathEvent.setDeathMessage(null); - } + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onPlayerDeath(PlayerDeathEvent playerDeathEvent) { + playerDeathEvent.setDeathMessage(null); + } - @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) - public void onPlayerQuit(PlayerQuitEvent playerQuitEvent) { - playerQuitEvent.setQuitMessage(null); - for (Player p : Bukkit.getOnlinePlayers()){ - if (settings.getShowLeaves(p.getUniqueId()) && !db.isIgnoringPlayer(p.getUniqueId(), playerQuitEvent.getPlayer().getUniqueId())){ - if (playerQuitEvent.getPlayer().hasPermission("civchat2.leavejoinimmune")) { - continue; - } - p.sendMessage(playerQuitEvent.getPlayer().getDisplayName() + ChatColor.YELLOW + " has left the game"); - } - } - } + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onPlayerQuit(PlayerQuitEvent playerQuitEvent) { + playerQuitEvent.setQuitMessage(null); + for (Player p : Bukkit.getOnlinePlayers()) { + if (settings.getShowLeaves(p.getUniqueId()) && !db.isIgnoringPlayer(p.getUniqueId(), playerQuitEvent.getPlayer().getUniqueId())) { + if (playerQuitEvent.getPlayer().hasPermission("civchat2.leavejoinimmune")) { + continue; + } + p.sendMessage(playerQuitEvent.getPlayer().getDisplayName() + ChatColor.YELLOW + " has left the game"); + } + } + } - @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) - public void onPlayerJoin(PlayerJoinEvent playerJoinEvent) { - if (!CivChat2.getInstance().getPluginConfig().getLoginAnnounce()) { - playerJoinEvent.setJoinMessage(null); - } - for (Player p : Bukkit.getOnlinePlayers()) { - if (settings.getShowJoins(p.getUniqueId()) && !db.isIgnoringPlayer(p.getUniqueId(), playerJoinEvent.getPlayer().getUniqueId())) { - if (playerJoinEvent.getPlayer().hasPermission("civchat2.leavejoinimmune")) { - continue; - } - p.sendMessage(playerJoinEvent.getPlayer().getDisplayName() + ChatColor.YELLOW + " has joined the game"); - } - } + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onPlayerJoin(PlayerJoinEvent playerJoinEvent) { + if (!CivChat2.getInstance().getPluginConfig().getLoginAnnounce()) { + playerJoinEvent.setJoinMessage(null); + } + for (Player p : Bukkit.getOnlinePlayers()) { + if (settings.getShowJoins(p.getUniqueId()) && !db.isIgnoringPlayer(p.getUniqueId(), playerJoinEvent.getPlayer().getUniqueId())) { + if (playerJoinEvent.getPlayer().hasPermission("civchat2.leavejoinimmune")) { + continue; + } + p.sendMessage(playerJoinEvent.getPlayer().getDisplayName() + ChatColor.YELLOW + " has joined the game"); + } + } - UUID player = chatman.getChannel(playerJoinEvent.getPlayer()); - if (player != null && Bukkit.getPlayer(player) == null) { - chatman.removeChannel(playerJoinEvent.getPlayer()); - } + UUID player = chatman.getChannel(playerJoinEvent.getPlayer()); + if (player != null && Bukkit.getPlayer(player) == null) { + chatman.removeChannel(playerJoinEvent.getPlayer()); + } - // Set current chat group in scoreboard - chatman.getScoreboardHUD().updateScoreboardHUD(playerJoinEvent.getPlayer()); + // Set current chat group in scoreboard + chatman.getScoreboardHUD().updateScoreboardHUD(playerJoinEvent.getPlayer()); - if (CivChat2.getInstance().getPluginConfig().getChatRangeWarn() && !playerJoinEvent.getPlayer().hasPlayedBefore()) { - localWarn.add(playerJoinEvent.getPlayer().getUniqueId()); - } - String globalChat = CivChat2.getInstance().getPluginConfig().getGlobalChatGroupName(); - if (globalChat != null && !playerJoinEvent.getPlayer().hasPlayedBefore()) { - Group group = GroupManager.getGroup(globalChat); - if (group != null) { - group.addMember(playerJoinEvent.getPlayer().getUniqueId(), PlayerType.MEMBERS); - playerJoinEvent.getPlayer().sendMessage(ChatColor.GREEN + "You autojoined global chat, which is called '!'. Use it like this: '/g ! Hello'"); - } - } - } + if (CivChat2.getInstance().getPluginConfig().getChatRangeWarn() && !playerJoinEvent.getPlayer().hasPlayedBefore()) { + localWarn.add(playerJoinEvent.getPlayer().getUniqueId()); + } + String globalChat = CivChat2.getInstance().getPluginConfig().getGlobalChatGroupName(); + if (globalChat != null && !playerJoinEvent.getPlayer().hasPlayedBefore()) { + Group group = GroupManager.getGroup(globalChat); + if (group != null) { + group.addMember(playerJoinEvent.getPlayer().getUniqueId(), PlayerType.MEMBERS); + playerJoinEvent.getPlayer().sendMessage(ChatColor.GREEN + "You autojoined global chat, which is called '!'. Use it like this: '/g ! Hello'"); + } + } + } - @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) - public void onPlayerKick(PlayerKickEvent playerKickEvent) { - playerKickEvent.setLeaveMessage("You have been kicked"); - } + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onPlayerKick(PlayerKickEvent playerKickEvent) { + playerKickEvent.setLeaveMessage("You have been kicked"); + } - @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) - public void onGlobalChatEvent(GlobalChatEvent localchat) { + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onGlobalChatEvent(GlobalChatEvent localchat) { - if (localWarn.contains(localchat.getPlayer().getUniqueId())) { - localchat.getPlayer().sendMessage(ChatColor.GOLD - + "Only players within " - + CivChat2.getInstance().getPluginConfig().getChatRange() - + " blocks of you can see your messages. Join a group to chat with players farther away!"); - localWarn.remove(localchat.getPlayer().getUniqueId()); - } - } + if (localWarn.contains(localchat.getPlayer().getUniqueId())) { + localchat.getPlayer().sendMessage(ChatColor.GOLD + + "Only players within " + + CivChat2.getInstance().getPluginConfig().getChatRange() + + " blocks of you can see your messages. Join a group to chat with players farther away!"); + localWarn.remove(localchat.getPlayer().getUniqueId()); + } + } - @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) - public void onPlayerChatEvent(final AsyncPlayerChatEvent asyncPlayerChatEvent) { + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onPlayerChatEvent(final AsyncPlayerChatEvent asyncPlayerChatEvent) { - asyncPlayerChatEvent.setCancelled(true); - // This needs to be done sync to avoid a rare deadlock due to minecraft - // internals - new BukkitRunnable() { + asyncPlayerChatEvent.setCancelled(true); + // This needs to be done sync to avoid a rare deadlock due to minecraft + // internals + new BukkitRunnable() { - @Override - public void run() { + @Override + public void run() { - String chatMessage = asyncPlayerChatEvent.getMessage(); - Player sender = asyncPlayerChatEvent.getPlayer(); - UUID chatChannel = chatman.getChannel(sender); - Group groupChat = chatman.getGroupChatting(sender); + String chatMessage = asyncPlayerChatEvent.getMessage(); + Player sender = asyncPlayerChatEvent.getPlayer(); + UUID chatChannel = chatman.getChannel(sender); + Group groupChat = chatman.getGroupChatting(sender); - if (chatChannel != null) { - StringBuilder sb = new StringBuilder(); - Player receiver = Bukkit.getPlayer(chatChannel); - if (receiver != null) { - chatman.sendPrivateMsg(sender, receiver, chatMessage); - return; - } else { - chatman.removeChannel(sender); - String offlineMessage = sb.append(ChatColor.GOLD) - .append("The player you were chatting with has gone offline,") - .append(" you have been moved to regular chat").toString(); - sb.delete(0, sb.length()); - sender.sendMessage(offlineMessage); - return; - } - } - if (groupChat != null) { - // Player is group chatting - if (NameAPI.getGroupManager().hasAccess(groupChat, sender.getUniqueId(), - PermissionType.getPermission("WRITE_CHAT"))) { - chatman.sendGroupMsg(sender, groupChat, chatMessage); - return; - // Player lost perm to write in the chat - } else { - chatman.removeGroupChat(sender); - sender.sendMessage(ChatColor.RED - + "You have been removed from groupchat because you were removed from the group or lost the permission required to groupchat"); - } - } - chatman.broadcastMessage(sender, chatMessage, asyncPlayerChatEvent.getFormat(), - asyncPlayerChatEvent.getRecipients()); - } - }.runTask(CivChat2.getInstance()); - } -} \ No newline at end of file + if (chatChannel != null) { + StringBuilder sb = new StringBuilder(); + Player receiver = Bukkit.getPlayer(chatChannel); + if (receiver != null) { + chatman.sendPrivateMsg(sender, receiver, chatMessage); + return; + } else { + chatman.removeChannel(sender); + String offlineMessage = sb.append(ChatColor.GOLD) + .append("The player you were chatting with has gone offline,") + .append(" you have been moved to regular chat").toString(); + sb.delete(0, sb.length()); + sender.sendMessage(offlineMessage); + return; + } + } + if (groupChat != null) { + // Player is group chatting + if (NameAPI.getGroupManager().hasAccess(groupChat, sender.getUniqueId(), + PermissionType.getPermission("WRITE_CHAT"))) { + chatman.sendGroupMsg(sender, groupChat, chatMessage); + return; + // Player lost perm to write in the chat + } else { + chatman.removeGroupChat(sender); + sender.sendMessage(ChatColor.RED + + "You have been removed from groupchat because you were removed from the group or lost the permission required to groupchat"); + } + } + chatman.broadcastMessage(sender, chatMessage, asyncPlayerChatEvent.getFormat(), + asyncPlayerChatEvent.getRecipients()); + } + }.runTask(CivChat2.getInstance()); + } +} diff --git a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/listeners/KillListener.java b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/listeners/KillListener.java index 908b91075..f80c48f1d 100644 --- a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/listeners/KillListener.java +++ b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/listeners/KillListener.java @@ -18,73 +18,73 @@ import vg.civcraft.mc.civmodcore.inventory.items.MaterialUtils; public class KillListener implements Listener { - private CivChat2SettingsManager settingsMan; - private CivChat2Config config; - private CivChatDAO dao; + private CivChat2SettingsManager settingsMan; + private CivChat2Config config; + private CivChatDAO dao; - public KillListener(CivChat2Config config, CivChatDAO dao, CivChat2SettingsManager settingsMan) { - this.config = config; - this.dao = dao; - this.settingsMan = settingsMan; - } + public KillListener(CivChat2Config config, CivChatDAO dao, CivChat2SettingsManager settingsMan) { + this.config = config; + this.dao = dao; + this.settingsMan = settingsMan; + } - @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) - public void onPlayerKill(PlayerDeathEvent event) { - Player victim = event.getEntity(); - if (victim.getKiller() == null) { - return; - } - Player killer = victim.getKiller(); - if (!settingsMan.getSendOwnKills(killer.getUniqueId())) { - return; - } - String msg; - ItemStack item = killer.getInventory().getItemInMainHand(); - String victimFormattedName = String.format("%s%s", ChatColor.ITALIC, victim.getDisplayName()); - String killerFormattedName = String.format("%s%s", ChatColor.ITALIC, killer.getDisplayName()); + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onPlayerKill(PlayerDeathEvent event) { + Player victim = event.getEntity(); + if (victim.getKiller() == null) { + return; + } + Player killer = victim.getKiller(); + if (!settingsMan.getSendOwnKills(killer.getUniqueId())) { + return; + } + String msg; + ItemStack item = killer.getInventory().getItemInMainHand(); + String victimFormattedName = String.format("%s%s", ChatColor.ITALIC, victim.getDisplayName()); + String killerFormattedName = String.format("%s%s", ChatColor.ITALIC, killer.getDisplayName()); - if (item == null || MaterialUtils.isAir(item.getType())) { - msg = String.format("%s%s %swas killed by %s %sby hand", ChatColor.DARK_GRAY, victimFormattedName, - ChatColor.DARK_GRAY, killerFormattedName, ChatColor.DARK_GRAY); - } else { - String itemName = ItemUtils.getItemName(item); - String displayName = ItemUtils.getDisplayName(item); - Boolean hasWordBank = Optional.ofNullable(ItemUtils.getItemMeta(item)) - .map(r -> r.displayName()) - .map(f -> f.children().size() > 0) - .orElse(false); - if (!hasWordBank) { - displayName = String.format("with a %s", itemName); - } else { - String killMessageFormat = settingsMan.getKillMessageFormat(killer.getUniqueId()).simpleDescription; - if (killMessageFormat.isBlank()) { - displayName = String.format("%s%s", killMessageFormat, displayName); - } else { - displayName = String.format("%s %s", killMessageFormat, displayName); - } - } + if (item == null || MaterialUtils.isAir(item.getType())) { + msg = String.format("%s%s %swas killed by %s %sby hand", ChatColor.DARK_GRAY, victimFormattedName, + ChatColor.DARK_GRAY, killerFormattedName, ChatColor.DARK_GRAY); + } else { + String itemName = ItemUtils.getItemName(item); + String displayName = ItemUtils.getDisplayName(item); + Boolean hasWordBank = Optional.ofNullable(ItemUtils.getItemMeta(item)) + .map(r -> r.displayName()) + .map(f -> f.children().size() > 0) + .orElse(false); + if (!hasWordBank) { + displayName = String.format("with a %s", itemName); + } else { + String killMessageFormat = settingsMan.getKillMessageFormat(killer.getUniqueId()).simpleDescription; + if (killMessageFormat.isBlank()) { + displayName = String.format("%s%s", killMessageFormat, displayName); + } else { + displayName = String.format("%s %s", killMessageFormat, displayName); + } + } - msg = String.format("%s%s %swas killed by %s %s%s", ChatColor.DARK_GRAY, victimFormattedName, - ChatColor.DARK_GRAY, killerFormattedName, ChatColor.DARK_GRAY, displayName); - } - Location killLoc = victim.getLocation(); - for (Player p : Bukkit.getOnlinePlayers()) { - Location loc = p.getLocation(); - if (!loc.getWorld().equals(killLoc.getWorld())) { - continue; - } - if (loc.distance(killLoc) > config.getKillBroadcastRange()) { - continue; - } - if (!settingsMan.getReceiveKills(p.getUniqueId())) { - continue; - } - if (!settingsMan.getReceiveKillsFromIgnored(p.getUniqueId()) - && dao.isIgnoringPlayer(p.getUniqueId(), killer.getUniqueId())) { - continue; - } - p.sendMessage(msg); - } - } + msg = String.format("%s%s %swas killed by %s %s%s", ChatColor.DARK_GRAY, victimFormattedName, + ChatColor.DARK_GRAY, killerFormattedName, ChatColor.DARK_GRAY, displayName); + } + Location killLoc = victim.getLocation(); + for (Player p : Bukkit.getOnlinePlayers()) { + Location loc = p.getLocation(); + if (!loc.getWorld().equals(killLoc.getWorld())) { + continue; + } + if (loc.distance(killLoc) > config.getKillBroadcastRange()) { + continue; + } + if (!settingsMan.getReceiveKills(p.getUniqueId())) { + continue; + } + if (!settingsMan.getReceiveKillsFromIgnored(p.getUniqueId()) + && dao.isIgnoringPlayer(p.getUniqueId(), killer.getUniqueId())) { + continue; + } + p.sendMessage(msg); + } + } } diff --git a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/utility/CivChat2Config.java b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/utility/CivChat2Config.java index 77dafe0bd..b1e7280ef 100644 --- a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/utility/CivChat2Config.java +++ b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/utility/CivChat2Config.java @@ -7,100 +7,100 @@ import org.bukkit.configuration.file.FileConfiguration; public class CivChat2Config { - private FileConfiguration config; - private TreeMap chatColor = null; + private FileConfiguration config; + private TreeMap chatColor = null; - public CivChat2Config(FileConfiguration config) { - this.config = config; - } + public CivChat2Config(FileConfiguration config) { + this.config = config; + } - public boolean getGroupsEnabled() { - return config.getBoolean("info.groups"); - } + public boolean getGroupsEnabled() { + return config.getBoolean("info.groups"); + } - public boolean getDebug() { - return config.getBoolean("info.debug"); - } + public boolean getDebug() { + return config.getBoolean("info.debug"); + } - public String getAfkMessage() { - return config.getString("info.afkmessage"); - } + public String getAfkMessage() { + return config.getString("info.afkmessage"); + } - public boolean getLoginAnnounce() { - return config.getBoolean("info.loginAnnounce", false); - } + public boolean getLoginAnnounce() { + return config.getBoolean("info.loginAnnounce", false); + } - public boolean getChatRangeWarn() { - return config.getBoolean("info.chatRangeWarn", true); - } + public boolean getChatRangeWarn() { + return config.getBoolean("info.chatRangeWarn", true); + } - public int getChatRange() { - return config.getInt("chat.globalChatRange"); - } + public int getChatRange() { + return config.getInt("chat.globalChatRange"); + } - public String getDefaultColor() { - return config.getString("chat.defaultChatColor"); - } - - public int getKillBroadcastRange() { - return config.getInt("chat.killRange", 1000); - } + public String getDefaultColor() { + return config.getString("chat.defaultChatColor"); + } - public String getOpChatColor() { - return config.getString("chat.opChatColor"); - } + public int getKillBroadcastRange() { + return config.getInt("chat.killRange", 1000); + } - public int getYInc() { - return config.getInt("chat.yIncreaseDist"); - } + public String getOpChatColor() { + return config.getString("chat.opChatColor"); + } - public double getYScale() { - return config.getDouble("chat.yIncreaseScale"); - } + public int getYInc() { + return config.getInt("chat.yIncreaseDist"); + } - public String getMysqlUsername() { - return config.getString("mysql.username"); - } + public double getYScale() { + return config.getDouble("chat.yIncreaseScale"); + } - public String getMysqlHost() { - return config.getString("mysql.host"); - } + public String getMysqlUsername() { + return config.getString("mysql.username"); + } - public int getMysqlPort() { - return config.getInt("mysql.port"); - } + public String getMysqlHost() { + return config.getString("mysql.host"); + } - public String getMysqlPassword() { - return config.getString("mysql.password"); - } + public int getMysqlPort() { + return config.getInt("mysql.port"); + } - public String getMysqlDBname() { - return config.getString("mysql.dbname"); - } - - public String getGlobalChatGroupName() { - return config.getString("chat.globalGroup", null); - } - - public boolean useDynamicRangeColoring() { - return config.getBoolean("chat.dynamicColoring"); - } + public String getMysqlPassword() { + return config.getString("mysql.password"); + } - public synchronized String getColorAtDistance(double distance) { + public String getMysqlDBname() { + return config.getString("mysql.dbname"); + } - if (chatColor == null) { - chatColor = new TreeMap<>(); - chatColor.put(0.0, getDefaultColor()); - if (config.contains("chat.colors")) { - ConfigurationSection section = config.getConfigurationSection("chat.colors"); - for (String s : section.getKeys(false)) { - chatColor.put(section.getDouble(s + ".range"), section.getString(s + ".color")); - } - } - } + public String getGlobalChatGroupName() { + return config.getString("chat.globalGroup", null); + } - String ret = "-"; - Map.Entry let = chatColor.floorEntry(distance); - return let == null ? ret : let.getValue(); - } + public boolean useDynamicRangeColoring() { + return config.getBoolean("chat.dynamicColoring"); + } + + public synchronized String getColorAtDistance(double distance) { + + if (chatColor == null) { + chatColor = new TreeMap<>(); + chatColor.put(0.0, getDefaultColor()); + if (config.contains("chat.colors")) { + ConfigurationSection section = config.getConfigurationSection("chat.colors"); + for (String s : section.getKeys(false)) { + chatColor.put(section.getDouble(s + ".range"), section.getString(s + ".color")); + } + } + } + + String ret = "-"; + Map.Entry let = chatColor.floorEntry(distance); + return let == null ? ret : let.getValue(); + } } diff --git a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/utility/CivChat2Executor.java b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/utility/CivChat2Executor.java index 13c6a7c2f..74719e097 100644 --- a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/utility/CivChat2Executor.java +++ b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/utility/CivChat2Executor.java @@ -10,81 +10,81 @@ import vg.civcraft.mc.civchat2.CivChat2; public class CivChat2Executor implements CommandExecutor { - private CivChat2 plugin; + private CivChat2 plugin; - private CivChat2Config config; + private CivChat2Config config; - private CivChat2Log logger; + private CivChat2Log logger; - public CivChat2Executor(CivChat2 instance) { + public CivChat2Executor(CivChat2 instance) { - this.plugin = instance; - this.config = plugin.getPluginConfig(); - this.logger = plugin.getCivChat2Log(); - } + this.plugin = instance; + this.config = plugin.getPluginConfig(); + this.logger = plugin.getCivChat2Log(); + } - @Override - public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { + @Override + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { - ChatColor sayChat = ChatColor.valueOf(config.getOpChatColor()); - String msgString = null; - if (cmd.getName().equalsIgnoreCase("say")) { - StringBuilder msg = new StringBuilder(); - for (int arg = 0; arg < args.length; arg++) { - msg.append(args[arg]); - msg.append(" "); - } - msgString = msg.toString(); - msg.delete(0, msg.length()); - } - if (sender instanceof Player) { - if (msgString == null) { - return true; - } - Player player = (Player) sender; - if (player.hasPermission("bukkit.command.say") || player.isOp()) { - this.plugin.getServer().broadcastMessage(sayChat + "[Server] " + msgString); - StringBuilder result = new StringBuilder(); - result.append("Player had good permissions, bukkit.command.say or OP"); - result.append(", "); - result.append("Broadcasted message =["); - result.append(msgString); - result.append("] ChatColor = ["); - result.append(sayChat); - result.append("]"); - debugMsg(result.toString()); - result.delete(0, result.length()); - return true; - } else { - player.sendMessage(ChatColor.RED + "You do not have permission to use that command"); - debugMsg("Player did not have proper permissions (not op)"); - return true; - } - } else if (sender instanceof ConsoleCommandSender) { - this.plugin.getServer().broadcastMessage(sayChat + "[Server] " + msgString); - StringBuilder result = new StringBuilder(); - result.append("Console sent the command"); - result.append(", "); - result.append("Broadcasted message =["); - result.append(msgString); - result.append("] ChatColor = ["); - result.append(sayChat); - result.append("]"); - debugMsg(result.toString()); - result.delete(0, result.length()); - return true; - } - debugMsg("Command was not a \"say\" command"); - return true; - } + ChatColor sayChat = ChatColor.valueOf(config.getOpChatColor()); + String msgString = null; + if (cmd.getName().equalsIgnoreCase("say")) { + StringBuilder msg = new StringBuilder(); + for (int arg = 0; arg < args.length; arg++) { + msg.append(args[arg]); + msg.append(" "); + } + msgString = msg.toString(); + msg.delete(0, msg.length()); + } + if (sender instanceof Player) { + if (msgString == null) { + return true; + } + Player player = (Player) sender; + if (player.hasPermission("bukkit.command.say") || player.isOp()) { + this.plugin.getServer().broadcastMessage(sayChat + "[Server] " + msgString); + StringBuilder result = new StringBuilder(); + result.append("Player had good permissions, bukkit.command.say or OP"); + result.append(", "); + result.append("Broadcasted message =["); + result.append(msgString); + result.append("] ChatColor = ["); + result.append(sayChat); + result.append("]"); + debugMsg(result.toString()); + result.delete(0, result.length()); + return true; + } else { + player.sendMessage(ChatColor.RED + "You do not have permission to use that command"); + debugMsg("Player did not have proper permissions (not op)"); + return true; + } + } else if (sender instanceof ConsoleCommandSender) { + this.plugin.getServer().broadcastMessage(sayChat + "[Server] " + msgString); + StringBuilder result = new StringBuilder(); + result.append("Console sent the command"); + result.append(", "); + result.append("Broadcasted message =["); + result.append(msgString); + result.append("] ChatColor = ["); + result.append(sayChat); + result.append("]"); + debugMsg(result.toString()); + result.delete(0, result.length()); + return true; + } + debugMsg("Command was not a \"say\" command"); + return true; + } - private void debugMsg(String text) { + private void debugMsg(String text) { - StringBuilder sb = new StringBuilder(); - sb.append(this.getClass().getName()); - sb.append(", "); - sb.append(text); - logger.debug(sb.toString()); - sb.delete(0, sb.length()); - } + StringBuilder sb = new StringBuilder(); + sb.append(this.getClass().getName()); + sb.append(", "); + sb.append(text); + logger.debug(sb.toString()); + sb.delete(0, sb.length()); + } } diff --git a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/utility/CivChat2FileLogger.java b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/utility/CivChat2FileLogger.java index 889fc1a9c..b72296c7c 100644 --- a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/utility/CivChat2FileLogger.java +++ b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/utility/CivChat2FileLogger.java @@ -8,54 +8,54 @@ import org.bukkit.entity.Player; public class CivChat2FileLogger { - private Logger logger; + private Logger logger; - public CivChat2FileLogger() { + public CivChat2FileLogger() { - logger = LogManager.getLogger("ChatLogs"); - } + logger = LogManager.getLogger("ChatLogs"); + } - public void logGlobalMessage(Player sender, String message, Set recivers) { + public void logGlobalMessage(Player sender, String message, Set recivers) { - String reciversNames = getPlayersNames(recivers); - Location playerLocation = sender.getLocation(); - String messageToLog = String.format( - "Sender: [%s], Message: [%s], Location: [%d, %d, %d], Channel: [GLOBAL], Recivers: [%s]", - sender.getName(), message, playerLocation.getBlockX(), playerLocation.getBlockY(), - playerLocation.getBlockZ(), reciversNames); - logger.info(messageToLog); - } + String reciversNames = getPlayersNames(recivers); + Location playerLocation = sender.getLocation(); + String messageToLog = String.format( + "Sender: [%s], Message: [%s], Location: [%d, %d, %d], Channel: [GLOBAL], Recivers: [%s]", + sender.getName(), message, playerLocation.getBlockX(), playerLocation.getBlockY(), + playerLocation.getBlockZ(), reciversNames); + logger.info(messageToLog); + } - public void logPrivateMessage(Player sender, String message, String reciverName) { + public void logPrivateMessage(Player sender, String message, String reciverName) { - Location playerLocation = sender.getLocation(); - String messageToLog = String.format( - "Sender: [%s], Message: [%s], Location: [%d, %d, %d], Channel: [PRIVATE], Reciver: [%s]", - sender.getName(), message, playerLocation.getBlockX(), playerLocation.getBlockY(), - playerLocation.getBlockZ(), reciverName); - logger.info(messageToLog); - } + Location playerLocation = sender.getLocation(); + String messageToLog = String.format( + "Sender: [%s], Message: [%s], Location: [%d, %d, %d], Channel: [PRIVATE], Reciver: [%s]", + sender.getName(), message, playerLocation.getBlockX(), playerLocation.getBlockY(), + playerLocation.getBlockZ(), reciverName); + logger.info(messageToLog); + } - public void logGroupMessage(Player sender, String message, String groupName, Set recivers) { + public void logGroupMessage(Player sender, String message, String groupName, Set recivers) { - String reciversNames = getPlayersNames(recivers); - Location playerLocation = sender.getLocation(); - String messageToLog = String.format( - "Sender: [%s], Message: [%s], Location: [%d, %d, %d], Channel: [GROUP], GroupName: [%s], Recivers: [%s]", - sender.getName(), message, playerLocation.getBlockX(), playerLocation.getBlockY(), - playerLocation.getBlockZ(), groupName, reciversNames); - logger.info(messageToLog); - } + String reciversNames = getPlayersNames(recivers); + Location playerLocation = sender.getLocation(); + String messageToLog = String.format( + "Sender: [%s], Message: [%s], Location: [%d, %d, %d], Channel: [GROUP], GroupName: [%s], Recivers: [%s]", + sender.getName(), message, playerLocation.getBlockX(), playerLocation.getBlockY(), + playerLocation.getBlockZ(), groupName, reciversNames); + logger.info(messageToLog); + } - private String getPlayersNames(Set players) { + private String getPlayersNames(Set players) { - StringBuilder builder = new StringBuilder(); - for (String player : players) { - builder.append(player).append(", "); - } - if (players.size() > 0) { - builder.deleteCharAt(builder.length() - 2); - } - return builder.toString(); - } + StringBuilder builder = new StringBuilder(); + for (String player : players) { + builder.append(player).append(", "); + } + if (players.size() > 0) { + builder.deleteCharAt(builder.length() - 2); + } + return builder.toString(); + } } diff --git a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/utility/CivChat2Log.java b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/utility/CivChat2Log.java index be37b1e40..0d195182a 100644 --- a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/utility/CivChat2Log.java +++ b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/utility/CivChat2Log.java @@ -5,31 +5,32 @@ import org.bukkit.plugin.java.JavaPlugin; import vg.civcraft.mc.civchat2.CivChat2; public class CivChat2Log { - private Logger log; - public void initializeLogger(JavaPlugin jp) { + private Logger log; - log = jp.getLogger(); - } + public void initializeLogger(JavaPlugin jp) { - public void info(String msg) { + log = jp.getLogger(); + } - log.info(msg); - } + public void info(String msg) { - public void warning(String msg) { + log.info(msg); + } - log.warning(msg); - } + public void warning(String msg) { - public void severe(String msg) { + log.warning(msg); + } - log.severe(msg); - } + public void severe(String msg) { - public void debug(String msg) { - if (CivChat2.getInstance().debugEnabled()) { - log.info("[Debug] " + msg); - } - } + log.severe(msg); + } + + public void debug(String msg) { + if (CivChat2.getInstance().debugEnabled()) { + log.info("[Debug] " + msg); + } + } } diff --git a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/utility/CivChat2SettingsManager.java b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/utility/CivChat2SettingsManager.java index 9e6115261..e9e8c0d73 100644 --- a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/utility/CivChat2SettingsManager.java +++ b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/utility/CivChat2SettingsManager.java @@ -13,120 +13,120 @@ import vg.civcraft.mc.civmodcore.players.settings.impl.LongSetting; public class CivChat2SettingsManager { - private BooleanSetting showJoins; - private BooleanSetting showLeaves; - private BooleanSetting sendOwnKills; - private BooleanSetting receiveKills; - private BooleanSetting receiveKillsFromIgnoredPlayers; - private BooleanSetting showChatGroup; - private DisplayLocationSetting chatGroupLocation; - private LongSetting chatUnmuteTimer; - private EnumSetting killMessageFormat; + private BooleanSetting showJoins; + private BooleanSetting showLeaves; + private BooleanSetting sendOwnKills; + private BooleanSetting receiveKills; + private BooleanSetting receiveKillsFromIgnoredPlayers; + private BooleanSetting showChatGroup; + private DisplayLocationSetting chatGroupLocation; + private LongSetting chatUnmuteTimer; + private EnumSetting killMessageFormat; - public CivChat2SettingsManager() { - initSettings(); - } + public CivChat2SettingsManager() { + initSettings(); + } - private void initSettings() { - MenuSection menu = PlayerSettingAPI.getMainMenu().createMenuSection("CivChat", - "All options related to CivChat.", new ItemStack(Material.OAK_SIGN)); + private void initSettings() { + MenuSection menu = PlayerSettingAPI.getMainMenu().createMenuSection("CivChat", + "All options related to CivChat.", new ItemStack(Material.OAK_SIGN)); - showJoins = new BooleanSetting(CivChat2.getInstance(), true, "Show Player Joins", "showJoins", - "Should player join messages be shown?"); - PlayerSettingAPI.registerSetting(showJoins, menu); + showJoins = new BooleanSetting(CivChat2.getInstance(), true, "Show Player Joins", "showJoins", + "Should player join messages be shown?"); + PlayerSettingAPI.registerSetting(showJoins, menu); - showLeaves = new BooleanSetting(CivChat2.getInstance(), true, "Show Players Leaving", "showLeaves", - "Should player leave messages be shown?"); - PlayerSettingAPI.registerSetting(showLeaves, menu); + showLeaves = new BooleanSetting(CivChat2.getInstance(), true, "Show Players Leaving", "showLeaves", + "Should player leave messages be shown?"); + PlayerSettingAPI.registerSetting(showLeaves, menu); - sendOwnKills = new BooleanSetting(CivChat2.getInstance(), true, "Broadcast your kills", "civChatBroadcastKills", - "Should kills you make be broadcasted to nearby players?"); - PlayerSettingAPI.registerSetting(sendOwnKills, menu); + sendOwnKills = new BooleanSetting(CivChat2.getInstance(), true, "Broadcast your kills", "civChatBroadcastKills", + "Should kills you make be broadcasted to nearby players?"); + PlayerSettingAPI.registerSetting(sendOwnKills, menu); - receiveKills = new BooleanSetting(CivChat2.getInstance(), true, "Receive kill broadcasts", - "civChatReceiveKills", "Do you want to receive broadcasts for nearby kills"); - PlayerSettingAPI.registerSetting(receiveKills, menu); + receiveKills = new BooleanSetting(CivChat2.getInstance(), true, "Receive kill broadcasts", + "civChatReceiveKills", "Do you want to receive broadcasts for nearby kills"); + PlayerSettingAPI.registerSetting(receiveKills, menu); - receiveKillsFromIgnoredPlayers = new BooleanSetting(CivChat2.getInstance(), false, - "Receive kill broadcasts from ignored players", "civChatReceiveKillsIgnored", - "Do you want to receive kill broadcasts from killers you have ignored"); - PlayerSettingAPI.registerSetting(receiveKillsFromIgnoredPlayers, menu); + receiveKillsFromIgnoredPlayers = new BooleanSetting(CivChat2.getInstance(), false, + "Receive kill broadcasts from ignored players", "civChatReceiveKillsIgnored", + "Do you want to receive kill broadcasts from killers you have ignored"); + PlayerSettingAPI.registerSetting(receiveKillsFromIgnoredPlayers, menu); - showChatGroup = new BooleanSetting(CivChat2.getInstance(), true, "Show current chat group", "showChatGroup", - "Should player chat group be shown?"); - PlayerSettingAPI.registerSetting(showChatGroup, menu); + showChatGroup = new BooleanSetting(CivChat2.getInstance(), true, "Show current chat group", "showChatGroup", + "Should player chat group be shown?"); + PlayerSettingAPI.registerSetting(showChatGroup, menu); - chatGroupLocation = new DisplayLocationSetting(CivChat2.getInstance(), DisplayLocationSetting.DisplayLocation.SIDEBAR, - "Chat Group Location", "chatGroupLocation", new ItemStack(Material.ARROW), "the current chat group"); - PlayerSettingAPI.registerSetting(chatGroupLocation, menu); - - chatUnmuteTimer = new LongSetting(CivChat2.getInstance(), 0L, "Global chat mute", "chatGlobalMuteTimer"); - PlayerSettingAPI.registerSetting(chatUnmuteTimer, null); + chatGroupLocation = new DisplayLocationSetting(CivChat2.getInstance(), DisplayLocationSetting.DisplayLocation.SIDEBAR, + "Chat Group Location", "chatGroupLocation", new ItemStack(Material.ARROW), "the current chat group"); + PlayerSettingAPI.registerSetting(chatGroupLocation, menu); - killMessageFormat = new EnumSetting<>(CivChat2.getInstance(), KillMessageFormat.WITH, "Kill Message Format", "killMessageFormat", new ItemStack(Material.WRITABLE_BOOK), "Choose your kill message format", true, KillMessageFormat.class); - PlayerSettingAPI.registerSetting(killMessageFormat, menu); - } - - public LongSetting getGlobalChatMuteSetting() { - return chatUnmuteTimer; - } + chatUnmuteTimer = new LongSetting(CivChat2.getInstance(), 0L, "Global chat mute", "chatGlobalMuteTimer"); + PlayerSettingAPI.registerSetting(chatUnmuteTimer, null); - public boolean getShowJoins(UUID uuid) { - return showJoins.getValue(uuid); - } + killMessageFormat = new EnumSetting<>(CivChat2.getInstance(), KillMessageFormat.WITH, "Kill Message Format", "killMessageFormat", new ItemStack(Material.WRITABLE_BOOK), "Choose your kill message format", true, KillMessageFormat.class); + PlayerSettingAPI.registerSetting(killMessageFormat, menu); + } - public boolean getShowLeaves(UUID uuid) { - return showLeaves.getValue(uuid); - } - - public boolean getSendOwnKills(UUID uuid) { - return sendOwnKills.getValue(uuid); - } - - public boolean getReceiveKills(UUID uuid) { - return receiveKills.getValue(uuid); - } - - public boolean getReceiveKillsFromIgnored(UUID uuid) { - return receiveKillsFromIgnoredPlayers.getValue(uuid); - } + public LongSetting getGlobalChatMuteSetting() { + return chatUnmuteTimer; + } - public boolean getShowChatGroup(UUID uuid) { - return showChatGroup.getValue(uuid); - } + public boolean getShowJoins(UUID uuid) { + return showJoins.getValue(uuid); + } - public DisplayLocationSetting getChatGroupLocation() { - return chatGroupLocation; - } + public boolean getShowLeaves(UUID uuid) { + return showLeaves.getValue(uuid); + } - public KillMessageFormat getKillMessageFormat(UUID uuid) { - return killMessageFormat.getValue(uuid); - } + public boolean getSendOwnKills(UUID uuid) { + return sendOwnKills.getValue(uuid); + } - public enum KillMessageFormat { - FOR( - "for" - ), - WHILE( - "while" - ), - BLANK( - "" - ), - USING( - "using" - ), - BY( - "by" - ), - WITH( - "with" - ); + public boolean getReceiveKills(UUID uuid) { + return receiveKills.getValue(uuid); + } - public final String simpleDescription; + public boolean getReceiveKillsFromIgnored(UUID uuid) { + return receiveKillsFromIgnoredPlayers.getValue(uuid); + } - private KillMessageFormat(String simpleDescription) { - this.simpleDescription = simpleDescription; - } - } + public boolean getShowChatGroup(UUID uuid) { + return showChatGroup.getValue(uuid); + } + + public DisplayLocationSetting getChatGroupLocation() { + return chatGroupLocation; + } + + public KillMessageFormat getKillMessageFormat(UUID uuid) { + return killMessageFormat.getValue(uuid); + } + + public enum KillMessageFormat { + FOR( + "for" + ), + WHILE( + "while" + ), + BLANK( + "" + ), + USING( + "using" + ), + BY( + "by" + ), + WITH( + "with" + ); + + public final String simpleDescription; + + private KillMessageFormat(String simpleDescription) { + this.simpleDescription = simpleDescription; + } + } } diff --git a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/utility/ScoreboardHUD.java b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/utility/ScoreboardHUD.java index 0adc05ed0..9ce13789e 100644 --- a/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/utility/ScoreboardHUD.java +++ b/plugins/civchat2-paper/src/main/java/vg/civcraft/mc/civchat2/utility/ScoreboardHUD.java @@ -13,44 +13,46 @@ import vg.civcraft.mc.civmodcore.players.scoreboard.side.ScoreBoardAPI; import vg.civcraft.mc.civmodcore.players.settings.impl.DisplayLocationSetting; public class ScoreboardHUD { - private final BottomLine chatBottomLine; - private final CivScoreBoard chatBoard; - private final CivChat2SettingsManager settingMan; - public ScoreboardHUD() { - this.chatBoard = ScoreBoardAPI.createBoard("CivChatDisplay"); - this.chatBottomLine = BottomLineAPI.createBottomLine("CivChatDisplay", 3); - this.settingMan = CivChat2.getInstance().getCivChat2SettingsManager(); - } + private final BottomLine chatBottomLine; + private final CivScoreBoard chatBoard; + private final CivChat2SettingsManager settingMan; - /** Updates the scoreboard to display the players currently in use private message channel or chat group - * - * @param p player to update scoreboard for - */ - public void updateScoreboardHUD(Player p) { - if (!settingMan.getShowChatGroup(p.getUniqueId())) { - chatBoard.hide(p); - chatBottomLine.removePlayer(p); - } else { - DisplayLocationSetting locSetting = settingMan.getChatGroupLocation(); - CivChat2Manager chatman = CivChat2.getInstance().getCivChat2Manager(); - String text; - if (chatman.getChannel(p) != null && Bukkit.getPlayer(chatman.getChannel(p)) != null) { - text = ChatColor.GOLD + "Messaging " + ChatColor.LIGHT_PURPLE + Bukkit.getPlayer(chatman.getChannel(p)).getName(); - } else if (chatman.getGroupChatting(p) != null) { - text = ChatColor.GOLD + "Chat Group " + ChatColor.LIGHT_PURPLE + chatman.getGroupChatting(p).getName(); - } else { - chatBoard.hide(p); - chatBottomLine.removePlayer(p); - return; - } - if (locSetting.showOnActionbar(p.getUniqueId())) { - chatBottomLine.updatePlayer(p, text); - } - if (locSetting.showOnSidebar(p.getUniqueId())) { - chatBoard.set(p, text); - } - } - } + public ScoreboardHUD() { + this.chatBoard = ScoreBoardAPI.createBoard("CivChatDisplay"); + this.chatBottomLine = BottomLineAPI.createBottomLine("CivChatDisplay", 3); + this.settingMan = CivChat2.getInstance().getCivChat2SettingsManager(); + } + + /** + * Updates the scoreboard to display the players currently in use private message channel or chat group + * + * @param p player to update scoreboard for + */ + public void updateScoreboardHUD(Player p) { + if (!settingMan.getShowChatGroup(p.getUniqueId())) { + chatBoard.hide(p); + chatBottomLine.removePlayer(p); + } else { + DisplayLocationSetting locSetting = settingMan.getChatGroupLocation(); + CivChat2Manager chatman = CivChat2.getInstance().getCivChat2Manager(); + String text; + if (chatman.getChannel(p) != null && Bukkit.getPlayer(chatman.getChannel(p)) != null) { + text = ChatColor.GOLD + "Messaging " + ChatColor.LIGHT_PURPLE + Bukkit.getPlayer(chatman.getChannel(p)).getName(); + } else if (chatman.getGroupChatting(p) != null) { + text = ChatColor.GOLD + "Chat Group " + ChatColor.LIGHT_PURPLE + chatman.getGroupChatting(p).getName(); + } else { + chatBoard.hide(p); + chatBottomLine.removePlayer(p); + return; + } + if (locSetting.showOnActionbar(p.getUniqueId())) { + chatBottomLine.updatePlayer(p, text); + } + if (locSetting.showOnSidebar(p.getUniqueId())) { + chatBoard.set(p, text); + } + } + } } diff --git a/plugins/civchat2-paper/src/main/resources/log4j2.xml b/plugins/civchat2-paper/src/main/resources/log4j2.xml index 9b4b0efd2..e671bf08c 100644 --- a/plugins/civchat2-paper/src/main/resources/log4j2.xml +++ b/plugins/civchat2-paper/src/main/resources/log4j2.xml @@ -2,72 +2,73 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/plugins/civchat2-paper/src/main/resources/plugin.yml b/plugins/civchat2-paper/src/main/resources/plugin.yml index d6dc0e5e2..22f1f1871 100644 --- a/plugins/civchat2-paper/src/main/resources/plugin.yml +++ b/plugins/civchat2-paper/src/main/resources/plugin.yml @@ -3,11 +3,11 @@ main: vg.civcraft.mc.civchat2.CivChat2 version: ${version} api-version: 1.16 authors: -- jjj5311 -- Maxopoly + - jjj5311 + - Maxopoly depend: -- NameLayer -- CivModCore + - NameLayer + - CivModCore description: CivChat2 limits the chat radius to 1000 blocks. However Private Messaging and Group Chat works above the 1000 block chat radius. permissions: CivChat2.*: diff --git a/plugins/civduties-paper/README.md b/plugins/civduties-paper/README.md index b8d818f9e..dbe9f7d3e 100644 --- a/plugins/civduties-paper/README.md +++ b/plugins/civduties-paper/README.md @@ -1,4 +1,7 @@ # CivDuties + Minecraft plugin built for Paper 1.16.5 -Custom plugin used to assign a limited range of moderation permissions for players. Used on CivClassic as a tool to allow designated player-moderators to use /duty to enter a mode which allows them to teleport and move around in spectator mode to investigate hacking. Also allows them to run commands such as kicking or banning while in /duty mode. +Custom plugin used to assign a limited range of moderation permissions for players. Used on CivClassic as a tool to +allow designated player-moderators to use /duty to enter a mode which allows them to teleport and move around in +spectator mode to investigate hacking. Also allows them to run commands such as kicking or banning while in /duty mode. diff --git a/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/CivDuties.java b/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/CivDuties.java index c126a43da..b099a4dde 100644 --- a/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/CivDuties.java +++ b/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/CivDuties.java @@ -14,83 +14,84 @@ import vg.civcraft.mc.civduties.listeners.PlayerListener; import vg.civcraft.mc.civmodcore.ACivMod; public class CivDuties extends ACivMod { - private static CivDuties pluginInstance; - private DutiesConfigManager config; - private DatabaseManager db; - private ModeManager modeManager; - private VaultManager vaultManager; - private CivDutiesCommandHandler commandHandler; - public CivDuties() { - pluginInstance = this; - } + private static CivDuties pluginInstance; + private DutiesConfigManager config; + private DatabaseManager db; + private ModeManager modeManager; + private VaultManager vaultManager; + private CivDutiesCommandHandler commandHandler; - @Override - public void onEnable() { - super.onEnable(); - config = new DutiesConfigManager(this); - config.parse(); - if (config.getDatabase() == null) { - getLogger().severe("Invalid database credentials, shutting down"); - Bukkit.getPluginManager().disablePlugin(this); - return; - } - db = new DatabaseManager(config.getDatabase()); - vaultManager = new VaultManager(); - modeManager = new ModeManager(); - commandHandler = new CivDutiesCommandHandler(this); - registerListeners(); - } + public CivDuties() { + pluginInstance = this; + } - @Override - public void onDisable() { - for(Player player : Bukkit.getOnlinePlayers()){ - if(modeManager.isInDuty(player)){ - Tier tier = config.getTier(db.getPlayerData(player.getUniqueId()).getTierName()); - for(Command command: tier.getCommands()){ - if(command.getTiming() == Timing.LOGOUT){ - command.execute(player); - } - } - vaultManager.addPermissionsToPlayer(player, tier.getTemporaryPermissions()); - vaultManager.addPlayerToGroups(player, tier.getTemporaryGroups()); - } - } - } + @Override + public void onEnable() { + super.onEnable(); + config = new DutiesConfigManager(this); + config.parse(); + if (config.getDatabase() == null) { + getLogger().severe("Invalid database credentials, shutting down"); + Bukkit.getPluginManager().disablePlugin(this); + return; + } + db = new DatabaseManager(config.getDatabase()); + vaultManager = new VaultManager(); + modeManager = new ModeManager(); + commandHandler = new CivDutiesCommandHandler(this); + registerListeners(); + } - public static CivDuties getInstance() { - return pluginInstance; - } + @Override + public void onDisable() { + for (Player player : Bukkit.getOnlinePlayers()) { + if (modeManager.isInDuty(player)) { + Tier tier = config.getTier(db.getPlayerData(player.getUniqueId()).getTierName()); + for (Command command : tier.getCommands()) { + if (command.getTiming() == Timing.LOGOUT) { + command.execute(player); + } + } + vaultManager.addPermissionsToPlayer(player, tier.getTemporaryPermissions()); + vaultManager.addPlayerToGroups(player, tier.getTemporaryGroups()); + } + } + } - public DutiesConfigManager getConfigManager() { - return config; - } + public static CivDuties getInstance() { + return pluginInstance; + } - public DatabaseManager getDatabaseManager() { - return db; - } + public DutiesConfigManager getConfigManager() { + return config; + } - public ModeManager getModeManager() { - return modeManager; - } + public DatabaseManager getDatabaseManager() { + return db; + } - public VaultManager getVaultManager() { - return vaultManager; - } - - public boolean isVaultEnabled() { - return Bukkit.getPluginManager().isPluginEnabled("Vault"); - } + public ModeManager getModeManager() { + return modeManager; + } - public boolean isCombatTagPlusEnabled() { - return Bukkit.getPluginManager().isPluginEnabled("CombatTagPlus"); - } + public VaultManager getVaultManager() { + return vaultManager; + } + + public boolean isVaultEnabled() { + return Bukkit.getPluginManager().isPluginEnabled("Vault"); + } + + public boolean isCombatTagPlusEnabled() { + return Bukkit.getPluginManager().isPluginEnabled("CombatTagPlus"); + } - private void registerListeners() { - getServer().getPluginManager().registerEvents(new PlayerListener(), this); - if (isCombatTagPlusEnabled()) { - getServer().getPluginManager().registerEvents(new CombatTagHandler(), this); - } - } + private void registerListeners() { + getServer().getPluginManager().registerEvents(new PlayerListener(), this); + if (isCombatTagPlusEnabled()) { + getServer().getPluginManager().registerEvents(new CombatTagHandler(), this); + } + } } diff --git a/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/ModeManager.java b/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/ModeManager.java index 14ab61ff0..08458caeb 100644 --- a/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/ModeManager.java +++ b/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/ModeManager.java @@ -18,98 +18,99 @@ import vg.civcraft.mc.civduties.external.VaultManager; import vg.civcraft.mc.civmodcore.nbt.wrappers.NBTCompound; public class ModeManager { - private DatabaseManager db; - private VaultManager vaultManager; - private Logger logger; - public ModeManager() { - db = CivDuties.getInstance().getDatabaseManager(); - vaultManager = CivDuties.getInstance().getVaultManager(); - logger = CivDuties.getInstance().getLogger(); - } + private DatabaseManager db; + private VaultManager vaultManager; + private Logger logger; - public boolean isInDuty(UUID uuid) { - if (db.getPlayerData(uuid) != null) { - return true; - } - return false; - } + public ModeManager() { + db = CivDuties.getInstance().getDatabaseManager(); + vaultManager = CivDuties.getInstance().getVaultManager(); + logger = CivDuties.getInstance().getLogger(); + } - public boolean isInDuty(Player player) { - return isInDuty(player.getUniqueId()); - } + public boolean isInDuty(UUID uuid) { + if (db.getPlayerData(uuid) != null) { + return true; + } + return false; + } - public boolean enableDutyMode(Player player, Tier tier) { - CompoundTag nmsCompound = new CompoundTag(); - CraftPlayer cPlayer = (CraftPlayer) player; - cPlayer.getHandle().saveWithoutId(nmsCompound); - NBTCompound compound = new NBTCompound(nmsCompound); - String serverName = Bukkit.getServer().getName(); - db.savePlayerData(player.getUniqueId(), compound.getRAW(), serverName, tier.getName()); + public boolean isInDuty(Player player) { + return isInDuty(player.getUniqueId()); + } - vaultManager.addPermissionsToPlayer(player, tier.getTemporaryPermissions()); - vaultManager.addPlayerToGroups(player, tier.getTemporaryGroups()); + public boolean enableDutyMode(Player player, Tier tier) { + CompoundTag nmsCompound = new CompoundTag(); + CraftPlayer cPlayer = (CraftPlayer) player; + cPlayer.getHandle().saveWithoutId(nmsCompound); + NBTCompound compound = new NBTCompound(nmsCompound); + String serverName = Bukkit.getServer().getName(); + db.savePlayerData(player.getUniqueId(), compound.getRAW(), serverName, tier.getName()); - for (Command command : tier.getCommands()) { - if (command.getTiming() == Timing.ENABLE) { - command.execute(player); - } - } + vaultManager.addPermissionsToPlayer(player, tier.getTemporaryPermissions()); + vaultManager.addPlayerToGroups(player, tier.getTemporaryGroups()); - player.sendMessage(ChatColor.RED + "You have entered duty mode. Type /duty to leave it"); - logger.log(Level.INFO, "player " + player.getName() + " has entered duty mode"); - return true; - } + for (Command command : tier.getCommands()) { + if (command.getTiming() == Timing.ENABLE) { + command.execute(player); + } + } - public boolean disableDutyMode(Player player, Tier tier) { - if (!isInDuty(player)) { - return false; - } - NBTCompound input = new NBTCompound(db.getPlayerData(player.getUniqueId()).getData()); - // Inform the client the gamemode was changed to fix graphical issues on the - // client side - // Teleport the players using the bukkit api to avoid triggering nocheat - // movement detection - double[] location = input.getDoubleArray("Pos"); - UUID worldUUID = new UUID(input.getLong("WorldUUIDMost"), input.getLong("WorldUUIDLeast")); - Location targetLocation = new Location(Bukkit.getWorld(worldUUID), location[0], location[1], location[2]); - player.teleport(targetLocation); - player.setGameMode(getGameModeByValue(input.getInt("playerGameType"))); - Bukkit.getScheduler().scheduleSyncDelayedTask(CivDuties.getInstance(), () -> { - player.teleport(targetLocation); - }, 3L); - CraftPlayer cPlayer = (CraftPlayer) player; - cPlayer.getHandle().load(input.getRAW()); + player.sendMessage(ChatColor.RED + "You have entered duty mode. Type /duty to leave it"); + logger.log(Level.INFO, "player " + player.getName() + " has entered duty mode"); + return true; + } - db.removePlayerData(player.getUniqueId()); + public boolean disableDutyMode(Player player, Tier tier) { + if (!isInDuty(player)) { + return false; + } + NBTCompound input = new NBTCompound(db.getPlayerData(player.getUniqueId()).getData()); + // Inform the client the gamemode was changed to fix graphical issues on the + // client side + // Teleport the players using the bukkit api to avoid triggering nocheat + // movement detection + double[] location = input.getDoubleArray("Pos"); + UUID worldUUID = new UUID(input.getLong("WorldUUIDMost"), input.getLong("WorldUUIDLeast")); + Location targetLocation = new Location(Bukkit.getWorld(worldUUID), location[0], location[1], location[2]); + player.teleport(targetLocation); + player.setGameMode(getGameModeByValue(input.getInt("playerGameType"))); + Bukkit.getScheduler().scheduleSyncDelayedTask(CivDuties.getInstance(), () -> { + player.teleport(targetLocation); + }, 3L); + CraftPlayer cPlayer = (CraftPlayer) player; + cPlayer.getHandle().load(input.getRAW()); - for (Command command : tier.getCommands()) { - if (command.getTiming() == Timing.DISABLE) { - command.execute(player); - } - } + db.removePlayerData(player.getUniqueId()); - vaultManager.removePermissionsFromPlayer(player, tier.getTemporaryPermissions()); - vaultManager.removePlayerFromGroups(player, tier.getTemporaryGroups()); + for (Command command : tier.getCommands()) { + if (command.getTiming() == Timing.DISABLE) { + command.execute(player); + } + } - player.sendMessage(ChatColor.RED + "You have left duty mode"); - logger.log(Level.INFO, "player " + player.getName() + " has left duty mode"); - return true; - } + vaultManager.removePermissionsFromPlayer(player, tier.getTemporaryPermissions()); + vaultManager.removePlayerFromGroups(player, tier.getTemporaryGroups()); - private GameMode getGameModeByValue(int num) { - switch (num) { - case 0: - return GameMode.SURVIVAL; - case 1: - return GameMode.CREATIVE; - case 2: - return GameMode.ADVENTURE; - case 3: - return GameMode.SPECTATOR; - default: - return null; - } - } + player.sendMessage(ChatColor.RED + "You have left duty mode"); + logger.log(Level.INFO, "player " + player.getName() + " has left duty mode"); + return true; + } + + private GameMode getGameModeByValue(int num) { + switch (num) { + case 0: + return GameMode.SURVIVAL; + case 1: + return GameMode.CREATIVE; + case 2: + return GameMode.ADVENTURE; + case 3: + return GameMode.SPECTATOR; + default: + return null; + } + } } diff --git a/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/command/CivDutiesCommandHandler.java b/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/command/CivDutiesCommandHandler.java index eda462b6c..fe3b784f0 100644 --- a/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/command/CivDutiesCommandHandler.java +++ b/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/command/CivDutiesCommandHandler.java @@ -6,14 +6,14 @@ import vg.civcraft.mc.civmodcore.commands.CommandManager; public class CivDutiesCommandHandler extends CommandManager { - public CivDutiesCommandHandler(Plugin plugin) { - super(plugin); - init(); - } + public CivDutiesCommandHandler(Plugin plugin) { + super(plugin); + init(); + } + + @Override + public void registerCommands() { + registerCommand(new Duty()); + } - @Override - public void registerCommands() { - registerCommand(new Duty()); - } - } diff --git a/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/command/commands/Duty.java b/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/command/commands/Duty.java index bc95ba77b..00fdd6e92 100644 --- a/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/command/commands/Duty.java +++ b/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/command/commands/Duty.java @@ -16,56 +16,57 @@ import vg.civcraft.mc.civduties.ModeManager; import vg.civcraft.mc.civduties.configuration.Tier; public class Duty extends BaseCommand { - private ModeManager modeManager = CivDuties.getInstance().getModeManager(); - @CommandAlias("duty") - @Syntax("[player]") - @Description("Allows you to enter duty mode") - @CommandPermission("civduties.duty") - public void execute(Player player, @Optional String targetPlayer) { - Tier tier = null; + private ModeManager modeManager = CivDuties.getInstance().getModeManager(); - if (!modeManager.isInDuty(player)) { - if (targetPlayer == null || targetPlayer.isEmpty()) { - tier = CivDuties.getInstance().getConfigManager().getTier(player); - } else { - tier = CivDuties.getInstance().getConfigManager().getTier(targetPlayer); - if (!player.hasPermission(tier.getPermission())) { - tier = null; - } - } + @CommandAlias("duty") + @Syntax("[player]") + @Description("Allows you to enter duty mode") + @CommandPermission("civduties.duty") + public void execute(Player player, @Optional String targetPlayer) { + Tier tier = null; - if (tier == null) { - player.sendMessage("You don't have permission to execute this command."); - return; - } + if (!modeManager.isInDuty(player)) { + if (targetPlayer == null || targetPlayer.isEmpty()) { + tier = CivDuties.getInstance().getConfigManager().getTier(player); + } else { + tier = CivDuties.getInstance().getConfigManager().getTier(targetPlayer); + if (!player.hasPermission(tier.getPermission())) { + tier = null; + } + } - if (CivDuties.getInstance().isCombatTagPlusEnabled() && tier.isCombattagBlock() - && ((CombatTagPlus) Bukkit.getPluginManager().getPlugin("CombatTagPlus")).getTagManager() - .isTagged(player.getUniqueId())) { - player.sendMessage("You can't enter duty mode while combat tagged"); - return; - } - modeManager.enableDutyMode(player, tier); - } else { - String tierName = CivDuties.getInstance().getDatabaseManager().getPlayerData(player.getUniqueId()) - .getTierName(); - tier = CivDuties.getInstance().getConfigManager().getTier(tierName); - modeManager.disableDutyMode(player, tier); - } - } + if (tier == null) { + player.sendMessage("You don't have permission to execute this command."); + return; + } + + if (CivDuties.getInstance().isCombatTagPlusEnabled() && tier.isCombattagBlock() + && ((CombatTagPlus) Bukkit.getPluginManager().getPlugin("CombatTagPlus")).getTagManager() + .isTagged(player.getUniqueId())) { + player.sendMessage("You can't enter duty mode while combat tagged"); + return; + } + modeManager.enableDutyMode(player, tier); + } else { + String tierName = CivDuties.getInstance().getDatabaseManager().getPlayerData(player.getUniqueId()) + .getTierName(); + tier = CivDuties.getInstance().getConfigManager().getTier(tierName); + modeManager.disableDutyMode(player, tier); + } + } + + public List tabComplete(CommandSender sender, String[] args) { + if (!(sender instanceof Player)) { + sender.sendMessage("No."); + return null; + } + + if (args.length < 2) { + return CivDuties.getInstance().getConfigManager().getTiersNames((Player) sender); + } + + return null; + } - public List tabComplete(CommandSender sender, String[] args) { - if (!(sender instanceof Player)) { - sender.sendMessage("No."); - return null; - } - - if (args.length < 2) { - return CivDuties.getInstance().getConfigManager().getTiersNames((Player)sender); - } - - return null; - } - } diff --git a/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/configuration/Command.java b/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/configuration/Command.java index 37e196f5a..e9d9fbdab 100644 --- a/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/configuration/Command.java +++ b/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/configuration/Command.java @@ -5,61 +5,62 @@ import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; public class Command { - private String syntax; - private Timing timing; - private Executor executor; - - public enum Timing{ - ENABLE, - DISABLE, - LOGIN, - LOGOUT; - } - - public enum Executor{ - PLAYER, - CONSOLE; - } - - public Command(String syntax, Timing timing, Executor executor) { - this.syntax = syntax; - this.timing = timing; - this.executor = executor; - } - - public String getSyntax() { - return syntax; - } - public void setSyntax(String syntax) { - this.syntax = syntax; - } + private String syntax; + private Timing timing; + private Executor executor; - public Timing getTiming() { - return timing; - } + public enum Timing { + ENABLE, + DISABLE, + LOGIN, + LOGOUT; + } - public void setTiming(Timing timing) { - this.timing = timing; - } + public enum Executor { + PLAYER, + CONSOLE; + } - public Executor getExecutor() { - return executor; - } + public Command(String syntax, Timing timing, Executor executor) { + this.syntax = syntax; + this.timing = timing; + this.executor = executor; + } - public void setExecutor(Executor executor) { - this.executor = executor; - } + public String getSyntax() { + return syntax; + } - public void execute(Player player){ - String parsedCommand = (syntax.charAt(0) == '/' ? syntax.substring(1) : syntax) - .replaceAll("%PLAYER_NAME%", player.getName()) - .replaceAll("%PLAYER_GAMEMODE%", player.getGameMode().toString()) - .replaceAll("%PLAYER_SERVER%", Bukkit.getServer().getName()); - CommandSender sender = player; - if(executor == Executor.CONSOLE){ - sender = Bukkit.getConsoleSender(); - } - Bukkit.dispatchCommand(sender, parsedCommand); - } + public void setSyntax(String syntax) { + this.syntax = syntax; + } + + public Timing getTiming() { + return timing; + } + + public void setTiming(Timing timing) { + this.timing = timing; + } + + public Executor getExecutor() { + return executor; + } + + public void setExecutor(Executor executor) { + this.executor = executor; + } + + public void execute(Player player) { + String parsedCommand = (syntax.charAt(0) == '/' ? syntax.substring(1) : syntax) + .replaceAll("%PLAYER_NAME%", player.getName()) + .replaceAll("%PLAYER_GAMEMODE%", player.getGameMode().toString()) + .replaceAll("%PLAYER_SERVER%", Bukkit.getServer().getName()); + CommandSender sender = player; + if (executor == Executor.CONSOLE) { + sender = Bukkit.getConsoleSender(); + } + Bukkit.dispatchCommand(sender, parsedCommand); + } } diff --git a/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/configuration/DutiesConfigManager.java b/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/configuration/DutiesConfigManager.java index a4c0330ba..bc10322a6 100644 --- a/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/configuration/DutiesConfigManager.java +++ b/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/configuration/DutiesConfigManager.java @@ -15,115 +15,116 @@ import vg.civcraft.mc.civmodcore.dao.DatabaseCredentials; import vg.civcraft.mc.civmodcore.dao.ManagedDatasource; public class DutiesConfigManager extends ConfigParser { - private ManagedDatasource db; - private List tiers; - - public DutiesConfigManager(CivDuties plugin){ - super(plugin); - } - - private void parseTiers(ConfigurationSection config){ - tiers = new ArrayList<>(); - for (String key : config.getKeys(false)) { - if (config.getConfigurationSection(key) == null) { - CivDuties.getInstance().warning("Found invalid section that should not exist at " + config.getCurrentPath() + key); - continue; - } - Tier tier = parseTier(key, config.getConfigurationSection(key)); - if (tier == null) { - CivDuties.getInstance().warning(String.format("Tier %s unable to be added.", key)); - } else { - tiers.add(tier); - } - } - } - - private Tier parseTier(String name, ConfigurationSection config){ - String permission = config.getString("permission"); - int priority = config.getInt("priority"); - List commands = parseCommands(config.getConfigurationSection("commands")); - Map temporaryPermissions = new HashMap<>(); - for(String temporaryPermission : config.getStringList("temporary.permissions")){ - String[] array = temporaryPermission.split(":"); - if(array.length > 1){ - temporaryPermissions.put(array[0], Boolean.valueOf(array[1])); - continue; - } - temporaryPermissions.put(array[0], true); - } - List temporaryGroups = config.getStringList("temporary.groups"); - boolean deathDrops = config.getBoolean("disable_death_drops"); - boolean combattagBlock = config.getBoolean("enable_combattag_block"); - return new Tier(name, priority, permission, commands, temporaryPermissions, temporaryGroups, deathDrops, combattagBlock); - } - - private List parseCommands(ConfigurationSection config){ - if(config == null){ - return new ArrayList<>(); - } - List commands = new ArrayList<>(); - for (String key : config.getKeys(false)) { - if (config.getConfigurationSection(key) == null) { - CivDuties.getInstance().warning("Found invalid section that should not exist at " + config.getCurrentPath() + key); - continue; - } - Command command = parseCommand(config.getConfigurationSection(key)); - if (command == null) { - CivDuties.getInstance().warning(String.format("Tier %s unable to be added.", key)); - } else { - commands.add(command); - } - } - return commands; - } - - private Command parseCommand(ConfigurationSection config){ - String syntax = config.getString("syntax"); - Timing timing = Timing.valueOf(config.getString("timing")); - Executor executor = Executor.valueOf(config.getString("executor")); - return new Command(syntax, timing, executor); - } - - public Tier getTier(Player player){ - Tier tier = null; - int maxPriority = Integer.MIN_VALUE; - for(Tier t : tiers){ - if((t.getPermission() == null || player.hasPermission(t.getPermission())) && (tier == null || t.getPriority() > maxPriority)){ - tier = t; - maxPriority = t.getPriority(); - } - } - return tier; - } - - public Tier getTier(String tierName){ - for(Tier tier : tiers){ - if(tier.getName().equals(tierName)){ - return tier; - } - } - return null; - } - - public List getTiersNames(Player player){ - List names = new ArrayList<>(); - for(Tier tier : tiers){ - if(tier.getPermission() == null || player.hasPermission(tier.getPermission())){ - names.add(tier.getName()); - } - } - return names; - } - - public ManagedDatasource getDatabase(){ - return db; - } - @Override - protected boolean parseInternal(ConfigurationSection config) { - parseTiers(config.getConfigurationSection("tiers")); - db = ManagedDatasource.construct((ACivMod) plugin, (DatabaseCredentials) config.get("database")); - return true; - } + private ManagedDatasource db; + private List tiers; + + public DutiesConfigManager(CivDuties plugin) { + super(plugin); + } + + private void parseTiers(ConfigurationSection config) { + tiers = new ArrayList<>(); + for (String key : config.getKeys(false)) { + if (config.getConfigurationSection(key) == null) { + CivDuties.getInstance().warning("Found invalid section that should not exist at " + config.getCurrentPath() + key); + continue; + } + Tier tier = parseTier(key, config.getConfigurationSection(key)); + if (tier == null) { + CivDuties.getInstance().warning(String.format("Tier %s unable to be added.", key)); + } else { + tiers.add(tier); + } + } + } + + private Tier parseTier(String name, ConfigurationSection config) { + String permission = config.getString("permission"); + int priority = config.getInt("priority"); + List commands = parseCommands(config.getConfigurationSection("commands")); + Map temporaryPermissions = new HashMap<>(); + for (String temporaryPermission : config.getStringList("temporary.permissions")) { + String[] array = temporaryPermission.split(":"); + if (array.length > 1) { + temporaryPermissions.put(array[0], Boolean.valueOf(array[1])); + continue; + } + temporaryPermissions.put(array[0], true); + } + List temporaryGroups = config.getStringList("temporary.groups"); + boolean deathDrops = config.getBoolean("disable_death_drops"); + boolean combattagBlock = config.getBoolean("enable_combattag_block"); + return new Tier(name, priority, permission, commands, temporaryPermissions, temporaryGroups, deathDrops, combattagBlock); + } + + private List parseCommands(ConfigurationSection config) { + if (config == null) { + return new ArrayList<>(); + } + List commands = new ArrayList<>(); + for (String key : config.getKeys(false)) { + if (config.getConfigurationSection(key) == null) { + CivDuties.getInstance().warning("Found invalid section that should not exist at " + config.getCurrentPath() + key); + continue; + } + Command command = parseCommand(config.getConfigurationSection(key)); + if (command == null) { + CivDuties.getInstance().warning(String.format("Tier %s unable to be added.", key)); + } else { + commands.add(command); + } + } + return commands; + } + + private Command parseCommand(ConfigurationSection config) { + String syntax = config.getString("syntax"); + Timing timing = Timing.valueOf(config.getString("timing")); + Executor executor = Executor.valueOf(config.getString("executor")); + return new Command(syntax, timing, executor); + } + + public Tier getTier(Player player) { + Tier tier = null; + int maxPriority = Integer.MIN_VALUE; + for (Tier t : tiers) { + if ((t.getPermission() == null || player.hasPermission(t.getPermission())) && (tier == null || t.getPriority() > maxPriority)) { + tier = t; + maxPriority = t.getPriority(); + } + } + return tier; + } + + public Tier getTier(String tierName) { + for (Tier tier : tiers) { + if (tier.getName().equals(tierName)) { + return tier; + } + } + return null; + } + + public List getTiersNames(Player player) { + List names = new ArrayList<>(); + for (Tier tier : tiers) { + if (tier.getPermission() == null || player.hasPermission(tier.getPermission())) { + names.add(tier.getName()); + } + } + return names; + } + + public ManagedDatasource getDatabase() { + return db; + } + + @Override + protected boolean parseInternal(ConfigurationSection config) { + parseTiers(config.getConfigurationSection("tiers")); + db = ManagedDatasource.construct((ACivMod) plugin, (DatabaseCredentials) config.get("database")); + return true; + } } diff --git a/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/configuration/Tier.java b/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/configuration/Tier.java index a36e66b33..c50ca6eab 100644 --- a/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/configuration/Tier.java +++ b/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/configuration/Tier.java @@ -4,57 +4,58 @@ import java.util.List; import java.util.Map; public class Tier { - private String name; - private String permission; - private int priority; - private List commands; - private Map temporaryPermissions; - private List temporaryGroups; - private boolean deathDrops; - private boolean combattagBlock; - public Tier(String name, int priority, String permission, List commands, - Map temporaryPermissions, List temporaryGroups, boolean deathDrops, - boolean combattagBlock) { - this.name = name; - this.priority = priority; - this.permission = permission; - this.commands = commands; - this.temporaryPermissions = temporaryPermissions; - this.temporaryGroups = temporaryGroups; - this.deathDrops = deathDrops; - this.combattagBlock = combattagBlock; - } + private String name; + private String permission; + private int priority; + private List commands; + private Map temporaryPermissions; + private List temporaryGroups; + private boolean deathDrops; + private boolean combattagBlock; - public String getName() { - return name; - } - - public int getPriority() { - return priority; - } - - public String getPermission() { - return permission; - } + public Tier(String name, int priority, String permission, List commands, + Map temporaryPermissions, List temporaryGroups, boolean deathDrops, + boolean combattagBlock) { + this.name = name; + this.priority = priority; + this.permission = permission; + this.commands = commands; + this.temporaryPermissions = temporaryPermissions; + this.temporaryGroups = temporaryGroups; + this.deathDrops = deathDrops; + this.combattagBlock = combattagBlock; + } - public List getCommands() { - return commands; - } + public String getName() { + return name; + } - public Map getTemporaryPermissions() { - return temporaryPermissions; - } + public int getPriority() { + return priority; + } - public List getTemporaryGroups() { - return temporaryGroups; - } + public String getPermission() { + return permission; + } - public boolean isDeathDrops() { - return deathDrops; - } + public List getCommands() { + return commands; + } - public boolean isCombattagBlock() { - return combattagBlock; - } + public Map getTemporaryPermissions() { + return temporaryPermissions; + } + + public List getTemporaryGroups() { + return temporaryGroups; + } + + public boolean isDeathDrops() { + return deathDrops; + } + + public boolean isCombattagBlock() { + return combattagBlock; + } } diff --git a/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/database/DatabaseManager.java b/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/database/DatabaseManager.java index b755113a1..df2c0e3e4 100644 --- a/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/database/DatabaseManager.java +++ b/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/database/DatabaseManager.java @@ -14,71 +14,72 @@ import vg.civcraft.mc.civmodcore.dao.ManagedDatasource; import vg.civcraft.mc.civmodcore.nbt.NBTSerialization; public class DatabaseManager { - private CivDuties plugin; - private ManagedDatasource db; - private Map playersDataCache = new ConcurrentHashMap<>(); + private CivDuties plugin; + private ManagedDatasource db; - public DatabaseManager(ManagedDatasource db) { - this.plugin = CivDuties.getInstance(); - this.db = db; - registerMigrations(); - db.updateDatabase(); - } + private Map playersDataCache = new ConcurrentHashMap<>(); - private void registerMigrations() { - db.registerMigration(1, false, - "create table if not exists DutiesPlayerData(uuid varchar(36) not null,entity blob, " - + "serverName varchar(256) not null, tierName varchar(256) not null, primary key (uuid));"); - } + public DatabaseManager(ManagedDatasource db) { + this.plugin = CivDuties.getInstance(); + this.db = db; + registerMigrations(); + db.updateDatabase(); + } - public void savePlayerData(UUID uuid, CompoundTag compound, String serverName, String tierName) { - try (Connection conn = db.getConnection(); - PreparedStatement addPlayerData = conn.prepareStatement( - "insert into DutiesPlayerData(uuid, entity, serverName, tierName) values(?,?,?,?);")) { - addPlayerData.setString(1, uuid.toString()); - addPlayerData.setBytes(2, NBTSerialization.toBytes(compound)); - addPlayerData.setString(3, serverName); - addPlayerData.setString(4, tierName); - addPlayerData.execute(); - } catch (SQLException e) { - plugin.getLogger().severe("Failed to insert player data " + e.toString()); - } - } + private void registerMigrations() { + db.registerMigration(1, false, + "create table if not exists DutiesPlayerData(uuid varchar(36) not null,entity blob, " + + "serverName varchar(256) not null, tierName varchar(256) not null, primary key (uuid));"); + } - public PlayerData getPlayerData(UUID uuid) { - if (playersDataCache.containsKey(uuid)) { - return playersDataCache.get(uuid); - } - try (Connection conn = db.getConnection(); - PreparedStatement getPlayerData = conn - .prepareStatement("select * from DutiesPlayerData where uuid = ?")) { - getPlayerData.setString(1, uuid.toString()); - try (ResultSet rs = getPlayerData.executeQuery()) { - if (rs.next()) { - CompoundTag compound = NBTSerialization.fromBytes(rs.getBytes("entity")); - String server = rs.getString("serverName"); - String tierName = rs.getString("tierName"); - PlayerData data = new PlayerData(compound, server, tierName); - playersDataCache.put(uuid, data); - return data; - } - } - } catch (SQLException e) { - plugin.getLogger().severe("Failed to retrieve player data " + e.toString()); - } - return null; - } + public void savePlayerData(UUID uuid, CompoundTag compound, String serverName, String tierName) { + try (Connection conn = db.getConnection(); + PreparedStatement addPlayerData = conn.prepareStatement( + "insert into DutiesPlayerData(uuid, entity, serverName, tierName) values(?,?,?,?);")) { + addPlayerData.setString(1, uuid.toString()); + addPlayerData.setBytes(2, NBTSerialization.toBytes(compound)); + addPlayerData.setString(3, serverName); + addPlayerData.setString(4, tierName); + addPlayerData.execute(); + } catch (SQLException e) { + plugin.getLogger().severe("Failed to insert player data " + e.toString()); + } + } - public void removePlayerData(UUID uuid) { - playersDataCache.remove(uuid); - try (Connection conn = db.getConnection(); - PreparedStatement removePlayerData = conn - .prepareStatement("delete from DutiesPlayerData where uuid = ?")) { - removePlayerData.setString(1, uuid.toString()); - removePlayerData.execute(); - } catch (SQLException e) { - plugin.getLogger().severe("Failed to remove player data " + e.toString()); - } - } + public PlayerData getPlayerData(UUID uuid) { + if (playersDataCache.containsKey(uuid)) { + return playersDataCache.get(uuid); + } + try (Connection conn = db.getConnection(); + PreparedStatement getPlayerData = conn + .prepareStatement("select * from DutiesPlayerData where uuid = ?")) { + getPlayerData.setString(1, uuid.toString()); + try (ResultSet rs = getPlayerData.executeQuery()) { + if (rs.next()) { + CompoundTag compound = NBTSerialization.fromBytes(rs.getBytes("entity")); + String server = rs.getString("serverName"); + String tierName = rs.getString("tierName"); + PlayerData data = new PlayerData(compound, server, tierName); + playersDataCache.put(uuid, data); + return data; + } + } + } catch (SQLException e) { + plugin.getLogger().severe("Failed to retrieve player data " + e.toString()); + } + return null; + } + + public void removePlayerData(UUID uuid) { + playersDataCache.remove(uuid); + try (Connection conn = db.getConnection(); + PreparedStatement removePlayerData = conn + .prepareStatement("delete from DutiesPlayerData where uuid = ?")) { + removePlayerData.setString(1, uuid.toString()); + removePlayerData.execute(); + } catch (SQLException e) { + plugin.getLogger().severe("Failed to remove player data " + e.toString()); + } + } } diff --git a/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/database/PlayerData.java b/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/database/PlayerData.java index 337af697f..f675b1e82 100644 --- a/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/database/PlayerData.java +++ b/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/database/PlayerData.java @@ -3,25 +3,26 @@ package vg.civcraft.mc.civduties.database; import net.minecraft.nbt.CompoundTag; public class PlayerData { - private CompoundTag data; - private String serverName; - private String tierName; - - public PlayerData(CompoundTag data, String serverName, String tierName) { - this.data = data; - this.serverName = serverName; - this.tierName = tierName; - } - public CompoundTag getData() { - return data; - } + private CompoundTag data; + private String serverName; + private String tierName; - public String getServerName() { - return serverName; - } + public PlayerData(CompoundTag data, String serverName, String tierName) { + this.data = data; + this.serverName = serverName; + this.tierName = tierName; + } - public String getTierName() { - return tierName; - } + public CompoundTag getData() { + return data; + } + + public String getServerName() { + return serverName; + } + + public String getTierName() { + return tierName; + } } diff --git a/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/external/CombatTagHandler.java b/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/external/CombatTagHandler.java index 768d2e96c..7069a515c 100644 --- a/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/external/CombatTagHandler.java +++ b/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/external/CombatTagHandler.java @@ -7,12 +7,12 @@ import net.minelink.ctplus.event.CombatLogEvent; import vg.civcraft.mc.civduties.CivDuties; public class CombatTagHandler implements Listener { - - @EventHandler - public void disableCombatTag(CombatLogEvent event) { - if (CivDuties.getInstance().getModeManager().isInDuty(event.getPlayer())) { - event.setCancelled(true); - } - } + + @EventHandler + public void disableCombatTag(CombatLogEvent event) { + if (CivDuties.getInstance().getModeManager().isInDuty(event.getPlayer())) { + event.setCancelled(true); + } + } } diff --git a/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/external/VaultManager.java b/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/external/VaultManager.java index 549e9c252..7c3213c5f 100644 --- a/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/external/VaultManager.java +++ b/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/external/VaultManager.java @@ -12,74 +12,74 @@ import vg.civcraft.mc.civduties.CivDuties; public class VaultManager { - private static Permission permissionProvider = null; + private static Permission permissionProvider = null; - public VaultManager() { - if (CivDuties.getInstance().isVaultEnabled()) { - setupPermissions(); - } - } + public VaultManager() { + if (CivDuties.getInstance().isVaultEnabled()) { + setupPermissions(); + } + } - private boolean setupPermissions() { - RegisteredServiceProvider permissionProvider = CivDuties.getInstance().getServer() - .getServicesManager().getRegistration(net.milkbowl.vault.permission.Permission.class); - if (permissionProvider != null) { - VaultManager.permissionProvider = permissionProvider.getProvider(); - return true; - } - CivDuties.getInstance().getLogger().log(Level.WARNING, "Duties was unable to find a permissions plugin"); - return false; - } + private boolean setupPermissions() { + RegisteredServiceProvider permissionProvider = CivDuties.getInstance().getServer() + .getServicesManager().getRegistration(net.milkbowl.vault.permission.Permission.class); + if (permissionProvider != null) { + VaultManager.permissionProvider = permissionProvider.getProvider(); + return true; + } + CivDuties.getInstance().getLogger().log(Level.WARNING, "Duties was unable to find a permissions plugin"); + return false; + } - public boolean addPermissionsToPlayer(Player player, Map permissions) { - if (permissionProvider == null) { - return false; - } - - for (Map.Entry entry: permissions.entrySet()) { - if(entry.getValue()){ - permissionProvider.playerAdd(player, entry.getKey()); - return true; - } - permissionProvider.playerRemove(player, entry.getKey()); - } - return true; - } - - public boolean removePermissionsFromPlayer(Player player, Map permissions) { - if (permissionProvider == null) { - return false; - } - - for (Map.Entry entry: permissions.entrySet()) { - if(!entry.getValue()){ - permissionProvider.playerAdd(player, entry.getKey()); - return true; - } - permissionProvider.playerRemove(player, entry.getKey()); - } - return true; - } - - public boolean addPlayerToGroups(Player player, List groups){ - if (permissionProvider == null) { - return false; - } - - for (String group : groups) { - permissionProvider.playerAddGroup(player, group); - } - return true; - } - - public boolean removePlayerFromGroups(Player player, List groups){ - if (permissionProvider == null) { - return false; - } - - for (String group : groups) { - permissionProvider.playerRemoveGroup(player, group); - } - return true; - } + public boolean addPermissionsToPlayer(Player player, Map permissions) { + if (permissionProvider == null) { + return false; + } + + for (Map.Entry entry : permissions.entrySet()) { + if (entry.getValue()) { + permissionProvider.playerAdd(player, entry.getKey()); + return true; + } + permissionProvider.playerRemove(player, entry.getKey()); + } + return true; + } + + public boolean removePermissionsFromPlayer(Player player, Map permissions) { + if (permissionProvider == null) { + return false; + } + + for (Map.Entry entry : permissions.entrySet()) { + if (!entry.getValue()) { + permissionProvider.playerAdd(player, entry.getKey()); + return true; + } + permissionProvider.playerRemove(player, entry.getKey()); + } + return true; + } + + public boolean addPlayerToGroups(Player player, List groups) { + if (permissionProvider == null) { + return false; + } + + for (String group : groups) { + permissionProvider.playerAddGroup(player, group); + } + return true; + } + + public boolean removePlayerFromGroups(Player player, List groups) { + if (permissionProvider == null) { + return false; + } + + for (String group : groups) { + permissionProvider.playerRemoveGroup(player, group); + } + return true; + } } diff --git a/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/listeners/PlayerListener.java b/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/listeners/PlayerListener.java index 0c172b7f6..7c295c38d 100644 --- a/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/listeners/PlayerListener.java +++ b/plugins/civduties-paper/src/main/java/vg/civcraft/mc/civduties/listeners/PlayerListener.java @@ -18,57 +18,58 @@ import vg.civcraft.mc.civduties.database.DatabaseManager; import vg.civcraft.mc.civduties.external.VaultManager; public class PlayerListener implements Listener { - private ModeManager modeManager; - private DatabaseManager db; - private DutiesConfigManager config; - private VaultManager vaultManager; - - public PlayerListener() { - this.modeManager = CivDuties.getInstance().getModeManager(); - this.db = CivDuties.getInstance().getDatabaseManager(); - this.config = CivDuties.getInstance().getConfigManager(); - this.vaultManager = CivDuties.getInstance().getVaultManager(); - } - - @EventHandler(priority = EventPriority.LOWEST) - public void playerQuitEvent(PlayerQuitEvent event) { - Player player = event.getPlayer(); - if(modeManager.isInDuty(player)){ - Tier tier = config.getTier(db.getPlayerData(player.getUniqueId()).getTierName()); - vaultManager.removePermissionsFromPlayer(player, tier.getTemporaryPermissions()); - vaultManager.removePlayerFromGroups(player, tier.getTemporaryGroups()); - for(Command command: tier.getCommands()){ - if(command.getTiming() == Timing.LOGOUT){ - command.execute(player); - } - } - } - } - @EventHandler(priority = EventPriority.LOWEST) - public void playerJoinEvent(PlayerJoinEvent event) { - Player player = event.getPlayer(); - if(modeManager.isInDuty(player)){ - Tier tier = config.getTier(db.getPlayerData(player.getUniqueId()).getTierName()); - for(Command command: tier.getCommands()){ - if(command.getTiming() == Timing.LOGIN){ - command.execute(player); - } - } - vaultManager.addPermissionsToPlayer(player, tier.getTemporaryPermissions()); - vaultManager.addPlayerToGroups(player, tier.getTemporaryGroups()); - } - } + private ModeManager modeManager; + private DatabaseManager db; + private DutiesConfigManager config; + private VaultManager vaultManager; - @EventHandler(priority = EventPriority.LOWEST) - public void onEntityDeath(EntityDeathEvent event) { - if (event.getEntity() instanceof Player && modeManager.isInDuty(((Player) event.getEntity()))) { - Player player = (Player) event.getEntity(); - Tier tier = config.getTier(db.getPlayerData(player.getUniqueId()).getTierName()); - if(tier.isDeathDrops()){ - event.getDrops().clear(); - event.setDroppedExp(0); - } - } - } + public PlayerListener() { + this.modeManager = CivDuties.getInstance().getModeManager(); + this.db = CivDuties.getInstance().getDatabaseManager(); + this.config = CivDuties.getInstance().getConfigManager(); + this.vaultManager = CivDuties.getInstance().getVaultManager(); + } + + @EventHandler(priority = EventPriority.LOWEST) + public void playerQuitEvent(PlayerQuitEvent event) { + Player player = event.getPlayer(); + if (modeManager.isInDuty(player)) { + Tier tier = config.getTier(db.getPlayerData(player.getUniqueId()).getTierName()); + vaultManager.removePermissionsFromPlayer(player, tier.getTemporaryPermissions()); + vaultManager.removePlayerFromGroups(player, tier.getTemporaryGroups()); + for (Command command : tier.getCommands()) { + if (command.getTiming() == Timing.LOGOUT) { + command.execute(player); + } + } + } + } + + @EventHandler(priority = EventPriority.LOWEST) + public void playerJoinEvent(PlayerJoinEvent event) { + Player player = event.getPlayer(); + if (modeManager.isInDuty(player)) { + Tier tier = config.getTier(db.getPlayerData(player.getUniqueId()).getTierName()); + for (Command command : tier.getCommands()) { + if (command.getTiming() == Timing.LOGIN) { + command.execute(player); + } + } + vaultManager.addPermissionsToPlayer(player, tier.getTemporaryPermissions()); + vaultManager.addPlayerToGroups(player, tier.getTemporaryGroups()); + } + } + + @EventHandler(priority = EventPriority.LOWEST) + public void onEntityDeath(EntityDeathEvent event) { + if (event.getEntity() instanceof Player && modeManager.isInDuty(((Player) event.getEntity()))) { + Player player = (Player) event.getEntity(); + Tier tier = config.getTier(db.getPlayerData(player.getUniqueId()).getTierName()); + if (tier.isDeathDrops()) { + event.getDrops().clear(); + event.setDroppedExp(0); + } + } + } } diff --git a/plugins/civduties-paper/src/main/resources/plugin.yml b/plugins/civduties-paper/src/main/resources/plugin.yml index d38133caf..8939d4e94 100644 --- a/plugins/civduties-paper/src/main/resources/plugin.yml +++ b/plugins/civduties-paper/src/main/resources/plugin.yml @@ -1,12 +1,12 @@ name: CivDuties main: vg.civcraft.mc.civduties.CivDuties version: ${version} -depend: [CivModCore] -softdepend: [Vault] +depend: [ CivModCore ] +softdepend: [ Vault ] api-version: 1.16 commands: - duty: - permission: civduties.duty + duty: + permission: civduties.duty permissions: civduties.duty: - default: op + default: op diff --git a/plugins/civmodcore-paper/README.md b/plugins/civmodcore-paper/README.md index 48fd4e266..844f3f95c 100644 --- a/plugins/civmodcore-paper/README.md +++ b/plugins/civmodcore-paper/README.md @@ -16,7 +16,8 @@ CivModCore is derived from Humbug. * [1.7.9](https://github.com/CivClassic/CivModCore/tree/306b4f7268a3c5d3bd551fe66992f2a4335e86f7) - Spigot 1.14.4 -* [1.6.1](https://github.com/CivClassic/CivModCore/tree/8d1043b7ad4bcf3ffe30d87ee5e974f1dd111113) - Spigot 1.12.2 (Mercury Removed -- incompatible with plugins that rely on Mercury hooks) +* [1.6.1](https://github.com/CivClassic/CivModCore/tree/8d1043b7ad4bcf3ffe30d87ee5e974f1dd111113) - Spigot 1.12.2 ( + Mercury Removed -- incompatible with plugins that rely on Mercury hooks) * [1.5.11](https://github.com/CivClassic/CivModCore/tree/d88d6bbcf231616dc1c7bc08a3fabc0f57911613) - Spigot 1.11.x @@ -30,7 +31,8 @@ No explicit backwards support is offered to any previous version, whether it be To compile CivModCore, you need JDK 17. -Clone this repo, run `./gradlew reobfJar` to create your jar, You can find the compiled jar in the paper `build/libs` directory. +Clone this repo, run `./gradlew reobfJar` to create your jar, You can find the compiled jar in the paper `build/libs` +directory. To get a full list of tasks, run ./gradlew tasks. @@ -60,7 +62,8 @@ To take full advantage of CivModCore, you should have your plugin class extend ` } -For more information, look through the [CivTemplate plugin](https://github.com/CivClassic/CivTemplate/blob/master/src/main/java/io/protonull/template/TemplatePlugin.java). +For more information, look through +the [CivTemplate plugin](https://github.com/CivClassic/CivTemplate/blob/master/src/main/java/io/protonull/template/TemplatePlugin.java). ---- diff --git a/plugins/civmodcore-paper/build.gradle.kts b/plugins/civmodcore-paper/build.gradle.kts index 3c32f58f1..bf4cfab08 100644 --- a/plugins/civmodcore-paper/build.gradle.kts +++ b/plugins/civmodcore-paper/build.gradle.kts @@ -1,26 +1,26 @@ plugins { - id("io.papermc.paperweight.userdev") - id("com.github.johnrengelman.shadow") - id("xyz.jpenilla.run-paper") + id("io.papermc.paperweight.userdev") + id("com.github.johnrengelman.shadow") + id("xyz.jpenilla.run-paper") } version = "3.0.6" dependencies { - paperweight { - paperDevBundle("1.20.4-R0.1-SNAPSHOT") - } + paperweight { + paperDevBundle("1.20.4-R0.1-SNAPSHOT") + } - api("co.aikar:acf-bukkit:0.5.1-SNAPSHOT") - api("com.mojang:datafixerupper:1.0.20") - api("com.zaxxer:HikariCP:5.0.1") - api("co.aikar:taskchain-bukkit:3.7.2") - api("org.apache.commons:commons-lang3:3.12.0") - api("org.apache.commons:commons-collections4:4.4") - api("com.google.code.findbugs:jsr305:3.0.2") + api("co.aikar:acf-bukkit:0.5.1-SNAPSHOT") + api("com.mojang:datafixerupper:1.0.20") + api("com.zaxxer:HikariCP:5.0.1") + api("co.aikar:taskchain-bukkit:3.7.2") + api("org.apache.commons:commons-lang3:3.12.0") + api("org.apache.commons:commons-collections4:4.4") + api("com.google.code.findbugs:jsr305:3.0.2") - compileOnly("it.unimi.dsi:fastutil:8.5.8") + compileOnly("it.unimi.dsi:fastutil:8.5.8") - testImplementation("org.junit.jupiter:junit-jupiter-api:5.8.2") - testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.8.2") + testImplementation("org.junit.jupiter:junit-jupiter-api:5.8.2") + testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.8.2") } diff --git a/plugins/civmodcore-paper/src/main/java/org/bukkit/pseudo/PseudoServer.java b/plugins/civmodcore-paper/src/main/java/org/bukkit/pseudo/PseudoServer.java index e3e8764b1..7b295797a 100644 --- a/plugins/civmodcore-paper/src/main/java/org/bukkit/pseudo/PseudoServer.java +++ b/plugins/civmodcore-paper/src/main/java/org/bukkit/pseudo/PseudoServer.java @@ -95,1167 +95,1167 @@ import java.util.logging.Logger; @SuppressWarnings("deprecation") public class PseudoServer implements Server { - public static final PseudoServer INSTANCE = new PseudoServer(); - private static final Logger LOGGER = Logger.getLogger(PseudoServer.class.getSimpleName()); - - public static void setup() { - if (Bukkit.getServer() == null) { // Ignore highlighter - final var previousLevel = LOGGER.getLevel(); - LOGGER.setLevel(Level.OFF); // This is to prevent unnecessary logging - SharedConstants.tryDetectVersion(); // SharedConstants.tryDetectVersion() - Bootstrap.bootStrap(); - Bootstrap.validate(); - Bukkit.setServer(INSTANCE); - LOGGER.setLevel(previousLevel); - } - } - - @Nonnull - @Override - public Logger getLogger() { - return LOGGER; - } - - @Nonnull - @Override - public ItemFactory getItemFactory() { - return CraftItemFactory.instance(); - } - - @Nonnull - @Override - public UnsafeValues getUnsafe() { - return CraftMagicNumbers.INSTANCE; - } - - @Nonnull - @Override - public BlockData createBlockData(@Nonnull final Material material) { - return CraftBlockData.newData(material, null); - } - - @Override - public @NotNull BlockData createBlockData(@NotNull Material material, @org.jetbrains.annotations.Nullable Consumer consumer) { - return null; - } - - // ------------------------------------------------------------ - // Not implemented - // ------------------------------------------------------------ - - @Override - public @NotNull File getPluginsFolder() { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public String getName() { - return getClass().getSimpleName(); - } - - @Nonnull - @Override - public String getVersion() { - return getClass().getPackage().getImplementationVersion(); - } - - @Nonnull - @Override - public String getBukkitVersion() { - return Versioning.getBukkitVersion(); - } - - @Nonnull - @Override - public String getMinecraftVersion() { - return SharedConstants.getCurrentVersion().toString(); - } - - @Nonnull - @Override - public Collection getOnlinePlayers() { - throw new NotImplementedException(); - } - - @Override - public int getMaxPlayers() { - throw new NotImplementedException(); - } - - @Override - public void setMaxPlayers(final int i) { - throw new NotImplementedException(); - } - - @Override - public int getPort() { - throw new NotImplementedException(); - } - - @Override - public int getViewDistance() { - throw new NotImplementedException(); - } - - @Override - public int getSimulationDistance() { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public String getIp() { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public String getWorldType() { - throw new NotImplementedException(); - } - - @Override - public boolean getGenerateStructures() { - throw new NotImplementedException(); - } - - @Override - public int getMaxWorldSize() { - throw new NotImplementedException(); - } - - @Override - public boolean getAllowEnd() { - throw new NotImplementedException(); - } - - @Override - public boolean getAllowNether() { - throw new NotImplementedException(); - } - - @Override - public boolean isLoggingIPs() { - throw new NotImplementedException(); - } - - @Override - public @NotNull List getInitialEnabledPacks() { - throw new NotImplementedException(); - } - - @Override - public @NotNull List getInitialDisabledPacks() { - throw new NotImplementedException(); - } - - @Override - public @NotNull DataPackManager getDataPackManager() { - throw new NotImplementedException(); - } - - @Override - public @NotNull ServerTickManager getServerTickManager() { - throw new NotImplementedException(); - } - - @Override - public @org.jetbrains.annotations.Nullable ResourcePack getServerResourcePack() { - throw new NotImplementedException(); - } - - @Override - public @NotNull String getResourcePack() { - throw new NotImplementedException(); - } - - @Override - public @NotNull String getResourcePackHash() { - throw new NotImplementedException(); - } - - @Override - public @NotNull String getResourcePackPrompt() { - throw new NotImplementedException(); - } - - @Override - public boolean isResourcePackRequired() { - throw new NotImplementedException(); - } - - @Override - public boolean hasWhitelist() { - throw new NotImplementedException(); - } - - @Override - public void setWhitelist(final boolean b) { - throw new NotImplementedException(); - } - - @Override - public boolean isWhitelistEnforced() { - throw new NotImplementedException(); - } - - @Override - public void setWhitelistEnforced(boolean bl) { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public Set getWhitelistedPlayers() { - throw new NotImplementedException(); - } - - @Override - public void reloadWhitelist() { - throw new NotImplementedException(); - } - - @Override - public int broadcastMessage(@Nonnull final String s) { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public String getUpdateFolder() { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public File getUpdateFolderFile() { - throw new NotImplementedException(); - } - - @Override - public long getConnectionThrottle() { - throw new NotImplementedException(); - } - - @Override - public int getTicksPerAnimalSpawns() { - throw new NotImplementedException(); - } - - @Override - public int getTicksPerMonsterSpawns() { - throw new NotImplementedException(); - } - - @Override - public int getTicksPerWaterSpawns() { - throw new NotImplementedException(); - } - - @Override - public int getTicksPerWaterAmbientSpawns() { - throw new NotImplementedException(); - } - - @Override - public int getTicksPerWaterUndergroundCreatureSpawns() { - throw new NotImplementedException(); - } - - @Override - public int getTicksPerAmbientSpawns() { - throw new NotImplementedException(); - } - - @Override - public int getTicksPerSpawns(@NotNull SpawnCategory spawnCategory) { - throw new NotImplementedException(); - } - - @Nullable - @Override - public Player getPlayer(@Nonnull final String s) { - throw new NotImplementedException(); - } - - @Nullable - @Override - public Player getPlayerExact(@Nonnull final String s) { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public List matchPlayer(@Nonnull final String s) { - throw new NotImplementedException(); - } - - @Nullable - @Override - public Player getPlayer(@Nonnull final UUID uuid) { - throw new NotImplementedException(); - } - - @Nullable - @Override - public UUID getPlayerUniqueId(@Nonnull final String s) { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public PluginManager getPluginManager() { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public BukkitScheduler getScheduler() { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public ServicesManager getServicesManager() { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public List getWorlds() { - throw new NotImplementedException(); - } - - @Override - public boolean isTickingWorlds() { - throw new NotImplementedException(); - } - - @Nullable - @Override - public World createWorld(@Nonnull final WorldCreator worldCreator) { - throw new NotImplementedException(); - } - - @Override - public boolean unloadWorld(@Nonnull final String s, final boolean b) { - throw new NotImplementedException(); - } - - @Override - public boolean unloadWorld(@Nonnull final World world, final boolean b) { - throw new NotImplementedException(); - } - - @Nullable - @Override - public World getWorld(@Nonnull final String s) { - throw new NotImplementedException(); - } - - @Nullable - @Override - public World getWorld(@Nonnull final UUID uuid) { - throw new NotImplementedException(); - } - - @Nullable - @Override - public World getWorld(@Nonnull final NamespacedKey namespacedKey) { - throw new NotImplementedException(); - } - - @Override - public @NotNull WorldBorder createWorldBorder() { - throw new NotImplementedException(); - } - - @Nullable - @Override - public MapView getMap(final int i) { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public MapView createMap(@Nonnull final World world) { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public ItemStack createExplorerMap(@Nonnull final World world, @Nonnull final Location location, @Nonnull final StructureType structureType) { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public ItemStack createExplorerMap(@Nonnull final World world, @Nonnull final Location location, @Nonnull final StructureType structureType, final int i, final boolean b) { - throw new NotImplementedException(); - } - - @Override - public @org.jetbrains.annotations.Nullable ItemStack createExplorerMap(@NotNull World world, @NotNull Location location, org.bukkit.generator.structure.@NotNull StructureType structureType, @NotNull MapCursor.Type type, int i, boolean b) { - return null; - } - - @Override - public void reload() { - throw new NotImplementedException(); - } - - @Override - public void reloadData() { - throw new NotImplementedException(); - } - - @Override - public void updateResources() { - - } - - @Override - public void updateRecipes() { - - } - - @Nullable - @Override - public PluginCommand getPluginCommand(@Nonnull final String s) { - throw new NotImplementedException(); - } - - @Override - public void savePlayers() { - throw new NotImplementedException(); - } - - @Override - public boolean dispatchCommand(@Nonnull final CommandSender commandSender, @Nonnull final String s) throws CommandException { - throw new NotImplementedException(); - } - - @Override - public boolean addRecipe(@Nullable final Recipe recipe) { - throw new NotImplementedException(); - } - - @Override - public boolean addRecipe(@org.jetbrains.annotations.Nullable Recipe recipe, boolean b) { - return false; - } - - @Nonnull - @Override - public List getRecipesFor(@Nonnull final ItemStack itemStack) { - throw new NotImplementedException(); - } - - @Nullable - @Override - public Recipe getRecipe(@Nonnull final NamespacedKey namespacedKey) { - throw new NotImplementedException(); - } - - @Nullable - @Override - public Recipe getCraftingRecipe(@Nonnull ItemStack[] itemStacks, @Nonnull World world) { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public ItemStack craftItem(@Nonnull ItemStack[] itemStacks, @Nonnull World world, @Nonnull Player player) { - throw new NotImplementedException(); - } - - @Override - public @NotNull ItemStack craftItem(@NotNull ItemStack[] itemStacks, @NotNull World world) { - return null; - } - - @Override - public @NotNull ItemCraftResult craftItemResult(@NotNull ItemStack[] itemStacks, @NotNull World world, @NotNull Player player) { - return null; - } - - @Override - public @NotNull ItemCraftResult craftItemResult(@NotNull ItemStack[] itemStacks, @NotNull World world) { - return null; - } - - @Nonnull - @Override - public Iterator recipeIterator() { - throw new NotImplementedException(); - } - - @Override - public void clearRecipes() { - throw new NotImplementedException(); - } - - @Override - public void resetRecipes() { - throw new NotImplementedException(); - } - - @Override - public boolean removeRecipe(@Nonnull final NamespacedKey namespacedKey) { - throw new NotImplementedException(); - } - - @Override - public boolean removeRecipe(@NotNull NamespacedKey namespacedKey, boolean b) { - return false; - } - - @Nonnull - @Override - public Map getCommandAliases() { - throw new NotImplementedException(); - } - - @Override - public int getSpawnRadius() { - throw new NotImplementedException(); - } - - @Override - public void setSpawnRadius(final int i) { - throw new NotImplementedException(); - } - - @Override - public boolean shouldSendChatPreviews() { - return false; - } - - @Override - public boolean isEnforcingSecureProfiles() { - return false; - } - - @Override - public boolean getHideOnlinePlayers() { - throw new NotImplementedException(); - } - - @Override - public boolean getOnlineMode() { - throw new NotImplementedException(); - } - - @Override - public boolean getAllowFlight() { - throw new NotImplementedException(); - } - - @Override - public boolean isHardcore() { - throw new NotImplementedException(); - } - - @Override - public void shutdown() { - throw new NotImplementedException(); - } - - @Override - public int broadcast(@Nonnull final String s, @Nonnull final String s1) { - throw new NotImplementedException(); - } - - @Override - public int broadcast(@Nonnull Component component) { - throw new NotImplementedException(); - } - - @Override - public int broadcast(@Nonnull final Component component, @Nonnull final String s) { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public OfflinePlayer getOfflinePlayer(@Nonnull final String s) { - throw new NotImplementedException(); - } - - @Nullable - @Override - public OfflinePlayer getOfflinePlayerIfCached(@Nonnull final String s) { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public OfflinePlayer getOfflinePlayer(@Nonnull final UUID uuid) { - throw new NotImplementedException(); - } - - @Override - public org.bukkit.profile.@NotNull PlayerProfile createPlayerProfile( - @org.jetbrains.annotations.Nullable UUID uniqueId, @org.jetbrains.annotations.Nullable String name) { - throw new NotImplementedException(); - } - - @Override - public org.bukkit.profile.@NotNull PlayerProfile createPlayerProfile( - @NotNull UUID uniqueId) { - throw new NotImplementedException(); - } - - @Override - public org.bukkit.profile.@NotNull PlayerProfile createPlayerProfile( - @NotNull String name) { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public Set getIPBans() { - throw new NotImplementedException(); - } - - @Override - public void banIP(@Nonnull final String s) { - throw new NotImplementedException(); - } - - @Override - public void unbanIP(@Nonnull final String s) { - throw new NotImplementedException(); - } - - @Override - public void banIP(@NotNull InetAddress inetAddress) { - - } - - @Override - public void unbanIP(@NotNull InetAddress inetAddress) { - - } - - @Nonnull - @Override - public Set getBannedPlayers() { - throw new NotImplementedException(); - } - - @Override - public , E> @NotNull B getBanList(@NotNull BanListType banListType) { - return null; - } - - @Nonnull - @Override - public > T getBanList(@Nonnull final BanList.Type type) { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public Set getOperators() { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public GameMode getDefaultGameMode() { - throw new NotImplementedException(); - } - - @Override - public void setDefaultGameMode(@Nonnull final GameMode gameMode) { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public ConsoleCommandSender getConsoleSender() { - throw new NotImplementedException(); - } - - @Override - public @NotNull CommandSender createCommandSender( - @NotNull Consumer feedback) { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public File getWorldContainer() { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public OfflinePlayer[] getOfflinePlayers() { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public Messenger getMessenger() { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public HelpMap getHelpMap() { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public Inventory createInventory(@Nullable final InventoryHolder inventoryHolder, @Nonnull final InventoryType inventoryType) { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public Inventory createInventory(@Nullable final InventoryHolder inventoryHolder, @Nonnull final InventoryType inventoryType, @Nonnull final Component component) { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public Inventory createInventory(@Nullable final InventoryHolder inventoryHolder, @Nonnull final InventoryType inventoryType, @Nonnull final String s) { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public Inventory createInventory(@Nullable final InventoryHolder inventoryHolder, final int i) throws IllegalArgumentException { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public Inventory createInventory(@Nullable final InventoryHolder inventoryHolder, final int i, @Nonnull final Component component) throws IllegalArgumentException { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public Inventory createInventory(@Nullable final InventoryHolder inventoryHolder, final int i, @Nonnull final String s) throws IllegalArgumentException { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public Merchant createMerchant(@Nullable final Component component) { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public Merchant createMerchant(@Nullable final String s) { - throw new NotImplementedException(); - } - - @Override - public int getMaxChainedNeighborUpdates() { - return 0; - } - - @Override - public int getMonsterSpawnLimit() { - throw new NotImplementedException(); - } - - @Override - public int getAnimalSpawnLimit() { - throw new NotImplementedException(); - } - - @Override - public int getWaterAnimalSpawnLimit() { - throw new NotImplementedException(); - } - - @Override - public int getWaterAmbientSpawnLimit() { - throw new NotImplementedException(); - } - - @Override - public int getWaterUndergroundCreatureSpawnLimit() { - throw new NotImplementedException(); - } - - @Override - public int getAmbientSpawnLimit() { - throw new NotImplementedException(); - } - - @Override - public int getSpawnLimit(@NotNull SpawnCategory spawnCategory) { - throw new NotImplementedException(); - } - - @Override - public boolean isPrimaryThread() { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public Component motd() { - throw new NotImplementedException(); - } - - @Override - public void motd(@NotNull Component component) { - - } - - @Nonnull - @Override - public String getMotd() { - throw new NotImplementedException(); - } - - @Override - public void setMotd(@NotNull String s) { - - } - - @Nullable - @Override - public Component shutdownMessage() { - throw new NotImplementedException(); - } - - @Nullable - @Override - public String getShutdownMessage() { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public Warning.WarningState getWarningState() { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public ScoreboardManager getScoreboardManager() { - throw new NotImplementedException(); - } - - @Override - public @NotNull Criteria getScoreboardCriteria(@NotNull String s) { - return null; - } - - @Nullable - @Override - public CachedServerIcon getServerIcon() { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public CachedServerIcon loadServerIcon(@Nonnull final File file) throws IllegalArgumentException, Exception { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public CachedServerIcon loadServerIcon(@Nonnull final BufferedImage bufferedImage) throws IllegalArgumentException, Exception { - throw new NotImplementedException(); - } - - @Override - public void setIdleTimeout(final int i) { - throw new NotImplementedException(); - } - - @Override - public int getIdleTimeout() { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public ChunkGenerator.ChunkData createChunkData(@Nonnull final World world) { - throw new NotImplementedException(); - } - - @Override - public ChunkGenerator.@NotNull ChunkData createVanillaChunkData( - @NotNull World world, int x, int z) { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public BossBar createBossBar(@Nullable final String s, @Nonnull final BarColor barColor, @Nonnull final BarStyle barStyle, @Nonnull final BarFlag... barFlags) { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public KeyedBossBar createBossBar(@Nonnull final NamespacedKey namespacedKey, @Nullable final String s, @Nonnull final BarColor barColor, @Nonnull final BarStyle barStyle, @Nonnull final BarFlag... barFlags) { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public Iterator getBossBars() { - throw new NotImplementedException(); - } - - @Nullable - @Override - public KeyedBossBar getBossBar(@Nonnull final NamespacedKey namespacedKey) { - throw new NotImplementedException(); - } - - @Override - public boolean removeBossBar(@Nonnull final NamespacedKey namespacedKey) { - throw new NotImplementedException(); - } - - @Nullable - @Override - public Entity getEntity(@Nonnull final UUID uuid) { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public double[] getTPS() { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public long[] getTickTimes() { - throw new NotImplementedException(); - } - - @Override - public double getAverageTickTime() { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public CommandMap getCommandMap() { - throw new NotImplementedException(); - } - - @Nullable - @Override - public Advancement getAdvancement(@Nonnull final NamespacedKey namespacedKey) { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public Iterator advancementIterator() { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public BlockData createBlockData(@Nonnull final String s) throws IllegalArgumentException { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public BlockData createBlockData(@Nullable final Material material, @Nullable final String s) throws IllegalArgumentException { - throw new NotImplementedException(); - } - - @Override - public Tag getTag(@Nonnull final String s, @Nonnull final NamespacedKey namespacedKey, @Nonnull final Class aClass) { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public Iterable> getTags(@Nonnull final String s, @Nonnull final Class aClass) { - throw new NotImplementedException(); - } - - @Nullable - @Override - public LootTable getLootTable(@Nonnull final NamespacedKey namespacedKey) { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public List selectEntities(@Nonnull final CommandSender commandSender, @Nonnull final String s) throws IllegalArgumentException { - throw new NotImplementedException(); - } - - @Override - public @NotNull StructureManager getStructureManager() { - throw new NotImplementedException(); - } - - @Override - public @org.jetbrains.annotations.Nullable Registry getRegistry(@NotNull Class aClass) { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public Spigot spigot() { - throw new NotImplementedException(); - } - - @Override - public void reloadPermissions() { - throw new NotImplementedException(); - } - - @Override - public boolean reloadCommandAliases() { - throw new NotImplementedException(); - } - - @Override - public boolean suggestPlayerNamesWhenNullTabCompletions() { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public String getPermissionMessage() { - throw new NotImplementedException(); - } - - @Override - public @NotNull Component permissionMessage() { - return null; - } - - @Nonnull - @Override - public PlayerProfile createProfile(@Nonnull final UUID uuid) { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public PlayerProfile createProfile(@Nonnull final String s) { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public PlayerProfile createProfile(@Nullable final UUID uuid, @Nullable final String s) { - throw new NotImplementedException(); - } - - @Override - public @NotNull PlayerProfile createProfileExact(@Nullable UUID uuid, - @Nullable String name) { - throw new NotImplementedException(); - } - - @Override - public int getCurrentTick() { - throw new NotImplementedException(); - } - - @Override - public boolean isStopping() { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public MobGoals getMobGoals() { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public DatapackManager getDatapackManager() { - throw new NotImplementedException(); - } - - @Override - public @NotNull PotionBrewer getPotionBrewer() { - throw new NotImplementedException(); - } - - @Override - public @NotNull RegionScheduler getRegionScheduler() { - throw new NotImplementedException(); - } - - @Override - public @NotNull AsyncScheduler getAsyncScheduler() { - throw new NotImplementedException(); - } - - @Override - public @NotNull GlobalRegionScheduler getGlobalRegionScheduler() { - throw new NotImplementedException(); - } - - @Override - public boolean isOwnedByCurrentRegion(@NotNull World world, @NotNull Position position) { - throw new NotImplementedException(); - } - - @Override - public boolean isOwnedByCurrentRegion(@NotNull World world, @NotNull Position position, int i) { - throw new NotImplementedException(); - } - - @Override - public boolean isOwnedByCurrentRegion(@NotNull Location location) { - throw new NotImplementedException(); - } - - @Override - public boolean isOwnedByCurrentRegion(@NotNull Location location, int i) { - throw new NotImplementedException(); - } - - @Override - public boolean isOwnedByCurrentRegion(@NotNull World world, int i, int i1) { - throw new NotImplementedException(); - } - - @Override - public boolean isOwnedByCurrentRegion(@NotNull World world, int i, int i1, int i2) { - throw new NotImplementedException(); - } - - @Override - public boolean isOwnedByCurrentRegion(@NotNull Entity entity) { - throw new NotImplementedException(); - } - - @Override - public void sendPluginMessage(@Nonnull final Plugin plugin, @Nonnull final String s, @Nonnull final byte[] bytes) { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public Set getListeningPluginChannels() { - throw new NotImplementedException(); - } - - @Nonnull - @Override - public Iterable audiences() { - throw new NotImplementedException(); - } + public static final PseudoServer INSTANCE = new PseudoServer(); + private static final Logger LOGGER = Logger.getLogger(PseudoServer.class.getSimpleName()); + + public static void setup() { + if (Bukkit.getServer() == null) { // Ignore highlighter + final var previousLevel = LOGGER.getLevel(); + LOGGER.setLevel(Level.OFF); // This is to prevent unnecessary logging + SharedConstants.tryDetectVersion(); // SharedConstants.tryDetectVersion() + Bootstrap.bootStrap(); + Bootstrap.validate(); + Bukkit.setServer(INSTANCE); + LOGGER.setLevel(previousLevel); + } + } + + @Nonnull + @Override + public Logger getLogger() { + return LOGGER; + } + + @Nonnull + @Override + public ItemFactory getItemFactory() { + return CraftItemFactory.instance(); + } + + @Nonnull + @Override + public UnsafeValues getUnsafe() { + return CraftMagicNumbers.INSTANCE; + } + + @Nonnull + @Override + public BlockData createBlockData(@Nonnull final Material material) { + return CraftBlockData.newData(material, null); + } + + @Override + public @NotNull BlockData createBlockData(@NotNull Material material, @org.jetbrains.annotations.Nullable Consumer consumer) { + return null; + } + + // ------------------------------------------------------------ + // Not implemented + // ------------------------------------------------------------ + + @Override + public @NotNull File getPluginsFolder() { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public String getName() { + return getClass().getSimpleName(); + } + + @Nonnull + @Override + public String getVersion() { + return getClass().getPackage().getImplementationVersion(); + } + + @Nonnull + @Override + public String getBukkitVersion() { + return Versioning.getBukkitVersion(); + } + + @Nonnull + @Override + public String getMinecraftVersion() { + return SharedConstants.getCurrentVersion().toString(); + } + + @Nonnull + @Override + public Collection getOnlinePlayers() { + throw new NotImplementedException(); + } + + @Override + public int getMaxPlayers() { + throw new NotImplementedException(); + } + + @Override + public void setMaxPlayers(final int i) { + throw new NotImplementedException(); + } + + @Override + public int getPort() { + throw new NotImplementedException(); + } + + @Override + public int getViewDistance() { + throw new NotImplementedException(); + } + + @Override + public int getSimulationDistance() { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public String getIp() { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public String getWorldType() { + throw new NotImplementedException(); + } + + @Override + public boolean getGenerateStructures() { + throw new NotImplementedException(); + } + + @Override + public int getMaxWorldSize() { + throw new NotImplementedException(); + } + + @Override + public boolean getAllowEnd() { + throw new NotImplementedException(); + } + + @Override + public boolean getAllowNether() { + throw new NotImplementedException(); + } + + @Override + public boolean isLoggingIPs() { + throw new NotImplementedException(); + } + + @Override + public @NotNull List getInitialEnabledPacks() { + throw new NotImplementedException(); + } + + @Override + public @NotNull List getInitialDisabledPacks() { + throw new NotImplementedException(); + } + + @Override + public @NotNull DataPackManager getDataPackManager() { + throw new NotImplementedException(); + } + + @Override + public @NotNull ServerTickManager getServerTickManager() { + throw new NotImplementedException(); + } + + @Override + public @org.jetbrains.annotations.Nullable ResourcePack getServerResourcePack() { + throw new NotImplementedException(); + } + + @Override + public @NotNull String getResourcePack() { + throw new NotImplementedException(); + } + + @Override + public @NotNull String getResourcePackHash() { + throw new NotImplementedException(); + } + + @Override + public @NotNull String getResourcePackPrompt() { + throw new NotImplementedException(); + } + + @Override + public boolean isResourcePackRequired() { + throw new NotImplementedException(); + } + + @Override + public boolean hasWhitelist() { + throw new NotImplementedException(); + } + + @Override + public void setWhitelist(final boolean b) { + throw new NotImplementedException(); + } + + @Override + public boolean isWhitelistEnforced() { + throw new NotImplementedException(); + } + + @Override + public void setWhitelistEnforced(boolean bl) { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public Set getWhitelistedPlayers() { + throw new NotImplementedException(); + } + + @Override + public void reloadWhitelist() { + throw new NotImplementedException(); + } + + @Override + public int broadcastMessage(@Nonnull final String s) { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public String getUpdateFolder() { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public File getUpdateFolderFile() { + throw new NotImplementedException(); + } + + @Override + public long getConnectionThrottle() { + throw new NotImplementedException(); + } + + @Override + public int getTicksPerAnimalSpawns() { + throw new NotImplementedException(); + } + + @Override + public int getTicksPerMonsterSpawns() { + throw new NotImplementedException(); + } + + @Override + public int getTicksPerWaterSpawns() { + throw new NotImplementedException(); + } + + @Override + public int getTicksPerWaterAmbientSpawns() { + throw new NotImplementedException(); + } + + @Override + public int getTicksPerWaterUndergroundCreatureSpawns() { + throw new NotImplementedException(); + } + + @Override + public int getTicksPerAmbientSpawns() { + throw new NotImplementedException(); + } + + @Override + public int getTicksPerSpawns(@NotNull SpawnCategory spawnCategory) { + throw new NotImplementedException(); + } + + @Nullable + @Override + public Player getPlayer(@Nonnull final String s) { + throw new NotImplementedException(); + } + + @Nullable + @Override + public Player getPlayerExact(@Nonnull final String s) { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public List matchPlayer(@Nonnull final String s) { + throw new NotImplementedException(); + } + + @Nullable + @Override + public Player getPlayer(@Nonnull final UUID uuid) { + throw new NotImplementedException(); + } + + @Nullable + @Override + public UUID getPlayerUniqueId(@Nonnull final String s) { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public PluginManager getPluginManager() { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public BukkitScheduler getScheduler() { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public ServicesManager getServicesManager() { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public List getWorlds() { + throw new NotImplementedException(); + } + + @Override + public boolean isTickingWorlds() { + throw new NotImplementedException(); + } + + @Nullable + @Override + public World createWorld(@Nonnull final WorldCreator worldCreator) { + throw new NotImplementedException(); + } + + @Override + public boolean unloadWorld(@Nonnull final String s, final boolean b) { + throw new NotImplementedException(); + } + + @Override + public boolean unloadWorld(@Nonnull final World world, final boolean b) { + throw new NotImplementedException(); + } + + @Nullable + @Override + public World getWorld(@Nonnull final String s) { + throw new NotImplementedException(); + } + + @Nullable + @Override + public World getWorld(@Nonnull final UUID uuid) { + throw new NotImplementedException(); + } + + @Nullable + @Override + public World getWorld(@Nonnull final NamespacedKey namespacedKey) { + throw new NotImplementedException(); + } + + @Override + public @NotNull WorldBorder createWorldBorder() { + throw new NotImplementedException(); + } + + @Nullable + @Override + public MapView getMap(final int i) { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public MapView createMap(@Nonnull final World world) { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public ItemStack createExplorerMap(@Nonnull final World world, @Nonnull final Location location, @Nonnull final StructureType structureType) { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public ItemStack createExplorerMap(@Nonnull final World world, @Nonnull final Location location, @Nonnull final StructureType structureType, final int i, final boolean b) { + throw new NotImplementedException(); + } + + @Override + public @org.jetbrains.annotations.Nullable ItemStack createExplorerMap(@NotNull World world, @NotNull Location location, org.bukkit.generator.structure.@NotNull StructureType structureType, @NotNull MapCursor.Type type, int i, boolean b) { + return null; + } + + @Override + public void reload() { + throw new NotImplementedException(); + } + + @Override + public void reloadData() { + throw new NotImplementedException(); + } + + @Override + public void updateResources() { + + } + + @Override + public void updateRecipes() { + + } + + @Nullable + @Override + public PluginCommand getPluginCommand(@Nonnull final String s) { + throw new NotImplementedException(); + } + + @Override + public void savePlayers() { + throw new NotImplementedException(); + } + + @Override + public boolean dispatchCommand(@Nonnull final CommandSender commandSender, @Nonnull final String s) throws CommandException { + throw new NotImplementedException(); + } + + @Override + public boolean addRecipe(@Nullable final Recipe recipe) { + throw new NotImplementedException(); + } + + @Override + public boolean addRecipe(@org.jetbrains.annotations.Nullable Recipe recipe, boolean b) { + return false; + } + + @Nonnull + @Override + public List getRecipesFor(@Nonnull final ItemStack itemStack) { + throw new NotImplementedException(); + } + + @Nullable + @Override + public Recipe getRecipe(@Nonnull final NamespacedKey namespacedKey) { + throw new NotImplementedException(); + } + + @Nullable + @Override + public Recipe getCraftingRecipe(@Nonnull ItemStack[] itemStacks, @Nonnull World world) { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public ItemStack craftItem(@Nonnull ItemStack[] itemStacks, @Nonnull World world, @Nonnull Player player) { + throw new NotImplementedException(); + } + + @Override + public @NotNull ItemStack craftItem(@NotNull ItemStack[] itemStacks, @NotNull World world) { + return null; + } + + @Override + public @NotNull ItemCraftResult craftItemResult(@NotNull ItemStack[] itemStacks, @NotNull World world, @NotNull Player player) { + return null; + } + + @Override + public @NotNull ItemCraftResult craftItemResult(@NotNull ItemStack[] itemStacks, @NotNull World world) { + return null; + } + + @Nonnull + @Override + public Iterator recipeIterator() { + throw new NotImplementedException(); + } + + @Override + public void clearRecipes() { + throw new NotImplementedException(); + } + + @Override + public void resetRecipes() { + throw new NotImplementedException(); + } + + @Override + public boolean removeRecipe(@Nonnull final NamespacedKey namespacedKey) { + throw new NotImplementedException(); + } + + @Override + public boolean removeRecipe(@NotNull NamespacedKey namespacedKey, boolean b) { + return false; + } + + @Nonnull + @Override + public Map getCommandAliases() { + throw new NotImplementedException(); + } + + @Override + public int getSpawnRadius() { + throw new NotImplementedException(); + } + + @Override + public void setSpawnRadius(final int i) { + throw new NotImplementedException(); + } + + @Override + public boolean shouldSendChatPreviews() { + return false; + } + + @Override + public boolean isEnforcingSecureProfiles() { + return false; + } + + @Override + public boolean getHideOnlinePlayers() { + throw new NotImplementedException(); + } + + @Override + public boolean getOnlineMode() { + throw new NotImplementedException(); + } + + @Override + public boolean getAllowFlight() { + throw new NotImplementedException(); + } + + @Override + public boolean isHardcore() { + throw new NotImplementedException(); + } + + @Override + public void shutdown() { + throw new NotImplementedException(); + } + + @Override + public int broadcast(@Nonnull final String s, @Nonnull final String s1) { + throw new NotImplementedException(); + } + + @Override + public int broadcast(@Nonnull Component component) { + throw new NotImplementedException(); + } + + @Override + public int broadcast(@Nonnull final Component component, @Nonnull final String s) { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public OfflinePlayer getOfflinePlayer(@Nonnull final String s) { + throw new NotImplementedException(); + } + + @Nullable + @Override + public OfflinePlayer getOfflinePlayerIfCached(@Nonnull final String s) { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public OfflinePlayer getOfflinePlayer(@Nonnull final UUID uuid) { + throw new NotImplementedException(); + } + + @Override + public org.bukkit.profile.@NotNull PlayerProfile createPlayerProfile( + @org.jetbrains.annotations.Nullable UUID uniqueId, @org.jetbrains.annotations.Nullable String name) { + throw new NotImplementedException(); + } + + @Override + public org.bukkit.profile.@NotNull PlayerProfile createPlayerProfile( + @NotNull UUID uniqueId) { + throw new NotImplementedException(); + } + + @Override + public org.bukkit.profile.@NotNull PlayerProfile createPlayerProfile( + @NotNull String name) { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public Set getIPBans() { + throw new NotImplementedException(); + } + + @Override + public void banIP(@Nonnull final String s) { + throw new NotImplementedException(); + } + + @Override + public void unbanIP(@Nonnull final String s) { + throw new NotImplementedException(); + } + + @Override + public void banIP(@NotNull InetAddress inetAddress) { + + } + + @Override + public void unbanIP(@NotNull InetAddress inetAddress) { + + } + + @Nonnull + @Override + public Set getBannedPlayers() { + throw new NotImplementedException(); + } + + @Override + public , E> @NotNull B getBanList(@NotNull BanListType banListType) { + return null; + } + + @Nonnull + @Override + public > T getBanList(@Nonnull final BanList.Type type) { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public Set getOperators() { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public GameMode getDefaultGameMode() { + throw new NotImplementedException(); + } + + @Override + public void setDefaultGameMode(@Nonnull final GameMode gameMode) { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public ConsoleCommandSender getConsoleSender() { + throw new NotImplementedException(); + } + + @Override + public @NotNull CommandSender createCommandSender( + @NotNull Consumer feedback) { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public File getWorldContainer() { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public OfflinePlayer[] getOfflinePlayers() { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public Messenger getMessenger() { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public HelpMap getHelpMap() { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public Inventory createInventory(@Nullable final InventoryHolder inventoryHolder, @Nonnull final InventoryType inventoryType) { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public Inventory createInventory(@Nullable final InventoryHolder inventoryHolder, @Nonnull final InventoryType inventoryType, @Nonnull final Component component) { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public Inventory createInventory(@Nullable final InventoryHolder inventoryHolder, @Nonnull final InventoryType inventoryType, @Nonnull final String s) { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public Inventory createInventory(@Nullable final InventoryHolder inventoryHolder, final int i) throws IllegalArgumentException { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public Inventory createInventory(@Nullable final InventoryHolder inventoryHolder, final int i, @Nonnull final Component component) throws IllegalArgumentException { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public Inventory createInventory(@Nullable final InventoryHolder inventoryHolder, final int i, @Nonnull final String s) throws IllegalArgumentException { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public Merchant createMerchant(@Nullable final Component component) { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public Merchant createMerchant(@Nullable final String s) { + throw new NotImplementedException(); + } + + @Override + public int getMaxChainedNeighborUpdates() { + return 0; + } + + @Override + public int getMonsterSpawnLimit() { + throw new NotImplementedException(); + } + + @Override + public int getAnimalSpawnLimit() { + throw new NotImplementedException(); + } + + @Override + public int getWaterAnimalSpawnLimit() { + throw new NotImplementedException(); + } + + @Override + public int getWaterAmbientSpawnLimit() { + throw new NotImplementedException(); + } + + @Override + public int getWaterUndergroundCreatureSpawnLimit() { + throw new NotImplementedException(); + } + + @Override + public int getAmbientSpawnLimit() { + throw new NotImplementedException(); + } + + @Override + public int getSpawnLimit(@NotNull SpawnCategory spawnCategory) { + throw new NotImplementedException(); + } + + @Override + public boolean isPrimaryThread() { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public Component motd() { + throw new NotImplementedException(); + } + + @Override + public void motd(@NotNull Component component) { + + } + + @Nonnull + @Override + public String getMotd() { + throw new NotImplementedException(); + } + + @Override + public void setMotd(@NotNull String s) { + + } + + @Nullable + @Override + public Component shutdownMessage() { + throw new NotImplementedException(); + } + + @Nullable + @Override + public String getShutdownMessage() { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public Warning.WarningState getWarningState() { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public ScoreboardManager getScoreboardManager() { + throw new NotImplementedException(); + } + + @Override + public @NotNull Criteria getScoreboardCriteria(@NotNull String s) { + return null; + } + + @Nullable + @Override + public CachedServerIcon getServerIcon() { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public CachedServerIcon loadServerIcon(@Nonnull final File file) throws IllegalArgumentException, Exception { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public CachedServerIcon loadServerIcon(@Nonnull final BufferedImage bufferedImage) throws IllegalArgumentException, Exception { + throw new NotImplementedException(); + } + + @Override + public void setIdleTimeout(final int i) { + throw new NotImplementedException(); + } + + @Override + public int getIdleTimeout() { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public ChunkGenerator.ChunkData createChunkData(@Nonnull final World world) { + throw new NotImplementedException(); + } + + @Override + public ChunkGenerator.@NotNull ChunkData createVanillaChunkData( + @NotNull World world, int x, int z) { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public BossBar createBossBar(@Nullable final String s, @Nonnull final BarColor barColor, @Nonnull final BarStyle barStyle, @Nonnull final BarFlag... barFlags) { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public KeyedBossBar createBossBar(@Nonnull final NamespacedKey namespacedKey, @Nullable final String s, @Nonnull final BarColor barColor, @Nonnull final BarStyle barStyle, @Nonnull final BarFlag... barFlags) { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public Iterator getBossBars() { + throw new NotImplementedException(); + } + + @Nullable + @Override + public KeyedBossBar getBossBar(@Nonnull final NamespacedKey namespacedKey) { + throw new NotImplementedException(); + } + + @Override + public boolean removeBossBar(@Nonnull final NamespacedKey namespacedKey) { + throw new NotImplementedException(); + } + + @Nullable + @Override + public Entity getEntity(@Nonnull final UUID uuid) { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public double[] getTPS() { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public long[] getTickTimes() { + throw new NotImplementedException(); + } + + @Override + public double getAverageTickTime() { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public CommandMap getCommandMap() { + throw new NotImplementedException(); + } + + @Nullable + @Override + public Advancement getAdvancement(@Nonnull final NamespacedKey namespacedKey) { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public Iterator advancementIterator() { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public BlockData createBlockData(@Nonnull final String s) throws IllegalArgumentException { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public BlockData createBlockData(@Nullable final Material material, @Nullable final String s) throws IllegalArgumentException { + throw new NotImplementedException(); + } + + @Override + public Tag getTag(@Nonnull final String s, @Nonnull final NamespacedKey namespacedKey, @Nonnull final Class aClass) { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public Iterable> getTags(@Nonnull final String s, @Nonnull final Class aClass) { + throw new NotImplementedException(); + } + + @Nullable + @Override + public LootTable getLootTable(@Nonnull final NamespacedKey namespacedKey) { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public List selectEntities(@Nonnull final CommandSender commandSender, @Nonnull final String s) throws IllegalArgumentException { + throw new NotImplementedException(); + } + + @Override + public @NotNull StructureManager getStructureManager() { + throw new NotImplementedException(); + } + + @Override + public @org.jetbrains.annotations.Nullable Registry getRegistry(@NotNull Class aClass) { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public Spigot spigot() { + throw new NotImplementedException(); + } + + @Override + public void reloadPermissions() { + throw new NotImplementedException(); + } + + @Override + public boolean reloadCommandAliases() { + throw new NotImplementedException(); + } + + @Override + public boolean suggestPlayerNamesWhenNullTabCompletions() { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public String getPermissionMessage() { + throw new NotImplementedException(); + } + + @Override + public @NotNull Component permissionMessage() { + return null; + } + + @Nonnull + @Override + public PlayerProfile createProfile(@Nonnull final UUID uuid) { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public PlayerProfile createProfile(@Nonnull final String s) { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public PlayerProfile createProfile(@Nullable final UUID uuid, @Nullable final String s) { + throw new NotImplementedException(); + } + + @Override + public @NotNull PlayerProfile createProfileExact(@Nullable UUID uuid, + @Nullable String name) { + throw new NotImplementedException(); + } + + @Override + public int getCurrentTick() { + throw new NotImplementedException(); + } + + @Override + public boolean isStopping() { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public MobGoals getMobGoals() { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public DatapackManager getDatapackManager() { + throw new NotImplementedException(); + } + + @Override + public @NotNull PotionBrewer getPotionBrewer() { + throw new NotImplementedException(); + } + + @Override + public @NotNull RegionScheduler getRegionScheduler() { + throw new NotImplementedException(); + } + + @Override + public @NotNull AsyncScheduler getAsyncScheduler() { + throw new NotImplementedException(); + } + + @Override + public @NotNull GlobalRegionScheduler getGlobalRegionScheduler() { + throw new NotImplementedException(); + } + + @Override + public boolean isOwnedByCurrentRegion(@NotNull World world, @NotNull Position position) { + throw new NotImplementedException(); + } + + @Override + public boolean isOwnedByCurrentRegion(@NotNull World world, @NotNull Position position, int i) { + throw new NotImplementedException(); + } + + @Override + public boolean isOwnedByCurrentRegion(@NotNull Location location) { + throw new NotImplementedException(); + } + + @Override + public boolean isOwnedByCurrentRegion(@NotNull Location location, int i) { + throw new NotImplementedException(); + } + + @Override + public boolean isOwnedByCurrentRegion(@NotNull World world, int i, int i1) { + throw new NotImplementedException(); + } + + @Override + public boolean isOwnedByCurrentRegion(@NotNull World world, int i, int i1, int i2) { + throw new NotImplementedException(); + } + + @Override + public boolean isOwnedByCurrentRegion(@NotNull Entity entity) { + throw new NotImplementedException(); + } + + @Override + public void sendPluginMessage(@Nonnull final Plugin plugin, @Nonnull final String s, @Nonnull final byte[] bytes) { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public Set getListeningPluginChannels() { + throw new NotImplementedException(); + } + + @Nonnull + @Override + public Iterable audiences() { + throw new NotImplementedException(); + } } diff --git a/plugins/civmodcore-paper/src/main/java/vg/civcraft/mc/civmodcore/ACivMod.java b/plugins/civmodcore-paper/src/main/java/vg/civcraft/mc/civmodcore/ACivMod.java index 641a860fe..54ce5aeb8 100644 --- a/plugins/civmodcore-paper/src/main/java/vg/civcraft/mc/civmodcore/ACivMod.java +++ b/plugins/civmodcore-paper/src/main/java/vg/civcraft/mc/civmodcore/ACivMod.java @@ -18,96 +18,100 @@ import org.bukkit.plugin.java.JavaPluginLoader; public abstract class ACivMod extends JavaPlugin { - private final Set> configClasses = new HashSet<>(0); + private final Set> configClasses = new HashSet<>(0); - /** Primary constructor used by the real server */ - protected ACivMod() { - super(); - } + /** + * Primary constructor used by the real server + */ + protected ACivMod() { + super(); + } - /** Secondary constructor used for testing */ - protected ACivMod(JavaPluginLoader loader, PluginDescriptionFile description, File dataFolder, File file) { - super(loader, description, dataFolder, file); - } + /** + * Secondary constructor used for testing + */ + protected ACivMod(JavaPluginLoader loader, PluginDescriptionFile description, File dataFolder, File file) { + super(loader, description, dataFolder, file); + } - @Override - public void onEnable() { - // Self disable when a hard dependency is disabled - registerListener(new Listener() { - @EventHandler - public void onPluginDisable(final PluginDisableEvent event) { - final String pluginName = event.getPlugin().getName(); - if (getDescription().getDepend().contains(pluginName)) { - warning("Plugin [" + pluginName + "] has been disabled, disabling this plugin."); - disable(); - } - } - }); - } - - @Override - public void onDisable() { - this.configClasses.forEach(ConfigurationSerialization::unregisterClass); - } + @Override + public void onEnable() { + // Self disable when a hard dependency is disabled + registerListener(new Listener() { + @EventHandler + public void onPluginDisable(final PluginDisableEvent event) { + final String pluginName = event.getPlugin().getName(); + if (getDescription().getDepend().contains(pluginName)) { + warning("Plugin [" + pluginName + "] has been disabled, disabling this plugin."); + disable(); + } + } + }); + } - /** - * Registers a listener class with this plugin. - * - * @param listener The listener class to register. - */ - public void registerListener(@Nonnull final Listener listener) { - getServer().getPluginManager().registerEvents( - Objects.requireNonNull(listener, "Cannot register a listener if it's null, you dummy"), this); - } + @Override + public void onDisable() { + this.configClasses.forEach(ConfigurationSerialization::unregisterClass); + } - /** - * Convenience method you can use to register {@link ConfigurationSerializable} classes, which will be - * automatically un-registered when this plugin is disabled. - * - * @param clazz The serializable class to register and automatically unregister upon disable. - */ - public void registerConfigClass(@Nonnull final Class clazz) { - Objects.requireNonNull(clazz, "Cannot register a config class if it's null, you dummy"); - ConfigurationSerialization.registerClass(clazz); - this.configClasses.add(clazz); - } + /** + * Registers a listener class with this plugin. + * + * @param listener The listener class to register. + */ + public void registerListener(@Nonnull final Listener listener) { + getServer().getPluginManager().registerEvents( + Objects.requireNonNull(listener, "Cannot register a listener if it's null, you dummy"), this); + } - /** - * Determines whether this plugin is in debug mode, which is determined by a config value. - * - * @return Returns true if this plugin is in debug mode. - */ - public boolean isDebugEnabled() { - return getConfig().getBoolean("debug", false); - } + /** + * Convenience method you can use to register {@link ConfigurationSerializable} classes, which will be + * automatically un-registered when this plugin is disabled. + * + * @param clazz The serializable class to register and automatically unregister upon disable. + */ + public void registerConfigClass(@Nonnull final Class clazz) { + Objects.requireNonNull(clazz, "Cannot register a config class if it's null, you dummy"); + ConfigurationSerialization.registerClass(clazz); + this.configClasses.add(clazz); + } - /** - * Generates a file instance based on a file within this plugin's data folder. - * - * @param path The path of the file relative to the data folder. - * @return Returns a file instance of the generated path. - */ - public File getDataFile(@Nonnull final String path) { - return new File(getDataFolder(), Objects.requireNonNull(path)); - } + /** + * Determines whether this plugin is in debug mode, which is determined by a config value. + * + * @return Returns true if this plugin is in debug mode. + */ + public boolean isDebugEnabled() { + return getConfig().getBoolean("debug", false); + } - /** - * Saves a default resource to the plugin's data folder if the file does not already exist. - * - * @param path The path to the default resource AND the data file. - */ - public void saveDefaultResource(@Nonnull final String path) { - if (!getDataFile(path).exists()) { - saveResource(path, false); - } - } + /** + * Generates a file instance based on a file within this plugin's data folder. + * + * @param path The path of the file relative to the data folder. + * @return Returns a file instance of the generated path. + */ + public File getDataFile(@Nonnull final String path) { + return new File(getDataFolder(), Objects.requireNonNull(path)); + } - /** - * Saves a particular default resource to a particular location. - * - * @param defaultPath The path of the file within the plugin's jar. - * @param dataPath The path the file should take within the plugin's data folder. - */ + /** + * Saves a default resource to the plugin's data folder if the file does not already exist. + * + * @param path The path to the default resource AND the data file. + */ + public void saveDefaultResource(@Nonnull final String path) { + if (!getDataFile(path).exists()) { + saveResource(path, false); + } + } + + /** + * Saves a particular default resource to a particular location. + * + * @param defaultPath The path of the file within the plugin's jar. + * @param dataPath The path the file should take within the plugin's data folder. + */ // public void saveDefaultResourceAs(@Nonnull String defaultPath, // @Nonnull String dataPath) { // if (getDataFile(defaultPath).exists()) { @@ -130,86 +134,86 @@ public abstract class ACivMod extends JavaPlugin { // } // } - /** - * Disables this plugin. - */ - public void disable() { - getServer().getPluginManager().disablePlugin(this); - } + /** + * Disables this plugin. + */ + public void disable() { + getServer().getPluginManager().disablePlugin(this); + } - /** - * Simple SEVERE level logging. - */ - public void severe(String message) { - getLogger().log(Level.SEVERE, message); - } + /** + * Simple SEVERE level logging. + */ + public void severe(String message) { + getLogger().log(Level.SEVERE, message); + } - /** - * Simple SEVERE level logging with Throwable record. - */ - public void severe(String message, Throwable error) { - getLogger().log(Level.SEVERE, message, error); - } + /** + * Simple SEVERE level logging with Throwable record. + */ + public void severe(String message, Throwable error) { + getLogger().log(Level.SEVERE, message, error); + } - /** - * Simple WARNING level logging. - */ - public void warning(String message) { - getLogger().log(Level.WARNING, message); - } + /** + * Simple WARNING level logging. + */ + public void warning(String message) { + getLogger().log(Level.WARNING, message); + } - /** - * Simple WARNING level logging with Throwable record. - */ - public void warning(String message, Throwable error) { - getLogger().log(Level.WARNING, message, error); - } + /** + * Simple WARNING level logging with Throwable record. + */ + public void warning(String message, Throwable error) { + getLogger().log(Level.WARNING, message, error); + } - /** - * Simple WARNING level logging with ellipsis notation shortcut for defered - * injection argument array. - */ - public void warning(String message, Object... vars) { - getLogger().log(Level.WARNING, message, vars); - } + /** + * Simple WARNING level logging with ellipsis notation shortcut for defered + * injection argument array. + */ + public void warning(String message, Object... vars) { + getLogger().log(Level.WARNING, message, vars); + } - /** - * Simple INFO level logging - */ - public void info(String message) { - getLogger().log(Level.INFO, message); - } + /** + * Simple INFO level logging + */ + public void info(String message) { + getLogger().log(Level.INFO, message); + } - /** - * Simple INFO level logging with ellipsis notation shortcut for defered - * injection argument array. - */ - public void info(String message, Object... vars) { - getLogger().log(Level.INFO, message, vars); - } + /** + * Simple INFO level logging with ellipsis notation shortcut for defered + * injection argument array. + */ + public void info(String message, Object... vars) { + getLogger().log(Level.INFO, message, vars); + } - /** - * Live activatable debug message (using plugin's config.yml top level debug tag to decide) at - * INFO level. - * - * Skipped if DebugLog is false. - */ - public void debug(String message) { - if (isDebugEnabled()) { - getLogger().log(Level.INFO, message); - } - } + /** + * Live activatable debug message (using plugin's config.yml top level debug tag to decide) at + * INFO level. + *

+ * Skipped if DebugLog is false. + */ + public void debug(String message) { + if (isDebugEnabled()) { + getLogger().log(Level.INFO, message); + } + } - /** - * Live activatable debug message (using plugin's config.yml top level debug tag to decide) at - * INFO level with ellipsis notation shorcut for defered injection argument - * array. - * - * Skipped if DebugLog is false. - */ - public void debug(String message, Object... vars) { - if (isDebugEnabled()) { - getLogger().log(Level.INFO, message, vars); - } - } + /** + * Live activatable debug message (using plugin's config.yml top level debug tag to decide) at + * INFO level with ellipsis notation shorcut for defered injection argument + * array. + *

+ * Skipped if DebugLog is false. + */ + public void debug(String message, Object... vars) { + if (isDebugEnabled()) { + getLogger().log(Level.INFO, message, vars); + } + } } diff --git a/plugins/civmodcore-paper/src/main/java/vg/civcraft/mc/civmodcore/CivModCoreConfig.java b/plugins/civmodcore-paper/src/main/java/vg/civcraft/mc/civmodcore/CivModCoreConfig.java index 9cbfc6c52..a056d4971 100644 --- a/plugins/civmodcore-paper/src/main/java/vg/civcraft/mc/civmodcore/CivModCoreConfig.java +++ b/plugins/civmodcore-paper/src/main/java/vg/civcraft/mc/civmodcore/CivModCoreConfig.java @@ -10,66 +10,66 @@ import java.util.Objects; public final class CivModCoreConfig extends ConfigParser { - private DatabaseCredentials databaseCredentials; - private static final DatabaseCredentials DEFAULT_DATABASE_CREDENTIALS = null; + private DatabaseCredentials databaseCredentials; + private static final DatabaseCredentials DEFAULT_DATABASE_CREDENTIALS = null; - private String scoreboardHeader; - private static final String DEFAULT_SCOREBOARD_HEADER = " Info "; + private String scoreboardHeader; + private static final String DEFAULT_SCOREBOARD_HEADER = " Info "; - private int skinCacheThreads; - private static final int DEFAULT_SKIN_CACHE_THREADS = Runtime.getRuntime().availableProcessors() / 2; + private int skinCacheThreads; + private static final int DEFAULT_SKIN_CACHE_THREADS = Runtime.getRuntime().availableProcessors() / 2; - private boolean chunkLoadingStatistics; - private static final boolean DEFAULT_CHUNK_LOADING_STATISTICS = true; + private boolean chunkLoadingStatistics; + private static final boolean DEFAULT_CHUNK_LOADING_STATISTICS = true; - private int chunkLoadingThreads; - private static final int DEFAULT_CHUNK_LOADING_THREADS = 1; + private int chunkLoadingThreads; + private static final int DEFAULT_CHUNK_LOADING_THREADS = 1; - CivModCoreConfig(@Nonnull final CivModCorePlugin plugin) { - super(plugin); - Objects.requireNonNull(plugin); - reset(); - } + CivModCoreConfig(@Nonnull final CivModCorePlugin plugin) { + super(plugin); + Objects.requireNonNull(plugin); + reset(); + } - @Override - protected boolean parseInternal(@Nonnull final ConfigurationSection config) { - this.databaseCredentials = config.getObject("database", - DatabaseCredentials.class, DEFAULT_DATABASE_CREDENTIALS); - this.scoreboardHeader = ChatColor.translateAlternateColorCodes('&', - config.getString("scoreboardHeader", DEFAULT_SCOREBOARD_HEADER)); - this.skinCacheThreads = config.getInt("skin-download-threads", DEFAULT_SKIN_CACHE_THREADS); - this.chunkLoadingStatistics = config.getBoolean("chunk-loading-statistics", DEFAULT_CHUNK_LOADING_STATISTICS); - this.chunkLoadingThreads = config.getInt("chunk-loading-threads", DEFAULT_CHUNK_LOADING_THREADS); - return true; - } + @Override + protected boolean parseInternal(@Nonnull final ConfigurationSection config) { + this.databaseCredentials = config.getObject("database", + DatabaseCredentials.class, DEFAULT_DATABASE_CREDENTIALS); + this.scoreboardHeader = ChatColor.translateAlternateColorCodes('&', + config.getString("scoreboardHeader", DEFAULT_SCOREBOARD_HEADER)); + this.skinCacheThreads = config.getInt("skin-download-threads", DEFAULT_SKIN_CACHE_THREADS); + this.chunkLoadingStatistics = config.getBoolean("chunk-loading-statistics", DEFAULT_CHUNK_LOADING_STATISTICS); + this.chunkLoadingThreads = config.getInt("chunk-loading-threads", DEFAULT_CHUNK_LOADING_THREADS); + return true; + } - @Override - public void reset() { - super.reset(); - this.databaseCredentials = DEFAULT_DATABASE_CREDENTIALS; - this.scoreboardHeader = DEFAULT_SCOREBOARD_HEADER; - this.skinCacheThreads = DEFAULT_SKIN_CACHE_THREADS; - this.chunkLoadingStatistics = DEFAULT_CHUNK_LOADING_STATISTICS; - this.chunkLoadingThreads = DEFAULT_CHUNK_LOADING_THREADS; - } + @Override + public void reset() { + super.reset(); + this.databaseCredentials = DEFAULT_DATABASE_CREDENTIALS; + this.scoreboardHeader = DEFAULT_SCOREBOARD_HEADER; + this.skinCacheThreads = DEFAULT_SKIN_CACHE_THREADS; + this.chunkLoadingStatistics = DEFAULT_CHUNK_LOADING_STATISTICS; + this.chunkLoadingThreads = DEFAULT_CHUNK_LOADING_THREADS; + } - public DatabaseCredentials getDatabaseCredentials() { - return databaseCredentials; - } + public DatabaseCredentials getDatabaseCredentials() { + return databaseCredentials; + } - public String getScoreboardHeader() { - return scoreboardHeader; - } + public String getScoreboardHeader() { + return scoreboardHeader; + } - public int getSkinCacheThreads() { - return skinCacheThreads; - } + public int getSkinCacheThreads() { + return skinCacheThreads; + } - public boolean getChunkLoadingStatistics() { - return this.chunkLoadingStatistics; - } + public boolean getChunkLoadingStatistics() { + return this.chunkLoadingStatistics; + } - public int getChunkLoadingThreads() { - return this.chunkLoadingThreads; - } + public int getChunkLoadingThreads() { + return this.chunkLoadingThreads; + } } diff --git a/plugins/civmodcore-paper/src/main/java/vg/civcraft/mc/civmodcore/CivModCorePlugin.java b/plugins/civmodcore-paper/src/main/java/vg/civcraft/mc/civmodcore/CivModCorePlugin.java index a003e37bb..1cacbad92 100644 --- a/plugins/civmodcore-paper/src/main/java/vg/civcraft/mc/civmodcore/CivModCorePlugin.java +++ b/plugins/civmodcore-paper/src/main/java/vg/civcraft/mc/civmodcore/CivModCorePlugin.java @@ -34,135 +34,136 @@ import vg.civcraft.mc.civmodcore.world.locations.global.WorldIDManager; public class CivModCorePlugin extends ACivMod { - /** Primary constructor used by the real server */ - public CivModCorePlugin() { - super(); - } + /** + * Primary constructor used by the real server + */ + public CivModCorePlugin() { + super(); + } - /** Secondary constructor used for testing */ - protected CivModCorePlugin(JavaPluginLoader loader, PluginDescriptionFile description, File dataFolder, File file) { - super(loader, description, dataFolder, file); - } + /** + * Secondary constructor used for testing + */ + protected CivModCorePlugin(JavaPluginLoader loader, PluginDescriptionFile description, File dataFolder, File file) { + super(loader, description, dataFolder, file); + } - private static CivModCorePlugin instance; + private static CivModCorePlugin instance; - private CivModCoreConfig config; - private GlobalChunkMetaManager chunkMetaManager; - private ManagedDatasource database; - private WorldIDManager worldIdManager; - private CommandManager commands; - private SkinCache skinCache; + private CivModCoreConfig config; + private GlobalChunkMetaManager chunkMetaManager; + private ManagedDatasource database; + private WorldIDManager worldIdManager; + private CommandManager commands; + private SkinCache skinCache; - @Override - public void onEnable() { - instance = this; - registerConfigClass(DatabaseCredentials.class); - // Save default resources - saveDefaultResource("enchants.yml"); - super.onEnable(); - // Load Config - this.config = new CivModCoreConfig(this); - this.config.parse(); - // Load Database - try { - this.database = ManagedDatasource.construct(this, this.config.getDatabaseCredentials()); - if (this.database != null) { - final var dao = new CMCWorldDAO(this.database, this); - if (dao.updateDatabase()) { - this.worldIdManager = new WorldIDManager(dao); - this.chunkMetaManager = new GlobalChunkMetaManager(dao, this.worldIdManager, this.config.getChunkLoadingThreads()); - info("Setup database successfully"); - } - else { - warning("Could not setup database"); - } - } - } - catch (final Throwable error) { - warning("Cannot get database from config.", error); - this.database = null; - } - ScoreBoardAPI.setDefaultHeader(this.config.getScoreboardHeader()); - // Register listeners - registerListener(new ClickableInventoryListener()); - registerListener(DialogManager.INSTANCE); - registerListener(new ScoreBoardListener()); - registerListener(new WorldTracker()); - registerListener(new PlayerNames()); - // Register commands - this.commands = new CommandManager(this); - this.commands.init(); - this.commands.registerCommand(new ConfigCommand()); - this.commands.registerCommand(new StatCommand()); - this.commands.registerCommand(new ChunkMetaCommand()); - // Load APIs - EnchantUtils.loadEnchantAbbreviations(this); - MoreTags.init(); - SpawnEggUtils.init(); - TreeTypeUtils.init(); - BottomLineAPI.init(); - this.skinCache = new SkinCache(this, this.config.getSkinCacheThreads()); + @Override + public void onEnable() { + instance = this; + registerConfigClass(DatabaseCredentials.class); + // Save default resources + saveDefaultResource("enchants.yml"); + super.onEnable(); + // Load Config + this.config = new CivModCoreConfig(this); + this.config.parse(); + // Load Database + try { + this.database = ManagedDatasource.construct(this, this.config.getDatabaseCredentials()); + if (this.database != null) { + final var dao = new CMCWorldDAO(this.database, this); + if (dao.updateDatabase()) { + this.worldIdManager = new WorldIDManager(dao); + this.chunkMetaManager = new GlobalChunkMetaManager(dao, this.worldIdManager, this.config.getChunkLoadingThreads()); + info("Setup database successfully"); + } else { + warning("Could not setup database"); + } + } + } catch (final Throwable error) { + warning("Cannot get database from config.", error); + this.database = null; + } + ScoreBoardAPI.setDefaultHeader(this.config.getScoreboardHeader()); + // Register listeners + registerListener(new ClickableInventoryListener()); + registerListener(DialogManager.INSTANCE); + registerListener(new ScoreBoardListener()); + registerListener(new WorldTracker()); + registerListener(new PlayerNames()); + // Register commands + this.commands = new CommandManager(this); + this.commands.init(); + this.commands.registerCommand(new ConfigCommand()); + this.commands.registerCommand(new StatCommand()); + this.commands.registerCommand(new ChunkMetaCommand()); + // Load APIs + EnchantUtils.loadEnchantAbbreviations(this); + MoreTags.init(); + SpawnEggUtils.init(); + TreeTypeUtils.init(); + BottomLineAPI.init(); + this.skinCache = new SkinCache(this, this.config.getSkinCacheThreads()); - if (this.config.getChunkLoadingStatistics()) - LoadStatisticManager.enable(); - } + if (this.config.getChunkLoadingStatistics()) + LoadStatisticManager.enable(); + } - @Override - public void onDisable() { - Bukkit.getOnlinePlayers().forEach(HumanEntity::closeInventory); - ChunkMetaAPI.saveAll(); - this.chunkMetaManager.disableWorlds(); - this.chunkMetaManager = null; - // Disconnect database - if (this.database != null) { - try { - this.database.close(); - } - catch (SQLException error) { - warning("Was unable to close the database.", error); - } - this.database = null; - } - DialogManager.resetDialogs(); - WorldTracker.reset(); - PlayerSettingAPI.saveAll(); - ConfigurationSerialization.unregisterClass(DatabaseCredentials.class); - if (this.commands != null) { - this.commands.reset(); - this.commands = null; - } - if (this.skinCache != null) { - this.skinCache.shutdown(); - this.skinCache = null; - } + @Override + public void onDisable() { + Bukkit.getOnlinePlayers().forEach(HumanEntity::closeInventory); + ChunkMetaAPI.saveAll(); + this.chunkMetaManager.disableWorlds(); + this.chunkMetaManager = null; + // Disconnect database + if (this.database != null) { + try { + this.database.close(); + } catch (SQLException error) { + warning("Was unable to close the database.", error); + } + this.database = null; + } + DialogManager.resetDialogs(); + WorldTracker.reset(); + PlayerSettingAPI.saveAll(); + ConfigurationSerialization.unregisterClass(DatabaseCredentials.class); + if (this.commands != null) { + this.commands.reset(); + this.commands = null; + } + if (this.skinCache != null) { + this.skinCache.shutdown(); + this.skinCache = null; + } - LoadStatisticManager.disable(); + LoadStatisticManager.disable(); - if (this.config != null) { - this.config.reset(); - this.config = null; - } - super.onDisable(); - } + if (this.config != null) { + this.config.reset(); + this.config = null; + } + super.onDisable(); + } - public static CivModCorePlugin getInstance() { - return instance; - } - - public GlobalChunkMetaManager getChunkMetaManager() { - return this.chunkMetaManager; - } - - public WorldIDManager getWorldIdManager() { - return this.worldIdManager; - } - - public ManagedDatasource getDatabase() { - return this.database; - } + public static CivModCorePlugin getInstance() { + return instance; + } - public SkinCache getSkinCache() { - return this.skinCache; - } + public GlobalChunkMetaManager getChunkMetaManager() { + return this.chunkMetaManager; + } + + public WorldIDManager getWorldIdManager() { + return this.worldIdManager; + } + + public ManagedDatasource getDatabase() { + return this.database; + } + + public SkinCache getSkinCache() { + return this.skinCache; + } } diff --git a/plugins/civmodcore-paper/src/main/java/vg/civcraft/mc/civmodcore/chat/ChatUtils.java b/plugins/civmodcore-paper/src/main/java/vg/civcraft/mc/civmodcore/chat/ChatUtils.java index a308a398a..a8fafa098 100644 --- a/plugins/civmodcore-paper/src/main/java/vg/civcraft/mc/civmodcore/chat/ChatUtils.java +++ b/plugins/civmodcore-paper/src/main/java/vg/civcraft/mc/civmodcore/chat/ChatUtils.java @@ -27,380 +27,377 @@ import vg.civcraft.mc.civmodcore.inventory.items.ItemUtils; public final class ChatUtils { - /** - * This is necessary as {@link ChatColor#values()} has all colours and all formats. - * - * @deprecated Use {@link NamedTextColor} instead. - */ - @Deprecated - public static final List COLOURS = List.of( - 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); + /** + * This is necessary as {@link ChatColor#values()} has all colours and all formats. + * + * @deprecated Use {@link NamedTextColor} instead. + */ + @Deprecated + public static final List COLOURS = List.of( + 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); - /** - * Converts an RGB value into a Bungee ChatColor. - * - * @param r The red value. - * @param g The green value. - * @param b The blue value. - * @return Returns a valid Bungee ChatColor. - * - * @deprecated Use {@link net.kyori.adventure.text.format.TextColor#color(int, int, int)} instead. - */ - @Nonnull - @Deprecated - public static ChatColor fromRGB(final byte r, final byte g, final byte b) { - return ChatColor.of(new Color(r, g, b)); - } + /** + * Converts an RGB value into a Bungee ChatColor. + * + * @param r The red value. + * @param g The green value. + * @param b The blue value. + * @return Returns a valid Bungee ChatColor. + * @deprecated Use {@link net.kyori.adventure.text.format.TextColor#color(int, int, int)} instead. + */ + @Nonnull + @Deprecated + public static ChatColor fromRGB(final byte r, final byte g, final byte b) { + return ChatColor.of(new Color(r, g, b)); + } - /** - * Attempts to collapse an RGB colour to established Minecraft colours. - * - * @param colour The given RGB colour. - * @return Returns the closest Minecraft match, or null. - */ - @Contract("!null -> !null") - @Nullable - public static ChatColor collapseColour(@Nullable final ChatColor colour) { - if (colour == null) { - return null; - } - final Color color = colour.getColor(); - ChatColor nearestColour = null; - double nearestDistance = Double.MAX_VALUE; - for (final ChatColor currentColour : COLOURS) { - final Color currentColor = currentColour.getColor(); - final double distance = Math.sqrt( - Math.pow(color.getRed() - currentColor.getRed(), 2) - - Math.pow(color.getGreen() - currentColor.getGreen(), 2) - - Math.pow(color.getBlue() - currentColor.getBlue(), 2)); - if (nearestDistance > distance) { - nearestDistance = distance; - nearestColour = currentColour; - } - } - return nearestColour; - } + /** + * Attempts to collapse an RGB colour to established Minecraft colours. + * + * @param colour The given RGB colour. + * @return Returns the closest Minecraft match, or null. + */ + @Contract("!null -> !null") + @Nullable + public static ChatColor collapseColour(@Nullable final ChatColor colour) { + if (colour == null) { + return null; + } + final Color color = colour.getColor(); + ChatColor nearestColour = null; + double nearestDistance = Double.MAX_VALUE; + for (final ChatColor currentColour : COLOURS) { + final Color currentColor = currentColour.getColor(); + final double distance = Math.sqrt( + Math.pow(color.getRed() - currentColor.getRed(), 2) + - Math.pow(color.getGreen() - currentColor.getGreen(), 2) + - Math.pow(color.getBlue() - currentColor.getBlue(), 2)); + if (nearestDistance > distance) { + nearestDistance = distance; + nearestColour = currentColour; + } + } + return nearestColour; + } - // -------------------------------------------- // - // Color parsing - // -------------------------------------------- // + // -------------------------------------------- // + // Color parsing + // -------------------------------------------- // - /** - * @deprecated Please use MiniMessage instead. - * Read More. - */ - @Nonnull - @Deprecated - public static String parseColor(@Nonnull String string) { - string = parseColorAmp(string); - string = parseColorAcc(string); - string = parseColorTags(string); - return string; - } + /** + * @deprecated Please use MiniMessage instead. + * Read More. + */ + @Nonnull + @Deprecated + public static String parseColor(@Nonnull String string) { + string = parseColorAmp(string); + string = parseColorAcc(string); + string = parseColorTags(string); + return string; + } - /** - * @deprecated Please use MiniMessage instead. - * Read More. - */ - @Nonnull - @Deprecated - public static String parseColorAmp(@Nonnull String string) { - string = string.replace("&&", "&"); - return ChatColor.translateAlternateColorCodes('&', string); - } + /** + * @deprecated Please use MiniMessage instead. + * Read More. + */ + @Nonnull + @Deprecated + public static String parseColorAmp(@Nonnull String string) { + string = string.replace("&&", "&"); + return ChatColor.translateAlternateColorCodes('&', string); + } - /** - * @deprecated Please use MiniMessage instead. - * Read More. - */ - @Nonnull - @Deprecated - public static String parseColorAcc(@Nonnull String string) { - return ChatColor.translateAlternateColorCodes('`', string); - } + /** + * @deprecated Please use MiniMessage instead. + * Read More. + */ + @Nonnull + @Deprecated + public static String parseColorAcc(@Nonnull String string) { + return ChatColor.translateAlternateColorCodes('`', string); + } - /** - * @deprecated Please use MiniMessage instead. - * Read More. - */ - @Nonnull - @Deprecated - public static String parseColorTags(@Nonnull String string) { - return string - .replace("", ChatColor.BLACK.toString()) - .replace("", ChatColor.DARK_BLUE.toString()) - .replace("", ChatColor.DARK_GREEN.toString()) - .replace("", ChatColor.DARK_AQUA.toString()) - .replace("", ChatColor.DARK_RED.toString()) - .replace("", ChatColor.DARK_PURPLE.toString()) - .replace("", ChatColor.GOLD.toString()) - .replace("", ChatColor.GRAY.toString()) // This has to be lgray because gray is already claimed. - .replace("", ChatColor.DARK_GRAY.toString()) - .replace("", ChatColor.BLUE.toString()) - .replace("", ChatColor.GREEN.toString()) - .replace("", ChatColor.AQUA.toString()) - .replace("", ChatColor.RED.toString()) - .replace("", ChatColor.LIGHT_PURPLE.toString()) - .replace("", ChatColor.YELLOW.toString()) - .replace("", ChatColor.WHITE.toString()) - .replace("", ChatColor.STRIKETHROUGH.toString()) - .replace("", ChatColor.UNDERLINE.toString()) - .replace("