Auto-detect. Now works as expected
This commit is contained in:
parent
b021bed467
commit
772098772f
|
|
@ -4,7 +4,7 @@ plugins {
|
|||
}
|
||||
|
||||
group 'org.adde0109'
|
||||
version '1.0.6-alpha'
|
||||
version '1.0.7-alpha'
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import org.slf4j.Logger;
|
|||
|
||||
import java.nio.file.Path;
|
||||
|
||||
@Plugin(id = "ambassador", name = "Ambassador", version = "1.0.6-alpha", authors = {"adde0109"})
|
||||
@Plugin(id = "ambassador", name = "Ambassador", version = "1.0.7-alpha", authors = {"adde0109"})
|
||||
public class Ambassador {
|
||||
|
||||
public ProxyServer server;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package org.adde0109.ambassador.forge;
|
||||
|
||||
import com.velocitypowered.api.event.Continuation;
|
||||
import com.velocitypowered.api.event.player.KickedFromServerEvent;
|
||||
import com.velocitypowered.api.proxy.server.RegisteredServer;
|
||||
import com.velocitypowered.api.util.UuidUtils;
|
||||
|
|
@ -12,23 +11,15 @@ import com.velocitypowered.proxy.connection.backend.VelocityServerConnection;
|
|||
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
|
||||
import com.velocitypowered.proxy.network.Connections;
|
||||
import com.velocitypowered.proxy.protocol.StateRegistry;
|
||||
import com.velocitypowered.proxy.protocol.packet.LoginPluginMessage;
|
||||
import com.velocitypowered.proxy.protocol.packet.LoginPluginResponse;
|
||||
import com.velocitypowered.proxy.protocol.packet.PluginMessage;
|
||||
import com.velocitypowered.proxy.protocol.packet.ServerLoginSuccess;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.ByteBufUtil;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.kyori.adventure.identity.Identity;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.adde0109.ambassador.velocity.VelocityForgeClientConnectionPhase;
|
||||
import org.adde0109.ambassador.velocity.VelocityForgeHandshakeSessionHandler;
|
||||
import org.adde0109.ambassador.velocity.VelocityLoginPayloadManager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class FML2CRPMClientConnectionPhase extends VelocityForgeClientConnectionPhase {
|
||||
private static String OUTBOUND_CATCHER_NAME = "ambassador-catcher";
|
||||
|
|
@ -36,18 +27,11 @@ public class FML2CRPMClientConnectionPhase extends VelocityForgeClientConnection
|
|||
//TODO: Use modData inside ConnectedPlayer instead
|
||||
public byte[] modListData;
|
||||
private RegisteredServer backupServer;
|
||||
@Override
|
||||
public void handleLogin(ConnectedPlayer player, VelocityServer server, Continuation continuation) {
|
||||
final MinecraftConnection connection = player.getConnection();
|
||||
VelocityForgeHandshakeSessionHandler sessionHandler = new VelocityForgeHandshakeSessionHandler(connection.getSessionHandler(), player);
|
||||
getPayloadManager().sendPayload("fml:loginwrapper",Unpooled.wrappedBuffer(ForgeHandshakeUtils.emptyModlist)).thenAccept((data) -> {
|
||||
if (modListData == null)
|
||||
modListData = ByteBufUtil.getBytes(data);
|
||||
this.clientPhase = ClientPhase.MODDED;
|
||||
continuation.resume();
|
||||
});
|
||||
connection.setSessionHandler(sessionHandler);
|
||||
connection.flush();
|
||||
|
||||
public FML2CRPMClientConnectionPhase(VelocityForgeClientConnectionPhase.ClientPhase clientPhase, VelocityLoginPayloadManager payloadManager) {
|
||||
super(clientPhase,payloadManager);
|
||||
}
|
||||
public FML2CRPMClientConnectionPhase() {
|
||||
}
|
||||
|
||||
public void reset(VelocityServerConnection serverConnection, ConnectedPlayer player, Runnable whenComplete) {
|
||||
|
|
@ -67,13 +51,18 @@ public class FML2CRPMClientConnectionPhase extends VelocityForgeClientConnection
|
|||
connection.write(new PluginMessage("fml:handshake",Unpooled.wrappedBuffer(ForgeHandshakeUtils.generatePluginResetPacket())));
|
||||
connection.setState(StateRegistry.LOGIN);
|
||||
}
|
||||
getPayloadManager().listenFor(98).thenAccept((ignored) -> {
|
||||
getPayloadManager().listenFor(98).thenAccept((response) -> {
|
||||
this.clientPhase = ClientPhase.HANDSHAKE;
|
||||
whenComplete.run();
|
||||
});
|
||||
|
||||
this.clientPhase = null;
|
||||
connection.getChannel().pipeline().addBefore(Connections.HANDLER,OUTBOUND_CATCHER_NAME,new FML2CRPMOutgoingCatcher());
|
||||
connection.getChannel().pipeline().addBefore(Connections.HANDLER,OUTBOUND_CATCHER_NAME,new FML2CRPMConnectionHandler(() -> {
|
||||
connection.setState(StateRegistry.PLAY);
|
||||
final FML2ClientConnectionPhase newPhase = new FML2ClientConnectionPhase(ClientPhase.HANDSHAKE,getPayloadManager());
|
||||
player.setPhase(newPhase);
|
||||
newPhase.reset(serverConnection,player,whenComplete);
|
||||
}));
|
||||
}
|
||||
public void complete(VelocityServer server, ConnectedPlayer player, MinecraftConnection connection) {
|
||||
VelocityConfiguration configuration = (VelocityConfiguration) server.getConfiguration();
|
||||
|
|
|
|||
|
|
@ -1,16 +1,23 @@
|
|||
package org.adde0109.ambassador.forge;
|
||||
|
||||
import com.velocitypowered.proxy.protocol.packet.LoginPluginMessage;
|
||||
import com.velocitypowered.proxy.protocol.packet.LoginPluginResponse;
|
||||
import com.velocitypowered.proxy.protocol.packet.ServerLoginSuccess;
|
||||
import io.netty.channel.ChannelDuplexHandler;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelOutboundHandlerAdapter;
|
||||
import io.netty.channel.ChannelPromise;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class FML2CRPMOutgoingCatcher extends ChannelOutboundHandlerAdapter {
|
||||
public class FML2CRPMConnectionHandler extends ChannelDuplexHandler {
|
||||
|
||||
private final Map<ChannelPromise, Object> catchedPackets = Collections.synchronizedMap(new LinkedHashMap<>());
|
||||
private final Runnable abort;
|
||||
|
||||
public FML2CRPMConnectionHandler(Runnable abort) {
|
||||
this.abort = abort;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
|
||||
|
|
@ -32,4 +39,15 @@ public class FML2CRPMOutgoingCatcher extends ChannelOutboundHandlerAdapter {
|
|||
catchedPackets.put(promise,msg);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelRead(@NotNull ChannelHandlerContext ctx, @NotNull Object msg) throws Exception {
|
||||
if (!(msg instanceof LoginPluginResponse)) {
|
||||
abort.run();
|
||||
ctx.pipeline().remove(this);
|
||||
ctx.pipeline().fireChannelRead(msg);
|
||||
} else {
|
||||
ctx.fireChannelRead(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4,35 +4,40 @@ import com.velocitypowered.api.event.Continuation;
|
|||
import com.velocitypowered.api.event.player.PlayerChooseInitialServerEvent;
|
||||
import com.velocitypowered.api.proxy.server.RegisteredServer;
|
||||
import com.velocitypowered.api.proxy.server.ServerPing;
|
||||
import com.velocitypowered.api.util.ModInfo;
|
||||
import com.velocitypowered.proxy.VelocityServer;
|
||||
import com.velocitypowered.proxy.connection.MinecraftConnection;
|
||||
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
||||
import com.velocitypowered.proxy.connection.backend.VelocityServerConnection;
|
||||
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
|
||||
import com.velocitypowered.proxy.connection.client.LoginSessionHandler;
|
||||
import com.velocitypowered.proxy.protocol.packet.LoginPluginResponse;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||
import com.velocitypowered.proxy.protocol.packet.LoginPluginMessage;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import org.adde0109.ambassador.velocity.VelocityForgeClientConnectionPhase;
|
||||
import org.adde0109.ambassador.velocity.VelocityLoginPayloadManager;
|
||||
import org.apache.commons.collections4.map.PassiveExpiringMap;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class FML2ClientConnectionPhase extends VelocityForgeClientConnectionPhase {
|
||||
|
||||
private static String OUTBOUND_CATCHER_NAME = "ambassador-catcher";
|
||||
|
||||
private static final PassiveExpiringMap<String,RegisteredServer> TEMPORARY_FORCED = new PassiveExpiringMap<>(120, TimeUnit.SECONDS);
|
||||
|
||||
private Throwable throwable;
|
||||
private RegisteredServer triedServer;
|
||||
private Continuation continuation;
|
||||
|
||||
public FML2ClientConnectionPhase(VelocityForgeClientConnectionPhase.ClientPhase clientPhase, VelocityLoginPayloadManager payloadManager) {
|
||||
super(clientPhase,payloadManager);
|
||||
}
|
||||
public FML2ClientConnectionPhase(){
|
||||
super();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void handleLogin(ConnectedPlayer player, VelocityServer server, Continuation continuation) {
|
||||
|
|
@ -50,20 +55,8 @@ public class FML2ClientConnectionPhase extends VelocityForgeClientConnectionPhas
|
|||
});
|
||||
};
|
||||
|
||||
final RegisteredServer forced = TEMPORARY_FORCED.remove(player.getUsername());
|
||||
if (forced != null) {
|
||||
forced.ping().whenCompleteAsync((msg,ex) -> {
|
||||
if (ex == null) {
|
||||
if (throwable == null)
|
||||
throwable = ex;
|
||||
handlePingResponse(msg);
|
||||
} else {
|
||||
defaultTask.run();
|
||||
}
|
||||
},connection.eventLoop());
|
||||
} else {
|
||||
connection.eventLoop().submit(defaultTask);
|
||||
}
|
||||
forced = TEMPORARY_FORCED.remove(player.getUsername());
|
||||
connection.eventLoop().submit(defaultTask);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -77,6 +70,14 @@ public class FML2ClientConnectionPhase extends VelocityForgeClientConnectionPhas
|
|||
if (triedServer != null)
|
||||
player.sendMessage(Component.translatable("velocity.error.connecting-server-error",
|
||||
Component.text(triedServer.getServerInfo().getName())));
|
||||
if (clientPhase == ClientPhase.VANILLA) {
|
||||
player.setPhase(new FML2CRPMClientConnectionPhase(ClientPhase.VANILLA,getPayloadManager()));
|
||||
} else if (clientPhase == ClientPhase.MODLIST) {
|
||||
clientPhase = ClientPhase.MODDED;
|
||||
internalServerConnection = player.getConnectionInFlight();
|
||||
player.resetInFlightConnection();
|
||||
continuation.resume();
|
||||
}
|
||||
}
|
||||
|
||||
private void tryServer(ConnectedPlayer player, RegisteredServer server) {
|
||||
|
|
@ -89,21 +90,37 @@ public class FML2ClientConnectionPhase extends VelocityForgeClientConnectionPhas
|
|||
if (ex != null) {
|
||||
if (throwable == null)
|
||||
throwable = ex;
|
||||
tryServer(player,player.getNextServerToTry().orElse(null));
|
||||
tryServer(player, player.getNextServerToTry().orElse(null));
|
||||
} else {
|
||||
handlePingResponse(msg);
|
||||
handlePingResponse(player, server, msg);
|
||||
}
|
||||
}, player.getConnection().eventLoop());
|
||||
}
|
||||
|
||||
private void handlePingResponse(ServerPing ping) {
|
||||
if (ping.getModinfo().isEmpty() || !ping.getModinfo().get().getType().equals("Ambassador")) {
|
||||
continuation.resume();
|
||||
return;
|
||||
|
||||
@Override
|
||||
public void forwardPayload(VelocityServerConnection serverConnection, LoginPluginMessage payload) {
|
||||
ByteBuf buf = payload.content().copy();
|
||||
String channel = ProtocolUtils.readString(buf);
|
||||
int length = ProtocolUtils.readVarInt(buf);
|
||||
int id = ProtocolUtils.readVarInt(buf);
|
||||
if (id == 1) {
|
||||
String[] mods = ProtocolUtils.readStringArray(buf);
|
||||
|
||||
if (Arrays.stream(mods).anyMatch(s -> s.equals("clientresetpacket"))) {
|
||||
serverConnection.getPlayer().setPhase(new FML2CRPMClientConnectionPhase(ClientPhase.VANILLA,getPayloadManager()));
|
||||
}
|
||||
}
|
||||
super.forwardPayload(serverConnection, payload);
|
||||
}
|
||||
|
||||
private void handlePingResponse(ConnectedPlayer player, RegisteredServer server, ServerPing ping) {
|
||||
if (ping.getModinfo().isEmpty()) {
|
||||
clientPhase = ClientPhase.VANILLA;
|
||||
continuation.resume();
|
||||
} else {
|
||||
player.createConnectionRequest(server).fireAndForget();
|
||||
}
|
||||
ModInfo.Mod mod = ping.getModinfo().get().getMods().get(0);
|
||||
String data = mod.getId();
|
||||
String markers = mod.getVersion();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,11 +2,14 @@ package org.adde0109.ambassador.velocity;
|
|||
|
||||
import com.velocitypowered.api.event.Continuation;
|
||||
import com.velocitypowered.api.event.PostOrder;
|
||||
import com.velocitypowered.api.event.ResultedEvent;
|
||||
import com.velocitypowered.api.event.Subscribe;
|
||||
import com.velocitypowered.api.event.connection.LoginEvent;
|
||||
import com.velocitypowered.api.event.connection.PostLoginEvent;
|
||||
import com.velocitypowered.api.event.permission.PermissionsSetupEvent;
|
||||
import com.velocitypowered.api.event.player.KickedFromServerEvent;
|
||||
import com.velocitypowered.api.event.player.PlayerChooseInitialServerEvent;
|
||||
import com.velocitypowered.api.event.player.ServerPreConnectEvent;
|
||||
import com.velocitypowered.proxy.VelocityServer;
|
||||
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
|
||||
import org.adde0109.ambassador.Ambassador;
|
||||
|
|
@ -40,4 +43,32 @@ public class VelocityEventHandler {
|
|||
}
|
||||
continuation.resume();
|
||||
}
|
||||
|
||||
@Subscribe(order = PostOrder.FIRST)
|
||||
public void onServerPreConnectEvent(ServerPreConnectEvent event, Continuation continuation) {
|
||||
ConnectedPlayer player = (ConnectedPlayer) event.getPlayer();
|
||||
if (!(player.getPhase() instanceof VelocityForgeClientConnectionPhase phase)) {
|
||||
continuation.resume();
|
||||
return;
|
||||
}
|
||||
if (phase.internalServerConnection != null) {
|
||||
event.setResult(ServerPreConnectEvent.ServerResult.denied());
|
||||
phase.internalServerConnection = null;
|
||||
}
|
||||
continuation.resume();
|
||||
}
|
||||
|
||||
@Subscribe(order = PostOrder.LAST)
|
||||
public void onPlayerChooseInitialServerEvent(PlayerChooseInitialServerEvent event, Continuation continuation) {
|
||||
ConnectedPlayer player = (ConnectedPlayer) event.getPlayer();
|
||||
if (!(player.getPhase() instanceof VelocityForgeClientConnectionPhase phase)) {
|
||||
continuation.resume();
|
||||
return;
|
||||
}
|
||||
if (phase.forced != null)
|
||||
event.setInitialServer(phase.forced);
|
||||
if (event.getInitialServer().isEmpty())
|
||||
event.setInitialServer(phase.internalServerConnection.getServer());
|
||||
continuation.resume();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
package org.adde0109.ambassador.velocity;
|
||||
|
||||
import com.velocitypowered.api.event.Continuation;
|
||||
import com.velocitypowered.api.proxy.ServerConnection;
|
||||
import com.velocitypowered.api.proxy.server.RegisteredServer;
|
||||
import com.velocitypowered.proxy.VelocityServer;
|
||||
import com.velocitypowered.proxy.connection.MinecraftConnection;
|
||||
import com.velocitypowered.proxy.connection.backend.VelocityServerConnection;
|
||||
|
|
@ -9,17 +11,24 @@ import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
|
|||
import com.velocitypowered.proxy.protocol.packet.LoginPluginMessage;
|
||||
import com.velocitypowered.proxy.protocol.packet.LoginPluginResponse;
|
||||
import org.adde0109.ambassador.forge.FML2CRPMClientConnectionPhase;
|
||||
import org.adde0109.ambassador.forge.ForgeHandshakeUtils;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public abstract class VelocityForgeClientConnectionPhase implements ClientConnectionPhase {
|
||||
//TODO:Make class when PCF is done
|
||||
|
||||
|
||||
VelocityLoginPayloadManager payloadManager;
|
||||
public FML2CRPMClientConnectionPhase.ClientPhase clientPhase = ClientPhase.HANDSHAKE;
|
||||
public VelocityForgeClientConnectionPhase.ClientPhase clientPhase = ClientPhase.HANDSHAKE;
|
||||
|
||||
public ServerConnection internalServerConnection;
|
||||
public RegisteredServer forced;
|
||||
|
||||
protected VelocityForgeClientConnectionPhase(ClientPhase clientPhase, VelocityLoginPayloadManager payloadManager) {
|
||||
this.clientPhase = clientPhase;
|
||||
this.payloadManager = payloadManager;
|
||||
}
|
||||
protected VelocityForgeClientConnectionPhase() {
|
||||
|
||||
}
|
||||
|
||||
public void handleLogin(ConnectedPlayer player, VelocityServer server, Continuation continuation) {
|
||||
}
|
||||
|
|
@ -34,6 +43,9 @@ public abstract class VelocityForgeClientConnectionPhase implements ClientConnec
|
|||
final void fireLoginEvent(ConnectedPlayer player, VelocityServer server, Continuation continuation) {
|
||||
payloadManager = new VelocityLoginPayloadManager(player.getConnection());
|
||||
handleLogin(player,server,continuation);
|
||||
|
||||
VelocityForgeHandshakeSessionHandler sessionHandler = new VelocityForgeHandshakeSessionHandler(player.getConnection().getSessionHandler(), player);
|
||||
player.getConnection().setSessionHandler(sessionHandler);
|
||||
}
|
||||
|
||||
public void forwardPayload(VelocityServerConnection serverConnection, LoginPluginMessage payload) {
|
||||
|
|
@ -44,6 +56,7 @@ public abstract class VelocityForgeClientConnectionPhase implements ClientConnec
|
|||
//Move this to the backend. Backend should have its own forwarder.
|
||||
serverConnection.getConnection().write(new LoginPluginResponse(payload.getId(),responseData.isReadable(),responseData.retain()));
|
||||
});
|
||||
clientPhase = ClientPhase.MODLIST;
|
||||
}
|
||||
|
||||
public final VelocityLoginPayloadManager getPayloadManager() {
|
||||
|
|
|
|||
|
|
@ -20,15 +20,13 @@ public class VelocityForgeBackendConnectionPhase implements BackendConnectionPha
|
|||
|
||||
public void handleSuccess(VelocityServerConnection serverCon, VelocityServer server) {
|
||||
VelocityForgeClientConnectionPhase clientPhase = ((VelocityForgeClientConnectionPhase) serverCon.getPlayer().getPhase());
|
||||
if (clientPhase.clientPhase == VelocityForgeClientConnectionPhase.ClientPhase.HANDSHAKE || clientPhase.clientPhase == VelocityForgeClientConnectionPhase.ClientPhase.MODLIST) {
|
||||
clientPhase.complete((VelocityServer) server,serverCon.getPlayer(),serverCon.getPlayer().getConnection());
|
||||
}
|
||||
clientPhase.complete((VelocityServer) server,serverCon.getPlayer(),serverCon.getPlayer().getConnection());
|
||||
}
|
||||
|
||||
public boolean handle(VelocityServerConnection server, ConnectedPlayer player, LoginPluginMessage message) throws Exception {
|
||||
VelocityForgeClientConnectionPhase clientPhase = ((FML2CRPMClientConnectionPhase) player.getPhase());
|
||||
VelocityForgeClientConnectionPhase clientPhase = ((VelocityForgeClientConnectionPhase) player.getPhase());
|
||||
message.retain();
|
||||
if (clientPhase.clientPhase == FML2CRPMClientConnectionPhase.ClientPhase.VANILLA) {
|
||||
if (clientPhase.clientPhase == VelocityForgeClientConnectionPhase.ClientPhase.VANILLA) {
|
||||
clientPhase.reset(server,player, () -> {
|
||||
for (LoginPluginMessage msg: queuedHandshakePackets) {
|
||||
clientPhase.forwardPayload(server,msg);
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import io.netty.channel.*;
|
|||
import io.netty.util.ReferenceCountUtil;
|
||||
import org.adde0109.ambassador.forge.ForgeConstants;
|
||||
import org.adde0109.ambassador.forge.FML2CRPMClientConnectionPhase;
|
||||
import org.adde0109.ambassador.velocity.VelocityForgeClientConnectionPhase;
|
||||
|
||||
public class VelocityForgeBackendHandshakeHandler extends ChannelDuplexHandler {
|
||||
|
||||
|
|
@ -30,9 +31,9 @@ public class VelocityForgeBackendHandshakeHandler extends ChannelDuplexHandler {
|
|||
ChannelHandler handler = ctx.pipeline().get(Connections.HANDLER);
|
||||
if (handler instanceof MinecraftConnection connection) {
|
||||
if (connection.getAssociation() instanceof VelocityServerConnection serverConnection) {
|
||||
if (serverConnection.getPlayer().getPhase() instanceof FML2CRPMClientConnectionPhase phase) {
|
||||
if (serverConnection.getPlayer().getPhase() instanceof VelocityForgeClientConnectionPhase phase) {
|
||||
init(connection,serverConnection);
|
||||
if (phase.clientPhase == FML2CRPMClientConnectionPhase.ClientPhase.MODDED) {
|
||||
if (phase.clientPhase == VelocityForgeClientConnectionPhase.ClientPhase.MODDED) {
|
||||
phase.reset(serverConnection ,serverConnection.getPlayer(), () -> {
|
||||
ctx.flush();
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user