Volver al índice

src/main/java/ar/com/companeros/body/LocalConnection.java

package ar.com.companeros.body;

import io.netty.channel.embedded.EmbeddedChannel;
import io.netty.util.AttributeKey;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import net.minecraft.network.Connection;
import net.minecraft.network.ConnectionProtocol;
import net.minecraft.network.PacketSendListener;
import net.minecraft.network.chat.Component;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.PacketFlow;
import net.minecraftforge.network.NetworkConstants;

/** Transporte de un participante del mismo servidor: canal local, sin abrir sockets. */
final class LocalConnection extends Connection {
    private final EmbeddedChannel localChannel;
    private long deliveredPackets;

    LocalConnection() {
        super(PacketFlow.SERVERBOUND);
        localChannel = new EmbeddedChannel();
        localChannel.pipeline().addLast("packet_handler", this);
        try {
            // channelActive inicializa los atributos vanilla sin reflection ni AccessTransformer.
            super.channelActive(localChannel.pipeline().context(this));
        } catch (Exception failure) {
            localChannel.finishAndReleaseAll();
            throw new IllegalStateException("No se pudo abrir el canal local del agente", failure);
        }
        localChannel.attr(AttributeKey.<String>valueOf("fml:netversion")).set(NetworkConstants.NETVERSION);
        setProtocol(ConnectionProtocol.PLAY);
        pump();
    }

    // Los paquetes dirigidos al propio agente no se guardan en una cola sin consumidor.
    @Override public void send(Packet<?> packet, PacketSendListener completion) {
        deliveredPackets++;
        if (completion != null) completion.onSuccess();
    }

    @Override public void tick() { }
    @Override public boolean isMemoryConnection() { return true; }
    @Override public SocketAddress getRemoteAddress() { return new InetSocketAddress("127.0.0.1", 0); }

    long deliveredPackets() { return deliveredPackets; }

    void pump() {
        localChannel.runPendingTasks();
        localChannel.checkException();
    }

    void close() {
        disconnect(Component.literal("Sesión del agente cerrada"));
        localChannel.finishAndReleaseAll();
    }
}