A bunch of Packet changes

This commit is contained in:
2023-12-11 18:07:31 +02:00
parent 085fc2ee36
commit 22ee07a5b3
45 changed files with 1667 additions and 171 deletions
@@ -1,16 +1,23 @@
package dev.wiing.gossip.server;
import dev.wiing.gossip.lib.models.SecretUser;
import dev.wiing.gossip.lib.models.Topic;
import dev.wiing.gossip.lib.models.User;
import java.net.Socket;
import java.security.SecureRandom;
import java.util.*;
public class Database {
private int userIdCounter = 1;
private final Map<Long, User> users = Collections.synchronizedMap(new HashMap<>());
private final Map<byte[], User> usersBySecret = Collections.synchronizedMap(new HashMap<>());
private final Map<String, User> usersBySecret = Collections.synchronizedMap(new HashMap<>());
private final Map<Long, Socket> userSockets = Collections.synchronizedMap(new HashMap<>());
private final Set<String> usedUsernames = Collections.synchronizedSet(new HashSet<>());
private int topicIdCounter = 1;
private final Map<Long, Topic> topics = Collections.synchronizedMap(new HashMap<>());
private Database() {
}
@@ -21,18 +28,19 @@ public class Database {
return instance;
}
public SecretUser registerUser(String username, char iconID) {
public SecretUser registerUser(String username, byte iconID, Socket socket) {
SecureRandom random = new SecureRandom();
byte[] secret = new byte[32];
random.nextBytes(secret);
long userID = random.nextLong();
long userID = userIdCounter++;
User user = new User(username, iconID, userID);
users.put(userID, user);
usersBySecret.put(secret, user);
userSockets.put(userID, socket);
usersBySecret.put(new String(secret), user);
usedUsernames.add(username);
System.out.println("Created user: " + username + " #" + Long.toUnsignedString(userID));
@@ -55,6 +63,23 @@ public class Database {
return usersBySecret.getOrDefault(secret, null);
}
public Collection<User> getUsers() {
return Collections.unmodifiableCollection(users.values());
}
public Socket getUserSocket(long uID) {
return userSockets.getOrDefault(uID, null);
}
public User getUserOfSocket(Socket socket) {
return userSockets.entrySet().stream()
.filter(entry -> entry.getValue().equals(socket))
.findFirst()
.map(Map.Entry::getKey)
.map(this::getUserByID)
.orElse(null);
}
public void removeUser(User user) {
users.remove(user.getUserID());
@@ -64,6 +89,36 @@ public class Database {
.findFirst()
.ifPresent(usersBySecret::remove);
userSockets.remove(user.getUserID());
usedUsernames.remove(user.getUsername());
}
public Topic createTopic(byte[] userSecret, String topicName, String topicDescription) {
if (!usersBySecret.containsKey(new String(userSecret))) return null;
User user = usersBySecret.get(new String(userSecret));
short colorHue = (short)Math.abs((new Random().nextInt(360)));
Topic topic = new Topic(
topicIdCounter++,
topicName,
topicDescription,
user,
colorHue
);
topics.put(topic.getId(), topic);
return topic;
}
public Topic getTopic(long topicID) {
return topics.getOrDefault(topicID, null);
}
public void removeTopic(long topicID) {
topics.remove(topicID);
}
}
@@ -1,11 +1,9 @@
package dev.wiing.gossip.server;
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.CredentialsPacket;
import dev.wiing.gossip.lib.packets.RegisterPacket;
import dev.wiing.gossip.lib.packets.Packet;
import dev.wiing.gossip.lib.packets.TestPacket;
import dev.wiing.gossip.lib.packets.*;
import java.io.BufferedInputStream;
import java.io.IOException;
@@ -31,6 +29,14 @@ public record UserSocket(Socket socket) implements Runnable {
case RegisterPacket.TYPE:
onRegisterUser((RegisterPacket) packet);
break;
case CreateTopicPacket.TYPE:
onCreateTopic((CreateTopicPacket) packet);
break;
case FetchUserPacket.TYPE:
onFetchUser((FetchUserPacket) packet);
break;
}
} catch (SocketException e) {
break;
@@ -38,17 +44,59 @@ public record UserSocket(Socket socket) implements Runnable {
throw new RuntimeException(e);
}
}
// Connection lost
User user = Database.getInstance().getUserOfSocket(socket);
Database.getInstance().removeUser(user);
}
private void onRegisterUser(RegisterPacket packet) {
SecretUser user = Database.getInstance().registerUser(packet.getUsername(), packet.getIconID());
SecretUser user = Database.getInstance().registerUser(packet.getUsername(), packet.getAvatarID(), packet.getSource());
CredentialsPacket creds = new CredentialsPacket();
creds.setSecret(user.getUserSecret());
creds.setUID(user.getUserID());
try {
Globals.getPacketManager().writePacket(packet.getSource().getOutputStream(), creds);
Globals.getPacketManager().replyPacket(packet, creds);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private void onCreateTopic(CreateTopicPacket packet) {
Topic topic = Database.getInstance().createTopic(packet.getUserSecret(), packet.getTopicName(), packet.getTopicDescription());
if (topic == null) return;
TopicAddedPacket added = new TopicAddedPacket();
added.setTopicID(topic.getId());
added.setHostID(topic.getHost().getUserID());
added.setTopicName(topic.getName());
added.setTopicDescription(topic.getDescription());
added.setTopicColor(topic.getColor());
for (User user : Database.getInstance().getUsers()) {
Socket socket = Database.getInstance().getUserSocket(user.getUserID());
try {
Globals.getPacketManager().writePacket(socket.getOutputStream(), added);
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void onFetchUser(FetchUserPacket packet) {
User user = Database.getInstance().getUserByID(packet.getUserID());
UserDataPacket resp = new UserDataPacket();
resp.setUserID(user.getUserID());
resp.setUsername(user.getUsername());
resp.setAvatarID((byte) user.getAvatarID());
try {
Globals.getPacketManager().replyPacket(packet, resp);
} catch (IOException e) {
throw new RuntimeException(e);
}