mirror of
https://github.com/GeyserMC/MCProtocolLib.git
synced 2024-11-14 11:24:57 -05:00
Use translatable components like vanilla and cleanup type casts (#831)
* Use translatable components like vanilla and cleanup type casts Just a few messages becoming dynamic using translatable components like vanilla instead of being hardcoded. * Use checkerframework * Readd disconnect string methods * Do not make nullable
This commit is contained in:
parent
002754f3af
commit
2b2af7a424
10 changed files with 80 additions and 89 deletions
|
@ -1,5 +1,6 @@
|
|||
package org.geysermc.mcprotocollib.network.example;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.geysermc.mcprotocollib.network.Session;
|
||||
import org.geysermc.mcprotocollib.network.event.session.ConnectedEvent;
|
||||
import org.geysermc.mcprotocollib.network.event.session.DisconnectedEvent;
|
||||
|
@ -14,23 +15,23 @@ public class ClientSessionListener extends SessionAdapter {
|
|||
|
||||
@Override
|
||||
public void packetReceived(Session session, Packet packet) {
|
||||
if (packet instanceof PingPacket) {
|
||||
String id = ((PingPacket) packet).getPingId();
|
||||
if (packet instanceof PingPacket pingPacket) {
|
||||
String id = pingPacket.getPingId();
|
||||
|
||||
log.info("CLIENT Received: {}", id);
|
||||
|
||||
if (id.equals("hello")) {
|
||||
session.send(new PingPacket("exit"));
|
||||
} else if (id.equals("exit")) {
|
||||
session.disconnect("Finished");
|
||||
session.disconnect(Component.text("Finished"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void packetSent(Session session, Packet packet) {
|
||||
if (packet instanceof PingPacket) {
|
||||
log.info("CLIENT Sent: {}", ((PingPacket) packet).getPingId());
|
||||
if (packet instanceof PingPacket pingPacket) {
|
||||
log.info("CLIENT Sent: {}", pingPacket.getPingId());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,16 +14,16 @@ public class ServerSessionListener extends SessionAdapter {
|
|||
|
||||
@Override
|
||||
public void packetReceived(Session session, Packet packet) {
|
||||
if (packet instanceof PingPacket) {
|
||||
log.info("SERVER Received: {}", ((PingPacket) packet).getPingId());
|
||||
if (packet instanceof PingPacket pingPacket) {
|
||||
log.info("SERVER Received: {}", pingPacket.getPingId());
|
||||
session.send(packet);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void packetSent(Session session, Packet packet) {
|
||||
if (packet instanceof PingPacket) {
|
||||
log.info("SERVER Sent: {}", ((PingPacket) packet).getPingId());
|
||||
if (packet instanceof PingPacket pingPacket) {
|
||||
log.info("SERVER Sent: {}", pingPacket.getPingId());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -112,9 +112,9 @@ public class MinecraftProtocolTest {
|
|||
event.getSession().addListener(new SessionAdapter() {
|
||||
@Override
|
||||
public void packetReceived(Session session, Packet packet) {
|
||||
if (packet instanceof ServerboundChatPacket) {
|
||||
if (packet instanceof ServerboundChatPacket chatPacket) {
|
||||
GameProfile profile = event.getSession().getFlag(MinecraftConstants.PROFILE_KEY);
|
||||
log.info("{}: {}", profile.getName(), ((ServerboundChatPacket) packet).getMessage());
|
||||
log.info("{}: {}", profile.getName(), chatPacket.getMessage());
|
||||
|
||||
Component msg = Component.text("Hello, ")
|
||||
.color(NamedTextColor.GREEN)
|
||||
|
@ -207,10 +207,10 @@ public class MinecraftProtocolTest {
|
|||
public void packetReceived(Session session, Packet packet) {
|
||||
if (packet instanceof ClientboundLoginPacket) {
|
||||
session.send(new ServerboundChatPacket("Hello, this is a test of MCProtocolLib.", Instant.now().toEpochMilli(), 0L, null, 0, new BitSet()));
|
||||
} else if (packet instanceof ClientboundSystemChatPacket) {
|
||||
Component message = ((ClientboundSystemChatPacket) packet).getContent();
|
||||
} else if (packet instanceof ClientboundSystemChatPacket systemChatPacket) {
|
||||
Component message = systemChatPacket.getContent();
|
||||
log.info("Received Message: {}", message);
|
||||
session.disconnect("Finished");
|
||||
session.disconnect(Component.text("Finished"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package org.geysermc.mcprotocollib.network;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.geysermc.mcprotocollib.network.event.server.ServerBoundEvent;
|
||||
import org.geysermc.mcprotocollib.network.event.server.ServerClosedEvent;
|
||||
import org.geysermc.mcprotocollib.network.event.server.ServerClosingEvent;
|
||||
|
@ -119,7 +120,7 @@ public abstract class AbstractServer implements Server {
|
|||
public void removeSession(Session session) {
|
||||
this.sessions.remove(session);
|
||||
if (session.isConnected()) {
|
||||
session.disconnect("Connection closed.");
|
||||
session.disconnect(Component.translatable("disconnect.endOfStream"));
|
||||
}
|
||||
|
||||
this.callEvent(new SessionRemovedEvent(this, session));
|
||||
|
@ -164,7 +165,7 @@ public abstract class AbstractServer implements Server {
|
|||
this.callEvent(new ServerClosingEvent(this));
|
||||
for (Session session : this.getSessions()) {
|
||||
if (session.isConnected()) {
|
||||
session.disconnect("Server closed.");
|
||||
session.disconnect(Component.translatable("multiplayer.disconnect.server_shutdown"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package org.geysermc.mcprotocollib.network;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.geysermc.mcprotocollib.network.codec.PacketCodecHelper;
|
||||
import org.geysermc.mcprotocollib.network.crypt.PacketEncryption;
|
||||
|
@ -259,12 +260,39 @@ public interface Session {
|
|||
*/
|
||||
void send(Packet packet);
|
||||
|
||||
/**
|
||||
* Disconnects the session.
|
||||
* This method just wraps the reason into a {@link Component}.
|
||||
* It is recommended to use Components instead as they provide more flexibility.
|
||||
*
|
||||
* @param reason Reason for disconnecting.
|
||||
* @see #disconnect(String, Throwable)
|
||||
*/
|
||||
default void disconnect(@NonNull String reason) {
|
||||
this.disconnect(reason, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnects the session.
|
||||
* This method just wraps the reason into a {@link Component}.
|
||||
* It is recommended to use Components instead as they provide more flexibility.
|
||||
*
|
||||
* @param reason Reason for disconnecting.
|
||||
* @param cause Throwable responsible for disconnecting.
|
||||
* @see #disconnect(Component, Throwable)
|
||||
*/
|
||||
default void disconnect(@NonNull String reason, @Nullable Throwable cause) {
|
||||
this.disconnect(Component.text(reason), cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnects the session.
|
||||
*
|
||||
* @param reason Reason for disconnecting.
|
||||
*/
|
||||
void disconnect(@Nullable String reason);
|
||||
default void disconnect(@NonNull Component reason) {
|
||||
this.disconnect(reason, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnects the session.
|
||||
|
@ -272,20 +300,5 @@ public interface Session {
|
|||
* @param reason Reason for disconnecting.
|
||||
* @param cause Throwable responsible for disconnecting.
|
||||
*/
|
||||
void disconnect(@Nullable String reason, Throwable cause);
|
||||
|
||||
/**
|
||||
* Disconnects the session.
|
||||
*
|
||||
* @param reason Reason for disconnecting.
|
||||
*/
|
||||
void disconnect(@Nullable Component reason);
|
||||
|
||||
/**
|
||||
* Disconnects the session.
|
||||
*
|
||||
* @param reason Reason for disconnecting.
|
||||
* @param cause Throwable responsible for disconnecting.
|
||||
*/
|
||||
void disconnect(@Nullable Component reason, Throwable cause);
|
||||
void disconnect(@NonNull Component reason, @Nullable Throwable cause);
|
||||
}
|
||||
|
|
|
@ -28,8 +28,8 @@ import io.netty.handler.proxy.Socks5ProxyHandler;
|
|||
import io.netty.resolver.dns.DnsNameResolver;
|
||||
import io.netty.resolver.dns.DnsNameResolverBuilder;
|
||||
import io.netty.util.concurrent.DefaultThreadFactory;
|
||||
import org.geysermc.mcprotocollib.network.ProxyInfo;
|
||||
import org.geysermc.mcprotocollib.network.BuiltinFlags;
|
||||
import org.geysermc.mcprotocollib.network.ProxyInfo;
|
||||
import org.geysermc.mcprotocollib.network.codec.PacketCodecHelper;
|
||||
import org.geysermc.mcprotocollib.network.helper.TransportHelper;
|
||||
import org.geysermc.mcprotocollib.network.packet.PacketProtocol;
|
||||
|
@ -256,11 +256,6 @@ public class TcpClientSession extends TcpSession {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnect(String reason, Throwable cause) {
|
||||
super.disconnect(reason, cause);
|
||||
}
|
||||
|
||||
private static void createTcpEventLoopGroup() {
|
||||
if (EVENT_LOOP_GROUP != null) {
|
||||
return;
|
||||
|
|
|
@ -3,17 +3,15 @@ package org.geysermc.mcprotocollib.network.tcp;
|
|||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelFutureListener;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ConnectTimeoutException;
|
||||
import io.netty.channel.DefaultEventLoopGroup;
|
||||
import io.netty.channel.EventLoop;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
import io.netty.handler.timeout.ReadTimeoutException;
|
||||
import io.netty.handler.timeout.ReadTimeoutHandler;
|
||||
import io.netty.handler.timeout.WriteTimeoutException;
|
||||
import io.netty.handler.timeout.WriteTimeoutHandler;
|
||||
import io.netty.util.concurrent.DefaultThreadFactory;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.geysermc.mcprotocollib.network.Flag;
|
||||
import org.geysermc.mcprotocollib.network.Session;
|
||||
|
@ -27,7 +25,6 @@ import org.geysermc.mcprotocollib.network.event.session.SessionListener;
|
|||
import org.geysermc.mcprotocollib.network.packet.Packet;
|
||||
import org.geysermc.mcprotocollib.network.packet.PacketProtocol;
|
||||
|
||||
import java.net.ConnectException;
|
||||
import java.net.SocketAddress;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
|
@ -35,6 +32,7 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
public abstract class TcpSession extends SimpleChannelInboundHandler<Packet> implements Session {
|
||||
/**
|
||||
|
@ -279,22 +277,7 @@ public abstract class TcpSession extends SimpleChannelInboundHandler<Packet> imp
|
|||
}
|
||||
|
||||
@Override
|
||||
public void disconnect(String reason) {
|
||||
this.disconnect(Component.text(reason));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnect(String reason, Throwable cause) {
|
||||
this.disconnect(Component.text(reason), cause);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnect(Component reason) {
|
||||
this.disconnect(reason, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnect(final Component reason, final Throwable cause) {
|
||||
public void disconnect(@NonNull Component reason, @Nullable Throwable cause) {
|
||||
if (this.disconnected) {
|
||||
return;
|
||||
}
|
||||
|
@ -303,11 +286,9 @@ public abstract class TcpSession extends SimpleChannelInboundHandler<Packet> imp
|
|||
|
||||
if (this.channel != null && this.channel.isOpen()) {
|
||||
this.callEvent(new DisconnectingEvent(this, reason, cause));
|
||||
this.channel.flush().close().addListener((ChannelFutureListener) future ->
|
||||
callEvent(new DisconnectedEvent(TcpSession.this,
|
||||
reason != null ? reason : Component.text("Connection closed."), cause)));
|
||||
this.channel.flush().close().addListener((ChannelFutureListener) future -> callEvent(new DisconnectedEvent(TcpSession.this, reason, cause)));
|
||||
} else {
|
||||
this.callEvent(new DisconnectedEvent(this, reason != null ? reason : Component.text("Connection closed."), cause));
|
||||
this.callEvent(new DisconnectedEvent(this, reason, cause));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -385,21 +366,17 @@ public abstract class TcpSession extends SimpleChannelInboundHandler<Packet> imp
|
|||
@Override
|
||||
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
|
||||
if (ctx.channel() == this.channel) {
|
||||
this.disconnect("Connection closed.");
|
||||
this.disconnect(Component.translatable("disconnect.endOfStream"));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
|
||||
String message;
|
||||
if (cause instanceof ConnectTimeoutException || (cause instanceof ConnectException && cause.getMessage().contains("connection timed out"))) {
|
||||
message = "Connection timed out.";
|
||||
} else if (cause instanceof ReadTimeoutException) {
|
||||
message = "Read timed out.";
|
||||
} else if (cause instanceof WriteTimeoutException) {
|
||||
message = "Write timed out.";
|
||||
Component message;
|
||||
if (cause instanceof TimeoutException) {
|
||||
message = Component.translatable("disconnect.timeout");
|
||||
} else {
|
||||
message = cause.toString();
|
||||
message = Component.translatable("disconnect.genericReason", Component.text("Internal Exception: " + cause));
|
||||
}
|
||||
|
||||
this.disconnect(message, cause);
|
||||
|
|
|
@ -3,6 +3,7 @@ package org.geysermc.mcprotocollib.protocol;
|
|||
import lombok.AllArgsConstructor;
|
||||
import lombok.NonNull;
|
||||
import lombok.SneakyThrows;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.geysermc.mcprotocollib.auth.GameProfile;
|
||||
import org.geysermc.mcprotocollib.auth.SessionService;
|
||||
import org.geysermc.mcprotocollib.network.Session;
|
||||
|
@ -77,10 +78,12 @@ public class ClientListener extends SessionAdapter {
|
|||
|
||||
SessionService sessionService = session.getFlag(MinecraftConstants.SESSION_SERVICE_KEY, new SessionService());
|
||||
String serverId = SessionService.getServerId(helloPacket.getServerId(), helloPacket.getPublicKey(), key);
|
||||
|
||||
// TODO: Add generic error, disabled multiplayer and banned from playing online errors
|
||||
try {
|
||||
sessionService.joinServer(profile, accessToken, serverId);
|
||||
} catch (IOException e) {
|
||||
session.disconnect("Login failed: Authentication error: " + e.getMessage(), e);
|
||||
session.disconnect(Component.translatable("disconnect.loginFailedInfo", Component.text(e.getMessage())), e);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -109,7 +112,7 @@ public class ClientListener extends SessionAdapter {
|
|||
handler.handle(session, time);
|
||||
}
|
||||
|
||||
session.disconnect("Finished");
|
||||
session.disconnect(Component.translatable("multiplayer.status.finished"));
|
||||
}
|
||||
} else if (protocol.getState() == ProtocolState.GAME) {
|
||||
if (packet instanceof ClientboundKeepAlivePacket keepAlivePacket && session.getFlag(MinecraftConstants.AUTOMATIC_KEEP_ALIVE_MANAGEMENT, true)) {
|
||||
|
@ -122,7 +125,7 @@ public class ClientListener extends SessionAdapter {
|
|||
if (session.getFlag(MinecraftConstants.FOLLOW_TRANSFERS, true)) {
|
||||
TcpClientSession newSession = new TcpClientSession(transferPacket.getHost(), transferPacket.getPort(), session.getPacketProtocol());
|
||||
newSession.setFlags(session.getFlags());
|
||||
session.disconnect("Transferring");
|
||||
session.disconnect(Component.translatable("disconnect.transfer"));
|
||||
newSession.connect(true, true);
|
||||
}
|
||||
}
|
||||
|
@ -137,7 +140,7 @@ public class ClientListener extends SessionAdapter {
|
|||
if (session.getFlag(MinecraftConstants.FOLLOW_TRANSFERS, true)) {
|
||||
TcpClientSession newSession = new TcpClientSession(transferPacket.getHost(), transferPacket.getPort(), session.getPacketProtocol());
|
||||
newSession.setFlags(session.getFlags());
|
||||
session.disconnect("Transferring");
|
||||
session.disconnect(Component.translatable("disconnect.transfer"));
|
||||
newSession.connect(true, true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -98,15 +98,15 @@ public class ServerListener extends SessionAdapter {
|
|||
case STATUS -> protocol.setState(ProtocolState.STATUS);
|
||||
case TRANSFER -> {
|
||||
if (!session.getFlag(MinecraftConstants.ACCEPT_TRANSFERS_KEY, false)) {
|
||||
session.disconnect("Server does not accept transfers.");
|
||||
session.disconnect(Component.translatable("multiplayer.disconnect.transfers_disabled"));
|
||||
}
|
||||
}
|
||||
case LOGIN -> {
|
||||
protocol.setState(ProtocolState.LOGIN);
|
||||
if (intentionPacket.getProtocolVersion() > protocol.getCodec().getProtocolVersion()) {
|
||||
session.disconnect("Outdated server! I'm still on " + protocol.getCodec().getMinecraftVersion() + ".");
|
||||
session.disconnect(Component.translatable("multiplayer.disconnect.incompatible", Component.text(protocol.getCodec().getMinecraftVersion())));
|
||||
} else if (intentionPacket.getProtocolVersion() < protocol.getCodec().getProtocolVersion()) {
|
||||
session.disconnect("Outdated client! Please use " + protocol.getCodec().getMinecraftVersion() + ".");
|
||||
session.disconnect(Component.translatable("multiplayer.disconnect.outdated_client", Component.text(protocol.getCodec().getMinecraftVersion())));
|
||||
}
|
||||
}
|
||||
default -> throw new UnsupportedOperationException("Invalid client intent: " + intentionPacket.getIntent());
|
||||
|
@ -125,8 +125,7 @@ public class ServerListener extends SessionAdapter {
|
|||
PrivateKey privateKey = KEY_PAIR.getPrivate();
|
||||
|
||||
if (!Arrays.equals(this.challenge, keyPacket.getEncryptedChallenge(privateKey))) {
|
||||
session.disconnect("Invalid challenge!");
|
||||
return;
|
||||
throw new IllegalStateException("Protocol error");
|
||||
}
|
||||
|
||||
SecretKey key = keyPacket.getSecretKey(privateKey);
|
||||
|
@ -183,6 +182,7 @@ public class ServerListener extends SessionAdapter {
|
|||
protocol.setState(ProtocolState.CONFIGURATION);
|
||||
} else if (packet instanceof ServerboundPingRequestPacket pingRequestPacket) {
|
||||
session.send(new ClientboundPongResponsePacket(pingRequestPacket.getPingTime()));
|
||||
session.disconnect(Component.translatable("multiplayer.status.request_handled"));
|
||||
}
|
||||
} else if (protocol.getState() == ProtocolState.CONFIGURATION) {
|
||||
if (packet instanceof ServerboundFinishConfigurationPacket) {
|
||||
|
@ -230,12 +230,13 @@ public class ServerListener extends SessionAdapter {
|
|||
try {
|
||||
profile = sessionService.getProfileByServer(username, SessionService.getServerId(SERVER_ID, KEY_PAIR.getPublic(), this.key));
|
||||
} catch (IOException e) {
|
||||
this.session.disconnect("Failed to make session service request.", e);
|
||||
session.disconnect(Component.translatable("multiplayer.disconnect.authservers_down"), e);
|
||||
return;
|
||||
}
|
||||
|
||||
if (profile == null) {
|
||||
this.session.disconnect("Failed to verify username.");
|
||||
session.disconnect(Component.translatable("multiplayer.disconnect.unverified_username"));
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
profile = new GameProfile(UUID.nameUUIDFromBytes(("OfflinePlayer:" + username).getBytes()), username);
|
||||
|
|
|
@ -83,11 +83,11 @@ public class MinecraftProtocolTest {
|
|||
session.addListener(new DisconnectListener());
|
||||
session.connect();
|
||||
|
||||
handler.status.await(4, SECONDS);
|
||||
assertTrue(handler.status.await(4, SECONDS), "Did not receive server info in time.");
|
||||
assertNotNull(handler.info, "Failed to get server info.");
|
||||
assertEquals(SERVER_INFO, handler.info, "Received incorrect server info.");
|
||||
} finally {
|
||||
session.disconnect("Status test complete.");
|
||||
session.disconnect(Component.text("Status test complete."));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -100,11 +100,11 @@ public class MinecraftProtocolTest {
|
|||
session.addListener(new DisconnectListener());
|
||||
session.connect();
|
||||
|
||||
listener.login.await(4, SECONDS);
|
||||
assertTrue(listener.login.await(4, SECONDS), "Did not receive login packet in time.");
|
||||
assertNotNull(listener.packet, "Failed to log in.");
|
||||
assertEquals(JOIN_GAME_PACKET, listener.packet, "Received incorrect join packet.");
|
||||
} finally {
|
||||
session.disconnect("Login test complete.");
|
||||
session.disconnect(Component.text("Login test complete."));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -125,8 +125,8 @@ public class MinecraftProtocolTest {
|
|||
|
||||
@Override
|
||||
public void packetReceived(Session session, Packet packet) {
|
||||
if (packet instanceof ClientboundLoginPacket) {
|
||||
this.packet = (ClientboundLoginPacket) packet;
|
||||
if (packet instanceof ClientboundLoginPacket loginPacket) {
|
||||
this.packet = loginPacket;
|
||||
this.login.countDown();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue