From 570321b274386a8c04371bbcd2c2a60f0daf9c3a Mon Sep 17 00:00:00 2001 From: HypherionMC Date: Sat, 24 Sep 2022 21:21:01 +0200 Subject: [PATCH] Initial Network System implementation --- .../client/gui/tabs/CreativeTabBuilder.java | 4 +- .../common/item/BlockItemDyable.java | 4 +- .../network/CraterNetworkHandler.java | 33 ++++++ .../craterlib/network/CraterPacket.java | 25 ++++ .../craterlib/network/PacketDirection.java | 10 ++ .../platform/{Services.java => Platform.java} | 9 +- .../platform/services/Environment.java | 11 ++ .../platform/services/ILoaderHelper.java | 19 +++ .../platform/services/IPlatformHelper.java | 11 -- .../platform/services/LibCommonHelper.java | 36 ++++++ .../craterlib/CraterLibInitializer.java | 4 +- .../craterlib/common/FabricCommonHelper.java | 76 ++++++++++++ .../craterlib/common/FabricLoaderHelper.java | 71 +++++++++++ .../common/FabricPlatformHelper.java | 26 ---- .../network/FabricNetworkHandler.java | 78 ++++++++++++ ....craterlib.platform.services.ILoaderHelper | 1 + ...raterlib.platform.services.IPlatformHelper | 1 - ...raterlib.platform.services.LibCommonHelper | 1 + .../craterlib/common/ForgeCommonHelper.java | 65 ++++++++++ .../craterlib/common/ForgeLoaderHelper.java | 72 +++++++++++ .../craterlib/common/ForgePlatformHelper.java | 27 ----- .../network/ForgeNetworkHandler.java | 112 ++++++++++++++++++ ....craterlib.platform.services.ILoaderHelper | 1 + ...raterlib.platform.services.IPlatformHelper | 1 - ...raterlib.platform.services.LibCommonHelper | 1 + 25 files changed, 625 insertions(+), 74 deletions(-) create mode 100644 Common/src/main/java/me/hypherionmc/craterlib/network/CraterNetworkHandler.java create mode 100644 Common/src/main/java/me/hypherionmc/craterlib/network/CraterPacket.java create mode 100644 Common/src/main/java/me/hypherionmc/craterlib/network/PacketDirection.java rename Common/src/main/java/me/hypherionmc/craterlib/platform/{Services.java => Platform.java} (67%) create mode 100644 Common/src/main/java/me/hypherionmc/craterlib/platform/services/Environment.java create mode 100644 Common/src/main/java/me/hypherionmc/craterlib/platform/services/ILoaderHelper.java delete mode 100644 Common/src/main/java/me/hypherionmc/craterlib/platform/services/IPlatformHelper.java create mode 100644 Common/src/main/java/me/hypherionmc/craterlib/platform/services/LibCommonHelper.java create mode 100644 Fabric/src/main/java/me/hypherionmc/craterlib/common/FabricCommonHelper.java create mode 100644 Fabric/src/main/java/me/hypherionmc/craterlib/common/FabricLoaderHelper.java delete mode 100644 Fabric/src/main/java/me/hypherionmc/craterlib/common/FabricPlatformHelper.java create mode 100644 Fabric/src/main/java/me/hypherionmc/craterlib/network/FabricNetworkHandler.java create mode 100644 Fabric/src/main/resources/META-INF/services/me.hypherionmc.craterlib.platform.services.ILoaderHelper delete mode 100644 Fabric/src/main/resources/META-INF/services/me.hypherionmc.craterlib.platform.services.IPlatformHelper create mode 100644 Fabric/src/main/resources/META-INF/services/me.hypherionmc.craterlib.platform.services.LibCommonHelper create mode 100644 Forge/src/main/java/me/hypherionmc/craterlib/common/ForgeCommonHelper.java create mode 100644 Forge/src/main/java/me/hypherionmc/craterlib/common/ForgeLoaderHelper.java delete mode 100644 Forge/src/main/java/me/hypherionmc/craterlib/common/ForgePlatformHelper.java create mode 100644 Forge/src/main/java/me/hypherionmc/craterlib/network/ForgeNetworkHandler.java create mode 100644 Forge/src/main/resources/META-INF/services/me.hypherionmc.craterlib.platform.services.ILoaderHelper delete mode 100644 Forge/src/main/resources/META-INF/services/me.hypherionmc.craterlib.platform.services.IPlatformHelper create mode 100644 Forge/src/main/resources/META-INF/services/me.hypherionmc.craterlib.platform.services.LibCommonHelper diff --git a/Common/src/main/java/me/hypherionmc/craterlib/client/gui/tabs/CreativeTabBuilder.java b/Common/src/main/java/me/hypherionmc/craterlib/client/gui/tabs/CreativeTabBuilder.java index bf972de..6595a1a 100644 --- a/Common/src/main/java/me/hypherionmc/craterlib/client/gui/tabs/CreativeTabBuilder.java +++ b/Common/src/main/java/me/hypherionmc/craterlib/client/gui/tabs/CreativeTabBuilder.java @@ -1,6 +1,6 @@ package me.hypherionmc.craterlib.client.gui.tabs; -import me.hypherionmc.craterlib.platform.Services; +import me.hypherionmc.craterlib.platform.Platform; import net.minecraft.world.item.CreativeModeTab; import net.minecraft.world.item.ItemStack; @@ -40,7 +40,7 @@ public class CreativeTabBuilder { } public CreativeModeTab build() { - return Services.CLIENT_HELPER.tabBuilder(this.modid, this.tabid, this.tabIcon, this.backgroundPrefix); + return Platform.CLIENT_HELPER.tabBuilder(this.modid, this.tabid, this.tabIcon, this.backgroundPrefix); } } diff --git a/Common/src/main/java/me/hypherionmc/craterlib/common/item/BlockItemDyable.java b/Common/src/main/java/me/hypherionmc/craterlib/common/item/BlockItemDyable.java index e3a0858..474da57 100644 --- a/Common/src/main/java/me/hypherionmc/craterlib/common/item/BlockItemDyable.java +++ b/Common/src/main/java/me/hypherionmc/craterlib/common/item/BlockItemDyable.java @@ -2,7 +2,7 @@ package me.hypherionmc.craterlib.common.item; import me.hypherionmc.craterlib.api.rendering.DyableBlock; import me.hypherionmc.craterlib.api.rendering.ItemDyable; -import me.hypherionmc.craterlib.platform.Services; +import me.hypherionmc.craterlib.platform.Platform; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; import net.minecraft.world.item.BlockItem; @@ -23,7 +23,7 @@ public class BlockItemDyable extends BlockItem implements ItemDyable { public BlockItemDyable(Block block, Properties properties) { super(block, properties); - Services.CLIENT_HELPER.registerItemProperty(this, "color"); + Platform.CLIENT_HELPER.registerItemProperty(this, "color"); } /** diff --git a/Common/src/main/java/me/hypherionmc/craterlib/network/CraterNetworkHandler.java b/Common/src/main/java/me/hypherionmc/craterlib/network/CraterNetworkHandler.java new file mode 100644 index 0000000..4f631b6 --- /dev/null +++ b/Common/src/main/java/me/hypherionmc/craterlib/network/CraterNetworkHandler.java @@ -0,0 +1,33 @@ +package me.hypherionmc.craterlib.network; + +import me.hypherionmc.craterlib.platform.Platform; +import net.minecraft.network.protocol.Packet; +import net.minecraft.server.level.ServerPlayer; + +import java.util.function.Supplier; + +/** + * @author HypherionSA + * @date 24/09/2022 + */ +public interface CraterNetworkHandler { + + > void registerPacket(Class clazz, Supplier supplier, PacketDirection packetDirection); + + Packet toServerBound(CraterPacket packet); + + Packet toClientBound(CraterPacket packet); + + default void sendToServer(CraterPacket packet) { + Platform.COMMON_HELPER.getClientConnection().send(this.toServerBound(packet)); + } + + default void sendTo(CraterPacket packet, ServerPlayer player) { + player.connection.send(this.toClientBound(packet)); + } + + default void sendToAll(CraterPacket packet) { + Platform.COMMON_HELPER.getMCServer().getPlayerList().broadcastAll(this.toClientBound(packet)); + } + +} diff --git a/Common/src/main/java/me/hypherionmc/craterlib/network/CraterPacket.java b/Common/src/main/java/me/hypherionmc/craterlib/network/CraterPacket.java new file mode 100644 index 0000000..ea8b4f1 --- /dev/null +++ b/Common/src/main/java/me/hypherionmc/craterlib/network/CraterPacket.java @@ -0,0 +1,25 @@ +package me.hypherionmc.craterlib.network; + +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.world.entity.player.Player; + +/** + * @author HypherionSA + * @date 24/09/2022 + */ +public interface CraterPacket> { + + void write(final FriendlyByteBuf buf); + + void read(final FriendlyByteBuf buf); + + default void handle(Player player, Object minecraft) { + this.createHandler().handle((T) this, player, minecraft); + } + + PacketHandler createHandler(); + + abstract class PacketHandler> { + public abstract void handle(T packet, Player player, Object minecraft); + } +} diff --git a/Common/src/main/java/me/hypherionmc/craterlib/network/PacketDirection.java b/Common/src/main/java/me/hypherionmc/craterlib/network/PacketDirection.java new file mode 100644 index 0000000..06c9393 --- /dev/null +++ b/Common/src/main/java/me/hypherionmc/craterlib/network/PacketDirection.java @@ -0,0 +1,10 @@ +package me.hypherionmc.craterlib.network; + +/** + * @author HypherionSA + * @date 24/09/2022 + */ +public enum PacketDirection { + TO_SERVER, + TO_CLIENT +} diff --git a/Common/src/main/java/me/hypherionmc/craterlib/platform/Services.java b/Common/src/main/java/me/hypherionmc/craterlib/platform/Platform.java similarity index 67% rename from Common/src/main/java/me/hypherionmc/craterlib/platform/Services.java rename to Common/src/main/java/me/hypherionmc/craterlib/platform/Platform.java index cbfeafb..a1503bf 100644 --- a/Common/src/main/java/me/hypherionmc/craterlib/platform/Services.java +++ b/Common/src/main/java/me/hypherionmc/craterlib/platform/Platform.java @@ -1,17 +1,20 @@ package me.hypherionmc.craterlib.platform; import me.hypherionmc.craterlib.CraterConstants; -import me.hypherionmc.craterlib.platform.services.IPlatformHelper; +import me.hypherionmc.craterlib.platform.services.ILoaderHelper; import me.hypherionmc.craterlib.platform.services.LibClientHelper; +import me.hypherionmc.craterlib.platform.services.LibCommonHelper; import java.util.ServiceLoader; -public class Services { +public class Platform { - public static final IPlatformHelper PLATFORM = load(IPlatformHelper.class); + public static final ILoaderHelper LOADER = load(ILoaderHelper.class); public static final LibClientHelper CLIENT_HELPER = load(LibClientHelper.class); + public static final LibCommonHelper COMMON_HELPER = load(LibCommonHelper.class); + public static T load(Class clazz) { final T loadedService = ServiceLoader.load(clazz) diff --git a/Common/src/main/java/me/hypherionmc/craterlib/platform/services/Environment.java b/Common/src/main/java/me/hypherionmc/craterlib/platform/services/Environment.java new file mode 100644 index 0000000..07d97e2 --- /dev/null +++ b/Common/src/main/java/me/hypherionmc/craterlib/platform/services/Environment.java @@ -0,0 +1,11 @@ +package me.hypherionmc.craterlib.platform.services; + +/** + * @author HypherionSA + * @date 24/09/2022 + */ +public enum Environment { + CLIENT, + SERVER, + UNKNOWN +} diff --git a/Common/src/main/java/me/hypherionmc/craterlib/platform/services/ILoaderHelper.java b/Common/src/main/java/me/hypherionmc/craterlib/platform/services/ILoaderHelper.java new file mode 100644 index 0000000..3754eb7 --- /dev/null +++ b/Common/src/main/java/me/hypherionmc/craterlib/platform/services/ILoaderHelper.java @@ -0,0 +1,19 @@ +package me.hypherionmc.craterlib.platform.services; + +import java.io.File; + +/** + * Helper class to provide information about the ModLoader + */ +public interface ILoaderHelper { + + public boolean isFabric(); + public boolean isForge(); + public String getGameVersion(); + public File getGameFolder(); + public File getConfigFolder(); + public File getModsFolder(); + public Environment getEnvironment(); + public boolean isModLoaded(String modid); + public boolean isDevEnv(); +} diff --git a/Common/src/main/java/me/hypherionmc/craterlib/platform/services/IPlatformHelper.java b/Common/src/main/java/me/hypherionmc/craterlib/platform/services/IPlatformHelper.java deleted file mode 100644 index bda69a3..0000000 --- a/Common/src/main/java/me/hypherionmc/craterlib/platform/services/IPlatformHelper.java +++ /dev/null @@ -1,11 +0,0 @@ -package me.hypherionmc.craterlib.platform.services; - -public interface IPlatformHelper { - - String getPlatformName(); - - boolean isModLoaded(String modId); - - boolean isDevelopmentEnvironment(); - -} diff --git a/Common/src/main/java/me/hypherionmc/craterlib/platform/services/LibCommonHelper.java b/Common/src/main/java/me/hypherionmc/craterlib/platform/services/LibCommonHelper.java new file mode 100644 index 0000000..1baf6cb --- /dev/null +++ b/Common/src/main/java/me/hypherionmc/craterlib/platform/services/LibCommonHelper.java @@ -0,0 +1,36 @@ +package me.hypherionmc.craterlib.platform.services; + +import me.hypherionmc.craterlib.network.CraterNetworkHandler; +import me.hypherionmc.craterlib.network.CraterPacket; +import net.minecraft.client.Minecraft; +import net.minecraft.network.Connection; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.MinecraftServer; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.Level; + +import java.util.function.Function; + +/** + * @author HypherionSA + * @date 24/09/2022 + */ +public interface LibCommonHelper { + + public CraterNetworkHandler createPacketHandler(String modid); + + public Minecraft getClientInstance(); + + public Player getClientPlayer(); + + public Level getClientLevel(); + + public Connection getClientConnection(); + + public MinecraftServer getMCServer(); + + /* FABRIC ONLY */ + public void registerClientReceiver(ResourceLocation channelName, Function> factory); + public void registerServerReceiver(ResourceLocation channelName, Function> factory); +} diff --git a/Fabric/src/main/java/me/hypherionmc/craterlib/CraterLibInitializer.java b/Fabric/src/main/java/me/hypherionmc/craterlib/CraterLibInitializer.java index 09c5ece..252213d 100644 --- a/Fabric/src/main/java/me/hypherionmc/craterlib/CraterLibInitializer.java +++ b/Fabric/src/main/java/me/hypherionmc/craterlib/CraterLibInitializer.java @@ -1,6 +1,8 @@ package me.hypherionmc.craterlib; +import me.hypherionmc.craterlib.common.FabricCommonHelper; import net.fabricmc.api.ModInitializer; +import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; import net.fabricmc.loader.api.entrypoint.PreLaunchEntrypoint; public class CraterLibInitializer implements ModInitializer, PreLaunchEntrypoint { @@ -12,6 +14,6 @@ public class CraterLibInitializer implements ModInitializer, PreLaunchEntrypoint @Override public void onInitialize() { - + ServerLifecycleEvents.SERVER_STARTING.register(server -> FabricCommonHelper.server = server); } } diff --git a/Fabric/src/main/java/me/hypherionmc/craterlib/common/FabricCommonHelper.java b/Fabric/src/main/java/me/hypherionmc/craterlib/common/FabricCommonHelper.java new file mode 100644 index 0000000..7e90bc3 --- /dev/null +++ b/Fabric/src/main/java/me/hypherionmc/craterlib/common/FabricCommonHelper.java @@ -0,0 +1,76 @@ +package me.hypherionmc.craterlib.common; + +import me.hypherionmc.craterlib.network.CraterNetworkHandler; +import me.hypherionmc.craterlib.network.CraterPacket; +import me.hypherionmc.craterlib.network.FabricNetworkHandler; +import me.hypherionmc.craterlib.platform.services.LibCommonHelper; +import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; +import net.fabricmc.fabric.api.networking.v1.PacketSender; +import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.ClientPacketListener; +import net.minecraft.network.Connection; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.network.ServerGamePacketListenerImpl; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.Level; + +import java.util.function.Function; + +/** + * @author HypherionSA + * @date 24/09/2022 + */ +public class FabricCommonHelper implements LibCommonHelper { + + public static MinecraftServer server; + + @Override + public CraterNetworkHandler createPacketHandler(String modid) { + return FabricNetworkHandler.of(modid); + } + + @Override + public Minecraft getClientInstance() { + return Minecraft.getInstance(); + } + + @Override + public Player getClientPlayer() { + return Minecraft.getInstance().player; + } + + @Override + public Level getClientLevel() { + return Minecraft.getInstance().level; + } + + @Override + public Connection getClientConnection() { + return Minecraft.getInstance().getConnection().getConnection(); + } + + @Override + public MinecraftServer getMCServer() { + return server; + } + + @Override + public void registerClientReceiver(ResourceLocation channelName, Function> factory) { + ClientPlayNetworking.registerGlobalReceiver(channelName, (Minecraft client, ClientPacketListener handler, FriendlyByteBuf buf, PacketSender responseSender) -> { + CraterPacket packet = factory.apply(buf); + client.execute(() -> packet.handle(client.player, client)); + }); + } + + @Override + public void registerServerReceiver(ResourceLocation channelName, Function> factory) { + ServerPlayNetworking.registerGlobalReceiver(channelName, (MinecraftServer server, ServerPlayer player, ServerGamePacketListenerImpl handler, FriendlyByteBuf buf, PacketSender responseSender) -> { + CraterPacket packet = factory.apply(buf); + server.execute(() -> packet.handle(player, server)); + }); + } +} diff --git a/Fabric/src/main/java/me/hypherionmc/craterlib/common/FabricLoaderHelper.java b/Fabric/src/main/java/me/hypherionmc/craterlib/common/FabricLoaderHelper.java new file mode 100644 index 0000000..e59150d --- /dev/null +++ b/Fabric/src/main/java/me/hypherionmc/craterlib/common/FabricLoaderHelper.java @@ -0,0 +1,71 @@ +package me.hypherionmc.craterlib.common; + +import me.hypherionmc.craterlib.platform.services.Environment; +import me.hypherionmc.craterlib.platform.services.ILoaderHelper; +import net.fabricmc.loader.api.FabricLoader; +import net.minecraft.SharedConstants; +import net.minecraft.client.Minecraft; + +import java.io.File; +import java.nio.file.Path; +import java.nio.file.Paths; + +/** + * @author HypherionSA + * @date 07/08/2022 + */ +public class FabricLoaderHelper implements ILoaderHelper { + + @Override + public boolean isFabric() { + return true; + } + + @Override + public boolean isForge() { + return false; + } + + @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(); + } +} diff --git a/Fabric/src/main/java/me/hypherionmc/craterlib/common/FabricPlatformHelper.java b/Fabric/src/main/java/me/hypherionmc/craterlib/common/FabricPlatformHelper.java deleted file mode 100644 index 1f6082a..0000000 --- a/Fabric/src/main/java/me/hypherionmc/craterlib/common/FabricPlatformHelper.java +++ /dev/null @@ -1,26 +0,0 @@ -package me.hypherionmc.craterlib.common; - -import me.hypherionmc.craterlib.platform.services.IPlatformHelper; -import net.fabricmc.loader.api.FabricLoader; - -/** - * @author HypherionSA - * @date 07/08/2022 - */ -public class FabricPlatformHelper implements IPlatformHelper { - - @Override - public String getPlatformName() { - return "Fabric"; - } - - @Override - public boolean isModLoaded(String modId) { - return FabricLoader.getInstance().isModLoaded(modId); - } - - @Override - public boolean isDevelopmentEnvironment() { - return FabricLoader.getInstance().isDevelopmentEnvironment(); - } -} diff --git a/Fabric/src/main/java/me/hypherionmc/craterlib/network/FabricNetworkHandler.java b/Fabric/src/main/java/me/hypherionmc/craterlib/network/FabricNetworkHandler.java new file mode 100644 index 0000000..b45db30 --- /dev/null +++ b/Fabric/src/main/java/me/hypherionmc/craterlib/network/FabricNetworkHandler.java @@ -0,0 +1,78 @@ +package me.hypherionmc.craterlib.network; + +import com.google.common.collect.Maps; +import me.hypherionmc.craterlib.platform.Platform; +import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; +import net.fabricmc.fabric.api.networking.v1.PacketByteBufs; +import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; +import net.minecraft.Util; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.protocol.Packet; +import net.minecraft.resources.ResourceLocation; + +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.BiFunction; +import java.util.function.Function; +import java.util.function.Supplier; + +/** + * @author HypherionSA + * @date 24/09/2022 + */ +public class FabricNetworkHandler implements CraterNetworkHandler { + + private static final Map NETWORK_HANDLERS = Maps.newConcurrentMap(); + private final Map>, PacketData> packets = Maps.newIdentityHashMap(); + + private final String modid; + private final AtomicInteger packetID = new AtomicInteger(); + + private FabricNetworkHandler(String modid) { + this.modid = modid; + } + + @Override + public > void registerPacket(Class clazz, Supplier supplier, PacketDirection packetDirection) { + ResourceLocation channelName = this.nextId(); + this.packets.put(clazz, new PacketData(clazz, channelName, packetDirection)); + + final Function> decoder = buf -> Util.make(supplier.get(), message -> message.read(buf)); + + switch (packetDirection) { + case TO_CLIENT -> Platform.COMMON_HELPER.registerClientReceiver(channelName, decoder); + case TO_SERVER -> Platform.COMMON_HELPER.registerServerReceiver(channelName, decoder); + } + } + + private ResourceLocation nextId() { + return new ResourceLocation(this.modid, "play/" + this.packetID.getAndIncrement()); + } + + @Override + public Packet toServerBound(CraterPacket packet) { + if (this.packets.get(packet.getClass()).direction() != PacketDirection.TO_SERVER) throw new IllegalStateException("Attempted sending message to wrong side, expected %s, was %s".formatted(PacketDirection.TO_SERVER, PacketDirection.TO_CLIENT)); + return this.toPacket(ClientPlayNetworking::createC2SPacket, packet); + } + + @Override + public Packet toClientBound(CraterPacket packet) { + if (this.packets.get(packet.getClass()).direction() != PacketDirection.TO_CLIENT) throw new IllegalStateException("Attempted sending message to wrong side, expected %s, was %s".formatted(PacketDirection.TO_CLIENT, PacketDirection.TO_SERVER)); + return this.toPacket(ServerPlayNetworking::createS2CPacket, packet); + } + + private Packet toPacket(BiFunction> packetFactory, CraterPacket message) { + ResourceLocation identifier = this.packets.get(message.getClass()).identifier(); + FriendlyByteBuf byteBuf = PacketByteBufs.create(); + message.write(byteBuf); + return packetFactory.apply(identifier, byteBuf); + } + + public synchronized static CraterNetworkHandler of(String modId) { + return NETWORK_HANDLERS.computeIfAbsent(modId, FabricNetworkHandler::new); + } + + private record PacketData(Class> clazz, ResourceLocation identifier, PacketDirection direction) { + + } +} diff --git a/Fabric/src/main/resources/META-INF/services/me.hypherionmc.craterlib.platform.services.ILoaderHelper b/Fabric/src/main/resources/META-INF/services/me.hypherionmc.craterlib.platform.services.ILoaderHelper new file mode 100644 index 0000000..128f2ed --- /dev/null +++ b/Fabric/src/main/resources/META-INF/services/me.hypherionmc.craterlib.platform.services.ILoaderHelper @@ -0,0 +1 @@ +me.hypherionmc.craterlib.common.FabricLoaderHelper diff --git a/Fabric/src/main/resources/META-INF/services/me.hypherionmc.craterlib.platform.services.IPlatformHelper b/Fabric/src/main/resources/META-INF/services/me.hypherionmc.craterlib.platform.services.IPlatformHelper deleted file mode 100644 index 59c73df..0000000 --- a/Fabric/src/main/resources/META-INF/services/me.hypherionmc.craterlib.platform.services.IPlatformHelper +++ /dev/null @@ -1 +0,0 @@ -me.hypherionmc.craterlib.common.FabricPlatformHelper diff --git a/Fabric/src/main/resources/META-INF/services/me.hypherionmc.craterlib.platform.services.LibCommonHelper b/Fabric/src/main/resources/META-INF/services/me.hypherionmc.craterlib.platform.services.LibCommonHelper new file mode 100644 index 0000000..41f2b3f --- /dev/null +++ b/Fabric/src/main/resources/META-INF/services/me.hypherionmc.craterlib.platform.services.LibCommonHelper @@ -0,0 +1 @@ +me.hypherionmc.craterlib.common.FabricCommonHelper diff --git a/Forge/src/main/java/me/hypherionmc/craterlib/common/ForgeCommonHelper.java b/Forge/src/main/java/me/hypherionmc/craterlib/common/ForgeCommonHelper.java new file mode 100644 index 0000000..8a3fc8e --- /dev/null +++ b/Forge/src/main/java/me/hypherionmc/craterlib/common/ForgeCommonHelper.java @@ -0,0 +1,65 @@ +package me.hypherionmc.craterlib.common; + +import me.hypherionmc.craterlib.network.CraterNetworkHandler; +import me.hypherionmc.craterlib.network.CraterPacket; +import me.hypherionmc.craterlib.network.ForgeNetworkHandler; +import me.hypherionmc.craterlib.platform.services.LibCommonHelper; +import net.minecraft.client.Minecraft; +import net.minecraft.network.Connection; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.MinecraftServer; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.Level; +import net.minecraftforge.server.ServerLifecycleHooks; + +import java.util.Objects; +import java.util.function.Function; + +/** + * @author HypherionSA + * @date 24/09/2022 + */ +public class ForgeCommonHelper implements LibCommonHelper { + + @Override + public CraterNetworkHandler createPacketHandler(String modid) { + return ForgeNetworkHandler.of(modid, true, true); + } + + @Override + public Minecraft getClientInstance() { + return Minecraft.getInstance(); + } + + @Override + public Player getClientPlayer() { + return Minecraft.getInstance().player; + } + + @Override + public Level getClientLevel() { + return Minecraft.getInstance().level; + } + + @Override + public Connection getClientConnection() { + Objects.requireNonNull(Minecraft.getInstance().getConnection(), "Cannot send packets when not in game!"); + return Minecraft.getInstance().getConnection().getConnection(); + } + + @Override + public MinecraftServer getMCServer() { + return ServerLifecycleHooks.getCurrentServer(); + } + + @Override + public void registerClientReceiver(ResourceLocation channelName, Function> factory) { + // UNUSED + } + + @Override + public void registerServerReceiver(ResourceLocation channelName, Function> factory) { + // UNUSED + } +} diff --git a/Forge/src/main/java/me/hypherionmc/craterlib/common/ForgeLoaderHelper.java b/Forge/src/main/java/me/hypherionmc/craterlib/common/ForgeLoaderHelper.java new file mode 100644 index 0000000..c5f26dc --- /dev/null +++ b/Forge/src/main/java/me/hypherionmc/craterlib/common/ForgeLoaderHelper.java @@ -0,0 +1,72 @@ +package me.hypherionmc.craterlib.common; + +import me.hypherionmc.craterlib.platform.services.Environment; +import me.hypherionmc.craterlib.platform.services.ILoaderHelper; +import net.minecraft.SharedConstants; +import net.minecraft.client.Minecraft; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.fml.ModList; +import net.minecraftforge.fml.loading.FMLLoader; +import net.minecraftforge.fml.loading.FMLPaths; + +import java.io.File; + +/** + * @author HypherionSA + * @date 07/08/2022 + */ +public class ForgeLoaderHelper implements ILoaderHelper { + + @Override + public boolean isFabric() { + return false; + } + + @Override + public boolean isForge() { + return true; + } + + @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(); + } +} diff --git a/Forge/src/main/java/me/hypherionmc/craterlib/common/ForgePlatformHelper.java b/Forge/src/main/java/me/hypherionmc/craterlib/common/ForgePlatformHelper.java deleted file mode 100644 index f8d443c..0000000 --- a/Forge/src/main/java/me/hypherionmc/craterlib/common/ForgePlatformHelper.java +++ /dev/null @@ -1,27 +0,0 @@ -package me.hypherionmc.craterlib.common; - -import me.hypherionmc.craterlib.platform.services.IPlatformHelper; -import net.minecraftforge.fml.ModList; -import net.minecraftforge.fml.loading.FMLLoader; - -/** - * @author HypherionSA - * @date 07/08/2022 - */ -public class ForgePlatformHelper implements IPlatformHelper { - - @Override - public String getPlatformName() { - return "Forge"; - } - - @Override - public boolean isModLoaded(String modId) { - return ModList.get().isLoaded(modId); - } - - @Override - public boolean isDevelopmentEnvironment() { - return !FMLLoader.isProduction(); - } -} diff --git a/Forge/src/main/java/me/hypherionmc/craterlib/network/ForgeNetworkHandler.java b/Forge/src/main/java/me/hypherionmc/craterlib/network/ForgeNetworkHandler.java new file mode 100644 index 0000000..f4f2b8e --- /dev/null +++ b/Forge/src/main/java/me/hypherionmc/craterlib/network/ForgeNetworkHandler.java @@ -0,0 +1,112 @@ +package me.hypherionmc.craterlib.network; + +import com.google.common.collect.Maps; +import me.hypherionmc.craterlib.platform.Platform; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.protocol.Packet; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.player.Player; +import net.minecraftforge.common.util.LogicalSidedProvider; +import net.minecraftforge.fml.LogicalSide; +import net.minecraftforge.network.NetworkDirection; +import net.minecraftforge.network.NetworkEvent; +import net.minecraftforge.network.NetworkRegistry; +import net.minecraftforge.network.simple.SimpleChannel; + +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.BiConsumer; +import java.util.function.Function; +import java.util.function.Supplier; + +/** + * @author HypherionSA + * @date 24/09/2022 + * Partly inspired by and based on https://github.com/Fuzss/puzzleslib/blob/1.19/Forge/src/main/java/fuzs/puzzleslib/network/ForgeNetworkHandler.java + */ +public class ForgeNetworkHandler implements CraterNetworkHandler { + + private static final Map NETWORK_HANDLERS = Maps.newConcurrentMap(); + private static final String PROTOCOL = Integer.toString(1); + + private final SimpleChannel channel; + + private final boolean clientRequired; + + private final boolean serverRequired; + + private final AtomicInteger packetID = new AtomicInteger(); + + private ForgeNetworkHandler(SimpleChannel channel, boolean clientRequired, boolean serverRequired) { + this.channel = channel; + this.clientRequired = clientRequired; + this.serverRequired = serverRequired; + } + + @Override + public > void registerPacket(Class clazz, Supplier supplier, PacketDirection packetDirection) { + BiConsumer encoder = CraterPacket::write; + Function decoder = buf -> { + T packet = supplier.get(); + packet.read(buf); + return packet; + }; + + BiConsumer> handler = (packet, sup) -> { + NetworkEvent.Context context = sup.get(); + LogicalSide expectedSide = getSideFromDirection(packetDirection); + LogicalSide currentSide = context.getDirection().getReceptionSide(); + + if (expectedSide != currentSide) { + throw new IllegalStateException(String.format("Received message on wrong side, expected %s, was %s", expectedSide, currentSide)); + } + + context.enqueueWork(() -> { + Player player; + if (packetDirection == PacketDirection.TO_CLIENT) { + player = Platform.COMMON_HELPER.getClientPlayer(); + } else { + player = context.getSender(); + } + packet.handle(player, LogicalSidedProvider.WORKQUEUE.get(expectedSide)); + }); + context.setPacketHandled(true); + }; + this.channel.registerMessage(this.packetID.getAndIncrement(), (Class) clazz, encoder, decoder, handler); + } + + @Override + public Packet toServerBound(CraterPacket packet) { + return this.channel.toVanillaPacket(packet, NetworkDirection.PLAY_TO_SERVER); + } + + @Override + public Packet toClientBound(CraterPacket packet) { + return this.channel.toVanillaPacket(packet, NetworkDirection.PLAY_TO_CLIENT); + } + + @Override + public void sendToServer(CraterPacket packet) { + CraterNetworkHandler.super.sendToServer(packet); + } + + public synchronized static CraterNetworkHandler of(String modId, boolean clientRequired, boolean serverRequired) { + ForgeNetworkHandler handler = NETWORK_HANDLERS.computeIfAbsent(modId, modId1 -> new ForgeNetworkHandler(buildSimpleChannel(modId1, clientRequired, serverRequired), clientRequired, serverRequired)); + if (handler.clientRequired != clientRequired) throw new IllegalArgumentException("client channel settings mismatch, expected %s, but was %s".formatted(handler.clientRequired, clientRequired)); + if (handler.serverRequired != serverRequired) throw new IllegalArgumentException("server channel settings mismatch, expected %s, but was %s".formatted(handler.serverRequired, serverRequired)); + return handler; + } + + private static SimpleChannel buildSimpleChannel(String modId, boolean clientAcceptsVanillaOrMissing, boolean serverAcceptsVanillaOrMissing) { + return NetworkRegistry.ChannelBuilder + .named(new ResourceLocation(modId, "crater_network")) + .networkProtocolVersion(() -> PROTOCOL) + .clientAcceptedVersions(clientAcceptsVanillaOrMissing ? NetworkRegistry.acceptMissingOr(PROTOCOL) : PROTOCOL::equals) + .serverAcceptedVersions(serverAcceptsVanillaOrMissing ? NetworkRegistry.acceptMissingOr(PROTOCOL) : PROTOCOL::equals) + .simpleChannel(); + } + + private LogicalSide getSideFromDirection(PacketDirection direction) { + return direction == PacketDirection.TO_CLIENT ? LogicalSide.CLIENT : LogicalSide.SERVER; + } +} diff --git a/Forge/src/main/resources/META-INF/services/me.hypherionmc.craterlib.platform.services.ILoaderHelper b/Forge/src/main/resources/META-INF/services/me.hypherionmc.craterlib.platform.services.ILoaderHelper new file mode 100644 index 0000000..abf0ea4 --- /dev/null +++ b/Forge/src/main/resources/META-INF/services/me.hypherionmc.craterlib.platform.services.ILoaderHelper @@ -0,0 +1 @@ +me.hypherionmc.craterlib.common.ForgeLoaderHelper diff --git a/Forge/src/main/resources/META-INF/services/me.hypherionmc.craterlib.platform.services.IPlatformHelper b/Forge/src/main/resources/META-INF/services/me.hypherionmc.craterlib.platform.services.IPlatformHelper deleted file mode 100644 index c1aaf3f..0000000 --- a/Forge/src/main/resources/META-INF/services/me.hypherionmc.craterlib.platform.services.IPlatformHelper +++ /dev/null @@ -1 +0,0 @@ -me.hypherionmc.craterlib.common.ForgePlatformHelper diff --git a/Forge/src/main/resources/META-INF/services/me.hypherionmc.craterlib.platform.services.LibCommonHelper b/Forge/src/main/resources/META-INF/services/me.hypherionmc.craterlib.platform.services.LibCommonHelper new file mode 100644 index 0000000..4ce84ae --- /dev/null +++ b/Forge/src/main/resources/META-INF/services/me.hypherionmc.craterlib.platform.services.LibCommonHelper @@ -0,0 +1 @@ +me.hypherionmc.craterlib.common.ForgeCommonHelper