Packet, Auth reworks & Messages

This commit is contained in:
2023-12-13 00:30:24 +02:00
parent 22ee07a5b3
commit 0b1270a916
42 changed files with 1175 additions and 152 deletions
+16
View File
@@ -20,6 +20,22 @@
<artifactId>Lib</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.20.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.20.0</version>
</dependency>
<dependency>
<groupId>com.lmax</groupId>
<artifactId>disruptor</artifactId>
<version>3.4.4</version>
</dependency>
</dependencies>
</project>
@@ -1,14 +1,20 @@
package dev.wiing.gossip.server;
import dev.wiing.gossip.lib.data.AuthSecret;
import dev.wiing.gossip.lib.models.SecretUser;
import dev.wiing.gossip.lib.models.Topic;
import dev.wiing.gossip.lib.models.User;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.net.Socket;
import java.security.SecureRandom;
import java.util.*;
public class Database {
private static final Logger logger = LogManager.getLogger(Database.class);
private int userIdCounter = 1;
private final Map<Long, User> users = Collections.synchronizedMap(new HashMap<>());
private final Map<String, User> usersBySecret = Collections.synchronizedMap(new HashMap<>());
@@ -31,8 +37,9 @@ public class Database {
public SecretUser registerUser(String username, byte iconID, Socket socket) {
SecureRandom random = new SecureRandom();
byte[] secret = new byte[32];
random.nextBytes(secret);
byte[] secretBytes = new byte[32];
random.nextBytes(secretBytes);
AuthSecret secret = new AuthSecret(secretBytes);
long userID = userIdCounter++;
@@ -40,10 +47,10 @@ public class Database {
users.put(userID, user);
userSockets.put(userID, socket);
usersBySecret.put(new String(secret), user);
usersBySecret.put(secret.getString(), user);
usedUsernames.add(username);
System.out.println("Created user: " + username + " #" + Long.toUnsignedString(userID));
logger.info("User created: \"{}\" (#{})", user.getUsername(), user.getUserID());
return new SecretUser(username, iconID, userID, secret);
}
@@ -59,8 +66,8 @@ public class Database {
.orElse(null);
}
public User getUserBySecret(byte[] secret) {
return usersBySecret.getOrDefault(secret, null);
public User getUserBySecret(AuthSecret secret) {
return usersBySecret.getOrDefault(secret.getString(), null);
}
public Collection<User> getUsers() {
@@ -92,12 +99,14 @@ public class Database {
userSockets.remove(user.getUserID());
usedUsernames.remove(user.getUsername());
logger.info("User removed: \"{}\" (#{})", user.getUsername(), user.getUserID());
}
public Topic createTopic(byte[] userSecret, String topicName, String topicDescription) {
if (!usersBySecret.containsKey(new String(userSecret))) return null;
public Topic createTopic(AuthSecret userSecret, String topicName, String topicDescription) {
if (!usersBySecret.containsKey(userSecret.getString())) return null;
User user = usersBySecret.get(new String(userSecret));
User user = usersBySecret.get(userSecret.getString());
short colorHue = (short)Math.abs((new Random().nextInt(360)));
@@ -111,6 +120,8 @@ public class Database {
topics.put(topic.getId(), topic);
logger.info("Topic created: \"{}\" (#{})", topic.getName(), topic.getId());
return topic;
}
@@ -119,6 +130,8 @@ public class Database {
}
public void removeTopic(long topicID) {
topics.remove(topicID);
Topic topic = topics.remove(topicID);
logger.info("Topic removed: \"{}\" (#{})", topic.getName(), topic.getId());
}
}
@@ -1,8 +1,6 @@
package dev.wiing.gossip.server;
import dev.wiing.gossip.lib.Config;
import dev.wiing.gossip.lib.packets.RegisterPacket;
import dev.wiing.gossip.lib.packets.TestPacket;
import java.io.*;
import java.net.ServerSocket;
@@ -13,6 +11,37 @@ public class Program {
public static void main(String[] args) throws IOException {
// try (FileOutputStream stream = new FileOutputStream("test.bin")) {
//
// TopicUpdatePacket packet = new TopicUpdatePacket();
// packet.setTopicID(123456789);
// packet.setTopicDescription("New Name");
// packet.getUsersJoined().add(new LongData().setValue(696969420L));
// packet.getUsersJoined().add(new LongData().setValue(987654231L));
//
// BufferedOutputStream out = new BufferedOutputStream(stream);
//
// ByteBuffer buffer = ByteBuffer.allocate(packet.getTotalLength());
// buffer.putShort(packet.getType());
// buffer.putInt(packet.getLength());
// packet.writeBytes(buffer);
//
// out.write(buffer.array());
// out.flush();
// }
//
// try (FileInputStream stream = new FileInputStream("test.bin")) {
//
// TopicUpdatePacket test = new TopicUpdatePacket();
//
// BufferedInputStream in = new BufferedInputStream(stream);
//
// ByteBuffer buffer = ByteBuffer.wrap(in.readAllBytes()).position(6);
// Packet result = test.readBytes(buffer, 0);
//
// int a = 10;
// }
Globals.getPacketManager().registerPackets();
int port = Config.getPort();
@@ -1,9 +1,13 @@
package dev.wiing.gossip.server;
import dev.wiing.gossip.lib.data.LongData;
import dev.wiing.gossip.lib.models.Message;
import dev.wiing.gossip.lib.models.SecretUser;
import dev.wiing.gossip.lib.models.Topic;
import dev.wiing.gossip.lib.models.User;
import dev.wiing.gossip.lib.packets.*;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.BufferedInputStream;
import java.io.IOException;
@@ -12,9 +16,19 @@ import java.net.SocketException;
public record UserSocket(Socket socket) implements Runnable {
private static final Logger logger = LogManager.getLogger(UserSocket.class);
private void info(String message, Object ...params) {
logger.info(socket.getInetAddress().toString() + ":" + socket.getPort() + " > " + message, params);
}
@Override
public void run() {
while (true) {
info("Established");
boolean loop = true;
while (socket.isConnected() && loop) {
try {
if (!socket.isConnected())
break;
@@ -26,22 +40,30 @@ public record UserSocket(Socket socket) implements Runnable {
packet.setSource(socket);
switch (packet.getType()) {
case RegisterPacket.TYPE:
onRegisterUser((RegisterPacket) packet);
case RegisterRequestPacket.TYPE:
onRegisterUser((RegisterRequestPacket) packet);
break;
case CreateTopicPacket.TYPE:
onCreateTopic((CreateTopicPacket) packet);
case TopicPushPacket.TYPE:
onCreateTopic((TopicPushPacket) packet);
break;
case FetchUserPacket.TYPE:
onFetchUser((FetchUserPacket) packet);
case TopicJoinPacket.TYPE:
onUserJoinTopic((TopicJoinPacket) packet);
break;
case UserFetchPacket.TYPE:
onFetchUser((UserFetchPacket) packet);
break;
case MessagePushPacket.TYPE:
onUserMessage((MessagePushPacket) packet);
break;
}
} catch (SocketException e) {
break;
loop = false;
} catch (IOException e) {
throw new RuntimeException(e);
logger.error(e);
}
}
@@ -50,26 +72,30 @@ public record UserSocket(Socket socket) implements Runnable {
Database.getInstance().removeUser(user);
}
private void onRegisterUser(RegisterPacket packet) {
private void onRegisterUser(RegisterRequestPacket packet) {
SecretUser user = Database.getInstance().registerUser(packet.getUsername(), packet.getAvatarID(), packet.getSource());
CredentialsPacket creds = new CredentialsPacket();
info("Register as \"{}\" (#{})", user.getUsername().toUpperCase(), user.getUserID());
RegisterCredentialsPacket creds = new RegisterCredentialsPacket();
creds.setSecret(user.getUserSecret());
creds.setUID(user.getUserID());
try {
Globals.getPacketManager().replyPacket(packet, creds);
} catch (IOException e) {
throw new RuntimeException(e);
logger.error(e);
}
}
private void onCreateTopic(CreateTopicPacket packet) {
Topic topic = Database.getInstance().createTopic(packet.getUserSecret(), packet.getTopicName(), packet.getTopicDescription());
private void onCreateTopic(TopicPushPacket packet) {
Topic topic = Database.getInstance().createTopic(packet.getAuth(), packet.getTopicName(), packet.getTopicDescription());
if (topic == null) return;
TopicAddedPacket added = new TopicAddedPacket();
info("\"{}\" created topic \"{}\" (#{})", topic.getHost().getUsername().toUpperCase(), topic.getName().toUpperCase(), topic.getId());
TopicCreatedPacket added = new TopicCreatedPacket();
added.setTopicID(topic.getId());
added.setHostID(topic.getHost().getUserID());
added.setTopicName(topic.getName());
@@ -82,14 +108,54 @@ public record UserSocket(Socket socket) implements Runnable {
try {
Globals.getPacketManager().writePacket(socket.getOutputStream(), added);
} catch (IOException e) {
e.printStackTrace();
logger.error(e);
}
}
}
private void onFetchUser(FetchUserPacket packet) {
private void onUserJoinTopic(TopicJoinPacket packet) {
Topic topic = Database.getInstance().getTopic(packet.getTopicID());
User requester = Database.getInstance().getUserBySecret(packet.getAuth());
if (requester == null) return;
if (topic == null) return;
if (!topic.hasUser(requester)) {
info("\"{}\" joined topic \"{}\" (#{})", topic.getHost().getUsername().toUpperCase(), topic.getName().toUpperCase(), topic.getId());
topic.addUser(requester);
}
AckPacket resp = new AckPacket();
resp.setAcknowledgement(packet);
try {
Globals.getPacketManager().replyPacket(packet, resp);
} catch (IOException e) {
logger.error(e);
}
TopicUpdatePacket updatePacket = new TopicUpdatePacket();
updatePacket.setTopicID(topic.getId());
updatePacket.getUsersJoined().add(new LongData().setValue(requester.getUserID()));
for (User user : Database.getInstance().getUsers()) {
Socket socket = Database.getInstance().getUserSocket(user.getUserID());
try {
Globals.getPacketManager().writePacket(socket.getOutputStream(), updatePacket);
} catch (IOException e) {
logger.error(e);
}
}
}
private void onFetchUser(UserFetchPacket packet) {
User user = Database.getInstance().getUserByID(packet.getUserID());
if (user == null) return;
info("Requested user #{}", user.getUserID());
UserDataPacket resp = new UserDataPacket();
resp.setUserID(user.getUserID());
resp.setUsername(user.getUsername());
@@ -98,7 +164,45 @@ public record UserSocket(Socket socket) implements Runnable {
try {
Globals.getPacketManager().replyPacket(packet, resp);
} catch (IOException e) {
throw new RuntimeException(e);
logger.error(e);
}
}
private void onUserMessage(MessagePushPacket packet) {
Topic topic = Database.getInstance().getTopic(packet.getTopicID());
User user = Database.getInstance().getUserBySecret(packet.getAuth());
if (user == null) return;
if (topic == null) return;
Message message = new Message(user, topic, packet.getMessage());
topic.addMessage(message);
info("\"{}\" in \"{}\" sends \"{}\"", user.getUsername().toUpperCase(), topic.getName().toUpperCase(), packet.getMessage());
AckPacket ack = new AckPacket();
ack.setAcknowledgement(packet);
try {
Globals.getPacketManager().replyPacket(packet, ack);
} catch (IOException e) {
logger.error(e);
}
MessageCreatedPacket messageCreated = new MessageCreatedPacket();
messageCreated.setAuthorID(user.getUserID());
messageCreated.setTopicID(topic.getId());
messageCreated.setContents(message.getContents());
for (User babbler : topic.getUsersReadOnly().values()) {
Socket userSocket = Database.getInstance().getUserSocket(babbler.getUserID());
try {
Globals.getPacketManager().writePacket(userSocket.getOutputStream(), messageCreated);
} catch (IOException e) {
logger.error(e);
}
}
}
+3
View File
@@ -1,3 +1,6 @@
module dev.wiing.gossip.server {
requires dev.wiing.gossip.lib;
requires org.apache.logging.log4j;
opens dev.wiing.gossip.server to org.apache.logging.log4j;
}
+12
View File
@@ -0,0 +1,12 @@
<Configuration name="GossipServer" packages="">
<Appenders>
<Console name="stdout" target="SYSTEM_OUT">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} %c{1} %highlight{ %p } %m%n"/>
</Console>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="stdout"/>
</Root>
</Loggers>
</Configuration>
BIN
View File
Binary file not shown.