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 5 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.net.NetClientSession;
import org.geysermc.mcprotocollib.network.net.NetServer;
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,11 @@ public static void main(String[] args) {
return;
}

Server server = new TcpServer("127.0.0.1", 25565, TestProtocol::new);
Server server = new NetServer(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 = new NetClientSession(new InetSocketAddress("127.0.0.1", 25565), new TestProtocol(key));
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.net.NetClientSession;
import org.geysermc.mcprotocollib.network.net.NetServer;
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.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 NetServer(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,7 @@ private static void status() {
sessionService.setProxy(AUTH_PROXY);

MinecraftProtocol protocol = new MinecraftProtocol();
Session client = new TcpClientSession(HOST, PORT, protocol, PROXY);
ClientSession client = new NetClientSession(ADDRESS, protocol, PROXY);
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 +205,7 @@ private static void login() {
SessionService sessionService = new SessionService();
sessionService.setProxy(AUTH_PROXY);

Session client = new TcpClientSession(HOST, PORT, protocol, PROXY);
ClientSession client = new NetClientSession(ADDRESS, protocol, PROXY);
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 @@ -10,6 +10,7 @@
import org.geysermc.mcprotocollib.network.event.server.SessionRemovedEvent;
import org.geysermc.mcprotocollib.network.packet.PacketProtocol;

import java.net.SocketAddress;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
Expand All @@ -18,29 +19,22 @@
import java.util.function.Supplier;

public abstract class AbstractServer implements Server {
private final String host;
private final int port;
private final SocketAddress bindAddress;
private final Supplier<? extends PacketProtocol> protocolSupplier;

private final List<Session> sessions = new ArrayList<>();

private final Map<String, Object> flags = new HashMap<>();
private final List<ServerListener> listeners = new ArrayList<>();

public AbstractServer(String host, int port, Supplier<? extends PacketProtocol> protocolSupplier) {
this.host = host;
this.port = port;
public AbstractServer(SocketAddress bindAddress, Supplier<? extends PacketProtocol> protocolSupplier) {
this.bindAddress = bindAddress;
this.protocolSupplier = protocolSupplier;
}

@Override
public String getHost() {
return this.host;
}

@Override
public int getPort() {
return this.port;
public SocketAddress getBindAddress() {
return this.bindAddress;
}

@Override
Expand All @@ -63,15 +57,10 @@ public boolean hasGlobalFlag(Flag<?> flag) {
}

@Override
public <T> T getGlobalFlag(Flag<T> flag) {
return this.getGlobalFlag(flag, null);
}

@Override
public <T> T getGlobalFlag(Flag<T> flag, T def) {
public <T> T getGlobalFlagSupplied(Flag<T> flag, Supplier<T> defSupplier) {
Object value = this.flags.get(flag.key());
if (value == null) {
return def;
return defSupplier.get();
}

try {
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,20 @@
package org.geysermc.mcprotocollib.network;

/**
* 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);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import org.geysermc.mcprotocollib.network.event.server.ServerListener;
import org.geysermc.mcprotocollib.network.packet.PacketProtocol;

import java.net.SocketAddress;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;
Expand All @@ -12,18 +13,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 +56,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,20 @@
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.net.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.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 +78,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 +96,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
Loading