From 5fb06c3753ef0ad532f49a82899968e872110dbb Mon Sep 17 00:00:00 2001 From: Trav Date: Thu, 12 Dec 2024 00:33:39 -0700 Subject: [PATCH] Modularize Codex (#39) * Modularize Codex for easier updates * Reorganize some other stuff * Get javadocs aggregating properly * Add Nexo support in new code * Code cleanup * Add setKiller to NMSProvider for Fabled * Add 1.21.4 * Remove VersionManager in favor of everything located in NMSProvider Add some other NMS methods to get Divinity and Fabled building * Slight organization tweaks * Split bungee into separate module * Oops * Ignore build directories * Fix some NMS-related issues * Move armor trims to version specific classes * Move other methods to NMS * Create EntityDamageByEntity via version-specific invocations * For testing, we can't actually compile against 1.16... This will be fun * More cleanup * Add some Attribute stuff to compatibility layers * De-Reflection InventoryUtil * Move event interfaces and event definitions to -api * Move other enums/interfaces to -api * Centralize fix/remove colors * Clean up * Fix testing issues * Work out a couple of kinks * Update nexo * Update nexo * Update version updating script * Update workflows * Can I use sdkman to run build tools? * Maybe this will work * More info * More info * Rearrange * Let's build spigot for release builds only * Don't update the nms version automatically --- .github/notify_published.py | 10 +- .github/update_version.py | 42 +- .github/workflows/devbuild.yml | 5 +- .github/workflows/maven.yml | 14 +- .github/workflows/release.yml | 35 +- .gitignore | 4 +- README.md | 14 +- .../resources/temp.yml => codex-api/.module | 0 codex-api/pom.xml | 108 ++++ .../java/studio/magemonkey/codex/Codex.java | 33 ++ .../magemonkey/codex/api/CommandType.java | 0 .../magemonkey/codex/api/DelayedCommand.java | 0 .../studio/magemonkey/codex/api/Replacer.java | 0 .../codex/api/armor/ArmorEquipEvent.java | 0 .../magemonkey/codex/api/armor/ArmorType.java | 15 +- .../codex/api}/events/EnginePacketEvent.java | 3 +- .../api}/events/EnginePlayerPacketEvent.java | 2 +- .../api}/events/EngineServerPacketEvent.java | 2 +- .../codex/api/events}/ICancellableEvent.java | 2 +- .../magemonkey/codex/api/events}/IEvent.java | 2 +- .../UnsupportedVersionException.java | 11 + .../magemonkey/codex/api}/items/ItemType.java | 6 +- .../codex/api/items/PrefixHelper.java | 15 + .../items/exception/CodexItemException.java | 4 +- .../items/exception/MissingItemException.java | 2 +- .../exception/MissingProviderException.java | 2 +- .../items/providers/ICodexItemProvider.java | 6 +- .../items/providers/ItemsAdderProvider.java | 10 +- .../api}/items/providers/NexoProvider.java | 10 +- .../api}/items/providers/OraxenProvider.java | 10 +- .../api}/items/providers/VanillaProvider.java | 10 +- .../codex/api/meta/NBTAttribute.java | 15 +- .../magemonkey/codex/compat/ArmorUtil.java | 18 + .../magemonkey/codex/compat/Compat.java | 14 + .../studio/magemonkey/codex/compat/NMS.java | 285 ++++++++++ .../codex/compat/VersionManager.java | 79 +++ .../codex/config/ResourceExtractor.java | 39 +- .../studio/magemonkey/codex/core/Version.java | 4 +- .../magemonkey/codex/hooks/HookState.java | 1 - .../placeholder/ArgPlaceholderData.java | 0 .../placeholder/BasePlaceholderData.java | 0 .../placeholder/BasePlaceholderItem.java | 2 +- .../placeholder/GlobalPlaceholderItem.java | 2 +- .../legacy/placeholder/PlaceholderData.java | 0 .../legacy/placeholder/PlaceholderItem.java | 0 .../placeholder/PlaceholderRegistry.java | 10 +- .../legacy/placeholder/PlaceholderType.java | 0 .../codex/legacy/utils/ChatColorUtils.java | 10 +- .../codex/legacy/utils/ComponentUtils.java | 0 .../codex/manager/AbstractListener.java | 4 +- .../magemonkey/codex/manager/IListener.java | 7 +- .../magemonkey/codex/manager/IManager.java | 5 +- .../codex/manager/api/Cleanable.java | 3 +- .../codex/manager/api}/ClickType.java | 3 +- .../codex/manager/api/Loadable.java | 3 +- .../codex/manager/api/Loggable.java | 11 + .../codex/manager/api}/MobGroup.java | 2 +- .../codex/manager/api/gui/ContentType.java | 1 - .../codex/manager/api/gui/GuiClick.java | 1 - .../codex/manager/api/gui/JIcon.java | 5 +- .../manager/api/menu/FileExplorerMenu.java | 0 .../codex/manager/api/menu/Menu.java | 26 +- .../codex/manager/api/menu/MenuManager.java | 8 +- .../codex/manager/api/menu/Slot.java | 4 +- .../codex/manager/api/menu/YAMLListMenu.java | 0 .../codex/manager/api/menu/YAMLMenu.java | 4 +- .../registry/attribute/AttributeProvider.java | 0 .../registry/attribute/AttributeRegistry.java | 6 +- .../codex/registry/damage/DamageRegistry.java | 7 +- .../registry/damage/DamageTypeProvider.java | 0 .../magemonkey/codex/util/ClickText.java | 49 +- .../magemonkey/codex/util/CollectionsUT.java | 20 +- .../studio/magemonkey/codex/util/DataUT.java | 0 .../magemonkey/codex/util/Debugger.java | 0 .../codex/util/DeserializationWorker.java | 0 .../magemonkey/codex/util/EffectUT.java | 0 .../magemonkey/codex/util/EntityUT.java | 38 ++ .../studio/magemonkey/codex/util/EnumUT.java | 0 .../studio/magemonkey/codex/util/FileUT.java | 0 .../magemonkey/codex/util/InventoryUtil.java | 129 +++++ .../studio/magemonkey/codex/util/LocUT.java | 40 +- .../studio/magemonkey/codex/util/MsgUT.java | 3 - .../magemonkey/codex/util/NumberUT.java | 0 .../magemonkey/codex/util/PlayerUT.java | 5 +- .../magemonkey/codex/util/RangeUtil.java | 0 .../studio/magemonkey/codex/util/Reflex.java | 16 +- .../codex/util/SerializationBuilder.java | 0 .../studio/magemonkey/codex/util/SoundUT.java | 5 +- .../magemonkey/codex/util/StringUT.java | 15 +- .../studio/magemonkey/codex/util/Zipper.java | 6 +- .../codex/util/constants/ItemHelper.java | 12 + .../codex/util/constants/JNumbers.java | 0 .../codex/util/constants/JStrings.java | 0 .../codex/util/craft/CraftManager.java | 18 +- .../codex/util/craft/api/IAbstractRecipe.java | 10 +- .../codex/util/craft/api/ICraftRecipe.java | 40 +- .../codex/util/craft/api/IFurnaceRecipe.java | 32 +- .../magemonkey/codex/util/eval/Evaluator.java | 16 +- .../eval/javaluator/AbstractEvaluator.java | 1 - .../eval/javaluator/AbstractVariableSet.java | 0 .../util/eval/javaluator/BracketPair.java | 0 .../codex/util/eval/javaluator/Constant.java | 0 .../util/eval/javaluator/DoubleEvaluator.java | 0 .../eval/javaluator/EvaluationContext.java | 0 .../codex/util/eval/javaluator/Function.java | 0 .../codex/util/eval/javaluator/Operator.java | 0 .../util/eval/javaluator/Parameters.java | 0 .../eval/javaluator/StaticVariableSet.java | 0 .../codex/util/eval/javaluator/Token.java | 0 .../codex/util/eval/javaluator/Tokenizer.java | 0 .../util/messages/AbstractMessageUtil.java | 88 +++ .../codex/util/messages/MessageData.java | 0 .../codex/util/random/MTRandom.java | 0 .../magemonkey/codex/util/random/Rnd.java | 0 .../magemonkey/codex/api/ReplacerTest.java | 34 ++ codex-bungee/pom.xml | 20 + .../magemonkey/codex/bungee/BungeeCore.java | 0 .../codex/bungee/BungeeListener.java | 0 .../magemonkey/codex/bungee/BungeeUtil.java | 31 +- .../src}/main/resources/bungee.yml | 0 codex-core/.module | 0 codex-core/pom.xml | 84 +++ .../codex/migration/MigrationUtil.java | 11 +- .../codex/util/NamespaceResolver.java | 20 +- codex-nms/codex-nms-v1_16_5/pom.xml | 28 + .../codex/nms/v1_16_5/CompatImpl.java | 17 + .../magemonkey/codex/nms/v1_16_5/NMSImpl.java | 184 ++++++ codex-nms/codex-nms-v1_17_1/pom.xml | 28 + .../codex/nms/v1_17/CompatImpl.java | 17 + .../magemonkey/codex/nms/v1_17/NMSImpl.java | 194 +++++++ codex-nms/codex-nms-v1_18_2/pom.xml | 28 + .../codex/nms/v1_18_2/CompatImpl.java | 17 + .../magemonkey/codex/nms/v1_18_2/NMSImpl.java | 274 +++++++++ codex-nms/codex-nms-v1_19_4/pom.xml | 28 + .../codex/nms/v1_19_4/ArmorUtilImpl.java | 72 +++ .../codex/nms/v1_19_4/CompatImpl.java | 17 + .../magemonkey/codex/nms/v1_19_4/NMSImpl.java | 315 ++++++++++ codex-nms/codex-nms-v1_20_2/pom.xml | 28 + .../codex/nms/v1_20_2/ArmorUtilImpl.java | 72 +++ .../codex/nms/v1_20_2/CompatImpl.java | 17 + .../magemonkey/codex/nms/v1_20_2/NMSImpl.java | 316 +++++++++++ codex-nms/codex-nms-v1_20_4/pom.xml | 28 + .../codex/nms/v1_20_4/ArmorUtilImpl.java | 72 +++ .../codex/nms/v1_20_4/CompatImpl.java | 17 + .../magemonkey/codex/nms/v1_20_4/NMSImpl.java | 330 +++++++++++ codex-nms/codex-nms-v1_20_6/pom.xml | 28 + .../codex/nms/v1_20_6/ArmorUtilImpl.java | 72 +++ .../codex/nms/v1_20_6/CompatImpl.java | 17 + .../magemonkey/codex/nms/v1_20_6/NMSImpl.java | 337 +++++++++++ codex-nms/codex-nms-v1_21_1/pom.xml | 28 + .../codex/nms/v1_21_1/ArmorUtilImpl.java | 72 +++ .../codex/nms/v1_21_1/CompatImpl.java | 19 + .../magemonkey/codex/nms/v1_21_1/NMSImpl.java | 337 +++++++++++ codex-nms/codex-nms-v1_21_2/pom.xml | 28 + .../codex/nms/v1_21_2/ArmorUtilImpl.java | 72 +++ .../codex/nms/v1_21_2/CompatImpl.java | 19 + .../magemonkey/codex/nms/v1_21_2/NMSImpl.java | 342 +++++++++++ codex-nms/codex-nms-v1_21_4/pom.xml | 28 + .../codex/nms/v1_21_4/ArmorUtilImpl.java | 72 +++ .../codex/nms/v1_21_4/CompatImpl.java | 19 + .../magemonkey/codex/nms/v1_21_4/NMSImpl.java | 342 +++++++++++ codex-nms/pom.xml | 35 ++ codex-plugin/.module | 0 codex-plugin/pom.xml | 63 ++ .../magemonkey/codex/CodexDataPlugin.java | 0 .../studio/magemonkey/codex/CodexEngine.java | 79 +-- .../studio/magemonkey/codex/CodexPlugin.java | 13 +- .../codex/action}/CommandBlock.java | 7 +- .../codex/commands/CommandManager.java | 0 .../codex/commands/CommandRegister.java | 0 .../codex/commands/UnstuckCommand.java | 44 +- .../codex/commands/api/IAbstractCommand.java | 4 +- .../codex/commands/api/IGeneralCommand.java | 0 .../codex/commands/api/ISubCommand.java | 0 .../codex/commands/list/AboutCommand.java | 0 .../codex/commands/list/EditorCommand.java | 2 +- .../codex/commands/list/HelpCommand.java | 0 .../codex/commands/list/MainCommand.java | 2 +- .../codex/commands/list/ReloadCommand.java | 0 .../codex/config/ConfigManager.java | 0 .../codex/config/api/IConfigTemplate.java | 1 - .../magemonkey/codex/config/api/ILangMsg.java | 0 .../codex/config/api/ILangTemplate.java | 1 - .../magemonkey/codex/config/api/JYML.java | 2 +- .../config/legacy/LegacyConfigManager.java | 0 .../codex/core/config/CoreConfig.java | 0 .../codex/core/config/CoreLang.java | 2 +- .../magemonkey/codex/data/DataTypes.java | 0 .../magemonkey/codex/data/IDataHandler.java | 0 .../magemonkey/codex/data/StorageType.java | 0 .../data/event/EngineUserCreatedEvent.java | 0 .../codex/data/event/EngineUserEvent.java | 2 +- .../codex/data/event/EngineUserLoadEvent.java | 0 .../data/event/EngineUserUnloadEvent.java | 0 .../codex/data/users/IAbstractUser.java | 0 .../codex/data/users/IUserManager.java | 29 +- .../magemonkey/codex/hooks/HookManager.java | 10 +- .../studio/magemonkey/codex/hooks/Hooks.java | 0 .../studio/magemonkey/codex/hooks/NHook.java | 0 .../codex/hooks/external/IMythicHook.java | 0 .../codex/hooks/external/MythicMobsHK.java | 0 .../codex/hooks/external/MythicMobsHKv5.java | 0 .../codex/hooks/external/VaultHK.java | 0 .../codex/hooks/external/WorldGuardHK.java | 0 .../hooks/external/citizens/CitizensHK.java | 1 - .../external/citizens/CitizensListener.java | 0 .../codex/items/CodexItemManager.java | 19 +- .../magemonkey/codex/legacy/RisePlugin.java | 12 +- .../codex/legacy/command/RiseCommand.java | 3 +- .../codex/legacy/item/BlockColors.java | 0 .../codex/legacy/item/BookDataBuilder.java | 14 +- .../codex/legacy/item/DataBuilder.java | 0 .../item/EnchantmentStorageBuilder.java | 0 .../codex/legacy/item/FireworkBuilder.java | 0 .../legacy/item/FireworkEffectBuilder.java | 0 .../codex/legacy/item/ItemBuilder.java | 6 +- .../codex/legacy/item/ItemColors.java | 0 .../legacy/item/LeatherArmorBuilder.java | 0 .../codex/legacy/item/MapBuilder.java | 0 .../codex/legacy/item/PotionDataBuilder.java | 0 .../codex/legacy/item/SkullBuilder.java | 6 +- .../codex/legacy/item/SkullType.java | 0 .../codex/legacy/riseitem/DarkRiseItem.java | 0 .../legacy/riseitem/DarkRiseItemImpl.java | 0 .../codex/legacy/utils/ItemComparator.java | 0 .../codex/legacy/utils/ReflectionUtil.java | 0 .../codex/legacy/utils/SimpleMap.java | 0 .../magemonkey/codex/legacy/utils/Utils.java | 56 +- .../serializers/BaseComponentSerializer.java | 0 .../serializers/ComponentSerializer.java | 0 .../serializers/TextComponentSerializer.java | 0 .../TranslatableComponentSerializer.java | 0 .../codex/listeners}/ArmorListener.java | 30 +- .../codex/listeners/BoatListener.java | 28 + .../codex/listeners/InteractListener.java | 2 +- .../codex/listeners/JoinListener.java | 0 .../codex/manager/LoadableItem.java | 0 .../codex/manager/api/Editable.java | 1 - .../codex/manager/api/IActionEditable.java | 1 - .../codex/manager/api/Saveable.java | 3 +- .../codex/manager/api/gui/GuiItem.java | 21 +- .../codex/manager/api/gui/NGUI.java | 10 +- .../codex/manager/api/task/ITask.java | 0 .../manager/editor/EditorActionsHandler.java | 0 .../codex/manager/editor/EditorHandler.java | 0 .../codex/manager/editor/EditorManager.java | 0 .../codex/manager/editor/EditorType.java | 0 .../editor/object/IEditorActionsMain.java | 2 +- .../object/IEditorActionsParametized.java | 0 .../editor/object/IEditorActionsParams.java | 2 +- .../editor/object/IEditorActionsSection.java | 0 .../magemonkey/codex/mccore/chat/Chat.java | 0 .../codex/mccore/chat/ChatCommander.java | 0 .../codex/mccore/chat/ChatData.java | 0 .../codex/mccore/chat/ChatListener.java | 0 .../codex/mccore/chat/ChatNodes.java | 0 .../codex/mccore/chat/ListCommand.java | 0 .../codex/mccore/chat/NameCommand.java | 0 .../magemonkey/codex/mccore/chat/Prefix.java | 0 .../codex/mccore/chat/PrefixCommand.java | 0 .../codex/mccore/chat/ResetCommand.java | 0 .../codex/mccore/commands/CommandHandler.java | 0 .../mccore/commands/CommandListener.java | 0 .../codex/mccore/commands/CommandManager.java | 0 .../mccore/commands/ConfigurableCommand.java | 0 .../codex/mccore/commands/ICommand.java | 0 .../codex/mccore/commands/IFunction.java | 0 .../codex/mccore/commands/LogFunction.java | 0 .../codex/mccore/commands/SenderType.java | 0 .../codex/mccore/config/CommentedConfig.java | 0 .../config/CommentedLanguageConfig.java | 0 .../codex/mccore/config/Config.java | 0 .../codex/mccore/config/ConfigSerializer.java | 0 .../codex/mccore/config/CustomFilter.java | 0 .../codex/mccore/config/DataFile.java | 0 .../codex/mccore/config/ExcludeField.java | 0 .../codex/mccore/config/Filter.java | 0 .../codex/mccore/config/FilterType.java | 0 .../codex/mccore/config/ISavable.java | 0 .../codex/mccore/config/LanguageConfig.java | 0 .../codex/mccore/config/LocationData.java | 0 .../codex/mccore/config/Resources.java | 0 .../mccore/config/SerializableField.java | 0 .../codex/mccore/config/parse/DataArray.java | 0 .../mccore/config/parse/DataSection.java | 0 .../codex/mccore/config/parse/JSONParser.java | 0 .../mccore/config/parse/NumberParser.java | 0 .../codex/mccore/config/parse/YAMLParser.java | 0 .../codex/mccore/gui/MapBuffer.java | 0 .../magemonkey/codex/mccore/gui/MapData.java | 0 .../magemonkey/codex/mccore/gui/MapFont.java | 0 .../magemonkey/codex/mccore/gui/MapImage.java | 0 .../codex/mccore/gui/MapImageManager.java | 0 .../codex/mccore/gui/MapListener.java | 0 .../magemonkey/codex/mccore/gui/MapMenu.java | 0 .../codex/mccore/gui/MapMenuManager.java | 0 .../codex/mccore/gui/MapObject.java | 0 .../magemonkey/codex/mccore/gui/MapScene.java | 0 .../codex/mccore/gui/MapScheme.java | 0 .../codex/mccore/gui/MapString.java | 0 .../codex/mccore/items/InventoryManager.java | 0 .../codex/mccore/items/ItemManager.java | 0 .../codex/mccore/scoreboard/Board.java | 0 .../mccore/scoreboard/BoardListener.java | 0 .../codex/mccore/scoreboard/BoardManager.java | 11 +- .../codex/mccore/scoreboard/CycleCommand.java | 0 .../codex/mccore/scoreboard/CycleTask.java | 0 .../codex/mccore/scoreboard/ListCommand.java | 0 .../codex/mccore/scoreboard/PlayerBoards.java | 0 .../scoreboard/ScoreboardCommander.java | 0 .../mccore/scoreboard/ScoreboardNodes.java | 0 .../codex/mccore/scoreboard/ShowCommand.java | 0 .../codex/mccore/scoreboard/StatBoard.java | 0 .../codex/mccore/scoreboard/StatHolder.java | 0 .../codex/mccore/scoreboard/StopCommand.java | 0 .../codex/mccore/scoreboard/Team.java | 0 .../mccore/scoreboard/ToggleCommand.java | 0 .../codex/mccore/scoreboard/UpdateTask.java | 0 .../codex/mccore/sql/ColumnType.java | 0 .../mccore/sql/direct/ISQLEntryData.java | 0 .../codex/mccore/sql/direct/SQLDatabase.java | 0 .../codex/mccore/sql/direct/SQLEntry.java | 0 .../codex/mccore/sql/direct/SQLTable.java | 0 .../codex/mccore/util/MobManager.java | 0 .../codex/mccore/util/TextFormatter.java | 0 .../codex/mccore/util/TextSizer.java | 0 .../codex/mccore/util/TextSplitter.java | 0 .../codex/modules/IExternalModule.java | 0 .../magemonkey/codex/modules/IModule.java | 0 .../codex/modules/IModuleExecutor.java | 0 .../codex/modules/ModuleManager.java | 0 .../codex/nms/packets/IPacketHandler.java | 4 +- .../codex/nms/packets/PacketManager.java | 9 +- .../studio/magemonkey/codex/util/ItemUT.java | 50 +- .../magemonkey/codex/util/ItemUtils.java | 109 +--- .../studio/magemonkey/codex/util/TimeUT.java | 0 .../codex/util/actions/ActionCategory.java | 0 .../codex/util/actions/ActionManipulator.java | 0 .../codex/util/actions/ActionSection.java | 0 .../codex/util/actions/ActionsManager.java | 0 .../codex/util/actions/Parametized.java | 0 .../util/actions/actions/IActionExecutor.java | 4 +- .../util/actions/actions/IActionType.java | 0 .../actions/list/Action_ActionBar.java | 0 .../actions/list/Action_Broadcast.java | 0 .../actions/actions/list/Action_Burn.java | 0 .../actions/list/Action_CommandConsole.java | 0 .../actions/list/Action_CommandOp.java | 0 .../actions/list/Action_CommandPlayer.java | 0 .../actions/actions/list/Action_Damage.java | 0 .../actions/actions/list/Action_Firework.java | 0 .../actions/actions/list/Action_Goto.java | 0 .../actions/actions/list/Action_Health.java | 4 +- .../actions/actions/list/Action_Hook.java | 0 .../actions/actions/list/Action_Hunger.java | 0 .../actions/list/Action_Lightning.java | 0 .../actions/actions/list/Action_Message.java | 0 .../actions/list/Action_ParticleSimple.java | 0 .../actions/actions/list/Action_Potion.java | 0 .../actions/list/Action_ProgressBar.java | 0 .../actions/list/Action_Projectile.java | 0 .../actions/list/Action_Saturation.java | 0 .../actions/actions/list/Action_Sound.java | 0 .../actions/actions/list/Action_Teleport.java | 0 .../actions/actions/list/Action_Throw.java | 0 .../actions/actions/list/Action_Titles.java | 0 .../codex/util/actions/api/IActioned.java | 0 .../actions/conditions/IConditionType.java | 0 .../conditions/IConditionValidator.java | 0 .../list/Condition_EntityHealth.java | 4 +- .../conditions/list/Condition_EntityType.java | 0 .../conditions/list/Condition_Permission.java | 0 .../list/Condition_VaultBalance.java | 0 .../conditions/list/Condition_WorldTime.java | 0 .../util/actions/params/IAutoValidated.java | 0 .../codex/util/actions/params/IParam.java | 0 .../util/actions/params/IParamResult.java | 0 .../codex/util/actions/params/IParamType.java | 0 .../util/actions/params/IParamValue.java | 0 .../params/defaults/IParamBoolean.java | 0 .../actions/params/defaults/IParamNumber.java | 0 .../actions/params/defaults/IParamString.java | 0 .../actions/params/list/AllowSelfParam.java | 0 .../actions/params/list/AttackableParam.java | 0 .../actions/params/list/LocationParam.java | 0 .../util/actions/params/list/OffsetParam.java | 0 .../actions/params/parser/IParamParser.java | 0 .../params/parser/ParamBooleanParser.java | 0 .../params/parser/ParamNumberParser.java | 0 .../params/parser/ParamStringParser.java | 0 .../util/actions/targets/ITargetSelector.java | 0 .../util/actions/targets/ITargetType.java | 0 .../targets/list/Target_FromSight.java | 2 +- .../actions/targets/list/Target_Radius.java | 2 +- .../actions/targets/list/Target_Self.java | 2 +- .../codex/util/messages/MessageUtil.java | 128 +++++ .../src}/main/resources/config.yml | 0 .../main/resources/editor/actions_main.yml | 0 .../resources/editor/actions_parametized.yml | 0 .../main/resources/editor/actions_params.yml | 0 .../main/resources/editor/actions_section.yml | 0 .../src}/main/resources/lang/messages_cn.yml | 0 .../src}/main/resources/lang/messages_en.yml | 0 .../src}/main/resources/paper-plugin.yml | 0 .../src}/main/resources/plugin.yml | 0 codex-plugin/src/main/resources/temp.yml | 0 .../studio/magemonkey/codex/CommandTest.java | 0 .../mccore/config/parse/YAMLParserTest.java | 0 .../codex/testutil/DependencyResolver.java | 0 .../magemonkey/codex/testutil/MockedTest.java | 79 +-- .../testutil/reflection/TestChannel.java | 0 .../magemonkey/codex/util/LocUTTest.java | 0 .../src}/test/resources/fabled-config.yml | 0 .../src}/test/resources/log4j.xml | 0 doc/README.md | 14 +- pom.xml | 204 +++---- .../codex/listeners/BoatListener.java | 54 -- .../codex/manager/api/Loggable.java | 12 - .../java/studio/magemonkey/codex/nms/NMS.java | 69 --- .../magemonkey/codex/util/AttributeUT.java | 48 -- .../magemonkey/codex/util/EntityUT.java | 98 ---- .../magemonkey/codex/util/InventoryUtil.java | 155 ----- .../codex/util/messages/MessageUtil.java | 329 ----------- .../codex/util/messages/NMSPlayerUtils.java | 77 --- .../reflection/DefaultReflectionUtil.java | 467 --------------- .../util/reflection/ReflectionManager.java | 33 -- .../codex/util/reflection/ReflectionUtil.java | 229 -------- .../util/reflection/Reflection_1_17.java | 537 ------------------ .../util/reflection/Reflection_1_18.java | 73 --- .../util/reflection/Reflection_1_20.java | 80 --- .../reflection/TestReflectionUtil.java | 169 ------ 431 files changed, 5854 insertions(+), 3345 deletions(-) rename src/main/resources/temp.yml => codex-api/.module (100%) create mode 100644 codex-api/pom.xml create mode 100644 codex-api/src/main/java/studio/magemonkey/codex/Codex.java rename {src => codex-api/src}/main/java/studio/magemonkey/codex/api/CommandType.java (100%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/api/DelayedCommand.java (100%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/api/Replacer.java (100%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/api/armor/ArmorEquipEvent.java (100%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/api/armor/ArmorType.java (85%) rename {src/main/java/studio/magemonkey/codex/nms/packets => codex-api/src/main/java/studio/magemonkey/codex/api}/events/EnginePacketEvent.java (84%) rename {src/main/java/studio/magemonkey/codex/nms/packets => codex-api/src/main/java/studio/magemonkey/codex/api}/events/EnginePlayerPacketEvent.java (83%) rename {src/main/java/studio/magemonkey/codex/nms/packets => codex-api/src/main/java/studio/magemonkey/codex/api}/events/EngineServerPacketEvent.java (83%) rename {src/main/java/studio/magemonkey/codex/manager/api/event => codex-api/src/main/java/studio/magemonkey/codex/api/events}/ICancellableEvent.java (91%) rename {src/main/java/studio/magemonkey/codex/manager/api/event => codex-api/src/main/java/studio/magemonkey/codex/api/events}/IEvent.java (91%) create mode 100644 codex-api/src/main/java/studio/magemonkey/codex/api/exception/UnsupportedVersionException.java rename {src/main/java/studio/magemonkey/codex => codex-api/src/main/java/studio/magemonkey/codex/api}/items/ItemType.java (83%) create mode 100644 codex-api/src/main/java/studio/magemonkey/codex/api/items/PrefixHelper.java rename {src/main/java/studio/magemonkey/codex => codex-api/src/main/java/studio/magemonkey/codex/api}/items/exception/CodexItemException.java (76%) rename {src/main/java/studio/magemonkey/codex => codex-api/src/main/java/studio/magemonkey/codex/api}/items/exception/MissingItemException.java (73%) rename {src/main/java/studio/magemonkey/codex => codex-api/src/main/java/studio/magemonkey/codex/api}/items/exception/MissingProviderException.java (74%) rename {src/main/java/studio/magemonkey/codex => codex-api/src/main/java/studio/magemonkey/codex/api}/items/providers/ICodexItemProvider.java (89%) rename {src/main/java/studio/magemonkey/codex => codex-api/src/main/java/studio/magemonkey/codex/api}/items/providers/ItemsAdderProvider.java (90%) rename {src/main/java/studio/magemonkey/codex => codex-api/src/main/java/studio/magemonkey/codex/api}/items/providers/NexoProvider.java (89%) rename {src/main/java/studio/magemonkey/codex => codex-api/src/main/java/studio/magemonkey/codex/api}/items/providers/OraxenProvider.java (89%) rename {src/main/java/studio/magemonkey/codex => codex-api/src/main/java/studio/magemonkey/codex/api}/items/providers/VanillaProvider.java (85%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/api/meta/NBTAttribute.java (79%) create mode 100644 codex-api/src/main/java/studio/magemonkey/codex/compat/ArmorUtil.java create mode 100644 codex-api/src/main/java/studio/magemonkey/codex/compat/Compat.java create mode 100644 codex-api/src/main/java/studio/magemonkey/codex/compat/NMS.java create mode 100644 codex-api/src/main/java/studio/magemonkey/codex/compat/VersionManager.java rename {src => codex-api/src}/main/java/studio/magemonkey/codex/config/ResourceExtractor.java (80%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/core/Version.java (95%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/hooks/HookState.java (99%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/legacy/placeholder/ArgPlaceholderData.java (100%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/legacy/placeholder/BasePlaceholderData.java (100%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/legacy/placeholder/BasePlaceholderItem.java (99%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/legacy/placeholder/GlobalPlaceholderItem.java (99%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/legacy/placeholder/PlaceholderData.java (100%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/legacy/placeholder/PlaceholderItem.java (100%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/legacy/placeholder/PlaceholderRegistry.java (95%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/legacy/placeholder/PlaceholderType.java (100%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/legacy/utils/ChatColorUtils.java (92%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/legacy/utils/ComponentUtils.java (100%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/manager/AbstractListener.java (71%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/manager/IListener.java (55%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/manager/IManager.java (59%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/manager/api/Cleanable.java (74%) rename {src/main/java/studio/magemonkey/codex/manager/types => codex-api/src/main/java/studio/magemonkey/codex/manager/api}/ClickType.java (95%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/manager/api/Loadable.java (82%) create mode 100644 codex-api/src/main/java/studio/magemonkey/codex/manager/api/Loggable.java rename {src/main/java/studio/magemonkey/codex/manager/types => codex-api/src/main/java/studio/magemonkey/codex/manager/api}/MobGroup.java (93%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/manager/api/gui/ContentType.java (99%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/manager/api/gui/GuiClick.java (99%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/manager/api/gui/JIcon.java (95%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/manager/api/menu/FileExplorerMenu.java (100%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/manager/api/menu/Menu.java (94%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/manager/api/menu/MenuManager.java (94%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/manager/api/menu/Slot.java (92%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/manager/api/menu/YAMLListMenu.java (100%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/manager/api/menu/YAMLMenu.java (97%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/registry/attribute/AttributeProvider.java (100%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/registry/attribute/AttributeRegistry.java (86%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/registry/damage/DamageRegistry.java (88%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/registry/damage/DamageTypeProvider.java (100%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/util/ClickText.java (75%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/util/CollectionsUT.java (77%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/util/DataUT.java (100%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/util/Debugger.java (100%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/util/DeserializationWorker.java (100%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/util/EffectUT.java (100%) create mode 100644 codex-api/src/main/java/studio/magemonkey/codex/util/EntityUT.java rename {src => codex-api/src}/main/java/studio/magemonkey/codex/util/EnumUT.java (100%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/util/FileUT.java (100%) create mode 100644 codex-api/src/main/java/studio/magemonkey/codex/util/InventoryUtil.java rename {src => codex-api/src}/main/java/studio/magemonkey/codex/util/LocUT.java (78%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/util/MsgUT.java (98%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/util/NumberUT.java (100%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/util/PlayerUT.java (95%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/util/RangeUtil.java (100%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/util/Reflex.java (95%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/util/SerializationBuilder.java (100%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/util/SoundUT.java (76%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/util/StringUT.java (96%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/util/Zipper.java (94%) create mode 100644 codex-api/src/main/java/studio/magemonkey/codex/util/constants/ItemHelper.java rename {src => codex-api/src}/main/java/studio/magemonkey/codex/util/constants/JNumbers.java (100%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/util/constants/JStrings.java (100%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/util/craft/CraftManager.java (81%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/util/craft/api/IAbstractRecipe.java (81%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/util/craft/api/ICraftRecipe.java (73%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/util/craft/api/IFurnaceRecipe.java (79%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/util/eval/Evaluator.java (86%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/util/eval/javaluator/AbstractEvaluator.java (99%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/util/eval/javaluator/AbstractVariableSet.java (100%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/util/eval/javaluator/BracketPair.java (100%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/util/eval/javaluator/Constant.java (100%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/util/eval/javaluator/DoubleEvaluator.java (100%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/util/eval/javaluator/EvaluationContext.java (100%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/util/eval/javaluator/Function.java (100%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/util/eval/javaluator/Operator.java (100%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/util/eval/javaluator/Parameters.java (100%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/util/eval/javaluator/StaticVariableSet.java (100%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/util/eval/javaluator/Token.java (100%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/util/eval/javaluator/Tokenizer.java (100%) create mode 100644 codex-api/src/main/java/studio/magemonkey/codex/util/messages/AbstractMessageUtil.java rename {src => codex-api/src}/main/java/studio/magemonkey/codex/util/messages/MessageData.java (100%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/util/random/MTRandom.java (100%) rename {src => codex-api/src}/main/java/studio/magemonkey/codex/util/random/Rnd.java (100%) create mode 100644 codex-api/src/test/java/studio/magemonkey/codex/api/ReplacerTest.java create mode 100644 codex-bungee/pom.xml rename {src => codex-bungee/src}/main/java/studio/magemonkey/codex/bungee/BungeeCore.java (100%) rename {src => codex-bungee/src}/main/java/studio/magemonkey/codex/bungee/BungeeListener.java (100%) rename {src => codex-bungee/src}/main/java/studio/magemonkey/codex/bungee/BungeeUtil.java (84%) rename {src => codex-bungee/src}/main/resources/bungee.yml (100%) create mode 100644 codex-core/.module create mode 100644 codex-core/pom.xml rename {src => codex-core/src}/main/java/studio/magemonkey/codex/migration/MigrationUtil.java (67%) rename {src => codex-core/src}/main/java/studio/magemonkey/codex/util/NamespaceResolver.java (66%) create mode 100644 codex-nms/codex-nms-v1_16_5/pom.xml create mode 100644 codex-nms/codex-nms-v1_16_5/src/main/java/studio/magemonkey/codex/nms/v1_16_5/CompatImpl.java create mode 100644 codex-nms/codex-nms-v1_16_5/src/main/java/studio/magemonkey/codex/nms/v1_16_5/NMSImpl.java create mode 100644 codex-nms/codex-nms-v1_17_1/pom.xml create mode 100644 codex-nms/codex-nms-v1_17_1/src/main/java/studio/magemonkey/codex/nms/v1_17/CompatImpl.java create mode 100644 codex-nms/codex-nms-v1_17_1/src/main/java/studio/magemonkey/codex/nms/v1_17/NMSImpl.java create mode 100644 codex-nms/codex-nms-v1_18_2/pom.xml create mode 100644 codex-nms/codex-nms-v1_18_2/src/main/java/studio/magemonkey/codex/nms/v1_18_2/CompatImpl.java create mode 100644 codex-nms/codex-nms-v1_18_2/src/main/java/studio/magemonkey/codex/nms/v1_18_2/NMSImpl.java create mode 100644 codex-nms/codex-nms-v1_19_4/pom.xml create mode 100644 codex-nms/codex-nms-v1_19_4/src/main/java/studio/magemonkey/codex/nms/v1_19_4/ArmorUtilImpl.java create mode 100644 codex-nms/codex-nms-v1_19_4/src/main/java/studio/magemonkey/codex/nms/v1_19_4/CompatImpl.java create mode 100644 codex-nms/codex-nms-v1_19_4/src/main/java/studio/magemonkey/codex/nms/v1_19_4/NMSImpl.java create mode 100644 codex-nms/codex-nms-v1_20_2/pom.xml create mode 100644 codex-nms/codex-nms-v1_20_2/src/main/java/studio/magemonkey/codex/nms/v1_20_2/ArmorUtilImpl.java create mode 100644 codex-nms/codex-nms-v1_20_2/src/main/java/studio/magemonkey/codex/nms/v1_20_2/CompatImpl.java create mode 100644 codex-nms/codex-nms-v1_20_2/src/main/java/studio/magemonkey/codex/nms/v1_20_2/NMSImpl.java create mode 100644 codex-nms/codex-nms-v1_20_4/pom.xml create mode 100644 codex-nms/codex-nms-v1_20_4/src/main/java/studio/magemonkey/codex/nms/v1_20_4/ArmorUtilImpl.java create mode 100644 codex-nms/codex-nms-v1_20_4/src/main/java/studio/magemonkey/codex/nms/v1_20_4/CompatImpl.java create mode 100644 codex-nms/codex-nms-v1_20_4/src/main/java/studio/magemonkey/codex/nms/v1_20_4/NMSImpl.java create mode 100644 codex-nms/codex-nms-v1_20_6/pom.xml create mode 100644 codex-nms/codex-nms-v1_20_6/src/main/java/studio/magemonkey/codex/nms/v1_20_6/ArmorUtilImpl.java create mode 100644 codex-nms/codex-nms-v1_20_6/src/main/java/studio/magemonkey/codex/nms/v1_20_6/CompatImpl.java create mode 100644 codex-nms/codex-nms-v1_20_6/src/main/java/studio/magemonkey/codex/nms/v1_20_6/NMSImpl.java create mode 100644 codex-nms/codex-nms-v1_21_1/pom.xml create mode 100644 codex-nms/codex-nms-v1_21_1/src/main/java/studio/magemonkey/codex/nms/v1_21_1/ArmorUtilImpl.java create mode 100644 codex-nms/codex-nms-v1_21_1/src/main/java/studio/magemonkey/codex/nms/v1_21_1/CompatImpl.java create mode 100644 codex-nms/codex-nms-v1_21_1/src/main/java/studio/magemonkey/codex/nms/v1_21_1/NMSImpl.java create mode 100644 codex-nms/codex-nms-v1_21_2/pom.xml create mode 100644 codex-nms/codex-nms-v1_21_2/src/main/java/studio/magemonkey/codex/nms/v1_21_2/ArmorUtilImpl.java create mode 100644 codex-nms/codex-nms-v1_21_2/src/main/java/studio/magemonkey/codex/nms/v1_21_2/CompatImpl.java create mode 100644 codex-nms/codex-nms-v1_21_2/src/main/java/studio/magemonkey/codex/nms/v1_21_2/NMSImpl.java create mode 100644 codex-nms/codex-nms-v1_21_4/pom.xml create mode 100644 codex-nms/codex-nms-v1_21_4/src/main/java/studio/magemonkey/codex/nms/v1_21_4/ArmorUtilImpl.java create mode 100644 codex-nms/codex-nms-v1_21_4/src/main/java/studio/magemonkey/codex/nms/v1_21_4/CompatImpl.java create mode 100644 codex-nms/codex-nms-v1_21_4/src/main/java/studio/magemonkey/codex/nms/v1_21_4/NMSImpl.java create mode 100644 codex-nms/pom.xml create mode 100644 codex-plugin/.module create mode 100644 codex-plugin/pom.xml rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/CodexDataPlugin.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/CodexEngine.java (86%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/CodexPlugin.java (96%) rename {src/main/java/studio/magemonkey/codex/api => codex-plugin/src/main/java/studio/magemonkey/codex/action}/CommandBlock.java (95%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/commands/CommandManager.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/commands/CommandRegister.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/commands/UnstuckCommand.java (73%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/commands/api/IAbstractCommand.java (96%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/commands/api/IGeneralCommand.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/commands/api/ISubCommand.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/commands/list/AboutCommand.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/commands/list/EditorCommand.java (89%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/commands/list/HelpCommand.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/commands/list/MainCommand.java (88%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/commands/list/ReloadCommand.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/config/ConfigManager.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/config/api/IConfigTemplate.java (99%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/config/api/ILangMsg.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/config/api/ILangTemplate.java (99%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/config/api/JYML.java (99%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/config/legacy/LegacyConfigManager.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/core/config/CoreConfig.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/core/config/CoreLang.java (99%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/data/DataTypes.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/data/IDataHandler.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/data/StorageType.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/data/event/EngineUserCreatedEvent.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/data/event/EngineUserEvent.java (92%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/data/event/EngineUserLoadEvent.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/data/event/EngineUserUnloadEvent.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/data/users/IAbstractUser.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/data/users/IUserManager.java (85%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/hooks/HookManager.java (91%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/hooks/Hooks.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/hooks/NHook.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/hooks/external/IMythicHook.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/hooks/external/MythicMobsHK.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/hooks/external/MythicMobsHKv5.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/hooks/external/VaultHK.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/hooks/external/WorldGuardHK.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/hooks/external/citizens/CitizensHK.java (99%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/hooks/external/citizens/CitizensListener.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/items/CodexItemManager.java (91%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/legacy/RisePlugin.java (88%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/legacy/command/RiseCommand.java (98%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/legacy/item/BlockColors.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/legacy/item/BookDataBuilder.java (91%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/legacy/item/DataBuilder.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/legacy/item/EnchantmentStorageBuilder.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/legacy/item/FireworkBuilder.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/legacy/item/FireworkEffectBuilder.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/legacy/item/ItemBuilder.java (98%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/legacy/item/ItemColors.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/legacy/item/LeatherArmorBuilder.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/legacy/item/MapBuilder.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/legacy/item/PotionDataBuilder.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/legacy/item/SkullBuilder.java (92%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/legacy/item/SkullType.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/legacy/riseitem/DarkRiseItem.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/legacy/riseitem/DarkRiseItemImpl.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/legacy/utils/ItemComparator.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/legacy/utils/ReflectionUtil.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/legacy/utils/SimpleMap.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/legacy/utils/Utils.java (88%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/legacy/utils/serializers/BaseComponentSerializer.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/legacy/utils/serializers/ComponentSerializer.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/legacy/utils/serializers/TextComponentSerializer.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/legacy/utils/serializers/TranslatableComponentSerializer.java (100%) rename {src/main/java/studio/magemonkey/codex/api/armor => codex-plugin/src/main/java/studio/magemonkey/codex/listeners}/ArmorListener.java (97%) create mode 100644 codex-plugin/src/main/java/studio/magemonkey/codex/listeners/BoatListener.java rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/listeners/InteractListener.java (96%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/listeners/JoinListener.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/manager/LoadableItem.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/manager/api/Editable.java (99%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/manager/api/IActionEditable.java (99%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/manager/api/Saveable.java (79%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/manager/api/gui/GuiItem.java (94%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/manager/api/gui/NGUI.java (97%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/manager/api/task/ITask.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/manager/editor/EditorActionsHandler.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/manager/editor/EditorHandler.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/manager/editor/EditorManager.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/manager/editor/EditorType.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/manager/editor/object/IEditorActionsMain.java (99%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/manager/editor/object/IEditorActionsParametized.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/manager/editor/object/IEditorActionsParams.java (98%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/manager/editor/object/IEditorActionsSection.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/chat/Chat.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/chat/ChatCommander.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/chat/ChatData.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/chat/ChatListener.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/chat/ChatNodes.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/chat/ListCommand.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/chat/NameCommand.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/chat/Prefix.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/chat/PrefixCommand.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/chat/ResetCommand.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/commands/CommandHandler.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/commands/CommandListener.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/commands/CommandManager.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/commands/ConfigurableCommand.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/commands/ICommand.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/commands/IFunction.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/commands/LogFunction.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/commands/SenderType.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/config/CommentedConfig.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/config/CommentedLanguageConfig.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/config/Config.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/config/ConfigSerializer.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/config/CustomFilter.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/config/DataFile.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/config/ExcludeField.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/config/Filter.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/config/FilterType.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/config/ISavable.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/config/LanguageConfig.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/config/LocationData.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/config/Resources.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/config/SerializableField.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/config/parse/DataArray.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/config/parse/DataSection.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/config/parse/JSONParser.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/config/parse/NumberParser.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/config/parse/YAMLParser.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/gui/MapBuffer.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/gui/MapData.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/gui/MapFont.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/gui/MapImage.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/gui/MapImageManager.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/gui/MapListener.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/gui/MapMenu.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/gui/MapMenuManager.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/gui/MapObject.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/gui/MapScene.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/gui/MapScheme.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/gui/MapString.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/items/InventoryManager.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/items/ItemManager.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/scoreboard/Board.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/scoreboard/BoardListener.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/scoreboard/BoardManager.java (96%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/scoreboard/CycleCommand.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/scoreboard/CycleTask.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/scoreboard/ListCommand.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/scoreboard/PlayerBoards.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/scoreboard/ScoreboardCommander.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/scoreboard/ScoreboardNodes.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/scoreboard/ShowCommand.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/scoreboard/StatBoard.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/scoreboard/StatHolder.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/scoreboard/StopCommand.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/scoreboard/Team.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/scoreboard/ToggleCommand.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/scoreboard/UpdateTask.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/sql/ColumnType.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/sql/direct/ISQLEntryData.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/sql/direct/SQLDatabase.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/sql/direct/SQLEntry.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/sql/direct/SQLTable.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/util/MobManager.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/util/TextFormatter.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/util/TextSizer.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/mccore/util/TextSplitter.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/modules/IExternalModule.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/modules/IModule.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/modules/IModuleExecutor.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/modules/ModuleManager.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/nms/packets/IPacketHandler.java (63%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/nms/packets/PacketManager.java (93%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/ItemUT.java (86%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/ItemUtils.java (71%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/TimeUT.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/ActionCategory.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/ActionManipulator.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/ActionSection.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/ActionsManager.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/Parametized.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/actions/IActionExecutor.java (95%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/actions/IActionType.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_ActionBar.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Broadcast.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Burn.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_CommandConsole.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_CommandOp.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_CommandPlayer.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Damage.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Firework.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Goto.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Health.java (94%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Hook.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Hunger.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Lightning.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Message.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_ParticleSimple.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Potion.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_ProgressBar.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Projectile.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Saturation.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Sound.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Teleport.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Throw.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Titles.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/api/IActioned.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/conditions/IConditionType.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/conditions/IConditionValidator.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/conditions/list/Condition_EntityHealth.java (95%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/conditions/list/Condition_EntityType.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/conditions/list/Condition_Permission.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/conditions/list/Condition_VaultBalance.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/conditions/list/Condition_WorldTime.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/params/IAutoValidated.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/params/IParam.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/params/IParamResult.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/params/IParamType.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/params/IParamValue.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/params/defaults/IParamBoolean.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/params/defaults/IParamNumber.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/params/defaults/IParamString.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/params/list/AllowSelfParam.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/params/list/AttackableParam.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/params/list/LocationParam.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/params/list/OffsetParam.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/params/parser/IParamParser.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/params/parser/ParamBooleanParser.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/params/parser/ParamNumberParser.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/params/parser/ParamStringParser.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/targets/ITargetSelector.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/targets/ITargetType.java (100%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/targets/list/Target_FromSight.java (94%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/targets/list/Target_Radius.java (92%) rename {src => codex-plugin/src}/main/java/studio/magemonkey/codex/util/actions/targets/list/Target_Self.java (89%) create mode 100644 codex-plugin/src/main/java/studio/magemonkey/codex/util/messages/MessageUtil.java rename {src => codex-plugin/src}/main/resources/config.yml (100%) rename {src => codex-plugin/src}/main/resources/editor/actions_main.yml (100%) rename {src => codex-plugin/src}/main/resources/editor/actions_parametized.yml (100%) rename {src => codex-plugin/src}/main/resources/editor/actions_params.yml (100%) rename {src => codex-plugin/src}/main/resources/editor/actions_section.yml (100%) rename {src => codex-plugin/src}/main/resources/lang/messages_cn.yml (100%) rename {src => codex-plugin/src}/main/resources/lang/messages_en.yml (100%) rename {src => codex-plugin/src}/main/resources/paper-plugin.yml (100%) rename {src => codex-plugin/src}/main/resources/plugin.yml (100%) create mode 100644 codex-plugin/src/main/resources/temp.yml rename {src => codex-plugin/src}/test/java/studio/magemonkey/codex/CommandTest.java (100%) rename {src => codex-plugin/src}/test/java/studio/magemonkey/codex/mccore/config/parse/YAMLParserTest.java (100%) rename {src => codex-plugin/src}/test/java/studio/magemonkey/codex/testutil/DependencyResolver.java (100%) rename {src => codex-plugin/src}/test/java/studio/magemonkey/codex/testutil/MockedTest.java (76%) rename {src => codex-plugin/src}/test/java/studio/magemonkey/codex/testutil/reflection/TestChannel.java (100%) rename {src => codex-plugin/src}/test/java/studio/magemonkey/codex/util/LocUTTest.java (100%) rename {src => codex-plugin/src}/test/resources/fabled-config.yml (100%) rename {src => codex-plugin/src}/test/resources/log4j.xml (100%) delete mode 100644 src/main/java/studio/magemonkey/codex/listeners/BoatListener.java delete mode 100644 src/main/java/studio/magemonkey/codex/manager/api/Loggable.java delete mode 100644 src/main/java/studio/magemonkey/codex/nms/NMS.java delete mode 100644 src/main/java/studio/magemonkey/codex/util/AttributeUT.java delete mode 100644 src/main/java/studio/magemonkey/codex/util/EntityUT.java delete mode 100644 src/main/java/studio/magemonkey/codex/util/InventoryUtil.java delete mode 100644 src/main/java/studio/magemonkey/codex/util/messages/MessageUtil.java delete mode 100644 src/main/java/studio/magemonkey/codex/util/messages/NMSPlayerUtils.java delete mode 100644 src/main/java/studio/magemonkey/codex/util/reflection/DefaultReflectionUtil.java delete mode 100644 src/main/java/studio/magemonkey/codex/util/reflection/ReflectionManager.java delete mode 100644 src/main/java/studio/magemonkey/codex/util/reflection/ReflectionUtil.java delete mode 100644 src/main/java/studio/magemonkey/codex/util/reflection/Reflection_1_17.java delete mode 100644 src/main/java/studio/magemonkey/codex/util/reflection/Reflection_1_18.java delete mode 100644 src/main/java/studio/magemonkey/codex/util/reflection/Reflection_1_20.java delete mode 100644 src/test/java/studio/magemonkey/codex/testutil/reflection/TestReflectionUtil.java diff --git a/.github/notify_published.py b/.github/notify_published.py index cabf16cf..09d1091e 100644 --- a/.github/notify_published.py +++ b/.github/notify_published.py @@ -5,7 +5,7 @@ is_dev = len(sys.argv) >= 3 and bool(sys.argv[2]) search_string = \ - r'Uploaded to (ossrh|central): (https:\/\/s01\.oss\.sonatype\.org(:443)?\/.*?\/studio\/magemonkey\/(.*?)\/(.*?)\/(' \ + r'Uploaded to (ossrh|central): (https:\/\/s01\.oss\.sonatype\.org(:443)?\/.*?\/studio\/magemonkey\/(codex)\/(.*?)\/(' \ r'.*?)(?= 3 and bool(sys.argv[2]) -def replace_version(): - regex = r'^[ ]{4}((((\d+\.?)+)((-R(\d+)\.?)(\d+)?)?)(-SNAPSHOT)?)<\/version>$' - with open('pom.xml', 'r') as pom: +def replace_version(pom_path): + regex = r'(.*codex.*<\/artifactId>\s*)((((\d+\.?)+)((-R(\d+)\.?)(\d+)?)?)(-SNAPSHOT)?)<\/version>$' + with open(pom_path, 'r') as pom: contents = pom.read() ver = re.findall(regex, contents, re.MULTILINE) - version = ver[0][0] - bare_version = ver[0][2] + version = ver[0][1] + bare_version = ver[0][3] if is_dev: if not '-R' in version: new_version = version + '-R0.1-SNAPSHOT' elif not '-SNAPSHOT' in version: new_version = version + '.1-SNAPSHOT' else: - r_version = ver[0][5] - patch = int(ver[0][7]) + 1 + r_version = ver[0][6] + patch = int(ver[0][8]) + 1 new_version = bare_version + r_version + str(patch) + '-SNAPSHOT' elif prep: - r_version = int(ver[0][6]) + 1 + r_version = int(ver[0][7]) + 1 new_version = bare_version + '-R' + str(r_version) else: - version = ver[0][2] - minor = int(ver[0][3]) + version = ver[0][3] + minor = int(ver[0][4]) new_version = version[:-(len(str(minor)))] + str(minor + 1) contents = re.sub(regex, - ' ' + new_version + '', + ver[0][0] + '' + new_version + '', contents, 1, re.MULTILINE) - with open('pom.xml', 'w') as pom: + with open(pom_path, 'w') as pom: pom.write(contents) -replace_version() +def find_pom_files(directory): + pom_files = [] + for root, dirs, files in os.walk(directory): + for file in files: + if file == 'pom.xml': + pom_files.append(os.path.join(root, file)) + return pom_files + +if __name__ == "__main__": + directory = os.getcwd() + pom_files = find_pom_files(directory) + for pom_file in pom_files: + # NMS versions should be updated manually when NMS is actually changed + if '-nms' in pom_file: continue + print(f'Updating version in {pom_file}') + replace_version(pom_file) diff --git a/.github/workflows/devbuild.yml b/.github/workflows/devbuild.yml index dd7affff..d9f7b2b4 100644 --- a/.github/workflows/devbuild.yml +++ b/.github/workflows/devbuild.yml @@ -36,7 +36,10 @@ jobs: env: MAVEN_GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} run: | - mvn clean deploy -P gpg,publish -DcreateChecksum=true 2>&1 | tee log.txt + mvn clean deploy -pl \!codex-nms,\!codex-nms/codex-nms-v1_16_5,\!codex-nms/codex-nms-v1_17_1,\ + \!codex-nms/codex-nms-v1_18_2,\!codex-nms/codex-nms-v1_19_4,\!codex-nms/codex-nms-v1_20_2,\ + \!codex-nms/codex-nms-v1_20_4,\!codex-nms/codex-nms-v1_20_6,\!codex-nms/codex-nms-v1_21_1,\ + \!codex-nms/codex-nms-v1_21_2,\!codex-nms/codex-nms-v1_21_4 -P gpg,publish -DcreateChecksum=true 2>&1 | tee log.txt result_code=${PIPESTATUS[0]} exit $result_code - name: Tag release version diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 72975e04..fb3d7a91 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -10,19 +10,25 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@v4 with: distribution: 'zulu' - java-version: 21 + java-version: | + 11 + 17 + 21 server-id: ossrh # Value of the distributionManagement/repository/id field of the pom.xml settings-path: ${{ github.workspace }} # location for the settings.xml file gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }} gpg-passphrase: MAVEN_GPG_PASSPHRASE + - uses: actions/checkout@v4 - name: 'Create settings.xml' uses: s4u/maven-settings-action@v3.0.0 with: githubServer: false - name: Build with Maven - run: mvn clean package -e \ No newline at end of file + run: mvn clean package -e -pl \!codex-nms,\!codex-nms/codex-nms-v1_16_5,\!codex-nms/codex-nms-v1_17_1,\ + \!codex-nms/codex-nms-v1_18_2,\!codex-nms/codex-nms-v1_19_4,\!codex-nms/codex-nms-v1_20_2,\ + \!codex-nms/codex-nms-v1_20_4,\!codex-nms/codex-nms-v1_20_6,\!codex-nms/codex-nms-v1_21_1,\ + \!codex-nms/codex-nms-v1_21_2,\!codex-nms/codex-nms-v1_21_4 \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9a0205aa..2dc20c1d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -10,22 +10,47 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - with: - token: ${{ secrets.ACTIONS_PAT }} - name: Configure git run: | git config user.name "Build Monkey" git config user.email "<>" - - name: Set up JDK 17 + - name: Set up JDK uses: actions/setup-java@v4 with: distribution: 'zulu' - java-version: 21 + java-version: | + 11 + 17 + 21 server-id: ossrh # Value of the distributionManagement/repository/id field of the pom.xml settings-path: ${{ github.workspace }} # location for the settings.xml file gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }} gpg-passphrase: MAVEN_GPG_PASSPHRASE + - name: Download BuildTools + run: wget https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar + - name: Build Spigot 1.16.5 + run: $JAVA_HOME_11_X64/bin/java -jar BuildTools.jar --rev 1.16.5 + - name: Build Spigot 1.17.1 + run: $JAVA_HOME_17_X64/bin/java -jar BuildTools.jar --rev 1.17.1 + - name: Build Spigot 1.18.2 + run: $JAVA_HOME_17_X64/bin/java -jar BuildTools.jar --rev 1.18.2 + - name: Build Spigot 1.19.4 + run: $JAVA_HOME_17_X64/bin/java -jar BuildTools.jar --rev 1.19.4 + - name: Build Spigot 1.20.2 + run: java -jar BuildTools.jar --rev 1.20.2 + - name: Build Spigot 1.20.4 + run: java -jar BuildTools.jar --rev 1.20.4 + - name: Build Spigot 1.20.6 + run: java -jar BuildTools.jar --rev 1.20.6 + - name: Build Spigot 1.21.1 + run: java -jar BuildTools.jar --rev 1.21.1 + - name: Build Spigot 1.21.2 + run: java -jar BuildTools.jar --rev 1.21.2 + - name: Build Spigot 1.21.4 + run: java -jar BuildTools.jar --rev 1.21.4 + - uses: actions/checkout@v4 + with: + token: ${{ secrets.ACTIONS_PAT }} - name: 'Create settings.xml' uses: s4u/maven-settings-action@v3.0.0 with: diff --git a/.gitignore b/.gitignore index b35c666d..552cb86f 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,9 @@ target/ *.iml /.idea/ gh-pages/ +apidocs/ settings.xml toolchains.xml log.txt -logs/ \ No newline at end of file +logs/ +**/build/*.jar \ No newline at end of file diff --git a/README.md b/README.md index acdd07d8..6c34fe73 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ -[![Build](https://github.com/promcteam/codex/actions/workflows/release.yml/badge.svg?branch=main)](https://s01.oss.sonatype.org/content/repositories/releases/studio/magemonkey/codex/1.0.1-R0.18-SNAPSHOT) -[![Build](https://github.com/promcteam/codex/actions/workflows/devbuild.yml/badge.svg?branch=dev)](https://s01.oss.sonatype.org/content/repositories/snapshots/studio/magemonkey/codex/1.0.1-R0.18-SNAPSHOT) +[![Build](https://github.com/magemonkeystudios/codex/actions/workflows/release.yml/badge.svg?branch=main)](https://s01.oss.sonatype.org/content/repositories/releases/studio/magemonkey/codex/1.1.0-R0.1-SNAPSHOT) +[![Build](https://github.com/magemonkeystudios/codex/actions/workflows/devbuild.yml/badge.svg?branch=dev)](https://s01.oss.sonatype.org/content/repositories/snapshots/studio/magemonkey/codex/1.1.0-R0.1-SNAPSHOT) [![Discord](https://dcbadge.vercel.app/api/server/6UzkTe6RvW?style=flat)](https://discord.gg/6UzkTe6RvW) -# CodexCore (Formerly ProMCCore) +# Codex (Formerly ProMCCore) -If you wish to use CodexCore as a dependency in your projects, CodexCore is available through Maven Central +If you wish to use Codex as a dependency in your projects, Codex is available through Maven Central or snapshots through Sonatype. ```xml @@ -16,12 +16,12 @@ or snapshots through Sonatype. studio.magemonkey codex - 1.0.1-R0.18-SNAPSHOT + 1.1.0-R0.1-SNAPSHOT ``` ### A huge thanks to our contributors - - + + \ No newline at end of file diff --git a/src/main/resources/temp.yml b/codex-api/.module similarity index 100% rename from src/main/resources/temp.yml rename to codex-api/.module diff --git a/codex-api/pom.xml b/codex-api/pom.xml new file mode 100644 index 00000000..40a7d26d --- /dev/null +++ b/codex-api/pom.xml @@ -0,0 +1,108 @@ + + + 4.0.0 + + studio.magemonkey + codex-parent + 1.1.0-R0.1-SNAPSHOT + + + codex-api + + + + nexo + Nexo Repository + https://repo.nexomc.com/snapshots/ + + + oraxen + Oraxen Repository + https://repo.oraxen.com/releases + + + + + + org.spigotmc + spigot-api + 1.16.5-R0.1-SNAPSHOT + + + + + studio.magemonkey + codex-bungee + 1.1.0-R0.1-SNAPSHOT + + + + com.nexomc + nexo + 0.5.0-dev.14 + dev + provided + + + * + * + + + + + io.th0rgal + oraxen + 1.173.0 + dev + provided + + + me.gabytm.util + actions-spigot + + + org.jetbrains + annotations + + + com.ticxo + PlayerAnimator + + + com.github.stefvanschie.inventoryframework + IF + + + io.th0rgal + protectionlib + + + dev.triumphteam + triumph-gui + + + org.bstats + bstats-bukkit + + + com.jeff-media + custom-block-data + + + com.jeff-media + persistent-data-serializer + + + com.jeff_media + MorePersistentDataTypes + + + gs.mclo + java + + + + + \ No newline at end of file diff --git a/codex-api/src/main/java/studio/magemonkey/codex/Codex.java b/codex-api/src/main/java/studio/magemonkey/codex/Codex.java new file mode 100644 index 00000000..0b66a45b --- /dev/null +++ b/codex-api/src/main/java/studio/magemonkey/codex/Codex.java @@ -0,0 +1,33 @@ +package studio.magemonkey.codex; + +import lombok.Setter; +import org.bukkit.plugin.java.JavaPlugin; + +public class Codex { + @Setter + public static JavaPlugin plugin; + + public static JavaPlugin getPlugin() { + if (plugin == null) { + throw new IllegalStateException("Codex has not been initialized"); + } + + return plugin; + } + + public static void info(String message) { + getPlugin().getLogger().info(message); + } + + public static void warn(String message) { + getPlugin().getLogger().warning(message); + } + + public static void error(String message) { + getPlugin().getLogger().severe(message); + } + + public static void trace(String message) { + getPlugin().getLogger().fine(message); + } +} \ No newline at end of file diff --git a/src/main/java/studio/magemonkey/codex/api/CommandType.java b/codex-api/src/main/java/studio/magemonkey/codex/api/CommandType.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/api/CommandType.java rename to codex-api/src/main/java/studio/magemonkey/codex/api/CommandType.java diff --git a/src/main/java/studio/magemonkey/codex/api/DelayedCommand.java b/codex-api/src/main/java/studio/magemonkey/codex/api/DelayedCommand.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/api/DelayedCommand.java rename to codex-api/src/main/java/studio/magemonkey/codex/api/DelayedCommand.java diff --git a/src/main/java/studio/magemonkey/codex/api/Replacer.java b/codex-api/src/main/java/studio/magemonkey/codex/api/Replacer.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/api/Replacer.java rename to codex-api/src/main/java/studio/magemonkey/codex/api/Replacer.java diff --git a/src/main/java/studio/magemonkey/codex/api/armor/ArmorEquipEvent.java b/codex-api/src/main/java/studio/magemonkey/codex/api/armor/ArmorEquipEvent.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/api/armor/ArmorEquipEvent.java rename to codex-api/src/main/java/studio/magemonkey/codex/api/armor/ArmorEquipEvent.java diff --git a/src/main/java/studio/magemonkey/codex/api/armor/ArmorType.java b/codex-api/src/main/java/studio/magemonkey/codex/api/armor/ArmorType.java similarity index 85% rename from src/main/java/studio/magemonkey/codex/api/armor/ArmorType.java rename to codex-api/src/main/java/studio/magemonkey/codex/api/armor/ArmorType.java index 86719abd..7107f893 100644 --- a/src/main/java/studio/magemonkey/codex/api/armor/ArmorType.java +++ b/codex-api/src/main/java/studio/magemonkey/codex/api/armor/ArmorType.java @@ -1,17 +1,18 @@ package studio.magemonkey.codex.api.armor; +import lombok.Getter; +import lombok.RequiredArgsConstructor; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.Nullable; +import studio.magemonkey.codex.util.constants.ItemHelper; +@Getter +@RequiredArgsConstructor public enum ArmorType { BOOTS(36), LEGGINGS(37), CHESTPLATE(38), HELMET(39), OFFHAND(40), MAIN_HAND(-1); private final int slot; - ArmorType(int slot) { - this.slot = slot; - } - /** * Attempts to match the ArmorType for the specified ItemStack. * @@ -20,7 +21,7 @@ public enum ArmorType { */ @Nullable public static ArmorType matchType(final ItemStack itemStack) { - if (ArmorListener.isAirOrNull(itemStack)) return null; + if (ItemHelper.isAirOrNull(itemStack)) return null; String type = itemStack.getType().name(); if (type.endsWith("_HELMET") || type.endsWith("_SKULL") || type.endsWith("_HEAD")) return HELMET; else if (type.endsWith("_CHESTPLATE") || type.equals("ELYTRA")) return CHESTPLATE; @@ -30,10 +31,6 @@ public static ArmorType matchType(final ItemStack itemStack) { else return MAIN_HAND; } - public int getSlot() { - return slot; - } - public boolean matchesSlot(int slot, int heldSlot) { switch (this) { case MAIN_HAND, OFFHAND -> { diff --git a/src/main/java/studio/magemonkey/codex/nms/packets/events/EnginePacketEvent.java b/codex-api/src/main/java/studio/magemonkey/codex/api/events/EnginePacketEvent.java similarity index 84% rename from src/main/java/studio/magemonkey/codex/nms/packets/events/EnginePacketEvent.java rename to codex-api/src/main/java/studio/magemonkey/codex/api/events/EnginePacketEvent.java index 451bf5dc..3ea8a599 100644 --- a/src/main/java/studio/magemonkey/codex/nms/packets/events/EnginePacketEvent.java +++ b/codex-api/src/main/java/studio/magemonkey/codex/api/events/EnginePacketEvent.java @@ -1,8 +1,7 @@ -package studio.magemonkey.codex.nms.packets.events; +package studio.magemonkey.codex.api.events; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; -import studio.magemonkey.codex.manager.api.event.ICancellableEvent; public abstract class EnginePacketEvent extends ICancellableEvent { diff --git a/src/main/java/studio/magemonkey/codex/nms/packets/events/EnginePlayerPacketEvent.java b/codex-api/src/main/java/studio/magemonkey/codex/api/events/EnginePlayerPacketEvent.java similarity index 83% rename from src/main/java/studio/magemonkey/codex/nms/packets/events/EnginePlayerPacketEvent.java rename to codex-api/src/main/java/studio/magemonkey/codex/api/events/EnginePlayerPacketEvent.java index e385a52f..d5009a49 100644 --- a/src/main/java/studio/magemonkey/codex/nms/packets/events/EnginePlayerPacketEvent.java +++ b/codex-api/src/main/java/studio/magemonkey/codex/api/events/EnginePlayerPacketEvent.java @@ -1,4 +1,4 @@ -package studio.magemonkey.codex.nms.packets.events; +package studio.magemonkey.codex.api.events; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; diff --git a/src/main/java/studio/magemonkey/codex/nms/packets/events/EngineServerPacketEvent.java b/codex-api/src/main/java/studio/magemonkey/codex/api/events/EngineServerPacketEvent.java similarity index 83% rename from src/main/java/studio/magemonkey/codex/nms/packets/events/EngineServerPacketEvent.java rename to codex-api/src/main/java/studio/magemonkey/codex/api/events/EngineServerPacketEvent.java index 8c8bc2b5..d483cc97 100644 --- a/src/main/java/studio/magemonkey/codex/nms/packets/events/EngineServerPacketEvent.java +++ b/codex-api/src/main/java/studio/magemonkey/codex/api/events/EngineServerPacketEvent.java @@ -1,4 +1,4 @@ -package studio.magemonkey.codex.nms.packets.events; +package studio.magemonkey.codex.api.events; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; diff --git a/src/main/java/studio/magemonkey/codex/manager/api/event/ICancellableEvent.java b/codex-api/src/main/java/studio/magemonkey/codex/api/events/ICancellableEvent.java similarity index 91% rename from src/main/java/studio/magemonkey/codex/manager/api/event/ICancellableEvent.java rename to codex-api/src/main/java/studio/magemonkey/codex/api/events/ICancellableEvent.java index 28c99dc4..3feaed9a 100644 --- a/src/main/java/studio/magemonkey/codex/manager/api/event/ICancellableEvent.java +++ b/codex-api/src/main/java/studio/magemonkey/codex/api/events/ICancellableEvent.java @@ -1,4 +1,4 @@ -package studio.magemonkey.codex.manager.api.event; +package studio.magemonkey.codex.api.events; import org.bukkit.event.Cancellable; diff --git a/src/main/java/studio/magemonkey/codex/manager/api/event/IEvent.java b/codex-api/src/main/java/studio/magemonkey/codex/api/events/IEvent.java similarity index 91% rename from src/main/java/studio/magemonkey/codex/manager/api/event/IEvent.java rename to codex-api/src/main/java/studio/magemonkey/codex/api/events/IEvent.java index c07377ea..84de8191 100644 --- a/src/main/java/studio/magemonkey/codex/manager/api/event/IEvent.java +++ b/codex-api/src/main/java/studio/magemonkey/codex/api/events/IEvent.java @@ -1,4 +1,4 @@ -package studio.magemonkey.codex.manager.api.event; +package studio.magemonkey.codex.api.events; import org.bukkit.event.Event; import org.bukkit.event.HandlerList; diff --git a/codex-api/src/main/java/studio/magemonkey/codex/api/exception/UnsupportedVersionException.java b/codex-api/src/main/java/studio/magemonkey/codex/api/exception/UnsupportedVersionException.java new file mode 100644 index 00000000..1e168489 --- /dev/null +++ b/codex-api/src/main/java/studio/magemonkey/codex/api/exception/UnsupportedVersionException.java @@ -0,0 +1,11 @@ +package studio.magemonkey.codex.api.exception; + +public class UnsupportedVersionException extends RuntimeException { + public UnsupportedVersionException(String message) { + super(message); + } + + public UnsupportedVersionException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/src/main/java/studio/magemonkey/codex/items/ItemType.java b/codex-api/src/main/java/studio/magemonkey/codex/api/items/ItemType.java similarity index 83% rename from src/main/java/studio/magemonkey/codex/items/ItemType.java rename to codex-api/src/main/java/studio/magemonkey/codex/api/items/ItemType.java index a14c102c..bb5e9428 100644 --- a/src/main/java/studio/magemonkey/codex/items/ItemType.java +++ b/codex-api/src/main/java/studio/magemonkey/codex/api/items/ItemType.java @@ -1,8 +1,8 @@ -package studio.magemonkey.codex.items; +package studio.magemonkey.codex.api.items; import org.bukkit.inventory.ItemStack; -import studio.magemonkey.codex.items.providers.ICodexItemProvider; -import studio.magemonkey.codex.items.providers.VanillaProvider; +import studio.magemonkey.codex.api.items.providers.ICodexItemProvider; +import studio.magemonkey.codex.api.items.providers.VanillaProvider; import java.util.Arrays; diff --git a/codex-api/src/main/java/studio/magemonkey/codex/api/items/PrefixHelper.java b/codex-api/src/main/java/studio/magemonkey/codex/api/items/PrefixHelper.java new file mode 100644 index 00000000..a0e30e94 --- /dev/null +++ b/codex-api/src/main/java/studio/magemonkey/codex/api/items/PrefixHelper.java @@ -0,0 +1,15 @@ +package studio.magemonkey.codex.api.items; + +public class PrefixHelper { + /** + * Removes the given prefix from the provided id, if applicable. + * + * @param prefix the provider prefix to remove + * @param id the item id, prefixed or not + * @return the stripped id + */ + public static String stripPrefix(String prefix, String id) { + String[] split = id.split("_", 2); + return split.length == 2 && split[0].equalsIgnoreCase(prefix) ? split[1] : id; + } +} diff --git a/src/main/java/studio/magemonkey/codex/items/exception/CodexItemException.java b/codex-api/src/main/java/studio/magemonkey/codex/api/items/exception/CodexItemException.java similarity index 76% rename from src/main/java/studio/magemonkey/codex/items/exception/CodexItemException.java rename to codex-api/src/main/java/studio/magemonkey/codex/api/items/exception/CodexItemException.java index b74cbe63..d72adc93 100644 --- a/src/main/java/studio/magemonkey/codex/items/exception/CodexItemException.java +++ b/codex-api/src/main/java/studio/magemonkey/codex/api/items/exception/CodexItemException.java @@ -1,6 +1,6 @@ -package studio.magemonkey.codex.items.exception; +package studio.magemonkey.codex.api.items.exception; -import studio.magemonkey.codex.items.providers.ICodexItemProvider; +import studio.magemonkey.codex.api.items.providers.ICodexItemProvider; /** * Thrown when an attempting to use an {@link ICodexItemProvider}. diff --git a/src/main/java/studio/magemonkey/codex/items/exception/MissingItemException.java b/codex-api/src/main/java/studio/magemonkey/codex/api/items/exception/MissingItemException.java similarity index 73% rename from src/main/java/studio/magemonkey/codex/items/exception/MissingItemException.java rename to codex-api/src/main/java/studio/magemonkey/codex/api/items/exception/MissingItemException.java index d7a68a61..953564d7 100644 --- a/src/main/java/studio/magemonkey/codex/items/exception/MissingItemException.java +++ b/codex-api/src/main/java/studio/magemonkey/codex/api/items/exception/MissingItemException.java @@ -1,4 +1,4 @@ -package studio.magemonkey.codex.items.exception; +package studio.magemonkey.codex.api.items.exception; public class MissingItemException extends CodexItemException { public MissingItemException(String message) { diff --git a/src/main/java/studio/magemonkey/codex/items/exception/MissingProviderException.java b/codex-api/src/main/java/studio/magemonkey/codex/api/items/exception/MissingProviderException.java similarity index 74% rename from src/main/java/studio/magemonkey/codex/items/exception/MissingProviderException.java rename to codex-api/src/main/java/studio/magemonkey/codex/api/items/exception/MissingProviderException.java index a95f7bb7..cc177553 100644 --- a/src/main/java/studio/magemonkey/codex/items/exception/MissingProviderException.java +++ b/codex-api/src/main/java/studio/magemonkey/codex/api/items/exception/MissingProviderException.java @@ -1,4 +1,4 @@ -package studio.magemonkey.codex.items.exception; +package studio.magemonkey.codex.api.items.exception; public class MissingProviderException extends CodexItemException { public MissingProviderException(String message) { diff --git a/src/main/java/studio/magemonkey/codex/items/providers/ICodexItemProvider.java b/codex-api/src/main/java/studio/magemonkey/codex/api/items/providers/ICodexItemProvider.java similarity index 89% rename from src/main/java/studio/magemonkey/codex/items/providers/ICodexItemProvider.java rename to codex-api/src/main/java/studio/magemonkey/codex/api/items/providers/ICodexItemProvider.java index a38c71ca..8339b389 100644 --- a/src/main/java/studio/magemonkey/codex/items/providers/ICodexItemProvider.java +++ b/codex-api/src/main/java/studio/magemonkey/codex/api/items/providers/ICodexItemProvider.java @@ -1,10 +1,10 @@ -package studio.magemonkey.codex.items.providers; +package studio.magemonkey.codex.api.items.providers; import org.bukkit.Bukkit; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.Nullable; -import studio.magemonkey.codex.items.ItemType; -import studio.magemonkey.codex.items.exception.MissingProviderException; +import studio.magemonkey.codex.api.items.ItemType; +import studio.magemonkey.codex.api.items.exception.MissingProviderException; public interface ICodexItemProvider { default void assertEnabled() throws MissingProviderException { diff --git a/src/main/java/studio/magemonkey/codex/items/providers/ItemsAdderProvider.java b/codex-api/src/main/java/studio/magemonkey/codex/api/items/providers/ItemsAdderProvider.java similarity index 90% rename from src/main/java/studio/magemonkey/codex/items/providers/ItemsAdderProvider.java rename to codex-api/src/main/java/studio/magemonkey/codex/api/items/providers/ItemsAdderProvider.java index 29ed3c54..7aae2686 100644 --- a/src/main/java/studio/magemonkey/codex/items/providers/ItemsAdderProvider.java +++ b/codex-api/src/main/java/studio/magemonkey/codex/api/items/providers/ItemsAdderProvider.java @@ -1,10 +1,10 @@ -package studio.magemonkey.codex.items.providers; +package studio.magemonkey.codex.api.items.providers; import dev.lone.itemsadder.api.CustomStack; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.Nullable; -import studio.magemonkey.codex.items.CodexItemManager; -import studio.magemonkey.codex.items.ItemType; +import studio.magemonkey.codex.api.items.ItemType; +import studio.magemonkey.codex.api.items.PrefixHelper; public class ItemsAdderProvider implements ICodexItemProvider { public static final String NAMESPACE = "ITEMSADDER"; @@ -29,7 +29,7 @@ public Category getCategory() { public ItemsAdderItemType getItem(String id) { if (id == null || id.isBlank()) return null; - id = CodexItemManager.stripPrefix(NAMESPACE, id); + id = PrefixHelper.stripPrefix(NAMESPACE, id); CustomStack customStack = CustomStack.getInstance(id); if (customStack == null) return null; @@ -51,7 +51,7 @@ public boolean isCustomItem(ItemStack item) { @Override public boolean isCustomItemOfId(ItemStack item, String id) { - id = CodexItemManager.stripPrefix(NAMESPACE, id); + id = PrefixHelper.stripPrefix(NAMESPACE, id); if (!CustomStack.isInRegistry(id)) return false; String itemId = CustomStack.byItemStack(item).getNamespacedID(); diff --git a/src/main/java/studio/magemonkey/codex/items/providers/NexoProvider.java b/codex-api/src/main/java/studio/magemonkey/codex/api/items/providers/NexoProvider.java similarity index 89% rename from src/main/java/studio/magemonkey/codex/items/providers/NexoProvider.java rename to codex-api/src/main/java/studio/magemonkey/codex/api/items/providers/NexoProvider.java index 2e65419e..e8eca540 100644 --- a/src/main/java/studio/magemonkey/codex/items/providers/NexoProvider.java +++ b/codex-api/src/main/java/studio/magemonkey/codex/api/items/providers/NexoProvider.java @@ -1,11 +1,11 @@ -package studio.magemonkey.codex.items.providers; +package studio.magemonkey.codex.api.items.providers; import com.nexomc.nexo.api.NexoItems; import com.nexomc.nexo.items.ItemBuilder; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.Nullable; -import studio.magemonkey.codex.items.CodexItemManager; -import studio.magemonkey.codex.items.ItemType; +import studio.magemonkey.codex.api.items.ItemType; +import studio.magemonkey.codex.api.items.PrefixHelper; public class NexoProvider implements ICodexItemProvider { public static final String NAMESPACE = "NEXO"; @@ -30,7 +30,7 @@ public Category getCategory() { public NexoItemType getItem(String id) { if (id == null || id.isBlank()) return null; - id = CodexItemManager.stripPrefix(NAMESPACE, id); + id = PrefixHelper.stripPrefix(NAMESPACE, id); ItemBuilder itemBuilder = NexoItems.itemFromId(id); if (itemBuilder == null) return null; @@ -50,7 +50,7 @@ public boolean isCustomItem(ItemStack item) { @Override public boolean isCustomItemOfId(ItemStack item, String id) { - id = CodexItemManager.stripPrefix(NAMESPACE, id); + id = PrefixHelper.stripPrefix(NAMESPACE, id); if (!NexoItems.exists(id)) return false; String itemId = NexoItems.idFromItem(item); diff --git a/src/main/java/studio/magemonkey/codex/items/providers/OraxenProvider.java b/codex-api/src/main/java/studio/magemonkey/codex/api/items/providers/OraxenProvider.java similarity index 89% rename from src/main/java/studio/magemonkey/codex/items/providers/OraxenProvider.java rename to codex-api/src/main/java/studio/magemonkey/codex/api/items/providers/OraxenProvider.java index dabd5df9..e408bfe1 100644 --- a/src/main/java/studio/magemonkey/codex/items/providers/OraxenProvider.java +++ b/codex-api/src/main/java/studio/magemonkey/codex/api/items/providers/OraxenProvider.java @@ -1,11 +1,11 @@ -package studio.magemonkey.codex.items.providers; +package studio.magemonkey.codex.api.items.providers; import io.th0rgal.oraxen.api.OraxenItems; import io.th0rgal.oraxen.items.ItemBuilder; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.Nullable; -import studio.magemonkey.codex.items.CodexItemManager; -import studio.magemonkey.codex.items.ItemType; +import studio.magemonkey.codex.api.items.ItemType; +import studio.magemonkey.codex.api.items.PrefixHelper; @Deprecated(forRemoval = true, since = "Dec 2024") public class OraxenProvider implements ICodexItemProvider { @@ -31,7 +31,7 @@ public Category getCategory() { public OraxenItemType getItem(String id) { if (id == null || id.isBlank()) return null; - id = CodexItemManager.stripPrefix(NAMESPACE, id); + id = PrefixHelper.stripPrefix(NAMESPACE, id); ItemBuilder itemBuilder = OraxenItems.getItemById(id); if (itemBuilder == null) return null; @@ -51,7 +51,7 @@ public boolean isCustomItem(ItemStack item) { @Override public boolean isCustomItemOfId(ItemStack item, String id) { - id = CodexItemManager.stripPrefix(NAMESPACE, id); + id = PrefixHelper.stripPrefix(NAMESPACE, id); if (!OraxenItems.exists(id)) return false; String itemId = OraxenItems.getIdByItem(item); diff --git a/src/main/java/studio/magemonkey/codex/items/providers/VanillaProvider.java b/codex-api/src/main/java/studio/magemonkey/codex/api/items/providers/VanillaProvider.java similarity index 85% rename from src/main/java/studio/magemonkey/codex/items/providers/VanillaProvider.java rename to codex-api/src/main/java/studio/magemonkey/codex/api/items/providers/VanillaProvider.java index 1bcd6e58..0716b61a 100644 --- a/src/main/java/studio/magemonkey/codex/items/providers/VanillaProvider.java +++ b/codex-api/src/main/java/studio/magemonkey/codex/api/items/providers/VanillaProvider.java @@ -1,10 +1,10 @@ -package studio.magemonkey.codex.items.providers; +package studio.magemonkey.codex.api.items.providers; import org.bukkit.Material; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.Nullable; -import studio.magemonkey.codex.items.CodexItemManager; -import studio.magemonkey.codex.items.ItemType; +import studio.magemonkey.codex.api.items.ItemType; +import studio.magemonkey.codex.api.items.PrefixHelper; public class VanillaProvider implements ICodexItemProvider { public static final String NAMESPACE = "VANILLA"; @@ -34,7 +34,7 @@ public Category getCategory() { public VanillaItemType getItem(String id) { if (id == null || id.isBlank()) return null; - Material material = Material.matchMaterial(CodexItemManager.stripPrefix(NAMESPACE, id).replaceAll("[ -]", "_")); + Material material = Material.matchMaterial(PrefixHelper.stripPrefix(NAMESPACE, id).replaceAll("[ -]", "_")); if (material == null) return null; return new VanillaItemType(material); @@ -56,7 +56,7 @@ public boolean isCustomItem(ItemStack item) { public boolean isCustomItemOfId(ItemStack item, String id) { return item.getType() .name() - .equalsIgnoreCase(CodexItemManager.stripPrefix(NAMESPACE, id).replaceAll("[ -]", "_")); + .equalsIgnoreCase(PrefixHelper.stripPrefix(NAMESPACE, id).replaceAll("[ -]", "_")); } public static class VanillaItemType extends ItemType { diff --git a/src/main/java/studio/magemonkey/codex/api/meta/NBTAttribute.java b/codex-api/src/main/java/studio/magemonkey/codex/api/meta/NBTAttribute.java similarity index 79% rename from src/main/java/studio/magemonkey/codex/api/meta/NBTAttribute.java rename to codex-api/src/main/java/studio/magemonkey/codex/api/meta/NBTAttribute.java index dc73e1bc..6aa9c356 100644 --- a/src/main/java/studio/magemonkey/codex/api/meta/NBTAttribute.java +++ b/codex-api/src/main/java/studio/magemonkey/codex/api/meta/NBTAttribute.java @@ -3,7 +3,6 @@ import org.bukkit.attribute.Attribute; import org.bukkit.inventory.EquipmentSlot; import org.jetbrains.annotations.NotNull; -import studio.magemonkey.codex.util.AttributeUT; import java.util.UUID; @@ -11,37 +10,37 @@ public enum NBTAttribute { ARMOR( "generic.armor", - AttributeUT.resolve("ARMOR"), + Attribute.GENERIC_ARMOR, "1f1173-9999-3333-5555-99cb0245f9c1"), // '1' at start ARMOR_TOUGHNESS( "generic.armorToughness", - AttributeUT.resolve("ARMOR_TOUGHNESS"), + Attribute.GENERIC_ARMOR_TOUGHNESS, "1f1173-9999-3333-5555-99cb0245f9c2"), ATTACK_DAMAGE( "generic.attackDamage", - AttributeUT.resolve("ATTACK_DAMAGE"), + Attribute.GENERIC_ATTACK_DAMAGE, "1f1173-9999-3333-5555-99cb0245f9c3"), ATTACK_SPEED( "generic.attackSpeed", - AttributeUT.resolve("ATTACK_SPEED"), + Attribute.GENERIC_ATTACK_SPEED, "1f1173-9999-3333-5555-99cb0245f9c4"), MOVEMENT_SPEED( "generic.movementSpeed", - AttributeUT.resolve("MOVEMENT_SPEED"), + Attribute.GENERIC_MOVEMENT_SPEED, "1f1173-9999-3333-5555-99cb0245f9c5"), MAX_HEALTH( "generic.maxHealth", - AttributeUT.resolve("MAX_HEALTH"), + Attribute.GENERIC_MAX_HEALTH, "1f1173-9999-3333-5555-99cb0245f9c6"), KNOCKBACK_RESISTANCE( "generic.knockbackResistance", - AttributeUT.resolve("KNOCKBACK_RESISTANCE"), + Attribute.GENERIC_KNOCKBACK_RESISTANCE, "1f1173-9999-3333-5555-99cb0245f9c7"), ; diff --git a/codex-api/src/main/java/studio/magemonkey/codex/compat/ArmorUtil.java b/codex-api/src/main/java/studio/magemonkey/codex/compat/ArmorUtil.java new file mode 100644 index 00000000..b4cbf5fc --- /dev/null +++ b/codex-api/src/main/java/studio/magemonkey/codex/compat/ArmorUtil.java @@ -0,0 +1,18 @@ +package studio.magemonkey.codex.compat; + +import org.bukkit.NamespacedKey; +import org.bukkit.inventory.meta.ItemMeta; + +public interface ArmorUtil { + // Armor trims were added in 1.19.4 + default Object getTrimMaterial(NamespacedKey key) { + return null; + } + + default Object getTrimPattern(NamespacedKey key) { + return null; + } + + default void addTrim(ItemMeta meta, String material, String pattern) { + } +} diff --git a/codex-api/src/main/java/studio/magemonkey/codex/compat/Compat.java b/codex-api/src/main/java/studio/magemonkey/codex/compat/Compat.java new file mode 100644 index 00000000..7c95e547 --- /dev/null +++ b/codex-api/src/main/java/studio/magemonkey/codex/compat/Compat.java @@ -0,0 +1,14 @@ +package studio.magemonkey.codex.compat; + +import org.bukkit.attribute.AttributeModifier; +import studio.magemonkey.codex.api.meta.NBTAttribute; + +import java.util.UUID; + +public interface Compat { + UUID ATTRIBUTE_BONUS_UUID = UUID.fromString("11f1173c-6666-4444-8888-02cb0285f9c1"); + + AttributeModifier createAttributeModifier(NBTAttribute attribute, double amount, AttributeModifier.Operation operation); + + String getAttributeKey(AttributeModifier attributeModifier); +} diff --git a/codex-api/src/main/java/studio/magemonkey/codex/compat/NMS.java b/codex-api/src/main/java/studio/magemonkey/codex/compat/NMS.java new file mode 100644 index 00000000..7e4b8a91 --- /dev/null +++ b/codex-api/src/main/java/studio/magemonkey/codex/compat/NMS.java @@ -0,0 +1,285 @@ +package studio.magemonkey.codex.compat; + +import com.mojang.authlib.GameProfile; +import com.mojang.authlib.properties.Property; +import io.netty.channel.Channel; +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.api.chat.HoverEvent; +import net.md_5.bungee.api.chat.TextComponent; +import net.md_5.bungee.api.chat.TranslatableComponent; +import org.bukkit.Material; +import org.bukkit.attribute.Attribute; +import org.bukkit.attribute.AttributeModifier; +import org.bukkit.block.Block; +import org.bukkit.entity.Boat; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.SkullMeta; +import org.bukkit.scoreboard.Objective; +import org.bukkit.scoreboard.Scoreboard; +import org.jetbrains.annotations.NotNull; +import studio.magemonkey.codex.Codex; + +import java.lang.reflect.Field; +import java.util.Collection; +import java.util.UUID; + +public interface NMS { + /** + * Gets the version of the NMS implementation + * + * @return the version of the NMS implementation + */ + String getVersion(); + + /** + * Gets the connection for the player. This is a PlayerConnection object. + * + * @param player the player to get the connection for + * @return the connection for the player + */ + @NotNull + Object getConnection(Player player); + + /** + * Gets the channel for the player + * + * @param player the player to get the channel for + * @return the channel for the player + */ + @NotNull + Channel getChannel(@NotNull Player player); + + /** + * Sends a packet to the player + * + * @param player the player to send the packet to + * @param packet the packet to send + */ + void sendPacket(@NotNull Player player, @NotNull Object packet); + + /** + * Plays the chest animation for the given block + * + * @param chest the chest block to play the animation for + * @param open true if the chest should be opened, false if it should be closed + */ + void openChestAnimation(@NotNull Block chest, boolean open); + + /** + * Simulates the player attacking + * + * @param player the player to simulate the attack for + * @param i the type of attack + */ + void sendAttackPacket(@NotNull Player player, int i); + + /** + * Attempts to parse/reparse the colors of a string to ensure consistent formatting + * + * @param str the string to fix + * @return the fixed string + */ + @NotNull + String fixColors(@NotNull String str); + + /** + * Gets the default attack damage for the given item. + * + * @param itemStack the item to get the default damage for + * @return the default attack damage for the item + */ + double getDefaultDamage(@NotNull ItemStack itemStack); + + /** + * Gets the default attack speed of the given item. + * + * @param itemStack the item to get the default speed of + * @return the default attack speed of the item + */ + double getDefaultSpeed(@NotNull ItemStack itemStack); + + /** + * Gets the default armor of the given item. + * + * @param itemStack the item to get the default armor of + * @return the default armor of the item + */ + double getDefaultArmor(@NotNull ItemStack itemStack); + + /** + * Gets the default armor toughness of the given item. + * + * @param itemStack the item to get the default toughness of + * @return the default armor toughness of the item + */ + double getDefaultToughness(@NotNull ItemStack itemStack); + + /** + * Determines if the given item is a weapon. Weapons include swords, bows, crossbows, tridents, and axes. + * + * @param itemStack the item to check + * @return true if the item is a weapon, false otherwise + */ + boolean isWeapon(@NotNull ItemStack itemStack); + + /** + * Determines if the given item is armor. Armor includes helmets, chestplates, leggings, and boots. + * + * @param itemStack the item to check + * @return true if the item is armor, false otherwise + */ + boolean isArmor(@NotNull ItemStack itemStack); + + /** + * Determines if the given item is a tool. Tools include pickaxes, axes, shovels, hoes, and shears. + * + * @param itemStack the item to check + * @return true if the item is a tool, false otherwise + */ + boolean isTool(@NotNull ItemStack itemStack); + + /** + * Gets the NBT string of the given item in JSON. + * + * @param itemStack the item to get the NBT string of + * @return the NBT string of the item + */ + String toJson(@NotNull ItemStack itemStack); + + void setKiller(@NotNull LivingEntity entity, @NotNull Player killer); + + void changeSkull(@NotNull Block block, @NotNull String hash); + + default void addSkullTexture(@NotNull ItemStack item, @NotNull String value, @NotNull UUID uuid) { + if (item.getType() != Material.PLAYER_HEAD) return; + + SkullMeta meta = (SkullMeta) item.getItemMeta(); + if (meta == null) return; + + try { + GameProfile profile = new GameProfile(uuid, uuid.toString().substring(0, 16)); + profile.getProperties().put("textures", new Property("textures", value)); + getField(meta.getClass(), "profile").set(meta, profile); + } catch (IllegalAccessException | NoSuchFieldException setException) { + Codex.warn("Could not set player skull texture. " + setException.getMessage()); + } + + item.setItemMeta(meta); + } + + default GameProfile getNonPlayerProfile(String hash) { + UUID uid = UUID.randomUUID(); + GameProfile profile = new GameProfile(uid, uid.toString().substring(0, 8)); + profile.getProperties().put("textures", new Property("textures", hash)); + + return profile; + } + + default double getAttributeValue(@NotNull ItemStack item, @NotNull Attribute attribute) { + ItemMeta meta = item.getItemMeta(); + if (meta == null) return 0; + if (meta.getAttributeModifiers() == null || meta.getAttributeModifiers().isEmpty()) return 0; + + Collection modifiers = meta.getAttributeModifiers(attribute); + if (modifiers == null || modifiers.isEmpty()) return 0; + + return modifiers.stream().mapToDouble(AttributeModifier::getAmount).sum(); + } + + @NotNull + default Attribute getAttribute(String name) { + Attribute attr = null; + try { + attr = Attribute.valueOf(name); + } catch (IllegalArgumentException ignored) { + } + if (attr == null) { + // Try with GENERIC_ prefix + try { + attr = Attribute.valueOf("GENERIC_" + name); + } catch (IllegalArgumentException ignored) { + } + } + + if (attr == null) { + // Try with PLAYER_ prefix + try { + attr = Attribute.valueOf("PLAYER_" + name); + } catch (IllegalArgumentException ignored) { + } + } + + if (attr == null) { + // Throw an exception if the attribute is still null + throw new IllegalArgumentException("Unknown attribute: " + name); + } + + return attr; + } + + Object getNMSCopy(@NotNull ItemStack itemStack); + + Material getMaterial(Boat boat); + + @SuppressWarnings("deprecation") + default HoverEvent getHoverEvent(@NotNull ItemStack itemStack) { + String json = toJson(itemStack); + if (json != null) { + new HoverEvent(HoverEvent.Action.SHOW_ITEM, TextComponent.fromLegacyText(json)); + } + + return new HoverEvent(HoverEvent.Action.SHOW_ITEM, new BaseComponent[0]); + } + + default Objective registerNewObjective(Scoreboard scoreboard, Objective objective) { + return scoreboard.registerNewObjective(objective.getName(), objective.getCriteria(), objective.getDisplayName()); + } + + default BaseComponent getTranslatedComponent(@NotNull ItemStack itemStack) { + ItemMeta meta = itemStack.getItemMeta(); + String string = null; + if (meta != null) { + string = meta.getDisplayName(); + if (string.isEmpty() && meta.hasLocalizedName()) { + string = meta.getLocalizedName(); + } + } + BaseComponent baseComponent; + if (string == null || string.isEmpty()) { + String id = itemStack.getType().getKey().getKey(); + if (itemStack.getType().isBlock()) { + id = "block.minecraft" + id; + } else if (itemStack.getType().isItem()) { + id = "item.minecraft" + id; + } + baseComponent = new TranslatableComponent(id); + } else { + baseComponent = new TextComponent(string); + } + + return baseComponent; + } + + default EntityDamageByEntityEvent createEntityDamageEvent(@NotNull Entity entity, @NotNull Entity attacker, @NotNull EntityDamageEvent.DamageCause cause, double damage) { + return new EntityDamageByEntityEvent(attacker, entity, cause, damage); + } + + @NotNull + default Field getField(@NotNull Class clazz, @NotNull String fieldName) throws NoSuchFieldException { + try { + return clazz.getDeclaredField(fieldName); + } catch (NoSuchFieldException e) { + Class superClass = clazz.getSuperclass(); + if (superClass == null) { + throw e; + } + return getField(superClass, fieldName); + } + } +} diff --git a/codex-api/src/main/java/studio/magemonkey/codex/compat/VersionManager.java b/codex-api/src/main/java/studio/magemonkey/codex/compat/VersionManager.java new file mode 100644 index 00000000..6eb670d6 --- /dev/null +++ b/codex-api/src/main/java/studio/magemonkey/codex/compat/VersionManager.java @@ -0,0 +1,79 @@ +package studio.magemonkey.codex.compat; + +import lombok.Setter; +import org.bukkit.Bukkit; +import studio.magemonkey.codex.api.exception.UnsupportedVersionException; +import studio.magemonkey.codex.core.Version; + +public class VersionManager { + @Setter + protected static NMS nms; + @Setter + private static ArmorUtil armorUtil; + @Setter + private static Compat compat; + + public static void setup() { + if (Version.CURRENT == Version.TEST) return; + String version = Bukkit.getServer().getBukkitVersion().split("-")[0]; + + try { + String packageName = getPackageFromVersion(version); + VersionManager.setNms((NMS) Class.forName("studio.magemonkey.codex.nms." + packageName + ".NMSImpl").getConstructor().newInstance()); + + try { + VersionManager.setArmorUtil((ArmorUtil) Class.forName("studio.magemonkey.codex.nms." + packageName + ".ArmorUtilImpl").getConstructor().newInstance()); + } catch (ClassNotFoundException ignored) { + // ArmorUtil is not implemented for this version -- (pre 1.19.4) + VersionManager.setArmorUtil(new ArmorUtil() { + }); + } + + VersionManager.setCompat((Compat) Class.forName("studio.magemonkey.codex.nms." + packageName + ".CompatImpl").getConstructor().newInstance()); + } catch (Exception e) { + throw new UnsupportedVersionException("Could not find NMS implementation for version " + version, e); + } + } + + private static String getPackageFromVersion(String version) { + return switch (version) { + case "1.18", "1.18.1", "1.19", "1.19.1", "1.19.2", "1.19.3", "1.20", "1.20.1" -> + throw new UnsupportedVersionException("Version " + version + " is not supported. Please upgrade to the latest minor version of your current major version."); + case "1.16.5" -> "v1_16_5"; + case "1.17", "1.17.1" -> "v1_17"; + case "1.18.2" -> "v1_18_2"; + case "1.19.4" -> "v1_19_4"; + case "1.20.2" -> "v1_20_2"; + case "1.20.3", "1.20.4" -> "v1_20_4"; + case "1.20.5", "1.20.6" -> "v1_20_6"; + case "1.21", "1.21.1" -> "v1_21_1"; + case "1.21.2", "1.21.3" -> "v1_21_2"; + case "1.21.4" -> "v1_21_4"; + default -> throw new UnsupportedVersionException("Unknown version " + version); + }; + } + + public static NMS getNms() { + if (nms == null) { + throw new RuntimeException("NMS has not been set yet! Something is wrong."); + } + + return nms; + } + + public static ArmorUtil getArmorUtil() { + if (armorUtil == null) { + throw new RuntimeException("ArmorUtil has not been set yet! Something is wrong."); + } + + return armorUtil; + } + + public static Compat getCompat() { + if (compat == null) { + throw new RuntimeException("Compat has not been set yet! Something is wrong."); + } + + return compat; + } +} diff --git a/src/main/java/studio/magemonkey/codex/config/ResourceExtractor.java b/codex-api/src/main/java/studio/magemonkey/codex/config/ResourceExtractor.java similarity index 80% rename from src/main/java/studio/magemonkey/codex/config/ResourceExtractor.java rename to codex-api/src/main/java/studio/magemonkey/codex/config/ResourceExtractor.java index 1ac3e716..653b1155 100644 --- a/src/main/java/studio/magemonkey/codex/config/ResourceExtractor.java +++ b/codex-api/src/main/java/studio/magemonkey/codex/config/ResourceExtractor.java @@ -14,29 +14,28 @@ import java.util.jar.JarFile; public final class ResourceExtractor { + private final JavaPlugin plugin; + private final File extractFolder; - protected final JavaPlugin plugin; - protected final File extractfolder; - - protected final String folderpath; - protected final String regex; + private final String folderPath; + private final String regex; /** * You can extract complete folders of resources from your plugin jar to a target folder. You * can append a regex to match the file names. * * @param plugin The plugin the files will be extracted from. - * @param extractfolder The folder where the files will be extracted to. - * @param folderpath The path where the files are inside in the jar located. + * @param extractFolder The folder where the files will be extracted to. + * @param folderPath The path where the files are inside in the jar located. * @param regex A regex to match the file names. This can be 'null' if you don't want to use it. */ - public ResourceExtractor(JavaPlugin plugin, File extractfolder, String folderpath, String regex) { + public ResourceExtractor(JavaPlugin plugin, File extractFolder, String folderPath, String regex) { Validate.notNull(plugin, "The plugin cannot be null!"); Validate.notNull(plugin, "The extract folder cannot be null!"); Validate.notNull(plugin, "The folder path cannot be null!"); - this.extractfolder = extractfolder; - this.folderpath = folderpath; + this.extractFolder = extractFolder; + this.folderPath = folderPath; this.plugin = plugin; this.regex = regex; } @@ -64,10 +63,10 @@ public void extract(boolean override) throws IOException { * Starts extracting the files. * * @param override Whether you want to override the old files. - * @param subpaths Whether you want to create sub folders if it's also found in the jar file. + * @param subPaths Whether you want to create sub folders if it's also found in the jar file. * @throws IOException */ - public void extract(boolean override, boolean subpaths) throws IOException { + public void extract(boolean override, boolean subPaths) throws IOException { File jarfile = null; /* @@ -85,8 +84,8 @@ public void extract(boolean override, boolean subpaths) throws IOException { /* * Make the folders if missing. */ - if (!this.extractfolder.exists()) { - this.extractfolder.mkdirs(); + if (!this.extractFolder.exists()) { + this.extractFolder.mkdirs(); } JarFile jar = new JarFile(jarfile); @@ -102,13 +101,13 @@ public void extract(boolean override, boolean subpaths) throws IOException { /* * Not in the folder. */ - if (!path.startsWith(this.folderpath)) { + if (!path.startsWith(this.folderPath)) { continue; } if (entry.isDirectory()) { - if (subpaths) { - File file = new File(this.extractfolder, entry.getName().replaceFirst(this.folderpath, "")); + if (subPaths) { + File file = new File(this.extractFolder, entry.getName().replaceFirst(this.folderPath, "")); if (!file.exists()) { file.mkdirs(); } @@ -127,10 +126,10 @@ public void extract(boolean override, boolean subpaths) throws IOException { /* * Use the right path. */ - if (subpaths) { - file = new File(this.extractfolder, path.replaceFirst(this.folderpath, "")); + if (subPaths) { + file = new File(this.extractFolder, path.replaceFirst(this.folderPath, "")); } else { - file = new File(this.extractfolder, path.substring(path.indexOf(File.separatorChar))); + file = new File(this.extractFolder, path.substring(path.indexOf(File.separatorChar))); } String name = file.getName(); diff --git a/src/main/java/studio/magemonkey/codex/core/Version.java b/codex-api/src/main/java/studio/magemonkey/codex/core/Version.java similarity index 95% rename from src/main/java/studio/magemonkey/codex/core/Version.java rename to codex-api/src/main/java/studio/magemonkey/codex/core/Version.java index b97f0dad..6906e35e 100644 --- a/src/main/java/studio/magemonkey/codex/core/Version.java +++ b/codex-api/src/main/java/studio/magemonkey/codex/core/Version.java @@ -20,7 +20,8 @@ public enum Version { V1_20_R3, V1_20_R4, V1_21_R1, - V1_21_R2; + V1_21_R2, + V1_21_R3; public static final Version CURRENT; @@ -38,6 +39,7 @@ else if (versionRaw.equals("craftbukkit")) { case "1.20.6-R0.1-SNAPSHOT" -> Version.V1_20_R4; case "1.21-R0.1-SNAPSHOT", "1.21.1-R0.1-SNAPSHOT" -> Version.V1_21_R1; case "1.21.2-R0.1-SNAPSHOT", "1.21.3-R0.1-SNAPSHOT" -> Version.V1_21_R2; + case "1.21.4-R0.1-SNAPSHOT" -> Version.V1_21_R3; default -> throw new IllegalStateException("Unexpected version: " + version); }; } else diff --git a/src/main/java/studio/magemonkey/codex/hooks/HookState.java b/codex-api/src/main/java/studio/magemonkey/codex/hooks/HookState.java similarity index 99% rename from src/main/java/studio/magemonkey/codex/hooks/HookState.java rename to codex-api/src/main/java/studio/magemonkey/codex/hooks/HookState.java index c626797f..abc53f43 100644 --- a/src/main/java/studio/magemonkey/codex/hooks/HookState.java +++ b/codex-api/src/main/java/studio/magemonkey/codex/hooks/HookState.java @@ -3,7 +3,6 @@ import org.jetbrains.annotations.NotNull; public enum HookState { - SUCCESS("Success!"), ERROR("Error!"), ; diff --git a/src/main/java/studio/magemonkey/codex/legacy/placeholder/ArgPlaceholderData.java b/codex-api/src/main/java/studio/magemonkey/codex/legacy/placeholder/ArgPlaceholderData.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/legacy/placeholder/ArgPlaceholderData.java rename to codex-api/src/main/java/studio/magemonkey/codex/legacy/placeholder/ArgPlaceholderData.java diff --git a/src/main/java/studio/magemonkey/codex/legacy/placeholder/BasePlaceholderData.java b/codex-api/src/main/java/studio/magemonkey/codex/legacy/placeholder/BasePlaceholderData.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/legacy/placeholder/BasePlaceholderData.java rename to codex-api/src/main/java/studio/magemonkey/codex/legacy/placeholder/BasePlaceholderData.java diff --git a/src/main/java/studio/magemonkey/codex/legacy/placeholder/BasePlaceholderItem.java b/codex-api/src/main/java/studio/magemonkey/codex/legacy/placeholder/BasePlaceholderItem.java similarity index 99% rename from src/main/java/studio/magemonkey/codex/legacy/placeholder/BasePlaceholderItem.java rename to codex-api/src/main/java/studio/magemonkey/codex/legacy/placeholder/BasePlaceholderItem.java index f43ff920..6095c727 100644 --- a/src/main/java/studio/magemonkey/codex/legacy/placeholder/BasePlaceholderItem.java +++ b/codex-api/src/main/java/studio/magemonkey/codex/legacy/placeholder/BasePlaceholderItem.java @@ -41,7 +41,7 @@ class BasePlaceholderItem implements PlaceholderItem { protected final Function func; /** - * Construct new placeholder item, using given type and functiom. + * Construct new placeholder item, using given type and function. * * @param type type of placeholder, like that "player" in player.name. * @param id id/name of placeholder, like that "name" in player.name. diff --git a/src/main/java/studio/magemonkey/codex/legacy/placeholder/GlobalPlaceholderItem.java b/codex-api/src/main/java/studio/magemonkey/codex/legacy/placeholder/GlobalPlaceholderItem.java similarity index 99% rename from src/main/java/studio/magemonkey/codex/legacy/placeholder/GlobalPlaceholderItem.java rename to codex-api/src/main/java/studio/magemonkey/codex/legacy/placeholder/GlobalPlaceholderItem.java index 9ef1a991..dbd1bbbc 100644 --- a/src/main/java/studio/magemonkey/codex/legacy/placeholder/GlobalPlaceholderItem.java +++ b/codex-api/src/main/java/studio/magemonkey/codex/legacy/placeholder/GlobalPlaceholderItem.java @@ -41,7 +41,7 @@ class GlobalPlaceholderItem implements PlaceholderItem { protected final Function func; /** - * Construct new placeholder item, using given type and functiom. + * Construct new placeholder item, using given type and function. * * @param type type of placeholder, like that "player" in player.name. * @param id id/name of placeholder, like that "name" in player.name. diff --git a/src/main/java/studio/magemonkey/codex/legacy/placeholder/PlaceholderData.java b/codex-api/src/main/java/studio/magemonkey/codex/legacy/placeholder/PlaceholderData.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/legacy/placeholder/PlaceholderData.java rename to codex-api/src/main/java/studio/magemonkey/codex/legacy/placeholder/PlaceholderData.java diff --git a/src/main/java/studio/magemonkey/codex/legacy/placeholder/PlaceholderItem.java b/codex-api/src/main/java/studio/magemonkey/codex/legacy/placeholder/PlaceholderItem.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/legacy/placeholder/PlaceholderItem.java rename to codex-api/src/main/java/studio/magemonkey/codex/legacy/placeholder/PlaceholderItem.java diff --git a/src/main/java/studio/magemonkey/codex/legacy/placeholder/PlaceholderRegistry.java b/codex-api/src/main/java/studio/magemonkey/codex/legacy/placeholder/PlaceholderRegistry.java similarity index 95% rename from src/main/java/studio/magemonkey/codex/legacy/placeholder/PlaceholderRegistry.java rename to codex-api/src/main/java/studio/magemonkey/codex/legacy/placeholder/PlaceholderRegistry.java index 2c47edea..e38bc362 100644 --- a/src/main/java/studio/magemonkey/codex/legacy/placeholder/PlaceholderRegistry.java +++ b/codex-api/src/main/java/studio/magemonkey/codex/legacy/placeholder/PlaceholderRegistry.java @@ -15,9 +15,8 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.java.JavaPlugin; -import studio.magemonkey.codex.CodexPlugin; +import studio.magemonkey.codex.compat.VersionManager; import studio.magemonkey.codex.util.EnumUT; -import studio.magemonkey.codex.util.messages.NMSPlayerUtils; public final class PlaceholderRegistry { public static final PlaceholderType LOCATION = PlaceholderType.create("location", Location.class); @@ -103,7 +102,7 @@ public static void load() { ITEM.registerItem("material", i -> { TextComponent textComponent = new TextComponent(i.getType().name().toLowerCase()); - textComponent.setHoverEvent(NMSPlayerUtils.convert(i)); + textComponent.setHoverEvent(VersionManager.getNms().getHoverEvent(i)); return textComponent; }); ITEM.registerItem("displayName", i -> @@ -113,7 +112,7 @@ public static void load() { } TextComponent textComponent = new TextComponent(i.getItemMeta().hasDisplayName() ? i.getItemMeta().getDisplayName() : ""); - textComponent.setHoverEvent(NMSPlayerUtils.convert(i)); + textComponent.setHoverEvent(VersionManager.getNms().getHoverEvent(i)); return textComponent; }); ITEM.registerItem("lore", i -> i.getItemMeta().getLore()); @@ -122,9 +121,6 @@ public static void load() { PLAYER.registerItem("exp", Player::getExp); PLAYER.registerItem("totalExperience", Player::getTotalExperience); PLAYER.registerItem("expToLevel", HumanEntity::getExpToLevel); - if (CodexPlugin.getEngine().getVault() != null) { - PLAYER.registerItem("money", player -> (int) CodexPlugin.getEngine().getVault().getBalance(player)); - } ENCHANTMENT.registerItem("id", e -> e/*.getId()*/.getKey().getKey()); //getKey used in 1.13+ ENCHANTMENT.registerItem("name", e -> e/*.getName()*/.getKey().getKey()); diff --git a/src/main/java/studio/magemonkey/codex/legacy/placeholder/PlaceholderType.java b/codex-api/src/main/java/studio/magemonkey/codex/legacy/placeholder/PlaceholderType.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/legacy/placeholder/PlaceholderType.java rename to codex-api/src/main/java/studio/magemonkey/codex/legacy/placeholder/PlaceholderType.java diff --git a/src/main/java/studio/magemonkey/codex/legacy/utils/ChatColorUtils.java b/codex-api/src/main/java/studio/magemonkey/codex/legacy/utils/ChatColorUtils.java similarity index 92% rename from src/main/java/studio/magemonkey/codex/legacy/utils/ChatColorUtils.java rename to codex-api/src/main/java/studio/magemonkey/codex/legacy/utils/ChatColorUtils.java index 57194935..9f6eac72 100644 --- a/src/main/java/studio/magemonkey/codex/legacy/utils/ChatColorUtils.java +++ b/codex-api/src/main/java/studio/magemonkey/codex/legacy/utils/ChatColorUtils.java @@ -1,6 +1,5 @@ package studio.magemonkey.codex.legacy.utils; - import com.google.common.collect.Sets; import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.chat.BaseComponent; @@ -12,11 +11,7 @@ public class ChatColorUtils { public static final char COLOR_CHAR = '\u00A7'; public static final char DEFAULT_ALTERNATE_COLOR_CHAR = '&'; private static final Pattern STRIP_COLOR_PATTERN; - private static final Set styles = Sets.newHashSet(ChatColor.UNDERLINE, - ChatColor.BOLD, - ChatColor.STRIKETHROUGH, - ChatColor.MAGIC, - ChatColor.ITALIC); + private static final Set styles = Sets.newHashSet(ChatColor.UNDERLINE, ChatColor.BOLD, ChatColor.STRIKETHROUGH, ChatColor.MAGIC, ChatColor.ITALIC); public static ChatColor getByChar(final char code) { return ChatColor.getByChar(code); @@ -34,8 +29,7 @@ public static BaseComponent[] translateAlternateColorCodes(final char altColorCh } public static BaseComponent[] translateAlternateColorCodes(final String textToTranslate) { - return ComponentUtils.fromLegacyText(translateAlternateColorCodesInString(DEFAULT_ALTERNATE_COLOR_CHAR, - textToTranslate)); + return ComponentUtils.fromLegacyText(translateAlternateColorCodesInString(DEFAULT_ALTERNATE_COLOR_CHAR, textToTranslate)); } public static String translateAlternateColorCodesInString(final char altColorChar, final String textToTranslate) { diff --git a/src/main/java/studio/magemonkey/codex/legacy/utils/ComponentUtils.java b/codex-api/src/main/java/studio/magemonkey/codex/legacy/utils/ComponentUtils.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/legacy/utils/ComponentUtils.java rename to codex-api/src/main/java/studio/magemonkey/codex/legacy/utils/ComponentUtils.java diff --git a/src/main/java/studio/magemonkey/codex/manager/AbstractListener.java b/codex-api/src/main/java/studio/magemonkey/codex/manager/AbstractListener.java similarity index 71% rename from src/main/java/studio/magemonkey/codex/manager/AbstractListener.java rename to codex-api/src/main/java/studio/magemonkey/codex/manager/AbstractListener.java index 0feea7a4..2c7c74fb 100644 --- a/src/main/java/studio/magemonkey/codex/manager/AbstractListener.java +++ b/codex-api/src/main/java/studio/magemonkey/codex/manager/AbstractListener.java @@ -5,9 +5,9 @@ public interface AbstractListener extends Listener { - public void registerListeners(); + void registerListeners(); - public default void unregisterListeners() { + default void unregisterListeners() { HandlerList.unregisterAll(this); } } diff --git a/src/main/java/studio/magemonkey/codex/manager/IListener.java b/codex-api/src/main/java/studio/magemonkey/codex/manager/IListener.java similarity index 55% rename from src/main/java/studio/magemonkey/codex/manager/IListener.java rename to codex-api/src/main/java/studio/magemonkey/codex/manager/IListener.java index 5ea0d344..34f581ec 100644 --- a/src/main/java/studio/magemonkey/codex/manager/IListener.java +++ b/codex-api/src/main/java/studio/magemonkey/codex/manager/IListener.java @@ -1,10 +1,9 @@ package studio.magemonkey.codex.manager; +import org.bukkit.plugin.java.JavaPlugin; import org.jetbrains.annotations.NotNull; -import studio.magemonkey.codex.CodexPlugin; - -public abstract class IListener

> implements AbstractListener { +public abstract class IListener

implements AbstractListener { @NotNull public final P plugin; @@ -14,6 +13,6 @@ public IListener(@NotNull P plugin) { @Override public void registerListeners() { - this.plugin.getPluginManager().registerEvents(this, this.plugin); + this.plugin.getServer().getPluginManager().registerEvents(this, this.plugin); } } diff --git a/src/main/java/studio/magemonkey/codex/manager/IManager.java b/codex-api/src/main/java/studio/magemonkey/codex/manager/IManager.java similarity index 59% rename from src/main/java/studio/magemonkey/codex/manager/IManager.java rename to codex-api/src/main/java/studio/magemonkey/codex/manager/IManager.java index 582a23e8..fa7a6ef2 100644 --- a/src/main/java/studio/magemonkey/codex/manager/IManager.java +++ b/codex-api/src/main/java/studio/magemonkey/codex/manager/IManager.java @@ -1,11 +1,10 @@ package studio.magemonkey.codex.manager; +import org.bukkit.plugin.java.JavaPlugin; import org.jetbrains.annotations.NotNull; -import studio.magemonkey.codex.CodexPlugin; import studio.magemonkey.codex.manager.api.Loadable; -public abstract class IManager

> extends IListener

implements Loadable { - +public abstract class IManager

extends IListener

implements Loadable { public IManager(@NotNull P plugin) { super(plugin); } diff --git a/src/main/java/studio/magemonkey/codex/manager/api/Cleanable.java b/codex-api/src/main/java/studio/magemonkey/codex/manager/api/Cleanable.java similarity index 74% rename from src/main/java/studio/magemonkey/codex/manager/api/Cleanable.java rename to codex-api/src/main/java/studio/magemonkey/codex/manager/api/Cleanable.java index f13ac382..cf688122 100644 --- a/src/main/java/studio/magemonkey/codex/manager/api/Cleanable.java +++ b/codex-api/src/main/java/studio/magemonkey/codex/manager/api/Cleanable.java @@ -1,6 +1,5 @@ package studio.magemonkey.codex.manager.api; public interface Cleanable { - - public void clear(); + void clear(); } diff --git a/src/main/java/studio/magemonkey/codex/manager/types/ClickType.java b/codex-api/src/main/java/studio/magemonkey/codex/manager/api/ClickType.java similarity index 95% rename from src/main/java/studio/magemonkey/codex/manager/types/ClickType.java rename to codex-api/src/main/java/studio/magemonkey/codex/manager/api/ClickType.java index 31feef69..d9c4d16e 100644 --- a/src/main/java/studio/magemonkey/codex/manager/types/ClickType.java +++ b/codex-api/src/main/java/studio/magemonkey/codex/manager/api/ClickType.java @@ -1,11 +1,10 @@ -package studio.magemonkey.codex.manager.types; +package studio.magemonkey.codex.manager.api; import org.bukkit.event.block.Action; import org.bukkit.event.inventory.InventoryClickEvent; import org.jetbrains.annotations.NotNull; public enum ClickType { - LEFT, RIGHT, MIDDLE, diff --git a/src/main/java/studio/magemonkey/codex/manager/api/Loadable.java b/codex-api/src/main/java/studio/magemonkey/codex/manager/api/Loadable.java similarity index 82% rename from src/main/java/studio/magemonkey/codex/manager/api/Loadable.java rename to codex-api/src/main/java/studio/magemonkey/codex/manager/api/Loadable.java index af3c65fd..613cf638 100644 --- a/src/main/java/studio/magemonkey/codex/manager/api/Loadable.java +++ b/codex-api/src/main/java/studio/magemonkey/codex/manager/api/Loadable.java @@ -1,12 +1,11 @@ package studio.magemonkey.codex.manager.api; public interface Loadable { - void setup(); void shutdown(); - public default void reload() { + default void reload() { this.shutdown(); this.setup(); } diff --git a/codex-api/src/main/java/studio/magemonkey/codex/manager/api/Loggable.java b/codex-api/src/main/java/studio/magemonkey/codex/manager/api/Loggable.java new file mode 100644 index 00000000..f03ccca0 --- /dev/null +++ b/codex-api/src/main/java/studio/magemonkey/codex/manager/api/Loggable.java @@ -0,0 +1,11 @@ +package studio.magemonkey.codex.manager.api; + +import org.jetbrains.annotations.NotNull; + +public interface Loggable { + void info(@NotNull String msg); + + void warn(@NotNull String msg); + + void error(@NotNull String msg); +} diff --git a/src/main/java/studio/magemonkey/codex/manager/types/MobGroup.java b/codex-api/src/main/java/studio/magemonkey/codex/manager/api/MobGroup.java similarity index 93% rename from src/main/java/studio/magemonkey/codex/manager/types/MobGroup.java rename to codex-api/src/main/java/studio/magemonkey/codex/manager/api/MobGroup.java index 40622eef..f300947c 100644 --- a/src/main/java/studio/magemonkey/codex/manager/types/MobGroup.java +++ b/codex-api/src/main/java/studio/magemonkey/codex/manager/api/MobGroup.java @@ -1,4 +1,4 @@ -package studio.magemonkey.codex.manager.types; +package studio.magemonkey.codex.manager.api; import org.bukkit.entity.*; import org.jetbrains.annotations.NotNull; diff --git a/src/main/java/studio/magemonkey/codex/manager/api/gui/ContentType.java b/codex-api/src/main/java/studio/magemonkey/codex/manager/api/gui/ContentType.java similarity index 99% rename from src/main/java/studio/magemonkey/codex/manager/api/gui/ContentType.java rename to codex-api/src/main/java/studio/magemonkey/codex/manager/api/gui/ContentType.java index eaa2c4f6..82d9dd7b 100644 --- a/src/main/java/studio/magemonkey/codex/manager/api/gui/ContentType.java +++ b/codex-api/src/main/java/studio/magemonkey/codex/manager/api/gui/ContentType.java @@ -1,7 +1,6 @@ package studio.magemonkey.codex.manager.api.gui; public enum ContentType { - NEXT, BACK, EXIT, diff --git a/src/main/java/studio/magemonkey/codex/manager/api/gui/GuiClick.java b/codex-api/src/main/java/studio/magemonkey/codex/manager/api/gui/GuiClick.java similarity index 99% rename from src/main/java/studio/magemonkey/codex/manager/api/gui/GuiClick.java rename to codex-api/src/main/java/studio/magemonkey/codex/manager/api/gui/GuiClick.java index 86bdb4c6..055dbad5 100644 --- a/src/main/java/studio/magemonkey/codex/manager/api/gui/GuiClick.java +++ b/codex-api/src/main/java/studio/magemonkey/codex/manager/api/gui/GuiClick.java @@ -6,6 +6,5 @@ import org.jetbrains.annotations.Nullable; public interface GuiClick { - void click(@NotNull Player p, @Nullable Enum type, @NotNull InventoryClickEvent e); } diff --git a/src/main/java/studio/magemonkey/codex/manager/api/gui/JIcon.java b/codex-api/src/main/java/studio/magemonkey/codex/manager/api/gui/JIcon.java similarity index 95% rename from src/main/java/studio/magemonkey/codex/manager/api/gui/JIcon.java rename to codex-api/src/main/java/studio/magemonkey/codex/manager/api/gui/JIcon.java index 04dee8b3..a31fa4c4 100644 --- a/src/main/java/studio/magemonkey/codex/manager/api/gui/JIcon.java +++ b/codex-api/src/main/java/studio/magemonkey/codex/manager/api/gui/JIcon.java @@ -1,6 +1,7 @@ package studio.magemonkey.codex.manager.api.gui; import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; import org.bukkit.event.inventory.InventoryClickEvent; @@ -8,14 +9,12 @@ import org.bukkit.inventory.meta.ItemMeta; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import studio.magemonkey.codex.util.NamespaceResolver; import studio.magemonkey.codex.util.StringUT; import java.util.ArrayList; import java.util.List; public class JIcon { - private final Material m; private final int amount; private String name; @@ -130,7 +129,7 @@ public ItemStack build() { meta.setLore(this.lore); } if (this.enchanted) { - meta.addEnchant(NamespaceResolver.getEnchantment("POWER", "ARROW_DAMAGE"), 1, true); + meta.addEnchant(Enchantment.ARROW_DAMAGE, 1, true); } //meta.addItemFlags(ItemFlag.values()); this.item.setItemMeta(meta); diff --git a/src/main/java/studio/magemonkey/codex/manager/api/menu/FileExplorerMenu.java b/codex-api/src/main/java/studio/magemonkey/codex/manager/api/menu/FileExplorerMenu.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/manager/api/menu/FileExplorerMenu.java rename to codex-api/src/main/java/studio/magemonkey/codex/manager/api/menu/FileExplorerMenu.java diff --git a/src/main/java/studio/magemonkey/codex/manager/api/menu/Menu.java b/codex-api/src/main/java/studio/magemonkey/codex/manager/api/menu/Menu.java similarity index 94% rename from src/main/java/studio/magemonkey/codex/manager/api/menu/Menu.java rename to codex-api/src/main/java/studio/magemonkey/codex/manager/api/menu/Menu.java index 77ed92d0..76ec2ea0 100644 --- a/src/main/java/studio/magemonkey/codex/manager/api/menu/Menu.java +++ b/codex-api/src/main/java/studio/magemonkey/codex/manager/api/menu/Menu.java @@ -1,5 +1,6 @@ package studio.magemonkey.codex.manager.api.menu; +import lombok.Getter; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Material; @@ -14,8 +15,8 @@ import org.bukkit.scheduler.BukkitTask; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import studio.magemonkey.codex.CodexEngine; -import studio.magemonkey.codex.util.ItemUT; +import studio.magemonkey.codex.Codex; +import studio.magemonkey.codex.compat.VersionManager; import studio.magemonkey.codex.util.StringUT; import java.util.*; @@ -34,8 +35,10 @@ public abstract class Menu implements InventoryHolder { protected final TreeMap slots = new TreeMap<>(); private final Set listeners = new HashSet<>(); private final Set tasks = new HashSet<>(); + @Getter private int page = 0; protected Menu parentMenu; + @Getter protected boolean opening = false; protected boolean fakeClosing = false; @@ -60,8 +63,6 @@ public int getPages() { } } - public int getPage() {return page;} - public void setSlot(int i, @Nullable Slot slot) { if (slot == null) { slots.remove(i); @@ -82,7 +83,7 @@ public void openSync() { new BukkitRunnable() { @Override public void run() {open();} - }.runTask(CodexEngine.get()); + }.runTask(Codex.getPlugin()); } public void open() {open(this.page);} @@ -120,8 +121,6 @@ public void openSubMenu(Menu menu) { this.opening = false; } - public boolean isOpening() {return opening;} - public void close() { close(1); } @@ -133,7 +132,7 @@ public void close(int layers) { public void run() { player.closeInventory(); } - }.runTaskLater(CodexEngine.get(), i); + }.runTaskLater(Codex.getPlugin(), i); } } @@ -165,8 +164,8 @@ public void fakeClose() { protected Slot getPrevButton() { ItemStack itemStack = new ItemStack(Material.PLAYER_HEAD); - ItemUT.addSkullTexture(itemStack, - "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZWE0YTliNzBhMjVhMjdkODE4OWU2MGQyN2VhOGNjOTYzMmMzNmI0NjkyODE1NWRlNzc1NWYzNjZlZjA0Yzg3NyJ9fX0="); + VersionManager.getNms().addSkullTexture(itemStack, + "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZWE0YTliNzBhMjVhMjdkODE4OWU2MGQyN2VhOGNjOTYzMmMzNmI0NjkyODE1NWRlNzc1NWYzNjZlZjA0Yzg3NyJ9fX0=", UUID.randomUUID()); ItemMeta meta = itemStack.getItemMeta(); if (meta != null) { meta.setDisplayName(ChatColor.RESET + "Previous Page"); @@ -184,8 +183,9 @@ public void onLeftClick() { protected Slot getNextButton() { ItemStack itemStack = new ItemStack(Material.PLAYER_HEAD); - ItemUT.addSkullTexture(itemStack, - "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNTkxNTJjMmU5MWY0NzA0ODViZTIyMmRiNWQyYTg5NWNhZGM5MDMzMjZmNWM2NzFiZjhhNTU5MTQ5NjczYmU4MCJ9fX0="); + VersionManager.getNms().addSkullTexture(itemStack, + "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNTkxNTJjMmU5MWY0NzA0ODViZTIyMmRiNWQyYTg5NWNhZGM5MDMzMjZmNWM2NzFiZjhhNTU5MTQ5NjczYmU4MCJ9fX0=", + UUID.randomUUID()); ItemMeta meta = itemStack.getItemMeta(); if (meta != null) { meta.setDisplayName(ChatColor.RESET + "Next Page"); @@ -202,7 +202,7 @@ public void onLeftClick() { } public void registerListener(Listener listener) { - Bukkit.getPluginManager().registerEvents(listener, CodexEngine.get()); + Bukkit.getPluginManager().registerEvents(listener, Codex.getPlugin()); this.listeners.add(listener); } diff --git a/src/main/java/studio/magemonkey/codex/manager/api/menu/MenuManager.java b/codex-api/src/main/java/studio/magemonkey/codex/manager/api/menu/MenuManager.java similarity index 94% rename from src/main/java/studio/magemonkey/codex/manager/api/menu/MenuManager.java rename to codex-api/src/main/java/studio/magemonkey/codex/manager/api/menu/MenuManager.java index cc6c0361..9fd9d200 100644 --- a/src/main/java/studio/magemonkey/codex/manager/api/menu/MenuManager.java +++ b/codex-api/src/main/java/studio/magemonkey/codex/manager/api/menu/MenuManager.java @@ -9,14 +9,14 @@ import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.InventoryHolder; +import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.scheduler.BukkitRunnable; -import studio.magemonkey.codex.CodexEngine; import studio.magemonkey.codex.manager.IManager; import studio.magemonkey.codex.util.InventoryUtil; -public class MenuManager extends IManager { +public class MenuManager extends IManager { - public MenuManager(CodexEngine plugin) { + public MenuManager(JavaPlugin plugin) { super(plugin); } @@ -90,7 +90,7 @@ public void onInventoryClose(InventoryCloseEvent event) { public void run() { menu.onClose(); } - }.runTask(CodexEngine.get()); + }.runTask(plugin); } } } diff --git a/src/main/java/studio/magemonkey/codex/manager/api/menu/Slot.java b/codex-api/src/main/java/studio/magemonkey/codex/manager/api/menu/Slot.java similarity index 92% rename from src/main/java/studio/magemonkey/codex/manager/api/menu/Slot.java rename to codex-api/src/main/java/studio/magemonkey/codex/manager/api/menu/Slot.java index e8dde481..5daaa7b8 100644 --- a/src/main/java/studio/magemonkey/codex/manager/api/menu/Slot.java +++ b/codex-api/src/main/java/studio/magemonkey/codex/manager/api/menu/Slot.java @@ -1,10 +1,12 @@ package studio.magemonkey.codex.manager.api.menu; +import lombok.Setter; import org.bukkit.inventory.ItemStack; public class Slot { protected Integer i = null; protected Menu menu; + @Setter protected ItemStack itemStack; public Slot(ItemStack itemStack) {this.itemStack = itemStack;} // Add permission @@ -16,8 +18,6 @@ void setMenu(int i, Menu menu) { public ItemStack getItemStack() {return itemStack == null ? null : itemStack.clone();} - public void setItemStack(ItemStack itemStack) {this.itemStack = itemStack;} - public void onLeftClick() {} public void onShiftLeftClick() {onLeftClick();} diff --git a/src/main/java/studio/magemonkey/codex/manager/api/menu/YAMLListMenu.java b/codex-api/src/main/java/studio/magemonkey/codex/manager/api/menu/YAMLListMenu.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/manager/api/menu/YAMLListMenu.java rename to codex-api/src/main/java/studio/magemonkey/codex/manager/api/menu/YAMLListMenu.java diff --git a/src/main/java/studio/magemonkey/codex/manager/api/menu/YAMLMenu.java b/codex-api/src/main/java/studio/magemonkey/codex/manager/api/menu/YAMLMenu.java similarity index 97% rename from src/main/java/studio/magemonkey/codex/manager/api/menu/YAMLMenu.java rename to codex-api/src/main/java/studio/magemonkey/codex/manager/api/menu/YAMLMenu.java index ad40cc8f..d74c335e 100644 --- a/src/main/java/studio/magemonkey/codex/manager/api/menu/YAMLMenu.java +++ b/codex-api/src/main/java/studio/magemonkey/codex/manager/api/menu/YAMLMenu.java @@ -9,7 +9,7 @@ import org.bukkit.plugin.Plugin; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import studio.magemonkey.codex.util.ItemUT; +import studio.magemonkey.codex.compat.VersionManager; import studio.magemonkey.codex.util.StringUT; import java.io.File; @@ -87,7 +87,7 @@ public void reload() { ItemStack itemStack = new ItemStack(material, yamlItem.getInt("amount", 1)); String skullTexture = yamlItem.getString("skull-texture", null); if (skullTexture != null) { - ItemUT.addSkullTexture(itemStack, skullTexture); + VersionManager.getNms().addSkullTexture(itemStack, skullTexture, UUID.randomUUID()); } ItemMeta meta = itemStack.getItemMeta(); if (meta != null) { diff --git a/src/main/java/studio/magemonkey/codex/registry/attribute/AttributeProvider.java b/codex-api/src/main/java/studio/magemonkey/codex/registry/attribute/AttributeProvider.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/registry/attribute/AttributeProvider.java rename to codex-api/src/main/java/studio/magemonkey/codex/registry/attribute/AttributeProvider.java diff --git a/src/main/java/studio/magemonkey/codex/registry/attribute/AttributeRegistry.java b/codex-api/src/main/java/studio/magemonkey/codex/registry/attribute/AttributeRegistry.java similarity index 86% rename from src/main/java/studio/magemonkey/codex/registry/attribute/AttributeRegistry.java rename to codex-api/src/main/java/studio/magemonkey/codex/registry/attribute/AttributeRegistry.java index 9c805fa5..c75f85ca 100644 --- a/src/main/java/studio/magemonkey/codex/registry/attribute/AttributeRegistry.java +++ b/codex-api/src/main/java/studio/magemonkey/codex/registry/attribute/AttributeRegistry.java @@ -1,7 +1,7 @@ package studio.magemonkey.codex.registry.attribute; import org.bukkit.entity.LivingEntity; -import studio.magemonkey.codex.CodexEngine; +import studio.magemonkey.codex.Codex; import java.util.ArrayList; import java.util.List; @@ -34,9 +34,7 @@ public static double scaleAttribute(String name, LivingEntity entity, double val try { scaled = provider.scaleAttribute(name, entity, scaled); } catch (Exception e) { - CodexEngine.get() - .getLogger() - .warning("Unable to scale stat with provider: " + provider.getClass().getSimpleName()); + Codex.warn("Unable to scale stat with provider: " + provider.getClass().getSimpleName()); e.printStackTrace(); } } diff --git a/src/main/java/studio/magemonkey/codex/registry/damage/DamageRegistry.java b/codex-api/src/main/java/studio/magemonkey/codex/registry/damage/DamageRegistry.java similarity index 88% rename from src/main/java/studio/magemonkey/codex/registry/damage/DamageRegistry.java rename to codex-api/src/main/java/studio/magemonkey/codex/registry/damage/DamageRegistry.java index 19f4f767..791bed92 100644 --- a/src/main/java/studio/magemonkey/codex/registry/damage/DamageRegistry.java +++ b/codex-api/src/main/java/studio/magemonkey/codex/registry/damage/DamageRegistry.java @@ -3,14 +3,13 @@ import org.bukkit.entity.LivingEntity; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import studio.magemonkey.codex.CodexEngine; +import studio.magemonkey.codex.Codex; import java.util.HashMap; import java.util.Locale; import java.util.Map; public class DamageRegistry { - private static final Map PROVIDERS = new HashMap<>(); public static void registerProvider(DamageTypeProvider provider) { @@ -20,9 +19,7 @@ public static void registerProvider(DamageTypeProvider provider) { } PROVIDERS.put(namespace, provider); - CodexEngine.get() - .getLogger() - .info("[DamageRegistry] Successfully registered provider for " + namespace + " damage"); + Codex.info("[DamageRegistry] Successfully registered provider for " + namespace + " damage"); } public static void unregisterProvider(Class providerClass) { diff --git a/src/main/java/studio/magemonkey/codex/registry/damage/DamageTypeProvider.java b/codex-api/src/main/java/studio/magemonkey/codex/registry/damage/DamageTypeProvider.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/registry/damage/DamageTypeProvider.java rename to codex-api/src/main/java/studio/magemonkey/codex/registry/damage/DamageTypeProvider.java diff --git a/src/main/java/studio/magemonkey/codex/util/ClickText.java b/codex-api/src/main/java/studio/magemonkey/codex/util/ClickText.java similarity index 75% rename from src/main/java/studio/magemonkey/codex/util/ClickText.java rename to codex-api/src/main/java/studio/magemonkey/codex/util/ClickText.java index f6887192..cf922f8b 100644 --- a/src/main/java/studio/magemonkey/codex/util/ClickText.java +++ b/codex-api/src/main/java/studio/magemonkey/codex/util/ClickText.java @@ -1,17 +1,13 @@ package studio.magemonkey.codex.util; import net.md_5.bungee.api.chat.*; -import net.md_5.bungee.api.chat.hover.content.Item; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; -import studio.magemonkey.codex.core.Version; -import studio.magemonkey.codex.util.constants.JNumbers; +import studio.magemonkey.codex.compat.VersionManager; import studio.magemonkey.codex.util.constants.JStrings; -import studio.magemonkey.codex.util.reflection.ReflectionManager; -import java.lang.reflect.Method; import java.util.*; /** @@ -157,30 +153,14 @@ public ClickWord hint(@NotNull String... text) { return this; } - @SuppressWarnings("deprecation") @NotNull public ClickWord showItem(@NotNull ItemStack item) { - if (Version.CURRENT.isAtLeast(Version.V1_20_R4)) { - String nbt = String.format("{\"id\":\"%s\",\"count\":%d,\"components\": %s}", - item.getType().getKey().getKey(), - item.getAmount(), - item.getItemMeta() != null ? item.getItemMeta().getAsString() : "{}"); - this.hover = new HoverEvent(HoverEvent.Action.SHOW_ITEM, new BaseComponent[]{new TextComponent(nbt)}); - } else if (Version.CURRENT.isAtLeast(Version.V1_18_R2)) { - this.hover = new HoverEvent(HoverEvent.Action.SHOW_ITEM, - new Item(item.getType().getKey().getKey().toString(), - item.getAmount(), - ItemTag.ofNbt(item.getItemMeta().getAsString()))); - } else { - // 1.16.5 - 1.18.1 - // We have to serialize the nbt from the item stack by hand - this.hover = new HoverEvent(HoverEvent.Action.SHOW_ITEM, toBase(item)); - } + this.hover = VersionManager.getNms().getHoverEvent(item); return this; } private BaseComponent[] toBase(@NotNull ItemStack item) { - String json = toJson(item); + String json = VersionManager.getNms().toJson(item); if (json != null) { return TextComponent.fromLegacyText(json); } @@ -188,29 +168,6 @@ private BaseComponent[] toBase(@NotNull ItemStack item) { return new BaseComponent[0]; } - private String toJson(@NotNull ItemStack item) { - try { - Object nbtCompound = ReflectionManager.getReflectionUtil().newNBTTagCompound(); - Object nmsItem = ReflectionManager.getReflectionUtil().getNMSCopy(item); - - nbtCompound = ReflectionManager.getReflectionUtil().save(nmsItem, nbtCompound); - - Method toString = Reflex.getMethod(nbtCompound.getClass(), "toString"); - - String js = (String) Reflex.invokeMethod(toString, nbtCompound); - if (js.length() > JNumbers.JSON_MAX) { - ItemStack item2 = new ItemStack(item.getType()); - return toJson(item2); - } - - return js; - } catch (Exception e) { - e.printStackTrace(); - } - - return null; - } - @Deprecated public void showEntity(@NotNull String json) { this.hover = new HoverEvent(HoverEvent.Action.SHOW_ENTITY, toBase(json)); diff --git a/src/main/java/studio/magemonkey/codex/util/CollectionsUT.java b/codex-api/src/main/java/studio/magemonkey/codex/util/CollectionsUT.java similarity index 77% rename from src/main/java/studio/magemonkey/codex/util/CollectionsUT.java rename to codex-api/src/main/java/studio/magemonkey/codex/util/CollectionsUT.java index 53b3132e..c6ceeab3 100644 --- a/src/main/java/studio/magemonkey/codex/util/CollectionsUT.java +++ b/codex-api/src/main/java/studio/magemonkey/codex/util/CollectionsUT.java @@ -11,8 +11,8 @@ public class CollectionsUT { public static final boolean[] BOOLEANS = new boolean[]{true, false}; @NotNull - public static List> split(@NotNull List list, int targetSize) { - List> lists = new ArrayList>(); + public static List> split(@NotNull List list, int targetSize) { + List> lists = new ArrayList<>(); if (targetSize <= 0) return lists; for (int i = 0; i < list.size(); i += targetSize) { @@ -24,13 +24,7 @@ public static List> split(@NotNull List list, int @NotNull public static > Map sortByValue(@NotNull Map map) { List> list = new LinkedList<>(map.entrySet()); - Collections.sort(list, new Comparator>() { - @SuppressWarnings("null") - @Override - public int compare(Map.Entry o1, Map.Entry o2) { - return (o1.getValue()).compareTo(o2.getValue()); - } - }); + list.sort(Map.Entry.comparingByValue()); Map result = new LinkedHashMap<>(); for (Map.Entry entry : list) { @@ -43,13 +37,7 @@ public int compare(Map.Entry o1, Map.Entry o2) { @NotNull public static > Map sortByValueUpDown(@NotNull Map map) { List> list = new LinkedList<>(map.entrySet()); - Collections.sort(list, Collections.reverseOrder(new Comparator>() { - @SuppressWarnings("null") - @Override - public int compare(Map.Entry o1, Map.Entry o2) { - return (o1.getValue()).compareTo(o2.getValue()); - } - })); + list.sort(Collections.reverseOrder(Map.Entry.comparingByValue())); Map result = new LinkedHashMap<>(); for (Map.Entry entry : list) { diff --git a/src/main/java/studio/magemonkey/codex/util/DataUT.java b/codex-api/src/main/java/studio/magemonkey/codex/util/DataUT.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/DataUT.java rename to codex-api/src/main/java/studio/magemonkey/codex/util/DataUT.java diff --git a/src/main/java/studio/magemonkey/codex/util/Debugger.java b/codex-api/src/main/java/studio/magemonkey/codex/util/Debugger.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/Debugger.java rename to codex-api/src/main/java/studio/magemonkey/codex/util/Debugger.java diff --git a/src/main/java/studio/magemonkey/codex/util/DeserializationWorker.java b/codex-api/src/main/java/studio/magemonkey/codex/util/DeserializationWorker.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/DeserializationWorker.java rename to codex-api/src/main/java/studio/magemonkey/codex/util/DeserializationWorker.java diff --git a/src/main/java/studio/magemonkey/codex/util/EffectUT.java b/codex-api/src/main/java/studio/magemonkey/codex/util/EffectUT.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/EffectUT.java rename to codex-api/src/main/java/studio/magemonkey/codex/util/EffectUT.java diff --git a/codex-api/src/main/java/studio/magemonkey/codex/util/EntityUT.java b/codex-api/src/main/java/studio/magemonkey/codex/util/EntityUT.java new file mode 100644 index 00000000..220a3153 --- /dev/null +++ b/codex-api/src/main/java/studio/magemonkey/codex/util/EntityUT.java @@ -0,0 +1,38 @@ +package studio.magemonkey.codex.util; + +import org.bukkit.attribute.Attribute; +import org.bukkit.attribute.AttributeInstance; +import org.bukkit.entity.LivingEntity; +import org.bukkit.inventory.EntityEquipment; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; + +public class EntityUT { + + public static double getAttribute(@NotNull LivingEntity entity, @NotNull Attribute attribute) { + AttributeInstance ai = entity.getAttribute(attribute); + return ai == null ? 0D : ai.getValue(); + } + + public static double getAttributeBase(@NotNull LivingEntity entity, @NotNull Attribute attribute) { + AttributeInstance ai = entity.getAttribute(attribute); + return ai == null ? 0D : ai.getBaseValue(); + } + + public static ItemStack[] getEquipment(@NotNull LivingEntity entity) { + ItemStack[] items = new ItemStack[6]; + + EntityEquipment equip = entity.getEquipment(); + if (equip == null) return items; + + int aCount = 0; + for (ItemStack armor : equip.getArmorContents()) { + items[aCount++] = armor; + } + + items[4] = equip.getItemInMainHand(); + items[5] = equip.getItemInOffHand(); + + return items; + } +} diff --git a/src/main/java/studio/magemonkey/codex/util/EnumUT.java b/codex-api/src/main/java/studio/magemonkey/codex/util/EnumUT.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/EnumUT.java rename to codex-api/src/main/java/studio/magemonkey/codex/util/EnumUT.java diff --git a/src/main/java/studio/magemonkey/codex/util/FileUT.java b/codex-api/src/main/java/studio/magemonkey/codex/util/FileUT.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/FileUT.java rename to codex-api/src/main/java/studio/magemonkey/codex/util/FileUT.java diff --git a/codex-api/src/main/java/studio/magemonkey/codex/util/InventoryUtil.java b/codex-api/src/main/java/studio/magemonkey/codex/util/InventoryUtil.java new file mode 100644 index 00000000..b9be7950 --- /dev/null +++ b/codex-api/src/main/java/studio/magemonkey/codex/util/InventoryUtil.java @@ -0,0 +1,129 @@ +package studio.magemonkey.codex.util; + +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.InventoryEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryView; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; + +public class InventoryUtil { + + /** + * Gets the top inventory from an InventoryEvent's InventoryView. We do + * this here because InventoryView is an interface in 1.21+. + * Running the code here allows us to compile against an older bytecode version + * and thus allow Spigot's auto-conversion system to upgrade the bytecode to look + * for the interface instead of the class where applicable. + * + * @param event The generic InventoryEvent with an InventoryView to inspect. + * @return The top Inventory object from the event's InventoryView. + */ + public static Inventory getTopInventory(InventoryEvent event) { + InventoryView view = event.getView(); + return view.getTopInventory(); + } + + /** + * Gets the top inventory from the player's open inventory. We do + * this here because the InventoryView class is actually an interface in 1.21+. + * Running the code here allows us to compile against an older bytecode version + * and thus allow Spigot's auto-conversion system to upgrade the bytecode to look + * for the interface instead of the class where applicable. + * + * @param player The player to get the top inventory from. + * @return The top Inventory object from the player's open inventory. + */ + @NotNull + public static Inventory getTopInventory(Player player) { + InventoryView view = player.getOpenInventory(); + return view.getTopInventory(); + } + + /** + * Gets the bottom inventory from the InventoryEvent's InventoryView. We do + * this here because the InventoryView class is actually an interface in 1.21+. + * Running the code here allows us to compile against an older bytecode version + * and thus allow Spigot's auto-conversion system to upgrade the bytecode to look + * for the interface instead of the class where applicable. + * + * @param event The generic InventoryEvent with an InventoryView to inspect. + * @return The bottom Inventory object from the event's InventoryView. + */ + public static Inventory getBottomInventory(InventoryEvent event) { + InventoryView view = event.getView(); + return view.getBottomInventory(); + } + + /** + * Again, version compatibility stuff. + * + * @param event The generic InventoryEvent with an InventoryView to modify. + * @param item The ItemStack to set as the cursor in the event's InventoryView. + */ + public static void setCursor(InventoryEvent event, ItemStack item) { + InventoryView view = event.getView(); + view.setCursor(item); + } + + /** + * Sets the item in the specified slot of the player's open inventory. Doing here for compatibility. + * + * @param player the player to set the item for + * @param slot the target slot + * @param item the item to set + */ + public static void setItem(Player player, int slot, ItemStack item) { + InventoryView view = player.getOpenInventory(); + view.setItem(slot, item); + } + + /** + * In API versions 1.20.6 and earlier, InventoryView is a class. + * In versions 1.21 and later, it is an interface. + * This code is compiled against 1.16.5 to avoid runtime errors. + * The slot parameter is used to determine which Inventory object to return. + * If the slot is in the top Inventory, the top Inventory is returned. + * If the slot is in the bottom Inventory, the bottom Inventory is returned. + * If the slot is not in either Inventory, null. + * + * @param event The generic InventoryEvent with an InventoryView to inspect. + * @param slot The slot index to check in the InventoryView. + * @return The Inventory object from the event's InventoryView at the specified slot. + */ + public static Inventory getInventory(InventoryEvent event, int slot) { + InventoryView view = event.getView(); + return view.getInventory(slot); + } + + /** + * In API versions 1.20.6 and earlier, InventoryView is a class. + * In versions 1.21 and later, it is an interface. + * This code is compiled against 1.16.5 to avoid runtime errors. + * The slot parameter is used to determine which ItemStack to return. + * + * @param event The generic InventoryEvent with an InventoryView to inspect. + * @param slot The slot index to check in the InventoryView. + * @return The ItemStack from the event's InventoryView at the specified slot. + */ + public static ItemStack getItem(InventoryEvent event, int slot) { + InventoryView view = event.getView(); + return view.getItem(slot); + } + + /** + * In API versions 1.20.6 and earlier, InventoryView is a class. + * In versions 1.21 and later, it is an interface. + * This code is compiled against 1.16.5 to avoid runtime errors. + * The slot parameter is used to determine which slot index to convert. + * + * @param event The generic InventoryEvent with an InventoryView to inspect. + * @param slot The slot index to convert in the InventoryView. + * @return The converted slot index from the event's InventoryView. + */ + public static int convertSlot(InventoryEvent event, int slot) { + InventoryView view = event.getView(); + return view.convertSlot(slot); + } + +} diff --git a/src/main/java/studio/magemonkey/codex/util/LocUT.java b/codex-api/src/main/java/studio/magemonkey/codex/util/LocUT.java similarity index 78% rename from src/main/java/studio/magemonkey/codex/util/LocUT.java rename to codex-api/src/main/java/studio/magemonkey/codex/util/LocUT.java index afbf67c9..34f46934 100644 --- a/src/main/java/studio/magemonkey/codex/util/LocUT.java +++ b/codex-api/src/main/java/studio/magemonkey/codex/util/LocUT.java @@ -9,8 +9,7 @@ import org.bukkit.util.Vector; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import studio.magemonkey.codex.CodexEngine; -import studio.magemonkey.codex.core.config.CoreConfig; +import studio.magemonkey.codex.Codex; import java.util.ArrayList; import java.util.List; @@ -23,18 +22,14 @@ public static String serialize(@NotNull Location loc) { World world = loc.getWorld(); if (world == null) return null; - StringBuilder raw = new StringBuilder() - .append(loc.getX()).append(",").append(loc.getY()).append(",") - .append(loc.getZ()).append(",").append(loc.getPitch()).append(",") - .append(loc.getYaw()).append(",").append(world.getName()); - - return raw.toString(); + return loc.getX() + "," + loc.getY() + "," + + loc.getZ() + "," + loc.getPitch() + "," + + loc.getYaw() + "," + world.getName(); } @NotNull public static List serialize(@NotNull List list) { - List raw = list.stream().map(loc -> serialize(loc)).collect(Collectors.toList()); - return raw; + return list.stream().map(LocUT::serialize).collect(Collectors.toList()); } @Nullable @@ -44,7 +39,7 @@ public static Location deserialize(@NotNull String raw) { World world = Bukkit.getWorld(split[5]); if (world == null) { - CodexEngine.get().error("Invalid/Unloaded world for: '" + raw + "' location!"); + Codex.error("Invalid/Unloaded world for: '" + raw + "' location!"); return null; } @@ -69,17 +64,6 @@ public static List deserialize(@NotNull List list) { return locations; } - @NotNull - public static String getWorldName(@NotNull Location loc) { - World world = loc.getWorld(); - return world == null ? "null" : getWorldName(world); - } - - @NotNull - public static String getWorldName(@NotNull World world) { - return CoreConfig.getWorldName(world.getName()); - } - @NotNull public static Location getFirstGroundBlock(@NotNull Location loc) { return getFirstGroundBlock(loc, false); @@ -126,7 +110,7 @@ public static Location getCenter(@NotNull Location loc) { } private static double getRelativeCoord(double cord) { - return cord < 0 ? cord + 0.5 : cord + 0.5; + return cord + 0.5; } @NotNull @@ -142,8 +126,8 @@ public static Location getPointOnCircle(@NotNull Location loc, double n, double @Nullable public static BlockFace getDirection(@NotNull Entity e) { float n = e.getLocation().getYaw(); - n = Float.valueOf(n / 90.0F); - n = Float.valueOf(Math.round(n)); + n = n / 90.0F; + n = (float) Math.round(n); if ((n == -4.0F) || (n == 0.0F) || (n == 4.0F)) { return BlockFace.SOUTH; } @@ -164,15 +148,13 @@ public static Vector getDirectionTo(@NotNull Location from, @NotNull Location to Location origin = from.clone(); Vector target = to.clone().toVector(); origin.setDirection(target.subtract(origin.toVector())); - Vector vector = origin.getDirection(); - return vector; + return origin.getDirection(); } @NotNull public static List getWorldNames() { - List list = Bukkit.getWorlds().stream().map(world -> world.getName()) + return Bukkit.getWorlds().stream().map(World::getName) .collect(Collectors.toList()); - return list; } } diff --git a/src/main/java/studio/magemonkey/codex/util/MsgUT.java b/codex-api/src/main/java/studio/magemonkey/codex/util/MsgUT.java similarity index 98% rename from src/main/java/studio/magemonkey/codex/util/MsgUT.java rename to codex-api/src/main/java/studio/magemonkey/codex/util/MsgUT.java index 734ea731..c8832603 100644 --- a/src/main/java/studio/magemonkey/codex/util/MsgUT.java +++ b/codex-api/src/main/java/studio/magemonkey/codex/util/MsgUT.java @@ -161,9 +161,6 @@ public static void sendWithJSON(@NotNull CommandSender p, @NotNull String orig) String textOriginal = e.getKey()[1]; ClickText.ClickWord jsonData = e.getValue(); - //System.out.println("JS Place: " + textPlaceholder); - //System.out.println("JS Orig: " + textOriginal); - ClickText.ClickWord clickWord = clickText.createPlaceholder(textPlaceholder, textOriginal); clickWord.click = jsonData.click; clickWord.hover = jsonData.hover; diff --git a/src/main/java/studio/magemonkey/codex/util/NumberUT.java b/codex-api/src/main/java/studio/magemonkey/codex/util/NumberUT.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/NumberUT.java rename to codex-api/src/main/java/studio/magemonkey/codex/util/NumberUT.java diff --git a/src/main/java/studio/magemonkey/codex/util/PlayerUT.java b/codex-api/src/main/java/studio/magemonkey/codex/util/PlayerUT.java similarity index 95% rename from src/main/java/studio/magemonkey/codex/util/PlayerUT.java rename to codex-api/src/main/java/studio/magemonkey/codex/util/PlayerUT.java index 4e14dae3..4e000ecf 100644 --- a/src/main/java/studio/magemonkey/codex/util/PlayerUT.java +++ b/codex-api/src/main/java/studio/magemonkey/codex/util/PlayerUT.java @@ -5,6 +5,7 @@ import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; +import studio.magemonkey.codex.util.constants.ItemHelper; import java.net.InetAddress; import java.net.InetSocketAddress; @@ -134,7 +135,7 @@ public static int getExpUntilNextLevel(@NotNull Player player) { public static boolean hasEmptyInventory(@NotNull Player player) { for (ItemStack item : player.getInventory().getContents()) { - if (!ItemUT.isAir(item)) { + if (!ItemHelper.isAirOrNull(item)) { return false; } } @@ -144,7 +145,7 @@ public static boolean hasEmptyInventory(@NotNull Player player) { public static int countItem(@NotNull Player player, @NotNull ItemStack item) { int userHas = 0; for (ItemStack itemHas : player.getInventory().getContents()) { - if (!ItemUT.isAir(itemHas) && itemHas.isSimilar(item)) { + if (!ItemHelper.isAirOrNull(itemHas) && itemHas.isSimilar(item)) { userHas += itemHas.getAmount(); } } diff --git a/src/main/java/studio/magemonkey/codex/util/RangeUtil.java b/codex-api/src/main/java/studio/magemonkey/codex/util/RangeUtil.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/RangeUtil.java rename to codex-api/src/main/java/studio/magemonkey/codex/util/RangeUtil.java diff --git a/src/main/java/studio/magemonkey/codex/util/Reflex.java b/codex-api/src/main/java/studio/magemonkey/codex/util/Reflex.java similarity index 95% rename from src/main/java/studio/magemonkey/codex/util/Reflex.java rename to codex-api/src/main/java/studio/magemonkey/codex/util/Reflex.java index 3528afeb..e72edd15 100644 --- a/src/main/java/studio/magemonkey/codex/util/Reflex.java +++ b/codex-api/src/main/java/studio/magemonkey/codex/util/Reflex.java @@ -1,10 +1,9 @@ package studio.magemonkey.codex.util; -import lombok.Setter; import org.bukkit.Bukkit; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import studio.magemonkey.codex.CodexEngine; +import studio.magemonkey.codex.Codex; import java.lang.reflect.Constructor; import java.lang.reflect.Field; @@ -15,8 +14,13 @@ import java.util.Collections; import java.util.List; +/** + * This class interacts with Spigot at a reflection level. This is used to hack some things together but should ultimately be removed for a more stable solution. + * + * @deprecated Transitioning to version-specific implementations for better stability + */ +@Deprecated(since = "1.1.0") public class Reflex { - public static final String VERSION = !Bukkit.getServer().getClass().getPackage().getName().contains("mockbukkit") ? ( Integer.parseInt(Bukkit.getServer().getBukkitVersion().split("[.-]")[1]) < 20 ? Bukkit.getServer() @@ -26,10 +30,6 @@ public class Reflex { .replace(".", ",") .split(",")[3] : Bukkit.getServer().getBukkitVersion().split("-")[0]) : ""; - @Setter - private static CodexEngine engine; - - @Nullable public static Class getClass(@NotNull String path, @NotNull String name) { return getClass(path + "." + name); @@ -45,7 +45,7 @@ public static Class getClass(@NotNull String path) { try { return Class.forName(path); } catch (ClassNotFoundException e) { - engine.error("[Reflex] Class not found: " + path); + Codex.error("[Reflex] Class not found: " + path); e.printStackTrace(); return null; } diff --git a/src/main/java/studio/magemonkey/codex/util/SerializationBuilder.java b/codex-api/src/main/java/studio/magemonkey/codex/util/SerializationBuilder.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/SerializationBuilder.java rename to codex-api/src/main/java/studio/magemonkey/codex/util/SerializationBuilder.java diff --git a/src/main/java/studio/magemonkey/codex/util/SoundUT.java b/codex-api/src/main/java/studio/magemonkey/codex/util/SoundUT.java similarity index 76% rename from src/main/java/studio/magemonkey/codex/util/SoundUT.java rename to codex-api/src/main/java/studio/magemonkey/codex/util/SoundUT.java index 2c904ed1..905e1401 100644 --- a/src/main/java/studio/magemonkey/codex/util/SoundUT.java +++ b/codex-api/src/main/java/studio/magemonkey/codex/util/SoundUT.java @@ -2,9 +2,10 @@ import org.bukkit.Keyed; import org.bukkit.Sound; -import studio.magemonkey.codex.CodexEngine; +import studio.magemonkey.codex.Codex; public class SoundUT { + @SuppressWarnings("unchecked") public static Keyed getSound(String name) { try { return Sound.valueOf(name); @@ -12,7 +13,7 @@ public static Keyed getSound(String name) { try { return (Keyed) Enum.valueOf((Class) Class.forName("org.bukkit.Sound"), name); } catch (ClassNotFoundException | ClassCastException e1) { - CodexEngine.get().error("Sound not found: " + name + " " + e1.getMessage()); + Codex.error("Sound not found: " + name + " " + e1.getMessage()); } } return null; diff --git a/src/main/java/studio/magemonkey/codex/util/StringUT.java b/codex-api/src/main/java/studio/magemonkey/codex/util/StringUT.java similarity index 96% rename from src/main/java/studio/magemonkey/codex/util/StringUT.java rename to codex-api/src/main/java/studio/magemonkey/codex/util/StringUT.java index 88d8f000..a223bf60 100644 --- a/src/main/java/studio/magemonkey/codex/util/StringUT.java +++ b/codex-api/src/main/java/studio/magemonkey/codex/util/StringUT.java @@ -8,7 +8,7 @@ import org.bukkit.util.StringUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import studio.magemonkey.codex.CodexEngine; +import studio.magemonkey.codex.compat.VersionManager; import java.util.*; import java.util.regex.Matcher; @@ -90,13 +90,13 @@ public static String color(@Nullable String str) { */ @NotNull public static String colorFix(@NotNull String str) { - return CodexEngine.get().getNMS().fixColors(str); + return VersionManager.getNms().fixColors(str); } @NotNull public static String colorHex(@NotNull String str) { - Matcher matcher = HEX_PATTERN.matcher(str); - StringBuffer buffer = new StringBuffer(str.length() + 4 * 8); + Matcher matcher = HEX_PATTERN.matcher(str); + StringBuilder buffer = new StringBuilder(str.length() + 4 * 8); while (matcher.find()) { String group = matcher.group(1); matcher.appendReplacement(buffer, ChatColor.COLOR_CHAR + "x" @@ -139,7 +139,7 @@ public static String colorOff(@NotNull String str) { @NotNull public static List color(@NotNull List list) { - list.replaceAll(line -> color(line)); + list.replaceAll(StringUT::color); return list; } @@ -207,13 +207,12 @@ public static int getInteger(@NotNull String input, int def, boolean nega) { } public static int[] getIntArray(@NotNull String str) { - int[] slots = new int[1]; String[] raw = str.replaceAll("\\s", ",").replace(",,", ",").split(","); - slots = new int[raw.length]; + int[] slots = new int[raw.length]; for (int i = 0; i < raw.length; i++) { try { slots[i] = Integer.parseInt(raw[i].trim()); - } catch (NumberFormatException ex) { + } catch (NumberFormatException ignored) { } } return slots; diff --git a/src/main/java/studio/magemonkey/codex/util/Zipper.java b/codex-api/src/main/java/studio/magemonkey/codex/util/Zipper.java similarity index 94% rename from src/main/java/studio/magemonkey/codex/util/Zipper.java rename to codex-api/src/main/java/studio/magemonkey/codex/util/Zipper.java index 3620021a..c6208dcc 100644 --- a/src/main/java/studio/magemonkey/codex/util/Zipper.java +++ b/codex-api/src/main/java/studio/magemonkey/codex/util/Zipper.java @@ -13,7 +13,7 @@ public class Zipper { - private List filesListInDir = new ArrayList(); + private final List filesListInDir = new ArrayList<>(); public static void createBackupZip(File dir) { String date = new SimpleDateFormat("dd-MM-yyyy").format(new Date()); @@ -39,7 +39,7 @@ private void zipDirectory(File dir, String zipDirName) { for (String filePath : filesListInDir) { //System.out.println("Zipping " + filePath); //for ZipEntry we need to keep only relative file path, so we used substring on absolute path - ZipEntry ze = new ZipEntry(filePath.substring(dir.getAbsolutePath().length() + 1, filePath.length())); + ZipEntry ze = new ZipEntry(filePath.substring(dir.getAbsolutePath().length() + 1)); zos.putNextEntry(ze); //read the file and write to ZipOutputStream FileInputStream fis = new FileInputStream(filePath); @@ -66,6 +66,8 @@ private void zipDirectory(File dir, String zipDirName) { */ private void populateFilesList(File dir) throws IOException { File[] files = dir.listFiles(); + if (files == null) return; + for (File file : files) { if (file.isFile()) filesListInDir.add(file.getAbsolutePath()); else populateFilesList(file); diff --git a/codex-api/src/main/java/studio/magemonkey/codex/util/constants/ItemHelper.java b/codex-api/src/main/java/studio/magemonkey/codex/util/constants/ItemHelper.java new file mode 100644 index 00000000..ba808fab --- /dev/null +++ b/codex-api/src/main/java/studio/magemonkey/codex/util/constants/ItemHelper.java @@ -0,0 +1,12 @@ +package studio.magemonkey.codex.util.constants; + +import org.bukkit.inventory.ItemStack; + +public class ItemHelper { + /** + * A utility method to support versions that use null or air ItemStacks. + */ + public static boolean isAirOrNull(ItemStack item) { + return item == null || item.getType().isAir(); + } +} diff --git a/src/main/java/studio/magemonkey/codex/util/constants/JNumbers.java b/codex-api/src/main/java/studio/magemonkey/codex/util/constants/JNumbers.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/constants/JNumbers.java rename to codex-api/src/main/java/studio/magemonkey/codex/util/constants/JNumbers.java diff --git a/src/main/java/studio/magemonkey/codex/util/constants/JStrings.java b/codex-api/src/main/java/studio/magemonkey/codex/util/constants/JStrings.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/constants/JStrings.java rename to codex-api/src/main/java/studio/magemonkey/codex/util/constants/JStrings.java diff --git a/src/main/java/studio/magemonkey/codex/util/craft/CraftManager.java b/codex-api/src/main/java/studio/magemonkey/codex/util/craft/CraftManager.java similarity index 81% rename from src/main/java/studio/magemonkey/codex/util/craft/CraftManager.java rename to codex-api/src/main/java/studio/magemonkey/codex/util/craft/CraftManager.java index 7be18127..43cb2fa9 100644 --- a/src/main/java/studio/magemonkey/codex/util/craft/CraftManager.java +++ b/codex-api/src/main/java/studio/magemonkey/codex/util/craft/CraftManager.java @@ -6,9 +6,9 @@ import org.bukkit.inventory.Recipe; import org.bukkit.inventory.ShapedRecipe; import org.bukkit.inventory.ShapelessRecipe; +import org.bukkit.plugin.java.JavaPlugin; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import studio.magemonkey.codex.CodexEngine; import studio.magemonkey.codex.manager.api.Loadable; import studio.magemonkey.codex.util.craft.api.IAbstractRecipe; @@ -17,11 +17,11 @@ import java.util.Set; public class CraftManager implements Loadable { + private final JavaPlugin plugin; - private CodexEngine plugin; private Set registered; - public CraftManager(@NotNull CodexEngine engine) { + public CraftManager(@NotNull JavaPlugin engine) { this.plugin = engine; } @@ -40,17 +40,17 @@ public boolean register(@NotNull IAbstractRecipe recipe) { Recipe bukkitRecipe = recipe.getRecipe(); try { if (!this.plugin.getServer().addRecipe(bukkitRecipe)) { - this.plugin.error("Could not register recipe: '" + recipe.getId() + "': Unknown reason."); + this.plugin.getLogger().severe("Could not register recipe: '" + recipe.getId() + "': Unknown reason."); return false; } } catch (Exception ex) { - this.plugin.error("Could not register recipe: '" + recipe.getId() + "': "); + this.plugin.getLogger().severe("Could not register recipe: '" + recipe.getId() + "': "); ex.printStackTrace(); return false; } this.discoverRecipe(recipe.getKey()); - this.plugin.info("Recipe registered: '" + recipe.getId() + "' !"); + this.plugin.getLogger().info("Recipe registered: '" + recipe.getId() + "' !"); return true; } @@ -59,7 +59,7 @@ public void discoverRecipe(@NotNull NamespacedKey key) { if (player == null) continue; player.discoverRecipe(key); - //this.plugin.info("Recipe undiscover for " + p.getName() + ": " + b + " (" + key.getKey() + ")"); + //this.plugin.getLogger().info("Recipe undiscover for " + p.getName() + ": " + b + " (" + key.getKey() + ")"); } } @@ -79,7 +79,7 @@ public void unregisterAll() { NamespacedKey recipeKey = getRecipeKey(recipe); if (recipeKey != null && this.registered.remove(recipeKey)) { this.undiscoverRecipe(recipeKey); - this.plugin.info("Recipe unregistered: '" + recipeKey.getKey() + "' !"); + this.plugin.getLogger().info("Recipe unregistered: '" + recipeKey.getKey() + "' !"); iter.remove(); } } @@ -97,7 +97,7 @@ public void unregister(@NotNull String id) { NamespacedKey key = getRecipeKey(recipe); if (key != null && key.getKey().endsWith(id) && this.registered.remove(key)) { this.undiscoverRecipe(key); - this.plugin.info("Recipe unregistered: '" + id + "' !"); + this.plugin.getLogger().info("Recipe unregistered: '" + id + "' !"); iter.remove(); } } diff --git a/src/main/java/studio/magemonkey/codex/util/craft/api/IAbstractRecipe.java b/codex-api/src/main/java/studio/magemonkey/codex/util/craft/api/IAbstractRecipe.java similarity index 81% rename from src/main/java/studio/magemonkey/codex/util/craft/api/IAbstractRecipe.java rename to codex-api/src/main/java/studio/magemonkey/codex/util/craft/api/IAbstractRecipe.java index 28349a5b..054e163f 100644 --- a/src/main/java/studio/magemonkey/codex/util/craft/api/IAbstractRecipe.java +++ b/codex-api/src/main/java/studio/magemonkey/codex/util/craft/api/IAbstractRecipe.java @@ -3,19 +3,19 @@ import org.bukkit.NamespacedKey; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.Recipe; +import org.bukkit.plugin.java.JavaPlugin; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import studio.magemonkey.codex.CodexPlugin; public abstract class IAbstractRecipe { - protected final CodexPlugin plugin; - protected final String id; - protected ItemStack result; + protected final JavaPlugin plugin; + protected final String id; + protected ItemStack result; protected final NamespacedKey key; - public IAbstractRecipe(@NotNull CodexPlugin plugin, @NotNull String id, @NotNull ItemStack result) { + public IAbstractRecipe(@NotNull JavaPlugin plugin, @NotNull String id, @NotNull ItemStack result) { this.plugin = plugin; this.id = id.toLowerCase().replace(" ", "_"); this.result = result; diff --git a/src/main/java/studio/magemonkey/codex/util/craft/api/ICraftRecipe.java b/codex-api/src/main/java/studio/magemonkey/codex/util/craft/api/ICraftRecipe.java similarity index 73% rename from src/main/java/studio/magemonkey/codex/util/craft/api/ICraftRecipe.java rename to codex-api/src/main/java/studio/magemonkey/codex/util/craft/api/ICraftRecipe.java index fc729feb..7b5e90f1 100644 --- a/src/main/java/studio/magemonkey/codex/util/craft/api/ICraftRecipe.java +++ b/codex-api/src/main/java/studio/magemonkey/codex/util/craft/api/ICraftRecipe.java @@ -1,44 +1,33 @@ package studio.magemonkey.codex.util.craft.api; +import lombok.Getter; import org.bukkit.Material; import org.bukkit.NamespacedKey; import org.bukkit.inventory.*; +import org.bukkit.plugin.java.JavaPlugin; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import studio.magemonkey.codex.CodexPlugin; +@Getter public class ICraftRecipe extends IAbstractRecipe { + private final boolean shaped; + @NotNull + private final String[] shape; + private final ItemStack[] ingredients; - private boolean isShape; - private String[] shape; - private ItemStack[] ings; - - public ICraftRecipe(@NotNull CodexPlugin plugin, + public ICraftRecipe(@NotNull JavaPlugin plugin, @NotNull String id, @NotNull ItemStack result, - boolean isShape) { + boolean shaped) { super(plugin, id, result); - this.isShape = isShape; + this.shaped = shaped; this.shape = new String[]{"ABC", "DEF", "GHI"}; - this.ings = new ItemStack[(int) Math.pow(this.shape.length, 2)]; - for (int i = 0; i < this.ings.length; i++) { - this.ings[i] = new ItemStack(Material.AIR); + this.ingredients = new ItemStack[(int) Math.pow(this.shape.length, 2)]; + for (int i = 0; i < this.ingredients.length; i++) { + this.ingredients[i] = new ItemStack(Material.AIR); } } - public boolean isShaped() { - return this.isShape; - } - - public ItemStack[] getIngredients() { - return this.ings; - } - - @NotNull - public String[] getShape() { - return this.shape; - } - @Override public void addIngredient(int pos, @Nullable ItemStack item) { if (pos >= Math.pow(shape.length, 2)) { @@ -46,10 +35,9 @@ public void addIngredient(int pos, @Nullable ItemStack item) { } if (item == null) item = new ItemStack(Material.AIR); - this.ings[pos] = item; + this.ingredients[pos] = item; } - @SuppressWarnings("deprecation") @Override @NotNull public Recipe getRecipe() { diff --git a/src/main/java/studio/magemonkey/codex/util/craft/api/IFurnaceRecipe.java b/codex-api/src/main/java/studio/magemonkey/codex/util/craft/api/IFurnaceRecipe.java similarity index 79% rename from src/main/java/studio/magemonkey/codex/util/craft/api/IFurnaceRecipe.java rename to codex-api/src/main/java/studio/magemonkey/codex/util/craft/api/IFurnaceRecipe.java index 8584f2ec..6b8bfd15 100644 --- a/src/main/java/studio/magemonkey/codex/util/craft/api/IFurnaceRecipe.java +++ b/codex-api/src/main/java/studio/magemonkey/codex/util/craft/api/IFurnaceRecipe.java @@ -1,22 +1,24 @@ package studio.magemonkey.codex.util.craft.api; +import lombok.Getter; import org.bukkit.Material; import org.bukkit.NamespacedKey; import org.bukkit.inventory.FurnaceRecipe; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.Recipe; import org.bukkit.inventory.RecipeChoice; +import org.bukkit.plugin.java.JavaPlugin; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import studio.magemonkey.codex.CodexPlugin; +@Getter public class IFurnaceRecipe extends IAbstractRecipe { + @Nullable + private ItemStack input; + private final float exp; + private final int time; - private ItemStack input; - private float exp; - private int time; - - public IFurnaceRecipe(@NotNull CodexPlugin plugin, + public IFurnaceRecipe(@NotNull JavaPlugin plugin, @NotNull String id, @NotNull ItemStack result, float exp, @@ -26,18 +28,6 @@ public IFurnaceRecipe(@NotNull CodexPlugin plugin, this.time = (int) Math.max(1, 20D * time); } - @NotNull - public ItemStack getInput() { - return this.input; - } - - public float getExp() { - return this.exp; - } - - public int getTime() { - return this.time; - } public void addIngredient(@NotNull ItemStack ing) { this.addIngredient(0, ing); @@ -48,10 +38,10 @@ public void addIngredient(int slot, @Nullable ItemStack ing) { if (ing == null || ing.getType() == Material.AIR) { throw new IllegalArgumentException("Input can not be null or AIR!"); } + this.input = ing; } - @SuppressWarnings("deprecation") @Override @NotNull public Recipe getRecipe() { @@ -61,6 +51,10 @@ public Recipe getRecipe() { float exp = this.getExp(); int time = this.getTime(); + if (input == null) { + throw new RuntimeException("Recipe input is null. Recipe is invalid"); + } + if (input.hasItemMeta()) { return new FurnaceRecipe(key, result, new RecipeChoice.ExactChoice(input), exp, time); } else { diff --git a/src/main/java/studio/magemonkey/codex/util/eval/Evaluator.java b/codex-api/src/main/java/studio/magemonkey/codex/util/eval/Evaluator.java similarity index 86% rename from src/main/java/studio/magemonkey/codex/util/eval/Evaluator.java rename to codex-api/src/main/java/studio/magemonkey/codex/util/eval/Evaluator.java index 84616085..c10f66a1 100644 --- a/src/main/java/studio/magemonkey/codex/util/eval/Evaluator.java +++ b/codex-api/src/main/java/studio/magemonkey/codex/util/eval/Evaluator.java @@ -1,6 +1,6 @@ package studio.magemonkey.codex.util.eval; -import studio.magemonkey.codex.CodexEngine; +import studio.magemonkey.codex.Codex; import studio.magemonkey.codex.util.eval.javaluator.DoubleEvaluator; public class Evaluator { @@ -24,7 +24,7 @@ private static double javaluator(String exp) { try { return jl.evaluate(exp); } catch (IllegalArgumentException e) { - CodexEngine.get().error("[E1] Unable to evaluate '" + exp + "'. Trying with E0..."); + Codex.error("[E1] Unable to evaluate '" + exp + "'. Trying with E0..."); return eval(exp, 0); } } @@ -93,11 +93,13 @@ boolean eat(int charToEat) { while (ch >= 'a' && ch <= 'z') nextChar(); String func = str.substring(startPos, this.pos); x = parseFactor(); - if (func.equals("sqrt")) x = Math.sqrt(x); - else if (func.equals("sin")) x = Math.sin(Math.toRadians(x)); - else if (func.equals("cos")) x = Math.cos(Math.toRadians(x)); - else if (func.equals("tan")) x = Math.tan(Math.toRadians(x)); - else throw new RuntimeException("Unknown function: " + func); + x = switch (func) { + case "sqrt" -> Math.sqrt(x); + case "sin" -> Math.sin(Math.toRadians(x)); + case "cos" -> Math.cos(Math.toRadians(x)); + case "tan" -> Math.tan(Math.toRadians(x)); + default -> throw new RuntimeException("Unknown function: " + func); + }; } else { throw new RuntimeException("Unexpected: " + (char) ch); } diff --git a/src/main/java/studio/magemonkey/codex/util/eval/javaluator/AbstractEvaluator.java b/codex-api/src/main/java/studio/magemonkey/codex/util/eval/javaluator/AbstractEvaluator.java similarity index 99% rename from src/main/java/studio/magemonkey/codex/util/eval/javaluator/AbstractEvaluator.java rename to codex-api/src/main/java/studio/magemonkey/codex/util/eval/javaluator/AbstractEvaluator.java index 11c22378..3859ed54 100644 --- a/src/main/java/studio/magemonkey/codex/util/eval/javaluator/AbstractEvaluator.java +++ b/codex-api/src/main/java/studio/magemonkey/codex/util/eval/javaluator/AbstractEvaluator.java @@ -99,7 +99,6 @@ protected AbstractEvaluator(Parameters parameters) { * * @param operators The operators to validate. * @throws IllegalArgumentException if the homonyms are not compatibles. - * @see #guessOperator(Token, List) */ private void validateHomonyms(List operators) { if (operators.size() > 2) { diff --git a/src/main/java/studio/magemonkey/codex/util/eval/javaluator/AbstractVariableSet.java b/codex-api/src/main/java/studio/magemonkey/codex/util/eval/javaluator/AbstractVariableSet.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/eval/javaluator/AbstractVariableSet.java rename to codex-api/src/main/java/studio/magemonkey/codex/util/eval/javaluator/AbstractVariableSet.java diff --git a/src/main/java/studio/magemonkey/codex/util/eval/javaluator/BracketPair.java b/codex-api/src/main/java/studio/magemonkey/codex/util/eval/javaluator/BracketPair.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/eval/javaluator/BracketPair.java rename to codex-api/src/main/java/studio/magemonkey/codex/util/eval/javaluator/BracketPair.java diff --git a/src/main/java/studio/magemonkey/codex/util/eval/javaluator/Constant.java b/codex-api/src/main/java/studio/magemonkey/codex/util/eval/javaluator/Constant.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/eval/javaluator/Constant.java rename to codex-api/src/main/java/studio/magemonkey/codex/util/eval/javaluator/Constant.java diff --git a/src/main/java/studio/magemonkey/codex/util/eval/javaluator/DoubleEvaluator.java b/codex-api/src/main/java/studio/magemonkey/codex/util/eval/javaluator/DoubleEvaluator.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/eval/javaluator/DoubleEvaluator.java rename to codex-api/src/main/java/studio/magemonkey/codex/util/eval/javaluator/DoubleEvaluator.java diff --git a/src/main/java/studio/magemonkey/codex/util/eval/javaluator/EvaluationContext.java b/codex-api/src/main/java/studio/magemonkey/codex/util/eval/javaluator/EvaluationContext.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/eval/javaluator/EvaluationContext.java rename to codex-api/src/main/java/studio/magemonkey/codex/util/eval/javaluator/EvaluationContext.java diff --git a/src/main/java/studio/magemonkey/codex/util/eval/javaluator/Function.java b/codex-api/src/main/java/studio/magemonkey/codex/util/eval/javaluator/Function.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/eval/javaluator/Function.java rename to codex-api/src/main/java/studio/magemonkey/codex/util/eval/javaluator/Function.java diff --git a/src/main/java/studio/magemonkey/codex/util/eval/javaluator/Operator.java b/codex-api/src/main/java/studio/magemonkey/codex/util/eval/javaluator/Operator.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/eval/javaluator/Operator.java rename to codex-api/src/main/java/studio/magemonkey/codex/util/eval/javaluator/Operator.java diff --git a/src/main/java/studio/magemonkey/codex/util/eval/javaluator/Parameters.java b/codex-api/src/main/java/studio/magemonkey/codex/util/eval/javaluator/Parameters.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/eval/javaluator/Parameters.java rename to codex-api/src/main/java/studio/magemonkey/codex/util/eval/javaluator/Parameters.java diff --git a/src/main/java/studio/magemonkey/codex/util/eval/javaluator/StaticVariableSet.java b/codex-api/src/main/java/studio/magemonkey/codex/util/eval/javaluator/StaticVariableSet.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/eval/javaluator/StaticVariableSet.java rename to codex-api/src/main/java/studio/magemonkey/codex/util/eval/javaluator/StaticVariableSet.java diff --git a/src/main/java/studio/magemonkey/codex/util/eval/javaluator/Token.java b/codex-api/src/main/java/studio/magemonkey/codex/util/eval/javaluator/Token.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/eval/javaluator/Token.java rename to codex-api/src/main/java/studio/magemonkey/codex/util/eval/javaluator/Token.java diff --git a/src/main/java/studio/magemonkey/codex/util/eval/javaluator/Tokenizer.java b/codex-api/src/main/java/studio/magemonkey/codex/util/eval/javaluator/Tokenizer.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/eval/javaluator/Tokenizer.java rename to codex-api/src/main/java/studio/magemonkey/codex/util/eval/javaluator/Tokenizer.java diff --git a/codex-api/src/main/java/studio/magemonkey/codex/util/messages/AbstractMessageUtil.java b/codex-api/src/main/java/studio/magemonkey/codex/util/messages/AbstractMessageUtil.java new file mode 100644 index 00000000..d6037b54 --- /dev/null +++ b/codex-api/src/main/java/studio/magemonkey/codex/util/messages/AbstractMessageUtil.java @@ -0,0 +1,88 @@ +package studio.magemonkey.codex.util.messages; + +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.api.chat.TextComponent; +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.plugin.java.JavaPlugin; +import org.jetbrains.annotations.NotNull; +import studio.magemonkey.codex.Codex; +import studio.magemonkey.codex.bungee.BungeeUtil; + +import java.util.*; + +public abstract class AbstractMessageUtil { + protected Map messages = new HashMap<>(); + + public abstract BaseComponent[] getMessageAsComponent(String path, MessageData... replace); + + public abstract String getMessageAsString(String path, String def, boolean stripColor, MessageData... data); + + public void reload(FileConfiguration config, JavaPlugin plugin) { + Map temp = getMessages(config); + for (String s : temp.keySet()) { + messages.remove(s); + } + messages.putAll(temp); + Codex.info("Mapped all language data for " + plugin.getName() + "."); + } + + public void load(FileConfiguration config, JavaPlugin plugin) { + reload(config, plugin); + } + + private Map getMessages(@NotNull ConfigurationSection section) { + Map temp = new HashMap<>(); + + for (String entry : section.getValues(false).keySet()) { + String id = section.getCurrentPath().trim().isEmpty() ? entry : section.getCurrentPath() + "." + entry; + if (section.get(entry) instanceof ConfigurationSection) { + temp.putAll(getMessages((ConfigurationSection) section.get(entry))); + } else if (section.get(entry) instanceof ArrayList) { + temp.put(id, section.get(entry)); + } else { + if (section.get(entry).toString().contains("\n")) { + List array = new ArrayList<>(Arrays.asList(section.get(entry).toString().split("\n"))); + temp.put(id, array); + } else + temp.put(id, section.get(entry).toString()); + } + } + + return temp; + } + + public String getMessageAsString(String path, final String def, MessageData... data) { + return getMessageAsString(path, def, false, data); + } + + public void sendMessage(CommandSender player, BaseComponent... comps) { + List send = new ArrayList<>(); + for (BaseComponent component : comps) { + if (component instanceof TextComponent && ((TextComponent) component).getText().equalsIgnoreCase("\n")) { + player.spigot().sendMessage(send.toArray(new BaseComponent[0])); + send.clear(); + } else + send.add(component); + } + if (!send.isEmpty()) + player.spigot().sendMessage(send.toArray(new BaseComponent[0])); + } + + public void sendMessage(String key, CommandSender player, MessageData... replace) { + BaseComponent[] comps = getMessageAsComponent(key, replace); + sendMessage(player, comps); + } + + public void broadcastMessage(String key, MessageData... data) { + Bukkit.getServer().getOnlinePlayers().forEach(online -> sendMessage(key, online, data)); + sendMessage(key, Bukkit.getConsoleSender(), data); + } + + public void broadcastNetworkMessage(String key, MessageData... data) { + if (!BungeeUtil.isBungee()) broadcastMessage(key, data); + else BungeeUtil.broadcastMessage(getMessageAsString(key, key, false, data)); + } +} diff --git a/src/main/java/studio/magemonkey/codex/util/messages/MessageData.java b/codex-api/src/main/java/studio/magemonkey/codex/util/messages/MessageData.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/messages/MessageData.java rename to codex-api/src/main/java/studio/magemonkey/codex/util/messages/MessageData.java diff --git a/src/main/java/studio/magemonkey/codex/util/random/MTRandom.java b/codex-api/src/main/java/studio/magemonkey/codex/util/random/MTRandom.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/random/MTRandom.java rename to codex-api/src/main/java/studio/magemonkey/codex/util/random/MTRandom.java diff --git a/src/main/java/studio/magemonkey/codex/util/random/Rnd.java b/codex-api/src/main/java/studio/magemonkey/codex/util/random/Rnd.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/random/Rnd.java rename to codex-api/src/main/java/studio/magemonkey/codex/util/random/Rnd.java diff --git a/codex-api/src/test/java/studio/magemonkey/codex/api/ReplacerTest.java b/codex-api/src/test/java/studio/magemonkey/codex/api/ReplacerTest.java new file mode 100644 index 00000000..fe238e20 --- /dev/null +++ b/codex-api/src/test/java/studio/magemonkey/codex/api/ReplacerTest.java @@ -0,0 +1,34 @@ +package studio.magemonkey.codex.api; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class ReplacerTest { + private Replacer replacer; + + @BeforeEach + void setUp() { + replacer = new Replacer("from", "to"); + } + + @Test + void use() { + String str = "get this from"; + String result = replacer.use(str); + assert result.equals("get this to"); + } + + @Test + void replacer_constructedWithNullGivesStringNull() { + Replacer replacer = Replacer.replacer(null, (String) null); + assert replacer.getFrom().equals("null"); + assert replacer.getTo().equals("null"); + } + + @Test + void replacer_supplierConstructor() { + Replacer replacer = Replacer.replacer("from", () -> "to"); + assert replacer.getFrom().equals("from"); + assert replacer.getTo().equals("to"); + } +} \ No newline at end of file diff --git a/codex-bungee/pom.xml b/codex-bungee/pom.xml new file mode 100644 index 00000000..10ca45be --- /dev/null +++ b/codex-bungee/pom.xml @@ -0,0 +1,20 @@ + + + 4.0.0 + + studio.magemonkey + codex-parent + 1.1.0-R0.1-SNAPSHOT + + + codex-bungee + + + + net.md-5 + bungeecord-api + + + \ No newline at end of file diff --git a/src/main/java/studio/magemonkey/codex/bungee/BungeeCore.java b/codex-bungee/src/main/java/studio/magemonkey/codex/bungee/BungeeCore.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/bungee/BungeeCore.java rename to codex-bungee/src/main/java/studio/magemonkey/codex/bungee/BungeeCore.java diff --git a/src/main/java/studio/magemonkey/codex/bungee/BungeeListener.java b/codex-bungee/src/main/java/studio/magemonkey/codex/bungee/BungeeListener.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/bungee/BungeeListener.java rename to codex-bungee/src/main/java/studio/magemonkey/codex/bungee/BungeeListener.java diff --git a/src/main/java/studio/magemonkey/codex/bungee/BungeeUtil.java b/codex-bungee/src/main/java/studio/magemonkey/codex/bungee/BungeeUtil.java similarity index 84% rename from src/main/java/studio/magemonkey/codex/bungee/BungeeUtil.java rename to codex-bungee/src/main/java/studio/magemonkey/codex/bungee/BungeeUtil.java index ffbb392f..a8e5b7c8 100644 --- a/src/main/java/studio/magemonkey/codex/bungee/BungeeUtil.java +++ b/codex-bungee/src/main/java/studio/magemonkey/codex/bungee/BungeeUtil.java @@ -3,10 +3,12 @@ import com.google.common.collect.Iterables; import com.google.common.io.ByteArrayDataOutput; import com.google.common.io.ByteStreams; +import lombok.Getter; +import lombok.Setter; import org.bukkit.Bukkit; import org.bukkit.entity.Player; +import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.scheduler.BukkitRunnable; -import studio.magemonkey.codex.CodexEngine; import java.util.ArrayList; import java.util.List; @@ -14,13 +16,20 @@ public class BungeeUtil { - public static final String CHANNEL = "promcteam:codex"; + public static final String CHANNEL = "magemonkey:codex"; private static final List queued = new ArrayList<>(); private static boolean queueRunning = false; - static { - queue(); - } + @Getter + @Setter + private static boolean bungee = false; + @Getter + @Setter + private static String bungeeId = "server"; + + @Getter + @Setter + private static JavaPlugin plugin; public static boolean sendMessage(String... data) { return sendMessage(CHANNEL, data); @@ -36,11 +45,11 @@ public static boolean sendMessage(String channel, Player sender, String... data) } private static boolean sendMessage(String channel, UUID id, Player sender, String... data) { - if (!CodexEngine.IS_BUNGEE) return false; + if (!isBungee()) return false; ByteArrayDataOutput out = ByteStreams.newDataOutput(); out.writeUTF(id == null ? UUID.randomUUID().toString() : id.toString()); - out.writeUTF(CodexEngine.BUNGEE_ID); + out.writeUTF(getBungeeId()); // out.writeUTF(event); for (String dat : data) out.writeUTF(dat); @@ -55,7 +64,7 @@ private static boolean sendMessage(String channel, UUID id, Player sender, Strin return true; } - sender.sendPluginMessage(CodexEngine.get(), channel, out.toByteArray()); + sender.sendPluginMessage(plugin, channel, out.toByteArray()); return true; } @@ -73,7 +82,7 @@ private static void sendMessage(String channel, ByteArrayDataOutput out) { } private static void sendMessage(String channel, Player sender, ByteArrayDataOutput out) { - sender.sendPluginMessage(CodexEngine.get(), channel, out.toByteArray()); + sender.sendPluginMessage(plugin, channel, out.toByteArray()); } public static void broadcastMessage(String message) { @@ -105,7 +114,7 @@ private static void sendFirstQueue() { queued.remove(out); } - private static void queue() { + public static void queue() { if (queueRunning) return; @@ -120,7 +129,7 @@ public void run() { queueRunning = false; this.cancel(); } - }.runTaskTimerAsynchronously(CodexEngine.get(), 20L, 20L); + }.runTaskTimerAsynchronously(plugin, 20L, 20L); } } diff --git a/src/main/resources/bungee.yml b/codex-bungee/src/main/resources/bungee.yml similarity index 100% rename from src/main/resources/bungee.yml rename to codex-bungee/src/main/resources/bungee.yml diff --git a/codex-core/.module b/codex-core/.module new file mode 100644 index 00000000..e69de29b diff --git a/codex-core/pom.xml b/codex-core/pom.xml new file mode 100644 index 00000000..dae6d335 --- /dev/null +++ b/codex-core/pom.xml @@ -0,0 +1,84 @@ + + + 4.0.0 + + studio.magemonkey + codex-parent + 1.1.0-R0.1-SNAPSHOT + + + codex-core + + + jar + 1.1.0-R0.1-SNAPSHOT + + + + + studio.magemonkey + codex-api + ${project.version} + + + + studio.magemonkey + codex-nms-v1_16_5 + ${nms.version} + + + studio.magemonkey + codex-nms-v1_17_1 + ${nms.version} + + + studio.magemonkey + codex-nms-v1_18_2 + ${nms.version} + + + studio.magemonkey + codex-nms-v1_19_4 + ${nms.version} + + + studio.magemonkey + codex-nms-v1_20_2 + ${nms.version} + + + studio.magemonkey + codex-nms-v1_20_4 + ${nms.version} + + + studio.magemonkey + codex-nms-v1_20_6 + ${nms.version} + + + studio.magemonkey + codex-nms-v1_21_1 + ${nms.version} + + + studio.magemonkey + codex-nms-v1_21_2 + ${nms.version} + + + studio.magemonkey + codex-nms-v1_21_4 + ${nms.version} + + + + org.mockito + mockito-core + 5.14.1 + test + + + \ No newline at end of file diff --git a/src/main/java/studio/magemonkey/codex/migration/MigrationUtil.java b/codex-core/src/main/java/studio/magemonkey/codex/migration/MigrationUtil.java similarity index 67% rename from src/main/java/studio/magemonkey/codex/migration/MigrationUtil.java rename to codex-core/src/main/java/studio/magemonkey/codex/migration/MigrationUtil.java index 8db63502..71b08010 100644 --- a/src/main/java/studio/magemonkey/codex/migration/MigrationUtil.java +++ b/codex-core/src/main/java/studio/magemonkey/codex/migration/MigrationUtil.java @@ -1,6 +1,6 @@ package studio.magemonkey.codex.migration; -import studio.magemonkey.codex.CodexEngine; +import studio.magemonkey.codex.Codex; import java.io.File; import java.io.FileInputStream; @@ -14,9 +14,9 @@ public static void renameDirectory(String oldPath, String newPath) { if (oldDir.exists()) { boolean renamed = oldDir.renameTo(newDir); if (!renamed) { - CodexEngine.get().getLogger().warning("Failed to rename directory: " + oldPath + " -> " + newPath); + Codex.warn("Failed to rename directory: " + oldPath + " -> " + newPath); } else { - CodexEngine.get().getLogger().info("Renamed directory: " + oldPath + " -> " + newPath); + Codex.info("Renamed directory: " + oldPath + " -> " + newPath); } } } @@ -30,10 +30,7 @@ public static void replace(String file, String searchRegex, String replacement) try (FileOutputStream fos = new FileOutputStream(f)) { fos.write(content.getBytes()); - CodexEngine.get() - .getLogger() - .info("Replaced instances of '" + searchRegex + "' with '" + replacement + "' in file: " - + file); + Codex.info("Replaced instances of '" + searchRegex + "' with '" + replacement + "' in file: " + file); } } } diff --git a/src/main/java/studio/magemonkey/codex/util/NamespaceResolver.java b/codex-core/src/main/java/studio/magemonkey/codex/util/NamespaceResolver.java similarity index 66% rename from src/main/java/studio/magemonkey/codex/util/NamespaceResolver.java rename to codex-core/src/main/java/studio/magemonkey/codex/util/NamespaceResolver.java index eac52fa9..8eb76988 100644 --- a/src/main/java/studio/magemonkey/codex/util/NamespaceResolver.java +++ b/codex-core/src/main/java/studio/magemonkey/codex/util/NamespaceResolver.java @@ -1,6 +1,7 @@ package studio.magemonkey.codex.util; import org.bukkit.NamespacedKey; +import org.bukkit.Registry; import org.bukkit.enchantments.Enchantment; import org.bukkit.potion.PotionEffectType; @@ -10,7 +11,13 @@ public class NamespaceResolver { public static PotionEffectType getPotion(String... possibleNames) { for (String possibleName : possibleNames) { - PotionEffectType potion = null; + PotionEffectType potion; + + try { + potion = Registry.EFFECT.get(NamespacedKey.minecraft(possibleName.toLowerCase(Locale.US))); + if (potion != null) return potion; + } catch (Throwable ignored) { + } try { potion = PotionEffectType.getByKey(NamespacedKey.minecraft(possibleName.toLowerCase(Locale.US))); @@ -32,8 +39,15 @@ public static PotionEffectType getPotion(String... possibleNames) { public static Enchantment getEnchantment(String... possibleNames) { for (String possibleName : possibleNames) { - Enchantment enchantment = - Enchantment.getByKey(NamespacedKey.minecraft(possibleName.toLowerCase(Locale.US))); + Enchantment enchantment; + + try { + enchantment = Registry.ENCHANTMENT.get(NamespacedKey.minecraft(possibleName.toLowerCase(Locale.US))); + if (enchantment != null) return enchantment; + } catch (Throwable ignored) { + } + + enchantment = Enchantment.getByKey(NamespacedKey.minecraft(possibleName.toLowerCase(Locale.US))); if (enchantment != null) { return enchantment; } diff --git a/codex-nms/codex-nms-v1_16_5/pom.xml b/codex-nms/codex-nms-v1_16_5/pom.xml new file mode 100644 index 00000000..e72094e5 --- /dev/null +++ b/codex-nms/codex-nms-v1_16_5/pom.xml @@ -0,0 +1,28 @@ + + + 4.0.0 + + studio.magemonkey + codex-nms + 1.1.0-R0.1-SNAPSHOT + + + codex-nms-v1_16_5 + + + + org.spigotmc + spigot-api + 1.16.5-R0.1-SNAPSHOT + provided + + + org.spigotmc + spigot + 1.16.5-R0.1-SNAPSHOT + provided + + + \ No newline at end of file diff --git a/codex-nms/codex-nms-v1_16_5/src/main/java/studio/magemonkey/codex/nms/v1_16_5/CompatImpl.java b/codex-nms/codex-nms-v1_16_5/src/main/java/studio/magemonkey/codex/nms/v1_16_5/CompatImpl.java new file mode 100644 index 00000000..94e23ede --- /dev/null +++ b/codex-nms/codex-nms-v1_16_5/src/main/java/studio/magemonkey/codex/nms/v1_16_5/CompatImpl.java @@ -0,0 +1,17 @@ +package studio.magemonkey.codex.nms.v1_16_5; + +import org.bukkit.attribute.AttributeModifier; +import studio.magemonkey.codex.compat.Compat; +import studio.magemonkey.codex.api.meta.NBTAttribute; + +public class CompatImpl implements Compat { + @Override + public AttributeModifier createAttributeModifier(NBTAttribute attribute, double amount, AttributeModifier.Operation operation) { + return new AttributeModifier(ATTRIBUTE_BONUS_UUID, attribute.getNmsName(), amount, operation); + } + + @Override + public String getAttributeKey(AttributeModifier attributeModifier) { + return attributeModifier.getName(); + } +} diff --git a/codex-nms/codex-nms-v1_16_5/src/main/java/studio/magemonkey/codex/nms/v1_16_5/NMSImpl.java b/codex-nms/codex-nms-v1_16_5/src/main/java/studio/magemonkey/codex/nms/v1_16_5/NMSImpl.java new file mode 100644 index 00000000..c0d7ce57 --- /dev/null +++ b/codex-nms/codex-nms-v1_16_5/src/main/java/studio/magemonkey/codex/nms/v1_16_5/NMSImpl.java @@ -0,0 +1,184 @@ +package studio.magemonkey.codex.nms.v1_16_5; + +import com.google.common.base.Preconditions; +import com.mojang.authlib.GameProfile; +import io.netty.channel.Channel; +import net.minecraft.server.v1_16_R3.*; +import org.bukkit.Material; +import org.bukkit.TreeSpecies; +import org.bukkit.attribute.Attribute; +import org.bukkit.block.Block; +import org.bukkit.block.Skull; +import org.bukkit.craftbukkit.v1_16_R3.CraftWorld; +import org.bukkit.craftbukkit.v1_16_R3.entity.CraftLivingEntity; +import org.bukkit.craftbukkit.v1_16_R3.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftItemStack; +import org.bukkit.craftbukkit.v1_16_R3.util.CraftChatMessage; +import org.bukkit.entity.Boat; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import studio.magemonkey.codex.compat.NMS; +import studio.magemonkey.codex.util.constants.JNumbers; + +import java.lang.reflect.Field; + +public class NMSImpl implements NMS { + @Override + public String getVersion() { + return "1.16.5"; + } + + @NotNull + @Override + public Object getConnection(Player player) { + return ((CraftPlayer) player).getHandle().playerConnection; + } + + @NotNull + @Override + public Channel getChannel(@NotNull Player player) { + return ((PlayerConnection) getConnection(player)).networkManager.channel; + } + + @Override + public void sendPacket(@NotNull Player player, @NotNull Object packet) { + Preconditions.checkArgument(packet instanceof Packet, "Packet must be an instance of net.minecraft.server.Packet"); + ((PlayerConnection) getConnection(player)).sendPacket((Packet) packet); + } + + @Override + public void openChestAnimation(@NotNull Block chest, boolean open) { + WorldServer world = ((CraftWorld) chest.getWorld()).getHandle(); + BlockPosition position = new BlockPosition(chest.getX(), chest.getY(), chest.getZ()); + IBlockData blockData = world.getType(position); + world.playBlockAction(position, blockData.getBlock(), 1, open ? 1 : 0); + } + + @Override + public void sendAttackPacket(@NotNull Player player, int i) { + PacketPlayOutAnimation packet = new PacketPlayOutAnimation(((CraftPlayer) player).getHandle(), i); + sendPacket(player, packet); + } + + @NotNull + @Override + public String fixColors(@NotNull String str) { + str = str.replace("\n", "%n%"); + + IChatBaseComponent baseComponent = CraftChatMessage.fromStringOrNull(str); + String singleColor = CraftChatMessage.fromComponent(baseComponent); + + return singleColor.replace("%n%", "\n"); + } + + @Override + public double getDefaultDamage(@NotNull ItemStack itemStack) { + return getAttributeValue(itemStack, Attribute.GENERIC_ATTACK_DAMAGE); + } + + @Override + public double getDefaultSpeed(@NotNull ItemStack itemStack) { + return getAttributeValue(itemStack, Attribute.GENERIC_ATTACK_SPEED); + } + + @Override + public double getDefaultArmor(@NotNull ItemStack itemStack) { + return getAttributeValue(itemStack, Attribute.GENERIC_ARMOR); + } + + @Override + public double getDefaultToughness(@NotNull ItemStack itemStack) { + return getAttributeValue(itemStack, Attribute.GENERIC_ARMOR_TOUGHNESS); + } + + @Override + public boolean isWeapon(@NotNull ItemStack itemStack) { + net.minecraft.server.v1_16_R3.ItemStack nmsItem = CraftItemStack.asNMSCopy(itemStack); + Item item = nmsItem.getItem(); + return item instanceof ItemSword || item instanceof ItemAxe || item instanceof ItemTrident; + } + + @Override + public boolean isArmor(@NotNull ItemStack itemStack) { + net.minecraft.server.v1_16_R3.ItemStack nmsItem = CraftItemStack.asNMSCopy(itemStack); + Item item = nmsItem.getItem(); + return item instanceof ItemArmor; + } + + @Override + public boolean isTool(@NotNull ItemStack itemStack) { + net.minecraft.server.v1_16_R3.ItemStack nmsItem = CraftItemStack.asNMSCopy(itemStack); + Item item = nmsItem.getItem(); + return item instanceof ItemTool || item instanceof ItemShears; + } + + @Override + public String toJson(@NotNull ItemStack item) { + try { + NBTTagCompound nbtCompound = new NBTTagCompound(); + net.minecraft.server.v1_16_R3.ItemStack nmsItem = CraftItemStack.asNMSCopy(item); + + nmsItem.save(nbtCompound); + + String js = nbtCompound.toString(); + if (js.length() > JNumbers.JSON_MAX) { + ItemStack item2 = new ItemStack(item.getType()); + return toJson(item2); + } + + return js; + } catch (Exception e) { + e.printStackTrace(); + } + + return null; + } + + @Override + public void setKiller(@NotNull LivingEntity entity, @NotNull Player killer) { + try { + EntityLiving hit = ((CraftLivingEntity) entity).getHandle(); + hit.killer = ((CraftPlayer) killer).getHandle(); + Field damageTime = getField(hit.getClass(), "lastDamageByPlayerTime"); + + damageTime.setAccessible(true); + + damageTime.set(hit, 100); + } catch (NoSuchFieldException | IllegalAccessException e) { + throw new RuntimeException("Unable to set killer. Something went wrong", e); + } + } + + @Override + public void changeSkull(@NotNull Block block, @NotNull String hash) { + if (!(block.getState() instanceof Skull)) return; + + TileEntitySkull skull = (TileEntitySkull) ((CraftWorld) block.getWorld()).getHandle().getTileEntity(new BlockPosition(block.getX(), block.getY(), block.getZ())); + if (skull == null) return; + + GameProfile profile = getNonPlayerProfile(hash); + skull.setGameProfile(profile); + skull.update(); + } + + @Override + public Object getNMSCopy(@NotNull ItemStack item) { + return CraftItemStack.asNMSCopy(item); + } + + @Override + public org.bukkit.Material getMaterial(Boat boat) { + TreeSpecies woodType = boat.getWoodType(); + + return switch (woodType) { + case REDWOOD -> org.bukkit.Material.SPRUCE_BOAT; + case BIRCH -> org.bukkit.Material.BIRCH_BOAT; + case JUNGLE -> org.bukkit.Material.JUNGLE_BOAT; + case ACACIA -> org.bukkit.Material.ACACIA_BOAT; + case DARK_OAK -> org.bukkit.Material.DARK_OAK_BOAT; + default -> Material.OAK_BOAT; + }; + } +} diff --git a/codex-nms/codex-nms-v1_17_1/pom.xml b/codex-nms/codex-nms-v1_17_1/pom.xml new file mode 100644 index 00000000..fc44d54d --- /dev/null +++ b/codex-nms/codex-nms-v1_17_1/pom.xml @@ -0,0 +1,28 @@ + + + 4.0.0 + + studio.magemonkey + codex-nms + 1.1.0-R0.1-SNAPSHOT + + + codex-nms-v1_17_1 + + + + org.spigotmc + spigot-api + 1.17.1-R0.1-SNAPSHOT + provided + + + org.spigotmc + spigot + 1.17.1-R0.1-SNAPSHOT + provided + + + \ No newline at end of file diff --git a/codex-nms/codex-nms-v1_17_1/src/main/java/studio/magemonkey/codex/nms/v1_17/CompatImpl.java b/codex-nms/codex-nms-v1_17_1/src/main/java/studio/magemonkey/codex/nms/v1_17/CompatImpl.java new file mode 100644 index 00000000..ea7dafa7 --- /dev/null +++ b/codex-nms/codex-nms-v1_17_1/src/main/java/studio/magemonkey/codex/nms/v1_17/CompatImpl.java @@ -0,0 +1,17 @@ +package studio.magemonkey.codex.nms.v1_17; + +import org.bukkit.attribute.AttributeModifier; +import studio.magemonkey.codex.compat.Compat; +import studio.magemonkey.codex.api.meta.NBTAttribute; + +public class CompatImpl implements Compat { + @Override + public AttributeModifier createAttributeModifier(NBTAttribute attribute, double amount, AttributeModifier.Operation operation) { + return new AttributeModifier(ATTRIBUTE_BONUS_UUID, attribute.getNmsName(), amount, operation); + } + + @Override + public String getAttributeKey(AttributeModifier attributeModifier) { + return attributeModifier.getName(); + } +} diff --git a/codex-nms/codex-nms-v1_17_1/src/main/java/studio/magemonkey/codex/nms/v1_17/NMSImpl.java b/codex-nms/codex-nms-v1_17_1/src/main/java/studio/magemonkey/codex/nms/v1_17/NMSImpl.java new file mode 100644 index 00000000..f3754a7d --- /dev/null +++ b/codex-nms/codex-nms-v1_17_1/src/main/java/studio/magemonkey/codex/nms/v1_17/NMSImpl.java @@ -0,0 +1,194 @@ +package studio.magemonkey.codex.nms.v1_17; + +import com.google.common.base.Preconditions; +import com.mojang.authlib.GameProfile; +import io.netty.channel.Channel; +import net.minecraft.core.BlockPosition; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.chat.IChatBaseComponent; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.PacketPlayOutAnimation; +import net.minecraft.server.level.WorldServer; +import net.minecraft.server.network.PlayerConnection; +import net.minecraft.world.entity.EntityLiving; +import net.minecraft.world.item.*; +import net.minecraft.world.level.block.entity.TileEntitySkull; +import net.minecraft.world.level.block.state.IBlockData; +import org.bukkit.Material; +import org.bukkit.TreeSpecies; +import org.bukkit.attribute.Attribute; +import org.bukkit.block.Block; +import org.bukkit.block.Skull; +import org.bukkit.craftbukkit.v1_17_R1.CraftWorld; +import org.bukkit.craftbukkit.v1_17_R1.entity.CraftLivingEntity; +import org.bukkit.craftbukkit.v1_17_R1.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack; +import org.bukkit.craftbukkit.v1_17_R1.util.CraftChatMessage; +import org.bukkit.entity.Boat; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import studio.magemonkey.codex.compat.NMS; +import studio.magemonkey.codex.util.constants.JNumbers; + +import java.lang.reflect.Field; + +public class NMSImpl implements NMS { + @Override + public String getVersion() { + return "1.17.1"; + } + + @NotNull + @Override + public Object getConnection(Player player) { + return ((CraftPlayer) player).getHandle().b; + } + + @NotNull + @Override + public Channel getChannel(@NotNull Player player) { + return ((PlayerConnection) getConnection(player)).a().k; + } + + @Override + public void sendPacket(@NotNull Player player, @NotNull Object packet) { + Preconditions.checkArgument(packet instanceof Packet, "Packet must be an instance of net.minecraft.server.Packet"); + ((PlayerConnection) getConnection(player)).sendPacket((Packet) packet); + } + + @Override + public void openChestAnimation(@NotNull Block chest, boolean open) { + WorldServer world = ((CraftWorld) chest.getWorld()).getHandle(); + BlockPosition position = new BlockPosition(chest.getX(), chest.getY(), chest.getZ()); + IBlockData blockData = world.getType(position); + world.playBlockAction(position, blockData.getBlock(), 1, open ? 1 : 0); + } + + @Override + public void sendAttackPacket(@NotNull Player player, int i) { + PacketPlayOutAnimation packet = new PacketPlayOutAnimation(((CraftPlayer) player).getHandle(), i); + sendPacket(player, packet); + } + + @NotNull + @Override + public String fixColors(@NotNull String str) { + str = str.replace("\n", "%n%"); + + IChatBaseComponent baseComponent = CraftChatMessage.fromStringOrNull(str); + String singleColor = CraftChatMessage.fromComponent(baseComponent); + + return singleColor.replace("%n%", "\n"); + } + + @Override + public double getDefaultDamage(@NotNull ItemStack itemStack) { + return getAttributeValue(itemStack, Attribute.GENERIC_ATTACK_DAMAGE); + } + + @Override + public double getDefaultSpeed(@NotNull ItemStack itemStack) { + return getAttributeValue(itemStack, Attribute.GENERIC_ATTACK_SPEED); + } + + @Override + public double getDefaultArmor(@NotNull ItemStack itemStack) { + return getAttributeValue(itemStack, Attribute.GENERIC_ARMOR); + } + + @Override + public double getDefaultToughness(@NotNull ItemStack itemStack) { + return getAttributeValue(itemStack, Attribute.GENERIC_ARMOR_TOUGHNESS); + } + + @Override + public boolean isWeapon(@NotNull ItemStack itemStack) { + net.minecraft.world.item.ItemStack nmsItem = CraftItemStack.asNMSCopy(itemStack); + Item item = nmsItem.getItem(); + return item instanceof ItemSword || item instanceof ItemAxe || item instanceof ItemTrident; + } + + @Override + public boolean isArmor(@NotNull ItemStack itemStack) { + net.minecraft.world.item.ItemStack nmsItem = CraftItemStack.asNMSCopy(itemStack); + Item item = nmsItem.getItem(); + return item instanceof ItemArmor; + } + + @Override + public boolean isTool(@NotNull ItemStack itemStack) { + net.minecraft.world.item.ItemStack nmsItem = CraftItemStack.asNMSCopy(itemStack); + Item item = nmsItem.getItem(); + return item instanceof ItemTool || item instanceof ItemShears; + } + + @Override + public String toJson(@NotNull ItemStack item) { + try { + NBTTagCompound nbtCompound = new NBTTagCompound(); + net.minecraft.world.item.ItemStack nmsItem = CraftItemStack.asNMSCopy(item); + + nmsItem.save(nbtCompound); + + String js = nbtCompound.toString(); + if (js.length() > JNumbers.JSON_MAX) { + ItemStack item2 = new ItemStack(item.getType()); + return toJson(item2); + } + + return js; + } catch (Exception e) { + e.printStackTrace(); + } + + return null; + } + + @Override + public void setKiller(@NotNull LivingEntity entity, @NotNull Player killer) { + try { + EntityLiving hit = ((CraftLivingEntity) entity).getHandle(); + hit.bc = ((CraftPlayer) killer).getHandle(); + Field damageTime = getField(hit.getClass(), "bd"); + + damageTime.setAccessible(true); + + damageTime.set(hit, 100); + } catch (NoSuchFieldException | IllegalAccessException e) { + throw new RuntimeException("Unable to set killer. Something went wrong", e); + } + } + + @Override + public void changeSkull(@NotNull Block block, @NotNull String hash) { + if (!(block.getState() instanceof Skull)) return; + + TileEntitySkull skull = (TileEntitySkull) ((CraftWorld) block.getWorld()).getHandle().getTileEntity(new BlockPosition(block.getX(), block.getY(), block.getZ())); + if (skull == null) return; + + GameProfile profile = getNonPlayerProfile(hash); + skull.setGameProfile(profile); + skull.update(); + } + + @Override + public Object getNMSCopy(@NotNull ItemStack item) { + return CraftItemStack.asNMSCopy(item); + } + + @Override + public Material getMaterial(Boat boat) { + TreeSpecies woodType = boat.getWoodType(); + + return switch (woodType) { + case REDWOOD -> Material.SPRUCE_BOAT; + case BIRCH -> Material.BIRCH_BOAT; + case JUNGLE -> Material.JUNGLE_BOAT; + case ACACIA -> Material.ACACIA_BOAT; + case DARK_OAK -> Material.DARK_OAK_BOAT; + default -> Material.OAK_BOAT; + }; + } +} diff --git a/codex-nms/codex-nms-v1_18_2/pom.xml b/codex-nms/codex-nms-v1_18_2/pom.xml new file mode 100644 index 00000000..8ad11c6b --- /dev/null +++ b/codex-nms/codex-nms-v1_18_2/pom.xml @@ -0,0 +1,28 @@ + + + 4.0.0 + + studio.magemonkey + codex-nms + 1.1.0-R0.1-SNAPSHOT + + + codex-nms-v1_18_2 + + + + org.spigotmc + spigot-api + 1.18.2-R0.1-SNAPSHOT + provided + + + org.spigotmc + spigot + 1.18.2-R0.1-SNAPSHOT + provided + + + \ No newline at end of file diff --git a/codex-nms/codex-nms-v1_18_2/src/main/java/studio/magemonkey/codex/nms/v1_18_2/CompatImpl.java b/codex-nms/codex-nms-v1_18_2/src/main/java/studio/magemonkey/codex/nms/v1_18_2/CompatImpl.java new file mode 100644 index 00000000..c95fa903 --- /dev/null +++ b/codex-nms/codex-nms-v1_18_2/src/main/java/studio/magemonkey/codex/nms/v1_18_2/CompatImpl.java @@ -0,0 +1,17 @@ +package studio.magemonkey.codex.nms.v1_18_2; + +import org.bukkit.attribute.AttributeModifier; +import studio.magemonkey.codex.compat.Compat; +import studio.magemonkey.codex.api.meta.NBTAttribute; + +public class CompatImpl implements Compat { + @Override + public AttributeModifier createAttributeModifier(NBTAttribute attribute, double amount, AttributeModifier.Operation operation) { + return new AttributeModifier(ATTRIBUTE_BONUS_UUID, attribute.getNmsName(), amount, operation); + } + + @Override + public String getAttributeKey(AttributeModifier attributeModifier) { + return attributeModifier.getName(); + } +} diff --git a/codex-nms/codex-nms-v1_18_2/src/main/java/studio/magemonkey/codex/nms/v1_18_2/NMSImpl.java b/codex-nms/codex-nms-v1_18_2/src/main/java/studio/magemonkey/codex/nms/v1_18_2/NMSImpl.java new file mode 100644 index 00000000..663a25ff --- /dev/null +++ b/codex-nms/codex-nms-v1_18_2/src/main/java/studio/magemonkey/codex/nms/v1_18_2/NMSImpl.java @@ -0,0 +1,274 @@ +package studio.magemonkey.codex.nms.v1_18_2; + +import com.google.common.base.Preconditions; +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.mojang.authlib.GameProfile; +import io.netty.channel.Channel; +import net.md_5.bungee.api.chat.*; +import net.minecraft.core.BlockPosition; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.chat.IChatBaseComponent; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.PacketPlayOutAnimation; +import net.minecraft.server.level.WorldServer; +import net.minecraft.server.network.PlayerConnection; +import net.minecraft.world.entity.EntityLiving; +import net.minecraft.world.item.*; +import net.minecraft.world.level.block.entity.TileEntitySkull; +import net.minecraft.world.level.block.state.IBlockData; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.TreeSpecies; +import org.bukkit.attribute.Attribute; +import org.bukkit.block.Block; +import org.bukkit.block.Skull; +import org.bukkit.craftbukkit.v1_18_R2.CraftWorld; +import org.bukkit.craftbukkit.v1_18_R2.entity.CraftLivingEntity; +import org.bukkit.craftbukkit.v1_18_R2.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_18_R2.inventory.CraftItemStack; +import org.bukkit.craftbukkit.v1_18_R2.util.CraftChatMessage; +import org.bukkit.entity.Boat; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.SkullMeta; +import org.bukkit.profile.PlayerProfile; +import org.bukkit.profile.PlayerTextures; +import org.jetbrains.annotations.NotNull; +import studio.magemonkey.codex.Codex; +import studio.magemonkey.codex.compat.NMS; +import studio.magemonkey.codex.util.constants.JNumbers; + +import java.lang.reflect.Field; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Base64; +import java.util.UUID; + +public class NMSImpl implements NMS { + @Override + public String getVersion() { + return "1.18.2"; + } + + @NotNull + @Override + public Object getConnection(Player player) { + return ((CraftPlayer) player).getHandle().b; + } + + @NotNull + @Override + public Channel getChannel(@NotNull Player player) { + return ((PlayerConnection) getConnection(player)).a().m; + } + + @Override + public void sendPacket(@NotNull Player player, @NotNull Object packet) { + Preconditions.checkArgument(packet instanceof Packet, "Packet must be an instance of net.minecraft.server.Packet"); + ((PlayerConnection) getConnection(player)).a((Packet) packet); + } + + @Override + public void openChestAnimation(@NotNull Block chest, boolean open) { + WorldServer world = ((CraftWorld) chest.getWorld()).getHandle(); + BlockPosition position = new BlockPosition(chest.getX(), chest.getY(), chest.getZ()); + IBlockData blockData = world.a_(position); + world.a(position, blockData.b(), 1, open ? 1 : 0); + } + + @Override + public void sendAttackPacket(@NotNull Player player, int i) { + PacketPlayOutAnimation packet = new PacketPlayOutAnimation(((CraftPlayer) player).getHandle(), i); + sendPacket(player, packet); + } + + @NotNull + @Override + public String fixColors(@NotNull String str) { + str = str.replace("\n", "%n%"); + + IChatBaseComponent baseComponent = CraftChatMessage.fromStringOrNull(str); + String singleColor = CraftChatMessage.fromComponent(baseComponent); + + return singleColor.replace("%n%", "\n"); + } + + @Override + public double getDefaultDamage(@NotNull ItemStack itemStack) { + return getAttributeValue(itemStack, Attribute.GENERIC_ATTACK_DAMAGE); + } + + @Override + public double getDefaultSpeed(@NotNull ItemStack itemStack) { + return getAttributeValue(itemStack, Attribute.GENERIC_ATTACK_SPEED); + } + + @Override + public double getDefaultArmor(@NotNull ItemStack itemStack) { + return getAttributeValue(itemStack, Attribute.GENERIC_ARMOR); + } + + @Override + public double getDefaultToughness(@NotNull ItemStack itemStack) { + return getAttributeValue(itemStack, Attribute.GENERIC_ARMOR_TOUGHNESS); + } + + @Override + public boolean isWeapon(@NotNull ItemStack itemStack) { + net.minecraft.world.item.ItemStack nmsItem = CraftItemStack.asNMSCopy(itemStack); + Item item = nmsItem.c(); + return item instanceof ItemSword || item instanceof ItemAxe || item instanceof ItemTrident; + } + + @Override + public boolean isArmor(@NotNull ItemStack itemStack) { + net.minecraft.world.item.ItemStack nmsItem = CraftItemStack.asNMSCopy(itemStack); + Item item = nmsItem.c(); + return item instanceof ItemArmor; + } + + @Override + public boolean isTool(@NotNull ItemStack itemStack) { + net.minecraft.world.item.ItemStack nmsItem = CraftItemStack.asNMSCopy(itemStack); + Item item = nmsItem.c(); + return item instanceof ItemTool || item instanceof ItemShears; + } + + @Override + public String toJson(@NotNull ItemStack item) { + try { + NBTTagCompound nbtCompound = new NBTTagCompound(); + net.minecraft.world.item.ItemStack nmsItem = CraftItemStack.asNMSCopy(item); + + nmsItem.b(nbtCompound); + + String js = nbtCompound.toString(); + if (js.length() > JNumbers.JSON_MAX) { + ItemStack item2 = new ItemStack(item.getType()); + return toJson(item2); + } + + return js; + } catch (Exception e) { + e.printStackTrace(); + } + + return null; + } + + @Override + public void setKiller(@NotNull LivingEntity entity, @NotNull Player killer) { + try { + EntityLiving hit = ((CraftLivingEntity) entity).getHandle(); + hit.bc = ((CraftPlayer) killer).getHandle(); + Field damageTime = getField(hit.getClass(), "bd"); + + damageTime.setAccessible(true); + + damageTime.set(hit, 100); + } catch (NoSuchFieldException | IllegalAccessException e) { + throw new RuntimeException("Unable to set killer. Something went wrong", e); + } + } + + @Override + public void changeSkull(@NotNull Block block, @NotNull String hash) { + try { + if (!(block.getState() instanceof Skull)) return; + + try { + Skull skull = (Skull) block.getState(); + PlayerProfile profile = Bukkit.createPlayerProfile(UUID.randomUUID(), hash.substring(0, 16)); + PlayerTextures textures = profile.getTextures(); + + // If the hash is a URL, we can just set the skin directly, otherwise, we need to decode + // the hash from Base64 and extract the url from the JSON data. + if (hash.startsWith("http")) { + textures.setSkin(new URL(hash)); + } else { + String decoded = new String(java.util.Base64.getDecoder().decode(hash)); + // Construct the json object + JsonObject json = new Gson().fromJson(decoded, JsonObject.class); + // Get the textures object + JsonObject texturesJson = json.getAsJsonObject("textures"); + // Get the skin object + JsonObject skin = texturesJson.getAsJsonObject("SKIN"); + // Get the url + String url = skin.get("url").getAsString(); + textures.setSkin(new URL(url)); + } + + profile = profile.update().get(); + skull.setOwnerProfile(profile); + skull.update(); + } catch (NoSuchMethodError | Exception e) { + Codex.info("Could not change skull with modern method, trying legacy method."); + if (!(block.getState() instanceof Skull)) return; + + TileEntitySkull skull = (TileEntitySkull) ((CraftWorld) block.getWorld()).getHandle().c_(new BlockPosition(block.getX(), block.getY(), block.getZ())); + if (skull == null) return; + + GameProfile profile = getNonPlayerProfile(hash); + skull.a(profile); + skull.e(); + } + } catch (Exception e) { + Codex.warn("Could not update skull"); + e.printStackTrace(); + } + } + + @Override + public void addSkullTexture(@NotNull ItemStack item, @NotNull String value, @NotNull UUID uuid) { + if (item.getType() != Material.PLAYER_HEAD) return; + + SkullMeta meta = (SkullMeta) item.getItemMeta(); + if (meta == null) return; + + try { + PlayerProfile playerProfile = Bukkit.createPlayerProfile(uuid, uuid.toString().substring(0, 16)); + String decoded = new String(Base64.getDecoder().decode(value)); + JsonObject json = new Gson().fromJson(decoded, JsonObject.class); + JsonObject texturesJson = json.getAsJsonObject("textures"); + JsonObject skin = texturesJson.getAsJsonObject("SKIN"); + String url = skin.get("url").getAsString(); + playerProfile.getTextures().setSkin(new URL(url)); + meta.setOwnerProfile(playerProfile); + item.setItemMeta(meta); + } catch (MalformedURLException | NoClassDefFoundError | NoSuchMethodError | IllegalArgumentException e) { + NMS.super.addSkullTexture(item, value, uuid); + } + } + + @Override + public Object getNMSCopy(@NotNull ItemStack item) { + return CraftItemStack.asNMSCopy(item); + } + + @Override + public Material getMaterial(Boat boat) { + TreeSpecies woodType = boat.getWoodType(); + + return switch (woodType) { + case REDWOOD -> Material.SPRUCE_BOAT; + case BIRCH -> Material.BIRCH_BOAT; + case JUNGLE -> Material.JUNGLE_BOAT; + case ACACIA -> Material.ACACIA_BOAT; + case DARK_OAK -> Material.DARK_OAK_BOAT; + default -> Material.OAK_BOAT; + }; + } + + @Override + public HoverEvent getHoverEvent(@NotNull ItemStack itemStack) { + ItemMeta meta = itemStack.getItemMeta(); + String itemString = meta != null ? meta.getAsString() : "{}"; + return new HoverEvent(HoverEvent.Action.SHOW_ITEM, + new net.md_5.bungee.api.chat.hover.content.Item(itemStack.getType().getKey().getKey(), + itemStack.getAmount(), + ItemTag.ofNbt(itemString))); + } +} diff --git a/codex-nms/codex-nms-v1_19_4/pom.xml b/codex-nms/codex-nms-v1_19_4/pom.xml new file mode 100644 index 00000000..86ac057f --- /dev/null +++ b/codex-nms/codex-nms-v1_19_4/pom.xml @@ -0,0 +1,28 @@ + + + 4.0.0 + + studio.magemonkey + codex-nms + 1.1.0-R0.1-SNAPSHOT + + + codex-nms-v1_19_4 + + + + org.spigotmc + spigot-api + 1.19.4-R0.1-SNAPSHOT + provided + + + org.spigotmc + spigot + 1.19.4-R0.1-SNAPSHOT + provided + + + \ No newline at end of file diff --git a/codex-nms/codex-nms-v1_19_4/src/main/java/studio/magemonkey/codex/nms/v1_19_4/ArmorUtilImpl.java b/codex-nms/codex-nms-v1_19_4/src/main/java/studio/magemonkey/codex/nms/v1_19_4/ArmorUtilImpl.java new file mode 100644 index 00000000..c5206d4d --- /dev/null +++ b/codex-nms/codex-nms-v1_19_4/src/main/java/studio/magemonkey/codex/nms/v1_19_4/ArmorUtilImpl.java @@ -0,0 +1,72 @@ +package studio.magemonkey.codex.nms.v1_19_4; + +import org.bukkit.NamespacedKey; +import org.bukkit.Registry; +import org.bukkit.inventory.meta.ArmorMeta; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.trim.ArmorTrim; +import org.bukkit.inventory.meta.trim.TrimMaterial; +import org.bukkit.inventory.meta.trim.TrimPattern; +import studio.magemonkey.codex.compat.ArmorUtil; +import studio.magemonkey.codex.util.random.Rnd; + +import java.util.Objects; + +@SuppressWarnings("UnstableApiUsage") +public class ArmorUtilImpl implements ArmorUtil { + @Override + public Object getTrimMaterial(NamespacedKey key) { + return Registry.TRIM_MATERIAL.get(key); + } + + @Override + public Object getTrimPattern(NamespacedKey key) { + return Registry.TRIM_PATTERN.get(key); + } + + @Override + public void addTrim(ItemMeta meta, String material, String pattern) { + if (!(meta instanceof ArmorMeta)) return; + ArmorMeta armorMeta = (ArmorMeta) meta; + + TrimMaterial trimMaterial = null; + if (material.equals("*")) { + int size = 0; + for (TrimMaterial ignored : Registry.TRIM_MATERIAL) { + size++; + } + int index = Rnd.get(size); + int i = 0; + for (TrimMaterial next : Registry.TRIM_MATERIAL) { + if (index == i) { + trimMaterial = next; + break; + } + i++; + } + } else { + trimMaterial = Registry.TRIM_MATERIAL.get(NamespacedKey.minecraft(material)); + } + + TrimPattern trimPattern = null; + if (pattern.equals("*")) { + int size = 0; + for (TrimPattern ignored : Registry.TRIM_PATTERN) size++; + + int index = Rnd.get(size); + int i = 0; + for (TrimPattern next : Registry.TRIM_PATTERN) { + if (index == i++) { + trimPattern = next; + break; + } + } + } else { + trimPattern = Registry.TRIM_PATTERN.get(NamespacedKey.minecraft(pattern)); + } + + ArmorTrim armorTrim = + new ArmorTrim(Objects.requireNonNull(trimMaterial), Objects.requireNonNull(trimPattern)); + armorMeta.setTrim(armorTrim); + } +} diff --git a/codex-nms/codex-nms-v1_19_4/src/main/java/studio/magemonkey/codex/nms/v1_19_4/CompatImpl.java b/codex-nms/codex-nms-v1_19_4/src/main/java/studio/magemonkey/codex/nms/v1_19_4/CompatImpl.java new file mode 100644 index 00000000..29fefc05 --- /dev/null +++ b/codex-nms/codex-nms-v1_19_4/src/main/java/studio/magemonkey/codex/nms/v1_19_4/CompatImpl.java @@ -0,0 +1,17 @@ +package studio.magemonkey.codex.nms.v1_19_4; + +import org.bukkit.attribute.AttributeModifier; +import studio.magemonkey.codex.compat.Compat; +import studio.magemonkey.codex.api.meta.NBTAttribute; + +public class CompatImpl implements Compat { + @Override + public AttributeModifier createAttributeModifier(NBTAttribute attribute, double amount, AttributeModifier.Operation operation) { + return new AttributeModifier(ATTRIBUTE_BONUS_UUID, attribute.getNmsName(), amount, operation); + } + + @Override + public String getAttributeKey(AttributeModifier attributeModifier) { + return attributeModifier.getName(); + } +} diff --git a/codex-nms/codex-nms-v1_19_4/src/main/java/studio/magemonkey/codex/nms/v1_19_4/NMSImpl.java b/codex-nms/codex-nms-v1_19_4/src/main/java/studio/magemonkey/codex/nms/v1_19_4/NMSImpl.java new file mode 100644 index 00000000..2567f6d7 --- /dev/null +++ b/codex-nms/codex-nms-v1_19_4/src/main/java/studio/magemonkey/codex/nms/v1_19_4/NMSImpl.java @@ -0,0 +1,315 @@ +package studio.magemonkey.codex.nms.v1_19_4; + +import com.google.common.base.Preconditions; +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.mojang.authlib.GameProfile; +import io.netty.channel.Channel; +import net.md_5.bungee.api.chat.*; +import net.minecraft.core.BlockPosition; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.NetworkManager; +import net.minecraft.network.chat.IChatBaseComponent; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.PacketPlayOutAnimation; +import net.minecraft.server.level.WorldServer; +import net.minecraft.server.network.PlayerConnection; +import net.minecraft.world.entity.EntityLiving; +import net.minecraft.world.item.*; +import net.minecraft.world.level.block.entity.TileEntitySkull; +import net.minecraft.world.level.block.state.IBlockData; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.attribute.Attribute; +import org.bukkit.block.Block; +import org.bukkit.block.Skull; +import org.bukkit.craftbukkit.v1_19_R3.CraftWorld; +import org.bukkit.craftbukkit.v1_19_R3.entity.CraftLivingEntity; +import org.bukkit.craftbukkit.v1_19_R3.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_19_R3.inventory.CraftItemStack; +import org.bukkit.craftbukkit.v1_19_R3.util.CraftChatMessage; +import org.bukkit.entity.Boat; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.SkullMeta; +import org.bukkit.profile.PlayerProfile; +import org.bukkit.profile.PlayerTextures; +import org.bukkit.scoreboard.Objective; +import org.bukkit.scoreboard.Scoreboard; +import org.jetbrains.annotations.NotNull; +import studio.magemonkey.codex.Codex; +import studio.magemonkey.codex.compat.NMS; +import studio.magemonkey.codex.util.constants.JNumbers; + +import java.lang.reflect.Field; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Base64; +import java.util.UUID; + +public class NMSImpl implements NMS { + @Override + public String getVersion() { + return "1.19.4"; + } + + @NotNull + @Override + public Object getConnection(Player player) { + return ((CraftPlayer) player).getHandle().b; + } + + @NotNull + @Override + public Channel getChannel(@NotNull Player player) { + PlayerConnection connection = ((PlayerConnection) getConnection(player)); + // We have to reflexively get the `channel` field + try { + Field networkManagerField = getField(connection.getClass(), "h"); + networkManagerField.setAccessible(true); + NetworkManager networkManager = (NetworkManager) networkManagerField.get(connection); + return networkManager.m; + } catch (IllegalAccessException | NoSuchFieldException e) { + throw new RuntimeException("Could not get Channel field from PlayerConnection", e); + } + } + + @Override + public void sendPacket(@NotNull Player player, @NotNull Object packet) { + Preconditions.checkArgument(packet instanceof Packet, "Packet must be an instance of net.minecraft.server.Packet"); + ((PlayerConnection) getConnection(player)).a((Packet) packet); + } + + @Override + public void openChestAnimation(@NotNull Block chest, boolean open) { + WorldServer world = ((CraftWorld) chest.getWorld()).getHandle(); + BlockPosition position = new BlockPosition(chest.getX(), chest.getY(), chest.getZ()); + IBlockData blockData = world.a_(position); + world.a(position, blockData.b(), 1, open ? 1 : 0); + } + + @Override + public void sendAttackPacket(@NotNull Player player, int i) { + PacketPlayOutAnimation packet = new PacketPlayOutAnimation(((CraftPlayer) player).getHandle(), i); + sendPacket(player, packet); + } + + @NotNull + @Override + public String fixColors(@NotNull String str) { + str = str.replace("\n", "%n%"); + + IChatBaseComponent baseComponent = CraftChatMessage.fromStringOrNull(str); + String singleColor = CraftChatMessage.fromComponent(baseComponent); + + return singleColor.replace("%n%", "\n"); + } + + @Override + public double getDefaultDamage(@NotNull ItemStack itemStack) { + return getAttributeValue(itemStack, Attribute.GENERIC_ATTACK_DAMAGE); + } + + @Override + public double getDefaultSpeed(@NotNull ItemStack itemStack) { + return getAttributeValue(itemStack, Attribute.GENERIC_ATTACK_SPEED); + } + + @Override + public double getDefaultArmor(@NotNull ItemStack itemStack) { + return getAttributeValue(itemStack, Attribute.GENERIC_ARMOR); + } + + @Override + public double getDefaultToughness(@NotNull ItemStack itemStack) { + return getAttributeValue(itemStack, Attribute.GENERIC_ARMOR_TOUGHNESS); + } + + @Override + public boolean isWeapon(@NotNull ItemStack itemStack) { + net.minecraft.world.item.ItemStack nmsItem = CraftItemStack.asNMSCopy(itemStack); + Item item = nmsItem.c(); + return item instanceof ItemSword || item instanceof ItemAxe || item instanceof ItemTrident; + } + + @Override + public boolean isArmor(@NotNull ItemStack itemStack) { + net.minecraft.world.item.ItemStack nmsItem = CraftItemStack.asNMSCopy(itemStack); + Item item = nmsItem.c(); + return item instanceof ItemArmor; + } + + @Override + public boolean isTool(@NotNull ItemStack itemStack) { + net.minecraft.world.item.ItemStack nmsItem = CraftItemStack.asNMSCopy(itemStack); + Item item = nmsItem.c(); + return item instanceof ItemTool || item instanceof ItemShears; + } + + @Override + public String toJson(@NotNull ItemStack item) { + try { + NBTTagCompound nbtCompound = new NBTTagCompound(); + net.minecraft.world.item.ItemStack nmsItem = CraftItemStack.asNMSCopy(item); + + nmsItem.b(nbtCompound); + + String js = nbtCompound.toString(); + if (js.length() > JNumbers.JSON_MAX) { + ItemStack item2 = new ItemStack(item.getType()); + return toJson(item2); + } + + return js; + } catch (Exception e) { + e.printStackTrace(); + } + + return null; + } + + @Override + public void setKiller(@NotNull LivingEntity entity, @NotNull Player killer) { + try { + EntityLiving hit = ((CraftLivingEntity) entity).getHandle(); + hit.aX = ((CraftPlayer) killer).getHandle(); + Field damageTime = getField(hit.getClass(), "aY"); + + damageTime.setAccessible(true); + + damageTime.set(hit, 100); + } catch (NoSuchFieldException | IllegalAccessException e) { + throw new RuntimeException("Unable to set killer. Something went wrong", e); + } + } + + @Override + public void changeSkull(@NotNull Block block, @NotNull String hash) { + try { + if (!(block.getState() instanceof Skull)) return; + + try { + Skull skull = (Skull) block.getState(); + PlayerProfile profile = Bukkit.createPlayerProfile(UUID.randomUUID(), hash.substring(0, 16)); + PlayerTextures textures = profile.getTextures(); + + // If the hash is a URL, we can just set the skin directly, otherwise, we need to decode + // the hash from Base64 and extract the url from the JSON data. + if (hash.startsWith("http")) { + textures.setSkin(new URL(hash)); + } else { + String decoded = new String(java.util.Base64.getDecoder().decode(hash)); + // Construct the json object + JsonObject json = new Gson().fromJson(decoded, JsonObject.class); + // Get the textures object + JsonObject texturesJson = json.getAsJsonObject("textures"); + // Get the skin object + JsonObject skin = texturesJson.getAsJsonObject("SKIN"); + // Get the url + String url = skin.get("url").getAsString(); + textures.setSkin(new URL(url)); + } + + profile = profile.update().get(); + skull.setOwnerProfile(profile); + skull.update(); + } catch (NoSuchMethodError | Exception e) { + Codex.info("Could not change skull with modern method, trying legacy method."); + if (!(block.getState() instanceof Skull)) return; + + TileEntitySkull skull = (TileEntitySkull) ((CraftWorld) block.getWorld()).getHandle().c_(new BlockPosition(block.getX(), block.getY(), block.getZ())); + if (skull == null) return; + + GameProfile profile = getNonPlayerProfile(hash); + skull.a(profile); + skull.e(); + } + } catch (Exception e) { + Codex.warn("Could not update skull"); + e.printStackTrace(); + } + } + + @Override + public void addSkullTexture(@NotNull ItemStack item, @NotNull String value, @NotNull UUID uuid) { + if (item.getType() != Material.PLAYER_HEAD) return; + + SkullMeta meta = (SkullMeta) item.getItemMeta(); + if (meta == null) return; + + try { + PlayerProfile playerProfile = Bukkit.createPlayerProfile(uuid, uuid.toString().substring(0, 16)); + String decoded = new String(Base64.getDecoder().decode(value)); + JsonObject json = new Gson().fromJson(decoded, JsonObject.class); + JsonObject texturesJson = json.getAsJsonObject("textures"); + JsonObject skin = texturesJson.getAsJsonObject("SKIN"); + String url = skin.get("url").getAsString(); + playerProfile.getTextures().setSkin(new URL(url)); + meta.setOwnerProfile(playerProfile); + item.setItemMeta(meta); + } catch (MalformedURLException | NoClassDefFoundError | NoSuchMethodError | IllegalArgumentException e) { + NMS.super.addSkullTexture(item, value, uuid); + } + } + + @Override + public Object getNMSCopy(@NotNull ItemStack item) { + return CraftItemStack.asNMSCopy(item); + } + + @Override + public Material getMaterial(Boat boat) { + Material woodType = boat.getBoatType().getMaterial(); + + return switch (woodType) { + case SPRUCE_PLANKS -> Material.SPRUCE_BOAT; + case BIRCH_PLANKS -> Material.BIRCH_BOAT; + case JUNGLE_PLANKS -> Material.JUNGLE_BOAT; + case ACACIA_PLANKS -> Material.ACACIA_BOAT; + case DARK_OAK_PLANKS -> Material.DARK_OAK_BOAT; + case MANGROVE_PLANKS -> Material.MANGROVE_BOAT; + case BAMBOO -> Material.BAMBOO_RAFT; + default -> Material.OAK_BOAT; + }; + } + + @Override + public Objective registerNewObjective(Scoreboard scoreboard, Objective objective) { + return scoreboard.registerNewObjective(objective.getName(), + objective.getTrackedCriteria(), + objective.getDisplayName()); + } + + @Override + public HoverEvent getHoverEvent(@NotNull ItemStack itemStack) { + ItemMeta meta = itemStack.getItemMeta(); + String itemString = meta != null ? meta.getAsString() : "{}"; + return new HoverEvent(HoverEvent.Action.SHOW_ITEM, + new net.md_5.bungee.api.chat.hover.content.Item(itemStack.getType().getKey().getKey(), + itemStack.getAmount(), + ItemTag.ofNbt(itemString))); + } + + @Override + public BaseComponent getTranslatedComponent(@NotNull ItemStack itemStack) { + ItemMeta meta = itemStack.getItemMeta(); + String string = null; + if (meta != null) { + string = meta.getDisplayName(); + if (string.isEmpty() && meta.hasLocalizedName()) { + string = meta.getLocalizedName(); + } + } + + BaseComponent baseComponent; + if (string == null || string.isEmpty()) { + baseComponent = new TranslatableComponent(itemStack.getType().getItemTranslationKey()); + } else { + baseComponent = new TextComponent(string); + } + + return baseComponent; + } +} diff --git a/codex-nms/codex-nms-v1_20_2/pom.xml b/codex-nms/codex-nms-v1_20_2/pom.xml new file mode 100644 index 00000000..31ffeda0 --- /dev/null +++ b/codex-nms/codex-nms-v1_20_2/pom.xml @@ -0,0 +1,28 @@ + + + 4.0.0 + + studio.magemonkey + codex-nms + 1.1.0-R0.1-SNAPSHOT + + + codex-nms-v1_20_2 + + + + org.spigotmc + spigot-api + 1.20.2-R0.1-SNAPSHOT + provided + + + org.spigotmc + spigot + 1.20.2-R0.1-SNAPSHOT + provided + + + \ No newline at end of file diff --git a/codex-nms/codex-nms-v1_20_2/src/main/java/studio/magemonkey/codex/nms/v1_20_2/ArmorUtilImpl.java b/codex-nms/codex-nms-v1_20_2/src/main/java/studio/magemonkey/codex/nms/v1_20_2/ArmorUtilImpl.java new file mode 100644 index 00000000..906edec5 --- /dev/null +++ b/codex-nms/codex-nms-v1_20_2/src/main/java/studio/magemonkey/codex/nms/v1_20_2/ArmorUtilImpl.java @@ -0,0 +1,72 @@ +package studio.magemonkey.codex.nms.v1_20_2; + +import org.bukkit.NamespacedKey; +import org.bukkit.Registry; +import org.bukkit.inventory.meta.ArmorMeta; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.trim.ArmorTrim; +import org.bukkit.inventory.meta.trim.TrimMaterial; +import org.bukkit.inventory.meta.trim.TrimPattern; +import studio.magemonkey.codex.compat.ArmorUtil; +import studio.magemonkey.codex.util.random.Rnd; + +import java.util.Objects; + +@SuppressWarnings("UnstableApiUsage") +public class ArmorUtilImpl implements ArmorUtil { + @Override + public Object getTrimMaterial(NamespacedKey key) { + return Registry.TRIM_MATERIAL.get(key); + } + + @Override + public Object getTrimPattern(NamespacedKey key) { + return Registry.TRIM_PATTERN.get(key); + } + + @Override + public void addTrim(ItemMeta meta, String material, String pattern) { + if (!(meta instanceof ArmorMeta)) return; + ArmorMeta armorMeta = (ArmorMeta) meta; + + TrimMaterial trimMaterial = null; + if (material.equals("*")) { + int size = 0; + for (TrimMaterial ignored : Registry.TRIM_MATERIAL) { + size++; + } + int index = Rnd.get(size); + int i = 0; + for (TrimMaterial next : Registry.TRIM_MATERIAL) { + if (index == i) { + trimMaterial = next; + break; + } + i++; + } + } else { + trimMaterial = Registry.TRIM_MATERIAL.get(NamespacedKey.minecraft(material)); + } + + TrimPattern trimPattern = null; + if (pattern.equals("*")) { + int size = 0; + for (TrimPattern ignored : Registry.TRIM_PATTERN) size++; + + int index = Rnd.get(size); + int i = 0; + for (TrimPattern next : Registry.TRIM_PATTERN) { + if (index == i++) { + trimPattern = next; + break; + } + } + } else { + trimPattern = Registry.TRIM_PATTERN.get(NamespacedKey.minecraft(pattern)); + } + + ArmorTrim armorTrim = + new ArmorTrim(Objects.requireNonNull(trimMaterial), Objects.requireNonNull(trimPattern)); + armorMeta.setTrim(armorTrim); + } +} diff --git a/codex-nms/codex-nms-v1_20_2/src/main/java/studio/magemonkey/codex/nms/v1_20_2/CompatImpl.java b/codex-nms/codex-nms-v1_20_2/src/main/java/studio/magemonkey/codex/nms/v1_20_2/CompatImpl.java new file mode 100644 index 00000000..22ff8cbe --- /dev/null +++ b/codex-nms/codex-nms-v1_20_2/src/main/java/studio/magemonkey/codex/nms/v1_20_2/CompatImpl.java @@ -0,0 +1,17 @@ +package studio.magemonkey.codex.nms.v1_20_2; + +import org.bukkit.attribute.AttributeModifier; +import studio.magemonkey.codex.compat.Compat; +import studio.magemonkey.codex.api.meta.NBTAttribute; + +public class CompatImpl implements Compat { + @Override + public AttributeModifier createAttributeModifier(NBTAttribute attribute, double amount, AttributeModifier.Operation operation) { + return new AttributeModifier(ATTRIBUTE_BONUS_UUID, attribute.getNmsName(), amount, operation); + } + + @Override + public String getAttributeKey(AttributeModifier attributeModifier) { + return attributeModifier.getName(); + } +} diff --git a/codex-nms/codex-nms-v1_20_2/src/main/java/studio/magemonkey/codex/nms/v1_20_2/NMSImpl.java b/codex-nms/codex-nms-v1_20_2/src/main/java/studio/magemonkey/codex/nms/v1_20_2/NMSImpl.java new file mode 100644 index 00000000..080adde4 --- /dev/null +++ b/codex-nms/codex-nms-v1_20_2/src/main/java/studio/magemonkey/codex/nms/v1_20_2/NMSImpl.java @@ -0,0 +1,316 @@ +package studio.magemonkey.codex.nms.v1_20_2; + +import com.google.common.base.Preconditions; +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.mojang.authlib.GameProfile; +import io.netty.channel.Channel; +import net.md_5.bungee.api.chat.*; +import net.minecraft.core.BlockPosition; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.NetworkManager; +import net.minecraft.network.chat.IChatBaseComponent; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.PacketPlayOutAnimation; +import net.minecraft.server.level.WorldServer; +import net.minecraft.server.network.PlayerConnection; +import net.minecraft.world.entity.EntityLiving; +import net.minecraft.world.item.*; +import net.minecraft.world.level.block.entity.TileEntitySkull; +import net.minecraft.world.level.block.state.IBlockData; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.attribute.Attribute; +import org.bukkit.block.Block; +import org.bukkit.block.Skull; +import org.bukkit.craftbukkit.v1_20_R2.CraftWorld; +import org.bukkit.craftbukkit.v1_20_R2.entity.CraftLivingEntity; +import org.bukkit.craftbukkit.v1_20_R2.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_20_R2.inventory.CraftItemStack; +import org.bukkit.craftbukkit.v1_20_R2.util.CraftChatMessage; +import org.bukkit.entity.Boat; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.SkullMeta; +import org.bukkit.profile.PlayerProfile; +import org.bukkit.profile.PlayerTextures; +import org.bukkit.scoreboard.Objective; +import org.bukkit.scoreboard.Scoreboard; +import org.jetbrains.annotations.NotNull; +import studio.magemonkey.codex.Codex; +import studio.magemonkey.codex.compat.NMS; +import studio.magemonkey.codex.util.constants.JNumbers; + +import java.lang.reflect.Field; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Base64; +import java.util.UUID; + +public class NMSImpl implements NMS { + @Override + public String getVersion() { + return "1.20.2"; + } + + @NotNull + @Override + public Object getConnection(Player player) { + return ((CraftPlayer) player).getHandle().c; + } + + @NotNull + @Override + public Channel getChannel(@NotNull Player player) { + PlayerConnection connection = ((PlayerConnection) getConnection(player)); + // We have to reflexively get the `channel` field + try { + Field networkManagerField = getField(connection.getClass(), "c"); + networkManagerField.setAccessible(true); + NetworkManager networkManager = (NetworkManager) networkManagerField.get(connection); + return networkManager.n; + } catch (IllegalAccessException | NoSuchFieldException e) { + throw new RuntimeException("Could not get Channel field from PlayerConnection", e); + } + } + + @Override + public void sendPacket(@NotNull Player player, @NotNull Object packet) { + Preconditions.checkArgument(packet instanceof Packet, "Packet must be an instance of net.minecraft.server.Packet"); + ((PlayerConnection) getConnection(player)).a((Packet) packet); + } + + @Override + public void openChestAnimation(@NotNull Block chest, boolean open) { + WorldServer world = ((CraftWorld) chest.getWorld()).getHandle(); + BlockPosition position = new BlockPosition(chest.getX(), chest.getY(), chest.getZ()); + IBlockData blockData = world.a_(position); + world.a(position, blockData.b(), 1, open ? 1 : 0); + } + + @Override + public void sendAttackPacket(@NotNull Player player, int i) { + PacketPlayOutAnimation packet = new PacketPlayOutAnimation(((CraftPlayer) player).getHandle(), i); + sendPacket(player, packet); + } + + @NotNull + @Override + public String fixColors(@NotNull String str) { + str = str.replace("\n", "%n%"); + + IChatBaseComponent baseComponent = CraftChatMessage.fromStringOrNull(str); + String singleColor = CraftChatMessage.fromComponent(baseComponent); + + return singleColor.replace("%n%", "\n"); + } + + @Override + public double getDefaultDamage(@NotNull ItemStack itemStack) { + return getAttributeValue(itemStack, Attribute.GENERIC_ATTACK_DAMAGE); + } + + @Override + public double getDefaultSpeed(@NotNull ItemStack itemStack) { + return getAttributeValue(itemStack, Attribute.GENERIC_ATTACK_SPEED); + } + + @Override + public double getDefaultArmor(@NotNull ItemStack itemStack) { + return getAttributeValue(itemStack, Attribute.GENERIC_ARMOR); + } + + @Override + public double getDefaultToughness(@NotNull ItemStack itemStack) { + return getAttributeValue(itemStack, Attribute.GENERIC_ARMOR_TOUGHNESS); + } + + @Override + public boolean isWeapon(@NotNull ItemStack itemStack) { + net.minecraft.world.item.ItemStack nmsItem = CraftItemStack.asNMSCopy(itemStack); + Item item = nmsItem.d(); + return item instanceof ItemSword || item instanceof ItemAxe || item instanceof ItemTrident; + } + + @Override + public boolean isArmor(@NotNull ItemStack itemStack) { + net.minecraft.world.item.ItemStack nmsItem = CraftItemStack.asNMSCopy(itemStack); + Item item = nmsItem.d(); + return item instanceof ItemArmor; + } + + @Override + public boolean isTool(@NotNull ItemStack itemStack) { + net.minecraft.world.item.ItemStack nmsItem = CraftItemStack.asNMSCopy(itemStack); + Item item = nmsItem.d(); + return item instanceof ItemTool || item instanceof ItemShears; + } + + @Override + public String toJson(@NotNull ItemStack item) { + try { + NBTTagCompound nbtCompound = new NBTTagCompound(); + net.minecraft.world.item.ItemStack nmsItem = CraftItemStack.asNMSCopy(item); + + nmsItem.b(nbtCompound); + + String js = nbtCompound.toString(); + if (js.length() > JNumbers.JSON_MAX) { + ItemStack item2 = new ItemStack(item.getType()); + return toJson(item2); + } + + return js; + } catch (Exception e) { + e.printStackTrace(); + } + + return null; + } + + @Override + public void setKiller(@NotNull LivingEntity entity, @NotNull Player killer) { + try { + EntityLiving hit = ((CraftLivingEntity) entity).getHandle(); + hit.aY = ((CraftPlayer) killer).getHandle(); + Field damageTime = getField(hit.getClass(), "aZ"); + + damageTime.setAccessible(true); + + damageTime.set(hit, 100); + } catch (NoSuchFieldException | IllegalAccessException e) { + throw new RuntimeException("Unable to set killer. Something went wrong", e); + } + } + + @Override + public void changeSkull(@NotNull Block block, @NotNull String hash) { + try { + if (!(block.getState() instanceof Skull)) return; + + try { + Skull skull = (Skull) block.getState(); + PlayerProfile profile = Bukkit.createPlayerProfile(UUID.randomUUID(), hash.substring(0, 16)); + PlayerTextures textures = profile.getTextures(); + + // If the hash is a URL, we can just set the skin directly, otherwise, we need to decode + // the hash from Base64 and extract the url from the JSON data. + if (hash.startsWith("http")) { + textures.setSkin(new URL(hash)); + } else { + String decoded = new String(java.util.Base64.getDecoder().decode(hash)); + // Construct the json object + JsonObject json = new Gson().fromJson(decoded, JsonObject.class); + // Get the textures object + JsonObject texturesJson = json.getAsJsonObject("textures"); + // Get the skin object + JsonObject skin = texturesJson.getAsJsonObject("SKIN"); + // Get the url + String url = skin.get("url").getAsString(); + textures.setSkin(new URL(url)); + } + + profile = profile.update().get(); + skull.setOwnerProfile(profile); + skull.update(); + } catch (NoSuchMethodError | Exception e) { + Codex.info("Could not change skull with modern method, trying legacy method."); + if (!(block.getState() instanceof Skull)) return; + + TileEntitySkull skull = (TileEntitySkull) ((CraftWorld) block.getWorld()).getHandle().c_(new BlockPosition(block.getX(), block.getY(), block.getZ())); + if (skull == null) return; + + GameProfile profile = getNonPlayerProfile(hash); + skull.a(profile); + skull.e(); + } + } catch (Exception e) { + Codex.warn("Could not update skull"); + e.printStackTrace(); + } + } + + @Override + public void addSkullTexture(@NotNull ItemStack item, @NotNull String value, @NotNull UUID uuid) { + if (item.getType() != Material.PLAYER_HEAD) return; + + SkullMeta meta = (SkullMeta) item.getItemMeta(); + if (meta == null) return; + + try { + PlayerProfile playerProfile = Bukkit.createPlayerProfile(uuid, uuid.toString().substring(0, 16)); + String decoded = new String(Base64.getDecoder().decode(value)); + JsonObject json = new Gson().fromJson(decoded, JsonObject.class); + JsonObject texturesJson = json.getAsJsonObject("textures"); + JsonObject skin = texturesJson.getAsJsonObject("SKIN"); + String url = skin.get("url").getAsString(); + playerProfile.getTextures().setSkin(new URL(url)); + meta.setOwnerProfile(playerProfile); + item.setItemMeta(meta); + } catch (MalformedURLException | NoClassDefFoundError | NoSuchMethodError | IllegalArgumentException e) { + NMS.super.addSkullTexture(item, value, uuid); + } + } + + @Override + public Object getNMSCopy(@NotNull ItemStack item) { + return CraftItemStack.asNMSCopy(item); + } + + @Override + public Material getMaterial(Boat boat) { + Material woodType = boat.getBoatType().getMaterial(); + + return switch (woodType) { + case SPRUCE_PLANKS -> Material.SPRUCE_BOAT; + case BIRCH_PLANKS -> Material.BIRCH_BOAT; + case JUNGLE_PLANKS -> Material.JUNGLE_BOAT; + case ACACIA_PLANKS -> Material.ACACIA_BOAT; + case CHERRY_PLANKS -> Material.CHERRY_BOAT; + case DARK_OAK_PLANKS -> Material.DARK_OAK_BOAT; + case MANGROVE_PLANKS -> Material.MANGROVE_BOAT; + case BAMBOO -> Material.BAMBOO_RAFT; + default -> Material.OAK_BOAT; + }; + } + + @Override + public Objective registerNewObjective(Scoreboard scoreboard, Objective objective) { + return scoreboard.registerNewObjective(objective.getName(), + objective.getTrackedCriteria(), + objective.getDisplayName()); + } + + @Override + public HoverEvent getHoverEvent(@NotNull ItemStack itemStack) { + ItemMeta meta = itemStack.getItemMeta(); + String itemString = meta != null ? meta.getAsString() : "{}"; + return new HoverEvent(HoverEvent.Action.SHOW_ITEM, + new net.md_5.bungee.api.chat.hover.content.Item(itemStack.getType().getKey().getKey(), + itemStack.getAmount(), + ItemTag.ofNbt(itemString))); + } + + @Override + public BaseComponent getTranslatedComponent(@NotNull ItemStack itemStack) { + ItemMeta meta = itemStack.getItemMeta(); + String string = null; + if (meta != null) { + string = meta.getDisplayName(); + if (string.isEmpty() && meta.hasLocalizedName()) { + string = meta.getLocalizedName(); + } + } + + BaseComponent baseComponent; + if (string == null || string.isEmpty()) { + baseComponent = new TranslatableComponent(itemStack.getType().getItemTranslationKey()); + } else { + baseComponent = new TextComponent(string); + } + + return baseComponent; + } +} diff --git a/codex-nms/codex-nms-v1_20_4/pom.xml b/codex-nms/codex-nms-v1_20_4/pom.xml new file mode 100644 index 00000000..234b8e5d --- /dev/null +++ b/codex-nms/codex-nms-v1_20_4/pom.xml @@ -0,0 +1,28 @@ + + + 4.0.0 + + studio.magemonkey + codex-nms + 1.1.0-R0.1-SNAPSHOT + + + codex-nms-v1_20_4 + + + + org.spigotmc + spigot-api + 1.20.4-R0.1-SNAPSHOT + provided + + + org.spigotmc + spigot + 1.20.4-R0.1-SNAPSHOT + provided + + + \ No newline at end of file diff --git a/codex-nms/codex-nms-v1_20_4/src/main/java/studio/magemonkey/codex/nms/v1_20_4/ArmorUtilImpl.java b/codex-nms/codex-nms-v1_20_4/src/main/java/studio/magemonkey/codex/nms/v1_20_4/ArmorUtilImpl.java new file mode 100644 index 00000000..0bcb69b7 --- /dev/null +++ b/codex-nms/codex-nms-v1_20_4/src/main/java/studio/magemonkey/codex/nms/v1_20_4/ArmorUtilImpl.java @@ -0,0 +1,72 @@ +package studio.magemonkey.codex.nms.v1_20_4; + +import org.bukkit.NamespacedKey; +import org.bukkit.Registry; +import org.bukkit.inventory.meta.ArmorMeta; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.trim.ArmorTrim; +import org.bukkit.inventory.meta.trim.TrimMaterial; +import org.bukkit.inventory.meta.trim.TrimPattern; +import studio.magemonkey.codex.compat.ArmorUtil; +import studio.magemonkey.codex.util.random.Rnd; + +import java.util.Objects; + +@SuppressWarnings("UnstableApiUsage") +public class ArmorUtilImpl implements ArmorUtil { + @Override + public Object getTrimMaterial(NamespacedKey key) { + return Registry.TRIM_MATERIAL.get(key); + } + + @Override + public Object getTrimPattern(NamespacedKey key) { + return Registry.TRIM_PATTERN.get(key); + } + + @Override + public void addTrim(ItemMeta meta, String material, String pattern) { + if (!(meta instanceof ArmorMeta)) return; + ArmorMeta armorMeta = (ArmorMeta) meta; + + TrimMaterial trimMaterial = null; + if (material.equals("*")) { + int size = 0; + for (TrimMaterial ignored : Registry.TRIM_MATERIAL) { + size++; + } + int index = Rnd.get(size); + int i = 0; + for (TrimMaterial next : Registry.TRIM_MATERIAL) { + if (index == i) { + trimMaterial = next; + break; + } + i++; + } + } else { + trimMaterial = Registry.TRIM_MATERIAL.get(NamespacedKey.minecraft(material)); + } + + TrimPattern trimPattern = null; + if (pattern.equals("*")) { + int size = 0; + for (TrimPattern ignored : Registry.TRIM_PATTERN) size++; + + int index = Rnd.get(size); + int i = 0; + for (TrimPattern next : Registry.TRIM_PATTERN) { + if (index == i++) { + trimPattern = next; + break; + } + } + } else { + trimPattern = Registry.TRIM_PATTERN.get(NamespacedKey.minecraft(pattern)); + } + + ArmorTrim armorTrim = + new ArmorTrim(Objects.requireNonNull(trimMaterial), Objects.requireNonNull(trimPattern)); + armorMeta.setTrim(armorTrim); + } +} diff --git a/codex-nms/codex-nms-v1_20_4/src/main/java/studio/magemonkey/codex/nms/v1_20_4/CompatImpl.java b/codex-nms/codex-nms-v1_20_4/src/main/java/studio/magemonkey/codex/nms/v1_20_4/CompatImpl.java new file mode 100644 index 00000000..6b4565a8 --- /dev/null +++ b/codex-nms/codex-nms-v1_20_4/src/main/java/studio/magemonkey/codex/nms/v1_20_4/CompatImpl.java @@ -0,0 +1,17 @@ +package studio.magemonkey.codex.nms.v1_20_4; + +import org.bukkit.attribute.AttributeModifier; +import studio.magemonkey.codex.compat.Compat; +import studio.magemonkey.codex.api.meta.NBTAttribute; + +public class CompatImpl implements Compat { + @Override + public AttributeModifier createAttributeModifier(NBTAttribute attribute, double amount, AttributeModifier.Operation operation) { + return new AttributeModifier(ATTRIBUTE_BONUS_UUID, attribute.getNmsName(), amount, operation); + } + + @Override + public String getAttributeKey(AttributeModifier attributeModifier) { + return attributeModifier.getName(); + } +} diff --git a/codex-nms/codex-nms-v1_20_4/src/main/java/studio/magemonkey/codex/nms/v1_20_4/NMSImpl.java b/codex-nms/codex-nms-v1_20_4/src/main/java/studio/magemonkey/codex/nms/v1_20_4/NMSImpl.java new file mode 100644 index 00000000..4b152615 --- /dev/null +++ b/codex-nms/codex-nms-v1_20_4/src/main/java/studio/magemonkey/codex/nms/v1_20_4/NMSImpl.java @@ -0,0 +1,330 @@ +package studio.magemonkey.codex.nms.v1_20_4; + +import com.google.common.base.Preconditions; +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.mojang.authlib.GameProfile; +import io.netty.channel.Channel; +import net.md_5.bungee.api.chat.*; +import net.minecraft.core.BlockPosition; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.NetworkManager; +import net.minecraft.network.chat.IChatBaseComponent; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.PacketPlayOutAnimation; +import net.minecraft.server.level.WorldServer; +import net.minecraft.server.network.PlayerConnection; +import net.minecraft.world.entity.EntityLiving; +import net.minecraft.world.item.*; +import net.minecraft.world.level.block.entity.TileEntitySkull; +import net.minecraft.world.level.block.state.IBlockData; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.attribute.Attribute; +import org.bukkit.block.Block; +import org.bukkit.block.Skull; +import org.bukkit.craftbukkit.v1_20_R3.CraftWorld; +import org.bukkit.craftbukkit.v1_20_R3.entity.CraftLivingEntity; +import org.bukkit.craftbukkit.v1_20_R3.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_20_R3.inventory.CraftItemStack; +import org.bukkit.craftbukkit.v1_20_R3.util.CraftChatMessage; +import org.bukkit.damage.DamageSource; +import org.bukkit.damage.DamageType; +import org.bukkit.entity.Boat; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.SkullMeta; +import org.bukkit.profile.PlayerProfile; +import org.bukkit.profile.PlayerTextures; +import org.bukkit.scoreboard.Objective; +import org.bukkit.scoreboard.Scoreboard; +import org.jetbrains.annotations.NotNull; +import studio.magemonkey.codex.Codex; +import studio.magemonkey.codex.compat.NMS; +import studio.magemonkey.codex.util.constants.JNumbers; + +import java.lang.reflect.Field; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Base64; +import java.util.UUID; + +public class NMSImpl implements NMS { + @Override + public String getVersion() { + return "1.20.4"; + } + + @NotNull + @Override + public Object getConnection(Player player) { + return ((CraftPlayer) player).getHandle().c; + } + + @NotNull + @Override + public Channel getChannel(@NotNull Player player) { + PlayerConnection connection = ((PlayerConnection) getConnection(player)); + // We have to reflexively get the `channel` field + try { + Field networkManagerField = getField(connection.getClass(), "c"); + networkManagerField.setAccessible(true); + NetworkManager networkManager = (NetworkManager) networkManagerField.get(connection); + return networkManager.n; + } catch (IllegalAccessException | NoSuchFieldException e) { + throw new RuntimeException("Could not get Channel field from PlayerConnection", e); + } + } + + @Override + public void sendPacket(@NotNull Player player, @NotNull Object packet) { + Preconditions.checkArgument(packet instanceof Packet, "Packet must be an instance of net.minecraft.server.Packet"); + ((PlayerConnection) getConnection(player)).a((Packet) packet); + } + + @Override + public void openChestAnimation(@NotNull Block chest, boolean open) { + WorldServer world = ((CraftWorld) chest.getWorld()).getHandle(); + BlockPosition position = new BlockPosition(chest.getX(), chest.getY(), chest.getZ()); + IBlockData blockData = world.a_(position); + world.a(position, blockData.b(), 1, open ? 1 : 0); + } + + @Override + public void sendAttackPacket(@NotNull Player player, int i) { + PacketPlayOutAnimation packet = new PacketPlayOutAnimation(((CraftPlayer) player).getHandle(), i); + sendPacket(player, packet); + } + + @NotNull + @Override + public String fixColors(@NotNull String str) { + str = str.replace("\n", "%n%"); + + IChatBaseComponent baseComponent = CraftChatMessage.fromStringOrNull(str); + String singleColor = CraftChatMessage.fromComponent(baseComponent); + + return singleColor.replace("%n%", "\n"); + } + + @Override + public double getDefaultDamage(@NotNull ItemStack itemStack) { + return getAttributeValue(itemStack, Attribute.GENERIC_ATTACK_DAMAGE); + } + + @Override + public double getDefaultSpeed(@NotNull ItemStack itemStack) { + return getAttributeValue(itemStack, Attribute.GENERIC_ATTACK_SPEED); + } + + @Override + public double getDefaultArmor(@NotNull ItemStack itemStack) { + return getAttributeValue(itemStack, Attribute.GENERIC_ARMOR); + } + + @Override + public double getDefaultToughness(@NotNull ItemStack itemStack) { + return getAttributeValue(itemStack, Attribute.GENERIC_ARMOR_TOUGHNESS); + } + + @Override + public boolean isWeapon(@NotNull ItemStack itemStack) { + net.minecraft.world.item.ItemStack nmsItem = CraftItemStack.asNMSCopy(itemStack); + Item item = nmsItem.d(); + return item instanceof ItemSword || item instanceof ItemAxe || item instanceof ItemTrident; + } + + @Override + public boolean isArmor(@NotNull ItemStack itemStack) { + net.minecraft.world.item.ItemStack nmsItem = CraftItemStack.asNMSCopy(itemStack); + Item item = nmsItem.d(); + return item instanceof ItemArmor; + } + + @Override + public boolean isTool(@NotNull ItemStack itemStack) { + net.minecraft.world.item.ItemStack nmsItem = CraftItemStack.asNMSCopy(itemStack); + Item item = nmsItem.d(); + return item instanceof ItemTool || item instanceof ItemShears; + } + + @Override + public String toJson(@NotNull ItemStack item) { + try { + NBTTagCompound nbtCompound = new NBTTagCompound(); + net.minecraft.world.item.ItemStack nmsItem = CraftItemStack.asNMSCopy(item); + + nmsItem.b(nbtCompound); + + String js = nbtCompound.toString(); + if (js.length() > JNumbers.JSON_MAX) { + ItemStack item2 = new ItemStack(item.getType()); + return toJson(item2); + } + + return js; + } catch (Exception e) { + e.printStackTrace(); + } + + return null; + } + + @Override + public void setKiller(@NotNull LivingEntity entity, @NotNull Player killer) { + try { + EntityLiving hit = ((CraftLivingEntity) entity).getHandle(); + hit.aY = ((CraftPlayer) killer).getHandle(); + Field damageTime = getField(hit.getClass(), "aZ"); + + damageTime.setAccessible(true); + + damageTime.set(hit, 100); + } catch (NoSuchFieldException | IllegalAccessException e) { + throw new RuntimeException("Unable to set killer. Something went wrong", e); + } + } + + @Override + public void changeSkull(@NotNull Block block, @NotNull String hash) { + try { + if (!(block.getState() instanceof Skull)) return; + + try { + Skull skull = (Skull) block.getState(); + PlayerProfile profile = Bukkit.createPlayerProfile(UUID.randomUUID(), hash.substring(0, 16)); + PlayerTextures textures = profile.getTextures(); + + // If the hash is a URL, we can just set the skin directly, otherwise, we need to decode + // the hash from Base64 and extract the url from the JSON data. + if (hash.startsWith("http")) { + textures.setSkin(new URL(hash)); + } else { + String decoded = new String(java.util.Base64.getDecoder().decode(hash)); + // Construct the json object + JsonObject json = new Gson().fromJson(decoded, JsonObject.class); + // Get the textures object + JsonObject texturesJson = json.getAsJsonObject("textures"); + // Get the skin object + JsonObject skin = texturesJson.getAsJsonObject("SKIN"); + // Get the url + String url = skin.get("url").getAsString(); + textures.setSkin(new URL(url)); + } + + profile = profile.update().get(); + skull.setOwnerProfile(profile); + skull.update(); + } catch (NoSuchMethodError | Exception e) { + Codex.info("Could not change skull with modern method, trying legacy method."); + if (!(block.getState() instanceof Skull)) return; + + TileEntitySkull skull = (TileEntitySkull) ((CraftWorld) block.getWorld()).getHandle().c_(new BlockPosition(block.getX(), block.getY(), block.getZ())); + if (skull == null) return; + + GameProfile profile = getNonPlayerProfile(hash); + skull.a(profile); + skull.e(); + } + } catch (Exception e) { + Codex.warn("Could not update skull"); + e.printStackTrace(); + } + } + + @Override + public void addSkullTexture(@NotNull ItemStack item, @NotNull String value, @NotNull UUID uuid) { + if (item.getType() != Material.PLAYER_HEAD) return; + + SkullMeta meta = (SkullMeta) item.getItemMeta(); + if (meta == null) return; + + try { + PlayerProfile playerProfile = Bukkit.createPlayerProfile(uuid, uuid.toString().substring(0, 16)); + String decoded = new String(Base64.getDecoder().decode(value)); + JsonObject json = new Gson().fromJson(decoded, JsonObject.class); + JsonObject texturesJson = json.getAsJsonObject("textures"); + JsonObject skin = texturesJson.getAsJsonObject("SKIN"); + String url = skin.get("url").getAsString(); + playerProfile.getTextures().setSkin(new URL(url)); + meta.setOwnerProfile(playerProfile); + item.setItemMeta(meta); + } catch (MalformedURLException | NoClassDefFoundError | NoSuchMethodError | IllegalArgumentException e) { + NMS.super.addSkullTexture(item, value, uuid); + } + } + + @Override + public Object getNMSCopy(@NotNull ItemStack item) { + return CraftItemStack.asNMSCopy(item); + } + + @Override + public Material getMaterial(Boat boat) { + Material woodType = boat.getBoatType().getMaterial(); + + return switch (woodType) { + case SPRUCE_PLANKS -> Material.SPRUCE_BOAT; + case BIRCH_PLANKS -> Material.BIRCH_BOAT; + case JUNGLE_PLANKS -> Material.JUNGLE_BOAT; + case ACACIA_PLANKS -> Material.ACACIA_BOAT; + case CHERRY_PLANKS -> Material.CHERRY_BOAT; + case DARK_OAK_PLANKS -> Material.DARK_OAK_BOAT; + case MANGROVE_PLANKS -> Material.MANGROVE_BOAT; + case BAMBOO -> Material.BAMBOO_RAFT; + default -> Material.OAK_BOAT; + }; + } + + @Override + public Objective registerNewObjective(Scoreboard scoreboard, Objective objective) { + return scoreboard.registerNewObjective(objective.getName(), + objective.getTrackedCriteria(), + objective.getDisplayName()); + } + + @Override + public HoverEvent getHoverEvent(@NotNull ItemStack itemStack) { + ItemMeta meta = itemStack.getItemMeta(); + String itemString = meta != null ? meta.getAsString() : "{}"; + return new HoverEvent(HoverEvent.Action.SHOW_ITEM, + new net.md_5.bungee.api.chat.hover.content.Item(itemStack.getType().getKey().getKey(), + itemStack.getAmount(), + ItemTag.ofNbt(itemString))); + } + + @Override + public BaseComponent getTranslatedComponent(@NotNull ItemStack itemStack) { + ItemMeta meta = itemStack.getItemMeta(); + String string = null; + if (meta != null) { + string = meta.getDisplayName(); + if (string.isEmpty() && meta.hasLocalizedName()) { + string = meta.getLocalizedName(); + } + } + + BaseComponent baseComponent; + if (string == null || string.isEmpty()) { + baseComponent = new TranslatableComponent(itemStack.getType().getItemTranslationKey()); + } else { + baseComponent = new TextComponent(string); + } + + return baseComponent; + } + + @Override + @SuppressWarnings("UnstableApiUsage") + public EntityDamageByEntityEvent createEntityDamageEvent(@NotNull Entity entity, @NotNull Entity attacker, @NotNull EntityDamageByEntityEvent.DamageCause cause, double damage) { + return new EntityDamageByEntityEvent(attacker, + entity, + cause, + DamageSource.builder(DamageType.MOB_ATTACK).build(), + damage); + } +} diff --git a/codex-nms/codex-nms-v1_20_6/pom.xml b/codex-nms/codex-nms-v1_20_6/pom.xml new file mode 100644 index 00000000..8e245875 --- /dev/null +++ b/codex-nms/codex-nms-v1_20_6/pom.xml @@ -0,0 +1,28 @@ + + + 4.0.0 + + studio.magemonkey + codex-nms + 1.1.0-R0.1-SNAPSHOT + + + codex-nms-v1_20_6 + + + + org.spigotmc + spigot-api + 1.20.6-R0.1-SNAPSHOT + provided + + + org.spigotmc + spigot + 1.20.6-R0.1-SNAPSHOT + provided + + + \ No newline at end of file diff --git a/codex-nms/codex-nms-v1_20_6/src/main/java/studio/magemonkey/codex/nms/v1_20_6/ArmorUtilImpl.java b/codex-nms/codex-nms-v1_20_6/src/main/java/studio/magemonkey/codex/nms/v1_20_6/ArmorUtilImpl.java new file mode 100644 index 00000000..c950002c --- /dev/null +++ b/codex-nms/codex-nms-v1_20_6/src/main/java/studio/magemonkey/codex/nms/v1_20_6/ArmorUtilImpl.java @@ -0,0 +1,72 @@ +package studio.magemonkey.codex.nms.v1_20_6; + +import org.bukkit.NamespacedKey; +import org.bukkit.Registry; +import org.bukkit.inventory.meta.ArmorMeta; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.trim.ArmorTrim; +import org.bukkit.inventory.meta.trim.TrimMaterial; +import org.bukkit.inventory.meta.trim.TrimPattern; +import studio.magemonkey.codex.compat.ArmorUtil; +import studio.magemonkey.codex.util.random.Rnd; + +import java.util.Objects; + +@SuppressWarnings("UnstableApiUsage") +public class ArmorUtilImpl implements ArmorUtil { + @Override + public Object getTrimMaterial(NamespacedKey key) { + return Registry.TRIM_MATERIAL.get(key); + } + + @Override + public Object getTrimPattern(NamespacedKey key) { + return Registry.TRIM_PATTERN.get(key); + } + + @Override + public void addTrim(ItemMeta meta, String material, String pattern) { + if (!(meta instanceof ArmorMeta)) return; + ArmorMeta armorMeta = (ArmorMeta) meta; + + TrimMaterial trimMaterial = null; + if (material.equals("*")) { + int size = 0; + for (TrimMaterial ignored : Registry.TRIM_MATERIAL) { + size++; + } + int index = Rnd.get(size); + int i = 0; + for (TrimMaterial next : Registry.TRIM_MATERIAL) { + if (index == i) { + trimMaterial = next; + break; + } + i++; + } + } else { + trimMaterial = Registry.TRIM_MATERIAL.get(NamespacedKey.minecraft(material)); + } + + TrimPattern trimPattern = null; + if (pattern.equals("*")) { + int size = 0; + for (TrimPattern ignored : Registry.TRIM_PATTERN) size++; + + int index = Rnd.get(size); + int i = 0; + for (TrimPattern next : Registry.TRIM_PATTERN) { + if (index == i++) { + trimPattern = next; + break; + } + } + } else { + trimPattern = Registry.TRIM_PATTERN.get(NamespacedKey.minecraft(pattern)); + } + + ArmorTrim armorTrim = + new ArmorTrim(Objects.requireNonNull(trimMaterial), Objects.requireNonNull(trimPattern)); + armorMeta.setTrim(armorTrim); + } +} diff --git a/codex-nms/codex-nms-v1_20_6/src/main/java/studio/magemonkey/codex/nms/v1_20_6/CompatImpl.java b/codex-nms/codex-nms-v1_20_6/src/main/java/studio/magemonkey/codex/nms/v1_20_6/CompatImpl.java new file mode 100644 index 00000000..03ce6435 --- /dev/null +++ b/codex-nms/codex-nms-v1_20_6/src/main/java/studio/magemonkey/codex/nms/v1_20_6/CompatImpl.java @@ -0,0 +1,17 @@ +package studio.magemonkey.codex.nms.v1_20_6; + +import org.bukkit.attribute.AttributeModifier; +import studio.magemonkey.codex.compat.Compat; +import studio.magemonkey.codex.api.meta.NBTAttribute; + +public class CompatImpl implements Compat { + @Override + public AttributeModifier createAttributeModifier(NBTAttribute attribute, double amount, AttributeModifier.Operation operation) { + return new AttributeModifier(ATTRIBUTE_BONUS_UUID, attribute.getNmsName(), amount, operation); + } + + @Override + public String getAttributeKey(AttributeModifier attributeModifier) { + return attributeModifier.getName(); + } +} diff --git a/codex-nms/codex-nms-v1_20_6/src/main/java/studio/magemonkey/codex/nms/v1_20_6/NMSImpl.java b/codex-nms/codex-nms-v1_20_6/src/main/java/studio/magemonkey/codex/nms/v1_20_6/NMSImpl.java new file mode 100644 index 00000000..e16d5062 --- /dev/null +++ b/codex-nms/codex-nms-v1_20_6/src/main/java/studio/magemonkey/codex/nms/v1_20_6/NMSImpl.java @@ -0,0 +1,337 @@ +package studio.magemonkey.codex.nms.v1_20_6; + +import com.google.common.base.Preconditions; +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import io.netty.channel.Channel; +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.api.chat.HoverEvent; +import net.md_5.bungee.api.chat.TextComponent; +import net.md_5.bungee.api.chat.TranslatableComponent; +import net.minecraft.core.BlockPosition; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.NetworkManager; +import net.minecraft.network.chat.IChatBaseComponent; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.PacketPlayOutAnimation; +import net.minecraft.server.level.WorldServer; +import net.minecraft.server.network.PlayerConnection; +import net.minecraft.world.entity.EntityLiving; +import net.minecraft.world.item.*; +import net.minecraft.world.item.component.ResolvableProfile; +import net.minecraft.world.level.block.entity.TileEntitySkull; +import net.minecraft.world.level.block.state.IBlockData; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.attribute.Attribute; +import org.bukkit.block.Block; +import org.bukkit.block.Skull; +import org.bukkit.craftbukkit.v1_20_R4.CraftRegistry; +import org.bukkit.craftbukkit.v1_20_R4.CraftWorld; +import org.bukkit.craftbukkit.v1_20_R4.entity.CraftLivingEntity; +import org.bukkit.craftbukkit.v1_20_R4.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_20_R4.inventory.CraftItemStack; +import org.bukkit.craftbukkit.v1_20_R4.util.CraftChatMessage; +import org.bukkit.damage.DamageSource; +import org.bukkit.damage.DamageType; +import org.bukkit.entity.Boat; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.SkullMeta; +import org.bukkit.profile.PlayerProfile; +import org.bukkit.profile.PlayerTextures; +import org.bukkit.scoreboard.Objective; +import org.bukkit.scoreboard.Scoreboard; +import org.jetbrains.annotations.NotNull; +import studio.magemonkey.codex.Codex; +import studio.magemonkey.codex.compat.NMS; +import studio.magemonkey.codex.util.constants.JNumbers; + +import java.lang.reflect.Field; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Base64; +import java.util.UUID; + +public class NMSImpl implements NMS { + @Override + public String getVersion() { + return "1.20.6"; + } + + @NotNull + @Override + public Object getConnection(Player player) { + return ((CraftPlayer) player).getHandle().c; + } + + @NotNull + @Override + public Channel getChannel(@NotNull Player player) { + PlayerConnection connection = ((PlayerConnection) getConnection(player)); + // We have to reflexively get the `channel` field + try { + Field networkManagerField = getField(connection.getClass(), "e"); + networkManagerField.setAccessible(true); + NetworkManager networkManager = (NetworkManager) networkManagerField.get(connection); + return networkManager.n; + } catch (IllegalAccessException | NoSuchFieldException e) { + throw new RuntimeException("Could not get Channel field from PlayerConnection", e); + } + } + + @Override + public void sendPacket(@NotNull Player player, @NotNull Object packet) { + Preconditions.checkArgument(packet instanceof Packet, "Packet must be an instance of net.minecraft.server.Packet"); + ((PlayerConnection) getConnection(player)).a((Packet) packet); + } + + @Override + public void openChestAnimation(@NotNull Block chest, boolean open) { + WorldServer world = ((CraftWorld) chest.getWorld()).getHandle(); + BlockPosition position = new BlockPosition(chest.getX(), chest.getY(), chest.getZ()); + IBlockData blockData = world.a_(position); + world.a(position, blockData.b(), 1, open ? 1 : 0); + } + + @Override + public void sendAttackPacket(@NotNull Player player, int i) { + PacketPlayOutAnimation packet = new PacketPlayOutAnimation(((CraftPlayer) player).getHandle(), i); + sendPacket(player, packet); + } + + @NotNull + @Override + public String fixColors(@NotNull String str) { + str = str.replace("\n", "%n%"); + + IChatBaseComponent baseComponent = CraftChatMessage.fromStringOrNull(str); + String singleColor = CraftChatMessage.fromComponent(baseComponent); + + return singleColor.replace("%n%", "\n"); + } + + @Override + public double getDefaultDamage(@NotNull ItemStack itemStack) { + return getAttributeValue(itemStack, Attribute.GENERIC_ATTACK_DAMAGE); + } + + @Override + public double getDefaultSpeed(@NotNull ItemStack itemStack) { + return getAttributeValue(itemStack, Attribute.GENERIC_ATTACK_SPEED); + } + + @Override + public double getDefaultArmor(@NotNull ItemStack itemStack) { + return getAttributeValue(itemStack, Attribute.GENERIC_ARMOR); + } + + @Override + public double getDefaultToughness(@NotNull ItemStack itemStack) { + return getAttributeValue(itemStack, Attribute.GENERIC_ARMOR_TOUGHNESS); + } + + @Override + public boolean isWeapon(@NotNull ItemStack itemStack) { + net.minecraft.world.item.ItemStack nmsItem = CraftItemStack.asNMSCopy(itemStack); + Item item = nmsItem.g(); + return item instanceof ItemSword || item instanceof ItemAxe || item instanceof ItemTrident; + } + + @Override + public boolean isArmor(@NotNull ItemStack itemStack) { + net.minecraft.world.item.ItemStack nmsItem = CraftItemStack.asNMSCopy(itemStack); + Item item = nmsItem.g(); + return item instanceof ItemArmor; + } + + @Override + public boolean isTool(@NotNull ItemStack itemStack) { + net.minecraft.world.item.ItemStack nmsItem = CraftItemStack.asNMSCopy(itemStack); + Item item = nmsItem.g(); + return item instanceof ItemTool || item instanceof ItemShears; + } + + @Override + public String toJson(@NotNull ItemStack item) { + try { + NBTTagCompound nbtCompound = new NBTTagCompound(); + net.minecraft.world.item.ItemStack nmsItem = CraftItemStack.asNMSCopy(item); + + nmsItem.b(CraftRegistry.getMinecraftRegistry(), nbtCompound); + + String js = nbtCompound.toString(); + if (js.length() > JNumbers.JSON_MAX) { + ItemStack item2 = new ItemStack(item.getType()); + return toJson(item2); + } + + return js; + } catch (Exception e) { + e.printStackTrace(); + } + + return null; + } + + @Override + public void setKiller(@NotNull LivingEntity entity, @NotNull Player killer) { + try { + EntityLiving hit = ((CraftLivingEntity) entity).getHandle(); + hit.bc = ((CraftPlayer) killer).getHandle(); + Field damageTime = getField(hit.getClass(), "bd"); + + damageTime.setAccessible(true); + + damageTime.set(hit, 100); + } catch (NoSuchFieldException | IllegalAccessException e) { + throw new RuntimeException("Unable to set killer. Something went wrong", e); + } + } + + @Override + public void changeSkull(@NotNull Block block, @NotNull String hash) { + try { + if (!(block.getState() instanceof Skull)) return; + + try { + Skull skull = (Skull) block.getState(); + PlayerProfile profile = Bukkit.createPlayerProfile(UUID.randomUUID(), hash.substring(0, 16)); + PlayerTextures textures = profile.getTextures(); + + // If the hash is a URL, we can just set the skin directly, otherwise, we need to decode + // the hash from Base64 and extract the url from the JSON data. + if (hash.startsWith("http")) { + textures.setSkin(new URL(hash)); + } else { + String decoded = new String(java.util.Base64.getDecoder().decode(hash)); + // Construct the json object + JsonObject json = new Gson().fromJson(decoded, JsonObject.class); + // Get the textures object + JsonObject texturesJson = json.getAsJsonObject("textures"); + // Get the skin object + JsonObject skin = texturesJson.getAsJsonObject("SKIN"); + // Get the url + String url = skin.get("url").getAsString(); + textures.setSkin(new URL(url)); + } + + profile = profile.update().get(); + skull.setOwnerProfile(profile); + skull.update(); + } catch (NoSuchMethodError | Exception e) { + Codex.info("Could not change skull with modern method, trying legacy method."); + if (!(block.getState() instanceof Skull)) return; + + TileEntitySkull skull = (TileEntitySkull) ((CraftWorld) block.getWorld()).getHandle().c_(new BlockPosition(block.getX(), block.getY(), block.getZ())); + if (skull == null) return; + + ResolvableProfile profile = new ResolvableProfile(getNonPlayerProfile(hash)); + skull.a(profile); + skull.e(); + } + } catch (Exception e) { + Codex.warn("Could not update skull"); + e.printStackTrace(); + } + } + + @Override + public void addSkullTexture(@NotNull ItemStack item, @NotNull String value, @NotNull UUID uuid) { + if (item.getType() != Material.PLAYER_HEAD) return; + + SkullMeta meta = (SkullMeta) item.getItemMeta(); + if (meta == null) return; + + try { + PlayerProfile playerProfile = Bukkit.createPlayerProfile(uuid, uuid.toString().substring(0, 16)); + String decoded = new String(Base64.getDecoder().decode(value)); + JsonObject json = new Gson().fromJson(decoded, JsonObject.class); + JsonObject texturesJson = json.getAsJsonObject("textures"); + JsonObject skin = texturesJson.getAsJsonObject("SKIN"); + String url = skin.get("url").getAsString(); + playerProfile.getTextures().setSkin(new URL(url)); + meta.setOwnerProfile(playerProfile); + item.setItemMeta(meta); + } catch (MalformedURLException | NoClassDefFoundError | NoSuchMethodError | IllegalArgumentException e) { + NMS.super.addSkullTexture(item, value, uuid); + } + } + + @Override + public Object getNMSCopy(@NotNull ItemStack item) { + return CraftItemStack.asNMSCopy(item); + } + + @Override + public Material getMaterial(Boat boat) { + Material woodType = boat.getBoatType().getMaterial(); + + return switch (woodType) { + case SPRUCE_PLANKS -> Material.SPRUCE_BOAT; + case BIRCH_PLANKS -> Material.BIRCH_BOAT; + case JUNGLE_PLANKS -> Material.JUNGLE_BOAT; + case ACACIA_PLANKS -> Material.ACACIA_BOAT; + case CHERRY_PLANKS -> Material.CHERRY_BOAT; + case DARK_OAK_PLANKS -> Material.DARK_OAK_BOAT; + case MANGROVE_PLANKS -> Material.MANGROVE_BOAT; + case BAMBOO -> Material.BAMBOO_RAFT; + default -> Material.OAK_BOAT; + }; + } + + @Override + public Objective registerNewObjective(Scoreboard scoreboard, Objective objective) { + return scoreboard.registerNewObjective(objective.getName(), + objective.getTrackedCriteria(), + objective.getDisplayName()); + } + + @Override + @SuppressWarnings("deprecation") + public HoverEvent getHoverEvent(@NotNull ItemStack itemStack) { + String nbt = String.format("{\"id\":\"%s\",\"count\":%d,\"components\": %s}", + itemStack.getType().getKey().getKey(), + itemStack.getAmount(), + itemStack.getItemMeta() != null ? itemStack.getItemMeta().getAsString() : "{}"); + return new HoverEvent(HoverEvent.Action.SHOW_ITEM, new BaseComponent[]{new TextComponent(nbt)}); + } + + @Override + public BaseComponent getTranslatedComponent(@NotNull ItemStack itemStack) { + ItemMeta meta = itemStack.getItemMeta(); + String string = null; + if (meta != null) { + string = meta.getDisplayName(); + if (string.isEmpty()) { + try { + string = meta.getItemName(); + } catch (NoSuchMethodError ignored) { + } + } + } + + BaseComponent baseComponent; + if (string == null || string.isEmpty()) { + baseComponent = new TranslatableComponent(itemStack.getType().getItemTranslationKey()); + } else { + baseComponent = new TextComponent(string); + } + + return baseComponent; + } + + @Override + @SuppressWarnings("UnstableApiUsage") + public EntityDamageByEntityEvent createEntityDamageEvent(@NotNull Entity entity, @NotNull Entity attacker, @NotNull EntityDamageByEntityEvent.DamageCause cause, double damage) { + return new EntityDamageByEntityEvent(attacker, + entity, + cause, + DamageSource.builder(DamageType.MOB_ATTACK).build(), + damage); + } +} diff --git a/codex-nms/codex-nms-v1_21_1/pom.xml b/codex-nms/codex-nms-v1_21_1/pom.xml new file mode 100644 index 00000000..aa5fb571 --- /dev/null +++ b/codex-nms/codex-nms-v1_21_1/pom.xml @@ -0,0 +1,28 @@ + + + 4.0.0 + + studio.magemonkey + codex-nms + 1.1.0-R0.1-SNAPSHOT + + + codex-nms-v1_21_1 + + + + org.spigotmc + spigot-api + 1.21.1-R0.1-SNAPSHOT + provided + + + org.spigotmc + spigot + 1.21.1-R0.1-SNAPSHOT + provided + + + \ No newline at end of file diff --git a/codex-nms/codex-nms-v1_21_1/src/main/java/studio/magemonkey/codex/nms/v1_21_1/ArmorUtilImpl.java b/codex-nms/codex-nms-v1_21_1/src/main/java/studio/magemonkey/codex/nms/v1_21_1/ArmorUtilImpl.java new file mode 100644 index 00000000..9eaf0e08 --- /dev/null +++ b/codex-nms/codex-nms-v1_21_1/src/main/java/studio/magemonkey/codex/nms/v1_21_1/ArmorUtilImpl.java @@ -0,0 +1,72 @@ +package studio.magemonkey.codex.nms.v1_21_1; + +import org.bukkit.NamespacedKey; +import org.bukkit.Registry; +import org.bukkit.inventory.meta.ArmorMeta; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.trim.ArmorTrim; +import org.bukkit.inventory.meta.trim.TrimMaterial; +import org.bukkit.inventory.meta.trim.TrimPattern; +import studio.magemonkey.codex.compat.ArmorUtil; +import studio.magemonkey.codex.util.random.Rnd; + +import java.util.Objects; + +@SuppressWarnings("UnstableApiUsage") +public class ArmorUtilImpl implements ArmorUtil { + @Override + public Object getTrimMaterial(NamespacedKey key) { + return Registry.TRIM_MATERIAL.get(key); + } + + @Override + public Object getTrimPattern(NamespacedKey key) { + return Registry.TRIM_PATTERN.get(key); + } + + @Override + public void addTrim(ItemMeta meta, String material, String pattern) { + if (!(meta instanceof ArmorMeta)) return; + ArmorMeta armorMeta = (ArmorMeta) meta; + + TrimMaterial trimMaterial = null; + if (material.equals("*")) { + int size = 0; + for (TrimMaterial ignored : Registry.TRIM_MATERIAL) { + size++; + } + int index = Rnd.get(size); + int i = 0; + for (TrimMaterial next : Registry.TRIM_MATERIAL) { + if (index == i) { + trimMaterial = next; + break; + } + i++; + } + } else { + trimMaterial = Registry.TRIM_MATERIAL.get(NamespacedKey.minecraft(material)); + } + + TrimPattern trimPattern = null; + if (pattern.equals("*")) { + int size = 0; + for (TrimPattern ignored : Registry.TRIM_PATTERN) size++; + + int index = Rnd.get(size); + int i = 0; + for (TrimPattern next : Registry.TRIM_PATTERN) { + if (index == i++) { + trimPattern = next; + break; + } + } + } else { + trimPattern = Registry.TRIM_PATTERN.get(NamespacedKey.minecraft(pattern)); + } + + ArmorTrim armorTrim = + new ArmorTrim(Objects.requireNonNull(trimMaterial), Objects.requireNonNull(trimPattern)); + armorMeta.setTrim(armorTrim); + } +} diff --git a/codex-nms/codex-nms-v1_21_1/src/main/java/studio/magemonkey/codex/nms/v1_21_1/CompatImpl.java b/codex-nms/codex-nms-v1_21_1/src/main/java/studio/magemonkey/codex/nms/v1_21_1/CompatImpl.java new file mode 100644 index 00000000..48db2e27 --- /dev/null +++ b/codex-nms/codex-nms-v1_21_1/src/main/java/studio/magemonkey/codex/nms/v1_21_1/CompatImpl.java @@ -0,0 +1,19 @@ +package studio.magemonkey.codex.nms.v1_21_1; + +import org.bukkit.attribute.AttributeModifier; +import org.bukkit.inventory.EquipmentSlotGroup; +import studio.magemonkey.codex.compat.Compat; +import studio.magemonkey.codex.api.meta.NBTAttribute; + +public class CompatImpl implements Compat { + @Override + @SuppressWarnings("UnstableApiUsage") + public AttributeModifier createAttributeModifier(NBTAttribute attribute, double amount, AttributeModifier.Operation operation) { + return new AttributeModifier(attribute.getAttribute().getKey(), amount, operation, EquipmentSlotGroup.ANY); + } + + @Override + public String getAttributeKey(AttributeModifier attributeModifier) { + return attributeModifier.getKey().toString(); + } +} diff --git a/codex-nms/codex-nms-v1_21_1/src/main/java/studio/magemonkey/codex/nms/v1_21_1/NMSImpl.java b/codex-nms/codex-nms-v1_21_1/src/main/java/studio/magemonkey/codex/nms/v1_21_1/NMSImpl.java new file mode 100644 index 00000000..1c244b84 --- /dev/null +++ b/codex-nms/codex-nms-v1_21_1/src/main/java/studio/magemonkey/codex/nms/v1_21_1/NMSImpl.java @@ -0,0 +1,337 @@ +package studio.magemonkey.codex.nms.v1_21_1; + +import com.google.common.base.Preconditions; +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import io.netty.channel.Channel; +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.api.chat.HoverEvent; +import net.md_5.bungee.api.chat.TextComponent; +import net.md_5.bungee.api.chat.TranslatableComponent; +import net.minecraft.core.BlockPosition; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.NetworkManager; +import net.minecraft.network.chat.IChatBaseComponent; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.PacketPlayOutAnimation; +import net.minecraft.server.level.WorldServer; +import net.minecraft.server.network.PlayerConnection; +import net.minecraft.world.entity.EntityLiving; +import net.minecraft.world.item.*; +import net.minecraft.world.item.component.ResolvableProfile; +import net.minecraft.world.level.block.entity.TileEntitySkull; +import net.minecraft.world.level.block.state.IBlockData; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.attribute.Attribute; +import org.bukkit.block.Block; +import org.bukkit.block.Skull; +import org.bukkit.craftbukkit.v1_21_R1.CraftRegistry; +import org.bukkit.craftbukkit.v1_21_R1.CraftWorld; +import org.bukkit.craftbukkit.v1_21_R1.entity.CraftLivingEntity; +import org.bukkit.craftbukkit.v1_21_R1.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_21_R1.inventory.CraftItemStack; +import org.bukkit.craftbukkit.v1_21_R1.util.CraftChatMessage; +import org.bukkit.damage.DamageSource; +import org.bukkit.damage.DamageType; +import org.bukkit.entity.Boat; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.SkullMeta; +import org.bukkit.profile.PlayerProfile; +import org.bukkit.profile.PlayerTextures; +import org.bukkit.scoreboard.Objective; +import org.bukkit.scoreboard.Scoreboard; +import org.jetbrains.annotations.NotNull; +import studio.magemonkey.codex.Codex; +import studio.magemonkey.codex.compat.NMS; +import studio.magemonkey.codex.util.constants.JNumbers; + +import java.lang.reflect.Field; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Base64; +import java.util.UUID; + +public class NMSImpl implements NMS { + @Override + public String getVersion() { + return "1.21.1"; + } + + @NotNull + @Override + public Object getConnection(Player player) { + return ((CraftPlayer) player).getHandle().c; + } + + @NotNull + @Override + public Channel getChannel(@NotNull Player player) { + PlayerConnection connection = ((PlayerConnection) getConnection(player)); + // We have to reflexively get the `channel` field + try { + Field networkManagerField = getField(connection.getClass(), "e"); + networkManagerField.setAccessible(true); + NetworkManager networkManager = (NetworkManager) networkManagerField.get(connection); + return networkManager.n; + } catch (IllegalAccessException | NoSuchFieldException e) { + throw new RuntimeException("Could not get Channel field from PlayerConnection", e); + } + } + + @Override + public void sendPacket(@NotNull Player player, @NotNull Object packet) { + Preconditions.checkArgument(packet instanceof Packet, "Packet must be an instance of net.minecraft.server.Packet"); + ((PlayerConnection) getConnection(player)).a((Packet) packet); + } + + @Override + public void openChestAnimation(@NotNull Block chest, boolean open) { + WorldServer world = ((CraftWorld) chest.getWorld()).getHandle(); + BlockPosition position = new BlockPosition(chest.getX(), chest.getY(), chest.getZ()); + IBlockData blockData = world.a_(position); + world.a(position, blockData.b(), 1, open ? 1 : 0); + } + + @Override + public void sendAttackPacket(@NotNull Player player, int i) { + PacketPlayOutAnimation packet = new PacketPlayOutAnimation(((CraftPlayer) player).getHandle(), i); + sendPacket(player, packet); + } + + @NotNull + @Override + public String fixColors(@NotNull String str) { + str = str.replace("\n", "%n%"); + + IChatBaseComponent baseComponent = CraftChatMessage.fromStringOrNull(str); + String singleColor = CraftChatMessage.fromComponent(baseComponent); + + return singleColor.replace("%n%", "\n"); + } + + @Override + public double getDefaultDamage(@NotNull ItemStack itemStack) { + return getAttributeValue(itemStack, Attribute.GENERIC_ATTACK_DAMAGE); + } + + @Override + public double getDefaultSpeed(@NotNull ItemStack itemStack) { + return getAttributeValue(itemStack, Attribute.GENERIC_ATTACK_SPEED); + } + + @Override + public double getDefaultArmor(@NotNull ItemStack itemStack) { + return getAttributeValue(itemStack, Attribute.GENERIC_ARMOR); + } + + @Override + public double getDefaultToughness(@NotNull ItemStack itemStack) { + return getAttributeValue(itemStack, Attribute.GENERIC_ARMOR_TOUGHNESS); + } + + @Override + public boolean isWeapon(@NotNull ItemStack itemStack) { + net.minecraft.world.item.ItemStack nmsItem = CraftItemStack.asNMSCopy(itemStack); + Item item = nmsItem.g(); + return item instanceof ItemSword || item instanceof ItemAxe || item instanceof ItemTrident; + } + + @Override + public boolean isArmor(@NotNull ItemStack itemStack) { + net.minecraft.world.item.ItemStack nmsItem = CraftItemStack.asNMSCopy(itemStack); + Item item = nmsItem.g(); + return item instanceof ItemArmor; + } + + @Override + public boolean isTool(@NotNull ItemStack itemStack) { + net.minecraft.world.item.ItemStack nmsItem = CraftItemStack.asNMSCopy(itemStack); + Item item = nmsItem.g(); + return item instanceof ItemTool || item instanceof ItemShears; + } + + @Override + public String toJson(@NotNull ItemStack item) { + try { + NBTTagCompound nbtCompound = new NBTTagCompound(); + net.minecraft.world.item.ItemStack nmsItem = CraftItemStack.asNMSCopy(item); + + nmsItem.b(CraftRegistry.getMinecraftRegistry(), nbtCompound); + + String js = nbtCompound.toString(); + if (js.length() > JNumbers.JSON_MAX) { + ItemStack item2 = new ItemStack(item.getType()); + return toJson(item2); + } + + return js; + } catch (Exception e) { + e.printStackTrace(); + } + + return null; + } + + @Override + public void setKiller(@NotNull LivingEntity entity, @NotNull Player killer) { + try { + EntityLiving hit = ((CraftLivingEntity) entity).getHandle(); + hit.bc = ((CraftPlayer) killer).getHandle(); + Field damageTime = getField(hit.getClass(), "bd"); + + damageTime.setAccessible(true); + + damageTime.set(hit, 100); + } catch (NoSuchFieldException | IllegalAccessException e) { + throw new RuntimeException("Unable to set killer. Something went wrong", e); + } + } + + @Override + public void changeSkull(@NotNull Block block, @NotNull String hash) { + try { + if (!(block.getState() instanceof Skull)) return; + + try { + Skull skull = (Skull) block.getState(); + PlayerProfile profile = Bukkit.createPlayerProfile(UUID.randomUUID(), hash.substring(0, 16)); + PlayerTextures textures = profile.getTextures(); + + // If the hash is a URL, we can just set the skin directly, otherwise, we need to decode + // the hash from Base64 and extract the url from the JSON data. + if (hash.startsWith("http")) { + textures.setSkin(new URL(hash)); + } else { + String decoded = new String(java.util.Base64.getDecoder().decode(hash)); + // Construct the json object + JsonObject json = new Gson().fromJson(decoded, JsonObject.class); + // Get the textures object + JsonObject texturesJson = json.getAsJsonObject("textures"); + // Get the skin object + JsonObject skin = texturesJson.getAsJsonObject("SKIN"); + // Get the url + String url = skin.get("url").getAsString(); + textures.setSkin(new URL(url)); + } + + profile = profile.update().get(); + skull.setOwnerProfile(profile); + skull.update(); + } catch (NoSuchMethodError | Exception e) { + Codex.info("Could not change skull with modern method, trying legacy method."); + if (!(block.getState() instanceof Skull)) return; + + TileEntitySkull skull = (TileEntitySkull) ((CraftWorld) block.getWorld()).getHandle().c_(new BlockPosition(block.getX(), block.getY(), block.getZ())); + if (skull == null) return; + + ResolvableProfile profile = new ResolvableProfile(getNonPlayerProfile(hash)); + skull.a(profile); + skull.e(); + } + } catch (Exception e) { + Codex.warn("Could not update skull"); + e.printStackTrace(); + } + } + + @Override + public void addSkullTexture(@NotNull ItemStack item, @NotNull String value, @NotNull UUID uuid) { + if (item.getType() != Material.PLAYER_HEAD) return; + + SkullMeta meta = (SkullMeta) item.getItemMeta(); + if (meta == null) return; + + try { + PlayerProfile playerProfile = Bukkit.createPlayerProfile(uuid, uuid.toString().substring(0, 16)); + String decoded = new String(Base64.getDecoder().decode(value)); + JsonObject json = new Gson().fromJson(decoded, JsonObject.class); + JsonObject texturesJson = json.getAsJsonObject("textures"); + JsonObject skin = texturesJson.getAsJsonObject("SKIN"); + String url = skin.get("url").getAsString(); + playerProfile.getTextures().setSkin(new URL(url)); + meta.setOwnerProfile(playerProfile); + item.setItemMeta(meta); + } catch (MalformedURLException | NoClassDefFoundError | NoSuchMethodError | IllegalArgumentException e) { + NMS.super.addSkullTexture(item, value, uuid); + } + } + + @Override + public Object getNMSCopy(@NotNull ItemStack item) { + return CraftItemStack.asNMSCopy(item); + } + + @Override + public Material getMaterial(Boat boat) { + Material woodType = boat.getBoatType().getMaterial(); + + return switch (woodType) { + case SPRUCE_PLANKS -> Material.SPRUCE_BOAT; + case BIRCH_PLANKS -> Material.BIRCH_BOAT; + case JUNGLE_PLANKS -> Material.JUNGLE_BOAT; + case ACACIA_PLANKS -> Material.ACACIA_BOAT; + case CHERRY_PLANKS -> Material.CHERRY_BOAT; + case DARK_OAK_PLANKS -> Material.DARK_OAK_BOAT; + case MANGROVE_PLANKS -> Material.MANGROVE_BOAT; + case BAMBOO -> Material.BAMBOO_RAFT; + default -> Material.OAK_BOAT; + }; + } + + @Override + public Objective registerNewObjective(Scoreboard scoreboard, Objective objective) { + return scoreboard.registerNewObjective(objective.getName(), + objective.getTrackedCriteria(), + objective.getDisplayName()); + } + + @Override + @SuppressWarnings("deprecation") + public HoverEvent getHoverEvent(@NotNull ItemStack itemStack) { + String nbt = String.format("{\"id\":\"%s\",\"count\":%d,\"components\": %s}", + itemStack.getType().getKey().getKey(), + itemStack.getAmount(), + itemStack.getItemMeta() != null ? itemStack.getItemMeta().getAsString() : "{}"); + return new HoverEvent(HoverEvent.Action.SHOW_ITEM, new BaseComponent[]{new TextComponent(nbt)}); + } + + @Override + public BaseComponent getTranslatedComponent(@NotNull ItemStack itemStack) { + ItemMeta meta = itemStack.getItemMeta(); + String string = null; + if (meta != null) { + string = meta.getDisplayName(); + if (string.isEmpty()) { + try { + string = meta.getItemName(); + } catch (NoSuchMethodError ignored) { + } + } + } + + BaseComponent baseComponent; + if (string == null || string.isEmpty()) { + baseComponent = new TranslatableComponent(itemStack.getType().getItemTranslationKey()); + } else { + baseComponent = new TextComponent(string); + } + + return baseComponent; + } + + @Override + @SuppressWarnings("UnstableApiUsage") + public EntityDamageByEntityEvent createEntityDamageEvent(@NotNull Entity entity, @NotNull Entity attacker, @NotNull EntityDamageByEntityEvent.DamageCause cause, double damage) { + return new EntityDamageByEntityEvent(attacker, + entity, + cause, + DamageSource.builder(DamageType.MOB_ATTACK).build(), + damage); + } +} diff --git a/codex-nms/codex-nms-v1_21_2/pom.xml b/codex-nms/codex-nms-v1_21_2/pom.xml new file mode 100644 index 00000000..40b6a1f7 --- /dev/null +++ b/codex-nms/codex-nms-v1_21_2/pom.xml @@ -0,0 +1,28 @@ + + + 4.0.0 + + studio.magemonkey + codex-nms + 1.1.0-R0.1-SNAPSHOT + + + codex-nms-v1_21_2 + + + + org.spigotmc + spigot-api + 1.21.3-R0.1-SNAPSHOT + provided + + + org.spigotmc + spigot + 1.21.3-R0.1-SNAPSHOT + provided + + + \ No newline at end of file diff --git a/codex-nms/codex-nms-v1_21_2/src/main/java/studio/magemonkey/codex/nms/v1_21_2/ArmorUtilImpl.java b/codex-nms/codex-nms-v1_21_2/src/main/java/studio/magemonkey/codex/nms/v1_21_2/ArmorUtilImpl.java new file mode 100644 index 00000000..abd9b848 --- /dev/null +++ b/codex-nms/codex-nms-v1_21_2/src/main/java/studio/magemonkey/codex/nms/v1_21_2/ArmorUtilImpl.java @@ -0,0 +1,72 @@ +package studio.magemonkey.codex.nms.v1_21_2; + +import org.bukkit.NamespacedKey; +import org.bukkit.Registry; +import org.bukkit.inventory.meta.ArmorMeta; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.trim.ArmorTrim; +import org.bukkit.inventory.meta.trim.TrimMaterial; +import org.bukkit.inventory.meta.trim.TrimPattern; +import studio.magemonkey.codex.compat.ArmorUtil; +import studio.magemonkey.codex.util.random.Rnd; + +import java.util.Objects; + +@SuppressWarnings("UnstableApiUsage") +public class ArmorUtilImpl implements ArmorUtil { + @Override + public Object getTrimMaterial(NamespacedKey key) { + return Registry.TRIM_MATERIAL.get(key); + } + + @Override + public Object getTrimPattern(NamespacedKey key) { + return Registry.TRIM_PATTERN.get(key); + } + + @Override + public void addTrim(ItemMeta meta, String material, String pattern) { + if (!(meta instanceof ArmorMeta)) return; + ArmorMeta armorMeta = (ArmorMeta) meta; + + TrimMaterial trimMaterial = null; + if (material.equals("*")) { + int size = 0; + for (TrimMaterial ignored : Registry.TRIM_MATERIAL) { + size++; + } + int index = Rnd.get(size); + int i = 0; + for (TrimMaterial next : Registry.TRIM_MATERIAL) { + if (index == i) { + trimMaterial = next; + break; + } + i++; + } + } else { + trimMaterial = Registry.TRIM_MATERIAL.get(NamespacedKey.minecraft(material)); + } + + TrimPattern trimPattern = null; + if (pattern.equals("*")) { + int size = 0; + for (TrimPattern ignored : Registry.TRIM_PATTERN) size++; + + int index = Rnd.get(size); + int i = 0; + for (TrimPattern next : Registry.TRIM_PATTERN) { + if (index == i++) { + trimPattern = next; + break; + } + } + } else { + trimPattern = Registry.TRIM_PATTERN.get(NamespacedKey.minecraft(pattern)); + } + + ArmorTrim armorTrim = + new ArmorTrim(Objects.requireNonNull(trimMaterial), Objects.requireNonNull(trimPattern)); + armorMeta.setTrim(armorTrim); + } +} diff --git a/codex-nms/codex-nms-v1_21_2/src/main/java/studio/magemonkey/codex/nms/v1_21_2/CompatImpl.java b/codex-nms/codex-nms-v1_21_2/src/main/java/studio/magemonkey/codex/nms/v1_21_2/CompatImpl.java new file mode 100644 index 00000000..e0d9e1ee --- /dev/null +++ b/codex-nms/codex-nms-v1_21_2/src/main/java/studio/magemonkey/codex/nms/v1_21_2/CompatImpl.java @@ -0,0 +1,19 @@ +package studio.magemonkey.codex.nms.v1_21_2; + +import org.bukkit.attribute.AttributeModifier; +import org.bukkit.inventory.EquipmentSlotGroup; +import studio.magemonkey.codex.compat.Compat; +import studio.magemonkey.codex.api.meta.NBTAttribute; + +public class CompatImpl implements Compat { + @Override + @SuppressWarnings("UnstableApiUsage") + public AttributeModifier createAttributeModifier(NBTAttribute attribute, double amount, AttributeModifier.Operation operation) { + return new AttributeModifier(attribute.getAttribute().getKey(), amount, operation, EquipmentSlotGroup.ANY); + } + + @Override + public String getAttributeKey(AttributeModifier attributeModifier) { + return attributeModifier.getKey().toString(); + } +} diff --git a/codex-nms/codex-nms-v1_21_2/src/main/java/studio/magemonkey/codex/nms/v1_21_2/NMSImpl.java b/codex-nms/codex-nms-v1_21_2/src/main/java/studio/magemonkey/codex/nms/v1_21_2/NMSImpl.java new file mode 100644 index 00000000..cd63e5d9 --- /dev/null +++ b/codex-nms/codex-nms-v1_21_2/src/main/java/studio/magemonkey/codex/nms/v1_21_2/NMSImpl.java @@ -0,0 +1,342 @@ +package studio.magemonkey.codex.nms.v1_21_2; + +import com.google.common.base.Preconditions; +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import io.netty.channel.Channel; +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.api.chat.HoverEvent; +import net.md_5.bungee.api.chat.TextComponent; +import net.md_5.bungee.api.chat.TranslatableComponent; +import net.minecraft.core.BlockPosition; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.NetworkManager; +import net.minecraft.network.chat.IChatBaseComponent; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.PacketPlayOutAnimation; +import net.minecraft.server.level.WorldServer; +import net.minecraft.server.network.PlayerConnection; +import net.minecraft.world.entity.EntityLiving; +import net.minecraft.world.item.*; +import net.minecraft.world.item.component.ResolvableProfile; +import net.minecraft.world.level.block.entity.TileEntitySkull; +import net.minecraft.world.level.block.state.IBlockData; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.NamespacedKey; +import org.bukkit.Registry; +import org.bukkit.attribute.Attribute; +import org.bukkit.block.Block; +import org.bukkit.block.Skull; +import org.bukkit.craftbukkit.v1_21_R2.CraftRegistry; +import org.bukkit.craftbukkit.v1_21_R2.CraftWorld; +import org.bukkit.craftbukkit.v1_21_R2.entity.CraftLivingEntity; +import org.bukkit.craftbukkit.v1_21_R2.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_21_R2.inventory.CraftItemStack; +import org.bukkit.craftbukkit.v1_21_R2.util.CraftChatMessage; +import org.bukkit.damage.DamageSource; +import org.bukkit.damage.DamageType; +import org.bukkit.entity.Boat; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.SkullMeta; +import org.bukkit.profile.PlayerProfile; +import org.bukkit.profile.PlayerTextures; +import org.bukkit.scoreboard.Objective; +import org.bukkit.scoreboard.Scoreboard; +import org.jetbrains.annotations.NotNull; +import studio.magemonkey.codex.Codex; +import studio.magemonkey.codex.compat.NMS; +import studio.magemonkey.codex.util.constants.JNumbers; + +import java.lang.reflect.Field; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Base64; +import java.util.Locale; +import java.util.UUID; + +public class NMSImpl implements NMS { + @Override + public String getVersion() { + return "1.21.2"; + } + + @NotNull + @Override + public Object getConnection(Player player) { + return ((CraftPlayer) player).getHandle().f; + } + + @NotNull + @Override + public Channel getChannel(@NotNull Player player) { + PlayerConnection connection = ((PlayerConnection) getConnection(player)); + // We have to reflexively get the `channel` field + try { + Field networkManagerField = getField(connection.getClass(), "e"); + networkManagerField.setAccessible(true); + NetworkManager networkManager = (NetworkManager) networkManagerField.get(connection); + return networkManager.n; + } catch (IllegalAccessException | NoSuchFieldException e) { + throw new RuntimeException("Could not get Channel field from PlayerConnection", e); + } + } + + @Override + public void sendPacket(@NotNull Player player, @NotNull Object packet) { + Preconditions.checkArgument(packet instanceof Packet, "Packet must be an instance of net.minecraft.server.Packet"); + ((PlayerConnection) getConnection(player)).a((Packet) packet); + } + + @Override + public void openChestAnimation(@NotNull Block chest, boolean open) { + WorldServer world = ((CraftWorld) chest.getWorld()).getHandle(); + BlockPosition position = new BlockPosition(chest.getX(), chest.getY(), chest.getZ()); + IBlockData blockData = world.a_(position); + world.a(position, blockData.b(), 1, open ? 1 : 0); + } + + @Override + public void sendAttackPacket(@NotNull Player player, int i) { + PacketPlayOutAnimation packet = new PacketPlayOutAnimation(((CraftPlayer) player).getHandle(), i); + sendPacket(player, packet); + } + + @NotNull + @Override + public String fixColors(@NotNull String str) { + str = str.replace("\n", "%n%"); + + IChatBaseComponent baseComponent = CraftChatMessage.fromStringOrNull(str); + String singleColor = CraftChatMessage.fromComponent(baseComponent); + + return singleColor.replace("%n%", "\n"); + } + + @Override + public double getDefaultDamage(@NotNull ItemStack itemStack) { + return getAttributeValue(itemStack, Attribute.ATTACK_DAMAGE); + } + + @Override + public double getDefaultSpeed(@NotNull ItemStack itemStack) { + return getAttributeValue(itemStack, Attribute.ATTACK_SPEED); + } + + @Override + public double getDefaultArmor(@NotNull ItemStack itemStack) { + return getAttributeValue(itemStack, Attribute.ARMOR); + } + + @Override + public double getDefaultToughness(@NotNull ItemStack itemStack) { + return getAttributeValue(itemStack, Attribute.ARMOR_TOUGHNESS); + } + + @Override + public boolean isWeapon(@NotNull ItemStack itemStack) { + net.minecraft.world.item.ItemStack nmsItem = CraftItemStack.asNMSCopy(itemStack); + Item item = nmsItem.h(); + return item instanceof ItemSword || item instanceof ItemAxe || item instanceof ItemTrident; + } + + @Override + public boolean isArmor(@NotNull ItemStack itemStack) { + net.minecraft.world.item.ItemStack nmsItem = CraftItemStack.asNMSCopy(itemStack); + Item item = nmsItem.h(); + return item instanceof ItemArmor; + } + + @Override + public boolean isTool(@NotNull ItemStack itemStack) { + net.minecraft.world.item.ItemStack nmsItem = CraftItemStack.asNMSCopy(itemStack); + Item item = nmsItem.h(); + return item instanceof ItemTool || item instanceof ItemShears; + } + + @Override + public String toJson(@NotNull ItemStack item) { + try { + NBTTagCompound nbtCompound = new NBTTagCompound(); + net.minecraft.world.item.ItemStack nmsItem = CraftItemStack.asNMSCopy(item); + + nmsItem.b(CraftRegistry.getMinecraftRegistry(), nbtCompound); + + String js = nbtCompound.toString(); + if (js.length() > JNumbers.JSON_MAX) { + ItemStack item2 = new ItemStack(item.getType()); + return toJson(item2); + } + + return js; + } catch (Exception e) { + e.printStackTrace(); + } + + return null; + } + + @Override + public void setKiller(@NotNull LivingEntity entity, @NotNull Player killer) { + try { + EntityLiving hit = ((CraftLivingEntity) entity).getHandle(); + hit.bc = ((CraftPlayer) killer).getHandle(); + Field damageTime = getField(hit.getClass(), "bd"); + + damageTime.setAccessible(true); + + damageTime.set(hit, 100); + } catch (NoSuchFieldException | IllegalAccessException e) { + throw new RuntimeException("Unable to set killer. Something went wrong", e); + } + } + + @Override + public void changeSkull(@NotNull Block block, @NotNull String hash) { + try { + if (!(block.getState() instanceof Skull)) return; + + try { + Skull skull = (Skull) block.getState(); + PlayerProfile profile = Bukkit.createPlayerProfile(UUID.randomUUID(), hash.substring(0, 16)); + PlayerTextures textures = profile.getTextures(); + + // If the hash is a URL, we can just set the skin directly, otherwise, we need to decode + // the hash from Base64 and extract the url from the JSON data. + if (hash.startsWith("http")) { + textures.setSkin(new URL(hash)); + } else { + String decoded = new String(java.util.Base64.getDecoder().decode(hash)); + // Construct the json object + JsonObject json = new Gson().fromJson(decoded, JsonObject.class); + // Get the textures object + JsonObject texturesJson = json.getAsJsonObject("textures"); + // Get the skin object + JsonObject skin = texturesJson.getAsJsonObject("SKIN"); + // Get the url + String url = skin.get("url").getAsString(); + textures.setSkin(new URL(url)); + } + + profile = profile.update().get(); + skull.setOwnerProfile(profile); + skull.update(); + } catch (NoSuchMethodError | Exception e) { + Codex.info("Could not change skull with modern method, trying legacy method."); + if (!(block.getState() instanceof Skull)) return; + + TileEntitySkull skull = (TileEntitySkull) ((CraftWorld) block.getWorld()).getHandle().c_(new BlockPosition(block.getX(), block.getY(), block.getZ())); + if (skull == null) return; + + ResolvableProfile profile = new ResolvableProfile(getNonPlayerProfile(hash)); + skull.a(profile); + skull.e(); + } + } catch (Exception e) { + Codex.warn("Could not update skull"); + e.printStackTrace(); + } + } + + @Override + public void addSkullTexture(@NotNull ItemStack item, @NotNull String value, @NotNull UUID uuid) { + if (item.getType() != Material.PLAYER_HEAD) return; + + SkullMeta meta = (SkullMeta) item.getItemMeta(); + if (meta == null) return; + + try { + PlayerProfile playerProfile = Bukkit.createPlayerProfile(uuid, uuid.toString().substring(0, 16)); + String decoded = new String(Base64.getDecoder().decode(value)); + JsonObject json = new Gson().fromJson(decoded, JsonObject.class); + JsonObject texturesJson = json.getAsJsonObject("textures"); + JsonObject skin = texturesJson.getAsJsonObject("SKIN"); + String url = skin.get("url").getAsString(); + playerProfile.getTextures().setSkin(new URL(url)); + meta.setOwnerProfile(playerProfile); + item.setItemMeta(meta); + } catch (MalformedURLException | NoClassDefFoundError | NoSuchMethodError | IllegalArgumentException e) { + NMS.super.addSkullTexture(item, value, uuid); + } + } + + @NotNull + @Override + public Attribute getAttribute(String name) { + return Registry.ATTRIBUTE.getOrThrow(NamespacedKey.minecraft(name.toLowerCase(Locale.US))); + } + + @Override + public Object getNMSCopy(@NotNull ItemStack item) { + return CraftItemStack.asNMSCopy(item); + } + + @Override + public Material getMaterial(Boat boat) { + String boatClassName = boat.getClass().getSimpleName(); + // Split on capital letters and join with underscores + // ex: AcaciaBoat -> ACACIA_BOAT + String materialName = String.join("_", boatClassName.split("(?=[A-Z])")).toUpperCase(Locale.US); + Material mat = Material.matchMaterial(materialName); + + if (mat == null) mat = Material.OAK_BOAT; + + return mat; + } + + @Override + public Objective registerNewObjective(Scoreboard scoreboard, Objective objective) { + return scoreboard.registerNewObjective(objective.getName(), + objective.getTrackedCriteria(), + objective.getDisplayName()); + } + + @Override + @SuppressWarnings("deprecation") + public HoverEvent getHoverEvent(@NotNull ItemStack itemStack) { + String nbt = String.format("{\"id\":\"%s\",\"count\":%d,\"components\": %s}", + itemStack.getType().getKey().getKey(), + itemStack.getAmount(), + itemStack.getItemMeta() != null ? itemStack.getItemMeta().getAsString() : "{}"); + return new HoverEvent(HoverEvent.Action.SHOW_ITEM, new BaseComponent[]{new TextComponent(nbt)}); + } + + @Override + public BaseComponent getTranslatedComponent(@NotNull ItemStack itemStack) { + ItemMeta meta = itemStack.getItemMeta(); + String string = null; + if (meta != null) { + string = meta.getDisplayName(); + if (string.isEmpty()) { + try { + string = meta.getItemName(); + } catch (NoSuchMethodError ignored) { + } + } + } + + BaseComponent baseComponent; + if (string == null || string.isEmpty()) { + baseComponent = new TranslatableComponent(itemStack.getType().getItemTranslationKey()); + } else { + baseComponent = new TextComponent(string); + } + + return baseComponent; + } + + @Override + @SuppressWarnings("UnstableApiUsage") + public EntityDamageByEntityEvent createEntityDamageEvent(@NotNull Entity entity, @NotNull Entity attacker, @NotNull EntityDamageByEntityEvent.DamageCause cause, double damage) { + return new EntityDamageByEntityEvent(attacker, + entity, + cause, + DamageSource.builder(DamageType.MOB_ATTACK).build(), + damage); + } +} diff --git a/codex-nms/codex-nms-v1_21_4/pom.xml b/codex-nms/codex-nms-v1_21_4/pom.xml new file mode 100644 index 00000000..1af7cdf0 --- /dev/null +++ b/codex-nms/codex-nms-v1_21_4/pom.xml @@ -0,0 +1,28 @@ + + + 4.0.0 + + studio.magemonkey + codex-nms + 1.1.0-R0.1-SNAPSHOT + + + codex-nms-v1_21_4 + + + + org.spigotmc + spigot-api + 1.21.4-R0.1-SNAPSHOT + provided + + + org.spigotmc + spigot + 1.21.4-R0.1-SNAPSHOT + provided + + + \ No newline at end of file diff --git a/codex-nms/codex-nms-v1_21_4/src/main/java/studio/magemonkey/codex/nms/v1_21_4/ArmorUtilImpl.java b/codex-nms/codex-nms-v1_21_4/src/main/java/studio/magemonkey/codex/nms/v1_21_4/ArmorUtilImpl.java new file mode 100644 index 00000000..74354104 --- /dev/null +++ b/codex-nms/codex-nms-v1_21_4/src/main/java/studio/magemonkey/codex/nms/v1_21_4/ArmorUtilImpl.java @@ -0,0 +1,72 @@ +package studio.magemonkey.codex.nms.v1_21_4; + +import org.bukkit.NamespacedKey; +import org.bukkit.Registry; +import org.bukkit.inventory.meta.ArmorMeta; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.trim.ArmorTrim; +import org.bukkit.inventory.meta.trim.TrimMaterial; +import org.bukkit.inventory.meta.trim.TrimPattern; +import studio.magemonkey.codex.compat.ArmorUtil; +import studio.magemonkey.codex.util.random.Rnd; + +import java.util.Objects; + +@SuppressWarnings("UnstableApiUsage") +public class ArmorUtilImpl implements ArmorUtil { + @Override + public Object getTrimMaterial(NamespacedKey key) { + return Registry.TRIM_MATERIAL.get(key); + } + + @Override + public Object getTrimPattern(NamespacedKey key) { + return Registry.TRIM_PATTERN.get(key); + } + + @Override + public void addTrim(ItemMeta meta, String material, String pattern) { + if (!(meta instanceof ArmorMeta)) return; + ArmorMeta armorMeta = (ArmorMeta) meta; + + TrimMaterial trimMaterial = null; + if (material.equals("*")) { + int size = 0; + for (TrimMaterial ignored : Registry.TRIM_MATERIAL) { + size++; + } + int index = Rnd.get(size); + int i = 0; + for (TrimMaterial next : Registry.TRIM_MATERIAL) { + if (index == i) { + trimMaterial = next; + break; + } + i++; + } + } else { + trimMaterial = Registry.TRIM_MATERIAL.get(NamespacedKey.minecraft(material)); + } + + TrimPattern trimPattern = null; + if (pattern.equals("*")) { + int size = 0; + for (TrimPattern ignored : Registry.TRIM_PATTERN) size++; + + int index = Rnd.get(size); + int i = 0; + for (TrimPattern next : Registry.TRIM_PATTERN) { + if (index == i++) { + trimPattern = next; + break; + } + } + } else { + trimPattern = Registry.TRIM_PATTERN.get(NamespacedKey.minecraft(pattern)); + } + + ArmorTrim armorTrim = + new ArmorTrim(Objects.requireNonNull(trimMaterial), Objects.requireNonNull(trimPattern)); + armorMeta.setTrim(armorTrim); + } +} diff --git a/codex-nms/codex-nms-v1_21_4/src/main/java/studio/magemonkey/codex/nms/v1_21_4/CompatImpl.java b/codex-nms/codex-nms-v1_21_4/src/main/java/studio/magemonkey/codex/nms/v1_21_4/CompatImpl.java new file mode 100644 index 00000000..2e47512e --- /dev/null +++ b/codex-nms/codex-nms-v1_21_4/src/main/java/studio/magemonkey/codex/nms/v1_21_4/CompatImpl.java @@ -0,0 +1,19 @@ +package studio.magemonkey.codex.nms.v1_21_4; + +import org.bukkit.attribute.AttributeModifier; +import org.bukkit.inventory.EquipmentSlotGroup; +import studio.magemonkey.codex.compat.Compat; +import studio.magemonkey.codex.api.meta.NBTAttribute; + +public class CompatImpl implements Compat { + @Override + @SuppressWarnings("UnstableApiUsage") + public AttributeModifier createAttributeModifier(NBTAttribute attribute, double amount, AttributeModifier.Operation operation) { + return new AttributeModifier(attribute.getAttribute().getKey(), amount, operation, EquipmentSlotGroup.ANY); + } + + @Override + public String getAttributeKey(AttributeModifier attributeModifier) { + return attributeModifier.getKey().toString(); + } +} diff --git a/codex-nms/codex-nms-v1_21_4/src/main/java/studio/magemonkey/codex/nms/v1_21_4/NMSImpl.java b/codex-nms/codex-nms-v1_21_4/src/main/java/studio/magemonkey/codex/nms/v1_21_4/NMSImpl.java new file mode 100644 index 00000000..59896539 --- /dev/null +++ b/codex-nms/codex-nms-v1_21_4/src/main/java/studio/magemonkey/codex/nms/v1_21_4/NMSImpl.java @@ -0,0 +1,342 @@ +package studio.magemonkey.codex.nms.v1_21_4; + +import com.google.common.base.Preconditions; +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import io.netty.channel.Channel; +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.api.chat.HoverEvent; +import net.md_5.bungee.api.chat.TextComponent; +import net.md_5.bungee.api.chat.TranslatableComponent; +import net.minecraft.core.BlockPosition; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.NetworkManager; +import net.minecraft.network.chat.IChatBaseComponent; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.PacketPlayOutAnimation; +import net.minecraft.server.level.WorldServer; +import net.minecraft.server.network.PlayerConnection; +import net.minecraft.world.entity.EntityLiving; +import net.minecraft.world.item.*; +import net.minecraft.world.item.component.ResolvableProfile; +import net.minecraft.world.level.block.entity.TileEntitySkull; +import net.minecraft.world.level.block.state.IBlockData; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.NamespacedKey; +import org.bukkit.Registry; +import org.bukkit.attribute.Attribute; +import org.bukkit.block.Block; +import org.bukkit.block.Skull; +import org.bukkit.craftbukkit.v1_21_R3.CraftRegistry; +import org.bukkit.craftbukkit.v1_21_R3.CraftWorld; +import org.bukkit.craftbukkit.v1_21_R3.entity.CraftLivingEntity; +import org.bukkit.craftbukkit.v1_21_R3.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_21_R3.inventory.CraftItemStack; +import org.bukkit.craftbukkit.v1_21_R3.util.CraftChatMessage; +import org.bukkit.damage.DamageSource; +import org.bukkit.damage.DamageType; +import org.bukkit.entity.Boat; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.SkullMeta; +import org.bukkit.profile.PlayerProfile; +import org.bukkit.profile.PlayerTextures; +import org.bukkit.scoreboard.Objective; +import org.bukkit.scoreboard.Scoreboard; +import org.jetbrains.annotations.NotNull; +import studio.magemonkey.codex.Codex; +import studio.magemonkey.codex.compat.NMS; +import studio.magemonkey.codex.util.constants.JNumbers; + +import java.lang.reflect.Field; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Base64; +import java.util.Locale; +import java.util.UUID; + +public class NMSImpl implements NMS { + @Override + public String getVersion() { + return "1.21.4"; + } + + @NotNull + @Override + public Object getConnection(Player player) { + return ((CraftPlayer) player).getHandle().f; + } + + @NotNull + @Override + public Channel getChannel(@NotNull Player player) { + PlayerConnection connection = ((PlayerConnection) getConnection(player)); + // We have to reflexively get the `channel` field + try { + Field networkManagerField = getField(connection.getClass(), "e"); + networkManagerField.setAccessible(true); + NetworkManager networkManager = (NetworkManager) networkManagerField.get(connection); + return networkManager.n; + } catch (IllegalAccessException | NoSuchFieldException e) { + throw new RuntimeException("Could not get Channel field from PlayerConnection", e); + } + } + + @Override + public void sendPacket(@NotNull Player player, @NotNull Object packet) { + Preconditions.checkArgument(packet instanceof Packet, "Packet must be an instance of net.minecraft.server.Packet"); + ((PlayerConnection) getConnection(player)).a((Packet) packet); + } + + @Override + public void openChestAnimation(@NotNull Block chest, boolean open) { + WorldServer world = ((CraftWorld) chest.getWorld()).getHandle(); + BlockPosition position = new BlockPosition(chest.getX(), chest.getY(), chest.getZ()); + IBlockData blockData = world.a_(position); + world.a(position, blockData.b(), 1, open ? 1 : 0); + } + + @Override + public void sendAttackPacket(@NotNull Player player, int i) { + PacketPlayOutAnimation packet = new PacketPlayOutAnimation(((CraftPlayer) player).getHandle(), i); + sendPacket(player, packet); + } + + @NotNull + @Override + public String fixColors(@NotNull String str) { + str = str.replace("\n", "%n%"); + + IChatBaseComponent baseComponent = CraftChatMessage.fromStringOrNull(str); + String singleColor = CraftChatMessage.fromComponent(baseComponent); + + return singleColor.replace("%n%", "\n"); + } + + @Override + public double getDefaultDamage(@NotNull ItemStack itemStack) { + return getAttributeValue(itemStack, Attribute.ATTACK_DAMAGE); + } + + @Override + public double getDefaultSpeed(@NotNull ItemStack itemStack) { + return getAttributeValue(itemStack, Attribute.ATTACK_SPEED); + } + + @Override + public double getDefaultArmor(@NotNull ItemStack itemStack) { + return getAttributeValue(itemStack, Attribute.ARMOR); + } + + @Override + public double getDefaultToughness(@NotNull ItemStack itemStack) { + return getAttributeValue(itemStack, Attribute.ARMOR_TOUGHNESS); + } + + @Override + public boolean isWeapon(@NotNull ItemStack itemStack) { + net.minecraft.world.item.ItemStack nmsItem = CraftItemStack.asNMSCopy(itemStack); + Item item = nmsItem.h(); + return item instanceof ItemSword || item instanceof ItemAxe || item instanceof ItemTrident; + } + + @Override + public boolean isArmor(@NotNull ItemStack itemStack) { + net.minecraft.world.item.ItemStack nmsItem = CraftItemStack.asNMSCopy(itemStack); + Item item = nmsItem.h(); + return item instanceof ItemArmor; + } + + @Override + public boolean isTool(@NotNull ItemStack itemStack) { + net.minecraft.world.item.ItemStack nmsItem = CraftItemStack.asNMSCopy(itemStack); + Item item = nmsItem.h(); + return item instanceof ItemTool || item instanceof ItemShears; + } + + @Override + public String toJson(@NotNull ItemStack item) { + try { + NBTTagCompound nbtCompound = new NBTTagCompound(); + net.minecraft.world.item.ItemStack nmsItem = CraftItemStack.asNMSCopy(item); + + nmsItem.b(CraftRegistry.getMinecraftRegistry(), nbtCompound); + + String js = nbtCompound.toString(); + if (js.length() > JNumbers.JSON_MAX) { + ItemStack item2 = new ItemStack(item.getType()); + return toJson(item2); + } + + return js; + } catch (Exception e) { + e.printStackTrace(); + } + + return null; + } + + @Override + public void setKiller(@NotNull LivingEntity entity, @NotNull Player killer) { + try { + EntityLiving hit = ((CraftLivingEntity) entity).getHandle(); + hit.bc = ((CraftPlayer) killer).getHandle(); + Field damageTime = getField(hit.getClass(), "bd"); + + damageTime.setAccessible(true); + + damageTime.set(hit, 100); + } catch (NoSuchFieldException | IllegalAccessException e) { + throw new RuntimeException("Unable to set killer. Something went wrong", e); + } + } + + @Override + public void changeSkull(@NotNull Block block, @NotNull String hash) { + try { + if (!(block.getState() instanceof Skull)) return; + + try { + Skull skull = (Skull) block.getState(); + PlayerProfile profile = Bukkit.createPlayerProfile(UUID.randomUUID(), hash.substring(0, 16)); + PlayerTextures textures = profile.getTextures(); + + // If the hash is a URL, we can just set the skin directly, otherwise, we need to decode + // the hash from Base64 and extract the url from the JSON data. + if (hash.startsWith("http")) { + textures.setSkin(new URL(hash)); + } else { + String decoded = new String(java.util.Base64.getDecoder().decode(hash)); + // Construct the json object + JsonObject json = new Gson().fromJson(decoded, JsonObject.class); + // Get the textures object + JsonObject texturesJson = json.getAsJsonObject("textures"); + // Get the skin object + JsonObject skin = texturesJson.getAsJsonObject("SKIN"); + // Get the url + String url = skin.get("url").getAsString(); + textures.setSkin(new URL(url)); + } + + profile = profile.update().get(); + skull.setOwnerProfile(profile); + skull.update(); + } catch (NoSuchMethodError | Exception e) { + Codex.info("Could not change skull with modern method, trying legacy method."); + if (!(block.getState() instanceof Skull)) return; + + TileEntitySkull skull = (TileEntitySkull) ((CraftWorld) block.getWorld()).getHandle().c_(new BlockPosition(block.getX(), block.getY(), block.getZ())); + if (skull == null) return; + + ResolvableProfile profile = new ResolvableProfile(getNonPlayerProfile(hash)); + skull.a(profile); + skull.e(); + } + } catch (Exception e) { + Codex.warn("Could not update skull"); + e.printStackTrace(); + } + } + + @Override + public void addSkullTexture(@NotNull ItemStack item, @NotNull String value, @NotNull UUID uuid) { + if (item.getType() != Material.PLAYER_HEAD) return; + + SkullMeta meta = (SkullMeta) item.getItemMeta(); + if (meta == null) return; + + try { + PlayerProfile playerProfile = Bukkit.createPlayerProfile(uuid, uuid.toString().substring(0, 16)); + String decoded = new String(Base64.getDecoder().decode(value)); + JsonObject json = new Gson().fromJson(decoded, JsonObject.class); + JsonObject texturesJson = json.getAsJsonObject("textures"); + JsonObject skin = texturesJson.getAsJsonObject("SKIN"); + String url = skin.get("url").getAsString(); + playerProfile.getTextures().setSkin(new URL(url)); + meta.setOwnerProfile(playerProfile); + item.setItemMeta(meta); + } catch (MalformedURLException | NoClassDefFoundError | NoSuchMethodError | IllegalArgumentException e) { + NMS.super.addSkullTexture(item, value, uuid); + } + } + + @NotNull + @Override + public Attribute getAttribute(String name) { + return Registry.ATTRIBUTE.getOrThrow(NamespacedKey.minecraft(name.toLowerCase(Locale.US))); + } + + @Override + public Object getNMSCopy(@NotNull ItemStack item) { + return CraftItemStack.asNMSCopy(item); + } + + @Override + public Material getMaterial(Boat boat) { + String boatClassName = boat.getClass().getSimpleName(); + // Split on capital letters and join with underscores + // ex: AcaciaBoat -> ACACIA_BOAT + String materialName = String.join("_", boatClassName.split("(?=[A-Z])")).toUpperCase(Locale.US); + Material mat = Material.matchMaterial(materialName); + + if (mat == null) mat = Material.OAK_BOAT; + + return mat; + } + + @Override + public Objective registerNewObjective(Scoreboard scoreboard, Objective objective) { + return scoreboard.registerNewObjective(objective.getName(), + objective.getTrackedCriteria(), + objective.getDisplayName()); + } + + @Override + @SuppressWarnings("deprecation") + public HoverEvent getHoverEvent(@NotNull ItemStack itemStack) { + String nbt = String.format("{\"id\":\"%s\",\"count\":%d,\"components\": %s}", + itemStack.getType().getKey().getKey(), + itemStack.getAmount(), + itemStack.getItemMeta() != null ? itemStack.getItemMeta().getAsString() : "{}"); + return new HoverEvent(HoverEvent.Action.SHOW_ITEM, new BaseComponent[]{new TextComponent(nbt)}); + } + + @Override + public BaseComponent getTranslatedComponent(@NotNull ItemStack itemStack) { + ItemMeta meta = itemStack.getItemMeta(); + String string = null; + if (meta != null) { + string = meta.getDisplayName(); + if (string.isEmpty()) { + try { + string = meta.getItemName(); + } catch (NoSuchMethodError ignored) { + } + } + } + + BaseComponent baseComponent; + if (string == null || string.isEmpty()) { + baseComponent = new TranslatableComponent(itemStack.getType().getItemTranslationKey()); + } else { + baseComponent = new TextComponent(string); + } + + return baseComponent; + } + + @Override + @SuppressWarnings("UnstableApiUsage") + public EntityDamageByEntityEvent createEntityDamageEvent(@NotNull Entity entity, @NotNull Entity attacker, @NotNull EntityDamageByEntityEvent.DamageCause cause, double damage) { + return new EntityDamageByEntityEvent(attacker, + entity, + cause, + DamageSource.builder(DamageType.MOB_ATTACK).build(), + damage); + } +} diff --git a/codex-nms/pom.xml b/codex-nms/pom.xml new file mode 100644 index 00000000..8ece4c29 --- /dev/null +++ b/codex-nms/pom.xml @@ -0,0 +1,35 @@ + + + 4.0.0 + + studio.magemonkey + codex-parent + 1.1.0-R0.1-SNAPSHOT + + + codex-nms + pom + + codex-nms-v1_16_5 + codex-nms-v1_17_1 + codex-nms-v1_18_2 + codex-nms-v1_19_4 + codex-nms-v1_20_2 + codex-nms-v1_20_4 + codex-nms-v1_20_6 + codex-nms-v1_21_1 + codex-nms-v1_21_2 + codex-nms-v1_21_4 + + + + + studio.magemonkey + codex-api + ${project.version} + provided + + + \ No newline at end of file diff --git a/codex-plugin/.module b/codex-plugin/.module new file mode 100644 index 00000000..e69de29b diff --git a/codex-plugin/pom.xml b/codex-plugin/pom.xml new file mode 100644 index 00000000..e76ecfa1 --- /dev/null +++ b/codex-plugin/pom.xml @@ -0,0 +1,63 @@ + + + 4.0.0 + + studio.magemonkey + codex-parent + 1.1.0-R0.1-SNAPSHOT + + + codex + CodexCore + The core plugin for MageMonkeyStudio plugins + + + + studio.magemonkey + codex-core + 1.1.0-R0.1-SNAPSHOT + + + studio.magemonkey + codex-bungee + 1.1.0-R0.1-SNAPSHOT + + + + + codex-${project.version} + + + org.apache.maven.plugins + maven-shade-plugin + + false + false + + + ${project.groupId}:* + + + + + *:* + + META-INF/maven/** + + + + + + + package + + shade + + + + + + + \ No newline at end of file diff --git a/src/main/java/studio/magemonkey/codex/CodexDataPlugin.java b/codex-plugin/src/main/java/studio/magemonkey/codex/CodexDataPlugin.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/CodexDataPlugin.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/CodexDataPlugin.java diff --git a/src/main/java/studio/magemonkey/codex/CodexEngine.java b/codex-plugin/src/main/java/studio/magemonkey/codex/CodexEngine.java similarity index 86% rename from src/main/java/studio/magemonkey/codex/CodexEngine.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/CodexEngine.java index 49e5258f..1a564113 100644 --- a/src/main/java/studio/magemonkey/codex/CodexEngine.java +++ b/codex-plugin/src/main/java/studio/magemonkey/codex/CodexEngine.java @@ -1,7 +1,6 @@ package studio.magemonkey.codex; import lombok.Getter; -import lombok.Setter; import org.bukkit.Bukkit; import org.bukkit.command.PluginCommand; import org.bukkit.configuration.serialization.ConfigurationSerialization; @@ -14,7 +13,8 @@ import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPluginLoader; import org.jetbrains.annotations.NotNull; -import studio.magemonkey.codex.api.armor.ArmorListener; +import studio.magemonkey.codex.compat.VersionManager; +import studio.magemonkey.codex.api.exception.UnsupportedVersionException; import studio.magemonkey.codex.bungee.BungeeListener; import studio.magemonkey.codex.bungee.BungeeUtil; import studio.magemonkey.codex.commands.UnstuckCommand; @@ -31,6 +31,7 @@ import studio.magemonkey.codex.legacy.item.*; import studio.magemonkey.codex.legacy.placeholder.PlaceholderRegistry; import studio.magemonkey.codex.legacy.riseitem.DarkRiseItemImpl; +import studio.magemonkey.codex.listeners.ArmorListener; import studio.magemonkey.codex.listeners.BoatListener; import studio.magemonkey.codex.listeners.InteractListener; import studio.magemonkey.codex.listeners.JoinListener; @@ -44,13 +45,13 @@ import studio.magemonkey.codex.mccore.scoreboard.ScoreboardCommander; import studio.magemonkey.codex.mccore.scoreboard.UpdateTask; import studio.magemonkey.codex.migration.MigrationUtil; -import studio.magemonkey.codex.nms.NMS; import studio.magemonkey.codex.nms.packets.PacketManager; import studio.magemonkey.codex.util.Debugger; import studio.magemonkey.codex.util.ItemUT; import studio.magemonkey.codex.util.Reflex; import studio.magemonkey.codex.util.actions.ActionsManager; import studio.magemonkey.codex.util.craft.CraftManager; +import studio.magemonkey.codex.util.messages.AbstractMessageUtil; import studio.magemonkey.codex.util.messages.MessageUtil; import java.io.File; @@ -64,9 +65,6 @@ public class CodexEngine extends CodexPlugin implements Listener { private static CodexEngine instance; private final Set> plugins; @Getter - @Setter - private NMS NMS; - @Getter private PluginManager pluginManager; @Getter private PacketManager packetManager; @@ -91,6 +89,9 @@ public class CodexEngine extends CodexPlugin implements Listener { @Getter private CodexItemManager itemManager; + @Getter + private AbstractMessageUtil messageUtil = new MessageUtil(); + /** * -- GETTER -- * Checks whether Codex's chat management is enabled @@ -127,6 +128,7 @@ public CodexEngine(JavaPluginLoader loader, PluginDescriptionFile description, F private void setInstance() { instance = this; + Codex.setPlugin(this); this.pluginManager = this.getServer().getPluginManager(); try { if (new File("plugins/ProMCCore").exists()) { @@ -147,7 +149,6 @@ private void setInstance() { getLogger().warning("Failed to migrate Codex to CodexCore. " + e.getMessage()); } ItemUT.setEngine(this); - Reflex.setEngine(this); } @NotNull @@ -176,16 +177,38 @@ final boolean loadCore() { getServer().getMessenger().registerOutgoingPluginChannel(this, BungeeUtil.CHANNEL); getServer().getMessenger().registerIncomingPluginChannel(this, BungeeUtil.CHANNEL, new BungeeListener()); + // This call actually sets up the NMS version in the NMSProvider + try { + VersionManager.setup(); + getLogger().info("Using NMS implementation for version " + VersionManager.getNms().getVersion()); + } catch (Exception e) { + getLogger().severe("Failed to setup NMSProvider. Plugin will be disabled."); + + if (e instanceof UnsupportedVersionException) { + Version current = Version.CURRENT; + String[] split = Bukkit.getServer().getClass().getPackage().getName().split("\\."); + String rawVersion = split[split.length - 1]; + this.info("You are running MC version " + rawVersion); + if (current == null) { + this.error("===== CodexCore Initialization Failure ====="); + this.error(rawVersion + " is not currently supported. Is this a new version of Spigot?"); + this.error("If this is a new version, please be patient and wait for a new build supporting the new version"); + this.error("If this is a version older than 1.16.5, sorry. We don't support <1.16.5"); + this.error("============================================"); + } + } - if (!this.setupNMS()) { - this.error("Could not setup NMS version. Plugin will be disabled."); + e.printStackTrace(); return false; } - MessageUtil.load(LegacyConfigManager.loadConfigFile(new File(getDataFolder() + File.separator + "lang", + messageUtil.load(LegacyConfigManager.loadConfigFile(new File(getDataFolder() + File.separator + "lang", "messages_en.yml"), getResource("lang/messages_en.yml")), this); // Placeholder registration PlaceholderRegistry.load(); + if (CodexEngine.get().getVault() != null) { + PlaceholderRegistry.PLAYER.registerItem("money", player -> (int) CodexEngine.get().getVault().getBalance(player)); + } setupManagers(); @@ -221,24 +244,6 @@ private void setupManagers() { this.menuManager.setup(); } - private boolean setupNMS() { - Version current = Version.CURRENT; - String[] split = Bukkit.getServer().getClass().getPackage().getName().split("\\."); - String rawVersion = split[split.length - 1]; - this.info("You are running MC version " + current + " (RAW: " + rawVersion + ")"); - if (current == null) { - this.error("===== CodexCore Initialization Failure ====="); - this.error(rawVersion + " is not currently supported. Is this a new version of Spigot?"); - this.error("If this is a new version, please be patient and wait for a new build supporting the new version"); - this.error("If this is a version older than 1.16.5, sorry. We don't support <1.16.5"); - this.error("============================================"); - return false; - } - - this.setNMS(new NMS()); - return true; - } - @Override public void enable() { EditorManager.setup(); @@ -283,8 +288,7 @@ public void setConfig() { scoreboardsEnabled = this.cfg.getJYML().getBoolean("Features.scoreboards-enabled", true); // Load config data - BUNGEE_ID = cfg().getJYML().getString("bungee_id", "server"); - IS_BUNGEE = cfg().getJYML().getBoolean("bungee", false); + setupBungee(); boolean debug = cfg().getJYML().getBoolean("debug", false); Debugger.setDebug(debug); @@ -293,15 +297,26 @@ public void setConfig() { new ChatCommander(this); new ChatListener(this); } + setupScoreboards(); + + this.lang = new CoreLang(this); + this.lang.setup(); + } + + private void setupScoreboards() { if (scoreboardsEnabled) { new ScoreboardCommander(this); new BoardListener(this); cTask = new CycleTask(this); uTask = new UpdateTask(this); } + } - this.lang = new CoreLang(this); - this.lang.setup(); + private void setupBungee() { + BungeeUtil.setBungeeId(cfg().getJYML().getString("bungee_id", "server")); + BungeeUtil.setBungee(cfg().getJYML().getBoolean("bungee", false)); + BungeeUtil.setPlugin(this); + if (BungeeUtil.isBungee()) BungeeUtil.queue(); } @Override diff --git a/src/main/java/studio/magemonkey/codex/CodexPlugin.java b/codex-plugin/src/main/java/studio/magemonkey/codex/CodexPlugin.java similarity index 96% rename from src/main/java/studio/magemonkey/codex/CodexPlugin.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/CodexPlugin.java index 80f229e7..3fdad678 100644 --- a/src/main/java/studio/magemonkey/codex/CodexPlugin.java +++ b/codex-plugin/src/main/java/studio/magemonkey/codex/CodexPlugin.java @@ -28,7 +28,6 @@ import studio.magemonkey.codex.manager.api.gui.NGUI; import studio.magemonkey.codex.manager.editor.EditorHandler; import studio.magemonkey.codex.modules.ModuleManager; -import studio.magemonkey.codex.nms.NMS; import studio.magemonkey.codex.nms.packets.PacketManager; import studio.magemonkey.codex.util.InventoryUtil; import studio.magemonkey.codex.util.actions.ActionsManager; @@ -41,9 +40,6 @@ @NoArgsConstructor public abstract class CodexPlugin

> extends JavaPlugin implements Loggable { - public static boolean IS_BUNGEE = false; - public static String BUNGEE_ID = "server"; - private Logger logger; private boolean isEngine; private final boolean isSpigot = true; @@ -162,9 +158,7 @@ private void unregisterListeners() { // To prevent take items after unregister listeners for (Player p : this.getServer().getOnlinePlayers()) { if (p != null) { - Object inv = p.getOpenInventory(); - if (InventoryUtil.getTopInventory(inv) == null) continue; - InventoryHolder ih = InventoryUtil.getTopInventory(inv).getHolder(); + InventoryHolder ih = InventoryUtil.getTopInventory(p).getHolder(); if (ih instanceof NGUI) { p.closeInventory(); } @@ -277,11 +271,6 @@ public String[] getLabels() { return this.cfg().cmds; } - @NotNull - public NMS getNMS() { - return getEngine().getNMS(); - } - @NotNull public MainCommand

getMainCommand() { return this.getCommandManager().getMainCommand(); diff --git a/src/main/java/studio/magemonkey/codex/api/CommandBlock.java b/codex-plugin/src/main/java/studio/magemonkey/codex/action/CommandBlock.java similarity index 95% rename from src/main/java/studio/magemonkey/codex/api/CommandBlock.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/action/CommandBlock.java index 8e2c55a4..e3d953df 100644 --- a/src/main/java/studio/magemonkey/codex/api/CommandBlock.java +++ b/codex-plugin/src/main/java/studio/magemonkey/codex/action/CommandBlock.java @@ -1,4 +1,4 @@ -package studio.magemonkey.codex.api; +package studio.magemonkey.codex.action; import lombok.AllArgsConstructor; import lombok.Getter; @@ -16,8 +16,11 @@ import org.bukkit.event.player.PlayerEvent; import org.jetbrains.annotations.NotNull; import studio.magemonkey.codex.CodexEngine; -import studio.magemonkey.codex.util.DeserializationWorker; +import studio.magemonkey.codex.api.CommandType; +import studio.magemonkey.codex.api.DelayedCommand; +import studio.magemonkey.codex.api.Replacer; import studio.magemonkey.codex.util.SerializationBuilder; +import studio.magemonkey.codex.util.DeserializationWorker; import java.util.*; diff --git a/src/main/java/studio/magemonkey/codex/commands/CommandManager.java b/codex-plugin/src/main/java/studio/magemonkey/codex/commands/CommandManager.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/commands/CommandManager.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/commands/CommandManager.java diff --git a/src/main/java/studio/magemonkey/codex/commands/CommandRegister.java b/codex-plugin/src/main/java/studio/magemonkey/codex/commands/CommandRegister.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/commands/CommandRegister.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/commands/CommandRegister.java diff --git a/src/main/java/studio/magemonkey/codex/commands/UnstuckCommand.java b/codex-plugin/src/main/java/studio/magemonkey/codex/commands/UnstuckCommand.java similarity index 73% rename from src/main/java/studio/magemonkey/codex/commands/UnstuckCommand.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/commands/UnstuckCommand.java index d613207e..67789d6e 100644 --- a/src/main/java/studio/magemonkey/codex/commands/UnstuckCommand.java +++ b/codex-plugin/src/main/java/studio/magemonkey/codex/commands/UnstuckCommand.java @@ -17,7 +17,6 @@ import studio.magemonkey.codex.CodexEngine; import studio.magemonkey.codex.config.legacy.LegacyConfigManager; import studio.magemonkey.codex.util.messages.MessageData; -import studio.magemonkey.codex.util.messages.MessageUtil; import java.io.File; import java.io.IOException; @@ -55,8 +54,7 @@ private void saveFile() { * Purge old locations every 3 days or more */ private void purge() { - if (!config.contains("lastPurge")) - config.set("lastPurge", System.currentTimeMillis()); + if (!config.contains("lastPurge")) config.set("lastPurge", System.currentTimeMillis()); long lastPurge = config.getLong("lastPurge", System.currentTimeMillis()); long diff = System.currentTimeMillis() - lastPurge; long days = TimeUnit.MILLISECONDS.toDays(diff); @@ -69,10 +67,7 @@ private void purge() { @Override - public boolean onCommand(@NotNull CommandSender sender, - @NotNull Command command, - @NotNull String label, - String[] args) { + public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { if (!(sender instanceof Player)) { sender.sendMessage(ChatColor.RED + "You have to be a player to use that command!"); return true; @@ -85,23 +80,18 @@ public boolean onCommand(@NotNull CommandSender sender, long time = cooldown.get(id) - System.currentTimeMillis(); if (time > 0) { long seconds = TimeUnit.MILLISECONDS.toSeconds(time); - MessageUtil.sendMessage("general.commands.unstuck.err.cooldown", - sender, - new MessageData("time", seconds)); + CodexEngine.get().getMessageUtil().sendMessage("general.commands.unstuck.err.cooldown", sender, new MessageData("time", seconds)); return true; - } else - cooldown.remove(id); + } else cooldown.remove(id); } if (warmingUp.containsKey(id)) { - MessageUtil.sendMessage("general.commands.unstuck.err.warmingUp", sender); + CodexEngine.get().getMessageUtil().sendMessage("general.commands.unstuck.err.warmingUp", sender); return true; } warmingUp.put(id, player.getLocation().getBlock().getLocation()); - MessageUtil.sendMessage("general.commands.unstuck.warmup", - sender, - new MessageData("time", CodexEngine.get().cfg().getJYML().getLong("unstuck.warmup"))); + CodexEngine.get().getMessageUtil().sendMessage("general.commands.unstuck.warmup", sender, new MessageData("time", CodexEngine.get().cfg().getJYML().getLong("unstuck.warmup"))); String locStr = locToString(player.getLocation()); CodexEngine.get().getLogger().info("STUCK - " + player.getName() + " executed '/stuck' at " + locStr); @@ -120,10 +110,8 @@ public void run() { player.teleport(locs.get(player.getUniqueId()).getFirst()); tasks.remove(id); warmingUp.remove(id); - cooldown.put(id, - TimeUnit.SECONDS.toMillis(CodexEngine.get().cfg().getJYML().getLong("unstuck.cooldown")) - + System.currentTimeMillis()); - MessageUtil.sendMessage("general.commands.unstuck.teleported", sender); + cooldown.put(id, TimeUnit.SECONDS.toMillis(CodexEngine.get().cfg().getJYML().getLong("unstuck.cooldown")) + System.currentTimeMillis()); + CodexEngine.get().getMessageUtil().sendMessage("general.commands.unstuck.teleported", sender); } }.runTaskLater(CodexEngine.get(), CodexEngine.get().cfg().getJYML().getLong("unstuck.warmup") * 20); @@ -135,16 +123,12 @@ public void run() { @EventHandler public void cancelWarmup(PlayerMoveEvent event) { if (warmingUp.containsKey(event.getPlayer().getUniqueId())) { - boolean same = event.getPlayer() - .getLocation() - .getBlock() - .getLocation() - .equals(warmingUp.get(event.getPlayer().getUniqueId())); + boolean same = event.getPlayer().getLocation().getBlock().getLocation().equals(warmingUp.get(event.getPlayer().getUniqueId())); if (!same) { BukkitTask task = tasks.get(event.getPlayer().getUniqueId()); if (task != null) task.cancel(); warmingUp.remove(event.getPlayer().getUniqueId()); - MessageUtil.sendMessage("general.commands.unstuck.err.cancelled", event.getPlayer()); + CodexEngine.get().getMessageUtil().sendMessage("general.commands.unstuck.err.cancelled", event.getPlayer()); } } } @@ -162,17 +146,13 @@ public void move(PlayerMoveEvent event) { pLocs.add(p.getLocation().getBlock().getLocation()); - if (pLocs.size() > 10) - pLocs.removeFirst(); + if (pLocs.size() > 10) pLocs.removeFirst(); locs.put(p.getUniqueId(), pLocs); } public String locToString(Location loc) { - String builder = loc.getWorld().getName() + "," + loc.getX() - + "," + loc.getY() - + "," + loc.getZ(); - return builder; + return Objects.requireNonNull(loc.getWorld()).getName() + "," + loc.getX() + "," + loc.getY() + "," + loc.getZ(); } } diff --git a/src/main/java/studio/magemonkey/codex/commands/api/IAbstractCommand.java b/codex-plugin/src/main/java/studio/magemonkey/codex/commands/api/IAbstractCommand.java similarity index 96% rename from src/main/java/studio/magemonkey/codex/commands/api/IAbstractCommand.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/commands/api/IAbstractCommand.java index 2a06ab07..5bcdce81 100644 --- a/src/main/java/studio/magemonkey/codex/commands/api/IAbstractCommand.java +++ b/codex-plugin/src/main/java/studio/magemonkey/codex/commands/api/IAbstractCommand.java @@ -18,7 +18,7 @@ public abstract class IAbstractCommand

> { protected String permission; public IAbstractCommand(@NotNull P plugin, @NotNull List aliases) { - this(plugin, aliases.toArray(new String[aliases.size()])); + this(plugin, aliases.toArray(new String[0])); } public IAbstractCommand(@NotNull P plugin, @NotNull String[] aliases) { @@ -26,7 +26,7 @@ public IAbstractCommand(@NotNull P plugin, @NotNull String[] aliases) { } public IAbstractCommand(@NotNull P plugin, @NotNull List aliases, @Nullable String permission) { - this(plugin, aliases.toArray(new String[aliases.size()]), permission); + this(plugin, aliases.toArray(new String[0]), permission); } public IAbstractCommand(@NotNull P plugin, @NotNull String[] aliases, @Nullable String permission) { diff --git a/src/main/java/studio/magemonkey/codex/commands/api/IGeneralCommand.java b/codex-plugin/src/main/java/studio/magemonkey/codex/commands/api/IGeneralCommand.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/commands/api/IGeneralCommand.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/commands/api/IGeneralCommand.java diff --git a/src/main/java/studio/magemonkey/codex/commands/api/ISubCommand.java b/codex-plugin/src/main/java/studio/magemonkey/codex/commands/api/ISubCommand.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/commands/api/ISubCommand.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/commands/api/ISubCommand.java diff --git a/src/main/java/studio/magemonkey/codex/commands/list/AboutCommand.java b/codex-plugin/src/main/java/studio/magemonkey/codex/commands/list/AboutCommand.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/commands/list/AboutCommand.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/commands/list/AboutCommand.java diff --git a/src/main/java/studio/magemonkey/codex/commands/list/EditorCommand.java b/codex-plugin/src/main/java/studio/magemonkey/codex/commands/list/EditorCommand.java similarity index 89% rename from src/main/java/studio/magemonkey/codex/commands/list/EditorCommand.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/commands/list/EditorCommand.java index 2415a4e4..074b5081 100644 --- a/src/main/java/studio/magemonkey/codex/commands/list/EditorCommand.java +++ b/codex-plugin/src/main/java/studio/magemonkey/codex/commands/list/EditorCommand.java @@ -30,7 +30,7 @@ public boolean playersOnly() { } @Override - public void perform(@NotNull CommandSender sender, String label, @NotNull String[] args) { + public void perform(@NotNull CommandSender sender, @NotNull String label, @NotNull String[] args) { Player player = (Player) sender; this.plugin.openEditor(player); } diff --git a/src/main/java/studio/magemonkey/codex/commands/list/HelpCommand.java b/codex-plugin/src/main/java/studio/magemonkey/codex/commands/list/HelpCommand.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/commands/list/HelpCommand.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/commands/list/HelpCommand.java diff --git a/src/main/java/studio/magemonkey/codex/commands/list/MainCommand.java b/codex-plugin/src/main/java/studio/magemonkey/codex/commands/list/MainCommand.java similarity index 88% rename from src/main/java/studio/magemonkey/codex/commands/list/MainCommand.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/commands/list/MainCommand.java index f3bcfc6e..0a6af88c 100644 --- a/src/main/java/studio/magemonkey/codex/commands/list/MainCommand.java +++ b/codex-plugin/src/main/java/studio/magemonkey/codex/commands/list/MainCommand.java @@ -29,7 +29,7 @@ public String usage() { } @Override - public void perform(@NotNull CommandSender sender, String label, @NotNull String[] args) { + public void perform(@NotNull CommandSender sender, @NotNull String label, @NotNull String[] args) { // We do not need to put here anything as this command has defaultCommand in CommandManager. } } diff --git a/src/main/java/studio/magemonkey/codex/commands/list/ReloadCommand.java b/codex-plugin/src/main/java/studio/magemonkey/codex/commands/list/ReloadCommand.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/commands/list/ReloadCommand.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/commands/list/ReloadCommand.java diff --git a/src/main/java/studio/magemonkey/codex/config/ConfigManager.java b/codex-plugin/src/main/java/studio/magemonkey/codex/config/ConfigManager.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/config/ConfigManager.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/config/ConfigManager.java diff --git a/src/main/java/studio/magemonkey/codex/config/api/IConfigTemplate.java b/codex-plugin/src/main/java/studio/magemonkey/codex/config/api/IConfigTemplate.java similarity index 99% rename from src/main/java/studio/magemonkey/codex/config/api/IConfigTemplate.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/config/api/IConfigTemplate.java index adc9707d..907ab80a 100644 --- a/src/main/java/studio/magemonkey/codex/config/api/IConfigTemplate.java +++ b/codex-plugin/src/main/java/studio/magemonkey/codex/config/api/IConfigTemplate.java @@ -9,7 +9,6 @@ import studio.magemonkey.codex.util.StringUT; public abstract class IConfigTemplate { - protected CodexPlugin plugin; protected JYML cfg; diff --git a/src/main/java/studio/magemonkey/codex/config/api/ILangMsg.java b/codex-plugin/src/main/java/studio/magemonkey/codex/config/api/ILangMsg.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/config/api/ILangMsg.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/config/api/ILangMsg.java diff --git a/src/main/java/studio/magemonkey/codex/config/api/ILangTemplate.java b/codex-plugin/src/main/java/studio/magemonkey/codex/config/api/ILangTemplate.java similarity index 99% rename from src/main/java/studio/magemonkey/codex/config/api/ILangTemplate.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/config/api/ILangTemplate.java index a4c715c2..27e5d165 100644 --- a/src/main/java/studio/magemonkey/codex/config/api/ILangTemplate.java +++ b/codex-plugin/src/main/java/studio/magemonkey/codex/config/api/ILangTemplate.java @@ -13,7 +13,6 @@ import java.util.Map; public abstract class ILangTemplate { - protected CodexPlugin plugin; protected JYML config; protected ILangTemplate parent; diff --git a/src/main/java/studio/magemonkey/codex/config/api/JYML.java b/codex-plugin/src/main/java/studio/magemonkey/codex/config/api/JYML.java similarity index 99% rename from src/main/java/studio/magemonkey/codex/config/api/JYML.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/config/api/JYML.java index aa3b59b6..4364d145 100644 --- a/src/main/java/studio/magemonkey/codex/config/api/JYML.java +++ b/codex-plugin/src/main/java/studio/magemonkey/codex/config/api/JYML.java @@ -18,7 +18,7 @@ import studio.magemonkey.codex.CodexPlugin; import studio.magemonkey.codex.manager.api.gui.ContentType; import studio.magemonkey.codex.manager.api.gui.GuiItem; -import studio.magemonkey.codex.manager.types.ClickType; +import studio.magemonkey.codex.manager.api.ClickType; import studio.magemonkey.codex.util.*; import studio.magemonkey.codex.util.actions.ActionManipulator; import studio.magemonkey.codex.util.constants.JStrings; diff --git a/src/main/java/studio/magemonkey/codex/config/legacy/LegacyConfigManager.java b/codex-plugin/src/main/java/studio/magemonkey/codex/config/legacy/LegacyConfigManager.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/config/legacy/LegacyConfigManager.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/config/legacy/LegacyConfigManager.java diff --git a/src/main/java/studio/magemonkey/codex/core/config/CoreConfig.java b/codex-plugin/src/main/java/studio/magemonkey/codex/core/config/CoreConfig.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/core/config/CoreConfig.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/core/config/CoreConfig.java diff --git a/src/main/java/studio/magemonkey/codex/core/config/CoreLang.java b/codex-plugin/src/main/java/studio/magemonkey/codex/core/config/CoreLang.java similarity index 99% rename from src/main/java/studio/magemonkey/codex/core/config/CoreLang.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/core/config/CoreLang.java index d32f6f49..8f8e399f 100644 --- a/src/main/java/studio/magemonkey/codex/core/config/CoreLang.java +++ b/codex-plugin/src/main/java/studio/magemonkey/codex/core/config/CoreLang.java @@ -140,7 +140,7 @@ public class CoreLang extends ILangTemplate { new ILangMsg(this, "This command is for players only."); public ILangMsg Error_Internal = new ILangMsg(this, "&cInternal error!"); - public CoreLang(@NotNull CodexPlugin plugin) { + public CoreLang(@NotNull CodexPlugin plugin) { super(plugin, plugin.getConfigManager().configLang, plugin.isEngine() ? null : CodexEngine.get().lang()); } diff --git a/src/main/java/studio/magemonkey/codex/data/DataTypes.java b/codex-plugin/src/main/java/studio/magemonkey/codex/data/DataTypes.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/data/DataTypes.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/data/DataTypes.java diff --git a/src/main/java/studio/magemonkey/codex/data/IDataHandler.java b/codex-plugin/src/main/java/studio/magemonkey/codex/data/IDataHandler.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/data/IDataHandler.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/data/IDataHandler.java diff --git a/src/main/java/studio/magemonkey/codex/data/StorageType.java b/codex-plugin/src/main/java/studio/magemonkey/codex/data/StorageType.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/data/StorageType.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/data/StorageType.java diff --git a/src/main/java/studio/magemonkey/codex/data/event/EngineUserCreatedEvent.java b/codex-plugin/src/main/java/studio/magemonkey/codex/data/event/EngineUserCreatedEvent.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/data/event/EngineUserCreatedEvent.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/data/event/EngineUserCreatedEvent.java diff --git a/src/main/java/studio/magemonkey/codex/data/event/EngineUserEvent.java b/codex-plugin/src/main/java/studio/magemonkey/codex/data/event/EngineUserEvent.java similarity index 92% rename from src/main/java/studio/magemonkey/codex/data/event/EngineUserEvent.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/data/event/EngineUserEvent.java index a2bfd4ca..ce3c1660 100644 --- a/src/main/java/studio/magemonkey/codex/data/event/EngineUserEvent.java +++ b/codex-plugin/src/main/java/studio/magemonkey/codex/data/event/EngineUserEvent.java @@ -3,7 +3,7 @@ import org.jetbrains.annotations.NotNull; import studio.magemonkey.codex.CodexDataPlugin; import studio.magemonkey.codex.data.users.IAbstractUser; -import studio.magemonkey.codex.manager.api.event.IEvent; +import studio.magemonkey.codex.api.events.IEvent; public abstract class EngineUserEvent

, U extends IAbstractUser

> extends IEvent { diff --git a/src/main/java/studio/magemonkey/codex/data/event/EngineUserLoadEvent.java b/codex-plugin/src/main/java/studio/magemonkey/codex/data/event/EngineUserLoadEvent.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/data/event/EngineUserLoadEvent.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/data/event/EngineUserLoadEvent.java diff --git a/src/main/java/studio/magemonkey/codex/data/event/EngineUserUnloadEvent.java b/codex-plugin/src/main/java/studio/magemonkey/codex/data/event/EngineUserUnloadEvent.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/data/event/EngineUserUnloadEvent.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/data/event/EngineUserUnloadEvent.java diff --git a/src/main/java/studio/magemonkey/codex/data/users/IAbstractUser.java b/codex-plugin/src/main/java/studio/magemonkey/codex/data/users/IAbstractUser.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/data/users/IAbstractUser.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/data/users/IAbstractUser.java diff --git a/src/main/java/studio/magemonkey/codex/data/users/IUserManager.java b/codex-plugin/src/main/java/studio/magemonkey/codex/data/users/IUserManager.java similarity index 85% rename from src/main/java/studio/magemonkey/codex/data/users/IUserManager.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/data/users/IUserManager.java index 8b4daae0..75d6d66a 100644 --- a/src/main/java/studio/magemonkey/codex/data/users/IUserManager.java +++ b/codex-plugin/src/main/java/studio/magemonkey/codex/data/users/IUserManager.java @@ -9,8 +9,8 @@ import org.bukkit.event.player.PlayerQuitEvent; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import studio.magemonkey.codex.CodexDataPlugin; import studio.magemonkey.codex.CodexEngine; +import studio.magemonkey.codex.CodexDataPlugin; import studio.magemonkey.codex.data.event.EngineUserCreatedEvent; import studio.magemonkey.codex.data.event.EngineUserLoadEvent; import studio.magemonkey.codex.data.event.EngineUserUnloadEvent; @@ -82,7 +82,7 @@ public void autosave() { int on = this.activeUsers.size(); int off = this.toSave.size(); - this.toSave.forEach(userOff -> this.save(userOff)); + this.toSave.forEach(this::save); this.toSave.clear(); plugin.info("Auto-save: Saved " + on + " online users | " + off + " offline users."); @@ -159,9 +159,9 @@ public final U getOrLoadUser(@NotNull String uuid, boolean isId) { final U user2 = user; this.activeUsers.put(user.getUUID().toString(), user2); - // Игрок уже успел войти полностью на сервер (пройти JoinEvent) - // поэтому кастомный ивент в JoinEvent вызван не будет, а значит - // вызываем его здесь в основном потоке. + // The player has already fully joined the server (passed the JoinEvent) + // so the custom event in JoinEvent will not be called, therefore + // we call it here in the main thread. if (this.isPassJoin.remove(user2.getUUID())) { this.plugin.getServer().getScheduler().runTask(plugin, () -> { this.onUserLoad(user2); @@ -185,8 +185,7 @@ public final U getOrLoadUser(@NotNull String uuid, boolean isId) { }); this.plugin.info("Created new user data for: '" + uuid + "'"); - this.plugin.getServer().getScheduler() - .runTaskAsynchronously(plugin, () -> this.plugin.getData().addUser(user2)); + this.plugin.getServer().getScheduler().runTaskAsynchronously(plugin, () -> this.plugin.getData().addUser(user2)); this.activeUsers.put(uuid, user2); this.toCreate.remove(user2.getUUID()); return user2; @@ -262,18 +261,18 @@ public void onUserLogin(AsyncPlayerPreLoginEvent e) { public void onUserJoin(PlayerJoinEvent e) { Player player = e.getPlayer(); - // Добавляем игрока в джойн лист для дальнейших проверок. + // Add the player to the join list for further checks. this.isPassJoin.add(player.getUniqueId()); - // Если игрок до сих пор не был загружен из БД и при этом запись о нем есть в базе, - // мы выходим из метода, оставляя его в "джойн" листе, таким образом - // при завершении загрузки из БД, в методе getOrLoadUser менеджер увидит - // его и загрузит в память с вызовом кастомного ивента. + // If the player has not yet been loaded from the database and there is a record of them in the database, + // we exit the method, leaving them in the "join" list, so that + // when the loading from the database is completed, the manager will see them in the getOrLoadUser method + // and load them into memory with a custom event call. if (!this.isLoaded(player) && !this.toCreate.contains(player.getUniqueId())) return; - // Так как при загрузке данных в асихнронном режиме мы не можем получить объект игрока, - // то мы получаем уже загруженные его данные здесь для вызова кастомного ивента. - // Либо здесь же создаются новые данные если игрока не было в базе. + // Since we cannot get the player object when loading data asynchronously, + // we get their already loaded data here to call the custom event. + // Or new data is created here if the player was not in the database. @Nullable U user = this.getOrLoadUser(player); if (user == null) return; diff --git a/src/main/java/studio/magemonkey/codex/hooks/HookManager.java b/codex-plugin/src/main/java/studio/magemonkey/codex/hooks/HookManager.java similarity index 91% rename from src/main/java/studio/magemonkey/codex/hooks/HookManager.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/hooks/HookManager.java index f266a416..27df3103 100644 --- a/src/main/java/studio/magemonkey/codex/hooks/HookManager.java +++ b/codex-plugin/src/main/java/studio/magemonkey/codex/hooks/HookManager.java @@ -26,12 +26,12 @@ public void setup() { @Override public void shutdown() { - this.hooks.values().forEach(hooks -> hooks.forEach(hook -> hook.unhook())); + this.hooks.values().forEach(hooks -> hooks.forEach(NHook::unhook)); this.hooks.clear(); } public void shutdown(@NotNull CodexPlugin holder) { - this.getHooks(holder).forEach(hook -> hook.unhook()); + this.getHooks(holder).forEach(NHook::unhook); this.hooks.remove(holder.getName()); } @@ -44,10 +44,8 @@ public > T register(@NotNull CodexPlugin holder, T hook; try { hook = clazz.getConstructor(holder.getClass()).newInstance(holder); - if (hook != null) { - hook.pluginName = pluginName; - return this.register(holder, hook); - } + hook.pluginName = pluginName; + return this.register(holder, hook); } catch (Exception | NoClassDefFoundError e) { holder.error("Could not initialize hook for '" + clazz.getSimpleName() + "' !"); e.printStackTrace(); diff --git a/src/main/java/studio/magemonkey/codex/hooks/Hooks.java b/codex-plugin/src/main/java/studio/magemonkey/codex/hooks/Hooks.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/hooks/Hooks.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/hooks/Hooks.java diff --git a/src/main/java/studio/magemonkey/codex/hooks/NHook.java b/codex-plugin/src/main/java/studio/magemonkey/codex/hooks/NHook.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/hooks/NHook.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/hooks/NHook.java diff --git a/src/main/java/studio/magemonkey/codex/hooks/external/IMythicHook.java b/codex-plugin/src/main/java/studio/magemonkey/codex/hooks/external/IMythicHook.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/hooks/external/IMythicHook.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/hooks/external/IMythicHook.java diff --git a/src/main/java/studio/magemonkey/codex/hooks/external/MythicMobsHK.java b/codex-plugin/src/main/java/studio/magemonkey/codex/hooks/external/MythicMobsHK.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/hooks/external/MythicMobsHK.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/hooks/external/MythicMobsHK.java diff --git a/src/main/java/studio/magemonkey/codex/hooks/external/MythicMobsHKv5.java b/codex-plugin/src/main/java/studio/magemonkey/codex/hooks/external/MythicMobsHKv5.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/hooks/external/MythicMobsHKv5.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/hooks/external/MythicMobsHKv5.java diff --git a/src/main/java/studio/magemonkey/codex/hooks/external/VaultHK.java b/codex-plugin/src/main/java/studio/magemonkey/codex/hooks/external/VaultHK.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/hooks/external/VaultHK.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/hooks/external/VaultHK.java diff --git a/src/main/java/studio/magemonkey/codex/hooks/external/WorldGuardHK.java b/codex-plugin/src/main/java/studio/magemonkey/codex/hooks/external/WorldGuardHK.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/hooks/external/WorldGuardHK.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/hooks/external/WorldGuardHK.java diff --git a/src/main/java/studio/magemonkey/codex/hooks/external/citizens/CitizensHK.java b/codex-plugin/src/main/java/studio/magemonkey/codex/hooks/external/citizens/CitizensHK.java similarity index 99% rename from src/main/java/studio/magemonkey/codex/hooks/external/citizens/CitizensHK.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/hooks/external/citizens/CitizensHK.java index 89aa8ea1..c0bb85c8 100644 --- a/src/main/java/studio/magemonkey/codex/hooks/external/citizens/CitizensHK.java +++ b/codex-plugin/src/main/java/studio/magemonkey/codex/hooks/external/citizens/CitizensHK.java @@ -16,7 +16,6 @@ import java.util.*; public class CitizensHK extends NHook { - private Map, Set> traits; private Map, Set> listeners; diff --git a/src/main/java/studio/magemonkey/codex/hooks/external/citizens/CitizensListener.java b/codex-plugin/src/main/java/studio/magemonkey/codex/hooks/external/citizens/CitizensListener.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/hooks/external/citizens/CitizensListener.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/hooks/external/citizens/CitizensListener.java diff --git a/src/main/java/studio/magemonkey/codex/items/CodexItemManager.java b/codex-plugin/src/main/java/studio/magemonkey/codex/items/CodexItemManager.java similarity index 91% rename from src/main/java/studio/magemonkey/codex/items/CodexItemManager.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/items/CodexItemManager.java index be3999a3..1fd65fcb 100644 --- a/src/main/java/studio/magemonkey/codex/items/CodexItemManager.java +++ b/codex-plugin/src/main/java/studio/magemonkey/codex/items/CodexItemManager.java @@ -5,9 +5,10 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import studio.magemonkey.codex.CodexEngine; -import studio.magemonkey.codex.items.exception.MissingItemException; -import studio.magemonkey.codex.items.exception.MissingProviderException; -import studio.magemonkey.codex.items.providers.*; +import studio.magemonkey.codex.api.items.ItemType; +import studio.magemonkey.codex.api.items.exception.MissingItemException; +import studio.magemonkey.codex.api.items.exception.MissingProviderException; +import studio.magemonkey.codex.api.items.providers.*; import java.util.*; import java.util.logging.Logger; @@ -19,18 +20,6 @@ public class CodexItemManager { private final Map> providers = new LinkedHashMap<>(); - /** - * Removes the given prefix from the provided id, if applicable. - * - * @param prefix the provider prefix to remove - * @param id the item id, prefixed or not - * @return the stripped id - */ - public static String stripPrefix(String prefix, String id) { - String[] split = id.split("_", 2); - return split.length == 2 && split[0].equalsIgnoreCase(prefix) ? split[1] : id; - } - /** * Removes any prefixes corresponding to the currently registered Item Providers, if there is any. * diff --git a/src/main/java/studio/magemonkey/codex/legacy/RisePlugin.java b/codex-plugin/src/main/java/studio/magemonkey/codex/legacy/RisePlugin.java similarity index 88% rename from src/main/java/studio/magemonkey/codex/legacy/RisePlugin.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/legacy/RisePlugin.java index a7fca3e8..4cccd377 100644 --- a/src/main/java/studio/magemonkey/codex/legacy/RisePlugin.java +++ b/codex-plugin/src/main/java/studio/magemonkey/codex/legacy/RisePlugin.java @@ -7,9 +7,9 @@ import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.scheduler.BukkitTask; +import studio.magemonkey.codex.CodexEngine; import studio.magemonkey.codex.config.legacy.LegacyConfigManager; import studio.magemonkey.codex.util.messages.MessageData; -import studio.magemonkey.codex.util.messages.MessageUtil; import java.io.File; import java.io.FileWriter; @@ -21,7 +21,7 @@ public class RisePlugin extends JavaPlugin { public Logger log; - { + public RisePlugin() { log = this.getLogger(); } @@ -50,7 +50,7 @@ public BukkitTask runTaskAsynchronously(Runnable run) { public boolean checkPermission(CommandSender sender, String s) { if (!(sender instanceof ConsoleCommandSender) && !sender.hasPermission(s)) { - MessageUtil.sendMessage("noPermissions", sender, new MessageData("permission", s)); + CodexEngine.get().getMessageUtil().sendMessage("noPermissions", sender, new MessageData("permission", s)); return false; } @@ -93,21 +93,21 @@ public void loadLang() { FileConfiguration conf = getLang(); if (conf == null) return; - MessageUtil.load(conf, this); + CodexEngine.get().getMessageUtil().load(conf, this); } public void reloadLang() { FileConfiguration conf = getLang(); if (conf == null) return; - MessageUtil.reload(conf, this); + CodexEngine.get().getMessageUtil().reload(conf, this); } public void reloadMessages() { FileConfiguration lang = LegacyConfigManager.loadConfigFile(new File(getDataFolder() + File.separator + "lang", "lang_en.yml"), getResource("lang/lang_en.yml")); - MessageUtil.reload(lang, this); + CodexEngine.get().getMessageUtil().reload(lang, this); } } \ No newline at end of file diff --git a/src/main/java/studio/magemonkey/codex/legacy/command/RiseCommand.java b/codex-plugin/src/main/java/studio/magemonkey/codex/legacy/command/RiseCommand.java similarity index 98% rename from src/main/java/studio/magemonkey/codex/legacy/command/RiseCommand.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/legacy/command/RiseCommand.java index 64f1d2ef..4183d364 100644 --- a/src/main/java/studio/magemonkey/codex/legacy/command/RiseCommand.java +++ b/codex-plugin/src/main/java/studio/magemonkey/codex/legacy/command/RiseCommand.java @@ -6,6 +6,7 @@ import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; import org.jetbrains.annotations.Nullable; +import studio.magemonkey.codex.CodexEngine; import studio.magemonkey.codex.util.messages.MessageData; import studio.magemonkey.codex.util.messages.MessageUtil; @@ -168,7 +169,7 @@ public void sendUsage(String usage, CommandSender sender, RiseCommand command, S } } String s = sb.toString(); - MessageUtil.sendMessage(usage, + CodexEngine.get().getMessageUtil().sendMessage(usage, sender, new MessageData("text", (s.isEmpty() ? "" : s + " ") + StringUtils.join(args, " "))); } diff --git a/src/main/java/studio/magemonkey/codex/legacy/item/BlockColors.java b/codex-plugin/src/main/java/studio/magemonkey/codex/legacy/item/BlockColors.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/legacy/item/BlockColors.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/legacy/item/BlockColors.java diff --git a/src/main/java/studio/magemonkey/codex/legacy/item/BookDataBuilder.java b/codex-plugin/src/main/java/studio/magemonkey/codex/legacy/item/BookDataBuilder.java similarity index 91% rename from src/main/java/studio/magemonkey/codex/legacy/item/BookDataBuilder.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/legacy/item/BookDataBuilder.java index b1d2d94a..fd755ab3 100644 --- a/src/main/java/studio/magemonkey/codex/legacy/item/BookDataBuilder.java +++ b/codex-plugin/src/main/java/studio/magemonkey/codex/legacy/item/BookDataBuilder.java @@ -7,8 +7,8 @@ import org.bukkit.inventory.meta.BookMeta; import org.bukkit.inventory.meta.ItemMeta; import org.jetbrains.annotations.NotNull; +import studio.magemonkey.codex.legacy.utils.Utils; import studio.magemonkey.codex.util.DeserializationWorker; -import studio.magemonkey.codex.util.ItemUtils; import studio.magemonkey.codex.util.SerializationBuilder; import java.util.*; @@ -112,9 +112,9 @@ public void apply(final ItemMeta itemMeta) { } BookMeta meta = (BookMeta) itemMeta; - meta.setPages(ItemUtils.fixColors(this.pages)); - meta.setAuthor(ItemUtils.fixColors(this.author)); - meta.setTitle(ItemUtils.fixColors(this.title)); + meta.setPages(Utils.fixColors(this.pages)); + meta.setAuthor(Utils.fixColors(this.author)); + meta.setTitle(Utils.fixColors(this.title)); } @Override @@ -124,9 +124,9 @@ public BookDataBuilder use(final ItemMeta itemMeta) { } BookMeta meta = (BookMeta) itemMeta; - this.title = ItemUtils.removeColors(meta.getTitle()); - this.author = ItemUtils.removeColors(meta.getAuthor()); - this.pages = ItemUtils.removeColors(new ArrayList<>(meta.getPages())); + this.title = Utils.removeColors(meta.getTitle()); + this.author = Utils.removeColors(meta.getAuthor()); + this.pages = Utils.removeColors(new ArrayList<>(meta.getPages())); return this; } diff --git a/src/main/java/studio/magemonkey/codex/legacy/item/DataBuilder.java b/codex-plugin/src/main/java/studio/magemonkey/codex/legacy/item/DataBuilder.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/legacy/item/DataBuilder.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/legacy/item/DataBuilder.java diff --git a/src/main/java/studio/magemonkey/codex/legacy/item/EnchantmentStorageBuilder.java b/codex-plugin/src/main/java/studio/magemonkey/codex/legacy/item/EnchantmentStorageBuilder.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/legacy/item/EnchantmentStorageBuilder.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/legacy/item/EnchantmentStorageBuilder.java diff --git a/src/main/java/studio/magemonkey/codex/legacy/item/FireworkBuilder.java b/codex-plugin/src/main/java/studio/magemonkey/codex/legacy/item/FireworkBuilder.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/legacy/item/FireworkBuilder.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/legacy/item/FireworkBuilder.java diff --git a/src/main/java/studio/magemonkey/codex/legacy/item/FireworkEffectBuilder.java b/codex-plugin/src/main/java/studio/magemonkey/codex/legacy/item/FireworkEffectBuilder.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/legacy/item/FireworkEffectBuilder.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/legacy/item/FireworkEffectBuilder.java diff --git a/src/main/java/studio/magemonkey/codex/legacy/item/ItemBuilder.java b/codex-plugin/src/main/java/studio/magemonkey/codex/legacy/item/ItemBuilder.java similarity index 98% rename from src/main/java/studio/magemonkey/codex/legacy/item/ItemBuilder.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/legacy/item/ItemBuilder.java index 52bfa377..394087dc 100644 --- a/src/main/java/studio/magemonkey/codex/legacy/item/ItemBuilder.java +++ b/codex-plugin/src/main/java/studio/magemonkey/codex/legacy/item/ItemBuilder.java @@ -13,6 +13,7 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.*; import org.jetbrains.annotations.NotNull; +import studio.magemonkey.codex.legacy.utils.Utils; import studio.magemonkey.codex.util.DeserializationWorker; import studio.magemonkey.codex.util.ItemUtils; import studio.magemonkey.codex.util.SerializationBuilder; @@ -46,6 +47,7 @@ public class ItemBuilder implements ConfigurationSerializable { /** * @deprecated Items should be store using ItemMeta and loaded the same way. It is less likely to break that way. */ + @Deprecated public ItemBuilder(final Map map) { final DeserializationWorker w = DeserializationWorker.start(map); Bukkit.getServer().getConsoleSender().sendMessage("Building item: " + w.getString("name", "none")); @@ -309,7 +311,7 @@ public ItemStack build() { //((Damageable) meta).setDamage(this.durability); // 1.13+ // } if (this.name != null) { - meta.setDisplayName(ItemUtils.fixColors(this.name)); + meta.setDisplayName(Utils.fixColors(this.name)); } if ((this.flags != null) && !this.flags.isEmpty()) { meta.addItemFlags(this.flags.toArray(new ItemFlag[this.flags.size()])); @@ -320,7 +322,7 @@ public ItemStack build() { Collections.addAll(lore, loreLine.split("\n")); } // this.lore.stream().forEach(str -> Collections.addAll(lore, str.split("\n"))); - meta.setLore(ItemUtils.fixColors(lore)); + meta.setLore(Utils.fixColors(lore)); } if (this.enchants != null) { for (final Map.Entry entry : this.enchants.entrySet()) { diff --git a/src/main/java/studio/magemonkey/codex/legacy/item/ItemColors.java b/codex-plugin/src/main/java/studio/magemonkey/codex/legacy/item/ItemColors.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/legacy/item/ItemColors.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/legacy/item/ItemColors.java diff --git a/src/main/java/studio/magemonkey/codex/legacy/item/LeatherArmorBuilder.java b/codex-plugin/src/main/java/studio/magemonkey/codex/legacy/item/LeatherArmorBuilder.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/legacy/item/LeatherArmorBuilder.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/legacy/item/LeatherArmorBuilder.java diff --git a/src/main/java/studio/magemonkey/codex/legacy/item/MapBuilder.java b/codex-plugin/src/main/java/studio/magemonkey/codex/legacy/item/MapBuilder.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/legacy/item/MapBuilder.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/legacy/item/MapBuilder.java diff --git a/src/main/java/studio/magemonkey/codex/legacy/item/PotionDataBuilder.java b/codex-plugin/src/main/java/studio/magemonkey/codex/legacy/item/PotionDataBuilder.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/legacy/item/PotionDataBuilder.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/legacy/item/PotionDataBuilder.java diff --git a/src/main/java/studio/magemonkey/codex/legacy/item/SkullBuilder.java b/codex-plugin/src/main/java/studio/magemonkey/codex/legacy/item/SkullBuilder.java similarity index 92% rename from src/main/java/studio/magemonkey/codex/legacy/item/SkullBuilder.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/legacy/item/SkullBuilder.java index 803b735d..9ff1e2b3 100644 --- a/src/main/java/studio/magemonkey/codex/legacy/item/SkullBuilder.java +++ b/codex-plugin/src/main/java/studio/magemonkey/codex/legacy/item/SkullBuilder.java @@ -8,8 +8,8 @@ import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.SkullMeta; import org.jetbrains.annotations.NotNull; +import studio.magemonkey.codex.legacy.utils.Utils; import studio.magemonkey.codex.util.DeserializationWorker; -import studio.magemonkey.codex.util.ItemUtils; import studio.magemonkey.codex.util.SerializationBuilder; import java.util.Map; @@ -43,7 +43,7 @@ public void apply(final ItemMeta itemMeta) { } SkullMeta meta = (SkullMeta) itemMeta; - meta.setOwner(ItemUtils.fixColors(this.owner)); + meta.setOwner(Utils.fixColors(this.owner)); } @Override @@ -53,7 +53,7 @@ public SkullBuilder use(final ItemMeta itemMeta) { } SkullMeta meta = (SkullMeta) itemMeta; - this.owner = ItemUtils.removeColors(meta.getOwner()); + this.owner = Utils.removeColors(meta.getOwner()); return this; } diff --git a/src/main/java/studio/magemonkey/codex/legacy/item/SkullType.java b/codex-plugin/src/main/java/studio/magemonkey/codex/legacy/item/SkullType.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/legacy/item/SkullType.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/legacy/item/SkullType.java diff --git a/src/main/java/studio/magemonkey/codex/legacy/riseitem/DarkRiseItem.java b/codex-plugin/src/main/java/studio/magemonkey/codex/legacy/riseitem/DarkRiseItem.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/legacy/riseitem/DarkRiseItem.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/legacy/riseitem/DarkRiseItem.java diff --git a/src/main/java/studio/magemonkey/codex/legacy/riseitem/DarkRiseItemImpl.java b/codex-plugin/src/main/java/studio/magemonkey/codex/legacy/riseitem/DarkRiseItemImpl.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/legacy/riseitem/DarkRiseItemImpl.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/legacy/riseitem/DarkRiseItemImpl.java diff --git a/src/main/java/studio/magemonkey/codex/legacy/utils/ItemComparator.java b/codex-plugin/src/main/java/studio/magemonkey/codex/legacy/utils/ItemComparator.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/legacy/utils/ItemComparator.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/legacy/utils/ItemComparator.java diff --git a/src/main/java/studio/magemonkey/codex/legacy/utils/ReflectionUtil.java b/codex-plugin/src/main/java/studio/magemonkey/codex/legacy/utils/ReflectionUtil.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/legacy/utils/ReflectionUtil.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/legacy/utils/ReflectionUtil.java diff --git a/src/main/java/studio/magemonkey/codex/legacy/utils/SimpleMap.java b/codex-plugin/src/main/java/studio/magemonkey/codex/legacy/utils/SimpleMap.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/legacy/utils/SimpleMap.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/legacy/utils/SimpleMap.java diff --git a/src/main/java/studio/magemonkey/codex/legacy/utils/Utils.java b/codex-plugin/src/main/java/studio/magemonkey/codex/legacy/utils/Utils.java similarity index 88% rename from src/main/java/studio/magemonkey/codex/legacy/utils/Utils.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/legacy/utils/Utils.java index 9b03ee31..38147511 100644 --- a/src/main/java/studio/magemonkey/codex/legacy/utils/Utils.java +++ b/codex-plugin/src/main/java/studio/magemonkey/codex/legacy/utils/Utils.java @@ -5,13 +5,16 @@ import org.bukkit.Location; import org.bukkit.World; import studio.magemonkey.codex.CodexEngine; +import studio.magemonkey.codex.util.ItemUtils; +import java.util.ArrayList; import java.util.Calendar; import java.util.GregorianCalendar; import java.util.List; import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Collectors; public final class Utils { private static final String[] EMPTY_STRING_ARRAY = new String[0]; @@ -31,6 +34,12 @@ public static Integer parseInt(final String num) { } } + /** + * Fixes color characters in a string + * + * @param string message to fix + * @return new string + */ public static String fixColors(final String string) { if (string == null) { return null; @@ -48,24 +57,32 @@ public static String[] fixColors(final String... strings) { return strings; } + /** + * Fixes color characters in a List + * + * @param list List to fix + * @return new List + */ public static List fixColors(final List list) { - if (list == null) { - return null; - } - for (int i = 0; i < list.size(); i++) { - list.set(i, fixColors(list.get(i))); + if (list == null) return null; + ArrayList ret = new ArrayList<>(); + for (String s : list) { + String fixColors = fixColors(s); + ret.add(fixColors); } - return list; + return ret; } + /** + * Strips colors from the list. + * + * @param list List of Strings to remove color from + * @return New ArrayList of cleaned Strings + */ public static List removeColors(final List list) { - if (list == null) { - return null; - } - for (int i = 0; i < list.size(); i++) { - list.set(i, removeColors(list.get(i))); - } - return list; + if (list == null) return null; + + return list.stream().map(Utils::removeColors).collect(Collectors.toList()); } public static String[] removeColors(final String... strings) { @@ -79,17 +96,8 @@ public static String[] removeColors(final String... strings) { } public static String removeColors(final String string) { - if (string == null) { - return null; - } - final char[] b = string.toCharArray(); - for (int i = 0; i < (b.length - 1); i++) { - if ((b[i] == ChatColor.COLOR_CHAR) && ("0123456789AaBbCcDdEeFfKkLlMmNnOoRr".indexOf(b[i + 1]) > -1)) { - b[i] = '&'; - b[i + 1] = Character.toLowerCase(b[i + 1]); - } - } - return new String(b); + if (string == null) return null; + return ChatColor.stripColor(string); } public static Integer toInt(final String str) { diff --git a/src/main/java/studio/magemonkey/codex/legacy/utils/serializers/BaseComponentSerializer.java b/codex-plugin/src/main/java/studio/magemonkey/codex/legacy/utils/serializers/BaseComponentSerializer.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/legacy/utils/serializers/BaseComponentSerializer.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/legacy/utils/serializers/BaseComponentSerializer.java diff --git a/src/main/java/studio/magemonkey/codex/legacy/utils/serializers/ComponentSerializer.java b/codex-plugin/src/main/java/studio/magemonkey/codex/legacy/utils/serializers/ComponentSerializer.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/legacy/utils/serializers/ComponentSerializer.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/legacy/utils/serializers/ComponentSerializer.java diff --git a/src/main/java/studio/magemonkey/codex/legacy/utils/serializers/TextComponentSerializer.java b/codex-plugin/src/main/java/studio/magemonkey/codex/legacy/utils/serializers/TextComponentSerializer.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/legacy/utils/serializers/TextComponentSerializer.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/legacy/utils/serializers/TextComponentSerializer.java diff --git a/src/main/java/studio/magemonkey/codex/legacy/utils/serializers/TranslatableComponentSerializer.java b/codex-plugin/src/main/java/studio/magemonkey/codex/legacy/utils/serializers/TranslatableComponentSerializer.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/legacy/utils/serializers/TranslatableComponentSerializer.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/legacy/utils/serializers/TranslatableComponentSerializer.java diff --git a/src/main/java/studio/magemonkey/codex/api/armor/ArmorListener.java b/codex-plugin/src/main/java/studio/magemonkey/codex/listeners/ArmorListener.java similarity index 97% rename from src/main/java/studio/magemonkey/codex/api/armor/ArmorListener.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/listeners/ArmorListener.java index a9f205c2..e85442bd 100644 --- a/src/main/java/studio/magemonkey/codex/api/armor/ArmorListener.java +++ b/codex-plugin/src/main/java/studio/magemonkey/codex/listeners/ArmorListener.java @@ -1,4 +1,4 @@ -package studio.magemonkey.codex.api.armor; +package studio.magemonkey.codex.listeners; import org.bukkit.Bukkit; import org.bukkit.Material; @@ -22,6 +22,8 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.PlayerInventory; import org.bukkit.inventory.meta.ItemMeta; +import studio.magemonkey.codex.api.armor.ArmorEquipEvent; +import studio.magemonkey.codex.api.armor.ArmorType; import studio.magemonkey.codex.util.InventoryUtil; import java.util.ArrayList; @@ -31,6 +33,7 @@ import static org.bukkit.event.inventory.InventoryType.CRAFTING; import static studio.magemonkey.codex.api.armor.ArmorEquipEvent.EquipMethod; +import static studio.magemonkey.codex.util.constants.ItemHelper.isAirOrNull; public class ArmorListener implements Listener { @@ -529,15 +532,14 @@ public void onItemConsumeEvent(PlayerItemConsumeEvent event) { if (armorType != ArmorType.MAIN_HAND && armorType != ArmorType.OFFHAND) { return; } - try { - switch (event.getHand()) { - case HAND -> armorType = ArmorType.MAIN_HAND; - case OFF_HAND -> armorType = ArmorType.OFFHAND; - } - } catch (NoSuchMethodError e) { - boolean inMainHand = event.getPlayer().getInventory().getItemInMainHand().equals(item); - armorType = inMainHand ? ArmorType.MAIN_HAND : ArmorType.OFFHAND; - } + // MODERN + // switch (event.getHand()) { + // case HAND -> armorType = ArmorType.MAIN_HAND; + // case OFF_HAND -> armorType = ArmorType.OFFHAND; + // } + boolean inMainHand = event.getPlayer().getInventory().getItemInMainHand().equals(item); + armorType = inMainHand ? ArmorType.MAIN_HAND : ArmorType.OFFHAND; + ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent(event.getPlayer(), EquipMethod.CONSUME, armorType, item, null); if (isChange(armorEquipEvent)) { @@ -620,12 +622,4 @@ public void onItemBreak(PlayerItemBreakEvent e) { } } } - - /** - * A utility method to support versions that use null or air ItemStacks. - */ - public static boolean isAirOrNull(ItemStack item) { - return item == null || item.getType().isAir(); - } - } diff --git a/codex-plugin/src/main/java/studio/magemonkey/codex/listeners/BoatListener.java b/codex-plugin/src/main/java/studio/magemonkey/codex/listeners/BoatListener.java new file mode 100644 index 00000000..81175862 --- /dev/null +++ b/codex-plugin/src/main/java/studio/magemonkey/codex/listeners/BoatListener.java @@ -0,0 +1,28 @@ +package studio.magemonkey.codex.listeners; + +import org.bukkit.entity.Boat; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.vehicle.VehicleExitEvent; +import org.bukkit.inventory.ItemStack; +import studio.magemonkey.codex.CodexEngine; +import studio.magemonkey.codex.compat.VersionManager; + +public class BoatListener implements Listener { + @EventHandler + public void exit(VehicleExitEvent event) { + if (!CodexEngine.get().cfg().getJYML().getBoolean("removeBoatOnExit")) return; + if (!(event.getVehicle() instanceof Boat)) return; + if (!(event.getExited() instanceof Player)) return; + + Player player = (Player) event.getExited(); + Boat boat = (Boat) event.getVehicle(); + + ItemStack item = new ItemStack(VersionManager.getNms().getMaterial(boat)); + if (!player.getInventory().addItem(item).isEmpty()) + player.getWorld() + .dropItemNaturally(player.getLocation(), item); + boat.remove(); + } +} diff --git a/src/main/java/studio/magemonkey/codex/listeners/InteractListener.java b/codex-plugin/src/main/java/studio/magemonkey/codex/listeners/InteractListener.java similarity index 96% rename from src/main/java/studio/magemonkey/codex/listeners/InteractListener.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/listeners/InteractListener.java index fe419204..3cd76246 100644 --- a/src/main/java/studio/magemonkey/codex/listeners/InteractListener.java +++ b/codex-plugin/src/main/java/studio/magemonkey/codex/listeners/InteractListener.java @@ -5,7 +5,7 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerInteractEvent; -import studio.magemonkey.codex.api.CommandBlock; +import studio.magemonkey.codex.action.CommandBlock; import studio.magemonkey.codex.config.api.JYML; import java.util.ArrayList; diff --git a/src/main/java/studio/magemonkey/codex/listeners/JoinListener.java b/codex-plugin/src/main/java/studio/magemonkey/codex/listeners/JoinListener.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/listeners/JoinListener.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/listeners/JoinListener.java diff --git a/src/main/java/studio/magemonkey/codex/manager/LoadableItem.java b/codex-plugin/src/main/java/studio/magemonkey/codex/manager/LoadableItem.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/manager/LoadableItem.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/manager/LoadableItem.java diff --git a/src/main/java/studio/magemonkey/codex/manager/api/Editable.java b/codex-plugin/src/main/java/studio/magemonkey/codex/manager/api/Editable.java similarity index 99% rename from src/main/java/studio/magemonkey/codex/manager/api/Editable.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/manager/api/Editable.java index a2600927..e3f1f2cd 100644 --- a/src/main/java/studio/magemonkey/codex/manager/api/Editable.java +++ b/codex-plugin/src/main/java/studio/magemonkey/codex/manager/api/Editable.java @@ -4,7 +4,6 @@ import studio.magemonkey.codex.manager.api.gui.NGUI; public interface Editable { - @NotNull public NGUI getEditor(); } diff --git a/src/main/java/studio/magemonkey/codex/manager/api/IActionEditable.java b/codex-plugin/src/main/java/studio/magemonkey/codex/manager/api/IActionEditable.java similarity index 99% rename from src/main/java/studio/magemonkey/codex/manager/api/IActionEditable.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/manager/api/IActionEditable.java index b4314570..6e75ee85 100644 --- a/src/main/java/studio/magemonkey/codex/manager/api/IActionEditable.java +++ b/codex-plugin/src/main/java/studio/magemonkey/codex/manager/api/IActionEditable.java @@ -6,7 +6,6 @@ import studio.magemonkey.codex.util.actions.api.IActioned; public interface IActionEditable extends IActioned, Editable { - @NotNull public IEditorActionsMain> getEditorActions(); diff --git a/src/main/java/studio/magemonkey/codex/manager/api/Saveable.java b/codex-plugin/src/main/java/studio/magemonkey/codex/manager/api/Saveable.java similarity index 79% rename from src/main/java/studio/magemonkey/codex/manager/api/Saveable.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/manager/api/Saveable.java index 97ee067b..408eb143 100644 --- a/src/main/java/studio/magemonkey/codex/manager/api/Saveable.java +++ b/codex-plugin/src/main/java/studio/magemonkey/codex/manager/api/Saveable.java @@ -4,6 +4,5 @@ import studio.magemonkey.codex.config.api.JYML; public interface Saveable { - - public void save(@NotNull JYML cfg); + void save(@NotNull JYML cfg); } diff --git a/src/main/java/studio/magemonkey/codex/manager/api/gui/GuiItem.java b/codex-plugin/src/main/java/studio/magemonkey/codex/manager/api/gui/GuiItem.java similarity index 94% rename from src/main/java/studio/magemonkey/codex/manager/api/gui/GuiItem.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/manager/api/gui/GuiItem.java index 88f103cc..a4dfca8d 100644 --- a/src/main/java/studio/magemonkey/codex/manager/api/gui/GuiItem.java +++ b/codex-plugin/src/main/java/studio/magemonkey/codex/manager/api/gui/GuiItem.java @@ -1,12 +1,14 @@ package studio.magemonkey.codex.manager.api.gui; +import lombok.Getter; +import lombok.Setter; import org.bukkit.entity.Player; import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import studio.magemonkey.codex.manager.types.ClickType; +import studio.magemonkey.codex.manager.api.ClickType; import studio.magemonkey.codex.util.actions.ActionManipulator; import java.util.ArrayList; @@ -16,7 +18,6 @@ import java.util.TreeMap; public class GuiItem { - private String id; private Enum type; private ItemStack item; @@ -25,9 +26,11 @@ public class GuiItem { private int animStartFrame; private TreeMap animFrames; - private String permission; - private int[] slots; - private GuiClick click; + private String permission; + @Setter + @Getter + private int[] slots; + private GuiClick click; private Map customClicks; public GuiItem( @@ -188,14 +191,6 @@ public void addAnimationFrame(int index, @NotNull ItemStack frame) { this.animFrames.put(index, new ItemStack(frame)); } - public int[] getSlots() { - return this.slots; - } - - public void setSlots(int[] slot) { - this.slots = slot; - } - @Nullable public String getPermission() { return this.permission; diff --git a/src/main/java/studio/magemonkey/codex/manager/api/gui/NGUI.java b/codex-plugin/src/main/java/studio/magemonkey/codex/manager/api/gui/NGUI.java similarity index 97% rename from src/main/java/studio/magemonkey/codex/manager/api/gui/NGUI.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/manager/api/gui/NGUI.java index 452d1aef..840eab6d 100644 --- a/src/main/java/studio/magemonkey/codex/manager/api/gui/NGUI.java +++ b/codex-plugin/src/main/java/studio/magemonkey/codex/manager/api/gui/NGUI.java @@ -15,7 +15,7 @@ import studio.magemonkey.codex.config.api.JYML; import studio.magemonkey.codex.manager.IListener; import studio.magemonkey.codex.manager.api.task.ITask; -import studio.magemonkey.codex.manager.types.ClickType; +import studio.magemonkey.codex.manager.api.ClickType; import studio.magemonkey.codex.util.InventoryUtil; import studio.magemonkey.codex.util.ItemUT; import studio.magemonkey.codex.util.StringUT; @@ -137,8 +137,7 @@ public void reopen() { // TODO Experimental public void refill() { this.getViewers().forEach(player -> { - Object view = player.getOpenInventory(); - Inventory top = InventoryUtil.getTopInventory(view); + Inventory top = InventoryUtil.getTopInventory(player); if (!(top.getHolder() instanceof NGUI)) return; for (int slot = 0; slot < top.getSize(); slot++) { @@ -516,10 +515,7 @@ public void action() { }); } - NGUI.this.getViewers().forEach(player -> { - Inventory inv = InventoryUtil.getTopInventory(player.getOpenInventory()); - NGUI.this.fillGUI(inv, player); - }); + NGUI.this.getViewers().forEach(player -> NGUI.this.fillGUI(InventoryUtil.getTopInventory(player), player)); } } } diff --git a/src/main/java/studio/magemonkey/codex/manager/api/task/ITask.java b/codex-plugin/src/main/java/studio/magemonkey/codex/manager/api/task/ITask.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/manager/api/task/ITask.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/manager/api/task/ITask.java diff --git a/src/main/java/studio/magemonkey/codex/manager/editor/EditorActionsHandler.java b/codex-plugin/src/main/java/studio/magemonkey/codex/manager/editor/EditorActionsHandler.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/manager/editor/EditorActionsHandler.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/manager/editor/EditorActionsHandler.java diff --git a/src/main/java/studio/magemonkey/codex/manager/editor/EditorHandler.java b/codex-plugin/src/main/java/studio/magemonkey/codex/manager/editor/EditorHandler.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/manager/editor/EditorHandler.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/manager/editor/EditorHandler.java diff --git a/src/main/java/studio/magemonkey/codex/manager/editor/EditorManager.java b/codex-plugin/src/main/java/studio/magemonkey/codex/manager/editor/EditorManager.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/manager/editor/EditorManager.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/manager/editor/EditorManager.java diff --git a/src/main/java/studio/magemonkey/codex/manager/editor/EditorType.java b/codex-plugin/src/main/java/studio/magemonkey/codex/manager/editor/EditorType.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/manager/editor/EditorType.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/manager/editor/EditorType.java diff --git a/src/main/java/studio/magemonkey/codex/manager/editor/object/IEditorActionsMain.java b/codex-plugin/src/main/java/studio/magemonkey/codex/manager/editor/object/IEditorActionsMain.java similarity index 99% rename from src/main/java/studio/magemonkey/codex/manager/editor/object/IEditorActionsMain.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/manager/editor/object/IEditorActionsMain.java index f081a50a..3faf6406 100644 --- a/src/main/java/studio/magemonkey/codex/manager/editor/object/IEditorActionsMain.java +++ b/codex-plugin/src/main/java/studio/magemonkey/codex/manager/editor/object/IEditorActionsMain.java @@ -59,7 +59,7 @@ public IEditorActionsMain(@NotNull P plugin, @NotNull IActionEditable actionObje GuiClick click = new GuiClick() { @Override - public void click(Player p, @Nullable Enum type, InventoryClickEvent e) { + public void click(@NotNull Player p, @Nullable Enum type, @NotNull InventoryClickEvent e) { if (type == null) return; Class clazz = type.getClass(); diff --git a/src/main/java/studio/magemonkey/codex/manager/editor/object/IEditorActionsParametized.java b/codex-plugin/src/main/java/studio/magemonkey/codex/manager/editor/object/IEditorActionsParametized.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/manager/editor/object/IEditorActionsParametized.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/manager/editor/object/IEditorActionsParametized.java diff --git a/src/main/java/studio/magemonkey/codex/manager/editor/object/IEditorActionsParams.java b/codex-plugin/src/main/java/studio/magemonkey/codex/manager/editor/object/IEditorActionsParams.java similarity index 98% rename from src/main/java/studio/magemonkey/codex/manager/editor/object/IEditorActionsParams.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/manager/editor/object/IEditorActionsParams.java index 8d3feb4b..434dce81 100644 --- a/src/main/java/studio/magemonkey/codex/manager/editor/object/IEditorActionsParams.java +++ b/codex-plugin/src/main/java/studio/magemonkey/codex/manager/editor/object/IEditorActionsParams.java @@ -51,7 +51,7 @@ public IEditorActionsParams( GuiClick click = new GuiClick() { @Override - public void click(Player p, @Nullable Enum type, InventoryClickEvent e) { + public void click(@NotNull Player p, @Nullable Enum type, @NotNull InventoryClickEvent e) { if (type == null) return; Class clazz = type.getClass(); diff --git a/src/main/java/studio/magemonkey/codex/manager/editor/object/IEditorActionsSection.java b/codex-plugin/src/main/java/studio/magemonkey/codex/manager/editor/object/IEditorActionsSection.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/manager/editor/object/IEditorActionsSection.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/manager/editor/object/IEditorActionsSection.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/chat/Chat.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/chat/Chat.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/chat/Chat.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/chat/Chat.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/chat/ChatCommander.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/chat/ChatCommander.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/chat/ChatCommander.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/chat/ChatCommander.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/chat/ChatData.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/chat/ChatData.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/chat/ChatData.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/chat/ChatData.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/chat/ChatListener.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/chat/ChatListener.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/chat/ChatListener.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/chat/ChatListener.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/chat/ChatNodes.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/chat/ChatNodes.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/chat/ChatNodes.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/chat/ChatNodes.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/chat/ListCommand.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/chat/ListCommand.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/chat/ListCommand.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/chat/ListCommand.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/chat/NameCommand.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/chat/NameCommand.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/chat/NameCommand.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/chat/NameCommand.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/chat/Prefix.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/chat/Prefix.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/chat/Prefix.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/chat/Prefix.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/chat/PrefixCommand.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/chat/PrefixCommand.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/chat/PrefixCommand.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/chat/PrefixCommand.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/chat/ResetCommand.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/chat/ResetCommand.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/chat/ResetCommand.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/chat/ResetCommand.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/commands/CommandHandler.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/commands/CommandHandler.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/commands/CommandHandler.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/commands/CommandHandler.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/commands/CommandListener.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/commands/CommandListener.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/commands/CommandListener.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/commands/CommandListener.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/commands/CommandManager.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/commands/CommandManager.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/commands/CommandManager.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/commands/CommandManager.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/commands/ConfigurableCommand.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/commands/ConfigurableCommand.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/commands/ConfigurableCommand.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/commands/ConfigurableCommand.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/commands/ICommand.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/commands/ICommand.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/commands/ICommand.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/commands/ICommand.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/commands/IFunction.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/commands/IFunction.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/commands/IFunction.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/commands/IFunction.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/commands/LogFunction.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/commands/LogFunction.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/commands/LogFunction.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/commands/LogFunction.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/commands/SenderType.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/commands/SenderType.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/commands/SenderType.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/commands/SenderType.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/config/CommentedConfig.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/config/CommentedConfig.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/config/CommentedConfig.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/config/CommentedConfig.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/config/CommentedLanguageConfig.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/config/CommentedLanguageConfig.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/config/CommentedLanguageConfig.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/config/CommentedLanguageConfig.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/config/Config.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/config/Config.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/config/Config.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/config/Config.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/config/ConfigSerializer.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/config/ConfigSerializer.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/config/ConfigSerializer.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/config/ConfigSerializer.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/config/CustomFilter.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/config/CustomFilter.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/config/CustomFilter.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/config/CustomFilter.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/config/DataFile.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/config/DataFile.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/config/DataFile.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/config/DataFile.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/config/ExcludeField.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/config/ExcludeField.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/config/ExcludeField.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/config/ExcludeField.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/config/Filter.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/config/Filter.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/config/Filter.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/config/Filter.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/config/FilterType.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/config/FilterType.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/config/FilterType.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/config/FilterType.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/config/ISavable.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/config/ISavable.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/config/ISavable.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/config/ISavable.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/config/LanguageConfig.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/config/LanguageConfig.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/config/LanguageConfig.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/config/LanguageConfig.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/config/LocationData.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/config/LocationData.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/config/LocationData.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/config/LocationData.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/config/Resources.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/config/Resources.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/config/Resources.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/config/Resources.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/config/SerializableField.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/config/SerializableField.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/config/SerializableField.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/config/SerializableField.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/config/parse/DataArray.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/config/parse/DataArray.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/config/parse/DataArray.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/config/parse/DataArray.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/config/parse/DataSection.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/config/parse/DataSection.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/config/parse/DataSection.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/config/parse/DataSection.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/config/parse/JSONParser.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/config/parse/JSONParser.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/config/parse/JSONParser.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/config/parse/JSONParser.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/config/parse/NumberParser.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/config/parse/NumberParser.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/config/parse/NumberParser.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/config/parse/NumberParser.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/config/parse/YAMLParser.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/config/parse/YAMLParser.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/config/parse/YAMLParser.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/config/parse/YAMLParser.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/gui/MapBuffer.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/gui/MapBuffer.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/gui/MapBuffer.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/gui/MapBuffer.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/gui/MapData.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/gui/MapData.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/gui/MapData.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/gui/MapData.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/gui/MapFont.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/gui/MapFont.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/gui/MapFont.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/gui/MapFont.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/gui/MapImage.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/gui/MapImage.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/gui/MapImage.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/gui/MapImage.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/gui/MapImageManager.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/gui/MapImageManager.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/gui/MapImageManager.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/gui/MapImageManager.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/gui/MapListener.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/gui/MapListener.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/gui/MapListener.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/gui/MapListener.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/gui/MapMenu.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/gui/MapMenu.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/gui/MapMenu.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/gui/MapMenu.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/gui/MapMenuManager.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/gui/MapMenuManager.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/gui/MapMenuManager.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/gui/MapMenuManager.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/gui/MapObject.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/gui/MapObject.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/gui/MapObject.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/gui/MapObject.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/gui/MapScene.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/gui/MapScene.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/gui/MapScene.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/gui/MapScene.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/gui/MapScheme.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/gui/MapScheme.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/gui/MapScheme.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/gui/MapScheme.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/gui/MapString.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/gui/MapString.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/gui/MapString.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/gui/MapString.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/items/InventoryManager.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/items/InventoryManager.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/items/InventoryManager.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/items/InventoryManager.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/items/ItemManager.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/items/ItemManager.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/items/ItemManager.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/items/ItemManager.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/scoreboard/Board.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/scoreboard/Board.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/scoreboard/Board.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/scoreboard/Board.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/scoreboard/BoardListener.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/scoreboard/BoardListener.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/scoreboard/BoardListener.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/scoreboard/BoardListener.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/scoreboard/BoardManager.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/scoreboard/BoardManager.java similarity index 96% rename from src/main/java/studio/magemonkey/codex/mccore/scoreboard/BoardManager.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/scoreboard/BoardManager.java index b0de1d30..967082b8 100644 --- a/src/main/java/studio/magemonkey/codex/mccore/scoreboard/BoardManager.java +++ b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/scoreboard/BoardManager.java @@ -32,6 +32,7 @@ import org.bukkit.scoreboard.Objective; import org.bukkit.scoreboard.Scoreboard; import studio.magemonkey.codex.CodexEngine; +import studio.magemonkey.codex.compat.VersionManager; import java.util.Collection; import java.util.HashMap; @@ -331,15 +332,7 @@ public static void update(Scoreboard update) { scoreboard.getObjectives().forEach(objective -> { Objective obj = update.getObjective(objective.getName()); if (obj == null) { - try { - obj = update.registerNewObjective(objective.getName(), - objective.getTrackedCriteria(), - objective.getDisplayName()); - } catch (NoSuchMethodError e) { - obj = update.registerNewObjective(objective.getName(), - objective.getCriteria(), - objective.getDisplayName()); - } + obj = VersionManager.getNms().registerNewObjective(update, objective); } obj.setDisplaySlot(objective.getDisplaySlot()); obj.setDisplayName(objective.getDisplayName()); diff --git a/src/main/java/studio/magemonkey/codex/mccore/scoreboard/CycleCommand.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/scoreboard/CycleCommand.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/scoreboard/CycleCommand.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/scoreboard/CycleCommand.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/scoreboard/CycleTask.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/scoreboard/CycleTask.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/scoreboard/CycleTask.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/scoreboard/CycleTask.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/scoreboard/ListCommand.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/scoreboard/ListCommand.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/scoreboard/ListCommand.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/scoreboard/ListCommand.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/scoreboard/PlayerBoards.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/scoreboard/PlayerBoards.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/scoreboard/PlayerBoards.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/scoreboard/PlayerBoards.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/scoreboard/ScoreboardCommander.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/scoreboard/ScoreboardCommander.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/scoreboard/ScoreboardCommander.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/scoreboard/ScoreboardCommander.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/scoreboard/ScoreboardNodes.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/scoreboard/ScoreboardNodes.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/scoreboard/ScoreboardNodes.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/scoreboard/ScoreboardNodes.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/scoreboard/ShowCommand.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/scoreboard/ShowCommand.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/scoreboard/ShowCommand.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/scoreboard/ShowCommand.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/scoreboard/StatBoard.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/scoreboard/StatBoard.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/scoreboard/StatBoard.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/scoreboard/StatBoard.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/scoreboard/StatHolder.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/scoreboard/StatHolder.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/scoreboard/StatHolder.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/scoreboard/StatHolder.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/scoreboard/StopCommand.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/scoreboard/StopCommand.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/scoreboard/StopCommand.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/scoreboard/StopCommand.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/scoreboard/Team.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/scoreboard/Team.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/scoreboard/Team.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/scoreboard/Team.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/scoreboard/ToggleCommand.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/scoreboard/ToggleCommand.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/scoreboard/ToggleCommand.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/scoreboard/ToggleCommand.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/scoreboard/UpdateTask.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/scoreboard/UpdateTask.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/scoreboard/UpdateTask.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/scoreboard/UpdateTask.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/sql/ColumnType.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/sql/ColumnType.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/sql/ColumnType.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/sql/ColumnType.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/sql/direct/ISQLEntryData.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/sql/direct/ISQLEntryData.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/sql/direct/ISQLEntryData.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/sql/direct/ISQLEntryData.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/sql/direct/SQLDatabase.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/sql/direct/SQLDatabase.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/sql/direct/SQLDatabase.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/sql/direct/SQLDatabase.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/sql/direct/SQLEntry.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/sql/direct/SQLEntry.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/sql/direct/SQLEntry.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/sql/direct/SQLEntry.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/sql/direct/SQLTable.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/sql/direct/SQLTable.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/sql/direct/SQLTable.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/sql/direct/SQLTable.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/util/MobManager.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/util/MobManager.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/util/MobManager.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/util/MobManager.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/util/TextFormatter.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/util/TextFormatter.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/util/TextFormatter.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/util/TextFormatter.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/util/TextSizer.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/util/TextSizer.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/util/TextSizer.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/util/TextSizer.java diff --git a/src/main/java/studio/magemonkey/codex/mccore/util/TextSplitter.java b/codex-plugin/src/main/java/studio/magemonkey/codex/mccore/util/TextSplitter.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/mccore/util/TextSplitter.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/mccore/util/TextSplitter.java diff --git a/src/main/java/studio/magemonkey/codex/modules/IExternalModule.java b/codex-plugin/src/main/java/studio/magemonkey/codex/modules/IExternalModule.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/modules/IExternalModule.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/modules/IExternalModule.java diff --git a/src/main/java/studio/magemonkey/codex/modules/IModule.java b/codex-plugin/src/main/java/studio/magemonkey/codex/modules/IModule.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/modules/IModule.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/modules/IModule.java diff --git a/src/main/java/studio/magemonkey/codex/modules/IModuleExecutor.java b/codex-plugin/src/main/java/studio/magemonkey/codex/modules/IModuleExecutor.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/modules/IModuleExecutor.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/modules/IModuleExecutor.java diff --git a/src/main/java/studio/magemonkey/codex/modules/ModuleManager.java b/codex-plugin/src/main/java/studio/magemonkey/codex/modules/ModuleManager.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/modules/ModuleManager.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/modules/ModuleManager.java diff --git a/src/main/java/studio/magemonkey/codex/nms/packets/IPacketHandler.java b/codex-plugin/src/main/java/studio/magemonkey/codex/nms/packets/IPacketHandler.java similarity index 63% rename from src/main/java/studio/magemonkey/codex/nms/packets/IPacketHandler.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/nms/packets/IPacketHandler.java index 1615f7aa..42eeda06 100644 --- a/src/main/java/studio/magemonkey/codex/nms/packets/IPacketHandler.java +++ b/codex-plugin/src/main/java/studio/magemonkey/codex/nms/packets/IPacketHandler.java @@ -1,8 +1,8 @@ package studio.magemonkey.codex.nms.packets; import org.jetbrains.annotations.NotNull; -import studio.magemonkey.codex.nms.packets.events.EnginePlayerPacketEvent; -import studio.magemonkey.codex.nms.packets.events.EngineServerPacketEvent; +import studio.magemonkey.codex.api.events.EnginePlayerPacketEvent; +import studio.magemonkey.codex.api.events.EngineServerPacketEvent; public interface IPacketHandler { diff --git a/src/main/java/studio/magemonkey/codex/nms/packets/PacketManager.java b/codex-plugin/src/main/java/studio/magemonkey/codex/nms/packets/PacketManager.java similarity index 93% rename from src/main/java/studio/magemonkey/codex/nms/packets/PacketManager.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/nms/packets/PacketManager.java index 6865eab1..b8bb1716 100644 --- a/src/main/java/studio/magemonkey/codex/nms/packets/PacketManager.java +++ b/codex-plugin/src/main/java/studio/magemonkey/codex/nms/packets/PacketManager.java @@ -8,10 +8,11 @@ import org.bukkit.event.player.PlayerQuitEvent; import org.jetbrains.annotations.NotNull; import studio.magemonkey.codex.CodexEngine; +import studio.magemonkey.codex.compat.VersionManager; import studio.magemonkey.codex.core.Version; import studio.magemonkey.codex.manager.IManager; -import studio.magemonkey.codex.nms.packets.events.EnginePlayerPacketEvent; -import studio.magemonkey.codex.nms.packets.events.EngineServerPacketEvent; +import studio.magemonkey.codex.api.events.EnginePlayerPacketEvent; +import studio.magemonkey.codex.api.events.EngineServerPacketEvent; import java.util.HashSet; import java.util.Set; @@ -58,11 +59,11 @@ public Set getHandlers() { } public Channel getChannel(@NotNull Player player) { - return this.plugin.getNMS().getChannel(player); + return VersionManager.getNms().getChannel(player); } public void sendPacket(@NotNull Player player, @NotNull Object packet) { - this.plugin.getNMS().sendPacket(player, packet); + VersionManager.getNms().sendPacket(player, packet); } diff --git a/src/main/java/studio/magemonkey/codex/util/ItemUT.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/ItemUT.java similarity index 86% rename from src/main/java/studio/magemonkey/codex/util/ItemUT.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/ItemUT.java index d57184a3..3acb3f2d 100644 --- a/src/main/java/studio/magemonkey/codex/util/ItemUT.java +++ b/codex-plugin/src/main/java/studio/magemonkey/codex/util/ItemUT.java @@ -1,13 +1,10 @@ package studio.magemonkey.codex.util; -import com.google.gson.Gson; -import com.google.gson.JsonObject; import com.mojang.authlib.GameProfile; import com.mojang.authlib.properties.Property; import lombok.Getter; import lombok.Setter; import me.clip.placeholderapi.PlaceholderAPI; -import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.NamespacedKey; import org.bukkit.World; @@ -17,17 +14,15 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.SkullMeta; -import org.bukkit.profile.PlayerProfile; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import studio.magemonkey.codex.CodexEngine; +import studio.magemonkey.codex.compat.VersionManager; import studio.magemonkey.codex.config.ConfigManager; import studio.magemonkey.codex.hooks.Hooks; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.net.MalformedURLException; -import java.net.URL; import java.util.*; import java.util.function.UnaryOperator; @@ -125,8 +120,8 @@ public static int getLoreIndex(@NotNull ItemStack item, @NotNull String id, int int count = 0; if (type == 0) { - for (int i = 0; i < lines.length; i++) { - lastText = lines[i]; + for (String line : lines) { + lastText = line; if (!StringUT.colorOff(lastText).isEmpty()) { break; } @@ -216,48 +211,19 @@ public static String getNameTag(@NotNull ItemStack item, @NotNull String id) { @NotNull public static String getItemName(@NotNull ItemStack item) { ItemMeta meta = item.getItemMeta(); - String name = meta != null && meta.hasDisplayName() + return meta != null && meta.hasDisplayName() ? meta.getDisplayName() : getEngine().lang().getEnum(item.getType()); - return name; } - @NotNull public static void addSkullTexture(@NotNull ItemStack item, @NotNull String value) { ItemUT.addSkullTexture(item, value, ""); } - @NotNull public static void addSkullTexture(@NotNull ItemStack item, @NotNull String value, @NotNull String id) { - if (item.getType() != Material.PLAYER_HEAD) return; - UUID uuid = ConfigManager.getTempUUID(id); if (uuid == null) uuid = UUID.randomUUID(); - - SkullMeta meta = (SkullMeta) item.getItemMeta(); - if (meta == null) return; - - try { - PlayerProfile playerProfile = Bukkit.createPlayerProfile(uuid, uuid.toString().substring(0, 16)); - String decoded = new String(Base64.getDecoder().decode(value)); - JsonObject json = new Gson().fromJson(decoded, JsonObject.class); - JsonObject texturesJson = json.getAsJsonObject("textures"); - JsonObject skin = texturesJson.getAsJsonObject("SKIN"); - String url = skin.get("url").getAsString(); - playerProfile.getTextures().setSkin(new URL(url)); - meta.setOwnerProfile(playerProfile); - } catch (MalformedURLException | NoClassDefFoundError | NoSuchMethodError | IllegalArgumentException e) { - try { - GameProfile profile = new GameProfile(uuid, uuid.toString().substring(0, 16)); - profile.getProperties().put("textures", new Property("textures", value)); - Objects.requireNonNull(Reflex.getField(meta.getClass(), "profile")).set(meta, profile); - } catch (NullPointerException | IllegalAccessException setException) { - engine.getLogger() - .warning("Could not set player skull texture. " + setException.getMessage()); - } - } - - item.setItemMeta(meta); + VersionManager.getNms().addSkullTexture(item, value, uuid); } @Nullable @@ -358,15 +324,15 @@ public static boolean isAir(@Nullable ItemStack item) { } public static boolean isWeapon(@NotNull ItemStack item) { - return getEngine().getNMS().isWeapon(item); + return VersionManager.getNms().isWeapon(item); } public static boolean isTool(@NotNull ItemStack item) { - return getEngine().getNMS().isTool(item); + return VersionManager.getNms().isTool(item); } public static boolean isArmor(@NotNull ItemStack item) { - return getEngine().getNMS().isArmor(item); + return VersionManager.getNms().isArmor(item); } public static boolean isBow(@NotNull ItemStack item) { diff --git a/src/main/java/studio/magemonkey/codex/util/ItemUtils.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/ItemUtils.java similarity index 71% rename from src/main/java/studio/magemonkey/codex/util/ItemUtils.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/ItemUtils.java index 8b2ae1cb..35109f1b 100644 --- a/src/main/java/studio/magemonkey/codex/util/ItemUtils.java +++ b/codex-plugin/src/main/java/studio/magemonkey/codex/util/ItemUtils.java @@ -2,17 +2,19 @@ import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.TextComponent; -import net.md_5.bungee.api.chat.TranslatableComponent; import org.apache.commons.lang3.StringUtils; -import org.bukkit.*; +import org.bukkit.Bukkit; +import org.bukkit.Color; +import org.bukkit.FireworkEffect; +import org.bukkit.Material; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; -import studio.magemonkey.codex.items.ItemType; +import studio.magemonkey.codex.CodexEngine; +import studio.magemonkey.codex.api.items.ItemType; +import studio.magemonkey.codex.compat.VersionManager; import studio.magemonkey.codex.legacy.placeholder.PlaceholderRegistry; import studio.magemonkey.codex.legacy.placeholder.PlaceholderType; import studio.magemonkey.codex.util.messages.MessageData; -import studio.magemonkey.codex.util.messages.MessageUtil; -import studio.magemonkey.codex.util.messages.NMSPlayerUtils; import java.util.ArrayList; import java.util.Collection; @@ -22,57 +24,25 @@ public class ItemUtils { public static final PlaceholderType ITEM_TYPE = - PlaceholderType.create("itemTYpe", ItemType.class); + PlaceholderType.create("itemType", ItemType.class); static { ITEM_TYPE.registerItem("name", item -> { - ItemStack itemStack = item.create(); - ItemMeta meta = itemStack.getItemMeta(); - String string = null; - if (meta != null) { - string = meta.getDisplayName(); - if (string.isEmpty()) { - try { - string = meta.getItemName(); - } catch (NoSuchMethodError ignored) { - } - } - } - BaseComponent baseComponent; - if (string == null || string.isEmpty()) { - baseComponent = new TranslatableComponent(itemStack.getType().getItemTranslationKey()); - } else { - baseComponent = new TextComponent(string); - } - baseComponent.setHoverEvent(NMSPlayerUtils.convert(itemStack)); + ItemStack itemStack = item.create(); + BaseComponent baseComponent = VersionManager.getNms().getTranslatedComponent(itemStack); + baseComponent.setHoverEvent(VersionManager.getNms().getHoverEvent(itemStack)); return baseComponent; }); ITEM_TYPE.registerItem("displayName", item -> { - ItemStack itemStack = item.create(); - ItemMeta meta = itemStack.getItemMeta(); - String string = null; - if (meta != null) { - string = meta.getDisplayName(); - if (string.isEmpty()) { - try { - string = meta.getItemName(); - } catch (NoSuchMethodError ignored) { - } - } - } - BaseComponent baseComponent; - if (string == null || string.isEmpty()) { - baseComponent = new TranslatableComponent(itemStack.getType().getItemTranslationKey()); - } else { - baseComponent = new TextComponent(string); - } - baseComponent.setHoverEvent(NMSPlayerUtils.convert(itemStack)); + ItemStack itemStack = item.create(); + BaseComponent baseComponent = VersionManager.getNms().getTranslatedComponent(itemStack); + baseComponent.setHoverEvent(VersionManager.getNms().getHoverEvent(itemStack)); return baseComponent; }); ITEM_TYPE.registerItem("material", d -> d.create().getType()); ITEM_TYPE.registerItem("id", item -> { TextComponent textComponent = new TextComponent(item.getNamespacedID()); - textComponent.setHoverEvent(NMSPlayerUtils.convert(item.create())); + textComponent.setHoverEvent(VersionManager.getNms().getHoverEvent(item.create())); return textComponent; }); ITEM_TYPE.registerItem("lore", c -> StringUtils.join(c.create().getItemMeta().getLore(), '\n')); @@ -86,13 +56,13 @@ public static ItemStack replaceText(ItemStack item, MessageData... replace) { ItemMeta im = getItemMeta(item); if (im.hasDisplayName()) { - im.setDisplayName(MessageUtil.getMessageAsString(im.getDisplayName(), im.getDisplayName(), false, replace)); + im.setDisplayName(CodexEngine.get().getMessageUtil().getMessageAsString(im.getDisplayName(), im.getDisplayName(), false, replace)); } if (im.getLore() != null && !im.getLore().isEmpty()) { List newLore = im.getLore() .stream() - .map(lore -> MessageUtil.getMessageAsString(lore, lore, false, replace)) + .map(lore -> CodexEngine.get().getMessageUtil().getMessageAsString(lore, lore, false, replace)) .collect(Collectors.toList()); im.setLore(newLore); } @@ -132,51 +102,6 @@ public static Material getMaterial(final String mat) { return null; } - public static String removeColors(String str) { - if (str == null) return null; - return ChatColor.stripColor(str); - } - - /** - * Strips colors from the list. - * - * @param list List of Strings to remove color from - * @return New ArrayList of cleaned Strings - */ - public static List removeColors(List list) { - if (list == null) return null; - - return list.stream().map(ItemUtils::removeColors).collect(Collectors.toList()); - } - - /** - * Fixes color characters in a string - * - * @param msg message - * @return new string - */ - public static String fixColors(String msg) { - if (msg == null) return null; - - return ChatColor.translateAlternateColorCodes('&', msg); - } - - /** - * Fixes color characters in a List - * - * @param msg List - * @return new List - */ - public static ArrayList fixColors(List msg) { - if (msg == null) return null; - ArrayList ret = new ArrayList<>(); - for (String s : msg) { - String fixColors = fixColors(s); - ret.add(fixColors); - } - return ret; - } - public static ItemMeta getItemMeta(final ItemStack itemStack) { final ItemMeta meta = itemStack.getItemMeta(); if (meta == null) return Bukkit.getItemFactory().getItemMeta(itemStack.getType()); diff --git a/src/main/java/studio/magemonkey/codex/util/TimeUT.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/TimeUT.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/TimeUT.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/TimeUT.java diff --git a/src/main/java/studio/magemonkey/codex/util/actions/ActionCategory.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/ActionCategory.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/actions/ActionCategory.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/ActionCategory.java diff --git a/src/main/java/studio/magemonkey/codex/util/actions/ActionManipulator.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/ActionManipulator.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/actions/ActionManipulator.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/ActionManipulator.java diff --git a/src/main/java/studio/magemonkey/codex/util/actions/ActionSection.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/ActionSection.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/actions/ActionSection.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/ActionSection.java diff --git a/src/main/java/studio/magemonkey/codex/util/actions/ActionsManager.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/ActionsManager.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/actions/ActionsManager.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/ActionsManager.java diff --git a/src/main/java/studio/magemonkey/codex/util/actions/Parametized.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/Parametized.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/actions/Parametized.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/Parametized.java diff --git a/src/main/java/studio/magemonkey/codex/util/actions/actions/IActionExecutor.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/actions/IActionExecutor.java similarity index 95% rename from src/main/java/studio/magemonkey/codex/util/actions/actions/IActionExecutor.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/actions/IActionExecutor.java index 3b7882a9..30c45afd 100644 --- a/src/main/java/studio/magemonkey/codex/util/actions/actions/IActionExecutor.java +++ b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/actions/IActionExecutor.java @@ -39,9 +39,7 @@ public final void process( final String fullStr2 = fullStr; if (delay > 0) { - plugin.getServer().getScheduler().runTaskLater(plugin, () -> { - this.process(exe, targetMap, fullStr2 + FLAG_NO_DELAY, manipulator); - }, delay); + plugin.getServer().getScheduler().runTaskLater(plugin, () -> this.process(exe, targetMap, fullStr2 + FLAG_NO_DELAY, manipulator), delay); return; } } diff --git a/src/main/java/studio/magemonkey/codex/util/actions/actions/IActionType.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/actions/IActionType.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/actions/actions/IActionType.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/actions/IActionType.java diff --git a/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_ActionBar.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_ActionBar.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_ActionBar.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_ActionBar.java diff --git a/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Broadcast.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Broadcast.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Broadcast.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Broadcast.java diff --git a/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Burn.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Burn.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Burn.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Burn.java diff --git a/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_CommandConsole.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_CommandConsole.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_CommandConsole.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_CommandConsole.java diff --git a/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_CommandOp.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_CommandOp.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_CommandOp.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_CommandOp.java diff --git a/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_CommandPlayer.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_CommandPlayer.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_CommandPlayer.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_CommandPlayer.java diff --git a/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Damage.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Damage.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Damage.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Damage.java diff --git a/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Firework.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Firework.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Firework.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Firework.java diff --git a/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Goto.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Goto.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Goto.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Goto.java diff --git a/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Health.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Health.java similarity index 94% rename from src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Health.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Health.java index caf0f115..1c606da9 100644 --- a/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Health.java +++ b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Health.java @@ -4,7 +4,7 @@ import org.bukkit.entity.LivingEntity; import org.jetbrains.annotations.NotNull; import studio.magemonkey.codex.CodexPlugin; -import studio.magemonkey.codex.util.AttributeUT; +import studio.magemonkey.codex.compat.VersionManager; import studio.magemonkey.codex.util.EntityUT; import studio.magemonkey.codex.util.actions.actions.IActionExecutor; import studio.magemonkey.codex.util.actions.actions.IActionType; @@ -52,7 +52,7 @@ protected void execute(@NotNull Entity exe, @NotNull Set targets, @NotNu LivingEntity livingEntity = (LivingEntity) target; double hp2 = hp; - double maxHp = EntityUT.getAttribute(livingEntity, AttributeUT.resolve("MAX_HEALTH")); + double maxHp = EntityUT.getAttribute(livingEntity, VersionManager.getNms().getAttribute("MAX_HEALTH")); if (percent) { hp2 = maxHp * (hp / 100D); diff --git a/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Hook.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Hook.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Hook.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Hook.java diff --git a/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Hunger.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Hunger.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Hunger.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Hunger.java diff --git a/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Lightning.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Lightning.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Lightning.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Lightning.java diff --git a/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Message.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Message.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Message.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Message.java diff --git a/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_ParticleSimple.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_ParticleSimple.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_ParticleSimple.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_ParticleSimple.java diff --git a/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Potion.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Potion.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Potion.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Potion.java diff --git a/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_ProgressBar.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_ProgressBar.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_ProgressBar.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_ProgressBar.java diff --git a/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Projectile.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Projectile.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Projectile.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Projectile.java diff --git a/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Saturation.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Saturation.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Saturation.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Saturation.java diff --git a/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Sound.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Sound.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Sound.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Sound.java diff --git a/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Teleport.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Teleport.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Teleport.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Teleport.java diff --git a/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Throw.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Throw.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Throw.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Throw.java diff --git a/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Titles.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Titles.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Titles.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/actions/list/Action_Titles.java diff --git a/src/main/java/studio/magemonkey/codex/util/actions/api/IActioned.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/api/IActioned.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/actions/api/IActioned.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/api/IActioned.java diff --git a/src/main/java/studio/magemonkey/codex/util/actions/conditions/IConditionType.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/conditions/IConditionType.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/actions/conditions/IConditionType.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/conditions/IConditionType.java diff --git a/src/main/java/studio/magemonkey/codex/util/actions/conditions/IConditionValidator.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/conditions/IConditionValidator.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/actions/conditions/IConditionValidator.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/conditions/IConditionValidator.java diff --git a/src/main/java/studio/magemonkey/codex/util/actions/conditions/list/Condition_EntityHealth.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/conditions/list/Condition_EntityHealth.java similarity index 95% rename from src/main/java/studio/magemonkey/codex/util/actions/conditions/list/Condition_EntityHealth.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/conditions/list/Condition_EntityHealth.java index 2a4b6466..0b0a1604 100644 --- a/src/main/java/studio/magemonkey/codex/util/actions/conditions/list/Condition_EntityHealth.java +++ b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/conditions/list/Condition_EntityHealth.java @@ -5,7 +5,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import studio.magemonkey.codex.CodexPlugin; -import studio.magemonkey.codex.util.AttributeUT; +import studio.magemonkey.codex.compat.VersionManager; import studio.magemonkey.codex.util.EntityUT; import studio.magemonkey.codex.util.actions.conditions.IConditionType; import studio.magemonkey.codex.util.actions.conditions.IConditionValidator; @@ -58,7 +58,7 @@ protected Predicate validate( LivingEntity livingEntity = (LivingEntity) target; double hpTarget = livingEntity.getHealth(); - double hpTargetMax = EntityUT.getAttribute(livingEntity, AttributeUT.resolve("MAX_HEALTH")); + double hpTargetMax = EntityUT.getAttribute(livingEntity, VersionManager.getNms().getAttribute("MAX_HEALTH")); if (isPercent) { hpTarget = hpTarget / hpTargetMax * 100D; diff --git a/src/main/java/studio/magemonkey/codex/util/actions/conditions/list/Condition_EntityType.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/conditions/list/Condition_EntityType.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/actions/conditions/list/Condition_EntityType.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/conditions/list/Condition_EntityType.java diff --git a/src/main/java/studio/magemonkey/codex/util/actions/conditions/list/Condition_Permission.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/conditions/list/Condition_Permission.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/actions/conditions/list/Condition_Permission.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/conditions/list/Condition_Permission.java diff --git a/src/main/java/studio/magemonkey/codex/util/actions/conditions/list/Condition_VaultBalance.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/conditions/list/Condition_VaultBalance.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/actions/conditions/list/Condition_VaultBalance.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/conditions/list/Condition_VaultBalance.java diff --git a/src/main/java/studio/magemonkey/codex/util/actions/conditions/list/Condition_WorldTime.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/conditions/list/Condition_WorldTime.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/actions/conditions/list/Condition_WorldTime.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/conditions/list/Condition_WorldTime.java diff --git a/src/main/java/studio/magemonkey/codex/util/actions/params/IAutoValidated.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/params/IAutoValidated.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/actions/params/IAutoValidated.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/params/IAutoValidated.java diff --git a/src/main/java/studio/magemonkey/codex/util/actions/params/IParam.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/params/IParam.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/actions/params/IParam.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/params/IParam.java diff --git a/src/main/java/studio/magemonkey/codex/util/actions/params/IParamResult.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/params/IParamResult.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/actions/params/IParamResult.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/params/IParamResult.java diff --git a/src/main/java/studio/magemonkey/codex/util/actions/params/IParamType.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/params/IParamType.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/actions/params/IParamType.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/params/IParamType.java diff --git a/src/main/java/studio/magemonkey/codex/util/actions/params/IParamValue.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/params/IParamValue.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/actions/params/IParamValue.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/params/IParamValue.java diff --git a/src/main/java/studio/magemonkey/codex/util/actions/params/defaults/IParamBoolean.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/params/defaults/IParamBoolean.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/actions/params/defaults/IParamBoolean.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/params/defaults/IParamBoolean.java diff --git a/src/main/java/studio/magemonkey/codex/util/actions/params/defaults/IParamNumber.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/params/defaults/IParamNumber.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/actions/params/defaults/IParamNumber.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/params/defaults/IParamNumber.java diff --git a/src/main/java/studio/magemonkey/codex/util/actions/params/defaults/IParamString.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/params/defaults/IParamString.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/actions/params/defaults/IParamString.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/params/defaults/IParamString.java diff --git a/src/main/java/studio/magemonkey/codex/util/actions/params/list/AllowSelfParam.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/params/list/AllowSelfParam.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/actions/params/list/AllowSelfParam.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/params/list/AllowSelfParam.java diff --git a/src/main/java/studio/magemonkey/codex/util/actions/params/list/AttackableParam.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/params/list/AttackableParam.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/actions/params/list/AttackableParam.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/params/list/AttackableParam.java diff --git a/src/main/java/studio/magemonkey/codex/util/actions/params/list/LocationParam.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/params/list/LocationParam.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/actions/params/list/LocationParam.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/params/list/LocationParam.java diff --git a/src/main/java/studio/magemonkey/codex/util/actions/params/list/OffsetParam.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/params/list/OffsetParam.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/actions/params/list/OffsetParam.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/params/list/OffsetParam.java diff --git a/src/main/java/studio/magemonkey/codex/util/actions/params/parser/IParamParser.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/params/parser/IParamParser.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/actions/params/parser/IParamParser.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/params/parser/IParamParser.java diff --git a/src/main/java/studio/magemonkey/codex/util/actions/params/parser/ParamBooleanParser.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/params/parser/ParamBooleanParser.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/actions/params/parser/ParamBooleanParser.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/params/parser/ParamBooleanParser.java diff --git a/src/main/java/studio/magemonkey/codex/util/actions/params/parser/ParamNumberParser.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/params/parser/ParamNumberParser.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/actions/params/parser/ParamNumberParser.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/params/parser/ParamNumberParser.java diff --git a/src/main/java/studio/magemonkey/codex/util/actions/params/parser/ParamStringParser.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/params/parser/ParamStringParser.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/actions/params/parser/ParamStringParser.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/params/parser/ParamStringParser.java diff --git a/src/main/java/studio/magemonkey/codex/util/actions/targets/ITargetSelector.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/targets/ITargetSelector.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/actions/targets/ITargetSelector.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/targets/ITargetSelector.java diff --git a/src/main/java/studio/magemonkey/codex/util/actions/targets/ITargetType.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/targets/ITargetType.java similarity index 100% rename from src/main/java/studio/magemonkey/codex/util/actions/targets/ITargetType.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/targets/ITargetType.java diff --git a/src/main/java/studio/magemonkey/codex/util/actions/targets/list/Target_FromSight.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/targets/list/Target_FromSight.java similarity index 94% rename from src/main/java/studio/magemonkey/codex/util/actions/targets/list/Target_FromSight.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/targets/list/Target_FromSight.java index 8ff1470e..1c2903eb 100644 --- a/src/main/java/studio/magemonkey/codex/util/actions/targets/list/Target_FromSight.java +++ b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/targets/list/Target_FromSight.java @@ -36,7 +36,7 @@ public void registerParams() { } @Override - protected void validateTarget(Entity exe, Set targets, IParamResult result) { + protected void validateTarget(@NotNull Entity exe, @NotNull Set targets, @NotNull IParamResult result) { double dist = -1; if (result.hasParam(IParamType.DISTANCE)) { dist = result.getParamValue(IParamType.DISTANCE).getDouble(0); diff --git a/src/main/java/studio/magemonkey/codex/util/actions/targets/list/Target_Radius.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/targets/list/Target_Radius.java similarity index 92% rename from src/main/java/studio/magemonkey/codex/util/actions/targets/list/Target_Radius.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/targets/list/Target_Radius.java index 21dfad26..3419bfb1 100644 --- a/src/main/java/studio/magemonkey/codex/util/actions/targets/list/Target_Radius.java +++ b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/targets/list/Target_Radius.java @@ -32,7 +32,7 @@ public void registerParams() { } @Override - protected void validateTarget(Entity exe, Set targets, IParamResult result) { + protected void validateTarget(@NotNull Entity exe, @NotNull Set targets, @NotNull IParamResult result) { double dist = -1; if (result.hasParam(IParamType.DISTANCE)) { dist = result.getParamValue(IParamType.DISTANCE).getDouble(0); diff --git a/src/main/java/studio/magemonkey/codex/util/actions/targets/list/Target_Self.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/targets/list/Target_Self.java similarity index 89% rename from src/main/java/studio/magemonkey/codex/util/actions/targets/list/Target_Self.java rename to codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/targets/list/Target_Self.java index b1b48724..944f119c 100644 --- a/src/main/java/studio/magemonkey/codex/util/actions/targets/list/Target_Self.java +++ b/codex-plugin/src/main/java/studio/magemonkey/codex/util/actions/targets/list/Target_Self.java @@ -29,7 +29,7 @@ public void registerParams() { } @Override - protected void validateTarget(Entity exe, Set targets, IParamResult result) { + protected void validateTarget(@NotNull Entity exe, @NotNull Set targets, @NotNull IParamResult result) { Set disTargets = new HashSet<>(); disTargets.add(exe); diff --git a/codex-plugin/src/main/java/studio/magemonkey/codex/util/messages/MessageUtil.java b/codex-plugin/src/main/java/studio/magemonkey/codex/util/messages/MessageUtil.java new file mode 100644 index 00000000..48955247 --- /dev/null +++ b/codex-plugin/src/main/java/studio/magemonkey/codex/util/messages/MessageUtil.java @@ -0,0 +1,128 @@ +package studio.magemonkey.codex.util.messages; + +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.api.chat.TextComponent; +import org.bukkit.ChatColor; +import studio.magemonkey.codex.legacy.placeholder.PlaceholderItem; +import studio.magemonkey.codex.legacy.placeholder.PlaceholderType; +import studio.magemonkey.codex.legacy.riseitem.DarkRiseItem; +import studio.magemonkey.codex.legacy.utils.ComponentUtils; +import studio.magemonkey.codex.legacy.utils.Utils; + +import java.util.*; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +public class MessageUtil extends AbstractMessageUtil { + @Override + public BaseComponent[] getMessageAsComponent(String path, MessageData... replace) { + List components = new ArrayList<>(); + + List msgs = getString(path); + Map> placeholders = new HashMap<>(); + Map data = Arrays.stream(replace) + .collect(Collectors.toMap(MessageData::getName, messageData -> messageData, (a, b) -> b, HashMap::new)); + + Pattern pat = Pattern.compile("\\$<(.*?)>"); + msgs.stream().map(pat::matcher).forEach(mat -> { + while (mat.find()) { + PlaceholderItem it = PlaceholderType.getQualifiedItem(mat.group(1)); + if (it != null) { + String id = "$<" + mat.group(1) + ">"; + placeholders.put(id, it); + } + } + }); + + for (String send : msgs) { + if (send.equalsIgnoreCase("false")) + continue; + + BaseComponent[] comps = ComponentUtils.fromLegacyText(send); + for (BaseComponent component : comps) { + for (Map.Entry> entry : placeholders.entrySet()) { + PlaceholderItem holder = entry.getValue(); + String id = entry.getKey(); + if (!component.toPlainText().contains(id)) + continue; + Object translated = holder.apply(data.get(holder.getType().getId()).getObject(), null); + if (translated instanceof BaseComponent) + ComponentUtils.replace(component, id, (BaseComponent) translated); + else + ComponentUtils.replace(component, id, translated.toString()); + } + for (MessageData datum : replace) { + String check = "$<" + datum.getName() + ">"; + if (!component.toPlainText().contains(check)) + continue; + if (datum.getObject() instanceof BaseComponent) + ComponentUtils.replace(component, check, (BaseComponent) datum.getObject()); + else + ComponentUtils.replace(component, check, datum.getObject().toString()); + } + components.add(component); + } + if (msgs.size() > 1) + components.add(new TextComponent("\n")); + } + + return components.toArray(new BaseComponent[0]); + } + + @Override + public String getMessageAsString(String path, final String def, boolean stripColor, MessageData... data) { + if (!messages.containsKey(path)) + path = def; + BaseComponent[] strs = getMessageAsComponent(path, data); + + StringBuilder bob = new StringBuilder(); + + for (BaseComponent str : strs) { + bob.append(str.toLegacyText()); + } + + return stripColor ? ChatColor.stripColor(bob.toString()) : bob.toString(); + } + + private List getString(String key) { + List ret = new ArrayList<>(); + if (!messages.containsKey(key)) { + ret.add(key); + return ret; + } + + + Object msg = messages.get(key); + if (msg == null) { + ret.add(key); + } else { + try { + ret.addAll(((List) msg)); + } catch (ClassCastException e) { + ret.add(msg.toString()); + } + } + + return Utils.fixColors(ret); + } + + public static String getReplacement(String string) { + string = "$<" + string + ">"; + + return string; + } + + private static MessageData[] translateSpecial(MessageData... data) { + List rep = new ArrayList<>(); + for (MessageData md : data) { + if (md.getName().equalsIgnoreCase("item")) { + DarkRiseItem it = (DarkRiseItem) md.getObject(); + rep.add(new MessageData("riseItem.name", it.getName())); + rep.add(new MessageData("riseItem.id", it.getId())); + } else + rep.add(md); + } + + return rep.toArray(new MessageData[0]); + } +} diff --git a/src/main/resources/config.yml b/codex-plugin/src/main/resources/config.yml similarity index 100% rename from src/main/resources/config.yml rename to codex-plugin/src/main/resources/config.yml diff --git a/src/main/resources/editor/actions_main.yml b/codex-plugin/src/main/resources/editor/actions_main.yml similarity index 100% rename from src/main/resources/editor/actions_main.yml rename to codex-plugin/src/main/resources/editor/actions_main.yml diff --git a/src/main/resources/editor/actions_parametized.yml b/codex-plugin/src/main/resources/editor/actions_parametized.yml similarity index 100% rename from src/main/resources/editor/actions_parametized.yml rename to codex-plugin/src/main/resources/editor/actions_parametized.yml diff --git a/src/main/resources/editor/actions_params.yml b/codex-plugin/src/main/resources/editor/actions_params.yml similarity index 100% rename from src/main/resources/editor/actions_params.yml rename to codex-plugin/src/main/resources/editor/actions_params.yml diff --git a/src/main/resources/editor/actions_section.yml b/codex-plugin/src/main/resources/editor/actions_section.yml similarity index 100% rename from src/main/resources/editor/actions_section.yml rename to codex-plugin/src/main/resources/editor/actions_section.yml diff --git a/src/main/resources/lang/messages_cn.yml b/codex-plugin/src/main/resources/lang/messages_cn.yml similarity index 100% rename from src/main/resources/lang/messages_cn.yml rename to codex-plugin/src/main/resources/lang/messages_cn.yml diff --git a/src/main/resources/lang/messages_en.yml b/codex-plugin/src/main/resources/lang/messages_en.yml similarity index 100% rename from src/main/resources/lang/messages_en.yml rename to codex-plugin/src/main/resources/lang/messages_en.yml diff --git a/src/main/resources/paper-plugin.yml b/codex-plugin/src/main/resources/paper-plugin.yml similarity index 100% rename from src/main/resources/paper-plugin.yml rename to codex-plugin/src/main/resources/paper-plugin.yml diff --git a/src/main/resources/plugin.yml b/codex-plugin/src/main/resources/plugin.yml similarity index 100% rename from src/main/resources/plugin.yml rename to codex-plugin/src/main/resources/plugin.yml diff --git a/codex-plugin/src/main/resources/temp.yml b/codex-plugin/src/main/resources/temp.yml new file mode 100644 index 00000000..e69de29b diff --git a/src/test/java/studio/magemonkey/codex/CommandTest.java b/codex-plugin/src/test/java/studio/magemonkey/codex/CommandTest.java similarity index 100% rename from src/test/java/studio/magemonkey/codex/CommandTest.java rename to codex-plugin/src/test/java/studio/magemonkey/codex/CommandTest.java diff --git a/src/test/java/studio/magemonkey/codex/mccore/config/parse/YAMLParserTest.java b/codex-plugin/src/test/java/studio/magemonkey/codex/mccore/config/parse/YAMLParserTest.java similarity index 100% rename from src/test/java/studio/magemonkey/codex/mccore/config/parse/YAMLParserTest.java rename to codex-plugin/src/test/java/studio/magemonkey/codex/mccore/config/parse/YAMLParserTest.java diff --git a/src/test/java/studio/magemonkey/codex/testutil/DependencyResolver.java b/codex-plugin/src/test/java/studio/magemonkey/codex/testutil/DependencyResolver.java similarity index 100% rename from src/test/java/studio/magemonkey/codex/testutil/DependencyResolver.java rename to codex-plugin/src/test/java/studio/magemonkey/codex/testutil/DependencyResolver.java diff --git a/src/test/java/studio/magemonkey/codex/testutil/MockedTest.java b/codex-plugin/src/test/java/studio/magemonkey/codex/testutil/MockedTest.java similarity index 76% rename from src/test/java/studio/magemonkey/codex/testutil/MockedTest.java rename to codex-plugin/src/test/java/studio/magemonkey/codex/testutil/MockedTest.java index 6c6a34b4..36fe526c 100644 --- a/src/test/java/studio/magemonkey/codex/testutil/MockedTest.java +++ b/codex-plugin/src/test/java/studio/magemonkey/codex/testutil/MockedTest.java @@ -1,6 +1,10 @@ package studio.magemonkey.codex.testutil; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; import org.bukkit.event.Event; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.Inventory; import org.bukkit.plugin.Plugin; import org.jetbrains.annotations.NotNull; import org.junit.jupiter.api.AfterAll; @@ -14,17 +18,15 @@ import studio.magemonkey.codex.CodexEngine; import studio.magemonkey.codex.commands.CommandRegister; import studio.magemonkey.codex.commands.api.IGeneralCommand; +import studio.magemonkey.codex.compat.NMS; +import studio.magemonkey.codex.compat.VersionManager; import studio.magemonkey.codex.core.config.CoreLang; import studio.magemonkey.codex.hooks.HookManager; import studio.magemonkey.codex.mccore.commands.CommandManager; import studio.magemonkey.codex.mccore.scoreboard.Board; -import studio.magemonkey.codex.nms.NMS; -import studio.magemonkey.codex.testutil.reflection.TestReflectionUtil; +import studio.magemonkey.codex.util.InventoryUtil; import studio.magemonkey.codex.util.Reflex; import studio.magemonkey.codex.util.actions.ActionsManager; -import studio.magemonkey.codex.util.reflection.ReflectionManager; -import studio.magemonkey.codex.util.reflection.ReflectionUtil; -import studio.magemonkey.codex.util.reflection.Reflection_1_17; import java.io.*; import java.util.ArrayList; @@ -40,33 +42,25 @@ @TestInstance(TestInstance.Lifecycle.PER_CLASS) public abstract class MockedTest { - protected ServerMock server; - protected CodexEngine plugin; - protected List players = new ArrayList<>(); - protected MockedStatic reflex; - protected MockedStatic commandRegister; - protected MockedStatic mockedReflection; - protected MockedStatic mockedReflection17; - protected MockedStatic board; - protected MockedStatic reflectionManager; - protected ReflectionUtil reflectionUtil; - protected HookManager hookManager; - protected NMS nms; - protected ActionsManager actionsManager; - protected CoreLang coreLang; + protected ServerMock server; + protected CodexEngine plugin; + protected List players = new ArrayList<>(); + protected MockedStatic reflex; + protected MockedStatic commandRegister; + protected MockedStatic board; + protected MockedStatic inventoryUtil; + protected HookManager hookManager; + protected ActionsManager actionsManager; + protected CoreLang coreLang; @BeforeAll public void setupServer() { server = spy(MockBukkit.mock()); - reflectionUtil = spy(new TestReflectionUtil()); - reflectionManager = mockStatic(ReflectionManager.class); - reflectionManager.when(ReflectionManager::getReflectionUtil) - .thenReturn(reflectionUtil); commandRegister = mockStatic(CommandRegister.class); commandRegister.when(() -> CommandRegister.register(any(), any(IGeneralCommand.class))) .thenAnswer(ans -> { - Plugin plugin = ans.getArgument(0); - IGeneralCommand command = ans.getArgument(1); + Plugin plugin = ans.getArgument(0); + IGeneralCommand command = ans.getArgument(1); CommandRegister cmd = new CommandRegister(command.labels(), command.description(), command.usage(), @@ -88,6 +82,25 @@ public void setupServer() { throw new RuntimeException(e); } board = mockStatic(Board.class); + + inventoryUtil = mockStatic(InventoryUtil.class); + inventoryUtil.when(() -> InventoryUtil.getTopInventory(any(Player.class))) + .thenAnswer(ans -> { + Player player = ((Player) ans.getArgument(0)); + Inventory inv = player.getOpenInventory().getTopInventory(); + //noinspection ConstantValue + if (inv != null) return inv; + + // It shouldn't be possible to have a null topInventory, but is for MockBukkit + return player.getInventory(); + }); + + NMS nms = mock(NMS.class); + when(nms.getVersion()).thenReturn("test"); + when(nms.fixColors(anyString())).thenAnswer(ans -> ans.getArgument(0)); + + VersionManager.setNms(nms); + reflex = mockStatic(Reflex.class); reflex.when(() -> Reflex.getClass(startsWith("studio.magemonkey"), anyString())) .thenCallRealMethod(); @@ -102,8 +115,6 @@ public void setupServer() { } return List.of(); }); - mockedReflection = mockStatic(ReflectionUtil.class); - mockedReflection17 = mockStatic(Reflection_1_17.class); coreLang = mock(CoreLang.class); when(coreLang.getEnum(any())) @@ -115,23 +126,17 @@ public void setupServer() { hookManager = mock(HookManager.class); actionsManager = mock(ActionsManager.class); - nms = mock(NMS.class); - when(nms.fixColors(anyString())) - .thenAnswer(args -> args.getArgument(0)); - plugin = MockBukkit.load(CodexEngine.class); } @AfterAll public void destroy() { - reflex.close(); - commandRegister.close(); - mockedReflection.close(); - mockedReflection17.close(); - board.close(); - reflectionManager.close(); + if (reflex != null) reflex.close(); + if (commandRegister != null) commandRegister.close(); + if (board != null) board.close(); CommandManager.unregisterAll(); MockBukkit.unmock(); + if (inventoryUtil != null) inventoryUtil.close(); } @AfterEach diff --git a/src/test/java/studio/magemonkey/codex/testutil/reflection/TestChannel.java b/codex-plugin/src/test/java/studio/magemonkey/codex/testutil/reflection/TestChannel.java similarity index 100% rename from src/test/java/studio/magemonkey/codex/testutil/reflection/TestChannel.java rename to codex-plugin/src/test/java/studio/magemonkey/codex/testutil/reflection/TestChannel.java diff --git a/src/test/java/studio/magemonkey/codex/util/LocUTTest.java b/codex-plugin/src/test/java/studio/magemonkey/codex/util/LocUTTest.java similarity index 100% rename from src/test/java/studio/magemonkey/codex/util/LocUTTest.java rename to codex-plugin/src/test/java/studio/magemonkey/codex/util/LocUTTest.java diff --git a/src/test/resources/fabled-config.yml b/codex-plugin/src/test/resources/fabled-config.yml similarity index 100% rename from src/test/resources/fabled-config.yml rename to codex-plugin/src/test/resources/fabled-config.yml diff --git a/src/test/resources/log4j.xml b/codex-plugin/src/test/resources/log4j.xml similarity index 100% rename from src/test/resources/log4j.xml rename to codex-plugin/src/test/resources/log4j.xml diff --git a/doc/README.md b/doc/README.md index db1a80fa..7710cafd 100644 --- a/doc/README.md +++ b/doc/README.md @@ -1,10 +1,10 @@ -[![Build](https://github.com/promcteam/${project.artifactId}/actions/workflows/release.yml/badge.svg?branch=main)](https://s01.oss.sonatype.org/content/repositories/releases/studio/magemonkey/${project.artifactId}/${project.version}) -[![Build](https://github.com/promcteam/${project.artifactId}/actions/workflows/devbuild.yml/badge.svg?branch=dev)](https://s01.oss.sonatype.org/content/repositories/snapshots/studio/magemonkey/${project.artifactId}/${project.version}) +[![Build](https://github.com/magemonkeystudios/codex/actions/workflows/release.yml/badge.svg?branch=main)](https://s01.oss.sonatype.org/content/repositories/releases/studio/magemonkey/codex/${project.version}) +[![Build](https://github.com/magemonkeystudios/codex/actions/workflows/devbuild.yml/badge.svg?branch=dev)](https://s01.oss.sonatype.org/content/repositories/snapshots/studio/magemonkey/codex/${project.version}) [![Discord](https://dcbadge.vercel.app/api/server/6UzkTe6RvW?style=flat)](https://discord.gg/6UzkTe6RvW) -# ${project.name} (Formerly ProMCCore) +# Codex (Formerly ProMCCore) -If you wish to use ${project.name} as a dependency in your projects, ${project.name} is available through Maven Central +If you wish to use Codex as a dependency in your projects, Codex is available through Maven Central or snapshots through Sonatype. ```xml @@ -15,13 +15,13 @@ or snapshots through Sonatype. ... ${project.groupId} - ${project.artifactId} + codex ${project.version} ``` ### A huge thanks to our contributors - - + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 00c64ac3..912eaba2 100644 --- a/pom.xml +++ b/pom.xml @@ -10,11 +10,19 @@ 1.21.3-R0.2 - codex - CodexCore - 1.0.1-R0.19-SNAPSHOT + codex-parent + 1.1.0-R0.1-SNAPSHOT + pom The core plugin for MageMonkeyStudio plugins + + codex-core + codex-nms + codex-plugin + codex-api + codex-bungee + + ${project.build.directory}/javadoc-delombok @@ -24,25 +32,9 @@ sonatype https://s01.oss.sonatype.org/content/repositories/snapshots - - - oraxen - Oraxen Repository - https://repo.oraxen.com/releases - - - - nexo - Nexo Repository - https://repo.nexomc.com/snapshots/ - - - net.md-5 - bungeecord-api - com.mojang authlib @@ -126,66 +118,6 @@ commons-io commons-io - - io.th0rgal - oraxen - 1.173.0 - dev - provided - - - me.gabytm.util - actions-spigot - - - org.jetbrains - annotations - - - com.ticxo - PlayerAnimator - - - com.github.stefvanschie.inventoryframework - IF - - - io.th0rgal - protectionlib - - - dev.triumphteam - triumph-gui - - - org.bstats - bstats-bukkit - - - com.jeff-media - custom-block-data - - - com.jeff-media - persistent-data-serializer - - - com.jeff_media - MorePersistentDataTypes - - - gs.mclo - java - - - - - com.nexomc - nexo - 0.1.0-dev.0 - dev - provided - com.github.LoneDev6 api-itemsadder @@ -196,22 +128,6 @@ - - org.apache.maven.plugins - maven-shade-plugin - 3.6.0 - - - package - - shade - - - false - - - - org.apache.maven.plugins maven-surefire-plugin @@ -241,36 +157,90 @@ delombok - ${project.basedir}/src/main/java + src/main/java ${delombok.dir} false + + + + + + module + + + .module + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.11.1 + + ${delombok.dir} + all,-missing + + + + attach-javadocs + + jar + + + false + true + + + + + + + + + parent + + + .github + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.11.1 + + ${project.basedir} + all,-missing + codex-api/target/javadoc-delombok;codex-core/target/javadoc-delombok;codex-plugin/target/javadoc-delombok + + + + + aggregate + + + + + + + + + + + org.apache.maven.plugins maven-javadoc-plugin - - ${delombok.dir} - ${project.basedir} - gh-pages/javadocs - all,-missing - - - - attach-javadocs - - jar - - - true - - - + 3.11.1 - + @@ -288,8 +258,8 @@ - scm:git:git://github.com/promcteam/${project.artifactId}.git - scm:git:ssh://github.com:promcteam/${project.artifactId}.git - https://github.com/promcteam/${project.artifactId} + scm:git:git://github.com/magemonkeystudio/${project.artifactId}.git + scm:git:ssh://github.com:magemonkeystudio/${project.artifactId}.git + https://github.com/magemonkeystudio/${project.artifactId} diff --git a/src/main/java/studio/magemonkey/codex/listeners/BoatListener.java b/src/main/java/studio/magemonkey/codex/listeners/BoatListener.java deleted file mode 100644 index 3e8bf018..00000000 --- a/src/main/java/studio/magemonkey/codex/listeners/BoatListener.java +++ /dev/null @@ -1,54 +0,0 @@ -package studio.magemonkey.codex.listeners; - -import org.bukkit.Material; -import org.bukkit.entity.Boat; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.vehicle.VehicleExitEvent; -import org.bukkit.inventory.ItemStack; -import studio.magemonkey.codex.CodexEngine; - -public class BoatListener implements Listener { - @EventHandler - public void exit(VehicleExitEvent event) { - if (!CodexEngine.get().cfg().getJYML().getBoolean("removeBoatOnExit")) return; - if (!(event.getVehicle() instanceof Boat)) return; - if (!(event.getExited() instanceof Player)) return; - - Player player = (Player) event.getExited(); - Boat boat = (Boat) event.getVehicle(); - - ItemStack item = new ItemStack(getMaterial(boat)); - if (!player.getInventory().addItem(item).isEmpty()) - player.getWorld() - .dropItemNaturally(player.getLocation(), item); - boat.remove(); - } - - private Material getMaterial(Boat boat) { - try { - return boat.getBoatType().getMaterial(); - } catch (NoSuchMethodError e) { - String woodName = boat.getWoodType().name(); - // Should `getWoodType` be removed in later versions, this Reflection should work - // String woodName = "OAK"; - // try { - // Method getWoodTypeMethod = boat.getClass().getMethod("getWoodType"); - // Enum woodType = (Enum) getWoodTypeMethod.invoke(boat); - // woodName = woodType.name(); - // } catch (NoSuchMethodError | NoSuchMethodException | InvocationTargetException | IllegalAccessException be) { - // CodexEngine.get().getLogger().warning("Failed to get wood type of boat, defaulting to OAK"); - // } - - return switch (woodName) { - case "REDWOOD" -> Material.SPRUCE_BOAT; - case "BIRCH" -> Material.BIRCH_BOAT; - case "JUNGLE" -> Material.JUNGLE_BOAT; - case "ACACIA" -> Material.ACACIA_BOAT; - case "DARK_OAK" -> Material.DARK_OAK_BOAT; - default -> Material.OAK_BOAT; - }; - } - } -} diff --git a/src/main/java/studio/magemonkey/codex/manager/api/Loggable.java b/src/main/java/studio/magemonkey/codex/manager/api/Loggable.java deleted file mode 100644 index 19ce59f8..00000000 --- a/src/main/java/studio/magemonkey/codex/manager/api/Loggable.java +++ /dev/null @@ -1,12 +0,0 @@ -package studio.magemonkey.codex.manager.api; - -import org.jetbrains.annotations.NotNull; - -public interface Loggable { - - public void info(@NotNull String msg); - - public void warn(@NotNull String msg); - - public void error(@NotNull String msg); -} diff --git a/src/main/java/studio/magemonkey/codex/nms/NMS.java b/src/main/java/studio/magemonkey/codex/nms/NMS.java deleted file mode 100644 index 11e9d0a5..00000000 --- a/src/main/java/studio/magemonkey/codex/nms/NMS.java +++ /dev/null @@ -1,69 +0,0 @@ -package studio.magemonkey.codex.nms; - -import io.netty.channel.Channel; -import org.bukkit.block.Block; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import studio.magemonkey.codex.util.reflection.ReflectionManager; -import studio.magemonkey.codex.util.reflection.ReflectionUtil; - -public class NMS { - private final ReflectionUtil reflectionUtil = ReflectionManager.getReflectionUtil(); - - public void openChestAnimation(@NotNull Block chest, boolean open) { - reflectionUtil.openChestAnimation(chest, open); - } - - public void sendAttackPacket(@NotNull Player p, int i) { - reflectionUtil.sendAttackPacket(p, i); - } - - @NotNull - public Channel getChannel(@NotNull Player p) { - return reflectionUtil.getChannel(p); - } - - public void sendPacket(@NotNull Player p, @NotNull Object packet) { - reflectionUtil.sendPacket(p, packet); - } - - @NotNull - public ItemStack damageItem(@NotNull ItemStack item, int amount, @Nullable Player player) { - return reflectionUtil.damageItem(item, amount, player); - } - - @NotNull - public String fixColors(@NotNull String str) { - return reflectionUtil.fixColors(str); - } - - public double getDefaultDamage(@NotNull ItemStack itemStack) { - return reflectionUtil.getDefaultDamage(itemStack); - } - - public double getDefaultSpeed(@NotNull ItemStack itemStack) { - return reflectionUtil.getDefaultSpeed(itemStack); - } - - public double getDefaultArmor(@NotNull ItemStack itemStack) { - return reflectionUtil.getDefaultArmor(itemStack); - } - - public double getDefaultToughness(@NotNull ItemStack itemStack) { - return reflectionUtil.getDefaultToughness(itemStack); - } - - public boolean isWeapon(@NotNull ItemStack itemStack) { - return reflectionUtil.isWeapon(itemStack); - } - - public boolean isTool(@NotNull ItemStack itemStack) { - return reflectionUtil.isTool(itemStack); - } - - public boolean isArmor(@NotNull ItemStack itemStack) { - return reflectionUtil.isArmor(itemStack); - } -} diff --git a/src/main/java/studio/magemonkey/codex/util/AttributeUT.java b/src/main/java/studio/magemonkey/codex/util/AttributeUT.java deleted file mode 100644 index 07d91e23..00000000 --- a/src/main/java/studio/magemonkey/codex/util/AttributeUT.java +++ /dev/null @@ -1,48 +0,0 @@ -package studio.magemonkey.codex.util; - -import lombok.SneakyThrows; -import org.bukkit.attribute.Attribute; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -public class AttributeUT { - private static Method valueOf; - - /** - * Resolve an attribute by name. This method is deprecated because - * the underlying method is also deprecated. This is a temporary fix - * until we determine where we want to go. - * @param name The name of the attribute - * @return The attribute - * @deprecated - */ - @SneakyThrows - @Deprecated - public static Attribute resolve(String name) { - if (valueOf == null) { - valueOf = Attribute.class.getDeclaredMethod("valueOf", String.class); - } - - Attribute attribute = null; - try { - attribute = (Attribute) valueOf.invoke(null, name); - } catch (InvocationTargetException ignored) { - } - - if (attribute == null) { - try { - attribute = (Attribute) valueOf.invoke(null, "GENERIC_" + name); - } catch (InvocationTargetException ignored) { - } - } - if (attribute == null) { - try { - attribute = (Attribute) valueOf.invoke(null, "PLAYER_" + name); - } catch (InvocationTargetException ignored) { - } - } - return attribute; - } - -} diff --git a/src/main/java/studio/magemonkey/codex/util/EntityUT.java b/src/main/java/studio/magemonkey/codex/util/EntityUT.java deleted file mode 100644 index 4ffc33bb..00000000 --- a/src/main/java/studio/magemonkey/codex/util/EntityUT.java +++ /dev/null @@ -1,98 +0,0 @@ -package studio.magemonkey.codex.util; - -import org.bukkit.Material; -import org.bukkit.attribute.Attribute; -import org.bukkit.attribute.AttributeInstance; -import org.bukkit.entity.*; -import org.bukkit.inventory.EntityEquipment; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.SkullMeta; -import org.jetbrains.annotations.NotNull; - -public class EntityUT { - - public static double getAttribute(@NotNull LivingEntity entity, @NotNull Attribute attribute) { - AttributeInstance ai = entity.getAttribute(attribute); - return ai == null ? 0D : ai.getValue(); - } - - public static double getAttributeBase(@NotNull LivingEntity entity, @NotNull Attribute attribute) { - AttributeInstance ai = entity.getAttribute(attribute); - return ai == null ? 0D : ai.getBaseValue(); - } - - public static ItemStack[] getArmor(@NotNull LivingEntity entity) { - EntityEquipment equip = entity.getEquipment(); - if (equip == null) return new ItemStack[4]; - - return equip.getArmorContents(); - } - - public static ItemStack[] getEquipment(@NotNull LivingEntity entity) { - ItemStack[] items = new ItemStack[6]; - - EntityEquipment equip = entity.getEquipment(); - if (equip == null) return items; - - int aCount = 0; - for (ItemStack armor : equip.getArmorContents()) { - items[aCount++] = armor; - } - - items[4] = equip.getItemInMainHand(); - items[5] = equip.getItemInOffHand(); - - return items; - } - - @SuppressWarnings("deprecation") - @NotNull - public static ItemStack getSkull(@NotNull LivingEntity victim) { - ItemStack item; - if (victim instanceof WitherSkeleton) { - item = new ItemStack(Material.WITHER_SKELETON_SKULL); - } else if (victim instanceof Zombie && !(victim instanceof ZombieVillager)) { - item = new ItemStack(Material.ZOMBIE_HEAD); - } else if (victim instanceof Skeleton) { - item = new ItemStack(Material.SKELETON_SKULL); - } else if (victim instanceof Creeper) { - item = new ItemStack(Material.CREEPER_HEAD); - } else if (victim instanceof EnderDragon) { - item = new ItemStack(Material.DRAGON_HEAD); - } else { - item = new ItemStack(Material.PLAYER_HEAD); - SkullMeta meta = (SkullMeta) item.getItemMeta(); - if (meta == null) return item; - - String owner = victim instanceof Player ? victim.getName() : getValidSkullName(victim); - meta.setOwner(owner); - item.setItemMeta(meta); - } - - return item; - } - - @NotNull - public static String getValidSkullName(@NotNull Entity entity) { - return getValidSkullName(entity.getType()); - } - - @NotNull - public static String getValidSkullName(@NotNull EntityType type) { - switch (type) { - case MAGMA_CUBE: { - return "MHF_LavaSlime"; - } - case ELDER_GUARDIAN: { - return "MHF_EGuardian"; - } - case IRON_GOLEM: { - return "MHF_Golem"; - } - default: { - String s = type.name().toLowerCase().replace("_", " "); - return "MHF_" + StringUT.capitalizeFully(s).replace(" ", ""); - } - } - } -} diff --git a/src/main/java/studio/magemonkey/codex/util/InventoryUtil.java b/src/main/java/studio/magemonkey/codex/util/InventoryUtil.java deleted file mode 100644 index 23301b50..00000000 --- a/src/main/java/studio/magemonkey/codex/util/InventoryUtil.java +++ /dev/null @@ -1,155 +0,0 @@ -package studio.magemonkey.codex.util; - -import org.bukkit.event.inventory.InventoryEvent; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -public class InventoryUtil { - - /** - * In API versions 1.20.6 and earlier, InventoryView is a class. - * In versions 1.21 and later, it is an interface. - * This method uses reflection to get the top Inventory object from the - * InventoryView associated with an InventoryEvent, to avoid runtime errors. - * - * @param event The generic InventoryEvent with an InventoryView to inspect. - * @return The top Inventory object from the event's InventoryView. - */ - public static Inventory getTopInventory(InventoryEvent event) { - Object view = event.getView(); - return getTopInventory(view); - } - - public static Inventory getTopInventory(Object view) { - try { - Method getTopInventory = view.getClass().getMethod("getTopInventory"); - getTopInventory.setAccessible(true); - return (Inventory) getTopInventory.invoke(view); - } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) { - throw new RuntimeException(e); - } - } - - /** - * In API versions 1.20.6 and earlier, InventoryView is a class. - * In versions 1.21 and later, it is an interface. - * This method uses reflection to get the bottom Inventory object from the - * InventoryView associated with an InventoryEvent, to avoid runtime errors. - * - * @param event The generic InventoryEvent with an InventoryView to inspect. - * @return The bottom Inventory object from the event's InventoryView. - */ - public static Inventory getBottomInventory(InventoryEvent event) { - try { - Object view = event.getView(); - Method getBottomInventory = view.getClass().getMethod("getBottomInventory"); - getBottomInventory.setAccessible(true); - return (Inventory) getBottomInventory.invoke(view); - } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) { - throw new RuntimeException(e); - } - } - - /** - * In API versions 1.20.6 and earlier, InventoryView is a class. - * In versions 1.21 and later, it is an interface. - * This method uses reflection to set the cursor ItemStack in the - * InventoryView associated with an InventoryEvent, to avoid runtime errors. - * - * @param event The generic InventoryEvent with an InventoryView to modify. - * @param item The ItemStack to set as the cursor in the event's InventoryView. - */ - public static void setCursor(InventoryEvent event, ItemStack item) { - try { - Object view = event.getView(); - Method setCursor = view.getClass().getMethod("setCursor", ItemStack.class); - setCursor.setAccessible(true); - setCursor.invoke(view, item); - } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) { - throw new RuntimeException(e); - } - } - - public static void setItem(Object view, int slot, ItemStack item) { - try { - Method setItem = view.getClass().getMethod("setItem", int.class, ItemStack.class); - setItem.setAccessible(true); - setItem.invoke(view, slot, item); - } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) { - throw new RuntimeException(e); - } - } - - /** - * In API versions 1.20.6 and earlier, InventoryView is a class. - * In versions 1.21 and later, it is an interface. - * This method uses reflection to get the Inventory object from the - * InventoryView associated with an InventoryEvent, to avoid runtime errors. - * The slot parameter is used to determine which Inventory object to return. - * If the slot is in the top Inventory, the top Inventory is returned. - * If the slot is in the bottom Inventory, the bottom Inventory is returned. - * If the slot is not in either Inventory, null is returned. - * - * @param event The generic InventoryEvent with an InventoryView to inspect. - * @param slot The slot index to check in the InventoryView. - * @return The Inventory object from the event's InventoryView at the specified slot. - */ - public static Inventory getInventory(InventoryEvent event, int slot) { - try { - Object view = event.getView(); - Method getInventory = view.getClass().getMethod("getInventory", int.class); - getInventory.setAccessible(true); - return (Inventory) getInventory.invoke(view, slot); - } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) { - throw new RuntimeException(e); - } - } - - /** - * In API versions 1.20.6 and earlier, InventoryView is a class. - * In versions 1.21 and later, it is an interface. - * This method uses reflection to get the ItemStack at the specified slot - * in the InventoryView associated with an InventoryEvent, to avoid runtime errors. - * The slot parameter is used to determine which ItemStack to return. - * - * @param event The generic InventoryEvent with an InventoryView to inspect. - * @param slot The slot index to check in the InventoryView. - * @return The ItemStack from the event's InventoryView at the specified slot. - */ - public static ItemStack getItem(InventoryEvent event, int slot) { - try { - Object view = event.getView(); - Method getItem = view.getClass().getMethod("getItem", int.class); - getItem.setAccessible(true); - return (ItemStack) getItem.invoke(view, slot); - } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) { - throw new RuntimeException(e); - } - } - - /** - * In API versions 1.20.6 and earlier, InventoryView is a class. - * In versions 1.21 and later, it is an interface. - * This method uses reflection to convert the slot index from the - * InventoryView associated with an InventoryEvent, to avoid runtime errors. - * The slot parameter is used to determine which slot index to convert. - * - * @param event The generic InventoryEvent with an InventoryView to inspect. - * @param slot The slot index to convert in the InventoryView. - * @return The converted slot index from the event's InventoryView. - */ - public static int convertSlot(InventoryEvent event, int slot) { - try { - Object view = event.getView(); - Method convertSlot = view.getClass().getMethod("convertSlot", int.class); - convertSlot.setAccessible(true); - return (int) convertSlot.invoke(view, slot); - } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) { - throw new RuntimeException(e); - } - } - -} diff --git a/src/main/java/studio/magemonkey/codex/util/messages/MessageUtil.java b/src/main/java/studio/magemonkey/codex/util/messages/MessageUtil.java deleted file mode 100644 index 3ea2f854..00000000 --- a/src/main/java/studio/magemonkey/codex/util/messages/MessageUtil.java +++ /dev/null @@ -1,329 +0,0 @@ -package studio.magemonkey.codex.util.messages; - -import net.md_5.bungee.api.chat.BaseComponent; -import net.md_5.bungee.api.chat.TextComponent; -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.command.CommandSender; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.plugin.Plugin; -import org.jetbrains.annotations.NotNull; -import studio.magemonkey.codex.CodexEngine; -import studio.magemonkey.codex.bungee.BungeeUtil; -import studio.magemonkey.codex.legacy.placeholder.PlaceholderItem; -import studio.magemonkey.codex.legacy.placeholder.PlaceholderType; -import studio.magemonkey.codex.legacy.riseitem.DarkRiseItem; -import studio.magemonkey.codex.legacy.utils.ComponentUtils; -import studio.magemonkey.codex.util.ItemUtils; - -import java.util.*; -import java.util.regex.Pattern; -import java.util.stream.Collectors; - -public class MessageUtil { - public static Map messages = new HashMap<>(); - - public static void load(FileConfiguration config, Plugin plugin) { - reload(config, plugin); - } - - public static void reload(FileConfiguration config, Plugin plugin) { - Map temp = getMessages(config); - for (String s : temp.keySet()) { - messages.remove(s); - } - messages.putAll(temp); - CodexEngine.get().getLogger().info("Mapped all language data for " + plugin.getName() + "."); - } - - public static Map getMessages(@NotNull ConfigurationSection section) { - Map temp = new HashMap<>(); - - for (String entry : section.getValues(false).keySet()) { - String id = section.getCurrentPath().trim().isEmpty() ? entry : section.getCurrentPath() + "." + entry; - if (section.get(entry) instanceof ConfigurationSection) { - temp.putAll(getMessages((ConfigurationSection) section.get(entry))); - } else if (section.get(entry) instanceof ArrayList) { - temp.put(id, section.get(entry)); - } else { - if (section.get(entry).toString().contains("\n")) { - List array = new ArrayList<>(Arrays.asList(section.get(entry).toString().split("\n"))); - temp.put(id, array); - } else - temp.put(id, section.get(entry).toString()); - } - } - - return temp; - } - - public static void sendMessage(CommandSender player, BaseComponent... comps) { - List send = new ArrayList<>(); - for (BaseComponent component : comps) { - if (component instanceof TextComponent && ((TextComponent) component).getText().equalsIgnoreCase("\n")) { - player.spigot().sendMessage(send.toArray(new BaseComponent[0])); - send.clear(); - } else - send.add(component); - } - if (!send.isEmpty()) - player.spigot().sendMessage(send.toArray(new BaseComponent[0])); - } - - public static void sendMessage(String key, CommandSender player, MessageData... replace) { - BaseComponent[] comps = getMessageAsComponent(key, replace); - sendMessage(player, comps); - -/* for (String send : msgs) { - if (send.equalsIgnoreCase("false")) - continue; - boolean asComponent = false; - String toSend = send; - LinkedHashMap map = new LinkedHashMap<>(); - for (MessageData messageData : replace) { - String rep = getReplacement(messageData.getName()); - toSend = toSend.replace(rep, "=!=" + messageData.getName() + "=!="); - if (messageData.getObject() instanceof BaseComponent && send.contains(rep)) - asComponent = true; - - if (asComponent) - map.put(messageData.getName(), messageData.getObject()); - else - send = send.replace(rep, messageData.getObject().toString()); -// if (messageData.getObject() instanceof BaseComponent) { -// asComponent = true; -// base.addExtra((BaseComponent) messageData.getObject()); -// } else { -// if (asComponent) -// base.addExtra(send.replace(messageData.getName(), messageData.getObject().toString())); -// else -// send = send.replace(messageData.getName(), messageData.getObject().toString()); -// } - } - - ArrayList comps = new ArrayList<>(); - if (asComponent) { - for (String st : toSend.split("=!=")) { - if (map.get(st) == null) - continue; - if (map.get(st) instanceof BaseComponent) - comps.add((BaseComponent) map.get(st)); - else - comps.add(new TextComponent(map.get(st).toString())); - } - player.spigot().sendMessage(comps.toArray(new BaseComponent[0])); - } else - player.sendMessage(send); - }*/ - } - - public static List getString(String key) { - List ret = new ArrayList<>(); - if (!messages.containsKey(key)) { - ret.add(key); - return ret; - } - - - Object msg = messages.get(key); - if (msg == null) { - ret.add(key); - } else { - try { - ((List) msg).forEach(e -> ret.add(e)); - } catch (ClassCastException e) { - ret.add(msg.toString()); - } - } - - return ItemUtils.fixColors(ret); - } - - public static BaseComponent[] getMessageAsComponent(String path, MessageData... replace) { -// if (!messages.containsKey(path)) -// return new BaseComponent[]{new TextComponent(path)}; - - List components = new ArrayList<>(); - - List msgs = getString(path); - Map> placeholders = new HashMap<>(); - Map data = Arrays.stream(replace) - .collect(Collectors.toMap(MessageData::getName, messageData -> messageData, (a, b) -> b, HashMap::new)); - - Pattern pat = Pattern.compile("\\$<(.*?)>"); - msgs.stream().map(pat::matcher).forEach(mat -> { - while (mat.find()) { - PlaceholderItem it = PlaceholderType.getQualifiedItem(mat.group(1)); - if (it != null) { - String id = "$<" + mat.group(1) + ">"; - placeholders.put(id, it); - } - } - }); - - for (String send : msgs) { - if (send.equalsIgnoreCase("false")) - continue; - - BaseComponent[] comps = ComponentUtils.fromLegacyText(send); - for (BaseComponent component : comps) { - for (Map.Entry> entry : placeholders.entrySet()) { - PlaceholderItem holder = entry.getValue(); - String id = entry.getKey(); - if (!component.toPlainText().contains(id)) - continue; - Object translated = holder.apply(data.get(holder.getType().getId()).getObject(), null); - if (translated instanceof BaseComponent) - ComponentUtils.replace(component, id, (BaseComponent) translated); - else - ComponentUtils.replace(component, id, translated.toString()); - } - for (MessageData datum : replace) { - String check = "$<" + datum.getName() + ">"; - if (!component.toPlainText().contains(check)) - continue; - if (datum.getObject() instanceof BaseComponent) - ComponentUtils.replace(component, check, (BaseComponent) datum.getObject()); - else - ComponentUtils.replace(component, check, datum.getObject().toString()); - } - components.add(component); - } -// for (String st : RiseStringUtils.splitAround(send, placeholders.keySet())) { -// -// TextComponent component = new TextComponent(st); -// -// for (Map.Entry> entry : placeholders.entrySet()) { -// PlaceholderItem holder = entry.getValue(); -// String id = entry.getKey(); -// if (!component.toPlainText().contains(id)) -// continue; -// -// Object translated = holder.apply(data.get(holder.getType().getId()).getObject(), null); -// -// if (translated instanceof BaseComponent) -// ComponentUtils.replace(component, id, (BaseComponent) translated); -// else -// ComponentUtils.replace(component, id, translated.toString()); -// } -// -// for (MessageData datum : replace) { -// String check = "$<" + datum.getName() + ">"; -// if (!component.toPlainText().contains(check)) -// continue; -// -// if (datum.getObject() instanceof BaseComponent) -// ComponentUtils.replace(component, check, (BaseComponent) datum.getObject()); -// else -// ComponentUtils.replace(component, check, datum.getObject().toString()); -// } -// components.add(component); -// } - if (msgs.size() > 1) - components.add(new TextComponent("\n")); - } - - return components.toArray(new BaseComponent[0]); - - -// String send = ItemUtils.fixColors(messages.get(path).toString()); -// ArrayList ret = new ArrayList<>(); -// HashMap rs = new HashMap<>(); -// -// for (MessageData datum : data) { -// if (datum.getName().equalsIgnoreCase("item")) { -// TextComponent comp = new TextComponent(((DarkRiseItem) datum.getObject()).getName());//.getItemMeta().getDisplayName()); -// comp.setHoverEvent(NMSPlayerUtils.convert(((DarkRiseItem) datum.getObject()).getItem())); -// rs.put("$", comp); -// rs.put("$", new TextComponent(((DarkRiseItem) datum.getObject()).getId())); -// } else { -// rs.put(getReplacement(datum.getName()), new TextComponent(String.valueOf(datum.getObject()))); -// } -// } -// -// String[] builder = new String[]{send}; -// for (String replace : rs.keySet()) { -// builder = RiseStringUtils.splitAround(builder, replace); -// } - - // ArrayList builder = new ArrayList<>(); - // String[] split = {send}; - // for (String replace : rs.keySet()) { - // System.out.println("Checking for \"" + replace + "\""); - // for (int j = 0; j < split.length; j++) { - // String pre = split[j]; - // String[] post = pre.split(replace); - // if (post.length > 1) { - // for (int i = 0; i < post.length; i++) { - // String sp = post[i]; - // builder.add(sp); - // if (i + 1 < post.length) - // builder.add(replace); - // } - // split = builder.toArray(split); - // builder.clear(); - // } - // } - // System.out.println(StringUtils.join(split, ", ")); - // } - -// for (String sp : builder) { -// if (rs.keySet().contains(sp)) { -// ret.add(rs.get(sp)); -// } else -// ret.add(new TextComponent(sp)); -// } -// -// return ret.toArray(new BaseComponent[0]); - } - - public static String getMessageAsString(String path, final String def, MessageData... data) { - return getMessageAsString(path, def, false, data); - } - - public static String getMessageAsString(String path, final String def, boolean stripColor, MessageData... data) { - if (!messages.containsKey(path)) - path = def; - BaseComponent[] strs = getMessageAsComponent(path, data); - - StringBuilder bob = new StringBuilder(); - - for (BaseComponent str : strs) { - bob.append(str.toLegacyText()); - } - - return stripColor ? ChatColor.stripColor(bob.toString()) : bob.toString(); - } - - - public static String getReplacement(String string) { - string = "$<" + string + ">"; - - return string; - } - - private static MessageData[] translateSpecial(MessageData... data) { - List rep = new ArrayList<>(); - for (MessageData md : data) { - if (md.getName().equalsIgnoreCase("item")) { - DarkRiseItem it = (DarkRiseItem) md.getObject(); - rep.add(new MessageData("riseItem.name", it.getName())); - rep.add(new MessageData("riseItem.id", it.getId())); - } else - rep.add(md); - } - - return rep.toArray(new MessageData[0]); - } - - public static void broadcastMessage(String key, MessageData... data) { - Bukkit.getServer().getOnlinePlayers().forEach(online -> sendMessage(key, online, data)); - sendMessage(key, Bukkit.getConsoleSender(), data); - } - - public static void broadcastNetworkMessage(String key, MessageData... data) { - if (!CodexEngine.IS_BUNGEE) broadcastMessage(key, data); - else BungeeUtil.broadcastMessage(getMessageAsString(key, key, false, data)); - } -} diff --git a/src/main/java/studio/magemonkey/codex/util/messages/NMSPlayerUtils.java b/src/main/java/studio/magemonkey/codex/util/messages/NMSPlayerUtils.java deleted file mode 100644 index cfbe0430..00000000 --- a/src/main/java/studio/magemonkey/codex/util/messages/NMSPlayerUtils.java +++ /dev/null @@ -1,77 +0,0 @@ -package studio.magemonkey.codex.util.messages; - -import net.md_5.bungee.api.ChatMessageType; -import net.md_5.bungee.api.chat.BaseComponent; -import net.md_5.bungee.api.chat.HoverEvent; -import net.md_5.bungee.api.chat.HoverEvent.Action; -import net.md_5.bungee.api.chat.ItemTag; -import net.md_5.bungee.api.chat.TextComponent; -import net.md_5.bungee.api.chat.hover.content.Item; -import net.md_5.bungee.api.chat.hover.content.Text; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import studio.magemonkey.codex.legacy.utils.ReflectionUtil; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Collections; - -public class NMSPlayerUtils { - - - /** - * Convert an item to a NBTTagCompound and get the HoverEvent from it - * - * @param itemStack The {@link ItemStack} to convert - * @return a {@link HoverEvent} object representing the item - */ - public static HoverEvent convert(ItemStack itemStack) { - try { //Use reflection for version independence. - Class cItemClass = ReflectionUtil.getBukkitClass("inventory.CraftItemStack"); - Method asNMSCopy = cItemClass.getMethod("asNMSCopy", ItemStack.class); - Object cItem = asNMSCopy.invoke(cItemClass, itemStack); - Object tagCompound; - if (ReflectionUtil.MINOR_VERSION >= 19) - tagCompound = cItem.getClass().getMethod("u").invoke(cItem); - else if (ReflectionUtil.MINOR_VERSION >= 18) - //Save method in 1.18 - tagCompound = cItem.getClass().getMethod("t").invoke(cItem); - else - tagCompound = cItem.getClass().getMethod("getTag").invoke(cItem); - - String tagString = tagCompound != null ? tagCompound.toString() : "{}"; - - if (ReflectionUtil.MINOR_VERSION >= 18) - return new HoverEvent( - Action.SHOW_ITEM, - new Item(itemStack.getType().getKey().getKey(), itemStack.getAmount(), ItemTag.ofNbt(tagString)) - ); - else - return new HoverEvent( - Action.SHOW_ITEM, - new ArrayList(Collections.singletonList(new Text(new BaseComponent[]{new TextComponent(tagString)}))) - ); - } catch (IllegalAccessException | ClassNotFoundException | NoSuchMethodException | - InvocationTargetException e) { - e.printStackTrace(); - } - return null; - //return new HoverEvent(Action.SHOW_ITEM, new BaseComponent[]{new TextComponent(CraftItemStack.asNMSCopy(itemStack).save(new NBTTagCompound()).toString())}); - } - - public void sendMessage(BaseComponent[] msg, ChatMessageType chatPosition, Player player) { - player.spigot().sendMessage(chatPosition, msg); -// try { -// Class cpClass = ReflectionUtil.getBukkitClass("entity.CraftPlayer"); -// Class pcktClass = ReflectionUtil.getNMSClass("PacketPlayOutChat"); -// Constructor pcktCtor = pcktClass.getConstructor() -// } catch (ClassNotFoundException e) { -// e.printStackTrace(); -// } -// CraftPlayer p = (CraftPlayer) player; -// PacketPlayOutChat packet = new PacketPlayOutChat(null, ChatMessageType.a((byte) chatPosition.ordinal())); -// packet.components = msg; -// p.getHandle().playerConnection.sendPacket(packet); - } -} \ No newline at end of file diff --git a/src/main/java/studio/magemonkey/codex/util/reflection/DefaultReflectionUtil.java b/src/main/java/studio/magemonkey/codex/util/reflection/DefaultReflectionUtil.java deleted file mode 100644 index fc7e7701..00000000 --- a/src/main/java/studio/magemonkey/codex/util/reflection/DefaultReflectionUtil.java +++ /dev/null @@ -1,467 +0,0 @@ -package studio.magemonkey.codex.util.reflection; - -import com.google.common.collect.Multimap; -import com.mojang.authlib.GameProfile; -import io.netty.channel.Channel; -import org.bukkit.Location; -import org.bukkit.World; -import org.bukkit.block.Block; -import org.bukkit.block.Chest; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import studio.magemonkey.codex.CodexEngine; -import studio.magemonkey.codex.util.Reflex; -import studio.magemonkey.codex.util.random.Rnd; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Method; -import java.util.Collection; -import java.util.Random; - -public class DefaultReflectionUtil implements ReflectionUtil { - - @Override - public Object newNBTTagCompound() { - try { - Class nbtTagClass = getNMSClass("NBTTagCompound"); - return nbtTagClass.getConstructor().newInstance(); - } catch (Exception e) { - e.printStackTrace(); - } - return null; - } - - @Override - public Object newNBTTagList() { - try { - Class nbtTagClass = getNMSClass("NBTTagList"); - return nbtTagClass.getConstructor().newInstance(); - } catch (Exception e) { - e.printStackTrace(); - } - - return null; - } - - @Override - public ItemStack toBukkitCopy(Object nmsItem) { - try { - Class craftItem = getCraftClass("inventory.CraftItemStack"); - Method asBukkitCopy = Reflex.getMethod(craftItem, "asBukkitCopy", getNMSClass("ItemStack")); - if (asBukkitCopy == null) return null; - - return (ItemStack) Reflex.invokeMethod(asBukkitCopy, null, nmsItem); - } catch (Exception e) { - e.printStackTrace(); - } - - return null; - } - - @Override - public Object save(Object nmsItem, Object nbtCompound) { - try { - Method save = Reflex.getMethod(nmsItem.getClass(), - "save", - nbtCompound.getClass()); - - return Reflex.invokeMethod(save, nmsItem, nbtCompound); - } catch (Exception e) { - e.printStackTrace(); - } - - return null; - } - - @Override - public Object getConnection(Player player) { - try { - Class craftPlayerClass = getCraftClass("entity.CraftPlayer"); - - Method getHandle = Reflex.getMethod(craftPlayerClass, "getHandle"); - Object nmsPlayer = Reflex.invokeMethod(getHandle, getCraftPlayer(player)); - - Object con = Reflex.getFieldValue(nmsPlayer, "playerConnection"); - return con; - } catch (Exception e) { - e.printStackTrace(); - } - - return null; - } - - @Override - public Object getEntity(Object craftEntity) { - try { - Class craftClass = getNMSClass("Entity"); - - Method getHandle = Reflex.getMethod(craftClass, "getHandle"); - - return craftClass.cast(getHandle.invoke(craftEntity)); - } catch (Exception e) { - e.printStackTrace(); - } - - return null; - } - - @Override - public Channel getChannel(Player p) { - try { - Object conn = getConnection(p); - Object manager = Reflex.getFieldValue(conn, "networkManager"); - Channel channel = (Channel) Reflex.getFieldValue(manager, "channel"); - - return channel; - } catch (Exception e) { - e.printStackTrace(); - } - - return null; - } - - @Override - public void sendPacket(Player p, Object packet) { - Object conn = getConnection(p); - Class packetClass = null; - try { - packetClass = getNMSClass("Packet"); - } catch (ClassNotFoundException e) { - e.printStackTrace(); - } - Method sendMethod = Reflex.getMethod(conn.getClass(), "sendPacket", packetClass); - Reflex.invokeMethod(sendMethod, conn, packet); - } - - @Override - public void sendAttackPacket(Player p, int id) { - try { - Object craftPlayer = getCraftPlayer(p); - Object entity = getEntity(craftPlayer); - - Class packetClass = getNMSClass("PacketPlayOutAnimation"); - Constructor ctor = Reflex.getConstructor(packetClass, entity.getClass(), int.class); - Object packet = Reflex.invokeConstructor(ctor, entity, id); - - sendPacket(p, packet); - } catch (ClassNotFoundException e) { - CodexEngine.get().getLogger().warning("Could not send attack packet."); - e.printStackTrace(); - } - } - - @Override - public void openChestAnimation(Block chest, boolean open) { - if (chest.getState() instanceof Chest) { - Location lo = chest.getLocation(); - World bWorld = lo.getWorld(); - if (bWorld == null) return; - - try { - Class worldClass = getNMSClass("World"); - Class craftWorld = getCraftClass("CraftWorld"); - Class blockClass = getNMSClass("Block"); - Class blockPosClass = getNMSClass("BlockPosition"); - - Object nmsWorld = worldClass.cast(bWorld); - Method getHandle = ReflectionManager.MINOR_VERSION >= 8 - ? Reflex.getMethod(nmsWorld.getClass(), "getWorld") - : Reflex.getMethod(nmsWorld.getClass(), "getHandle"); - - Object world = craftWorld.cast(Reflex.invokeMethod(getHandle, nmsWorld)); - Method playBlockAction = Reflex.getMethod(craftWorld, - "playBlockAction", - blockPosClass, - blockClass, - int.class, - int.class); - - Constructor ctor = Reflex.getConstructor(blockPosClass, double.class, double.class, double.class); - Object position = Reflex.invokeConstructor(ctor, lo.getX(), lo.getY(), lo.getZ()); - - Method getType = Reflex.getMethod(world.getClass(), "getType", blockPosClass); - Class blockData = getNMSClass("IBlockData"); - Object data = blockData.cast(Reflex.invokeMethod(getType, world, position)); - - Method getBlock = Reflex.getMethod(blockData, "getBlock"); - - //TileEntityChest tileChest = (TileEntityChest) world.getTileEntity(position); - Reflex.invokeMethod(playBlockAction, world, position, getBlock.invoke(data), 1, open ? 1 : 0); - } catch (Exception e) { - CodexEngine.get().getLogger().warning("Problem sending chest animation"); - e.printStackTrace(); - } - } - } - - @Override - public ItemStack damageItem(@NotNull ItemStack item, int amount, @Nullable Player player) { - try { - Object nmsStack = getNMSCopy(item); - - Object nmsPlayer = player != null ? getEntity(getCraftPlayer(player)) : null; - - Method isDamaged = - Reflex.getMethod(nmsStack.getClass(), "a", int.class, Random.class, getNMSClass("EntityPlayer")); - - Reflex.invokeMethod(isDamaged, nmsStack, amount, Rnd.rnd, nmsPlayer); - - return toBukkitCopy(nmsStack); - } catch (Exception e) { - e.printStackTrace(); - } - - return null; - } - - @Override - public Multimap getAttributes(@NotNull ItemStack itemStack) { - try { - Object nmsItem = getNMSCopy(itemStack); - Method getItem = Reflex.getMethod(nmsItem.getClass(), - ReflectionManager.MINOR_VERSION > 17 ? "c" : "getItem"); - Object item = Reflex.invokeMethod(getItem, nmsItem); - - - Class enumItemSlotClass = (Class) ( - getNMSClass("EnumItemSlot")); - Class itemArmorClass = getNMSClass("ItemArmor"); - Class itemToolClass = getNMSClass("ItemTool"); - Class itemSwordClass = getNMSClass("ItemSword"); - Class itemTridentClass = getNMSClass("ItemTrident"); - - Enum mainhand = (Enum) Reflex.invokeMethod( - Reflex.getMethod(enumItemSlotClass, - "fromName", - String.class), - null, "mainhand"); - - if (itemArmorClass.isInstance(item)) { - Object tool = itemArmorClass.cast(item); - Method b = Reflex.getMethod(itemArmorClass, "b"); - Object bObj = Reflex.invokeMethod(b, tool); - Method a = Reflex.getMethod(itemArmorClass, "a", enumItemSlotClass); - - return (Multimap) Reflex.invokeMethod(a, tool, bObj); - } - - Object tool; - Method a; - if (itemToolClass.isInstance(item)) { - tool = itemToolClass.cast(item); - a = Reflex.getMethod(itemToolClass, "a", enumItemSlotClass); - } else if (itemSwordClass.isInstance(item)) { - tool = itemSwordClass.cast(item); - a = Reflex.getMethod(itemSwordClass, "a", enumItemSlotClass); - } else if (itemTridentClass.isInstance(item)) { - tool = itemTridentClass.cast(item); - a = Reflex.getMethod(itemTridentClass, "a", enumItemSlotClass); - } else { - return null; - } - - return (Multimap) Reflex.invokeMethod(a, tool, mainhand); - } catch (Exception e) { - e.printStackTrace(); - } - - return null; - } - - @Override - public double getAttributeValue(@NotNull ItemStack item, @NotNull Object attribute) { - double value = 0; - try { - Class attributeModifierClass = getNMSClass("AttributeModifier"); - if (attribute.getClass().getSuperclass().getSimpleName().equals("IAttribute")) { - Class iAttributeClass = getNMSClass("IAttribute"); - Multimap attMap = getAttributes(item); - if (attMap == null) return 0D; - Object atkDmg = iAttributeClass.cast(attribute); - Method getName = Reflex.getMethod(iAttributeClass, "getName"); - - //Collection - Collection att = attMap.get(Reflex.invokeMethod(getName, atkDmg)); - Object mod = attributeModifierClass.cast((att == null || att.isEmpty()) - ? 0 - : att.stream().findFirst().get()); - - Method getAmount = Reflex.getMethod(attributeModifierClass, "getAmount"); - value = (double) Reflex.invokeMethod(getAmount, mod); - } else if (getNMSClass("AttributeBase").isInstance(attribute)) { - Class attributeBaseClass = getNMSClass("AttributeBase"); - Multimap attMap = getAttributes(item); - if (attMap == null) return 0D; - - Collection att = attMap.get(attributeBaseClass.cast(attribute)); - Object mod = att != null && !att.isEmpty() - ? attributeModifierClass.cast(att.stream().findFirst().get()) - : null; - - if (mod != null) { - Method getAmount = Reflex.getMethod(attributeModifierClass, "getAmount"); - value = (double) Reflex.invokeMethod(getAmount, mod); - } else value = 0; - } - if (attribute.equals(getGenericAttribute("ATTACK_DAMAGE"))) { - value += 1; - } else if (attribute.equals(getGenericAttribute("ATTACK_SPEED"))) { - value += 4; - } - } catch (Exception e) { - e.printStackTrace(); - } - - return value; - } - - @Override - public double getDefaultDamage(@NotNull ItemStack itemStack) { - return getAttributeValue(itemStack, getGenericAttribute("ATTACK_DAMAGE")); - } - - @Override - public double getDefaultSpeed(@NotNull ItemStack itemStack) { - return getAttributeValue(itemStack, getGenericAttribute("ATTACK_SPEED")); - } - - @Override - public double getDefaultArmor(@NotNull ItemStack itemStack) { - return getAttributeValue(itemStack, getGenericAttribute("ARMOR")); - } - - @Override - public double getDefaultToughness(@NotNull ItemStack itemStack) { - return getAttributeValue(itemStack, getGenericAttribute("ARMOR_TOUGHNESS")); - } - - @Override - public Object getGenericAttribute(String field) { - try { - Class attributes = getNMSClass("GenericAttributes"); - Object value = Reflex.getField(attributes, field).get(null); - - //AttributeBase or IAttribute - return value; - } catch (Exception e) { - e.printStackTrace(); - } - - return null; - } - - @Override - public boolean isWeapon(@NotNull ItemStack itemStack) { - try { - Object nmsItem = getNMSCopy(itemStack); - - Method getItem = Reflex.getMethod(nmsItem.getClass(), "getItem"); - - Object item = Reflex.invokeMethod(getItem, nmsItem); - - Class swordClass = getNMSClass("ItemSword"); - Class axeClass = getNMSClass("ItemAxe"); - Class tridentClass = getNMSClass("ItemTrident"); - - return swordClass.isInstance(item) || axeClass.isInstance(item) || tridentClass.isInstance(item); - } catch (Exception e) { - e.printStackTrace(); - } - return false; - } - - @Override - public boolean isTool(@NotNull ItemStack itemStack) { - try { - Object nmsItem = getNMSCopy(itemStack); - - Method getItem = Reflex.getMethod(nmsItem.getClass(), "getItem"); - - Object item = Reflex.invokeMethod(getItem, nmsItem); - - Class toolClass = getNMSClass("ItemTool"); - - return toolClass.isInstance(item); - } catch (Exception e) { - e.printStackTrace(); - } - return false; - } - - @Override - public boolean isArmor(@NotNull ItemStack itemStack) { - try { - Object nmsItem = getNMSCopy(itemStack); - - Method getItem = Reflex.getMethod(nmsItem.getClass(), "getItem"); - - Object item = Reflex.invokeMethod(getItem, nmsItem); - - Class toolClass = getNMSClass("ItemArmor"); - - return toolClass.isInstance(item); - } catch (Exception e) { - e.printStackTrace(); - } - return false; - } - - @Override - public String fixColors(@NotNull String str) { - try { - str = str.replace("\n", "%n%"); // CraftChatMessage wipes all lines out. - - Class baseComponentClass; - try { - baseComponentClass = getNMSClass("IChatBaseComponent"); - } catch (ClassNotFoundException e) { - baseComponentClass = Reflex.getClass("net.minecraft.network.chat", "IChatBaseComponent"); - } - Class chatMessageClass = getCraftClass("util.CraftChatMessage"); - - Method fromComponent = Reflex.getMethod(chatMessageClass, "fromComponent", baseComponentClass); - Method fromStringOrNull = Reflex.getMethod(chatMessageClass, "fromStringOrNull", String.class); - - Object baseComponent = Reflex.invokeMethod(fromStringOrNull, null, str); - String singleColor = - (String) Reflex.invokeMethod(fromComponent, null, baseComponentClass.cast(baseComponent)); - return singleColor.replace("%n%", "\n"); - } catch (Exception e) { - e.printStackTrace(); - } - - return str; - } - - @Override - public void changeSkull(Block b, String hash) { - try { - Class tileSkullClass = getNMSClass("TileEntitySkull"); - Class craftWorldClass = getCraftClass("CraftWorld"); -// Class worldServerClass = getNMSClass("WorldServer"); - Class blockAccessClass = getNMSClass("IBlockAccess"); - Class blockPosClass = getNMSClass("BlockPosition"); - - Constructor ctor = Reflex.getConstructor(blockPosClass, int.class, int.class, int.class); - - Method getHandle = Reflex.getMethod(craftWorldClass, "getHandle"); - Method getTileEntity = Reflex.getMethod(blockAccessClass, "getTileEntity", blockPosClass); - - Object bPos = Reflex.invokeConstructor(ctor, b.getX(), b.getY(), b.getZ()); - - Object worldServer = Reflex.invokeMethod(getHandle, craftWorldClass.cast(b.getWorld())); - Object skullTile = tileSkullClass.cast(Reflex.invokeMethod(getTileEntity, worldServer, bPos)); - - - Method setGameProfile = Reflex.getMethod(tileSkullClass, "setGameProfile", GameProfile.class); - - Reflex.invokeMethod(setGameProfile, skullTile, getNonPlayerProfile(hash)); - b.getState().update(true); - } catch (Exception e) { - CodexEngine.get().getLogger().warning("Could not update skull"); - e.printStackTrace(); - } - } -} diff --git a/src/main/java/studio/magemonkey/codex/util/reflection/ReflectionManager.java b/src/main/java/studio/magemonkey/codex/util/reflection/ReflectionManager.java deleted file mode 100644 index e7f9ed72..00000000 --- a/src/main/java/studio/magemonkey/codex/util/reflection/ReflectionManager.java +++ /dev/null @@ -1,33 +0,0 @@ -package studio.magemonkey.codex.util.reflection; - -import org.bukkit.Bukkit; -import studio.magemonkey.codex.core.Version; - -public class ReflectionManager { - - public static final String VERSION = - Bukkit.getServer().getClass().getPackage().getName().contains("mockbukkit") ? "testing_19" - : (Integer.parseInt(Bukkit.getServer().getBukkitVersion().split("[.-]")[1]) < 20 - ? Bukkit.getServer() - .getClass() - .getPackage() - .getName() - .replace(".", ",") - .split(",")[3] : Bukkit.getServer().getBukkitVersion().split("-")[0].replace(".", "_")); - public static final int MINOR_VERSION = Integer.parseInt(VERSION.split("_")[1]); - private static ReflectionUtil reflection; - - public static ReflectionUtil getReflectionUtil() { - if (reflection != null) return reflection; - - switch (Version.CURRENT) { - case V1_17_R1 -> reflection = new Reflection_1_17(); - case V1_18_R1, V1_18_R2, V1_19_R1, V1_19_R2, V1_19_R3 -> reflection = new Reflection_1_18(); - case V1_20_R1, V1_20_R2, V1_20_R3, V1_20_R4, V1_21_R1, V1_21_R2 -> reflection = new Reflection_1_20(); - default -> reflection = new DefaultReflectionUtil(); - } - - return reflection; - } - -} diff --git a/src/main/java/studio/magemonkey/codex/util/reflection/ReflectionUtil.java b/src/main/java/studio/magemonkey/codex/util/reflection/ReflectionUtil.java deleted file mode 100644 index 2c695811..00000000 --- a/src/main/java/studio/magemonkey/codex/util/reflection/ReflectionUtil.java +++ /dev/null @@ -1,229 +0,0 @@ -package studio.magemonkey.codex.util.reflection; - -import com.google.common.collect.Multimap; -import com.mojang.authlib.GameProfile; -import com.mojang.authlib.properties.Property; -import io.netty.channel.Channel; -import org.bukkit.Bukkit; -import org.bukkit.block.Block; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import studio.magemonkey.codex.CodexEngine; -import studio.magemonkey.codex.core.Version; -import studio.magemonkey.codex.util.Reflex; - -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.Collection; -import java.util.UUID; - -public interface ReflectionUtil { - - Object newNBTTagCompound(); - - Object newNBTTagList(); - - default Object getNMSCopy(ItemStack item) { - try { - Class craftItemClass = getCraftClass("inventory.CraftItemStack"); - Method asNMSCopy = Reflex.getMethod(craftItemClass, "asNMSCopy", ItemStack.class); - - return Reflex.invokeMethod(asNMSCopy, null, item); - } catch (Exception e) { - e.printStackTrace(); - } - - return null; - } - - ItemStack toBukkitCopy(Object nmsItem); - - Object save(Object nmsItem, Object nbtCompound); - - default Class getNMSClass(String nmsClassName) throws ClassNotFoundException { - String version = ReflectionManager.VERSION + "."; - String name = "net.minecraft.server." + version + nmsClassName; - Class nmsClass = Class.forName(name); - return nmsClass; - } - - default Class getCraftClass(String craftClassName) throws ClassNotFoundException { - String pkg = - Bukkit.getServer().getClass().getPackage().getName(); - String name = pkg + "." + craftClassName; - Class craftClass = Class.forName(name); - return craftClass; - } - - Object getConnection(Player player); - - default Object getCraftPlayer(Player player) { - try { - Class craftClass = getCraftClass("entity.CraftPlayer"); - return craftClass.cast(player); - } catch (Exception e) { - e.printStackTrace(); - } - - return null; - } - - Object getEntity(Object craftEntity); - - Channel getChannel(Player player); - - default void sendPackets(Player player, Collection packets) { - for (Object packet : packets) { - sendPacket(player, packet); - } - } - - void sendPacket(Player player, Object packet); - - void sendAttackPacket(Player player, int id); - - void openChestAnimation(Block chest, boolean open); - - default String getNbtString(@NotNull ItemStack item) { - try { - Object nmsCopy = getNMSCopy(item); - Method getOrCreateTag = Reflex.getMethod(nmsCopy.getClass(), "getOrCreateTag"); - Object tag = Reflex.invokeMethod(getOrCreateTag, nmsCopy); - Method asString = Reflex.getMethod(tag.getClass(), "asString"); - return (String) Reflex.invokeMethod(asString, tag); - } catch (Exception e) { - e.printStackTrace(); - } - - return null; - } - - ItemStack damageItem(@NotNull ItemStack item, int amount, @Nullable Player player); - - Multimap getAttributes(@NotNull ItemStack item); - - double getAttributeValue(@NotNull ItemStack item, @NotNull Object attribute); - - double getDefaultDamage(@NotNull ItemStack item); - - double getDefaultSpeed(@NotNull ItemStack item); - - double getDefaultArmor(@NotNull ItemStack item); - - double getDefaultToughness(@NotNull ItemStack item); - - Object getGenericAttribute(String field); - - boolean isWeapon(@NotNull ItemStack item); - - boolean isTool(@NotNull ItemStack item); - - boolean isArmor(@NotNull ItemStack item); - - String fixColors(@NotNull String str); - - void changeSkull(Block b, String hash); - - default GameProfile getNonPlayerProfile(String hash) { - UUID uid = UUID.randomUUID(); - GameProfile profile = new GameProfile(uid, uid.toString().substring(0, 8)); - profile.getProperties().put("textures", new Property("textures", hash)); - - return profile; - } - - default void setKiller(LivingEntity entity, Player player) { - try { - Class living = - ReflectionManager.MINOR_VERSION >= 17 ? Reflex.getClass("net.minecraft.world.entity.EntityLiving") - : Reflex.getNMSClass("EntityLiving"); - Method handle = Reflex.getCraftClass("entity.CraftEntity").getDeclaredMethod("getHandle"); - Field killer = living.getDeclaredField(getKillerField()); - Field damageTime = living.getDeclaredField(getDamageTimeField()); - - killer.setAccessible(true); - damageTime.setAccessible(true); - - Object hit = handle.invoke(entity); - Object source = handle.invoke(player); - killer.set(hit, source); - damageTime.set(hit, 100); - } catch (Exception e) { - CodexEngine.get().error("Could not set killer."); - e.printStackTrace(); - } - } - - // ServerCommonPacketListenerImpl, find the NetworkManager variable - default String getNetworkManagerFieldName() { - return switch (Version.CURRENT) { - case V1_16_R3 -> "networkManager"; - case V1_17_R1, V1_18_R1, V1_18_R2 -> "a"; - case V1_19_R1, V1_19_R2 -> "b"; - case V1_20_R2, V1_20_R3 -> "c"; - case V1_20_R4, V1_21_R1, V1_21_R2 -> "e"; - default -> "h"; - }; - } - - // NetworkManager, find the Channel variable - default String getChannelFieldName() { - return switch (Version.CURRENT) { - case V1_16_R3 -> "channel"; - case V1_17_R1, V1_18_R1 -> "k"; - case V1_20_R2, V1_20_R3, V1_20_R4, V1_21_R1, V1_21_R2 -> "n"; - default -> "m"; - }; - } - - // EntityPlayer, the method signature should look something like - // public int F() { return this.de; } - default String getAttackCooldownMethodName() { - return switch (Version.CURRENT) { - case V1_16_R3, V1_17_R1 -> "getAttackCooldown"; - case V1_18_R1, V1_18_R2, V1_19_R1 -> "v"; - case V1_19_R2 -> "w"; - case V1_19_R3 -> "z"; - case V1_20_R2, V1_20_R3 -> "B"; - case V1_20_R4 -> "D"; - case V1_21_R1, V1_21_R2 -> "F"; - default -> "A"; - }; - } - - // EntityLiving, look for @Nullable EntityHuman field (somewhere around bc) - default String getKillerField() { - return switch (Version.CURRENT) { - case V1_16_R3 -> "killer"; - case V1_17_R1, V1_18_R1, V1_18_R2, V1_19_R1, V1_19_R2, V1_20_R4, V1_21_R1, V1_21_R2 -> "bc"; - case V1_19_R3 -> "aX"; - case V1_20_R2, V1_20_R3 -> "aY"; - default -> "aZ"; - }; - } - - // EntityLiving, should be RIGHT after the killer field - default String getDamageTimeField() { - return switch (Version.CURRENT) { - case V1_16_R3 -> "lastDamageByPlayerTime"; - case V1_17_R1, V1_18_R1, V1_18_R2, V1_19_R1, V1_19_R2, V1_20_R4, V1_21_R1, V1_21_R2 -> "bd"; - case V1_19_R3 -> "aY"; - case V1_20_R2, V1_20_R3 -> "aZ"; - default -> "ba"; - }; - } - - default String getRegistryAccessMethodName() { - // Really not verified... thanks Copilot :3 - return switch (Version.CURRENT) { - case V1_16_R3 -> "getServer"; - case V1_17_R1, V1_18_R1, V1_18_R2, V1_19_R1, V1_19_R2, V1_19_R3, V1_20_R1, V1_20_R2, V1_20_R3, V1_20_R4, - V1_21_R1 -> "bc"; - case V1_21_R2 -> "ba"; - default -> "b"; - }; - } -} diff --git a/src/main/java/studio/magemonkey/codex/util/reflection/Reflection_1_17.java b/src/main/java/studio/magemonkey/codex/util/reflection/Reflection_1_17.java deleted file mode 100644 index 2661f896..00000000 --- a/src/main/java/studio/magemonkey/codex/util/reflection/Reflection_1_17.java +++ /dev/null @@ -1,537 +0,0 @@ -package studio.magemonkey.codex.util.reflection; - -import com.google.common.collect.Multimap; -import com.google.gson.Gson; -import com.google.gson.JsonObject; -import com.mojang.authlib.GameProfile; -import io.netty.channel.Channel; -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.World; -import org.bukkit.block.Block; -import org.bukkit.block.Chest; -import org.bukkit.block.Skull; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.bukkit.profile.PlayerProfile; -import org.bukkit.profile.PlayerTextures; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import studio.magemonkey.codex.CodexEngine; -import studio.magemonkey.codex.core.Version; -import studio.magemonkey.codex.util.Reflex; -import studio.magemonkey.codex.util.random.Rnd; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Method; -import java.net.URL; -import java.util.Collection; -import java.util.Random; -import java.util.UUID; - -public class Reflection_1_17 implements ReflectionUtil { - private static final String DAMAGE_ATTRIBUTE = "f"; - private static final String SPEED_ATTRIBUTE = "h"; - private static final String ARMOR_ATTRIBUTE = "i"; - private static final String TOUGHNESS_ATTRIBUTE = "j"; - - @Override - public Object newNBTTagCompound() { - try { - Class nbtTagClass = getClazz("net.minecraft.nbt.NBTTagCompound"); - return nbtTagClass.getConstructor().newInstance(); - } catch (Exception e) { - e.printStackTrace(); - } - return null; - } - - @Override - public Object newNBTTagList() { - try { - Class nbtTagClass = getClazz("net.minecraft.nbt.NBTTagList"); - return nbtTagClass.getConstructor().newInstance(); - } catch (Exception e) { - e.printStackTrace(); - } - - return null; - } - - @Override - public ItemStack toBukkitCopy(Object nmsItem) { - try { - Class craftItem = getCraftClass("inventory.CraftItemStack"); - Method asBukkitCopy = - Reflex.getMethod(craftItem, "asBukkitCopy", getClazz("net.minecraft.world.item.ItemStack")); - if (asBukkitCopy == null) return null; - - return (ItemStack) Reflex.invokeMethod(asBukkitCopy, null, nmsItem); - } catch (Exception e) { - e.printStackTrace(); - } - - return null; - } - - @Override - public Object save(Object nmsItem, Object nbtCompound) { - try { - Method save = Reflex.getMethod(nmsItem.getClass(), "save", nbtCompound.getClass()); - - return Reflex.invokeMethod(save, nmsItem, nbtCompound); - } catch (Exception e) { - e.printStackTrace(); - } - - return null; - } - - public Class getClazz(String classString) throws ClassNotFoundException { - String name = classString; - Class clazz = Class.forName(name); - return clazz; - } - - @Override - public Object getEntity(Object craftEntity) { - try { - Class craftClass = getClazz("net.minecraft.world.entity.Entity"); - Class craftEntityClass = getCraftClass("org.bukkit.entity.Entity"); - - Method getHandle = Reflex.getMethod(craftEntityClass, "getHandle"); - - return craftClass.cast(getHandle.invoke(craftEntity)); - } catch (Exception e) { - e.printStackTrace(); - } - - return null; - } - - @Override - public Channel getChannel(Player p) { - String managerFieldName = getNetworkManagerFieldName(); - String channelFieldName = getChannelFieldName(); - Object conn = null, - manager = null, - channel = null; - try { - conn = getConnection(p); - manager = Reflex.getFieldValue(conn, managerFieldName); - channel = Reflex.getFieldValue(manager, channelFieldName); - - if (channel == null) { - CodexEngine.get().error( - "Could not setup Channel for player." + - "\n\nConnection: " + conn + - "\nUsing Manager Field Name: " + managerFieldName + - "\nManager: " + manager + - "\nChannel Field name: " + channelFieldName + - "\nChannel: " + channel + "\n" - ); - } - return (Channel) channel; - } catch (ClassCastException e) { - CodexEngine.get().error("Could not setup Channel for player." + - "\n\nConnection: " + conn + - "\nUsing Manager Field Name: " + managerFieldName + - "\nManager: " + manager + - "\nChannel Field name: " + channelFieldName + - "\nChannel: " + channel + "\n" - ); - e.printStackTrace(); - } catch (Exception e) { - e.printStackTrace(); - } - - return null; - } - - @Override - public Object getConnection(Player player) { - try { - Class craftPlayerClass = getCraftClass("entity.CraftPlayer"); - - Method getHandle = Reflex.getMethod(craftPlayerClass, "getHandle"); - Object nmsPlayer = Reflex.invokeMethod(getHandle, getCraftPlayer(player)); - - String fieldName = "b"; - Object con = Reflex.getFieldValue(nmsPlayer, fieldName); //WHY must you obfuscate - if (!con.getClass().getSimpleName().equals("PlayerConnection") && !con.getClass() - .getSimpleName() - .equals("GeneratedInterceptor")) { - throw new ClassNotFoundException("Could not get connection from CraftPlayer using field " + fieldName + - "\nNMS Player: " + nmsPlayer + "\n"); - } - return con; - } catch (Exception e) { - e.printStackTrace(); - } - - return null; - } - - @Override - public void sendPacket(Player p, Object packet) { - Object conn = getConnection(p); - Class packetClass = null; - try { - packetClass = getClazz("net.minecraft.network.protocol.Packet"); - } catch (ClassNotFoundException e) { - e.printStackTrace(); - } - Method sendPacket; - if (ReflectionManager.MINOR_VERSION == 17) { - sendPacket = Reflex.getMethod(conn.getClass(), "sendPacket", packetClass); - } else { // if (ReflectionManager.MINOR_VERSION > 17) { // If we're newer.. we're using obfuscated methods again ;( - sendPacket = Reflex.getMethod(conn.getClass(), "a", packetClass); - } - Reflex.invokeMethod(sendPacket, conn, packet); - } - - @Override - public void sendAttackPacket(Player p, int id) { - try { - Object craftPlayer = getCraftPlayer(p); - Object entity = getEntity(craftPlayer); - - Class packetClass = getClazz("net.minecraft.network.protocol.game.PacketPlayOutAnimation"); - Constructor ctor = Reflex.getConstructor(packetClass, entity.getClass(), int.class); - Object packet = Reflex.invokeConstructor(ctor, entity, id); - - sendPacket(p, packet); - } catch (ClassNotFoundException e) { - CodexEngine.get().getLogger().warning("Could not send attack packet."); - e.printStackTrace(); - } - } - - @Override - public void openChestAnimation(Block chest, boolean open) { - if (chest.getState() instanceof Chest) { - Location lo = chest.getLocation(); - World bWorld = lo.getWorld(); - if (bWorld == null) return; - - try { - Class worldClass = getClazz("net.minecraft.world.level.World"); - Class craftWorld = getCraftClass("CraftWorld"); - Class blockClass = getClazz("net.minecraft.world.level.block.Block"); - Class blockPosClass = getClazz("net.minecraft.core.BlockPosition"); - - Object cWorld = craftWorld.cast(bWorld); - Method getHandle = Reflex.getMethod(cWorld.getClass(), "getHandle"); - - Object world = worldClass.cast(Reflex.invokeMethod(getHandle, cWorld)); - Method playBlockAction = Reflex.getMethod(worldClass, - ReflectionManager.MINOR_VERSION == 17 ? "playBlockAction" : "a", //Curse you obfuscation - blockPosClass, blockClass, int.class, int.class); - - Constructor ctor = Reflex.getConstructor(blockPosClass, int.class, int.class, int.class); - Object position = - Reflex.invokeConstructor(ctor, (int) lo.getX(), (int) lo.getY(), (int) lo.getZ()); - - Method getType = Reflex.getMethod(world.getClass(), - ReflectionManager.MINOR_VERSION == 17 ? "getType" : "a_", - blockPosClass); - Class blockData = getClazz("net.minecraft.world.level.block.state.IBlockData"); - Object data = blockData.cast(Reflex.invokeMethod(getType, world, position)); - - Method getBlock = Reflex.getMethod(blockData, - ReflectionManager.MINOR_VERSION == 17 ? "getBlock" : "b"); - - //TileEntityChest tileChest = (TileEntityChest) world.getTileEntity(position); - Reflex.invokeMethod(playBlockAction, world, position, getBlock.invoke(data), 1, open ? 1 : 0); - } catch (Exception e) { - CodexEngine.get().getLogger().warning("Problem sending chest animation"); - e.printStackTrace(); - } - } - } - - @Override - public ItemStack damageItem(@NotNull ItemStack item, int amount, @Nullable Player player) { - try { - Object nmsStack = getNMSCopy(item); - - Object nmsPlayer = player != null ? getEntity(getCraftPlayer(player)) : null; - - if (ReflectionManager.MINOR_VERSION == 19) { - Class randSourceClass = getClazz("net.minecraft.util.RandomSource"); - Method isDamaged = Reflex.getMethod( - nmsStack.getClass(), - "a", - int.class, - randSourceClass, - getClazz("net.minecraft.server.level.EntityPlayer") - ); - - Object randSource = Reflex.invokeMethod(Reflex.getMethod(randSourceClass, "c"), null); - Reflex.invokeMethod(isDamaged, nmsStack, amount, randSource, nmsPlayer); - } else { - Method isDamaged = Reflex.getMethod( - nmsStack.getClass(), - ReflectionManager.MINOR_VERSION == 17 ? "isDamaged" : "a", - int.class, - Random.class, - getClazz("net.minecraft.server.level.EntityPlayer") - ); - - Reflex.invokeMethod(isDamaged, nmsStack, amount, Rnd.rnd, nmsPlayer); - } - - return toBukkitCopy(nmsStack); - } catch (Exception e) { - e.printStackTrace(); - } - - return null; - } - - @Override - public Multimap getAttributes(@NotNull ItemStack itemStack) { - try { - Object nmsItem = getNMSCopy(itemStack); - Method getItem = Reflex.getMethod(nmsItem.getClass(), - ReflectionManager.MINOR_VERSION > 17 ? "c" : "getItem"); - Object item = Reflex.invokeMethod(getItem, nmsItem); - - - Class enumItemSlotClass = (Class) ( - getClazz("net.minecraft.world.entity.EnumItemSlot") - ); - Class itemArmorClass = getClazz("net.minecraft.world.item.ItemArmor"); - Class itemToolClass = getClazz("net.minecraft.world.item.ItemTool"); - Class itemSwordClass = getClazz("net.minecraft.world.item.ItemSword"); - Class itemTridentClass = getClazz("net.minecraft.world.item.ItemTrident"); - - Enum mainhand = (Enum) Reflex.invokeMethod( - Reflex.getMethod(enumItemSlotClass, - ReflectionManager.MINOR_VERSION <= 17 ? "fromName" : "a", - String.class), - null, "mainhand"); - - if (itemArmorClass.isInstance(item)) { - Object tool = itemArmorClass.cast(item); - Method getEquipmentSlot = Reflex.getMethod(itemArmorClass, "b"); - Object armorEquipmentSlot = Reflex.invokeMethod(getEquipmentSlot, tool); - if (Version.V1_19_R3.isCurrent()) { - // If it's 1.19.4, the 'b' method returns a different enum, so we have to get the slot out of that enum - armorEquipmentSlot = Reflex.invokeMethod(Reflex.getMethod(armorEquipmentSlot.getClass(), "a"), - armorEquipmentSlot); - } - Method getDefaultAttributeModifiers = Reflex.getMethod(itemArmorClass, "a", enumItemSlotClass); - - return (Multimap) Reflex.invokeMethod(getDefaultAttributeModifiers, - tool, - armorEquipmentSlot); - } - - Object tool; - Method getDefaultAttributeModifiers; - if (itemToolClass.isInstance(item)) { - tool = itemToolClass.cast(item); - getDefaultAttributeModifiers = Reflex.getMethod(itemToolClass, "a", enumItemSlotClass); - } else if (itemSwordClass.isInstance(item)) { - tool = itemSwordClass.cast(item); - getDefaultAttributeModifiers = Reflex.getMethod(itemSwordClass, "a", enumItemSlotClass); - } else if (itemTridentClass.isInstance(item)) { - tool = itemTridentClass.cast(item); - getDefaultAttributeModifiers = Reflex.getMethod(itemTridentClass, "a", enumItemSlotClass); - } else { - return null; - } - - return (Multimap) Reflex.invokeMethod(getDefaultAttributeModifiers, tool, mainhand); - } catch (Exception e) { - e.printStackTrace(); - } - - return null; - } - - @Override - public double getAttributeValue(@NotNull ItemStack item, @NotNull Object attribute) { - try { - Class attributeModifierClass = - getClazz("net.minecraft.world.entity.ai.attributes.AttributeModifier"); - Class attributeBaseClass = - getClazz("net.minecraft.world.entity.ai.attributes.AttributeBase"); - Multimap attMap = (Multimap) getAttributes(item); - if (attMap == null || attMap.isEmpty()) return 0D; - - Collection att = attMap.get(attributeBaseClass.cast(attribute)); - if (att == null || att.isEmpty()) return 0D; - Object mod = attributeModifierClass.cast(att.stream().findFirst().get()); - - Method getAmount = Reflex.getMethod(attributeModifierClass, - ReflectionManager.MINOR_VERSION == 17 ? "getAmount" : - (Version.CURRENT == Version.V1_20_R3 ? "c" : "d")); - double value = (double) Reflex.invokeMethod(getAmount, mod); - if (attribute.equals(getGenericAttribute(DAMAGE_ATTRIBUTE))) { // Damage - value += 1; - } - return value; - } catch (Exception e) { - e.printStackTrace(); - } - - return 0; - } - - @Override - public double getDefaultDamage(@NotNull ItemStack itemStack) { - return getAttributeValue(itemStack, getGenericAttribute(DAMAGE_ATTRIBUTE)); // generic.attack_damage - } - - @Override - public double getDefaultSpeed(@NotNull ItemStack itemStack) { - return getAttributeValue(itemStack, getGenericAttribute(SPEED_ATTRIBUTE)); // generic.attack_speed - } - - @Override - public double getDefaultArmor(@NotNull ItemStack itemStack) { - return getAttributeValue(itemStack, getGenericAttribute(ARMOR_ATTRIBUTE)); // generic.armor - } - - @Override - public double getDefaultToughness(@NotNull ItemStack itemStack) { - return getAttributeValue(itemStack, getGenericAttribute(TOUGHNESS_ATTRIBUTE)); // generic.armor_toughness - } - - @Override - public Object getGenericAttribute(String field) { - try { - Class attributes = getClazz("net.minecraft.world.entity.ai.attributes.GenericAttributes"); - Object value = Reflex.getField(attributes, field).get(null); - - if (Version.CURRENT.isAtLeast(Version.V1_20_R4)) { - value = Reflex.invokeMethod(Reflex.getMethod(value.getClass(), "a"), value); - } - - //AttributeBase or IAttribute - return value; - } catch (Exception e) { - e.printStackTrace(); - } - - return null; - } - - @Override - public boolean isWeapon(@NotNull ItemStack itemStack) { - try { - Object nmsItem = getNMSCopy(itemStack); - - Method getItem = Reflex.getMethod(nmsItem.getClass(), "getItem"); - - Object item = Reflex.invokeMethod(getItem, nmsItem); - - Class swordClass = getClazz("net.minecraft.world.item.ItemSword"); - Class axeClass = getClazz("net.minecraft.world.item.ItemAxe"); - Class tridentClass = getClazz("net.minecraft.world.item.ItemTrident"); - - return swordClass.isInstance(item) || axeClass.isInstance(item) || tridentClass.isInstance(item); - } catch (Exception e) { - e.printStackTrace(); - } - return false; - } - - @Override - public boolean isTool(@NotNull ItemStack itemStack) { - try { - Object nmsItem = getNMSCopy(itemStack); - - Method getItem = Reflex.getMethod(nmsItem.getClass(), "getItem"); - - Object item = Reflex.invokeMethod(getItem, nmsItem); - - Class toolClass = getClazz("net.minecraft.world.item.ItemTool"); - - return toolClass.isInstance(item); - } catch (Exception e) { - e.printStackTrace(); - } - return false; - } - - public boolean isArmor(@NotNull ItemStack itemStack) { - try { - Object nmsItem = getNMSCopy(itemStack); - - Method getItem = Reflex.getMethod(nmsItem.getClass(), "getItem"); - - Object item = Reflex.invokeMethod(getItem, nmsItem); - - Class armorClass = getClazz("net.minecraft.world.item.ItemArmor"); - - return armorClass.isInstance(item); - } catch (Exception e) { - e.printStackTrace(); - } - return false; - } - - public String fixColors(@NotNull String str) { - try { - str = str.replace("\n", "%n%"); // CraftChatMessage wipes all lines out. - - Class baseComponentClass = getClazz("net.minecraft.network.chat.IChatBaseComponent"); - Class chatMessageClass = getCraftClass("util.CraftChatMessage"); - - Method fromComponent = Reflex.getMethod(chatMessageClass, "fromComponent", baseComponentClass); - Method fromStringOrNull = Reflex.getMethod(chatMessageClass, "fromStringOrNull", String.class); - - Object baseComponent = Reflex.invokeMethod(fromStringOrNull, null, str); - String singleColor = - (String) Reflex.invokeMethod(fromComponent, null, baseComponentClass.cast(baseComponent)); - return singleColor.replace("%n%", "\n"); - } catch (Exception e) { - e.printStackTrace(); - } - - return str; - } - - public void changeSkull(Block b, String hash) { - try { - if (!(b.getState() instanceof Skull)) return; - - Skull skull = (Skull) b.getState(); - try { - PlayerProfile profile = Bukkit.createPlayerProfile(UUID.randomUUID(), hash.substring(0, 16)); - PlayerTextures textures = profile.getTextures(); - - // If the hash is a URL, we can just set the skin directly, otherwise, we need to decode - // the hash from Base64 and extract the url from the JSON data. - if (hash.startsWith("http")) { - textures.setSkin(new URL(hash)); - } else { - String decoded = new String(java.util.Base64.getDecoder().decode(hash)); - // Construct the json object - JsonObject json = new Gson().fromJson(decoded, JsonObject.class); - // Get the textures object - JsonObject texturesJson = json.getAsJsonObject("textures"); - // Get the skin object - JsonObject skin = texturesJson.getAsJsonObject("SKIN"); - // Get the url - String url = skin.get("url").getAsString(); - textures.setSkin(new URL(url)); - } - - profile = profile.update().get(); - skull.setOwnerProfile(profile); - } catch (NoSuchMethodError | Exception e) { - CodexEngine.get().getLogger().info("Could not change skull with modern method, trying legacy method."); - GameProfile profile = getNonPlayerProfile(hash); - Reflex.setFieldValue(skull, "profile", profile); - } - skull.update(); - } catch (Exception e) { - CodexEngine.get().getLogger().warning("Could not update skull"); - e.printStackTrace(); - } - } -} diff --git a/src/main/java/studio/magemonkey/codex/util/reflection/Reflection_1_18.java b/src/main/java/studio/magemonkey/codex/util/reflection/Reflection_1_18.java deleted file mode 100644 index 6728542f..00000000 --- a/src/main/java/studio/magemonkey/codex/util/reflection/Reflection_1_18.java +++ /dev/null @@ -1,73 +0,0 @@ -package studio.magemonkey.codex.util.reflection; - -import com.google.common.collect.Multimap; -import org.bukkit.attribute.Attribute; -import org.bukkit.attribute.AttributeModifier; -import org.bukkit.inventory.EquipmentSlot; -import org.bukkit.inventory.ItemStack; -import org.jetbrains.annotations.NotNull; -import studio.magemonkey.codex.util.AttributeUT; -import studio.magemonkey.codex.util.Reflex; - -import java.lang.reflect.Method; -import java.util.Collection; - -public class Reflection_1_18 extends Reflection_1_17 { - @Override - public Object save(Object nmsItem, Object nbtCompound) { - try { - Method save = Reflex.getMethod(nmsItem.getClass(), "b", nbtCompound.getClass()); - - return Reflex.invokeMethod(save, nmsItem, nbtCompound); - } catch (Exception e) { - e.printStackTrace(); - } - - return null; - } - - @Override - public Object getGenericAttribute(String name) { - try { - return Attribute.valueOf("GENERIC_" + name); - } catch (IllegalArgumentException e) { - return null; - } - } - - @Override - public Multimap getAttributes(@NotNull ItemStack itemStack) { - EquipmentSlot slot = itemStack.getType().getEquipmentSlot(); - return itemStack.getType().getDefaultAttributeModifiers(slot); - } - - @Override - public double getAttributeValue(@NotNull ItemStack item, @NotNull Object attribute) { - Attribute attr = (Attribute) attribute; - Multimap modifiers = getAttributes(item); - Collection mod = modifiers.get(attr); - if (mod.isEmpty()) return 0; - - return mod.stream().mapToDouble(AttributeModifier::getAmount).sum(); - } - - @Override - public double getDefaultDamage(@NotNull ItemStack itemStack) { - return getAttributeValue(itemStack, AttributeUT.resolve("GENERIC_ATTACK_DAMAGE")); // generic.attack_damage - } - - @Override - public double getDefaultSpeed(@NotNull ItemStack itemStack) { - return getAttributeValue(itemStack, AttributeUT.resolve("GENERIC_ATTACK_SPEED")); // generic.attack_speed - } - - @Override - public double getDefaultArmor(@NotNull ItemStack itemStack) { - return getAttributeValue(itemStack, AttributeUT.resolve("GENERIC_ARMOR")); // generic.armor - } - - @Override - public double getDefaultToughness(@NotNull ItemStack itemStack) { - return getAttributeValue(itemStack, AttributeUT.resolve("GENERIC_ARMOR_TOUGHNESS")); // generic.armor_toughness - } -} diff --git a/src/main/java/studio/magemonkey/codex/util/reflection/Reflection_1_20.java b/src/main/java/studio/magemonkey/codex/util/reflection/Reflection_1_20.java deleted file mode 100644 index a8cb50cb..00000000 --- a/src/main/java/studio/magemonkey/codex/util/reflection/Reflection_1_20.java +++ /dev/null @@ -1,80 +0,0 @@ -package studio.magemonkey.codex.util.reflection; - -import org.bukkit.attribute.Attribute; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.jetbrains.annotations.NotNull; -import studio.magemonkey.codex.CodexEngine; -import studio.magemonkey.codex.core.Version; -import studio.magemonkey.codex.util.Reflex; - -import java.lang.reflect.Method; - -public class Reflection_1_20 extends Reflection_1_18 { - private boolean isConnClass(Object con) { - return con.getClass().getSimpleName().equals("PlayerConnection") || con.getClass() - .getSimpleName() - .equals("ServerGamePacketListenerImpl") || con.getClass() - .getSimpleName() - .equals("GeneratedInterceptor"); - } - - @Override - public Object getConnection(Player player) { - try { - Class craftPlayerClass = getCraftClass("entity.CraftPlayer"); - - Method getHandle = Reflex.getMethod(craftPlayerClass, "getHandle"); - Object nmsPlayer = Reflex.invokeMethod(getHandle, getCraftPlayer(player)); - - String fieldName = "f"; - Object con = Reflex.getFieldValue(nmsPlayer, fieldName); //WHY must you obfuscate - if (isConnClass(con)) { - return con; - } else { - // Try with "c" instead (for <=1.21.1) - fieldName = "c"; - con = Reflex.getFieldValue(nmsPlayer, fieldName); - } - - if (isConnClass(con)) { - return con; - } - - CodexEngine.get() - .getLogger() - .warning("Expected PlayerConnection, got " + con.getClass().getSimpleName() + " instead!"); - throw new ClassNotFoundException( - "Could not get connection from CraftPlayer using field " + fieldName + "\nNMS Player: " - + nmsPlayer + "\n"); - } catch (Exception e) { - e.printStackTrace(); - } - - return null; - } - - @Override - public double getDefaultDamage(@NotNull ItemStack itemStack) { - if (Version.CURRENT.isAtLeast(Version.V1_21_R2)) return getAttributeValue(itemStack, Attribute.ATTACK_DAMAGE); - else return super.getDefaultDamage(itemStack); - } - - @Override - public double getDefaultSpeed(@NotNull ItemStack itemStack) { - if (Version.CURRENT.isAtLeast(Version.V1_21_R2)) return getAttributeValue(itemStack, Attribute.ATTACK_SPEED); - else return super.getDefaultSpeed(itemStack); - } - - @Override - public double getDefaultArmor(@NotNull ItemStack itemStack) { - if (Version.CURRENT.isAtLeast(Version.V1_21_R2)) return getAttributeValue(itemStack, Attribute.ARMOR); - else return super.getDefaultArmor(itemStack); - } - - @Override - public double getDefaultToughness(@NotNull ItemStack itemStack) { - if (Version.CURRENT.isAtLeast(Version.V1_21_R2)) return getAttributeValue(itemStack, Attribute.ARMOR_TOUGHNESS); - else return super.getDefaultToughness(itemStack); - } -} diff --git a/src/test/java/studio/magemonkey/codex/testutil/reflection/TestReflectionUtil.java b/src/test/java/studio/magemonkey/codex/testutil/reflection/TestReflectionUtil.java deleted file mode 100644 index 81fcd407..00000000 --- a/src/test/java/studio/magemonkey/codex/testutil/reflection/TestReflectionUtil.java +++ /dev/null @@ -1,169 +0,0 @@ -package studio.magemonkey.codex.testutil.reflection; - -import com.google.common.collect.Multimap; -import com.mojang.authlib.GameProfile; -import io.netty.channel.Channel; -import org.bukkit.block.Block; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import studio.magemonkey.codex.util.reflection.ReflectionUtil; - -import java.util.Collection; -import java.util.UUID; - -public class TestReflectionUtil implements ReflectionUtil { - @Override - public Object newNBTTagCompound() { - return null; - } - - @Override - public Object newNBTTagList() { - return null; - } - - @Override - public Object getNMSCopy(ItemStack item) { - return null; - } - - @Override - public ItemStack toBukkitCopy(Object nmsItem) { - return null; - } - - @Override - public Object save(Object nmsItem, Object nbtCompound) { - return null; - } - - @Override - public Class getNMSClass(String nmsClassName) throws ClassNotFoundException { - return null; - } - - @Override - public Class getCraftClass(String craftClassName) throws ClassNotFoundException { - return null; - } - - @Override - public Object getConnection(Player player) { - return null; - } - - @Override - public Object getCraftPlayer(Player player) { - return null; - } - - @Override - public Object getEntity(Object craftEntity) { - return null; - } - - @Override - public Channel getChannel(Player player) { - return new TestChannel(); - } - - @Override - public void sendPackets(Player player, Collection packets) { - - } - - @Override - public void sendPacket(Player player, Object packet) { - - } - - @Override - public void sendAttackPacket(Player player, int id) { - - } - - @Override - public void openChestAnimation(Block chest, boolean open) { - - } - - @Override - public ItemStack damageItem(@NotNull ItemStack item, int amount, @Nullable Player player) { - // TODO Actually damage the item - return item; - } - - @Override - public Multimap getAttributes(@NotNull ItemStack item) { - return null; - } - - @Override - public double getAttributeValue(@NotNull ItemStack item, @NotNull Object attribute) { - return 0; - } - - @Override - public double getDefaultDamage(@NotNull ItemStack item) { - return 0; - } - - @Override - public double getDefaultSpeed(@NotNull ItemStack item) { - return 0; - } - - @Override - public double getDefaultArmor(@NotNull ItemStack item) { - return 0; - } - - @Override - public double getDefaultToughness(@NotNull ItemStack item) { - return 0; - } - - @Override - public Object getGenericAttribute(String field) { - return null; - } - - @Override - public boolean isWeapon(@NotNull ItemStack item) { - return false; - } - - @Override - public boolean isTool(@NotNull ItemStack item) { - return false; - } - - @Override - public boolean isArmor(@NotNull ItemStack item) { - return false; - } - - @Override - public String fixColors(@NotNull String str) { - return str; - } - - @Override - public void changeSkull(Block b, String hash) { - - } - - @Override - public GameProfile getNonPlayerProfile(String hash) { - UUID uid = UUID.randomUUID(); - GameProfile profile = new GameProfile(uid, uid.toString()); - return profile; - } - - @Override - public void setKiller(LivingEntity entity, Player player) { - } -}