A bunch of Packet changes
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user