Résolu 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’erreurJ’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
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.
-
Ce message a été supprimé !