Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reimplement session structure #869

Merged
merged 16 commits into from
Jan 18, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
package org.geysermc.mcprotocollib.network.example;

import org.geysermc.mcprotocollib.network.ClientSession;
import org.geysermc.mcprotocollib.network.Server;
import org.geysermc.mcprotocollib.network.Session;
import org.geysermc.mcprotocollib.network.tcp.TcpClientSession;
import org.geysermc.mcprotocollib.network.tcp.TcpServer;
import org.geysermc.mcprotocollib.network.factory.ClientNetworkSessionFactory;
import org.geysermc.mcprotocollib.network.server.NetworkServer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.net.InetSocketAddress;
import java.security.NoSuchAlgorithmException;

public class PingServerTest {
Expand All @@ -25,11 +26,14 @@ public static void main(String[] args) {
return;
}

Server server = new TcpServer("127.0.0.1", 25565, TestProtocol::new);
Server server = new NetworkServer(new InetSocketAddress("127.0.0.1", 25565), TestProtocol::new);
server.addListener(new ServerListener(key));
server.bind();

Session client = new TcpClientSession("127.0.0.1", 25565, new TestProtocol(key));
ClientSession client = ClientNetworkSessionFactory.factory()
.setAddress("127.0.0.1", 25565)
.setProtocol(new TestProtocol(key))
.create();
client.connect();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public ServerListener(SecretKey key) {

@Override
public void serverBound(ServerBoundEvent event) {
log.info("SERVER Bound: {}:{}", event.getServer().getHost(), event.getServer().getPort());
log.info("SERVER Bound: {}", event.getServer().getBindAddress());
}

@Override
Expand All @@ -36,14 +36,14 @@ public void serverClosed(ServerClosedEvent event) {

@Override
public void sessionAdded(SessionAddedEvent event) {
log.info("SERVER Session Added: {}:{}", event.getSession().getHost(), event.getSession().getPort());
log.info("SERVER Session Added: {}", event.getSession().getRemoteAddress());
((TestProtocol) event.getSession().getPacketProtocol()).setSecretKey(this.key);
event.getSession().setEncryption(((TestProtocol) event.getSession().getPacketProtocol()).getEncryption());
}

@Override
public void sessionRemoved(SessionRemovedEvent event) {
log.info("SERVER Session Removed: {}:{}", event.getSession().getHost(), event.getSession().getPort());
log.info("SERVER Session Removed: {}", event.getSession().getRemoteAddress());
event.getServer().close(false);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public EncryptionConfig getEncryption() {
}

@Override
public void newClientSession(Session session, boolean transferring) {
public void newClientSession(Session session) {
session.addListener(new ClientSessionListener());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import net.raphimc.minecraftauth.step.msa.StepCredentialsMsaCode;
import org.geysermc.mcprotocollib.auth.GameProfile;
import org.geysermc.mcprotocollib.auth.SessionService;
import org.geysermc.mcprotocollib.network.ClientSession;
import org.geysermc.mcprotocollib.network.ProxyInfo;
import org.geysermc.mcprotocollib.network.Server;
import org.geysermc.mcprotocollib.network.Session;
Expand All @@ -20,9 +21,9 @@
import org.geysermc.mcprotocollib.network.event.server.SessionRemovedEvent;
import org.geysermc.mcprotocollib.network.event.session.DisconnectedEvent;
import org.geysermc.mcprotocollib.network.event.session.SessionAdapter;
import org.geysermc.mcprotocollib.network.factory.ClientNetworkSessionFactory;
import org.geysermc.mcprotocollib.network.packet.Packet;
import org.geysermc.mcprotocollib.network.tcp.TcpClientSession;
import org.geysermc.mcprotocollib.network.tcp.TcpServer;
import org.geysermc.mcprotocollib.network.server.NetworkServer;
import org.geysermc.mcprotocollib.protocol.MinecraftConstants;
import org.geysermc.mcprotocollib.protocol.MinecraftProtocol;
import org.geysermc.mcprotocollib.protocol.codec.MinecraftCodec;
Expand All @@ -38,6 +39,8 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.util.ArrayList;
Expand All @@ -50,8 +53,7 @@ public class MinecraftProtocolTest {
private static final boolean SPAWN_SERVER = true;
private static final boolean ENCRYPT_CONNECTION = true;
private static final boolean SHOULD_AUTHENTICATE = false;
private static final String HOST = "127.0.0.1";
private static final int PORT = 25565;
private static final SocketAddress ADDRESS = new InetSocketAddress("127.0.0.1", 25565);
private static final ProxyInfo PROXY = null;
private static final ProxyInfo AUTH_PROXY = null;
private static final String USERNAME = "Username";
Expand All @@ -62,7 +64,7 @@ public static void main(String[] args) {
SessionService sessionService = new SessionService();
sessionService.setProxy(AUTH_PROXY);

Server server = new TcpServer(HOST, PORT, MinecraftProtocol::new);
Server server = new NetworkServer(ADDRESS, MinecraftProtocol::new);
server.setGlobalFlag(MinecraftConstants.SESSION_SERVICE_KEY, sessionService);
server.setGlobalFlag(MinecraftConstants.ENCRYPT_CONNECTION, ENCRYPT_CONNECTION);
server.setGlobalFlag(MinecraftConstants.SHOULD_AUTHENTICATE, SHOULD_AUTHENTICATE);
Expand Down Expand Up @@ -155,7 +157,11 @@ private static void status() {
sessionService.setProxy(AUTH_PROXY);

MinecraftProtocol protocol = new MinecraftProtocol();
Session client = new TcpClientSession(HOST, PORT, protocol, PROXY);
ClientSession client = ClientNetworkSessionFactory.factory()
.setRemoteSocketAddress(ADDRESS)
.setProtocol(protocol)
.setProxy(PROXY)
.create();
client.setFlag(MinecraftConstants.SESSION_SERVICE_KEY, sessionService);
client.setFlag(MinecraftConstants.SERVER_INFO_HANDLER_KEY, (session, info) -> {
log.info("Version: {}, {}", info.getVersionInfo().getVersionName(), info.getVersionInfo().getProtocolVersion());
Expand Down Expand Up @@ -203,7 +209,12 @@ private static void login() {
SessionService sessionService = new SessionService();
sessionService.setProxy(AUTH_PROXY);

Session client = new TcpClientSession(HOST, PORT, protocol, PROXY);

ClientSession client = ClientNetworkSessionFactory.factory()
.setRemoteSocketAddress(ADDRESS)
.setProtocol(protocol)
.setProxy(PROXY)
.create();
client.setFlag(MinecraftConstants.SESSION_SERVICE_KEY, sessionService);
client.addListener(new SessionAdapter() {
@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ public class BuiltinFlags {
*/
public static final Flag<InetSocketAddress> CLIENT_PROXIED_ADDRESS = new Flag<>("client-proxied-address", InetSocketAddress.class);

/**
* Whether the current client is transferring.
*/
public static final Flag<Boolean> CLIENT_TRANSFERRING = new Flag<>("transferring", Boolean.class);

/**
* When set to false, an SRV record resolve is not attempted.
*/
Expand All @@ -34,7 +39,7 @@ public class BuiltinFlags {
* Used by both the server and client.
*/
public static final Flag<Integer> READ_TIMEOUT = new Flag<>("read-timeout", Integer.class);

/**
* Write timeout in seconds.
* Used by both the server and client.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package org.geysermc.mcprotocollib.network;

import org.checkerframework.checker.nullness.qual.Nullable;

/**
* A network client session.
*/
public interface ClientSession extends Session {
/**
* Connects this session to its host and port.
*/
default void connect() {
connect(true);
}

/**
* Connects this session to its host and port.
*
* @param wait Whether to wait for the connection to be established before returning.
*/
void connect(boolean wait);

/**
* Get the proxy used by this session.
*
* @return The proxy used by this session.
*/
@Nullable ProxyInfo getProxy();
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

import org.geysermc.mcprotocollib.network.event.server.ServerListener;
import org.geysermc.mcprotocollib.network.packet.PacketProtocol;
import org.geysermc.mcprotocollib.network.server.AbstractServer;

import java.net.SocketAddress;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;
Expand All @@ -12,18 +14,11 @@
*/
public interface Server {
/**
* Gets the host the session is listening on.
* Gets the bind address the server is listening on.
*
* @return The listening host.
* @return The listening bind address.
*/
String getHost();

/**
* Gets the port the session is listening on.
*
* @return The listening port.
*/
int getPort();
SocketAddress getBindAddress();

/**
* Gets the packet protocol of the server.
Expand Down Expand Up @@ -62,19 +57,28 @@ public interface Server {
* @return Value of the flag.
* @throws IllegalStateException If the flag's value isn't of the required type.
*/
<T> T getGlobalFlag(Flag<T> flag);
default <T> T getGlobalFlag(Flag<T> flag) {
return getGlobalFlagSupplied(flag, () -> null);
}

/**
* @see #getGlobalFlagSupplied(Flag, Supplier)
*/
default <T> T getGlobalFlag(Flag<T> flag, T def) {
return getGlobalFlagSupplied(flag, () -> def);
}

/**
* Gets the value of the given flag as an instance of the given type.
* If the flag is not set, the specified default value will be returned.
*
* @param <T> Type of the flag.
* @param flag Flag to check for.
* @param def Default value of the flag.
* @param defSupplier Default value supplier.
* @return Value of the flag.
* @throws IllegalStateException If the flag's value isn't of the required type.
*/
<T> T getGlobalFlag(Flag<T> flag, T def);
<T> T getGlobalFlagSupplied(Flag<T> flag, Supplier<T> defSupplier);

/**
* Sets the value of a flag. The flag will be used in sessions if a session does
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.geysermc.mcprotocollib.network;

/**
* A network server session.
*/
public interface ServerSession extends Session {
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,53 +9,21 @@
import org.geysermc.mcprotocollib.network.crypt.EncryptionConfig;
import org.geysermc.mcprotocollib.network.event.session.SessionEvent;
import org.geysermc.mcprotocollib.network.event.session.SessionListener;
import org.geysermc.mcprotocollib.network.netty.FlushHandler;
import org.geysermc.mcprotocollib.network.packet.Packet;
import org.geysermc.mcprotocollib.network.packet.PacketProtocol;
import org.geysermc.mcprotocollib.network.tcp.FlushHandler;

import java.net.SocketAddress;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executor;
import java.util.function.Supplier;

/**
* A network session.
*/
public interface Session {

/**
* Connects this session to its host and port.
*/
void connect();

/**
* Connects this session to its host and port.
*
* @param wait Whether to wait for the connection to be established before returning.
*/
void connect(boolean wait);

/**
* Connects this session to its host and port.
*
* @param wait Whether to wait for the connection to be established before returning.
* @param transferring Whether the session is a client being transferred.
*/
void connect(boolean wait, boolean transferring);

/**
* Gets the host the session is connected to.
*
* @return The connected host.
*/
String getHost();

/**
* Gets the port the session is connected to.
*
* @return The connected port.
*/
int getPort();

/**
* Gets the local address of the session.
*
Expand Down Expand Up @@ -111,7 +79,16 @@ public interface Session {
* @return Value of the flag.
* @throws IllegalStateException If the flag's value isn't of the required type.
*/
<T> T getFlag(Flag<T> flag);
default <T> T getFlag(Flag<T> flag) {
return this.getFlagSupplied(flag, () -> null);
}

/**
* @see #getFlagSupplied(Flag, Supplier)
*/
default <T> T getFlag(Flag<T> flag, T def) {
return this.getFlagSupplied(flag, () -> def);
}

/**
* Gets the value of the given flag as an instance of the given type. If this
Expand All @@ -120,11 +97,11 @@ public interface Session {
*
* @param <T> Type of the flag.
* @param flag Flag to check for.
* @param def Default value of the flag.
* @param defSupplier Default value supplier.
* @return Value of the flag.
* @throws IllegalStateException If the flag's value isn't of the required type.
*/
<T> T getFlag(Flag<T> flag, T def);
<T> T getFlagSupplied(Flag<T> flag, Supplier<T> defSupplier);

/**
* Sets the value of a flag. This does not change a server's flags if this session
Expand Down Expand Up @@ -286,6 +263,13 @@ default void disconnect(@NonNull Component reason) {
*/
Channel getChannel();

/**
* Returns the executor that handles packet handling.
*
* @return The packet handler executor
*/
Executor getPacketHandlerExecutor();

/**
* Changes the inbound state of the session and then re-enables auto read.
* This is used after a terminal packet was handled and the session is ready to receive more packets in the new state.
Expand Down
Loading
Loading