- Updated to new repo

This commit is contained in:
Finn
2025-09-24 22:02:10 +02:00
parent 1556896a5a
commit d090b1067c
40 changed files with 201 additions and 195 deletions

View File

@@ -0,0 +1,67 @@
package org.openautonomousconnection.protocol.versions;
import lombok.Getter;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public enum ProtocolVersion implements Serializable {
PV_1_0_0_CLASSIC("1.0.0", ProtocolType.CLASSIC, ProtocolSide.BOTH),
PV_1_0_0_BETA("1.0.0", ProtocolType.BETA, ProtocolSide.BOTH, PV_1_0_0_CLASSIC);
@Getter
private final String version;
@Getter
private final ProtocolType protocolType;
@Getter
private final ProtocolSide protocolSide;
@Getter
private final List<ProtocolVersion> compatibleVersions;
ProtocolVersion(String version, ProtocolType protocolType, ProtocolSide protocolSide, ProtocolVersion... compatibleVersions) {
this.version = version;
this.protocolType = protocolType;
this.protocolSide = protocolSide;
this.compatibleVersions = new ArrayList<>(Arrays.stream(compatibleVersions).toList());
if (!this.compatibleVersions.contains(this)) this.compatibleVersions.add(this);
}
@Override
public final String toString() {
StringBuilder compatible = new StringBuilder("[");
for (ProtocolVersion compatibleVersion : compatibleVersions) compatible.append(compatibleVersion.buildName());
compatible.append("]");
return "{version=" + version + ";type=" + protocolType.toString() + ";side=" + protocolSide.toString() + ";compatible=" + compatible + "}";
}
public final String buildName() {
return version + "-" + protocolType.toString();
}
public enum ProtocolType implements Serializable {
CLASSIC, // -> See "_old" Projects on GitHub Organisation https://github.com/Open-Autonomous-Connection/
BETA,
STABLE;
@Override
public final String toString() {
return name().toUpperCase();
}
}
public enum ProtocolSide implements Serializable {
CLIENT, // Protocol version can only used on Client
SERVER, // Protocol version can only used on Server
BOTH // Protocol version can only used on Server and Client
;
@Override
public final String toString() {
return name().toUpperCase();
}
}
}

View File

@@ -0,0 +1,47 @@
package org.openautonomousconnection.protocol.versions.v1_0_0.beta;
import lombok.Getter;
import java.io.Serializable;
public enum DNSResponseCode implements Serializable {
RESPONSE_NOT_REQUIRED(0, "Response code not required"),
RESPONSE_INVALID_REQUEST(1, "Invalid request"),
RESPONSE_AUTH_SUCCESS(4, "Auth success"),
RESPONSE_AUTH_FAILED(5, "Auth failed"),
RESPONSE_DOMAIN_NAME_EXIST(100, "Domainname exist"),
RESPONSE_DOMAIN_NAME_NOT_EXIST(101, "Domainname does not exist"),
RESPONSE_DOMAIN_NAME_CREATED(105, "Domainname created"),
RESPONSE_DOMAIN_NAME_DELETED(106, "Domainname deleted"),
RESPONSE_DOMAIN_TLN_EXIST(110, "TopLevelName exist"),
RESPONSE_DOMAIN_TLN_NOT_EXIST(111, "TopLevelName does not exist"),
RESPONSE_DOMAIN_TLN_CREATED(115, "TopLevelName created"),
RESPONSE_DOMAIN_TLN_DELETED(116, "TopLevelName deleted"),
RESPONSE_DOMAIN_SUBNAME_EXIST(120, "Subname exist"),
RESPONSE_DOMAIN_SUBNAME_NOT_EXIST(121, "Subname does not exist"),
RESPONSE_DOMAIN_SUBNAME_CREATED(125, "Subname created"),
RESPONSE_DOMAIN_SUBNAME_DELETED(126, "Subname deleted"),
RESPONSE_DOMAIN_FULLY_EXIST(130, "Full domain exist"),
RESPONSE_DOMAIN_FULLY_NOT_EXIST(131, "Full domain does not exist");
@Getter
private final int code;
@Getter
private final String description;
DNSResponseCode(int code, String description) {
this.code = code;
this.description = description;
}
@Override
public String toString() {
return "{code=" + code + ";description=" + description + "}";
}
}

View File

@@ -0,0 +1,102 @@
package org.openautonomousconnection.protocol.versions.v1_0_0.beta;
import org.openautonomousconnection.protocol.ProtocolBridge;
import lombok.Getter;
import java.io.Serializable;
import java.util.Arrays;
import java.util.List;
public class Domain implements Serializable {
@Getter
private final String subname;
@Getter
private final String name;
@Getter
private final String topLevelName;
@Getter
private String path;
@Getter
private String query;
@Getter
private String fragment;
@Getter
private String protocol;
public Domain(String fullDomain) {
// Remove protocol
String domainWithPath = fullDomain.contains("://") ? fullDomain.split("://", 2)[1] : fullDomain;
this.protocol = fullDomain.contains("://") ? fullDomain.split("://", 2)[0] : "";
if (this.protocol.endsWith("://"))
this.protocol = this.protocol.substring(0, this.protocol.length() - "://".length());
// Cut path
String[] domainPartsAndPath = domainWithPath.split("/", 2);
String host = domainPartsAndPath[0]; // z.B. hello.world.com
String fullPath = domainPartsAndPath.length > 1 ? "/" + domainPartsAndPath[1] : "";
// Split domain in labels
List<String> labels = Arrays.asList(host.split("\\."));
if (labels.size() < 2) throw new IllegalArgumentException("Invalid domain: " + host);
this.topLevelName = labels.getLast();
this.name = labels.get(labels.size() - 2);
this.subname = labels.size() > 2 ? String.join(".", labels.subList(0, labels.size() - 2)) : null;
if (fullPath.contains("#")) {
this.fragment = "#" + Arrays.stream(fullPath.split("#")).toList().getLast();
fullPath = fullPath.substring(0, fullPath.length() - ("#" + fragment).length());
} else this.fragment = "";
// Split path and query
if (fullPath.contains("?")) {
String[] parts = fullPath.split("\\?", 2);
this.path = parts[0];
this.query = parts[1];
} else {
this.path = fullPath;
this.query = "";
}
if (this.path.startsWith("/")) this.path = this.path.substring(1);
if (this.path.endsWith("/")) this.path = this.path.substring(0, this.path.length() - 1);
if (this.query.startsWith("?")) this.query = this.query.substring(1);
if (this.fragment.startsWith("#")) this.fragment = this.fragment.substring(1);
}
public final boolean hasSubname() {
return subname != null;
}
@Override
public final boolean equals(Object obj) {
if (!(obj instanceof Domain domain)) return false;
return domain.getSubname().equalsIgnoreCase(this.subname) && domain.getName().equalsIgnoreCase(this.name) &&
domain.getTopLevelName().equalsIgnoreCase(this.topLevelName) && domain.getProtocol().equalsIgnoreCase(this.protocol);
}
public final String getDestination() {
if (ProtocolBridge.getInstance().isRunningAsClient())
return DNSResponseCode.RESPONSE_INVALID_REQUEST.toString();
if (this.equals(DefaultDomains.DNS_INFO_SITE))
return ProtocolBridge.getInstance().getProtocolServer().getDNSInfoSite();
if (this.equals(DefaultDomains.DNS_REGISTER_SITE))
return ProtocolBridge.getInstance().getProtocolServer().getDNSRegisterSite();
if (this.name.equalsIgnoreCase("about") && this.protocol.equalsIgnoreCase("oac"))
return ProtocolBridge.getInstance().getProtocolServer().getTLNInfoSite(topLevelName);
return !hasSubname() ? ProtocolBridge.getInstance().getProtocolServer().getDomainDestination(this) : ProtocolBridge.getInstance().getProtocolServer().getSubnameDestination(this, subname);
}
public static class DefaultDomains {
public static final Domain DNS_INFO_SITE = new Domain("oac://about.oac/");
public static final Domain DNS_REGISTER_SITE = new Domain("oac://register.oac/");
public static Domain TLN_INFO_SITE(String topLevelName) {
return new Domain("oac://about." + topLevelName + "/");
}
}
}

View File

@@ -0,0 +1,25 @@
package org.openautonomousconnection.protocol.versions.v1_0_0.classic;
import org.openautonomousconnection.protocol.versions.ProtocolVersion;
import org.openautonomousconnection.protocol.versions.v1_0_0.beta.Domain;
public class ClassicConverter {
public static Domain classicDomainToNewDomain(Classic_Domain classicDomain) {
return new Domain(classicDomain.name + "." + classicDomain.topLevelDomain + (classicDomain.path.startsWith("/") ? classicDomain.path : "/" + classicDomain.path));
}
public static Classic_Domain newDomainToClassicDomain(Domain newDomain) {
return new Classic_Domain(newDomain.getName(), newDomain.getTopLevelName(), newDomain.getDestination(), newDomain.getPath());
}
public static ProtocolVersion classicProtocolVersionToNewProtocolVersion(Classic_ProtocolVersion classicProtocolVersion) {
if (classicProtocolVersion == Classic_ProtocolVersion.PV_1_0_0) return ProtocolVersion.PV_1_0_0_CLASSIC;
return null;
}
public static Classic_ProtocolVersion newProtocolVersionToClassicProtocolVersion(ProtocolVersion newProtocolVersion) {
return Classic_ProtocolVersion.PV_1_0_0;
}
}

View File

@@ -0,0 +1,10 @@
package org.openautonomousconnection.protocol.versions.v1_0_0.classic;
public abstract class ClassicHandlerClient {
public abstract void unsupportedClassicPacket(String classicPacketClassName, Object[] content);
public abstract void handleHTMLContent(Classic_SiteType siteType, Classic_Domain domain, String html);
public abstract void handleMessage(String message);
}

View File

@@ -0,0 +1,15 @@
package org.openautonomousconnection.protocol.versions.v1_0_0.classic;
import org.openautonomousconnection.protocol.side.server.ConnectedProtocolClient;
import java.sql.SQLException;
public abstract class ClassicHandlerServer {
public abstract void handleMessage(ConnectedProtocolClient client, String message, Classic_ProtocolVersion protocolVersion);
public abstract Classic_Domain getDomain(Classic_RequestDomain requestDomain) throws SQLException;
public abstract Classic_Domain ping(Classic_RequestDomain requestDomain) throws SQLException;
public abstract void unsupportedClassicPacket(String className, Object[] content, ConnectedProtocolClient client);
}

View File

@@ -0,0 +1,78 @@
package org.openautonomousconnection.protocol.versions.v1_0_0.classic;
import org.openautonomousconnection.protocol.ProtocolBridge;
import org.openautonomousconnection.protocol.packets.v1_0_0.classic.Classic_PingPacket;
import dev.unlegitdqrk.unlegitlibrary.event.EventListener;
import dev.unlegitdqrk.unlegitlibrary.event.Listener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class Classic_ClientListener extends EventListener {
@Listener
public void onDomain(Classic_DomainPacketReceivedEvent event) {
boolean exists = event.domain != null;
if (exists) {
try {
if (!ProtocolBridge.getInstance().getProtocolClient().getNetworkClient().sendPacket(new Classic_PingPacket(event.requestDomain, event.domain, false))) {
ProtocolBridge.getInstance().getClassicHandlerClient().handleHTMLContent(Classic_SiteType.PROTOCOL, new Classic_LocalDomain("error-occurred", "html", ""),
Classic_WebsitesContent.ERROR_OCCURRED(event.domain + "/" + event.domain.path));
}
} catch (IOException | ClassNotFoundException e) {
ProtocolBridge.getInstance().getClassicHandlerClient().handleHTMLContent(Classic_SiteType.PROTOCOL, new Classic_LocalDomain("error-occurred", "html", ""),
Classic_WebsitesContent.ERROR_OCCURRED(event.domain + "/" + event.domain.path + ":\n" + e.getMessage()));
}
} else
ProtocolBridge.getInstance().getClassicHandlerClient().handleHTMLContent(Classic_SiteType.PROTOCOL, new Classic_LocalDomain("domain-not-found", "html", ""), Classic_WebsitesContent.DOMAIN_NOT_FOUND);
}
@Listener
public void onPing(Classic_PingPacketReceivedEvent event) {
if (event.reachable) {
String destination = event.domain.getDomain().getDestination();
try {
URL url = new URL(destination);
HttpURLConnection connection2 = (HttpURLConnection) url.openConnection();
connection2.setRequestMethod("GET");
StringBuilder content = new StringBuilder();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection2.getInputStream()))) {
String line;
while ((line = reader.readLine()) != null) content.append(line);
}
ProtocolBridge.getInstance().getClassicHandlerClient().handleHTMLContent(Classic_SiteType.PUBLIC, event.domain, content.toString());
} catch (IOException exception) {
ProtocolBridge.getInstance().getClassicHandlerClient().handleHTMLContent(Classic_SiteType.PROTOCOL, new Classic_LocalDomain("error-occurred", "html", ""),
Classic_WebsitesContent.ERROR_OCCURRED(exception.getMessage().replace(event.domain.getDomain().getDestination(), event.domain + "/" + event.domain.path)));
}
} else
ProtocolBridge.getInstance().getClassicHandlerClient().handleHTMLContent(Classic_SiteType.PROTOCOL, new Classic_LocalDomain("error-not-reached", "html", ""), Classic_WebsitesContent.DOMAIN_NOT_REACHABLE);
}
@Override
protected final Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public final boolean equals(Object obj) {
return super.equals(obj);
}
@Override
public final String toString() {
return super.toString();
}
@Override
public final int hashCode() {
return super.hashCode();
}
}

View File

@@ -0,0 +1,39 @@
package org.openautonomousconnection.protocol.versions.v1_0_0.classic;
import org.openautonomousconnection.protocol.versions.v1_0_0.beta.Domain;
import lombok.Getter;
import java.io.Serializable;
public class Classic_Domain implements Serializable {
public final String name;
public final String topLevelDomain;
public final String path;
private final String destination;
@Getter
private final Domain domain;
public Classic_Domain(String name, String topLevelDomain, String destination, String path) {
this.domain = new Domain(name + "." + topLevelDomain + "/" + (path.startsWith("/") ? path : "/" + path));
this.name = domain.getName();
this.topLevelDomain = domain.getTopLevelName();
this.destination = domain.getDestination();
this.path = domain.getPath();
}
@Override
protected final Object clone() throws CloneNotSupportedException {
return new Classic_Domain(name, topLevelDomain, destination, path);
}
@Override
public final boolean equals(Object obj) {
if (!(obj instanceof Classic_Domain other)) return false;
return other.name.equalsIgnoreCase(name) && other.topLevelDomain.equalsIgnoreCase(topLevelDomain);
}
@Override
public final int hashCode() {
return super.hashCode();
}
}

View File

@@ -0,0 +1,38 @@
package org.openautonomousconnection.protocol.versions.v1_0_0.classic;
import dev.unlegitdqrk.unlegitlibrary.event.impl.Event;
public class Classic_DomainPacketReceivedEvent extends Event {
public final Classic_ProtocolVersion protocolVersion;
public final Classic_Domain domain;
public final Classic_RequestDomain requestDomain;
public final int clientID;
public Classic_DomainPacketReceivedEvent(Classic_ProtocolVersion protocolVersion, Classic_Domain domain, Classic_RequestDomain requestDomain, int clientID) {
this.protocolVersion = protocolVersion;
this.domain = domain;
this.requestDomain = requestDomain;
this.clientID = clientID;
}
@Override
protected final Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public final boolean equals(Object obj) {
return super.equals(obj);
}
@Override
public final String toString() {
return super.toString();
}
@Override
public final int hashCode() {
return super.hashCode();
}
}

View File

@@ -0,0 +1,76 @@
package org.openautonomousconnection.protocol.versions.v1_0_0.classic;
import dev.unlegitdqrk.unlegitlibrary.utils.DefaultMethodsOverrider;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
class Classic_DomainUtils extends DefaultMethodsOverrider {
public static String getTopLevelDomain(String url) throws MalformedURLException {
URL uri = null;
String tldString = null;
if (url.startsWith(Classic_SiteType.PUBLIC.name + "://"))
url = url.substring((Classic_SiteType.PUBLIC.name + "://").length());
if (url.startsWith(Classic_SiteType.CLIENT.name + "://"))
url = url.substring((Classic_SiteType.CLIENT.name + "://").length());
if (url.startsWith(Classic_SiteType.SERVER.name + "://"))
url = url.substring((Classic_SiteType.SERVER.name + "://").length());
if (url.startsWith(Classic_SiteType.PROTOCOL.name + "://"))
url = url.substring((Classic_SiteType.PROTOCOL.name + "://").length());
if (url.startsWith(Classic_SiteType.LOCAL.name + "://"))
url = url.substring((Classic_SiteType.LOCAL.name + "://").length());
if (!url.startsWith("https://") && !url.startsWith("http://")) url = "https://" + url;
uri = new URL(url);
String[] domainNameParts = uri.getHost().split("\\.");
tldString = domainNameParts[domainNameParts.length - 1];
return tldString;
}
public static String getDomainName(String url) throws URISyntaxException, MalformedURLException {
if (url.startsWith(Classic_SiteType.PUBLIC.name + "://"))
url = url.substring((Classic_SiteType.PUBLIC.name + "://").length());
if (url.startsWith(Classic_SiteType.CLIENT.name + "://"))
url = url.substring((Classic_SiteType.CLIENT.name + "://").length());
if (url.startsWith(Classic_SiteType.SERVER.name + "://"))
url = url.substring((Classic_SiteType.SERVER.name + "://").length());
if (url.startsWith(Classic_SiteType.PROTOCOL.name + "://"))
url = url.substring((Classic_SiteType.PROTOCOL.name + "://").length());
if (url.startsWith(Classic_SiteType.LOCAL.name + "://"))
url = url.substring((Classic_SiteType.LOCAL.name + "://").length());
if (!url.startsWith("https://") && !url.startsWith("http://")) url = "https://" + url;
URI uri = new URI(url);
String domain = uri.getHost().replace("." + getTopLevelDomain(url), "");
return domain;
}
public static String getPath(String url) {
if (!url.startsWith(Classic_SiteType.PUBLIC.name + "://") && !url.startsWith(Classic_SiteType.CLIENT.name + "://") &&
!url.startsWith(Classic_SiteType.SERVER.name + "://") && !url.startsWith(Classic_SiteType.PROTOCOL.name + "://") &&
!url.startsWith(Classic_SiteType.LOCAL.name + "://") && !url.startsWith("http") && !url.startsWith("https")) {
url = Classic_SiteType.PUBLIC.name + "://" + url;
}
String[] split = url.split("/");
if (split.length <= 3) return "";
StringBuilder path = new StringBuilder();
for (int i = 3; i < split.length; i++) path.append(split[i]).append("/");
String pathStr = path.toString();
if (pathStr.startsWith("/")) pathStr = pathStr.substring("/".length());
if (pathStr.endsWith("/")) pathStr = pathStr.substring(0, pathStr.length() - "/".length());
return pathStr;
}
}

View File

@@ -0,0 +1,7 @@
package org.openautonomousconnection.protocol.versions.v1_0_0.classic;
public class Classic_LocalDomain extends Classic_Domain {
public Classic_LocalDomain(String name, String endName, String path) {
super(name, endName, null, path);
}
}

View File

@@ -0,0 +1,40 @@
package org.openautonomousconnection.protocol.versions.v1_0_0.classic;
import dev.unlegitdqrk.unlegitlibrary.event.impl.Event;
public class Classic_PingPacketReceivedEvent extends Event {
public final Classic_ProtocolVersion protocolVersion;
public final Classic_Domain domain;
public final Classic_RequestDomain requestDomain;
public final boolean reachable;
public final int clientID;
public Classic_PingPacketReceivedEvent(Classic_ProtocolVersion protocolVersion, Classic_Domain domain, Classic_RequestDomain requestDomain, boolean reachable, int clientID) {
this.protocolVersion = protocolVersion;
this.domain = domain;
this.requestDomain = requestDomain;
this.reachable = reachable;
this.clientID = clientID;
}
@Override
protected final Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public final boolean equals(Object obj) {
return super.equals(obj);
}
@Override
public final String toString() {
return super.toString();
}
@Override
public final int hashCode() {
return super.hashCode();
}
}

View File

@@ -0,0 +1,12 @@
package org.openautonomousconnection.protocol.versions.v1_0_0.classic;
import java.io.Serializable;
public enum Classic_ProtocolVersion implements Serializable {
PV_1_0_0("1.0.0");
public final String version;
Classic_ProtocolVersion(String version) {
this.version = version;
}
}

View File

@@ -0,0 +1,10 @@
package org.openautonomousconnection.protocol.versions.v1_0_0.classic;
import java.io.Serializable;
public class Classic_RequestDomain extends Classic_Domain implements Serializable {
public Classic_RequestDomain(String name, String topLevelDomain, String path) {
super(name, topLevelDomain, null, path);
}
}

View File

@@ -0,0 +1,14 @@
package org.openautonomousconnection.protocol.versions.v1_0_0.classic;
import java.io.Serializable;
enum Classic_SiteType implements Serializable {
CLIENT("oac-client"), SERVER("oac-server"),
PUBLIC("oac"), PROTOCOL("oac-protocol"), LOCAL("oac-local");
public final String name;
Classic_SiteType(String name) {
this.name = name;
}
}

View File

@@ -0,0 +1,67 @@
package org.openautonomousconnection.protocol.versions.v1_0_0.classic;
import dev.unlegitdqrk.unlegitlibrary.utils.DefaultMethodsOverrider;
public class Classic_WebsitesContent extends DefaultMethodsOverrider {
public static final String DOMAIN_NOT_FOUND = """
<html>
<head>
<title>404 - Domain not found</title>
<meta content="UTF-8" name="charset"/>
<meta content="Open Autonomous Connection" name="author"/>
<meta content="Domain not found" name="description"/>
</head>
<body>
<h1>404 - This domain was not found</h1>
</body>
</html>
""";
public static final String FILE_NOT_FOUND = """
<html>
<head>
<title>404 - File not found</title>
<meta content="UTF-8" name="charset"/>
<meta content="Open Autonomous Connection" name="author"/>
<meta content="File not found" name="description"/>
</head>
<body>
<h1>404 - This file was not found</h1>
</body>
</html>
""";
public static final String DOMAIN_NOT_REACHABLE = """
<html>
<head>
<title>504 - Site not reachable</title>
<meta content="UTF-8" name="charset"/>
<meta content="Open Autonomous Connection" name="author"/>
<meta content="Site not reached" name="description"/>
</head>
<body>
<h1>504 - This site is currently not reachable</h1>
</body>
</html>
""";
public static String ERROR_OCCURRED = ERROR_OCCURRED("No specified details!");
public static String ERROR_OCCURRED(String errorDetails) {
return """
<html>
<head>
<title>500 - Error occurred</title>
<meta content="UTF-8" name="charset"/>
<meta content="Open Autonomous Connection" name="author"/>
<meta content="Site not reached" name="description"/>
</head>
<body>
<h1>500 - Error occured while resolving domain!</h1>
<h4>Details:</h2>
<h5>""" + errorDetails + "</h5>" + """
</body>
</html>
""";
}
}