From 22c5af10e3f5a51f39f0b5d3f1cbdf6a7805a598 Mon Sep 17 00:00:00 2001 From: XiaoMoMi <972454774@qq.com> Date: Thu, 18 Jan 2024 02:01:28 +0800 Subject: [PATCH] backup-1 --- .gitignore | 145 +- api/.gitignore | 42 + api/build.gradle.kts | 4 + .../api/CustomNameplatesPlugin.java | 112 + .../customnameplates/api/common/Key.java | 31 +- .../customnameplates/api/common/Pair.java | 11 +- .../api/common/SimpleLocation.java | 63 + .../customnameplates/api/common/Tuple.java | 59 + .../customnameplates/api/data/OnlineUser.java | 79 + .../customnameplates/api/data/PlayerData.java | 58 + .../event/CustomNameplatesReloadEvent.java | 30 + .../api/event/NameplateDataLoadEvent.java | 39 + .../api/event/PlayerEquipBubbleEvent.java | 43 + .../api/event/PlayerEquipNameplateEvent.java | 43 + .../api/event/PlayerUnequipBubbleEvent.java | 37 + .../event/PlayerUnequipNameplateEvent.java | 37 + .../api/manager/ActionBarManager.java | 17 + .../api/manager/AdventureManager.java | 186 + .../api/manager/BackGroundManager.java | 40 + .../api/manager/BossBarManager.java | 5 + .../api/manager/ImageManager.java | 40 + .../api/manager/NameplateManager.java | 158 + .../api/manager/PlaceholderManager.java | 73 + .../api/manager/RequirementManager.java | 104 + .../api/manager/ResourcePackManager.java | 15 + .../api/manager/StorageManager.java | 88 + .../api/manager/TeamManager.java | 47 + .../api/manager/TeamTagManager.java | 29 + .../api/manager/UnlimitedTagManager.java | 56 + .../api/manager/VersionManager.java | 26 + .../api/manager/WidthManager.java | 5 + .../api/mechanic/background/BackGround.java | 212 + .../mechanic/character/CharacterArranger.java | 25 + .../mechanic/character/ConfiguredChar.java | 107 + .../api/mechanic/font/OffsetFont.java | 180 + .../api/mechanic/misc/ViewerText.java | 111 + .../mechanic/nameplate/CachedNameplate.java | 70 + .../api/mechanic/nameplate/Nameplate.java | 166 + .../api/mechanic/nameplate/TagMode.java | 7 + .../mechanic/placeholder/BackGroundText.java | 65 + .../api/mechanic/placeholder/CachedText.java | 54 + .../mechanic/placeholder/ConditionalText.java | 58 + .../api/mechanic/placeholder/DescentText.java | 68 + .../mechanic/placeholder/NameplateText.java | 71 + .../api/mechanic/placeholder/StaticText.java | 98 + .../api/mechanic/placeholder/SwitchText.java | 63 + .../api/mechanic/placeholder/VanillaHud.java | 58 + .../api/mechanic/tag/NameplatePlayer.java | 13 + .../api/mechanic/tag/team/TeamPlayer.java | 109 + .../mechanic/tag/unlimited/NamedEntity.java | 60 + .../tag/unlimited/UnlimitedObject.java | 39 + .../tag/unlimited/UnlimitedPlayer.java | 201 + .../tag/unlimited/UnlimitedTagSetting.java | 106 + .../api/mechanic/team/TeamCollisionRule.java | 31 + .../api/mechanic/team/TeamColor.java | 29 + .../api/mechanic/team/TeamCreatePacket.java | 154 + .../api/mechanic/team/TeamRemovePacket.java | 39 + .../api/mechanic/team/TeamTagVisibility.java | 31 + .../api/mechanic/team/TeamUpdatePacket.java | 136 + .../api/requirement/Condition.java | 16 + .../api/requirement}/Requirement.java | 13 +- .../api/requirement/RequirementExpansion.java | 53 + .../api/requirement/RequirementFactory.java | 30 +- .../api/scheduler/CancellableTask.java | 12 +- .../api/scheduler/Scheduler.java | 93 + .../customnameplates/api/util/FontUtils.java | 76 + .../customnameplates/api/util/LogUtils.java | 77 + build.gradle | 81 - build.gradle.kts | 80 + bungeecord/.gitignore | 42 + bungeecord/build.gradle.kts | 3 + bungeecord/src/main/resources/plugin.yml | 9 + gradle/wrapper/gradle-wrapper.jar | Bin 59536 -> 62076 bytes gradle/wrapper/gradle-wrapper.properties | 3 +- gradlew | 35 +- gradlew.bat | 15 +- jitpack.yml | 2 + libs/MagicCosmetics-2.3.7-API.jar | Bin 174575 -> 0 bytes libs/TrChat-2.0.8.jar | Bin 3864847 -> 0 bytes libs/VentureChat-3.6.0.jar | Bin 383361 -> 0 bytes libs/oraxen-api.jar | Bin 358964 -> 0 bytes paper/.gitignore | 42 + paper/build.gradle.kts | 62 + {libs => paper/libs}/BiomeAPI.jar | Bin 11703 -> 12922 bytes paper/libs/CMI-API-9.6.5.0.jar | Bin 0 -> 872744 bytes paper/libs/TrChat-2.0.11.jar | Bin 0 -> 97302 bytes paper/libs/VentureChat-3.7.1.jar | Bin 0 -> 12847 bytes .../paper/CustomNameplatesPluginImpl.java | 147 + .../paper/adventure/AdventureManagerImpl.java | 333 ++ .../paper/command/CommandManager.java | 99 + .../paper}/helper/LibraryLoader.java | 154 +- .../paper}/helper/MavenLibraries.java | 7 +- .../paper}/helper/MavenLibrary.java | 13 +- .../paper}/helper/Repository.java | 4 +- .../paper}/helper/URLClassLoaderAccess.java | 11 +- .../mechanic/actionbar/ActionBarConfig.java | 79 + .../actionbar/ActionBarManagerImpl.java | 219 + .../mechanic/actionbar/ActionBarReceiver.java | 102 + .../listener}/ActionBarListener.java | 12 +- .../listener}/ChatMessageListener.java | 12 +- .../listener}/SystemChatListener.java | 12 +- .../background/BackGroundManagerImpl.java | 194 + .../paper/mechanic/bossbar/BarColor.java | 23 + .../paper/mechanic/bossbar/BossBar.java | 87 + .../paper/mechanic/bossbar/BossBarConfig.java | 101 + .../mechanic/bossbar/BossBarManagerImpl.java | 134 + .../mechanic/bossbar/BossBarReceiver.java | 98 + .../paper/mechanic}/bossbar/Overlay.java | 16 +- .../paper/mechanic/font/FontData.java | 22 + .../paper/mechanic/font/WidthManagerImpl.java | 38 + .../mechanic/image/ImageManagerImpl.java | 100 + .../paper/mechanic/misc/CoolDownManager.java | 107 + .../mechanic/misc/DisplayController.java | 116 + .../paper/mechanic/misc/MessageManager.java | 9 + .../paper/mechanic/misc/PacketManager.java | 32 + .../paper/mechanic/misc/TimeLimitText.java | 82 + .../mechanic/misc/VersionManagerImpl.java | 209 +- .../nameplate/NameplateManagerImpl.java | 565 ++ .../tag/listener}/EntityDestroyListener.java | 16 +- .../tag/listener}/EntityLookListener.java | 16 +- .../tag/listener}/EntityMoveListener.java | 16 +- .../tag/listener}/EntitySpawnListener.java | 16 +- .../tag/listener}/EntityTeleportListener.java | 23 +- .../tag/listener}/MagicCosmeticsListener.java | 41 +- .../tag/team/TeamTagManagerImpl.java | 128 + .../tag/unlimited/NamedEntityImpl.java | 393 ++ .../unlimited/UnlimitedTagManagerImpl.java | 199 + .../pack/ResourcePackManagerImpl.java | 285 + .../placeholder/PlaceholderManagerImpl.java | 254 + .../placeholder/PluginPlaceholders.java | 141 + .../requirement/EmptyRequirement.java | 18 +- .../requirement/RequirementManagerImpl.java | 706 +++ .../paper/mechanic/team/Team.java | 6 + .../paper/mechanic/team/TeamManagerImpl.java | 175 + .../team/packet/TeamPacketAdaptor.java | 15 + .../mechanic/team/packet/TeamPacket_1_17.java | 69 + .../mechanic/team/provider/CMIProvider.java | 15 + .../team/provider/DefaultProvider.java | 11 + .../mechanic/team/provider/TABProvider.java | 26 + .../mechanic/team/provider/TeamProvider.java | 8 + .../paper/scheduler/BukkitSchedulerImpl.java | 100 + .../paper/scheduler/FoliaSchedulerImpl.java | 96 + .../paper/scheduler/SchedulerImpl.java | 183 + .../paper/scheduler/SyncScheduler.java | 53 + .../paper/setting/CNConfig.java | 132 + .../paper/setting/CNLocale.java | 95 + .../paper/storage}/DataStorageInterface.java | 26 +- .../paper/storage/StorageManagerImpl.java | 239 + .../paper/storage}/StorageType.java | 13 +- .../paper/storage/method/AbstractStorage.java | 43 + .../method/database/nosql/MongoDBImpl.java | 171 + .../method/database/nosql/RedisManager.java | 194 + .../database/sql/AbstractHikariDatabase.java | 139 + .../database/sql/AbstractSQLDatabase.java | 189 + .../storage/method/database/sql/H2Impl.java | 73 + .../method/database/sql/MariaDBImpl.java | 20 +- .../method/database/sql/MySQLImpl.java | 20 +- .../method/database/sql/SQLiteImpl.java | 176 + .../paper/storage/method/file/JsonImpl.java | 128 + .../paper/storage/method/file/YAMLImpl.java | 105 + .../paper/util}/ClassUtils.java | 2 +- .../paper/util/ConfigUtils.java | 98 + .../paper/util/LocationUtils.java | 13 + .../paper/util/ReflectionUtils.java | 62 + .../shaders/core/rendertype_text.fsh | 0 .../shaders/core/rendertype_text.json | 0 .../shaders/core/rendertype_text.vsh | 0 .../assets/minecraft/textures/gui/bars.png | Bin .../sprites/boss_bar/yellow_background.png | Bin .../gui/sprites/boss_bar/yellow_progress.png | Bin .../main/resources/ResourcePack/pack.mcmeta | 0 paper/src/main/resources/config.yml | 103 + .../src/main/resources/configs/actionbar.yml | 14 + paper/src/main/resources/configs/bossbar.yml | 34 + .../resources/configs/custom-placeholders.yml | 30 +- .../main/resources/configs/image-width.yml | 5 + .../src/main/resources/configs/nameplate.yml | 46 + .../resources/contents/backgrounds/b0.png | Bin .../resources/contents/backgrounds/b1.png | Bin .../resources/contents/backgrounds/b128.png | Bin .../resources/contents/backgrounds/b16.png | Bin .../resources/contents/backgrounds/b2.png | Bin .../resources/contents/backgrounds/b32.png | Bin .../resources/contents/backgrounds/b4.png | Bin .../resources/contents/backgrounds/b64.png | Bin .../resources/contents/backgrounds/b8.png | Bin .../contents/backgrounds/bedrock_1.yml | 0 .../contents/backgrounds/bedrock_2.yml | 0 .../contents/backgrounds/bedrock_3.yml | 0 .../main/resources/contents/bubbles/chat.yml | 0 .../resources/contents/bubbles/chat_left.png | Bin .../contents/bubbles/chat_middle.png | Bin .../resources/contents/bubbles/chat_right.png | Bin .../resources/contents/bubbles/chat_tail.png | Bin .../main/resources/contents/images/bell.png | Bin .../main/resources/contents/images/bell.yml | 0 .../main/resources/contents/images/bubble.png | Bin .../main/resources/contents/images/bubble.yml | 0 .../main/resources/contents/images/clock.png | Bin .../main/resources/contents/images/clock.yml | 0 .../main/resources/contents/images/coin.png | Bin .../main/resources/contents/images/coin.yml | 0 .../resources/contents/images/compass.png | Bin .../resources/contents/images/compass.yml | 0 .../resources/contents/images/stamina_0.png | Bin .../resources/contents/images/stamina_0.yml | 0 .../resources/contents/images/stamina_1.png | Bin .../resources/contents/images/stamina_1.yml | 0 .../resources/contents/images/stamina_2.png | Bin .../resources/contents/images/stamina_2.yml | 0 .../resources/contents/images/weather.png | Bin .../resources/contents/images/weather.yml | 0 .../resources/contents/nameplates/cat.yml | 0 .../contents/nameplates/cat_left.png | Bin .../contents/nameplates/cat_middle.png | Bin .../contents/nameplates/cat_right.png | Bin .../resources/contents/nameplates/cheems.yml | 0 .../contents/nameplates/cheems_left.png | Bin .../contents/nameplates/cheems_middle.png | Bin .../contents/nameplates/cheems_right.png | Bin .../resources/contents/nameplates/egg.yml | 0 .../contents/nameplates/egg_left.png | Bin .../contents/nameplates/egg_middle.png | Bin .../contents/nameplates/egg_right.png | Bin .../contents/nameplates/halloween.yml | 0 .../contents/nameplates/halloween_left.png | Bin .../contents/nameplates/halloween_middle.png | Bin .../contents/nameplates/halloween_right.png | Bin .../resources/contents/nameplates/hutao.yml | 0 .../contents/nameplates/hutao_left.png | Bin .../contents/nameplates/hutao_middle.png | Bin .../contents/nameplates/hutao_right.png | Bin .../resources/contents/nameplates/rabbit.yml | 0 .../contents/nameplates/rabbit_left.png | Bin .../contents/nameplates/rabbit_middle.png | Bin .../contents/nameplates/rabbit_right.png | Bin .../resources/contents/nameplates/starsky.yml | 0 .../contents/nameplates/starsky_left.png | Bin .../contents/nameplates/starsky_middle.png | Bin .../contents/nameplates/starsky_right.png | Bin .../resources/contents/nameplates/trident.yml | 0 .../contents/nameplates/trident_left.png | Bin .../contents/nameplates/trident_middle.png | Bin .../contents/nameplates/trident_right.png | Bin .../resources/contents/nameplates/wither.yml | 0 .../contents/nameplates/wither_left.png | Bin .../contents/nameplates/wither_middle.png | Bin .../contents/nameplates/wither_right.png | Bin .../resources/contents/nameplates/xmas.yml | 0 .../contents/nameplates/xmas_left.png | Bin .../contents/nameplates/xmas_middle.png | Bin .../contents/nameplates/xmas_right.png | Bin paper/src/main/resources/database.yml | 77 + .../src}/main/resources/messages/chinese.yml | 8 +- .../src}/main/resources/messages/english.yml | 8 +- .../src}/main/resources/messages/french.yml | 8 +- .../src}/main/resources/messages/russian.yml | 8 +- .../src}/main/resources/messages/spanish.yml | 8 +- .../src}/main/resources/messages/turkish.yml | 8 +- paper/src/main/resources/plugin.yml | 7 + paper/src/main/resources/schema/h2.sql | 6 + paper/src/main/resources/schema/mariadb.sql | 10 + paper/src/main/resources/schema/mysql.sql | 6 + paper/src/main/resources/schema/sqlite.sql | 6 + .../src}/main/resources/space_split.png | Bin settings.gradle | 1 - settings.gradle.kts | 5 + .../customnameplates/CustomNameplates.java | 244 - .../api/CustomNameplatesAPI.java | 92 - .../api/events/BubblesEvent.java | 75 - .../bungeecord/BungeeConfigManager.java | 40 - .../bungeecord/BungeeEventListener.java | 71 - .../bungeecord/CustomNameplatesBC.java | 51 - .../command/AbstractMainCommand.java | 81 - .../command/AbstractSubCommand.java | 141 - .../command/BubblesCommand.java | 36 - .../command/NameplateCommand.java | 42 - .../command/subcmd/AboutCommand.java | 44 - .../command/subcmd/BubblesEquipCommand.java | 58 - .../subcmd/BubblesForceEquipCommand.java | 60 - .../subcmd/BubblesForceUnequipCommand.java | 55 - .../command/subcmd/BubblesListCommand.java | 55 - .../command/subcmd/BubblesUnequipCommand.java | 45 - .../command/subcmd/ForcePreviewCommand.java | 88 - .../command/subcmd/HelpCommand.java | 58 - .../subcmd/NameplatesEquipCommand.java | 58 - .../subcmd/NameplatesForceEquipCommand.java | 58 - .../subcmd/NameplatesForceUnequipCommand.java | 55 - .../command/subcmd/NameplatesListCommand.java | 54 - .../subcmd/NameplatesUnequipCommand.java | 45 - .../command/subcmd/PreviewCommand.java | 69 - .../command/subcmd/ReloadCommand.java | 43 - .../data/FileStorageImpl.java | 73 - .../data/MySQLStorageImpl.java | 113 - .../customnameplates/data/PlayerData.java | 54 - .../customnameplates/data/SqlConnection.java | 155 - .../customnameplates/data/SqlConstants.java | 26 - .../customnameplates/helper/Log.java | 63 - .../helper/NonnullByDefault.java | 45 - .../listener/AbstractChatListener.java | 30 - .../listener/AsyncChatListener.java | 36 - .../listener/EntityTagListener.java | 54 - .../listener/JoinQuitListener.java | 37 - .../listener/TrChatListener.java | 40 - .../listener/VentureChatListener.java | 45 - .../manager/ActionBarManager.java | 219 - .../manager/BackgroundManager.java | 174 - .../manager/BossBarManager.java | 121 - .../manager/ChatBubblesManager.java | 377 -- .../manager/ConfigManager.java | 144 - .../customnameplates/manager/DataManager.java | 167 - .../customnameplates/manager/FontManager.java | 343 -- .../manager/ImageManager.java | 100 - .../manager/MessageManager.java | 91 - .../manager/NameplateManager.java | 315 - .../manager/PlaceholderManager.java | 237 - .../manager/ResourceManager.java | 418 -- .../customnameplates/manager/TeamManager.java | 155 - .../object/ConditionalText.java | 25 - .../customnameplates/object/DisplayMode.java | 25 - .../customnameplates/object/DynamicText.java | 85 - .../customnameplates/object/SimpleChar.java | 55 - .../object/actionbar/ActionBarConfig.java | 24 - .../object/actionbar/ActionBarSender.java | 70 - .../object/actionbar/ActionBarTask.java | 75 - .../object/background/BackGroundConfig.java | 28 - .../object/bossbar/BossBarConfig.java | 25 - .../object/bossbar/BossBarSender.java | 157 - .../object/bossbar/BossBarTask.java | 72 - .../object/bubble/BubbleConfig.java | 29 - .../carrier/AbstractPacketsHandler.java | 72 - .../object/carrier/AbstractTextCarrier.java | 71 - .../object/carrier/DisableNameplate.java | 26 - .../object/carrier/NamedEntity.java | 39 - .../object/carrier/NamedEntityCarrier.java | 162 - .../object/carrier/NamedEntityImpl.java | 330 - .../object/carrier/NamedEntityManager.java | 192 - .../carrier/NamedEntityPacketsHandler.java | 107 - .../object/carrier/TeamInfoCarrier.java | 43 - .../object/carrier/TextDisplayMeta.java | 7 - .../object/carrier/VehicleChecker.java | 91 - .../object/font/ASCIIWidth.java | 64 - .../object/font/OffsetFont.java | 68 - .../object/img/ImageParser.java | 25 - .../object/img/ItemsAdderImageImpl.java | 29 - .../object/img/OraxenImageImpl.java | 44 - .../object/nameplate/NameplateConfig.java | 25 - .../object/nameplate/NameplatesTeam.java | 100 - .../object/placeholders/BackGroundText.java | 22 - .../object/placeholders/ConditionalTexts.java | 44 - .../object/placeholders/DescentText.java | 22 - .../placeholders/NameplatePlaceholders.java | 250 - .../object/placeholders/NameplateText.java | 22 - .../object/placeholders/VanillaHud.java | 22 - .../object/requirements/BiomeImpl.java | 31 - .../object/requirements/CustomPapiImpl.java | 77 - .../object/requirements/DateImpl.java | 33 - .../object/requirements/GeyserImpl.java | 29 - .../object/requirements/PermissionImpl.java | 28 - .../object/requirements/TimeImpl.java | 37 - .../object/requirements/WeatherImpl.java | 46 - .../object/requirements/WorldImpl.java | 31 - .../object/requirements/YPosImpl.java | 37 - .../object/requirements/papi/PapiGreater.java | 30 - .../requirements/papi/PapiNoLarger.java | 30 - .../object/requirements/papi/PapiNoLess.java | 30 - .../requirements/papi/PapiNotEquals.java | 32 - .../object/requirements/papi/PapiRegex.java | 12 - .../requirements/papi/PapiRequirement.java | 24 - .../object/requirements/papi/PapiSmaller.java | 30 - .../object/scheduler/BukkitSchedulerImpl.java | 70 - .../object/scheduler/FoliaSchedulerImpl.java | 71 - .../object/scheduler/FoliaTimerTask.java | 39 - .../object/scheduler/Scheduler.java | 37 - .../object/scheduler/SchedulerPlatform.java | 41 - .../object/team/TeamNameInterface.java | 29 - .../object/team/TeamPacketInterface.java | 26 - .../object/team/name/PlayerNameTeamImpl.java | 120 - .../object/team/name/TABBungeeCordImpl.java | 108 - .../object/team/name/TABImpl.java | 60 - .../object/team/name/VelocitabImpl.java | 108 - .../object/team/packet/TeamInfoImpl.java | 85 - .../team/packet/TeamVisibilityImpl.java | 78 - .../utils/AdventureUtils.java | 157 - .../utils/ArmorStandUtils.java | 101 - .../customnameplates/utils/ConfigUtils.java | 117 - .../customnameplates/utils/GeyserUtils.java | 12 - .../velocity/CustomNameplatesVC.java | 87 - src/main/resources/bungee.yml | 5 - src/main/resources/config.yml | 101 - src/main/resources/configs/actionbar.yml | 10 - src/main/resources/configs/bossbar.yml | 35 - src/main/resources/configs/bubble.yml | 57 - src/main/resources/configs/image-width.yml | 2212 ------- src/main/resources/configs/nameplate.yml | 64 - src/main/resources/database.yml | 42 - src/main/resources/plugin.yml | 82 - src/main/resources/templates/default.json | 191 - src/main/resources/templates/unicode.json | 5297 ----------------- .../resources/unicodes/unicode_page_00.png | Bin 2356 -> 0 bytes .../resources/unicodes/unicode_page_01.png | Bin 2267 -> 0 bytes .../resources/unicodes/unicode_page_02.png | Bin 2087 -> 0 bytes .../resources/unicodes/unicode_page_03.png | Bin 1843 -> 0 bytes .../resources/unicodes/unicode_page_04.png | Bin 2242 -> 0 bytes .../resources/unicodes/unicode_page_05.png | Bin 1771 -> 0 bytes .../resources/unicodes/unicode_page_06.png | Bin 2430 -> 0 bytes .../resources/unicodes/unicode_page_07.png | Bin 2362 -> 0 bytes .../resources/unicodes/unicode_page_09.png | Bin 3541 -> 0 bytes .../resources/unicodes/unicode_page_0a.png | Bin 2332 -> 0 bytes .../resources/unicodes/unicode_page_0b.png | Bin 2457 -> 0 bytes .../resources/unicodes/unicode_page_0c.png | Bin 2566 -> 0 bytes .../resources/unicodes/unicode_page_0d.png | Bin 2801 -> 0 bytes .../resources/unicodes/unicode_page_0e.png | Bin 1409 -> 0 bytes .../resources/unicodes/unicode_page_0f.png | Bin 2360 -> 0 bytes .../resources/unicodes/unicode_page_10.png | Bin 2646 -> 0 bytes .../resources/unicodes/unicode_page_11.png | Bin 1955 -> 0 bytes .../resources/unicodes/unicode_page_12.png | Bin 2942 -> 0 bytes .../resources/unicodes/unicode_page_13.png | Bin 2881 -> 0 bytes .../resources/unicodes/unicode_page_14.png | Bin 1588 -> 0 bytes .../resources/unicodes/unicode_page_15.png | Bin 2138 -> 0 bytes .../resources/unicodes/unicode_page_16.png | Bin 2357 -> 0 bytes .../resources/unicodes/unicode_page_17.png | Bin 2688 -> 0 bytes .../resources/unicodes/unicode_page_18.png | Bin 1946 -> 0 bytes .../resources/unicodes/unicode_page_19.png | Bin 2570 -> 0 bytes .../resources/unicodes/unicode_page_1a.png | Bin 482 -> 0 bytes .../resources/unicodes/unicode_page_1b.png | Bin 2169 -> 0 bytes .../resources/unicodes/unicode_page_1c.png | Bin 1440 -> 0 bytes .../resources/unicodes/unicode_page_1d.png | Bin 2032 -> 0 bytes .../resources/unicodes/unicode_page_1e.png | Bin 1961 -> 0 bytes .../resources/unicodes/unicode_page_1f.png | Bin 1160 -> 0 bytes .../resources/unicodes/unicode_page_20.png | Bin 2111 -> 0 bytes .../resources/unicodes/unicode_page_21.png | Bin 2382 -> 0 bytes .../resources/unicodes/unicode_page_22.png | Bin 1857 -> 0 bytes .../resources/unicodes/unicode_page_23.png | Bin 2252 -> 0 bytes .../resources/unicodes/unicode_page_24.png | Bin 2589 -> 0 bytes .../resources/unicodes/unicode_page_25.png | Bin 1199 -> 0 bytes .../resources/unicodes/unicode_page_26.png | Bin 2648 -> 0 bytes .../resources/unicodes/unicode_page_27.png | Bin 3488 -> 0 bytes .../resources/unicodes/unicode_page_28.png | Bin 272 -> 0 bytes .../resources/unicodes/unicode_page_29.png | Bin 2753 -> 0 bytes .../resources/unicodes/unicode_page_2a.png | Bin 2668 -> 0 bytes .../resources/unicodes/unicode_page_2b.png | Bin 1010 -> 0 bytes .../resources/unicodes/unicode_page_2c.png | Bin 2457 -> 0 bytes .../resources/unicodes/unicode_page_2d.png | Bin 2327 -> 0 bytes .../resources/unicodes/unicode_page_2e.png | Bin 2532 -> 0 bytes .../resources/unicodes/unicode_page_2f.png | Bin 4293 -> 0 bytes .../resources/unicodes/unicode_page_30.png | Bin 3649 -> 0 bytes .../resources/unicodes/unicode_page_31.png | Bin 3101 -> 0 bytes .../resources/unicodes/unicode_page_32.png | Bin 3340 -> 0 bytes .../resources/unicodes/unicode_page_33.png | Bin 4347 -> 0 bytes .../resources/unicodes/unicode_page_34.png | Bin 6026 -> 0 bytes .../resources/unicodes/unicode_page_35.png | Bin 6187 -> 0 bytes .../resources/unicodes/unicode_page_36.png | Bin 6354 -> 0 bytes .../resources/unicodes/unicode_page_37.png | Bin 6085 -> 0 bytes .../resources/unicodes/unicode_page_38.png | Bin 6217 -> 0 bytes .../resources/unicodes/unicode_page_39.png | Bin 6342 -> 0 bytes .../resources/unicodes/unicode_page_3a.png | Bin 6381 -> 0 bytes .../resources/unicodes/unicode_page_3b.png | Bin 6497 -> 0 bytes .../resources/unicodes/unicode_page_3c.png | Bin 6441 -> 0 bytes .../resources/unicodes/unicode_page_3d.png | Bin 6768 -> 0 bytes .../resources/unicodes/unicode_page_3e.png | Bin 6385 -> 0 bytes .../resources/unicodes/unicode_page_3f.png | Bin 6260 -> 0 bytes .../resources/unicodes/unicode_page_40.png | Bin 6315 -> 0 bytes .../resources/unicodes/unicode_page_41.png | Bin 5879 -> 0 bytes .../resources/unicodes/unicode_page_42.png | Bin 6113 -> 0 bytes .../resources/unicodes/unicode_page_43.png | Bin 6356 -> 0 bytes .../resources/unicodes/unicode_page_44.png | Bin 5851 -> 0 bytes .../resources/unicodes/unicode_page_45.png | Bin 6272 -> 0 bytes .../resources/unicodes/unicode_page_46.png | Bin 6334 -> 0 bytes .../resources/unicodes/unicode_page_47.png | Bin 6408 -> 0 bytes .../resources/unicodes/unicode_page_48.png | Bin 6371 -> 0 bytes .../resources/unicodes/unicode_page_49.png | Bin 6361 -> 0 bytes .../resources/unicodes/unicode_page_4a.png | Bin 6056 -> 0 bytes .../resources/unicodes/unicode_page_4b.png | Bin 6203 -> 0 bytes .../resources/unicodes/unicode_page_4c.png | Bin 6337 -> 0 bytes .../resources/unicodes/unicode_page_4d.png | Bin 4966 -> 0 bytes .../resources/unicodes/unicode_page_4e.png | Bin 4741 -> 0 bytes .../resources/unicodes/unicode_page_4f.png | Bin 5621 -> 0 bytes .../resources/unicodes/unicode_page_50.png | Bin 6184 -> 0 bytes .../resources/unicodes/unicode_page_51.png | Bin 5724 -> 0 bytes .../resources/unicodes/unicode_page_52.png | Bin 5620 -> 0 bytes .../resources/unicodes/unicode_page_53.png | Bin 5142 -> 0 bytes .../resources/unicodes/unicode_page_54.png | Bin 5394 -> 0 bytes .../resources/unicodes/unicode_page_55.png | Bin 6115 -> 0 bytes .../resources/unicodes/unicode_page_56.png | Bin 6398 -> 0 bytes .../resources/unicodes/unicode_page_57.png | Bin 5483 -> 0 bytes .../resources/unicodes/unicode_page_58.png | Bin 6174 -> 0 bytes .../resources/unicodes/unicode_page_59.png | Bin 5481 -> 0 bytes .../resources/unicodes/unicode_page_5a.png | Bin 6222 -> 0 bytes .../resources/unicodes/unicode_page_5b.png | Bin 5790 -> 0 bytes .../resources/unicodes/unicode_page_5c.png | Bin 5496 -> 0 bytes .../resources/unicodes/unicode_page_5d.png | Bin 6212 -> 0 bytes .../resources/unicodes/unicode_page_5e.png | Bin 5552 -> 0 bytes .../resources/unicodes/unicode_page_5f.png | Bin 5880 -> 0 bytes .../resources/unicodes/unicode_page_60.png | Bin 5767 -> 0 bytes .../resources/unicodes/unicode_page_61.png | Bin 6553 -> 0 bytes .../resources/unicodes/unicode_page_62.png | Bin 5693 -> 0 bytes .../resources/unicodes/unicode_page_63.png | Bin 6043 -> 0 bytes .../resources/unicodes/unicode_page_64.png | Bin 6588 -> 0 bytes .../resources/unicodes/unicode_page_65.png | Bin 6249 -> 0 bytes .../resources/unicodes/unicode_page_66.png | Bin 5841 -> 0 bytes .../resources/unicodes/unicode_page_67.png | Bin 5604 -> 0 bytes .../resources/unicodes/unicode_page_68.png | Bin 5964 -> 0 bytes .../resources/unicodes/unicode_page_69.png | Bin 6278 -> 0 bytes .../resources/unicodes/unicode_page_6a.png | Bin 6640 -> 0 bytes .../resources/unicodes/unicode_page_6b.png | Bin 6403 -> 0 bytes .../resources/unicodes/unicode_page_6c.png | Bin 5518 -> 0 bytes .../resources/unicodes/unicode_page_6d.png | Bin 5876 -> 0 bytes .../resources/unicodes/unicode_page_6e.png | Bin 6197 -> 0 bytes .../resources/unicodes/unicode_page_6f.png | Bin 6469 -> 0 bytes .../resources/unicodes/unicode_page_70.png | Bin 6514 -> 0 bytes .../resources/unicodes/unicode_page_71.png | Bin 6445 -> 0 bytes .../resources/unicodes/unicode_page_72.png | Bin 6365 -> 0 bytes .../resources/unicodes/unicode_page_73.png | Bin 6232 -> 0 bytes .../resources/unicodes/unicode_page_74.png | Bin 6282 -> 0 bytes .../resources/unicodes/unicode_page_75.png | Bin 5578 -> 0 bytes .../resources/unicodes/unicode_page_76.png | Bin 5956 -> 0 bytes .../resources/unicodes/unicode_page_77.png | Bin 5957 -> 0 bytes .../resources/unicodes/unicode_page_78.png | Bin 6014 -> 0 bytes .../resources/unicodes/unicode_page_79.png | Bin 6125 -> 0 bytes .../resources/unicodes/unicode_page_7a.png | Bin 5936 -> 0 bytes .../resources/unicodes/unicode_page_7b.png | Bin 5192 -> 0 bytes .../resources/unicodes/unicode_page_7c.png | Bin 6145 -> 0 bytes .../resources/unicodes/unicode_page_7d.png | Bin 5934 -> 0 bytes .../resources/unicodes/unicode_page_7e.png | Bin 6448 -> 0 bytes .../resources/unicodes/unicode_page_7f.png | Bin 6138 -> 0 bytes .../resources/unicodes/unicode_page_80.png | Bin 5867 -> 0 bytes .../resources/unicodes/unicode_page_81.png | Bin 6046 -> 0 bytes .../resources/unicodes/unicode_page_82.png | Bin 5214 -> 0 bytes .../resources/unicodes/unicode_page_83.png | Bin 5034 -> 0 bytes .../resources/unicodes/unicode_page_84.png | Bin 5564 -> 0 bytes .../resources/unicodes/unicode_page_85.png | Bin 5885 -> 0 bytes .../resources/unicodes/unicode_page_86.png | Bin 6023 -> 0 bytes .../resources/unicodes/unicode_page_87.png | Bin 6504 -> 0 bytes .../resources/unicodes/unicode_page_88.png | Bin 6283 -> 0 bytes .../resources/unicodes/unicode_page_89.png | Bin 6572 -> 0 bytes .../resources/unicodes/unicode_page_8a.png | Bin 5523 -> 0 bytes .../resources/unicodes/unicode_page_8b.png | Bin 6199 -> 0 bytes .../resources/unicodes/unicode_page_8c.png | Bin 6380 -> 0 bytes .../resources/unicodes/unicode_page_8d.png | Bin 5821 -> 0 bytes .../resources/unicodes/unicode_page_8e.png | Bin 6349 -> 0 bytes .../resources/unicodes/unicode_page_8f.png | Bin 5672 -> 0 bytes .../resources/unicodes/unicode_page_90.png | Bin 5790 -> 0 bytes .../resources/unicodes/unicode_page_91.png | Bin 6015 -> 0 bytes .../resources/unicodes/unicode_page_92.png | Bin 5893 -> 0 bytes .../resources/unicodes/unicode_page_93.png | Bin 6556 -> 0 bytes .../resources/unicodes/unicode_page_94.png | Bin 6478 -> 0 bytes .../resources/unicodes/unicode_page_95.png | Bin 5329 -> 0 bytes .../resources/unicodes/unicode_page_96.png | Bin 5796 -> 0 bytes .../resources/unicodes/unicode_page_97.png | Bin 5773 -> 0 bytes .../resources/unicodes/unicode_page_98.png | Bin 5993 -> 0 bytes .../resources/unicodes/unicode_page_99.png | Bin 6241 -> 0 bytes .../resources/unicodes/unicode_page_9a.png | Bin 6055 -> 0 bytes .../resources/unicodes/unicode_page_9b.png | Bin 5832 -> 0 bytes .../resources/unicodes/unicode_page_9c.png | Bin 6184 -> 0 bytes .../resources/unicodes/unicode_page_9d.png | Bin 5978 -> 0 bytes .../resources/unicodes/unicode_page_9e.png | Bin 6381 -> 0 bytes .../resources/unicodes/unicode_page_9f.png | Bin 4745 -> 0 bytes .../resources/unicodes/unicode_page_a0.png | Bin 3259 -> 0 bytes .../resources/unicodes/unicode_page_a1.png | Bin 3549 -> 0 bytes .../resources/unicodes/unicode_page_a2.png | Bin 3404 -> 0 bytes .../resources/unicodes/unicode_page_a3.png | Bin 3416 -> 0 bytes .../resources/unicodes/unicode_page_a4.png | Bin 2536 -> 0 bytes .../resources/unicodes/unicode_page_a5.png | Bin 3193 -> 0 bytes .../resources/unicodes/unicode_page_a6.png | Bin 1658 -> 0 bytes .../resources/unicodes/unicode_page_a7.png | Bin 1486 -> 0 bytes .../resources/unicodes/unicode_page_a8.png | Bin 2545 -> 0 bytes .../resources/unicodes/unicode_page_a9.png | Bin 1056 -> 0 bytes .../resources/unicodes/unicode_page_aa.png | Bin 1310 -> 0 bytes .../resources/unicodes/unicode_page_ab.png | Bin 166 -> 0 bytes .../resources/unicodes/unicode_page_ac.png | Bin 1258 -> 0 bytes .../resources/unicodes/unicode_page_ad.png | Bin 1472 -> 0 bytes .../resources/unicodes/unicode_page_ae.png | Bin 1319 -> 0 bytes .../resources/unicodes/unicode_page_af.png | Bin 1563 -> 0 bytes .../resources/unicodes/unicode_page_b0.png | Bin 1451 -> 0 bytes .../resources/unicodes/unicode_page_b1.png | Bin 1361 -> 0 bytes .../resources/unicodes/unicode_page_b2.png | Bin 1369 -> 0 bytes .../resources/unicodes/unicode_page_b3.png | Bin 1347 -> 0 bytes .../resources/unicodes/unicode_page_b4.png | Bin 1430 -> 0 bytes .../resources/unicodes/unicode_page_b5.png | Bin 1300 -> 0 bytes .../resources/unicodes/unicode_page_b6.png | Bin 1532 -> 0 bytes .../resources/unicodes/unicode_page_b7.png | Bin 1369 -> 0 bytes .../resources/unicodes/unicode_page_b8.png | Bin 1612 -> 0 bytes .../resources/unicodes/unicode_page_b9.png | Bin 1569 -> 0 bytes .../resources/unicodes/unicode_page_ba.png | Bin 1450 -> 0 bytes .../resources/unicodes/unicode_page_bb.png | Bin 1366 -> 0 bytes .../resources/unicodes/unicode_page_bc.png | Bin 1206 -> 0 bytes .../resources/unicodes/unicode_page_bd.png | Bin 1414 -> 0 bytes .../resources/unicodes/unicode_page_be.png | Bin 1383 -> 0 bytes .../resources/unicodes/unicode_page_bf.png | Bin 1557 -> 0 bytes .../resources/unicodes/unicode_page_c0.png | Bin 1615 -> 0 bytes .../resources/unicodes/unicode_page_c1.png | Bin 1608 -> 0 bytes .../resources/unicodes/unicode_page_c2.png | Bin 1485 -> 0 bytes .../resources/unicodes/unicode_page_c3.png | Bin 1395 -> 0 bytes .../resources/unicodes/unicode_page_c4.png | Bin 1475 -> 0 bytes .../resources/unicodes/unicode_page_c5.png | Bin 1313 -> 0 bytes .../resources/unicodes/unicode_page_c6.png | Bin 1494 -> 0 bytes .../resources/unicodes/unicode_page_c7.png | Bin 1562 -> 0 bytes .../resources/unicodes/unicode_page_c8.png | Bin 1581 -> 0 bytes .../resources/unicodes/unicode_page_c9.png | Bin 1571 -> 0 bytes .../resources/unicodes/unicode_page_ca.png | Bin 1631 -> 0 bytes .../resources/unicodes/unicode_page_cb.png | Bin 1447 -> 0 bytes .../resources/unicodes/unicode_page_cc.png | Bin 1432 -> 0 bytes .../resources/unicodes/unicode_page_cd.png | Bin 1639 -> 0 bytes .../resources/unicodes/unicode_page_ce.png | Bin 1558 -> 0 bytes .../resources/unicodes/unicode_page_cf.png | Bin 1548 -> 0 bytes .../resources/unicodes/unicode_page_d0.png | Bin 1493 -> 0 bytes .../resources/unicodes/unicode_page_d1.png | Bin 1462 -> 0 bytes .../resources/unicodes/unicode_page_d2.png | Bin 1383 -> 0 bytes .../resources/unicodes/unicode_page_d3.png | Bin 1271 -> 0 bytes .../resources/unicodes/unicode_page_d4.png | Bin 1490 -> 0 bytes .../resources/unicodes/unicode_page_d5.png | Bin 1488 -> 0 bytes .../resources/unicodes/unicode_page_d6.png | Bin 1757 -> 0 bytes .../resources/unicodes/unicode_page_d7.png | Bin 1286 -> 0 bytes .../resources/unicodes/unicode_page_f9.png | Bin 6615 -> 0 bytes .../resources/unicodes/unicode_page_fa.png | Bin 5451 -> 0 bytes .../resources/unicodes/unicode_page_fb.png | Bin 1560 -> 0 bytes .../resources/unicodes/unicode_page_fc.png | Bin 2292 -> 0 bytes .../resources/unicodes/unicode_page_fd.png | Bin 2577 -> 0 bytes .../resources/unicodes/unicode_page_fe.png | Bin 1731 -> 0 bytes .../resources/unicodes/unicode_page_ff.png | Bin 2669 -> 0 bytes velocity/.gitignore | 42 + velocity/build.gradle.kts | 2 + velocity/src/main/resources/plugin.yml | 9 + 624 files changed, 12741 insertions(+), 18497 deletions(-) create mode 100644 api/.gitignore create mode 100644 api/build.gradle.kts create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/CustomNameplatesPlugin.java rename src/main/java/net/momirealms/customnameplates/object/scheduler/BukkitTimerTask.java => api/src/main/java/net/momirealms/customnameplates/api/common/Key.java (51%) rename src/main/java/net/momirealms/customnameplates/object/placeholders/StaticText.java => api/src/main/java/net/momirealms/customnameplates/api/common/Pair.java (76%) create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/common/SimpleLocation.java create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/common/Tuple.java create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/data/OnlineUser.java create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/data/PlayerData.java create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/event/CustomNameplatesReloadEvent.java create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/event/NameplateDataLoadEvent.java create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/event/PlayerEquipBubbleEvent.java create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/event/PlayerEquipNameplateEvent.java create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/event/PlayerUnequipBubbleEvent.java create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/event/PlayerUnequipNameplateEvent.java create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/manager/ActionBarManager.java create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/manager/AdventureManager.java create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/manager/BackGroundManager.java create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/manager/BossBarManager.java create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/manager/ImageManager.java create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/manager/NameplateManager.java create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/manager/PlaceholderManager.java create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/manager/RequirementManager.java create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/manager/ResourcePackManager.java create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/manager/StorageManager.java create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/manager/TeamManager.java create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/manager/TeamTagManager.java create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/manager/UnlimitedTagManager.java create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/manager/VersionManager.java create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/manager/WidthManager.java create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/mechanic/background/BackGround.java create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/mechanic/character/CharacterArranger.java create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/mechanic/character/ConfiguredChar.java create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/mechanic/font/OffsetFont.java create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/mechanic/misc/ViewerText.java create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/mechanic/nameplate/CachedNameplate.java create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/mechanic/nameplate/Nameplate.java create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/mechanic/nameplate/TagMode.java create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/mechanic/placeholder/BackGroundText.java create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/mechanic/placeholder/CachedText.java create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/mechanic/placeholder/ConditionalText.java create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/mechanic/placeholder/DescentText.java create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/mechanic/placeholder/NameplateText.java create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/mechanic/placeholder/StaticText.java create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/mechanic/placeholder/SwitchText.java create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/mechanic/placeholder/VanillaHud.java create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/mechanic/tag/NameplatePlayer.java create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/mechanic/tag/team/TeamPlayer.java create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/mechanic/tag/unlimited/NamedEntity.java create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/mechanic/tag/unlimited/UnlimitedObject.java create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/mechanic/tag/unlimited/UnlimitedPlayer.java create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/mechanic/tag/unlimited/UnlimitedTagSetting.java create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/mechanic/team/TeamCollisionRule.java create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/mechanic/team/TeamColor.java create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/mechanic/team/TeamCreatePacket.java create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/mechanic/team/TeamRemovePacket.java create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/mechanic/team/TeamTagVisibility.java create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/mechanic/team/TeamUpdatePacket.java create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/requirement/Condition.java rename {src/main/java/net/momirealms/customnameplates/object/requirements => api/src/main/java/net/momirealms/customnameplates/api/requirement}/Requirement.java (75%) create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/requirement/RequirementExpansion.java rename src/main/java/net/momirealms/customnameplates/object/Function.java => api/src/main/java/net/momirealms/customnameplates/api/requirement/RequirementFactory.java (64%) rename src/main/java/net/momirealms/customnameplates/object/scheduler/TimerTask.java => api/src/main/java/net/momirealms/customnameplates/api/scheduler/CancellableTask.java (76%) create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/scheduler/Scheduler.java create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/util/FontUtils.java create mode 100644 api/src/main/java/net/momirealms/customnameplates/api/util/LogUtils.java delete mode 100644 build.gradle create mode 100644 build.gradle.kts create mode 100644 bungeecord/.gitignore create mode 100644 bungeecord/build.gradle.kts create mode 100644 bungeecord/src/main/resources/plugin.yml create mode 100644 jitpack.yml delete mode 100644 libs/MagicCosmetics-2.3.7-API.jar delete mode 100644 libs/TrChat-2.0.8.jar delete mode 100644 libs/VentureChat-3.6.0.jar delete mode 100644 libs/oraxen-api.jar create mode 100644 paper/.gitignore create mode 100644 paper/build.gradle.kts rename {libs => paper/libs}/BiomeAPI.jar (67%) create mode 100644 paper/libs/CMI-API-9.6.5.0.jar create mode 100644 paper/libs/TrChat-2.0.11.jar create mode 100644 paper/libs/VentureChat-3.7.1.jar create mode 100644 paper/src/main/java/net/momirealms/customnameplates/paper/CustomNameplatesPluginImpl.java create mode 100644 paper/src/main/java/net/momirealms/customnameplates/paper/adventure/AdventureManagerImpl.java create mode 100644 paper/src/main/java/net/momirealms/customnameplates/paper/command/CommandManager.java rename {src/main/java/net/momirealms/customnameplates => paper/src/main/java/net/momirealms/customnameplates/paper}/helper/LibraryLoader.java (53%) rename {src/main/java/net/momirealms/customnameplates => paper/src/main/java/net/momirealms/customnameplates/paper}/helper/MavenLibraries.java (93%) rename {src/main/java/net/momirealms/customnameplates => paper/src/main/java/net/momirealms/customnameplates/paper}/helper/MavenLibrary.java (93%) rename {src/main/java/net/momirealms/customnameplates => paper/src/main/java/net/momirealms/customnameplates/paper}/helper/Repository.java (94%) rename {src/main/java/net/momirealms/customnameplates => paper/src/main/java/net/momirealms/customnameplates/paper}/helper/URLClassLoaderAccess.java (94%) create mode 100644 paper/src/main/java/net/momirealms/customnameplates/paper/mechanic/actionbar/ActionBarConfig.java create mode 100644 paper/src/main/java/net/momirealms/customnameplates/paper/mechanic/actionbar/ActionBarManagerImpl.java create mode 100644 paper/src/main/java/net/momirealms/customnameplates/paper/mechanic/actionbar/ActionBarReceiver.java rename {src/main/java/net/momirealms/customnameplates/listener/packet => paper/src/main/java/net/momirealms/customnameplates/paper/mechanic/actionbar/listener}/ActionBarListener.java (70%) rename {src/main/java/net/momirealms/customnameplates/listener/packet => paper/src/main/java/net/momirealms/customnameplates/paper/mechanic/actionbar/listener}/ChatMessageListener.java (70%) rename {src/main/java/net/momirealms/customnameplates/listener/packet => paper/src/main/java/net/momirealms/customnameplates/paper/mechanic/actionbar/listener}/SystemChatListener.java (70%) create mode 100644 paper/src/main/java/net/momirealms/customnameplates/paper/mechanic/background/BackGroundManagerImpl.java create mode 100644 paper/src/main/java/net/momirealms/customnameplates/paper/mechanic/bossbar/BarColor.java create mode 100644 paper/src/main/java/net/momirealms/customnameplates/paper/mechanic/bossbar/BossBar.java create mode 100644 paper/src/main/java/net/momirealms/customnameplates/paper/mechanic/bossbar/BossBarConfig.java create mode 100644 paper/src/main/java/net/momirealms/customnameplates/paper/mechanic/bossbar/BossBarManagerImpl.java create mode 100644 paper/src/main/java/net/momirealms/customnameplates/paper/mechanic/bossbar/BossBarReceiver.java rename {src/main/java/net/momirealms/customnameplates/object => paper/src/main/java/net/momirealms/customnameplates/paper/mechanic}/bossbar/Overlay.java (64%) create mode 100644 paper/src/main/java/net/momirealms/customnameplates/paper/mechanic/font/FontData.java create mode 100644 paper/src/main/java/net/momirealms/customnameplates/paper/mechanic/font/WidthManagerImpl.java create mode 100644 paper/src/main/java/net/momirealms/customnameplates/paper/mechanic/image/ImageManagerImpl.java create mode 100644 paper/src/main/java/net/momirealms/customnameplates/paper/mechanic/misc/CoolDownManager.java create mode 100644 paper/src/main/java/net/momirealms/customnameplates/paper/mechanic/misc/DisplayController.java create mode 100644 paper/src/main/java/net/momirealms/customnameplates/paper/mechanic/misc/MessageManager.java create mode 100644 paper/src/main/java/net/momirealms/customnameplates/paper/mechanic/misc/PacketManager.java create mode 100644 paper/src/main/java/net/momirealms/customnameplates/paper/mechanic/misc/TimeLimitText.java rename src/main/java/net/momirealms/customnameplates/helper/VersionHelper.java => paper/src/main/java/net/momirealms/customnameplates/paper/mechanic/misc/VersionManagerImpl.java (59%) create mode 100644 paper/src/main/java/net/momirealms/customnameplates/paper/mechanic/nameplate/NameplateManagerImpl.java rename {src/main/java/net/momirealms/customnameplates/listener/packet => paper/src/main/java/net/momirealms/customnameplates/paper/mechanic/nameplate/tag/listener}/EntityDestroyListener.java (67%) rename {src/main/java/net/momirealms/customnameplates/listener/packet => paper/src/main/java/net/momirealms/customnameplates/paper/mechanic/nameplate/tag/listener}/EntityLookListener.java (71%) rename {src/main/java/net/momirealms/customnameplates/listener/packet => paper/src/main/java/net/momirealms/customnameplates/paper/mechanic/nameplate/tag/listener}/EntityMoveListener.java (71%) rename {src/main/java/net/momirealms/customnameplates/listener/packet => paper/src/main/java/net/momirealms/customnameplates/paper/mechanic/nameplate/tag/listener}/EntitySpawnListener.java (59%) rename {src/main/java/net/momirealms/customnameplates/listener/packet => paper/src/main/java/net/momirealms/customnameplates/paper/mechanic/nameplate/tag/listener}/EntityTeleportListener.java (58%) rename {src/main/java/net/momirealms/customnameplates/listener/compatibility => paper/src/main/java/net/momirealms/customnameplates/paper/mechanic/nameplate/tag/listener}/MagicCosmeticsListener.java (54%) create mode 100644 paper/src/main/java/net/momirealms/customnameplates/paper/mechanic/nameplate/tag/team/TeamTagManagerImpl.java create mode 100644 paper/src/main/java/net/momirealms/customnameplates/paper/mechanic/nameplate/tag/unlimited/NamedEntityImpl.java create mode 100644 paper/src/main/java/net/momirealms/customnameplates/paper/mechanic/nameplate/tag/unlimited/UnlimitedTagManagerImpl.java create mode 100644 paper/src/main/java/net/momirealms/customnameplates/paper/mechanic/pack/ResourcePackManagerImpl.java create mode 100644 paper/src/main/java/net/momirealms/customnameplates/paper/mechanic/placeholder/PlaceholderManagerImpl.java create mode 100644 paper/src/main/java/net/momirealms/customnameplates/paper/mechanic/placeholder/PluginPlaceholders.java rename src/main/java/net/momirealms/customnameplates/object/requirements/papi/PapiEquals.java => paper/src/main/java/net/momirealms/customnameplates/paper/mechanic/requirement/EmptyRequirement.java (58%) create mode 100644 paper/src/main/java/net/momirealms/customnameplates/paper/mechanic/requirement/RequirementManagerImpl.java create mode 100644 paper/src/main/java/net/momirealms/customnameplates/paper/mechanic/team/Team.java create mode 100644 paper/src/main/java/net/momirealms/customnameplates/paper/mechanic/team/TeamManagerImpl.java create mode 100644 paper/src/main/java/net/momirealms/customnameplates/paper/mechanic/team/packet/TeamPacketAdaptor.java create mode 100644 paper/src/main/java/net/momirealms/customnameplates/paper/mechanic/team/packet/TeamPacket_1_17.java create mode 100644 paper/src/main/java/net/momirealms/customnameplates/paper/mechanic/team/provider/CMIProvider.java create mode 100644 paper/src/main/java/net/momirealms/customnameplates/paper/mechanic/team/provider/DefaultProvider.java create mode 100644 paper/src/main/java/net/momirealms/customnameplates/paper/mechanic/team/provider/TABProvider.java create mode 100644 paper/src/main/java/net/momirealms/customnameplates/paper/mechanic/team/provider/TeamProvider.java create mode 100644 paper/src/main/java/net/momirealms/customnameplates/paper/scheduler/BukkitSchedulerImpl.java create mode 100644 paper/src/main/java/net/momirealms/customnameplates/paper/scheduler/FoliaSchedulerImpl.java create mode 100644 paper/src/main/java/net/momirealms/customnameplates/paper/scheduler/SchedulerImpl.java create mode 100644 paper/src/main/java/net/momirealms/customnameplates/paper/scheduler/SyncScheduler.java create mode 100644 paper/src/main/java/net/momirealms/customnameplates/paper/setting/CNConfig.java create mode 100644 paper/src/main/java/net/momirealms/customnameplates/paper/setting/CNLocale.java rename {src/main/java/net/momirealms/customnameplates/data => paper/src/main/java/net/momirealms/customnameplates/paper/storage}/DataStorageInterface.java (60%) create mode 100644 paper/src/main/java/net/momirealms/customnameplates/paper/storage/StorageManagerImpl.java rename {src/main/java/net/momirealms/customnameplates/data => paper/src/main/java/net/momirealms/customnameplates/paper/storage}/StorageType.java (83%) create mode 100644 paper/src/main/java/net/momirealms/customnameplates/paper/storage/method/AbstractStorage.java create mode 100644 paper/src/main/java/net/momirealms/customnameplates/paper/storage/method/database/nosql/MongoDBImpl.java create mode 100644 paper/src/main/java/net/momirealms/customnameplates/paper/storage/method/database/nosql/RedisManager.java create mode 100644 paper/src/main/java/net/momirealms/customnameplates/paper/storage/method/database/sql/AbstractHikariDatabase.java create mode 100644 paper/src/main/java/net/momirealms/customnameplates/paper/storage/method/database/sql/AbstractSQLDatabase.java create mode 100644 paper/src/main/java/net/momirealms/customnameplates/paper/storage/method/database/sql/H2Impl.java rename src/main/java/net/momirealms/customnameplates/object/requirements/papi/ExpressionAnd.java => paper/src/main/java/net/momirealms/customnameplates/paper/storage/method/database/sql/MariaDBImpl.java (62%) rename src/main/java/net/momirealms/customnameplates/object/requirements/papi/ExpressionOr.java => paper/src/main/java/net/momirealms/customnameplates/paper/storage/method/database/sql/MySQLImpl.java (62%) create mode 100644 paper/src/main/java/net/momirealms/customnameplates/paper/storage/method/database/sql/SQLiteImpl.java create mode 100644 paper/src/main/java/net/momirealms/customnameplates/paper/storage/method/file/JsonImpl.java create mode 100644 paper/src/main/java/net/momirealms/customnameplates/paper/storage/method/file/YAMLImpl.java rename {src/main/java/net/momirealms/customnameplates/utils => paper/src/main/java/net/momirealms/customnameplates/paper/util}/ClassUtils.java (98%) create mode 100644 paper/src/main/java/net/momirealms/customnameplates/paper/util/ConfigUtils.java create mode 100644 paper/src/main/java/net/momirealms/customnameplates/paper/util/LocationUtils.java create mode 100644 paper/src/main/java/net/momirealms/customnameplates/paper/util/ReflectionUtils.java rename {src => paper/src}/main/resources/ResourcePack/assets/minecraft/shaders/core/rendertype_text.fsh (100%) rename {src => paper/src}/main/resources/ResourcePack/assets/minecraft/shaders/core/rendertype_text.json (100%) rename {src => paper/src}/main/resources/ResourcePack/assets/minecraft/shaders/core/rendertype_text.vsh (100%) rename {src => paper/src}/main/resources/ResourcePack/assets/minecraft/textures/gui/bars.png (100%) rename {src => paper/src}/main/resources/ResourcePack/assets/minecraft/textures/gui/sprites/boss_bar/yellow_background.png (100%) rename {src => paper/src}/main/resources/ResourcePack/assets/minecraft/textures/gui/sprites/boss_bar/yellow_progress.png (100%) rename {src => paper/src}/main/resources/ResourcePack/pack.mcmeta (100%) create mode 100644 paper/src/main/resources/config.yml create mode 100644 paper/src/main/resources/configs/actionbar.yml create mode 100644 paper/src/main/resources/configs/bossbar.yml rename {src => paper/src}/main/resources/configs/custom-placeholders.yml (90%) create mode 100644 paper/src/main/resources/configs/image-width.yml create mode 100644 paper/src/main/resources/configs/nameplate.yml rename {src => paper/src}/main/resources/contents/backgrounds/b0.png (100%) rename {src => paper/src}/main/resources/contents/backgrounds/b1.png (100%) rename {src => paper/src}/main/resources/contents/backgrounds/b128.png (100%) rename {src => paper/src}/main/resources/contents/backgrounds/b16.png (100%) rename {src => paper/src}/main/resources/contents/backgrounds/b2.png (100%) rename {src => paper/src}/main/resources/contents/backgrounds/b32.png (100%) rename {src => paper/src}/main/resources/contents/backgrounds/b4.png (100%) rename {src => paper/src}/main/resources/contents/backgrounds/b64.png (100%) rename {src => paper/src}/main/resources/contents/backgrounds/b8.png (100%) rename {src => paper/src}/main/resources/contents/backgrounds/bedrock_1.yml (100%) rename {src => paper/src}/main/resources/contents/backgrounds/bedrock_2.yml (100%) rename {src => paper/src}/main/resources/contents/backgrounds/bedrock_3.yml (100%) rename {src => paper/src}/main/resources/contents/bubbles/chat.yml (100%) rename {src => paper/src}/main/resources/contents/bubbles/chat_left.png (100%) rename {src => paper/src}/main/resources/contents/bubbles/chat_middle.png (100%) rename {src => paper/src}/main/resources/contents/bubbles/chat_right.png (100%) rename {src => paper/src}/main/resources/contents/bubbles/chat_tail.png (100%) rename {src => paper/src}/main/resources/contents/images/bell.png (100%) rename {src => paper/src}/main/resources/contents/images/bell.yml (100%) rename {src => paper/src}/main/resources/contents/images/bubble.png (100%) rename {src => paper/src}/main/resources/contents/images/bubble.yml (100%) rename {src => paper/src}/main/resources/contents/images/clock.png (100%) rename {src => paper/src}/main/resources/contents/images/clock.yml (100%) rename {src => paper/src}/main/resources/contents/images/coin.png (100%) rename {src => paper/src}/main/resources/contents/images/coin.yml (100%) rename {src => paper/src}/main/resources/contents/images/compass.png (100%) rename {src => paper/src}/main/resources/contents/images/compass.yml (100%) rename {src => paper/src}/main/resources/contents/images/stamina_0.png (100%) rename {src => paper/src}/main/resources/contents/images/stamina_0.yml (100%) rename {src => paper/src}/main/resources/contents/images/stamina_1.png (100%) rename {src => paper/src}/main/resources/contents/images/stamina_1.yml (100%) rename {src => paper/src}/main/resources/contents/images/stamina_2.png (100%) rename {src => paper/src}/main/resources/contents/images/stamina_2.yml (100%) rename {src => paper/src}/main/resources/contents/images/weather.png (100%) rename {src => paper/src}/main/resources/contents/images/weather.yml (100%) rename {src => paper/src}/main/resources/contents/nameplates/cat.yml (100%) rename {src => paper/src}/main/resources/contents/nameplates/cat_left.png (100%) rename {src => paper/src}/main/resources/contents/nameplates/cat_middle.png (100%) rename {src => paper/src}/main/resources/contents/nameplates/cat_right.png (100%) rename {src => paper/src}/main/resources/contents/nameplates/cheems.yml (100%) rename {src => paper/src}/main/resources/contents/nameplates/cheems_left.png (100%) rename {src => paper/src}/main/resources/contents/nameplates/cheems_middle.png (100%) rename {src => paper/src}/main/resources/contents/nameplates/cheems_right.png (100%) rename {src => paper/src}/main/resources/contents/nameplates/egg.yml (100%) rename {src => paper/src}/main/resources/contents/nameplates/egg_left.png (100%) rename {src => paper/src}/main/resources/contents/nameplates/egg_middle.png (100%) rename {src => paper/src}/main/resources/contents/nameplates/egg_right.png (100%) rename {src => paper/src}/main/resources/contents/nameplates/halloween.yml (100%) rename {src => paper/src}/main/resources/contents/nameplates/halloween_left.png (100%) rename {src => paper/src}/main/resources/contents/nameplates/halloween_middle.png (100%) rename {src => paper/src}/main/resources/contents/nameplates/halloween_right.png (100%) rename {src => paper/src}/main/resources/contents/nameplates/hutao.yml (100%) rename {src => paper/src}/main/resources/contents/nameplates/hutao_left.png (100%) rename {src => paper/src}/main/resources/contents/nameplates/hutao_middle.png (100%) rename {src => paper/src}/main/resources/contents/nameplates/hutao_right.png (100%) rename {src => paper/src}/main/resources/contents/nameplates/rabbit.yml (100%) rename {src => paper/src}/main/resources/contents/nameplates/rabbit_left.png (100%) rename {src => paper/src}/main/resources/contents/nameplates/rabbit_middle.png (100%) rename {src => paper/src}/main/resources/contents/nameplates/rabbit_right.png (100%) rename {src => paper/src}/main/resources/contents/nameplates/starsky.yml (100%) rename {src => paper/src}/main/resources/contents/nameplates/starsky_left.png (100%) rename {src => paper/src}/main/resources/contents/nameplates/starsky_middle.png (100%) rename {src => paper/src}/main/resources/contents/nameplates/starsky_right.png (100%) rename {src => paper/src}/main/resources/contents/nameplates/trident.yml (100%) rename {src => paper/src}/main/resources/contents/nameplates/trident_left.png (100%) rename {src => paper/src}/main/resources/contents/nameplates/trident_middle.png (100%) rename {src => paper/src}/main/resources/contents/nameplates/trident_right.png (100%) rename {src => paper/src}/main/resources/contents/nameplates/wither.yml (100%) rename {src => paper/src}/main/resources/contents/nameplates/wither_left.png (100%) rename {src => paper/src}/main/resources/contents/nameplates/wither_middle.png (100%) rename {src => paper/src}/main/resources/contents/nameplates/wither_right.png (100%) rename {src => paper/src}/main/resources/contents/nameplates/xmas.yml (100%) rename {src => paper/src}/main/resources/contents/nameplates/xmas_left.png (100%) rename {src => paper/src}/main/resources/contents/nameplates/xmas_middle.png (100%) rename {src => paper/src}/main/resources/contents/nameplates/xmas_right.png (100%) create mode 100644 paper/src/main/resources/database.yml rename {src => paper/src}/main/resources/messages/chinese.yml (85%) rename {src => paper/src}/main/resources/messages/english.yml (85%) rename {src => paper/src}/main/resources/messages/french.yml (85%) rename {src => paper/src}/main/resources/messages/russian.yml (84%) rename {src => paper/src}/main/resources/messages/spanish.yml (84%) rename {src => paper/src}/main/resources/messages/turkish.yml (85%) create mode 100644 paper/src/main/resources/plugin.yml create mode 100644 paper/src/main/resources/schema/h2.sql create mode 100644 paper/src/main/resources/schema/mariadb.sql create mode 100644 paper/src/main/resources/schema/mysql.sql create mode 100644 paper/src/main/resources/schema/sqlite.sql rename {src => paper/src}/main/resources/space_split.png (100%) delete mode 100644 settings.gradle create mode 100644 settings.gradle.kts delete mode 100644 src/main/java/net/momirealms/customnameplates/CustomNameplates.java delete mode 100644 src/main/java/net/momirealms/customnameplates/api/CustomNameplatesAPI.java delete mode 100644 src/main/java/net/momirealms/customnameplates/api/events/BubblesEvent.java delete mode 100644 src/main/java/net/momirealms/customnameplates/bungeecord/BungeeConfigManager.java delete mode 100644 src/main/java/net/momirealms/customnameplates/bungeecord/BungeeEventListener.java delete mode 100644 src/main/java/net/momirealms/customnameplates/bungeecord/CustomNameplatesBC.java delete mode 100644 src/main/java/net/momirealms/customnameplates/command/AbstractMainCommand.java delete mode 100644 src/main/java/net/momirealms/customnameplates/command/AbstractSubCommand.java delete mode 100644 src/main/java/net/momirealms/customnameplates/command/BubblesCommand.java delete mode 100644 src/main/java/net/momirealms/customnameplates/command/NameplateCommand.java delete mode 100644 src/main/java/net/momirealms/customnameplates/command/subcmd/AboutCommand.java delete mode 100644 src/main/java/net/momirealms/customnameplates/command/subcmd/BubblesEquipCommand.java delete mode 100644 src/main/java/net/momirealms/customnameplates/command/subcmd/BubblesForceEquipCommand.java delete mode 100644 src/main/java/net/momirealms/customnameplates/command/subcmd/BubblesForceUnequipCommand.java delete mode 100644 src/main/java/net/momirealms/customnameplates/command/subcmd/BubblesListCommand.java delete mode 100644 src/main/java/net/momirealms/customnameplates/command/subcmd/BubblesUnequipCommand.java delete mode 100644 src/main/java/net/momirealms/customnameplates/command/subcmd/ForcePreviewCommand.java delete mode 100644 src/main/java/net/momirealms/customnameplates/command/subcmd/HelpCommand.java delete mode 100644 src/main/java/net/momirealms/customnameplates/command/subcmd/NameplatesEquipCommand.java delete mode 100644 src/main/java/net/momirealms/customnameplates/command/subcmd/NameplatesForceEquipCommand.java delete mode 100644 src/main/java/net/momirealms/customnameplates/command/subcmd/NameplatesForceUnequipCommand.java delete mode 100644 src/main/java/net/momirealms/customnameplates/command/subcmd/NameplatesListCommand.java delete mode 100644 src/main/java/net/momirealms/customnameplates/command/subcmd/NameplatesUnequipCommand.java delete mode 100644 src/main/java/net/momirealms/customnameplates/command/subcmd/PreviewCommand.java delete mode 100644 src/main/java/net/momirealms/customnameplates/command/subcmd/ReloadCommand.java delete mode 100644 src/main/java/net/momirealms/customnameplates/data/FileStorageImpl.java delete mode 100644 src/main/java/net/momirealms/customnameplates/data/MySQLStorageImpl.java delete mode 100644 src/main/java/net/momirealms/customnameplates/data/PlayerData.java delete mode 100644 src/main/java/net/momirealms/customnameplates/data/SqlConnection.java delete mode 100644 src/main/java/net/momirealms/customnameplates/data/SqlConstants.java delete mode 100644 src/main/java/net/momirealms/customnameplates/helper/Log.java delete mode 100644 src/main/java/net/momirealms/customnameplates/helper/NonnullByDefault.java delete mode 100644 src/main/java/net/momirealms/customnameplates/listener/AbstractChatListener.java delete mode 100644 src/main/java/net/momirealms/customnameplates/listener/AsyncChatListener.java delete mode 100644 src/main/java/net/momirealms/customnameplates/listener/EntityTagListener.java delete mode 100644 src/main/java/net/momirealms/customnameplates/listener/JoinQuitListener.java delete mode 100644 src/main/java/net/momirealms/customnameplates/listener/TrChatListener.java delete mode 100644 src/main/java/net/momirealms/customnameplates/listener/VentureChatListener.java delete mode 100644 src/main/java/net/momirealms/customnameplates/manager/ActionBarManager.java delete mode 100644 src/main/java/net/momirealms/customnameplates/manager/BackgroundManager.java delete mode 100644 src/main/java/net/momirealms/customnameplates/manager/BossBarManager.java delete mode 100644 src/main/java/net/momirealms/customnameplates/manager/ChatBubblesManager.java delete mode 100644 src/main/java/net/momirealms/customnameplates/manager/ConfigManager.java delete mode 100644 src/main/java/net/momirealms/customnameplates/manager/DataManager.java delete mode 100644 src/main/java/net/momirealms/customnameplates/manager/FontManager.java delete mode 100644 src/main/java/net/momirealms/customnameplates/manager/ImageManager.java delete mode 100644 src/main/java/net/momirealms/customnameplates/manager/MessageManager.java delete mode 100644 src/main/java/net/momirealms/customnameplates/manager/NameplateManager.java delete mode 100644 src/main/java/net/momirealms/customnameplates/manager/PlaceholderManager.java delete mode 100644 src/main/java/net/momirealms/customnameplates/manager/ResourceManager.java delete mode 100644 src/main/java/net/momirealms/customnameplates/manager/TeamManager.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/ConditionalText.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/DisplayMode.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/DynamicText.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/SimpleChar.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/actionbar/ActionBarConfig.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/actionbar/ActionBarSender.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/actionbar/ActionBarTask.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/background/BackGroundConfig.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/bossbar/BossBarConfig.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/bossbar/BossBarSender.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/bossbar/BossBarTask.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/bubble/BubbleConfig.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/carrier/AbstractPacketsHandler.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/carrier/AbstractTextCarrier.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/carrier/DisableNameplate.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/carrier/NamedEntity.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/carrier/NamedEntityCarrier.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/carrier/NamedEntityImpl.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/carrier/NamedEntityManager.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/carrier/NamedEntityPacketsHandler.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/carrier/TeamInfoCarrier.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/carrier/TextDisplayMeta.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/carrier/VehicleChecker.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/font/ASCIIWidth.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/font/OffsetFont.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/img/ImageParser.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/img/ItemsAdderImageImpl.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/img/OraxenImageImpl.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/nameplate/NameplateConfig.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/nameplate/NameplatesTeam.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/placeholders/BackGroundText.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/placeholders/ConditionalTexts.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/placeholders/DescentText.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/placeholders/NameplatePlaceholders.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/placeholders/NameplateText.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/placeholders/VanillaHud.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/requirements/BiomeImpl.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/requirements/CustomPapiImpl.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/requirements/DateImpl.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/requirements/GeyserImpl.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/requirements/PermissionImpl.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/requirements/TimeImpl.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/requirements/WeatherImpl.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/requirements/WorldImpl.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/requirements/YPosImpl.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/requirements/papi/PapiGreater.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/requirements/papi/PapiNoLarger.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/requirements/papi/PapiNoLess.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/requirements/papi/PapiNotEquals.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/requirements/papi/PapiRegex.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/requirements/papi/PapiRequirement.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/requirements/papi/PapiSmaller.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/scheduler/BukkitSchedulerImpl.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/scheduler/FoliaSchedulerImpl.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/scheduler/FoliaTimerTask.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/scheduler/Scheduler.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/scheduler/SchedulerPlatform.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/team/TeamNameInterface.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/team/TeamPacketInterface.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/team/name/PlayerNameTeamImpl.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/team/name/TABBungeeCordImpl.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/team/name/TABImpl.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/team/name/VelocitabImpl.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/team/packet/TeamInfoImpl.java delete mode 100644 src/main/java/net/momirealms/customnameplates/object/team/packet/TeamVisibilityImpl.java delete mode 100644 src/main/java/net/momirealms/customnameplates/utils/AdventureUtils.java delete mode 100644 src/main/java/net/momirealms/customnameplates/utils/ArmorStandUtils.java delete mode 100644 src/main/java/net/momirealms/customnameplates/utils/ConfigUtils.java delete mode 100644 src/main/java/net/momirealms/customnameplates/utils/GeyserUtils.java delete mode 100644 src/main/java/net/momirealms/customnameplates/velocity/CustomNameplatesVC.java delete mode 100644 src/main/resources/bungee.yml delete mode 100644 src/main/resources/config.yml delete mode 100644 src/main/resources/configs/actionbar.yml delete mode 100644 src/main/resources/configs/bossbar.yml delete mode 100644 src/main/resources/configs/bubble.yml delete mode 100644 src/main/resources/configs/image-width.yml delete mode 100644 src/main/resources/configs/nameplate.yml delete mode 100644 src/main/resources/database.yml delete mode 100644 src/main/resources/plugin.yml delete mode 100644 src/main/resources/templates/default.json delete mode 100644 src/main/resources/templates/unicode.json delete mode 100644 src/main/resources/unicodes/unicode_page_00.png delete mode 100644 src/main/resources/unicodes/unicode_page_01.png delete mode 100644 src/main/resources/unicodes/unicode_page_02.png delete mode 100644 src/main/resources/unicodes/unicode_page_03.png delete mode 100644 src/main/resources/unicodes/unicode_page_04.png delete mode 100644 src/main/resources/unicodes/unicode_page_05.png delete mode 100644 src/main/resources/unicodes/unicode_page_06.png delete mode 100644 src/main/resources/unicodes/unicode_page_07.png delete mode 100644 src/main/resources/unicodes/unicode_page_09.png delete mode 100644 src/main/resources/unicodes/unicode_page_0a.png delete mode 100644 src/main/resources/unicodes/unicode_page_0b.png delete mode 100644 src/main/resources/unicodes/unicode_page_0c.png delete mode 100644 src/main/resources/unicodes/unicode_page_0d.png delete mode 100644 src/main/resources/unicodes/unicode_page_0e.png delete mode 100644 src/main/resources/unicodes/unicode_page_0f.png delete mode 100644 src/main/resources/unicodes/unicode_page_10.png delete mode 100644 src/main/resources/unicodes/unicode_page_11.png delete mode 100644 src/main/resources/unicodes/unicode_page_12.png delete mode 100644 src/main/resources/unicodes/unicode_page_13.png delete mode 100644 src/main/resources/unicodes/unicode_page_14.png delete mode 100644 src/main/resources/unicodes/unicode_page_15.png delete mode 100644 src/main/resources/unicodes/unicode_page_16.png delete mode 100644 src/main/resources/unicodes/unicode_page_17.png delete mode 100644 src/main/resources/unicodes/unicode_page_18.png delete mode 100644 src/main/resources/unicodes/unicode_page_19.png delete mode 100644 src/main/resources/unicodes/unicode_page_1a.png delete mode 100644 src/main/resources/unicodes/unicode_page_1b.png delete mode 100644 src/main/resources/unicodes/unicode_page_1c.png delete mode 100644 src/main/resources/unicodes/unicode_page_1d.png delete mode 100644 src/main/resources/unicodes/unicode_page_1e.png delete mode 100644 src/main/resources/unicodes/unicode_page_1f.png delete mode 100644 src/main/resources/unicodes/unicode_page_20.png delete mode 100644 src/main/resources/unicodes/unicode_page_21.png delete mode 100644 src/main/resources/unicodes/unicode_page_22.png delete mode 100644 src/main/resources/unicodes/unicode_page_23.png delete mode 100644 src/main/resources/unicodes/unicode_page_24.png delete mode 100644 src/main/resources/unicodes/unicode_page_25.png delete mode 100644 src/main/resources/unicodes/unicode_page_26.png delete mode 100644 src/main/resources/unicodes/unicode_page_27.png delete mode 100644 src/main/resources/unicodes/unicode_page_28.png delete mode 100644 src/main/resources/unicodes/unicode_page_29.png delete mode 100644 src/main/resources/unicodes/unicode_page_2a.png delete mode 100644 src/main/resources/unicodes/unicode_page_2b.png delete mode 100644 src/main/resources/unicodes/unicode_page_2c.png delete mode 100644 src/main/resources/unicodes/unicode_page_2d.png delete mode 100644 src/main/resources/unicodes/unicode_page_2e.png delete mode 100644 src/main/resources/unicodes/unicode_page_2f.png delete mode 100644 src/main/resources/unicodes/unicode_page_30.png delete mode 100644 src/main/resources/unicodes/unicode_page_31.png delete mode 100644 src/main/resources/unicodes/unicode_page_32.png delete mode 100644 src/main/resources/unicodes/unicode_page_33.png delete mode 100644 src/main/resources/unicodes/unicode_page_34.png delete mode 100644 src/main/resources/unicodes/unicode_page_35.png delete mode 100644 src/main/resources/unicodes/unicode_page_36.png delete mode 100644 src/main/resources/unicodes/unicode_page_37.png delete mode 100644 src/main/resources/unicodes/unicode_page_38.png delete mode 100644 src/main/resources/unicodes/unicode_page_39.png delete mode 100644 src/main/resources/unicodes/unicode_page_3a.png delete mode 100644 src/main/resources/unicodes/unicode_page_3b.png delete mode 100644 src/main/resources/unicodes/unicode_page_3c.png delete mode 100644 src/main/resources/unicodes/unicode_page_3d.png delete mode 100644 src/main/resources/unicodes/unicode_page_3e.png delete mode 100644 src/main/resources/unicodes/unicode_page_3f.png delete mode 100644 src/main/resources/unicodes/unicode_page_40.png delete mode 100644 src/main/resources/unicodes/unicode_page_41.png delete mode 100644 src/main/resources/unicodes/unicode_page_42.png delete mode 100644 src/main/resources/unicodes/unicode_page_43.png delete mode 100644 src/main/resources/unicodes/unicode_page_44.png delete mode 100644 src/main/resources/unicodes/unicode_page_45.png delete mode 100644 src/main/resources/unicodes/unicode_page_46.png delete mode 100644 src/main/resources/unicodes/unicode_page_47.png delete mode 100644 src/main/resources/unicodes/unicode_page_48.png delete mode 100644 src/main/resources/unicodes/unicode_page_49.png delete mode 100644 src/main/resources/unicodes/unicode_page_4a.png delete mode 100644 src/main/resources/unicodes/unicode_page_4b.png delete mode 100644 src/main/resources/unicodes/unicode_page_4c.png delete mode 100644 src/main/resources/unicodes/unicode_page_4d.png delete mode 100644 src/main/resources/unicodes/unicode_page_4e.png delete mode 100644 src/main/resources/unicodes/unicode_page_4f.png delete mode 100644 src/main/resources/unicodes/unicode_page_50.png delete mode 100644 src/main/resources/unicodes/unicode_page_51.png delete mode 100644 src/main/resources/unicodes/unicode_page_52.png delete mode 100644 src/main/resources/unicodes/unicode_page_53.png delete mode 100644 src/main/resources/unicodes/unicode_page_54.png delete mode 100644 src/main/resources/unicodes/unicode_page_55.png delete mode 100644 src/main/resources/unicodes/unicode_page_56.png delete mode 100644 src/main/resources/unicodes/unicode_page_57.png delete mode 100644 src/main/resources/unicodes/unicode_page_58.png delete mode 100644 src/main/resources/unicodes/unicode_page_59.png delete mode 100644 src/main/resources/unicodes/unicode_page_5a.png delete mode 100644 src/main/resources/unicodes/unicode_page_5b.png delete mode 100644 src/main/resources/unicodes/unicode_page_5c.png delete mode 100644 src/main/resources/unicodes/unicode_page_5d.png delete mode 100644 src/main/resources/unicodes/unicode_page_5e.png delete mode 100644 src/main/resources/unicodes/unicode_page_5f.png delete mode 100644 src/main/resources/unicodes/unicode_page_60.png delete mode 100644 src/main/resources/unicodes/unicode_page_61.png delete mode 100644 src/main/resources/unicodes/unicode_page_62.png delete mode 100644 src/main/resources/unicodes/unicode_page_63.png delete mode 100644 src/main/resources/unicodes/unicode_page_64.png delete mode 100644 src/main/resources/unicodes/unicode_page_65.png delete mode 100644 src/main/resources/unicodes/unicode_page_66.png delete mode 100644 src/main/resources/unicodes/unicode_page_67.png delete mode 100644 src/main/resources/unicodes/unicode_page_68.png delete mode 100644 src/main/resources/unicodes/unicode_page_69.png delete mode 100644 src/main/resources/unicodes/unicode_page_6a.png delete mode 100644 src/main/resources/unicodes/unicode_page_6b.png delete mode 100644 src/main/resources/unicodes/unicode_page_6c.png delete mode 100644 src/main/resources/unicodes/unicode_page_6d.png delete mode 100644 src/main/resources/unicodes/unicode_page_6e.png delete mode 100644 src/main/resources/unicodes/unicode_page_6f.png delete mode 100644 src/main/resources/unicodes/unicode_page_70.png delete mode 100644 src/main/resources/unicodes/unicode_page_71.png delete mode 100644 src/main/resources/unicodes/unicode_page_72.png delete mode 100644 src/main/resources/unicodes/unicode_page_73.png delete mode 100644 src/main/resources/unicodes/unicode_page_74.png delete mode 100644 src/main/resources/unicodes/unicode_page_75.png delete mode 100644 src/main/resources/unicodes/unicode_page_76.png delete mode 100644 src/main/resources/unicodes/unicode_page_77.png delete mode 100644 src/main/resources/unicodes/unicode_page_78.png delete mode 100644 src/main/resources/unicodes/unicode_page_79.png delete mode 100644 src/main/resources/unicodes/unicode_page_7a.png delete mode 100644 src/main/resources/unicodes/unicode_page_7b.png delete mode 100644 src/main/resources/unicodes/unicode_page_7c.png delete mode 100644 src/main/resources/unicodes/unicode_page_7d.png delete mode 100644 src/main/resources/unicodes/unicode_page_7e.png delete mode 100644 src/main/resources/unicodes/unicode_page_7f.png delete mode 100644 src/main/resources/unicodes/unicode_page_80.png delete mode 100644 src/main/resources/unicodes/unicode_page_81.png delete mode 100644 src/main/resources/unicodes/unicode_page_82.png delete mode 100644 src/main/resources/unicodes/unicode_page_83.png delete mode 100644 src/main/resources/unicodes/unicode_page_84.png delete mode 100644 src/main/resources/unicodes/unicode_page_85.png delete mode 100644 src/main/resources/unicodes/unicode_page_86.png delete mode 100644 src/main/resources/unicodes/unicode_page_87.png delete mode 100644 src/main/resources/unicodes/unicode_page_88.png delete mode 100644 src/main/resources/unicodes/unicode_page_89.png delete mode 100644 src/main/resources/unicodes/unicode_page_8a.png delete mode 100644 src/main/resources/unicodes/unicode_page_8b.png delete mode 100644 src/main/resources/unicodes/unicode_page_8c.png delete mode 100644 src/main/resources/unicodes/unicode_page_8d.png delete mode 100644 src/main/resources/unicodes/unicode_page_8e.png delete mode 100644 src/main/resources/unicodes/unicode_page_8f.png delete mode 100644 src/main/resources/unicodes/unicode_page_90.png delete mode 100644 src/main/resources/unicodes/unicode_page_91.png delete mode 100644 src/main/resources/unicodes/unicode_page_92.png delete mode 100644 src/main/resources/unicodes/unicode_page_93.png delete mode 100644 src/main/resources/unicodes/unicode_page_94.png delete mode 100644 src/main/resources/unicodes/unicode_page_95.png delete mode 100644 src/main/resources/unicodes/unicode_page_96.png delete mode 100644 src/main/resources/unicodes/unicode_page_97.png delete mode 100644 src/main/resources/unicodes/unicode_page_98.png delete mode 100644 src/main/resources/unicodes/unicode_page_99.png delete mode 100644 src/main/resources/unicodes/unicode_page_9a.png delete mode 100644 src/main/resources/unicodes/unicode_page_9b.png delete mode 100644 src/main/resources/unicodes/unicode_page_9c.png delete mode 100644 src/main/resources/unicodes/unicode_page_9d.png delete mode 100644 src/main/resources/unicodes/unicode_page_9e.png delete mode 100644 src/main/resources/unicodes/unicode_page_9f.png delete mode 100644 src/main/resources/unicodes/unicode_page_a0.png delete mode 100644 src/main/resources/unicodes/unicode_page_a1.png delete mode 100644 src/main/resources/unicodes/unicode_page_a2.png delete mode 100644 src/main/resources/unicodes/unicode_page_a3.png delete mode 100644 src/main/resources/unicodes/unicode_page_a4.png delete mode 100644 src/main/resources/unicodes/unicode_page_a5.png delete mode 100644 src/main/resources/unicodes/unicode_page_a6.png delete mode 100644 src/main/resources/unicodes/unicode_page_a7.png delete mode 100644 src/main/resources/unicodes/unicode_page_a8.png delete mode 100644 src/main/resources/unicodes/unicode_page_a9.png delete mode 100644 src/main/resources/unicodes/unicode_page_aa.png delete mode 100644 src/main/resources/unicodes/unicode_page_ab.png delete mode 100644 src/main/resources/unicodes/unicode_page_ac.png delete mode 100644 src/main/resources/unicodes/unicode_page_ad.png delete mode 100644 src/main/resources/unicodes/unicode_page_ae.png delete mode 100644 src/main/resources/unicodes/unicode_page_af.png delete mode 100644 src/main/resources/unicodes/unicode_page_b0.png delete mode 100644 src/main/resources/unicodes/unicode_page_b1.png delete mode 100644 src/main/resources/unicodes/unicode_page_b2.png delete mode 100644 src/main/resources/unicodes/unicode_page_b3.png delete mode 100644 src/main/resources/unicodes/unicode_page_b4.png delete mode 100644 src/main/resources/unicodes/unicode_page_b5.png delete mode 100644 src/main/resources/unicodes/unicode_page_b6.png delete mode 100644 src/main/resources/unicodes/unicode_page_b7.png delete mode 100644 src/main/resources/unicodes/unicode_page_b8.png delete mode 100644 src/main/resources/unicodes/unicode_page_b9.png delete mode 100644 src/main/resources/unicodes/unicode_page_ba.png delete mode 100644 src/main/resources/unicodes/unicode_page_bb.png delete mode 100644 src/main/resources/unicodes/unicode_page_bc.png delete mode 100644 src/main/resources/unicodes/unicode_page_bd.png delete mode 100644 src/main/resources/unicodes/unicode_page_be.png delete mode 100644 src/main/resources/unicodes/unicode_page_bf.png delete mode 100644 src/main/resources/unicodes/unicode_page_c0.png delete mode 100644 src/main/resources/unicodes/unicode_page_c1.png delete mode 100644 src/main/resources/unicodes/unicode_page_c2.png delete mode 100644 src/main/resources/unicodes/unicode_page_c3.png delete mode 100644 src/main/resources/unicodes/unicode_page_c4.png delete mode 100644 src/main/resources/unicodes/unicode_page_c5.png delete mode 100644 src/main/resources/unicodes/unicode_page_c6.png delete mode 100644 src/main/resources/unicodes/unicode_page_c7.png delete mode 100644 src/main/resources/unicodes/unicode_page_c8.png delete mode 100644 src/main/resources/unicodes/unicode_page_c9.png delete mode 100644 src/main/resources/unicodes/unicode_page_ca.png delete mode 100644 src/main/resources/unicodes/unicode_page_cb.png delete mode 100644 src/main/resources/unicodes/unicode_page_cc.png delete mode 100644 src/main/resources/unicodes/unicode_page_cd.png delete mode 100644 src/main/resources/unicodes/unicode_page_ce.png delete mode 100644 src/main/resources/unicodes/unicode_page_cf.png delete mode 100644 src/main/resources/unicodes/unicode_page_d0.png delete mode 100644 src/main/resources/unicodes/unicode_page_d1.png delete mode 100644 src/main/resources/unicodes/unicode_page_d2.png delete mode 100644 src/main/resources/unicodes/unicode_page_d3.png delete mode 100644 src/main/resources/unicodes/unicode_page_d4.png delete mode 100644 src/main/resources/unicodes/unicode_page_d5.png delete mode 100644 src/main/resources/unicodes/unicode_page_d6.png delete mode 100644 src/main/resources/unicodes/unicode_page_d7.png delete mode 100644 src/main/resources/unicodes/unicode_page_f9.png delete mode 100644 src/main/resources/unicodes/unicode_page_fa.png delete mode 100644 src/main/resources/unicodes/unicode_page_fb.png delete mode 100644 src/main/resources/unicodes/unicode_page_fc.png delete mode 100644 src/main/resources/unicodes/unicode_page_fd.png delete mode 100644 src/main/resources/unicodes/unicode_page_fe.png delete mode 100644 src/main/resources/unicodes/unicode_page_ff.png create mode 100644 velocity/.gitignore create mode 100644 velocity/build.gradle.kts create mode 100644 velocity/src/main/resources/plugin.yml diff --git a/.gitignore b/.gitignore index f9e1624..b63da45 100644 --- a/.gitignore +++ b/.gitignore @@ -1,117 +1,42 @@ -# User-specific stuff -.idea/ - -*.iml -*.ipr -*.iws - -# IntelliJ -out/ -# mpeltonen/sbt-idea plugin -.idea_modules/ - -# JIRA plugin -atlassian-ide-plugin.xml - -# Compiled class file -*.class - -# Log file -*.log - -# BlueJ files -*.ctxt - -# Package Files # -*.war -*.nar -*.ear -*.zip -*.tar.gz -*.rar - -# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml -hs_err_pid* - -*~ - -# temporary files which can be created if a process still has a handle open of a deleted file -.fuse_hidden* - -# KDE directory preferences -.directory - -# Linux trash folder which might appear on any partition or disk -.Trash-* - -# .nfs files are created when an open file is removed but is still being accessed -.nfs* - -# General -.DS_Store -.AppleDouble -.LSOverride - -# Icon must end with two \r -Icon - -# Thumbnails -._* - -# Files that might appear in the root of a volume -.DocumentRevisions-V100 -.fseventsd -.Spotlight-V100 -.TemporaryItems -.Trashes -.VolumeIcon.icns -.com.apple.timemachine.donotpresent - -# Directories potentially created on remote AFP share -.AppleDB -.AppleDesktop -Network Trash Folder -Temporary Items -.apdisk - -# Windows thumbnail cache files -Thumbs.db -Thumbs.db:encryptable -ehthumbs.db -ehthumbs_vista.db - -# Dump file -*.stackdump - -# Folder config file -[Dd]esktop.ini - -# Recycle Bin used on file shares -$RECYCLE.BIN/ - -# Windows Installer files -*.cab -*.msi -*.msix -*.msm -*.msp - -# Windows shortcuts -*.lnk - .gradle build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ -# Ignore Gradle GUI config -gradle-app.setting +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ -# Cache of project -.gradletasknamecache +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ -**/build/ +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ -# Common working directory -run/ +### VS Code ### +.vscode/ -# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) -!gradle-wrapper.jar +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/api/.gitignore b/api/.gitignore new file mode 100644 index 0000000..b63da45 --- /dev/null +++ b/api/.gitignore @@ -0,0 +1,42 @@ +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/api/build.gradle.kts b/api/build.gradle.kts new file mode 100644 index 0000000..c742b50 --- /dev/null +++ b/api/build.gradle.kts @@ -0,0 +1,4 @@ +dependencies { + compileOnly("dev.folia:folia-api:1.20.1-R0.1-SNAPSHOT") + compileOnly("me.clip:placeholderapi:2.11.5") +} \ No newline at end of file diff --git a/api/src/main/java/net/momirealms/customnameplates/api/CustomNameplatesPlugin.java b/api/src/main/java/net/momirealms/customnameplates/api/CustomNameplatesPlugin.java new file mode 100644 index 0000000..aad50cb --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/CustomNameplatesPlugin.java @@ -0,0 +1,112 @@ +package net.momirealms.customnameplates.api; + +import net.momirealms.customnameplates.api.manager.*; +import net.momirealms.customnameplates.api.scheduler.Scheduler; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.plugin.java.JavaPlugin; + +public abstract class CustomNameplatesPlugin extends JavaPlugin { + + protected static CustomNameplatesPlugin instance; + protected Scheduler scheduler; + protected StorageManager storageManager; + protected VersionManager versionManager; + protected AdventureManager adventureManager; + protected RequirementManager requirementManager; + protected BossBarManager bossBarManager; + protected ImageManager imageManager; + protected PlaceholderManager placeholderManager; + protected ResourcePackManager resourcePackManager; + protected BackGroundManager backGroundManager; + protected TeamManager teamManager; + protected NameplateManager nameplateManager; + protected ActionBarManager actionBarManager; + + protected CustomNameplatesPlugin() { + instance = this; + } + + /* Get plugin instance */ + public static CustomNameplatesPlugin getInstance() { + return instance; + } + + /* Get plugin instance */ + public static CustomNameplatesPlugin get() { + return instance; + } + + /* reload the plugin */ + public abstract void reload(boolean generatePack); + + /* Get the scheduler */ + public Scheduler getScheduler() { + return scheduler; + } + + /* Get the storage manager */ + public StorageManager getStorageManager() { + return storageManager; + } + + /* Get the requirement manager */ + public RequirementManager getRequirementManager() { + return requirementManager; + } + + /* Get the image manager */ + public ImageManager getImageManager() { + return imageManager; + } + + /* Get the background manager */ + public BackGroundManager getBackGroundManager() { + return backGroundManager; + } + + /* Get the resource pack manager */ + public ResourcePackManager getResourcePackManager() { + return resourcePackManager; + } + + /* Get the adventure manager */ + public AdventureManager getAdventure() { + return adventureManager; + } + + /* Get the version manager */ + public VersionManager getVersionManager() { + return versionManager; + } + + /* Get the bossbar manager */ + public BossBarManager getBossBarManager() { + return bossBarManager; + } + + /* Get the placeholder manager */ + public PlaceholderManager getPlaceholderManager() { + return placeholderManager; + } + + /* Get the team manager */ + public TeamManager getTeamManager() { + return teamManager; + } + + /* Get the actionbar manager */ + public ActionBarManager getActionBarManager() { + return actionBarManager; + } + + /* Get the nameplate manager */ + public NameplateManager getNameplateManager() { + return nameplateManager; + } + + /* debug get config by file name */ + public abstract YamlConfiguration getConfig(String file); + + /* debug message */ + public abstract void debug(String s); +} diff --git a/src/main/java/net/momirealms/customnameplates/object/scheduler/BukkitTimerTask.java b/api/src/main/java/net/momirealms/customnameplates/api/common/Key.java similarity index 51% rename from src/main/java/net/momirealms/customnameplates/object/scheduler/BukkitTimerTask.java rename to api/src/main/java/net/momirealms/customnameplates/api/common/Key.java index efd7fe9..52829e1 100644 --- a/src/main/java/net/momirealms/customnameplates/object/scheduler/BukkitTimerTask.java +++ b/api/src/main/java/net/momirealms/customnameplates/api/common/Key.java @@ -15,25 +15,32 @@ * along with this program. If not, see . */ -package net.momirealms.customnameplates.object.scheduler; +package net.momirealms.customnameplates.api.common; -import org.bukkit.scheduler.BukkitTask; +public record Key(String namespace, String value) { -public class BukkitTimerTask implements TimerTask { - - private final BukkitTask bukkitTask; - - public BukkitTimerTask(BukkitTask bukkitTask) { - this.bukkitTask = bukkitTask; + public static Key of(String namespace, String value) { + return new Key(namespace, value); } @Override - public void cancel() { - bukkitTask.cancel(); + public int hashCode() { + int result = this.namespace.hashCode(); + result = (31 * result) + this.value.hashCode(); + return result; } @Override - public boolean isCancelled() { - return bukkitTask.isCancelled(); + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (!(obj instanceof Key key)) return false; + return this.namespace.equals(key.namespace()) && this.value.equals(key.value()); + } + + @Override + public String toString() { + return namespace + ":" + value; } } diff --git a/src/main/java/net/momirealms/customnameplates/object/placeholders/StaticText.java b/api/src/main/java/net/momirealms/customnameplates/api/common/Pair.java similarity index 76% rename from src/main/java/net/momirealms/customnameplates/object/placeholders/StaticText.java rename to api/src/main/java/net/momirealms/customnameplates/api/common/Pair.java index b9c4fac..3e5f923 100644 --- a/src/main/java/net/momirealms/customnameplates/object/placeholders/StaticText.java +++ b/api/src/main/java/net/momirealms/customnameplates/api/common/Pair.java @@ -15,14 +15,11 @@ * along with this program. If not, see . */ -package net.momirealms.customnameplates.object.placeholders; +package net.momirealms.customnameplates.api.common; -public record StaticText(String text, int value, StaticState staticState) { +public record Pair(L left, R right) { - public enum StaticState { - - LEFT, - MIDDLE, - RIGHT + public static Pair of(final L left, final R right) { + return new Pair<>(left, right); } } \ No newline at end of file diff --git a/api/src/main/java/net/momirealms/customnameplates/api/common/SimpleLocation.java b/api/src/main/java/net/momirealms/customnameplates/api/common/SimpleLocation.java new file mode 100644 index 0000000..1102057 --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/common/SimpleLocation.java @@ -0,0 +1,63 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customnameplates.api.common; + +import org.bukkit.Location; + +import java.util.Objects; + +public record SimpleLocation(String worldName, int x, int y, int z) { + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final SimpleLocation other = (SimpleLocation) obj; + if (!Objects.equals(worldName, other.worldName())) { + return false; + } + if (Double.doubleToLongBits(this.x) != Double.doubleToLongBits(other.x)) { + return false; + } + if (Double.doubleToLongBits(this.y) != Double.doubleToLongBits(other.y)) { + return false; + } + if (Double.doubleToLongBits(this.z) != Double.doubleToLongBits(other.z)) { + return false; + } + return true; + } + + @Override + public int hashCode() { + int hash = 3; + hash = 19 * hash + (worldName != null ? worldName.hashCode() : 0); + hash = 19 * hash + (int) (Double.doubleToLongBits(this.x) ^ (Double.doubleToLongBits(this.x) >>> 32)); + hash = 19 * hash + (int) (Double.doubleToLongBits(this.y) ^ (Double.doubleToLongBits(this.y) >>> 32)); + hash = 19 * hash + (int) (Double.doubleToLongBits(this.z) ^ (Double.doubleToLongBits(this.z) >>> 32)); + return hash; + } + + public static SimpleLocation getByBukkitLocation(Location location) { + return new SimpleLocation(location.getWorld().getName(), location.getBlockX(), location.getBlockY(), location.getBlockZ()); + } +} \ No newline at end of file diff --git a/api/src/main/java/net/momirealms/customnameplates/api/common/Tuple.java b/api/src/main/java/net/momirealms/customnameplates/api/common/Tuple.java new file mode 100644 index 0000000..a1ed9e4 --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/common/Tuple.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customnameplates.api.common; + +public class Tuple { + + private L left; + private M mid; + private R right; + + public Tuple(L left, M mid, R right) { + this.left = left; + this.mid = mid; + this.right = right; + } + + public static Tuple of(final L left, final M mid, final R right) { + return new Tuple<>(left, mid, right); + } + + public L getLeft() { + return left; + } + + public void setLeft(L left) { + this.left = left; + } + + public M getMid() { + return mid; + } + + public void setMid(M mid) { + this.mid = mid; + } + + public R getRight() { + return right; + } + + public void setRight(R right) { + this.right = right; + } +} \ No newline at end of file diff --git a/api/src/main/java/net/momirealms/customnameplates/api/data/OnlineUser.java b/api/src/main/java/net/momirealms/customnameplates/api/data/OnlineUser.java new file mode 100644 index 0000000..f536e75 --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/data/OnlineUser.java @@ -0,0 +1,79 @@ +package net.momirealms.customnameplates.api.data; + +import net.momirealms.customnameplates.api.CustomNameplatesPlugin; +import net.momirealms.customnameplates.api.mechanic.nameplate.Nameplate; +import org.bukkit.entity.Player; + +import java.util.UUID; + +public class OnlineUser { + + private final Player player; + private String nameplate; + private String bubble; + + public OnlineUser(Player player, PlayerData playerData) { + this.player = player; + this.nameplate = playerData.getNameplate(); + this.bubble = playerData.getBubble(); + } + + public PlayerData toPlayerData() { + return PlayerData.builder() + .setBubble(bubble) + .setNameplate(nameplate) + .build(); + } + + public UUID getUUID() { + return player.getUniqueId(); + } + + public Player getPlayer() { + return player; + } + + /** + * Get the original nameplate key from data + */ + public String getNameplateKey() { + return nameplate; + } + + /** + * Get the original bubble key from data + */ + public String getBubbleKey() { + return bubble; + } + + /** + * This value might be inconsistent with the key get by "getNameplateKey()" + * Because if a player doesn't have a nameplate, his nameplate would be the default one + */ + public Nameplate getNameplate() { + String temp = nameplate; + if (temp.equals("none")) { + temp = CustomNameplatesPlugin.get().getNameplateManager().getDefaultNameplate(); + } + return CustomNameplatesPlugin.get().getNameplateManager().getNameplate(temp); + } + + /** + * Set nameplate for a player + * + * @param nameplate nameplate + */ + public void setNameplate(String nameplate) { + this.nameplate = nameplate; + } + + /** + * Set bubble for a player + * + * @param bubble bubble + */ + public void setBubble(String bubble) { + this.bubble = bubble; + } +} diff --git a/api/src/main/java/net/momirealms/customnameplates/api/data/PlayerData.java b/api/src/main/java/net/momirealms/customnameplates/api/data/PlayerData.java new file mode 100644 index 0000000..258ad99 --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/data/PlayerData.java @@ -0,0 +1,58 @@ +package net.momirealms.customnameplates.api.data; + +import com.google.gson.annotations.SerializedName; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class PlayerData { + + @SerializedName("nameplate") + private String nameplate; + @SerializedName("bubble") + private String bubble; + + public static Builder builder() { + return new Builder(); + } + + public static PlayerData empty() { + return new PlayerData.Builder() + .setNameplate("none") + .setBubble("none") + .build(); + } + + public String getNameplate() { + return nameplate; + } + + public String getBubble() { + return bubble; + } + + public static class Builder { + + private final PlayerData playerData; + + public Builder() { + this.playerData = new PlayerData(); + } + + @NotNull + public Builder setNameplate(@Nullable String nameplate) { + this.playerData.nameplate = nameplate; + return this; + } + + @NotNull + public Builder setBubble(@Nullable String bubble) { + this.playerData.bubble = bubble; + return this; + } + + @NotNull + public PlayerData build() { + return this.playerData; + } + } +} diff --git a/api/src/main/java/net/momirealms/customnameplates/api/event/CustomNameplatesReloadEvent.java b/api/src/main/java/net/momirealms/customnameplates/api/event/CustomNameplatesReloadEvent.java new file mode 100644 index 0000000..9044641 --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/event/CustomNameplatesReloadEvent.java @@ -0,0 +1,30 @@ +package net.momirealms.customnameplates.api.event; + +import net.momirealms.customnameplates.api.CustomNameplatesPlugin; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.NotNull; + +public class CustomNameplatesReloadEvent extends Event { + + private static final HandlerList handlerList = new HandlerList(); + private final CustomNameplatesPlugin plugin; + + public CustomNameplatesReloadEvent(CustomNameplatesPlugin plugin) { + this.plugin = plugin; + } + + public static HandlerList getHandlerList() { + return handlerList; + } + + @NotNull + @Override + public HandlerList getHandlers() { + return getHandlerList(); + } + + public CustomNameplatesPlugin getPlugin() { + return plugin; + } +} diff --git a/api/src/main/java/net/momirealms/customnameplates/api/event/NameplateDataLoadEvent.java b/api/src/main/java/net/momirealms/customnameplates/api/event/NameplateDataLoadEvent.java new file mode 100644 index 0000000..ae47291 --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/event/NameplateDataLoadEvent.java @@ -0,0 +1,39 @@ +package net.momirealms.customnameplates.api.event; + +import net.momirealms.customnameplates.api.data.OnlineUser; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.NotNull; + +import java.util.UUID; + +public class NameplateDataLoadEvent extends Event { + + private static final HandlerList handlerList = new HandlerList(); + private final UUID uuid; + private final OnlineUser onlineUser; + + public NameplateDataLoadEvent(UUID uuid, OnlineUser onlineUser) { + super(true); + this.uuid = uuid; + this.onlineUser = onlineUser; + } + + public UUID getUUID() { + return uuid; + } + + public OnlineUser getOnlineUser() { + return onlineUser; + } + + public static HandlerList getHandlerList() { + return handlerList; + } + + @NotNull + @Override + public HandlerList getHandlers() { + return getHandlerList(); + } +} diff --git a/api/src/main/java/net/momirealms/customnameplates/api/event/PlayerEquipBubbleEvent.java b/api/src/main/java/net/momirealms/customnameplates/api/event/PlayerEquipBubbleEvent.java new file mode 100644 index 0000000..b92e049 --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/event/PlayerEquipBubbleEvent.java @@ -0,0 +1,43 @@ +package net.momirealms.customnameplates.api.event; + +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerEvent; +import org.jetbrains.annotations.NotNull; + +public class PlayerEquipBubbleEvent extends PlayerEvent implements Cancellable { + + private static final HandlerList handlerList = new HandlerList(); + private final String bubble; + private boolean isCancelled; + + public PlayerEquipBubbleEvent(@NotNull Player who, String bubble) { + super(who); + this.bubble = bubble; + this.isCancelled = false; + } + + @Override + public @NotNull HandlerList getHandlers() { + return handlerList; + } + + public static HandlerList getHandlerList() { + return handlerList; + } + + public String getBubble() { + return bubble; + } + + @Override + public boolean isCancelled() { + return isCancelled; + } + + @Override + public void setCancelled(boolean cancel) { + isCancelled = cancel; + } +} diff --git a/api/src/main/java/net/momirealms/customnameplates/api/event/PlayerEquipNameplateEvent.java b/api/src/main/java/net/momirealms/customnameplates/api/event/PlayerEquipNameplateEvent.java new file mode 100644 index 0000000..522339e --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/event/PlayerEquipNameplateEvent.java @@ -0,0 +1,43 @@ +package net.momirealms.customnameplates.api.event; + +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerEvent; +import org.jetbrains.annotations.NotNull; + +public class PlayerEquipNameplateEvent extends PlayerEvent implements Cancellable { + + private static final HandlerList handlerList = new HandlerList(); + private final String nameplate; + private boolean isCancelled; + + public PlayerEquipNameplateEvent(@NotNull Player who, String nameplate) { + super(who); + this.nameplate = nameplate; + this.isCancelled = false; + } + + @Override + public @NotNull HandlerList getHandlers() { + return handlerList; + } + + public static HandlerList getHandlerList() { + return handlerList; + } + + public String getNameplate() { + return nameplate; + } + + @Override + public boolean isCancelled() { + return isCancelled; + } + + @Override + public void setCancelled(boolean cancel) { + isCancelled = cancel; + } +} diff --git a/api/src/main/java/net/momirealms/customnameplates/api/event/PlayerUnequipBubbleEvent.java b/api/src/main/java/net/momirealms/customnameplates/api/event/PlayerUnequipBubbleEvent.java new file mode 100644 index 0000000..4a1fe0f --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/event/PlayerUnequipBubbleEvent.java @@ -0,0 +1,37 @@ +package net.momirealms.customnameplates.api.event; + +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerEvent; +import org.jetbrains.annotations.NotNull; + +public class PlayerUnequipBubbleEvent extends PlayerEvent implements Cancellable { + + private static final HandlerList handlerList = new HandlerList(); + private boolean isCancelled; + + public PlayerUnequipBubbleEvent(@NotNull Player who) { + super(who); + this.isCancelled = false; + } + + @Override + public @NotNull HandlerList getHandlers() { + return handlerList; + } + + public static HandlerList getHandlerList() { + return handlerList; + } + + @Override + public boolean isCancelled() { + return isCancelled; + } + + @Override + public void setCancelled(boolean cancel) { + isCancelled = cancel; + } +} diff --git a/api/src/main/java/net/momirealms/customnameplates/api/event/PlayerUnequipNameplateEvent.java b/api/src/main/java/net/momirealms/customnameplates/api/event/PlayerUnequipNameplateEvent.java new file mode 100644 index 0000000..eb0be64 --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/event/PlayerUnequipNameplateEvent.java @@ -0,0 +1,37 @@ +package net.momirealms.customnameplates.api.event; + +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerEvent; +import org.jetbrains.annotations.NotNull; + +public class PlayerUnequipNameplateEvent extends PlayerEvent implements Cancellable { + + private static final HandlerList handlerList = new HandlerList(); + private boolean isCancelled; + + public PlayerUnequipNameplateEvent(@NotNull Player who) { + super(who); + this.isCancelled = false; + } + + @Override + public @NotNull HandlerList getHandlers() { + return handlerList; + } + + public static HandlerList getHandlerList() { + return handlerList; + } + + @Override + public boolean isCancelled() { + return isCancelled; + } + + @Override + public void setCancelled(boolean cancel) { + isCancelled = cancel; + } +} diff --git a/api/src/main/java/net/momirealms/customnameplates/api/manager/ActionBarManager.java b/api/src/main/java/net/momirealms/customnameplates/api/manager/ActionBarManager.java new file mode 100644 index 0000000..3df91be --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/manager/ActionBarManager.java @@ -0,0 +1,17 @@ +package net.momirealms.customnameplates.api.manager; + +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +public interface ActionBarManager { + + /** + * Get the actionbar sent by other plugins in MiniMessage format + * Return "" if no other actionbar received + * + * @param player receiver + * @return text + */ + @NotNull + String getOtherPluginActionBar(Player player); +} diff --git a/api/src/main/java/net/momirealms/customnameplates/api/manager/AdventureManager.java b/api/src/main/java/net/momirealms/customnameplates/api/manager/AdventureManager.java new file mode 100644 index 0000000..6271313 --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/manager/AdventureManager.java @@ -0,0 +1,186 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customnameplates.api.manager; + +import net.kyori.adventure.key.Key; +import net.kyori.adventure.sound.Sound; +import net.kyori.adventure.text.Component; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public interface AdventureManager { + + Object getIChatComponentFromMiniMessage(String text); + + /** + * Strip all the tags from text + * + * @param text text + * @return stripped + */ + String stripTags(String text); + + /** + * Get component from text + * + * @param text text + * @return component + */ + Component getComponentFromMiniMessage(String text); + + /** + * Send a message to a command sender + * + * @param sender sender + * @param msg message + */ + void sendMessage(CommandSender sender, String msg); + + /** + * Send a message with prefix to a command sender + * + * @param sender sender + * @param msg message + */ + void sendMessageWithPrefix(CommandSender sender, String msg); + + /** + * Send a message to console + * + * @param msg message + */ + void sendConsoleMessage(String msg); + + /** + * Send a message to a player + * + * @param player player + * @param msg message + */ + void sendPlayerMessage(Player player, String msg); + + /** + * Send a title + * + * @param player player + * @param title title + * @param subtitle subtitle + * @param in in (ms) + * @param duration duration (ms) + * @param out out (ms) + */ + void sendTitle(Player player, String title, String subtitle, int in, int duration, int out); + + /** + * Send a title + * + * @param player player + * @param title title + * @param subtitle subtitle + * @param in in (ms) + * @param duration duration (ms) + * @param out out (ms) + */ + void sendTitle(Player player, Component title, Component subtitle, int in, int duration, int out); + + /** + * Send an actionbar + * + * @param player player + * @param msg msg + */ + void sendActionbar(Player player, String msg); + + /** + * Send an actionbar + * + * @param player player + * @param component component + */ + void sendActionbar(Player player, Component component); + + /** + * Play a sound to a player + * + * @param player player + * @param source sound source + * @param key sound key + * @param volume volume + * @param pitch pitch + */ + void sendSound(Player player, Sound.Source source, Key key, float volume, float pitch); + + /** + * Play a sound to a player + * + * @param player player + * @param sound sound + */ + void sendSound(Player player, Sound sound); + + /** + * Replace legacy color codes to MiniMessage format + * + * @param legacy legacy text + * @return MiniMessage format text + */ + String legacyToMiniMessage(String legacy); + + /** + * If a char is legacy color code + * + * @param c char + * @return is legacy color + */ + @SuppressWarnings("BooleanMethodIsAlwaysInverted") + boolean isColorCode(char c); + + /** + * Get legacy format text + * + * @param component component + * @return legacy format text + */ + String componentToLegacy(Component component); + + /** + * Get json by component + * + * @param component component + * @return json + */ + String componentToJson(Component component); + + /** + * Get the component in original package + * + * @param component shaded component + * @return paper component + */ + Object shadedToOriginal(Component component); + + /** + * Get MiniMessage format text from component + * + * @param component component + * @return text + */ + String getMiniMessageFormat(Component component); + + Object getIChatComponent(String json); +} diff --git a/api/src/main/java/net/momirealms/customnameplates/api/manager/BackGroundManager.java b/api/src/main/java/net/momirealms/customnameplates/api/manager/BackGroundManager.java new file mode 100644 index 0000000..3ec95dc --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/manager/BackGroundManager.java @@ -0,0 +1,40 @@ +package net.momirealms.customnameplates.api.manager; + +import net.momirealms.customnameplates.api.mechanic.background.BackGround; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; + +public interface BackGroundManager { + + /** + * Get a background's config by key + * + * @param key key + * @return background + */ + @Nullable + BackGround getBackGround(@NotNull String key); + + Collection getBackGrounds(); + + /** + * Register a background into the plugin + * This will fail if there already exists one with the same key + * + * @param key key + * @param backGround background + * @return success or not + */ + boolean registerBackGround(@NotNull String key, @NotNull BackGround backGround); + + /** + * Unregister a background by key + * This will fail if the key doesn't exist + * + * @param key key + * @return success or not + */ + boolean unregisterBackGround(@NotNull String key); +} diff --git a/api/src/main/java/net/momirealms/customnameplates/api/manager/BossBarManager.java b/api/src/main/java/net/momirealms/customnameplates/api/manager/BossBarManager.java new file mode 100644 index 0000000..54abdc7 --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/manager/BossBarManager.java @@ -0,0 +1,5 @@ +package net.momirealms.customnameplates.api.manager; + +public interface BossBarManager { + +} diff --git a/api/src/main/java/net/momirealms/customnameplates/api/manager/ImageManager.java b/api/src/main/java/net/momirealms/customnameplates/api/manager/ImageManager.java new file mode 100644 index 0000000..834d9f7 --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/manager/ImageManager.java @@ -0,0 +1,40 @@ +package net.momirealms.customnameplates.api.manager; + +import net.momirealms.customnameplates.api.mechanic.character.ConfiguredChar; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; + +public interface ImageManager { + + /** + * Get an image by key + * + * @param key key + * @return image + */ + @Nullable + ConfiguredChar getImage(@NotNull String key); + + Collection getImages(); + + /** + * Register am image into the plugin + * This will fail if there already exists one with the same key + * + * @param key key + * @param configuredChar image + * @return success or not + */ + boolean registerImage(@NotNull String key, @NotNull ConfiguredChar configuredChar); + + /** + * Unregister an image by key + * This will fail if the key doesn't exist + * + * @param key key + * @return success or not + */ + boolean unregisterImage(@NotNull String key); +} diff --git a/api/src/main/java/net/momirealms/customnameplates/api/manager/NameplateManager.java b/api/src/main/java/net/momirealms/customnameplates/api/manager/NameplateManager.java new file mode 100644 index 0000000..337c7ea --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/manager/NameplateManager.java @@ -0,0 +1,158 @@ +package net.momirealms.customnameplates.api.manager; + +import net.momirealms.customnameplates.api.mechanic.nameplate.CachedNameplate; +import net.momirealms.customnameplates.api.mechanic.nameplate.Nameplate; +import net.momirealms.customnameplates.api.mechanic.nameplate.TagMode; +import net.momirealms.customnameplates.api.mechanic.tag.NameplatePlayer; +import net.momirealms.customnameplates.api.mechanic.team.TeamColor; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; +import java.util.List; +import java.util.UUID; + +public interface NameplateManager { + + /** + * Get the default nameplate + */ + @NotNull + String getDefaultNameplate(); + + /** + * Put an entity's ID to map + * This map is used for quickly getting the entity instance + * Removal from the map is necessary when the entity is invalid + * Otherwise it would cause memory leak + * + * @param entityID entityID + * @param entity entity + */ + boolean putEntityIDToMap(int entityID, Entity entity); + + /** + * Remove the entity from map + * + * @param entityID entityID + * @return the removed entity + */ + @Nullable + Entity removeEntityIDFromMap(int entityID); + + /** + * Nameplates are cached in memory so they would not be frequently updated + * The update rate is decided by "refresh-frequency" in nameplate.yml + * + * @param uuid player uuid + * @param nameplate cached nameplate + */ + boolean putCachedNameplateToMap(UUID uuid, CachedNameplate nameplate); + + /** + * Remove CachedNameplate from map + * + * @param uuid player uuid + * @return removed CachedNameplate + */ + @Nullable + CachedNameplate removeCachedNameplateFromMap(UUID uuid); + + /** + * Get player by entityID from the cache + * + * @param id entityID + * @return player + */ + @Nullable + Player getPlayerByEntityID(int id); + + /** + * Get entity by entityID from the cache + * + * @param id entityID + * @return entity + */ + @Nullable + Entity getEntityByEntityID(int id); + + /** + * Update a player's cached nameplate + * The nameplate is affected by "prefix" and "suffix" option + * + * @param player player + * @return if the nameplate is updated + */ + boolean updateCachedNameplate(Player player); + + /** + * Update a player's cached nameplate + * The nameplate is affected by "prefix" and "suffix" option + * + * @param player player + * @return if the nameplate is updated + */ + boolean updateCachedNameplate(Player player, Nameplate nameplate); + + /** + * This should not be null when player's data is loaded (async process) + * + * @param player player + * @return cached nameplate + */ + @Nullable + CachedNameplate getCacheNameplate(Player player); + + /** + * Create a name tag for a player, the tag type is decided by the mode in nameplate.yml + * + * @param player player + */ + void createNameTag(Player player); + + void putNameplatePlayerToMap(NameplatePlayer player); + + NameplatePlayer removeNameplatePlayerFromMap(UUID uuid); + + String getNameplatePrefix(Player player); + + String getNameplateSuffix(Player player); + + String getFullNameTag(Player player); + + boolean registerNameplate(String key, Nameplate nameplate); + + void unEquipNameplate(Player player); + + boolean unregisterNameplate(String key); + + boolean isProxyMode(); + + TagMode getTagMode(); + + Nameplate getNameplate(String key); + + Collection getNameplates(); + + boolean containsNameplate(String key); + + List getAvailableNameplates(Player player); + + /** + * If player has permission for a certain nameplate + */ + boolean hasNameplate(Player player, String nameplate); + + /** + * Return false if nameplate doesn't exist + */ + boolean equipNameplate(Player player, String nameplate); + + TeamColor getTeamColor(Player player); + + TeamTagManager getTeamTagManager(); + + UnlimitedTagManager getUnlimitedTagManager(); +} diff --git a/api/src/main/java/net/momirealms/customnameplates/api/manager/PlaceholderManager.java b/api/src/main/java/net/momirealms/customnameplates/api/manager/PlaceholderManager.java new file mode 100644 index 0000000..0463b19 --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/manager/PlaceholderManager.java @@ -0,0 +1,73 @@ +package net.momirealms.customnameplates.api.manager; + +import net.momirealms.customnameplates.api.mechanic.placeholder.*; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public interface PlaceholderManager { + + /** + * Detect all the placeholders + * + * @param text text + * @return placeholder + */ + @NotNull + List detectPlaceholders(String text); + + /** + * Get a static text instance + * + * @param key key + * @return static text + */ + @Nullable + StaticText getStaticText(String key); + + /** + * Get a switch text instance + * + * @param key key + * @return switch text + */ + @Nullable + SwitchText getSwitchText(String key); + + /** + * Get a descent text instance + * + * @param key key + * @return descent text + */ + @Nullable + DescentText getDescentText(String key); + + /** + * Get a conditional text + * + * @param key key + * @return conditional text + */ + @Nullable + ConditionalText getConditionalText(String key); + + /** + * Get a nameplate text + * + * @param key key + * @return nameplate text + */ + @Nullable + NameplateText getNameplateText(String key); + + /** + * Get a background text + * + * @param key key + * @return background text + */ + @Nullable + BackGroundText getBackGroundText(String key); +} diff --git a/api/src/main/java/net/momirealms/customnameplates/api/manager/RequirementManager.java b/api/src/main/java/net/momirealms/customnameplates/api/manager/RequirementManager.java new file mode 100644 index 0000000..6c9a77f --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/manager/RequirementManager.java @@ -0,0 +1,104 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customnameplates.api.manager; + +import net.momirealms.customnameplates.api.requirement.Condition; +import net.momirealms.customnameplates.api.requirement.Requirement; +import net.momirealms.customnameplates.api.requirement.RequirementFactory; +import org.bukkit.configuration.ConfigurationSection; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public interface RequirementManager { + + /** + * Registers a custom requirement type with its corresponding factory. + * + * @param type The type identifier of the requirement. + * @param requirementFactory The factory responsible for creating instances of the requirement. + * @return True if registration was successful, false if the type is already registered. + */ + boolean registerRequirement(String type, RequirementFactory requirementFactory); + + /** + * Unregisters a custom requirement type. + * + * @param type The type identifier of the requirement to unregister. + * @return True if unregistration was successful, false if the type is not registered. + */ + boolean unregisterRequirement(String type); + + /** + * Retrieves an array of requirements based on a configuration section. + * + * @param section The configuration section containing requirement definitions. + * @return An array of Requirement objects based on the configuration section + */ + @Nullable Requirement[] getRequirements(ConfigurationSection section); + + /** + * Retrieves a Requirement object based on a configuration section and advanced flag. + *

+ * requirement_1: <- section + * type: xxx + * value: xxx + * + * @param section The configuration section containing requirement definitions. + * @return A Requirement object based on the configuration section, or an EmptyRequirement if the section is null or invalid. + */ + @NotNull Requirement getRequirement(ConfigurationSection section); + + /** + * Gets a requirement based on the provided type and value. + * If a valid RequirementFactory is found for the type, it is used to create the requirement. + * If no factory is found, a warning is logged, and an empty requirement instance is returned. + *

+ * world: <- type + * - world <- value + * + * @param type The type representing the requirement type. + * @param value The value associated with the requirement. + * @return A Requirement instance based on the type and value, or an EmptyRequirement if the type is invalid. + */ + @NotNull Requirement getRequirement(String type, Object value); + + /** + * Retrieves a RequirementFactory based on the specified requirement type. + * + * @param type The requirement type for which to retrieve a factory. + * @return A RequirementFactory for the specified type, or null if no factory is found. + */ + @Nullable RequirementFactory getRequirementFactory(String type); + + /** + * Checks if an array of requirements is met for a given condition. + * + * @param condition The Condition object to check against the requirements. + * @param requirements An array of Requirement instances to be evaluated. + * @return True if all requirements are met, false otherwise. Returns true if the requirements array is null. + */ + static boolean isRequirementMet(Condition condition, Requirement... requirements) { + if (requirements == null) return true; + for (Requirement requirement : requirements) { + if (!requirement.isConditionMet(condition)) { + return false; + } + } + return true; + } +} diff --git a/api/src/main/java/net/momirealms/customnameplates/api/manager/ResourcePackManager.java b/api/src/main/java/net/momirealms/customnameplates/api/manager/ResourcePackManager.java new file mode 100644 index 0000000..4df85fd --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/manager/ResourcePackManager.java @@ -0,0 +1,15 @@ +package net.momirealms.customnameplates.api.manager; + +import java.io.File; + +public interface ResourcePackManager { + + /** + * Generate the resource pack + */ + void generateResourcePack(); + + void deleteDirectory(File file); + + String native2ascii(char c); +} diff --git a/api/src/main/java/net/momirealms/customnameplates/api/manager/StorageManager.java b/api/src/main/java/net/momirealms/customnameplates/api/manager/StorageManager.java new file mode 100644 index 0000000..5165ca6 --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/manager/StorageManager.java @@ -0,0 +1,88 @@ +package net.momirealms.customnameplates.api.manager; + +import net.momirealms.customnameplates.api.data.OnlineUser; +import net.momirealms.customnameplates.api.data.PlayerData; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; +import java.util.Optional; +import java.util.UUID; +import java.util.concurrent.CompletableFuture; + +public interface StorageManager { + + /** + * Get online users + * + * @return online users + */ + Collection getOnlineUsers(); + + /** + * Get a player's data by uuid + * The player can be an offline one + * + * @param uuid uuid + * @return player data + */ + CompletableFuture> getPlayerData(UUID uuid); + + /** + * Save online players' data + * + * @param uuid uuid + * @return success or not + */ + CompletableFuture saveOnlinePlayerData(UUID uuid); + + /** + * Save specified data + * + * @param uuid uuid + * @param playerData playerData + * @return success or not + */ + CompletableFuture savePlayerData(UUID uuid, PlayerData playerData); + + /** + * Get an online user by uuid + * + * @param uuid uuid + * @return online user + */ + Optional getOnlineUser(UUID uuid); + + /** + * Get player data from json + * + * @param json json + * @return data + */ + @NotNull + PlayerData fromJson(String json); + + /** + * Get player data from bytes + * + * @param data data + * @return data + */ + PlayerData fromBytes(byte[] data); + + /** + * Convert player data to bytes + * + * @param playerData playerData + * @return bytes + */ + byte[] toBytes(PlayerData playerData); + + /** + * Convert player data to json + * + * @param playerData playerData + * @return json + */ + @NotNull + String toJson(@NotNull PlayerData playerData); +} diff --git a/api/src/main/java/net/momirealms/customnameplates/api/manager/TeamManager.java b/api/src/main/java/net/momirealms/customnameplates/api/manager/TeamManager.java new file mode 100644 index 0000000..14e4721 --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/manager/TeamManager.java @@ -0,0 +1,47 @@ +package net.momirealms.customnameplates.api.manager; + +import net.kyori.adventure.text.Component; +import net.momirealms.customnameplates.api.mechanic.team.TeamColor; +import net.momirealms.customnameplates.api.mechanic.team.TeamTagVisibility; +import org.bukkit.entity.Player; + +public interface TeamManager { + + /** + * Create team for a player + * + * @param player player + */ + void createTeam(Player player); + + /** + * Create a team for a player on proxy + * + * @param player player + */ + void createProxyTeam(Player player); + + /** + * Remove a team for a player + * + * @param player player + */ + void removeTeam(Player player); + + /** + * Remove a team for a player on proxy + * + * @param player player + */ + void removeProxyTeam(Player player); + + void updateTeam(Player owner, Player viewer, Component prefix, Component suffix, TeamColor color, TeamTagVisibility visibility); + + /** + * Get the team player in + * + * @param player player + * @return team name + */ + String getTeamName(Player player); +} diff --git a/api/src/main/java/net/momirealms/customnameplates/api/manager/TeamTagManager.java b/api/src/main/java/net/momirealms/customnameplates/api/manager/TeamTagManager.java new file mode 100644 index 0000000..ffa408d --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/manager/TeamTagManager.java @@ -0,0 +1,29 @@ +package net.momirealms.customnameplates.api.manager; + +import net.momirealms.customnameplates.api.mechanic.tag.team.TeamPlayer; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.Nullable; + +import java.util.UUID; + +public interface TeamTagManager { + + /** + * Create team tag for a player + * If failed, the return value would be null + * This happens when there already exists a team tag for a player + * + * @return team tag + */ + @Nullable + TeamPlayer createTagForPlayer(Player player, String prefix, String suffix); + + /** + * Remove a team tag from map by uuid + * + * @param uuid uuid + * @return team tag + */ + @Nullable + TeamPlayer removeTeamPlayerFromMap(UUID uuid); +} diff --git a/api/src/main/java/net/momirealms/customnameplates/api/manager/UnlimitedTagManager.java b/api/src/main/java/net/momirealms/customnameplates/api/manager/UnlimitedTagManager.java new file mode 100644 index 0000000..305e03c --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/manager/UnlimitedTagManager.java @@ -0,0 +1,56 @@ +package net.momirealms.customnameplates.api.manager; + +import net.momirealms.customnameplates.api.mechanic.tag.unlimited.NamedEntity; +import net.momirealms.customnameplates.api.mechanic.tag.unlimited.UnlimitedObject; +import net.momirealms.customnameplates.api.mechanic.tag.unlimited.UnlimitedPlayer; +import net.momirealms.customnameplates.api.mechanic.tag.unlimited.UnlimitedTagSetting; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; +import java.util.UUID; + +public interface UnlimitedTagManager { + + /** + * Create a named entity (ArmorStand) for a player + * To apply the changes, you should add it the named player instance + * + * @param player player + * @param setting setting + * @return named entity + */ + @NotNull + NamedEntity createNamedEntity(UnlimitedPlayer player, UnlimitedTagSetting setting); + + /** + * Create unlimited tags for a player + * If failed, the return value would be null + * This happens when there already exists an UnlimitedObject for a player + * + * @param player player + * @param settings settings + * @return unlimited tag + */ + @Nullable + UnlimitedPlayer createTagForPlayer(Player player, List settings); + + /** + * Remove UnlimitedObject from map by uuid + * + * @param uuid uuid + * @return The removed unlimited object + */ + @Nullable + UnlimitedObject removeUnlimitedObjectFromMap(UUID uuid); + + /** + * Get an UnlimitedObject from map by uuid + * + * @param uuid uuid + * @return The unlimited object + */ + @Nullable + UnlimitedObject getUnlimitedObject(UUID uuid); +} diff --git a/api/src/main/java/net/momirealms/customnameplates/api/manager/VersionManager.java b/api/src/main/java/net/momirealms/customnameplates/api/manager/VersionManager.java new file mode 100644 index 0000000..261ae9d --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/manager/VersionManager.java @@ -0,0 +1,26 @@ +package net.momirealms.customnameplates.api.manager; + +import java.util.concurrent.CompletionStage; + +public interface VersionManager { + + boolean isFolia(); + + String getServerVersion(); + + CompletionStage checkUpdate(); + + boolean isVersionNewerThan1_19_R2(); + + boolean isVersionNewerThan1_20(); + + boolean isVersionNewerThan1_20_R2(); + + String getPluginVersion(); + + boolean isLatest(); + + boolean isVersionNewerThan1_19(); + + int getPackFormat(); +} diff --git a/api/src/main/java/net/momirealms/customnameplates/api/manager/WidthManager.java b/api/src/main/java/net/momirealms/customnameplates/api/manager/WidthManager.java new file mode 100644 index 0000000..96b17e7 --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/manager/WidthManager.java @@ -0,0 +1,5 @@ +package net.momirealms.customnameplates.api.manager; + +public interface WidthManager { + +} diff --git a/api/src/main/java/net/momirealms/customnameplates/api/mechanic/background/BackGround.java b/api/src/main/java/net/momirealms/customnameplates/api/mechanic/background/BackGround.java new file mode 100644 index 0000000..785c55b --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/mechanic/background/BackGround.java @@ -0,0 +1,212 @@ +package net.momirealms.customnameplates.api.mechanic.background; + +import net.momirealms.customnameplates.api.mechanic.character.ConfiguredChar; +import net.momirealms.customnameplates.api.mechanic.font.OffsetFont; + +public class BackGround { + + private ConfiguredChar left, offset_1, offset_2, offset_4, offset_8, offset_16, offset_32, offset_64, offset_128, right; + private int leftMargin, rightMargin; + + private BackGround() { + } + + public BackGround( + ConfiguredChar left, + ConfiguredChar offset_1, + ConfiguredChar offset_2, + ConfiguredChar offset_4, + ConfiguredChar offset_8, + ConfiguredChar offset_16, + ConfiguredChar offset_32, + ConfiguredChar offset_64, + ConfiguredChar offset_128, + ConfiguredChar right, + int leftMargin, + int rightMargin + ) { + this.left = left; + this.offset_1 = offset_1; + this.offset_2 = offset_2; + this.offset_4 = offset_4; + this.offset_8 = offset_8; + this.offset_16 = offset_16; + this.offset_32 = offset_32; + this.offset_64 = offset_64; + this.offset_128 = offset_128; + this.right = right; + this.leftMargin = leftMargin; + this.rightMargin = rightMargin; + } + + public ConfiguredChar getLeft() { + return left; + } + + public ConfiguredChar getOffset_1() { + return offset_1; + } + + public ConfiguredChar getOffset_2() { + return offset_2; + } + + public ConfiguredChar getOffset_4() { + return offset_4; + } + + public ConfiguredChar getOffset_8() { + return offset_8; + } + + public ConfiguredChar getOffset_16() { + return offset_16; + } + + public ConfiguredChar getOffset_32() { + return offset_32; + } + + public ConfiguredChar getOffset_64() { + return offset_64; + } + + public ConfiguredChar getOffset_128() { + return offset_128; + } + + public ConfiguredChar getRight() { + return right; + } + + public static Builder builder() { + return new Builder(); + } + + public String getBackGroundImage(int n) { + String offset = OffsetFont.getShortestNegChars(n + rightMargin + 2); + n = n + leftMargin + rightMargin + 2; + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append(left.getCharacter()); + while (n >= 128) { + stringBuilder.append(OffsetFont.NEG_1.getCharacter()); + stringBuilder.append(offset_128.getCharacter()); + n -= 128; + } + if (n - 64 >= 0) { + stringBuilder.append(OffsetFont.NEG_1.getCharacter()); + stringBuilder.append(offset_64.getCharacter()); + n -= 64; + } + if (n - 32 >= 0) { + stringBuilder.append(OffsetFont.NEG_1.getCharacter()); + stringBuilder.append(offset_32.getCharacter()); + n -= 32; + } + if (n - 16 >= 0) { + stringBuilder.append(OffsetFont.NEG_1.getCharacter()); + stringBuilder.append(offset_16.getCharacter()); + n -= 16; + } + if (n - 8 >= 0) { + stringBuilder.append(OffsetFont.NEG_1.getCharacter()); + stringBuilder.append(offset_8.getCharacter()); + n -= 8; + } + if (n - 4 >= 0) { + stringBuilder.append(OffsetFont.NEG_1.getCharacter()); + stringBuilder.append(offset_4.getCharacter()); + n -= 4; + } + if (n - 2 >= 0) { + stringBuilder.append(OffsetFont.NEG_1.getCharacter()); + stringBuilder.append(offset_2.getCharacter()); + n -= 2; + } + if (n - 1 >= 0) { + stringBuilder.append(OffsetFont.NEG_1.getCharacter()); + stringBuilder.append(offset_1.getCharacter()); + } + stringBuilder.append(OffsetFont.NEG_1.getCharacter()); + stringBuilder.append(right.getCharacter()); + stringBuilder.append(offset); + return stringBuilder.toString(); + } + + public static class Builder { + + private final BackGround backGround; + + public static Builder of() { + return new Builder(); + } + + public Builder() { + this.backGround = new BackGround(); + } + + public Builder left(ConfiguredChar configuredChar) { + backGround.left = configuredChar; + return this; + } + + public Builder right(ConfiguredChar configuredChar) { + backGround.right = configuredChar; + return this; + } + + public Builder offset_1(ConfiguredChar configuredChar) { + backGround.offset_1 = configuredChar; + return this; + } + + public Builder offset_2(ConfiguredChar configuredChar) { + backGround.offset_2 = configuredChar; + return this; + } + + public Builder offset_4(ConfiguredChar configuredChar) { + backGround.offset_4 = configuredChar; + return this; + } + + public Builder offset_8(ConfiguredChar configuredChar) { + backGround.offset_8 = configuredChar; + return this; + } + + public Builder offset_16(ConfiguredChar configuredChar) { + backGround.offset_16 = configuredChar; + return this; + } + + public Builder offset_32(ConfiguredChar configuredChar) { + backGround.offset_32 = configuredChar; + return this; + } + + public Builder offset_64(ConfiguredChar configuredChar) { + backGround.offset_64 = configuredChar; + return this; + } + + public Builder offset_128(ConfiguredChar configuredChar) { + backGround.offset_128 = configuredChar; + return this; + } + + public Builder leftMargin(int margin) { + backGround.leftMargin = margin; + return this; + } + + public Builder rightMargin(int margin) { + backGround.rightMargin = margin; + return this; + } + + public BackGround build() { + return backGround; + } + } +} diff --git a/api/src/main/java/net/momirealms/customnameplates/api/mechanic/character/CharacterArranger.java b/api/src/main/java/net/momirealms/customnameplates/api/mechanic/character/CharacterArranger.java new file mode 100644 index 0000000..aac98ec --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/mechanic/character/CharacterArranger.java @@ -0,0 +1,25 @@ +package net.momirealms.customnameplates.api.mechanic.character; + +public class CharacterArranger { + + public static char currentChar; + + public static void increase() { + currentChar = (char) (currentChar + '\u0001'); + } + + public static char getAndIncrease() { + char temp = currentChar; + increase(); + return temp; + } + + public static char increaseAndGet() { + increase(); + return currentChar; + } + + public static void reset(char c) { + currentChar = c; + } +} diff --git a/api/src/main/java/net/momirealms/customnameplates/api/mechanic/character/ConfiguredChar.java b/api/src/main/java/net/momirealms/customnameplates/api/mechanic/character/ConfiguredChar.java new file mode 100644 index 0000000..cc70116 --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/mechanic/character/ConfiguredChar.java @@ -0,0 +1,107 @@ +package net.momirealms.customnameplates.api.mechanic.character; + +import net.momirealms.customnameplates.api.util.LogUtils; + +public class ConfiguredChar { + + private char character; + private String pngFile; + private int height; + private int width; + private int ascent; + + private ConfiguredChar() { + + } + + public ConfiguredChar(char character, String pngFile, int height, int width, int ascent) { + this.character = character; + this.pngFile = pngFile; + this.height = height; + this.width = width; + this.ascent = ascent; + } + + public char getCharacter() { + return character; + } + + public static Builder builder() { + return new Builder(); + } + + public String getPngFile() { + return pngFile; + } + + public int getHeight() { + return height; + } + + public int getWidth() { + return width; + } + + public int getAscent() { + return ascent; + } + + public String getFile() { + return pngFile + ".png"; + } + + public static class Builder { + + private final ConfiguredChar configuredChar; + + public static Builder of() { + return new Builder(); + } + + public Builder() { + this.configuredChar = new ConfiguredChar(); + } + + public Builder character(char character) { + configuredChar.character = character; + return this; + } + + public Builder png(String png) { + configuredChar.pngFile = png; + return this; + } + + public Builder height(int height) { + configuredChar.height = height; + return this; + } + + public Builder ascent(int ascent) { + configuredChar.ascent = ascent; + if (ascent >= configuredChar.height) { + LogUtils.warn("Invalid config for " + configuredChar.pngFile); + LogUtils.warn("Ascent " + ascent + " should be no higher than Height " + configuredChar.height); + } + return this; + } + + public Builder descent(int descent) { + if (descent < 0) { + LogUtils.warn("Invalid config for " + configuredChar.pngFile); + LogUtils.warn("Descent " + descent + " should be no lower than 0"); + } + configuredChar.ascent = configuredChar.height - descent; + return this; + } + + public Builder width(int width) { + configuredChar.width = width; + return this; + } + + public ConfiguredChar build() { + return configuredChar; + } + } +} diff --git a/api/src/main/java/net/momirealms/customnameplates/api/mechanic/font/OffsetFont.java b/api/src/main/java/net/momirealms/customnameplates/api/mechanic/font/OffsetFont.java new file mode 100644 index 0000000..4d24ab1 --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/mechanic/font/OffsetFont.java @@ -0,0 +1,180 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customnameplates.api.mechanic.font; + +public enum OffsetFont { + + NEG_1('\uf801', -1, -3), + NEG_2('\uf802', -2, -4), + NEG_3('\uf803', -3, -5), + NEG_4('\uf804', -4, -6), + NEG_5('\uf805', -5, -7), + NEG_6('\uf806', -6, -8), + NEG_7('\uf807', -7, -9), + NEG_8('\uf808', -8, -10), + NEG_16('\uf809', -16, -18), + NEG_32('\uf80a', -32, -34), + NEG_64('\uf80b', -64, -66), + NEG_128('\uf80c', -128, -130), + POS_1('\uf811', 1, -1), + POS_2('\uf812', 2, 1), + POS_3('\uf813', 3, 2), + POS_4('\uf814', 4, 3), + POS_5('\uf815', 5, 4), + POS_6('\uf816', 6, 5), + POS_7('\uf817', 7, 6), + POS_8('\uf818', 8, 7), + POS_16('\uf819', 16, 15), + POS_32('\uf81a', 32, 31), + POS_64('\uf81b', 64, 63), + POS_128('\uf81c', 128, 127); + + private final char character; + private final int space; + private final int height; + + OffsetFont(char character, int space, int height) { + this.character = character; + this.space = space; + this.height = height; + } + + public char getCharacter() { + return this.character; + } + + public int getSpace() { + return this.space; + } + + public int getHeight() { + return this.height; + } + + public static String getOffsetChars(int offset) { + if (offset >= 0) { + return getShortestPosChars(offset); + } else { + return getShortestNegChars(-offset); + } + } + + public static String getShortestNegChars(int n) { + StringBuilder stringBuilder = new StringBuilder(); + while (n >= 128) { + stringBuilder.append(OffsetFont.NEG_128.getCharacter()); + n -= 128; + } + if (n - 64 >= 0) { + stringBuilder.append(OffsetFont.NEG_64.getCharacter()); + n -= 64; + } + if (n - 32 >= 0) { + stringBuilder.append(OffsetFont.NEG_32.getCharacter()); + n -= 32; + } + if (n - 16 >= 0) { + stringBuilder.append(OffsetFont.NEG_16.getCharacter()); + n -= 16; + } + if (n - 8 >= 0) { + stringBuilder.append(OffsetFont.NEG_8.getCharacter()); + n -= 8; + } + if (n - 7 >= 0) { + stringBuilder.append(OffsetFont.NEG_7.getCharacter()); + n -= 7; + } + if (n - 6 >= 0) { + stringBuilder.append(OffsetFont.NEG_6.getCharacter()); + n -= 6; + } + if (n - 5 >= 0) { + stringBuilder.append(OffsetFont.NEG_5.getCharacter()); + n -= 5; + } + if (n - 4 >= 0) { + stringBuilder.append(OffsetFont.NEG_4.getCharacter()); + n -= 4; + } + if (n - 3 >= 0) { + stringBuilder.append(OffsetFont.NEG_3.getCharacter()); + n -= 3; + } + if (n - 2 >= 0) { + stringBuilder.append(OffsetFont.NEG_2.getCharacter()); + n -= 2; + } + if (n - 1 >= 0) { + stringBuilder.append(OffsetFont.NEG_1.getCharacter()); + } + return stringBuilder.toString(); + } + + public static String getShortestPosChars(int n) { + StringBuilder stringBuilder = new StringBuilder(); + while (n >= 128) { + stringBuilder.append(OffsetFont.POS_128.getCharacter()); + n -= 128; + } + if (n - 64 >= 0) { + stringBuilder.append(OffsetFont.POS_64.getCharacter()); + n -= 64; + } + if (n - 32 >= 0) { + stringBuilder.append(OffsetFont.POS_32.getCharacter()); + n -= 32; + } + if (n - 16 >= 0) { + stringBuilder.append(OffsetFont.POS_16.getCharacter()); + n -= 16; + } + if (n - 8 >= 0) { + stringBuilder.append(OffsetFont.POS_8.getCharacter()); + n -= 8; + } + if (n - 7 >= 0) { + stringBuilder.append(OffsetFont.POS_7.getCharacter()); + n -= 7; + } + if (n - 6 >= 0) { + stringBuilder.append(OffsetFont.POS_6.getCharacter()); + n -= 6; + } + if (n - 5 >= 0) { + stringBuilder.append(OffsetFont.POS_5.getCharacter()); + n -= 5; + } + if (n - 4 >= 0) { + stringBuilder.append(OffsetFont.POS_4.getCharacter()); + n -= 4; + } + if (n - 3 >= 0) { + stringBuilder.append(OffsetFont.POS_3.getCharacter()); + n -= 3; + } + if (n - 2 >= 0) { + stringBuilder.append(OffsetFont.POS_2.getCharacter()); + n -= 2; + } + if (n - 1 >= 0) { + stringBuilder.append(OffsetFont.POS_1.getCharacter()); + } + return stringBuilder.toString(); + } +} diff --git a/api/src/main/java/net/momirealms/customnameplates/api/mechanic/misc/ViewerText.java b/api/src/main/java/net/momirealms/customnameplates/api/mechanic/misc/ViewerText.java new file mode 100644 index 0000000..ad7af9b --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/mechanic/misc/ViewerText.java @@ -0,0 +1,111 @@ +package net.momirealms.customnameplates.api.mechanic.misc; + +import me.clip.placeholderapi.PlaceholderAPI; +import net.momirealms.customnameplates.api.CustomNameplatesPlugin; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; + +import java.util.List; +import java.util.Objects; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; + +public class ViewerText { + + private final Player owner; + private String processedText; + private final ClaimedText[] placeholders; + private final ConcurrentHashMap valueMap; + + public ViewerText(Player owner, String rawText) { + this.processedText = rawText; + this.valueMap = new ConcurrentHashMap<>(); + this.owner = owner; + List placeholders = CustomNameplatesPlugin.get().getPlaceholderManager().detectPlaceholders(rawText); + this.placeholders = new ClaimedText[placeholders.size()]; + int i = 0; + for (String placeholder : placeholders) { + processedText = processedText.replace(placeholder, "%s"); + if (placeholder.startsWith("%viewer_")) { + this.placeholders[i] = new ClaimedText(null, "%" + placeholder.substring("%viewer_".length())); + } else { + this.placeholders[i] = new ClaimedText(owner, placeholder); + } + i++; + } + } + + public void updateForOwner() { + for (ClaimedText text : placeholders) { + text.update(); + } + } + + public boolean updateForViewer(Player viewer) { + String string; + if ("%s".equals(processedText)) { + string = placeholders[0].getValue(viewer); + } else if (placeholders.length != 0) { + Object[] values = new String[placeholders.length]; + for (int i = 0; i < placeholders.length; i++) { + values[i] = placeholders[i].getValue(viewer); + } + string = String.format(processedText, values); + } else { + string = processedText; + } + var uuid = viewer.getUniqueId(); + if (!valueMap.containsKey(uuid)) { + valueMap.put(uuid, string); + return true; + } + String previousValue = valueMap.get(uuid); + if (!previousValue.equals(string)) { + valueMap.put(uuid, string); + return true; + } + return false; + } + + public void removeViewer(Player viewer) { + valueMap.remove(viewer.getUniqueId()); + } + + public String getProcessedText() { + return processedText; + } + + public String getLatestValue(Player viewer) { + return valueMap.get(viewer.getUniqueId()); + } + + public Entity getOwner() { + return owner; + } + + public static class ClaimedText { + + private final String placeholder; + private final Player owner; + private String latestValue; + + public ClaimedText(Player owner, String placeholder) { + this.placeholder = placeholder; + this.owner = owner; + this.latestValue = null; + this.update(); + } + + public void update() { + if (owner == null) return; + this.latestValue = PlaceholderAPI.setPlaceholders(owner, placeholder); + } + + public String getValue(Player viewer) { + return Objects.requireNonNullElseGet( + latestValue, + () -> PlaceholderAPI.setPlaceholders(owner == null ? viewer : owner, placeholder) + ); + } + } +} diff --git a/api/src/main/java/net/momirealms/customnameplates/api/mechanic/nameplate/CachedNameplate.java b/api/src/main/java/net/momirealms/customnameplates/api/mechanic/nameplate/CachedNameplate.java new file mode 100644 index 0000000..40c1e6b --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/mechanic/nameplate/CachedNameplate.java @@ -0,0 +1,70 @@ +package net.momirealms.customnameplates.api.mechanic.nameplate; + +import net.momirealms.customnameplates.api.mechanic.team.TeamColor; + +public class CachedNameplate { + + private TeamColor teamColor; + private String tagPrefix; + private String tagSuffix; + private String namePrefix; + private String nameSuffix; + private String playerName; + + public CachedNameplate() { + this.tagPrefix = ""; + this.tagSuffix = ""; + this.namePrefix = ""; + this.nameSuffix = ""; + this.playerName = ""; + this.teamColor = TeamColor.WHITE; + } + + public String getTagPrefix() { + return tagPrefix; + } + + public void setTagPrefix(String prefix) { + this.tagPrefix = prefix; + } + + public String getTagSuffix() { + return tagSuffix; + } + + public void setTagSuffix(String suffix) { + this.tagSuffix = suffix; + } + + public void setNamePrefix(String namePrefix) { + this.namePrefix = namePrefix; + } + + public void setNameSuffix(String nameSuffix) { + this.nameSuffix = nameSuffix; + } + + public String getNamePrefix() { + return namePrefix; + } + + public String getNameSuffix() { + return nameSuffix; + } + + public TeamColor getTeamColor() { + return teamColor; + } + + public void setTeamColor(TeamColor teamColor) { + this.teamColor = teamColor; + } + + public String getPlayerName() { + return playerName; + } + + public void setPlayerName(String playerName) { + this.playerName = playerName; + } +} diff --git a/api/src/main/java/net/momirealms/customnameplates/api/mechanic/nameplate/Nameplate.java b/api/src/main/java/net/momirealms/customnameplates/api/mechanic/nameplate/Nameplate.java new file mode 100644 index 0000000..bdd40e3 --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/mechanic/nameplate/Nameplate.java @@ -0,0 +1,166 @@ +package net.momirealms.customnameplates.api.mechanic.nameplate; + +import net.momirealms.customnameplates.api.mechanic.character.ConfiguredChar; +import net.momirealms.customnameplates.api.mechanic.font.OffsetFont; +import net.momirealms.customnameplates.api.mechanic.team.TeamColor; +import net.momirealms.customnameplates.api.util.FontUtils; + +public class Nameplate { + + private String displayName; + private TeamColor teamColor; + private String namePrefix; + private String nameSuffix; + private ConfiguredChar left; + private ConfiguredChar middle; + private ConfiguredChar right; + + private Nameplate() { + } + + public Nameplate( + String displayName, + TeamColor teamColor, + String namePrefix, + String nameSuffix, + ConfiguredChar left, + ConfiguredChar middle, + ConfiguredChar right + ) { + this.displayName = displayName; + this.teamColor = teamColor; + this.left = left; + this.middle = middle; + this.right = right; + this.namePrefix = namePrefix; + this.nameSuffix = nameSuffix; + } + + public String getDisplayName() { + return displayName; + } + + public TeamColor getTeamColor() { + return teamColor; + } + + public ConfiguredChar getLeft() { + return left; + } + + public ConfiguredChar getMiddle() { + return middle; + } + + public ConfiguredChar getRight() { + return right; + } + + public String getNamePrefix() { + if (teamColor == TeamColor.NONE) { + return ""; + } + if (teamColor == TeamColor.CUSTOM) { + return namePrefix; + } + return "<" + teamColor.name() + ">"; + } + + public String getNameSuffix() { + if (teamColor == TeamColor.NONE) { + return ""; + } + if (teamColor == TeamColor.CUSTOM) { + return nameSuffix; + } + return ""; + } + + public static Builder builder() { + return new Builder(); + } + + public String getPrefixWithFont(int textWidth) { + return FontUtils.surroundNameplateFont(getPrefix(textWidth)); + } + + public String getPrefix(int textWidth) { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append(OffsetFont.getShortestNegChars(textWidth % 2 == 0 ? textWidth + left.getWidth() : textWidth + left.getWidth() + 1)); + stringBuilder.append(left.getCharacter()); + stringBuilder.append(OffsetFont.NEG_1.getCharacter()); + int mid_amount = (textWidth - 1) / (middle.getWidth()); + if (mid_amount != 0) { + for (int i = 0; i < mid_amount; i++) { + stringBuilder.append(middle.getCharacter()); + stringBuilder.append(OffsetFont.NEG_1.getCharacter()); + } + stringBuilder.append(OffsetFont.getShortestNegChars(middle.getWidth() - textWidth % middle.getWidth())); // +1 + } + stringBuilder.append(middle.getCharacter()); + stringBuilder.append(OffsetFont.NEG_1.getCharacter()); + stringBuilder.append(right.getCharacter()); + stringBuilder.append(OffsetFont.getShortestNegChars(textWidth + right.getWidth() - 1)); // -1 + return stringBuilder.toString(); + } + + public String getSuffixWithFont(int textWidth) { + return FontUtils.surroundNameplateFont(getSuffix(textWidth)); + } + + public String getSuffix(int textWidth) { + return OffsetFont.getShortestNegChars(textWidth + textWidth % 2 + 1); + } + + public static class Builder { + + private final Nameplate nameplate; + + public Builder() { + this.nameplate = new Nameplate(); + } + + public static Builder of() { + return new Builder(); + } + + public Builder displayName(String display) { + nameplate.displayName = display; + return this; + } + + public Builder teamColor(TeamColor teamColor) { + nameplate.teamColor = teamColor; + return this; + } + + public Builder namePrefix(String namePrefix) { + nameplate.namePrefix = namePrefix; + return this; + } + + public Builder nameSuffix(String nameSuffix) { + nameplate.nameSuffix = nameSuffix; + return this; + } + + public Builder left(ConfiguredChar configuredChar) { + nameplate.left = configuredChar; + return this; + } + + public Builder middle(ConfiguredChar configuredChar) { + nameplate.middle = configuredChar; + return this; + } + + public Builder right(ConfiguredChar configuredChar) { + nameplate.right = configuredChar; + return this; + } + + public Nameplate build() { + return nameplate; + } + } +} diff --git a/api/src/main/java/net/momirealms/customnameplates/api/mechanic/nameplate/TagMode.java b/api/src/main/java/net/momirealms/customnameplates/api/mechanic/nameplate/TagMode.java new file mode 100644 index 0000000..774c228 --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/mechanic/nameplate/TagMode.java @@ -0,0 +1,7 @@ +package net.momirealms.customnameplates.api.mechanic.nameplate; + +public enum TagMode { + TEAM, + UNLIMITED, + DISABLE +} diff --git a/api/src/main/java/net/momirealms/customnameplates/api/mechanic/placeholder/BackGroundText.java b/api/src/main/java/net/momirealms/customnameplates/api/mechanic/placeholder/BackGroundText.java new file mode 100644 index 0000000..a359e64 --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/mechanic/placeholder/BackGroundText.java @@ -0,0 +1,65 @@ +package net.momirealms.customnameplates.api.mechanic.placeholder; + +import me.clip.placeholderapi.PlaceholderAPI; +import net.momirealms.customnameplates.api.mechanic.background.BackGround; +import net.momirealms.customnameplates.api.util.FontUtils; +import org.bukkit.OfflinePlayer; + +public class BackGroundText { + + private String text; + private BackGround backGround; + + private BackGroundText() { + } + + public BackGroundText(String text, BackGround backGround) { + this.text = text; + this.backGround = backGround; + } + + public String getText() { + return text; + } + + public BackGround getBackGround() { + return backGround; + } + + public String getValue(OfflinePlayer player) { + String parsed = PlaceholderAPI.setPlaceholders(player, text); + int parsedWidth = FontUtils.getTextWidth(parsed); + return backGround.getBackGroundImage(parsedWidth) + parsed; + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + + private final BackGroundText text; + + public Builder() { + this.text = new BackGroundText(); + } + + public static Builder of() { + return new Builder(); + } + + public Builder text(String value) { + text.text = value; + return this; + } + + public Builder background(BackGround backGround) { + text.backGround = backGround; + return this; + } + + public BackGroundText build() { + return text; + } + } +} diff --git a/api/src/main/java/net/momirealms/customnameplates/api/mechanic/placeholder/CachedText.java b/api/src/main/java/net/momirealms/customnameplates/api/mechanic/placeholder/CachedText.java new file mode 100644 index 0000000..b52ba7e --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/mechanic/placeholder/CachedText.java @@ -0,0 +1,54 @@ +package net.momirealms.customnameplates.api.mechanic.placeholder; + +public class CachedText { + + private long refreshInterval; + private String text; + + private CachedText() { + } + + public CachedText(long refreshInterval, String text) { + this.refreshInterval = refreshInterval; + this.text = text; + } + + public long getRefreshInterval() { + return refreshInterval; + } + + public String getText() { + return text; + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + + private final CachedText text; + + public Builder() { + this.text = new CachedText(); + } + + public static Builder of() { + return new Builder(); + } + + public Builder refreshInterval(long time) { + this.text.refreshInterval = time; + return this; + } + + public Builder text(String text) { + this.text.text = text; + return this; + } + + public CachedText build() { + return text; + } + } +} diff --git a/api/src/main/java/net/momirealms/customnameplates/api/mechanic/placeholder/ConditionalText.java b/api/src/main/java/net/momirealms/customnameplates/api/mechanic/placeholder/ConditionalText.java new file mode 100644 index 0000000..bf64792 --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/mechanic/placeholder/ConditionalText.java @@ -0,0 +1,58 @@ +package net.momirealms.customnameplates.api.mechanic.placeholder; + +import me.clip.placeholderapi.PlaceholderAPI; +import net.momirealms.customnameplates.api.common.Pair; +import net.momirealms.customnameplates.api.manager.RequirementManager; +import net.momirealms.customnameplates.api.requirement.Condition; +import net.momirealms.customnameplates.api.requirement.Requirement; +import org.bukkit.OfflinePlayer; + +import java.util.List; + +public class ConditionalText { + + private List> textList; + + private ConditionalText() { + } + + public ConditionalText(List> textList) { + this.textList = textList; + } + + public static Builder builder() { + return new Builder(); + } + + public String getValue(OfflinePlayer player) { + Condition condition = new Condition(player); + for (Pair pair : textList) { + if (RequirementManager.isRequirementMet(condition, pair.right())) { + return PlaceholderAPI.setPlaceholders(player, pair.left()); + } + } + return ""; + } + + public static class Builder { + + private final ConditionalText conditionalText; + + public static Builder of() { + return new Builder(); + } + + public Builder() { + this.conditionalText = new ConditionalText(); + } + + public Builder textList(List> textList) { + conditionalText.textList = textList; + return this; + } + + public ConditionalText build() { + return conditionalText; + } + } +} diff --git a/api/src/main/java/net/momirealms/customnameplates/api/mechanic/placeholder/DescentText.java b/api/src/main/java/net/momirealms/customnameplates/api/mechanic/placeholder/DescentText.java new file mode 100644 index 0000000..e3a3379 --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/mechanic/placeholder/DescentText.java @@ -0,0 +1,68 @@ +package net.momirealms.customnameplates.api.mechanic.placeholder; + +import me.clip.placeholderapi.PlaceholderAPI; +import net.momirealms.customnameplates.api.util.FontUtils; +import org.bukkit.OfflinePlayer; + +public class DescentText { + + private int ascent; + private String text; + private boolean isUnicode; + + public DescentText(int ascent, String text, boolean isUnicode) { + this.ascent = ascent; + this.text = text; + this.isUnicode = isUnicode; + } + + private DescentText() { + + } + + public static Builder builder() { + return new Builder(); + } + + public String getValue(OfflinePlayer player) { + var parsed = PlaceholderAPI.setPlaceholders(player, text); + return isUnicode ? FontUtils.surroundAscentUnicodeFont(parsed, ascent) : FontUtils.surroundAscentFont(parsed, ascent); + } + + public static class Builder { + + private final DescentText descentText; + + public static Builder of() { + return new Builder(); + } + + public Builder() { + this.descentText = new DescentText(); + } + + public Builder ascent(int ascent) { + descentText.ascent = ascent; + return this; + } + + public Builder descent(int descent) { + descentText.ascent = 8 - descent; + return this; + } + + public Builder text(String text) { + descentText.text = text; + return this; + } + + public Builder unicode(boolean unicode) { + descentText.isUnicode = unicode; + return this; + } + + public DescentText build() { + return descentText; + } + } +} diff --git a/api/src/main/java/net/momirealms/customnameplates/api/mechanic/placeholder/NameplateText.java b/api/src/main/java/net/momirealms/customnameplates/api/mechanic/placeholder/NameplateText.java new file mode 100644 index 0000000..932823c --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/mechanic/placeholder/NameplateText.java @@ -0,0 +1,71 @@ +package net.momirealms.customnameplates.api.mechanic.placeholder; + +import me.clip.placeholderapi.PlaceholderAPI; +import net.momirealms.customnameplates.api.mechanic.nameplate.Nameplate; +import net.momirealms.customnameplates.api.util.FontUtils; +import org.bukkit.OfflinePlayer; + +public class NameplateText { + + private String text; + private Nameplate nameplate; + + private NameplateText() { + } + + public NameplateText(String text, Nameplate nameplate) { + this.text = text; + this.nameplate = nameplate; + } + + public String getText() { + return text; + } + + public Nameplate getNameplate() { + return nameplate; + } + + public String getValue(OfflinePlayer player) { + String temp; + switch (nameplate.getTeamColor()) { + case CUSTOM -> temp = nameplate.getNamePrefix() + text + nameplate.getNameSuffix(); + case NONE -> temp = text; + default -> temp = "<" + nameplate.getTeamColor().name() + ">" + text + ""; + } + String parsed = PlaceholderAPI.setPlaceholders(player, temp); + int parsedWidth = FontUtils.getTextWidth(parsed); + return nameplate.getPrefixWithFont(parsedWidth) + parsed + nameplate.getSuffixWithFont(parsedWidth); + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + + private final NameplateText text; + + public Builder() { + this.text = new NameplateText(); + } + + public static Builder of() { + return new Builder(); + } + + public Builder text(String value) { + text.text = value; + return this; + } + + public Builder nameplate(Nameplate value) { + text.nameplate = value; + return this; + } + + public NameplateText build() { + return text; + } + } +} diff --git a/api/src/main/java/net/momirealms/customnameplates/api/mechanic/placeholder/StaticText.java b/api/src/main/java/net/momirealms/customnameplates/api/mechanic/placeholder/StaticText.java new file mode 100644 index 0000000..a2bf8a4 --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/mechanic/placeholder/StaticText.java @@ -0,0 +1,98 @@ +package net.momirealms.customnameplates.api.mechanic.placeholder; + +import me.clip.placeholderapi.PlaceholderAPI; +import net.momirealms.customnameplates.api.mechanic.font.OffsetFont; +import net.momirealms.customnameplates.api.util.FontUtils; +import org.bukkit.OfflinePlayer; + +public class StaticText { + + private String text; + private int value; + private StaticState staticState; + + private StaticText() { + } + + public StaticText(String text, int value, StaticState staticState) { + this.text = text; + this.value = value; + this.staticState = staticState; + } + + public String getText() { + return text; + } + + public int getValue() { + return value; + } + + public static Builder builder() { + return new Builder(); + } + + public StaticState getStaticState() { + return staticState; + } + + public String getValue(OfflinePlayer player) { + String parsed = PlaceholderAPI.setPlaceholders(player, text); + int parsedWidth = FontUtils.getTextWidth(parsed); + switch (staticState) { + case LEFT -> { + return parsed + FontUtils.surroundNameplateFont(OffsetFont.getOffsetChars(value - parsedWidth)); + } + case RIGHT -> { + return FontUtils.surroundNameplateFont(OffsetFont.getOffsetChars(value - parsedWidth)) + parsed; + } + case MIDDLE -> { + int half = (value - parsedWidth) / 2; + String left = FontUtils.surroundNameplateFont(OffsetFont.getOffsetChars(half)); + String right = FontUtils.surroundNameplateFont(OffsetFont.getOffsetChars(value - parsedWidth - half)); + return left + parsed + right; + } + default -> { + return ""; + } + } + } + + public static class Builder { + + private final StaticText text; + + public Builder() { + this.text = new StaticText(); + } + + public static Builder of() { + return new Builder(); + } + + public Builder value(int value) { + text.value = value; + return this; + } + + public Builder text(String value) { + text.text = value; + return this; + } + + public Builder state(StaticState state) { + text.staticState = state; + return this; + } + + public StaticText build() { + return text; + } + } + + public enum StaticState { + LEFT, + MIDDLE, + RIGHT + } +} diff --git a/api/src/main/java/net/momirealms/customnameplates/api/mechanic/placeholder/SwitchText.java b/api/src/main/java/net/momirealms/customnameplates/api/mechanic/placeholder/SwitchText.java new file mode 100644 index 0000000..4b54934 --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/mechanic/placeholder/SwitchText.java @@ -0,0 +1,63 @@ +package net.momirealms.customnameplates.api.mechanic.placeholder; + +import me.clip.placeholderapi.PlaceholderAPI; +import org.bukkit.entity.Player; + +import java.util.HashMap; + +public class SwitchText { + + private HashMap valueMap; + private String toParse; + private String defaultValue; + + public static Builder builder() { + return new Builder(); + } + + private SwitchText() { + + } + + public SwitchText(HashMap valueMap, String toParse) { + this.valueMap = valueMap; + this.toParse = toParse; + } + + public String getValue(Player player) { + String parsed = PlaceholderAPI.setPlaceholders(player, toParse); + return valueMap.getOrDefault(parsed, defaultValue); + } + + public static class Builder { + + private final SwitchText switchText; + + public Builder() { + this.switchText = new SwitchText(); + } + + public static Builder of() { + return new Builder(); + } + + public Builder toParse(String toParse) { + this.switchText.toParse = toParse; + return this; + } + + public Builder defaultValue(String value) { + this.switchText.defaultValue = value; + return this; + } + + public Builder valueMap(HashMap valueMap) { + this.switchText.valueMap = valueMap; + return this; + } + + public SwitchText build() { + return switchText; + } + } +} diff --git a/api/src/main/java/net/momirealms/customnameplates/api/mechanic/placeholder/VanillaHud.java b/api/src/main/java/net/momirealms/customnameplates/api/mechanic/placeholder/VanillaHud.java new file mode 100644 index 0000000..6a8d137 --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/mechanic/placeholder/VanillaHud.java @@ -0,0 +1,58 @@ +package net.momirealms.customnameplates.api.mechanic.placeholder; + +import me.clip.placeholderapi.PlaceholderAPI; +import net.momirealms.customnameplates.api.CustomNameplatesPlugin; +import net.momirealms.customnameplates.api.util.FontUtils; +import net.momirealms.customnameplates.api.util.LogUtils; +import org.bukkit.entity.Player; + +public class VanillaHud { + + private final char empty; + private final char half; + private final char full; + private final String maxPapi; + private final String currentPapi; + private final boolean reverse; + + public VanillaHud(String empty, String half, String full, String maxPapi, String currentPapi, boolean reverse) { + this.empty = CustomNameplatesPlugin.get().getImageManager().getImage(empty).getCharacter(); + this.half = CustomNameplatesPlugin.get().getImageManager().getImage(half).getCharacter(); + this.full = CustomNameplatesPlugin.get().getImageManager().getImage(full).getCharacter(); + this.maxPapi = maxPapi; + this.currentPapi = currentPapi; + this.reverse = reverse; + } + + public String getValue(Player player) { + double current; + double max; + try { + current= Double.parseDouble(PlaceholderAPI.setPlaceholders(player, currentPapi)); + max = Double.parseDouble(PlaceholderAPI.setPlaceholders(player, maxPapi)); + } catch (NumberFormatException e) { + current = 1; + max = 1; + LogUtils.warn("Invalid number format when parsing: " + currentPapi + "/" + maxPapi); + } + if (current >= max) current = max; + if (current < 0) current = 0; + int point = (int) ((current / max) * 20); + int full_amount = point / 2; + int half_amount = point % 2; + int empty_amount = 10 - full_amount - half_amount; + StringBuilder builder = new StringBuilder(); + if (reverse) { + builder + .append(String.valueOf(empty).repeat(empty_amount)) + .append(String.valueOf(half).repeat(half_amount)) + .append(String.valueOf(full).repeat(full_amount)); + } else { + builder + .append(String.valueOf(full).repeat(full_amount)) + .append(String.valueOf(half).repeat(half_amount)) + .append(String.valueOf(empty).repeat(empty_amount)); + } + return FontUtils.surroundNameplateFont(builder.toString()); + } +} diff --git a/api/src/main/java/net/momirealms/customnameplates/api/mechanic/tag/NameplatePlayer.java b/api/src/main/java/net/momirealms/customnameplates/api/mechanic/tag/NameplatePlayer.java new file mode 100644 index 0000000..0c33ecf --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/mechanic/tag/NameplatePlayer.java @@ -0,0 +1,13 @@ +package net.momirealms.customnameplates.api.mechanic.tag; + +import net.momirealms.customnameplates.api.mechanic.nameplate.Nameplate; +import org.bukkit.entity.Player; + +public interface NameplatePlayer { + + void preview(); + + void preview(Nameplate nameplate); + + Player getOwner(); +} diff --git a/api/src/main/java/net/momirealms/customnameplates/api/mechanic/tag/team/TeamPlayer.java b/api/src/main/java/net/momirealms/customnameplates/api/mechanic/tag/team/TeamPlayer.java new file mode 100644 index 0000000..b4813e7 --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/mechanic/tag/team/TeamPlayer.java @@ -0,0 +1,109 @@ +package net.momirealms.customnameplates.api.mechanic.tag.team; + +import net.kyori.adventure.text.Component; +import net.momirealms.customnameplates.api.CustomNameplatesPlugin; +import net.momirealms.customnameplates.api.manager.TeamTagManager; +import net.momirealms.customnameplates.api.mechanic.misc.ViewerText; +import net.momirealms.customnameplates.api.mechanic.nameplate.Nameplate; +import net.momirealms.customnameplates.api.mechanic.tag.NameplatePlayer; +import net.momirealms.customnameplates.api.mechanic.team.TeamColor; +import net.momirealms.customnameplates.api.mechanic.team.TeamTagVisibility; +import org.bukkit.entity.Player; + +import java.util.Vector; + +public class TeamPlayer implements NameplatePlayer { + + private final TeamTagManager manager; + private final Player owner; + private final ViewerText prefix; + private final ViewerText suffix; + private final Vector nearbyPlayers; + + public TeamPlayer(TeamTagManager manager, Player owner, String prefix, String suffix) { + this.manager = manager; + this.owner = owner; + this.prefix = new ViewerText(owner, prefix); + this.suffix = new ViewerText(owner, suffix); + this.nearbyPlayers = new Vector<>(); + this.prefix.updateForOwner(); + this.suffix.updateForOwner(); + } + + public void updateForNearbyPlayers(boolean force) { + this.prefix.updateForOwner(); + this.suffix.updateForOwner(); + for (Player viewer : nearbyPlayers) { + updateForOne(viewer, force); + } + } + + public void removeNearbyPlayer(Player player) { + if (!nearbyPlayers.contains(player)) { + return; + } + nearbyPlayers.remove(player); + removeForOne(player); + prefix.removeViewer(player); + suffix.removeViewer(player); + } + + public void addNearbyPlayer(Player player) { + if (nearbyPlayers.contains(player)) { + return; + } + nearbyPlayers.add(player); + updateForOne(player, false); + } + + public void destroy() { + manager.removeTeamPlayerFromMap(owner.getUniqueId()); + for (Player viewer : nearbyPlayers) { + removeForOne(viewer); + } + nearbyPlayers.clear(); + } + + private void updateForOne(Player viewer, boolean force) { + try { + if ((prefix.updateForViewer(viewer) | suffix.updateForViewer(viewer)) || force) { + CustomNameplatesPlugin.get().getTeamManager().updateTeam( + owner, + viewer, + CustomNameplatesPlugin.get().getAdventure().getComponentFromMiniMessage(prefix.getLatestValue(viewer)), + CustomNameplatesPlugin.get().getAdventure().getComponentFromMiniMessage(suffix.getLatestValue(viewer)), + CustomNameplatesPlugin.get().getNameplateManager().getTeamColor(owner), + TeamTagVisibility.ALWAYS + ); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void removeForOne(Player viewer) { + CustomNameplatesPlugin.get().getTeamManager().updateTeam( + owner, + viewer, + Component.text(""), + Component.text(""), + TeamColor.WHITE, + TeamTagVisibility.ALWAYS + ); + } + + @Override + public void preview() { + + } + + @Override + public void preview(Nameplate nameplate) { + + } + + @Override + public Player getOwner() { + return owner; + } +} diff --git a/api/src/main/java/net/momirealms/customnameplates/api/mechanic/tag/unlimited/NamedEntity.java b/api/src/main/java/net/momirealms/customnameplates/api/mechanic/tag/unlimited/NamedEntity.java new file mode 100644 index 0000000..9627010 --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/mechanic/tag/unlimited/NamedEntity.java @@ -0,0 +1,60 @@ +package net.momirealms.customnameplates.api.mechanic.tag.unlimited; + +import net.momirealms.customnameplates.api.mechanic.misc.ViewerText; +import org.bukkit.entity.Player; +import org.bukkit.entity.Pose; + +import java.util.UUID; + +public interface NamedEntity { + + boolean canSee(Player viewer); + + void timer(); + + boolean canShow(); + + boolean isShownTo(Player viewer); + + void spawn(Player viewer, Pose pose); + + void spawn(Pose pose); + + void destroy(); + + void destroy(Player viewer); + + void teleport(double x, double y, double z, boolean onGround); + + void teleport(Player viewer, double x, double y, double z, boolean onGround); + + void setSneak(boolean sneaking, boolean respawn); + + void removePlayerFromViewers(Player player); + + void addPlayerToViewers(Player player); + + double getOffset(); + + void setOffset(double v); + + ViewerText getViewerText(); + + int getEntityId(); + + void move(short x, short y, short z, boolean onGround); + + void move(Player viewer, short x, short y, short z, boolean onGround); + + void respawn(Player viewer, Pose pose); + + void respawn(Pose pose); + + void updateText(); + + void updateText(Player viewer); + + UUID getUuid(); + + void handlePose(Pose previous, Pose pose); +} diff --git a/api/src/main/java/net/momirealms/customnameplates/api/mechanic/tag/unlimited/UnlimitedObject.java b/api/src/main/java/net/momirealms/customnameplates/api/mechanic/tag/unlimited/UnlimitedObject.java new file mode 100644 index 0000000..f31689f --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/mechanic/tag/unlimited/UnlimitedObject.java @@ -0,0 +1,39 @@ +package net.momirealms.customnameplates.api.mechanic.tag.unlimited; + +import net.momirealms.customnameplates.api.manager.UnlimitedTagManager; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Pose; + +import java.util.Vector; + +public abstract class UnlimitedObject { + + protected final UnlimitedTagManager manager; + protected final Entity entity; + protected final Vector nearbyPlayers; + + public UnlimitedObject(UnlimitedTagManager manager, Entity entity) { + this.manager = manager; + this.entity = entity; + this.nearbyPlayers = new Vector<>(); + } + + public Vector getNearbyPlayers() { + return nearbyPlayers; + } + + public abstract void addNearbyPlayer(Player player); + + public abstract void removeNearbyPlayer(Player player); + + public abstract void move(Player receiver, short x, short y, short z, boolean onGround); + + public abstract void teleport(Player receiver, double x, double y, double z, boolean onGround); + + public abstract void destroy(); + + public abstract void sneak(boolean sneaking, boolean flying); + + public abstract void handlePose(Pose previous, Pose pose); +} diff --git a/api/src/main/java/net/momirealms/customnameplates/api/mechanic/tag/unlimited/UnlimitedPlayer.java b/api/src/main/java/net/momirealms/customnameplates/api/mechanic/tag/unlimited/UnlimitedPlayer.java new file mode 100644 index 0000000..dd04925 --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/mechanic/tag/unlimited/UnlimitedPlayer.java @@ -0,0 +1,201 @@ +package net.momirealms.customnameplates.api.mechanic.tag.unlimited; + +import net.kyori.adventure.text.Component; +import net.momirealms.customnameplates.api.CustomNameplatesPlugin; +import net.momirealms.customnameplates.api.manager.UnlimitedTagManager; +import net.momirealms.customnameplates.api.mechanic.nameplate.Nameplate; +import net.momirealms.customnameplates.api.mechanic.tag.NameplatePlayer; +import net.momirealms.customnameplates.api.mechanic.team.TeamColor; +import net.momirealms.customnameplates.api.mechanic.team.TeamTagVisibility; +import org.bukkit.entity.Player; +import org.bukkit.entity.Pose; + +import java.util.Vector; + +public class UnlimitedPlayer extends UnlimitedObject implements NameplatePlayer { + + private final Player owner; + private final Vector tags; + private double hatOffset; + + public UnlimitedPlayer(UnlimitedTagManager manager, Player player) { + super(manager, player); + this.owner = player; + this.tags = new Vector<>(); + } + + /** + * Add a tag for a player + * + * @param tag tag + */ + public void addTag(NamedEntity tag) { + if (tags.contains(tag)) { + return; + } + tags.add(tag); + for (Player all : nearbyPlayers) { + if (tag.canShow() && tag.canSee(all)) { + tag.addPlayerToViewers(all); + } + } + } + + /** + * Remove a tag for a player + * + * @param tag tag + */ + public void removeTag(NamedEntity tag) { + if (tags.remove(tag)) { + tag.destroy(); + } + } + + /** + * Get the tags that player own + * + * @return tags + */ + public Vector getTags() { + return tags; + } + + /** + * Set hat offset. This is useful for cosmetics plugins + * because hat might hide the name tags + * + * @param hatOffset hat offset + */ + public void setHatOffset(double hatOffset) { + this.hatOffset = hatOffset; + } + + @Override + public void preview() { + + } + + @Override + public void preview(Nameplate nameplate) { + + } + + /** + * Get the owner + */ + @Override + public Player getOwner() { + return owner; + } + + /** + * Get the hat offset + */ + public double getHatOffset() { + return hatOffset; + } + + /** + * Add a nearby player so he could see the tag + * This process is automatically handled by CustomNameplates + * + * @param player player + */ + @Override + public void addNearbyPlayer(Player player) { + if (nearbyPlayers.contains(player)) { + return; + } + nearbyPlayers.add(player); + addForOne(player); + for (NamedEntity tag : tags) { + if (tag.canShow() && tag.canSee(player)) { + tag.addPlayerToViewers(player); + } + } + } + + /** + * Remove a nearby player so he would no longer receive tag updates + * This process is automatically handled by CustomNameplates + * + * @param player player + */ + @Override + public void removeNearbyPlayer(Player player) { + if (!nearbyPlayers.contains(player)) { + return; + } + super.nearbyPlayers.remove(player); + removeForOne(player); + for (NamedEntity tag : tags) { + tag.removePlayerFromViewers(player); + } + } + + @Override + public void destroy() { + manager.removeUnlimitedObjectFromMap(entity.getUniqueId()); + for (Player viewer : nearbyPlayers) { + removeForOne(viewer); + } + for (NamedEntity tag : tags) { + tag.destroy(); + } + nearbyPlayers.clear(); + tags.clear(); + } + + public void move(Player receiver, short x, short y, short z, boolean onGround) { + for (NamedEntity tag : tags) { + tag.move(receiver, x, y, z, onGround); + } + } + + public void teleport(Player receiver, double x, double y, double z, boolean onGround) { + for (NamedEntity tag : tags) { + tag.teleport(receiver, x, y, z, onGround); + } + } + + public void sneak(boolean sneaking, boolean flying) { + for (NamedEntity tag : tags) { + tag.setSneak(sneaking, !flying); + } + } + + public void handlePose(Pose previous, Pose pose) { + for (NamedEntity tag : tags) { + tag.handlePose(previous, pose); + } + } + + private void addForOne(Player viewer) { + CustomNameplatesPlugin.get().getTeamManager().updateTeam( + owner, + viewer, + Component.text(""), + Component.text(""), + TeamColor.WHITE, + TeamTagVisibility.NEVER + ); + } + + private void removeForOne(Player viewer) { + CustomNameplatesPlugin.get().getTeamManager().updateTeam( + owner, + viewer, + Component.text(""), + Component.text(""), + TeamColor.WHITE, + TeamTagVisibility.ALWAYS + ); + } + + public void timer() { + for (NamedEntity tag : tags) { + tag.timer(); + } + } +} diff --git a/api/src/main/java/net/momirealms/customnameplates/api/mechanic/tag/unlimited/UnlimitedTagSetting.java b/api/src/main/java/net/momirealms/customnameplates/api/mechanic/tag/unlimited/UnlimitedTagSetting.java new file mode 100644 index 0000000..8905345 --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/mechanic/tag/unlimited/UnlimitedTagSetting.java @@ -0,0 +1,106 @@ +package net.momirealms.customnameplates.api.mechanic.tag.unlimited; + +import net.momirealms.customnameplates.api.requirement.Requirement; + +public class UnlimitedTagSetting { + + private double verticalOffset; + private String rawText; + private int checkFrequency; + private int refreshFrequency; + private Requirement[] viewerRequirements; + private Requirement[] ownerRequirements; + + private UnlimitedTagSetting() { + verticalOffset = 0; + rawText = ""; + checkFrequency = 10; + refreshFrequency = 10; + viewerRequirements = new Requirement[0]; + ownerRequirements = new Requirement[0]; + } + + public UnlimitedTagSetting(double verticalOffset, String rawText, int checkFrequency, int refreshFrequency, Requirement[] viewerRequirements, Requirement[] ownerRequirements) { + this.verticalOffset = verticalOffset; + this.rawText = rawText; + this.checkFrequency = checkFrequency; + this.refreshFrequency = refreshFrequency; + this.viewerRequirements = viewerRequirements; + this.ownerRequirements = ownerRequirements; + } + + public static Builder builder() { + return new Builder(); + } + + public double getVerticalOffset() { + return verticalOffset; + } + + public String getRawText() { + return rawText; + } + + public int getCheckFrequency() { + return checkFrequency; + } + + public int getRefreshFrequency() { + return refreshFrequency; + } + + public Requirement[] getViewerRequirements() { + return viewerRequirements; + } + + public Requirement[] getOwnerRequirements() { + return ownerRequirements; + } + + public static class Builder { + + private final UnlimitedTagSetting setting; + + public static Builder of() { + return new Builder(); + } + + public Builder() { + this.setting = new UnlimitedTagSetting(); + } + + public Builder checkFrequency(int checkFrequency) { + this.setting.checkFrequency = checkFrequency; + return this; + } + + public Builder refreshFrequency(int refreshFrequency) { + this.setting.refreshFrequency = refreshFrequency; + return this; + } + + public Builder rawText(String rawText) { + this.setting.rawText = rawText; + return this; + } + + public Builder verticalOffset(double verticalOffset) { + this.setting.verticalOffset = verticalOffset; + return this; + } + + public Builder ownerRequirements(Requirement[] ownerRequirements) { + this.setting.ownerRequirements = ownerRequirements; + return this; + } + + public Builder viewerRequirements(Requirement[] viewerRequirements) { + this.setting.viewerRequirements = viewerRequirements; + return this; + } + + public UnlimitedTagSetting build() { + return setting; + } + } +} diff --git a/api/src/main/java/net/momirealms/customnameplates/api/mechanic/team/TeamCollisionRule.java b/api/src/main/java/net/momirealms/customnameplates/api/mechanic/team/TeamCollisionRule.java new file mode 100644 index 0000000..341ce87 --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/mechanic/team/TeamCollisionRule.java @@ -0,0 +1,31 @@ +package net.momirealms.customnameplates.api.mechanic.team; + +import org.jetbrains.annotations.NotNull; + +import java.util.Arrays; + +public enum TeamCollisionRule { + + ALWAYS("always"), + NEVER("never"), + PUSH_OTHER_TEAMS("pushOtherTeams"), + PUSH_OWN_TEAM("pushOwnTeam"); + + private final String id; + + TeamCollisionRule(@NotNull String id) { + this.id = id; + } + + public String getId() { + return id; + } + + @NotNull + public static TeamCollisionRule byId(String id) { + return Arrays.stream(values()) + .filter(mode -> mode.id.equals(id)) + .findFirst() + .orElse(ALWAYS); + } +} diff --git a/api/src/main/java/net/momirealms/customnameplates/api/mechanic/team/TeamColor.java b/api/src/main/java/net/momirealms/customnameplates/api/mechanic/team/TeamColor.java new file mode 100644 index 0000000..fb20fdf --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/mechanic/team/TeamColor.java @@ -0,0 +1,29 @@ +package net.momirealms.customnameplates.api.mechanic.team; + +import java.util.Locale; + +public enum TeamColor { + + NONE, + BLACK, + DARK_BLUE, + DARK_GREEN, + DARK_AQUA, + DARK_RED, + DARK_PURPLE, + GOLD, + GRAY, + DARK_GRAY, + BLUE, + GREEN, + AQUA, + RED, + LIGHT_PURPLE, + YELLOW, + WHITE, + CUSTOM; + + public TeamColor getById(String id) throws IllegalArgumentException { + return valueOf(id.toUpperCase(Locale.ENGLISH)); + } +} diff --git a/api/src/main/java/net/momirealms/customnameplates/api/mechanic/team/TeamCreatePacket.java b/api/src/main/java/net/momirealms/customnameplates/api/mechanic/team/TeamCreatePacket.java new file mode 100644 index 0000000..d1cede2 --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/mechanic/team/TeamCreatePacket.java @@ -0,0 +1,154 @@ +package net.momirealms.customnameplates.api.mechanic.team; + +import net.kyori.adventure.text.Component; + +import java.util.Collection; +import java.util.Collections; + +public class TeamCreatePacket { + + // String i + private String teamName; + // Collection j + private Collection members; + + /* + Optional k + */ + // IChatBaseComponent a + private Component teamDisplay; + // IChatBaseComponent b + private Component teamPrefix; + // IChatBaseComponent c + private Component teamSuffix; + // String d + private TeamTagVisibility tagVisibility; + // String e + private TeamCollisionRule collisionRule; + // Enum f + private TeamColor teamColor; + + private TeamCreatePacket() { + this.teamName = ""; + this.members = Collections.singleton(""); + this.teamDisplay = Component.text(""); + this.teamPrefix = Component.text(""); + this.teamSuffix = Component.text(""); + this.tagVisibility = TeamTagVisibility.ALWAYS; + this.collisionRule = TeamCollisionRule.ALWAYS; + this.teamColor = TeamColor.WHITE; + } + + public TeamCreatePacket( + String teamName, + Collection members, + Component teamDisplay, + Component teamPrefix, + Component teamSuffix, + TeamTagVisibility tagVisibility, + TeamCollisionRule collisionRule, + TeamColor teamColor + ) { + this.teamName = teamName; + this.members = members; + this.teamDisplay = teamDisplay; + this.teamPrefix = teamPrefix; + this.teamSuffix = teamSuffix; + this.tagVisibility = tagVisibility; + this.collisionRule = collisionRule; + this.teamColor = teamColor; + } + + public String getTeamName() { + return teamName; + } + + public Collection getMembers() { + return members; + } + + public Component getTeamDisplay() { + return teamDisplay; + } + + public Component getTeamPrefix() { + return teamPrefix; + } + + public Component getTeamSuffix() { + return teamSuffix; + } + + public TeamTagVisibility getTagVisibility() { + return tagVisibility; + } + + public TeamCollisionRule getCollisionRule() { + return collisionRule; + } + + public TeamColor getTeamColor() { + return teamColor; + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + + private final TeamCreatePacket packet; + + public Builder() { + this.packet = new TeamCreatePacket(); + } + + public static Builder of() { + return new Builder(); + } + + public Builder teamName(String name) { + packet.teamName = name; + return this; + } + + public Builder members(Collection members) { + packet.members = members; + return this; + } + + public Builder display(Component display) { + packet.teamDisplay = display; + return this; + } + + public Builder prefix(Component prefix) { + packet.teamPrefix = prefix; + return this; + } + + public Builder suffix(Component suffix) { + packet.teamSuffix = suffix; + return this; + } + + public Builder color(TeamColor color) { + packet.teamColor = color; + return this; + } + + public Builder tagVisibility(TeamTagVisibility visibility) { + packet.tagVisibility = visibility; + return this; + } + + public Builder collisionRule(TeamCollisionRule rule) { + packet.collisionRule = rule; + return this; + } + + public TeamCreatePacket build() { + return packet; + } + } +} diff --git a/api/src/main/java/net/momirealms/customnameplates/api/mechanic/team/TeamRemovePacket.java b/api/src/main/java/net/momirealms/customnameplates/api/mechanic/team/TeamRemovePacket.java new file mode 100644 index 0000000..60d3038 --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/mechanic/team/TeamRemovePacket.java @@ -0,0 +1,39 @@ +package net.momirealms.customnameplates.api.mechanic.team; + +public class TeamRemovePacket { + + private String teamName; + + private TeamRemovePacket() { + } + + public TeamRemovePacket(String teamName) { + this.teamName = teamName; + } + + public String getTeamName() { + return teamName; + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + + private final TeamRemovePacket packet; + + public Builder() { + this.packet = new TeamRemovePacket(); + } + + public Builder teamName(String teamName) { + packet.teamName = teamName; + return this; + } + + public TeamRemovePacket build() { + return packet; + } + } +} diff --git a/api/src/main/java/net/momirealms/customnameplates/api/mechanic/team/TeamTagVisibility.java b/api/src/main/java/net/momirealms/customnameplates/api/mechanic/team/TeamTagVisibility.java new file mode 100644 index 0000000..421d983 --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/mechanic/team/TeamTagVisibility.java @@ -0,0 +1,31 @@ +package net.momirealms.customnameplates.api.mechanic.team; + +import org.jetbrains.annotations.NotNull; + +import java.util.Arrays; + +public enum TeamTagVisibility { + + ALWAYS("always"), + HIDE_FOR_OTHER_TEAMS("hideForOtherTeams"), + HIDE_FOR_OWN_TEAM("hideForOwnTeam"), + NEVER("never"); + + private final String id; + + TeamTagVisibility(@NotNull String id) { + this.id = id; + } + + public String getId() { + return id; + } + + @NotNull + public static TeamTagVisibility byId(String id) { + return Arrays.stream(values()) + .filter(mode -> mode.id.equals(id)) + .findFirst() + .orElse(ALWAYS); + } +} diff --git a/api/src/main/java/net/momirealms/customnameplates/api/mechanic/team/TeamUpdatePacket.java b/api/src/main/java/net/momirealms/customnameplates/api/mechanic/team/TeamUpdatePacket.java new file mode 100644 index 0000000..4b53360 --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/mechanic/team/TeamUpdatePacket.java @@ -0,0 +1,136 @@ +package net.momirealms.customnameplates.api.mechanic.team; + +import net.kyori.adventure.text.Component; + +public class TeamUpdatePacket { + + private String teamName; + + /* + Optional k + */ + // IChatBaseComponent a + private Component teamDisplay; + // IChatBaseComponent b + private Component teamPrefix; + // IChatBaseComponent c + private Component teamSuffix; + // String d + private TeamTagVisibility tagVisibility; + // String e + private TeamCollisionRule collisionRule; + // Enum f + private TeamColor teamColor; + + private TeamUpdatePacket() { + this.teamName = ""; + this.teamDisplay = Component.text(""); + this.teamPrefix = Component.text(""); + this.teamSuffix = Component.text(""); + this.tagVisibility = TeamTagVisibility.ALWAYS; + this.collisionRule = TeamCollisionRule.ALWAYS; + this.teamColor = TeamColor.WHITE; + } + + public TeamUpdatePacket( + String teamName, + Component teamDisplay, + Component teamPrefix, + Component teamSuffix, + TeamTagVisibility tagVisibility, + TeamCollisionRule collisionRule, + TeamColor teamColor + ) { + this.teamName = teamName; + this.teamDisplay = teamDisplay; + this.teamPrefix = teamPrefix; + this.teamSuffix = teamSuffix; + this.tagVisibility = tagVisibility; + this.collisionRule = collisionRule; + this.teamColor = teamColor; + } + + public String getTeamName() { + return teamName; + } + + public Component getTeamDisplay() { + return teamDisplay; + } + + public Component getTeamPrefix() { + return teamPrefix; + } + + public Component getTeamSuffix() { + return teamSuffix; + } + + public TeamTagVisibility getTagVisibility() { + return tagVisibility; + } + + public TeamCollisionRule getCollisionRule() { + return collisionRule; + } + + public TeamColor getTeamColor() { + return teamColor; + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + + private final TeamUpdatePacket packet; + + public Builder() { + this.packet = new TeamUpdatePacket(); + } + + public static Builder of() { + return new Builder(); + } + + public Builder teamName(String name) { + packet.teamName = name; + return this; + } + + public Builder display(Component display) { + packet.teamDisplay = display; + return this; + } + + public Builder prefix(Component prefix) { + packet.teamPrefix = prefix; + return this; + } + + public Builder suffix(Component suffix) { + packet.teamSuffix = suffix; + return this; + } + + public Builder color(TeamColor color) { + packet.teamColor = color; + return this; + } + + public Builder tagVisibility(TeamTagVisibility visibility) { + packet.tagVisibility = visibility; + return this; + } + + public Builder collisionRule(TeamCollisionRule rule) { + packet.collisionRule = rule; + return this; + } + + public TeamUpdatePacket build() { + return packet; + } + } +} diff --git a/api/src/main/java/net/momirealms/customnameplates/api/requirement/Condition.java b/api/src/main/java/net/momirealms/customnameplates/api/requirement/Condition.java new file mode 100644 index 0000000..60238bb --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/requirement/Condition.java @@ -0,0 +1,16 @@ +package net.momirealms.customnameplates.api.requirement; + +import org.bukkit.OfflinePlayer; + +public class Condition { + + private final OfflinePlayer player; + + public Condition(OfflinePlayer player) { + this.player = player; + } + + public OfflinePlayer getOfflinePlayer() { + return player; + } +} diff --git a/src/main/java/net/momirealms/customnameplates/object/requirements/Requirement.java b/api/src/main/java/net/momirealms/customnameplates/api/requirement/Requirement.java similarity index 75% rename from src/main/java/net/momirealms/customnameplates/object/requirements/Requirement.java rename to api/src/main/java/net/momirealms/customnameplates/api/requirement/Requirement.java index 8ee8b79..9424121 100644 --- a/src/main/java/net/momirealms/customnameplates/object/requirements/Requirement.java +++ b/api/src/main/java/net/momirealms/customnameplates/api/requirement/Requirement.java @@ -15,10 +15,15 @@ * along with this program. If not, see . */ -package net.momirealms.customnameplates.object.requirements; - -import org.bukkit.entity.Player; +package net.momirealms.customnameplates.api.requirement; public interface Requirement { - boolean isConditionMet(Player player); + + /** + * Is condition met the requirement + * + * @param condition condition + * @return meet or not + */ + boolean isConditionMet(Condition condition); } diff --git a/api/src/main/java/net/momirealms/customnameplates/api/requirement/RequirementExpansion.java b/api/src/main/java/net/momirealms/customnameplates/api/requirement/RequirementExpansion.java new file mode 100644 index 0000000..df9ce14 --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/requirement/RequirementExpansion.java @@ -0,0 +1,53 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customnameplates.api.requirement; + +/** + * An abstract class representing a requirement expansion + * Requirement expansions are used to define custom requirements for various functionalities. + */ +public abstract class RequirementExpansion { + + /** + * Get the version of this requirement expansion. + * + * @return The version of the expansion. + */ + public abstract String getVersion(); + + /** + * Get the author of this requirement expansion. + * + * @return The author of the expansion. + */ + public abstract String getAuthor(); + + /** + * Get the type of requirement provided by this expansion. + * + * @return The type of requirement. + */ + public abstract String getRequirementType(); + + /** + * Get the factory for creating requirements defined by this expansion. + * + * @return The requirement factory. + */ + public abstract RequirementFactory getRequirementFactory(); +} diff --git a/src/main/java/net/momirealms/customnameplates/object/Function.java b/api/src/main/java/net/momirealms/customnameplates/api/requirement/RequirementFactory.java similarity index 64% rename from src/main/java/net/momirealms/customnameplates/object/Function.java rename to api/src/main/java/net/momirealms/customnameplates/api/requirement/RequirementFactory.java index 8b0061b..74b2840 100644 --- a/src/main/java/net/momirealms/customnameplates/object/Function.java +++ b/api/src/main/java/net/momirealms/customnameplates/api/requirement/RequirementFactory.java @@ -15,24 +15,18 @@ * along with this program. If not, see . */ -package net.momirealms.customnameplates.object; +package net.momirealms.customnameplates.api.requirement; -import org.bukkit.entity.Player; +/** + * An interface for a requirement factory that builds requirements. + */ +public interface RequirementFactory { -public abstract class Function { - - public void load() { - } - - public void unload() { - } - - public void disable() { - } - - public void onJoin(Player player) { - } - - public void onQuit(Player player) { - } + /** + * Build a requirement with the given arguments. + * + * @param args The arguments used to build the requirement. + * @return The built requirement. + */ + Requirement build(Object args); } diff --git a/src/main/java/net/momirealms/customnameplates/object/scheduler/TimerTask.java b/api/src/main/java/net/momirealms/customnameplates/api/scheduler/CancellableTask.java similarity index 76% rename from src/main/java/net/momirealms/customnameplates/object/scheduler/TimerTask.java rename to api/src/main/java/net/momirealms/customnameplates/api/scheduler/CancellableTask.java index 793de07..d226bf8 100644 --- a/src/main/java/net/momirealms/customnameplates/object/scheduler/TimerTask.java +++ b/api/src/main/java/net/momirealms/customnameplates/api/scheduler/CancellableTask.java @@ -15,11 +15,19 @@ * along with this program. If not, see . */ -package net.momirealms.customnameplates.object.scheduler; +package net.momirealms.customnameplates.api.scheduler; -public interface TimerTask { +public interface CancellableTask { + /** + * Cancel the task + */ void cancel(); + /** + * Get if the task is cancelled or not + * + * @return cancelled or not + */ boolean isCancelled(); } diff --git a/api/src/main/java/net/momirealms/customnameplates/api/scheduler/Scheduler.java b/api/src/main/java/net/momirealms/customnameplates/api/scheduler/Scheduler.java new file mode 100644 index 0000000..9b20769 --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/scheduler/Scheduler.java @@ -0,0 +1,93 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customnameplates.api.scheduler; + +import org.bukkit.Location; + +import java.util.concurrent.TimeUnit; + +public interface Scheduler { + + /** + * Runs a task synchronously on the main server thread or region thread. + * + * @param runnable The task to run. + * @param location The location associated with the task. + */ + void runTaskSync(Runnable runnable, Location location); + + /** + * Runs a task synchronously with a specified delay and period. + * + * @param runnable The task to run. + * @param location The location associated with the task. + * @param delayTicks The delay in ticks before the first execution. + * @param periodTicks The period between subsequent executions in ticks. + * @return A CancellableTask for managing the scheduled task. + */ + CancellableTask runTaskSyncTimer(Runnable runnable, Location location, long delayTicks, long periodTicks); + + /** + * Runs a task asynchronously with a specified delay. + * + * @param runnable The task to run. + * @param delay The delay before the task execution. + * @param timeUnit The time unit for the delay. + * @return A CancellableTask for managing the scheduled task. + */ + CancellableTask runTaskAsyncLater(Runnable runnable, long delay, TimeUnit timeUnit); + + /** + * Runs a task asynchronously. + * + * @param runnable The task to run. + */ + void runTaskAsync(Runnable runnable); + + /** + * Runs a task synchronously with a specified delay. + * + * @param runnable The task to run. + * @param location The location associated with the task. + * @param delay The delay before the task execution. + * @param timeUnit The time unit for the delay. + * @return A CancellableTask for managing the scheduled task. + */ + CancellableTask runTaskSyncLater(Runnable runnable, Location location, long delay, TimeUnit timeUnit); + + /** + * Runs a task synchronously with a specified delay in ticks. + * + * @param runnable The task to run. + * @param location The location associated with the task. + * @param delayTicks The delay in ticks before the task execution. + * @return A CancellableTask for managing the scheduled task. + */ + CancellableTask runTaskSyncLater(Runnable runnable, Location location, long delayTicks); + + /** + * Runs a task asynchronously with a specified delay and period. + * + * @param runnable The task to run. + * @param delay The delay before the first execution. + * @param period The period between subsequent executions. + * @param timeUnit The time unit for the delay and period. + * @return A CancellableTask for managing the scheduled task. + */ + CancellableTask runTaskAsyncTimer(Runnable runnable, long delay, long period, TimeUnit timeUnit); +} diff --git a/api/src/main/java/net/momirealms/customnameplates/api/util/FontUtils.java b/api/src/main/java/net/momirealms/customnameplates/api/util/FontUtils.java new file mode 100644 index 0000000..c1afdd0 --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/util/FontUtils.java @@ -0,0 +1,76 @@ +package net.momirealms.customnameplates.api.util; + +public class FontUtils { + + private static String namespace; + private static String font; + + /** + * Surround the text with ascent font + * + * @param text text + * @param ascent ascent + * @return ascent font text + */ + public static String surroundAscentFont(String text, int ascent) { + return getAscentFontTag(ascent) + text + getFontTagCloser(); + } + + /** + * Surround the text with ascent unicode + * + * @param text text + * @param ascent ascent + * @return ascent font text + */ + public static String surroundAscentUnicodeFont(String text, int ascent) { + return getAscentUnicodeFontTag(ascent) + text + getFontTagCloser(); + } + + /** + * Surround the text with custom nameplates font + * + * @param text text + * @return font text + */ + public static String surroundNameplateFont(String text) { + return getMiniMessageFontTag() + text + getFontTagCloser(); + } + + private static String getAscentFontTag(int ascent) { + return ""; + } + + private static String getAscentUnicodeFontTag(int ascent) { + return ""; + } + + private static String getMiniMessageFontTag() { + return ""; + } + + private static String getFontTagCloser() { + return ""; + } + + /** + * Get a text's width + * + * @param text text + * @return width + */ + public static int getTextWidth(String text) { + return 0; + } + + /** + * Set namespace and font + * + * @param n namespace + * @param f font + */ + public static void setNameSpaceAndFont(String n, String f) { + namespace = n; + font = f; + } +} diff --git a/api/src/main/java/net/momirealms/customnameplates/api/util/LogUtils.java b/api/src/main/java/net/momirealms/customnameplates/api/util/LogUtils.java new file mode 100644 index 0000000..dde8f82 --- /dev/null +++ b/api/src/main/java/net/momirealms/customnameplates/api/util/LogUtils.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customnameplates.api.util; + +import net.momirealms.customnameplates.api.CustomNameplatesPlugin; +import org.jetbrains.annotations.NotNull; + +import java.util.logging.Level; + +public final class LogUtils { + + /** + * Log an informational message. + * + * @param message The message to log. + */ + public static void info(@NotNull String message) { + CustomNameplatesPlugin.getInstance().getLogger().info(message); + } + + /** + * Log a warning message. + * + * @param message The message to log. + */ + public static void warn(@NotNull String message) { + CustomNameplatesPlugin.getInstance().getLogger().warning(message); + } + + /** + * Log a severe error message. + * + * @param message The message to log. + */ + public static void severe(@NotNull String message) { + CustomNameplatesPlugin.getInstance().getLogger().severe(message); + } + + /** + * Log a warning message with a throwable exception. + * + * @param message The message to log. + * @param throwable The throwable exception to log. + */ + public static void warn(@NotNull String message, Throwable throwable) { + CustomNameplatesPlugin.getInstance().getLogger().log(Level.WARNING, message, throwable); + } + + /** + * Log a severe error message with a throwable exception. + * + * @param message The message to log. + * @param throwable The throwable exception to log. + */ + public static void severe(@NotNull String message, Throwable throwable) { + CustomNameplatesPlugin.getInstance().getLogger().log(Level.SEVERE, message, throwable); + } + + private LogUtils() { + throw new UnsupportedOperationException("This class cannot be instantiated"); + } +} diff --git a/build.gradle b/build.gradle deleted file mode 100644 index 28a7e0e..0000000 --- a/build.gradle +++ /dev/null @@ -1,81 +0,0 @@ -plugins { - id 'java' - id 'com.github.johnrengelman.shadow' version '7.1.2' -} - -group = 'net.momirealms' -version = '2.2.3.18.1' - -repositories { - maven {name = "aliyun-repo"; url = "https://maven.aliyun.com/repository/public/"} - maven {name = "sk89q-repo"; url = "https://maven.enginehub.org/repo/"} - maven {name = 'sonatype'; url = 'https://oss.sonatype.org/content/groups/public/'} - maven {name = 'sonatype-snapshot'; url = 'https://s01.oss.sonatype.org/content/repositories/snapshots/'} - maven {name = "dmulloy2-repo"; url = "https://repo.dmulloy2.net/repository/public/"} - maven {name = "clip-repo"; url = 'https://repo.extendedclip.com/content/repositories/placeholderapi/'} - maven {name = "jitpack"; url = 'https://jitpack.io'} - maven {name = "codecrafter47-repo"; url = 'https://nexus.codecrafter47.de/content/repositories/public/'} - maven {name = "opencollab-snapshot-repo"; url = 'https://repo.opencollab.dev/main/'} - maven {name = 'papermc-repo'; url = 'https://papermc.io/repo/repository/maven-public/'} - maven {name = 'William278-repo'; url = 'https://repo.william278.net/releases/'} - maven {name = 'kryptonmc-repo'; url = 'https://repo.kryptonmc.org/releases'} - mavenCentral() -} - -dependencies { - compileOnly fileTree(dir:'libs',includes:['*.jar']) - compileOnly('dev.folia:folia-api:1.20.1-R0.1-SNAPSHOT') - compileOnly ('me.clip:placeholderapi:2.11.3') - compileOnly ('com.zaxxer:HikariCP:5.0.1') - compileOnly ('commons-io:commons-io:2.11.0') - compileOnly ('dev.dejvokep:boosted-yaml:1.3.1') - compileOnly ("com.comphenix.protocol:ProtocolLib:5.1.0") - compileOnly ('net.md-5:bungeecord-api:1.19-R0.1-SNAPSHOT') - compileOnly ('com.github.LoneDev6:api-itemsadder:3.4.1-r4') - compileOnly ("com.velocitypowered:velocity-api:3.1.1") - compileOnly ('org.geysermc.geyser:api:2.2.0-SNAPSHOT') - compileOnly ("net.william278:velocitab:1.5.1") - compileOnly ('me.neznamy:tab-api:4.0.2') - compileOnly ('com.github.FrancoBM12:API-MagicCosmetics:2.2.5') - annotationProcessor ('com.velocitypowered:velocity-api:3.1.1') - - compileOnly ('org.apache.commons:commons-lang3:3.12.0') - implementation ('net.kyori:adventure-api:4.14.0') - implementation ('net.kyori:adventure-platform-bukkit:4.3.3-SNAPSHOT') - implementation ('net.kyori:adventure-text-minimessage:4.14.0') - implementation ('net.kyori:adventure-text-serializer-gson:4.14.0') - implementation ("org.bstats:bstats-bukkit:3.0.1") - implementation fileTree (dir:'libs',includes:['BiomeAPI.jar']) -} - -def targetJavaVersion = 17 -java { - def javaVersion = JavaVersion.toVersion(targetJavaVersion) - sourceCompatibility = javaVersion - targetCompatibility = javaVersion -} - -tasks.withType(JavaCompile).configureEach { - options.release = targetJavaVersion - options.encoding = "UTF-8" -} - -processResources { - def props = [version: version] - inputs.properties props - filteringCharset 'UTF-8' - filesMatching('plugin.yml') { - expand props - } -} - -shadowJar { - relocate ('net.kyori', 'net.momirealms.customnameplates.libs.net.kyori') - relocate ('org.bstats', 'net.momirealms.customnameplates.libs.org.bstats') - relocate ('net.momirealms.biomeapi', 'net.momirealms.customnameplates.libs.net.momirealms.biomeapi') -} - -tasks.register("delete", Delete).get().delete("build/libs/"+project.name+"-"+project.version+".jar") -tasks.named("build").get().dependsOn("shadowJar").finalizedBy("delete").doLast { - println("Deleting: "+ "build/libs/"+project.name+"-"+project.version+".jar") -} \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 0000000..1241825 --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,80 @@ +plugins { + id("java") + id("application") + id("maven-publish") + id("com.github.johnrengelman.shadow") version "8.1.1" +} + +allprojects { + + version = "2.3.0.0" + + apply() + apply(plugin = "java") + apply(plugin = "application") + apply(plugin = "com.github.johnrengelman.shadow") + apply(plugin = "org.gradle.maven-publish") + + application { + mainClass.set("") + } + + repositories { + maven("https://maven.aliyun.com/repository/public/") + mavenCentral() + maven("https://papermc.io/repo/repository/maven-public/") + maven("https://oss.sonatype.org/content/groups/public/") + maven("https://repo.dmulloy2.net/repository/public/") + maven("https://repo.extendedclip.com/content/repositories/placeholderapi/") + maven("https://repo.codemc.org/repository/maven-public/") + maven("https://maven.enginehub.org/repo/") + maven("https://jitpack.io/") + maven("https://mvn.lumine.io/repository/maven-public/") + maven("https://repo.rapture.pw/repository/maven-releases/") + maven("https://nexus.phoenixdevt.fr/repository/maven-public/") + maven("https://r.irepo.space/maven/") + maven("https://repo.auxilor.io/repository/maven-public/") + maven("https://betonquest.org/nexus/repository/betonquest/") + maven("https://repo.william278.net/releases/") + maven("https://s01.oss.sonatype.org/content/repositories/snapshots/") + maven("https://repo.minebench.de/") + maven("https://repo.xenondevs.xyz/releases/") + maven("https://repo.kryptonmc.org/releases") + maven("https://repo.oraxen.com/releases") + } +} + +subprojects { + tasks.processResources { + val props = mapOf("version" to version) + inputs.properties(props) + filteringCharset = "UTF-8" + filesMatching("*plugin.yml") { + expand(props) + } + } + + tasks.withType { + options.encoding = "UTF-8" + options.release.set(17) + } + + tasks.shadowJar { + destinationDirectory.set(file("$rootDir/target")) + archiveClassifier.set("") + archiveFileName.set("CustomNameplates-" + project.name + "-" + project.version + ".jar") + } + + if ("api" == project.name) { + publishing { + publications { + create("mavenJava") { + groupId = "net.momirealms" + artifactId = "CustomNameplates" + version = rootProject.version.toString() + artifact(tasks.shadowJar) + } + } + } + } +} \ No newline at end of file diff --git a/bungeecord/.gitignore b/bungeecord/.gitignore new file mode 100644 index 0000000..b63da45 --- /dev/null +++ b/bungeecord/.gitignore @@ -0,0 +1,42 @@ +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/bungeecord/build.gradle.kts b/bungeecord/build.gradle.kts new file mode 100644 index 0000000..0ce6a16 --- /dev/null +++ b/bungeecord/build.gradle.kts @@ -0,0 +1,3 @@ +dependencies { + +} \ No newline at end of file diff --git a/bungeecord/src/main/resources/plugin.yml b/bungeecord/src/main/resources/plugin.yml new file mode 100644 index 0000000..5bf5d9b --- /dev/null +++ b/bungeecord/src/main/resources/plugin.yml @@ -0,0 +1,9 @@ +name: CustomNameplates +version: '${version}' +main: net.momirealms.customnameplates.paper.Main +api-version: 1.17 +authors: [ XiaoMoMi ] +folia-supported: true +depend: + - ProtocolLib + - PlaceholderAPI \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 7454180f2ae8848c63b8b4dea2cb829da983f2fa..c1962a79e29d3e0ab67b14947c167a862655af9b 100644 GIT binary patch delta 40133 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/dev/null 2>&1 +then + die "xargs is not available" +fi + # Use "xargs" to parse quoted args. # # With -n1 it outputs one arg per line, with the quotes and backslashes removed. diff --git a/gradlew.bat b/gradlew.bat index 107acd3..93e3f59 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -14,7 +14,7 @@ @rem limitations under the License. @rem -@if "%DEBUG%" == "" @echo off +@if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @@ -25,7 +25,8 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @@ -40,7 +41,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute +if %ERRORLEVEL% equ 0 goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -75,13 +76,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar :end @rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd +if %ERRORLEVEL% equ 0 goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% :mainEnd if "%OS%"=="Windows_NT" endlocal diff --git a/jitpack.yml b/jitpack.yml new file mode 100644 index 0000000..1e41e00 --- /dev/null +++ b/jitpack.yml @@ -0,0 +1,2 @@ +jdk: + - openjdk17 \ No newline at end of file diff --git a/libs/MagicCosmetics-2.3.7-API.jar b/libs/MagicCosmetics-2.3.7-API.jar deleted file mode 100644 index f13e6cba65c9722bcb9ca2770c4985014db0dd12..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 174575 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

Ee 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

~!$Px|;4A^F1*J7cybR1` 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