certFiles = new HashMap<>();
+
+ for (File f : FileUtils.listFiles(folderStructure.privateClientFolder, ".key", ".pem")) {
+ if (f.getName().endsWith(".srl")) continue;
+ String base = FileUtils.stripExt(f.getName());
+ if (f.getName().endsWith(".key")) keyFiles.put(base, f);
+ if (f.getName().endsWith(".pem")) certFiles.put(base, f);
+ }
+
+ int clientIndex = 0;
+ for (String base : keyFiles.keySet()) {
+ File keyFile = keyFiles.get(base);
+ File certFile = certFiles.get(base);
+ if (certFile == null) {
+ File alt = new File(folderStructure.publicClientFolder, base + ".pem");
+ if (alt.exists()) certFile = alt;
+ }
+ if (certFile == null) continue;
+
+ PrivateKey key = PemUtils.loadPrivateKey(keyFile);
+ X509Certificate cert = PemUtils.loadCertificate(certFile);
+
+ String alias = "client-" + (clientIndex++);
+ keyStore.setKeyEntry(alias, key, keyPass, new X509Certificate[]{cert});
+ }
+
+ clientToServer = new NetworkClient.Builder().sslEnabled(ssl).
+ packetHandler(protocolBridge.getProtocolValues().packetHandler)
+ .eventManager(protocolBridge.getProtocolValues().eventManager)
+ .keyStore(keyStore, keyPass)
+ .trustStore(trustStore)
+ .build();
+ } else {
+ clientToServer = new NetworkClient.Builder().sslEnabled(ssl).
+ packetHandler(protocolBridge.getProtocolValues().packetHandler)
+ .eventManager(protocolBridge.getProtocolValues().eventManager)
+ .build();
+ }
}
- /**
- * Gets the Server connection client.
- *
- * @return the NetworkClient handling the Server connection.
- */
public final NetworkClient getClientServerConnection() {
return clientToServer;
}
- /**
- * Initialize connection to Server
- *
- * @param host Server host
- * @param tcpPort Server port
- * @param udpPort Server port
- */
- private final void createServerConnection(String host, int tcpPort, int udpPort) {
- clientToServer = new NetworkClient.ClientBuilder()
- .setLogger(protocolBridge.getLogger())
- .setProxy(protocolBridge.getProxy())
- .setHost(host)
- .setTcpPort(tcpPort)
- .setUdpPort(udpPort)
- .setPacketHandler(protocolBridge.getProtocolValues().packetHandler)
- .setEventManager(protocolBridge.getProtocolValues().eventManager)
- .setRootCAFolder(folderStructure.publicCAFolder)
- .setClientCertificatesFolder(
- folderStructure.publicClientFolder,
- folderStructure.privateClientFolder
- )
- .build();
- }
-
- /**
- * Injects the ProtocolBridge.
- *
- * @param bridge the Bridge instance.
- * @throws IOException when NetworkServer failed to create.
- */
- public final void attachBridge(ProtocolBridge bridge) throws IOException {
+ public final void attachBridge(ProtocolBridge bridge) throws Exception {
if (this.protocolBridge != null)
throw new IllegalStateException("ProtocolBridge already attached!");
-
this.protocolBridge = bridge;
+ protocolBridge.getProtocolValues().eventManager.registerListener(this.getClass());
}
- /**
- * Gets the INS connection client.
- *
- * @return the NetworkClient handling the INS connection.
- */
public final NetworkClient getClientINSConnection() {
return clientToINS;
}
- /**
- * Checks if the required certificate files exist in the specified folder.
- *
- * @param folder the folder to check for certificate files.
- * @param prefix the prefix of the certificate files.
- * @param extension the extension of the certificate files.
- * @throws CertificateException if any required certificate file is missing or invalid.
- * @throws IOException if there are I/O issues during the check.
- */
- private final void checkFileExists(File folder, String prefix, String extension) throws CertificateException, IOException {
+ private void checkFileExists(File folder, String prefix, String extension) throws CertificateException, IOException {
boolean found = false;
- // Check if folder exists
if (folder == null) throw new FileNotFoundException("Folder does not exist");
- // List files in the folder
File[] files = folder.listFiles();
- // Check if folder is empty
if (files == null || files.length == 0)
throw new FileNotFoundException("Folder " + folder.getAbsolutePath() + " is empty");
- // Validate each file in the folder
for (File file : files) {
if (!file.getName().startsWith(prefix))
throw new CertificateException(file.getAbsolutePath() + " is not valid");
- // Check for specific files
if (!found) found = file.getName().equalsIgnoreCase(prefix + NetworkUtils.getPublicIPAddress() + extension);
}
- // If the specific file is not found, throw an exception
if (!found) throw new CertificateException("Missing " + prefix + NetworkUtils.getPublicIPAddress() + extension);
}
- /**
- * Gets the protocol version of the connected server.
- *
- * @return the ProtocolVersion of the server, or PV_1_0_0_CLASSIC if not set.
- */
public final ProtocolVersion getServerVersion() {
return serverVersion == null ? ProtocolVersion.PV_1_0_0_CLASSIC : serverVersion;
}
- /**
- * Sets the protocol version of the connected server.
- *
- * @param serverVersion the ProtocolVersion to set for the server.
- */
public final void setServerVersion(ProtocolVersion serverVersion) {
if (serverVersion == null) this.serverVersion = serverVersion;
}
- /**
- * Gets the protocol version of the connected server.
- *
- * @return the ProtocolVersion of the server, or PV_1_0_0_CLASSIC if not set.
- */
public final ProtocolVersion getInsVersion() {
return insVersion == null ? ProtocolVersion.PV_1_0_0_CLASSIC : insVersion;
}
- /**
- * Sets the protocol version of the connected server.
- *
- * @param insVersion the ProtocolVersion to set for the server.
- */
public final void setInsVersion(ProtocolVersion insVersion) {
if (insVersion == null) this.insVersion = insVersion;
}
- /**
- * Handles disconnect events, resetting the server version and closing the server client connection if necessary.
- *
- * @param event the ClientDisconnectedEvent triggered on INS disconnection.
- */
- public final void onDisconnect(ClientFullyDisconnectedEvent event) {
- // Reset server version on INS disconnect
- if (!clientToINS.isFullyConnected() && clientToINS != null) {
+ @Listener
+ public final void onDisconnect(ClientDisconnectedEvent event) {
+ if (clientToINS != null && !clientToINS.isConnected()) {
insVersion = null;
clientToINS = null;
disconnectFromServer();
}
- if (!clientToServer.isFullyConnected() && clientToServer != null) {
+ if (clientToServer != null && !clientToServer.isConnected()) {
serverVersion = null;
clientToServer = null;
}
}
- /**
- * Checks if the connected insserver is a stable server.
- *
- * @return true if the server is stable, false otherwise.
- */
public final boolean isINSStableServer() {
- // Check if the server version is stable
return !isINSBetaServer() && !isINSClassicServer();
}
- /**
- * Checks if the connected insserver or its compatible versions support stable protocol.
- *
- * @return true if stable protocol is supported, false otherwise.
- */
public final boolean supportINSServerStable() {
boolean yes = false;
for (ProtocolVersion compatibleVersion : getServerVersion().getCompatibleVersions()) {
- // Check if compatible version is stable
yes = compatibleVersion.getProtocolType() == ProtocolVersion.ProtocolType.STABLE;
if (yes) break;
}
-
- // Check if the server version is stable
return isINSStableServer() || yes;
}
- /**
- * Checks if the connected insserver is a beta server.
- *
- * @return true if the server is beta, false otherwise.
- */
public final boolean isINSBetaServer() {
- // Check if the server version is beta
return getInsVersion().getProtocolType() == ProtocolVersion.ProtocolType.BETA;
}
- /**
- * Checks if the connected insserver or its compatible versions support beta protocol.
- *
- * @return true if beta protocol is supported, false otherwise.
- */
public final boolean supportINSServerBeta() {
boolean yes = false;
for (ProtocolVersion compatibleVersion : getInsVersion().getCompatibleVersions()) {
- // Check if compatible version is beta
yes = compatibleVersion.getProtocolType() == ProtocolVersion.ProtocolType.BETA;
if (yes) break;
}
-
- // Check if the server version is beta
return isINSBetaServer() || yes;
}
- /**
- * Checks if the connected insserver is a classic server.
- *
- * @return true if the server is classic, false otherwise.
- */
public final boolean isINSClassicServer() {
- // Check if the server version is classic
return getInsVersion().getProtocolType() == ProtocolVersion.ProtocolType.CLASSIC;
}
- /**
- * Checks if the connected insserver or its compatible versions support classic protocol.
- *
- * @return true if classic protocol is supported, false otherwise.
- */
public final boolean supportINSServerClassic() {
boolean yes = false;
for (ProtocolVersion compatibleVersion : getInsVersion().getCompatibleVersions()) {
- // Check if compatible version is classic
yes = compatibleVersion.getProtocolType() == ProtocolVersion.ProtocolType.CLASSIC;
if (yes) break;
}
-
- // Check if the server version is classic
return isINSClassicServer() || yes;
}
- /**
- * Checks if the connected insserver supports the protocol version of the given packet.
- *
- * @param packet the OACPacket to check against the server's supported protocol version.
- * @return true if the server supports the packet's protocol version, false otherwise.
- */
public final boolean supportINSServerPacket(OACPacket packet) {
- // Check if the server supports the protocol version of the packet
return supportINSServerVersion(packet.getProtocolVersion());
}
- /**
- * Checks if the connected insserver or its compatible versions support the specified protocol version.
- *
- * @param targetVersion the ProtocolVersion to check for support.
- * @return true if the server or its compatible versions support the target version, false otherwise.
- */
public final boolean supportINSServerVersion(ProtocolVersion targetVersion) {
- // Directly check if the server version matches or is in the list of compatible versions
return getInsVersion() == targetVersion || getInsVersion().getCompatibleVersions().contains(targetVersion);
}
- /**
- * Checks if the connected insserver or its compatible versions support the specified protocol.
- *
- * @param protocol the Protocol to check for support.
- * @return true if the server or its compatible versions support the protocol, false otherwise.
- */
public final boolean supportINSServerProtocol(ProtocolVersion.Protocol protocol) {
boolean yes = false;
for (ProtocolVersion compatibleVersion : getInsVersion().getCompatibleVersions()) {
- // Check if compatible version supports the protocol
yes = compatibleVersion.getSupportedProtocols().contains(protocol);
if (yes) break;
}
-
- // Check if the server version supports the protocol
return getInsVersion().getSupportedProtocols().contains(protocol) || yes;
}
- //fwfwef
-
- /**
- * Checks if the connected server is a stable server.
- *
- * @return true if the server is stable, false otherwise.
- */
public final boolean isStableServer() {
- // Check if the server version is stable
return !isBetaServer() && !isClassicServer();
}
- /**
- * Checks if the connected server or its compatible versions support stable protocol.
- *
- * @return true if stable protocol is supported, false otherwise.
- */
public final boolean supportServerStable() {
boolean yes = false;
for (ProtocolVersion compatibleVersion : getServerVersion().getCompatibleVersions()) {
- // Check if compatible version is stable
yes = compatibleVersion.getProtocolType() == ProtocolVersion.ProtocolType.STABLE;
if (yes) break;
}
-
- // Check if the server version is stable
return isBetaServer() || yes;
}
- /**
- * Checks if the connected server is a beta server.
- *
- * @return true if the server is beta, false otherwise.
- */
public final boolean isBetaServer() {
- // Check if the server version is beta
return getServerVersion().getProtocolType() == ProtocolVersion.ProtocolType.BETA;
}
- /**
- * Checks if the connected server or its compatible versions support beta protocol.
- *
- * @return true if beta protocol is supported, false otherwise.
- */
public final boolean supportServerBeta() {
boolean yes = false;
for (ProtocolVersion compatibleVersion : getServerVersion().getCompatibleVersions()) {
- // Check if compatible version is beta
yes = compatibleVersion.getProtocolType() == ProtocolVersion.ProtocolType.BETA;
if (yes) break;
}
-
- // Check if the server version is beta
return isStableServer() || yes;
}
- /**
- * Checks if the connected server is a classic server.
- *
- * @return true if the server is classic, false otherwise.
- */
public final boolean isClassicServer() {
- // Check if the server version is classic
return getServerVersion().getProtocolType() == ProtocolVersion.ProtocolType.CLASSIC;
}
- /**
- * Checks if the connected server or its compatible versions support classic protocol.
- *
- * @return true if classic protocol is supported, false otherwise.
- */
public final boolean supportServerClassic() {
boolean yes = false;
for (ProtocolVersion compatibleVersion : getServerVersion().getCompatibleVersions()) {
- // Check if compatible version is classic
yes = compatibleVersion.getProtocolType() == ProtocolVersion.ProtocolType.CLASSIC;
if (yes) break;
}
-
- // Check if the server version is classic
return isClassicServer() || yes;
}
- /**
- * Checks if the connected server supports the protocol version of the given packet.
- *
- * @param packet the OACPacket to check against the server's supported protocol version.
- * @return true if the server supports the packet's protocol version, false otherwise.
- */
public final boolean supportServerPacket(OACPacket packet) {
- // Check if the server supports the protocol version of the packet
return supportServerVersion(packet.getProtocolVersion());
}
- /**
- * Checks if the connected server or its compatible versions support the specified protocol version.
- *
- * @param targetVersion the ProtocolVersion to check for support.
- * @return true if the server or its compatible versions support the target version, false otherwise.
- */
public final boolean supportServerVersion(ProtocolVersion targetVersion) {
- // Directly check if the server version matches or is in the list of compatible versions
return getServerVersion() == targetVersion || getServerVersion().getCompatibleVersions().contains(targetVersion);
}
- /**
- * Checks if the connected server or its compatible versions support the specified protocol.
- *
- * @param protocol the Protocol to check for support.
- * @return true if the server or its compatible versions support the protocol, false otherwise.
- */
public final boolean supportServerProtocol(ProtocolVersion.Protocol protocol) {
boolean yes = false;
for (ProtocolVersion compatibleVersion : getServerVersion().getCompatibleVersions()) {
- // Check if compatible version supports the protocol
yes = compatibleVersion.getSupportedProtocols().contains(protocol);
if (yes) break;
}
-
- // Check if the server version supports the protocol
return getServerVersion().getSupportedProtocols().contains(protocol) || yes;
}
- /**
- * Sends an INS query to the INS server.
- *
- * The client requests a specific record type for a given TLN, name and optional subname.
- * After sending the packet, {@link #onQuerySent(String, String, String, INSRecordType)} is invoked.
- *
- * @param tln The TLN.
- * @param name The InfoName.
- * @param sub Optional subname or {@code null}.
- * @param type The requested record type.
- * @throws IOException If sending the packet fails.
- * @throws ClassNotFoundException If packet serialization fails.
- */
- public final void sendINSQuery(String tln, String name, String sub, INSRecordType type) throws IOException, ClassNotFoundException {
+ public final void sendINSQuery(String tln, String name, String sub, INSRecordType type) throws Exception {
if (!protocolBridge.isRunningAsClient()) return;
- getClientINSConnection().sendPacket(new INSQueryPacket(tln, name, sub, type, getClientINSConnection().getClientId()), Transport.TCP);
+ getClientINSConnection().sendPacket(
+ new INSQueryPacket(tln, name, sub, type, getClientINSConnection().getUniqueID()),
+ TransportProtocol.TCP
+ );
onQuerySent(tln, name, sub, type);
}
- /**
- * Disconnects from the Server.
- */
public final void disconnectFromServer() {
if (clientToServer != null) {
+ protocolBridge.getProtocolValues().eventManager.unregisterListener(this.getClass());
clientToServer.disconnect();
clientToServer = null;
}
}
-
- /**
- * Called when the client receives an INS response from the server.
- *
- *
- * @param status The response status from the server.
- * @param records The list of records returned by the server.
- */
public void onResponse(INSResponseStatus status, List records) {
}
- /**
- * Called after a query was sent to the INS server.
- *
- *
- * @param tln The TLN requested.
- * @param name The InfoName.
- * @param sub Optional subname.
- * @param type The requested record type.
- */
public void onQuerySent(String tln, String name, String sub, INSRecordType type) {
}
- /**
- * Manages the folder structure for client certificates.
- */
public static final class ClientCertificateFolderStructure {
public final File certificatesFolder;
diff --git a/src/main/java/org/openautonomousconnection/protocol/side/client/ProtocolWebClient.java b/src/main/java/org/openautonomousconnection/protocol/side/client/ProtocolWebClient.java
deleted file mode 100644
index 3654853..0000000
--- a/src/main/java/org/openautonomousconnection/protocol/side/client/ProtocolWebClient.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package org.openautonomousconnection.protocol.side.client;
-
-import org.openautonomousconnection.protocol.annotations.ProtocolInfo;
-import org.openautonomousconnection.protocol.versions.ProtocolVersion;
-
-/**
- * Abstract class defining the client-side protocol operations and interactions with INS and servers.
- */
-@ProtocolInfo(protocolSide = ProtocolVersion.ProtocolSide.CLIENT)
-public class ProtocolWebClient extends ProtocolClient {
-}
diff --git a/src/main/java/org/openautonomousconnection/protocol/side/ins/ConnectedProtocolClient.java b/src/main/java/org/openautonomousconnection/protocol/side/ins/ConnectedProtocolClient.java
deleted file mode 100644
index a4e6304..0000000
--- a/src/main/java/org/openautonomousconnection/protocol/side/ins/ConnectedProtocolClient.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package org.openautonomousconnection.protocol.side.ins;
-
-import dev.unlegitdqrk.unlegitlibrary.network.system.server.ConnectionHandler;
-import org.openautonomousconnection.protocol.annotations.ProtocolInfo;
-import org.openautonomousconnection.protocol.side.server.CustomConnectedClient;
-import org.openautonomousconnection.protocol.versions.ProtocolVersion;
-
-/**
- * Represents a connected protocol client on the INS server side.
- */
-@ProtocolInfo(protocolSide = ProtocolVersion.ProtocolSide.INS)
-public final class ConnectedProtocolClient extends CustomConnectedClient {
-
- public ConnectedProtocolClient(ConnectionHandler connectionHandler, ProtocolINSServer protocolINSServer) {
- super(connectionHandler, protocolINSServer);
- }
-}
diff --git a/src/main/java/org/openautonomousconnection/protocol/side/ins/ProtocolINSServer.java b/src/main/java/org/openautonomousconnection/protocol/side/ins/ProtocolINSServer.java
index 1142a30..e22c9d8 100644
--- a/src/main/java/org/openautonomousconnection/protocol/side/ins/ProtocolINSServer.java
+++ b/src/main/java/org/openautonomousconnection/protocol/side/ins/ProtocolINSServer.java
@@ -1,7 +1,8 @@
package org.openautonomousconnection.protocol.side.ins;
import dev.unlegitdqrk.unlegitlibrary.file.ConfigurationManager;
-import dev.unlegitdqrk.unlegitlibrary.network.system.utils.TransportPolicy;
+import dev.unlegitdqrk.unlegitlibrary.network.system.server.NetworkServer;
+import dev.unlegitdqrk.unlegitlibrary.network.system.utils.ClientAuthMode;
import lombok.Getter;
import org.openautonomousconnection.protocol.annotations.ProtocolInfo;
import org.openautonomousconnection.protocol.side.server.ProtocolCustomServer;
@@ -9,6 +10,8 @@ import org.openautonomousconnection.protocol.versions.ProtocolVersion;
import org.openautonomousconnection.protocol.versions.v1_0_0.beta.INSRecord;
import org.openautonomousconnection.protocol.versions.v1_0_0.beta.INSRecordType;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLServerSocketFactory;
import java.io.File;
import java.io.IOException;
import java.security.cert.CertificateException;
@@ -25,17 +28,22 @@ public abstract class ProtocolINSServer extends ProtocolCustomServer {
*
* @return The INS information site URL.
*/
- @Getter
private final String insInfoSite;
+ public final String getInsInfoSite() {
+ return insInfoSite;
+ }
/**
* Gets the INS registration site URL from the configuration.
*
* @return The INS registration site URL.
*/
- @Getter
private String insFrontendSite;
+ public final String getInsFrontendSite() {
+ return insFrontendSite;
+ }
+
/**
* Constructs a ProtocolINSServer with the specified configuration file.
*
@@ -44,11 +52,14 @@ public abstract class ProtocolINSServer extends ProtocolCustomServer {
* @throws IOException If an I/O error occurs.
* @throws CertificateException If a certificate error occurs.
*/
- public ProtocolINSServer(String insInfoSite, String insFrontendSite, int tcpPort, int udpPort) throws Exception {
- super("ins", "ins", tcpPort, udpPort);
+ public ProtocolINSServer(String insInfoSite, String insFrontendSite) throws Exception {
+ super("ins", "ins");
this.insInfoSite = insInfoSite;
this.insFrontendSite = insFrontendSite;
- setCustomClient(ConnectedProtocolClient.class);
+ }
+
+ public void start(int tcpPort) throws IOException, InterruptedException {
+ getNetwork().start(tcpPort, -1);
}
/**
diff --git a/src/main/java/org/openautonomousconnection/protocol/side/server/CustomConnectedClient.java b/src/main/java/org/openautonomousconnection/protocol/side/server/CustomConnectedClient.java
index c6dbc5d..6017358 100644
--- a/src/main/java/org/openautonomousconnection/protocol/side/server/CustomConnectedClient.java
+++ b/src/main/java/org/openautonomousconnection/protocol/side/server/CustomConnectedClient.java
@@ -1,14 +1,19 @@
package org.openautonomousconnection.protocol.side.server;
-import dev.unlegitdqrk.unlegitlibrary.network.system.server.ConnectionHandler;
+import dev.unlegitdqrk.unlegitlibrary.event.EventListener;
+import dev.unlegitdqrk.unlegitlibrary.event.EventManager;
+import dev.unlegitdqrk.unlegitlibrary.event.EventPriority;
+import dev.unlegitdqrk.unlegitlibrary.event.Listener;
+import dev.unlegitdqrk.unlegitlibrary.network.system.server.ConnectedClient;
+import dev.unlegitdqrk.unlegitlibrary.network.system.server.events.client.S_ClientDisconnectedEvent;
import lombok.Getter;
import org.openautonomousconnection.protocol.packets.OACPacket;
import org.openautonomousconnection.protocol.versions.ProtocolVersion;
-public abstract class CustomConnectedClient {
+public class CustomConnectedClient extends EventListener {
@Getter
- private final ConnectionHandler connection;
+ private final ConnectedClient connection;
@Getter
private final ProtocolCustomServer server;
@@ -18,16 +23,15 @@ public abstract class CustomConnectedClient {
@Getter
private boolean clientVersionLoaded = false;
- public CustomConnectedClient(ConnectionHandler connection, ProtocolCustomServer protocolServer) {
+ public CustomConnectedClient(ConnectedClient connection, ProtocolCustomServer protocolServer) throws Exception {
this.connection = connection;
this.server = protocolServer;
+ server.getProtocolBridge().getProtocolValues().eventManager.registerListener(this.getClass());
}
public synchronized void disconnect() {
- try {
- server.clientDisconnected(this);
- } catch (Exception ignored) {
- }
+ server.getProtocolBridge().getProtocolValues().eventManager.unregisterListener(this.getClass());
+
try {
connection.disconnect();
} catch (Exception ignored) {
@@ -36,6 +40,13 @@ public abstract class CustomConnectedClient {
clientVersion = null;
}
+ @Listener(priority = EventPriority.HIGH)
+ public void onDisconnect(S_ClientDisconnectedEvent event) {
+ if (event.getClient().getUniqueID().equals(this.connection.getUniqueID())) {
+ clientVersion = null;
+ }
+ }
+
/**
* Gets the protocol version of the connected client.
diff --git a/src/main/java/org/openautonomousconnection/protocol/side/server/ProtocolCustomServer.java b/src/main/java/org/openautonomousconnection/protocol/side/server/ProtocolCustomServer.java
index c2c178c..d4dc218 100644
--- a/src/main/java/org/openautonomousconnection/protocol/side/server/ProtocolCustomServer.java
+++ b/src/main/java/org/openautonomousconnection/protocol/side/server/ProtocolCustomServer.java
@@ -1,28 +1,42 @@
package org.openautonomousconnection.protocol.side.server;
+import dev.unlegitdqrk.unlegitlibrary.event.EventListener;
+import dev.unlegitdqrk.unlegitlibrary.event.EventPriority;
+import dev.unlegitdqrk.unlegitlibrary.event.Listener;
+import dev.unlegitdqrk.unlegitlibrary.file.FileUtils;
+import dev.unlegitdqrk.unlegitlibrary.network.system.client.events.state.ClientDisconnectedEvent;
import dev.unlegitdqrk.unlegitlibrary.network.system.server.NetworkServer;
-import dev.unlegitdqrk.unlegitlibrary.network.system.utils.ClientID;
-import dev.unlegitdqrk.unlegitlibrary.network.system.utils.TransportPolicy;
+import dev.unlegitdqrk.unlegitlibrary.network.system.server.events.state.ServerStoppedEvent;
+import dev.unlegitdqrk.unlegitlibrary.network.system.utils.ClientAuthMode;
import dev.unlegitdqrk.unlegitlibrary.network.utils.NetworkUtils;
+import dev.unlegitdqrk.unlegitlibrary.network.utils.PemUtils;
import lombok.Getter;
-import lombok.Setter;
import org.openautonomousconnection.protocol.ProtocolBridge;
+import org.openautonomousconnection.protocol.side.server.events.S_CustomClientDisconnectedEvent;
+import org.openautonomousconnection.protocol.side.web.managers.AuthManager;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
+import java.security.KeyStore;
+import java.security.PrivateKey;
import java.security.cert.CertificateException;
-import java.util.ArrayList;
-import java.util.List;
+import java.security.cert.X509Certificate;
+import java.util.*;
-public abstract class ProtocolCustomServer {
+public abstract class ProtocolCustomServer extends EventListener {
/**
* Structure for server.
*/
- @Getter
private final ServerCertificateFolderStructure folderStructure;
+ public final ServerCertificateFolderStructure getFolderStructure() {
+ return folderStructure;
+ }
+
/**
* Certificate files for SSL.
*/
@@ -35,43 +49,43 @@ public abstract class ProtocolCustomServer {
/**
* The reference to the ProtocolBridge Object
*/
- @Getter
private ProtocolBridge protocolBridge;
+ public final ProtocolBridge getProtocolBridge() {
+ return protocolBridge;
+ }
+
/**
* List of connected web clients.
*/
- @Getter
- private List clients;
+ private final List clients;
- @Setter
- @Getter
- private Class extends CustomConnectedClient> customClient;
+ public final List getClients() {
+ return clients;
+ }
/**
* The network server handling pipeline connections.
*/
- @Getter
private NetworkServer network;
- @Getter
- private int tcpPort;
+ public final NetworkServer getNetwork() {
+ return network;
+ }
- @Getter
- private int udpPort;
+ protected final void setNetwork(NetworkServer network) {
+ this.network = network;
+ }
/**
* Initializes the web server with the given configuration, authentication, and rules files.
*
* @throws Exception If an error occurs during initialization.
*/
- public ProtocolCustomServer(String caPrefix, String certPrefix, int tcpPort, int udpPort) throws Exception {
+ public ProtocolCustomServer(String caPrefix, String certPrefix) throws Exception {
// Initialize the list of connected clients
this.clients = new ArrayList<>();
- this.tcpPort = tcpPort;
- this.udpPort = udpPort;
-
// Set up folder structure for certificates
folderStructure = new ServerCertificateFolderStructure(caPrefix, certPrefix);
@@ -90,36 +104,95 @@ public abstract class ProtocolCustomServer {
* @param bridge the Bridge instance.
* @throws IOException when NetworkServer failed to create.
*/
- public final void attachBridge(ProtocolBridge bridge) throws IOException {
+ public final void attachBridge(ProtocolBridge bridge, String keyPassword, boolean ssl, ClientAuthMode authMode) throws Exception {
if (this.protocolBridge != null)
throw new IllegalStateException("ProtocolBridge already attached!");
- this.protocolBridge = bridge;
- createNetworkServer();
+ if (ssl) {
+ char[] keyPass = new char[0];
+ if (keyPassword != null) keyPass = keyPassword.toCharArray();
+
+ KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
+ trustStore.load(null, null);
+
+ int caIndex = 0;
+ for (File caPem : FileUtils.listFiles(folderStructure.publicCAFolder, ".pem", ".crt", ".cer")) {
+ if (caPem.getName().endsWith(".srl")) continue;
+ if (!caPem.getName().startsWith(folderStructure.getCaPrefix())) continue;
+
+ X509Certificate caCert = PemUtils.loadCertificate(caPem);
+ trustStore.setCertificateEntry("root-ca-" + (caIndex++), caCert);
+ }
+
+ KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
+ keyStore.load(null, null);
+
+ Map keyFiles = new HashMap<>();
+ Map certFiles = new HashMap<>();
+
+ for (File f : FileUtils.listFiles(folderStructure.privateServerFolder, ".key", ".pem")) {
+ if (f.getName().endsWith(".srl")) continue;
+ if (!f.getName().startsWith(folderStructure.getCertPrefix())) continue;
+
+ String base = FileUtils.stripExt(f.getName());
+ if (f.getName().endsWith(".key")) keyFiles.put(base, f);
+ if (f.getName().endsWith(".pem")) certFiles.put(base, f);
+ }
+
+ int serverIndex = 0;
+ for (String base : keyFiles.keySet()) {
+ File keyFile = keyFiles.get(base);
+ File certFile = certFiles.get(base);
+ if (certFile == null) {
+ File alt = new File(folderStructure.publicServerFolder, base + ".pem");
+ if (alt.exists()) certFile = alt;
+ }
+ if (certFile == null) continue;
+
+ PrivateKey key = PemUtils.loadPrivateKey(keyFile);
+ X509Certificate cert = PemUtils.loadCertificate(certFile);
+
+ String alias = "server-" + (serverIndex++);
+ keyStore.setKeyEntry(alias, key, keyPass, new X509Certificate[]{cert});
+ }
+
+ bridge.getProtocolValues().eventManager.registerListener(this.getClass());
+
+ network = new NetworkServer.Builder()
+ .packetHandler(bridge.getProtocolValues().packetHandler)
+ .eventManager(bridge.getProtocolValues().eventManager)
+ .sslEnabled(true)
+ .clientAuthMode(authMode)
+ .keyStore(keyStore, keyPass)
+ .trustStore(trustStore)
+ .build();
+ } else {
+ network = new NetworkServer.Builder()
+ .packetHandler(bridge.getProtocolValues().packetHandler)
+ .eventManager(bridge.getProtocolValues().eventManager)
+ .sslEnabled(false)
+ .clientAuthMode(ClientAuthMode.NONE)
+ .build();
+ }
}
- /**
- * Initialize the pipeline server
- */
- private void createNetworkServer() {
- network = new NetworkServer.ServerBuilder().
- setTcpPort(tcpPort).setUdpPort(udpPort).setTransportPolicy(TransportPolicy.bothRequired()).
- setTimeout(0).
- setPacketHandler(protocolBridge.getProtocolValues().packetHandler).
- setEventManager(protocolBridge.getProtocolValues().eventManager).setLogger(protocolBridge.getLogger()).
- setServerCertificate(certFile, keyFile).setRootCAFolder(folderStructure.publicCAFolder).
- build();
+ @Listener
+ public void onStop(ServerStoppedEvent event) {
+ if (event.getServer() == network) {
+ protocolBridge.getProtocolValues().eventManager.unregisterListener(this.getClass());
+ }
}
+
/**
* Retrieves a connected web client by its client ID.
*
* @param clientID The client ID to search for.
* @return The connected web client with the specified ID, or null if not found.
*/
- public final T getClientByID(ClientID clientID) {
+ public final T getClientByID(UUID clientID) {
for (CustomConnectedClient client : clients)
- if (client.getConnection().getClientId() == clientID) return (T) client;
+ if (client.getConnection().getUniqueID().equals(clientID)) return (T) client;
return null;
}
@@ -156,15 +229,14 @@ public abstract class ProtocolCustomServer {
if (!found) throw new CertificateException("Missing " + prefix + NetworkUtils.getPublicIPAddress() + extension);
}
- public final void clientDisconnected(CustomConnectedClient client) {
- clients.remove(client);
- onDisconnect(client);
- }
-
- /**
- * Optional callback when the connection closes.
- */
- public void onDisconnect(CustomConnectedClient client) {
+ @Listener(priority = EventPriority.NORMAL)
+ public final void clientDisconnected(ClientDisconnectedEvent event) {
+ for (CustomConnectedClient client : new ArrayList<>(clients)) {
+ if (client.getConnection().getUniqueID().equals(event.getClient().getUniqueID())) {
+ protocolBridge.getProtocolValues().eventManager.executeEvent(new S_CustomClientDisconnectedEvent(client));
+ clients.remove(client);
+ }
+ }
}
/**
diff --git a/src/main/java/org/openautonomousconnection/protocol/side/web/ConnectedWebClient.java b/src/main/java/org/openautonomousconnection/protocol/side/web/ConnectedWebClient.java
deleted file mode 100644
index ba8265d..0000000
--- a/src/main/java/org/openautonomousconnection/protocol/side/web/ConnectedWebClient.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package org.openautonomousconnection.protocol.side.web;
-
-import dev.unlegitdqrk.unlegitlibrary.network.system.server.ConnectionHandler;
-import lombok.Getter;
-import org.openautonomousconnection.protocol.side.server.CustomConnectedClient;
-
-/**
- * A connected web client using pure protocol packets.
- */
-public final class ConnectedWebClient extends CustomConnectedClient {
-
- public ConnectedWebClient(ConnectionHandler pipelineConnection, ProtocolWebServer webServer) {
- super(pipelineConnection, webServer);
- }
-}
diff --git a/src/main/java/org/openautonomousconnection/protocol/side/web/ProtocolWebServer.java b/src/main/java/org/openautonomousconnection/protocol/side/web/ProtocolWebServer.java
index 4a08682..2f18f7d 100644
--- a/src/main/java/org/openautonomousconnection/protocol/side/web/ProtocolWebServer.java
+++ b/src/main/java/org/openautonomousconnection/protocol/side/web/ProtocolWebServer.java
@@ -1,12 +1,13 @@
package org.openautonomousconnection.protocol.side.web;
import dev.unlegitdqrk.unlegitlibrary.file.FileUtils;
-import dev.unlegitdqrk.unlegitlibrary.network.system.utils.TransportPolicy;
+import dev.unlegitdqrk.unlegitlibrary.network.system.utils.ClientAuthMode;
import dev.unlegitdqrk.unlegitlibrary.string.RandomString;
import lombok.Getter;
import org.openautonomousconnection.protocol.annotations.ProtocolInfo;
import org.openautonomousconnection.protocol.packets.v1_0_0.beta.web.WebRequestPacket;
import org.openautonomousconnection.protocol.packets.v1_0_0.beta.web.WebResponsePacket;
+import org.openautonomousconnection.protocol.side.server.CustomConnectedClient;
import org.openautonomousconnection.protocol.side.server.ProtocolCustomServer;
import org.openautonomousconnection.protocol.side.web.managers.AuthManager;
import org.openautonomousconnection.protocol.side.web.managers.RuleManager;
@@ -23,31 +24,47 @@ public abstract class ProtocolWebServer extends ProtocolCustomServer {
/**
* Folder for web content.
*/
- @Getter
private final File contentFolder;
+ public final File getContentFolder() {
+ return contentFolder;
+ }
+
/**
* Folder for error pages.
*/
- @Getter
private final File errorsFolder;
+
+ public final File getErrorsFolder() {
+ return errorsFolder;
+ }
+
/**
* A unique secret for session management.
*/
- @Getter
- private String uniqueSessionString;
+ private final String uniqueSessionString;
+
+ public final String getUniqueSessionString() {
+ return uniqueSessionString;
+ }
/**
* The expiration time of a Session in minutes
*/
- @Getter
- private int sessionExpire;
+ private final int sessionExpire;
+
+ public final int getSessionExpire() {
+ return sessionExpire;
+ }
/**
* The max upload size in MB
*/
- @Getter
- private int maxUploadSize;
+ private final int maxUploadSize;
+
+ public final int getMaxUploadSize() {
+ return maxUploadSize;
+ }
/**
* Initializes the web server with the given configuration, authentication, and rules files.
@@ -58,9 +75,8 @@ public abstract class ProtocolWebServer extends ProtocolCustomServer {
* @param uploadSize The max upload size in MB
* @throws Exception If an error occurs during initialization.
*/
- public ProtocolWebServer(File authFile, File rulesFile, int tcpPort, int udpPort,
- int sessionExpire, int uploadSize) throws Exception {
- super("server", "server", tcpPort, udpPort);
+ public ProtocolWebServer(File authFile, File rulesFile, int sessionExpire, int uploadSize) throws Exception {
+ super("server", "server");
this.sessionExpire = sessionExpire;
this.maxUploadSize = uploadSize;
@@ -108,8 +124,6 @@ public abstract class ProtocolWebServer extends ProtocolCustomServer {
AuthManager.loadAuthFile(authFile);
RuleManager.loadRules(rulesFile);
-
- setCustomClient(ConnectedWebClient.class);
}
/**
@@ -119,5 +133,5 @@ public abstract class ProtocolWebServer extends ProtocolCustomServer {
* @param request The full decoded request packet.
* @return The response packet that should be sent back to the client.
*/
- public abstract WebResponsePacket onWebRequest(ConnectedWebClient client, WebRequestPacket request);
+ public abstract WebResponsePacket onWebRequest(CustomConnectedClient client, WebRequestPacket request);
}