Initial Network System implementation
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -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");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -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 {
|
||||
|
||||
<T extends CraterPacket<T>> void registerPacket(Class<? extends T> clazz, Supplier<T> 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));
|
||||
}
|
||||
|
||||
}
|
@@ -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<T extends CraterPacket<T>> {
|
||||
|
||||
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<T> createHandler();
|
||||
|
||||
abstract class PacketHandler<T extends CraterPacket<T>> {
|
||||
public abstract void handle(T packet, Player player, Object minecraft);
|
||||
}
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
package me.hypherionmc.craterlib.network;
|
||||
|
||||
/**
|
||||
* @author HypherionSA
|
||||
* @date 24/09/2022
|
||||
*/
|
||||
public enum PacketDirection {
|
||||
TO_SERVER,
|
||||
TO_CLIENT
|
||||
}
|
@@ -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> T load(Class<T> clazz) {
|
||||
|
||||
final T loadedService = ServiceLoader.load(clazz)
|
@@ -0,0 +1,11 @@
|
||||
package me.hypherionmc.craterlib.platform.services;
|
||||
|
||||
/**
|
||||
* @author HypherionSA
|
||||
* @date 24/09/2022
|
||||
*/
|
||||
public enum Environment {
|
||||
CLIENT,
|
||||
SERVER,
|
||||
UNKNOWN
|
||||
}
|
@@ -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();
|
||||
}
|
@@ -1,11 +0,0 @@
|
||||
package me.hypherionmc.craterlib.platform.services;
|
||||
|
||||
public interface IPlatformHelper {
|
||||
|
||||
String getPlatformName();
|
||||
|
||||
boolean isModLoaded(String modId);
|
||||
|
||||
boolean isDevelopmentEnvironment();
|
||||
|
||||
}
|
@@ -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<FriendlyByteBuf, CraterPacket<?>> factory);
|
||||
public void registerServerReceiver(ResourceLocation channelName, Function<FriendlyByteBuf, CraterPacket<?>> factory);
|
||||
}
|
@@ -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);
|
||||
}
|
||||
}
|
||||
|
@@ -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<FriendlyByteBuf, CraterPacket<?>> 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<FriendlyByteBuf, CraterPacket<?>> 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));
|
||||
});
|
||||
}
|
||||
}
|
@@ -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();
|
||||
}
|
||||
}
|
@@ -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();
|
||||
}
|
||||
}
|
@@ -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<String, FabricNetworkHandler> NETWORK_HANDLERS = Maps.newConcurrentMap();
|
||||
private final Map<Class<? extends CraterPacket<?>>, PacketData> packets = Maps.newIdentityHashMap();
|
||||
|
||||
private final String modid;
|
||||
private final AtomicInteger packetID = new AtomicInteger();
|
||||
|
||||
private FabricNetworkHandler(String modid) {
|
||||
this.modid = modid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends CraterPacket<T>> void registerPacket(Class<? extends T> clazz, Supplier<T> supplier, PacketDirection packetDirection) {
|
||||
ResourceLocation channelName = this.nextId();
|
||||
this.packets.put(clazz, new PacketData(clazz, channelName, packetDirection));
|
||||
|
||||
final Function<FriendlyByteBuf, CraterPacket<?>> 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<ResourceLocation, FriendlyByteBuf, Packet<?>> 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<? extends CraterPacket<?>> clazz, ResourceLocation identifier, PacketDirection direction) {
|
||||
|
||||
}
|
||||
}
|
@@ -0,0 +1 @@
|
||||
me.hypherionmc.craterlib.common.FabricLoaderHelper
|
@@ -1 +0,0 @@
|
||||
me.hypherionmc.craterlib.common.FabricPlatformHelper
|
@@ -0,0 +1 @@
|
||||
me.hypherionmc.craterlib.common.FabricCommonHelper
|
@@ -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<FriendlyByteBuf, CraterPacket<?>> factory) {
|
||||
// UNUSED
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerServerReceiver(ResourceLocation channelName, Function<FriendlyByteBuf, CraterPacket<?>> factory) {
|
||||
// UNUSED
|
||||
}
|
||||
}
|
@@ -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();
|
||||
}
|
||||
}
|
@@ -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();
|
||||
}
|
||||
}
|
@@ -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<String, ForgeNetworkHandler> 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 <T extends CraterPacket<T>> void registerPacket(Class<? extends T> clazz, Supplier<T> supplier, PacketDirection packetDirection) {
|
||||
BiConsumer<T, FriendlyByteBuf> encoder = CraterPacket::write;
|
||||
Function<FriendlyByteBuf, T> decoder = buf -> {
|
||||
T packet = supplier.get();
|
||||
packet.read(buf);
|
||||
return packet;
|
||||
};
|
||||
|
||||
BiConsumer<T, Supplier<NetworkEvent.Context>> 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<T>) 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;
|
||||
}
|
||||
}
|
@@ -0,0 +1 @@
|
||||
me.hypherionmc.craterlib.common.ForgeLoaderHelper
|
@@ -1 +0,0 @@
|
||||
me.hypherionmc.craterlib.common.ForgePlatformHelper
|
@@ -0,0 +1 @@
|
||||
me.hypherionmc.craterlib.common.ForgeCommonHelper
|
Reference in New Issue
Block a user