diff --git a/src/main/java/net/frozenorb/apiv3/model/Server.java b/src/main/java/net/frozenorb/apiv3/model/Server.java index a189655..6340425 100644 --- a/src/main/java/net/frozenorb/apiv3/model/Server.java +++ b/src/main/java/net/frozenorb/apiv3/model/Server.java @@ -12,6 +12,7 @@ import fr.javatic.mongo.jacksonCodec.objectId.Id; import lombok.Getter; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.serialization.gson.ExcludeFromReplies; +import net.frozenorb.apiv3.util.TimeUtils; import org.bson.Document; import java.time.Instant; @@ -46,6 +47,7 @@ public final class Server { static { updateCache(); APIv3.getVertxInstance().setPeriodic(TimeUnit.MINUTES.toMillis(1), (id) -> updateCache()); + APIv3.getVertxInstance().setPeriodic(TimeUnit.MINUTES.toMillis(1), (id) -> updateTimedOutServers()); } private static void updateCache() { @@ -66,6 +68,42 @@ public final class Server { }); } + // TODO: This code isn't multi-instance safe AND will send more + // db requests than needed. + private static void updateTimedOutServers() { + for (Server server : serverCache) { + int lastUpdatedAgo = TimeUtils.getSecondsBetween(server.getLastUpdatedAt(), Instant.now()); + + if (lastUpdatedAgo < TimeUnit.SECONDS.toSeconds(30)) { + return; + } + + for (UUID online : server.getPlayers()) { + User.findById(online, (user, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + if (user.leftServer(server)) { + user.save((ignored, error2) -> { + if (error2 != null) { + error2.printStackTrace(); + } + }); + } + }); + } + + server.players = new HashSet<>(); + server.save((ignored, error) -> { + if (error != null) { + error.printStackTrace(); + } + }); + } + } + private Server() {} // For Jackson public Server(String id, String displayName, String apiKey, ServerGroup serverGroup, String serverIp) { diff --git a/src/main/java/net/frozenorb/apiv3/model/User.java b/src/main/java/net/frozenorb/apiv3/model/User.java index 53827b6..3ce90b5 100644 --- a/src/main/java/net/frozenorb/apiv3/model/User.java +++ b/src/main/java/net/frozenorb/apiv3/model/User.java @@ -349,12 +349,16 @@ public final class User { return true; } - public void leftServer(Server server) { + // Returns if any change was actually made. + public boolean leftServer(Server server) { // We have this check to prevent issues where one server's // leave is processed after another server's login. if (server.getId().equals(lastSeenOn)) { this.lastSeenAt = Instant.now(); this.online = false; + return true; + } else { + return false; } }