aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/de/cowtipper/cowlection/handler
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/de/cowtipper/cowlection/handler')
-rw-r--r--src/main/java/de/cowtipper/cowlection/handler/FriendsHandler.java89
-rw-r--r--src/main/java/de/cowtipper/cowlection/handler/PlayerCache.java5
2 files changed, 79 insertions, 15 deletions
diff --git a/src/main/java/de/cowtipper/cowlection/handler/FriendsHandler.java b/src/main/java/de/cowtipper/cowlection/handler/FriendsHandler.java
index ae1467a..6229e0e 100644
--- a/src/main/java/de/cowtipper/cowlection/handler/FriendsHandler.java
+++ b/src/main/java/de/cowtipper/cowlection/handler/FriendsHandler.java
@@ -2,13 +2,15 @@ package de.cowtipper.cowlection.handler;
import com.google.gson.JsonParseException;
import com.google.gson.reflect.TypeToken;
+import com.mojang.realmsclient.util.Pair;
import de.cowtipper.cowlection.Cowlection;
import de.cowtipper.cowlection.command.exception.ApiContactException;
import de.cowtipper.cowlection.command.exception.MooCommandException;
import de.cowtipper.cowlection.data.Friend;
-import de.cowtipper.cowlection.util.ApiUtils;
-import de.cowtipper.cowlection.util.GsonUtils;
+import de.cowtipper.cowlection.data.HyPlayerData;
+import de.cowtipper.cowlection.util.*;
import io.netty.util.internal.ConcurrentSet;
+import net.minecraft.client.Minecraft;
import net.minecraft.command.PlayerNotFoundException;
import net.minecraft.event.ClickEvent;
import net.minecraft.event.HoverEvent;
@@ -16,14 +18,14 @@ import net.minecraft.util.ChatComponentText;
import net.minecraft.util.ChatStyle;
import net.minecraft.util.EnumChatFormatting;
import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang3.time.DurationFormatUtils;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
-import java.util.Set;
-import java.util.TreeSet;
-import java.util.UUID;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
@@ -33,13 +35,16 @@ public class FriendsHandler {
private final Cowlection main;
private final Set<Friend> bestFriends = new ConcurrentSet<>();
private final File bestFriendsFile;
- private final AtomicInteger bestFriendQueue = new AtomicInteger();
+ private final AtomicInteger bestFriendNameCheckingQueue = new AtomicInteger();
+ private final AtomicInteger bestFriendOnlineStatusQueue = new AtomicInteger();
+ private final Set<String> bestFriendsOnlineStatusWithApiErrors = new ConcurrentSet<>();
+ private long nextBestFriendOnlineCheck = 0;
public FriendsHandler(Cowlection main, File friendsFile) {
this.main = main;
this.bestFriendsFile = friendsFile;
loadBestFriends();
- updateBestFriends();
+ doBestFriendsNameChangeCheck();
}
public boolean isBestFriend(String playerName, boolean ignoreCase) {
@@ -90,15 +95,15 @@ public class FriendsHandler {
return bestFriends.stream().filter(friend -> friend.getUuid().equals(uuid)).findFirst().orElse(Friend.FRIEND_NOT_FOUND);
}
- public void updateBestFriends() {
+ public void doBestFriendsNameChangeCheck() {
bestFriends.stream().filter(friend -> System.currentTimeMillis() - friend.getLastChecked() > UPDATE_FREQUENCY_DEFAULT)
.forEach(friend1 -> {
- bestFriendQueue.incrementAndGet();
- updateBestFriend(friend1, false);
+ bestFriendNameCheckingQueue.incrementAndGet();
+ doBestFriendNameChangeCheck(friend1, false);
});
}
- public void updateBestFriend(Friend friend, boolean isCommandTriggered) {
+ public void doBestFriendNameChangeCheck(Friend friend, boolean isCommandTriggered) {
ApiUtils.fetchCurrentName(friend, newName -> {
if (newName == null) {
// skipping friend, something went wrong with API request
@@ -132,7 +137,7 @@ public class FriendsHandler {
if (isCommandTriggered) {
saveBestFriends();
} else {
- int remainingFriendsToCheck = bestFriendQueue.decrementAndGet();
+ int remainingFriendsToCheck = bestFriendNameCheckingQueue.decrementAndGet();
if (remainingFriendsToCheck == 0) {
// we're done with checking for name changes, save updates to file!
saveBestFriends();
@@ -141,6 +146,66 @@ public class FriendsHandler {
});
}
+ public void runBestFriendsOnlineCheck(boolean isCommandTriggered) {
+ long now = System.currentTimeMillis();
+ int delay = (isCommandTriggered ? 5 : 1) * 60000;
+ if (nextBestFriendOnlineCheck < now) {
+ // ^ prevent too frequent checks
+ nextBestFriendOnlineCheck = now + delay;
+ bestFriendOnlineStatusQueue.set(0);
+ bestFriendsOnlineStatusWithApiErrors.clear();
+ final Map<String, HyPlayerData> onlineBestFriends = new ConcurrentHashMap<>();
+
+ main.getLogger().info("Checking best friends online status... (might take a bit)");
+
+ for (Friend bestFriend : bestFriends) {
+ bestFriendOnlineStatusQueue.incrementAndGet();
+ ApiUtils.fetchHyPlayerDetails(bestFriend, hyPlayerData -> {
+ if (hyPlayerData != null && hyPlayerData.getLastLogin() > hyPlayerData.getLastLogout()) {
+ // online & not hiding their online status
+ main.getPlayerCache().addBestFriend(bestFriend.getName());
+
+ onlineBestFriends.put(bestFriend.getName(), hyPlayerData);
+ }
+
+ int remainingFriendsToCheck = bestFriendOnlineStatusQueue.decrementAndGet();
+ if (remainingFriendsToCheck == 0 && Minecraft.getMinecraft().thePlayer != null) {
+ // we're done with checking for online status
+ MooChatComponent bestFriendsComponent = new MooChatComponent("⬤ Online best friends ("
+ + EnumChatFormatting.DARK_GREEN + onlineBestFriends.size() + EnumChatFormatting.GREEN + "/" + EnumChatFormatting.DARK_GREEN + bestFriends.size() + EnumChatFormatting.GREEN + "): ").green();
+ if (onlineBestFriends.isEmpty()) {
+ bestFriendsComponent.appendText("none...");
+ } else {
+ TreeMap<String, HyPlayerData> onlineBestFriendsSorted = new TreeMap<>(onlineBestFriends);
+ for (Map.Entry<String, HyPlayerData> bestFriendData : onlineBestFriendsSorted.entrySet()) {
+ if (bestFriendsComponent.getSiblings().size() > 0) {
+ bestFriendsComponent.appendSibling(new MooChatComponent(", ").green());
+ }
+ HyPlayerData hyBestFriendData = bestFriendData.getValue();
+ Pair<String, String> lastOnline = Utils.getDurationAsWords(hyBestFriendData.getLastLogin());
+ bestFriendsComponent.appendSibling(new MooChatComponent(bestFriendData.getKey()).darkGreen()
+ .setHover(new MooChatComponent(hyBestFriendData.getLastGame()).yellow().appendFreshSibling(new MooChatComponent("Online for " + (lastOnline.second() != null ? lastOnline.second() : lastOnline.first())).white())));
+ }
+ }
+ if (bestFriendsOnlineStatusWithApiErrors.size() > 0) {
+ String bestFriendsWithApiErrors = String.join(EnumChatFormatting.RED + ", " + EnumChatFormatting.DARK_RED, bestFriendsOnlineStatusWithApiErrors);
+ bestFriendsComponent.appendFreshSibling(new MooChatComponent("Failed to check " + EnumChatFormatting.DARK_RED + bestFriendsOnlineStatusWithApiErrors.size() + EnumChatFormatting.RED + " best friends' online status due to Hypixel API errors: " + EnumChatFormatting.DARK_RED + bestFriendsWithApiErrors).red());
+ bestFriendsOnlineStatusWithApiErrors.clear();
+ }
+ main.getChatHelper().sendMessage(bestFriendsComponent);
+ }
+ });
+ }
+ } else {
+ new TickDelay(() -> main.getChatHelper().sendMessage(EnumChatFormatting.RED, "Couldn't check best friends online status because it has not been long enough since the last check. Next check via " + EnumChatFormatting.WHITE + "/moo online" + EnumChatFormatting.RED + " available in " + DurationFormatUtils.formatDurationWords(nextBestFriendOnlineCheck - System.currentTimeMillis(), true, true))
+ , isCommandTriggered ? 1 : 100);
+ }
+ }
+
+ public void addErroredApiRequest(String playerName) {
+ bestFriendsOnlineStatusWithApiErrors.add(playerName);
+ }
+
public synchronized void saveBestFriends() {
try {
String bestFriendsJsonZoned = GsonUtils.toJson(this.bestFriends);
diff --git a/src/main/java/de/cowtipper/cowlection/handler/PlayerCache.java b/src/main/java/de/cowtipper/cowlection/handler/PlayerCache.java
index 2206473..0092670 100644
--- a/src/main/java/de/cowtipper/cowlection/handler/PlayerCache.java
+++ b/src/main/java/de/cowtipper/cowlection/handler/PlayerCache.java
@@ -6,11 +6,10 @@ import de.cowtipper.cowlection.Cowlection;
import java.util.SortedSet;
import java.util.TreeSet;
+@SuppressWarnings("UnstableApiUsage")
public class PlayerCache {
- @SuppressWarnings("UnstableApiUsage")
private final EvictingQueue<String> nameCache = EvictingQueue.create(50);
- @SuppressWarnings("UnstableApiUsage")
- private final EvictingQueue<String> bestFriendCache = EvictingQueue.create(50);
+ private final EvictingQueue<String> bestFriendCache = EvictingQueue.create(100);
private final Cowlection main;
public PlayerCache(Cowlection main) {