package org.openautonomousconnection.protocol; import dev.unlegitdqrk.unlegitlibrary.addon.AddonLoader; import dev.unlegitdqrk.unlegitlibrary.file.FileUtils; import dev.unlegitdqrk.unlegitlibrary.network.system.utils.ClientAuthMode; import dev.unlegitdqrk.unlegitlibrary.utils.Logger; import lombok.Getter; import org.openautonomousconnection.protocol.annotations.ProtocolInfo; import org.openautonomousconnection.protocol.listeners.ClientListener; import org.openautonomousconnection.protocol.listeners.CustomServerListener; 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.INSQueryPacket; import org.openautonomousconnection.protocol.packets.v1_0_0.beta.INSResponsePacket; 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.packets.v1_0_0.beta.web.stream.WebStreamChunkPacket_v1_0_0_B; import org.openautonomousconnection.protocol.packets.v1_0_0.beta.web.stream.WebStreamEndPacket_v1_0_0_B; import org.openautonomousconnection.protocol.packets.v1_0_0.beta.web.stream.WebStreamStartPacket_v1_0_0_B; import org.openautonomousconnection.protocol.packets.v1_0_1.beta.web.impl.document.WebDocumentApplyRequestPacket; import org.openautonomousconnection.protocol.packets.v1_0_1.beta.web.impl.document.WebDocumentApplyResponsePacket; import org.openautonomousconnection.protocol.packets.v1_0_1.beta.web.impl.document.WebDocumentSnapshotEventPacket; import org.openautonomousconnection.protocol.packets.v1_0_1.beta.web.impl.navigate.WebNavigateAckPacket; import org.openautonomousconnection.protocol.packets.v1_0_1.beta.web.impl.navigate.WebNavigateRequestPacket; import org.openautonomousconnection.protocol.packets.v1_0_1.beta.web.impl.resource.WebResourceRequestPacket; import org.openautonomousconnection.protocol.packets.v1_0_1.beta.web.impl.resource.WebResourceResponsePacket; import org.openautonomousconnection.protocol.packets.v1_0_1.beta.web.impl.stream.WebStreamChunkPacket_v1_0_1_B; import org.openautonomousconnection.protocol.packets.v1_0_1.beta.web.impl.stream.WebStreamEndPacket_v1_0_1_B; import org.openautonomousconnection.protocol.packets.v1_0_1.beta.web.impl.stream.WebStreamStartPacket_v1_0_1_B; import org.openautonomousconnection.protocol.side.client.ProtocolClient; import org.openautonomousconnection.protocol.side.client.ProtocolWebClient; import org.openautonomousconnection.protocol.side.ins.ProtocolINSServer; import org.openautonomousconnection.protocol.side.server.ProtocolCustomServer; import org.openautonomousconnection.protocol.side.web.ProtocolWebServer; import org.openautonomousconnection.protocol.urlhandler.v1_0_0.beta.OacWebUrlInstaller_v1_0_0_B; import org.openautonomousconnection.protocol.urlhandler.v1_0_1.beta.LibClientImpl_v1_0_1_B; import org.openautonomousconnection.protocol.urlhandler.v1_0_1.beta.OacUrlHandlerInstaller_v1_0_1_B; import org.openautonomousconnection.protocol.versions.ProtocolVersion; import org.openautonomousconnection.protocol.versions.v1_0_0.beta.ProtocolWebServer_1_0_0_B; import java.io.File; import java.io.IOException; import java.util.ResourceBundle; import java.util.function.Supplier; /** * The main bridge class for the protocol connection. * It manages the protocol settings, version, and side instances. */ public final class ProtocolBridge { /** * The protocol settings for the current connection */ @Getter private final ProtocolValues protocolValues; /** * The protocol side instances */ @Getter private ProtocolClient protocolClient; /** * The protocol side instances */ @Getter private ProtocolCustomServer protocolServer; /** * Initialize the ProtocolBridge instance for the client side * * @param protocolServer The ProtocolCustomServer instance * @param protocolValues The ProtocolSettings instance * @throws Exception if an error occurs while initializing the ProtocolBridge */ public ProtocolBridge(ProtocolCustomServer protocolServer, ProtocolValues protocolValues) throws Exception { // Assign the parameters to the class fields this.protocolServer = protocolServer; this.protocolValues = protocolValues; if (protocolServer instanceof ProtocolINSServer) protocolServer.attachBridge(this, null, false, ClientAuthMode.NONE); else protocolServer.attachBridge(this, protocolValues.keyPass, protocolValues.ssl, protocolValues.authMode); initializeProtocolVersion(); downloadLicenses(); // Register the appropriate listeners and packets registerListeners(); registerPackets(); } /** * Initialize the ProtocolBridge instance for the client side * * @param protocolClient The ProtocolClient instance * @param protocolValues The ProtocolSettings instance * @throws Exception if an error occurs while initializing the ProtocolBridge */ @ProtocolInfo(protocolSide = ProtocolVersion.ProtocolSide.CLIENT) public ProtocolBridge(ProtocolClient protocolClient, LibClientImpl_v1_0_1_B libClientImpl, ProtocolValues protocolValues) throws Exception { // Assign the parameters to the class fields this.protocolClient = protocolClient; this.protocolValues = protocolValues; protocolClient.attachBridge(this); initializeProtocolVersion(); downloadLicenses(); // Register the appropriate listeners and packets registerListeners(); registerPackets(); installUrl(libClientImpl); } private void installUrl(LibClientImpl_v1_0_1_B libClientImpl) { if (protocolValues.protocolVersion == ProtocolVersion.PV_1_0_0_BETA) { OacWebUrlInstaller_v1_0_0_B.installOnce(this, libClientImpl); } if (protocolValues.protocolVersion == ProtocolVersion.PV_1_0_1_BETA) { OacUrlHandlerInstaller_v1_0_1_B.installOnce(this, libClientImpl, libClientImpl, libClientImpl); } } private void downloadLicenses() throws IOException { File licensesFolder = new File("licenses"); if (!licensesFolder.exists() || !licensesFolder.isDirectory()) { if (licensesFolder.exists()) licensesFolder.delete(); File output = new File("licenses.zip"); output.createNewFile(); FileUtils.downloadFile("https://open-autonomous-connection.org/assets/licenses.zip", output); FileUtils.unzip(output, licensesFolder.getParent()); output.deleteOnExit(); } } /** * Register the appropriate packets * *

Overview of all Packets * * * * * * * * * * * * * * * * * * * * * * * *
IDPacketProtocolVersion
8{@link org.openautonomousconnection.protocol.packets.v1_0_0.beta.AuthPacket AuthPacket}{@link org.openautonomousconnection.protocol.versions.ProtocolVersion#PV_1_0_0_BETA PV_1_0_0_BETA}
7{@link org.openautonomousconnection.protocol.packets.v1_0_0.beta.INSQueryPacket INSQueryPacket}{@link org.openautonomousconnection.protocol.versions.ProtocolVersion#PV_1_0_0_BETA PV_1_0_0_BETA}
6{@link org.openautonomousconnection.protocol.packets.v1_0_0.beta.INSResponsePacket INSResponsePacket}{@link org.openautonomousconnection.protocol.versions.ProtocolVersion#PV_1_0_0_BETA PV_1_0_0_BETA}
10{@link org.openautonomousconnection.protocol.packets.v1_0_0.beta.web.WebRequestPacket WebRequestPacket}{@link org.openautonomousconnection.protocol.versions.ProtocolVersion#PV_1_0_0_BETA PV_1_0_0_BETA}
9{@link org.openautonomousconnection.protocol.packets.v1_0_0.beta.web.WebResponsePacket WebResponsePacket}{@link org.openautonomousconnection.protocol.versions.ProtocolVersion#PV_1_0_0_BETA PV_1_0_0_BETA}
11{@link WebStreamStartPacket_v1_0_0_B v1_0_0.beta.web.stream.WebStreamStartPacket}{@link org.openautonomousconnection.protocol.versions.ProtocolVersion#PV_1_0_0_BETA PV_1_0_0_BETA}
13{@link WebStreamChunkPacket_v1_0_0_B v1_0_0.beta.web.stream.WebStreamChunkPacket}{@link org.openautonomousconnection.protocol.versions.ProtocolVersion#PV_1_0_0_BETA PV_1_0_0_BETA}
12{@link WebStreamEndPacket_v1_0_0_B v1_0_0.beta.web.stream.WebStreamEndPacket}{@link org.openautonomousconnection.protocol.versions.ProtocolVersion#PV_1_0_0_BETA PV_1_0_0_BETA}
1{@link org.openautonomousconnection.protocol.packets.v1_0_1.beta.web.impl.navigate.WebNavigateRequestPacket WebNavigateRequestPacket}{@link org.openautonomousconnection.protocol.versions.ProtocolVersion#PV_1_0_1_BETA PV_1_0_1_BETA}
2{@link org.openautonomousconnection.protocol.packets.v1_0_1.beta.web.impl.navigate.WebNavigateAckPacket WebNavigateAckPacket}{@link org.openautonomousconnection.protocol.versions.ProtocolVersion#PV_1_0_1_BETA PV_1_0_1_BETA}
3{@link org.openautonomousconnection.protocol.packets.v1_0_1.beta.web.impl.resource.WebResourceRequestPacket WebResourceRequestPacket}{@link org.openautonomousconnection.protocol.versions.ProtocolVersion#PV_1_0_1_BETA PV_1_0_1_BETA}
4{@link org.openautonomousconnection.protocol.packets.v1_0_1.beta.web.impl.resource.WebResourceResponsePacket WebResourceResponsePacket}{@link org.openautonomousconnection.protocol.versions.ProtocolVersion#PV_1_0_1_BETA PV_1_0_1_BETA}
14{@link WebStreamStartPacket_v1_0_1_B v1_0_1.beta.web.impl.stream.WebStreamStartPacket}{@link org.openautonomousconnection.protocol.versions.ProtocolVersion#PV_1_0_1_BETA PV_1_0_1_BETA}
15{@link WebStreamChunkPacket_v1_0_1_B v1_0_1.beta.web.impl.stream.WebStreamChunkPacket}{@link org.openautonomousconnection.protocol.versions.ProtocolVersion#PV_1_0_1_BETA PV_1_0_1_BETA}
16{@link WebStreamEndPacket_v1_0_1_B v1_0_1.beta.web.impl.stream.WebStreamEndPacket}{@link org.openautonomousconnection.protocol.versions.ProtocolVersion#PV_1_0_1_BETA PV_1_0_1_BETA}
17{@link org.openautonomousconnection.protocol.packets.v1_0_1.beta.web.impl.document.WebDocumentSnapshotEventPacket WebDocumentSnapshotEventPacket}{@link org.openautonomousconnection.protocol.versions.ProtocolVersion#PV_1_0_1_BETA PV_1_0_1_BETA}
5{@link org.openautonomousconnection.protocol.packets.v1_0_1.beta.web.impl.document.WebDocumentApplyResponsePacket WebDocumentApplyResponsePacket}{@link org.openautonomousconnection.protocol.versions.ProtocolVersion#PV_1_0_1_BETA PV_1_0_1_BETA}
18{@link org.openautonomousconnection.protocol.packets.v1_0_1.beta.web.impl.document.WebDocumentApplyRequestPacket WebDocumentApplyRequestPacket}{@link org.openautonomousconnection.protocol.versions.ProtocolVersion#PV_1_0_1_BETA PV_1_0_1_BETA}
* * @see org.openautonomousconnection.protocol.versions.ProtocolVersion */ private void registerPackets() { // 1.0.0-BETA packets registerPacket(() -> new AuthPacket(this)); registerPacket(INSQueryPacket::new); registerPacket(() -> new INSResponsePacket(this)); registerPacket(WebRequestPacket::new); registerPacket(WebResponsePacket::new); registerPacket(WebStreamStartPacket_v1_0_0_B::new); registerPacket(WebStreamChunkPacket_v1_0_0_B::new); registerPacket(WebStreamEndPacket_v1_0_0_B::new); // 1.0.1-BETA Packets registerPacket(() -> new WebDocumentApplyRequestPacket(this)); registerPacket(WebDocumentApplyResponsePacket::new); registerPacket(WebDocumentSnapshotEventPacket::new); registerPacket(() -> new WebNavigateRequestPacket(this)); registerPacket(WebNavigateAckPacket::new); registerPacket(() -> new WebResourceRequestPacket(this)); registerPacket(WebResourceResponsePacket::new); registerPacket(WebStreamStartPacket_v1_0_1_B::new); registerPacket(WebStreamChunkPacket_v1_0_1_B::new); registerPacket(WebStreamEndPacket_v1_0_1_B::new); } private void registerPacket(Supplier factory) { if (isPacketSupported(factory.get())) protocolValues.packetHandler.registerPacket(factory); } /** * Register the appropriate listeners based on the current side * * @throws Exception if an error occurs while registering the listeners */ private void registerListeners() throws Exception { // Client Listeners if (isRunningAsClient()) { protocolValues.eventManager.registerListener(new ClientListener(protocolClient)); protocolValues.eventManager.unregisterListener(CustomServerListener.class); } // Server Listeners if (isRunningAsServer()) { protocolValues.eventManager.registerListener(new CustomServerListener(protocolServer)); protocolValues.eventManager.unregisterListener(ClientListener.class); } } /** * Initialize the protocol version * Validate if the protocol version is valid for the current side * If not, log an error and exit the application */ private void initializeProtocolVersion() { // Check if the protocol version is valid for the current side // If not, log an error and exit the application if (!validateProtocolSide()) { protocolValues.logger.error("Invalid protocol version '" + protocolValues.protocolVersion.toString() + "'!"); System.exit(1); } } /** * Check if the classic protocol is supported by the current protocol version * * @return true if the classic protocol is supported, false otherwise */ public boolean isClassicSupported() { boolean yes = false; for (ProtocolVersion compatibleVersion : protocolValues.protocolVersion.getCompatibleVersions()) { // Check if the compatible version is classic yes = compatibleVersion.getProtocolType() == ProtocolVersion.ProtocolType.CLASSIC; if (yes) break; } // Check if the current protocol version is classic or if it is supported by any of the compatible versions return protocolValues.protocolVersion.getProtocolType() == ProtocolVersion.ProtocolType.CLASSIC || yes; } /** * Check if the target protocol is supported by the current protocol version * * @param protocol The target protocol to check * @return true If the target protocol is supported, false otherwise */ public boolean isProtocolSupported(ProtocolVersion.Protocol protocol) { boolean yes = false; for (ProtocolVersion compatibleVersion : protocolValues.protocolVersion.getCompatibleVersions()) { // Check if the compatible version supports the target protocol yes = compatibleVersion.getSupportedProtocols().contains(protocol); if (yes) break; } // Check if the current protocol version supports the target protocol or if it is supported by any of the compatible versions return protocolValues.protocolVersion.getSupportedProtocols().contains(protocol) || yes; } /** * Check if the target packet is supported by the current protocol version * * @param packet The target packet to check * @return true if the target packet is supported, false otherwise */ public boolean isPacketSupported(OACPacket packet) { boolean compatible = false; for (ProtocolVersion compatibleVersion : packet.getCompatibleVersions()) { if (!compatible) compatible = isVersionSupported(compatibleVersion); } return compatible; } /** * Check if the target protocol version is supported by the current protocol version * * @param targetVersion The target protocol version to check * @return true if the target protocol version is supported, false otherwise */ public boolean isVersionSupported(ProtocolVersion targetVersion) { // Check if the target protocol version is the same as the current protocol version or if it is in the list of compatible versions return protocolValues.protocolVersion == targetVersion || protocolValues.protocolVersion.getCompatibleVersions().contains(targetVersion); } /** * Validate if the protocol version is valid for the current side * * @return true if the protocol version is valid for the current side, false otherwise */ private boolean validateProtocolSide() { return (isRunningAsClient() && protocolValues.protocolVersion.getProtocolSide() == ProtocolVersion.ProtocolSide.CLIENT) || (isRunningAsClient() && protocolValues.protocolVersion.getProtocolSide() == ProtocolVersion.ProtocolSide.CLIENT_WEB) || (isRunningAsClient() && protocolValues.protocolVersion.getProtocolSide() == ProtocolVersion.ProtocolSide.CLIENT_INS) || (isRunningAsClient() && protocolValues.protocolVersion.getProtocolSide() == ProtocolVersion.ProtocolSide.ALL) || (isRunningAsWebServer() && protocolValues.protocolVersion.getProtocolSide() == ProtocolVersion.ProtocolSide.WEB) || (isRunningAsWebServer() && protocolValues.protocolVersion.getProtocolSide() == ProtocolVersion.ProtocolSide.CLIENT_WEB) || (isRunningAsWebServer() && protocolValues.protocolVersion.getProtocolSide() == ProtocolVersion.ProtocolSide.WEB_INS) || (isRunningAsWebServer() && protocolValues.protocolVersion.getProtocolSide() == ProtocolVersion.ProtocolSide.ALL) || (isRunningAsServer() && protocolValues.protocolVersion.getProtocolSide() == ProtocolVersion.ProtocolSide.ALL) || (isRunningAsINSServer() && protocolValues.protocolVersion.getProtocolSide() == ProtocolVersion.ProtocolSide.INS) || (isRunningAsINSServer() && protocolValues.protocolVersion.getProtocolSide() == ProtocolVersion.ProtocolSide.WEB_INS) || (isRunningAsINSServer() && protocolValues.protocolVersion.getProtocolSide() == ProtocolVersion.ProtocolSide.CLIENT_INS) || (isRunningAsINSServer() && protocolValues.protocolVersion.getProtocolSide() == ProtocolVersion.ProtocolSide.ALL); } /** * Check if the current instance is running as a INS server * * @return true if the current instance is running as a INS server, false otherwise */ public boolean isRunningAsINSServer() { return isRunningAsServer() && protocolServer instanceof ProtocolINSServer; } /** * Check if the current instance is running as a client * * @return true if the current instance is running as a client, false otherwise */ public boolean isRunningAsClient() { return protocolClient != null; } /** * Check if the current instance is running as a web server * * @return true if the current instance is running as a web server, false otherwise */ public boolean isRunningAsWebServer() { if (protocolValues.protocolVersion == ProtocolVersion.PV_1_0_0_BETA) return isRunningAsServer() && protocolServer instanceof ProtocolWebServer_1_0_0_B; return isRunningAsServer() && protocolServer instanceof ProtocolWebServer; } /** * Check if the current instance is running as a custom server * * @return true if the current instance is running as a custom server, false otherwise */ public boolean isRunningAsServer() { return protocolServer != null; } }