Added missing option to connect to WebServer

This commit is contained in:
Finn
2025-12-12 20:57:01 +01:00
parent a00a3b319f
commit ebccdf5b36
11 changed files with 536 additions and 150 deletions

View File

@@ -6,7 +6,7 @@
<groupId>org.openautonomousconnection</groupId> <groupId>org.openautonomousconnection</groupId>
<artifactId>protocol</artifactId> <artifactId>protocol</artifactId>
<version>1.0.0-BETA.3</version> <version>1.0.0-BETA.4</version>
<organization> <organization>
<name>Open Autonomous Connection</name> <name>Open Autonomous Connection</name>
<url>https://open-autonomous-connection.org/</url> <url>https://open-autonomous-connection.org/</url>

View File

@@ -8,10 +8,7 @@ import org.openautonomousconnection.protocol.listeners.ClientListener;
import org.openautonomousconnection.protocol.listeners.INSServerListener; import org.openautonomousconnection.protocol.listeners.INSServerListener;
import org.openautonomousconnection.protocol.listeners.WebServerListener; import org.openautonomousconnection.protocol.listeners.WebServerListener;
import org.openautonomousconnection.protocol.packets.OACPacket; import org.openautonomousconnection.protocol.packets.OACPacket;
import org.openautonomousconnection.protocol.packets.v1_0_0.beta.AuthPacket; import org.openautonomousconnection.protocol.packets.v1_0_0.beta.*;
import org.openautonomousconnection.protocol.packets.v1_0_0.beta.INSQueryPacket;
import org.openautonomousconnection.protocol.packets.v1_0_0.beta.INSResponsePacket;
import org.openautonomousconnection.protocol.packets.v1_0_0.beta.UnsupportedClassicPacket;
import org.openautonomousconnection.protocol.packets.v1_0_0.classic.Classic_DomainPacket; import org.openautonomousconnection.protocol.packets.v1_0_0.classic.Classic_DomainPacket;
import org.openautonomousconnection.protocol.packets.v1_0_0.classic.Classic_MessagePacket; import org.openautonomousconnection.protocol.packets.v1_0_0.classic.Classic_MessagePacket;
import org.openautonomousconnection.protocol.packets.v1_0_0.classic.Classic_PingPacket; import org.openautonomousconnection.protocol.packets.v1_0_0.classic.Classic_PingPacket;
@@ -196,14 +193,21 @@ public final class ProtocolBridge {
UnsupportedClassicPacket v100bUnsupportedClassicPacket = new UnsupportedClassicPacket(); UnsupportedClassicPacket v100bUnsupportedClassicPacket = new UnsupportedClassicPacket();
INSQueryPacket v100BINSQueryPacket = new INSQueryPacket(); INSQueryPacket v100BINSQueryPacket = new INSQueryPacket();
INSResponsePacket v100BINSResponsePacket = new INSResponsePacket(this); INSResponsePacket v100BINSResponsePacket = new INSResponsePacket(this);
WebRequestPacket v100BWebRequestPacket = new WebRequestPacket();
WebResponsePacket v100BResponsePacket = new WebResponsePacket();
WebStreamChunkPacket v100BStreamChunkPacket = new WebStreamChunkPacket();
WebStreamStartPacket v100BStreamStartPacket = new WebStreamStartPacket();
WebStreamEndPacket v100BStreamEndPacket = new WebStreamEndPacket();
if (isPacketSupported(v100bAuthPath)) protocolSettings.packetHandler.registerPacket(v100bAuthPath); if (isPacketSupported(v100bAuthPath)) protocolSettings.packetHandler.registerPacket(v100bAuthPath);
if (isPacketSupported(v100bUnsupportedClassicPacket)) if (isPacketSupported(v100bUnsupportedClassicPacket)) protocolSettings.packetHandler.registerPacket(v100bUnsupportedClassicPacket);
protocolSettings.packetHandler.registerPacket(v100bUnsupportedClassicPacket); if (isPacketSupported(v100BINSQueryPacket)) protocolSettings.packetHandler.registerPacket(v100BINSQueryPacket);
if (isPacketSupported(v100BINSQueryPacket)) if (isPacketSupported(v100BINSResponsePacket)) protocolSettings.packetHandler.registerPacket(v100BINSResponsePacket);
protocolSettings.packetHandler.registerPacket(v100BINSQueryPacket); if (isPacketSupported(v100BWebRequestPacket)) protocolSettings.packetHandler.registerPacket(v100BWebRequestPacket);
if (isPacketSupported(v100BINSResponsePacket)) if (isPacketSupported(v100BResponsePacket)) protocolSettings.packetHandler.registerPacket(v100BResponsePacket);
protocolSettings.packetHandler.registerPacket(v100BINSResponsePacket); if (isPacketSupported(v100BStreamChunkPacket)) protocolSettings.packetHandler.registerPacket(v100BStreamChunkPacket);
if (isPacketSupported(v100BStreamStartPacket)) protocolSettings.packetHandler.registerPacket(v100BStreamStartPacket);
if (isPacketSupported(v100BStreamEndPacket)) protocolSettings.packetHandler.registerPacket(v100BStreamEndPacket);
} }
/** /**

View File

@@ -7,6 +7,7 @@ import dev.unlegitdqrk.unlegitlibrary.network.utils.NetworkUtils;
import org.openautonomousconnection.protocol.ProtocolBridge; import org.openautonomousconnection.protocol.ProtocolBridge;
import org.openautonomousconnection.protocol.packets.OACPacket; import org.openautonomousconnection.protocol.packets.OACPacket;
import org.openautonomousconnection.protocol.side.client.events.ConnectedToProtocolINSServerEvent; import org.openautonomousconnection.protocol.side.client.events.ConnectedToProtocolINSServerEvent;
import org.openautonomousconnection.protocol.side.client.events.ConnectedToProtocolWebServerEvent;
import org.openautonomousconnection.protocol.side.ins.ConnectedProtocolClient; import org.openautonomousconnection.protocol.side.ins.ConnectedProtocolClient;
import org.openautonomousconnection.protocol.side.ins.events.ConnectedProtocolClientEvent; import org.openautonomousconnection.protocol.side.ins.events.ConnectedProtocolClientEvent;
import org.openautonomousconnection.protocol.side.web.ConnectedWebClient; import org.openautonomousconnection.protocol.side.web.ConnectedWebClient;
@@ -61,7 +62,8 @@ public final class AuthPacket extends OACPacket {
*/ */
@Override @Override
public void onWrite(PacketHandler packetHandler, ObjectOutputStream objectOutputStream) throws IOException, ClassNotFoundException { public void onWrite(PacketHandler packetHandler, ObjectOutputStream objectOutputStream) throws IOException, ClassNotFoundException {
if (protocolBridge.isRunningAsINSServer()) { if (protocolBridge.isRunningAsWebServer()) objectOutputStream.writeObject(protocolBridge.getProtocolVersion());
else if (protocolBridge.isRunningAsINSServer()) {
objectOutputStream.writeObject(protocolBridge.getProtocolVersion()); objectOutputStream.writeObject(protocolBridge.getProtocolVersion());
// Read ca files // Read ca files
@@ -131,6 +133,7 @@ public final class AuthPacket extends OACPacket {
} else if (protocolBridge.isRunningAsClient()) { } else if (protocolBridge.isRunningAsClient()) {
ProtocolVersion serverVersion = (ProtocolVersion) objectInputStream.readObject(); ProtocolVersion serverVersion = (ProtocolVersion) objectInputStream.readObject();
try {
if (!protocolBridge.isVersionSupported(serverVersion)) { if (!protocolBridge.isVersionSupported(serverVersion)) {
setResponseCode(INSResponseStatus.RESPONSE_AUTH_FAILED); setResponseCode(INSResponseStatus.RESPONSE_AUTH_FAILED);
protocolBridge.getProtocolClient().getClientINSConnection().disconnect(); protocolBridge.getProtocolClient().getClientINSConnection().disconnect();
@@ -165,8 +168,12 @@ public final class AuthPacket extends OACPacket {
} }
} }
protocolBridge.getProtocolClient().setServerVersion(serverVersion); protocolBridge.getProtocolClient().setInsServerVersion(serverVersion);
protocolBridge.getProtocolSettings().eventManager.executeEvent(new ConnectedToProtocolINSServerEvent(protocolBridge.getProtocolClient())); protocolBridge.getProtocolSettings().eventManager.executeEvent(new ConnectedToProtocolINSServerEvent(protocolBridge.getProtocolClient()));
} catch (Exception ignored) {
protocolBridge.getProtocolClient().setWebServerVersion(serverVersion);
protocolBridge.getProtocolSettings().eventManager.executeEvent(new ConnectedToProtocolWebServerEvent(protocolBridge.getProtocolClient()));
}
} }
} }
} }

View File

@@ -0,0 +1,43 @@
package org.openautonomousconnection.protocol.packets.v1_0_0.beta;
import dev.unlegitdqrk.unlegitlibrary.network.system.packets.PacketHandler;
import lombok.Getter;
import org.openautonomousconnection.protocol.packets.OACPacket;
import org.openautonomousconnection.protocol.versions.ProtocolVersion;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public final class WebStreamChunkPacket extends OACPacket {
@Getter
private int seq;
@Getter
private byte[] data;
public WebStreamChunkPacket() {
super(11, ProtocolVersion.PV_1_0_0_BETA);
}
public WebStreamChunkPacket(int seq, byte[] data) {
super(11, ProtocolVersion.PV_1_0_0_BETA);
this.seq = seq;
this.data = (data != null) ? data : new byte[0];
}
@Override
public void onWrite(PacketHandler handler, ObjectOutputStream out) throws IOException {
out.writeInt(seq);
out.writeInt(data.length);
out.write(data);
}
@Override
public void onRead(PacketHandler handler, ObjectInputStream in) throws IOException {
seq = in.readInt();
int len = in.readInt();
if (len < 0) throw new IOException("Negative chunk length");
data = in.readNBytes(len);
}
}

View File

@@ -0,0 +1,35 @@
package org.openautonomousconnection.protocol.packets.v1_0_0.beta;
import dev.unlegitdqrk.unlegitlibrary.network.system.packets.PacketHandler;
import lombok.Getter;
import org.openautonomousconnection.protocol.packets.OACPacket;
import org.openautonomousconnection.protocol.versions.ProtocolVersion;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public final class WebStreamEndPacket extends OACPacket {
@Getter
private boolean ok;
public WebStreamEndPacket() {
super(12, ProtocolVersion.PV_1_0_0_BETA);
}
public WebStreamEndPacket(boolean ok) {
super(12, ProtocolVersion.PV_1_0_0_BETA);
this.ok = ok;
}
@Override
public void onWrite(PacketHandler handler, ObjectOutputStream out) throws IOException {
out.writeBoolean(ok);
}
@Override
public void onRead(PacketHandler handler, ObjectInputStream in) throws IOException {
ok = in.readBoolean();
}
}

View File

@@ -0,0 +1,52 @@
package org.openautonomousconnection.protocol.packets.v1_0_0.beta;
import dev.unlegitdqrk.unlegitlibrary.network.system.packets.PacketHandler;
import lombok.Getter;
import org.openautonomousconnection.protocol.packets.OACPacket;
import org.openautonomousconnection.protocol.versions.ProtocolVersion;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Map;
public final class WebStreamStartPacket extends OACPacket {
@Getter
private int statusCode;
@Getter
private String contentType;
@Getter
private Map<String, String> headers;
@Getter
private long totalLength;
public WebStreamStartPacket() {
super(10, ProtocolVersion.PV_1_0_0_BETA);
}
public WebStreamStartPacket(int statusCode, String contentType, Map<String, String> headers, long totalLength) {
super(10, ProtocolVersion.PV_1_0_0_BETA);
this.statusCode = statusCode;
this.contentType = contentType;
this.headers = headers;
this.totalLength = totalLength;
}
@Override
public void onWrite(PacketHandler handler, ObjectOutputStream out) throws IOException {
out.writeInt(statusCode);
out.writeUTF(contentType != null ? contentType : "application/octet-stream");
out.writeObject(headers);
out.writeLong(totalLength);
}
@SuppressWarnings("unchecked")
@Override
public void onRead(PacketHandler handler, ObjectInputStream in) throws IOException, ClassNotFoundException {
statusCode = in.readInt();
contentType = in.readUTF();
headers = (Map<String, String>) in.readObject();
totalLength = in.readLong();
}
}

View File

@@ -30,6 +30,11 @@ public abstract class ProtocolClient extends DefaultMethodsOverrider {
*/ */
private NetworkClient clientToINS; private NetworkClient clientToINS;
/**
* Handles everything with WebServer-Connection.
*/
private NetworkClient clientToWeb;
/** /**
* Manages the folder structure for client certificates. * Manages the folder structure for client certificates.
*/ */
@@ -41,9 +46,13 @@ public abstract class ProtocolClient extends DefaultMethodsOverrider {
@Getter @Getter
private ProtocolBridge protocolBridge; private ProtocolBridge protocolBridge;
/** /**
* Stores the protocol version of the connected server. * Stores the protocol version of the connected insserver.
*/ */
private ProtocolVersion serverVersion = null; private ProtocolVersion insServerVersion = null;
/**
* Stores the protocol version of the connected webserver.
*/
private ProtocolVersion webServerVersion = null;
/** /**
* Initializes the ProtocolClient, setting up certificate folders and the INS client connection. * Initializes the ProtocolClient, setting up certificate folders and the INS client connection.
@@ -64,6 +73,53 @@ public abstract class ProtocolClient extends DefaultMethodsOverrider {
build(); build();
} }
/**
* Connects to a WebServer.
*
* @param host WebServer host
* @param port WebServer port
*/
public final void connectToWebServer(String host, int port) {
if (!protocolBridge.isRunningAsClient())
throw new IllegalStateException("Not running as client");
if (clientToWeb != null && clientToWeb.isConnected())
return;
createWebClient(host, port);
}
/**
* Gets the WebServer connection client.
*
* @return the NetworkClient handling the WebServer connection.
*/
public final NetworkClient getClientWebConnection() {
return clientToWeb;
}
/**
* Initialize connection to WebServer
*
* @param host WebServer host
* @param port WebServer port
*/
private final void createWebClient(String host, int port) {
clientToWeb = new NetworkClient.ClientBuilder()
.setLogger(protocolBridge.getLogger())
.setProxy(protocolBridge.getProxy())
.setHost(host)
.setPort(port)
.setPacketHandler(protocolBridge.getProtocolSettings().packetHandler)
.setEventManager(protocolBridge.getProtocolSettings().eventManager)
.setRootCAFolder(folderStructure.publicCAFolder)
.setClientCertificatesFolder(
folderStructure.publicClientFolder,
folderStructure.privateClientFolder
)
.build();
}
/** /**
* Injects the ProtocolBridge. * Injects the ProtocolBridge.
* @param bridge the Bridge instance. * @param bridge the Bridge instance.
@@ -125,148 +181,293 @@ public abstract class ProtocolClient extends DefaultMethodsOverrider {
* *
* @return the ProtocolVersion of the server, or PV_1_0_0_CLASSIC if not set. * @return the ProtocolVersion of the server, or PV_1_0_0_CLASSIC if not set.
*/ */
public final ProtocolVersion getServerVersion() { public final ProtocolVersion getWebServerVersion() {
return serverVersion == null ? ProtocolVersion.PV_1_0_0_CLASSIC : serverVersion; return webServerVersion == null ? ProtocolVersion.PV_1_0_0_CLASSIC : webServerVersion;
} }
/** /**
* Sets the protocol version of the connected server. * Sets the protocol version of the connected server.
* *
* @param serverVersion the ProtocolVersion to set for the server. * @param webServerVersion the ProtocolVersion to set for the server.
*/ */
public final void setServerVersion(ProtocolVersion serverVersion) { public final void setWebServerVersion(ProtocolVersion webServerVersion) {
if (serverVersion == null) this.serverVersion = serverVersion; if (webServerVersion == null) this.webServerVersion = insServerVersion;
} }
/** /**
* Handles INS disconnection events, resetting the server version and closing the web client connection if necessary. * 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 getInsServerVersion() {
return insServerVersion == null ? ProtocolVersion.PV_1_0_0_CLASSIC : insServerVersion;
}
/**
* Sets the protocol version of the connected server.
*
* @param insServerVersion the ProtocolVersion to set for the server.
*/
public final void setInsServerVersion(ProtocolVersion insServerVersion) {
if (insServerVersion == null) this.insServerVersion = insServerVersion;
}
/**
* Handles disconnect events, resetting the server version and closing the web client connection if necessary.
* *
* @param event the ClientDisconnectedEvent triggered on INS disconnection. * @param event the ClientDisconnectedEvent triggered on INS disconnection.
*/ */
public final void onINSDisconnect(ClientDisconnectedEvent event) { public final void onDisconnect(ClientDisconnectedEvent event) {
// Reset server version on INS disconnect // Reset server version on INS disconnect
serverVersion = null; if (!clientToINS.isConnected()) {
insServerVersion = null;
disconnectFromWebServer();
}
if (!clientToWeb.isConnected()) webServerVersion = null;
} }
/** /**
* Checks if the connected server is a stable server. * Checks if the connected insserver is a stable server.
* *
* @return true if the server is stable, false otherwise. * @return true if the server is stable, false otherwise.
*/ */
public final boolean isStableServer() { public final boolean isINSStableServer() {
// Check if the server version is stable // Check if the server version is stable
return !isBetaServer() && !isClassicServer(); return !isINSBetaServer() && !isINSClassicServer();
} }
/** /**
* Checks if the connected server or its compatible versions support stable protocol. * Checks if the connected insserver or its compatible versions support stable protocol.
* *
* @return true if stable protocol is supported, false otherwise. * @return true if stable protocol is supported, false otherwise.
*/ */
public final boolean supportServerStable() { public final boolean supportINSServerStable() {
boolean yes = false; boolean yes = false;
for (ProtocolVersion compatibleVersion : getServerVersion().getCompatibleVersions()) { for (ProtocolVersion compatibleVersion : getWebServerVersion().getCompatibleVersions()) {
// Check if compatible version is stable // Check if compatible version is stable
yes = compatibleVersion.getProtocolType() == ProtocolVersion.ProtocolType.STABLE; yes = compatibleVersion.getProtocolType() == ProtocolVersion.ProtocolType.STABLE;
if (yes) break; if (yes) break;
} }
// Check if the server version is stable // Check if the server version is stable
return isStableServer() || yes; return isINSStableServer() || yes;
} }
/** /**
* Checks if the connected server is a beta server. * Checks if the connected insserver is a beta server.
* *
* @return true if the server is beta, false otherwise. * @return true if the server is beta, false otherwise.
*/ */
public final boolean isBetaServer() { public final boolean isINSBetaServer() {
// Check if the server version is beta // Check if the server version is beta
return getServerVersion().getProtocolType() == ProtocolVersion.ProtocolType.BETA; return getInsServerVersion().getProtocolType() == ProtocolVersion.ProtocolType.BETA;
} }
/** /**
* Checks if the connected server or its compatible versions support beta protocol. * Checks if the connected insserver or its compatible versions support beta protocol.
* *
* @return true if beta protocol is supported, false otherwise. * @return true if beta protocol is supported, false otherwise.
*/ */
public final boolean supportServerBeta() { public final boolean supportINSServerBeta() {
boolean yes = false; boolean yes = false;
for (ProtocolVersion compatibleVersion : getServerVersion().getCompatibleVersions()) { for (ProtocolVersion compatibleVersion : getInsServerVersion().getCompatibleVersions()) {
// Check if compatible version is beta // Check if compatible version is beta
yes = compatibleVersion.getProtocolType() == ProtocolVersion.ProtocolType.BETA; yes = compatibleVersion.getProtocolType() == ProtocolVersion.ProtocolType.BETA;
if (yes) break; if (yes) break;
} }
// Check if the server version is beta // Check if the server version is beta
return isBetaServer() || yes; return isINSBetaServer() || yes;
} }
/** /**
* Checks if the connected server is a classic server. * Checks if the connected insserver is a classic server.
* *
* @return true if the server is classic, false otherwise. * @return true if the server is classic, false otherwise.
*/ */
public final boolean isClassicServer() { public final boolean isINSClassicServer() {
// Check if the server version is classic // Check if the server version is classic
return getServerVersion().getProtocolType() == ProtocolVersion.ProtocolType.CLASSIC; return getInsServerVersion().getProtocolType() == ProtocolVersion.ProtocolType.CLASSIC;
} }
/** /**
* Checks if the connected server or its compatible versions support classic protocol. * Checks if the connected insserver or its compatible versions support classic protocol.
* *
* @return true if classic protocol is supported, false otherwise. * @return true if classic protocol is supported, false otherwise.
*/ */
public final boolean supportServerClassic() { public final boolean supportINSServerClassic() {
boolean yes = false; boolean yes = false;
for (ProtocolVersion compatibleVersion : getServerVersion().getCompatibleVersions()) { for (ProtocolVersion compatibleVersion : getInsServerVersion().getCompatibleVersions()) {
// Check if compatible version is classic // Check if compatible version is classic
yes = compatibleVersion.getProtocolType() == ProtocolVersion.ProtocolType.CLASSIC; yes = compatibleVersion.getProtocolType() == ProtocolVersion.ProtocolType.CLASSIC;
if (yes) break; if (yes) break;
} }
// Check if the server version is classic // Check if the server version is classic
return isClassicServer() || yes; return isINSClassicServer() || yes;
} }
/** /**
* Checks if the connected server supports the protocol version of the given packet. * 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. * @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. * @return true if the server supports the packet's protocol version, false otherwise.
*/ */
public final boolean supportServerPacket(OACPacket packet) { public final boolean supportINSServerPacket(OACPacket packet) {
// Check if the server supports the protocol version of the packet // Check if the server supports the protocol version of the packet
return supportServerVersion(packet.getProtocolVersion()); return supportINSServerVersion(packet.getProtocolVersion());
} }
/** /**
* Checks if the connected server or its compatible versions support the specified protocol version. * Checks if the connected insserver or its compatible versions support the specified protocol version.
* *
* @param targetVersion the ProtocolVersion to check for support. * @param targetVersion the ProtocolVersion to check for support.
* @return true if the server or its compatible versions support the target version, false otherwise. * @return true if the server or its compatible versions support the target version, false otherwise.
*/ */
public final boolean supportServerVersion(ProtocolVersion targetVersion) { public final boolean supportINSServerVersion(ProtocolVersion targetVersion) {
// Directly check if the server version matches or is in the list of compatible versions // Directly check if the server version matches or is in the list of compatible versions
return getServerVersion() == targetVersion || getServerVersion().getCompatibleVersions().contains(targetVersion); return getInsServerVersion() == targetVersion || getInsServerVersion().getCompatibleVersions().contains(targetVersion);
} }
/** /**
* Checks if the connected server or its compatible versions support the specified protocol. * Checks if the connected insserver or its compatible versions support the specified protocol.
* *
* @param protocol the Protocol to check for support. * @param protocol the Protocol to check for support.
* @return true if the server or its compatible versions support the protocol, false otherwise. * @return true if the server or its compatible versions support the protocol, false otherwise.
*/ */
public final boolean supportServerProtocol(ProtocolVersion.Protocol protocol) { public final boolean supportINSServerProtocol(ProtocolVersion.Protocol protocol) {
boolean yes = false; boolean yes = false;
for (ProtocolVersion compatibleVersion : getServerVersion().getCompatibleVersions()) { for (ProtocolVersion compatibleVersion : getInsServerVersion().getCompatibleVersions()) {
// Check if compatible version supports the protocol // Check if compatible version supports the protocol
yes = compatibleVersion.getSupportedProtocols().contains(protocol); yes = compatibleVersion.getSupportedProtocols().contains(protocol);
if (yes) break; if (yes) break;
} }
// Check if the server version supports the protocol // Check if the server version supports the protocol
return getServerVersion().getSupportedProtocols().contains(protocol) || yes; return getInsServerVersion().getSupportedProtocols().contains(protocol) || yes;
}
//fwfwef
/**
* Checks if the connected webserver is a stable server.
*
* @return true if the server is stable, false otherwise.
*/
public final boolean isWebStableServer() {
// Check if the server version is stable
return !isWebBetaServer() && !isWebClassicServer();
}
/**
* Checks if the connected webserver or its compatible versions support stable protocol.
*
* @return true if stable protocol is supported, false otherwise.
*/
public final boolean supportWebServerStable() {
boolean yes = false;
for (ProtocolVersion compatibleVersion : getWebServerVersion().getCompatibleVersions()) {
// Check if compatible version is stable
yes = compatibleVersion.getProtocolType() == ProtocolVersion.ProtocolType.STABLE;
if (yes) break;
}
// Check if the server version is stable
return isWebBetaServer() || yes;
}
/**
* Checks if the connected webserver is a beta server.
*
* @return true if the server is beta, false otherwise.
*/
public final boolean isWebBetaServer() {
// Check if the server version is beta
return getWebServerVersion().getProtocolType() == ProtocolVersion.ProtocolType.BETA;
}
/**
* Checks if the connected webserver or its compatible versions support beta protocol.
*
* @return true if beta protocol is supported, false otherwise.
*/
public final boolean supportWebServerBeta() {
boolean yes = false;
for (ProtocolVersion compatibleVersion : getWebServerVersion().getCompatibleVersions()) {
// Check if compatible version is beta
yes = compatibleVersion.getProtocolType() == ProtocolVersion.ProtocolType.BETA;
if (yes) break;
}
// Check if the server version is beta
return isWebStableServer() || yes;
}
/**
* Checks if the connected webserver is a classic server.
*
* @return true if the server is classic, false otherwise.
*/
public final boolean isWebClassicServer() {
// Check if the server version is classic
return getWebServerVersion().getProtocolType() == ProtocolVersion.ProtocolType.CLASSIC;
}
/**
* Checks if the connected webserver or its compatible versions support classic protocol.
*
* @return true if classic protocol is supported, false otherwise.
*/
public final boolean supportWebServerClassic() {
boolean yes = false;
for (ProtocolVersion compatibleVersion : getWebServerVersion().getCompatibleVersions()) {
// Check if compatible version is classic
yes = compatibleVersion.getProtocolType() == ProtocolVersion.ProtocolType.CLASSIC;
if (yes) break;
}
// Check if the server version is classic
return isWebClassicServer() || yes;
}
/**
* Checks if the connected webserver 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 supportWebServerPacket(OACPacket packet) {
// Check if the server supports the protocol version of the packet
return supportWebServerVersion(packet.getProtocolVersion());
}
/**
* Checks if the connected webserver 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 supportWebServerVersion(ProtocolVersion targetVersion) {
// Directly check if the server version matches or is in the list of compatible versions
return getWebServerVersion() == targetVersion || getWebServerVersion().getCompatibleVersions().contains(targetVersion);
}
/**
* Checks if the connected webserver 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 supportWebServerProtocol(ProtocolVersion.Protocol protocol) {
boolean yes = false;
for (ProtocolVersion compatibleVersion : getWebServerVersion().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 getWebServerVersion().getSupportedProtocols().contains(protocol) || yes;
} }
/** /**
@@ -289,6 +490,17 @@ public abstract class ProtocolClient extends DefaultMethodsOverrider {
onQuerySent(tln, name, sub, type); onQuerySent(tln, name, sub, type);
} }
/**
* Disconnects from the WebServer.
*/
public final void disconnectFromWebServer() {
if (clientToWeb != null) {
clientToWeb.disconnect();
clientToWeb = null;
}
}
/** /**
* Called when the client receives an INS response from the server. * Called when the client receives an INS response from the server.
* <p> * <p>

View File

@@ -0,0 +1,25 @@
package org.openautonomousconnection.protocol.side.client.events;
import dev.unlegitdqrk.unlegitlibrary.event.impl.Event;
import lombok.Getter;
import org.openautonomousconnection.protocol.annotations.ProtocolInfo;
import org.openautonomousconnection.protocol.side.client.ProtocolClient;
import org.openautonomousconnection.protocol.versions.ProtocolVersion;
/**
* Event triggered when a client successfully connects to a INS protocol server.
*/
@ProtocolInfo(protocolSide = ProtocolVersion.ProtocolSide.INS)
public final class ConnectedToProtocolWebServerEvent extends Event {
/**
* Reference to the ProtocolClient object.
*/
@Getter
private final ProtocolClient client;
public ConnectedToProtocolWebServerEvent(ProtocolClient client) {
this.client = client;
}
}

View File

@@ -1,11 +1,13 @@
package org.openautonomousconnection.protocol.side.web; package org.openautonomousconnection.protocol.side.web;
import dev.unlegitdqrk.unlegitlibrary.network.system.server.ConnectionHandler; import dev.unlegitdqrk.unlegitlibrary.network.system.server.ConnectionHandler;
import dev.unlegitdqrk.unlegitlibrary.network.system.packets.PacketHandler;
import lombok.Getter; import lombok.Getter;
import org.openautonomousconnection.protocol.packets.OACPacket; import org.openautonomousconnection.protocol.packets.OACPacket;
import org.openautonomousconnection.protocol.packets.v1_0_0.beta.WebRequestPacket; import org.openautonomousconnection.protocol.packets.v1_0_0.beta.WebRequestPacket;
import org.openautonomousconnection.protocol.packets.v1_0_0.beta.WebResponsePacket; import org.openautonomousconnection.protocol.packets.v1_0_0.beta.WebResponsePacket;
import org.openautonomousconnection.protocol.packets.v1_0_0.beta.WebStreamChunkPacket;
import org.openautonomousconnection.protocol.packets.v1_0_0.beta.WebStreamEndPacket;
import org.openautonomousconnection.protocol.packets.v1_0_0.beta.WebStreamStartPacket;
import org.openautonomousconnection.protocol.versions.ProtocolVersion; import org.openautonomousconnection.protocol.versions.ProtocolVersion;
import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocket;
@@ -14,8 +16,7 @@ import java.io.ObjectInputStream;
import java.io.ObjectOutputStream; import java.io.ObjectOutputStream;
/** /**
* A connected web client using pure OAC packets. * A connected web client using pure protocol packets.
* No HTTP, no GET/POST, no header parsing.
*/ */
public final class ConnectedWebClient { public final class ConnectedWebClient {
@@ -28,13 +29,11 @@ public final class ConnectedWebClient {
@Getter @Getter
private ProtocolWebServer server; private ProtocolWebServer server;
/** private ObjectOutputStream out;
* The protocol version of the connected client. private ObjectInputStream in;
*/
private ProtocolVersion clientVersion = null; private ProtocolVersion clientVersion = null;
/**
* Indicates if the client version has been loaded.
*/
@Getter @Getter
private boolean clientVersionLoaded = false; private boolean clientVersionLoaded = false;
@@ -44,46 +43,6 @@ public final class ConnectedWebClient {
this.pipelineConnection = pipelineConnection; this.pipelineConnection = pipelineConnection;
} }
public void attachWebServer(SSLSocket socket, ProtocolWebServer server) {
if (this.webSocket != null) return;
this.webSocket = socket;
this.server = server;
this.receiveThread = new Thread(this::receiveLoop, "OAC-WebClient-Receiver");
this.receiveThread.start();
}
private void receiveLoop() {
try {
ObjectInputStream in = new ObjectInputStream(webSocket.getInputStream());
ObjectOutputStream out = new ObjectOutputStream(webSocket.getOutputStream());
PacketHandler handler = server.getProtocolBridge().getProtocolSettings().packetHandler;
while (!webSocket.isClosed() && pipelineConnection.isConnected()) {
Object obj = in.readObject();
if (!(obj instanceof OACPacket packet)) continue;
if (packet instanceof WebRequestPacket requestPacket) {
WebResponsePacket response =
server.onWebRequest(this, requestPacket);
if (response != null) {
out.writeObject(response);
out.flush();
}
}
}
} catch (Exception ignored) {
} finally {
disconnect();
}
}
public boolean isConnected() { public boolean isConnected() {
return webSocket != null && return webSocket != null &&
webSocket.isConnected() && webSocket.isConnected() &&
@@ -91,25 +50,72 @@ public final class ConnectedWebClient {
pipelineConnection.isConnected(); pipelineConnection.isConnected();
} }
public void attachWebServer(SSLSocket socket, ProtocolWebServer server) throws IOException {
if (this.webSocket != null) return;
this.webSocket = socket;
this.server = server;
// IMPORTANT: ObjectOutputStream first, flush, then ObjectInputStream
this.out = new ObjectOutputStream(webSocket.getOutputStream());
this.out.flush();
this.in = new ObjectInputStream(webSocket.getInputStream());
this.receiveThread = new Thread(this::receiveLoop, "OAC-WebClient-Receiver");
this.receiveThread.start();
}
private void receiveLoop() {
try {
while (isConnected()) {
Object obj = in.readObject();
if (!(obj instanceof OACPacket packet)) continue;
if (packet instanceof WebRequestPacket req) {
// server decides whether it returns normal response or does streaming itself
WebResponsePacket resp = server.onWebRequest(this, req);
if (resp != null) send(resp);
}
}
} catch (Exception ignored) {
} finally {
disconnect();
}
}
public synchronized void send(Object packet) throws IOException {
if (!isConnected()) return;
out.writeObject(packet);
out.flush();
}
public synchronized void streamStart(WebStreamStartPacket start) throws IOException {
send(start);
}
public synchronized void streamChunk(WebStreamChunkPacket chunk) throws IOException {
send(chunk);
}
public synchronized void streamEnd(WebStreamEndPacket end) throws IOException {
send(end);
}
public synchronized void disconnect() { public synchronized void disconnect() {
try { try { server.onDisconnect(this); } catch (Exception ignored) {}
server.onDisconnect(this);
clientVersionLoaded = false;
clientVersion = null;
} catch (Exception ignored) {}
try { try { pipelineConnection.disconnect(); } catch (Exception ignored) {}
pipelineConnection.disconnect();
} catch (Exception ignored) {}
try { try { if (in != null) in.close(); } catch (Exception ignored) {}
if (webSocket != null) webSocket.close(); try { if (out != null) out.close(); } catch (Exception ignored) {}
} catch (IOException ignored) {} try { if (webSocket != null) webSocket.close(); } catch (Exception ignored) {}
in = null;
out = null;
webSocket = null; webSocket = null;
} }
/** /**
* Gets the protocol version of the connected client. * Gets the protocol version of the connected client.
* *
* @return The protocol version of the client, defaults to PV_1_0_0_CLASSIC if not set. * @return The protocol version of the client, defaults to PV_1_0_0_CLASSIC if not set.

View File

@@ -10,6 +10,7 @@ import org.openautonomousconnection.protocol.ProtocolBridge;
import org.openautonomousconnection.protocol.annotations.ProtocolInfo; import org.openautonomousconnection.protocol.annotations.ProtocolInfo;
import org.openautonomousconnection.protocol.packets.v1_0_0.beta.WebRequestPacket; import org.openautonomousconnection.protocol.packets.v1_0_0.beta.WebRequestPacket;
import org.openautonomousconnection.protocol.packets.v1_0_0.beta.WebResponsePacket; import org.openautonomousconnection.protocol.packets.v1_0_0.beta.WebResponsePacket;
import org.openautonomousconnection.protocol.side.web.events.WebClientConnectedEvent;
import org.openautonomousconnection.protocol.side.web.managers.AuthManager; import org.openautonomousconnection.protocol.side.web.managers.AuthManager;
import org.openautonomousconnection.protocol.side.web.managers.RuleManager; import org.openautonomousconnection.protocol.side.web.managers.RuleManager;
import org.openautonomousconnection.protocol.versions.ProtocolVersion; import org.openautonomousconnection.protocol.versions.ProtocolVersion;
@@ -252,6 +253,7 @@ public abstract class ProtocolWebServer {
if (connectedWebClient.getPipelineConnection().getClientID() != -1 && connectedWebClient.isClientVersionLoaded()) { if (connectedWebClient.getPipelineConnection().getClientID() != -1 && connectedWebClient.isClientVersionLoaded()) {
// Assign socket to an existing connected client // Assign socket to an existing connected client
connectedWebClient.attachWebServer(client, this); connectedWebClient.attachWebServer(client, this);
protocolBridge.getProtocolSettings().eventManager.executeEvent(new WebClientConnectedEvent(connectedWebClient));
} }
} }
} catch (IOException e) { } catch (IOException e) {

View File

@@ -10,7 +10,7 @@ import org.openautonomousconnection.protocol.versions.ProtocolVersion;
* Event triggered when a web client connects to the web server. * Event triggered when a web client connects to the web server.
*/ */
@ProtocolInfo(protocolSide = ProtocolVersion.ProtocolSide.WEB) @ProtocolInfo(protocolSide = ProtocolVersion.ProtocolSide.WEB)
public final class ConnectedWebClientEvent extends Event { public final class WebClientConnectedEvent extends Event {
/** /**
* The connected web client. * The connected web client.
@@ -18,7 +18,7 @@ public final class ConnectedWebClientEvent extends Event {
@Getter @Getter
private final ConnectedWebClient webClient; private final ConnectedWebClient webClient;
public ConnectedWebClientEvent(ConnectedWebClient webClient) { public WebClientConnectedEvent(ConnectedWebClient webClient) {
this.webClient = webClient; this.webClient = webClient;
} }
} }