diff --git a/src/main/java/de/mrjulsen/crn/network/NetworkManager.java b/src/main/java/de/mrjulsen/crn/network/NetworkManager.java index 8c304378..5c1868cf 100644 --- a/src/main/java/de/mrjulsen/crn/network/NetworkManager.java +++ b/src/main/java/de/mrjulsen/crn/network/NetworkManager.java @@ -23,7 +23,6 @@ import de.mrjulsen.crn.network.packets.stc.TrackStationResponsePacket; import de.mrjulsen.crn.network.packets.stc.TrainDataResponsePacket; import de.mrjulsen.mcdragonlib.network.IPacketBase; -import de.mrjulsen.mcdragonlib.network.NetworkManagerBase; public class NetworkManager extends NetworkManagerBase { @@ -34,7 +33,7 @@ public NetworkManager(String modid, String channelName, String protocolVersion) } public static void create() { - instance = NetworkManagerBase.create(NetworkManager.class, ModMain.MOD_ID, "crn_network_channel", "5"); + instance = NetworkManagerBase.create(NetworkManager.class, ModMain.MOD_ID, "createrailwaysnavigator_network", "v6"); } public static NetworkManager getInstance() { diff --git a/src/main/java/de/mrjulsen/crn/network/NetworkManagerBase.java b/src/main/java/de/mrjulsen/crn/network/NetworkManagerBase.java new file mode 100644 index 00000000..2d48049c --- /dev/null +++ b/src/main/java/de/mrjulsen/crn/network/NetworkManagerBase.java @@ -0,0 +1,97 @@ +package de.mrjulsen.crn.network; + +import java.lang.reflect.InvocationTargetException; +import java.util.Collection; +import java.util.Optional; +import java.util.function.Supplier; + +import de.mrjulsen.mcdragonlib.DragonLib; +import de.mrjulsen.mcdragonlib.network.IPacketBase; +import net.minecraft.network.Connection; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerPlayer; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.fml.DistExecutor; +import net.minecraftforge.network.NetworkDirection; +import net.minecraftforge.network.NetworkEvent; +import net.minecraftforge.network.NetworkRegistry; +import net.minecraftforge.network.simple.SimpleChannel; + +public abstract class NetworkManagerBase> { + + public final String PROTOCOL_VERSION; + private static int currentId = 0; + + public final SimpleChannel MOD_CHANNEL; + + protected NetworkManagerBase(String modid, String channelName, String protocolVersion) { + PROTOCOL_VERSION = protocolVersion; + MOD_CHANNEL = NetworkRegistry.ChannelBuilder.named(new ResourceLocation(modid, channelName)).networkProtocolVersion(() -> PROTOCOL_VERSION).clientAcceptedVersions(PROTOCOL_VERSION::equals).serverAcceptedVersions(PROTOCOL_VERSION::equals).simpleChannel(); + + registerPackets(packets()); + } + + public > void registerPackets(Collection>> classes) { + for (Class> clazz : classes) { + registerPacketHelper(clazz); + } + } + + @SuppressWarnings("unchecked") + private > void registerPacketHelper(Class clazz) { + registerPacket((Class)clazz); + } + + + public static > T create(Class networkManager, String modid, String channelName, String protocolVersion) { + try { + return networkManager.getConstructor(String.class, String.class, String.class).newInstance(modid, channelName, protocolVersion); + } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) { + e.printStackTrace(); + DragonLib.LOGGER.error("Unable to create NetworkManager.", e); + return null; + } + } + + public abstract Collection>> packets(); + + public SimpleChannel getPlayChannel() { + return MOD_CHANNEL; + } + + private > void registerPacket(Class clazz) { + try { + T packet = clazz.getConstructor().newInstance(); + currentId++; + final int id = currentId; + MOD_CHANNEL.registerMessage(id, clazz, packet::encode, packet::decode, packet::handle, Optional.of(packet.getDirection())); + } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) { + e.printStackTrace(); + DragonLib.LOGGER.error("Unable to register packet.", e); + } + } + + public void sendToClient(IPacketBase o, ServerPlayer player) { + MOD_CHANNEL.sendTo(o, player.connection.getConnection(), NetworkDirection.PLAY_TO_CLIENT); + } + + public void sendToServer(Connection connection, IPacketBase o) { + MOD_CHANNEL.sendTo(o, connection, NetworkDirection.PLAY_TO_SERVER); + } + + public static void executeOnClient(Runnable task) { + DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> task.run()); + } + + public static > void handlePacket(T packet, Supplier context, Runnable run) { + context.get().enqueueWork(() -> { + if (packet.getDirection() == NetworkDirection.PLAY_TO_SERVER || packet.getDirection() == NetworkDirection.LOGIN_TO_SERVER) { + run.run(); + } else if (packet.getDirection() == NetworkDirection.PLAY_TO_CLIENT || packet.getDirection() == NetworkDirection.LOGIN_TO_CLIENT) { + executeOnClient(run); + } + }); + context.get().setPacketHandled(true); + } +} +