1.12.2 Communication bidirectionnelle Forge Spigot



  • Salut

    Pour un mod, j'ai besoin d'établir une communication bi-directionnelle entre mon mod et mon plugin spigot

    Je dois pouvoir envoyer des données depuis mon mod vers mon plugin et inversement.
    Pour m'entrainer, j'ai commencé à créer un plugin et un mod. Mais je suis confronté à un problème que je n'arrive pas à résoudre (j'essaie depuis plusieurs heures)

    J'arrive à envoyer des messages depuis forge et à les traiter dans spigot. Mais par contre, je ne peut envoyer de message depuis spigot vers forge
    Il n'y a pas de message d'erreur

    J'ai essayé de voir ce qui se passait dans Wireshark, mais la masse de paquets rend la tâche très ardue car je ne sais pas où regarder. Je soupçonne néanmoins Spigot de ne pas envoyer du tout le paquet

    Déja voila la source du mods forge

    PacketHandler:
    
    import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
    import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
    import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
    
    public class PacketHandler implements IMessageHandler<GenericMessage, IMessage> {
    	@Override
    	public IMessage onMessage(GenericMessage message, MessageContext ctx) {
    		System.out.println("RECEIVED CL MESSAGE !");
    		return message;
    	}
    }
    

    HUDData:

    
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
    import net.minecraftforge.fml.common.gameevent.TickEvent;
    import net.minecraftforge.fml.common.network.NetworkRegistry;
    import net.minecraftforge.fml.common.network.simpleimpl.SimpleNetworkWrapper;
    import net.minecraftforge.fml.relauncher.Side;
    
    public class HUDData {
    	public SimpleNetworkWrapper network;
    
    	public int ticksSinceLastPulse = 0;
    	
    	public void preInit()
    	{
    		network = NetworkRegistry.INSTANCE.newSimpleChannel("LKHud");
    		PacketHandler handler = new PacketHandler();
    		network.registerMessage(handler, GenericMessage.class, 0, Side.CLIENT);
    	    System.out.println("LKHud registered as CLIENT Side with 0");
    	}
    	
    	@SubscribeEvent
    	public void onClientTick(TickEvent.ClientTickEvent event) {
    		if (event.phase == TickEvent.Phase.START) {
    			ticksSinceLastPulse++;
    
    			if (ticksSinceLastPulse > 300) {
    				this.sendHUDRefresh();
    				ticksSinceLastPulse = 0;
    			}
    		}
    	}
    
    	void sendHUDRefresh() {
    		System.out.println("Sending test message to server");
    		network.sendToServer(new GenericMessage(new SimpleDateFormat("dd-MM-yyyy hh:mm:ss").format(new Date())));
    		System.out.println("Sent test message to server");
    	}
    }
    
    
    GenericMessage:
    
    
    import io.netty.buffer.ByteBuf;
    import net.minecraftforge.fml.common.network.ByteBufUtils;
    import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
    
    public class GenericMessage implements IMessage {
    	String s;
    
    	public GenericMessage() {
    		System.out.println("Incoming message");
    		// Empty constructor for incoming messages.
    	}
    
    	// Constructor for outgoing messages
    	public GenericMessage(String s) {
    		this.s = s;
    	}
    
    	@Override
    	public void fromBytes(ByteBuf buf) {
    		// Convert the ByteBuf object to a String object
    		System.out.println("From Bytes");
    		s = ByteBufUtils.readUTF8String(buf);
    	}
    
    	// Just returns the message stored in the GenericMessage object
    	public String getMessage() {
    		return s;
    	}
    
    	@Override
    	public void toBytes(ByteBuf buf) {
    		// Converts the message from the outgoing constructor to bytes for sending.
    		buf.writeBytes(s.getBytes());
    	}
    }
    

    Ensuite, le plugin Spigot

    Main:

    import java.util.logging.Logger;
    import org.bukkit.Bukkit;
    import org.bukkit.plugin.java.JavaPlugin;
    
    public class LKHudServer extends JavaPlugin {
    
    	static LKHudServer plugin;
    
    	// Fired when plugin is disabled
    	@Override
    	public void onDisable() {
    
    	}
    
    	@Override
    	public void onEnable() {
    		plugin = this;
    		Logger logger = this.getLogger();
    		logger.info("Initializing LKHudServer side");
    		Bukkit.getMessenger().registerOutgoingPluginChannel(this, "LKHud");
    		Bukkit.getMessenger().registerIncomingPluginChannel(this, "LKHud", new MessageListener());
    	}
    
    }
    
    

    MessageListenener:

    import org.bukkit.entity.Player;
    import org.bukkit.plugin.messaging.PluginMessageListener;
    
    import java.util.Arrays;
    
    public class MessageListener implements PluginMessageListener {
        @Override
        public void onPluginMessageReceived(String channel, Player player, byte[] message) {
            System.out.println("Received message >" + channel + "<");
            if (channel.equals("LKHud")) {
                byte[] effectiveMessage = Arrays.copyOfRange(message, 1, message.length);
                System.out.println(new String(effectiveMessage));
                player.sendMessage("RECEIVED MESSAGE");
                byte[] output = new byte[8];
                output[0] = (byte)0;
                output[1] = (byte)0;
                output[2] = (byte)0;
                output[3] = (byte)0;
                output[4] = (byte)0;
                output[5] = (byte)0;
                output[6] = (byte)0;
                output[7] = (byte)0;
                player.sendPluginMessage(LKHudServer.plugin, "LKHud", output);
                System.out.println("Sent back to the client");
            }
    
        }
    }
    

    J'ai lu sur les forums que le premier byte devait être égal au packet ID défini dans HUDData (network.registerMessage(handler, GenericMessage.class, 0, Side.CLIENT))

    Toute aide ou suggestion est appréciée
    Merci d'avance



  • Rebonjour !
    J'ai trouvé.

    En fait maintenant je passe par ProtocolLib pour envoyer un PacketType.Play.Server.CUSTOM_PAYLOAD (Le même type de paquet qu'envoyé par forge)

    En gros cela se résume à ceci:

    ByteBuf bf = Unpooled.buffer(256);
    bf.setByte(0, (byte) 0);
    bf.setByte(1, (byte) 0); // J'envoie toujours un byte vide car je crois avoir repéré une erreur d'alignement.
    bf.setInt(2, 999); // On peut envoyer des données
    
    
    PacketContainer pluginAnswer = new PacketContainer(PacketType.Play.Server.CUSTOM_PAYLOAD);
    pluginAnswer.getStrings().write(0, "LKHud"); // Le nom du channel
    pluginAnswer.getModifier().write(1, MinecraftReflection.getPacketDataSerializer(bf));
    try {
        LKHudServer.plugin.protocolManager.sendServerPacket(player, pluginAnswer);
    } catch (InvocationTargetException e) {
        e.printStackTrace();
    }
    


  • @Alcibiade est ce que tu peux expliquer ton code stp?



  • @sportday24 Salut, pas de problème, tu voudrais que j'explique quelle partie ?



  • @Alcibiade Comment tu fait pour envoyer les info?

    J'ai change ton code pour que minecraft reconait le mod



  • @Alcibiade j'ai ca bf644733-4e41-444a-a489-d2d45181c4c4-image.png

    mais comment je peux voir l'info qui est envoyer ?



  • L'info envoyée c'est à toi de la définir dans ça.

    bf.setByte(0, (byte) 0);
    bf.setByte(1, (byte) 0); // J'envoie toujours un byte vide car je crois avoir repéré une erreur d'alignement.
    bf.setInt(2, 999); // On peut envoyer des données
    

    Après pour la voir, il faut que tu la print côté client.
    Je complète ma réponse demain, là je vais dormir



  • @Alcibiade la c'est envoyer depuis forge c'est ca?

    ok bonne nuit



  • @sportday24 Dans ma deuxième réponse (où j'ai trouvé la solution), on se trouve côté serveur. Plus spécifiquement dans le message listener, à partir de la ligne 11 inclus.

    Dans ma deuxième réponse, j'utilise la librarie ProtocolLib.

    Puis je traite côté client ce paquet dans la classe GenericMessage.



  • This post is deleted!

Log in to reply