initial commit

This commit is contained in:
MrLetsplay 2023-12-03 21:32:09 +01:00
commit e41b0cfe8a
Signed by: mr
SSH Key Fingerprint: SHA256:92jBH80vpXyaZHjaIl47pjRq+Yt7XGTArqQg1V7hSqg
7 changed files with 224 additions and 0 deletions

5
.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
/bin/
/target/
/.settings/
/.classpath
/dependency-reduced-pom.xml

23
.project Normal file
View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>ShareServer</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

32
pom.xml Normal file
View File

@ -0,0 +1,32 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>me.mrletsplay</groupId>
<artifactId>ShareServer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<release>17</release>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>me.mrletsplay</groupId>
<artifactId>ShareClient-Core</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.java-websocket</groupId>
<artifactId>Java-WebSocket</artifactId>
<version>1.5.4</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,20 @@
package me.mrletsplay.shareserver;
public class Session {
private String id;
private int nextSiteID = 0;
public Session(String id) {
this.id = id;
}
public String getID() {
return id;
}
public int getNewSiteID() {
return nextSiteID++;
}
}

View File

@ -0,0 +1,3 @@
package me.mrletsplay.shareserver;
public record SessionUser(Session session, int siteID) {}

View File

@ -0,0 +1,22 @@
package me.mrletsplay.shareserver;
import java.util.HashMap;
import java.util.Map;
public class ShareServer {
private static final Map<String, Session> SESSIONS = new HashMap<>();
public static void main(String[] args) {
new ShareWSServer().start();
}
public static Session getOrCreateSession(String sessionID) {
return SESSIONS.computeIfAbsent(sessionID, Session::new);
}
public static void deleteSession(String sessionID) {
SESSIONS.remove(sessionID);
}
}

View File

@ -0,0 +1,119 @@
package me.mrletsplay.shareserver;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.util.List;
import java.util.Objects;
import org.java_websocket.WebSocket;
import org.java_websocket.framing.CloseFrame;
import org.java_websocket.handshake.ClientHandshake;
import org.java_websocket.server.WebSocketServer;
import me.mrletsplay.shareclientcore.connection.RemoteConnection;
import me.mrletsplay.shareclientcore.connection.message.ChangeMessage;
import me.mrletsplay.shareclientcore.connection.message.ClientHelloMessage;
import me.mrletsplay.shareclientcore.connection.message.Message;
import me.mrletsplay.shareclientcore.connection.message.PeerJoinMessage;
import me.mrletsplay.shareclientcore.connection.message.PeerLeaveMessage;
import me.mrletsplay.shareclientcore.connection.message.ServerHelloMessage;
public class ShareWSServer extends WebSocketServer {
public ShareWSServer() {
super(new InetSocketAddress("0.0.0.0", 5473));
}
@Override
public void onOpen(WebSocket conn, ClientHandshake handshake) {
System.out.println("Client connected");
}
@Override
public void onClose(WebSocket conn, int code, String reason, boolean remote) {
System.out.println("Client disconnected");
if(conn.getAttachment() != null) {
SessionUser user = conn.getAttachment();
var peers = getPeers(user.session());
if(peers.isEmpty()) {
ShareServer.deleteSession(reason);
return;
}
peers.forEach(peer -> send(peer, new PeerLeaveMessage(user.siteID())));
}
}
@Override
public void onMessage(WebSocket conn, String message) {
}
@Override
public void onMessage(WebSocket conn, ByteBuffer bytes) {
Message m;
try {
m = Message.deserialize(bytes);
}catch(IOException e) {
conn.close(CloseFrame.POLICY_VALIDATION, "Invalid message");
return;
}
if(conn.getAttachment() == null) {
// Only valid message is CLIENT_HELLO
if(m instanceof ClientHelloMessage hello) {
Session session = ShareServer.getOrCreateSession(hello.sessionID());
int siteID = session.getNewSiteID();
conn.setAttachment(new SessionUser(session, siteID));
send(conn, new ServerHelloMessage(RemoteConnection.PROTOCOL_VERSION, siteID));
getPeers(session).forEach(peer -> send(peer, new PeerJoinMessage(hello.username(), siteID)));
}else {
conn.close(CloseFrame.POLICY_VALIDATION, "First message must be CLIENT_HELLO");
}
return;
}
Session session = conn.getAttachment();
if(m instanceof ChangeMessage change) {
getPeers(session).forEach(peer -> send(peer, m));
}
// System.out.println("Got a message");
// getConnections().forEach(c -> {
// if(conn != c) c.send(message);
// });
}
private List<WebSocket> getPeers(Session session) {
return getConnections().stream()
.filter(c -> Objects.equals(c.getAttachment(), session))
.toList();
}
@Override
public void onError(WebSocket conn, Exception ex) {
}
@Override
public void onStart() {
}
public void send(WebSocket connection, Message message) {
try {
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
DataOutputStream dOut = new DataOutputStream(bOut);
dOut.writeUTF(message.getType().name());
message.serialize(dOut);
connection.send(bOut.toByteArray());
} catch (IOException e) {
connection.close(CloseFrame.PROTOCOL_ERROR);
}
}
}