From f4d9e45427d9a5468c9bc8a0e0fca7543919dad4 Mon Sep 17 00:00:00 2001 From: hypherionmc Date: Thu, 9 May 2024 14:28:27 +0200 Subject: [PATCH] [DEV] Convert to new porting system --- .gitignore | 4 +- Common/build.gradle | 68 --- Common/gradle.properties | 2 - .../craterlib/CraterConstants.java | 10 - .../craterlib/api/commands/CraterCommand.java | 53 --- .../events/client/CraterClientTickEvent.java | 14 - .../client/CraterSinglePlayerEvent.java | 21 - .../api/events/client/LateInitEvent.java | 16 - .../events/client/PlayerJoinRealmEvent.java | 14 - .../api/events/client/ScreenEvent.java | 27 -- .../events/common/CraterPlayerDeathEvent.java | 21 - .../events/server/CraterAdvancementEvent.java | 34 -- .../api/events/server/CraterCommandEvent.java | 58 --- .../api/events/server/CraterPlayerEvent.java | 30 -- .../server/CraterRegisterCommandEvent.java | 15 - .../events/server/CraterServerChatEvent.java | 25 -- .../server/CraterServerLifecycleEvent.java | 34 -- .../events/server/MessageBroadcastEvent.java | 20 - .../events/server/PlayerPreLoginEvent.java | 20 - .../api/networking/CommonPacketWrapper.java | 19 - .../api/networking/CraterNetworkHandler.java | 28 -- .../client/gui/config/CraterConfigScreen.java | 393 ------------------ .../config/widgets/AbstractConfigWidget.java | 27 -- .../client/gui/config/widgets/BaseWidget.java | 61 --- .../config/widgets/InternalConfigButton.java | 51 --- .../client/gui/config/widgets/Option.java | 71 ---- .../gui/config/widgets/SubConfigWidget.java | 40 -- .../gui/config/widgets/TextConfigOption.java | 45 -- .../gui/config/widgets/ToggleButton.java | 33 -- .../gui/config/widgets/WrappedEditBox.java | 29 -- .../client/mentions/MentionCondition.java | 13 - .../client/mentions/MentionsController.java | 47 --- .../core/config/ConfigController.java | 49 --- .../craterlib/core/config/ModuleConfig.java | 184 -------- .../config/annotations/HideFromScreen.java | 8 - .../config/annotations/NoConfigScreen.java | 12 - .../core/config/annotations/SubConfig.java | 16 - .../core/config/annotations/Syncable.java | 15 - .../core/config/annotations/Tooltip.java | 16 - .../craterlib/core/event/CraterEvent.java | 30 -- .../craterlib/core/event/CraterEventBus.java | 241 ----------- .../core/event/CraterEventPriority.java | 13 - .../core/event/annot/Cancellable.java | 8 - .../core/event/annot/CraterEventListener.java | 11 - .../CraterEventCancellationException.java | 9 - .../craterlib/core/event/package-info.java | 5 - .../core/networking/CraterPacketNetwork.java | 43 -- .../networking/DeferredPacketRegistrar.java | 41 -- .../core/networking/PacketRegistrar.java | 21 - .../core/networking/PacketRegistry.java | 41 -- .../core/networking/data/PacketContext.java | 15 - .../core/networking/data/PacketHolder.java | 40 -- .../core/networking/data/PacketSide.java | 13 - .../core/platform/ClientPlatform.java | 23 - .../core/platform/CommonPlatform.java | 15 - .../craterlib/core/platform/CompatUtils.java | 13 - .../craterlib/core/platform/Environment.java | 18 - .../core/platform/ModloaderEnvironment.java | 32 -- .../core/rpcsdk/DiscordEventHandlers.java | 90 ---- .../craterlib/core/rpcsdk/DiscordRPC.java | 99 ----- .../core/rpcsdk/DiscordRichPresence.java | 248 ----------- .../craterlib/core/rpcsdk/DiscordUser.java | 39 -- .../callbacks/DisconnectedCallback.java | 18 - .../rpcsdk/callbacks/ErroredCallback.java | 18 - .../rpcsdk/callbacks/JoinGameCallback.java | 17 - .../rpcsdk/callbacks/JoinRequestCallback.java | 19 - .../core/rpcsdk/callbacks/ReadyCallback.java | 19 - .../callbacks/SpectateGameCallback.java | 17 - .../core/rpcsdk/helpers/RPCButton.java | 55 --- .../mixin/ChatInputSuggestorMixin.java | 84 ---- .../craterlib/mixin/events/CommandMixin.java | 37 -- .../mixin/events/PlayerAdvancementsMixin.java | 31 -- .../mixin/events/PlayerListMixin.java | 53 --- .../craterlib/mixin/events/PlayerMixin.java | 21 - .../mixin/events/ServerPlayerMixin.java | 21 - .../mixin/events/client/ClientLevelMixin.java | 25 -- .../mixin/events/client/MinecraftMixin.java | 31 -- .../events/client/RealmsMainScreenMixin.java | 23 - .../advancements/BridgedAdvancement.java | 21 - .../advancements/BridgedDisplayInfo.java | 29 -- .../nojang/authlib/BridgedGameProfile.java | 29 -- .../nojang/client/BridgedMinecraft.java | 84 ---- .../nojang/client/BridgedOptions.java | 15 - .../nojang/client/gui/BridgedScreen.java | 36 -- .../multiplayer/BridgedClientLevel.java | 59 --- .../client/multiplayer/BridgedServerData.java | 40 -- .../server/BridgedIntegratedServer.java | 19 - .../commands/BridgedCommandSourceStack.java | 22 - .../nojang/commands/BridgedFakePlayer.java | 55 --- .../nojang/commands/CommandsRegistry.java | 85 ---- .../nojang/core/BridgedBlockPos.java | 27 -- .../nojang/nbt/BridgedCompoundTag.java | 49 --- .../network/BridgedFriendlyByteBuf.java | 34 -- .../craterlib/nojang/package-info.java | 9 - .../realmsclient/dto/BridgedRealmsServer.java | 40 -- .../nojang/resources/ResourceIdentifier.java | 36 -- .../nojang/server/BridgedMinecraftServer.java | 91 ---- .../world/entity/player/BridgedPlayer.java | 63 --- .../craterlib/utils/ChatUtils.java | 90 ---- .../craterlib/utils/InternalServiceUtil.java | 27 -- .../craterlib/utils/OptifineUtils.java | 46 -- .../assets/craterlib/lang/en_us.json | 8 - .../src/main/resources/craterlib.mixins.json | 24 -- Common/src/main/resources/pack.mcmeta | 6 - Fabric/build.gradle | 126 ------ .../craterlib/CraterLibInitializer.java | 42 -- .../CraterLibModMenuIntegration.java | 30 -- .../client/CraterLibClientInitializer.java | 27 -- .../client/FabricClientPlatform.java | 34 -- .../common/FabricCommonPlatform.java | 18 - .../craterlib/common/FabricCompatHelper.java | 23 - .../craterlib/common/FabricLoaderHelper.java | 69 --- .../craterlib/compat/FabricTailor.java | 23 - .../hypherionmc/craterlib/compat/Vanish.java | 25 -- .../ServerGamePacketListenerImplMixin.java | 36 -- .../craterlib/mixin/TutorialMixin.java | 24 -- .../network/CraterFabricNetworkHandler.java | 68 --- ...nmc.craterlib.core.platform.ClientPlatform | 1 - ...nmc.craterlib.core.platform.CommonPlatform | 1 - ...rionmc.craterlib.core.platform.CompatUtils | 1 - ...aterlib.core.platform.ModloaderEnvironment | 1 - .../assets/craterlib/craterlib_logo.png | Bin 49343 -> 0 bytes .../resources/craterlib.fabric.mixins.json | 17 - Fabric/src/main/resources/fabric.mod.json | 39 -- Forge/build.gradle | 112 ----- .../com/hypherionmc/craterlib/CraterLib.java | 41 -- .../craterlib/client/ForgeClientEvents.java | 25 -- .../craterlib/client/ForgeClientHelper.java | 41 -- .../craterlib/common/ForgeCommonHelper.java | 26 -- .../craterlib/common/ForgeCompatHelper.java | 22 - .../craterlib/common/ForgeLoaderHelper.java | 73 ---- .../craterlib/common/ForgeServerEvents.java | 43 -- .../hypherionmc/craterlib/compat/Vanish.java | 24 -- .../mixin/ConfigScreenHandlerMixin.java | 43 -- .../ServerGamePacketListenerImplMixin.java | 36 -- .../network/CraterForgeNetworkHandler.java | 98 ----- Forge/src/main/resources/META-INF/mods.toml | 31 -- ...nmc.craterlib.core.platform.ClientPlatform | 1 - ...nmc.craterlib.core.platform.CommonPlatform | 1 - ...rionmc.craterlib.core.platform.CompatUtils | 1 - ...aterlib.core.platform.ModloaderEnvironment | 1 - .../resources/craterlib.forge.mixins.json | 17 - Forge/src/main/resources/craterlib_logo.png | Bin 49343 -> 0 bytes NeoForge/build.gradle | 111 ----- .../com/hypherionmc/craterlib/CraterLib.java | 59 --- .../client/NeoForgeClientEvents.java | 25 -- .../client/NeoForgeClientHelper.java | 40 -- .../common/NeoForgeCommonHelper.java | 19 - .../common/NeoForgeCompatHelper.java | 22 - .../common/NeoForgeLoaderHelper.java | 73 ---- .../common/NeoForgeServerEvents.java | 43 -- .../hypherionmc/craterlib/compat/Vanish.java | 24 -- .../ServerGamePacketListenerImplMixin.java | 36 -- .../network/CraterNeoForgeNetworkHandler.java | 77 ---- .../resources/META-INF/neoforge.mods.toml | 31 -- ...nmc.craterlib.core.platform.ClientPlatform | 1 - ...nmc.craterlib.core.platform.CommonPlatform | 1 - ...rionmc.craterlib.core.platform.CompatUtils | 1 - ...aterlib.core.platform.ModloaderEnvironment | 1 - .../resources/craterlib.neoforge.mixins.json | 15 - .../src/main/resources/craterlib_logo.png | Bin 49343 -> 0 bytes build.gradle | 109 +---- changelog-fabric.md | 1 - changelog-forge.md | 1 - gradle.properties | 43 -- settings.gradle | 3 +- 166 files changed, 8 insertions(+), 6253 deletions(-) delete mode 100644 Common/build.gradle delete mode 100644 Common/gradle.properties delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/CraterConstants.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/api/commands/CraterCommand.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/api/events/client/CraterClientTickEvent.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/api/events/client/CraterSinglePlayerEvent.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/api/events/client/LateInitEvent.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/api/events/client/PlayerJoinRealmEvent.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/api/events/client/ScreenEvent.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/api/events/common/CraterPlayerDeathEvent.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterAdvancementEvent.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterCommandEvent.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterPlayerEvent.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterRegisterCommandEvent.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterServerChatEvent.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterServerLifecycleEvent.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/api/events/server/MessageBroadcastEvent.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/api/events/server/PlayerPreLoginEvent.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/api/networking/CommonPacketWrapper.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/api/networking/CraterNetworkHandler.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/CraterConfigScreen.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/AbstractConfigWidget.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/BaseWidget.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/InternalConfigButton.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/Option.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/SubConfigWidget.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/TextConfigOption.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/ToggleButton.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/WrappedEditBox.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/client/mentions/MentionCondition.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/client/mentions/MentionsController.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/core/config/ConfigController.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/core/config/ModuleConfig.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/core/config/annotations/HideFromScreen.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/core/config/annotations/NoConfigScreen.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/core/config/annotations/SubConfig.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/core/config/annotations/Syncable.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/core/config/annotations/Tooltip.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/core/event/CraterEvent.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/core/event/CraterEventBus.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/core/event/CraterEventPriority.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/core/event/annot/Cancellable.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/core/event/annot/CraterEventListener.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/core/event/exception/CraterEventCancellationException.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/core/event/package-info.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/core/networking/CraterPacketNetwork.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/core/networking/DeferredPacketRegistrar.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/core/networking/PacketRegistrar.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/core/networking/PacketRegistry.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/core/networking/data/PacketContext.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/core/networking/data/PacketHolder.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/core/networking/data/PacketSide.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/core/platform/ClientPlatform.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/core/platform/CommonPlatform.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/core/platform/CompatUtils.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/core/platform/Environment.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/core/platform/ModloaderEnvironment.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/core/rpcsdk/DiscordEventHandlers.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/core/rpcsdk/DiscordRPC.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/core/rpcsdk/DiscordRichPresence.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/core/rpcsdk/DiscordUser.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/core/rpcsdk/callbacks/DisconnectedCallback.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/core/rpcsdk/callbacks/ErroredCallback.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/core/rpcsdk/callbacks/JoinGameCallback.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/core/rpcsdk/callbacks/JoinRequestCallback.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/core/rpcsdk/callbacks/ReadyCallback.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/core/rpcsdk/callbacks/SpectateGameCallback.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/core/rpcsdk/helpers/RPCButton.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/mixin/ChatInputSuggestorMixin.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/mixin/events/CommandMixin.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/mixin/events/PlayerAdvancementsMixin.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/mixin/events/PlayerListMixin.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/mixin/events/PlayerMixin.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/mixin/events/ServerPlayerMixin.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/mixin/events/client/ClientLevelMixin.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/mixin/events/client/MinecraftMixin.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/mixin/events/client/RealmsMainScreenMixin.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/nojang/advancements/BridgedAdvancement.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/nojang/advancements/BridgedDisplayInfo.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/nojang/authlib/BridgedGameProfile.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/nojang/client/BridgedMinecraft.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/nojang/client/BridgedOptions.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/nojang/client/gui/BridgedScreen.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/nojang/client/multiplayer/BridgedClientLevel.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/nojang/client/multiplayer/BridgedServerData.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/nojang/client/server/BridgedIntegratedServer.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/BridgedCommandSourceStack.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/BridgedFakePlayer.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/CommandsRegistry.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/nojang/core/BridgedBlockPos.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/nojang/nbt/BridgedCompoundTag.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/nojang/network/BridgedFriendlyByteBuf.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/nojang/package-info.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/nojang/realmsclient/dto/BridgedRealmsServer.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/nojang/resources/ResourceIdentifier.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/nojang/server/BridgedMinecraftServer.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/nojang/world/entity/player/BridgedPlayer.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/utils/ChatUtils.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/utils/InternalServiceUtil.java delete mode 100644 Common/src/main/java/com/hypherionmc/craterlib/utils/OptifineUtils.java delete mode 100644 Common/src/main/resources/assets/craterlib/lang/en_us.json delete mode 100644 Common/src/main/resources/craterlib.mixins.json delete mode 100644 Common/src/main/resources/pack.mcmeta delete mode 100644 Fabric/build.gradle delete mode 100644 Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibInitializer.java delete mode 100644 Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibModMenuIntegration.java delete mode 100644 Fabric/src/main/java/com/hypherionmc/craterlib/client/CraterLibClientInitializer.java delete mode 100644 Fabric/src/main/java/com/hypherionmc/craterlib/client/FabricClientPlatform.java delete mode 100644 Fabric/src/main/java/com/hypherionmc/craterlib/common/FabricCommonPlatform.java delete mode 100644 Fabric/src/main/java/com/hypherionmc/craterlib/common/FabricCompatHelper.java delete mode 100644 Fabric/src/main/java/com/hypherionmc/craterlib/common/FabricLoaderHelper.java delete mode 100644 Fabric/src/main/java/com/hypherionmc/craterlib/compat/FabricTailor.java delete mode 100644 Fabric/src/main/java/com/hypherionmc/craterlib/compat/Vanish.java delete mode 100644 Fabric/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java delete mode 100644 Fabric/src/main/java/com/hypherionmc/craterlib/mixin/TutorialMixin.java delete mode 100644 Fabric/src/main/java/com/hypherionmc/craterlib/network/CraterFabricNetworkHandler.java delete mode 100644 Fabric/src/main/resources/META-INF/services/com.hypherionmc.craterlib.core.platform.ClientPlatform delete mode 100644 Fabric/src/main/resources/META-INF/services/com.hypherionmc.craterlib.core.platform.CommonPlatform delete mode 100644 Fabric/src/main/resources/META-INF/services/com.hypherionmc.craterlib.core.platform.CompatUtils delete mode 100644 Fabric/src/main/resources/META-INF/services/com.hypherionmc.craterlib.core.platform.ModloaderEnvironment delete mode 100644 Fabric/src/main/resources/assets/craterlib/craterlib_logo.png delete mode 100644 Fabric/src/main/resources/craterlib.fabric.mixins.json delete mode 100644 Fabric/src/main/resources/fabric.mod.json delete mode 100644 Forge/build.gradle delete mode 100644 Forge/src/main/java/com/hypherionmc/craterlib/CraterLib.java delete mode 100644 Forge/src/main/java/com/hypherionmc/craterlib/client/ForgeClientEvents.java delete mode 100644 Forge/src/main/java/com/hypherionmc/craterlib/client/ForgeClientHelper.java delete mode 100644 Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeCommonHelper.java delete mode 100644 Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeCompatHelper.java delete mode 100644 Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeLoaderHelper.java delete mode 100644 Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java delete mode 100644 Forge/src/main/java/com/hypherionmc/craterlib/compat/Vanish.java delete mode 100644 Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java delete mode 100644 Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java delete mode 100644 Forge/src/main/java/com/hypherionmc/craterlib/network/CraterForgeNetworkHandler.java delete mode 100644 Forge/src/main/resources/META-INF/mods.toml delete mode 100644 Forge/src/main/resources/META-INF/services/com.hypherionmc.craterlib.core.platform.ClientPlatform delete mode 100644 Forge/src/main/resources/META-INF/services/com.hypherionmc.craterlib.core.platform.CommonPlatform delete mode 100644 Forge/src/main/resources/META-INF/services/com.hypherionmc.craterlib.core.platform.CompatUtils delete mode 100644 Forge/src/main/resources/META-INF/services/com.hypherionmc.craterlib.core.platform.ModloaderEnvironment delete mode 100644 Forge/src/main/resources/craterlib.forge.mixins.json delete mode 100644 Forge/src/main/resources/craterlib_logo.png delete mode 100644 NeoForge/build.gradle delete mode 100644 NeoForge/src/main/java/com/hypherionmc/craterlib/CraterLib.java delete mode 100644 NeoForge/src/main/java/com/hypherionmc/craterlib/client/NeoForgeClientEvents.java delete mode 100644 NeoForge/src/main/java/com/hypherionmc/craterlib/client/NeoForgeClientHelper.java delete mode 100644 NeoForge/src/main/java/com/hypherionmc/craterlib/common/NeoForgeCommonHelper.java delete mode 100644 NeoForge/src/main/java/com/hypherionmc/craterlib/common/NeoForgeCompatHelper.java delete mode 100644 NeoForge/src/main/java/com/hypherionmc/craterlib/common/NeoForgeLoaderHelper.java delete mode 100644 NeoForge/src/main/java/com/hypherionmc/craterlib/common/NeoForgeServerEvents.java delete mode 100644 NeoForge/src/main/java/com/hypherionmc/craterlib/compat/Vanish.java delete mode 100644 NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java delete mode 100644 NeoForge/src/main/java/com/hypherionmc/craterlib/network/CraterNeoForgeNetworkHandler.java delete mode 100644 NeoForge/src/main/resources/META-INF/neoforge.mods.toml delete mode 100644 NeoForge/src/main/resources/META-INF/services/com.hypherionmc.craterlib.core.platform.ClientPlatform delete mode 100644 NeoForge/src/main/resources/META-INF/services/com.hypherionmc.craterlib.core.platform.CommonPlatform delete mode 100644 NeoForge/src/main/resources/META-INF/services/com.hypherionmc.craterlib.core.platform.CompatUtils delete mode 100644 NeoForge/src/main/resources/META-INF/services/com.hypherionmc.craterlib.core.platform.ModloaderEnvironment delete mode 100644 NeoForge/src/main/resources/craterlib.neoforge.mixins.json delete mode 100644 NeoForge/src/main/resources/craterlib_logo.png delete mode 100644 changelog-fabric.md delete mode 100644 changelog-forge.md diff --git a/.gitignore b/.gitignore index 73ea0d4..dcfc706 100644 --- a/.gitignore +++ b/.gitignore @@ -22,4 +22,6 @@ eclipse run artifacts -src/test/** \ No newline at end of file +src/test/** +dev +upstream \ No newline at end of file diff --git a/Common/build.gradle b/Common/build.gradle deleted file mode 100644 index 843d62a..0000000 --- a/Common/build.gradle +++ /dev/null @@ -1,68 +0,0 @@ -archivesBaseName = "${mod_name.replace(" ", "")}-Common-${minecraft_version}" - -dependencies { - -} - -shadowJar { - from sourceSets.main.output - configurations = [project.configurations.shade] - - dependencies { - exclude(dependency('com.google.code.gson:.*')) - - relocate 'me.hypherionmc.moonconfig', 'shadow.hypherionmc.moonconfig' - relocate 'me.hypherionmc.mcdiscordformatter', 'shadow.hypherionmc.mcdiscordformatter' - relocate 'net.kyori', 'shadow.kyori' - } - setArchiveClassifier("dev") -} - -/** - * =============================================================================== - * = DO NOT EDIT BELOW THIS LINE UNLESS YOU KNOW WHAT YOU ARE DOING = - * =============================================================================== - */ - -unimined.minecraft { - fabric { - loader fabric_loader - } - - defaultRemapJar = false -} - -processResources { - def buildProps = project.properties.clone() - - filesMatching(['pack.mcmeta']) { - expand buildProps - } -} - -/** - * Publishing Config - */ -publishing { - publications { - mavenCommon(MavenPublication) { - artifactId project.archivesBaseName - from components.java - - pom.withXml { - Node pomNode = asNode() - pomNode.dependencies.'*'.findAll() { - it.artifactId.text() == 'regutils-joined-fabric' || - it.artifactId.text() == 'core' || - it.artifactId.text() == 'toml' - }.each() { - it.parent().remove(it) - } - } - } - } - - repositories { - maven rootProject.orion.getPublishingMaven() - } -} \ No newline at end of file diff --git a/Common/gradle.properties b/Common/gradle.properties deleted file mode 100644 index 65fcf04..0000000 --- a/Common/gradle.properties +++ /dev/null @@ -1,2 +0,0 @@ -# We don't need the common jar to be remapped -fabric.loom.dontRemap=true \ No newline at end of file diff --git a/Common/src/main/java/com/hypherionmc/craterlib/CraterConstants.java b/Common/src/main/java/com/hypherionmc/craterlib/CraterConstants.java deleted file mode 100644 index 93edffc..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/CraterConstants.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.hypherionmc.craterlib; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class CraterConstants { - public static final String MOD_ID = "craterlib"; - public static final String MOD_NAME = "CraterLib"; - public static final Logger LOG = LoggerFactory.getLogger(MOD_NAME); -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/api/commands/CraterCommand.java b/Common/src/main/java/com/hypherionmc/craterlib/api/commands/CraterCommand.java deleted file mode 100644 index 463d774..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/api/commands/CraterCommand.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.hypherionmc.craterlib.api.commands; - -import com.hypherionmc.craterlib.nojang.authlib.BridgedGameProfile; -import com.hypherionmc.craterlib.nojang.commands.BridgedCommandSourceStack; -import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer; -import com.mojang.brigadier.arguments.ArgumentType; -import lombok.Getter; -import net.minecraft.commands.arguments.GameProfileArgument; -import org.apache.commons.lang3.function.TriConsumer; -import org.apache.commons.lang3.tuple.Pair; - -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.function.Consumer; - -@Getter -public class CraterCommand { - - private final HashMap, TriConsumer>> arguments = new LinkedHashMap<>(); - private Consumer executor; - - private final String commandName; - private int permissionLevel = 4; - - CraterCommand(String commandName) { - this.commandName = commandName; - } - - public static CraterCommand literal(String commandName) { - return new CraterCommand(commandName); - } - - public CraterCommand requiresPermission(int perm) { - this.permissionLevel = perm; - return this; - } - - public CraterCommand withGameProfileArgument(String key, TriConsumer, BridgedCommandSourceStack> executor) { - arguments.put(key, Pair.of(GameProfileArgument.gameProfile(), executor)); - return this; - } - - public CraterCommand executes(Consumer ctx) { - executor = ctx; - return this; - } - - public boolean hasArguments() { - return !arguments.isEmpty(); - } - -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/api/events/client/CraterClientTickEvent.java b/Common/src/main/java/com/hypherionmc/craterlib/api/events/client/CraterClientTickEvent.java deleted file mode 100644 index c68c596..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/api/events/client/CraterClientTickEvent.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.hypherionmc.craterlib.api.events.client; - -import com.hypherionmc.craterlib.core.event.CraterEvent; -import com.hypherionmc.craterlib.nojang.client.multiplayer.BridgedClientLevel; -import lombok.Getter; -import lombok.RequiredArgsConstructor; - -@RequiredArgsConstructor -@Getter -public class CraterClientTickEvent extends CraterEvent { - - private final BridgedClientLevel level; - -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/api/events/client/CraterSinglePlayerEvent.java b/Common/src/main/java/com/hypherionmc/craterlib/api/events/client/CraterSinglePlayerEvent.java deleted file mode 100644 index ab671f0..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/api/events/client/CraterSinglePlayerEvent.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.hypherionmc.craterlib.api.events.client; - -import com.hypherionmc.craterlib.core.event.CraterEvent; -import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer; -import lombok.Getter; -import lombok.RequiredArgsConstructor; - -@RequiredArgsConstructor -@Getter -public class CraterSinglePlayerEvent extends CraterEvent { - - private final BridgedPlayer player; - - public static class PlayerLogin extends CraterSinglePlayerEvent { - - public PlayerLogin(BridgedPlayer player) { - super(player); - } - - } -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/api/events/client/LateInitEvent.java b/Common/src/main/java/com/hypherionmc/craterlib/api/events/client/LateInitEvent.java deleted file mode 100644 index 33c06fb..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/api/events/client/LateInitEvent.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.hypherionmc.craterlib.api.events.client; - -import com.hypherionmc.craterlib.core.event.CraterEvent; -import com.hypherionmc.craterlib.nojang.client.BridgedMinecraft; -import com.hypherionmc.craterlib.nojang.client.BridgedOptions; -import lombok.Getter; -import lombok.RequiredArgsConstructor; - -@RequiredArgsConstructor -@Getter -public class LateInitEvent extends CraterEvent { - - private final BridgedMinecraft minecraft; - private final BridgedOptions options; - -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/api/events/client/PlayerJoinRealmEvent.java b/Common/src/main/java/com/hypherionmc/craterlib/api/events/client/PlayerJoinRealmEvent.java deleted file mode 100644 index 1ef95de..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/api/events/client/PlayerJoinRealmEvent.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.hypherionmc.craterlib.api.events.client; - -import com.hypherionmc.craterlib.core.event.CraterEvent; -import com.hypherionmc.craterlib.nojang.realmsclient.dto.BridgedRealmsServer; -import lombok.Getter; -import lombok.RequiredArgsConstructor; - -@RequiredArgsConstructor -@Getter -public class PlayerJoinRealmEvent extends CraterEvent { - - private final BridgedRealmsServer server; - -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/api/events/client/ScreenEvent.java b/Common/src/main/java/com/hypherionmc/craterlib/api/events/client/ScreenEvent.java deleted file mode 100644 index 034ca4a..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/api/events/client/ScreenEvent.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.hypherionmc.craterlib.api.events.client; - -import com.hypherionmc.craterlib.core.event.CraterEvent; -import com.hypherionmc.craterlib.nojang.client.gui.BridgedScreen; -import lombok.Getter; -import lombok.RequiredArgsConstructor; -import lombok.Setter; - -@Getter -@RequiredArgsConstructor -public class ScreenEvent extends CraterEvent { - - private final BridgedScreen screen; - - @Getter - public static class Opening extends ScreenEvent { - - private final BridgedScreen currentScreen; - @Setter private BridgedScreen newScreen; - - public Opening(BridgedScreen currentScreen, BridgedScreen newScreen) { - super(newScreen); - this.currentScreen = currentScreen; - this.newScreen = newScreen; - } - } -} \ No newline at end of file diff --git a/Common/src/main/java/com/hypherionmc/craterlib/api/events/common/CraterPlayerDeathEvent.java b/Common/src/main/java/com/hypherionmc/craterlib/api/events/common/CraterPlayerDeathEvent.java deleted file mode 100644 index 02cd63c..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/api/events/common/CraterPlayerDeathEvent.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.hypherionmc.craterlib.api.events.common; - -import com.hypherionmc.craterlib.core.event.CraterEvent; -import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer; -import com.hypherionmc.craterlib.utils.ChatUtils; -import lombok.Getter; -import lombok.RequiredArgsConstructor; -import net.kyori.adventure.text.Component; -import net.minecraft.world.damagesource.DamageSource; - -@RequiredArgsConstructor -@Getter -public class CraterPlayerDeathEvent extends CraterEvent { - - private final BridgedPlayer player; - private final DamageSource damageSource; - - public Component getDeathMessage() { - return ChatUtils.mojangToAdventure(damageSource.getLocalizedDeathMessage(player.toMojang())); - } -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterAdvancementEvent.java b/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterAdvancementEvent.java deleted file mode 100644 index 5cd659d..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterAdvancementEvent.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.hypherionmc.craterlib.api.events.server; - -import com.hypherionmc.craterlib.core.event.CraterEvent; -import com.hypherionmc.craterlib.nojang.advancements.BridgedAdvancement; -import com.hypherionmc.craterlib.nojang.advancements.BridgedDisplayInfo; -import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer; -import lombok.Getter; -import net.kyori.adventure.text.Component; - -import java.util.Optional; - -@Getter -public class CraterAdvancementEvent extends CraterEvent { - - private final BridgedAdvancement advancement; - private final BridgedPlayer player; - private final Component title; - private final Component description; - - public CraterAdvancementEvent(BridgedPlayer player, BridgedAdvancement advancement) { - this.advancement = advancement; - this.player = player; - - Optional displayInfo = advancement.displayInfo(); - - if (displayInfo.isPresent()) { - this.title = displayInfo.get().displayName(); - this.description = displayInfo.get().description(); - } else { - this.title = Component.text("Unknown"); - this.description = Component.text("Unknown"); - } - } -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterCommandEvent.java b/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterCommandEvent.java deleted file mode 100644 index 364cc22..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterCommandEvent.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.hypherionmc.craterlib.api.events.server; - -import com.hypherionmc.craterlib.core.event.CraterEvent; -import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer; -import com.hypherionmc.craterlib.utils.ChatUtils; -import com.mojang.brigadier.ParseResults; -import com.mojang.brigadier.context.CommandContext; -import com.mojang.brigadier.context.StringRange; -import lombok.Getter; -import lombok.Setter; -import net.kyori.adventure.text.Component; -import net.minecraft.commands.CommandSourceStack; -import net.minecraft.commands.arguments.ComponentArgument; -import net.minecraft.world.entity.player.Player; -import org.jetbrains.annotations.Nullable; - -@Getter -public class CraterCommandEvent extends CraterEvent { - - private final ParseResults parseResults; - @Setter private Throwable exception; - private final String command; - - private CraterCommandEvent(ParseResults parseResults, String command) { - this.parseResults = parseResults; - this.command = command; - } - - public static CraterCommandEvent of(ParseResults stack, String command) { - return new CraterCommandEvent(stack, command); - } - - public String getCommandString() { - return parseResults.getReader().getString(); - } - - @Nullable - public BridgedPlayer getPlayer() { - try { - Player p = parseResults.getContext().getLastChild().getSource().getPlayer(); - - if (p != null) - return BridgedPlayer.of(p); - } catch (Exception ignored) {} - - return null; - } - - public String getTarget() { - CommandContext context = parseResults.getContext().build(parseResults.getReader().getString()); - StringRange selector_range = parseResults.getContext().getArguments().get("targets").getRange(); - return context.getInput().substring(selector_range.getStart(), selector_range.getEnd()); - } - - public Component getMessage() { - return ChatUtils.mojangToAdventure(ComponentArgument.getComponent(parseResults.getContext().build(parseResults.getReader().getString()), "message")); - } -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterPlayerEvent.java b/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterPlayerEvent.java deleted file mode 100644 index 7eb3701..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterPlayerEvent.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.hypherionmc.craterlib.api.events.server; - -import com.hypherionmc.craterlib.core.event.CraterEvent; -import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer; -import lombok.Getter; -import lombok.RequiredArgsConstructor; - -@RequiredArgsConstructor -@Getter -public class CraterPlayerEvent extends CraterEvent { - - private final BridgedPlayer player; - - public static class PlayerLoggedIn extends CraterPlayerEvent { - - public PlayerLoggedIn(BridgedPlayer player) { - super(player); - } - - } - - public static class PlayerLoggedOut extends CraterPlayerEvent { - - public PlayerLoggedOut(BridgedPlayer player) { - super(player); - } - - } - -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterRegisterCommandEvent.java b/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterRegisterCommandEvent.java deleted file mode 100644 index 269065a..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterRegisterCommandEvent.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.hypherionmc.craterlib.api.events.server; - -import com.hypherionmc.craterlib.api.commands.CraterCommand; -import com.hypherionmc.craterlib.core.event.CraterEvent; -import com.hypherionmc.craterlib.nojang.commands.CommandsRegistry; -import lombok.NoArgsConstructor; - -@NoArgsConstructor -public class CraterRegisterCommandEvent extends CraterEvent { - - public void registerCommand(CraterCommand cmd) { - CommandsRegistry.INSTANCE.registerCommand(cmd); - } - -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterServerChatEvent.java b/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterServerChatEvent.java deleted file mode 100644 index b25170a..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterServerChatEvent.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.hypherionmc.craterlib.api.events.server; - -import com.hypherionmc.craterlib.core.event.CraterEvent; -import com.hypherionmc.craterlib.core.event.annot.Cancellable; -import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer; -import lombok.Getter; -import lombok.Setter; -import net.kyori.adventure.text.Component; - -@Cancellable -@Getter -public class CraterServerChatEvent extends CraterEvent { - - public final String message, username; - public final BridgedPlayer player; - @Setter private Component component; - - public CraterServerChatEvent(BridgedPlayer player, String message, Component component) { - this.message = message; - this.player = player; - this.username = player.getGameProfile().getName(); - this.component = component; - } - -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterServerLifecycleEvent.java b/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterServerLifecycleEvent.java deleted file mode 100644 index 3f87d04..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterServerLifecycleEvent.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.hypherionmc.craterlib.api.events.server; - -import com.hypherionmc.craterlib.core.event.CraterEvent; -import com.hypherionmc.craterlib.nojang.server.BridgedMinecraftServer; -import lombok.Getter; -import lombok.RequiredArgsConstructor; - -public class CraterServerLifecycleEvent extends CraterEvent { - - @RequiredArgsConstructor - @Getter - public static class Starting extends CraterServerLifecycleEvent { - private final BridgedMinecraftServer server; - } - - @RequiredArgsConstructor - @Getter - public static class Started extends CraterServerLifecycleEvent { - private final BridgedMinecraftServer server; - } - - @RequiredArgsConstructor - @Getter - public static class Stopping extends CraterServerLifecycleEvent { - private final BridgedMinecraftServer server; - } - - @RequiredArgsConstructor - @Getter - public static class Stopped extends CraterServerLifecycleEvent { - private final BridgedMinecraftServer server; - } - -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/MessageBroadcastEvent.java b/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/MessageBroadcastEvent.java deleted file mode 100644 index 6b11404..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/MessageBroadcastEvent.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.hypherionmc.craterlib.api.events.server; - -import com.hypherionmc.craterlib.core.event.CraterEvent; -import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer; -import lombok.Getter; -import lombok.RequiredArgsConstructor; -import net.kyori.adventure.text.Component; - -import java.util.function.Function; - -@RequiredArgsConstructor -@Getter -public class MessageBroadcastEvent extends CraterEvent { - - private final Component component; - private final Function function; - private final boolean bl; - private final String threadName; - -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/PlayerPreLoginEvent.java b/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/PlayerPreLoginEvent.java deleted file mode 100644 index eaabffd..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/PlayerPreLoginEvent.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.hypherionmc.craterlib.api.events.server; - -import com.hypherionmc.craterlib.core.event.CraterEvent; -import com.hypherionmc.craterlib.nojang.authlib.BridgedGameProfile; -import lombok.Getter; -import lombok.RequiredArgsConstructor; -import lombok.Setter; -import net.kyori.adventure.text.Component; - -import java.net.SocketAddress; - -@RequiredArgsConstructor -@Getter -public class PlayerPreLoginEvent extends CraterEvent { - - private final SocketAddress address; - private final BridgedGameProfile gameProfile; - @Setter private Component message; - -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/api/networking/CommonPacketWrapper.java b/Common/src/main/java/com/hypherionmc/craterlib/api/networking/CommonPacketWrapper.java deleted file mode 100644 index fe94544..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/api/networking/CommonPacketWrapper.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.hypherionmc.craterlib.api.networking; - -import com.hypherionmc.craterlib.core.networking.data.PacketHolder; -import com.hypherionmc.craterlib.nojang.network.BridgedFriendlyByteBuf; -import net.minecraft.network.protocol.common.custom.CustomPacketPayload; - -public record CommonPacketWrapper(PacketHolder container, T packet) implements CustomPacketPayload -{ - public void encode(BridgedFriendlyByteBuf buf) - { - container().encoder().accept(packet(), buf); - } - - @Override - public Type type() - { - return container.type(); - } -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/api/networking/CraterNetworkHandler.java b/Common/src/main/java/com/hypherionmc/craterlib/api/networking/CraterNetworkHandler.java deleted file mode 100644 index 6b57e96..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/api/networking/CraterNetworkHandler.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.hypherionmc.craterlib.api.networking; - -import com.hypherionmc.craterlib.nojang.server.BridgedMinecraftServer; -import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer; - -import java.util.List; - -/** - * Based on https://github.com/mysticdrew/common-networking/tree/1.20.4 - */ -public interface CraterNetworkHandler { - - void sendToServer(T packet); - - void sendToServer(T packet, boolean ignoreCheck); - - void sendToClient(T packet, BridgedPlayer player); - - default void sendToClients(T packet, List players) { - for (BridgedPlayer player : players) { - sendToClient(packet, player); - } - } - - default void sendToAllClients(T packet, BridgedMinecraftServer server) { - sendToClients(packet, server.getPlayers()); - } -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/CraterConfigScreen.java b/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/CraterConfigScreen.java deleted file mode 100644 index 70084eb..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/CraterConfigScreen.java +++ /dev/null @@ -1,393 +0,0 @@ -package com.hypherionmc.craterlib.client.gui.config; - -import com.hypherionmc.craterlib.CraterConstants; -import com.hypherionmc.craterlib.client.gui.config.widgets.*; -import com.hypherionmc.craterlib.core.config.ModuleConfig; -import com.hypherionmc.craterlib.core.config.annotations.HideFromScreen; -import com.hypherionmc.craterlib.core.config.annotations.SubConfig; -import com.hypherionmc.craterlib.core.config.annotations.Tooltip; -import com.mojang.blaze3d.systems.RenderSystem; -import com.mojang.blaze3d.vertex.*; -import me.hypherionmc.moonconfig.core.conversion.SpecComment; -import net.minecraft.ChatFormatting; -import net.minecraft.client.gui.Font; -import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.client.gui.screens.ConfirmScreen; -import net.minecraft.client.gui.screens.Screen; -import net.minecraft.client.renderer.GameRenderer; -import net.minecraft.network.chat.Component; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.util.Mth; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.joml.Matrix4f; - -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Objects; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.function.Supplier; - -/** - * @author HypherionSA - */ -public class CraterConfigScreen extends Screen { - public static final float SCROLLBAR_BOTTOM_COLOR = .5f; - public static final float SCROLLBAR_TOP_COLOR = .67f; - private static final int TOP = 26; - private static final int BOTTOM = 24; - private final Screen parent; - private final List> options = new ArrayList<>(); - private final ModuleConfig config; - public double scrollerAmount; - private boolean dragging; - - public CraterConfigScreen(ModuleConfig config, Screen parent, Object subConfig) { - super(Component.translatable("cl." + config.getClass().getSimpleName().toLowerCase() + ".title")); - this.parent = parent; - this.config = config; - if (subConfig != null) { - setupScreenFromConfig(subConfig, subConfig.getClass()); - } else { - setupScreenFromConfig(config, config.getClass()); - } - } - - public CraterConfigScreen(ModuleConfig config, Screen parent) { - this(config, parent, null); - } - - private static Component toText(Enum val) { - return Component.translatable(val.toString()); - } - - private static Component toText(Boolean bool) { - return Component.translatable(bool.toString()); - } - - private void setupScreenFromConfig(Object object, Class clazz) { - while (clazz != Object.class) { - for (Field field : clazz.getDeclaredFields()) { - final int fieldModifiers = field.getModifiers(); - if (object == null || Modifier.isStatic(fieldModifiers) || Modifier.isTransient(fieldModifiers)) { - continue; - } - - try { - if (!field.isAccessible()) { - field.setAccessible(true); - } - if (field.isAnnotationPresent(HideFromScreen.class)) - return; - Object val = field.get(object); - - /* Lang Stuff */ - String baseLangKey = "cl." + clazz.getSimpleName().toLowerCase() + "." + field.getName().toLowerCase(); - String[] tooltipLang = field.isAnnotationPresent(SpecComment.class) ? new String[]{field.getAnnotation(SpecComment.class).value()} : new String[0]; - if (field.isAnnotationPresent(Tooltip.class)) { - tooltipLang = field.getAnnotation(Tooltip.class).value(); - } - - add(Component.translatable(baseLangKey), - val, - () -> val, - (ret) -> { - try { - field.set(object, ret); - config.saveConfig(config); - } catch (IllegalAccessException e) { - CraterConstants.LOG.error("Failed to update value for field {} in config {}", field.getName(), config.getConfigName(), e); - } - }, - field.isAnnotationPresent(SubConfig.class), - tooltipLang - ); - } catch (IllegalAccessException e) { - CraterConstants.LOG.error("Failed to access value for field {} in config {}", field.getName(), config.getConfigName(), e); - } - } - clazz = clazz.getSuperclass(); - } - } - - public void add(Component text, T value, @Nullable Supplier defaultValue, Consumer savingConsumer, boolean isSubConfig, String... langKeys) { - Option option = (Option) createOption(value, isSubConfig); - option.text = text; - option.defaultValue = defaultValue; - option.savingConsumer = savingConsumer; - option.originalValue = value; - option.value = value; - option.setLangKeys(List.of(langKeys)); - options.add(option); - option.onAdd(); - } - - private Option createOption(T value, boolean isSubConfig) { - if (value instanceof Enum) { - Object[] objects = value.getClass().getEnumConstants(); - return new ToggleButton>((List) Arrays.asList(objects), CraterConfigScreen::toText); - } - if (value instanceof Boolean) { - return new ToggleButton<>(Arrays.asList(Boolean.TRUE, Boolean.FALSE), CraterConfigScreen::toText); - } - if (value instanceof String) { - return new TextConfigOption<>(Function.identity(), Function.identity()); - } - if (value instanceof Integer) { - return new TextConfigOption<>(Objects::toString, Integer::valueOf); - } - if (value instanceof Long) { - return new TextConfigOption<>(Objects::toString, Long::valueOf); - } - if (value instanceof Double) { - return new TextConfigOption<>(Objects::toString, Double::valueOf); - } - if (value instanceof Float) { - return new TextConfigOption<>(Objects::toString, Float::valueOf); - } - if (value instanceof BigInteger) { - return new TextConfigOption<>(Objects::toString, BigInteger::new); - } - if (value instanceof BigDecimal) { - return new TextConfigOption<>(Objects::toString, BigDecimal::new); - } - if (value instanceof ResourceLocation) { - return new TextConfigOption<>(Objects::toString, ResourceLocation::new); - } - if (isSubConfig) { - return new SubConfigWidget<>(config, this, value); - } - throw new IllegalArgumentException(String.valueOf(value)); - } - - @Override - protected void init() { - super.init(); - ((List) children()).addAll(options); - - int buttonWidths = Math.min(200, (width - 50 - 12) / 3); - addRenderableWidget(new InternalConfigButton(this, width / 2 - buttonWidths - 3, height - 22, buttonWidths, 20, Component.empty(), true)); - addRenderableWidget(new InternalConfigButton(this, width / 2 + 3, height - 22, buttonWidths, 20, Component.empty(), false)); - } - - @Override - public void render(@NotNull GuiGraphics matrices, int mouseX, int mouseY, float delta) { - overlayBackground(matrices.pose(), TOP, height - BOTTOM, 32); - renderScrollBar(); - - matrices.pose().pushPose(); - matrices.pose().translate(0, 0, 500.0); - overlayBackground(matrices.pose(), 0, TOP, 64); - overlayBackground(matrices.pose(), height - BOTTOM, height, 64); - renderShadow(matrices.pose()); - matrices.drawCenteredString(font, getTitle(), width / 2, 9, 0xFFFFFF); - matrices.pose().popPose(); - - super.render(matrices, mouseX, mouseY, delta); - - int y = (int) (TOP + 4 - Math.round(scrollerAmount)); - for (Option option : options) { - int height1 = option.height(); - option.render(minecraft, font, 40, y, width - 80, height1, matrices, mouseX, mouseY, delta); - renderConfigTooltip(matrices, font, mouseX, mouseY, 40, y, font.width(option.text), height1, option.text.getString(), option.getLangKeys().toArray(new String[0])); - y += height1; - } - } - - private void renderScrollBar() { - int listHeight = height - BOTTOM - TOP; - int totalHeight = totalHeight(); - if (totalHeight > listHeight) { - int maxScroll = Math.max(0, totalHeight - listHeight); - int height = listHeight * listHeight / totalHeight; - height = Mth.clamp(height, 32, listHeight); - height = Math.max(10, height); - int minY = Math.min(Math.max((int) scrollerAmount * (listHeight - height) / maxScroll + TOP, TOP), this.height - BOTTOM - height); - - int scrollbarPositionMaxX = width; - int scrollbarPositionMinX = scrollbarPositionMaxX - 6; - - int maxY = this.height - BOTTOM; - //RenderSystem.disableTexture(); - Tesselator tesselator = Tesselator.getInstance(); - BufferBuilder buffer = tesselator.getBuilder(); - RenderSystem.setShader(GameRenderer::getPositionColorShader); - buffer.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR); - - buffer.vertex(scrollbarPositionMinX, maxY, 0.0D).color(0, 0, 0, 255).endVertex(); - buffer.vertex(scrollbarPositionMaxX, maxY, 0.0D).color(0, 0, 0, 255).endVertex(); - buffer.vertex(scrollbarPositionMaxX, TOP, 0.0D).color(0, 0, 0, 255).endVertex(); - buffer.vertex(scrollbarPositionMinX, TOP, 0.0D).color(0, 0, 0, 255).endVertex(); - - buffer.vertex(scrollbarPositionMinX, minY + height, 0.0D).color(SCROLLBAR_BOTTOM_COLOR, SCROLLBAR_BOTTOM_COLOR, SCROLLBAR_BOTTOM_COLOR, 1).endVertex(); - buffer.vertex(scrollbarPositionMaxX, minY + height, 0.0D).color(SCROLLBAR_BOTTOM_COLOR, SCROLLBAR_BOTTOM_COLOR, SCROLLBAR_BOTTOM_COLOR, 1).endVertex(); - buffer.vertex(scrollbarPositionMaxX, minY, 0.0D).color(SCROLLBAR_BOTTOM_COLOR, SCROLLBAR_BOTTOM_COLOR, SCROLLBAR_BOTTOM_COLOR, 1).endVertex(); - buffer.vertex(scrollbarPositionMinX, minY, 0.0D).color(SCROLLBAR_BOTTOM_COLOR, SCROLLBAR_BOTTOM_COLOR, SCROLLBAR_BOTTOM_COLOR, 1).endVertex(); - buffer.vertex(scrollbarPositionMinX, (minY + height - 1), 0.0D).color(SCROLLBAR_TOP_COLOR, SCROLLBAR_TOP_COLOR, SCROLLBAR_TOP_COLOR, 1).endVertex(); - buffer.vertex((scrollbarPositionMaxX - 1), (minY + height - 1), 0.0D).color(SCROLLBAR_TOP_COLOR, SCROLLBAR_TOP_COLOR, SCROLLBAR_TOP_COLOR, 1).endVertex(); - buffer.vertex((scrollbarPositionMaxX - 1), minY, 0.0D).color(SCROLLBAR_TOP_COLOR, SCROLLBAR_TOP_COLOR, SCROLLBAR_TOP_COLOR, 1).endVertex(); - buffer.vertex(scrollbarPositionMinX, minY, 0.0D).color(SCROLLBAR_TOP_COLOR, SCROLLBAR_TOP_COLOR, SCROLLBAR_TOP_COLOR, 1).endVertex(); - tesselator.end(); - RenderSystem.disableBlend(); - //RenderSystem.enableTexture(); - } - } - - private void renderShadow(PoseStack matrices) { - Tesselator tesselator = Tesselator.getInstance(); - BufferBuilder buffer = tesselator.getBuilder(); - RenderSystem.enableBlend(); - RenderSystem.blendFuncSeparate(770, 771, 0, 1); - //RenderSystem.disableTexture(); - RenderSystem.setShader(GameRenderer::getPositionTexColorShader); - Matrix4f matrix = matrices.last().pose(); - buffer.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX_COLOR); - buffer.vertex(matrix, 0, TOP + 4, 0.0F).uv(0, 1).color(0, 0, 0, 0).endVertex(); - buffer.vertex(matrix, width, TOP + 4, 0.0F).uv(1, 1).color(0, 0, 0, 0).endVertex(); - buffer.vertex(matrix, width, TOP, 0.0F).uv(1, 0).color(0, 0, 0, 185).endVertex(); - buffer.vertex(matrix, 0, TOP, 0.0F).uv(0, 0).color(0, 0, 0, 185).endVertex(); - buffer.vertex(matrix, 0, height - BOTTOM, 0.0F).uv(0, 1).color(0, 0, 0, 185).endVertex(); - buffer.vertex(matrix, width, height - BOTTOM, 0.0F).uv(1, 1).color(0, 0, 0, 185).endVertex(); - buffer.vertex(matrix, width, height - BOTTOM - 4, 0.0F).uv(1, 0).color(0, 0, 0, 0).endVertex(); - buffer.vertex(matrix, 0, height - BOTTOM - 4, 0.0F).uv(0, 0).color(0, 0, 0, 0).endVertex(); - tesselator.end(); - //RenderSystem.enableTexture(); - RenderSystem.disableBlend(); - } - - protected void overlayBackground(PoseStack matrices, int h1, int h2, int color) { - overlayBackground(matrices.last().pose(), 0, h1, width, h2, color, color, color, 255, 255); - } - - protected void overlayBackground(Matrix4f matrix, int minX, int minY, int maxX, int maxY, int red, int green, int blue, int startAlpha, int endAlpha) { - Tesselator tesselator = Tesselator.getInstance(); - BufferBuilder buffer = tesselator.getBuilder(); - RenderSystem.setShader(GameRenderer::getPositionTexColorShader); - RenderSystem.setShaderTexture(0, Screen.MENU_BACKGROUND); - RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f); - buffer.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX_COLOR); - buffer.vertex(matrix, minX, maxY, 0.0F).uv(minX / 32.0F, maxY / 32.0F).color(red, green, blue, endAlpha).endVertex(); - buffer.vertex(matrix, maxX, maxY, 0.0F).uv(maxX / 32.0F, maxY / 32.0F).color(red, green, blue, endAlpha).endVertex(); - buffer.vertex(matrix, maxX, minY, 0.0F).uv(maxX / 32.0F, minY / 32.0F).color(red, green, blue, startAlpha).endVertex(); - buffer.vertex(matrix, minX, minY, 0.0F).uv(minX / 32.0F, minY / 32.0F).color(red, green, blue, startAlpha).endVertex(); - tesselator.end(); - } - - public int scrollHeight() { - int totalHeight = totalHeight(); - int listHeight = height - BOTTOM - TOP; - if (totalHeight <= listHeight) { - return 0; - } - return totalHeight - listHeight; - } - - public int totalHeight() { - int i = 8; - for (Option option : options) { - i += option.height(); - } - return i; - } - - public boolean hasErrors() { - for (Option option : options) { - if (option.hasErrors) { - return true; - } - } - return false; - } - - public boolean isEdited() { - for (Option option : options) { - if (option.isEdited()) { - return true; - } - } - return false; - } - - public void save() { - for (Option option : options) { - option.save(); - option.originalValue = option.value; - } - } - - @Override - public void onClose() { - if (isEdited()) { - minecraft.setScreen(new ConfirmScreen(this::acceptConfirm, Component.translatable("t.clc.quit_config"), - Component.translatable("t.clc.quit_config_sure"), - Component.translatable("t.clc.quit_discard"), - Component.translatable("gui.cancel"))); - } else { - minecraft.setScreen(parent); - } - } - - @Override - public boolean mouseScrolled(double d, double e, double f, double g) { - if (e >= TOP && e <= height - BOTTOM) { - scrollerAmount = Mth.clamp(scrollerAmount - f * 16.0D, 0, scrollHeight()); - return true; - } - return super.mouseScrolled(d, e, f, g); - } - - @Override - public boolean mouseClicked(double d, double e, int i) { - this.dragging = i == 0 && d >= width - 6 && d < width; - return super.mouseClicked(d, e, i) || dragging; - } - - @Override - public boolean mouseDragged(double d, double e, int i, double f, double g) { - if (super.mouseDragged(d, e, i, f, g)) { - return true; - } - if (i != 0 || !this.dragging) { - return false; - } - if (e < TOP) { - scrollerAmount = 0; - } else if (e > height - BOTTOM) { - scrollerAmount = scrollHeight(); - } else { - double h = Math.max(1, this.scrollHeight()); - int j = height - BOTTOM - TOP; - int k = Mth.clamp((int) ((float) (j * j) / (float) this.scrollHeight()), 32, j - 8); - double l = Math.max(1.0, h / (double) (j - k)); - scrollerAmount = Mth.clamp(scrollerAmount + g * l, 0, scrollHeight()); - } - return true; - } - - private void acceptConfirm(boolean t) { - if (!t) { - minecraft.setScreen(this); - } else { - minecraft.setScreen(parent); - } - } - - private void renderConfigTooltip(GuiGraphics stack, Font font, int mouseX, int mouseY, int startX, int startY, int sizeX, int sizeY, String title, String... description) { - if (mouseX > startX && mouseX < startX + sizeX) { - if (mouseY > startY && mouseY < startY + sizeY) { - List list = new ArrayList<>(); - list.add(Component.translatable(ChatFormatting.BOLD + "" + ChatFormatting.YELLOW + title)); - for (String desc : description) { - list.add(Component.translatable(desc)); - } - stack.renderComponentTooltip(font, list, mouseX, mouseY); - } - } - } -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/AbstractConfigWidget.java b/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/AbstractConfigWidget.java deleted file mode 100644 index ed34f6b..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/AbstractConfigWidget.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.hypherionmc.craterlib.client.gui.config.widgets; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.Font; -import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.client.gui.components.AbstractWidget; -import net.minecraft.client.gui.components.EditBox; - -/** - * Copied from Cloth Config Lite - * ... - */ -public class AbstractConfigWidget extends BaseWidget { - - public static final int buttonWidth = 200; - public static final int buttonHeight = 20; - public W widget; - - @Override - public void render(Minecraft minecraft, Font font, int x, int y, int width, int height, GuiGraphics matrices, int mouseX, int mouseY, float delta) { - super.render(minecraft, font, x, y, width, height, matrices, mouseX, mouseY, delta); - int i = (widget instanceof EditBox ? 1 : 0); - widget.setX(x + width - 200 - resetButtonOffset + i); - widget.setY(y + i + 1); - widget.render(matrices, mouseX, mouseY, delta); - } -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/BaseWidget.java b/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/BaseWidget.java deleted file mode 100644 index 0583e61..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/BaseWidget.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.hypherionmc.craterlib.client.gui.config.widgets; - -import net.minecraft.ChatFormatting; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.Font; -import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.client.gui.components.Button; -import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.MutableComponent; -import net.minecraft.network.chat.TextColor; - -/** - * Copied from Cloth Config Lite - * ... - */ -public class BaseWidget extends Option { - - public static final int resetButtonOffset = 48; - private final Button resetButton = addChild(Button.builder(Component.literal("Reset"), this::onResetPressed).size(46, 20).build()); - private boolean hideReset = false; - - private boolean isSubConfig = false; - - private void onResetPressed(Button button) { - value = defaultValue.get(); - reset(); - } - - public void hideReset() { - this.hideReset = true; - } - - public boolean isSubConfig() { - return isSubConfig; - } - - public void setSubConfig(boolean subConfig) { - isSubConfig = subConfig; - } - - @Override - public void render(Minecraft minecraft, Font font, int x, int y, int width, int height, GuiGraphics matrices, int mouseX, int mouseY, float delta) { - MutableComponent text = Component.literal(this.text.getString()); - boolean edited = isEdited() || hasErrors; - if (edited) { - text.withStyle(ChatFormatting.ITALIC); - if (hasErrors) { - text.withStyle(style -> style.withColor(TextColor.fromRgb(16733525))); - } - } else { - text.withStyle(ChatFormatting.GRAY); - } - matrices.drawString(font, text, x, y + font.lineHeight - 2, 0xFFFFFF); - resetButton.setX(x + width - 46); - resetButton.setY(y + 1); - resetButton.active = isNotDefault(); - if (!hideReset) { - resetButton.render(matrices, mouseX, mouseY, delta); - } - } -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/InternalConfigButton.java b/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/InternalConfigButton.java deleted file mode 100644 index 2478c7d..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/InternalConfigButton.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.hypherionmc.craterlib.client.gui.config.widgets; - -import com.hypherionmc.craterlib.client.gui.config.CraterConfigScreen; -import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.client.gui.components.AbstractButton; -import net.minecraft.client.gui.narration.NarratedElementType; -import net.minecraft.client.gui.narration.NarrationElementOutput; -import net.minecraft.network.chat.Component; - -/** - * @author HypherionSA - */ -public class InternalConfigButton extends AbstractButton { - - CraterConfigScreen screen; - boolean cancel; - - public InternalConfigButton(CraterConfigScreen screen, int i, int j, int k, int l, Component component, boolean cancel) { - super(i, j, k, l, component); - this.screen = screen; - this.cancel = cancel; - } - - @Override - protected void renderWidget(GuiGraphics arg, int i, int j, float f) { - if (cancel) { - setMessage(Component.translatable(screen.isEdited() ? "t.clc.cancel_discard" : "gui.cancel")); - } else { - boolean hasErrors = screen.hasErrors(); - active = screen.isEdited() && !hasErrors; - setMessage(Component.translatable(hasErrors ? "t.clc.error" : "t.clc.save")); - } - super.renderWidget(arg, i, j, f); - } - - @Override - protected void updateWidgetNarration(NarrationElementOutput narrationElementOutput) { - narrationElementOutput.add(NarratedElementType.USAGE, getMessage()); - } - - @Override - public void onPress() { - if (cancel) { - screen.onClose(); - } else { - screen.save(); - } - } - - -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/Option.java b/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/Option.java deleted file mode 100644 index f49ca68..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/Option.java +++ /dev/null @@ -1,71 +0,0 @@ -package com.hypherionmc.craterlib.client.gui.config.widgets; - -import lombok.Getter; -import lombok.Setter; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.Font; -import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.client.gui.components.events.AbstractContainerEventHandler; -import net.minecraft.client.gui.components.events.GuiEventListener; -import net.minecraft.network.chat.Component; -import org.jetbrains.annotations.Nullable; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.function.Consumer; -import java.util.function.Supplier; - -/** - * Copied from Cloth Config Lite - * ... - */ -public abstract class Option extends AbstractContainerEventHandler { - - public Component text; - @Nullable - public Supplier defaultValue; - public Consumer savingConsumer; - public T originalValue; - public T value; - public boolean hasErrors; - public List children = new ArrayList<>(); - @Setter - @Getter - private List langKeys = new ArrayList<>(); - - public abstract void render(Minecraft minecraft, Font font, int x, int y, int width, int height, GuiGraphics matrices, int mouseX, int mouseY, float delta); - - public int height() { - return 22; - } - - @Override - public List children() { - return children; - } - - protected R addChild(R listener) { - ((List) children).add(listener); - return listener; - } - - public void onAdd() { - } - - protected void reset() { - onAdd(); - } - - public boolean isEdited() { - return !Objects.equals(originalValue, value); - } - - protected boolean isNotDefault() { - return defaultValue != null && !Objects.equals(defaultValue.get(), value); - } - - public void save() { - savingConsumer.accept(value); - } -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/SubConfigWidget.java b/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/SubConfigWidget.java deleted file mode 100644 index 9426ccf..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/SubConfigWidget.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.hypherionmc.craterlib.client.gui.config.widgets; - -import com.hypherionmc.craterlib.client.gui.config.CraterConfigScreen; -import com.hypherionmc.craterlib.core.config.ModuleConfig; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.Font; -import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.client.gui.components.Button; -import net.minecraft.client.gui.screens.Screen; -import net.minecraft.network.chat.Component; - -/** - * @author HypherionSA - */ -public class SubConfigWidget extends AbstractConfigWidget { - - private final Object subConfig; - private final ModuleConfig config; - private final Screen screen; - - public SubConfigWidget(ModuleConfig config, Screen screen, Object subConfig) { - this.config = config; - this.subConfig = subConfig; - this.screen = screen; - - this.widget = addChild(Button.builder(Component.translatable("t.clc.opensubconfig"), this::openSubConfig).size(200, buttonHeight).build()); - } - - @Override - public void render(Minecraft minecraft, Font font, int x, int y, int width, int height, GuiGraphics matrices, int mouseX, int mouseY, float delta) { - this.text = Component.literal(subConfig.getClass().getSimpleName().toLowerCase()); - this.hideReset(); - super.render(minecraft, font, x, y, width, height, matrices, mouseX, mouseY, delta); - } - - private void openSubConfig(Button button) { - Minecraft.getInstance().setScreen(new CraterConfigScreen(config, screen, subConfig)); - } - -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/TextConfigOption.java b/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/TextConfigOption.java deleted file mode 100644 index cc05cec..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/TextConfigOption.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.hypherionmc.craterlib.client.gui.config.widgets; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.Font; -import net.minecraft.client.gui.GuiGraphics; - -import java.util.function.Function; - -/** - * Copied from Cloth Config Lite - * ... - */ -public class TextConfigOption extends AbstractConfigWidget { - - private final Function toString; - private final Function fromString; - - public TextConfigOption(Function toString, Function fromString) { - this.toString = toString; - this.fromString = fromString; - this.widget = addChild(new WrappedEditBox(Minecraft.getInstance().font, 0, 0, 198, 18, null)); - } - - @Override - public void onAdd() { - widget.setMaxLength(1000000); - widget.setValue(toString.apply(value)); - widget.setResponder(this::update); - } - - @Override - public void render(Minecraft minecraft, Font font, int x, int y, int width, int height, GuiGraphics matrices, int mouseX, int mouseY, float delta) { - widget.setTextColor(hasErrors ? 16733525 : 14737632); - super.render(minecraft, font, x, y, width, height, matrices, mouseX, mouseY, delta); - } - - private void update(String s) { - try { - this.value = fromString.apply(s); - this.hasErrors = false; - } catch (Exception e) { - this.hasErrors = true; - } - } -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/ToggleButton.java b/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/ToggleButton.java deleted file mode 100644 index 03ea11d..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/ToggleButton.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.hypherionmc.craterlib.client.gui.config.widgets; - -import net.minecraft.client.gui.components.Button; -import net.minecraft.network.chat.Component; - -import java.util.List; -import java.util.function.Function; - -/** - * Copied from Cloth Config Lite - * ... - */ -public class ToggleButton extends AbstractConfigWidget { - - private final List options; - private final Function toComponent; - - public ToggleButton(List options, Function toComponent) { - this.options = options; - this.toComponent = toComponent; - this.widget = addChild(Button.builder(Component.empty(), this::switchNext).size(buttonWidth, buttonHeight).build()); - } - - @Override - public void onAdd() { - widget.setMessage(toComponent.apply(value)); - } - - private void switchNext(Button button) { - value = options.get((options.indexOf(value) + 1) % options.size()); - onAdd(); - } -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/WrappedEditBox.java b/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/WrappedEditBox.java deleted file mode 100644 index 42c0c0c..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/WrappedEditBox.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.hypherionmc.craterlib.client.gui.config.widgets; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.Font; -import net.minecraft.client.gui.components.EditBox; -import net.minecraft.client.gui.components.events.GuiEventListener; -import net.minecraft.network.chat.Component; -import org.jetbrains.annotations.NotNull; - -/** - * @author HypherionSA - */ -public class WrappedEditBox extends EditBox { - - public WrappedEditBox(Font font, int i, int j, int k, int l, @NotNull Component component) { - super(font, i, j, k, l, component); - } - - @Override - public void setFocused(boolean bl) { - for (GuiEventListener child : Minecraft.getInstance().screen.children()) { - if (child instanceof TextConfigOption option) { - WrappedEditBox box = option.widget; - super.setFocused(box == this); - } - } - super.setFocused(bl); - } -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/client/mentions/MentionCondition.java b/Common/src/main/java/com/hypherionmc/craterlib/client/mentions/MentionCondition.java deleted file mode 100644 index e8bffde..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/client/mentions/MentionCondition.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.hypherionmc.craterlib.client.mentions; - -/** - * Based on ... - */ -@FunctionalInterface -public interface MentionCondition { - - boolean shouldAddMention(String currentWord); - - MentionCondition ALWAYS = currentWord -> true; - -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/client/mentions/MentionsController.java b/Common/src/main/java/com/hypherionmc/craterlib/client/mentions/MentionsController.java deleted file mode 100644 index bad3b43..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/client/mentions/MentionsController.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.hypherionmc.craterlib.client.mentions; - -import com.hypherionmc.craterlib.nojang.resources.ResourceIdentifier; -import lombok.Getter; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.LinkedHashMap; -import java.util.Map; - -/** - * Based on ... - */ -public class MentionsController { - - private static final Map> mentions = new LinkedHashMap<>(); - private static final Map mentionConditions = new LinkedHashMap<>(); - @Getter - private static boolean lastMentionConditional = true; - - public static void registerMention(ResourceIdentifier mentionClass, Collection suggestions, MentionCondition condition) { - mentions.put(mentionClass, suggestions); - mentionConditions.put(mentionClass, condition); - } - - public static Collection getMentions(String currentWord) { - ArrayList applicableMentions = new ArrayList<>(); - lastMentionConditional = false; - - mentionConditions.forEach((mention, condition) -> { - boolean shouldSuggest = condition.shouldAddMention(currentWord); - if (!shouldSuggest) return; - - if (!lastMentionConditional && condition != MentionCondition.ALWAYS) { - lastMentionConditional = true; - } - - applicableMentions.addAll(mentions.get(mention)); - }); - - return applicableMentions; - } - - public static boolean hasMentions() { - return !mentions.isEmpty(); - } -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/core/config/ConfigController.java b/Common/src/main/java/com/hypherionmc/craterlib/core/config/ConfigController.java deleted file mode 100644 index 41c9471..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/core/config/ConfigController.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.hypherionmc.craterlib.core.config; - -import com.hypherionmc.craterlib.CraterConstants; -import lombok.Getter; -import me.hypherionmc.moonconfig.core.file.FileWatcher; -import org.jetbrains.annotations.ApiStatus; - -import java.io.Serializable; -import java.util.HashMap; - -/** - * @author HypherionSA - * Controls Config File Reloads and Events - */ -public final class ConfigController implements Serializable { - - /** - * Cache of registered configs - */ - @Getter - private static final HashMap monitoredConfigs = new HashMap<>(); - - /** - * INTERNAL METHOD - Register and watch the config - * - * @param config - The config class to register and watch - */ - @ApiStatus.Internal - public static void register_config(ModuleConfig config) { - if (monitoredConfigs.containsKey(config)) { - CraterConstants.LOG.error("Failed to register " + config.getConfigPath().getName() + ". Config already registered"); - } else { - FileWatcher configWatcher = new FileWatcher(); - try { - configWatcher.setWatch(config.getConfigPath(), () -> { - if (!config.isSaveCalled()) { - CraterConstants.LOG.info("Sending Reload Event for: " + config.getConfigPath().getName()); - config.configReloaded(); - } - }); - } catch (Exception e) { - CraterConstants.LOG.error("Failed to register " + config.getConfigPath().getName() + " for auto reloading. " + e.getMessage()); - } - monitoredConfigs.put(config, configWatcher); - CraterConstants.LOG.info("Registered " + config.getConfigPath().getName() + " successfully!"); - } - } - -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/core/config/ModuleConfig.java b/Common/src/main/java/com/hypherionmc/craterlib/core/config/ModuleConfig.java deleted file mode 100644 index 181efdc..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/core/config/ModuleConfig.java +++ /dev/null @@ -1,184 +0,0 @@ -package com.hypherionmc.craterlib.core.config; - -import me.hypherionmc.moonconfig.core.CommentedConfig; -import me.hypherionmc.moonconfig.core.Config; -import me.hypherionmc.moonconfig.core.conversion.ObjectConverter; -import me.hypherionmc.moonconfig.core.file.CommentedFileConfig; - -import java.io.File; - -/** - * @author HypherionSA - * Base Config class containing the save, upgrading and loading logic. - * All config classes must extend this class - */ -public class ModuleConfig { - - /* Final Variables */ - private final transient File configPath; - private final transient String networkID; - - private final transient String configName; - - private final transient String modId; - - private transient boolean isSaveCalled = false; - - /** - * Set up the config - * - * @param modId - The ID of the Mod/Module the config belongs to - * @param configName - The name of the config file, excluding extension - */ - public ModuleConfig(String modId, String configName) { - this(modId, "", configName); - } - - public ModuleConfig(String modId, String subFolder, String configName) { - /* Preserve the order of the config values */ - Config.setInsertionOrderPreserved(true); - - /* Configure Paths and Network SYNC ID */ - File configDir = new File("config" + (subFolder.isEmpty() ? "" : File.separator + subFolder)); - configPath = new File(configDir + File.separator + configName + ".toml"); - networkID = modId + ":conf_" + configName.replace("-", "_"); - this.modId = modId; - this.configName = configName; - - /* Check if the required directories exists, otherwise we create them */ - if (!configDir.exists()) { - configDir.mkdirs(); - } - } - - /** - * This method has to be called in the config constructor. This creates or upgrades the config file as needed - * - * @param config - The config class to use - */ - public void registerAndSetup(ModuleConfig config) { - if (!configPath.exists() || configPath.length() < 2) { - saveConfig(config); - } else { - migrateConfig(config); - } - /* Register the Config for Watching and events */ - ConfigController.register_config(this); - this.configReloaded(); - } - - /** - * Save the config to the disk - * - * @param conf - The config class to serialize and save - */ - public void saveConfig(ModuleConfig conf) { - this.isSaveCalled = true; - /* Set up the Serializer and Config Object */ - ObjectConverter converter = new ObjectConverter(); - CommentedFileConfig config = CommentedFileConfig.builder(configPath).build(); - - /* Save the config and fire the reload events */ - converter.toConfig(conf, config); - config.save(); - configReloaded(); - this.isSaveCalled = false; - } - - /** - * Load the config from the file into a Class - * - * @param conf - The config Class to load - * @return - Returns the loaded version of the class - */ - public T loadConfig(Object conf) { - /* Set up the Serializer and Config Object */ - ObjectConverter converter = new ObjectConverter(); - CommentedFileConfig config = CommentedFileConfig.builder(configPath).build(); - config.load(); - - /* Load the config and return the loaded config */ - converter.toObject(config, conf); - return (T) conf; - } - - /** - * INTERNAL METHOD - Upgrades the config files in the events the config structure changes - * - * @param conf - The config class to load - */ - public void migrateConfig(ModuleConfig conf) { - /* Set up the Serializer and Config Objects */ - CommentedFileConfig config = CommentedFileConfig.builder(configPath).build(); - CommentedFileConfig newConfig = CommentedFileConfig.builder(configPath).build(); - config.load(); - - /* Upgrade the config */ - new ObjectConverter().toConfig(conf, newConfig); - updateConfigValues(config, newConfig, newConfig, ""); - newConfig.save(); - - config.close(); - newConfig.close(); - } - - public void updateConfigValues(CommentedConfig oldConfig, CommentedConfig newConfig, CommentedConfig outputConfig, String subKey) { - /* Loop over the config keys and check what has changed */ - newConfig.valueMap().forEach((key, value) -> { - String finalKey = subKey + (subKey.isEmpty() ? "" : ".") + key; - if (value instanceof CommentedConfig commentedConfig) { - updateConfigValues(oldConfig, commentedConfig, outputConfig, finalKey); - } else { - outputConfig.set(finalKey, - oldConfig.contains(finalKey) ? oldConfig.get(finalKey) : value); - } - }); - } - - /** - * Get the location of the config file - * - * @return - The FILE object containing the config file - */ - public File getConfigPath() { - return configPath; - } - - /** - * Get the NETWORK SYNC ID - * - * @return - Returns the Sync ID in format modid:config_name - */ - public String getNetworkID() { - return networkID; - } - - /** - * Fired whenever changes to the config are detected - */ - public void configReloaded() { - - } - - /** - * Get the name of the Config File - * - * @return - */ - public String getConfigName() { - return configName; - } - - /** - * Get the MODID of the Module the config is registered to - * - * @return - */ - public String getModId() { - return modId; - } - - public boolean isSaveCalled() { - return isSaveCalled; - } -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/core/config/annotations/HideFromScreen.java b/Common/src/main/java/com/hypherionmc/craterlib/core/config/annotations/HideFromScreen.java deleted file mode 100644 index 512a025..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/core/config/annotations/HideFromScreen.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.hypherionmc.craterlib.core.config.annotations; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -@Retention(RetentionPolicy.RUNTIME) -public @interface HideFromScreen { -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/core/config/annotations/NoConfigScreen.java b/Common/src/main/java/com/hypherionmc/craterlib/core/config/annotations/NoConfigScreen.java deleted file mode 100644 index 4288ee0..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/core/config/annotations/NoConfigScreen.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.hypherionmc.craterlib.core.config.annotations; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -/** - * @author HypherionSA - * Allows Modules to disable Automatic Config Screens - */ -@Retention(RetentionPolicy.RUNTIME) -public @interface NoConfigScreen { -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/core/config/annotations/SubConfig.java b/Common/src/main/java/com/hypherionmc/craterlib/core/config/annotations/SubConfig.java deleted file mode 100644 index e3ec808..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/core/config/annotations/SubConfig.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.hypherionmc.craterlib.core.config.annotations; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * @author HypherionSA - * Used to determine if a Config section should be rendered as a separate screen - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.FIELD) -public @interface SubConfig { -} - diff --git a/Common/src/main/java/com/hypherionmc/craterlib/core/config/annotations/Syncable.java b/Common/src/main/java/com/hypherionmc/craterlib/core/config/annotations/Syncable.java deleted file mode 100644 index 838b35b..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/core/config/annotations/Syncable.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.hypherionmc.craterlib.core.config.annotations; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * @author HypherionSA - * //TODO Currently unused, but to be used with Config Syncing in the future - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.FIELD) -public @interface Syncable { -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/core/config/annotations/Tooltip.java b/Common/src/main/java/com/hypherionmc/craterlib/core/config/annotations/Tooltip.java deleted file mode 100644 index 538471c..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/core/config/annotations/Tooltip.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.hypherionmc.craterlib.core.config.annotations; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * @author HypherionSA - * Provides tooltips to the config GUI - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.FIELD) -public @interface Tooltip { - String[] value(); -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/core/event/CraterEvent.java b/Common/src/main/java/com/hypherionmc/craterlib/core/event/CraterEvent.java deleted file mode 100644 index 89ff00a..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/core/event/CraterEvent.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.hypherionmc.craterlib.core.event; - -import com.hypherionmc.craterlib.core.event.annot.Cancellable; -import com.hypherionmc.craterlib.core.event.exception.CraterEventCancellationException; - -public class CraterEvent { - - private boolean canceled = false; - - private boolean canCancel() { - return this.getClass().isAnnotationPresent(Cancellable.class); - } - - public void cancelEvent() { - try { - if (!this.canCancel()) { - throw new CraterEventCancellationException("Tried to cancel non-cancelable event: " + this.getClass().getName()); - } - - this.canceled = true; - } catch (Exception e) { - e.printStackTrace(); - } - } - - public boolean wasCancelled() { - return this.canceled; - } - -} \ No newline at end of file diff --git a/Common/src/main/java/com/hypherionmc/craterlib/core/event/CraterEventBus.java b/Common/src/main/java/com/hypherionmc/craterlib/core/event/CraterEventBus.java deleted file mode 100644 index 74eeecc..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/core/event/CraterEventBus.java +++ /dev/null @@ -1,241 +0,0 @@ -package com.hypherionmc.craterlib.core.event; - -import com.hypherionmc.craterlib.CraterConstants; -import com.hypherionmc.craterlib.core.event.annot.CraterEventListener; -import org.slf4j.Logger; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.*; -import java.util.function.Consumer; - -public final class CraterEventBus { - - public static final CraterEventBus INSTANCE = new CraterEventBus(); - private static final Logger LOGGER = CraterConstants.LOG; - private final Map, List> events = new HashMap<>(); - - public void postEvent(CraterEvent event) { - if (eventsRegisteredForType(event.getClass())) { - List l = new ArrayList<>(events.get(event.getClass())); - l.sort((o1, o2) -> Integer.compare(o2.priority, o1.priority)); - - for (ListenerContainer c : l) { - c.notifyListener(event); - } - } - } - - public void registerEventListener(Class clazz) { - this.registerListenerMethods(this.getEventMethodsOf(clazz)); - } - - public void registerEventListener(Object object) { - this.registerListenerMethods(this.getEventMethodsOf(object)); - } - - private void registerListenerMethods(List methods) { - for (EventMethod m : methods) { - Consumer listener = (event) -> { - try { - m.method.invoke(m.parentObject, event); - } catch (Exception e) { - throw new RuntimeException(e); - } - }; - - ListenerContainer container = new ListenerContainer(m.eventType, listener, m.priority); - container.listenerParentClassName = m.parentClass.getName(); - container.listenerMethodName = m.method.getName(); - this.registerListener(container); - } - } - - private List getEventMethodsOf(Object objectOrClass) { - List l = new ArrayList<>(); - try { - if (objectOrClass != null) { - boolean isClass = (objectOrClass instanceof Class); - Class c = isClass ? (Class) objectOrClass : objectOrClass.getClass(); - for (Method m : c.getMethods()) { - if (isClass && Modifier.isStatic(m.getModifiers())) { - EventMethod em = EventMethod.tryCreateFrom(new AnalyzedMethod(m, c)); - if ((em != null) && this.hasEventAnnotation(em)) l.add(em); - } - if (!isClass && !Modifier.isStatic(m.getModifiers())) { - EventMethod em = EventMethod.tryCreateFrom(new AnalyzedMethod(m, objectOrClass)); - if ((em != null) && this.hasEventAnnotation(em)) l.add(em); - } - } - } - } catch (Exception e) { - e.printStackTrace(); - } - return l; - } - - private boolean hasEventAnnotation(EventMethod m) { - for (Annotation a : m.annotations) { - if (a instanceof CraterEventListener) return true; - } - return false; - } - - public void registerListener(Consumer listener, Class eventType) { - this.registerListener(listener, eventType, 0); - } - - public void registerListener(Consumer listener, Class eventType, int priority) { - this.registerListener(new ListenerContainer(eventType, listener, priority)); - } - - private void registerListener(ListenerContainer listenerContainer) { - try { - if (!eventsRegisteredForType(listenerContainer.eventType)) { - events.put(listenerContainer.eventType, new ArrayList<>()); - } - events.get(listenerContainer.eventType).add(listenerContainer); - } catch (Exception e) { - e.printStackTrace(); - } - } - - public boolean eventsRegisteredForType(Class eventType) { - if (eventType == null) { - return false; - } - return this.events.containsKey(eventType); - } - - protected final static class ListenerContainer { - - private final Consumer listener; - private final Class eventType; - private final int priority; - private String listenerParentClassName = "[unknown]"; - private String listenerMethodName = "[unknown]"; - - private ListenerContainer(Class eventType, Consumer listener, int priority) { - this.eventType = eventType; - this.listener = listener; - this.priority = priority; - } - - private void notifyListener(CraterEvent event) { - try { - this.listener.accept(event); - } catch (Exception e) { - LOGGER.error("##################################"); - LOGGER.error("Failed to notify event listener!"); - LOGGER.error("Event Type: " + this.eventType.getName()); - LOGGER.error("Listener Parent Class Name: " + this.listenerParentClassName); - LOGGER.error("Listener Method Name In Parent Class: " + this.listenerMethodName); - LOGGER.error("##################################"); - e.printStackTrace(); - } - } - } - - protected static class AnalyzedMethod { - - protected Method method; - protected Object parentObject; - protected Class parentClass; - protected boolean isStatic; - protected List annotations = new ArrayList<>(); - - protected AnalyzedMethod() { - } - - protected AnalyzedMethod(Method method, Object parentObjectOrClass) { - this.method = method; - this.parentObject = parentObjectOrClass; - this.parentClass = this.tryGetParentClass(); - this.isStatic = Modifier.isStatic(method.getModifiers()); - collectMethodAnnotations(this.isStatic ? null : this.parentObject.getClass(), this.method, this.annotations); - } - - protected static void collectMethodAnnotations(Class c, Method m, List addToList) { - try { - addToList.addAll(Arrays.asList(m.getAnnotations())); - if (!Modifier.isStatic(m.getModifiers()) && (c != null)) { - Class sc = c.getSuperclass(); - if (sc != null) { - try { - Method sm = sc.getMethod(m.getName(), m.getParameterTypes()); - collectMethodAnnotations(sc, sm, addToList); - } catch (Exception ignored) { - } - } - } - } catch (Exception ignored) { - } - } - - protected Class tryGetParentClass() { - if (this.parentObject instanceof Class) { - return (Class) this.parentObject; - } - return this.parentObject.getClass(); - } - - } - - protected static class EventMethod extends AnalyzedMethod { - - protected final int priority; - protected final Class eventType; - - protected EventMethod(AnalyzedMethod method) { - - super(); - this.method = method.method; - this.parentObject = method.parentObject; - this.parentClass = method.parentClass; - this.isStatic = method.isStatic; - this.annotations = method.annotations; - - this.priority = this.tryGetPriority(); - this.eventType = this.tryGetEventType(); - - } - - protected static EventMethod tryCreateFrom(AnalyzedMethod method) { - EventMethod em = new EventMethod(method); - return (em.eventType != null) ? em : null; - } - - protected Class tryGetEventType() { - try { - if (this.method != null) { - Class[] params = this.method.getParameterTypes(); - if (params.length > 0) { - Class firstParam = params[0]; - if (CraterEvent.class.isAssignableFrom(firstParam)) { - return (Class) firstParam; - } - } - } - } catch (Exception e) { - e.printStackTrace(); - } - return null; - } - - protected int tryGetPriority() { - try { - for (Annotation a : this.annotations) { - if (a instanceof CraterEventListener craterEventListener) { - return craterEventListener.priority(); - } - } - } catch (Exception e) { - e.printStackTrace(); - } - return 0; - } - - } - -} \ No newline at end of file diff --git a/Common/src/main/java/com/hypherionmc/craterlib/core/event/CraterEventPriority.java b/Common/src/main/java/com/hypherionmc/craterlib/core/event/CraterEventPriority.java deleted file mode 100644 index 0c97134..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/core/event/CraterEventPriority.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.hypherionmc.craterlib.core.event; - -public class CraterEventPriority { - - public static final int LOWEST = -3; - public static final int LOWER = -2; - public static final int LOW = -1; - public static final int NORMAL = 0; - public static final int HIGH = 1; - public static final int HIGHER = 2; - public static final int HIGHEST = 3; - -} \ No newline at end of file diff --git a/Common/src/main/java/com/hypherionmc/craterlib/core/event/annot/Cancellable.java b/Common/src/main/java/com/hypherionmc/craterlib/core/event/annot/Cancellable.java deleted file mode 100644 index ee3c2fc..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/core/event/annot/Cancellable.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.hypherionmc.craterlib.core.event.annot; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -@Retention(RetentionPolicy.RUNTIME) -public @interface Cancellable { -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/core/event/annot/CraterEventListener.java b/Common/src/main/java/com/hypherionmc/craterlib/core/event/annot/CraterEventListener.java deleted file mode 100644 index 7b42490..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/core/event/annot/CraterEventListener.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.hypherionmc.craterlib.core.event.annot; - -import com.hypherionmc.craterlib.core.event.CraterEventPriority; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -@Retention(RetentionPolicy.RUNTIME) -public @interface CraterEventListener { - int priority() default CraterEventPriority.NORMAL; -} \ No newline at end of file diff --git a/Common/src/main/java/com/hypherionmc/craterlib/core/event/exception/CraterEventCancellationException.java b/Common/src/main/java/com/hypherionmc/craterlib/core/event/exception/CraterEventCancellationException.java deleted file mode 100644 index fe2a8a3..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/core/event/exception/CraterEventCancellationException.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.hypherionmc.craterlib.core.event.exception; - -public class CraterEventCancellationException extends Exception { - - public CraterEventCancellationException(String msg) { - super(msg); - } - -} \ No newline at end of file diff --git a/Common/src/main/java/com/hypherionmc/craterlib/core/event/package-info.java b/Common/src/main/java/com/hypherionmc/craterlib/core/event/package-info.java deleted file mode 100644 index 5ec1749..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/core/event/package-info.java +++ /dev/null @@ -1,5 +0,0 @@ -/** - * The event system code in this package is based on, and adapted from Acara (https://github.com/Keksuccino/acara/) - * and is licensed under MIT by Keksuccino - */ -package com.hypherionmc.craterlib.core.event; \ No newline at end of file diff --git a/Common/src/main/java/com/hypherionmc/craterlib/core/networking/CraterPacketNetwork.java b/Common/src/main/java/com/hypherionmc/craterlib/core/networking/CraterPacketNetwork.java deleted file mode 100644 index 081c8fb..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/core/networking/CraterPacketNetwork.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.hypherionmc.craterlib.core.networking; - -import com.hypherionmc.craterlib.core.networking.data.PacketContext; -import com.hypherionmc.craterlib.nojang.network.BridgedFriendlyByteBuf; -import com.hypherionmc.craterlib.nojang.resources.ResourceIdentifier; -import lombok.Getter; - -import java.util.function.BiConsumer; -import java.util.function.Consumer; -import java.util.function.Function; - -/** - * Based on https://github.com/mysticdrew/common-networking/tree/1.20.4 - */ -@Getter -public class CraterPacketNetwork { - - private final PacketRegistry packetRegistry; - public static CraterPacketNetwork INSTANCE; - private static DeferredPacketRegistrar delayedHandler; - - public CraterPacketNetwork(PacketRegistry registry) { - INSTANCE = this; - this.packetRegistry = registry; - getDelayedHandler().registerQueuedPackets(registry); - } - - private static DeferredPacketRegistrar getDelayedHandler() { - if (delayedHandler == null) { - delayedHandler = new DeferredPacketRegistrar(); - } - return delayedHandler; - } - - public static PacketRegistrar registerPacket(ResourceIdentifier id, Class messageType, BiConsumer encoder, Function decoder, Consumer> handler) { - if (INSTANCE != null) { - return INSTANCE.packetRegistry.registerPacket(id, messageType, encoder, decoder, handler); - } else { - return getDelayedHandler().registerPacket(id, messageType, encoder, decoder, handler); - } - } - -} \ No newline at end of file diff --git a/Common/src/main/java/com/hypherionmc/craterlib/core/networking/DeferredPacketRegistrar.java b/Common/src/main/java/com/hypherionmc/craterlib/core/networking/DeferredPacketRegistrar.java deleted file mode 100644 index 25556f4..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/core/networking/DeferredPacketRegistrar.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.hypherionmc.craterlib.core.networking; - -import com.hypherionmc.craterlib.core.networking.data.PacketContext; -import com.hypherionmc.craterlib.core.networking.data.PacketHolder; -import com.hypherionmc.craterlib.core.networking.data.PacketSide; -import com.hypherionmc.craterlib.nojang.network.BridgedFriendlyByteBuf; -import com.hypherionmc.craterlib.nojang.resources.ResourceIdentifier; - -import java.util.HashMap; -import java.util.Map; -import java.util.function.BiConsumer; -import java.util.function.Consumer; -import java.util.function.Function; - -/** - * Based on https://github.com/mysticdrew/common-networking/tree/1.20.4 - */ -public class DeferredPacketRegistrar implements PacketRegistrar { - - private static final Map, PacketHolder> QUEUED_PACKET_MAP = new HashMap<>(); - - @Override - public PacketSide side() { - return PacketSide.CLIENT; - } - - @Override - public PacketRegistrar registerPacket(ResourceIdentifier packetIdentifier, Class messageType, BiConsumer encoder, Function decoder, Consumer> handler) { - PacketHolder container = new PacketHolder<>(packetIdentifier, messageType, encoder, decoder, handler); - QUEUED_PACKET_MAP.put(messageType, container); - return this; - } - - - public void registerQueuedPackets(PacketRegistry packetRegistration) { - if (!QUEUED_PACKET_MAP.isEmpty()) { - packetRegistration.PACKET_MAP.putAll(QUEUED_PACKET_MAP); - QUEUED_PACKET_MAP.forEach((aClass, container) -> packetRegistration.registerPacket(container)); - } - } -} \ No newline at end of file diff --git a/Common/src/main/java/com/hypherionmc/craterlib/core/networking/PacketRegistrar.java b/Common/src/main/java/com/hypherionmc/craterlib/core/networking/PacketRegistrar.java deleted file mode 100644 index 3ea55fa..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/core/networking/PacketRegistrar.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.hypherionmc.craterlib.core.networking; - -import com.hypherionmc.craterlib.core.networking.data.PacketContext; -import com.hypherionmc.craterlib.core.networking.data.PacketSide; -import com.hypherionmc.craterlib.nojang.network.BridgedFriendlyByteBuf; -import com.hypherionmc.craterlib.nojang.resources.ResourceIdentifier; - -import java.util.function.BiConsumer; -import java.util.function.Consumer; -import java.util.function.Function; - -/** - * Based on https://github.com/mysticdrew/common-networking/tree/1.20.4 - */ -public interface PacketRegistrar { - - PacketSide side(); - - PacketRegistrar registerPacket(ResourceIdentifier id, Class messageType, BiConsumer encoder, Function decoder, Consumer> handler); - -} \ No newline at end of file diff --git a/Common/src/main/java/com/hypherionmc/craterlib/core/networking/PacketRegistry.java b/Common/src/main/java/com/hypherionmc/craterlib/core/networking/PacketRegistry.java deleted file mode 100644 index d1ec06c..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/core/networking/PacketRegistry.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.hypherionmc.craterlib.core.networking; - -import com.hypherionmc.craterlib.api.networking.CraterNetworkHandler; -import com.hypherionmc.craterlib.core.networking.data.PacketContext; -import com.hypherionmc.craterlib.core.networking.data.PacketHolder; -import com.hypherionmc.craterlib.core.networking.data.PacketSide; -import com.hypherionmc.craterlib.nojang.network.BridgedFriendlyByteBuf; -import com.hypherionmc.craterlib.nojang.resources.ResourceIdentifier; - -import java.util.HashMap; -import java.util.Map; -import java.util.function.BiConsumer; -import java.util.function.Consumer; -import java.util.function.Function; - -/** - * Based on https://github.com/mysticdrew/common-networking/tree/1.20.4 - */ -public abstract class PacketRegistry implements CraterNetworkHandler, PacketRegistrar { - - protected final Map, PacketHolder> PACKET_MAP = new HashMap<>(); - - protected final PacketSide side; - - public PacketRegistry(PacketSide side) { - this.side = side; - } - - public PacketRegistrar registerPacket(ResourceIdentifier id, Class messageType, BiConsumer encoder, Function decoder, Consumer> handler) { - PacketHolder holder = new PacketHolder<>(id, messageType, encoder, decoder, handler); - PACKET_MAP.put(messageType, holder); - registerPacket(holder); - return this; - } - - public PacketSide side() { - return side; - } - - protected abstract void registerPacket(PacketHolder packetHolder); -} \ No newline at end of file diff --git a/Common/src/main/java/com/hypherionmc/craterlib/core/networking/data/PacketContext.java b/Common/src/main/java/com/hypherionmc/craterlib/core/networking/data/PacketContext.java deleted file mode 100644 index fc432dc..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/core/networking/data/PacketContext.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.hypherionmc.craterlib.core.networking.data; - -import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer; -import org.jetbrains.annotations.Nullable; - -/** - * Based on https://github.com/mysticdrew/common-networking/tree/1.20.4 - */ -public record PacketContext(@Nullable BridgedPlayer sender, T message, PacketSide side) { - - public PacketContext(T message, PacketSide side) { - this(null, message, side); - } - -} \ No newline at end of file diff --git a/Common/src/main/java/com/hypherionmc/craterlib/core/networking/data/PacketHolder.java b/Common/src/main/java/com/hypherionmc/craterlib/core/networking/data/PacketHolder.java deleted file mode 100644 index 10873c5..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/core/networking/data/PacketHolder.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.hypherionmc.craterlib.core.networking.data; - -import com.hypherionmc.craterlib.api.networking.CommonPacketWrapper; -import com.hypherionmc.craterlib.nojang.network.BridgedFriendlyByteBuf; -import com.hypherionmc.craterlib.nojang.resources.ResourceIdentifier; -import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.network.codec.StreamCodec; -import net.minecraft.network.protocol.common.custom.CustomPacketPayload; - -import java.util.function.BiConsumer; -import java.util.function.Consumer; -import java.util.function.Function; - -/** - * Based on https://github.com/mysticdrew/common-networking/tree/1.20.4 - */ -public record PacketHolder(CustomPacketPayload.Type type, - Class messageType, - BiConsumer encoder, - Function decoder, - Consumer> handler) { - - public PacketHolder(ResourceIdentifier packetId, Class messageType, BiConsumer encoder, Function decoder, Consumer> handler) { - this(new CustomPacketPayload.Type<>(packetId.toMojang()), messageType, encoder, decoder, handler); - } - - @SuppressWarnings("unchecked") - public CustomPacketPayload.Type getType() - { - return (CustomPacketPayload.Type) type(); - } - - public StreamCodec getCodec() - { - return CustomPacketPayload.codec( - (packet, buf) -> this.encoder().accept((T)packet.packet(), BridgedFriendlyByteBuf.of(buf)), - (buf) -> new CommonPacketWrapper<>(this, this.decoder().apply(BridgedFriendlyByteBuf.of(buf)))); - } - -} \ No newline at end of file diff --git a/Common/src/main/java/com/hypherionmc/craterlib/core/networking/data/PacketSide.java b/Common/src/main/java/com/hypherionmc/craterlib/core/networking/data/PacketSide.java deleted file mode 100644 index ad6f8ec..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/core/networking/data/PacketSide.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.hypherionmc.craterlib.core.networking.data; - -public enum PacketSide { - CLIENT, - SERVER; - - public PacketSide flipped() { - if (CLIENT.equals(this)) - return SERVER; - - return CLIENT; - } -} \ No newline at end of file diff --git a/Common/src/main/java/com/hypherionmc/craterlib/core/platform/ClientPlatform.java b/Common/src/main/java/com/hypherionmc/craterlib/core/platform/ClientPlatform.java deleted file mode 100644 index 089fb36..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/core/platform/ClientPlatform.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.hypherionmc.craterlib.core.platform; - -import com.hypherionmc.craterlib.nojang.client.BridgedMinecraft; -import com.hypherionmc.craterlib.nojang.client.multiplayer.BridgedClientLevel; -import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer; -import com.hypherionmc.craterlib.utils.InternalServiceUtil; -import net.minecraft.network.Connection; - -/** - * @author HypherionSA - */ -public interface ClientPlatform { - - public final ClientPlatform INSTANCE = InternalServiceUtil.load(ClientPlatform.class); - - BridgedMinecraft getClientInstance(); - - BridgedPlayer getClientPlayer(); - - BridgedClientLevel getClientLevel(); - - Connection getClientConnection(); -} \ No newline at end of file diff --git a/Common/src/main/java/com/hypherionmc/craterlib/core/platform/CommonPlatform.java b/Common/src/main/java/com/hypherionmc/craterlib/core/platform/CommonPlatform.java deleted file mode 100644 index ee7f944..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/core/platform/CommonPlatform.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.hypherionmc.craterlib.core.platform; - -import com.hypherionmc.craterlib.nojang.server.BridgedMinecraftServer; -import com.hypherionmc.craterlib.utils.InternalServiceUtil; - -/** - * @author HypherionSA - */ -public interface CommonPlatform { - - public CommonPlatform INSTANCE = InternalServiceUtil.load(CommonPlatform.class); - - BridgedMinecraftServer getMCServer(); - -} \ No newline at end of file diff --git a/Common/src/main/java/com/hypherionmc/craterlib/core/platform/CompatUtils.java b/Common/src/main/java/com/hypherionmc/craterlib/core/platform/CompatUtils.java deleted file mode 100644 index fb745fc..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/core/platform/CompatUtils.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.hypherionmc.craterlib.core.platform; - -import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer; -import com.hypherionmc.craterlib.utils.InternalServiceUtil; - -public interface CompatUtils { - - public static final CompatUtils INSTANCE = InternalServiceUtil.load(CompatUtils.class); - - boolean isPlayerActive(BridgedPlayer player); - String getSkinUUID(BridgedPlayer player); - -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/core/platform/Environment.java b/Common/src/main/java/com/hypherionmc/craterlib/core/platform/Environment.java deleted file mode 100644 index 2ef219e..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/core/platform/Environment.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.hypherionmc.craterlib.core.platform; - -/** - * @author HypherionSA - */ -public enum Environment { - CLIENT, - SERVER, - UNKNOWN; - - public boolean isClient() { - return this == CLIENT; - } - - public boolean isServer() { - return this == SERVER; - } -} \ No newline at end of file diff --git a/Common/src/main/java/com/hypherionmc/craterlib/core/platform/ModloaderEnvironment.java b/Common/src/main/java/com/hypherionmc/craterlib/core/platform/ModloaderEnvironment.java deleted file mode 100644 index c1bc176..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/core/platform/ModloaderEnvironment.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.hypherionmc.craterlib.core.platform; - -import com.hypherionmc.craterlib.utils.InternalServiceUtil; - -import java.io.File; - -/** - * @author HypherionSA - * Helper class to provide information about the ModLoader - */ -public interface ModloaderEnvironment { - - public final ModloaderEnvironment INSTANCE = InternalServiceUtil.load(ModloaderEnvironment.class); - - boolean isFabric(); - - String getGameVersion(); - - File getGameFolder(); - - File getConfigFolder(); - - File getModsFolder(); - - Environment getEnvironment(); - - boolean isModLoaded(String modid); - - boolean isDevEnv(); - - int getModCount(); -} \ No newline at end of file diff --git a/Common/src/main/java/com/hypherionmc/craterlib/core/rpcsdk/DiscordEventHandlers.java b/Common/src/main/java/com/hypherionmc/craterlib/core/rpcsdk/DiscordEventHandlers.java deleted file mode 100644 index 3f1ffcb..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/core/rpcsdk/DiscordEventHandlers.java +++ /dev/null @@ -1,90 +0,0 @@ -package com.hypherionmc.craterlib.core.rpcsdk; - -import com.hypherionmc.craterlib.core.rpcsdk.callbacks.*; -import com.sun.jna.Structure; - -import java.util.Arrays; -import java.util.List; - -/** - * @author HypherionSA - * Class containing references to all available discord event handles. - * Registering a handler is optional, and non-assigned handlers will be ignored - */ -public class DiscordEventHandlers extends Structure { - - // Callback for when the RPC was initialized successfully - public ReadyCallback ready; - - // Callback for when the Discord connection was ended - public DisconnectedCallback disconnected; - - // Callback for when a Discord Error occurs - public ErroredCallback errored; - - // Callback for when a player joins the game - public JoinGameCallback joinGame; - - // Callback for when a player spectates the game - public SpectateGameCallback spectateGame; - - // Callback for when a players request to join your game - public JoinRequestCallback joinRequest; - - /** - * DO NOT TOUCH THIS... EVER! - */ - @Override - protected List getFieldOrder() { - return Arrays.asList( - "ready", - "disconnected", - "errored", - "joinGame", - "spectateGame", - "joinRequest" - ); - } - - public static class Builder { - private final DiscordEventHandlers handlers; - - public Builder() { - this.handlers = new DiscordEventHandlers(); - } - - public Builder ready(ReadyCallback readyCallback) { - handlers.ready = readyCallback; - return this; - } - - public Builder disconnected(DisconnectedCallback disconnectedCallback) { - handlers.disconnected = disconnectedCallback; - return this; - } - - public Builder errored(ErroredCallback erroredCallback) { - handlers.errored = erroredCallback; - return this; - } - - public Builder joinGame(JoinGameCallback joinGameCallback) { - handlers.joinGame = joinGameCallback; - return this; - } - - public Builder spectateGame(SpectateGameCallback spectateGameCallback) { - handlers.spectateGame = spectateGameCallback; - return this; - } - - public Builder joinRequest(JoinRequestCallback joinRequestCallback) { - handlers.joinRequest = joinRequestCallback; - return this; - } - - public DiscordEventHandlers build() { - return handlers; - } - } -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/core/rpcsdk/DiscordRPC.java b/Common/src/main/java/com/hypherionmc/craterlib/core/rpcsdk/DiscordRPC.java deleted file mode 100644 index 7cf53ff..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/core/rpcsdk/DiscordRPC.java +++ /dev/null @@ -1,99 +0,0 @@ -package com.hypherionmc.craterlib.core.rpcsdk; - -import com.sun.jna.Library; -import com.sun.jna.Native; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -/** - * @author HypherionSA - * Java Wrapper of the Discord-RPC Library - */ -public interface DiscordRPC extends Library { - - DiscordRPC INSTANCE = Native.load("discord-rpc", DiscordRPC.class); - - /** - * Open a New RPC Connection - * - * @param applicationId The ID of the Application the RPC is tied to - * @param handlers Optional Event Callback Handlers - * @param autoRegister Auto Register the running game - * @param steamId Steam ID of the game - */ - void Discord_Initialize(@NotNull String applicationId, @Nullable DiscordEventHandlers handlers, boolean autoRegister, @Nullable String steamId); - - /** - * Shutdown the RPC instance and disconnect from discord - */ - void Discord_Shutdown(); - - /** - * Need to be called manually at least every 2 seconds, to allow RPC updates - * and callback handlers to fire - */ - void Discord_RunCallbacks(); - - /** - * Not sure about this. Believe it needs to be called manually in some circumstances - */ - void Discord_UpdateConnection(); - - /** - * Update the Rich Presence - * - * @param struct Constructed {@link DiscordRichPresence} - */ - void Discord_UpdatePresence(@Nullable DiscordRichPresence struct); - - /** - * Clear the current Rich Presence - */ - void Discord_ClearPresence(); - - /** - * Respond to Join/Spectate callback - * - * @param userid The Discord User ID of the user that initiated the request - * @param reply Reply to the request. See {@link DiscordReply} - */ - void Discord_Respond(@NotNull String userid, int reply); - - /** - * Replace the already registered {@link DiscordEventHandlers} - * - * @param handlers The new handlers to apply - */ - void Discord_UpdateHandlers(@Nullable DiscordEventHandlers handlers); - - /** - * Register the executable of the application/game - * Only applicable when autoRegister is set to false - * - * @param applicationId The Application ID - * @param command The Launch command of the game - *

- * NB: THIS DOES NOT WORK WITH MINECRAFT - */ - void Discord_Register(String applicationId, String command); - - /** - * Register the Steam executable of the application/game - * - * @param applicationId The Application ID - * @param steamId The Steam ID of the application/game - */ - void Discord_RegisterSteamGame(String applicationId, String steamId); - - public enum DiscordReply { - NO(0), - YES(1), - IGNORE(2); - - public final int reply; - - DiscordReply(int reply) { - this.reply = reply; - } - } -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/core/rpcsdk/DiscordRichPresence.java b/Common/src/main/java/com/hypherionmc/craterlib/core/rpcsdk/DiscordRichPresence.java deleted file mode 100644 index 51fd720..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/core/rpcsdk/DiscordRichPresence.java +++ /dev/null @@ -1,248 +0,0 @@ -package com.hypherionmc.craterlib.core.rpcsdk; - -import com.hypherionmc.craterlib.core.rpcsdk.helpers.RPCButton; -import com.sun.jna.Structure; -import org.jetbrains.annotations.NotNull; - -import java.time.OffsetDateTime; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -/** - * @author HypherionSA - * Class reprenting a Discord RPC activity - */ -public class DiscordRichPresence extends Structure { - - // First line of text on the RPC - public String state; - - // Second line of text on the RPC - public String details; - - // Time the activity started in UNIX-Timestamp format - public long startTimestamp; - - // Time the activity will end in UNIX-Timestamp format - public long endTimestamp; - - // URL or Asset key of the Large Image - public String largeImageKey; - - // Hover text to display when hovering the Large Image - public String largeImageText; - - // URL or Asset key of the Small Image - public String smallImageKey; - - // Hover text to display when hovering the Small Image - public String smallImageText; - - // Id of the player's party, lobby, or group. - public String partyId; - - // Current size of the player's party, lobby, or group. - public int partySize; - - // Maximum size of the player's party, lobby, or group. - public int partyMax; - - // Unused - public String partyPrivacy; - - // Unused. - public String matchSecret; - - // Unique hashed string for chat invitations and Ask to Join. - public String joinSecret; - - // Unique hashed string for Spectate button. - public String spectateSecret; - - // Label of the First RPC Button - public String button_label_1; - - // URL of the First RPC Button - public String button_url_1; - - // Label of the Second RPC Button - public String button_label_2; - - // URL of the Second RPC Button - public String button_url_2; - - // Unused - public int instance; - - public DiscordRichPresence() { - setStringEncoding("UTF-8"); - } - - /** - * DO NOT TOUCH THIS... EVER! - */ - @Override - protected List getFieldOrder() { - return Arrays.asList( - "state", - "details", - "startTimestamp", - "endTimestamp", - "largeImageKey", - "largeImageText", - "smallImageKey", - "smallImageText", - "partyId", - "partySize", - "partyMax", - "partyPrivacy", - "matchSecret", - "joinSecret", - "spectateSecret", - "button_label_1", - "button_url_1", - "button_label_2", - "button_url_2", - "instance" - ); - } - - public static class Builder { - private final DiscordRichPresence rpc; - - public Builder(String state) { - rpc = new DiscordRichPresence(); - - if (state != null && !state.isEmpty()) { - rpc.state = state.substring(0, Math.min(state.length(), 128)); - } - } - - public Builder setDetails(String details) { - if (details != null && !details.isEmpty()) { - rpc.details = details.substring(0, Math.min(details.length(), 128)); - } - return this; - } - - public Builder setStartTimestamp(long timestamp) { - rpc.startTimestamp = timestamp; - return this; - } - - public Builder setStartTimestamp(OffsetDateTime timestamp) { - rpc.startTimestamp = timestamp.toEpochSecond(); - return this; - } - - public Builder setEndTimestamp(long timestamp) { - rpc.endTimestamp = timestamp; - return this; - } - - public Builder setEndTimestamp(OffsetDateTime timestamp) { - rpc.endTimestamp = timestamp.toEpochSecond(); - return this; - } - - public Builder setLargeImage(String key) { - return this.setLargeImage(key, ""); - } - - public Builder setLargeImage(@NotNull String key, String text) { - // Null check used for users blatantly ignoring the NotNull marker - if ((text != null && !text.isEmpty()) && key != null) { - throw new IllegalArgumentException("Image key cannot be null when assigning a hover text"); - } - - rpc.largeImageKey = key; - rpc.largeImageText = text; - return this; - } - - public Builder setSmallImage(String key) { - return this.setSmallImage(key, ""); - } - - public Builder setSmallImage(@NotNull String key, String text) { - // Null check used for users blatantly ignoring the NotNull marker - if ((text != null && !text.isEmpty()) && key != null) { - throw new IllegalArgumentException("Image key cannot be null when assigning a hover text"); - } - - rpc.smallImageKey = key; - rpc.smallImageText = text; - return this; - } - - public Builder setParty(String party, int size, int max) { - // Buttons are present, ignore - if ((rpc.button_label_1 != null && rpc.button_label_1.isEmpty()) || (rpc.button_label_2 != null && rpc.button_label_2.isEmpty())) - return this; - - rpc.partyId = party; - rpc.partySize = size; - rpc.partyMax = max; - return this; - } - - public Builder setSecrets(String match, String join, String spectate) { - // Buttons are present, ignore - if ((rpc.button_label_1 != null && rpc.button_label_1.isEmpty()) || (rpc.button_label_2 != null && rpc.button_label_2.isEmpty())) - return this; - - rpc.matchSecret = match; - rpc.joinSecret = join; - rpc.spectateSecret = spectate; - return this; - } - - public Builder setSecrets(String join, String spectate) { - // Buttons are present, ignore - if ((rpc.button_label_1 != null && rpc.button_label_1.isEmpty()) || (rpc.button_label_2 != null && rpc.button_label_2.isEmpty())) - return this; - - rpc.joinSecret = join; - rpc.spectateSecret = spectate; - return this; - } - - public Builder setInstance(boolean i) { - // Buttons are present, ignore - if ((rpc.button_label_1 != null && rpc.button_label_1.isEmpty()) || (rpc.button_label_2 != null && rpc.button_label_2.isEmpty())) - return this; - - rpc.instance = i ? 1 : 0; - return this; - } - - public Builder setButtons(RPCButton button) { - return this.setButtons(Collections.singletonList(button)); - } - - public Builder setButtons(RPCButton button1, RPCButton button2) { - return this.setButtons(Arrays.asList(button1, button2)); - } - - public Builder setButtons(List rpcButtons) { - // Limit to 2 Buttons. Discord Limitation - if (rpcButtons != null && !rpcButtons.isEmpty()) { - int length = Math.min(rpcButtons.size(), 2); - rpc.button_label_1 = rpcButtons.get(0).getLabel(); - rpc.button_url_1 = rpcButtons.get(0).getUrl(); - - if (length == 2) { - rpc.button_label_2 = rpcButtons.get(1).getLabel(); - rpc.button_url_2 = rpcButtons.get(1).getUrl(); - } - } - - return this; - } - - public DiscordRichPresence build() { - return rpc; - } - } -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/core/rpcsdk/DiscordUser.java b/Common/src/main/java/com/hypherionmc/craterlib/core/rpcsdk/DiscordUser.java deleted file mode 100644 index e8bc085..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/core/rpcsdk/DiscordUser.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.hypherionmc.craterlib.core.rpcsdk; - -import com.sun.jna.Structure; - -import java.util.Arrays; -import java.util.List; - -/** - * @author HypherionSA - * Class representing the Discord User - */ -public class DiscordUser extends Structure { - - // The User ID of the User - public String userId; - - // The Username of the User - public String username; - - // The unique identifier of the user. Discontinued by Discord - @Deprecated - public String discriminator; - - // The avatar has of the user - public String avatar; - - /** - * DO NOT TOUCH THIS... EVER! - */ - @Override - protected List getFieldOrder() { - return Arrays.asList( - "userId", - "username", - "discriminator", - "avatar" - ); - } -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/core/rpcsdk/callbacks/DisconnectedCallback.java b/Common/src/main/java/com/hypherionmc/craterlib/core/rpcsdk/callbacks/DisconnectedCallback.java deleted file mode 100644 index 7ea59e1..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/core/rpcsdk/callbacks/DisconnectedCallback.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.hypherionmc.craterlib.core.rpcsdk.callbacks; - -import com.sun.jna.Callback; - -/** - * @author HypherionSA - * Callback for when the Discord RPC disconnects - */ -public interface DisconnectedCallback extends Callback { - - /** - * Called when RPC disconnected - * - * @param errorCode Error code if any - * @param message Details about the disconnection - */ - void apply(int errorCode, String message); -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/core/rpcsdk/callbacks/ErroredCallback.java b/Common/src/main/java/com/hypherionmc/craterlib/core/rpcsdk/callbacks/ErroredCallback.java deleted file mode 100644 index 1f86c90..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/core/rpcsdk/callbacks/ErroredCallback.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.hypherionmc.craterlib.core.rpcsdk.callbacks; - -import com.sun.jna.Callback; - -/** - * @author HypherionSA - * Callback for when the RPC ran into an error - */ -public interface ErroredCallback extends Callback { - - /** - * Called when an RPC error occurs - * - * @param errorCode Error code if any - * @param message Details about the error - */ - void apply(int errorCode, String message); -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/core/rpcsdk/callbacks/JoinGameCallback.java b/Common/src/main/java/com/hypherionmc/craterlib/core/rpcsdk/callbacks/JoinGameCallback.java deleted file mode 100644 index cc752af..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/core/rpcsdk/callbacks/JoinGameCallback.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.hypherionmc.craterlib.core.rpcsdk.callbacks; - -import com.sun.jna.Callback; - -/** - * @author HypherionSA - * Callback for when someone was approved to join your game - */ -public interface JoinGameCallback extends Callback { - - /** - * Called when someone joins a game from {@link JoinRequestCallback} - * - * @param joinSecret Secret or Password required to let the player join the game - */ - void apply(String joinSecret); -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/core/rpcsdk/callbacks/JoinRequestCallback.java b/Common/src/main/java/com/hypherionmc/craterlib/core/rpcsdk/callbacks/JoinRequestCallback.java deleted file mode 100644 index 115fd4f..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/core/rpcsdk/callbacks/JoinRequestCallback.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.hypherionmc.craterlib.core.rpcsdk.callbacks; - -import com.hypherionmc.craterlib.core.rpcsdk.DiscordUser; -import com.sun.jna.Callback; - -/** - * @author HypherionSA - * Callback for when someone requests to join your game - */ -public interface JoinRequestCallback extends Callback { - - /** - * Called when someone clicks on the Join Game button - * - * @param user The Discord User trying to join your game - * @see DiscordUser - */ - void apply(DiscordUser user); -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/core/rpcsdk/callbacks/ReadyCallback.java b/Common/src/main/java/com/hypherionmc/craterlib/core/rpcsdk/callbacks/ReadyCallback.java deleted file mode 100644 index 66f3b59..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/core/rpcsdk/callbacks/ReadyCallback.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.hypherionmc.craterlib.core.rpcsdk.callbacks; - -import com.hypherionmc.craterlib.core.rpcsdk.DiscordUser; -import com.sun.jna.Callback; - -/** - * @author HypherionSA - * Callback for when the RPC has connected successfully - */ -public interface ReadyCallback extends Callback { - - /** - * Called when the RPC is connected and ready to be used - * - * @param user The user the RPC is displayed on - * @see DiscordUser - */ - void apply(DiscordUser user); -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/core/rpcsdk/callbacks/SpectateGameCallback.java b/Common/src/main/java/com/hypherionmc/craterlib/core/rpcsdk/callbacks/SpectateGameCallback.java deleted file mode 100644 index 979e53d..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/core/rpcsdk/callbacks/SpectateGameCallback.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.hypherionmc.craterlib.core.rpcsdk.callbacks; - -import com.sun.jna.Callback; - -/** - * @author HypherionSA - * Callback for when someone is requesting to spectate your game - */ -public interface SpectateGameCallback extends Callback { - - /** - * Called when joining the game - * - * @param spectateSecret Secret or Password required to let the player spectate - */ - void apply(String spectateSecret); -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/core/rpcsdk/helpers/RPCButton.java b/Common/src/main/java/com/hypherionmc/craterlib/core/rpcsdk/helpers/RPCButton.java deleted file mode 100644 index ab2bdc8..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/core/rpcsdk/helpers/RPCButton.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.hypherionmc.craterlib.core.rpcsdk.helpers; - -import org.jetbrains.annotations.NotNull; - -import java.io.Serializable; - -/** - * @author HypherionSA - * Helper class to add Buttons to Discord Rich Presence - * This can not be used with Join/Spectate - */ -public class RPCButton implements Serializable { - - // The label of the button - private final String label; - - // The URL the button will open when clicked - private final String url; - - protected RPCButton(String label, String url) { - this.label = label; - this.url = url; - } - - /** - * Create a new RPC Button - * - * @param label The label of the button - * @param url The URL the button will open when clicked - * @return The constructed button - */ - public static RPCButton create(@NotNull String label, @NotNull String url) { - // Null check used here for users blatantly ignoring the NotNull marker - if (label == null || label.isEmpty() || url == null || url.isEmpty()) { - throw new IllegalArgumentException("RPC Buttons require both a label and url"); - } - - label = label.substring(0, Math.min(label.length(), 31)); - return new RPCButton(label, url); - } - - /** - * @return The label assigned to the button - */ - public String getLabel() { - return label; - } - - /** - * @return The URL of the button - */ - public String getUrl() { - return url; - } -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/mixin/ChatInputSuggestorMixin.java b/Common/src/main/java/com/hypherionmc/craterlib/mixin/ChatInputSuggestorMixin.java deleted file mode 100644 index c48dfbc..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/mixin/ChatInputSuggestorMixin.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.hypherionmc.craterlib.mixin; - -import com.hypherionmc.craterlib.client.mentions.MentionsController; -import net.minecraft.client.gui.components.CommandSuggestions; -import net.minecraft.client.gui.components.EditBox; -import org.objectweb.asm.Opcodes; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.ModifyVariable; -import org.spongepowered.asm.mixin.injection.Slice; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import java.util.ArrayList; -import java.util.Collection; - -/** - * @author HypherionSA - * Allow Users, Roles and Channels to be pingable from MC chat (Client Side) - */ -@Mixin(CommandSuggestions.class) -public abstract class ChatInputSuggestorMixin { - - @Shadow - public abstract void showSuggestions(boolean p_93931_); - - @Shadow @Final - EditBox input; - - @Shadow - private static int getLastWordIndex(String p_93913_) { - return 0; - } - - @Inject( - method = "updateCommandInfo", - at = @At( - value = "FIELD", - target = "Lnet/minecraft/client/gui/components/CommandSuggestions;pendingSuggestions:Ljava/util/concurrent/CompletableFuture;", - opcode = Opcodes.PUTFIELD, - shift = At.Shift.AFTER, - ordinal = 0 - ), - slice = @Slice( - from = @At( - value = "INVOKE", - target = "Lnet/minecraft/client/gui/components/CommandSuggestions;getLastWordIndex(Ljava/lang/String;)I" - ) - ) - ) - private void injectSuggestions(CallbackInfo ci) { - if (MentionsController.hasMentions() && MentionsController.isLastMentionConditional()) { - this.showSuggestions(true); - } - } - - @SuppressWarnings("InvalidInjectorMethodSignature") - @ModifyVariable(method = "updateCommandInfo", at = @At(value = "STORE"), ordinal = 0, name = "collection") - private Collection injectMentions(Collection vanilla) { - if (!MentionsController.hasMentions()) - return vanilla; - - ArrayList newSuggest = new ArrayList<>(vanilla); - - String currentInput = this.input.getValue(); - int currentCursorPosition = this.input.getCursorPosition(); - - String textBeforeCursor = currentInput.substring(0, currentCursorPosition); - int startOfCurrentWord = getLastWordIndex(textBeforeCursor); - - String currentWord = textBeforeCursor.substring(startOfCurrentWord); - String finalWord = currentWord.replace("[", "").replace("]", ""); - - Collection mentions = MentionsController.getMentions(finalWord); - - if (!mentions.isEmpty()) { - mentions.forEach(m -> newSuggest.add("[" + m + "]")); - } - - return newSuggest; - } -} \ No newline at end of file diff --git a/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/CommandMixin.java b/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/CommandMixin.java deleted file mode 100644 index bb9dec4..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/CommandMixin.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.hypherionmc.craterlib.mixin.events; - -import com.google.common.base.Throwables; -import com.hypherionmc.craterlib.api.events.server.CraterCommandEvent; -import com.hypherionmc.craterlib.core.event.CraterEventBus; -import com.mojang.brigadier.ParseResults; -import net.minecraft.commands.CommandSourceStack; -import net.minecraft.commands.Commands; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(Commands.class) -public class CommandMixin { - - @Inject(method = "performCommand", - at = @At(value = "INVOKE", - target = "Lnet/minecraft/commands/Commands;finishParsing(Lcom/mojang/brigadier/ParseResults;Ljava/lang/String;Lnet/minecraft/commands/CommandSourceStack;)Lcom/mojang/brigadier/context/ContextChain;", - shift = At.Shift.BEFORE - ), cancellable = true - ) - private void injectCommandEvent(ParseResults stackParseResults, String command, CallbackInfo ci) { - CraterCommandEvent commandEvent = CraterCommandEvent.of(stackParseResults, command); - CraterEventBus.INSTANCE.postEvent(commandEvent); - if (commandEvent.wasCancelled()) { - ci.cancel(); - return; - } - - if (commandEvent.getException() != null) { - Throwables.throwIfUnchecked(commandEvent.getException()); - ci.cancel(); - } - } - -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/PlayerAdvancementsMixin.java b/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/PlayerAdvancementsMixin.java deleted file mode 100644 index 30fa64f..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/PlayerAdvancementsMixin.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.hypherionmc.craterlib.mixin.events; - -import com.hypherionmc.craterlib.api.events.server.CraterAdvancementEvent; -import com.hypherionmc.craterlib.core.event.CraterEventBus; -import com.hypherionmc.craterlib.nojang.advancements.BridgedAdvancement; -import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer; -import net.minecraft.advancements.Advancement; -import net.minecraft.advancements.AdvancementHolder; -import net.minecraft.server.PlayerAdvancements; -import net.minecraft.server.level.ServerPlayer; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -@Mixin(PlayerAdvancements.class) -public class PlayerAdvancementsMixin { - - @Shadow - private ServerPlayer player; - - @Inject(method = "award", at = @At(value = "INVOKE", target = "Lnet/minecraft/advancements/AdvancementRewards;grant(Lnet/minecraft/server/level/ServerPlayer;)V", shift = At.Shift.AFTER)) - private void injectAdvancementEvent(AdvancementHolder advancementHolder, String string, CallbackInfoReturnable cir) { - Advancement advancement = advancementHolder.value(); - - if (advancement.display().isPresent() && advancement.display().get().shouldAnnounceChat()) { - CraterEventBus.INSTANCE.postEvent(new CraterAdvancementEvent(BridgedPlayer.of(this.player), BridgedAdvancement.of(advancementHolder.value()))); - } - } -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/PlayerListMixin.java b/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/PlayerListMixin.java deleted file mode 100644 index 3bc6f6b..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/PlayerListMixin.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.hypherionmc.craterlib.mixin.events; - -import com.hypherionmc.craterlib.api.events.server.CraterPlayerEvent; -import com.hypherionmc.craterlib.api.events.server.MessageBroadcastEvent; -import com.hypherionmc.craterlib.api.events.server.PlayerPreLoginEvent; -import com.hypherionmc.craterlib.core.event.CraterEventBus; -import com.hypherionmc.craterlib.nojang.authlib.BridgedGameProfile; -import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer; -import com.hypherionmc.craterlib.utils.ChatUtils; -import com.mojang.authlib.GameProfile; -import net.minecraft.network.Connection; -import net.minecraft.network.chat.Component; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.server.network.CommonListenerCookie; -import net.minecraft.server.players.PlayerList; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import java.net.SocketAddress; -import java.util.function.Function; - -@Mixin(PlayerList.class) -public class PlayerListMixin { - - @Inject(method = "broadcastSystemMessage(Lnet/minecraft/network/chat/Component;Ljava/util/function/Function;Z)V", at = @At("HEAD")) - private void injectBroadcastEvent(Component component, Function function, boolean bl, CallbackInfo ci) { - String thread = Thread.currentThread().getStackTrace()[3].getClassName(); - MessageBroadcastEvent event = new MessageBroadcastEvent(ChatUtils.mojangToAdventure(component), (f) -> ChatUtils.mojangToAdventure(component), bl, thread); - CraterEventBus.INSTANCE.postEvent(event); - } - - @Inject(method = "placeNewPlayer", at = @At("TAIL")) - private void injectPlayerLoginEvent(Connection connection, ServerPlayer serverPlayer, CommonListenerCookie commonListenerCookie, CallbackInfo ci) { - CraterEventBus.INSTANCE.postEvent(new CraterPlayerEvent.PlayerLoggedIn(BridgedPlayer.of(serverPlayer))); - } - - @Inject(method = "remove", at = @At("HEAD")) - private void injectPlayerLogoutEvent(ServerPlayer player, CallbackInfo ci) { - CraterEventBus.INSTANCE.postEvent(new CraterPlayerEvent.PlayerLoggedOut(BridgedPlayer.of(player))); - } - - @Inject(method = "canPlayerLogin", at = @At("HEAD"), cancellable = true) - private void injectPreLoginEvent(SocketAddress address, GameProfile gameProfile, CallbackInfoReturnable cir) { - PlayerPreLoginEvent event = new PlayerPreLoginEvent(address, BridgedGameProfile.of(gameProfile)); - CraterEventBus.INSTANCE.postEvent(event); - if (event.getMessage() != null) { - cir.setReturnValue(ChatUtils.adventureToMojang(event.getMessage())); - } - } -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/PlayerMixin.java b/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/PlayerMixin.java deleted file mode 100644 index 5fd03bd..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/PlayerMixin.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.hypherionmc.craterlib.mixin.events; - -import com.hypherionmc.craterlib.api.events.common.CraterPlayerDeathEvent; -import com.hypherionmc.craterlib.core.event.CraterEventBus; -import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer; -import net.minecraft.world.damagesource.DamageSource; -import net.minecraft.world.entity.player.Player; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(Player.class) -public class PlayerMixin { - - @Inject(method = "die", at = @At("HEAD")) - private void injectPlayerDeathEvent(DamageSource damageSource, CallbackInfo ci) { - CraterEventBus.INSTANCE.postEvent(new CraterPlayerDeathEvent(BridgedPlayer.of(((Player) (Object) this)), damageSource)); - } - -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/ServerPlayerMixin.java b/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/ServerPlayerMixin.java deleted file mode 100644 index ae028e7..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/ServerPlayerMixin.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.hypherionmc.craterlib.mixin.events; - -import com.hypherionmc.craterlib.api.events.common.CraterPlayerDeathEvent; -import com.hypherionmc.craterlib.core.event.CraterEventBus; -import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.world.damagesource.DamageSource; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(ServerPlayer.class) -public class ServerPlayerMixin { - - @Inject(method = "die", at = @At("HEAD")) - private void injectPlayerDeathEvent(DamageSource damageSource, CallbackInfo ci) { - CraterEventBus.INSTANCE.postEvent(new CraterPlayerDeathEvent(BridgedPlayer.of(((ServerPlayer) (Object) this)), damageSource)); - } - -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/client/ClientLevelMixin.java b/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/client/ClientLevelMixin.java deleted file mode 100644 index 2368d6d..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/client/ClientLevelMixin.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.hypherionmc.craterlib.mixin.events.client; - -import com.hypherionmc.craterlib.api.events.client.CraterSinglePlayerEvent; -import com.hypherionmc.craterlib.core.event.CraterEventBus; -import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer; -import net.minecraft.client.multiplayer.ClientLevel; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.player.Player; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(ClientLevel.class) -public class ClientLevelMixin { - - @Inject(method = "addEntity", at = @At("HEAD")) - private void injectSinglePlayerJoinEvent(Entity entity, CallbackInfo ci) { - if (entity instanceof Player player) { - CraterSinglePlayerEvent.PlayerLogin playerLogin = new CraterSinglePlayerEvent.PlayerLogin(BridgedPlayer.of(player)); - CraterEventBus.INSTANCE.postEvent(playerLogin); - } - } - -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/client/MinecraftMixin.java b/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/client/MinecraftMixin.java deleted file mode 100644 index 2903131..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/client/MinecraftMixin.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.hypherionmc.craterlib.mixin.events.client; - -import com.hypherionmc.craterlib.api.events.client.ScreenEvent; -import com.hypherionmc.craterlib.core.event.CraterEventBus; -import com.hypherionmc.craterlib.nojang.client.gui.BridgedScreen; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.screens.Screen; -import org.jetbrains.annotations.Nullable; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(Minecraft.class) -public class MinecraftMixin { - - @Shadow - @Nullable - public Screen screen; - - @Inject(method = "setScreen", at = @At(value = "TAIL")) - private void injectScreenOpeningEvent(Screen screen, CallbackInfo ci) { - Screen old = this.screen; - if (screen != null) { - ScreenEvent.Opening opening = new ScreenEvent.Opening(BridgedScreen.of(old), BridgedScreen.of(screen)); - CraterEventBus.INSTANCE.postEvent(opening); - } - } - -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/client/RealmsMainScreenMixin.java b/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/client/RealmsMainScreenMixin.java deleted file mode 100644 index c1ce895..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/client/RealmsMainScreenMixin.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.hypherionmc.craterlib.mixin.events.client; - -import com.hypherionmc.craterlib.api.events.client.PlayerJoinRealmEvent; -import com.hypherionmc.craterlib.core.event.CraterEventBus; -import com.hypherionmc.craterlib.nojang.realmsclient.dto.BridgedRealmsServer; -import com.mojang.realmsclient.RealmsMainScreen; -import com.mojang.realmsclient.dto.RealmsServer; -import net.minecraft.client.gui.screens.Screen; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(RealmsMainScreen.class) -public class RealmsMainScreenMixin { - - @Inject(at = @At("HEAD"), method = "play(Lcom/mojang/realmsclient/dto/RealmsServer;Lnet/minecraft/client/gui/screens/Screen;Z)V") - private static void play(RealmsServer serverData, Screen arg2, boolean bl, CallbackInfo ci) { - PlayerJoinRealmEvent playerJoinRealm = new PlayerJoinRealmEvent(BridgedRealmsServer.of(serverData)); - CraterEventBus.INSTANCE.postEvent(playerJoinRealm); - } - -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/nojang/advancements/BridgedAdvancement.java b/Common/src/main/java/com/hypherionmc/craterlib/nojang/advancements/BridgedAdvancement.java deleted file mode 100644 index 19a7e7a..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/nojang/advancements/BridgedAdvancement.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.hypherionmc.craterlib.nojang.advancements; - -import lombok.RequiredArgsConstructor; -import net.minecraft.advancements.Advancement; - -import java.util.Optional; - -@RequiredArgsConstructor(staticName = "of") -public class BridgedAdvancement { - - private final Advancement internal; - - public Optional displayInfo() { - if (internal.display().isPresent()) { - return Optional.of(BridgedDisplayInfo.of(internal.display().get())); - } - - return Optional.empty(); - } - -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/nojang/advancements/BridgedDisplayInfo.java b/Common/src/main/java/com/hypherionmc/craterlib/nojang/advancements/BridgedDisplayInfo.java deleted file mode 100644 index 5a0c155..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/nojang/advancements/BridgedDisplayInfo.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.hypherionmc.craterlib.nojang.advancements; - -import com.hypherionmc.craterlib.utils.ChatUtils; -import lombok.RequiredArgsConstructor; -import net.kyori.adventure.text.Component; -import net.minecraft.advancements.DisplayInfo; - -@RequiredArgsConstructor(staticName = "of") -public class BridgedDisplayInfo { - - private final DisplayInfo internal; - - public boolean shouldDisplay() { - return internal.shouldAnnounceChat(); - } - - public boolean isHidden() { - return internal.isHidden(); - } - - public Component displayName() { - return ChatUtils.mojangToAdventure(internal.getTitle()); - } - - public Component description() { - return ChatUtils.mojangToAdventure(internal.getDescription()); - } - -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/nojang/authlib/BridgedGameProfile.java b/Common/src/main/java/com/hypherionmc/craterlib/nojang/authlib/BridgedGameProfile.java deleted file mode 100644 index c83f3c4..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/nojang/authlib/BridgedGameProfile.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.hypherionmc.craterlib.nojang.authlib; - -import com.mojang.authlib.GameProfile; -import lombok.RequiredArgsConstructor; - -import java.util.UUID; - -@RequiredArgsConstructor(staticName = "of") -public class BridgedGameProfile { - - private final GameProfile internal; - - public static BridgedGameProfile mojang(UUID id, String name) { - return new BridgedGameProfile(new GameProfile(id, name)); - } - - public String getName() { - return internal.getName(); - } - - public UUID getId() { - return internal.getId(); - } - - public GameProfile toMojang() { - return internal; - } - -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/nojang/client/BridgedMinecraft.java b/Common/src/main/java/com/hypherionmc/craterlib/nojang/client/BridgedMinecraft.java deleted file mode 100644 index 89e5d05..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/nojang/client/BridgedMinecraft.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.hypherionmc.craterlib.nojang.client; - -import com.hypherionmc.craterlib.nojang.client.multiplayer.BridgedClientLevel; -import com.hypherionmc.craterlib.nojang.client.multiplayer.BridgedServerData; -import com.hypherionmc.craterlib.nojang.client.server.BridgedIntegratedServer; -import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer; -import lombok.Getter; -import net.minecraft.SharedConstants; -import net.minecraft.client.Minecraft; -import org.jetbrains.annotations.Nullable; - -import java.io.File; -import java.util.UUID; - -public class BridgedMinecraft { - - @Getter - private static final BridgedMinecraft instance = new BridgedMinecraft(); - private final Minecraft internal = Minecraft.getInstance(); - - public File getGameDirectory() { - return internal.gameDirectory; - } - - public BridgedOptions getOptions() { - return BridgedOptions.of(internal.options); - } - - @Nullable - public BridgedClientLevel getLevel() { - if (internal.level == null) - return null; - - return BridgedClientLevel.of(internal.level); - } - - public boolean isRealmServer() { - return internal.getCurrentServer() != null && internal.getCurrentServer().isRealm(); - } - - public boolean isSinglePlayer() { - return internal.hasSingleplayerServer(); - } - - @Nullable - public BridgedPlayer getPlayer() { - if (internal.player == null) - return null; - - return BridgedPlayer.of(internal.player); - } - - public String getGameVersion() { - return SharedConstants.getCurrentVersion().getName(); - } - - public String getUserName() { - return internal.getUser().getName(); - } - - public UUID getPlayerId() { - return internal.getUser().getProfileId(); - } - - @Nullable - public BridgedServerData getCurrentServer() { - if (internal.getCurrentServer() == null) - return null; - - return BridgedServerData.of(internal.getCurrentServer()); - } - - @Nullable - public BridgedIntegratedServer getSinglePlayerServer() { - return BridgedIntegratedServer.of(internal.getSingleplayerServer()); - } - - public int getServerPlayerCount () { - if (internal.getConnection() == null) - return 0; - - return internal.getConnection().getOnlinePlayers().size(); - } -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/nojang/client/BridgedOptions.java b/Common/src/main/java/com/hypherionmc/craterlib/nojang/client/BridgedOptions.java deleted file mode 100644 index 7063feb..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/nojang/client/BridgedOptions.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.hypherionmc.craterlib.nojang.client; - -import lombok.RequiredArgsConstructor; -import net.minecraft.client.Options; - -@RequiredArgsConstructor(staticName = "of") -public class BridgedOptions { - - private final Options internal; - - public String getLanguage() { - return internal.languageCode; - } - -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/nojang/client/gui/BridgedScreen.java b/Common/src/main/java/com/hypherionmc/craterlib/nojang/client/gui/BridgedScreen.java deleted file mode 100644 index c4bcc23..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/nojang/client/gui/BridgedScreen.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.hypherionmc.craterlib.nojang.client.gui; - -import lombok.RequiredArgsConstructor; -import net.minecraft.client.gui.screens.LevelLoadingScreen; -import net.minecraft.client.gui.screens.ReceivingLevelScreen; -import net.minecraft.client.gui.screens.Screen; -import net.minecraft.client.gui.screens.TitleScreen; -import net.minecraft.client.gui.screens.multiplayer.JoinMultiplayerScreen; -import net.minecraft.realms.RealmsScreen; - -@RequiredArgsConstructor(staticName = "of") -public class BridgedScreen { - - private final Screen internal; - - public boolean isTitleScreen() { - return internal instanceof TitleScreen; - } - - public boolean isRealmsScreen() { - return internal instanceof RealmsScreen; - } - - public boolean isServerBrowserScreen() { - return internal instanceof JoinMultiplayerScreen; - } - - public boolean isLoadingScreen() { - return internal instanceof LevelLoadingScreen || internal instanceof ReceivingLevelScreen; - } - - public Screen toMojang() { - return internal; - } - -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/nojang/client/multiplayer/BridgedClientLevel.java b/Common/src/main/java/com/hypherionmc/craterlib/nojang/client/multiplayer/BridgedClientLevel.java deleted file mode 100644 index 4e7b60b..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/nojang/client/multiplayer/BridgedClientLevel.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.hypherionmc.craterlib.nojang.client.multiplayer; - -import com.hypherionmc.craterlib.nojang.core.BridgedBlockPos; -import com.hypherionmc.craterlib.nojang.resources.ResourceIdentifier; -import com.hypherionmc.craterlib.utils.ChatUtils; -import lombok.RequiredArgsConstructor; -import net.kyori.adventure.text.Component; -import net.minecraft.client.multiplayer.ClientLevel; -import org.jetbrains.annotations.Nullable; - -import java.util.concurrent.atomic.AtomicReference; - -@RequiredArgsConstructor(staticName = "of") -public class BridgedClientLevel { - - private final ClientLevel internal; - - public boolean isClientSide() { - return internal.isClientSide(); - } - - public long getGameTime() { - return internal.getGameTime(); - } - - public long getDayTime() { - return internal.getDayTime(); - } - - public long dayTime() { - return internal.dayTime(); - } - - public boolean isRaining() { - return internal.isRaining(); - } - - public boolean isThundering() { - return internal.isThundering(); - } - - @Nullable - public ResourceIdentifier getDimensionKey() { - return ResourceIdentifier.fromMojang(internal.dimension().location()); - } - - @Nullable - public ResourceIdentifier getBiomeIdentifier(BridgedBlockPos onPos) { - AtomicReference identifier = new AtomicReference<>(null); - internal.getBiome(onPos.toMojang()).unwrap().ifLeft(b -> identifier.set(ResourceIdentifier.fromMojang(b.location()))); - return identifier.get(); - } - - @Nullable - public Component getDifficulty() { - return ChatUtils.mojangToAdventure(internal.getDifficulty().getDisplayName()); - } - -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/nojang/client/multiplayer/BridgedServerData.java b/Common/src/main/java/com/hypherionmc/craterlib/nojang/client/multiplayer/BridgedServerData.java deleted file mode 100644 index 8a2a5a0..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/nojang/client/multiplayer/BridgedServerData.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.hypherionmc.craterlib.nojang.client.multiplayer; - -import com.hypherionmc.craterlib.utils.ChatUtils; -import lombok.RequiredArgsConstructor; -import net.kyori.adventure.text.Component; -import net.minecraft.client.multiplayer.ServerData; -import net.minecraft.client.multiplayer.ServerStatusPinger; - -@RequiredArgsConstructor(staticName = "of") -public class BridgedServerData { - - private final ServerData internal; - - public String name() { - return internal.name; - } - - public String ip() { - return internal.ip; - } - - public Component motd() { - return ChatUtils.mojangToAdventure(internal.motd); - } - - public int getMaxPlayers() { - if (internal.players == null) { - try { - new ServerStatusPinger().pingServer(internal, () -> {}, () -> {}); - } catch (Exception ignored) {} - } - - return internal.players == null ? 0 : internal.players.max(); - } - - public ServerData toMojang() { - return internal; - } - -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/nojang/client/server/BridgedIntegratedServer.java b/Common/src/main/java/com/hypherionmc/craterlib/nojang/client/server/BridgedIntegratedServer.java deleted file mode 100644 index 0ecacaf..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/nojang/client/server/BridgedIntegratedServer.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.hypherionmc.craterlib.nojang.client.server; - -import lombok.RequiredArgsConstructor; -import net.minecraft.client.server.IntegratedServer; - -@RequiredArgsConstructor(staticName = "of") -public class BridgedIntegratedServer { - - private final IntegratedServer internal; - - public String getLevelName() { - return internal.getWorldData().getLevelName(); - } - - public IntegratedServer toMojang() { - return internal; - } - -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/BridgedCommandSourceStack.java b/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/BridgedCommandSourceStack.java deleted file mode 100644 index 5a15402..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/BridgedCommandSourceStack.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.hypherionmc.craterlib.nojang.commands; - -import com.hypherionmc.craterlib.utils.ChatUtils; -import lombok.RequiredArgsConstructor; -import net.kyori.adventure.text.Component; -import net.minecraft.commands.CommandSourceStack; - -import java.util.function.Supplier; - -@RequiredArgsConstructor(staticName = "of") -public class BridgedCommandSourceStack { - - private final CommandSourceStack internal; - - public void sendSuccess(Supplier supplier, boolean bl) { - internal.sendSuccess(() -> ChatUtils.adventureToMojang(supplier.get()), bl); - } - - public CommandSourceStack toMojang() { - return internal; - } -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/BridgedFakePlayer.java b/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/BridgedFakePlayer.java deleted file mode 100644 index 42b65cb..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/BridgedFakePlayer.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.hypherionmc.craterlib.nojang.commands; - -import com.hypherionmc.craterlib.nojang.server.BridgedMinecraftServer; -import com.hypherionmc.craterlib.utils.ChatUtils; -import net.minecraft.commands.CommandSource; -import net.minecraft.commands.CommandSourceStack; -import net.minecraft.network.chat.Component; -import net.minecraft.server.MinecraftServer; -import net.minecraft.world.phys.Vec2; -import net.minecraft.world.phys.Vec3; - -import java.util.function.BiConsumer; -import java.util.function.Consumer; -import java.util.function.Supplier; - -public abstract class BridgedFakePlayer { - - final MojangBridge internal; - - public BridgedFakePlayer(BridgedMinecraftServer server, int perm, String name) { - internal = new MojangBridge(server.toMojang(), perm, name, this::onSuccess, this::onError); - } - - public abstract void onSuccess(Supplier supplier, Boolean aBoolean); - - public void onError(net.kyori.adventure.text.Component component) { - this.onSuccess(() -> component, false); - } - - public CommandSourceStack toMojang() { - return internal; - } - - static class MojangBridge extends CommandSourceStack { - - private final BiConsumer, Boolean> successCallback; - public final Consumer errorCallback; - - MojangBridge(MinecraftServer server, int perm, String name, BiConsumer, Boolean> successCallback, Consumer errorCallback) { - super(CommandSource.NULL, Vec3.ZERO, Vec2.ZERO, server.overworld(), perm, name, Component.literal(name), server, null); - this.successCallback = successCallback; - this.errorCallback = errorCallback; - } - - @Override - public void sendSuccess(Supplier supplier, boolean bl) { - successCallback.accept(() -> ChatUtils.mojangToAdventure(supplier.get()), bl); - } - - @Override - public void sendFailure(Component arg) { - errorCallback.accept(ChatUtils.mojangToAdventure(arg)); - } - } -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/CommandsRegistry.java b/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/CommandsRegistry.java deleted file mode 100644 index 3244a93..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/CommandsRegistry.java +++ /dev/null @@ -1,85 +0,0 @@ -package com.hypherionmc.craterlib.nojang.commands; - -import com.hypherionmc.craterlib.api.commands.CraterCommand; -import com.hypherionmc.craterlib.nojang.authlib.BridgedGameProfile; -import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer; -import com.mojang.authlib.GameProfile; -import com.mojang.brigadier.CommandDispatcher; -import com.mojang.brigadier.builder.LiteralArgumentBuilder; -import lombok.AccessLevel; -import lombok.NoArgsConstructor; -import net.minecraft.commands.CommandSourceStack; -import net.minecraft.commands.Commands; -import net.minecraft.commands.arguments.GameProfileArgument; -import org.apache.commons.lang3.function.TriConsumer; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -@NoArgsConstructor(access = AccessLevel.PRIVATE) -public class CommandsRegistry { - - public static final CommandsRegistry INSTANCE = new CommandsRegistry(); - - private final List commands = new ArrayList<>(); - - public void registerCommand(CraterCommand cmd) { - commands.add(cmd); - } - - public void registerCommands(CommandDispatcher stack) { - commands.forEach(cmd -> { - if (cmd.hasArguments()) { - CommandWithArguments.register(cmd, stack); - } else { - CommandWithoutArguments.register(cmd, stack); - } - }); - } - - static class CommandWithoutArguments { - - public static void register(CraterCommand cmd, CommandDispatcher dispatcher) { - LiteralArgumentBuilder command = Commands.literal(cmd.getCommandName()) - .requires(source -> source.hasPermission(cmd.getPermissionLevel())) - .executes(context -> { - cmd.getExecutor().accept(BridgedCommandSourceStack.of(context.getSource())); - return 1; - }); - - dispatcher.register(command); - } - - } - - @SuppressWarnings("unchecked") - static class CommandWithArguments { - - public static void register(CraterCommand cmd, CommandDispatcher dispatcher) { - LiteralArgumentBuilder command = Commands.literal(cmd.getCommandName()) - .requires(source -> source.hasPermission(cmd.getPermissionLevel())); - - cmd.getArguments().forEach((key, pair) -> command.then(Commands.argument(key, pair.getLeft()).executes(context -> { - - // This is FUCKING UGLY.... Need to improve this in the future - if (pair.getLeft() instanceof GameProfileArgument) { - Collection profiles = GameProfileArgument.getGameProfiles(context, key); - List bridgedGameProfiles = new ArrayList<>(); - - profiles.forEach(p -> bridgedGameProfiles.add(BridgedGameProfile.of(p))); - - ((TriConsumer, BridgedCommandSourceStack>) pair.getRight()) - .accept(BridgedPlayer.of(context.getSource().getPlayer()), bridgedGameProfiles, BridgedCommandSourceStack.of(context.getSource())); - return 1; - } - - return 1; - }))); - - dispatcher.register(command); - } - - } - -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/nojang/core/BridgedBlockPos.java b/Common/src/main/java/com/hypherionmc/craterlib/nojang/core/BridgedBlockPos.java deleted file mode 100644 index bd49e2c..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/nojang/core/BridgedBlockPos.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.hypherionmc.craterlib.nojang.core; - -import lombok.RequiredArgsConstructor; -import net.minecraft.core.BlockPos; - -@RequiredArgsConstructor(staticName = "of") -public class BridgedBlockPos { - - private final BlockPos internal; - - public int getX() { - return internal.getX(); - } - - public int getY() { - return internal.getY(); - } - - public int getZ() { - return internal.getZ(); - } - - public BlockPos toMojang() { - return internal; - } - -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/nojang/nbt/BridgedCompoundTag.java b/Common/src/main/java/com/hypherionmc/craterlib/nojang/nbt/BridgedCompoundTag.java deleted file mode 100644 index 17a2d04..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/nojang/nbt/BridgedCompoundTag.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.hypherionmc.craterlib.nojang.nbt; - -import lombok.RequiredArgsConstructor; -import net.minecraft.nbt.CompoundTag; - -import java.util.Set; - -@RequiredArgsConstructor(staticName = "of") -public class BridgedCompoundTag { - - private final CompoundTag internal; - - public static BridgedCompoundTag empty() { - return new BridgedCompoundTag(new CompoundTag()); - } - - public BridgedCompoundTag getCompound(String key) { - return BridgedCompoundTag.of(internal.getCompound(key)); - } - - public Set getAllKeys() { - return internal.getAllKeys(); - } - - public String getString(String key) { - return internal.getString(key); - } - - public boolean getBoolean(String key) { - return internal.getBoolean(key); - } - - public void putString(String key, String value) { - internal.putString(key, value); - } - - public void put(String key, BridgedCompoundTag value) { - internal.put(key, value.toMojang()); - } - - public void putBoolean(String key, boolean value) { - internal.putBoolean(key, value); - } - - public CompoundTag toMojang() { - return internal; - } - -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/nojang/network/BridgedFriendlyByteBuf.java b/Common/src/main/java/com/hypherionmc/craterlib/nojang/network/BridgedFriendlyByteBuf.java deleted file mode 100644 index a7bafd0..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/nojang/network/BridgedFriendlyByteBuf.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.hypherionmc.craterlib.nojang.network; - -import com.hypherionmc.craterlib.nojang.nbt.BridgedCompoundTag; -import lombok.RequiredArgsConstructor; -import net.minecraft.network.FriendlyByteBuf; - -@RequiredArgsConstructor(staticName = "of") -public class BridgedFriendlyByteBuf { - - private final FriendlyByteBuf internal; - - public BridgedCompoundTag readNbt() { - return BridgedCompoundTag.of(internal.readNbt()); - } - - public BridgedFriendlyByteBuf writeNbt(BridgedCompoundTag tag) { - internal.writeNbt(tag.toMojang()); - return BridgedFriendlyByteBuf.of(internal); - } - - public BridgedFriendlyByteBuf writeUtf(String value) { - internal.writeUtf(value); - return BridgedFriendlyByteBuf.of(internal); - } - - public String readUtf() { - return internal.readUtf(); - } - - public FriendlyByteBuf toMojang() { - return internal; - } - -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/nojang/package-info.java b/Common/src/main/java/com/hypherionmc/craterlib/nojang/package-info.java deleted file mode 100644 index 4c177a5..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/nojang/package-info.java +++ /dev/null @@ -1,9 +0,0 @@ -/** - * @author HypherionSA - * This package, called NoJang, exposes various wrapped API's. - * Using this api, a mod can essentially run on ANY minecraft version this library - * supports, from one code base. - * IMPORTANT NOTE: THESE API'S MUST NEVER EXPOSE ANY MINECRAFT CLASSES OR CODE!!!! - * THEY MUST ALWAYS BE HANDLED INTERNALLY AND ONLY RETURN WRAPPED VARIANTS - */ -package com.hypherionmc.craterlib.nojang; \ No newline at end of file diff --git a/Common/src/main/java/com/hypherionmc/craterlib/nojang/realmsclient/dto/BridgedRealmsServer.java b/Common/src/main/java/com/hypherionmc/craterlib/nojang/realmsclient/dto/BridgedRealmsServer.java deleted file mode 100644 index dddf746..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/nojang/realmsclient/dto/BridgedRealmsServer.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.hypherionmc.craterlib.nojang.realmsclient.dto; - -import com.mojang.realmsclient.dto.PlayerInfo; -import com.mojang.realmsclient.dto.RealmsServer; -import lombok.RequiredArgsConstructor; - -@RequiredArgsConstructor(staticName = "of") -public class BridgedRealmsServer { - - private final RealmsServer internal; - - public String getName() { - return internal.getName(); - } - - public String getDescription() { - return internal.getDescription(); - } - - public String getWorldType() { - return internal.worldType.name(); - } - - public String getMinigameName() { - return internal.getMinigameName(); - } - - public String getMinigameImage() { - return internal.minigameImage; - } - - public long getPlayerCount() { - return internal.players.stream().filter(PlayerInfo::getOnline).count(); - } - - public RealmsServer toMojang() { - return internal; - } - -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/nojang/resources/ResourceIdentifier.java b/Common/src/main/java/com/hypherionmc/craterlib/nojang/resources/ResourceIdentifier.java deleted file mode 100644 index 9b848f4..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/nojang/resources/ResourceIdentifier.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.hypherionmc.craterlib.nojang.resources; - -import net.minecraft.resources.ResourceLocation; - -public class ResourceIdentifier { - - private final ResourceLocation internal; - - public ResourceIdentifier(String namespace, String path) { - this.internal = new ResourceLocation(namespace, path); - } - - public ResourceIdentifier(String path) { - this.internal = new ResourceLocation(path); - } - - public String getNamespace() { - return internal.getNamespace(); - } - - public String getPath() { - return internal.getPath(); - } - - public String getString() { - return internal.toString(); - } - - public static ResourceIdentifier fromMojang(ResourceLocation location) { - return new ResourceIdentifier(location.getNamespace(), location.getPath()); - } - - public ResourceLocation toMojang() { - return internal; - } -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/nojang/server/BridgedMinecraftServer.java b/Common/src/main/java/com/hypherionmc/craterlib/nojang/server/BridgedMinecraftServer.java deleted file mode 100644 index cb818b7..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/nojang/server/BridgedMinecraftServer.java +++ /dev/null @@ -1,91 +0,0 @@ -package com.hypherionmc.craterlib.nojang.server; - -import com.hypherionmc.craterlib.nojang.authlib.BridgedGameProfile; -import com.hypherionmc.craterlib.nojang.commands.BridgedFakePlayer; -import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer; -import com.hypherionmc.craterlib.utils.ChatUtils; -import lombok.RequiredArgsConstructor; -import net.kyori.adventure.text.Component; -import net.minecraft.SharedConstants; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.players.UserBanListEntry; -import net.minecraft.server.players.UserWhiteListEntry; - -import java.util.ArrayList; -import java.util.List; - -@RequiredArgsConstructor(staticName = "of") -public class BridgedMinecraftServer { - - private final MinecraftServer internal; - - public boolean isUsingWhitelist() { - return internal.getPlayerList().isUsingWhitelist(); - } - - public int getPlayerCount() { - return internal.getPlayerList().getPlayerCount(); - } - - public int getMaxPlayers() { - return internal.getPlayerList().getMaxPlayers(); - } - - public String getServerModName() { - return internal.getServerModName(); - } - - public String getName() { - return SharedConstants.getCurrentVersion().getName(); - } - - public boolean usesAuthentication() { - return internal.usesAuthentication(); - } - - public void broadcastSystemMessage(Component text, boolean bl) { - internal.getPlayerList().broadcastSystemMessage(ChatUtils.adventureToMojang(text), bl); - } - - public boolean isPlayerBanned(BridgedGameProfile profile) { - return internal.getPlayerList().getBans().isBanned(profile.toMojang()); - } - - public void whitelistPlayer(BridgedGameProfile gameProfile) { - if (!internal.getPlayerList().isUsingWhitelist()) - return; - - internal.getPlayerList().getWhiteList().add(new UserWhiteListEntry(gameProfile.toMojang())); - } - - public void unWhitelistPlayer(BridgedGameProfile gameProfile) { - if (!internal.getPlayerList().isUsingWhitelist()) - return; - - internal.getPlayerList().getWhiteList().remove(new UserWhiteListEntry(gameProfile.toMojang())); - } - - public List getPlayers() { - List profiles = new ArrayList<>(); - - if (internal.getPlayerList() == null) - return profiles; - - internal.getPlayerList().getPlayers().forEach(p -> profiles.add(BridgedPlayer.of(p))); - - return profiles; - } - - public void banPlayer(BridgedGameProfile profile) { - internal.getPlayerList().getBans().add(new UserBanListEntry(profile.toMojang())); - } - - public void executeCommand(BridgedMinecraftServer server, BridgedFakePlayer player, String command) { - internal.getCommands().performPrefixedCommand(player.toMojang(), command); - } - - public MinecraftServer toMojang() { - return internal; - } - -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/nojang/world/entity/player/BridgedPlayer.java b/Common/src/main/java/com/hypherionmc/craterlib/nojang/world/entity/player/BridgedPlayer.java deleted file mode 100644 index 8aa6d49..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/nojang/world/entity/player/BridgedPlayer.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.hypherionmc.craterlib.nojang.world.entity.player; - -import com.hypherionmc.craterlib.nojang.authlib.BridgedGameProfile; -import com.hypherionmc.craterlib.nojang.core.BridgedBlockPos; -import com.hypherionmc.craterlib.utils.ChatUtils; -import lombok.RequiredArgsConstructor; -import net.kyori.adventure.text.Component; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.server.network.ServerGamePacketListenerImpl; -import net.minecraft.world.entity.player.Player; -import org.jetbrains.annotations.Nullable; - -import java.util.UUID; - -@RequiredArgsConstructor(staticName = "of") -public class BridgedPlayer { - - private final Player internal; - - public Component getDisplayName() { - return ChatUtils.mojangToAdventure(internal.getDisplayName()); - } - - public Component getName() { - return ChatUtils.mojangToAdventure(internal.getName()); - } - - public UUID getUUID() { - return internal.getUUID(); - } - - public String getStringUUID() { - return internal.getStringUUID(); - } - - public BridgedGameProfile getGameProfile() { - return BridgedGameProfile.of(internal.getGameProfile()); - } - - public boolean isServerPlayer() { - return internal instanceof ServerPlayer; - } - - public Player toMojang() { - return internal; - } - - public BridgedBlockPos getOnPos() { - return BridgedBlockPos.of(internal.getOnPos()); - } - - @Nullable - public ServerGamePacketListenerImpl getConnection() { - if (isServerPlayer()) { - return ((ServerPlayer) internal).connection; - } - return null; - } - - public ServerPlayer toMojangServerPlayer() { - return (ServerPlayer) internal; - } -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/utils/ChatUtils.java b/Common/src/main/java/com/hypherionmc/craterlib/utils/ChatUtils.java deleted file mode 100644 index b6c6cc3..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/utils/ChatUtils.java +++ /dev/null @@ -1,90 +0,0 @@ -package com.hypherionmc.craterlib.utils; - -import com.hypherionmc.craterlib.nojang.resources.ResourceIdentifier; -import me.hypherionmc.mcdiscordformatter.discord.DiscordSerializer; -import me.hypherionmc.mcdiscordformatter.minecraft.MinecraftSerializer; -import net.kyori.adventure.text.format.NamedTextColor; -import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; -import net.minecraft.ChatFormatting; -import net.minecraft.Util; -import net.minecraft.core.RegistryAccess; -import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.Style; - -public class ChatUtils { - - public static Component adventureToMojang(net.kyori.adventure.text.Component inComponent) { - final String serialised = GsonComponentSerializer.gson().serialize(inComponent); - return Component.Serializer.fromJson(serialised, RegistryAccess.EMPTY); - } - - public static net.kyori.adventure.text.Component mojangToAdventure(Component inComponent) { - final String serialised = Component.Serializer.toJson(inComponent, RegistryAccess.EMPTY); - return GsonComponentSerializer.gson().deserialize(serialised); - } - - // Some text components contain duplicate text, resulting in duplicate messages - // sent back to discord. This should help fix those issues - public static Component safeCopy(Component inComponent) { - String value = inComponent.getString(); - Style style = inComponent.getStyle(); - return Component.literal(value).withStyle(style); - } - - public static String strip(String inString, String... toStrip) { - String finalString = inString; - - for (String strip : toStrip) { - if (finalString.startsWith(strip)) - finalString = finalString.replaceFirst(strip, ""); - - if (finalString.startsWith(" ")) - finalString = finalString.replaceFirst(" ", ""); - } - - return finalString; - } - - public static String resolve(net.kyori.adventure.text.Component component, boolean formatted) { - Component c = adventureToMojang(component); - String returnVal = ChatFormatting.stripFormatting(c.getString()); - - if (formatted) { - returnVal = DiscordSerializer.INSTANCE.serialize(safeCopy(c).copy()); - } - - return returnVal; - } - - public static net.kyori.adventure.text.Component resolve(String component, boolean formatted) { - Component returnVal = Component.literal(component); - if (formatted) { - returnVal = MinecraftSerializer.INSTANCE.serialize(component); - } - - return mojangToAdventure(returnVal); - } - - public static net.kyori.adventure.text.Component getTooltipTitle(String key) { - return net.kyori.adventure.text.Component.text(NamedTextColor.YELLOW + net.kyori.adventure.text.Component.translatable(key).key()); - } - - public static String resolveTranslation(String key) { - return net.kyori.adventure.text.Component.translatable(key).key(); - } - - public static net.kyori.adventure.text.Component getTranslation(String key) { - return net.kyori.adventure.text.Component.translatable(key); - } - - public static net.kyori.adventure.text.Component makeComponent(String text) { - return net.kyori.adventure.text.Component.translatable(text); - } - - public static net.kyori.adventure.text.Component getBiomeName(ResourceIdentifier identifier) { - if (identifier == null) - return net.kyori.adventure.text.Component.text("Unknown"); - - return mojangToAdventure(Component.translatable(Util.makeDescriptionId("biome", identifier.toMojang()))); - } -} diff --git a/Common/src/main/java/com/hypherionmc/craterlib/utils/InternalServiceUtil.java b/Common/src/main/java/com/hypherionmc/craterlib/utils/InternalServiceUtil.java deleted file mode 100644 index 2305d14..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/utils/InternalServiceUtil.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.hypherionmc.craterlib.utils; - -import com.hypherionmc.craterlib.CraterConstants; - -import java.util.ServiceLoader; - -/** - * @author HypherionSA - * Utility class to handle SPI loading - */ -public class InternalServiceUtil { - - /** - * Try to load a service - * - * @param clazz The service class type to load - * @return The loaded class - */ - public static T load(Class clazz) { - final T loadedService = ServiceLoader.load(clazz) - .findFirst() - .orElseThrow(() -> new NullPointerException("Failed to load service for " + clazz.getName())); - CraterConstants.LOG.debug("Loaded {} for service {}", loadedService, clazz); - return loadedService; - } - -} \ No newline at end of file diff --git a/Common/src/main/java/com/hypherionmc/craterlib/utils/OptifineUtils.java b/Common/src/main/java/com/hypherionmc/craterlib/utils/OptifineUtils.java deleted file mode 100644 index 8a06da2..0000000 --- a/Common/src/main/java/com/hypherionmc/craterlib/utils/OptifineUtils.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.hypherionmc.craterlib.utils; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -/** - * @author HypherionSA - * Utility class for Optifine compatibility - */ -public class OptifineUtils { - - private static final boolean hasOptifine = checkOptifine(); - - private static boolean checkOptifine() { - try { - Class ofConfigClass = Class.forName("net.optifine.Config"); - return true; - } catch (ClassNotFoundException e) { - // Optifine is probably not present. Ignore the error - return false; - } catch (Exception e) { - e.printStackTrace(); - } - return false; - } - - public static boolean isRenderRegions() { - try { - Class ofConfigClass = Class.forName("net.optifine.Config"); - Method rrField = ofConfigClass.getMethod("isRenderRegions"); - return (boolean) rrField.invoke(null); - } catch (ClassNotFoundException | InvocationTargetException | NoSuchMethodException | - IllegalAccessException e) { - // Optifine is probably not present. Ignore the error - return false; - } catch (Exception e) { - e.printStackTrace(); - } - return false; - } - - public static boolean hasOptifine() { - return hasOptifine; - } - -} \ No newline at end of file diff --git a/Common/src/main/resources/assets/craterlib/lang/en_us.json b/Common/src/main/resources/assets/craterlib/lang/en_us.json deleted file mode 100644 index 03115d9..0000000 --- a/Common/src/main/resources/assets/craterlib/lang/en_us.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "t.clc.opensubconfig": "Open Config", - "t.clc.save": "Save", - "t.clc.cancel_discard": "Discard", - "t.clc.quit_config": "Unsaved Changes", - "t.clc.quit_config_sure": "You have unsaved config changes. Are you sure you want to discard them?", - "t.clc.quit_discard": "Quit & Discard" -} diff --git a/Common/src/main/resources/craterlib.mixins.json b/Common/src/main/resources/craterlib.mixins.json deleted file mode 100644 index 1a739db..0000000 --- a/Common/src/main/resources/craterlib.mixins.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "required": true, - "minVersion": "0.8", - "package": "com.hypherionmc.craterlib.mixin", - "compatibilityLevel": "JAVA_17", - "mixins": [ - ], - "client": [ - "ChatInputSuggestorMixin", - "events.PlayerMixin", - "events.client.ClientLevelMixin", - "events.client.MinecraftMixin", - "events.client.RealmsMainScreenMixin" - ], - "server": [ - "events.CommandMixin", - "events.PlayerAdvancementsMixin", - "events.PlayerListMixin", - "events.ServerPlayerMixin" - ], - "injectors": { - "defaultRequire": 1 - } -} diff --git a/Common/src/main/resources/pack.mcmeta b/Common/src/main/resources/pack.mcmeta deleted file mode 100644 index 263d366..0000000 --- a/Common/src/main/resources/pack.mcmeta +++ /dev/null @@ -1,6 +0,0 @@ -{ - "pack": { - "description": "${mod_name}", - "pack_format": 18 - } -} diff --git a/Fabric/build.gradle b/Fabric/build.gradle deleted file mode 100644 index 4badf5c..0000000 --- a/Fabric/build.gradle +++ /dev/null @@ -1,126 +0,0 @@ -archivesBaseName = "${mod_name.replace(" ", "")}-Fabric-${minecraft_version}" - -dependencies { - // Core - modImplementation "net.fabricmc.fabric-api:fabric-api:${fabric_api}" - - // Compat - modImplementation("com.terraformersmc:modmenu:${mod_menu_version}") { - exclude(group: "net.fabricmc.fabric-api") - } - - modImplementation "maven.modrinth:fabrictailor:${fabrictailor}" - modImplementation "maven.modrinth:vanish:${vanish}" - - // Do not edit or remove - implementation project(":Common") -} - -shadowJar { - from sourceSets.main.output - configurations = [project.configurations.shade] - - dependencies { - exclude(dependency('com.google.code.gson:.*')) - - relocate 'me.hypherionmc.moonconfig', 'shadow.hypherionmc.moonconfig' - relocate 'me.hypherionmc.mcdiscordformatter', 'shadow.hypherionmc.mcdiscordformatter' - relocate 'net.kyori', 'shadow.kyori' - } - - setArchiveClassifier('dev-shadow') -} - -/** - * =============================================================================== - * = DO NOT EDIT BELOW THIS LINE UNLESS YOU KNOW WHAT YOU ARE DOING = - * =============================================================================== - */ - -unimined.minecraft { - fabric { - loader fabric_loader - } -} - -remapJar { - inputFile.set shadowJar.archiveFile - dependsOn shadowJar - archiveClassifier.set null -} - -jar { - archiveClassifier.set "dev" -} - -processResources { - from project(":Common").sourceSets.main.resources - def buildProps = project.properties.clone() - - filesMatching(['fabric.mod.json']) { - expand buildProps - } -} - -compileTestJava.enabled = false - -tasks.withType(JavaCompile).configureEach { - source(project(":Common").sourceSets.main.allSource) -} - -/** - * Publishing Config - */ -publishing { - publications { - mavenJava(MavenPublication) { - artifactId project.archivesBaseName - from components.java - - artifact(remapJar) { - builtBy remapJar - } - - pom.withXml { - Node pomNode = asNode() - pomNode.dependencies.'*'.findAll() { - it.artifactId.text() == 'regutils-joined-fabric' || - it.artifactId.text() == 'core' || - it.artifactId.text() == 'toml' - }.each() { - it.parent().remove(it) - } - } - } - } - - repositories { - maven rootProject.orion.getPublishingMaven() - } -} - -publisher { - apiKeys { - modrinth(System.getenv("MODRINTH_TOKEN")) - curseforge(System.getenv("CURSE_TOKEN")) - } - - setCurseID(curse_id) - setModrinthID(modrinth_id) - setVersionType("release") - setChangelog("https://raw.githubusercontent.com/hypherionmc/changelogs/main/craterlib/changelog-fabric.md") - setProjectVersion("${minecraft_version}-${project.version}") - setDisplayName("[FABRIC/QUILT 1.20.6] CraterLib - ${project.version}") - setGameVersions("1.20.6") - setLoaders("fabric", "quilt") - setArtifact(remapJar) - setCurseEnvironment("both") - - modrinthDepends { - required("fabric-api") - } - - curseDepends { - required("fabric-api") - } -} \ No newline at end of file diff --git a/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibInitializer.java b/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibInitializer.java deleted file mode 100644 index c66c210..0000000 --- a/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibInitializer.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.hypherionmc.craterlib; - -import com.hypherionmc.craterlib.api.events.server.CraterRegisterCommandEvent; -import com.hypherionmc.craterlib.api.events.server.CraterServerLifecycleEvent; -import com.hypherionmc.craterlib.common.FabricCommonPlatform; -import com.hypherionmc.craterlib.compat.Vanish; -import com.hypherionmc.craterlib.core.event.CraterEventBus; -import com.hypherionmc.craterlib.core.networking.CraterPacketNetwork; -import com.hypherionmc.craterlib.core.networking.data.PacketSide; -import com.hypherionmc.craterlib.core.platform.ModloaderEnvironment; -import com.hypherionmc.craterlib.network.CraterFabricNetworkHandler; -import com.hypherionmc.craterlib.nojang.commands.CommandsRegistry; -import com.hypherionmc.craterlib.nojang.server.BridgedMinecraftServer; -import net.fabricmc.api.ModInitializer; -import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; -import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; - -public class CraterLibInitializer implements ModInitializer { - - @Override - public void onInitialize() { - new CraterPacketNetwork(new CraterFabricNetworkHandler(PacketSide.SERVER)); - CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> { - CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent()); - CommandsRegistry.INSTANCE.registerCommands(dispatcher); - }); - - - ServerLifecycleEvents.SERVER_STARTING.register(server -> { - FabricCommonPlatform.server = server; - CraterEventBus.INSTANCE.postEvent(new CraterServerLifecycleEvent.Starting(BridgedMinecraftServer.of(server))); - }); - - ServerLifecycleEvents.SERVER_STARTED.register(li -> CraterEventBus.INSTANCE.postEvent(new CraterServerLifecycleEvent.Started(BridgedMinecraftServer.of(li)))); - ServerLifecycleEvents.SERVER_STOPPING.register(server -> CraterEventBus.INSTANCE.postEvent(new CraterServerLifecycleEvent.Stopping(BridgedMinecraftServer.of(server)))); - ServerLifecycleEvents.SERVER_STOPPED.register(server -> CraterEventBus.INSTANCE.postEvent(new CraterServerLifecycleEvent.Stopped(BridgedMinecraftServer.of(server)))); - - if (ModloaderEnvironment.INSTANCE.isModLoaded("melius-vanish")) { - Vanish.register(); - } - } -} diff --git a/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibModMenuIntegration.java b/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibModMenuIntegration.java deleted file mode 100644 index 6615352..0000000 --- a/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibModMenuIntegration.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.hypherionmc.craterlib; - -import com.hypherionmc.craterlib.client.gui.config.CraterConfigScreen; -import com.hypherionmc.craterlib.core.config.ConfigController; -import com.hypherionmc.craterlib.core.config.ModuleConfig; -import com.hypherionmc.craterlib.core.config.annotations.NoConfigScreen; -import com.terraformersmc.modmenu.api.ConfigScreenFactory; -import com.terraformersmc.modmenu.api.ModMenuApi; - -import java.util.HashMap; -import java.util.Map; - -/** - * @author HypherionSA - */ -public class CraterLibModMenuIntegration implements ModMenuApi { - - @Override - public Map> getProvidedConfigScreenFactories() { - Map> configScreens = new HashMap<>(); - - ConfigController.getMonitoredConfigs().forEach((conf, watcher) -> { - if (!conf.getClass().isAnnotationPresent(NoConfigScreen.class)) { - configScreens.put(((ModuleConfig) conf).getModId(), screen -> new CraterConfigScreen((ModuleConfig) conf, screen)); - } - }); - - return configScreens; - } -} diff --git a/Fabric/src/main/java/com/hypherionmc/craterlib/client/CraterLibClientInitializer.java b/Fabric/src/main/java/com/hypherionmc/craterlib/client/CraterLibClientInitializer.java deleted file mode 100644 index b5ec5b1..0000000 --- a/Fabric/src/main/java/com/hypherionmc/craterlib/client/CraterLibClientInitializer.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.hypherionmc.craterlib.client; - -import com.hypherionmc.craterlib.api.events.client.CraterClientTickEvent; -import com.hypherionmc.craterlib.core.event.CraterEventBus; -import com.hypherionmc.craterlib.core.networking.CraterPacketNetwork; -import com.hypherionmc.craterlib.core.networking.data.PacketSide; -import com.hypherionmc.craterlib.network.CraterFabricNetworkHandler; -import com.hypherionmc.craterlib.nojang.client.multiplayer.BridgedClientLevel; -import net.fabricmc.api.ClientModInitializer; -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; - -public class CraterLibClientInitializer implements ClientModInitializer { - - @Override - public void onInitializeClient() { - new CraterPacketNetwork(new CraterFabricNetworkHandler(PacketSide.CLIENT)); - ClientTickEvents.START_CLIENT_TICK.register((listener) -> { - if (listener.level == null) - return; - - CraterClientTickEvent event = new CraterClientTickEvent(BridgedClientLevel.of(listener.level)); - CraterEventBus.INSTANCE.postEvent(event); - }); - - CraterEventBus.INSTANCE.registerEventListener(CraterLibClientInitializer.class); - } -} diff --git a/Fabric/src/main/java/com/hypherionmc/craterlib/client/FabricClientPlatform.java b/Fabric/src/main/java/com/hypherionmc/craterlib/client/FabricClientPlatform.java deleted file mode 100644 index 7852f12..0000000 --- a/Fabric/src/main/java/com/hypherionmc/craterlib/client/FabricClientPlatform.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.hypherionmc.craterlib.client; - -import com.hypherionmc.craterlib.core.platform.ClientPlatform; -import com.hypherionmc.craterlib.nojang.client.BridgedMinecraft; -import com.hypherionmc.craterlib.nojang.client.multiplayer.BridgedClientLevel; -import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer; -import net.minecraft.client.Minecraft; -import net.minecraft.network.Connection; - -/** - * @author HypherionSA - */ -public class FabricClientPlatform implements ClientPlatform { - - @Override - public BridgedMinecraft getClientInstance() { - return new BridgedMinecraft(); - } - - @Override - public BridgedPlayer getClientPlayer() { - return BridgedPlayer.of(Minecraft.getInstance().player); - } - - @Override - public BridgedClientLevel getClientLevel() { - return BridgedClientLevel.of(Minecraft.getInstance().level); - } - - @Override - public Connection getClientConnection() { - return Minecraft.getInstance().getConnection().getConnection(); - } -} diff --git a/Fabric/src/main/java/com/hypherionmc/craterlib/common/FabricCommonPlatform.java b/Fabric/src/main/java/com/hypherionmc/craterlib/common/FabricCommonPlatform.java deleted file mode 100644 index c1a30c7..0000000 --- a/Fabric/src/main/java/com/hypherionmc/craterlib/common/FabricCommonPlatform.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.hypherionmc.craterlib.common; - -import com.hypherionmc.craterlib.core.platform.CommonPlatform; -import com.hypherionmc.craterlib.nojang.server.BridgedMinecraftServer; -import net.minecraft.server.MinecraftServer; - -/** - * @author HypherionSA - */ -public class FabricCommonPlatform implements CommonPlatform { - - public static MinecraftServer server; - - @Override - public BridgedMinecraftServer getMCServer() { - return BridgedMinecraftServer.of(server); - } -} diff --git a/Fabric/src/main/java/com/hypherionmc/craterlib/common/FabricCompatHelper.java b/Fabric/src/main/java/com/hypherionmc/craterlib/common/FabricCompatHelper.java deleted file mode 100644 index dbcaf63..0000000 --- a/Fabric/src/main/java/com/hypherionmc/craterlib/common/FabricCompatHelper.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.hypherionmc.craterlib.common; - -import com.hypherionmc.craterlib.compat.FabricTailor; -import com.hypherionmc.craterlib.compat.Vanish; -import com.hypherionmc.craterlib.core.platform.CompatUtils; -import com.hypherionmc.craterlib.core.platform.ModloaderEnvironment; -import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer; - -public class FabricCompatHelper implements CompatUtils { - - @Override - public boolean isPlayerActive(BridgedPlayer player) { - if (!ModloaderEnvironment.INSTANCE.isModLoaded("melius-vanish")) - return true; - - return Vanish.isPlayerVanished(player.toMojangServerPlayer()); - } - - @Override - public String getSkinUUID(BridgedPlayer player) { - return FabricTailor.getTailorSkin(player.toMojangServerPlayer()); - } -} diff --git a/Fabric/src/main/java/com/hypherionmc/craterlib/common/FabricLoaderHelper.java b/Fabric/src/main/java/com/hypherionmc/craterlib/common/FabricLoaderHelper.java deleted file mode 100644 index 95f5c42..0000000 --- a/Fabric/src/main/java/com/hypherionmc/craterlib/common/FabricLoaderHelper.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.hypherionmc.craterlib.common; - -import com.hypherionmc.craterlib.core.platform.Environment; -import com.hypherionmc.craterlib.core.platform.ModloaderEnvironment; -import net.fabricmc.loader.api.FabricLoader; -import net.minecraft.SharedConstants; -import net.minecraft.client.Minecraft; - -import java.io.File; - -/** - * @author HypherionSA - * @date 07/08/2022 - */ -public class FabricLoaderHelper implements ModloaderEnvironment { - - @Override - public boolean isFabric() { - return true; - } - - @Override - public String getGameVersion() { - return SharedConstants.VERSION_STRING; - } - - @Override - public File getGameFolder() { - return Minecraft.getInstance().gameDirectory; - } - - @Override - public File getConfigFolder() { - return FabricLoader.getInstance().getConfigDir().toFile(); - } - - @Override - public File getModsFolder() { - return new File(FabricLoader.getInstance().getGameDir().toString() + File.separator + "mods"); - } - - @Override - public Environment getEnvironment() { - switch (FabricLoader.getInstance().getEnvironmentType()) { - case SERVER -> { - return Environment.SERVER; - } - case CLIENT -> { - return Environment.CLIENT; - } - } - return Environment.UNKNOWN; - } - - @Override - public boolean isModLoaded(String modid) { - return FabricLoader.getInstance().isModLoaded(modid); - } - - @Override - public boolean isDevEnv() { - return FabricLoader.getInstance().isDevelopmentEnvironment(); - } - - @Override - public int getModCount() { - return FabricLoader.getInstance().getAllMods().size(); - } -} diff --git a/Fabric/src/main/java/com/hypherionmc/craterlib/compat/FabricTailor.java b/Fabric/src/main/java/com/hypherionmc/craterlib/compat/FabricTailor.java deleted file mode 100644 index b95a7d7..0000000 --- a/Fabric/src/main/java/com/hypherionmc/craterlib/compat/FabricTailor.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.hypherionmc.craterlib.compat; - -import com.hypherionmc.craterlib.core.platform.ModloaderEnvironment; -import net.minecraft.server.level.ServerPlayer; -import org.samo_lego.fabrictailor.casts.TailoredPlayer; -public class FabricTailor { - - public static String getTailorSkin(ServerPlayer player) { - if (!ModloaderEnvironment.INSTANCE.isModLoaded("fabrictailor")) - return player.getStringUUID(); - - try { - if (player instanceof TailoredPlayer tp) { - return tp.getSkinId(); - } - } catch (Exception e) { - e.printStackTrace(); - } - - return player.getStringUUID(); - } - -} \ No newline at end of file diff --git a/Fabric/src/main/java/com/hypherionmc/craterlib/compat/Vanish.java b/Fabric/src/main/java/com/hypherionmc/craterlib/compat/Vanish.java deleted file mode 100644 index cc6c1e0..0000000 --- a/Fabric/src/main/java/com/hypherionmc/craterlib/compat/Vanish.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.hypherionmc.craterlib.compat; - -import com.hypherionmc.craterlib.api.events.server.CraterPlayerEvent; -import com.hypherionmc.craterlib.core.event.CraterEventBus; -import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer; -import me.drex.vanish.api.VanishAPI; -import me.drex.vanish.api.VanishEvents; -import net.minecraft.server.level.ServerPlayer; - -public class Vanish { - - public static void register() { - VanishEvents.VANISH_EVENT.register((serverPlayer, b) -> { - if (b) { - CraterEventBus.INSTANCE.postEvent(new CraterPlayerEvent.PlayerLoggedOut(BridgedPlayer.of(serverPlayer))); - } else { - CraterEventBus.INSTANCE.postEvent(new CraterPlayerEvent.PlayerLoggedIn(BridgedPlayer.of(serverPlayer))); - } - }); - } - - public static boolean isPlayerVanished(ServerPlayer player) { - return VanishAPI.isVanished(player); - } -} diff --git a/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java b/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java deleted file mode 100644 index c654433..0000000 --- a/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.hypherionmc.craterlib.mixin; - -import com.hypherionmc.craterlib.api.events.server.CraterServerChatEvent; -import com.hypherionmc.craterlib.core.event.CraterEventBus; -import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer; -import com.hypherionmc.craterlib.utils.ChatUtils; -import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.PlayerChatMessage; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.server.network.FilteredText; -import net.minecraft.server.network.ServerGamePacketListenerImpl; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(value = ServerGamePacketListenerImpl.class, priority = Integer.MIN_VALUE) -public class ServerGamePacketListenerImplMixin { - - @Shadow - public ServerPlayer player; - - @Inject( - method = "lambda$handleChat$5", - at = @At("HEAD"), - cancellable = true - ) - private void injectChatEvent(PlayerChatMessage arg, Component arg2, FilteredText arg3, CallbackInfo ci) { - CraterServerChatEvent event = new CraterServerChatEvent(BridgedPlayer.of(this.player), arg.decoratedContent().getString(), ChatUtils.mojangToAdventure(arg.decoratedContent())); - CraterEventBus.INSTANCE.postEvent(event); - if (event.wasCancelled()) - ci.cancel(); - } - -} diff --git a/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/TutorialMixin.java b/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/TutorialMixin.java deleted file mode 100644 index f9eaa50..0000000 --- a/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/TutorialMixin.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.hypherionmc.craterlib.mixin; - -import com.hypherionmc.craterlib.api.events.client.LateInitEvent; -import com.hypherionmc.craterlib.core.event.CraterEventBus; -import com.hypherionmc.craterlib.nojang.client.BridgedMinecraft; -import com.hypherionmc.craterlib.nojang.client.BridgedOptions; -import net.minecraft.client.Minecraft; -import net.minecraft.client.Options; -import net.minecraft.client.tutorial.Tutorial; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(Tutorial.class) -public class TutorialMixin { - - @Inject(method = "", at = @At("RETURN")) - private void injectEarlyInitEvent(Minecraft minecraft, Options options, CallbackInfo ci) { - LateInitEvent event = new LateInitEvent(new BridgedMinecraft(), BridgedOptions.of(options)); - CraterEventBus.INSTANCE.postEvent(event); - } - -} diff --git a/Fabric/src/main/java/com/hypherionmc/craterlib/network/CraterFabricNetworkHandler.java b/Fabric/src/main/java/com/hypherionmc/craterlib/network/CraterFabricNetworkHandler.java deleted file mode 100644 index cd8740b..0000000 --- a/Fabric/src/main/java/com/hypherionmc/craterlib/network/CraterFabricNetworkHandler.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.hypherionmc.craterlib.network; - -import com.hypherionmc.craterlib.api.networking.CommonPacketWrapper; -import com.hypherionmc.craterlib.core.networking.PacketRegistry; -import com.hypherionmc.craterlib.core.networking.data.PacketContext; -import com.hypherionmc.craterlib.core.networking.data.PacketHolder; -import com.hypherionmc.craterlib.core.networking.data.PacketSide; -import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer; -import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; -import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry; -import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; - -/** - * Based on https://github.com/mysticdrew/common-networking/tree/1.20.4 - */ -public class CraterFabricNetworkHandler extends PacketRegistry { - - public CraterFabricNetworkHandler(PacketSide side) { - super(side); - } - - protected void registerPacket(PacketHolder holder) { - try - { - PayloadTypeRegistry.playC2S().register(holder.getType(), holder.getCodec()); - PayloadTypeRegistry.playS2C().register(holder.getType(), holder.getCodec()); - } - catch (IllegalArgumentException e) - { - // do nothing - } - - if (PacketSide.CLIENT.equals(this.side)) { - ClientPlayNetworking.registerGlobalReceiver(holder.getType(), - (ClientPlayNetworking.PlayPayloadHandler>) (payload, context) -> context.client().execute(() -> - holder.handler().accept( - new PacketContext<>(payload.packet(), side)))); - } - - ServerPlayNetworking.registerGlobalReceiver(holder.getType(), - (ServerPlayNetworking.PlayPayloadHandler>) (payload, context) -> context.player().server.execute(() -> - holder.handler().accept( - new PacketContext<>(BridgedPlayer.of(context.player()), payload.packet(), side)))); - } - - public void sendToServer(T packet) { - this.sendToServer(packet, false); - } - - public void sendToServer(T packet, boolean ignoreCheck) { - PacketHolder container = (PacketHolder) PACKET_MAP.get(packet.getClass()); - - if (container != null) { - if (ignoreCheck || ClientPlayNetworking.canSend(container.type().id())) { - ClientPlayNetworking.send(new CommonPacketWrapper<>(container, packet)); - } - } - } - - public void sendToClient(T packet, BridgedPlayer player) { - PacketHolder container = (PacketHolder) PACKET_MAP.get(packet.getClass()); - if (container != null) { - if (ServerPlayNetworking.canSend(player.toMojangServerPlayer(), container.type().id())) { - ServerPlayNetworking.send(player.toMojangServerPlayer(), new CommonPacketWrapper<>(container, packet)); - } - } - } -} diff --git a/Fabric/src/main/resources/META-INF/services/com.hypherionmc.craterlib.core.platform.ClientPlatform b/Fabric/src/main/resources/META-INF/services/com.hypherionmc.craterlib.core.platform.ClientPlatform deleted file mode 100644 index a78d9e5..0000000 --- a/Fabric/src/main/resources/META-INF/services/com.hypherionmc.craterlib.core.platform.ClientPlatform +++ /dev/null @@ -1 +0,0 @@ -com.hypherionmc.craterlib.client.FabricClientPlatform diff --git a/Fabric/src/main/resources/META-INF/services/com.hypherionmc.craterlib.core.platform.CommonPlatform b/Fabric/src/main/resources/META-INF/services/com.hypherionmc.craterlib.core.platform.CommonPlatform deleted file mode 100644 index 9a2fdb0..0000000 --- a/Fabric/src/main/resources/META-INF/services/com.hypherionmc.craterlib.core.platform.CommonPlatform +++ /dev/null @@ -1 +0,0 @@ -com.hypherionmc.craterlib.common.FabricCommonPlatform diff --git a/Fabric/src/main/resources/META-INF/services/com.hypherionmc.craterlib.core.platform.CompatUtils b/Fabric/src/main/resources/META-INF/services/com.hypherionmc.craterlib.core.platform.CompatUtils deleted file mode 100644 index 62f79a8..0000000 --- a/Fabric/src/main/resources/META-INF/services/com.hypherionmc.craterlib.core.platform.CompatUtils +++ /dev/null @@ -1 +0,0 @@ -com.hypherionmc.craterlib.common.FabricCompatHelper \ No newline at end of file diff --git a/Fabric/src/main/resources/META-INF/services/com.hypherionmc.craterlib.core.platform.ModloaderEnvironment b/Fabric/src/main/resources/META-INF/services/com.hypherionmc.craterlib.core.platform.ModloaderEnvironment deleted file mode 100644 index 9a1fb33..0000000 --- a/Fabric/src/main/resources/META-INF/services/com.hypherionmc.craterlib.core.platform.ModloaderEnvironment +++ /dev/null @@ -1 +0,0 @@ -com.hypherionmc.craterlib.common.FabricLoaderHelper diff --git a/Fabric/src/main/resources/assets/craterlib/craterlib_logo.png b/Fabric/src/main/resources/assets/craterlib/craterlib_logo.png deleted file mode 100644 index ce0159cc4aa4d823ea354042e531b4522d6dfead..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49343 zcmb@t_g_=b6E}Jiib0B@BOMV0q*&-RB1P#Plq#qoph%aRpr}A77K+lP6Obysssse3 zgMfh1Aksm4PwwXPeV%*&f%}6m%sIPzW_EU`z9-tmNSE;>_eltX7_VQ`GJ_y$808;= z7CfC@eSGhPy=g3?XC2eo!GOS-@u>HT|Joj`46rOS zK9(qOTMkf;@-#!$-D6S88KkL-k28VADq>*fGR_7UVLEyTXD)~T#;?7yF7Uq|gI*2l z3+mesg*1EeU0(0L+D)H3Jjx_^{W{(y$c)$Dr&4*ILNcD#cpj58-n#7gVR9JoS8;DH zCa1n)3mva9mqJn}923@B$bV^!*E$ifGN;M*zIXXFq>Y46<-rfl^3zfsgw zu4?NgtZ>Qd`%ZH^`5DK*^J&_qLm>!rq{aSmV)c1U#HkPJ)HXjB1nh6_*=|umkgTx+ z+nakK`Ka?(G5Jr)dqYIDZodZDNR+vK>;)%r1!bfe+dYF;a^X zLdd=Q@~Yx-r(m^=%e;<1wyhUWK~TGUpDvdP8{Xn|2txJ}_|~?7r@^U)H-{>MwM9vLuFR5_7I*)JUYJoM@tTd>``)-TNdL%zbd zUMwaE%z&V`lcsF=ey}^~MZUD8He- z_HH1S%hxSYuk@h*XfIv-RU47PS`t>3rB_Zp{y(+^c0(x?*sOk~oJWhd{nv_FKl3m%>-H3ckI2RQH{7UmV3|VUns*NoyOVq;vs_HnkFN%N{5QZ`B#t)mdrmA=< zE$7OTIaBcLmtL8}NqDW}@2ts+*5}Y9ZGaISWvr8afaLv(T}wxBK51!Bg#7m*&ylkH zxSiGoTbK6y&665S`xNdg*u!}E##4|^3+bPZ%o-?!4rp*Ve-uv<} zT;7)Mf;ixOi*lhuJ7<>M~PMCP0^!}`+fUSXbDICKRRmy@$Q)OR`4PUe;7%-O734V zNf3@QP>`Oom7!n{WJ-7NWjE+3x2uBk2C91KZ^|~~5%$jG8KiA$u%$|wJu;fQv}gGr zizmRuh5tlkVy!~a74|D0wsO?q`RkBbNj?jO? zy6pjoV!sM8!oW{KkMqx<^ZX~kf!zEw3TPYE7iu@tfO09MWZ#g!zb8}vf3~i-+8J@-&r@KEFr5t_esWTX zKvl0Sh6jGVim`X_qb!>V1c=%yy+ z9z#+>|62n2A5Z#}lLlpr{Qog6x}av0u}lU64cXLgNMg&hj8H9dPU zf5b{pzs51g8D7(=G3{~dxAl1vT7Gj44h^xwAr$;8Ct$&iQcj)P zpTNK!sg2E1M!Lo%s%gE)vt7(kcK%-rI1t(N^r8LLtkw@-5@^Wrd@YQ-Uu+{4ytkb4 zGf&L*qmc|+*O2Vg!7R{#C=eF+oqT+&eOTj}t>}cWhpc`jCnBjJ*^C)*ht3CVJWuA> zpFX8>xMg1FBN)%3C3ZoBocuQu`t!{jf;K8bKMJ_+t*pNOqz8z=!9GHek{KO@TJh6A z$Q4Eh4tjkw&X77q`?s(4uNVySmjm2q`&51vpg*?R>Uw}qb6pzd)zH}eYLtXhV7t(Y z#BhVd@xmc61?~OYD5WdXcdQoHlhcH$rmvWe4!AnA$L<5S9v$IgQqmm0e!!oQf*rJy2V z%nXY1Q2QltVLsSP9&vIWha~M^rSeZ;bdyG4kU(z9ftz*zp6~4KH#l;fE4&LxT@j&% z+^`Q^+Mdkh;=!R>^M9Vqihw@60>ir#52%)ekdPar5QG}G*`u;$j%crbJ)C+HF8dn1 z7jMix^4s<*bNg5OYM$D$7LgLbI6biG2#9luPmvv8n7}`KJZygXK3W1w1$XmBwM`=a zG}`xQlX+&cueWVj%%4)dYI61Mcp5#KcH)FKRLu!0y^~$VeV74(+?s7uMiE#5fmMW!riWgc;bF z$jtS(O%^jm@xu>JK(}?l_puKe$m1WG%Wr5mVvlSFWL8JWXO{R5r#d3BA3u7;u$m{7 zgce8dWkg+Q_l99Sfp`}sIn*j=H00IY2VY;4)yDE2*^CDUZZxSJj(mPwZH~X+UFU8xcmAKk6o^7Y0J8I6#5~M{hrqaqPtQ+7maM z@6!_rMu$CnY2prJRcJ?|t9U?FuK2so$TZge8(SBmPqk1%i&qhlNyPj=0YehM`T=_r zDa~)62`zabwYQM6*U;!i?A9mOKH$3WVXH8cnuoRDI&?WXFmt*7xx5f7JU6&RP-;}L@=CSNpJTy7kmfYy+pBqqXdIkf9^Y# zwW~QA97h4P#XmlY>WvB)rDiA%@6X4evUwN~G*-1oMeUW{oGPO*O%2Qj!~a!KkK$nm z!U0q+V~#208tovoWU}PJM3If8j#AKDV6r7=3DRu!Rr9;dmau-K)^T4+DvVSb(7{{L zn~cemP52`^8TX zD-9%XU<_fltM(j6q&5?@(aQ%alg94A3AtOjP#L99eL}{Out~wI5Rn|?f7~zd9+HDDp4e!k(XCsB@%w0kvb9vEs0V?Hina& zWDe4Z>5)U{#J{SJ`JS|AtKW8N)@b4PGvoysp!zezFi3jrFTU-mhCe6Y)>l~#vekDD zs=2=eiPf}6Rhzqy%829bzoV(%7bBzAHaqAO{C|Fa3WLrceu+tde=w0G^`~bnE?=q@ zhoYXMzY$48e9y7Qo@6`k-MuGp$lasj5Av7YU!iuN!J^IaKYrfRzc^#kyrvv^(L4A) zqaYr?<BeO7iMIV%APOweX&RZkE4SAs4!GsvJy;3!h^iN!o8py=vb6ev$ul6yDpm zfPqU2@i00QLWO7-drFeJnBqVDRf^i|>o+o5S~RZh;Xn1pmNMMvwAmN)e zImo6Y9xTcAoTF@4R%w#jX~EqBj4gBj{YaRuXy?sAlM52>asnUkYGptD3*wxc!Vi30 z*2$em#a7hNv@gky8O8V+`_7qet8L9tj3)Gn-f2<`ZJa z$V|RM8g&tm5U{n+&vh!_>2O5<$<)b;h|Boa)OKXD-ksp_Pj^#`9Diw6{dBhDnG3PM zF2FkwEG}cs#b=Q5PKt0MA_n%O-5bgtBsMP%zdj`!tZEfl>gWgaGIRBtc2p&ev}zE~&T3lChZ>`Xci)FTz%{kHvF zq_QGbSpCl6scf?Ioa!gcXVw$kaxX=2d}kPtT(Hx_V3Kj*PjuovdCCdBmN=5SbV`83 ze&K80Pyso|x_cuRzE1j1?cE!VlHl%FJ_G&HLqNAh^vI4`=;F(3ZQ{p1$ z^OoTnn6Y5~Tr@FE>L)=RefY@bfRY?sJkB>wDc}8R9ycE{#7Gsdap+tq z?%qed$=)^ETu0>(JSq2c0cJ)9Y7P`B#ql1Fu@h_)m8s5Sq3q?p4Nc6VHWzYsYf#}= z8sU-p(gnevV>3Ve-T&6(pzPX62=!iTrp>52|5@)F2g8Z{z8BS1XpJ0~7T>Au!3?p1 z$O}${FZ^*-5kG+OsX@k(`_eNcT6Z@pb$Sz9UsW|_UM(Z4y<1in4E7l@H~)mGPtJJs zyRxrFDm)Xm2wVz_)qfo}>)>v6%8_gn#Q6Nf*@CrS*HmQ$uw{QwWufh;kt*}{eos~O zgm8Fmz592L*s~UHlzZjnjiGPrMD)Hj+97l+w~g>~4(-(LOr0EEJ<^Xpd}&7DbiNX_ zyLVMB!Ca&5aGDT^lW*NzA=?~H6OO|!`pqy-*k2|t9lzE%o^jsWu~i{_)n*mPET&u2 zK^8f^P2?0T=>+$+k0*%7?~a~f%C}T?TBOPuqVBxN$XD-beKe~dIwplsF@wKic3}p%Seqov9ctaM!dr=&dtZzy4OAJ-5 z#Z?jbsCn;bWoF_j>}v^}m!8Uu84l&gobGN|C3P{ZCt6Sq1c>9HPnF#ZnO$ETWv8$g ze(4AD8j(mXmfmrpA-|u0auTEyf=pt@2NmUfn=cD1)lHL)#{S7@jNDUC^05|w0FR^3 zdv9h5>mdG{I*0x(*+Ih0GW+OyK;5;}|WfG8B5)ztk8t;zciwhGD zsS5U)xqI=hX;<&e)`-De<-AsgSK)kgKSbJZcM?Y)kT(61ETBInTzu#yKhddu&?blY|}@1c*u^A$|C1eB1&TVd8J~A%>7~& zrluqT##kSfLxH)gGBSs4ug0GS9cBpF{mxp<60?o7KkwE!FTj%De+N5FusOP7ZTC4d z^XTRrL%8&r7p-VwG^2eRBz<`|L_l0!$&L;Gu)h%cj%*4fuNjlBR(gyvmXNQ?vC=Oc z2lB2i(~?#L(QWT!R*6pu98^?P-2wB$egpXQ0&K2Kv1W(c!9Mx;k6r)F2Wz_%M*Zmv zc0A7>9Qm!EBL8EpK}!?or?W^C8cRo#wl*$n!R^s}6nzDq z1Prr{)&7S*AO*%$KFOU>^)NkXLvNWl28_6j&F2anAKxB@)HHQk61G zCng+^yVf|-+bQIRId2>3fU!2pwVnF6fHt#3f3B$se?Yv+rUs`iKkmYpxH?Wg^ye9H zr+h2==^C&=6R{-hM&G!Icy7A-=;^;@z`a0gftpKOLDHt&_it?xy=|~@t3h>{eu?er93%@=Q5XrN)3uT3$L84JQNTa zE9RpAa#xGSinlAqfyJM5n2MtEIy*Ouhp2F~icke^s)sytm%RCTCO@U0yzxFT=J%wR zp;ZqrIRnc{ZYsDd`{}%^vFNn@aZejb$2(jotKr{>ZsK^?_SrHiZ>{XU>Vp)4Q;IEk zk^*Wb11O|YF=b?%I@!$iZrHRoRg28DcfIe9hUH9oQ>VZpAg$8(<{XcSO+t}GjQv*& zqRop;Zcj^#ByIm27H_p{Ze-x=KP&uo^l5><1KS*|b^Z5}hDs9t#uv9EPLVX*m7_LO zQwLu1iUm=uGq8|f|3FPs1AlsH#9W(S?ZB?zrQ$}HXdyQ3*-qf6d}VC*O5DDAcj`EN ze~{}%XEfh3h$c9mJQ?#N@k z+>m|ih%gm4|Hd4L{GWmtLXu4pepM<_NN>&9K+WpVL8>Fkkypj$(`K#GM_1B z|04JEYIpHl=itTJ?=)~zWiH_+v*g7GRv8c6bKHp?^!Ebi4e13H20ut{59ag}9KzAa zA5x#*zY(nPx^4VE>-qdW_c|pYKUx za0II*(wq7dBcD>#0>|@s-fIU*IJjUwFAg5dOr3o3%nMa~A6l~6`9y7L#uEOoa-niu zX{w}zm=713vx%(0IDO+Q&zliLc&_!;W%Vo5+9qkrkk}SnuyX#oFK~91RaX5+`GmP5 zXfVtXx6g6BFLY2(&fB~nI~8reF{q;Mc$Bh69wRzG32?}bU2pIbkRt7t|D4`zP>!C) zk{9|(mh0B&{Vb0|xz2ukdpl}K)L@M8@O@>($j!(a@~$JPsqfHDuM&A!XG{vw;62Me zLp`I+K31x+U#($8@@?Z^mpk5X+pF%|?lC>>Rdslr?`FLK`J!yab$`WJf zL+T9l=UtQA`znvH#IL#&p^0^WB?IPi^aC@fFp8V}*vWJ_<{_bjRV^V&Dp<*{&8vwu`Ob~C20XYiI%U?n12P`CyGH($_?2MMYO>rgjRfi4e#*#Ogsl_W}<7#^Ac#VC5V0CLw@4Fl4$x8~# z8A)lxqfbrvE)7y8F+siV{6ZkxsQ8mH(hSj$>J!@rOH)*Wnzz>-$IZ4QEP8mq<%u#j zYp~w6{`W9B@AB{b2Sn~melvwwflzXr{9-D@mZA)GcCz#OK~^g{pt+!#*jY~T0+Pv09OTJva zJ@z2*olWB{a!*_MhrPdpb2m-h_Xwnev5e_Vjs0Pb)qT4O9i82PzD#*F zw|B~xC!pVG5|-TCuQ(Co(cySJOEy3Ht#NRBg=5P5)OtUeh?XQBl%rPy8B%pcpl#M( z$oIcAUelW8k`YvtJH8TSpP;;JB6f9oM{DM@#2?kZSHUG$A&PUMBg>jU-Pn8EMcIgY z)}Q4ym7Q+(TiP-Sbze~S(QR%WxncopKJGhJ6)NTYlE(#uGn;iQJ0HD426o16Wv^`h z{`$_RQ|Ed5AMK_HxZCe(1`+G6c$JFHB$J(UqF!QTuTN36$oe)1xV*&XFFj&^?S(P> zR!p63iukHH48-wTqwVBE`Feg{G-ELK9jVLN0i{BA3-ym!dQD3z3qn}f=El)Y31=Zl&ZjW!A!(M4m6of8` zQfG4zb*kg(fAo$kR26O>CyGcndau8?9o3r3CWOwAj1)qxIO*SvPZz(+;QgNa;MPnS zt1(VG$G=hS&Kalj*YziusZp&!w`hKo^?Fs+nzgt4{UQ|QgLi-b;V~!{{f7mZA6cOd z3nK=_Jd3tmT>T@v5|}`W5-ltzFI(LI=|PNoNyqu&2K91QTUfJ|3-!#g(9d(R$jBoE ztmx^>LAAJGAtqzq`5?~{;+eyil!Q@fC@O7p{%)yOpo{YrbN>_bdpBaTiqi{y2GD~F zXGHZzv?F76USBc&mT`RV+{1F)EX<=eBsIz*60(r)6D?Hs;+_sLAFrHAZB71y$JZDs z%-T<{qdhnFd4PG=iLj@ru)a6f!{9%p;xB5qMJdPe#M$>NvNB4>w70|q0{OMG8TOHI zlZG(5uP@D$U+i5_E@6PKP2Uv^cdFSD2( z^S;`WB=NjH>U*(dosBYCAin{Wbw)Rp8N^M1qr#@@FDIH@N8E&`4yT)^9uSbnN zmuPPJ_xY^CyO%G}&WCf#=!EIsI>P>yehu^FrLtq) zkq6I%Q8EXrm-lOKW*j?8!=YZCTgSw}16_?w+{$GRT}1BV0b2M-Pr4o?!P@PQvoD%$ zB3Hh+J`uI@g|?ICyA(74U1)h!mb;i^)MyC{rulO|U?%fzXm+(tkq3ml1%LtHWx~r{ zs`NAPhrMsB&skEVdci3)I9DG!r`V7@UsJKt+=mF-Zt`b~upK84l*krZ<|)cl#YU z;C7_8uWX$2=V@Tu3=q>vNPc!nS%oxNtB8Na+92E}s z=vb>tYYdKlDEiYnXWem{lMW7nrB;i5@ASJT-u7;lt8nPZ+ zbat+NS*=+!^QKNS$BXLeJ%+A<$=u$X+%9;t#{JIYrJKL3)@v-Kr0WCY`KwgYD#hsI zSpH3EWyRYdGSgGnH|vR4{7~+M6pxz9 z)1LEi@p@*L^=9Xhe#Yj#`@b|Nc}`zdwdSdK;pf1(E^k7r}fQE8P4&)(L5booJk>d z^TXBUegQEvyS4Ax;p;b7d8TbaEufpUEt&jj904^G+W%TqMw`j)iob|NVtg!3Kh+LO zV9M$TFqcxn4eq&H%fQ)FP1Ntt8V0jihaJ+9T@jee`^SJRg-!v>>D>LY>WPDOIFkOEWOq;SRx2AsuHn7rM*kS|cou zGP_Q1?(f$rqra~=2Q_n;zGKE7?_E|;wYz8Grg$>UeETBiQG#JutgpzbBc+CSP~OA0 z-Ake6z8QwzO$9i0=P53m?RHBS+z(XEGf;x0*r#sGf=Q>5ew+uOX71_zQe&^!`Qg9R zKEkBmGlkGio_@{*{;;w+Z>JfYD(wK@?2VLY>Q$F)Hn4t44$IKX zq!j#p{Y%eDXFoY+7Q6a?X??Do96zTA9{2}(6GkIR%ghy@L7sqv=KQLq;GF;CP=X#KBN`xb{tYOE;+tvTE`I z(}jDFf9l2Z_cy+`V7u4l)8Xx_x`+ptqk~v?chwt*1 z0^1G`jc&|=;H>ZxbRdM2Ak8`+r4dyKq>{dVt^tAmutT?XUG&z(pZ>o$cNx9CEEIO7yi+b*``q5ee9My3JV)(w{KAFL_QFud8uz zn52$%Y@9J!|62ERAt>~`bKnvsjL0Hm7jZoDdQkgK(xfA~(RXI+6zSudtL?0&KSxLz z@2V}H{ok#NM7h=XW{dH^ZH={!?Iqwju9~6K$E|Bml9kBJ<%&G)y=3CIn@MxzCZd7+ z4d2f$eg0E>e^F3-uvU$MY*>sqx9JrsYZi@j>zh@Cc@44N&$?}|n)S|0ggEET>EOg> z)P+|SZ~@MXl|7#kUowywf2>&z$XqP?k;|`kt=B6_HA%`zKk|2!q=Uwb5Pd|1VWeBd zD;q(ri534Rj$%@7G#qKn0-4v^imL)2g_?hK;CqazKM{A`=rJ^|Dg;@xsgOY_u-ZLq z+CS`mX2mg&L4|@a>Db@FNf+f!rbMTolO)SeMh)qSC3BDm-Q+mPebbuz&Q)fMaY=~1 z+99WM=_{zMhU;OGa8M6#k2&);e&d7KVL}F3S&H=ecvn5C^s49bW4xg^pZ5MQ!qJMc zGGmAz+VwJVP9;?nzh)r`-7B2MqFu;>arF<@cqU$NO~m6vG~lfWxI;!st)AFw1a3Yb zGIUagQaV0qaF>B9-uvksbOWB&@_8`7jBR4(XxPtS3tFw+)rI1e>5l4K-oo2kf5zMg zVX3l>eBeMBh4f=OoO4C)$Y34_w}&5>b;${H{I(=q*5P9A;=%ZXD(VND=AbqHR{x99 z{L^Xp`HFDIcKI`fl@Z=98Y-K5bDcj8?BylkAJ>dPK4t*hi*3IUKqW&&F@};0LZHu{HW!2#_^6y%Idv zuhK?BhQpEC_pGJo8dFV}O(g9vtnsRyRdO{a?h3+Tx->&k|D*$Uod?mue`9&fZDsW-r4{Q_d`-!!S(p z$YpRX5F`#PQ#B6OEvm{Jn0gbJ9(vvO6D+-k7+`~A7Ue_`Vt!-!#?I%&;1OK<63FrN z@$Q(*Bwts@;rWx7lB-T;<6NNg#h+VVhH%ddQM)}ZpoR>`pO#(Sw{5F;8!}#RVxEzk z$z5bN^XI^l##^x3ZJpr*4B{ma(P6Riqs+)+lnGxvE|m)sI79u#-W-k*^PScRE@Ji? zs2ty49hr%8Bjmz)HJ1k1S8Xz)B*T7(2QA)#Xy`Z9c`&fCj^23Y2Se`im zqFQYpV`Or8-8&Mo>a4+W08nHB0edrR;pprP;Khx!{85v?)|ak!RN3rpAvb zYlRErQTU8Qg53eSBffPg%qf?Go!E(67C#R9y3!oNhr2O7Jm8}V@HxH90I~4RN9Z(X zF@UiU7PsUAB->QBZRGQNzm6W43PB^dPXd&citnR;8^ zF)pf43BUJu@7Z~Lws`oOF#a5Xs&ehbe0OX%J$6Lzuf-&UZ|zp^r@Fj5%vWJzC+~El z9gjfmgRr?@doXLe#?~e3C@Jl5w1%G}EtG{i3`ax|{pb%Aq4vA}t7D|kZTcHW#{$L~ zVx+ITWDklS5fof~Li%G&u76d&BS89nE=J=>H_OlQDi6rIzj&FBgMfbTJWp{BMi^Fl5R<) za!1)~vDKmL>C?xv&)vfe1U1EU;gFMm@#BRfWtH})qG3C0VwoHq1!MVS?-3&)bFhhCujvkuq?LHUfBy=jQ zgya>C7EYnQB4C$H$0CP_ZM@YW6z1#z;iU82{(EzO48Wb)OkA;q(pU&zLCwP|K=#t( zG=Q1fRb?_1p>{HNHs#J=;vmn)+=EZ&!W9VhZHlC2Y|;t%#T^7R-=bc?1)KT+JXtq3 zE*?S435BY2H#ANZr6Mtm(SM~Vxr=JCxFLTm*{^ZNuQ38;fv_-Dww`klhfI?+)6)7imSMNBAdNzjo%G50$|D252y+^4t+zmT&J@2JSiCiGu^`flKb!5&B(h zKY{NKJ^84^6jR3;Zj%m*+hBFt8Tp_4JZ1i}jnlT;mP-KuSR$yu= zByZWOvR%KZ%Y7YzO0Y5DSN6%?`}wsi#?f)_`kY-ND%-(%OvoX{=BRKytlrKp5r)Z8 zRQ1l@auwLe`RbaX+QlcC5##2jrFK0`9j z;i&5m0ur>p+U_Eydh%g|itZ`P?_&QtMqJ`)2E;TWd6Ayn96Ec86Ck(2TgqHv239?>nEnm$sQ0v3dQ`L&b z-{>G}6v&NuPi0Lbplg9_PPO@rFze0v!MPX^*_Ccg_~6G;yY;dWNI_OpID7Sx?*Jne zFYEZ5*=mw`{NZF#Lv{J+jt3RS!i<+D>h7cX-`g=d5tdtGF}-h7?#6@L)W8hC{RbHF z>Vx3iST&9sZbX?>4_(Qd?Y7e|o9h}>E<$Yj!@*{D)xJg4?=`2e7NY{~Am` z&t>jLi+BCGivgC<^`*y$U(dCZw0JY3?$KL*J0LKKL_;QLc}~wYHZ|7Ew32@oS{;YJ zbBy zj0^0K0pi8G@woRA+sn@%4aedz@^Lq!d7gn_>kDy;tY-lO2L~uA(I8P-qJ7r5AXYH@ zWIWA_^FpWsVy|>hhYyGFKVW*ij;JHXkI`YId{DHfQp@_PZOLg36{XderAU1W6b>5m zT3t5AQp}4UX%fsA2J_EsH+vj?lsu%8tOIpDO2J>Jpr~Pu6v#&bkm1>(YnQnP`~zo* z7sGty_t9gOkk1)vwjOR#mrx%XR7yPC5?4EmQuPIY<(;E=HKp2Os zbb76>d^F=#pj1$F+w&JN@EO9wCV`q5+Gy=b!>fS-+zqo2mVaHdx`GOQzb-eo3R2<{ zI|=-t+o}Cd&Tp@n-0*m~r~On{$FYICDc!+zaaUFNs@n-66qUAc9R+B39sa|(vZ(L3 z8;TW#}N!@=M#!vy?6Hf1#q+Xv=Yvz8X^WvykQMN^L;&c z3wHFUL#Y4oLs}+&pm?#km3Se63$jYV2|&lJE>tCtj9j$*EaFl2bTDp7y?4akH40)* zX)dD#0oP&q_Gh{%oeEPg*h$nlxMpD7yA{e0?NzY7hVjzOw}Dc(!B16{cp6o;{hG|K zchZrN6mrIlXlKF8996Z(oAD;N)N0fElyU4GPN;+C!hyEd1bQpJV($cITi;vYQn^I= zTF%h=VD7?sml^eoqt~vF7yW;T4Z9Gnu_3NouO`pP>y6DsT^$A4XvSlZRb32fj(6_T z2w*od>J{5Pfia93T5a2(%t|C}X`8GC+s9vaEmWS{HjfDzD{72PeM^b0>;^#E%ZAsr zY9>`OGpguz)aH_9G&Bp!<{6jD8)KdVB(F<{iA4ke`M-9jqV%0)cFiZ?R)6PcSo8Kj z<$mkSn~itYRcrjHt9iP6bE|vek86Rv1j|&BbCF(bSg{KjP+kIBBMyYM z&D-q~JpZ0q#o`n>1|~dtjx0bSP6QYl)8GJry#(nP?#|Jm=3f9tQ~2t#6|;Jtv~bg_ z2T$54=uB7Hyr&w_mSc=|x(hUmHGDO4OW%_p{{bpu6@mmH!3BbNXYD(Dcz$7Bu=%2L9`_wy`t&skn3WRP^qp0LsX}z|KjO~ z^Isy)7Q06>QlfQW2JoBww_-tSUS1MzW565Z2UvX(Ohy0w47JmAPW8P=*dVGxy2r?J zhQUeJuh^{cx1;J>4+$pNpvYoVi#ROdkC>7l)EBR*FEj{BXSWijcDhQ0voliXo^4^$ zr3MpA(rJ+j)a$BU+C6bF$O7O@@5aoj;_QHMdngcwox)7ebxQ>(13#k45y&tTQK}aNko{cI0lIs>gWqtepvWn)EzStck_%`G?oc6(GX9C zn+XJpl+j+e^a2Ocu9jekI`_ldujlpyK_dbkvstvLY&;+&EZ^;<&1|HIx}?Mt+(EZ3%1 zaiXXp?+DOIaDVsT`+Rg*D%F@VyCK|sH$P_@pj6CaH={3;mR?q!bOJa(*Vr=X*b#Hh&fF5F8oU*BPXj`U=3IC3B<5AQbjfAVj+w{t95~y5e`t{TcKr==lDQtWSJn2ty|ZEs^d?gg$0!ftq>Gu*(HHN!rDPZ zzoqI>F!AyiJFrkbiRF4H0^u<dCMk%i%q|$_ zC_N4RwWKrEnR^7-lN!>?R%KQ1cKT1rbg=PPd{43@I+@}hv7~6RV?;GUYp{6PLOj(U znLA#XqSiPEy9#!&WXD9_Dg7X3(9IRNJqq4Rhsj|i>}quo?FIPL@|KW5lmfXP0YSa* ze#I`a!>#bxyMiy0`>pF;fK=mKVW6vZDKx zCXsD8grObceX*@~gAqAeFREX01H8XOn0Ig;Po_wjGT@mW^9D#>*34bp$W?$EC>mMs z1qc2j2Dk{zLA;O~Ey$m1^~4ETHc-CJ$a8wyc6r=8?p&Ez3;??O`GRi#0H7oE$N=2$ z7N0l@nI@@#o`X$AI}l?q>L)1&q^?XK0t@Qz4ZIkMg2KB;pkDH%H$w`o+zwRfQc!Ft zUs}4+PEASQoy(Ds=a;f~JTa32h1W}RCmfoie*)A15tRQz)Ez~@75Jd*Y0z-**^B>+ z1xQ?|ZYtXy9uYJZNp=5l+hPuP_Es)ffoz6YDy`AnlJ|n6M5ey_EnPnr&~! zdyI|aNEN>C1u?=WxF`Xb%Qa`->nFXFCHgG3;6XwhRHb2t>(_EJ*KI6V{kM|TMja#KKT2`c4|KK0}^*$On zv|UwULaNkCf_hnXZOxUO%^)5@U}Vkw1>$ISHzY7$@pC&&34uKuUsu_YWYYL?fn z?_(I|KuLj&9cmL5LT!Q$yX)V_dJ-XdkSA~K;L*obVwP5lxbN&&syOO!A(Lp=*J=(= zfgA=W5-vOJKKlOnuALyy#fO&bZ*#RxRf#uTq+I)qMBbi6V%NrJ39J54-G3V+A{A5yhrWDq1&k3jIG5{;H|6^wD$&(hZ=Jo!rr}7-6={72;^z15okHZ&y z81`hx-{{5Bat$Bj1%h>KYHZd!wm8Y|G$iJ{-YD{d-ofE$kVe49jBuYbDBoI2_T|!t zyahFS32L`&#l>Kd=qa)s9h(|jj29F z(QsDeo_5W`^0)KXNon2${@t|-4k5@RW^-HI?CYD48fx1V?N$;xtz%+SOgKH4}-?WBE= z2VQVp8wS;$F%-cdv%Af;c9UgWar!nbJLYKz3K zUzC2>74M;}8+J7yXzZPYlak3g^22t;@^~GcuWfDTWHce^(>!g$-LFCT2Kl&J2->pW zGK(Rxc#n+rvwWq4)t|N89k6f#J>WgBoH@r{V*cvaC>2~01h3|!F3MhvFYq)~E))W! zHu-LPiQHRG#+ki#*Fr}tO4!OrP*#{%yyPv|&APt)$FJW7G}S6+WM9cvTI)^0aibFG z8bOXK?~!>_;$=LZ1rmG;_{}l9EFpid%tH6hHchrZ0_7Uu_6;dD3APmflzuiv1qS84 zSiFY9#TepVdj9D6!XLrH2cQv2Zw-xGrhvsk^_f{Hxi5YXEsp<&qs;~e`)p%{mY#ax zPN7-?74%0^TRbrK5i7Ng@wgt> z_52R_zXLf0plv5~Kf|C*k>S}tKk{vt0^{d1vMxO?=r1T^1g>EEvIs#8h|13rylt6Uv+k;YoggRmqbJzi1V}q97kUH zNKcrX5^}A{h)f03SZ{+313hu; zD1RtG1IN!SHm962pbXSa}&d0lhm$x>%U2oDGl?i*mS8g6ozQ@Flnrh{`+xk~Wi zXbN?XxxhP~5aDQQR@fUHcz0(Q>PcT#2?FLRaHc{o6VQ6MPddS+BEB$52#j-w6yNlu zF6$6L_aG$p^oF{e-=n#jOTdn+yQ;6PCp9m=x&-o5ca#h-79by+Y*XcjfgOFE_w!#L ze@Gnz;NojD|LQ->}Q;Ab~H(%E~q5U>jGhOr*-!XyiO;c0{biNTn@Wf0>w* zwb`!%`Z3tMDHEMMCRq!%#XvpYe}6dahA zJlf70S6fg@(Z@=p`}g~kz||EGFiiQ;LY}_&3jiLgk1gTlO#5xdBq*eMj?HMVhcsklu5An{BnBQfZpDo6Z z8)g?YEQdS+6n15hxer`^LXVE}g(}Ns1|R!nKnwc(um$o=LlJZNeQa3=8hb3df<}(sVNEY=4!xTjQQ!Fbq!9 zPu74~s|K$gTo^gfic}25^+5(&GSv5V&6*|(A1=Du{g8{wl?(is8hT5(Yk*W0N@orL z*9ylOWdn5Z6^c>QSn3#} z^Jn1FI6PyyWEkuCXQ zo!jBr_HgzkB#fhAMGxpEut@0Y(k^9;R?pSo!)vzU;0mw0LlOCA zSug6(&=43&}#x#ZnFH0xoD@n5Ao0m$T z&hFPrjLdrc_Ze2%`_8er!QRPxr2V)49WXw>rh>&?Qaz&);WF5=uh~T{v(BFo9a(w) zB@8DB!N=4Lj>@|*FC>5xQx6vz@VoK*JFyO>{gUe-?DW^q4AWjc3BdYYB`sjc(HZal zH3W7Ov@FO$J|%NvC(c2Bms`OXmqVa#>%BZ4ku1R513D!zze~;p2H23%_k2xFTvpq` z28ex?geXex`H#D-x99ii_eI3{k{P(>z1?;xc z3@Kp~%2|_5iqahIL(0Nuh+<4Q6XDnA?fRU0>Mqo@0ownJv^c?^#&bPmLUc;nGdas9< z{&1^Ue!~zg%~^;RxKm*0FY1u6iKkaKu9OIa3mfK(gf}+BK?2zYH6nuv*PMY=_H$n< z*aeH-H_t5=NKfO_ReCjCwVCtDuA-_4sT_nh;XOq#$ma21 zFkrg9hIZ^cKPZCcErn#00Fu~w!}DGe5^#+P0&q@z5E8!`;M*mP_+%OT83F}LAn7ad z3}3*YAWdpf|4d96?7CI#XPZRCPXlCfbG?YMaX?7N}{`C^ayJv6DL4ECMv&DMuKS)nf$s>2RfUj9CJG&KfFCKbK* zKDAu3Z6Mvw-Ixb`AiL}7@J~Xw|3?BT+Uk;tyQWQ3)Q~jFC233QTK?hVyjozK?0}pP zUk|o`H>=VSq)-7fFh#s4*>{=uHk^#a@|8f_w5+$ktf?uW))CE*tsp}&$0>)M zo73^q*)QXz=G-hIM`2k+m5aIzr_NvBHz3*gb=vhttpFY1*ifDZ<%h0llamPC z8^2a)1TDzwc1kpvz^%S|S9kFHxUWkb9Kwh93)`J8=FXDxBfgZgXp@sTk)#xqSQ59+ zj8gix+O^#VZwL66AmWqR_#AAGju-luKKylqP{hriaDLC28`Vrk3fh@r@L__ugM=>8 zhbWAC2N@{BW4(f11J|6yiPuuu1K_{37)qq+5>YDR00fu$=YS$@xNa6V1@zO#!M9G% zerX?>Zn6khk$?buY}4jF2e?%N=u1@LHU|R$AKml9&7|o(-LC>(J${|^UN7F9`4i21 zSBqXN4R?dJ^^AGj=st+dXZP+rlZpszEc;^wHD^9w1_h0HC(8%`z{}EHNaXIZMRn}4 z2~f`ETQ+(pIxwDzZM!{Dmg&*?;dEx-wc6XydtmgY6tW+$BzKuWn>NWrGU=e-EHu-< zDc<4#5ok!!lB>Pfunltpi41<4TWzjgtUqueZHs@x9+34HW6;OO+;8_6#0%x znc|0twlfj`_&2ld(?PE|^#pN1h(Fbp%G3}9lQ>3c1A0@2%B9~2o|rVAKt{Nu&{ss7 z_*W5tG^(~W|C*d*K#$%y(!7ZyE40k%1DE(qfyf&x@5jJcu&gYR{qq1eNfG!{LbLF~ zF}NA=Qd|Jft@x(2zEz)8PD`K$*Ua>;Ai)d`5t!}owm85KzA1-ze9MVk0lzrVQbLeH z&EJgH4HsK!14vH@@kxI?4FbfdUEl&iP9P~AJa)xF#46C&vws8k3NQ6BVN@+%9aDWW z7xL=8~AeAN~Uqy9nh-l)V}YLlKMgbK}NizLpu&+o4?(ac{QSp-8qZ+qywaq zr_EcH+t(eAc9U-CY0Mei4piU>e|NZi(rm2t=KH1(=46U{qhWt<+OJG8N)f^(I=g)J zQ<+uy4eo<5O7a=cYv=z*o!_zy2Tq@8*!Enh$-A$M0~`j{mR4^mCN;zE^-r%whgvm8 zsL3%~TJB$6FshV;k{_4QkFm1ADYf6;lBxExa{;^X9AssEiqRwZ+27>lm3kzFKH2!b zkgcGNzYQuv0l084WZ49VioivYZQSc*fCvi9=9DCaRG4-#3Z6*Q+6V;Rg$xX0G5t~f z=fuM3lfHous^~7SEj8TwkG124g)plx_dZ07BFI3EhPKe(q*b@I+=8 zCqqC&071>5yY5FX{^P@~Y$y4hN1%_L0{mBtFT+4dh}jcwM^WZ|ASj#hf0BBi0^cC58#ehEa{CQ?Ss3BL9Rl>%-%*E2IS=fsH|9Ru* zzg50-(x?2?zG=0Ejg3AX+vko`JVBqlVrCuKm-qXLyM6MviA4B^gE`B7l}OOHX^G?B zOD9`oA9gz4&qATa!S3(_lfSq)H}m-5vS6 z9(S29v|GCLt2WlNDasFQUD~`8h(YCt@}v6H!36W$@iWEk+fKIEqR2?~;Y=hY@rEEd*)=Bdx^03^tg=m1kiB`NdxgruOyc^9cKCWf_X>$3&i z^=-W42yFk-JZj%pRd%mBM+L;Nb4cf>d1VnHA#EO-7V*AU#JdXkv;LBb3l(!+2VQTU z{wgT_!}6|W{qZabiuwBmh%FUiCeH%-kz`UzPRu+XfNog;zlp5p#PUfAeGE|~%vr(7 z>jO}w=VJ3={W0tSnmWt!>!f=Bv_Gl%`GLzIzkIADCM?}ApB%FMw#350I$#5Er*3+*?rs$i%AzwDxKC$+yf$azY zMpsy(eOz=#yJ{&FFjj)voo)56iw$aNv6+a2(8{paJ}Zq>TzDBjuow2L4peUKr^tc7 zpUIk#`I~<${UNM~3WB^wddqA#g%EaE@>Ujr!K{!qA%0R?zCXT_h&C&ufa?0+9M}d- zE`bzm}!U+TSr5W9`G+F(Tpym_FT9aUd`ox?p;GWYb0CXxTE`NJIDvotjl^yfd zQWfNJ&4OUS+5uO2u>b1)e(aMZxBr~Qe;c^uSA?$D4D2p;Oicbr?ET$Y)mUD6a)0)B z()Yoq|H>&TSCT_GrZg!k&o>RcS)k(9mONNB(LwpM9ri*FC???|m&Oo>63qSxYRbfI z(Y#y!d;B39us^4dU!7=r)Qe7m3WgHLYdUV^@|waT|AoPdU2H{3WuBr&sX#>3-n8qC z4ZwD15C27Pnx|V(86Qa;_NwgPM8{FOPn3BFT!H(y8 zyiKpl9|IF?eM-T#(E8^^;>~Zyy}2y9D>{QFdXWi1f?W(Z1ri`C?iJNoYnD>or>YZQ zd7BTFcA2=mziqtUJ5=#_v2gr||3Oyv$CCpkkI>OQZ5#f+ss8!9J4)7D*+7RD;5@7^ zz;Gyt#$-#{E57S;@!yHR2HuC$qJOj`!x? zzUr4JmBB2%se$>LH+U*HrSQlT!WAE@-xs)b#2x%ykoCnqk87_Tg#1)zXED8eclvnWYLLMsS&rW9lD-P595BXNVITepfz#rio90r@{5fySd7AR$@#=oX zpr>@=A@%kiol|(7)d*Fi`|n{N3GzVm){#W+sfFLb3V~WcQmfFb9#zg$dyy-4B?`}v zbwx463dre`(q`YFK53e`ArVTPiS*X-ZqMZE?A713LAT&g`)4w^f||urv>wIKeLiRR z)Y5qN1T&IRk|9YSVq;D(CukNefP|RJ zewd5b4>V{$Fj_Cl&t=9_H{0S|EEFFDSqkC7yaX1=s#k`wtzhG@_BK?I`<$tJO zkI9f=9Rz;KW@I7;3JC)F4OoL~2B&5p=`8X85rPa#R?fCD!VKs!r1`}5eGg$@Qv^wq z8>xxSN2{Ha6Y1hZ$N7?CidLgFf}cd;ff$0T5@=ZguA{mr-L<8$<52at)gsqbG%;-* z5!8scm%`d!xV>qdUjwZmThJAs-(lspht>(7MwgDUInK2ie*W$Hoz*tiG#shP7Zjp3 z*3Ch4G(5`C3Km#NNESkpG(Ti+{-Tkv$AN%VT_`&q?TGCNkBN@FDrObvgnb^yf&h<# zK%V14w@bExK@yz$b(b4|mmF(9H>(*KvA&(8wCyL^n?o8QX1r}*F(fPnv}$zQ&M`C* z?wJ17qdvs58YKmER+)_QOZa_9XczOB{N}m!=K}Fid z2Lf{_u#3wnlu*f@n)`N^&9|C%I=V!}MwhfoGHEPV=@GOKm@#-@c#3c5_L~0OTcMgw zV_iDg zLh{9b(v-I$TxrQtVW#baK4D^Q`6Qj$-l!6|-}uUNFB`sm3+@Qx1CO$*M4ghs<<4+K z%~KwMv0paq!OiOyFLAhgMlL;bV02tF5^kra_izL$L#!}^4~|$<<=vc#5MH~Tm6n(Z z0x?j!z54H+w?>~(h?usqMUQzSKZ{<6Z5ZUtK_Pao$kk|jvfCB7p{VDmAkmvkpf?*+ zQ(kAf0Z88zU$OWZ#%i;F>7IRER~r}&FPCEg8#bZ>M}zvW+W1?eBOJnsAD{n#M9_|q zCSR4|oTLV|MPs0O866aqVS$W*66hW6!T**}K8^Zx1`!i;^@(qSrb8QLRTT;j%Vfjl z73IgzZb0jwbAsx5(E=nN!9&4==F z+(#{if&$~uZ+&l#!RZSi2^@ZVi1e3>xK*-X1Su)_M|EmiCg6-fLe6Za3*GW57 zvvbI%0L8MY9|o6lyqf*>-%dHImrr8}|83lJ=TUD!!e_9KFsK_enQ48z*9W!;`rk&76z*SHA?BH4bRz!k)5k=_6@%oLHPRe?&ws%IqA}fNa#^WajFqM zJy+OySo4k?$9#8BX<6B|J~?7pr3hUjj%J`*gz5m^_q_E6VBh z;zsm$HVN<=ZxI{c{TtIzjD0&=y=xzAVf@-gXaO}WA%FUJ{kc7te7P51?$bI}VEXGV zEiP{ZLXdC`=SP{L7_qLY@rmmEO73l56mP;F*4_`}1a25X z-}VdGkqa%_`;!en4l_HUitEPtWTK#kHSv3hEV-W}T;o3s&hZlhn!P&IMj#8_GeLu^ zt1BaSXXhKpg6#cfOqq{xaRetypgiO7Y@8@1H04aTL=AgGGgCe;X5l!V+k6d>+#C z$c8`3S!}AGmjdwi`RPKaGMV z)kEW+gUxUq*h=cT*M@4X<3A+p`}g~LXoI#YK_1-ZiUXN=H$0UNx5NNJZkx^7^*sLZ9eiM{LWU!aOi4SVe!t&tFd!+efxt8rle4z- zcI}JfzB&qH;*eh%7&^-#K+&4LQwRCe32jkAggRI1-9nZEwoOWAuHkOa)hQbY@U3T+z8|IjuJCibcq}f$X&3w}OyxGh zh%?k{|5fX-s(bw-1btpR%vKw|C!OeWD*LiRU7RQDjfL>`uS)-Fe|ihLJy5YBAj1G0J(rriHh| zS;0Y%Ie&{F<{!tOZ3F&L5#6*{E3Iv}v8bzw^e-UVmk3Oo}bs;}2S=6!U4IFWQxA$I9E8DhfMgoF%KaRZ@JAbfl&z zLG!UM>16HaD9*^ofj*)|v-bBteI`F`>2C~HIFPo}Vt47neU>|!z!odznJcR>dj>E4 za^KBl*~a{)$K_i|lNSt$-a^3moj2xc8)6{K=UNojORLpSbqKzunWz8tmj$2RXRT#A zO_e*L>Gv@2Q(udiqS=991g$FhHq)m}vp|^mx=$@I2{Yq1nAbTuxTFGk#&rdsoe3bC zFgax|BK{sY96L9kwFY1@X~ZB%vyvJiX=`!%WWQN zfO}wEm)m1{!k`prBx-d0L{ClLNo%p$WDSCEK+A={AFOSBuuj6$qvXKt+nQv>L>KAf zsQqgHtSNeK>ecDy-)1*=-vyTawduHl)St~{W@0!=2&astU(cXLse*s1-9J;q4t?mG zmUB#}!`;VWS)ZMDblr!gQbCr~asG;GgnjV9pSLIZ7<9|XB*CigEe~}%k3-KUm-isXlQRe%s0S9|+g||DOt`vcD@yW)%K7oXu-X%O&~pZ0f`)U;^$|Bs%n28yhl*jiH?Da} zns-NlVIz~or-Fbn{%E>{`32zuDmut72ok@iQstT5@h{Zo8Y)&B~PE6nQLxB~9-PM$L5F2OPvA&i08aW!)6@Vx2+Zm_KzHyCkxe5h>GVij3- z){=Jeh*sY|XX9sD1)5CUiL|_VbqqTAxc=in`@dP>B!o%-l9i`!Ac7Jq_k{G|14TW# za47!t$`h@yY&LG7r_MeoB9x2O;nEN*prYaY?KbZq zc&pur{&{kaoKh_NWTlXBc&PKsS0^`;B(&Bvvv=~Czs=8g*M^VIi6TDku>Y>T0(csHp zD=M#eRjRVl^FceDeY}O!%h_ymM_L$2=i$pA=uy7aW4Bx`j8sc4Y>@_v(w&2g;~A6F z*~p+`Bcr|d4WW1Hn||i)-16#9$ErJ(D0tTB42P?qiXY4EOpn~@yVHMX;7*(-50WSi zYBmjTpBEx4h{oXTLnH`DICRrQC|R?N#}qzr#uUO#?^ib6DsKuH4kFoI=zZ!R%-4F= zdNq4>dkuOw`rdyuMj(KDwUN&YrGt~S4>3aaHHZxBz>&Rn{$odXOmv}9f^-R$-6D)I zCm>vFx*IabtFBO%onM34e!la4hvPC>R?IU^ADdqtf!-_y5ulU0{q@j8oGgSYn$r@5 z{c$AIFaqCSh-FAwy{Vu}QWUp5I_YaoSb4X>|8HCK1THSw)snot+a~y_d!}~4-Z%^1 zYVv6dB>PGmTF$R?j5F=rO_Y>Nvdk1dT&44+CCYx95V0K(xpMbW_CV=lo9>UzMoyLD zLv{o>jPh``Jdg|5AVS{i3%WspC%;)EFEgAWZAd#eWVPf2G%U^Xo8GCv9{JCG>w}tK zC*Oxr(~IgLF!bh>cUrm=ZUXBoGUOCrN=5O(=_(^m3m+mqa%*NhR884i=IGqV`S6$H z@1Zo6C=Ind!y*D?TqU1jTJ^}6unnF+DilW8tPum30>w&x%P8Lbe&E;4Kb7YX-FGeK zFYN^V5evolLUBtxR|@S?BDJ6onyOF*0=%_;R$vOpO(<)Tcl=sh&-HA)($7qs3f-F< z4+%x5=iqw@uSa6Pg>`1z=^>b<^HwO4Pp&?;IfNAe8!#{A)Xt5TBC0!20&-H@z$e^8 z=0pC6?_N8V|6b!PJ5bc;ETeZ3g!9F-nDs4wTF(VuK-Bw}qL^dIL<5B}ZV9il=1LYr zM(GyEPWT*X>EibNOqeeV;AGwpE~(xr>NOCAbDS%Q|1Yl=K7`mN0TeuxcqJh+J3%D; zY*BnZQmVEOm1lYJ=CPl#}@PJsM*8xM-~Mi2};#vM_52rN7(F3@f*3-OoGx+v#n zJj-HI$taBmPbz`-$UxZ97y`3DOYp#rWtXm=t7E`rpY)0jY>E=6M<%WY1h(S*RgYl= z!dL>u&%-P+AQHAh85>HoS|Bj)t?%39NDJU7rgz<7PB+U9t7;?WRuQW)fl z0PVMq$;=fPW!~d5umk(C6^fnXewU9lrkiDwu3^AOr1tI_(2MY+h&51TIPUg@qGynA zKLf@KEXn1fP`m+z5{uhV@kD+gIukTgVJJxCL1f6cbM2`V%q*VpF2lWRalhYo{pYrl zNt&CfgV6Ld=nxM5sL@#vK;o609Nn^;Wc({YWh$<$A(nmt96Rp&5iIyd8vWx_p+aa0 zG=jH;e*%8+kD5;u_Lp%Ru_c2e%#eSDc6F>fI)DJo`R7+vp=srIyiz2v^_z;c-E?#6X6HiwpOd_Im)xSH+dNCr{J zzWNqVQNT>(BK@Q0eFiS{g{fCE_B(>9JJ;nv6yNxZMQx|9rAX)8h;ROC7Q^?7l z#nnODE)azfIWsMzqL5-Q07Yr5;ih}k+~{4e{IW=Ag1xrb?W4q8n0~pkanjT)B?_%~ zFB22`3BS}(L=CJ-q%P3TKNUF%*_hXjv~t(Q$kvtJ(Fw&inB&lgJyTZQYiIF7)HUTR z9q`e^O$-vxKY`d^<$sPhr0~Rq5sGs09XK76tbuuo{Fzub(-HoR9u%DEeVMJ@Gj*eb z9G>8k=5z&(djpom9`}GZ6#@Nt$`;;vbjMzwNY{P7UqM&vyWe!Z!jF74$v(@jm(^W$ z`J#6Jnrj|}$Whyyv7vY_zy^qWWA5hCFoK_DnxBYzG(`k%&XPRzs;tI{1*tLLv?*L3 zoTL8nu_!vUNZ~-B5 z6otGo;pTLCpWr%4!!CN>7@}0_f&ZV(a{VcTLs%+<8iBDU1EvQyNr|M%X;+^NN8;b} zqobCpzfjoGK^0tu&^nOKR9Ol;)q6r}q$O4Zg&$slj&g(*bT8Kma-u9Rm4A_#X8(X> zQX@Rt4DC|Cg8|(M9G9Elz;Cf}bn-WpVWA*c!Ie=cP8SBcIOkwRjZ-D~@+0vkXhGO> z1oX@Pm7S=7SIMpKKFxa;h7cwc0GdLTDY|N{n^uXDS#06;^S29tO4BVpi<7~r+y;je zo%$}o%Bw{Fj9!j&#L+FrWiYRbn5&|M_FT*d4HU5riw?$uq7uJ=-`oqwXUg~FcICcX ztJ)iN+sGm}(GZ2OU~{G7R(naS!c!!B>m%1c@)Nr>2%A;=6_pLMHJ%sAh$^Y@Ryf$F z!T*vpb)h&2LyMLR)+2Bjt(D4}wWOe}dC+^|+Okj;_J0i@)#{M(1H3rBH;_ zMA63`sR9jtDDv!U8S@NL%?brjGvZII3H$|rCX~z{$4H|G>*}1n=$)&CEQuS=w0er$ zCWr#(M$jdNu_Q*w{{vK|BxC@if~O`9AM>^jSjh|(@nMkg)}NP2M#=+=4x5F?04u_j z$wsEaQy;gF;elAZlJC*1dCIE2Yq4}G67tbvg=>++e^t2;lZOn@6?Bxb+AP+O=e290 zZgOz$@G@T?^fdrLjk_^5bOixRzJVNK?h@9NbweQwk_K`*+;8oMi#b-G(a6BUap>ur z81gJFHNyQ+b(y4GfI?x^Wg#f4Gp|YEDfFxG0t)zaNLu(p(fte4R<@UdT3Z2D{dG37 zZ+!SG?QN*!{+h=;&_ml~B5yV}?lrf-#N1$2^5yq0biC)+MnUX1P$5qc4cK9~J77wL zg98=Kto64rjs1{t$_kDwShY!&1*H@EK?XH}9RRuyz|ok3vtA03vp$O?fr4+}QG#Qo zsqKQxhaNfIhHDgBlK+lxS*Tz_5Zdn%OmKEL6@wL6|2AoH zuar= zFM~GpyWB4WEBakgNap(!*MBZj5}vQMK;PFQtj(>eIbgT?kH~HVB%Q;3#p(8Cjr+J( zo{LR$)ww$l06YmLpLOc=1B&cz9iJXd68KjcqiXl*^BVU7_)-wvp$fQNdhl$bZHRa zw@?*ZIo47Jads>&8ti{0hzj<){}&>_3F(j>16b3NjShAO_}bumTjW1G=teKTrj=}6 zqpcMcWbqmA_z9n)Yz5yZ{9lW!;{E?1NeW_hrZOeWl^WUh-=z}*9S5AB84NEn%vf6V zseU&xL0X)QU;7fy!N8=O3i?ds!(0aYyWn`n;O+W{-Z%e)o2BWOrf=uwGMT8QqwFlG ziAy%$RejF?3nhrwxT40amP!I?aY`97Jgg?I0Fsc1!t$kNg*n`%gB=^~UH%JpPZwJQ zOXb(ZK*&6%F>_UjY=K9z_uWeT|ORcCdP$eL)JI zxCWca0vSLLgLBFPX)}5Qx0EP`@LnnI@gc<*L^*N(-JU{(jyzsm2zI%|AFlsLBt-69 zzFCQqnX`0L|5j$YM~%mqQqyqxtqk~cr)8#GtVP_H^1))&yPfPbF@m71rl4s;il*}8 zn*W3NELEn3Lo4IYG;FDrW~s=zS`(T4#N~q2?cOk7pXv)z-{l_2397u>=q-XFdL+X& zODQPsa>%rpFP%4#uQmf)>)5DsWRu+Zw9%;sM(A+g!NFU00fDfz=SkNf#j zb|wHE`(Bjz+Ouv;@)L;&`VzKG3>Fj`B?iJ21!&=if#jeW1KvlW(?ESEtzWMvf z!x->+8~^GunHr9Kcxv?8pbGjROyBS@>&pjGNo)%lf@-d4J1pULSokLEDuA4<%uABC z?|P+EW=}4J?HyT6;{3xIo5dAJBlgJbqL_A{5!ZdsyG&*vxJ4w2Xvwh9UO z5p3MqhTLCeyISi>ZfBYEcsU_(@qSh7>lF(cNweTMVW9ua)27q6@Q1MZOb zN6e}zA>T}{K6V}1$5!ap8DycXC^;@gl-Om-t07d)>9^v^?`Mm7q?cvMhs5GLeg+Bc1B)Gte!P~@(EfJ z`r30(73#b^9sjZx?O^r7um;anUc(T#!ZM^?{4+Ok*n^o|9t)qjV@1weH#Of9rv;+9 z531tz9t@GAkx$p6ldrBb3?_1Vmiax>B+7W9BeH>?Byi&ruB)i7%u3>sKk+^mYKy@@ z9G8uC%jqII-dE|6ql=k%r{fq61w5@}>;?NW&+oviTq(4l;sfe#naDbc+LYh6f~=sJ zGeDEX55tG6b;!Sd&SNGN5ngYHT}wrvTn(NKHxK$M6AFzlwqB@q7xH>a-nvGepn-zu zE}C)6S`ih{rLC8|F1W61^;9ayJ%Y4}GP+%GF!rbd0lH~fXZ*^Qf}OG4dBD7o^6&;7 zuvExMk#(yPF=bN_6=oy2ZIkId9@a%gjBHzy-#t8{2k@qSnoP-pB4?{u)%+qk!~kOK zxd8c14ZEsAX^HXkuztDQBAI)>n$27gmgq?+u#}AwP#3{c&s!CiKkT?COBj}Ugaye< zV3M5$5YZAX&}zBJ+PPeCbsR!i&lNxJqYU=q_#mntQwrS_JyQ5=Axqi?Zm*XAJY=#kvgSjO%qYmsc3emva|G_c%k1 zhK}5aT~olYK=j#Ijv#nMtU9mRNu|OI)`m)xCi`Y$KL0i&4(Gi=|Lxnc>-_2^w08bk z+Pa^)EbH!bX6%Una>~Q(uP1MnH*9(UUjCKB_M@Lc9d$(tIf-P@8h6sdSL+FR1y~lq z2Svz5D8G3U6b-bzayPQ2manfm*Fa~`aYyg3TOYX%hC6ME-wOV9;>lF53fMahfQiD) zNK1l?pG6G@yJ+(VJG?sh%4l8**bIfEd`rH@06 z7}KWMnpzR^K7Q|(cJ38!>F<7S9RV(|;#fTdR!Xb_5$RrOy6c>{4)_DjXE(}I{hc0)LRDNN5rnkw0z0SX z2`1u;%7Qc`k`lpUWE|47a(XG#^~t`!IGQT%xC%_s^^R^h!N)D%UYRkGse9e>#eKg| z`HY0LKADw1wP*f$BQf1eyiS)G@&A}!Y<;c>V0!q=LNsQnDVk`g5V~1273KCAbh2Jz z69~Y>qTVm173o9Oa)+0I8n%tznHv0 z@P-Qu5;J4X)x0OHMcK3PzPzn++DAh${c9d`>!|avdsf4cr}6PxMJ7z42C|FCKwm72 zE6Q%A2}S5+!6C7T4Y0EHKVle8I|Y=a4u%M6l0)CW+>m6{aAX_n2Z4TRuT)6mKWo-`mlr0Xw|Of)H!k_wj0W*iQq>e2!Iw}EKQ|RmVR;B z^-`iKHHxm#)x*=`Or2<`!(WjexU!f61i-m2d9{p?Cvew0t4Co(kFihdpEEl-4Ve5> zH&vhT)Ou2s?D^GiG_nB}4jxgMVkKLZr;9Nuh>kt9*)L+Eb`PJ+JE7~;{wtBUkblCg zPq*$6L~C~&JdKD!TFL9^LTKXoweJiSEiPM5WR_20C4VD=v9Ul@MpwNICH1srw{}CQ zG6qYK_p1DEt7AoYCL_~o@2+XJcv84mR{{~99T-+yQ9S{wcXrdD20vL+2JC-n_l8bqg`c>* zeMbNkryuo@&3Lb(cDnQns>r7eOz4GWZSIpqe$quc)ti!c{**Ek*UO6 zc&`4Hc>_Jda1SvZA^ZC%;^dn6=#9CTjY0lB(=sMo%iWVKJ+?meVLPXi!Ct;c^W4`N zj0;3B!0;l&m#s!$lr7Pq&N;y>3&_i>xdh^7i_HeTS;u%W#cLHN6IXd~=B=}-)w_U? zSF`deue2cQH*UBN*nwPyDZF!2xf0F+;WlJ_W$iPFt4@*yuT>m0@pCBzWMpH`R9W`Y zqElaIyE{yPX;hK}?h@`t-FVd^T=5%l1ARH77Z;=Y_-SzOv<*cE@+M5ZmM;@cuQ-94 z6Drbc&sS^un|0V3gN$NVPE?;6im6j^-Mo2t>^jx#tx1004{tWqU}|gjNbfG)WpEAE z`WE@FSS`30kz@F+SC*KEBQ-6Y#|DcGpEcoKw>C*^&4#NZ#0s0EqsQ+gkGv$JP2Sbt zT|v$t*xf|;B>MM=_zq^8$i{Zn0Gg2XmOLIH=g3Gy?iZ}Z)`ZubUxvv!-n-XCqea0R zl}QqyoA~bbn3bB`G414Kg3r^gI)!uG;~pa(629AjxqMvy5aH1Mp}4h5Q#{zX5W3_f z#WFcqV9ac{P#=v41W3u)k`#`T)qE`U-n7`KyhGF4r&>q%iOM%|ZpFxJW*!0+#sL#- z#n0K3y-$Fz#0oxaIlie2rPt0>hnPqFKrL@-KbVuC!awECmp#J>X8K^Dr^3Trlm3{7K74|9r%lhuZ-*p3#{$ld7ht|oX9$tUt{OjHT zC9URt=pq22SQ8!%ou!)I4hEseL%S(Xa+S;OM5`n~E7l`$=duehLGSzR+ZuHNsS255 z67vESOzb%WiSXX=enk}@@p4cvBJ9Kxd}DLXw#RUMSRb!^F*fh?b@u)2?(o0ArfU|8 z7IXliSgHSB&gWoGYwoaqI_f9Cfq5ka5iluK1dQ9w9q@X-D%x>Nfi>Bw$gCv$PG|vpjwN{ICDV`__jBuj{U7P3HJT*4 z1r(X+%U@_~zr=eWYV^-kNr5voKT~SkXjkbqt~Z2^9{iklc-0b*CM%jM&3^OJL+zjYb2`%Fx&6!~^Niu?^piJN%g_6azI;$^YYrqQOT^W2qX;>~kvIxs(rf zl+VxlxRwqXMa(GJuP+(BxniAl=S7G$a@ae3E5*azy-QXnT_t>}eKjxcypL-5k0&8= zGg)2G$xbw{^J!gPk*4Wm-pwEOHsOEga%!Lc)w~|w&!&*_cSNq`NoaaZ(uI!-O$uMK z>m$RYQsYWK7Yk)ZE%L68skhQeW$-gW#`wc0dF3O1V%@W>=!$OW6TH=A$?Qsxz!DRR zA=I3D)A$LO#0zDfvEbsRErwUDt=Ajxu~Z8wu})gBUrewB50g1Hvk`>b`HZe|2Z|fH z7^{ppL7RWNvNJmg(XRb3HcI)5f7n~woEnj}29ye?jPRt})6hQ5@a+v{kpi%z>*Bnb zMrfJ)2E`%+WW;P&W3#e!FSS>nGF@+)-RnGW;G)}9El%_}+^ZWskRnhN92vxDm9!N9 zBJqaW%j6oE-;JLwu^C_&$1i|zt4u*%KxA$XmB0r44Al422U?;LD$*#H*->anfFh;?>(KqC$BcIVV z(V%TgoPY?ip!JbpmU)|`1N&_}UbdGSd6UmZHmG-N@HBa$(ZP)wT3m6L3$HihLEky} z1Y$-WJhcUTNf4KPTMSNP$)d95Pvh#M&qB^A`(SZpb;OgCVZre+ECAVbOuCBwasTye zuB$m*58uDf+ca2wI{D&slVj_*?|4bUf-Mj4C#_Sd*^6|*wA{Wiu(#;frgrw2!rHs> z{f+*Rz@F)YqP?|u-*>sSeE7BEks8lazy9^{mU1g;G=8X%gTCDt+3U+ibnrVvE7JY5 zYyMizw%>lPsdjVc5N~llu%51zC{>ia{3~W8NJCi-u2cWva5+=7X86wZ@d3@dFNUpz zpb`dL{f0cwt!XK-#3&d=nH94%QPQ(q7I&VQq<3E=rg*x_op{M#UpoZ`r9JfeGiJOM z5bx(ry7?V{tQ)s0&wq^+ar}w7>8JDO;r)k>q`Q20b+| zuZMc@<=-&P?RmF+B9oai?W3^SUj^2EJ+fyd^*=}DY7!3I^u*?+^Lwt5`!RIjz+Zf- zf&ABpqj@ctS_+Ysk?g%!qHtTth|Gv6 z^CGgk*1h+8ZtwT!^Zot<-`6kP*F3NDI^#JWkH^7mvuNuIol2lX2SOY0ivQ+9>5-(D zbd?;EJE1%8*}Hc^`|q@X*Q6ih%-LInxIX_uBlEQH`NDJM&9fD5=(CTiM?=@94v!6W zk6Vvo#9E2Qce|jW!qRYfdPC(+LtWf;>&Kz8(8!7}>n09Q7_PaL0E~Cn?_^72Te_sKlMUAAj5+#BVfSuUn)qoA53FsX~2C zK}~GKyx`Zu7MO*xj=eAJNHo#-3DG5zp6PLKLVN@I^so7QeJu+9x>AFD`6lStjAFD= zG&GFP(1Ne)Z96P?&pjzEag;qA)Rm_-@f696SWDNG@KYK!C$@(pwO+>B^sSf{knas% zMYccg&)>jKggh9c&eh83mmMYq58y7;?P&F{Tsc{iFfE9MDWjxpgDbW_ni}d%*3Wia z6v5E-EQ?QX7KD!8lM_oWali((wZ1o8>izXV2!q6-y?r zl5Vb;uJ1`YJVb*&v+KOcr~jN{nH(s1@nk=UXnpd`C*n-6vj@Zsmc#7(Qa}MFspWhk z9zx}lZ5JWq;b(xQkKiDs$0A7;u;yoFb`w)wl&Yqp=6mV>bNsA=`rAu0u(s97y2g4e3OxZl*)##GB(P-@{9`GuSzwa36jj^5&S5PM=&@ z)`E=Q`Cgq36!sj~IDgV(1aaS0K{d!F_>uTw?+QBCS~L=^nP; zJ8GNkASnzDI<(fmdym}=xmsa8ZeMpxed}8F?sf?-6N@W>Fq)*!g1Lt>O z^ZaD&K7VM=`0UHV0Qs@izH7!|x!H^A?EK10Fl0lcA~@W#Vf1uu68yeVVkSKl-IDg1 z>AT%Xyce=cSqz2rv9UkJLm(k8LMLX%)DH(n{>S9HbzeLIfRPh$O*h+??=A{tEoVA~ zgD0;>=U^dh31>zY;EpG;_bSD&Fmg+`Mqm@3I#(#j%R5DeWe0D*s*qNaK5nDzE@Ac+ z0X7r2-h6MKqHMKchG8R^ULHl;3cGY?6UeEQ4sq@q=|6%_&=X#i~z5%&7p3`XQdk4ZqE3$X#+8Y;N`Eato zXw+a=epB&B7E!A>8%&Y8e0$P4REPcxtwAUa_ByA+JvCfGZ2|c<%8oY>E&-+E?4s@T%aSU&%epTVvCQQ zJSWc?{F)>dj+oIf1PR}vR*|}r9Zczq9QU%{UD5XX zCulQ1jauZC-`%3%2K{ewYgWJFe0Jtj%a#=ee?k;CSF;lN zjCf6<4;|Pze`tKab{M{-VtcVvhV@AfUsIsg{WybSCi2UmjKaG|L5KT}lFB@VvS@!X za9s*Av}$*uQQ6j7iiP9=m%0tU8;ydUY&wZU1ls_=>n&nU&L?8f09_H)oRr?`A#0aV zQf`+{FZ48i*^(*!6nP#Of=SlOLjuUN`d8{))^C)y+YJSjj3!<0)+?&}W<4fm9MBx8 zr}9eiJ)wVPmoF|3pV(EZqZr4QIj(nG&pxhpdL|JLV>Y_GJJ7sP=A@T=a=hxWt)JT8 zD-Ifwp9NF`2>y(H!02hri!K8k0R1HGbc*;U#($fL;j65iUi^6GI{iF$X>nrjGAV5$ zSX1Md-vJcx(W^I|Hl4cqBv-U%hwJ9gO(}b;P~yd5hV>U~+dUhP0G{~Fi@H-oRow2! zd7b`#qw$_6fgmQH*|KtTNIY|yn zn>CwA91OoFi{IA{dy2&?j&4vFSulPR+shM-n{OdUjUXbIFJHUpC*-y?(W0yx>lE5V zT4p4^tvqPlt6ebN@ypdNu!kAEU50T<@gCXy_rJ+ zpb>6ig8El#20D?+H9mM289!TYv(@@63J<4nJH;|1XKIf& zyoqYo;wB8R#Rp#SOU{g^!V$Q9^JLCS%?>-{IVBIUOuzxkT9_qU0Y=%+GUmlDq8eOL z$c6X}%A>$_nx02Sulz0~W}u#z)m>5AcdV4nWqro@#=@b>8kfsSGjScHAn5U1$FxTK zfXOQmJAU1`C!5&1ddVNR<`~DTrf4H6ticNQvp#)YCwZAx`}^s=94F9XRygSU16SNy9__D3WxEv10O%)d+Y;c_-zhnx$b`b zsZky@_sYSAbP7~LKMJz{j4V1{2SM=Y*XA7vLmtNk?crW~hfD=6&q?jY8RL?l4|yr6 zP=B(Az9^$lO?~kOn#hlRWXtCE3NYkzi}&!N@JWS_cIfW+ZYG+o)exO?8{hOEex@YY z=LT7IoE>A#Rox$Yi zyK7Vtn|e6$97ksP8+hqqO{}v_@quwT!)zu2@IrD!0(kAkuxGR@P~_C_9V(MAsG%DT zXJ?9K<$$a)g3tXkO1+8F9GQ(&m*U-U(ay7ng_Qu|y?RQstU&rr_jN;XSgXJBLQ5h9 zDXKAawKGHZvYQ9%At~!rA}+m{EE&>OncJncx8kzXq-<=b9SW*0cX*bxOmP zk25`E%Nn2)%dLxLQg+FP_ctP*l(BQcrKR_xTz~YS%DynK`9pYEi0pn8p?)FuPV& zLSF8@J1nLwsE@C=4~Gc&-E%&$53q;__Gk8A^vX8tDfLirx*YL%h=(06f0s^J#1_vx zU?Hz$-iQsz;T1}ETnV zFTc{Avn4`KZ~~Hu?r17C6i?i#@RU@b>ZCMJ!0W%(xI>E>vNx{Gt&V``9Qua}6M|jk zJ#+}cBnDBNG3$||=4I3?dSb9meAp5Ng{HnWUI5E?JUtHS^b9xQPq_Br68?4UJ|GvX z@O{)zTtyir=meGZD1HkS3DjgdaCZkHpFm;8%;T&xfC*$qZ8X()G4(33LmDfPvx*4A zE4Ics*Ep4lZN(1nlyp*IAXuXGs(y~En(ht;+&5GKW>ofsL?ptd-YOy_#8TlBBTzQh z+~{5v8rd7*5DjT6tNRtQ-$Y@zAxDz$Fz4laEuUQXo-Qo8QW$}F4xw`8m~`Wum}4Yf za&inhaQb@Y@;>nsSGbbdz*cr-roy;Q#C_~LCds$K*HNOAS)5d%50A!HLaFW+_mWHi zwwpR|>pA=iAJrVeNEGOYmYMsSffZ?&u=bUQ)2^5>ixG#mCP6i@?%8V))H9CdqIj}%+@6!Beg;&A;?(cMD1 zZ!$X>X+TXm$qH7#IzN&Clb%X@&}TXdufe*80b`Z?#*M|=%VGGcufy)#`rG-K)@^d< zCn5%X{5?>F`Lhp6IL?Fw+UomJuTyT6^9~A9ojm|HUQ|I^6r845T#CpqL%7c72AJd=0k z0`z!4Ka%HEKg!vU9)i4>QsnT;_@t_i6f;3=EHaTXv?JLfou!v%jT42j;leExRq z4m+T)W+u2#<*>#osAG>nMrMzvMCOon1fv?rbb#}Asx8Sdl^1Y%L#|=XTqbKT6d6Dw zMAKm&sQM;mIbM*2AQeAf#!PTIkUn>1`iu_E4&bEDFW<^J4X*mFKL~^ue=W7mlV|BE{_F8v~ z0mY4Wy7;dFBNZeYB)YxQT`2V%*i+#sVJ#bWQ7fN|**x5bG8%clarp@Z7^0=`qOpg~ zUZnjHQGku)`Lmy#4^$>-bCH2fcSZV56?yub*&d*4|frxm8pIK3-A#v{(MBO@1v4qX^?NruO zpGzZG;4PSjZ0i#z46d}oSsaGj6Xy+m^6PXX{zD%az6YGKpr(6iF4)E$Oc zetfU!j6FXU2k}-l)k#K3VDtO{h+t0v*vWRLIl&JaH#wF8xrP@%(vm} z-KWSyT1lrf$2RyzMryjfpu6PUk9p4Kd^X|n7asWT2Zz?}G%}rWja5gN&R_ZfFOOYF zi7a)pV;+yxet3xEtTvkWhuc(z4YgeF!XHNLscti8;cN{K5TR?0MBHs^;qC5)fyll* zE*E+E$Op@Yjf$)mk95PdKTP{mWIXp=gjmovC!sytc|)%0?_v)$oCgXpeS0p&M8Uk>HVM6l@tjkG(k!ClL1U&Z>{ zCn(0g9m??21NcIr7NwVMr&k0BuhqJ^e_6F8p7r}v38~LkZ>0b%YcdpgQ1U3|x`@US zDM}}^`p*D|a-LMwkWdd>rgP)lgqiF!UlMlCiQO|5D*b%tF-#GoZ!@EmO~(cNgpPPo z0!YdotaP9fou1T;*^VqU&7F%^d~=e==$PL2@GK@TGb!z}pY`|Z#A7_Ge7j~N6A1Ke zJw-E3i)SN7V#sni$c5(4#@@Q@aq_!st|oC}VJZha3fw{4j_!%)XmLuJuz-lr3>4^t zzNQYI+hC!$n3H5wG-S%3>EA~O2*LSu---0dqwny!dCl7avQvQQ`;09dVAWq)E(g%0 zBPykIgl-B6D2{^vVgU@I*ql#7Wuh*T87w}HbH7o%{l|;))FN-n_$8=Ynp6w>*TI}d z4ck(UydU(9SACd~z)EK!3@CE$zeBOY-8LL>KDcURF~u1|YNWM2Vs}d@j+b5spjBXv zqKMa;mK)37oqjp6p<95a8zd(%0*GeC65uF+8eh*pQ2Thm*(7@Uwa7!m5x$OJ->Q5s z_f?p(N*;>f;|pn;U7>MHvDvkEOc;lI`4~)~(vOwSk9FZ`lX`6$Z)lmupbR6@wS}=rwEa(* z)BP4gPQxvRuBXMk9-$SjU#ENAyJ0zXsrlI{CuHH3f9ZslK>zpT)fn6?%K`i{GzT#m zyUlMFilv85qOaa54cf#t$b0miwl;g%4a2D;-cK}=`;y(2dP1s(&(+s2t)Ps!i(7`@hWejm zOIg4qK82!@>b1r{2EHcA53-P(UmYCLE_1vvB!r+4cXN-iiuHe{8g23*@_l%ric3N) zw>~rKzUq*6Z4Fi33zMk1AwRKCeF$@A43{RZ^ z4xi0TC(MaDHykf~z5>^Z%v{BZK~`814#prA&jg2?;<~iXK@T=_yXnUiNNw8OHYKF7(`)9&eVXM+1SNvzK#!#_c5 zl;D)UgvD52CH5&%DSY<6FsL_acO)eG^eccr2?w$s`z@#2XNq;t&Efva zj%cPP6GO{(f8Ih)btdV-cZj3@UZwtQ-i%&xnqU-`_<0mEx^F6sbHGTd;#R`hyapob zemT6=O!BdJ_2GAuQ-D}M%2H*#><3qhDx}-K{*z2WRl3SH_C4R=;ht=JfMP9jY-wN(rKuBowJNs8>rWw!sxvx{ErK(M#c#(yA zJgPD1mDc7lNDXtb4lYcL)?`x#nadRB=~BpCy-bs*F@LlV5Loi*pqPwRKI3a^P83Ym z2zv0|Nlg<0nQTyw+ixp&@kfK?n}UzpBqD@*@XmdSBPlU&u6K3tu7q}tZ^p1UWGItl z8+Sj{L)<4w(wy2#h|7<{SA_l+e>!tzcqQ(6hf0iVfD&iy~ z08OXs3FLo{Ljd$+A0HX`+3k*nb2}8s~de}-Kx1mP8X>Os*5;z;EhDjPeHvb zPl_?rPy$K%>)V5GwH51l3a`fTGM*aegfc809Q`VS`ODNz6EwE&k5g_?)AFvM(FY9w ziz_3+ERGZoR3IGe56D*-lScn1%!Hyk7hfP)dhb42{1#jjv@%Zpoi9AaNh>2WoGM<3q>(uNC?C%$mA7v>9kOsMAC`|jUIL#ZO;Cut_*Fl-ey ztKWSQWyZ-2bmA2V?g!IMrdk3MPtKR^-u)T^Sffs{gCP}zX^{iGBqL5;bpiyx=;A@%xFD^qJNX*}NhNE3${}HY2 z#9tQ@1i<_3HAydbNB!N5)Sb%M%ug`9D_nESyua;upel6U8mqf5ppQFVM*`_X9v1j; zZkSi@C-#I0A5?>Z}=ho4(U^|koOylv;zo)qzgeyP9 zCuh@6jqKC8EPxnyz$rpd=381hHq*qe_Tr9hKL9Z&5qGEn0In(>N&GZyK6yM;t@h z&6Gl-!V+NzPEkB!Atq!BVv%Ry9cN&a`n3RtBs=_e$A^~5$=SULli|xFv#FLi!Os0g zPvD5BI=Y839bbU}1WUgo*Uovt+8Lgs&5B9EQfEUJrX)0AdTAu@_2LP#A#TSv=`jb( zxW^%$>RgQ{a1g9<{UPLVz%+^p#UUYyWGvpzc}XheM5j|e*1ksKv*#Nt@^KyIPg3;8 z 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 De~rmR diff --git a/Fabric/src/main/resources/craterlib.fabric.mixins.json b/Fabric/src/main/resources/craterlib.fabric.mixins.json deleted file mode 100644 index 7c59043..0000000 --- a/Fabric/src/main/resources/craterlib.fabric.mixins.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "required": true, - "minVersion": "0.8", - "package": "com.hypherionmc.craterlib.mixin", - "compatibilityLevel": "JAVA_17", - "mixins": [ - ], - "client": [ - "TutorialMixin" - ], - "server": [ - "ServerGamePacketListenerImplMixin" - ], - "injectors": { - "defaultRequire": 1 - } -} diff --git a/Fabric/src/main/resources/fabric.mod.json b/Fabric/src/main/resources/fabric.mod.json deleted file mode 100644 index 47a55c0..0000000 --- a/Fabric/src/main/resources/fabric.mod.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "schemaVersion": 1, - "id": "${mod_id}", - "version": "${version}", - "name": "${mod_name}", - "description": "A library mod used by First Dark Development and HypherionSA Mods", - "authors": [ - "${mod_author}", - "Misha" - ], - "contact": { - "homepage": "https://modrinth.com/mod/craterlib", - "sources": "https://github.com/firstdarkdev/craterLib/" - }, - "license": "MIT", - "icon": "assets/craterlib/craterlib_logo.png", - "environment": "*", - "entrypoints": { - "main": [ - "com.hypherionmc.craterlib.CraterLibInitializer" - ], - "client": [ - "com.hypherionmc.craterlib.client.CraterLibClientInitializer" - ], - "modmenu": [ - "com.hypherionmc.craterlib.CraterLibModMenuIntegration" - ] - }, - "mixins": [ - "${mod_id}.mixins.json", - "${mod_id}.fabric.mixins.json" - ], - "depends": { - "fabricloader": ">=0.15.0", - "fabric-api": "*", - "minecraft": ">=1.20.6", - "java": ">=21" - } -} diff --git a/Forge/build.gradle b/Forge/build.gradle deleted file mode 100644 index c839fb5..0000000 --- a/Forge/build.gradle +++ /dev/null @@ -1,112 +0,0 @@ -// Adjust the output jar name here -archivesBaseName = "${mod_name.replace(" ", "")}-Forge-${minecraft_version}" - -dependencies { - // Compat - modImplementation("maven.modrinth:vanishmod:${vanishmod}") - - // Do not edit or remove - implementation project(":Common") -} - -shadowJar { - from sourceSets.main.output - configurations = [project.configurations.shade] - - dependencies { - exclude(dependency('com.google.code.gson:.*')) - - relocate 'me.hypherionmc.moonconfig', 'shadow.hypherionmc.moonconfig' - relocate 'me.hypherionmc.mcdiscordformatter', 'shadow.hypherionmc.mcdiscordformatter' - relocate 'net.kyori', 'shadow.kyori' - } - - setArchiveClassifier('dev-shadow') -} - -/** - * =============================================================================== - * = DO NOT EDIT BELOW THIS LINE UNLESS YOU KNOW WHAT YOU ARE DOING = - * =============================================================================== - */ - -unimined.minecraft { - minecraftForge { - loader forge_version - mixinConfig("${mod_id}.mixins.json", "${mod_id}.forge.mixins.json") - } -} - -remapJar { - inputFile.set shadowJar.archiveFile - dependsOn shadowJar - archiveClassifier.set null -} - -jar { - archiveClassifier.set "dev" -} - -processResources { - from project(":Common").sourceSets.main.resources - def buildProps = project.properties.clone() - - filesMatching("META-INF/mods.toml") { - expand buildProps - } -} - -compileTestJava.enabled = false - -tasks.withType(JavaCompile).configureEach { - source(project(":Common").sourceSets.main.allSource) -} - -/** - * Publishing Config - */ -publishing { - publications { - mavenJava(MavenPublication) { - artifactId project.archivesBaseName - from components.java - - artifact(remapJar) { - builtBy remapJar - } - - pom.withXml { - Node pomNode = asNode() - pomNode.dependencies.'*'.findAll() { - it.artifactId.text() == 'regutils-joined-fabric' || - it.artifactId.text() == 'core' || - it.artifactId.text() == 'toml' - }.each() { - it.parent().remove(it) - } - } - } - } - - repositories { - maven rootProject.orion.getPublishingMaven() - } -} - -publisher { - apiKeys { - modrinth(System.getenv("MODRINTH_TOKEN")) - curseforge(System.getenv("CURSE_TOKEN")) - } - - setCurseID(curse_id) - setModrinthID(modrinth_id) - setVersionType("release") - setChangelog("https://raw.githubusercontent.com/hypherionmc/changelogs/main/craterlib/changelog-forge.md") - setProjectVersion("${minecraft_version}-${project.version}") - setDisplayName("[Forge 1.20.6] CraterLib - ${project.version}") - setGameVersions("1.20.6") - setLoaders("forge") - setArtifact(remapJar) - setCurseEnvironment("both") -} \ No newline at end of file diff --git a/Forge/src/main/java/com/hypherionmc/craterlib/CraterLib.java b/Forge/src/main/java/com/hypherionmc/craterlib/CraterLib.java deleted file mode 100644 index 968da05..0000000 --- a/Forge/src/main/java/com/hypherionmc/craterlib/CraterLib.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.hypherionmc.craterlib; - -import com.hypherionmc.craterlib.api.events.client.LateInitEvent; -import com.hypherionmc.craterlib.common.ForgeServerEvents; -import com.hypherionmc.craterlib.compat.Vanish; -import com.hypherionmc.craterlib.core.event.CraterEventBus; -import com.hypherionmc.craterlib.core.networking.CraterPacketNetwork; -import com.hypherionmc.craterlib.core.networking.data.PacketSide; -import com.hypherionmc.craterlib.core.platform.ModloaderEnvironment; -import com.hypherionmc.craterlib.network.CraterForgeNetworkHandler; -import com.hypherionmc.craterlib.nojang.client.BridgedMinecraft; -import com.hypherionmc.craterlib.nojang.client.BridgedOptions; -import net.minecraft.client.Minecraft; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.fml.DistExecutor; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; -import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; -import net.minecraftforge.fml.loading.FMLLoader; - -@Mod(CraterConstants.MOD_ID) -public class CraterLib { - - public CraterLib() { - MinecraftForge.EVENT_BUS.register(new ForgeServerEvents()); - FMLJavaModLoadingContext.get().getModEventBus().addListener(this::commonSetup); - } - - public void commonSetup(FMLCommonSetupEvent evt) { - new CraterPacketNetwork(new CraterForgeNetworkHandler(FMLLoader.getDist().isClient() ? PacketSide.CLIENT : PacketSide.SERVER)); - DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> { - LateInitEvent event = new LateInitEvent(new BridgedMinecraft(), BridgedOptions.of(Minecraft.getInstance().options)); - CraterEventBus.INSTANCE.postEvent(event); - }); - - if (ModloaderEnvironment.INSTANCE.isModLoaded("vmod")) { - MinecraftForge.EVENT_BUS.register(new Vanish()); - } - } -} diff --git a/Forge/src/main/java/com/hypherionmc/craterlib/client/ForgeClientEvents.java b/Forge/src/main/java/com/hypherionmc/craterlib/client/ForgeClientEvents.java deleted file mode 100644 index 2b9d5cc..0000000 --- a/Forge/src/main/java/com/hypherionmc/craterlib/client/ForgeClientEvents.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.hypherionmc.craterlib.client; - -import com.hypherionmc.craterlib.CraterConstants; -import com.hypherionmc.craterlib.api.events.client.CraterClientTickEvent; -import com.hypherionmc.craterlib.core.event.CraterEventBus; -import com.hypherionmc.craterlib.nojang.client.multiplayer.BridgedClientLevel; -import net.minecraft.client.Minecraft; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.event.TickEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.common.Mod; - -@Mod.EventBusSubscriber(modid = CraterConstants.MOD_ID, bus = Mod.EventBusSubscriber.Bus.FORGE, value = Dist.CLIENT) -public class ForgeClientEvents { - - @SubscribeEvent - public static void clientTick(TickEvent.LevelTickEvent event) { - if (event.level == null) - return; - - CraterClientTickEvent craterClientTickEvent = new CraterClientTickEvent(BridgedClientLevel.of(Minecraft.getInstance().level)); - CraterEventBus.INSTANCE.postEvent(craterClientTickEvent); - } - -} diff --git a/Forge/src/main/java/com/hypherionmc/craterlib/client/ForgeClientHelper.java b/Forge/src/main/java/com/hypherionmc/craterlib/client/ForgeClientHelper.java deleted file mode 100644 index 6776622..0000000 --- a/Forge/src/main/java/com/hypherionmc/craterlib/client/ForgeClientHelper.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.hypherionmc.craterlib.client; - -import com.hypherionmc.craterlib.core.platform.ClientPlatform; -import com.hypherionmc.craterlib.nojang.client.BridgedMinecraft; -import com.hypherionmc.craterlib.nojang.client.multiplayer.BridgedClientLevel; -import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer; -import net.minecraft.client.Minecraft; -import net.minecraft.network.Connection; - -import java.util.Objects; - -/** - * @author HypherionSA - * @date 16/06/2022 - */ -public class ForgeClientHelper implements ClientPlatform { - - public ForgeClientHelper() { - } - - @Override - public BridgedMinecraft getClientInstance() { - return new BridgedMinecraft(); - } - - @Override - public BridgedPlayer getClientPlayer() { - return BridgedPlayer.of(Minecraft.getInstance().player); - } - - @Override - public BridgedClientLevel getClientLevel() { - return BridgedClientLevel.of(Minecraft.getInstance().level); - } - - @Override - public Connection getClientConnection() { - Objects.requireNonNull(Minecraft.getInstance().getConnection(), "Cannot send packets when not in game!"); - return Minecraft.getInstance().getConnection().getConnection(); - } -} diff --git a/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeCommonHelper.java b/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeCommonHelper.java deleted file mode 100644 index 281ddd7..0000000 --- a/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeCommonHelper.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.hypherionmc.craterlib.common; - -import com.hypherionmc.craterlib.core.platform.CommonPlatform; -import com.hypherionmc.craterlib.nojang.server.BridgedMinecraftServer; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.item.CreativeModeTab; -import net.minecraftforge.server.ServerLifecycleHooks; - -import java.util.HashMap; -import java.util.Map; - -/** - * @author HypherionSA - */ -public class ForgeCommonHelper implements CommonPlatform { - - public static Map TABS = new HashMap<>(); - - public ForgeCommonHelper() { - } - - @Override - public BridgedMinecraftServer getMCServer() { - return BridgedMinecraftServer.of(ServerLifecycleHooks.getCurrentServer()); - } -} diff --git a/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeCompatHelper.java b/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeCompatHelper.java deleted file mode 100644 index 34d519d..0000000 --- a/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeCompatHelper.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.hypherionmc.craterlib.common; - -import com.hypherionmc.craterlib.core.platform.CompatUtils; -import com.hypherionmc.craterlib.core.platform.ModloaderEnvironment; -import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer; -import redstonedubstep.mods.vanishmod.VanishUtil; - -public class ForgeCompatHelper implements CompatUtils { - - @Override - public boolean isPlayerActive(BridgedPlayer player) { - if (!ModloaderEnvironment.INSTANCE.isModLoaded("vmod")) - return true; - - return VanishUtil.isVanished(player.toMojangServerPlayer()); - } - - @Override - public String getSkinUUID(BridgedPlayer player) { - return player.getStringUUID(); - } -} diff --git a/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeLoaderHelper.java b/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeLoaderHelper.java deleted file mode 100644 index 2be70fc..0000000 --- a/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeLoaderHelper.java +++ /dev/null @@ -1,73 +0,0 @@ -package com.hypherionmc.craterlib.common; - -import com.hypherionmc.craterlib.core.platform.Environment; -import com.hypherionmc.craterlib.core.platform.ModloaderEnvironment; -import net.minecraft.SharedConstants; -import net.minecraft.client.Minecraft; -import net.minecraftforge.fml.ModList; -import net.minecraftforge.fml.loading.FMLLoader; -import net.minecraftforge.fml.loading.FMLPaths; - -import java.io.File; - -/** - * @author HypherionSA - */ -public class ForgeLoaderHelper implements ModloaderEnvironment { - - public ForgeLoaderHelper() { - } - - @Override - public boolean isFabric() { - return false; - } - - @Override - public String getGameVersion() { - return SharedConstants.VERSION_STRING; - } - - @Override - public File getGameFolder() { - return Minecraft.getInstance().gameDirectory; - } - - @Override - public File getConfigFolder() { - return FMLPaths.CONFIGDIR.get().toFile(); - } - - @Override - public File getModsFolder() { - return FMLPaths.MODSDIR.get().toFile(); - } - - @Override - public Environment getEnvironment() { - switch (FMLLoader.getDist()) { - case CLIENT -> { - return Environment.CLIENT; - } - case DEDICATED_SERVER -> { - return Environment.SERVER; - } - } - return Environment.UNKNOWN; - } - - @Override - public boolean isModLoaded(String modid) { - return ModList.get().isLoaded(modid); - } - - @Override - public boolean isDevEnv() { - return !FMLLoader.isProduction(); - } - - @Override - public int getModCount() { - return ModList.get().size(); - } -} diff --git a/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java b/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java deleted file mode 100644 index f354ddc..0000000 --- a/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.hypherionmc.craterlib.common; - -import com.hypherionmc.craterlib.api.events.server.CraterRegisterCommandEvent; -import com.hypherionmc.craterlib.api.events.server.CraterServerLifecycleEvent; -import com.hypherionmc.craterlib.core.event.CraterEventBus; -import com.hypherionmc.craterlib.nojang.commands.CommandsRegistry; -import com.hypherionmc.craterlib.nojang.server.BridgedMinecraftServer; -import net.minecraftforge.event.RegisterCommandsEvent; -import net.minecraftforge.event.server.ServerStartedEvent; -import net.minecraftforge.event.server.ServerStartingEvent; -import net.minecraftforge.event.server.ServerStoppedEvent; -import net.minecraftforge.event.server.ServerStoppingEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; - -public class ForgeServerEvents { - - @SubscribeEvent - public void serverStarting(ServerStartingEvent event) { - CraterEventBus.INSTANCE.postEvent(new CraterServerLifecycleEvent.Starting(BridgedMinecraftServer.of(event.getServer()))); - } - - @SubscribeEvent - public void serverStarted(ServerStartedEvent event) { - CraterEventBus.INSTANCE.postEvent(new CraterServerLifecycleEvent.Started(BridgedMinecraftServer.of(event.getServer()))); - } - - @SubscribeEvent - public void serverStopping(ServerStoppingEvent event) { - CraterEventBus.INSTANCE.postEvent(new CraterServerLifecycleEvent.Stopping(BridgedMinecraftServer.of(event.getServer()))); - } - - @SubscribeEvent - public void serverStopped(ServerStoppedEvent event) { - CraterEventBus.INSTANCE.postEvent(new CraterServerLifecycleEvent.Stopped(BridgedMinecraftServer.of(event.getServer()))); - } - - @SubscribeEvent - public void onCommandRegister(RegisterCommandsEvent event) { - CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent()); - CommandsRegistry.INSTANCE.registerCommands(event.getDispatcher()); - } - -} diff --git a/Forge/src/main/java/com/hypherionmc/craterlib/compat/Vanish.java b/Forge/src/main/java/com/hypherionmc/craterlib/compat/Vanish.java deleted file mode 100644 index 1727255..0000000 --- a/Forge/src/main/java/com/hypherionmc/craterlib/compat/Vanish.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.hypherionmc.craterlib.compat; - -import com.hypherionmc.craterlib.api.events.server.CraterPlayerEvent; -import com.hypherionmc.craterlib.core.event.CraterEventBus; -import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import redstonedubstep.mods.vanishmod.api.PlayerVanishEvent; - -public class Vanish { - - public Vanish() { - - } - - @SubscribeEvent - public void vanishevent(PlayerVanishEvent event) { - if (event.isVanished()) { - CraterEventBus.INSTANCE.postEvent(new CraterPlayerEvent.PlayerLoggedOut(BridgedPlayer.of(event.getEntity()))); - } else { - CraterEventBus.INSTANCE.postEvent(new CraterPlayerEvent.PlayerLoggedIn(BridgedPlayer.of(event.getEntity()))); - } - } - -} diff --git a/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java b/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java deleted file mode 100644 index 927bd23..0000000 --- a/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.hypherionmc.craterlib.mixin; - -import com.hypherionmc.craterlib.client.gui.config.CraterConfigScreen; -import com.hypherionmc.craterlib.core.config.ConfigController; -import com.hypherionmc.craterlib.core.config.ModuleConfig; -import com.hypherionmc.craterlib.core.config.annotations.NoConfigScreen; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.screens.Screen; -import net.minecraftforge.client.ConfigScreenHandler; -import net.minecraftforge.forgespi.language.IModInfo; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import java.util.Optional; -import java.util.function.BiFunction; - -/** - * @author HypherionSA - */ -@Mixin(ConfigScreenHandler.class) -public class ConfigScreenHandlerMixin { - - /** - * Inject Auto Generated config Screens into forge - * - */ - @Inject(at = @At("RETURN"), method = "getScreenFactoryFor", cancellable = true, remap = false) - private static void injectConfigScreen(IModInfo selectedMod, CallbackInfoReturnable>> cir) { - ConfigController.getMonitoredConfigs().forEach((conf, watcher) -> { - if (!conf.getClass().isAnnotationPresent(NoConfigScreen.class)) { - ModuleConfig config = (ModuleConfig) conf; - if (config.getModId().equals(selectedMod.getModId())) { - cir.setReturnValue( - Optional.of((minecraft, screen) -> new CraterConfigScreen(config, screen)) - ); - } - } - }); - } - -} diff --git a/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java b/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java deleted file mode 100644 index 299f52c..0000000 --- a/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.hypherionmc.craterlib.mixin; - -import com.hypherionmc.craterlib.api.events.server.CraterServerChatEvent; -import com.hypherionmc.craterlib.core.event.CraterEventBus; -import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer; -import com.hypherionmc.craterlib.utils.ChatUtils; -import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.PlayerChatMessage; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.server.network.FilteredText; -import net.minecraft.server.network.ServerGamePacketListenerImpl; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(value = ServerGamePacketListenerImpl.class, priority = Integer.MIN_VALUE) -public class ServerGamePacketListenerImplMixin { - - @Shadow - public ServerPlayer player; - - @Inject( - method = "lambda$handleChat$5", - at = @At("HEAD"), - cancellable = true - ) - private void injectChatEvent(Component component, PlayerChatMessage arg, FilteredText p_296589_, CallbackInfo ci) { - CraterServerChatEvent event = new CraterServerChatEvent(BridgedPlayer.of(this.player), arg.decoratedContent().getString(), ChatUtils.mojangToAdventure(arg.decoratedContent())); - CraterEventBus.INSTANCE.postEvent(event); - if (event.wasCancelled()) - ci.cancel(); - } - -} diff --git a/Forge/src/main/java/com/hypherionmc/craterlib/network/CraterForgeNetworkHandler.java b/Forge/src/main/java/com/hypherionmc/craterlib/network/CraterForgeNetworkHandler.java deleted file mode 100644 index cc14988..0000000 --- a/Forge/src/main/java/com/hypherionmc/craterlib/network/CraterForgeNetworkHandler.java +++ /dev/null @@ -1,98 +0,0 @@ -package com.hypherionmc.craterlib.network; - -import com.hypherionmc.craterlib.CraterConstants; -import com.hypherionmc.craterlib.core.networking.PacketRegistry; -import com.hypherionmc.craterlib.core.networking.data.PacketContext; -import com.hypherionmc.craterlib.core.networking.data.PacketHolder; -import com.hypherionmc.craterlib.core.networking.data.PacketSide; -import com.hypherionmc.craterlib.nojang.network.BridgedFriendlyByteBuf; -import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer; -import net.minecraft.client.Minecraft; -import net.minecraft.network.Connection; -import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.server.network.ServerGamePacketListenerImpl; -import net.minecraftforge.event.network.CustomPayloadEvent; -import net.minecraftforge.network.ChannelBuilder; -import net.minecraftforge.network.PacketDistributor; -import net.minecraftforge.network.SimpleChannel; - -import java.util.HashMap; -import java.util.Map; -import java.util.function.BiConsumer; -import java.util.function.Consumer; -import java.util.function.Function; - -/** - * Based on https://github.com/mysticdrew/common-networking/tree/1.20.4 - */ -public class CraterForgeNetworkHandler extends PacketRegistry { - private final Map, SimpleChannel> CHANNELS = new HashMap<>(); - - public CraterForgeNetworkHandler(PacketSide side) { - super(side); - } - - protected void registerPacket(PacketHolder holder) { - if (CHANNELS.get(holder.messageType()) == null) { - SimpleChannel channel = ChannelBuilder - .named(holder.type().id()) - .clientAcceptedVersions((a, b) -> true) - .serverAcceptedVersions((a, b) -> true) - .networkProtocolVersion(1) - .simpleChannel(); - - channel.messageBuilder(holder.messageType()) - .decoder(mojangDecoder(holder.decoder())) - .encoder(mojangEncoder(holder.encoder())) - .consumerNetworkThread(buildHandler(holder.handler())) - .add(); - - CHANNELS.put(holder.messageType(), channel); - } else { - CraterConstants.LOG.error("Trying to register duplicate packet for type {}", holder.messageType()); - } - } - - public void sendToServer(T packet) { - this.sendToServer(packet, false); - } - - public void sendToServer(T packet, boolean ignoreCheck) { - SimpleChannel channel = CHANNELS.get(packet.getClass()); - Connection connection = Minecraft.getInstance().getConnection().getConnection(); - if (channel.isRemotePresent(connection) || ignoreCheck) { - channel.send(packet, PacketDistributor.SERVER.noArg()); - } - } - - public void sendToClient(T packet, BridgedPlayer player) { - SimpleChannel channel = CHANNELS.get(packet.getClass()); - ServerGamePacketListenerImpl connection = player.getConnection(); - if (connection == null) - return; - - if (channel.isRemotePresent(connection.getConnection())) { - channel.send(packet, PacketDistributor.PLAYER.with(player.toMojangServerPlayer())); - } - } - - private Function mojangDecoder(Function handler) { - return byteBuf -> handler.apply(BridgedFriendlyByteBuf.of(byteBuf)); - } - - private BiConsumer mojangEncoder(BiConsumer handler) { - return ((t, byteBuf) -> handler.accept(t, BridgedFriendlyByteBuf.of(byteBuf))); - } - - private BiConsumer buildHandler(Consumer> handler) { - return (message, ctx) -> { - ctx.enqueueWork(() -> { - PacketSide side = ctx.getDirection().getReceptionSide().isServer() ? PacketSide.SERVER : PacketSide.CLIENT; - ServerPlayer player = ctx.getSender(); - handler.accept(new PacketContext<>(BridgedPlayer.of(player), message, side)); - }); - ctx.setPacketHandled(true); - }; - } -} \ No newline at end of file diff --git a/Forge/src/main/resources/META-INF/mods.toml b/Forge/src/main/resources/META-INF/mods.toml deleted file mode 100644 index c2c7608..0000000 --- a/Forge/src/main/resources/META-INF/mods.toml +++ /dev/null @@ -1,31 +0,0 @@ -modLoader = "javafml" -loaderVersion = "[50,)" -license = "MIT" -issueTrackerURL = "https://github.com/firstdarkdev/craterLib/issues" - -[[mods]] - modId = "${mod_id}" - version = "${version}" - displayName = "${mod_name}" - displayURL = "https://modrinth.com/mod/craterlib" - logoFile = "craterlib_logo.png" - #credits="Thanks for this example mod goes to Java" - authors = "${mod_author}, Zenith" - description = ''' - A library mod used by First Dark Development and HypherionSA Mods - ''' - displayTest = "NONE" - -[[dependencies.${ mod_id }]] - modId = "forge" - mandatory = true - versionRange = "[50,)" - ordering = "NONE" - side = "BOTH" - -[[dependencies.${ mod_id }]] - modId = "minecraft" - mandatory = true - versionRange = "[1.20.6,1.21)" - ordering = "NONE" - side = "BOTH" diff --git a/Forge/src/main/resources/META-INF/services/com.hypherionmc.craterlib.core.platform.ClientPlatform b/Forge/src/main/resources/META-INF/services/com.hypherionmc.craterlib.core.platform.ClientPlatform deleted file mode 100644 index a12ad8c..0000000 --- a/Forge/src/main/resources/META-INF/services/com.hypherionmc.craterlib.core.platform.ClientPlatform +++ /dev/null @@ -1 +0,0 @@ -com.hypherionmc.craterlib.client.ForgeClientHelper \ No newline at end of file diff --git a/Forge/src/main/resources/META-INF/services/com.hypherionmc.craterlib.core.platform.CommonPlatform b/Forge/src/main/resources/META-INF/services/com.hypherionmc.craterlib.core.platform.CommonPlatform deleted file mode 100644 index 09e119f..0000000 --- a/Forge/src/main/resources/META-INF/services/com.hypherionmc.craterlib.core.platform.CommonPlatform +++ /dev/null @@ -1 +0,0 @@ -com.hypherionmc.craterlib.common.ForgeCommonHelper \ No newline at end of file diff --git a/Forge/src/main/resources/META-INF/services/com.hypherionmc.craterlib.core.platform.CompatUtils b/Forge/src/main/resources/META-INF/services/com.hypherionmc.craterlib.core.platform.CompatUtils deleted file mode 100644 index a9f823d..0000000 --- a/Forge/src/main/resources/META-INF/services/com.hypherionmc.craterlib.core.platform.CompatUtils +++ /dev/null @@ -1 +0,0 @@ -com.hypherionmc.craterlib.common.ForgeCompatHelper \ No newline at end of file diff --git a/Forge/src/main/resources/META-INF/services/com.hypherionmc.craterlib.core.platform.ModloaderEnvironment b/Forge/src/main/resources/META-INF/services/com.hypherionmc.craterlib.core.platform.ModloaderEnvironment deleted file mode 100644 index 02b4e07..0000000 --- a/Forge/src/main/resources/META-INF/services/com.hypherionmc.craterlib.core.platform.ModloaderEnvironment +++ /dev/null @@ -1 +0,0 @@ -com.hypherionmc.craterlib.common.ForgeLoaderHelper \ No newline at end of file diff --git a/Forge/src/main/resources/craterlib.forge.mixins.json b/Forge/src/main/resources/craterlib.forge.mixins.json deleted file mode 100644 index aa072d1..0000000 --- a/Forge/src/main/resources/craterlib.forge.mixins.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "required": true, - "minVersion": "0.8", - "package": "com.hypherionmc.craterlib.mixin", - "compatibilityLevel": "JAVA_17", - "mixins": [ - ], - "client": [ - "ConfigScreenHandlerMixin" - ], - "server": [ - "ServerGamePacketListenerImplMixin" - ], - "injectors": { - "defaultRequire": 1 - } -} diff --git a/Forge/src/main/resources/craterlib_logo.png b/Forge/src/main/resources/craterlib_logo.png deleted file mode 100644 index ce0159cc4aa4d823ea354042e531b4522d6dfead..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49343 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 z 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 De~rmR diff --git a/NeoForge/build.gradle b/NeoForge/build.gradle deleted file mode 100644 index 877fe37..0000000 --- a/NeoForge/build.gradle +++ /dev/null @@ -1,111 +0,0 @@ -archivesBaseName = "${mod_name.replace(" ", "")}-NeoForge-${minecraft_version}" - -dependencies { - // Compat - modImplementation("maven.modrinth:vanishmod:${vanishmod_neo}") - - // Do not edit or remove - implementation project(":Common") -} - -shadowJar { - from sourceSets.main.output - configurations = [project.configurations.shade] - - dependencies { - exclude(dependency('com.google.code.gson:.*')) - - relocate 'me.hypherionmc.moonconfig', 'shadow.hypherionmc.moonconfig' - relocate 'me.hypherionmc.mcdiscordformatter', 'shadow.hypherionmc.mcdiscordformatter' - relocate 'net.kyori', 'shadow.kyori' - } - - setArchiveClassifier('dev-shadow') -} - -/** - * =============================================================================== - * = DO NOT EDIT BELOW THIS LINE UNLESS YOU KNOW WHAT YOU ARE DOING = - * =============================================================================== - */ - -unimined.minecraft { - neoForged { - loader neoforge_version - mixinConfig("${mod_id}.mixins.json", "${mod_id}.neoforge.mixins.json") - } -} - -remapJar { - inputFile.set shadowJar.archiveFile - dependsOn shadowJar - archiveClassifier.set null -} - -jar { - archiveClassifier.set "dev" -} - -processResources { - from project(":Common").sourceSets.main.resources - def buildProps = project.properties.clone() - - filesMatching("META-INF/neoforge.mods.toml") { - expand buildProps - } -} - -compileTestJava.enabled = false - -tasks.withType(JavaCompile).configureEach { - source(project(":Common").sourceSets.main.allSource) -} - -/** - * Publishing Config - */ -publishing { - publications { - mavenJava(MavenPublication) { - artifactId project.archivesBaseName - from components.java - - artifact(remapJar) { - builtBy remapJar - } - - pom.withXml { - Node pomNode = asNode() - pomNode.dependencies.'*'.findAll() { - it.artifactId.text() == 'regutils-joined-fabric' || - it.artifactId.text() == 'core' || - it.artifactId.text() == 'toml' - }.each() { - it.parent().remove(it) - } - } - } - } - - repositories { - maven rootProject.orion.getPublishingMaven() - } -} - -publisher { - apiKeys { - modrinth(System.getenv("MODRINTH_TOKEN")) - curseforge(System.getenv("CURSE_TOKEN")) - } - - setCurseID(curse_id) - setModrinthID(modrinth_id) - setVersionType("release") - setChangelog("https://raw.githubusercontent.com/hypherionmc/changelogs/main/craterlib/changelog-forge.md") - setProjectVersion("${minecraft_version}-${project.version}") - setDisplayName("[NeoForge 1.20.6] CraterLib - ${project.version}") - setGameVersions("1.20.6") - setLoaders("neoforge") - setArtifact(remapJar) - setCurseEnvironment("both") -} \ No newline at end of file diff --git a/NeoForge/src/main/java/com/hypherionmc/craterlib/CraterLib.java b/NeoForge/src/main/java/com/hypherionmc/craterlib/CraterLib.java deleted file mode 100644 index 900cdf1..0000000 --- a/NeoForge/src/main/java/com/hypherionmc/craterlib/CraterLib.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.hypherionmc.craterlib; - -import com.hypherionmc.craterlib.api.events.client.LateInitEvent; -import com.hypherionmc.craterlib.client.gui.config.CraterConfigScreen; -import com.hypherionmc.craterlib.common.NeoForgeServerEvents; -import com.hypherionmc.craterlib.compat.Vanish; -import com.hypherionmc.craterlib.core.config.ConfigController; -import com.hypherionmc.craterlib.core.config.ModuleConfig; -import com.hypherionmc.craterlib.core.config.annotations.NoConfigScreen; -import com.hypherionmc.craterlib.core.event.CraterEventBus; -import com.hypherionmc.craterlib.core.networking.CraterPacketNetwork; -import com.hypherionmc.craterlib.core.networking.PacketRegistry; -import com.hypherionmc.craterlib.core.networking.data.PacketSide; -import com.hypherionmc.craterlib.core.platform.ModloaderEnvironment; -import com.hypherionmc.craterlib.network.CraterNeoForgeNetworkHandler; -import com.hypherionmc.craterlib.nojang.client.BridgedMinecraft; -import com.hypherionmc.craterlib.nojang.client.BridgedOptions; -import net.minecraft.client.Minecraft; -import net.neoforged.bus.api.IEventBus; -import net.neoforged.fml.ModList; -import net.neoforged.fml.common.Mod; -import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent; -import net.neoforged.fml.loading.FMLEnvironment; -import net.neoforged.fml.loading.FMLLoader; -import net.neoforged.neoforge.client.gui.IConfigScreenFactory; -import net.neoforged.neoforge.common.NeoForge; - -import java.util.Optional; - -@Mod(CraterConstants.MOD_ID) -public class CraterLib { - - private final PacketRegistry handler; - - public CraterLib(IEventBus eventBus) { - NeoForge.EVENT_BUS.register(new NeoForgeServerEvents()); - eventBus.addListener(this::commonSetup); - handler = new CraterNeoForgeNetworkHandler(FMLLoader.getDist().isClient() ? PacketSide.CLIENT : PacketSide.SERVER); - - if (ModloaderEnvironment.INSTANCE.isModLoaded("vmod")) { - eventBus.register(new Vanish()); - } - } - - public void commonSetup(FMLCommonSetupEvent evt) { - new CraterPacketNetwork(handler); - if (FMLEnvironment.dist.isClient()) { - LateInitEvent event = new LateInitEvent(new BridgedMinecraft(), BridgedOptions.of(Minecraft.getInstance().options)); - CraterEventBus.INSTANCE.postEvent(event); - - ConfigController.getMonitoredConfigs().forEach((conf, watcher) -> { - if (!conf.getClass().isAnnotationPresent(NoConfigScreen.class)) { - ModuleConfig config = (ModuleConfig) conf; - ModList.get().getModContainerById(config.getModId()).ifPresent(c -> c.registerExtensionPoint(IConfigScreenFactory.class, ((minecraft, screen) -> new CraterConfigScreen(config, screen)))); - } - }); - } - } -} diff --git a/NeoForge/src/main/java/com/hypherionmc/craterlib/client/NeoForgeClientEvents.java b/NeoForge/src/main/java/com/hypherionmc/craterlib/client/NeoForgeClientEvents.java deleted file mode 100644 index 3e6455a..0000000 --- a/NeoForge/src/main/java/com/hypherionmc/craterlib/client/NeoForgeClientEvents.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.hypherionmc.craterlib.client; - -import com.hypherionmc.craterlib.CraterConstants; -import com.hypherionmc.craterlib.api.events.client.CraterClientTickEvent; -import com.hypherionmc.craterlib.core.event.CraterEventBus; -import com.hypherionmc.craterlib.nojang.client.multiplayer.BridgedClientLevel; -import net.minecraft.client.Minecraft; -import net.neoforged.api.distmarker.Dist; -import net.neoforged.bus.api.SubscribeEvent; -import net.neoforged.fml.common.EventBusSubscriber; -import net.neoforged.neoforge.event.tick.LevelTickEvent; - -@EventBusSubscriber(modid = CraterConstants.MOD_ID, value = Dist.CLIENT) -public class NeoForgeClientEvents { - - @SubscribeEvent - public static void clientTick(LevelTickEvent.Pre event) { - if (Minecraft.getInstance().level == null) - return; - - CraterClientTickEvent craterClientTickEvent = new CraterClientTickEvent(BridgedClientLevel.of(Minecraft.getInstance().level)); - CraterEventBus.INSTANCE.postEvent(craterClientTickEvent); - } - -} diff --git a/NeoForge/src/main/java/com/hypherionmc/craterlib/client/NeoForgeClientHelper.java b/NeoForge/src/main/java/com/hypherionmc/craterlib/client/NeoForgeClientHelper.java deleted file mode 100644 index d6c2ef7..0000000 --- a/NeoForge/src/main/java/com/hypherionmc/craterlib/client/NeoForgeClientHelper.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.hypherionmc.craterlib.client; - -import com.hypherionmc.craterlib.core.platform.ClientPlatform; -import com.hypherionmc.craterlib.nojang.client.BridgedMinecraft; -import com.hypherionmc.craterlib.nojang.client.multiplayer.BridgedClientLevel; -import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer; -import net.minecraft.client.Minecraft; -import net.minecraft.network.Connection; - -import java.util.Objects; - -/** - * @author HypherionSA - */ -public class NeoForgeClientHelper implements ClientPlatform { - - public NeoForgeClientHelper() { - } - - @Override - public BridgedMinecraft getClientInstance() { - return new BridgedMinecraft(); - } - - @Override - public BridgedPlayer getClientPlayer() { - return BridgedPlayer.of(Minecraft.getInstance().player); - } - - @Override - public BridgedClientLevel getClientLevel() { - return BridgedClientLevel.of(Minecraft.getInstance().level); - } - - @Override - public Connection getClientConnection() { - Objects.requireNonNull(Minecraft.getInstance().getConnection(), "Cannot send packets when not in game!"); - return Minecraft.getInstance().getConnection().getConnection(); - } -} diff --git a/NeoForge/src/main/java/com/hypherionmc/craterlib/common/NeoForgeCommonHelper.java b/NeoForge/src/main/java/com/hypherionmc/craterlib/common/NeoForgeCommonHelper.java deleted file mode 100644 index 50622a8..0000000 --- a/NeoForge/src/main/java/com/hypherionmc/craterlib/common/NeoForgeCommonHelper.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.hypherionmc.craterlib.common; - -import com.hypherionmc.craterlib.core.platform.CommonPlatform; -import com.hypherionmc.craterlib.nojang.server.BridgedMinecraftServer; -import net.neoforged.neoforge.server.ServerLifecycleHooks; - -/** - * @author HypherionSA - */ -public class NeoForgeCommonHelper implements CommonPlatform { - - public NeoForgeCommonHelper() { - } - - @Override - public BridgedMinecraftServer getMCServer() { - return BridgedMinecraftServer.of(ServerLifecycleHooks.getCurrentServer()); - } -} diff --git a/NeoForge/src/main/java/com/hypherionmc/craterlib/common/NeoForgeCompatHelper.java b/NeoForge/src/main/java/com/hypherionmc/craterlib/common/NeoForgeCompatHelper.java deleted file mode 100644 index 469c172..0000000 --- a/NeoForge/src/main/java/com/hypherionmc/craterlib/common/NeoForgeCompatHelper.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.hypherionmc.craterlib.common; - -import com.hypherionmc.craterlib.core.platform.CompatUtils; -import com.hypherionmc.craterlib.core.platform.ModloaderEnvironment; -import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer; -import redstonedubstep.mods.vanishmod.VanishUtil; - -public class NeoForgeCompatHelper implements CompatUtils { - - @Override - public boolean isPlayerActive(BridgedPlayer player) { - if (!ModloaderEnvironment.INSTANCE.isModLoaded("vmod")) - return true; - - return VanishUtil.isVanished(player.toMojangServerPlayer()); - } - - @Override - public String getSkinUUID(BridgedPlayer player) { - return player.getStringUUID(); - } -} diff --git a/NeoForge/src/main/java/com/hypherionmc/craterlib/common/NeoForgeLoaderHelper.java b/NeoForge/src/main/java/com/hypherionmc/craterlib/common/NeoForgeLoaderHelper.java deleted file mode 100644 index 2eb4c4a..0000000 --- a/NeoForge/src/main/java/com/hypherionmc/craterlib/common/NeoForgeLoaderHelper.java +++ /dev/null @@ -1,73 +0,0 @@ -package com.hypherionmc.craterlib.common; - -import com.hypherionmc.craterlib.core.platform.Environment; -import com.hypherionmc.craterlib.core.platform.ModloaderEnvironment; -import net.minecraft.SharedConstants; -import net.minecraft.client.Minecraft; -import net.neoforged.fml.ModList; -import net.neoforged.fml.loading.FMLLoader; -import net.neoforged.fml.loading.FMLPaths; - -import java.io.File; - -/** - * @author HypherionSA - */ -public class NeoForgeLoaderHelper implements ModloaderEnvironment { - - public NeoForgeLoaderHelper() { - } - - @Override - public boolean isFabric() { - return false; - } - - @Override - public String getGameVersion() { - return SharedConstants.VERSION_STRING; - } - - @Override - public File getGameFolder() { - return Minecraft.getInstance().gameDirectory; - } - - @Override - public File getConfigFolder() { - return FMLPaths.CONFIGDIR.get().toFile(); - } - - @Override - public File getModsFolder() { - return FMLPaths.MODSDIR.get().toFile(); - } - - @Override - public Environment getEnvironment() { - switch (FMLLoader.getDist()) { - case CLIENT -> { - return Environment.CLIENT; - } - case DEDICATED_SERVER -> { - return Environment.SERVER; - } - } - return Environment.UNKNOWN; - } - - @Override - public boolean isModLoaded(String modid) { - return ModList.get().isLoaded(modid); - } - - @Override - public boolean isDevEnv() { - return !FMLLoader.isProduction(); - } - - @Override - public int getModCount() { - return ModList.get().size(); - } -} diff --git a/NeoForge/src/main/java/com/hypherionmc/craterlib/common/NeoForgeServerEvents.java b/NeoForge/src/main/java/com/hypherionmc/craterlib/common/NeoForgeServerEvents.java deleted file mode 100644 index 91ca5b7..0000000 --- a/NeoForge/src/main/java/com/hypherionmc/craterlib/common/NeoForgeServerEvents.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.hypherionmc.craterlib.common; - -import com.hypherionmc.craterlib.api.events.server.CraterRegisterCommandEvent; -import com.hypherionmc.craterlib.api.events.server.CraterServerLifecycleEvent; -import com.hypherionmc.craterlib.core.event.CraterEventBus; -import com.hypherionmc.craterlib.nojang.commands.CommandsRegistry; -import com.hypherionmc.craterlib.nojang.server.BridgedMinecraftServer; -import net.neoforged.bus.api.SubscribeEvent; -import net.neoforged.neoforge.event.RegisterCommandsEvent; -import net.neoforged.neoforge.event.server.ServerStartedEvent; -import net.neoforged.neoforge.event.server.ServerStartingEvent; -import net.neoforged.neoforge.event.server.ServerStoppedEvent; -import net.neoforged.neoforge.event.server.ServerStoppingEvent; - -public class NeoForgeServerEvents { - - @SubscribeEvent - public void serverStarting(ServerStartingEvent event) { - CraterEventBus.INSTANCE.postEvent(new CraterServerLifecycleEvent.Starting(BridgedMinecraftServer.of(event.getServer()))); - } - - @SubscribeEvent - public void serverStarted(ServerStartedEvent event) { - CraterEventBus.INSTANCE.postEvent(new CraterServerLifecycleEvent.Started(BridgedMinecraftServer.of(event.getServer()))); - } - - @SubscribeEvent - public void serverStopping(ServerStoppingEvent event) { - CraterEventBus.INSTANCE.postEvent(new CraterServerLifecycleEvent.Stopping(BridgedMinecraftServer.of(event.getServer()))); - } - - @SubscribeEvent - public void serverStopped(ServerStoppedEvent event) { - CraterEventBus.INSTANCE.postEvent(new CraterServerLifecycleEvent.Stopped(BridgedMinecraftServer.of(event.getServer()))); - } - - @SubscribeEvent - public void onCommandRegister(RegisterCommandsEvent event) { - CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent()); - CommandsRegistry.INSTANCE.registerCommands(event.getDispatcher()); - } - -} diff --git a/NeoForge/src/main/java/com/hypherionmc/craterlib/compat/Vanish.java b/NeoForge/src/main/java/com/hypherionmc/craterlib/compat/Vanish.java deleted file mode 100644 index 0302e29..0000000 --- a/NeoForge/src/main/java/com/hypherionmc/craterlib/compat/Vanish.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.hypherionmc.craterlib.compat; - -import com.hypherionmc.craterlib.api.events.server.CraterPlayerEvent; -import com.hypherionmc.craterlib.core.event.CraterEventBus; -import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer; -import net.neoforged.bus.api.SubscribeEvent; -import redstonedubstep.mods.vanishmod.api.PlayerVanishEvent; - -public class Vanish { - - public Vanish() { - - } - - @SubscribeEvent - public void vanishevent(PlayerVanishEvent event) { - if (event.isVanished()) { - CraterEventBus.INSTANCE.postEvent(new CraterPlayerEvent.PlayerLoggedOut(BridgedPlayer.of(event.getEntity()))); - } else { - CraterEventBus.INSTANCE.postEvent(new CraterPlayerEvent.PlayerLoggedIn(BridgedPlayer.of(event.getEntity()))); - } - } - -} diff --git a/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java b/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java deleted file mode 100644 index 299f52c..0000000 --- a/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.hypherionmc.craterlib.mixin; - -import com.hypherionmc.craterlib.api.events.server.CraterServerChatEvent; -import com.hypherionmc.craterlib.core.event.CraterEventBus; -import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer; -import com.hypherionmc.craterlib.utils.ChatUtils; -import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.PlayerChatMessage; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.server.network.FilteredText; -import net.minecraft.server.network.ServerGamePacketListenerImpl; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(value = ServerGamePacketListenerImpl.class, priority = Integer.MIN_VALUE) -public class ServerGamePacketListenerImplMixin { - - @Shadow - public ServerPlayer player; - - @Inject( - method = "lambda$handleChat$5", - at = @At("HEAD"), - cancellable = true - ) - private void injectChatEvent(Component component, PlayerChatMessage arg, FilteredText p_296589_, CallbackInfo ci) { - CraterServerChatEvent event = new CraterServerChatEvent(BridgedPlayer.of(this.player), arg.decoratedContent().getString(), ChatUtils.mojangToAdventure(arg.decoratedContent())); - CraterEventBus.INSTANCE.postEvent(event); - if (event.wasCancelled()) - ci.cancel(); - } - -} diff --git a/NeoForge/src/main/java/com/hypherionmc/craterlib/network/CraterNeoForgeNetworkHandler.java b/NeoForge/src/main/java/com/hypherionmc/craterlib/network/CraterNeoForgeNetworkHandler.java deleted file mode 100644 index 59cb127..0000000 --- a/NeoForge/src/main/java/com/hypherionmc/craterlib/network/CraterNeoForgeNetworkHandler.java +++ /dev/null @@ -1,77 +0,0 @@ -package com.hypherionmc.craterlib.network; - -import com.hypherionmc.craterlib.CraterConstants; -import com.hypherionmc.craterlib.api.networking.CommonPacketWrapper; -import com.hypherionmc.craterlib.core.networking.PacketRegistry; -import com.hypherionmc.craterlib.core.networking.data.PacketContext; -import com.hypherionmc.craterlib.core.networking.data.PacketHolder; -import com.hypherionmc.craterlib.core.networking.data.PacketSide; -import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer; -import net.neoforged.bus.api.SubscribeEvent; -import net.neoforged.fml.LogicalSide; -import net.neoforged.neoforge.network.PacketDistributor; -import net.neoforged.neoforge.network.event.RegisterPayloadHandlersEvent; -import net.neoforged.neoforge.network.handling.IPayloadHandler; - -import java.util.function.Consumer; - -/** - * Based on https://github.com/mysticdrew/common-networking/tree/1.20.4 - */ -public class CraterNeoForgeNetworkHandler extends PacketRegistry { - - public CraterNeoForgeNetworkHandler(PacketSide side) { - super(side); - } - - @SubscribeEvent - public void register(final RegisterPayloadHandlersEvent event) { - if (!PACKET_MAP.isEmpty()) { - PACKET_MAP.forEach((type, container) -> event.registrar(container.getType().id().getNamespace()) - .optional().commonBidirectional(container.getType(), container.getCodec(), buildHandler(container.handler()))); - } - } - - @Override - protected void registerPacket(PacketHolder container) { - - } - - public void sendToServer(T packet) { - this.sendToServer(packet, false); - } - - public void sendToServer(T packet, boolean ignoreCheck) { - PacketHolder container = (PacketHolder) PACKET_MAP.get(packet.getClass()); - if (container != null) { - PacketDistributor.sendToServer(new CommonPacketWrapper<>(container, packet)); - } - } - - public void sendToClient(T packet, BridgedPlayer player) { - PacketHolder container = (PacketHolder) PACKET_MAP.get(packet.getClass()); - if (container != null) { - if (player.getConnection().hasChannel(container.type())) { - PacketDistributor.sendToPlayer(player.toMojangServerPlayer(), new CommonPacketWrapper<>(container, packet)); - } - } - } - - private > IPayloadHandler buildHandler(Consumer> handler) { - return (payload, ctx) -> { - try - { - PacketSide side = ctx.flow().getReceptionSide().equals(LogicalSide.SERVER) ? PacketSide.SERVER : PacketSide.CLIENT; - if (PacketSide.SERVER.equals(side)) { - handler.accept(new PacketContext<>(BridgedPlayer.of(ctx.player()), payload.packet(), side)); - } else { - handler.accept(new PacketContext<>(payload.packet(), side)); - } - - } - catch (Throwable t) { - CraterConstants.LOG.error("Error handling packet: {} -> ", payload.packet().getClass(), t); - } - }; - } -} \ No newline at end of file diff --git a/NeoForge/src/main/resources/META-INF/neoforge.mods.toml b/NeoForge/src/main/resources/META-INF/neoforge.mods.toml deleted file mode 100644 index b5afd9b..0000000 --- a/NeoForge/src/main/resources/META-INF/neoforge.mods.toml +++ /dev/null @@ -1,31 +0,0 @@ -modLoader = "javafml" -loaderVersion = "[1,)" -license = "MIT" -issueTrackerURL = "https://github.com/firstdarkdev/craterLib/issues" - -[[mods]] - modId = "${mod_id}" - version = "${version}" - displayName = "${mod_name}" - displayURL = "https://modrinth.com/mod/craterlib" - logoFile = "craterlib_logo.png" - #credits="Thanks for this example mod goes to Java" - authors = "${mod_author}, Zenith" - description = ''' - A library mod used by First Dark Development and HypherionSA Mods - ''' - displayTest = "NONE" - -[[dependencies.${ mod_id }]] - modId = "neoforge" - type="required" - versionRange = "[20.6,)" - ordering = "NONE" - side = "BOTH" - -[[dependencies.${ mod_id }]] - modId = "minecraft" - type="required" - versionRange = "[1.20.6,1.21)" - ordering = "NONE" - side = "BOTH" diff --git a/NeoForge/src/main/resources/META-INF/services/com.hypherionmc.craterlib.core.platform.ClientPlatform b/NeoForge/src/main/resources/META-INF/services/com.hypherionmc.craterlib.core.platform.ClientPlatform deleted file mode 100644 index 5bd719f..0000000 --- a/NeoForge/src/main/resources/META-INF/services/com.hypherionmc.craterlib.core.platform.ClientPlatform +++ /dev/null @@ -1 +0,0 @@ -com.hypherionmc.craterlib.client.NeoForgeClientHelper \ No newline at end of file diff --git a/NeoForge/src/main/resources/META-INF/services/com.hypherionmc.craterlib.core.platform.CommonPlatform b/NeoForge/src/main/resources/META-INF/services/com.hypherionmc.craterlib.core.platform.CommonPlatform deleted file mode 100644 index 6cb6efb..0000000 --- a/NeoForge/src/main/resources/META-INF/services/com.hypherionmc.craterlib.core.platform.CommonPlatform +++ /dev/null @@ -1 +0,0 @@ -com.hypherionmc.craterlib.common.NeoForgeCommonHelper \ No newline at end of file diff --git a/NeoForge/src/main/resources/META-INF/services/com.hypherionmc.craterlib.core.platform.CompatUtils b/NeoForge/src/main/resources/META-INF/services/com.hypherionmc.craterlib.core.platform.CompatUtils deleted file mode 100644 index 9475f11..0000000 --- a/NeoForge/src/main/resources/META-INF/services/com.hypherionmc.craterlib.core.platform.CompatUtils +++ /dev/null @@ -1 +0,0 @@ -com.hypherionmc.craterlib.common.NeoForgeCompatHelper \ No newline at end of file diff --git a/NeoForge/src/main/resources/META-INF/services/com.hypherionmc.craterlib.core.platform.ModloaderEnvironment b/NeoForge/src/main/resources/META-INF/services/com.hypherionmc.craterlib.core.platform.ModloaderEnvironment deleted file mode 100644 index 9a41f05..0000000 --- a/NeoForge/src/main/resources/META-INF/services/com.hypherionmc.craterlib.core.platform.ModloaderEnvironment +++ /dev/null @@ -1 +0,0 @@ -com.hypherionmc.craterlib.common.NeoForgeLoaderHelper \ No newline at end of file diff --git a/NeoForge/src/main/resources/craterlib.neoforge.mixins.json b/NeoForge/src/main/resources/craterlib.neoforge.mixins.json deleted file mode 100644 index e1af981..0000000 --- a/NeoForge/src/main/resources/craterlib.neoforge.mixins.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "required": true, - "minVersion": "0.8", - "package": "com.hypherionmc.craterlib.mixin", - "compatibilityLevel": "JAVA_17", - "mixins": [ - ], - "client": [], - "server": [ - "ServerGamePacketListenerImplMixin" - ], - "injectors": { - "defaultRequire": 1 - } -} diff --git a/NeoForge/src/main/resources/craterlib_logo.png b/NeoForge/src/main/resources/craterlib_logo.png deleted file mode 100644 index ce0159cc4aa4d823ea354042e531b4522d6dfead..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49343 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 z 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 De~rmR diff --git a/build.gradle b/build.gradle index 5718fe6..edcfa2d 100644 --- a/build.gradle +++ b/build.gradle @@ -1,109 +1,8 @@ plugins { id 'java' - id 'com.github.johnrengelman.shadow' version '8.1.1' apply false - id "xyz.wagyourtail.unimined" version "1.2.4" apply false - id "com.hypherionmc.modutils.modpublisher" version "2.1.+" - id "com.hypherionmc.modutils.orion" version "1.0.10" - id 'maven-publish' + id "com.hypherionmc.modutils.orion" version "1.0.+" } -orion.setup { - multiProject = true - enableMirrorMaven = true - enableReleasesMaven = true - - dopplerToken = System.getenv("DOPPLER_KEY") - - versioning { - identifier("${release_type}") - } -} - -group = project_group - -subprojects { - apply plugin: "xyz.wagyourtail.unimined" - apply plugin: "java" - apply plugin: 'maven-publish' - apply plugin: 'com.github.johnrengelman.shadow' - apply plugin: 'com.hypherionmc.modutils.modpublisher' - - sourceCompatibility = JavaVersion.VERSION_21 - targetCompatibility = JavaVersion.VERSION_21 - - group = rootProject.group - - repositories { - mavenCentral() - - maven { - name = "Modrinth" - url = "https://api.modrinth.com/maven" - content { - includeGroup "maven.modrinth" - } - } - } - - configurations { - shade - modCompileOnly - implementation.extendsFrom shade - compileOnly.extendsFrom modCompileOnly - } - - dependencies { - // All Projects - shade "me.hypherionmc.moon-config:core:${moon_config}" - shade "me.hypherionmc.moon-config:toml:${moon_config}" - shade "com.hypherionmc:rpcsdk:${rpc_sdk}" - shade "me.hypherionmc.sdlink:mcdiscordformatter-1.20.3:${discord_formatter}" - shade "net.kyori:adventure-api:${adventure}" - shade "net.kyori:adventure-text-serializer-gson:${adventure}" - - compileOnly("org.projectlombok:lombok:${lombok}") - annotationProcessor("org.projectlombok:lombok:${lombok}") - } - - jar { - manifest { - attributes([ - 'Specification-Title' : mod_name, - 'Specification-Vendor' : mod_author, - 'Specification-Version' : project.jar.archiveVersion, - 'Implementation-Title' : project.name, - 'Implementation-Version' : project.jar.archiveVersion, - 'Implementation-Vendor' : mod_author, - 'Implementation-Timestamp': new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"), - 'Timestamp' : System.currentTimeMillis(), - 'Built-On-Java' : "${System.getProperty('java.vm.version')} (${System.getProperty('java.vm.vendor')})", - 'Built-On-Minecraft' : minecraft_version - ]) - } - } - -/** - * =============================================================================== - * = DO NOT EDIT BELOW THIS LINE UNLESS YOU KNOW WHAT YOU ARE DOING = - * =============================================================================== - */ - unimined.minecraft(sourceSets.main, true) { - version minecraft_version - - mappings { - mojmap() - devNamespace "mojmap" - } - } - - tasks.withType(JavaCompile).configureEach { - it.options.encoding = 'UTF-8' - it.options.release = 17 - } - - tasks.withType(GenerateModuleMetadata).configureEach { - enabled = false - } -} - -// TODO MODULE JARS \ No newline at end of file +orionporting { + upstreamBranch = "dev" +} \ No newline at end of file diff --git a/changelog-fabric.md b/changelog-fabric.md deleted file mode 100644 index 3ce015c..0000000 --- a/changelog-fabric.md +++ /dev/null @@ -1 +0,0 @@ -# Dummy file. To be filled by Jenkins \ No newline at end of file diff --git a/changelog-forge.md b/changelog-forge.md deleted file mode 100644 index 3ce015c..0000000 --- a/changelog-forge.md +++ /dev/null @@ -1 +0,0 @@ -# Dummy file. To be filled by Jenkins \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index ddccf64..1866634 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,46 +1,3 @@ -#Project -version_major=2 -version_minor=0 -version_patch=0 - -#Mod -mod_author=HypherionSA -mod_id=craterlib -mod_name=CraterLib - -# Shared -minecraft_version=1.20.6 -project_group=com.hypherionmc.craterlib - -# Fabric -fabric_loader=0.15.0 -fabric_api=0.97.8+1.20.6 - -# Forge -forge_version=50.0.6 - -# NeoForged -neoforge_version=41-beta - -# Dependencies -moon_config=1.0.9 -lombok=1.18.32 -adventure=4.16.0 -rpc_sdk=1.0 -discord_formatter=2.0.0 - -# Mod Dependencies -fabrictailor=2.3.1 -vanish=1.5.4+1.20.5 -mod_menu_version=10.0.0-beta.1 -vanishmod=1.1.12.1 -vanishmod_neo=puxrKAMr - -# Publishing -curse_id=867099 -modrinth_id=Nn8Wasaq -release_type=release - # Gradle org.gradle.jvmargs=-Xmx3G org.gradle.daemon=false \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 090bd43..7ad2501 100644 --- a/settings.gradle +++ b/settings.gradle @@ -10,5 +10,4 @@ pluginManagement { } } -rootProject.name = 'CraterLib' -include("Common", "Fabric", "NeoForge", "Forge") \ No newline at end of file +rootProject.name = 'CraterLib' \ No newline at end of file