Access restrictions, errors & properties
This commit is contained in:
@@ -12,6 +12,7 @@ public class PacketManager {
|
||||
{
|
||||
add(new TestPacket());
|
||||
add(new AckPacket());
|
||||
add(new ErrorPacket());
|
||||
|
||||
add(new RegisterRequestPacket());
|
||||
add(new RegisterCredentialsPacket());
|
||||
|
||||
@@ -1,16 +1,25 @@
|
||||
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.format.DateTimeFormatter;
|
||||
import java.time.format.FormatStyle;
|
||||
|
||||
public class Message {
|
||||
private long id;
|
||||
private final Topic topic;
|
||||
private final LocalDateTime postTime;
|
||||
|
||||
private final DynamicProperty<String> relativeTime;
|
||||
|
||||
public Message(long id, Topic topic, LocalDateTime postTime) {
|
||||
this.id = id;
|
||||
this.topic = topic;
|
||||
this.postTime = postTime;
|
||||
|
||||
relativeTime = new DynamicProperty<>("Just now");
|
||||
}
|
||||
|
||||
public Message(long id, Topic topic) {
|
||||
@@ -32,4 +41,32 @@ public class Message {
|
||||
public LocalDateTime getPostTime() {
|
||||
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.PropertyChangeSupport;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@@ -97,10 +98,14 @@ public class Topic {
|
||||
}
|
||||
|
||||
public void addMessage(Message message) {
|
||||
messages.add(message);
|
||||
messageByIDs.put(message.getId(), message);
|
||||
synchronized (messageByIDs) {
|
||||
if (messageByIDs.containsKey(message.getId())) return;
|
||||
|
||||
this.changeSupport.firePropertyChange("messageAdd", null, message);
|
||||
messageByIDs.put(message.getId(), message);
|
||||
messages.add(message);
|
||||
|
||||
this.changeSupport.firePropertyChange("messageAdd", null, message);
|
||||
}
|
||||
}
|
||||
|
||||
public Set<User> getTypingUsersReadOnly() {
|
||||
@@ -131,6 +136,10 @@ public class Topic {
|
||||
return messageByIDs.getOrDefault(messageID, null);
|
||||
}
|
||||
|
||||
public boolean hasMessageByID(long messageID) {
|
||||
return messageByIDs.containsKey(messageID);
|
||||
}
|
||||
|
||||
public long getNextMessageID() {
|
||||
return messageTrackerID++;
|
||||
}
|
||||
@@ -142,4 +151,13 @@ public class Topic {
|
||||
public void removeChangeListener(PropertyChangeListener 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;
|
||||
|
||||
import dev.wiing.gossip.lib.models.ext.DynamicProperty;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
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 java.nio.ByteBuffer;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneOffset;
|
||||
|
||||
public class MessageCreatedPacket extends Packet {
|
||||
|
||||
public static final short TYPE = 0x32;
|
||||
public static final int LENGTH = 0x01C;
|
||||
public static final int LENGTH = 0x024;
|
||||
|
||||
private long messageID;
|
||||
private long authorID;
|
||||
private long topicID;
|
||||
private LocalDateTime createdTimestamp;
|
||||
private final StringData contents = new StringData();
|
||||
|
||||
public MessageCreatedPacket() {
|
||||
@@ -42,13 +46,21 @@ public class MessageCreatedPacket extends Packet {
|
||||
this.topicID = topicID;
|
||||
}
|
||||
|
||||
public LocalDateTime getCreatedTimestamp() {
|
||||
return createdTimestamp;
|
||||
}
|
||||
|
||||
public void setCreatedTimestamp(LocalDateTime createdTimestamp) {
|
||||
this.createdTimestamp = createdTimestamp;
|
||||
}
|
||||
|
||||
public String getContents() {
|
||||
return contents.getValue();
|
||||
}
|
||||
|
||||
public void setContents(String contents) {
|
||||
this.contents.setValue(contents);
|
||||
setLength(24 + this.contents.getLength());
|
||||
setLength(32 + this.contents.getLength());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -59,6 +71,7 @@ public class MessageCreatedPacket extends Packet {
|
||||
packet.messageID = buffer.getLong();
|
||||
packet.authorID = buffer.getLong();
|
||||
packet.topicID = buffer.getLong();
|
||||
packet.createdTimestamp = LocalDateTime.ofInstant(Instant.ofEpochMilli(buffer.getLong()), ZoneOffset.UTC);
|
||||
packet.contents.setBytes(buffer);
|
||||
|
||||
return packet;
|
||||
@@ -69,6 +82,7 @@ public class MessageCreatedPacket extends Packet {
|
||||
buffer.putLong(messageID);
|
||||
buffer.putLong(authorID);
|
||||
buffer.putLong(topicID);
|
||||
buffer.putLong(createdTimestamp.toInstant(ZoneOffset.UTC).toEpochMilli());
|
||||
buffer.put(contents.getBytes());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,10 @@ package dev.wiing.gossip.lib.packets;
|
||||
import dev.wiing.gossip.lib.data.StringData;
|
||||
|
||||
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 {
|
||||
|
||||
@@ -16,6 +20,7 @@ public class MessageDataPacket extends Packet {
|
||||
|
||||
private long messageID;
|
||||
private long topicID;
|
||||
private LocalDateTime createdTimestamp;
|
||||
|
||||
private byte messageType;
|
||||
|
||||
@@ -33,7 +38,7 @@ public class MessageDataPacket extends Packet {
|
||||
}
|
||||
|
||||
private void updateLength() {
|
||||
setLength(17 +
|
||||
setLength(25 +
|
||||
(isUserMessage() ? (8 + userContents.getLength()) : 0) +
|
||||
(isSystemMessage() ? (16 + systemContents.getLength()) : 0));
|
||||
}
|
||||
@@ -62,6 +67,14 @@ public class MessageDataPacket extends Packet {
|
||||
this.topicID = topicID;
|
||||
}
|
||||
|
||||
public LocalDateTime getCreatedTimestamp() {
|
||||
return createdTimestamp;
|
||||
}
|
||||
|
||||
public void setCreatedTimestamp(LocalDateTime createdTimestamp) {
|
||||
this.createdTimestamp = createdTimestamp;
|
||||
}
|
||||
|
||||
public byte getMessageType() {
|
||||
return messageType;
|
||||
}
|
||||
@@ -119,6 +132,7 @@ public class MessageDataPacket extends Packet {
|
||||
|
||||
packet.messageID = buffer.getLong();
|
||||
packet.topicID = buffer.getLong();
|
||||
packet.createdTimestamp = LocalDateTime.ofInstant(Instant.ofEpochMilli(buffer.getLong()), ZoneOffset.UTC);
|
||||
packet.messageType = buffer.get();
|
||||
|
||||
if (packet.isUserMessage()) {
|
||||
@@ -137,6 +151,7 @@ public class MessageDataPacket extends Packet {
|
||||
public void writeBytes(ByteBuffer buffer) {
|
||||
buffer.putLong(messageID);
|
||||
buffer.putLong(topicID);
|
||||
buffer.putLong(createdTimestamp.toInstant(ZoneOffset.UTC).toEpochMilli());
|
||||
buffer.put(messageType);
|
||||
|
||||
if (isUserMessage()) {
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
package dev.wiing.gossip.lib.packets;
|
||||
|
||||
import dev.wiing.gossip.lib.data.AuthSecret;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class MessageFetchPacket extends Packet {
|
||||
public class MessageFetchPacket extends AuthRequiredPacket {
|
||||
|
||||
public static final short TYPE = 0x36;
|
||||
public static final int LENGTH = 0x010;
|
||||
public static final int LENGTH = 0x030;
|
||||
|
||||
private long topicID;
|
||||
private long messageID;
|
||||
@@ -34,6 +36,7 @@ public class MessageFetchPacket extends Packet {
|
||||
public Packet readBytes(ByteBuffer buffer, int size) {
|
||||
MessageFetchPacket packet = new MessageFetchPacket();
|
||||
|
||||
packet.setAuth(new AuthSecret(buffer));
|
||||
packet.topicID = buffer.getLong();
|
||||
packet.messageID = buffer.getLong();
|
||||
|
||||
@@ -42,6 +45,7 @@ public class MessageFetchPacket extends Packet {
|
||||
|
||||
@Override
|
||||
public void writeBytes(ByteBuffer buffer) {
|
||||
buffer.put(getAuth().getBytes());
|
||||
buffer.putLong(topicID);
|
||||
buffer.putLong(messageID);
|
||||
}
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
package dev.wiing.gossip.lib.packets;
|
||||
|
||||
import dev.wiing.gossip.lib.data.AuthSecret;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class MessageListFetchPacket extends Packet {
|
||||
public class MessageListFetchPacket extends AuthRequiredPacket {
|
||||
|
||||
public static final short TYPE = 0x34;
|
||||
public static final int LENGTH = 0x008;
|
||||
public static final int LENGTH = 0x028;
|
||||
|
||||
private long topicID;
|
||||
|
||||
@@ -25,6 +27,7 @@ public class MessageListFetchPacket extends Packet {
|
||||
public Packet readBytes(ByteBuffer buffer, int size) {
|
||||
MessageListFetchPacket packet = new MessageListFetchPacket();
|
||||
|
||||
packet.setAuth(new AuthSecret(buffer));
|
||||
packet.topicID = buffer.getLong();
|
||||
|
||||
return packet;
|
||||
@@ -32,6 +35,7 @@ public class MessageListFetchPacket extends Packet {
|
||||
|
||||
@Override
|
||||
public void writeBytes(ByteBuffer buffer) {
|
||||
buffer.put(getAuth().getBytes());
|
||||
buffer.putLong(topicID);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,15 +3,19 @@ package dev.wiing.gossip.lib.packets;
|
||||
import dev.wiing.gossip.lib.data.StringData;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneOffset;
|
||||
import java.util.Objects;
|
||||
|
||||
public class MessageSystemPacket extends Packet {
|
||||
|
||||
public static final short TYPE = 0x33;
|
||||
public static final int LENGTH = 0x01E;
|
||||
public static final int LENGTH = 0x026;
|
||||
|
||||
private long messageID;
|
||||
private long topicID;
|
||||
private LocalDateTime createdTimestamp;
|
||||
private short systemType = 0;
|
||||
private long userID = 0;
|
||||
private final StringData content = new StringData();
|
||||
@@ -36,6 +40,14 @@ public class MessageSystemPacket extends Packet {
|
||||
this.topicID = topicID;
|
||||
}
|
||||
|
||||
public LocalDateTime getCreatedTimestamp() {
|
||||
return createdTimestamp;
|
||||
}
|
||||
|
||||
public void setCreatedTimestamp(LocalDateTime createdTimestamp) {
|
||||
this.createdTimestamp = createdTimestamp;
|
||||
}
|
||||
|
||||
public short getSystemType() {
|
||||
return systemType;
|
||||
}
|
||||
@@ -58,7 +70,7 @@ public class MessageSystemPacket extends Packet {
|
||||
|
||||
public void setContent(String content) {
|
||||
this.content.setValue(content);
|
||||
setLength(26 + this.content.getLength());
|
||||
setLength(34 + this.content.getLength());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -68,6 +80,7 @@ public class MessageSystemPacket extends Packet {
|
||||
|
||||
packet.messageID = buffer.getLong();
|
||||
packet.topicID = buffer.getLong();
|
||||
packet.createdTimestamp = LocalDateTime.ofInstant(Instant.ofEpochMilli(buffer.getLong()), ZoneOffset.UTC);
|
||||
packet.systemType = buffer.getShort();
|
||||
packet.userID = buffer.getLong();
|
||||
packet.content.setBytes(buffer);
|
||||
@@ -79,6 +92,7 @@ public class MessageSystemPacket extends Packet {
|
||||
public void writeBytes(ByteBuffer buffer) {
|
||||
buffer.putLong(messageID);
|
||||
buffer.putLong(topicID);
|
||||
buffer.putLong(createdTimestamp.toInstant(ZoneOffset.UTC).toEpochMilli());
|
||||
buffer.putShort(systemType);
|
||||
buffer.putLong(userID);
|
||||
buffer.put(content.getBytes());
|
||||
|
||||
@@ -6,7 +6,7 @@ import java.nio.ByteBuffer;
|
||||
|
||||
public class RegisterCredentialsPacket extends Packet {
|
||||
|
||||
public static short TYPE = 0x04;
|
||||
public static short TYPE = 0x05;
|
||||
public static int LENGTH = 0x028;
|
||||
|
||||
private AuthSecret secret;
|
||||
|
||||
@@ -6,7 +6,7 @@ import java.nio.ByteBuffer;
|
||||
|
||||
public class RegisterRequestPacket extends Packet {
|
||||
|
||||
public static final short TYPE = 0x03;
|
||||
public static final short TYPE = 0x04;
|
||||
public static final int SIZE = 0x0005;
|
||||
|
||||
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.data;
|
||||
exports dev.wiing.gossip.lib.models;
|
||||
exports dev.wiing.gossip.lib.models.ext;
|
||||
}
|
||||
Reference in New Issue
Block a user