Skip to content

Commit

Permalink
Merge pull request #9 from Sitrica/beta
Browse files Browse the repository at this point in the history
1.1.4.0
  • Loading branch information
TheLimeGlass authored Sep 7, 2021
2 parents 9aa3624 + 80652e9 commit 841bc3e
Show file tree
Hide file tree
Showing 12 changed files with 115 additions and 145 deletions.
20 changes: 7 additions & 13 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ plugins {

jar.archiveName = project.name + '.jar'
// Add SNAPSHOT to make this publish as a beta.
version '1.1.3'
version '1.1.4.0'

sourceCompatibility = 1.8

Expand All @@ -20,20 +20,20 @@ repositories {
dependencies {

// Google Flogger
shadow (group: 'com.google.flogger', name: 'flogger-system-backend', version: '0.5.1')
shadow (group: 'com.google.flogger', name: 'flogger', version: '0.5.1')
implementation (group: 'com.google.flogger', name: 'flogger-system-backend', version: '0.5.1')
implementation (group: 'com.google.flogger', name: 'flogger', version: '0.5.1')

// Google Gson
shadow (group: 'com.google.code.gson', name: 'gson', version: '2.8.6')
implementation (group: 'com.google.code.gson', name: 'gson', version: '2.8.0')

// Google Guava
shadow (group: 'com.google.guava', name: 'guava', version: '29.0-jre')
implementation (group: 'com.google.guava', name: 'guava', version: '19.0')

// JUnit
testRuntimeOnly (group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.6.0')
testImplementation (group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.6.0')
testImplementation (group: 'com.google.code.gson', name: 'gson', version: '2.8.6')
testImplementation (group: 'com.google.guava', name: 'guava', version: '29.0-jre')
testImplementation (group: 'com.google.code.gson', name: 'gson', version: '2.8.0')
testImplementation (group: 'com.google.guava', name: 'guava', version: '19.0')
testImplementation (group: 'com.google.flogger', name: 'flogger-system-backend', version: '0.5.1')
testImplementation (group: 'com.google.flogger', name: 'flogger', version: '0.5.1')

Expand Down Expand Up @@ -70,19 +70,13 @@ processResources {
}

shadowJar {
configurations = [project.configurations.shadow]
archiveVersion = version
baseName = project.name
classifier = ''
relocate 'com.google.gson', 'com.sitrica.japson.gson'
minimize {
exclude(dependency('com.google.flogger:'))
}
dependencies {
exclude(dependency('org.spigotmc:'))
exclude(dependency('org.yaml:'))
exclude(dependency('io.netty:'))
}
}

test {
Expand Down
37 changes: 12 additions & 25 deletions src/main/java/com/sitrica/japson/client/JapsonClient.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.sitrica.japson.client;

import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
Expand All @@ -22,53 +23,43 @@ public class JapsonClient extends Japson {

protected long HEARTBEAT = 1000L, DELAY = 1000L; // in milliseconds.

protected final InetAddress address;
protected final int port;
protected final InetSocketAddress address;

private boolean check, valid = true;
private final Gson gson;

public JapsonClient(int port) throws UnknownHostException {
this(InetAddress.getLocalHost(), port);
this(new InetSocketAddress(InetAddress.getLocalHost().getHostName(), port));
}

public JapsonClient(String host, int port) throws UnknownHostException {
this(InetAddress.getByName(host), port);
}

public JapsonClient(InetAddress address, int port) {
this(address, port, new GsonBuilder()
public JapsonClient(InetSocketAddress address) {
this(address, new GsonBuilder()
.enableComplexMapKeySerialization()
.serializeNulls()
.setLenient()
.create());
}

public JapsonClient(int port, Gson gson) throws UnknownHostException {
this(InetAddress.getLocalHost(), port, gson);
}

public JapsonClient(String host, int port, Gson gson) throws UnknownHostException {
this(InetAddress.getByName(host), port, gson);
this(new InetSocketAddress(InetAddress.getLocalHost().getHostName(), port), gson);
}

public JapsonClient(InetAddress address, int port, Gson gson) {
public JapsonClient(InetSocketAddress address, Gson gson) {
this.address = address;
this.port = port;
this.gson = gson;
}

public JapsonClient start() {
executor.scheduleAtFixedRate(() -> {
try {
Boolean success = sendPacket(new HeartbeatPacket(password, port));
Boolean success = sendPacket(new HeartbeatPacket(password, address.getPort()));
if (check && success != null && success)
valid = true;
} catch (TimeoutException | InterruptedException | ExecutionException e) {
valid = false;
}
}, DELAY, HEARTBEAT, TimeUnit.MILLISECONDS);
logger.atInfo().log("Started Japson client bound to %s.", address.getHostAddress() + ":" + port);
logger.atInfo().log("Started Japson client bound to %s.", address.getHostName() + ":" + address.getPort());
return this;
}

Expand Down Expand Up @@ -124,14 +115,10 @@ public JapsonClient enableDebug() {
return this;
}

public InetAddress getAddress() {
public InetSocketAddress getAddress() {
return address;
}

public int getPort() {
return port;
}

public void shutdown() {
executor.shutdown();
}
Expand All @@ -143,11 +130,11 @@ public void kill() {
public <T> T sendPacket(ReturnablePacket<T> packet) throws TimeoutException, InterruptedException, ExecutionException {
if (check && !valid && !(packet instanceof HeartbeatPacket))
throw new TimeoutException("No connection to the server. Cancelling sending packet.");
return super.sendPacket(address, port, packet, gson);
return super.sendPacket(address, packet, gson);
}

public void sendPacket(Packet packet) throws InterruptedException, ExecutionException, TimeoutException {
super.sendPacket(address, port, packet, gson);
super.sendPacket(address, packet, gson);
}

}
57 changes: 23 additions & 34 deletions src/main/java/com/sitrica/japson/server/Connections.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
package com.sitrica.japson.server;

import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
Expand All @@ -26,7 +23,6 @@ public class Connections extends Handler {
private final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
private final LoadingCache<InetSocketAddress, JapsonConnection> disconnected;
private final List<JapsonConnection> connections = new ArrayList<>();
private final Set<Listener> listeners = new HashSet<>();
private final JapsonServer japson;

public Connections(JapsonServer japson) {
Expand All @@ -42,79 +38,77 @@ public void onRemoval(RemovalNotification<InetSocketAddress, JapsonConnection> n
// Connection was reacquired.
if (notification.getCause() == RemovalCause.EXPLICIT)
return;
listeners.forEach(listener -> listener.onForget(connection));
japson.getListeners().forEach(listener -> listener.onForget(connection));
}
}).build(new CacheLoader<InetSocketAddress, JapsonConnection>() {
@Override
public JapsonConnection load(InetSocketAddress address) throws Exception {
return getConnection(address.getAddress(), address.getPort())
return getConnection(address)
.orElseGet(() -> {
JapsonConnection created = new JapsonConnection(address.getAddress(), address.getPort());
JapsonConnection created = new JapsonConnection(address);
connections.add(created);
return created;
});
}
});
listeners.addAll(japson.getListeners());
executor.schedule(() -> {
for (JapsonConnection connection : connections) {
if (System.currentTimeMillis() - connection.getLastUpdate() < japson.getTimeout())
continue;
listeners.forEach(listener -> listener.onUnresponsive(connection));
japson.getListeners().forEach(listener -> listener.onUnresponsive(connection));
connection.unresponsive();
if (connection.getUnresponsiveCount() > japson.getMaxReconnectAttempts()) {
listeners.forEach(listener -> listener.onDisconnect(connection));
disconnected.put(InetSocketAddress.createUnresolved(connection.getAddress().getHostName(), connection.getPort()), connection);
japson.getListeners().forEach(listener -> listener.onDisconnect(connection));
disconnected.put(connection.getAddress(), connection);
}
}
connections.removeIf(connection -> connection.getUnresponsiveCount() > japson.getMaxReconnectAttempts());
}, 1, TimeUnit.SECONDS);
}

public JapsonConnection addConnection(InetAddress address, int port) {
return getConnection(address, port)
public JapsonConnection addConnection(InetSocketAddress address) {
return getConnection(address)
.orElseGet(() -> {
JapsonConnection connection = new JapsonConnection(address, port);
listeners.forEach(listener -> listener.onAcquiredCommunication(connection));
JapsonConnection connection = new JapsonConnection(address);
japson.getListeners().forEach(listener -> listener.onAcquiredCommunication(connection));
connections.add(connection);
return connection;
});
}

public Optional<JapsonConnection> getConnection(InetAddress address, int port) {
public Optional<JapsonConnection> getConnection(InetSocketAddress address) {
Optional<JapsonConnection> optional = connections.stream()
.filter(existing -> existing.getAddress().equals(address))
.filter(existing -> existing.getPort() == port)
.findFirst();
if (optional.isPresent())
return optional;
InetSocketAddress socketAddress = InetSocketAddress.createUnresolved(address.getHostName(), port);
optional = Optional.ofNullable(disconnected.getIfPresent(socketAddress));
optional = Optional.ofNullable(disconnected.getIfPresent(address));
if (!optional.isPresent())
return Optional.empty();
JapsonConnection connection = optional.get();
listeners.forEach(listener -> listener.onReacquiredCommunication(connection));
japson.getListeners().forEach(listener -> listener.onReacquiredCommunication(connection));
connections.add(connection);
disconnected.invalidate(socketAddress);
disconnected.invalidate(address);
return optional;
}

@Override
public JsonObject handle(InetAddress address, int packetPort, JsonObject json) {
public JsonObject handle(InetSocketAddress address, JsonObject json) {
int port = json.get("port").getAsInt();
InetSocketAddress server = InetSocketAddress.createUnresolved(address.getHostName(), port);
if (!japson.hasPassword()) {
JapsonConnection connection = addConnection(address, port);
JapsonConnection connection = addConnection(server);
connection.update();
} else {
Optional<JsonElement> optional = Optional.ofNullable(json.get("password"));
if (!optional.isPresent())
return null;
String password = optional.get().getAsString();
if (!japson.passwordMatches(password)) {
japson.getLogger().atWarning().log("A packet from %s did not match the correct password!", address.getHostName());
japson.getLogger().atWarning().log("A packet from %s did not match the correct password!", server.getHostName());
return null;
}
JapsonConnection connection = addConnection(address, port);
JapsonConnection connection = addConnection(server);
connection.update();
}
JsonObject returning = new JsonObject();
Expand All @@ -133,20 +127,18 @@ public void kill() {
public class JapsonConnection {

private long updated = System.currentTimeMillis();
private final InetAddress address;
private final int port;
private final InetSocketAddress address;
private int fails = 0;

public JapsonConnection(InetAddress address, int port) {
public JapsonConnection(InetSocketAddress address) {
this.address = address;
this.port = port;
}

public int getUnresponsiveCount() {
return fails;
}

public InetAddress getAddress() {
public InetSocketAddress getAddress() {
return address;
}

Expand All @@ -158,12 +150,9 @@ public void unresponsive() {
fails++;
}

public int getPort() {
return port;
}

public void update() {
updated = System.currentTimeMillis();
japson.getListeners().forEach(listener -> listener.onHeartbeat(this));
}

}
Expand Down
Loading

0 comments on commit 841bc3e

Please sign in to comment.