From f0686a8e45528e3dd682a6f7a69dd904730f6fb1 Mon Sep 17 00:00:00 2001 From: Cow Date: Tue, 21 Apr 2020 16:17:10 +0200 Subject: Improved player stalking feature - offline player now include 'offline since ' --- .../eu/olli/cowmoonication/command/MooCommand.java | 13 +++- .../java/eu/olli/cowmoonication/util/ApiUtils.java | 73 ++++++++++++++-------- .../eu/olli/cowmoonication/util/SlothStalking.java | 25 ++++++++ 3 files changed, 84 insertions(+), 27 deletions(-) create mode 100644 src/main/java/eu/olli/cowmoonication/util/SlothStalking.java (limited to 'src') diff --git a/src/main/java/eu/olli/cowmoonication/command/MooCommand.java b/src/main/java/eu/olli/cowmoonication/command/MooCommand.java index 2ddf7ce..a38eec7 100644 --- a/src/main/java/eu/olli/cowmoonication/command/MooCommand.java +++ b/src/main/java/eu/olli/cowmoonication/command/MooCommand.java @@ -15,6 +15,7 @@ import net.minecraft.command.ICommandSender; import net.minecraft.event.ClickEvent; import net.minecraft.event.HoverEvent; import net.minecraft.util.*; +import org.apache.commons.lang3.time.DurationFormatUtils; import java.awt.*; import java.io.IOException; @@ -175,7 +176,17 @@ public class MooCommand extends CommandBase { + (session.getMode() != null ? ": " + EnumChatFormatting.GOLD + session.getMode() : "") + (session.getMap() != null ? EnumChatFormatting.YELLOW + " (Map: " + EnumChatFormatting.GOLD + session.getMap() + EnumChatFormatting.YELLOW + ")" : "")); } else { - main.getChatHelper().sendMessage(EnumChatFormatting.YELLOW, EnumChatFormatting.GOLD + stalkedPlayer.getName() + EnumChatFormatting.YELLOW + " is currently " + EnumChatFormatting.RED + "offline" + EnumChatFormatting.YELLOW + " (or deactivated API access)."); + ApiUtils.fetchPlayerOfflineStatus(stalkedPlayer, slothStalking -> { + if (slothStalking == null) { + main.getChatHelper().sendMessage(EnumChatFormatting.RED, "Something went wrong contacting the Slothpixel API. Couldn't stalk " + EnumChatFormatting.DARK_RED + stalkedPlayer.getName() + EnumChatFormatting.RED + " but they appear to be offline currently."); + } else if (slothStalking.getLastLogout() < 1) { // last_logout == null in API response + main.getChatHelper().sendMessage(EnumChatFormatting.YELLOW, slothStalking.getPlayerNameFormatted() + EnumChatFormatting.YELLOW + " is hiding their online status."); + } else { + String offlineSince = DurationFormatUtils.formatDurationWords(System.currentTimeMillis() - slothStalking.getLastLogout(), true, true); + + main.getChatHelper().sendMessage(EnumChatFormatting.YELLOW, slothStalking.getPlayerNameFormatted() + EnumChatFormatting.YELLOW + " is " + EnumChatFormatting.GOLD + "offline" + EnumChatFormatting.YELLOW + " since " + EnumChatFormatting.GOLD + offlineSince + EnumChatFormatting.YELLOW + (slothStalking.getLastGame() != null ? " (last played gamemode: " + EnumChatFormatting.GOLD + slothStalking.getLastGame() + EnumChatFormatting.YELLOW + ")" : "") + "."); + } + }); } } else { String cause = (hyStalking != null) ? hyStalking.getCause() : null; diff --git a/src/main/java/eu/olli/cowmoonication/util/ApiUtils.java b/src/main/java/eu/olli/cowmoonication/util/ApiUtils.java index d408721..2a62153 100644 --- a/src/main/java/eu/olli/cowmoonication/util/ApiUtils.java +++ b/src/main/java/eu/olli/cowmoonication/util/ApiUtils.java @@ -24,7 +24,8 @@ public class ApiUtils { public static final String UUID_NOT_FOUND = "UUID-NOT-FOUND"; private static final String NAME_TO_UUID_URL = "https://api.mojang.com/users/profiles/minecraft/"; private static final String UUID_TO_NAME_URL = "https://api.mojang.com/user/profiles/%s/names"; - private static final String STALKING_URL = "https://api.hypixel.net/status?key=%s&uuid=%s"; + private static final String STALKING_URL_OFFICIAL = "https://api.hypixel.net/status?key=%s&uuid=%s"; + private static final String STALKING_URL_UNOFFICIAL = "https://api.slothpixel.me/api/players/%s"; private static ExecutorService pool = Executors.newCachedThreadPool(); private static Gson gson = new GsonBuilder().registerTypeAdapter(UUID.class, new UUIDTypeAdapter()).registerTypeAdapter(Friend.class, new Friend.FriendCreator()).create(); @@ -37,12 +38,11 @@ public class ApiUtils { private static Friend getFriend(String name) { try { - HttpURLConnection connection = (HttpURLConnection) new URL(NAME_TO_UUID_URL + name).openConnection(); - connection.setReadTimeout(5000); - if (connection.getResponseCode() == 204) { + BufferedReader reader = makeApiCall(NAME_TO_UUID_URL + name); + if (reader == null) { return Friend.FRIEND_NOT_FOUND; - } else if (connection.getResponseCode() == 200) { - return gson.fromJson(new BufferedReader(new InputStreamReader(connection.getInputStream())), Friend.class); + } else { + return gson.fromJson(reader, Friend.class); } } catch (IOException e) { e.printStackTrace(); @@ -56,12 +56,11 @@ public class ApiUtils { private static String getCurrentName(Friend friend) { try { - HttpURLConnection connection = (HttpURLConnection) new URL(String.format(UUID_TO_NAME_URL, UUIDTypeAdapter.fromUUID(friend.getUuid()))).openConnection(); - connection.setReadTimeout(5000); - if (connection.getResponseCode() == 204) { + BufferedReader reader = makeApiCall(String.format(UUID_TO_NAME_URL, UUIDTypeAdapter.fromUUID(friend.getUuid()))); + if (reader == null) { return UUID_NOT_FOUND; - } else if (connection.getResponseCode() == 200) { - JsonArray nameHistoryData = new JsonParser().parse(new BufferedReader(new InputStreamReader(connection.getInputStream()))).getAsJsonArray(); + } else { + JsonArray nameHistoryData = new JsonParser().parse(reader).getAsJsonArray(); if (nameHistoryData.size() > 0) { return nameHistoryData.get(nameHistoryData.size() - 1).getAsJsonObject().get("name").getAsString(); } @@ -78,27 +77,49 @@ public class ApiUtils { private static HyStalking stalkPlayer(Friend friend) { try { - HttpURLConnection connection = (HttpURLConnection) new URL(String.format(STALKING_URL, MooConfig.moo, UUIDTypeAdapter.fromUUID(friend.getUuid()))).openConnection(); - connection.setReadTimeout(5000); - connection.addRequestProperty("User-Agent", "Forge Mod " + Cowmoonication.MODNAME + "/" + Cowmoonication.VERSION + " (https://github.com/cow-mc/Cowmoonication/)"); + BufferedReader reader = makeApiCall(String.format(STALKING_URL_OFFICIAL, MooConfig.moo, UUIDTypeAdapter.fromUUID(friend.getUuid()))); + if (reader != null) { + return gson.fromJson(reader, HyStalking.class); + } + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } - connection.getResponseCode(); - if (connection.getResponseCode() == 204) { - return null; - } else { // various possible http status code: 200, 403, 422 - BufferedReader reader; - InputStream errorStream = connection.getErrorStream(); - if (errorStream != null) { - reader = new BufferedReader(new InputStreamReader(errorStream)); - } else { - reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); - } + public static void fetchPlayerOfflineStatus(Friend stalkedPlayer, Consumer action) { + pool.execute(() -> action.accept(stalkOfflinePlayer(stalkedPlayer))); + } - return gson.fromJson(reader, HyStalking.class); + private static SlothStalking stalkOfflinePlayer(Friend stalkedPlayer) { + try { + BufferedReader reader = makeApiCall(String.format(STALKING_URL_UNOFFICIAL, UUIDTypeAdapter.fromUUID(stalkedPlayer.getUuid()))); + if (reader != null) { + return gson.fromJson(reader, SlothStalking.class); } } catch (IOException e) { e.printStackTrace(); } return null; } + + private static BufferedReader makeApiCall(String url) throws IOException { + HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection(); + connection.setReadTimeout(5000); + connection.addRequestProperty("User-Agent", "Forge Mod " + Cowmoonication.MODNAME + "/" + Cowmoonication.VERSION + " (https://github.com/cow-mc/Cowmoonication/)"); + + connection.getResponseCode(); + if (connection.getResponseCode() == 204) { + return null; + } else { + BufferedReader reader; + InputStream errorStream = connection.getErrorStream(); + if (errorStream != null) { + reader = new BufferedReader(new InputStreamReader(errorStream)); + } else { + reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); + } + return reader; + } + } } diff --git a/src/main/java/eu/olli/cowmoonication/util/SlothStalking.java b/src/main/java/eu/olli/cowmoonication/util/SlothStalking.java new file mode 100644 index 0000000..bcd0e01 --- /dev/null +++ b/src/main/java/eu/olli/cowmoonication/util/SlothStalking.java @@ -0,0 +1,25 @@ +package eu.olli.cowmoonication.util; + +public class SlothStalking { + private String username; + private String rank_formatted; + // private boolean online; + // private long last_login; + private long last_logout; + private String last_game; + + public SlothStalking() { + } + + public String getPlayerNameFormatted() { + return rank_formatted.replace('&', 'ยง') + " " + username; + } + + public long getLastLogout() { + return last_logout; + } + + public String getLastGame() { + return last_game; + } +} -- cgit