Gossip Initial
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
package dev.wiing.gossip.lib;
|
||||
|
||||
public final class Config {
|
||||
|
||||
public static int getPort() {
|
||||
String portStr = System.getenv("GOSSIP_PORT");
|
||||
if (portStr != null) {
|
||||
return Integer.parseInt(portStr);
|
||||
}
|
||||
|
||||
return 5601;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package dev.wiing.gossip.lib;
|
||||
|
||||
import dev.wiing.gossip.lib.packets.Packet;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class PacketHandler {
|
||||
|
||||
private final Map<Class<? extends Packet>, Set<PacketListener<? extends Packet>>> listeners = new ConcurrentHashMap<>();
|
||||
|
||||
public <T extends Packet> void addListener(Class<T> type, PacketListener<T> listener) {
|
||||
if (!listeners.containsKey(type)) {
|
||||
listeners.put(type, new HashSet<>());
|
||||
}
|
||||
|
||||
listeners.get(type).add(listener);
|
||||
}
|
||||
|
||||
public <T extends Packet> void removeListener(Class<T> type, PacketListener<T> listener) {
|
||||
if (!listeners.containsKey(type)) {
|
||||
return;
|
||||
}
|
||||
|
||||
listeners.get(type).remove(listener);
|
||||
}
|
||||
|
||||
public <T extends Packet> void runPacket(Class<T> packetClass, T packet) {
|
||||
Set<PacketListener<T>> result = getListeners(packetClass);
|
||||
|
||||
if (result == null) return;
|
||||
|
||||
for (PacketListener<T> packetListener : result) {
|
||||
packetListener.onReceive(packet);
|
||||
}
|
||||
}
|
||||
|
||||
public <T extends Packet> Set<PacketListener<T>> getListeners(Class<T> packetClass) {
|
||||
if (!listeners.containsKey(packetClass))
|
||||
return null;
|
||||
|
||||
return listeners.get(packetClass).stream().map(listener -> {
|
||||
return (PacketListener<T>) listener;
|
||||
}).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package dev.wiing.gossip.lib;
|
||||
|
||||
import dev.wiing.gossip.lib.packets.Packet;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface PacketListener<T extends Packet> {
|
||||
void onReceive(T packet);
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package dev.wiing.gossip.lib;
|
||||
|
||||
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 java.io.*;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class PacketManager {
|
||||
|
||||
private final List<Packet> packetList = new ArrayList<>() {
|
||||
{
|
||||
add(new TestPacket());
|
||||
|
||||
add(new RegisterPacket());
|
||||
add(new CredentialsPacket());
|
||||
}
|
||||
};
|
||||
|
||||
private final Map<Short, Packet> packetMap = new HashMap<>();
|
||||
|
||||
public void addPacket(Packet packet) {
|
||||
packetList.add(packet);
|
||||
}
|
||||
|
||||
public void registerPackets() {
|
||||
packetMap.clear();
|
||||
|
||||
for (Packet packet : packetList) {
|
||||
packetMap.put(packet.getType(), packet);
|
||||
}
|
||||
}
|
||||
|
||||
public Packet readPacket(BufferedInputStream stream) throws IOException {
|
||||
ByteBuffer buffer = ByteBuffer.wrap(stream.readNBytes(6));
|
||||
|
||||
short type = buffer.getShort();
|
||||
int size = buffer.getInt();
|
||||
|
||||
Packet packet = packetMap.getOrDefault(type, null);
|
||||
|
||||
if (packet == null) return null;
|
||||
|
||||
return packet.readBytes(ByteBuffer.wrap(stream.readNBytes(size)), size);
|
||||
}
|
||||
|
||||
public Packet readPacket(InputStream stream) throws IOException {
|
||||
return readPacket(new BufferedInputStream(stream));
|
||||
}
|
||||
|
||||
public void writePacket(BufferedOutputStream stream, Packet packet) throws IOException {
|
||||
ByteBuffer buffer = ByteBuffer.allocate(packet.getTotalLength());
|
||||
|
||||
buffer.putShort(packet.getType());
|
||||
buffer.putInt(packet.getLength());
|
||||
|
||||
packet.writeBytes(buffer);
|
||||
|
||||
stream.write(buffer.array());
|
||||
stream.flush();
|
||||
}
|
||||
|
||||
public void writePacket(OutputStream stream, Packet packet) throws IOException {
|
||||
BufferedOutputStream outputStream = new BufferedOutputStream(stream);
|
||||
writePacket(outputStream, packet);
|
||||
outputStream.flush();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package dev.wiing.gossip.lib.data;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public interface DataType<T> {
|
||||
|
||||
T getValue();
|
||||
void setValue(T val);
|
||||
|
||||
int getLength();
|
||||
|
||||
ByteBuffer getBytes();
|
||||
void setBytes(ByteBuffer buffer);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package dev.wiing.gossip.lib.data;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
public class StringType implements DataType<String> {
|
||||
|
||||
private String value;
|
||||
|
||||
@Override
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(String val) {
|
||||
this.value = val;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLength() {
|
||||
return 4 + this.value.length();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer getBytes() {
|
||||
ByteBuffer out = ByteBuffer.allocate(getLength());
|
||||
|
||||
out.putInt(this.value.length());
|
||||
out.put(getValue().getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
return out.rewind();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBytes(ByteBuffer buffer) {
|
||||
int size = buffer.getInt();
|
||||
|
||||
byte[] b = new byte[size];
|
||||
buffer.get(b);
|
||||
|
||||
setValue(new String(b, StandardCharsets.UTF_8));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package dev.wiing.gossip.lib.models;
|
||||
|
||||
public class SecretUser extends User {
|
||||
private final byte[] userSecret;
|
||||
|
||||
public SecretUser(String username, int iconID, long userID, byte[] userSecret) {
|
||||
super(username, iconID, userID);
|
||||
this.userSecret = userSecret;
|
||||
}
|
||||
|
||||
public byte[] getUserSecret() {
|
||||
return userSecret;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package dev.wiing.gossip.lib.models;
|
||||
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
|
||||
public class User {
|
||||
private final PropertyChangeSupport change;
|
||||
|
||||
private String username;
|
||||
private int iconID;
|
||||
private long userID;
|
||||
|
||||
public User(String username, int iconID, long userID) {
|
||||
this.username = username;
|
||||
this.iconID = iconID;
|
||||
this.userID = userID;
|
||||
|
||||
this.change = new PropertyChangeSupport(this);
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
String previous = this.username;
|
||||
this.username = username;
|
||||
change.firePropertyChange("username", previous, username);
|
||||
}
|
||||
|
||||
public int getIconID() {
|
||||
return iconID;
|
||||
}
|
||||
|
||||
public void setIconID(int iconID) {
|
||||
int previous = this.iconID;
|
||||
this.iconID = iconID;
|
||||
change.firePropertyChange("iconID", previous, iconID);
|
||||
}
|
||||
|
||||
public long getUserID() {
|
||||
return userID;
|
||||
}
|
||||
|
||||
public void setUserID(long userID) {
|
||||
long previous = this.userID;
|
||||
this.userID = userID;
|
||||
change.firePropertyChange("userID", previous, userID);
|
||||
}
|
||||
|
||||
public void addPropertyListener(PropertyChangeListener listener) {
|
||||
change.addPropertyChangeListener(listener);
|
||||
}
|
||||
|
||||
public void removePropertyListener(PropertyChangeListener listener) {
|
||||
change.removePropertyChangeListener(listener);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package dev.wiing.gossip.lib.packets;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class CredentialsPacket extends Packet {
|
||||
|
||||
public static short TYPE = 0x03;
|
||||
public static int LENGTH = 0x028;
|
||||
|
||||
private byte[] secret = new byte[32];
|
||||
private long uID;
|
||||
|
||||
public CredentialsPacket() {
|
||||
super(TYPE, LENGTH);
|
||||
}
|
||||
|
||||
public byte[] getSecret() {
|
||||
return secret;
|
||||
}
|
||||
|
||||
public void setSecret(byte[] secret) {
|
||||
this.secret = secret;
|
||||
}
|
||||
|
||||
public long getUID() {
|
||||
return uID;
|
||||
}
|
||||
|
||||
public void setUID(long uID) {
|
||||
this.uID = uID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Packet readBytes(ByteBuffer buffer, int size) {
|
||||
CredentialsPacket packet = new CredentialsPacket();
|
||||
|
||||
buffer.get(packet.secret);
|
||||
packet.setUID(buffer.getLong());
|
||||
|
||||
return packet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeBytes(ByteBuffer buffer) {
|
||||
buffer.put(getSecret());
|
||||
buffer.putLong(getUID());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package dev.wiing.gossip.lib.packets;
|
||||
|
||||
import java.net.Socket;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public abstract class Packet {
|
||||
|
||||
private final short type;
|
||||
private int length;
|
||||
|
||||
private Socket source;
|
||||
|
||||
public Packet(short type, int length) {
|
||||
this.type = type;
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
public Socket getSource() {
|
||||
return source;
|
||||
}
|
||||
|
||||
public void setSource(Socket source) {
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
public short getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public int getTotalLength() {
|
||||
return 6 + getLength();
|
||||
}
|
||||
|
||||
public int getLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
protected void setLength(int length) {
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
public abstract Packet readBytes(ByteBuffer buffer, int size);
|
||||
|
||||
public abstract void writeBytes(ByteBuffer buffer);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package dev.wiing.gossip.lib.packets;
|
||||
|
||||
import dev.wiing.gossip.lib.data.StringType;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class RegisterPacket extends Packet {
|
||||
|
||||
public static final short TYPE = 0x02;
|
||||
public static final int SIZE = 0x0001;
|
||||
|
||||
private final StringType username = new StringType();
|
||||
private char iconID;
|
||||
|
||||
public RegisterPacket() {
|
||||
super(TYPE, SIZE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Packet readBytes(ByteBuffer buffer, int size) {
|
||||
RegisterPacket packet = new RegisterPacket();
|
||||
packet.setLength(size);
|
||||
|
||||
packet.username.setBytes(buffer);
|
||||
|
||||
return packet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeBytes(ByteBuffer buffer) {
|
||||
buffer.put(username.getBytes());
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username.getValue();
|
||||
}
|
||||
|
||||
public RegisterPacket setUsername(String username) {
|
||||
this.username.setValue(username);
|
||||
this.setLength(1 + this.username.getLength());
|
||||
return this;
|
||||
}
|
||||
|
||||
public char getIconID() {
|
||||
return iconID;
|
||||
}
|
||||
|
||||
public RegisterPacket setIconID(char iconID) {
|
||||
this.iconID = iconID;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package dev.wiing.gossip.lib.packets;
|
||||
|
||||
import dev.wiing.gossip.lib.data.StringType;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class TestPacket extends Packet {
|
||||
|
||||
public static final short TYPE = 0x01;
|
||||
public static final int SIZE = 0x0000;
|
||||
|
||||
private final StringType message = new StringType();
|
||||
|
||||
public TestPacket() {
|
||||
super(TYPE, SIZE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Packet readBytes(ByteBuffer buffer, int size) {
|
||||
TestPacket packet = new TestPacket();
|
||||
packet.setLength(size);
|
||||
|
||||
packet.message.setBytes(buffer);
|
||||
|
||||
return packet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeBytes(ByteBuffer buffer) {
|
||||
buffer.put(message.getBytes());
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message.getValue();
|
||||
}
|
||||
|
||||
public TestPacket setMessage(String message) {
|
||||
this.message.setValue(message);
|
||||
this.setLength(this.message.getLength());
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
module dev.wiing.gossip.lib {
|
||||
requires java.desktop;
|
||||
|
||||
exports dev.wiing.gossip.lib;
|
||||
exports dev.wiing.gossip.lib.packets;
|
||||
exports dev.wiing.gossip.lib.data;
|
||||
exports dev.wiing.gossip.lib.models;
|
||||
}
|
||||
Reference in New Issue
Block a user