Access restrictions, errors & properties
This commit is contained in:
parent
a477a87c3d
commit
3c7845f439
@ -84,8 +84,13 @@ public class Connection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
connection.updateConnectionStats();
|
connection.updateConnectionStats();
|
||||||
|
|
||||||
|
} catch (PacketException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
|
||||||
} catch (SocketException e) {
|
} catch (SocketException e) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
@ -212,9 +217,19 @@ public class Connection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return getPacketManager().readPacket(getSocket().getInputStream());
|
Packet packet = getPacketManager().readPacket(getSocket().getInputStream());
|
||||||
|
|
||||||
|
if (packet.getType() == ErrorPacket.TYPE) {
|
||||||
|
ErrorPacket errorPacket = (ErrorPacket) packet;
|
||||||
|
|
||||||
|
throw new PacketException(packetManager.getPacketMap().get(errorPacket.getErrorType()), errorPacket.getReason());
|
||||||
|
}
|
||||||
|
|
||||||
|
return packet;
|
||||||
|
|
||||||
} catch (SocketException e) {
|
} catch (SocketException e) {
|
||||||
throw e;
|
throw e;
|
||||||
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return null;
|
return null;
|
||||||
@ -231,6 +246,7 @@ public class Connection {
|
|||||||
|
|
||||||
if (packet.getType() != packetType) {
|
if (packet.getType() != packetType) {
|
||||||
queuedPackets.add(packet);
|
queuedPackets.add(packet);
|
||||||
|
updateConnectionStats();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,9 @@
|
|||||||
|
package dev.wiing.gossip.client;
|
||||||
|
|
||||||
|
import dev.wiing.gossip.lib.packets.Packet;
|
||||||
|
|
||||||
|
public class PacketException extends RuntimeException {
|
||||||
|
public PacketException(Packet packet, String message) {
|
||||||
|
super("Packet of type=" + packet.getType() + " (" + packet.getClass().getSimpleName() + ") caused an error: " + message);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -13,6 +13,7 @@ import dev.wiing.gossip.lib.packets.MessagePushPacket;
|
|||||||
import dev.wiing.gossip.lib.packets.TopicJoinPacket;
|
import dev.wiing.gossip.lib.packets.TopicJoinPacket;
|
||||||
import dev.wiing.gossip.lib.packets.TypingPingPacket;
|
import dev.wiing.gossip.lib.packets.TypingPingPacket;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
|
import javafx.collections.ListChangeListener;
|
||||||
import javafx.event.ActionEvent;
|
import javafx.event.ActionEvent;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.scene.Parent;
|
import javafx.scene.Parent;
|
||||||
@ -109,6 +110,13 @@ public class MainChatController {
|
|||||||
});
|
});
|
||||||
|
|
||||||
updateTypingMembers();
|
updateTypingMembers();
|
||||||
|
|
||||||
|
txtCompose.getParagraphs().addListener((ListChangeListener<? super CharSequence>) c -> {
|
||||||
|
int height = 8 + Math.min(c.getList().size(), 5) * 17;
|
||||||
|
|
||||||
|
txtCompose.setMinHeight(height);
|
||||||
|
txtCompose.setPrefHeight(height);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setTopicName(String name) {
|
private void setTopicName(String name) {
|
||||||
@ -256,7 +264,12 @@ public class MainChatController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void updateTypingMembers() {
|
public void updateTypingMembers() {
|
||||||
if (topic.getTypingUsersCount() == 0) {
|
int typingUsersCount = topic.getTypingUsersCount();
|
||||||
|
|
||||||
|
if (topic.getTypingUsersReadOnly().stream().anyMatch(user -> user.getUserID() == Connection.getInstance().getSelf().getUserID()))
|
||||||
|
--typingUsersCount;
|
||||||
|
|
||||||
|
if (typingUsersCount == 0) {
|
||||||
lblTyping.setText("");
|
lblTyping.setText("");
|
||||||
lblTyping.setMinHeight(0);
|
lblTyping.setMinHeight(0);
|
||||||
lblTyping.setMaxHeight(0);
|
lblTyping.setMaxHeight(0);
|
||||||
@ -266,7 +279,7 @@ public class MainChatController {
|
|||||||
lblTyping.setMinHeight(Region.USE_COMPUTED_SIZE);
|
lblTyping.setMinHeight(Region.USE_COMPUTED_SIZE);
|
||||||
lblTyping.setMaxHeight(Region.USE_COMPUTED_SIZE);
|
lblTyping.setMaxHeight(Region.USE_COMPUTED_SIZE);
|
||||||
|
|
||||||
if (topic.getTypingUsersCount() > 3) {
|
if (typingUsersCount > 3) {
|
||||||
lblTyping.setText("Several babblers are writing...");
|
lblTyping.setText("Several babblers are writing...");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -274,11 +287,14 @@ public class MainChatController {
|
|||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
for (User user : topic.getTypingUsersReadOnly()) {
|
for (User user : topic.getTypingUsersReadOnly()) {
|
||||||
|
if (user.getUserID() == Connection.getInstance().getSelf().getUserID())
|
||||||
|
continue;
|
||||||
|
|
||||||
if (!sb.isEmpty()) sb.append(", ");
|
if (!sb.isEmpty()) sb.append(", ");
|
||||||
sb.append(user.getUsername());
|
sb.append(user.getUsername());
|
||||||
}
|
}
|
||||||
|
|
||||||
sb.append(topic.getTypingUsersCount() == 1 ? " is" : " are");
|
sb.append(typingUsersCount == 1 ? " is" : " are");
|
||||||
|
|
||||||
sb.append(" writing...");
|
sb.append(" writing...");
|
||||||
|
|
||||||
@ -290,6 +306,3 @@ public class MainChatController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: better mutliline input
|
|
||||||
// 25 + 17 per extra line
|
|
||||||
@ -31,6 +31,7 @@ public class MainController implements Initializable {
|
|||||||
Topic activeTopic = null;
|
Topic activeTopic = null;
|
||||||
Parent activeTopicElement = null;
|
Parent activeTopicElement = null;
|
||||||
private final Map<Long, Pair<Parent, MainChatController>> topicMap = new ConcurrentHashMap<>();
|
private final Map<Long, Pair<Parent, MainChatController>> topicMap = new ConcurrentHashMap<>();
|
||||||
|
private final Map<Long, Thread> topicUpdateThreadMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private VBox vboxRoot;
|
private VBox vboxRoot;
|
||||||
@ -121,6 +122,10 @@ public class MainController implements Initializable {
|
|||||||
for (LongData userID : packet.getUsersJoined()) {
|
for (LongData userID : packet.getUsersJoined()) {
|
||||||
User userJoined = Connection.getInstance().getUser(userID.getValue());
|
User userJoined = Connection.getInstance().getUser(userID.getValue());
|
||||||
topic.addUser(userJoined);
|
topic.addUser(userJoined);
|
||||||
|
|
||||||
|
if (userJoined.getUserID() == Connection.getInstance().getSelf().getUserID()) {
|
||||||
|
pullTopicMessages(topic);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,7 +144,7 @@ public class MainController implements Initializable {
|
|||||||
|
|
||||||
User author = Connection.getInstance().getUser(packet.getAuthorID());
|
User author = Connection.getInstance().getUser(packet.getAuthorID());
|
||||||
|
|
||||||
UserMessage userMessage = new UserMessage(packet.getMessageID(), author, topic, packet.getContents());
|
UserMessage userMessage = new UserMessage(packet.getMessageID(), author, topic, packet.getContents(), packet.getCreatedTimestamp());
|
||||||
|
|
||||||
topic.addMessage(userMessage);
|
topic.addMessage(userMessage);
|
||||||
});
|
});
|
||||||
@ -154,7 +159,7 @@ public class MainController implements Initializable {
|
|||||||
targetUser = Connection.getInstance().getUser(packet.getUserID());
|
targetUser = Connection.getInstance().getUser(packet.getUserID());
|
||||||
}
|
}
|
||||||
|
|
||||||
SystemMessage systemMessage = new SystemMessage(packet.getMessageID(), topic, packet.getSystemType(), targetUser, packet.getContent());
|
SystemMessage systemMessage = new SystemMessage(packet.getMessageID(), topic, packet.getSystemType(), targetUser, packet.getContent(), packet.getCreatedTimestamp());
|
||||||
|
|
||||||
topic.addMessage(systemMessage);
|
topic.addMessage(systemMessage);
|
||||||
});
|
});
|
||||||
@ -178,10 +183,12 @@ public class MainController implements Initializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void fetchTopicMessage(Topic topic, long messageID) {
|
private void fetchTopicMessage(Topic topic, long messageID) {
|
||||||
|
if (topic.hasMessageByID(messageID)) return;
|
||||||
|
|
||||||
MessageFetchPacket messageFetchPacket = new MessageFetchPacket();
|
MessageFetchPacket messageFetchPacket = new MessageFetchPacket();
|
||||||
messageFetchPacket.setMessageID(messageID);
|
messageFetchPacket.setMessageID(messageID);
|
||||||
messageFetchPacket.setTopicID(topic.getId());
|
messageFetchPacket.setTopicID(topic.getId());
|
||||||
Connection.getInstance().sendPacket(messageFetchPacket);
|
Connection.getInstance().sendPacketAuthenticated(messageFetchPacket);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Packet messageFetchResult = Connection.getInstance().nextPacket(MessageDataPacket.TYPE);
|
Packet messageFetchResult = Connection.getInstance().nextPacket(MessageDataPacket.TYPE);
|
||||||
@ -195,7 +202,8 @@ public class MainController implements Initializable {
|
|||||||
messageData.getMessageID(),
|
messageData.getMessageID(),
|
||||||
Connection.getInstance().getUser(messageData.getUserAuthorID()),
|
Connection.getInstance().getUser(messageData.getUserAuthorID()),
|
||||||
Connection.getInstance().getTopic(messageData.getTopicID()),
|
Connection.getInstance().getTopic(messageData.getTopicID()),
|
||||||
messageData.getUserContents()
|
messageData.getUserContents(),
|
||||||
|
messageData.getCreatedTimestamp()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else if (messageData.isSystemMessage()) {
|
else if (messageData.isSystemMessage()) {
|
||||||
@ -204,7 +212,8 @@ public class MainController implements Initializable {
|
|||||||
Connection.getInstance().getTopic(messageData.getTopicID()),
|
Connection.getInstance().getTopic(messageData.getTopicID()),
|
||||||
messageData.getSystemType(),
|
messageData.getSystemType(),
|
||||||
Connection.getInstance().getUser(messageData.getSystemUserID()),
|
Connection.getInstance().getUser(messageData.getSystemUserID()),
|
||||||
messageData.getSystemContents()
|
messageData.getSystemContents(),
|
||||||
|
messageData.getCreatedTimestamp()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,10 +241,6 @@ public class MainController implements Initializable {
|
|||||||
AnchorPane.setRightAnchor(contentPair.first(), 0.0);
|
AnchorPane.setRightAnchor(contentPair.first(), 0.0);
|
||||||
contentPair.first().setVisible(false);
|
contentPair.first().setVisible(false);
|
||||||
|
|
||||||
MessageListFetchPacket messageListFetchPacket = new MessageListFetchPacket();
|
|
||||||
messageListFetchPacket.setTopicID(topic.getId());
|
|
||||||
Connection.getInstance().sendPacket(messageListFetchPacket);
|
|
||||||
|
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> {
|
||||||
paneContent.getChildren().add(contentPair.first());
|
paneContent.getChildren().add(contentPair.first());
|
||||||
|
|
||||||
@ -246,6 +251,16 @@ public class MainController implements Initializable {
|
|||||||
setActiveTopic(topic, pair.first());
|
setActiveTopic(topic, pair.first());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
pullTopicMessages(topic);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void pullTopicMessages(Topic topic) {
|
||||||
|
if (!topic.hasUser(Connection.getInstance().getSelf())) return;
|
||||||
|
|
||||||
|
MessageListFetchPacket messageListFetchPacket = new MessageListFetchPacket();
|
||||||
|
messageListFetchPacket.setTopicID(topic.getId());
|
||||||
|
Connection.getInstance().sendPacketAuthenticated(messageListFetchPacket);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Packet messageListFetchResult = Connection.getInstance().nextPacket(MessageListDataPacket.TYPE);
|
Packet messageListFetchResult = Connection.getInstance().nextPacket(MessageListDataPacket.TYPE);
|
||||||
if (messageListFetchResult == null) return;
|
if (messageListFetchResult == null) return;
|
||||||
@ -259,6 +274,22 @@ public class MainController implements Initializable {
|
|||||||
} catch (SocketException e) {
|
} catch (SocketException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
long topicID = topic.getId();
|
||||||
|
|
||||||
|
Thread thread = new Thread(() -> {
|
||||||
|
while (topicMap.containsKey(topicID)) {
|
||||||
|
topic.updateAllRelativeTimes();
|
||||||
|
|
||||||
|
try {
|
||||||
|
Thread.sleep(30_000);
|
||||||
|
} catch (InterruptedException ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
thread.start();
|
||||||
|
|
||||||
|
topicUpdateThreadMap.put(topicID, thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setActiveTopic(Topic topic, Parent element) {
|
public void setActiveTopic(Topic topic, Parent element) {
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import dev.wiing.gossip.client.generic.Pair;
|
|||||||
import dev.wiing.gossip.client.utils.Utils;
|
import dev.wiing.gossip.client.utils.Utils;
|
||||||
import dev.wiing.gossip.lib.models.UserMessage;
|
import dev.wiing.gossip.lib.models.UserMessage;
|
||||||
import dev.wiing.gossip.lib.models.User;
|
import dev.wiing.gossip.lib.models.User;
|
||||||
|
import javafx.application.Platform;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.fxml.Initializable;
|
import javafx.fxml.Initializable;
|
||||||
import javafx.scene.Parent;
|
import javafx.scene.Parent;
|
||||||
@ -42,6 +43,7 @@ public class MessageItemController implements Initializable {
|
|||||||
@Override
|
@Override
|
||||||
public void initialize(URL location, ResourceBundle resources) {
|
public void initialize(URL location, ResourceBundle resources) {
|
||||||
vboxMessages.getChildren().clear();
|
vboxMessages.getChildren().clear();
|
||||||
|
lblTimeAgo.setText("");
|
||||||
}
|
}
|
||||||
|
|
||||||
public User getAuthor() {
|
public User getAuthor() {
|
||||||
@ -70,6 +72,10 @@ public class MessageItemController implements Initializable {
|
|||||||
this.lblTag.getStyleClass().add("secondary");
|
this.lblTag.getStyleClass().add("secondary");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (userMessages.isEmpty()) {
|
||||||
|
userMessage.attachRelativeTime(data -> Platform.runLater(() -> lblTimeAgo.setText(data)));
|
||||||
|
}
|
||||||
|
|
||||||
userMessages.add(userMessage);
|
userMessages.add(userMessage);
|
||||||
|
|
||||||
Label label = new Label(userMessage.getContents());
|
Label label = new Label(userMessage.getContents());
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package dev.wiing.gossip.client.controllers.item;
|
|||||||
import dev.wiing.gossip.client.generic.Pair;
|
import dev.wiing.gossip.client.generic.Pair;
|
||||||
import dev.wiing.gossip.client.utils.Utils;
|
import dev.wiing.gossip.client.utils.Utils;
|
||||||
import dev.wiing.gossip.lib.models.SystemMessage;
|
import dev.wiing.gossip.lib.models.SystemMessage;
|
||||||
|
import javafx.application.Platform;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
import javafx.scene.Parent;
|
import javafx.scene.Parent;
|
||||||
@ -32,6 +33,9 @@ public class SystemMessageItemController {
|
|||||||
public void setSystemMessage(SystemMessage systemMessage) {
|
public void setSystemMessage(SystemMessage systemMessage) {
|
||||||
this.systemMessage = systemMessage;
|
this.systemMessage = systemMessage;
|
||||||
|
|
||||||
|
lblTimeAgo.setText("");
|
||||||
|
systemMessage.attachRelativeTime(data -> Platform.runLater(() -> this.lblTimeAgo.setText(data)));
|
||||||
|
|
||||||
switch (this.systemMessage.getType()) {
|
switch (this.systemMessage.getType()) {
|
||||||
case SystemMessage.SystemType.USER_JOIN:
|
case SystemMessage.SystemType.USER_JOIN:
|
||||||
removeNode(lblPrefix);
|
removeNode(lblPrefix);
|
||||||
|
|||||||
@ -88,7 +88,7 @@
|
|||||||
<String fx:value="list" />
|
<String fx:value="list" />
|
||||||
</styleClass>
|
</styleClass>
|
||||||
<children>
|
<children>
|
||||||
<TextArea fx:id="txtCompose" maxHeight="1.7976931348623157E308" minHeight="1.0" onKeyPressed="#onKeyPressed" onKeyTyped="#onKeyTyped" prefHeight="25.0" prefRowCount="1" promptText="Compose..." styleClass="transparent" wrapText="true" HBox.hgrow="ALWAYS" />
|
<TextArea fx:id="txtCompose" maxHeight="1.7976931348623157E308" minHeight="25.0" onKeyPressed="#onKeyPressed" onKeyTyped="#onKeyTyped" prefHeight="25.0" prefRowCount="1" promptText="Compose..." styleClass="transparent" wrapText="true" HBox.hgrow="ALWAYS" />
|
||||||
<ImageView fitHeight="20.0" fitWidth="20.0" onMouseClicked="#onSend" opacity="0.5" pickOnBounds="true" preserveRatio="true">
|
<ImageView fitHeight="20.0" fitWidth="20.0" onMouseClicked="#onSend" opacity="0.5" pickOnBounds="true" preserveRatio="true">
|
||||||
<image>
|
<image>
|
||||||
<Image url="@../icons/icon-send-2.png" />
|
<Image url="@../icons/icon-send-2.png" />
|
||||||
|
|||||||
@ -12,6 +12,7 @@ public class PacketManager {
|
|||||||
{
|
{
|
||||||
add(new TestPacket());
|
add(new TestPacket());
|
||||||
add(new AckPacket());
|
add(new AckPacket());
|
||||||
|
add(new ErrorPacket());
|
||||||
|
|
||||||
add(new RegisterRequestPacket());
|
add(new RegisterRequestPacket());
|
||||||
add(new RegisterCredentialsPacket());
|
add(new RegisterCredentialsPacket());
|
||||||
|
|||||||
@ -1,16 +1,25 @@
|
|||||||
package dev.wiing.gossip.lib.models;
|
package dev.wiing.gossip.lib.models;
|
||||||
|
|
||||||
|
import dev.wiing.gossip.lib.models.ext.DynamicProperty;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.time.format.FormatStyle;
|
||||||
|
|
||||||
public class Message {
|
public class Message {
|
||||||
private long id;
|
private long id;
|
||||||
private final Topic topic;
|
private final Topic topic;
|
||||||
private final LocalDateTime postTime;
|
private final LocalDateTime postTime;
|
||||||
|
|
||||||
|
private final DynamicProperty<String> relativeTime;
|
||||||
|
|
||||||
public Message(long id, Topic topic, LocalDateTime postTime) {
|
public Message(long id, Topic topic, LocalDateTime postTime) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.topic = topic;
|
this.topic = topic;
|
||||||
this.postTime = postTime;
|
this.postTime = postTime;
|
||||||
|
|
||||||
|
relativeTime = new DynamicProperty<>("Just now");
|
||||||
}
|
}
|
||||||
|
|
||||||
public Message(long id, Topic topic) {
|
public Message(long id, Topic topic) {
|
||||||
@ -32,4 +41,32 @@ public class Message {
|
|||||||
public LocalDateTime getPostTime() {
|
public LocalDateTime getPostTime() {
|
||||||
return postTime;
|
return postTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void attachRelativeTime(DynamicProperty.ICallback<String> callback) {
|
||||||
|
relativeTime.attach(callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void recalculateRelativeTime(LocalDateTime now) {
|
||||||
|
Duration duration = Duration.between(postTime, now);
|
||||||
|
|
||||||
|
if (duration.toDays() > 7) {
|
||||||
|
relativeTime.setValue(postTime.format(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT, FormatStyle.SHORT)));
|
||||||
|
|
||||||
|
} else if (duration.toDays() > 0) {
|
||||||
|
setRelativeTime("day", duration.toDays());
|
||||||
|
|
||||||
|
} else if (duration.toHours() > 0) {
|
||||||
|
setRelativeTime("hour", duration.toHours());
|
||||||
|
|
||||||
|
} else if (duration.toMinutes() > 0) {
|
||||||
|
setRelativeTime("minute", duration.toMinutes());
|
||||||
|
|
||||||
|
} else {
|
||||||
|
relativeTime.setValue("Just now");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setRelativeTime(String unit, long value) {
|
||||||
|
relativeTime.setValue(value + " " + unit + (value > 1 ? "s" : "") + " ago");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,7 @@ package dev.wiing.gossip.lib.models;
|
|||||||
|
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
import java.beans.PropertyChangeSupport;
|
import java.beans.PropertyChangeSupport;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
@ -97,11 +98,15 @@ public class Topic {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void addMessage(Message message) {
|
public void addMessage(Message message) {
|
||||||
messages.add(message);
|
synchronized (messageByIDs) {
|
||||||
|
if (messageByIDs.containsKey(message.getId())) return;
|
||||||
|
|
||||||
messageByIDs.put(message.getId(), message);
|
messageByIDs.put(message.getId(), message);
|
||||||
|
messages.add(message);
|
||||||
|
|
||||||
this.changeSupport.firePropertyChange("messageAdd", null, message);
|
this.changeSupport.firePropertyChange("messageAdd", null, message);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Set<User> getTypingUsersReadOnly() {
|
public Set<User> getTypingUsersReadOnly() {
|
||||||
return Collections.unmodifiableSet(typingUsers);
|
return Collections.unmodifiableSet(typingUsers);
|
||||||
@ -131,6 +136,10 @@ public class Topic {
|
|||||||
return messageByIDs.getOrDefault(messageID, null);
|
return messageByIDs.getOrDefault(messageID, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasMessageByID(long messageID) {
|
||||||
|
return messageByIDs.containsKey(messageID);
|
||||||
|
}
|
||||||
|
|
||||||
public long getNextMessageID() {
|
public long getNextMessageID() {
|
||||||
return messageTrackerID++;
|
return messageTrackerID++;
|
||||||
}
|
}
|
||||||
@ -142,4 +151,13 @@ public class Topic {
|
|||||||
public void removeChangeListener(PropertyChangeListener listener) {
|
public void removeChangeListener(PropertyChangeListener listener) {
|
||||||
this.changeSupport.removePropertyChangeListener(listener);
|
this.changeSupport.removePropertyChangeListener(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void updateAllRelativeTimes() {
|
||||||
|
synchronized (messages) {
|
||||||
|
for (Message message : messages) {
|
||||||
|
LocalDateTime now = LocalDateTime.now();
|
||||||
|
message.recalculateRelativeTime(now);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
package dev.wiing.gossip.lib.models;
|
package dev.wiing.gossip.lib.models;
|
||||||
|
|
||||||
|
import dev.wiing.gossip.lib.models.ext.DynamicProperty;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
public class UserMessage extends Message {
|
public class UserMessage extends Message {
|
||||||
|
|||||||
@ -0,0 +1,52 @@
|
|||||||
|
package dev.wiing.gossip.lib.models.ext;
|
||||||
|
|
||||||
|
import java.beans.PropertyChangeSupport;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class DynamicProperty<T> {
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface ICallback<T> {
|
||||||
|
void run(T data);
|
||||||
|
}
|
||||||
|
|
||||||
|
private T value;
|
||||||
|
|
||||||
|
private final Set<ICallback<T>> callbacks = Collections.synchronizedSet(new HashSet<>());
|
||||||
|
|
||||||
|
public DynamicProperty(T defaultValue) {
|
||||||
|
this.value = defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(T value) {
|
||||||
|
if (this.value.equals(value)) return;
|
||||||
|
|
||||||
|
this.value = value;
|
||||||
|
|
||||||
|
runCallbacks();
|
||||||
|
}
|
||||||
|
|
||||||
|
public T getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void attach(ICallback<T> callback) {
|
||||||
|
callbacks.add(callback);
|
||||||
|
|
||||||
|
callback.run(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void detach(ICallback<T> callback) {
|
||||||
|
callbacks.remove(callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void runCallbacks() {
|
||||||
|
synchronized (callbacks) {
|
||||||
|
for (ICallback<T> callback : callbacks) {
|
||||||
|
callback.run(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,52 @@
|
|||||||
|
package dev.wiing.gossip.lib.packets;
|
||||||
|
|
||||||
|
import dev.wiing.gossip.lib.data.StringData;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
public class ErrorPacket extends Packet {
|
||||||
|
|
||||||
|
public static short TYPE = 0x03;
|
||||||
|
public static int LENGTH = 0x006;
|
||||||
|
|
||||||
|
private short errorType;
|
||||||
|
private final StringData reason = new StringData();
|
||||||
|
|
||||||
|
public ErrorPacket() {
|
||||||
|
super(TYPE, LENGTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
public short getErrorType() {
|
||||||
|
return errorType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setErrorType(short errorType) {
|
||||||
|
this.errorType = errorType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getReason() {
|
||||||
|
return reason.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReason(String reason) {
|
||||||
|
this.reason.setValue(reason);
|
||||||
|
this.setLength(2 + this.reason.getLength());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Packet readBytes(ByteBuffer buffer, int size) {
|
||||||
|
ErrorPacket packet = new ErrorPacket();
|
||||||
|
packet.setLength(size);
|
||||||
|
|
||||||
|
packet.errorType = buffer.getShort();
|
||||||
|
packet.reason.setBytes(buffer);
|
||||||
|
|
||||||
|
return packet;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeBytes(ByteBuffer buffer) {
|
||||||
|
buffer.putShort(errorType);
|
||||||
|
buffer.put(reason.getBytes());
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -3,15 +3,19 @@ package dev.wiing.gossip.lib.packets;
|
|||||||
import dev.wiing.gossip.lib.data.StringData;
|
import dev.wiing.gossip.lib.data.StringData;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.ZoneOffset;
|
||||||
|
|
||||||
public class MessageCreatedPacket extends Packet {
|
public class MessageCreatedPacket extends Packet {
|
||||||
|
|
||||||
public static final short TYPE = 0x32;
|
public static final short TYPE = 0x32;
|
||||||
public static final int LENGTH = 0x01C;
|
public static final int LENGTH = 0x024;
|
||||||
|
|
||||||
private long messageID;
|
private long messageID;
|
||||||
private long authorID;
|
private long authorID;
|
||||||
private long topicID;
|
private long topicID;
|
||||||
|
private LocalDateTime createdTimestamp;
|
||||||
private final StringData contents = new StringData();
|
private final StringData contents = new StringData();
|
||||||
|
|
||||||
public MessageCreatedPacket() {
|
public MessageCreatedPacket() {
|
||||||
@ -42,13 +46,21 @@ public class MessageCreatedPacket extends Packet {
|
|||||||
this.topicID = topicID;
|
this.topicID = topicID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LocalDateTime getCreatedTimestamp() {
|
||||||
|
return createdTimestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreatedTimestamp(LocalDateTime createdTimestamp) {
|
||||||
|
this.createdTimestamp = createdTimestamp;
|
||||||
|
}
|
||||||
|
|
||||||
public String getContents() {
|
public String getContents() {
|
||||||
return contents.getValue();
|
return contents.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setContents(String contents) {
|
public void setContents(String contents) {
|
||||||
this.contents.setValue(contents);
|
this.contents.setValue(contents);
|
||||||
setLength(24 + this.contents.getLength());
|
setLength(32 + this.contents.getLength());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -59,6 +71,7 @@ public class MessageCreatedPacket extends Packet {
|
|||||||
packet.messageID = buffer.getLong();
|
packet.messageID = buffer.getLong();
|
||||||
packet.authorID = buffer.getLong();
|
packet.authorID = buffer.getLong();
|
||||||
packet.topicID = buffer.getLong();
|
packet.topicID = buffer.getLong();
|
||||||
|
packet.createdTimestamp = LocalDateTime.ofInstant(Instant.ofEpochMilli(buffer.getLong()), ZoneOffset.UTC);
|
||||||
packet.contents.setBytes(buffer);
|
packet.contents.setBytes(buffer);
|
||||||
|
|
||||||
return packet;
|
return packet;
|
||||||
@ -69,6 +82,7 @@ public class MessageCreatedPacket extends Packet {
|
|||||||
buffer.putLong(messageID);
|
buffer.putLong(messageID);
|
||||||
buffer.putLong(authorID);
|
buffer.putLong(authorID);
|
||||||
buffer.putLong(topicID);
|
buffer.putLong(topicID);
|
||||||
|
buffer.putLong(createdTimestamp.toInstant(ZoneOffset.UTC).toEpochMilli());
|
||||||
buffer.put(contents.getBytes());
|
buffer.put(contents.getBytes());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,10 @@ package dev.wiing.gossip.lib.packets;
|
|||||||
import dev.wiing.gossip.lib.data.StringData;
|
import dev.wiing.gossip.lib.data.StringData;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.ZoneId;
|
||||||
|
import java.time.ZoneOffset;
|
||||||
|
|
||||||
public class MessageDataPacket extends Packet {
|
public class MessageDataPacket extends Packet {
|
||||||
|
|
||||||
@ -16,6 +20,7 @@ public class MessageDataPacket extends Packet {
|
|||||||
|
|
||||||
private long messageID;
|
private long messageID;
|
||||||
private long topicID;
|
private long topicID;
|
||||||
|
private LocalDateTime createdTimestamp;
|
||||||
|
|
||||||
private byte messageType;
|
private byte messageType;
|
||||||
|
|
||||||
@ -33,7 +38,7 @@ public class MessageDataPacket extends Packet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updateLength() {
|
private void updateLength() {
|
||||||
setLength(17 +
|
setLength(25 +
|
||||||
(isUserMessage() ? (8 + userContents.getLength()) : 0) +
|
(isUserMessage() ? (8 + userContents.getLength()) : 0) +
|
||||||
(isSystemMessage() ? (16 + systemContents.getLength()) : 0));
|
(isSystemMessage() ? (16 + systemContents.getLength()) : 0));
|
||||||
}
|
}
|
||||||
@ -62,6 +67,14 @@ public class MessageDataPacket extends Packet {
|
|||||||
this.topicID = topicID;
|
this.topicID = topicID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LocalDateTime getCreatedTimestamp() {
|
||||||
|
return createdTimestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreatedTimestamp(LocalDateTime createdTimestamp) {
|
||||||
|
this.createdTimestamp = createdTimestamp;
|
||||||
|
}
|
||||||
|
|
||||||
public byte getMessageType() {
|
public byte getMessageType() {
|
||||||
return messageType;
|
return messageType;
|
||||||
}
|
}
|
||||||
@ -119,6 +132,7 @@ public class MessageDataPacket extends Packet {
|
|||||||
|
|
||||||
packet.messageID = buffer.getLong();
|
packet.messageID = buffer.getLong();
|
||||||
packet.topicID = buffer.getLong();
|
packet.topicID = buffer.getLong();
|
||||||
|
packet.createdTimestamp = LocalDateTime.ofInstant(Instant.ofEpochMilli(buffer.getLong()), ZoneOffset.UTC);
|
||||||
packet.messageType = buffer.get();
|
packet.messageType = buffer.get();
|
||||||
|
|
||||||
if (packet.isUserMessage()) {
|
if (packet.isUserMessage()) {
|
||||||
@ -137,6 +151,7 @@ public class MessageDataPacket extends Packet {
|
|||||||
public void writeBytes(ByteBuffer buffer) {
|
public void writeBytes(ByteBuffer buffer) {
|
||||||
buffer.putLong(messageID);
|
buffer.putLong(messageID);
|
||||||
buffer.putLong(topicID);
|
buffer.putLong(topicID);
|
||||||
|
buffer.putLong(createdTimestamp.toInstant(ZoneOffset.UTC).toEpochMilli());
|
||||||
buffer.put(messageType);
|
buffer.put(messageType);
|
||||||
|
|
||||||
if (isUserMessage()) {
|
if (isUserMessage()) {
|
||||||
|
|||||||
@ -1,11 +1,13 @@
|
|||||||
package dev.wiing.gossip.lib.packets;
|
package dev.wiing.gossip.lib.packets;
|
||||||
|
|
||||||
|
import dev.wiing.gossip.lib.data.AuthSecret;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
public class MessageFetchPacket extends Packet {
|
public class MessageFetchPacket extends AuthRequiredPacket {
|
||||||
|
|
||||||
public static final short TYPE = 0x36;
|
public static final short TYPE = 0x36;
|
||||||
public static final int LENGTH = 0x010;
|
public static final int LENGTH = 0x030;
|
||||||
|
|
||||||
private long topicID;
|
private long topicID;
|
||||||
private long messageID;
|
private long messageID;
|
||||||
@ -34,6 +36,7 @@ public class MessageFetchPacket extends Packet {
|
|||||||
public Packet readBytes(ByteBuffer buffer, int size) {
|
public Packet readBytes(ByteBuffer buffer, int size) {
|
||||||
MessageFetchPacket packet = new MessageFetchPacket();
|
MessageFetchPacket packet = new MessageFetchPacket();
|
||||||
|
|
||||||
|
packet.setAuth(new AuthSecret(buffer));
|
||||||
packet.topicID = buffer.getLong();
|
packet.topicID = buffer.getLong();
|
||||||
packet.messageID = buffer.getLong();
|
packet.messageID = buffer.getLong();
|
||||||
|
|
||||||
@ -42,6 +45,7 @@ public class MessageFetchPacket extends Packet {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeBytes(ByteBuffer buffer) {
|
public void writeBytes(ByteBuffer buffer) {
|
||||||
|
buffer.put(getAuth().getBytes());
|
||||||
buffer.putLong(topicID);
|
buffer.putLong(topicID);
|
||||||
buffer.putLong(messageID);
|
buffer.putLong(messageID);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,11 +1,13 @@
|
|||||||
package dev.wiing.gossip.lib.packets;
|
package dev.wiing.gossip.lib.packets;
|
||||||
|
|
||||||
|
import dev.wiing.gossip.lib.data.AuthSecret;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
public class MessageListFetchPacket extends Packet {
|
public class MessageListFetchPacket extends AuthRequiredPacket {
|
||||||
|
|
||||||
public static final short TYPE = 0x34;
|
public static final short TYPE = 0x34;
|
||||||
public static final int LENGTH = 0x008;
|
public static final int LENGTH = 0x028;
|
||||||
|
|
||||||
private long topicID;
|
private long topicID;
|
||||||
|
|
||||||
@ -25,6 +27,7 @@ public class MessageListFetchPacket extends Packet {
|
|||||||
public Packet readBytes(ByteBuffer buffer, int size) {
|
public Packet readBytes(ByteBuffer buffer, int size) {
|
||||||
MessageListFetchPacket packet = new MessageListFetchPacket();
|
MessageListFetchPacket packet = new MessageListFetchPacket();
|
||||||
|
|
||||||
|
packet.setAuth(new AuthSecret(buffer));
|
||||||
packet.topicID = buffer.getLong();
|
packet.topicID = buffer.getLong();
|
||||||
|
|
||||||
return packet;
|
return packet;
|
||||||
@ -32,6 +35,7 @@ public class MessageListFetchPacket extends Packet {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeBytes(ByteBuffer buffer) {
|
public void writeBytes(ByteBuffer buffer) {
|
||||||
|
buffer.put(getAuth().getBytes());
|
||||||
buffer.putLong(topicID);
|
buffer.putLong(topicID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,15 +3,19 @@ package dev.wiing.gossip.lib.packets;
|
|||||||
import dev.wiing.gossip.lib.data.StringData;
|
import dev.wiing.gossip.lib.data.StringData;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.ZoneOffset;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
public class MessageSystemPacket extends Packet {
|
public class MessageSystemPacket extends Packet {
|
||||||
|
|
||||||
public static final short TYPE = 0x33;
|
public static final short TYPE = 0x33;
|
||||||
public static final int LENGTH = 0x01E;
|
public static final int LENGTH = 0x026;
|
||||||
|
|
||||||
private long messageID;
|
private long messageID;
|
||||||
private long topicID;
|
private long topicID;
|
||||||
|
private LocalDateTime createdTimestamp;
|
||||||
private short systemType = 0;
|
private short systemType = 0;
|
||||||
private long userID = 0;
|
private long userID = 0;
|
||||||
private final StringData content = new StringData();
|
private final StringData content = new StringData();
|
||||||
@ -36,6 +40,14 @@ public class MessageSystemPacket extends Packet {
|
|||||||
this.topicID = topicID;
|
this.topicID = topicID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LocalDateTime getCreatedTimestamp() {
|
||||||
|
return createdTimestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreatedTimestamp(LocalDateTime createdTimestamp) {
|
||||||
|
this.createdTimestamp = createdTimestamp;
|
||||||
|
}
|
||||||
|
|
||||||
public short getSystemType() {
|
public short getSystemType() {
|
||||||
return systemType;
|
return systemType;
|
||||||
}
|
}
|
||||||
@ -58,7 +70,7 @@ public class MessageSystemPacket extends Packet {
|
|||||||
|
|
||||||
public void setContent(String content) {
|
public void setContent(String content) {
|
||||||
this.content.setValue(content);
|
this.content.setValue(content);
|
||||||
setLength(26 + this.content.getLength());
|
setLength(34 + this.content.getLength());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -68,6 +80,7 @@ public class MessageSystemPacket extends Packet {
|
|||||||
|
|
||||||
packet.messageID = buffer.getLong();
|
packet.messageID = buffer.getLong();
|
||||||
packet.topicID = buffer.getLong();
|
packet.topicID = buffer.getLong();
|
||||||
|
packet.createdTimestamp = LocalDateTime.ofInstant(Instant.ofEpochMilli(buffer.getLong()), ZoneOffset.UTC);
|
||||||
packet.systemType = buffer.getShort();
|
packet.systemType = buffer.getShort();
|
||||||
packet.userID = buffer.getLong();
|
packet.userID = buffer.getLong();
|
||||||
packet.content.setBytes(buffer);
|
packet.content.setBytes(buffer);
|
||||||
@ -79,6 +92,7 @@ public class MessageSystemPacket extends Packet {
|
|||||||
public void writeBytes(ByteBuffer buffer) {
|
public void writeBytes(ByteBuffer buffer) {
|
||||||
buffer.putLong(messageID);
|
buffer.putLong(messageID);
|
||||||
buffer.putLong(topicID);
|
buffer.putLong(topicID);
|
||||||
|
buffer.putLong(createdTimestamp.toInstant(ZoneOffset.UTC).toEpochMilli());
|
||||||
buffer.putShort(systemType);
|
buffer.putShort(systemType);
|
||||||
buffer.putLong(userID);
|
buffer.putLong(userID);
|
||||||
buffer.put(content.getBytes());
|
buffer.put(content.getBytes());
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import java.nio.ByteBuffer;
|
|||||||
|
|
||||||
public class RegisterCredentialsPacket extends Packet {
|
public class RegisterCredentialsPacket extends Packet {
|
||||||
|
|
||||||
public static short TYPE = 0x04;
|
public static short TYPE = 0x05;
|
||||||
public static int LENGTH = 0x028;
|
public static int LENGTH = 0x028;
|
||||||
|
|
||||||
private AuthSecret secret;
|
private AuthSecret secret;
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import java.nio.ByteBuffer;
|
|||||||
|
|
||||||
public class RegisterRequestPacket extends Packet {
|
public class RegisterRequestPacket extends Packet {
|
||||||
|
|
||||||
public static final short TYPE = 0x03;
|
public static final short TYPE = 0x04;
|
||||||
public static final int SIZE = 0x0005;
|
public static final int SIZE = 0x0005;
|
||||||
|
|
||||||
private final StringData username = new StringData();
|
private final StringData username = new StringData();
|
||||||
|
|||||||
@ -5,4 +5,5 @@ module dev.wiing.gossip.lib {
|
|||||||
exports dev.wiing.gossip.lib.packets;
|
exports dev.wiing.gossip.lib.packets;
|
||||||
exports dev.wiing.gossip.lib.data;
|
exports dev.wiing.gossip.lib.data;
|
||||||
exports dev.wiing.gossip.lib.models;
|
exports dev.wiing.gossip.lib.models;
|
||||||
|
exports dev.wiing.gossip.lib.models.ext;
|
||||||
}
|
}
|
||||||
@ -89,6 +89,54 @@ public record UserSocket(Socket socket) implements Runnable {
|
|||||||
Database.getInstance().disconnectUser(user);
|
Database.getInstance().disconnectUser(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void replyError(Packet source, String reason) {
|
||||||
|
ErrorPacket packet = new ErrorPacket();
|
||||||
|
packet.setErrorType(source.getType());
|
||||||
|
packet.setReason(reason);
|
||||||
|
|
||||||
|
try {
|
||||||
|
Globals.getPacketManager().replyPacket(source, packet);
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean errorNullTopic(Packet source, Topic topic) {
|
||||||
|
if (topic == null) {
|
||||||
|
replyError(source, "Topic does not exist");
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean errorNullUser(Packet source, User user) {
|
||||||
|
if (user == null) {
|
||||||
|
replyError(source, "User does not exist");
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean errorNullMessage(Packet source, Message message) {
|
||||||
|
if (message == null) {
|
||||||
|
replyError(source, "Message does not exist");
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean errorUserNotInTopic(Packet source, Topic topic, User user) {
|
||||||
|
if (!topic.hasUser(user)) {
|
||||||
|
replyError(source, "User does not have access to Topic");
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private void onRegisterUser(RegisterRequestPacket packet) {
|
private void onRegisterUser(RegisterRequestPacket packet) {
|
||||||
SecretUser user = Database.getInstance().registerUser(packet.getUsername(), packet.getAvatarID(), packet.getSource());
|
SecretUser user = Database.getInstance().registerUser(packet.getUsername(), packet.getAvatarID(), packet.getSource());
|
||||||
|
|
||||||
@ -108,7 +156,7 @@ public record UserSocket(Socket socket) implements Runnable {
|
|||||||
private void onCreateTopic(TopicPushPacket packet) {
|
private void onCreateTopic(TopicPushPacket packet) {
|
||||||
Topic topic = Database.getInstance().createTopic(packet.getAuth(), packet.getTopicName(), packet.getTopicDescription());
|
Topic topic = Database.getInstance().createTopic(packet.getAuth(), packet.getTopicName(), packet.getTopicDescription());
|
||||||
|
|
||||||
if (topic == null) return;
|
if (errorNullTopic(packet, topic)) return;
|
||||||
|
|
||||||
info("\"{}\" created topic \"{}\" (#{})", topic.getHost().getUsername().toUpperCase(), topic.getName().toUpperCase(), topic.getId());
|
info("\"{}\" created topic \"{}\" (#{})", topic.getHost().getUsername().toUpperCase(), topic.getName().toUpperCase(), topic.getId());
|
||||||
|
|
||||||
@ -136,12 +184,12 @@ public record UserSocket(Socket socket) implements Runnable {
|
|||||||
Topic topic = Database.getInstance().getTopic(packet.getTopicID());
|
Topic topic = Database.getInstance().getTopic(packet.getTopicID());
|
||||||
User requester = Database.getInstance().getUserBySecret(packet.getAuth());
|
User requester = Database.getInstance().getUserBySecret(packet.getAuth());
|
||||||
|
|
||||||
if (requester == null) return;
|
if (errorNullUser(packet, requester)) return;
|
||||||
if (topic == null) return;
|
if (errorNullTopic(packet, topic)) return;
|
||||||
|
|
||||||
if (topic.hasUser(requester)) return;
|
if (topic.hasUser(requester)) return;
|
||||||
|
|
||||||
info("\"{}\" joined topic \"{}\" (#{})", topic.getHost().getUsername().toUpperCase(), topic.getName().toUpperCase(), topic.getId());
|
info("\"{}\" joined topic \"{}\" (#{})", requester.getUsername().toUpperCase(), topic.getName().toUpperCase(), topic.getId());
|
||||||
topic.addUser(requester);
|
topic.addUser(requester);
|
||||||
|
|
||||||
SystemMessage message = new SystemMessage(topic.getNextMessageID(), topic, SystemMessage.SystemType.USER_JOIN, requester, "");
|
SystemMessage message = new SystemMessage(topic.getNextMessageID(), topic, SystemMessage.SystemType.USER_JOIN, requester, "");
|
||||||
@ -161,7 +209,9 @@ public record UserSocket(Socket socket) implements Runnable {
|
|||||||
updatePacket.getUsersJoined().add(new LongData().setValue(requester.getUserID()));
|
updatePacket.getUsersJoined().add(new LongData().setValue(requester.getUserID()));
|
||||||
|
|
||||||
MessageSystemPacket systemPacket = new MessageSystemPacket();
|
MessageSystemPacket systemPacket = new MessageSystemPacket();
|
||||||
|
systemPacket.setMessageID(message.getId());
|
||||||
systemPacket.setTopicID(topic.getId());
|
systemPacket.setTopicID(topic.getId());
|
||||||
|
systemPacket.setCreatedTimestamp(message.getPostTime());
|
||||||
systemPacket.setSystemType(message.getType());
|
systemPacket.setSystemType(message.getType());
|
||||||
systemPacket.setUserID(message.getUser().getUserID());
|
systemPacket.setUserID(message.getUser().getUserID());
|
||||||
|
|
||||||
@ -197,7 +247,7 @@ public record UserSocket(Socket socket) implements Runnable {
|
|||||||
private void onFetchTopic(TopicFetchPacket packet) {
|
private void onFetchTopic(TopicFetchPacket packet) {
|
||||||
Topic topic = Database.getInstance().getTopic(packet.getTopicID());
|
Topic topic = Database.getInstance().getTopic(packet.getTopicID());
|
||||||
|
|
||||||
if (topic == null) return;
|
if (errorNullTopic(packet, topic)) return;
|
||||||
|
|
||||||
info("Requested topic #{}", topic.getId());
|
info("Requested topic #{}", topic.getId());
|
||||||
|
|
||||||
@ -221,7 +271,7 @@ public record UserSocket(Socket socket) implements Runnable {
|
|||||||
private void onFetchUser(UserFetchPacket packet) {
|
private void onFetchUser(UserFetchPacket packet) {
|
||||||
User user = Database.getInstance().getUserByID(packet.getUserID());
|
User user = Database.getInstance().getUserByID(packet.getUserID());
|
||||||
|
|
||||||
if (user == null) return;
|
if (errorNullUser(packet, user)) return;
|
||||||
|
|
||||||
info("Requested user #{}", user.getUserID());
|
info("Requested user #{}", user.getUserID());
|
||||||
|
|
||||||
@ -241,8 +291,8 @@ public record UserSocket(Socket socket) implements Runnable {
|
|||||||
Topic topic = Database.getInstance().getTopic(packet.getTopicID());
|
Topic topic = Database.getInstance().getTopic(packet.getTopicID());
|
||||||
User user = Database.getInstance().getUserBySecret(packet.getAuth());
|
User user = Database.getInstance().getUserBySecret(packet.getAuth());
|
||||||
|
|
||||||
if (user == null) return;
|
if (errorNullUser(packet, user)) return;
|
||||||
if (topic == null) return;
|
if (errorNullTopic(packet, topic)) return;
|
||||||
|
|
||||||
UserMessage userMessage = new UserMessage(topic.getNextMessageID(), user, topic, packet.getMessage());
|
UserMessage userMessage = new UserMessage(topic.getNextMessageID(), user, topic, packet.getMessage());
|
||||||
|
|
||||||
@ -260,8 +310,10 @@ public record UserSocket(Socket socket) implements Runnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
MessageCreatedPacket messageCreated = new MessageCreatedPacket();
|
MessageCreatedPacket messageCreated = new MessageCreatedPacket();
|
||||||
|
messageCreated.setMessageID(userMessage.getId());
|
||||||
messageCreated.setAuthorID(user.getUserID());
|
messageCreated.setAuthorID(user.getUserID());
|
||||||
messageCreated.setTopicID(topic.getId());
|
messageCreated.setTopicID(topic.getId());
|
||||||
|
messageCreated.setCreatedTimestamp(userMessage.getPostTime());
|
||||||
messageCreated.setContents(userMessage.getContents());
|
messageCreated.setContents(userMessage.getContents());
|
||||||
|
|
||||||
for (User babbler : topic.getUsersReadOnly().values()) {
|
for (User babbler : topic.getUsersReadOnly().values()) {
|
||||||
@ -279,8 +331,12 @@ public record UserSocket(Socket socket) implements Runnable {
|
|||||||
|
|
||||||
private void onMessageListFetch(MessageListFetchPacket packet) {
|
private void onMessageListFetch(MessageListFetchPacket packet) {
|
||||||
Topic topic = Database.getInstance().getTopic(packet.getTopicID());
|
Topic topic = Database.getInstance().getTopic(packet.getTopicID());
|
||||||
|
User requester = Database.getInstance().getUserBySecret(packet.getAuth());
|
||||||
|
|
||||||
if (topic == null) return;
|
if (errorNullTopic(packet, topic)) return;
|
||||||
|
if (errorNullUser(packet, requester)) return;
|
||||||
|
|
||||||
|
if (errorUserNotInTopic(packet, topic, requester)) return;
|
||||||
|
|
||||||
info("Requested Message list on #{}", topic.getId());
|
info("Requested Message list on #{}", topic.getId());
|
||||||
|
|
||||||
@ -299,18 +355,23 @@ public record UserSocket(Socket socket) implements Runnable {
|
|||||||
|
|
||||||
private void onFetchMessage(MessageFetchPacket packet) {
|
private void onFetchMessage(MessageFetchPacket packet) {
|
||||||
Topic topic = Database.getInstance().getTopic(packet.getTopicID());
|
Topic topic = Database.getInstance().getTopic(packet.getTopicID());
|
||||||
|
User requester = Database.getInstance().getUserBySecret(packet.getAuth());
|
||||||
|
|
||||||
if (topic == null) return;
|
if (errorNullTopic(packet, topic)) return;
|
||||||
|
if (errorNullUser(packet, requester)) return;
|
||||||
|
|
||||||
|
if (errorUserNotInTopic(packet, topic, requester)) return;
|
||||||
|
|
||||||
Message message = topic.getMessageByID(packet.getMessageID());
|
Message message = topic.getMessageByID(packet.getMessageID());
|
||||||
|
|
||||||
if (message == null) return;
|
if (errorNullMessage(packet, message)) return;
|
||||||
|
|
||||||
info("Requested message #{} on #{}", message.getId(), topic.getId());
|
info("Requested message #{} on #{}", message.getId(), topic.getId());
|
||||||
|
|
||||||
MessageDataPacket resp = new MessageDataPacket();
|
MessageDataPacket resp = new MessageDataPacket();
|
||||||
resp.setMessageID(message.getId());
|
resp.setMessageID(message.getId());
|
||||||
resp.setTopicID(message.getTopic().getId());
|
resp.setTopicID(message.getTopic().getId());
|
||||||
|
resp.setCreatedTimestamp(message.getPostTime());
|
||||||
|
|
||||||
if (message instanceof UserMessage userMessage) {
|
if (message instanceof UserMessage userMessage) {
|
||||||
resp.setMessageType(MessageDataPacket.MessageType.USER);
|
resp.setMessageType(MessageDataPacket.MessageType.USER);
|
||||||
@ -335,11 +396,13 @@ public record UserSocket(Socket socket) implements Runnable {
|
|||||||
private void onTypingUser(TypingPingPacket packet) {
|
private void onTypingUser(TypingPingPacket packet) {
|
||||||
User user = Database.getInstance().getUserBySecret(packet.getAuth());
|
User user = Database.getInstance().getUserBySecret(packet.getAuth());
|
||||||
|
|
||||||
if (user == null) return;
|
if (errorNullUser(packet, user)) return;
|
||||||
|
|
||||||
TypingTopic topic = Database.getInstance().getTopic(packet.getTopicID());
|
TypingTopic topic = Database.getInstance().getTopic(packet.getTopicID());
|
||||||
|
|
||||||
if (topic == null || !topic.hasUser(user)) return;
|
if (errorNullTopic(packet, topic)) return;
|
||||||
|
|
||||||
|
if (!topic.hasUser(user)) return;
|
||||||
|
|
||||||
if (packet.isTyping()) {
|
if (packet.isTyping()) {
|
||||||
topic.addTypingUser(user);
|
topic.addTypingUser(user);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user