From c26e5835b7aef1c5e765589d837d94f71e04d7eb Mon Sep 17 00:00:00 2001 From: ajgeiss0702 Date: Sat, 27 May 2023 18:14:28 -0700 Subject: [PATCH] Added Spigot-side API --- api/build.gradle.kts | 1 + .../java/us/ajg0702/queue/api/AjQueueAPI.java | 7 +- .../queue/api/communication/ComResponse.java | 86 ++++++++++ .../queue/api/spigot/AjQueueSpigotAPI.java | 84 ++++++++++ .../queue/api/spigot/MessagedResponse.java | 36 ++++ .../queue/common/EventHandlerImpl.java | 123 +------------- .../communication/CommunicationManager.java | 69 ++++++++ .../common/communication/MessageHandler.java | 15 ++ .../communication/handlers/AckHandler.java | 19 +++ .../handlers/EstimatedTimeHandler.java | 39 +++++ .../handlers/InQueueHandler.java | 23 +++ .../handlers/LeaveQueueHandler.java | 25 +++ .../handlers/MassQueueHandler.java | 33 ++++ .../handlers/PlayerStatusHandler.java | 33 ++++ .../handlers/PositionHandler.java | 31 ++++ .../handlers/PositionOfHandler.java | 32 ++++ .../communication/handlers/QueueHandler.java | 25 +++ .../handlers/QueueNameHandler.java | 31 ++++ .../handlers/QueuedForHandler.java | 29 ++++ .../communication/handlers/StatusHandler.java | 32 ++++ .../queue/common/utils/MapBuilder.java | 12 ++ .../platforms/bungeecord/BungeeMethods.java | 1 - .../platforms/velocity/VelocityMethods.java | 1 - spigot/build.gradle.kts | 1 + .../us/ajg0702/queue/spigot/SpigotMain.java | 111 +++---------- .../ajg0702/queue/spigot/api/SpigotAPI.java | 157 ++++++++++++++++++ .../spigot/communication/ResponseKey.java | 34 ++++ .../spigot/communication/ResponseManager.java | 31 ++++ .../placeholders/CachedPlaceholder.java | 21 +++ .../spigot/placeholders/Placeholder.java | 32 ++++ .../placeholders/PlaceholderExpansion.java | 88 ++++++++++ .../placeholders/EstimatedTime.java | 55 ++++++ .../placeholders/placeholders/InQueue.java | 54 ++++++ .../placeholders/placeholders/Position.java | 55 ++++++ .../placeholders/placeholders/PositionOf.java | 55 ++++++ .../placeholders/placeholders/Queued.java | 55 ++++++ .../placeholders/placeholders/QueuedFor.java | 62 +++++++ .../placeholders/placeholders/Status.java | 62 +++++++ 38 files changed, 1454 insertions(+), 206 deletions(-) create mode 100644 api/src/main/java/us/ajg0702/queue/api/communication/ComResponse.java create mode 100644 api/src/main/java/us/ajg0702/queue/api/spigot/AjQueueSpigotAPI.java create mode 100644 api/src/main/java/us/ajg0702/queue/api/spigot/MessagedResponse.java create mode 100644 common/src/main/java/us/ajg0702/queue/common/communication/CommunicationManager.java create mode 100644 common/src/main/java/us/ajg0702/queue/common/communication/MessageHandler.java create mode 100644 common/src/main/java/us/ajg0702/queue/common/communication/handlers/AckHandler.java create mode 100644 common/src/main/java/us/ajg0702/queue/common/communication/handlers/EstimatedTimeHandler.java create mode 100644 common/src/main/java/us/ajg0702/queue/common/communication/handlers/InQueueHandler.java create mode 100644 common/src/main/java/us/ajg0702/queue/common/communication/handlers/LeaveQueueHandler.java create mode 100644 common/src/main/java/us/ajg0702/queue/common/communication/handlers/MassQueueHandler.java create mode 100644 common/src/main/java/us/ajg0702/queue/common/communication/handlers/PlayerStatusHandler.java create mode 100644 common/src/main/java/us/ajg0702/queue/common/communication/handlers/PositionHandler.java create mode 100644 common/src/main/java/us/ajg0702/queue/common/communication/handlers/PositionOfHandler.java create mode 100644 common/src/main/java/us/ajg0702/queue/common/communication/handlers/QueueHandler.java create mode 100644 common/src/main/java/us/ajg0702/queue/common/communication/handlers/QueueNameHandler.java create mode 100644 common/src/main/java/us/ajg0702/queue/common/communication/handlers/QueuedForHandler.java create mode 100644 common/src/main/java/us/ajg0702/queue/common/communication/handlers/StatusHandler.java create mode 100644 common/src/main/java/us/ajg0702/queue/common/utils/MapBuilder.java create mode 100644 spigot/src/main/java/us/ajg0702/queue/spigot/api/SpigotAPI.java create mode 100644 spigot/src/main/java/us/ajg0702/queue/spigot/communication/ResponseKey.java create mode 100644 spigot/src/main/java/us/ajg0702/queue/spigot/communication/ResponseManager.java create mode 100644 spigot/src/main/java/us/ajg0702/queue/spigot/placeholders/CachedPlaceholder.java create mode 100644 spigot/src/main/java/us/ajg0702/queue/spigot/placeholders/Placeholder.java create mode 100644 spigot/src/main/java/us/ajg0702/queue/spigot/placeholders/PlaceholderExpansion.java create mode 100644 spigot/src/main/java/us/ajg0702/queue/spigot/placeholders/placeholders/EstimatedTime.java create mode 100644 spigot/src/main/java/us/ajg0702/queue/spigot/placeholders/placeholders/InQueue.java create mode 100644 spigot/src/main/java/us/ajg0702/queue/spigot/placeholders/placeholders/Position.java create mode 100644 spigot/src/main/java/us/ajg0702/queue/spigot/placeholders/placeholders/PositionOf.java create mode 100644 spigot/src/main/java/us/ajg0702/queue/spigot/placeholders/placeholders/Queued.java create mode 100644 spigot/src/main/java/us/ajg0702/queue/spigot/placeholders/placeholders/QueuedFor.java create mode 100644 spigot/src/main/java/us/ajg0702/queue/spigot/placeholders/placeholders/Status.java diff --git a/api/build.gradle.kts b/api/build.gradle.kts index 89724a8..71cfb61 100644 --- a/api/build.gradle.kts +++ b/api/build.gradle.kts @@ -16,6 +16,7 @@ repositories { dependencies { implementation("net.kyori:adventure-api:4.13.1") implementation("net.kyori:adventure-text-serializer-plain:4.13.1") + implementation("com.google.code.gson:gson:2.10.1") compileOnly("com.google.guava:guava:30.1.1-jre") compileOnly("us.ajg0702:ajUtils:1.2.10") diff --git a/api/src/main/java/us/ajg0702/queue/api/AjQueueAPI.java b/api/src/main/java/us/ajg0702/queue/api/AjQueueAPI.java index 2f54b52..dd3aea5 100644 --- a/api/src/main/java/us/ajg0702/queue/api/AjQueueAPI.java +++ b/api/src/main/java/us/ajg0702/queue/api/AjQueueAPI.java @@ -2,6 +2,7 @@ package us.ajg0702.queue.api; import us.ajg0702.queue.api.premium.Logic; import us.ajg0702.queue.api.premium.LogicGetter; +import us.ajg0702.queue.api.spigot.AjQueueSpigotAPI; import us.ajg0702.queue.api.util.QueueLogger; import us.ajg0702.utils.common.Config; import us.ajg0702.utils.common.Messages; @@ -11,6 +12,7 @@ import java.util.concurrent.ExecutorService; public abstract class AjQueueAPI { public static AjQueueAPI INSTANCE; + public static AjQueueSpigotAPI SPIGOT_INSTANCE; /** * Gets the instance of the ajQueue API @@ -21,6 +23,10 @@ public abstract class AjQueueAPI { return INSTANCE; } + public static AjQueueSpigotAPI getSpigotInstance() { + return SPIGOT_INSTANCE; + } + /** * Gets the time that ajQueue will wait between sending players. In seconds @@ -79,7 +85,6 @@ public abstract class AjQueueAPI { /** * Gets the event handler. - * * This class will probably be replaced in the future with an actual event system * @return the EventHandler */ diff --git a/api/src/main/java/us/ajg0702/queue/api/communication/ComResponse.java b/api/src/main/java/us/ajg0702/queue/api/communication/ComResponse.java new file mode 100644 index 0000000..bcdd5bb --- /dev/null +++ b/api/src/main/java/us/ajg0702/queue/api/communication/ComResponse.java @@ -0,0 +1,86 @@ +package us.ajg0702.queue.api.communication; + +import com.google.common.io.ByteArrayDataInput; + +import java.util.UUID; + +public class ComResponse { + private String from; + private String response; + private String identifier; + private String noneMessage; + + private ComResponse(String from, String response) { + this.from = from; + this.response = response; + } + + public static ComResponse from(String from) { + return new ComResponse(from, null); + } + public static ComResponse from(String from, ByteArrayDataInput in) { + String id = in.readUTF(); + String response = in.readUTF(); + String noneMessage = in.readUTF(); + + if(id.equalsIgnoreCase("null")) id = null; + if(response.equalsIgnoreCase("null")) response = null; + if(noneMessage.equalsIgnoreCase("null")) noneMessage = null; + + return from(from) + .id(id) + .with(response) + .noneMessage(noneMessage); + } + public ComResponse id(String id) { + this.identifier = id; + return this; + } + public ComResponse id(UUID id) { + this.identifier = String.valueOf(id); + return this; + } + public ComResponse with(String response) { + this.response = response; + return this; + } + public ComResponse with(boolean response) { + this.response = String.valueOf(response); + return this; + } + public ComResponse with(Integer response) { + this.response = String.valueOf(response); + return this; + } + + public ComResponse noneMessage(String message) { + this.noneMessage = message; + return this; + } + + public String getIdentifier() { + return identifier; + } + + public String getFrom() { + return from; + } + + public String getNoneMessage() { + return noneMessage; + } + + public String getResponse() { + return response; + } + + @Override + public String toString() { + return "ComResponse{" + + "from='" + from + '\'' + + ", response='" + response + '\'' + + ", identifier='" + identifier + '\'' + + ", noneMessage='" + noneMessage + '\'' + + '}'; + } +} diff --git a/api/src/main/java/us/ajg0702/queue/api/spigot/AjQueueSpigotAPI.java b/api/src/main/java/us/ajg0702/queue/api/spigot/AjQueueSpigotAPI.java new file mode 100644 index 0000000..2c191fa --- /dev/null +++ b/api/src/main/java/us/ajg0702/queue/api/spigot/AjQueueSpigotAPI.java @@ -0,0 +1,84 @@ +package us.ajg0702.queue.api.spigot; + +import java.util.UUID; +import java.util.concurrent.Future; + +/** + * An API that is usable from the spigot-side + */ +public abstract class AjQueueSpigotAPI { + + public static AjQueueSpigotAPI INSTANCE; + + /** + * Gets the instance of the ajQueue spigot API + * @return the ajQueue API + */ + @SuppressWarnings("unused") + public static AjQueueSpigotAPI getInstance() { + return INSTANCE; + } + + public abstract Future isInQueue(UUID player); + + /** + * Adds a player to a queue + * @param player The player to be added + * @param queueName The server or group to add the player to + * @return True if adding was successful, false if not. + */ + public abstract Future addToQueue(UUID player, String queueName); + + /** + * Gets the name of the queue that the player is in + * @param player the player + * @return the name of the queue that the player is in + */ + public abstract Future> getQueueName(UUID player); + + /** + * Gets the position of the player in their queue + * @param player The player + * @return The position of the player in their queue + */ + public abstract Future> getPosition(UUID player); + + /** + * Gets the total number of players who are in queue with the player + * @param player The player + * @return The number of player in the queue that the player is in. + */ + public abstract Future> getTotalPositions(UUID player); + + /** + * Gets the number of players in a specific queue + * @param queueName The name of the queue + * @return The number of players in that queue. + */ + public abstract Future getPlayersInQueue(String queueName); + + /** + * Gets the status string for the queue specified (e.g. full, restarting, etc) + * This is the display status, which is meant to be shown to players (and is pulled from the messages file) + * @param queueName the name of the queue + * @return The status string for the queue you specified. + */ + public abstract Future getServerStatusString(String queueName); + + /** + * Gets the status string for the queue specified (e.g. full, restarting, etc) + * This is the display status, which is meant to be shown to players (and is pulled from the messages file) + * @param queueName the name of the queue + * @param player the player to check with + * @return The status string for the queue you specified. + */ + public abstract Future getServerStatusString(String queueName, UUID player); + + /** + * Gets the estimated time until the player is sent to the server + * @param player The player to get + * @return The estimated time until the player is sent to the server + */ + public abstract Future> getEstimatedTime(UUID player); + +} diff --git a/api/src/main/java/us/ajg0702/queue/api/spigot/MessagedResponse.java b/api/src/main/java/us/ajg0702/queue/api/spigot/MessagedResponse.java new file mode 100644 index 0000000..ff4489f --- /dev/null +++ b/api/src/main/java/us/ajg0702/queue/api/spigot/MessagedResponse.java @@ -0,0 +1,36 @@ +package us.ajg0702.queue.api.spigot; + +public class MessagedResponse { + private final T response; + private final String none; + + public MessagedResponse(T response, String none) { + this.response = response; + this.none = none; + } + + /** + * Gets the response from the method. + * @return The response. Null if there is a "none" message + */ + public T getResponse() { + return response; + } + + /** + * Gets the "none" message + * @return The none message. null if there is a response. + */ + public String getNone() { + return none; + } + + /** + * Gets either the response (as a string) or the none message, whichever is available + * @return A string + */ + public String getEither() { + if(response == null) return none; + return String.valueOf(response); + } +} diff --git a/common/src/main/java/us/ajg0702/queue/common/EventHandlerImpl.java b/common/src/main/java/us/ajg0702/queue/common/EventHandlerImpl.java index b6860d4..cde11a5 100644 --- a/common/src/main/java/us/ajg0702/queue/common/EventHandlerImpl.java +++ b/common/src/main/java/us/ajg0702/queue/common/EventHandlerImpl.java @@ -5,20 +5,16 @@ import net.kyori.adventure.text.Component; import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; import org.jetbrains.annotations.NotNull; import us.ajg0702.queue.api.EventHandler; -import us.ajg0702.queue.api.commands.IBaseCommand; import us.ajg0702.queue.api.players.AdaptedPlayer; import us.ajg0702.queue.api.players.QueuePlayer; import us.ajg0702.queue.api.queues.QueueServer; import us.ajg0702.queue.api.server.AdaptedServer; -import us.ajg0702.queue.commands.commands.PlayerSender; import us.ajg0702.queue.commands.commands.manage.PauseQueueServer; import us.ajg0702.queue.commands.commands.queue.QueueCommand; +import us.ajg0702.queue.common.communication.CommunicationManager; import us.ajg0702.queue.common.players.QueuePlayerImpl; import us.ajg0702.queue.common.utils.Debug; -import us.ajg0702.utils.common.TimeUtils; -import java.io.ByteArrayInputStream; -import java.io.DataInputStream; import java.io.IOException; import java.util.List; import java.util.concurrent.TimeUnit; @@ -26,121 +22,20 @@ import java.util.concurrent.TimeUnit; public class EventHandlerImpl implements EventHandler { final QueueMain main; + CommunicationManager communicationManager; public EventHandlerImpl(QueueMain main) { this.main = main; } @Override - public void handleMessage(AdaptedPlayer recievingPlayer, byte[] data) { - IBaseCommand moveCommand = main.getPlatformMethods().getCommands().get(0); - IBaseCommand leaveCommand = main.getPlatformMethods().getCommands().get(1); - DataInputStream in = new DataInputStream(new ByteArrayInputStream(data)); + public void handleMessage(AdaptedPlayer receivingPlayer, byte[] data) { + if(communicationManager == null) { + communicationManager = new CommunicationManager(main); + } try { - String subchannel = in.readUTF(); - - if(subchannel.equals("ack")) { - main.getPlatformMethods().sendPluginMessage(recievingPlayer, "ack", "yes, im here"); - } - - if(subchannel.equals("queue")) { - String rawData = in.readUTF(); - String[] args = new String[1]; - args[0] = rawData; - moveCommand.execute(new PlayerSender(recievingPlayer), args); - } - if(subchannel.equals("massqueue")) { - String inData = in.readUTF(); - String[] parts = inData.split(","); - for(String part : parts) { - String[] pparts = part.split(":"); - if(pparts.length < 2) continue; - String pname = pparts[0]; - String pserver = pparts[1]; - AdaptedPlayer p = main.getPlatformMethods().getPlayer(pname); - String[] args = new String[1]; - args[0] = pserver; - moveCommand.execute(new PlayerSender(p), args); - } - } - if(subchannel.equals("queuename")) { - QueueServer server = main.getQueueManager().getSingleServer(recievingPlayer); - String name = main.getMessages().getString("placeholders.position.none"); - if(server != null) { - name = server.getAlias(); - } - main.getPlatformMethods().sendPluginMessage(recievingPlayer, "queuename", name); - } - if(subchannel.equals("position")) { - QueueServer server = main.getQueueManager().getSingleServer(recievingPlayer); - String pos = main.getMessages().getString("placeholders.position.none"); - if(server != null) { - pos = server.getQueue().indexOf(server.findPlayer(recievingPlayer))+1+""; - } - main.getPlatformMethods().sendPluginMessage(recievingPlayer, "position", pos); - } - if(subchannel.equals("positionof")) { - QueueServer server = main.getQueueManager().getSingleServer(recievingPlayer); - String pos = main.getMessages().getString("placeholders.position.none"); - if(server != null) { - pos = server.getQueue().size()+""; - } - main.getPlatformMethods().sendPluginMessage(recievingPlayer, "positionof", pos); - } - if(subchannel.equals("estimated_time")) { - QueueServer server = main.getQueueManager().getSingleServer(recievingPlayer); - - int time; - String timeString; - if(server != null) { - QueuePlayer queuePlayer = server.findPlayer(recievingPlayer); - time = (int) Math.round(queuePlayer.getPosition() * main.getTimeBetweenPlayers()); - timeString = TimeUtils.timeString( - time, - main.getMessages().getString("format.time.mins"), - main.getMessages().getString("format.time.secs") - ); - } else { - timeString = main.getMessages().getString("placeholders.estimated_time.none"); - } - main.getPlatformMethods().sendPluginMessage( - recievingPlayer, - "estimated_time", - timeString - ); - } - if(subchannel.equals("inqueue")) { - QueueServer server = main.getQueueManager().getSingleServer(recievingPlayer); - main.getPlatformMethods().sendPluginMessage(recievingPlayer, "inqueue", (server != null)+""); - } - if(subchannel.equals("queuedfor")) { - String srv = in.readUTF(); - QueueServer server = main.getQueueManager().findServer(srv); - if(server == null) return; - main.getPlatformMethods().sendPluginMessage(recievingPlayer, "queuedfor", srv, server.getQueue().size()+""); - } - if(subchannel.equals("status")) { - String srv = in.readUTF(); - QueueServer server = main.getQueueManager().findServer(srv); - if(server == null) return; - if(!recievingPlayer.isConnected() || recievingPlayer.getServerName() == null) return; - main.getPlatformMethods().sendPluginMessage( - recievingPlayer, - "status", - srv, - main.getMessages().getRawString("placeholders.status."+server.getStatus(recievingPlayer)) - ); - } - if(subchannel.equals("leavequeue")) { - String[] args = new String[1]; - try { - args[0] = in.readUTF(); - } catch(Exception ignored) {} - leaveCommand.execute(new PlayerSender(recievingPlayer), args); - } - - } catch (IOException e1) { - main.getLogger().warning("An error occured while reading data from spigot side:"); - e1.printStackTrace(); + communicationManager.handle(receivingPlayer, data); + } catch (IOException e) { + main.getLogger().warning("An error occurred while reading data from spigot side:", e); } } diff --git a/common/src/main/java/us/ajg0702/queue/common/communication/CommunicationManager.java b/common/src/main/java/us/ajg0702/queue/common/communication/CommunicationManager.java new file mode 100644 index 0000000..bd2eb3a --- /dev/null +++ b/common/src/main/java/us/ajg0702/queue/common/communication/CommunicationManager.java @@ -0,0 +1,69 @@ +package us.ajg0702.queue.common.communication; + +import us.ajg0702.queue.api.communication.ComResponse; +import us.ajg0702.queue.api.players.AdaptedPlayer; +import us.ajg0702.queue.common.QueueMain; +import us.ajg0702.queue.common.communication.handlers.*; +import us.ajg0702.queue.common.utils.Debug; +import us.ajg0702.queue.common.utils.MapBuilder; + +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; +import java.io.IOException; +import java.util.Map; + +public class CommunicationManager { + private final QueueMain main; + Map handlers; + + public CommunicationManager(QueueMain main) { + this.main = main; + + handlers = new MapBuilder<>( + "ack", new AckHandler(main), + + "queue", new QueueHandler(main), + "massqueue", new MassQueueHandler(main), + "leavequeue", new LeaveQueueHandler(main), + + "queuename", new QueueNameHandler(main), + "position", new PositionHandler(main), + "positionof", new PositionOfHandler(main), + "estimated_time", new EstimatedTimeHandler(main), + "inqueue", new InQueueHandler(main), + "queuedfor", new QueuedForHandler(main), + "status", new StatusHandler(main), + "playerstatus", new PlayerStatusHandler(main) + ); + } + + public void handle(AdaptedPlayer receivingPlayer, byte[] data) throws IOException { + DataInputStream in = new DataInputStream(new ByteArrayInputStream(data)); + String subChannel = in.readUTF(); + + MessageHandler handler = handlers.get(subChannel); + + if(handler == null) { + main.getLogger().warn("Invalid sub-channel " + subChannel); + return; + } + + ComResponse response = handler.handleMessage(receivingPlayer, in.readUTF()); + + if(response == null) return; + + Debug.info("Responding with " + response); + + main.getPlatformMethods().sendPluginMessage( + receivingPlayer, + s(response.getFrom()), + s(response.getIdentifier()), + s(response.getResponse()), + s(response.getNoneMessage()) + ); + } + + private String s(String s) { + return s + ""; + } +} diff --git a/common/src/main/java/us/ajg0702/queue/common/communication/MessageHandler.java b/common/src/main/java/us/ajg0702/queue/common/communication/MessageHandler.java new file mode 100644 index 0000000..6d46c2d --- /dev/null +++ b/common/src/main/java/us/ajg0702/queue/common/communication/MessageHandler.java @@ -0,0 +1,15 @@ +package us.ajg0702.queue.common.communication; + +import us.ajg0702.queue.api.communication.ComResponse; +import us.ajg0702.queue.api.players.AdaptedPlayer; +import us.ajg0702.queue.common.QueueMain; + +public abstract class MessageHandler { + protected final QueueMain main; + + public MessageHandler(QueueMain main) { + this.main = main; + } + + public abstract ComResponse handleMessage(AdaptedPlayer player, String data); +} diff --git a/common/src/main/java/us/ajg0702/queue/common/communication/handlers/AckHandler.java b/common/src/main/java/us/ajg0702/queue/common/communication/handlers/AckHandler.java new file mode 100644 index 0000000..5b20172 --- /dev/null +++ b/common/src/main/java/us/ajg0702/queue/common/communication/handlers/AckHandler.java @@ -0,0 +1,19 @@ +package us.ajg0702.queue.common.communication.handlers; + +import us.ajg0702.queue.api.players.AdaptedPlayer; +import us.ajg0702.queue.common.QueueMain; +import us.ajg0702.queue.api.communication.ComResponse; +import us.ajg0702.queue.common.communication.MessageHandler; + +public class AckHandler extends MessageHandler { + public AckHandler(QueueMain main) { + super(main); + } + + @Override + public ComResponse handleMessage(AdaptedPlayer player, String data) { + return ComResponse + .from("ack") + .with("yes, im here"); + } +} diff --git a/common/src/main/java/us/ajg0702/queue/common/communication/handlers/EstimatedTimeHandler.java b/common/src/main/java/us/ajg0702/queue/common/communication/handlers/EstimatedTimeHandler.java new file mode 100644 index 0000000..e9cf49e --- /dev/null +++ b/common/src/main/java/us/ajg0702/queue/common/communication/handlers/EstimatedTimeHandler.java @@ -0,0 +1,39 @@ +package us.ajg0702.queue.common.communication.handlers; + +import us.ajg0702.queue.api.players.AdaptedPlayer; +import us.ajg0702.queue.api.players.QueuePlayer; +import us.ajg0702.queue.api.queues.QueueServer; +import us.ajg0702.queue.common.QueueMain; +import us.ajg0702.queue.api.communication.ComResponse; +import us.ajg0702.queue.common.communication.MessageHandler; +import us.ajg0702.utils.common.TimeUtils; + +public class EstimatedTimeHandler extends MessageHandler { + + public EstimatedTimeHandler(QueueMain main) { + super(main); + } + + @Override + public ComResponse handleMessage(AdaptedPlayer player, String data) { + QueueServer server = main.getQueueManager().getSingleServer(player); + + int time; + String timeString; + if(server != null) { + QueuePlayer queuePlayer = server.findPlayer(player); + time = (int) Math.round(queuePlayer.getPosition() * main.getTimeBetweenPlayers()); + timeString = TimeUtils.timeString( + time, + main.getMessages().getString("format.time.mins"), + main.getMessages().getString("format.time.secs") + ); + } else { + timeString = main.getMessages().getString("placeholders.estimated_time.none"); + } + return ComResponse + .from("estimated_time") + .id(player.getUniqueId()) + .with(timeString); + } +} diff --git a/common/src/main/java/us/ajg0702/queue/common/communication/handlers/InQueueHandler.java b/common/src/main/java/us/ajg0702/queue/common/communication/handlers/InQueueHandler.java new file mode 100644 index 0000000..f21d300 --- /dev/null +++ b/common/src/main/java/us/ajg0702/queue/common/communication/handlers/InQueueHandler.java @@ -0,0 +1,23 @@ +package us.ajg0702.queue.common.communication.handlers; + +import us.ajg0702.queue.api.players.AdaptedPlayer; +import us.ajg0702.queue.api.queues.QueueServer; +import us.ajg0702.queue.common.QueueMain; +import us.ajg0702.queue.api.communication.ComResponse; +import us.ajg0702.queue.common.communication.MessageHandler; + +public class InQueueHandler extends MessageHandler { + + public InQueueHandler(QueueMain main) { + super(main); + } + + @Override + public ComResponse handleMessage(AdaptedPlayer player, String data) { + QueueServer server = main.getQueueManager().getSingleServer(player); + return ComResponse + .from("inqueue") + .id(player.getUniqueId()) + .with(server != null); + } +} diff --git a/common/src/main/java/us/ajg0702/queue/common/communication/handlers/LeaveQueueHandler.java b/common/src/main/java/us/ajg0702/queue/common/communication/handlers/LeaveQueueHandler.java new file mode 100644 index 0000000..3a33ac7 --- /dev/null +++ b/common/src/main/java/us/ajg0702/queue/common/communication/handlers/LeaveQueueHandler.java @@ -0,0 +1,25 @@ +package us.ajg0702.queue.common.communication.handlers; + +import us.ajg0702.queue.api.commands.IBaseCommand; +import us.ajg0702.queue.api.players.AdaptedPlayer; +import us.ajg0702.queue.commands.commands.PlayerSender; +import us.ajg0702.queue.common.QueueMain; +import us.ajg0702.queue.api.communication.ComResponse; +import us.ajg0702.queue.common.communication.MessageHandler; + +public class LeaveQueueHandler extends MessageHandler { + IBaseCommand leaveCommand; + + public LeaveQueueHandler(QueueMain main) { + super(main); + leaveCommand = main.getPlatformMethods().getCommands().get(1); + } + + @Override + public ComResponse handleMessage(AdaptedPlayer player, String data) { + String[] args = new String[1]; + args[0] = data; + leaveCommand.execute(new PlayerSender(player), args); + return null; + } +} diff --git a/common/src/main/java/us/ajg0702/queue/common/communication/handlers/MassQueueHandler.java b/common/src/main/java/us/ajg0702/queue/common/communication/handlers/MassQueueHandler.java new file mode 100644 index 0000000..fd28a95 --- /dev/null +++ b/common/src/main/java/us/ajg0702/queue/common/communication/handlers/MassQueueHandler.java @@ -0,0 +1,33 @@ +package us.ajg0702.queue.common.communication.handlers; + +import us.ajg0702.queue.api.commands.IBaseCommand; +import us.ajg0702.queue.api.players.AdaptedPlayer; +import us.ajg0702.queue.commands.commands.PlayerSender; +import us.ajg0702.queue.common.QueueMain; +import us.ajg0702.queue.api.communication.ComResponse; +import us.ajg0702.queue.common.communication.MessageHandler; + +public class MassQueueHandler extends MessageHandler { + private final IBaseCommand moveCommand; + + public MassQueueHandler(QueueMain main) { + super(main); + moveCommand = main.getPlatformMethods().getCommands().get(0); + } + + @Override + public ComResponse handleMessage(AdaptedPlayer player, String data) { + String[] parts = data.split(","); + for(String part : parts) { + String[] playerParts = part.split(":"); + if(playerParts.length < 2) continue; + String playerName = playerParts[0]; + String targetServer = playerParts[1]; + AdaptedPlayer p = main.getPlatformMethods().getPlayer(playerName); + String[] args = new String[1]; + args[0] = targetServer; + moveCommand.execute(new PlayerSender(p), args); + } + return null; + } +} diff --git a/common/src/main/java/us/ajg0702/queue/common/communication/handlers/PlayerStatusHandler.java b/common/src/main/java/us/ajg0702/queue/common/communication/handlers/PlayerStatusHandler.java new file mode 100644 index 0000000..62e3d6e --- /dev/null +++ b/common/src/main/java/us/ajg0702/queue/common/communication/handlers/PlayerStatusHandler.java @@ -0,0 +1,33 @@ +package us.ajg0702.queue.common.communication.handlers; + +import us.ajg0702.queue.api.communication.ComResponse; +import us.ajg0702.queue.api.players.AdaptedPlayer; +import us.ajg0702.queue.api.queues.QueueServer; +import us.ajg0702.queue.common.QueueMain; +import us.ajg0702.queue.common.communication.MessageHandler; + +public class PlayerStatusHandler extends MessageHandler { + public PlayerStatusHandler(QueueMain main) { + super(main); + } + + @Override + public ComResponse handleMessage(AdaptedPlayer player, String data) { + QueueServer server = main.getQueueManager().findServer(data); + if(server == null) { + return ComResponse + .from("playerstatus") + .id(data) + .with("invalid_server"); + } + if(!player.isConnected() || player.getServerName() == null) return null; + return ComResponse + .from("playerstatus") + .id(player.getUniqueId() + data) + .with( + main.getMessages().getRawString( + "placeholders.status." + server.getStatus(player) + ) + ); + } +} diff --git a/common/src/main/java/us/ajg0702/queue/common/communication/handlers/PositionHandler.java b/common/src/main/java/us/ajg0702/queue/common/communication/handlers/PositionHandler.java new file mode 100644 index 0000000..ad71e87 --- /dev/null +++ b/common/src/main/java/us/ajg0702/queue/common/communication/handlers/PositionHandler.java @@ -0,0 +1,31 @@ +package us.ajg0702.queue.common.communication.handlers; + +import us.ajg0702.queue.api.players.AdaptedPlayer; +import us.ajg0702.queue.api.queues.QueueServer; +import us.ajg0702.queue.common.QueueMain; +import us.ajg0702.queue.api.communication.ComResponse; +import us.ajg0702.queue.common.communication.MessageHandler; + +public class PositionHandler extends MessageHandler { + + public PositionHandler(QueueMain main) { + super(main); + } + + @Override + public ComResponse handleMessage(AdaptedPlayer player, String data) { + QueueServer server = main.getQueueManager().getSingleServer(player); + Integer pos = null; + String noneMessage = null; + if(server != null) { + pos = server.getQueue().indexOf(server.findPlayer(player)) + 1; + } else { + noneMessage = main.getMessages().getString("placeholders.position.none"); + } + return ComResponse + .from("position") + .id(player.getUniqueId()) + .with(pos) + .noneMessage(noneMessage); + } +} diff --git a/common/src/main/java/us/ajg0702/queue/common/communication/handlers/PositionOfHandler.java b/common/src/main/java/us/ajg0702/queue/common/communication/handlers/PositionOfHandler.java new file mode 100644 index 0000000..0872d76 --- /dev/null +++ b/common/src/main/java/us/ajg0702/queue/common/communication/handlers/PositionOfHandler.java @@ -0,0 +1,32 @@ +package us.ajg0702.queue.common.communication.handlers; + +import us.ajg0702.queue.api.players.AdaptedPlayer; +import us.ajg0702.queue.api.queues.QueueServer; +import us.ajg0702.queue.common.QueueMain; +import us.ajg0702.queue.api.communication.ComResponse; +import us.ajg0702.queue.common.communication.MessageHandler; + +public class PositionOfHandler extends MessageHandler { + + + public PositionOfHandler(QueueMain main) { + super(main); + } + + @Override + public ComResponse handleMessage(AdaptedPlayer player, String data) { + QueueServer server = main.getQueueManager().getSingleServer(player); + Integer size = null; + String noneMessage = null; + if(server != null) { + size = server.getQueue().size(); + } else { + noneMessage = main.getMessages().getString("placeholders.position.none"); + } + return ComResponse + .from("positionof") + .id(player.getUniqueId()) + .with(size) + .noneMessage(noneMessage); + } +} diff --git a/common/src/main/java/us/ajg0702/queue/common/communication/handlers/QueueHandler.java b/common/src/main/java/us/ajg0702/queue/common/communication/handlers/QueueHandler.java new file mode 100644 index 0000000..30cf62a --- /dev/null +++ b/common/src/main/java/us/ajg0702/queue/common/communication/handlers/QueueHandler.java @@ -0,0 +1,25 @@ +package us.ajg0702.queue.common.communication.handlers; + +import us.ajg0702.queue.api.commands.IBaseCommand; +import us.ajg0702.queue.api.players.AdaptedPlayer; +import us.ajg0702.queue.commands.commands.PlayerSender; +import us.ajg0702.queue.common.QueueMain; +import us.ajg0702.queue.api.communication.ComResponse; +import us.ajg0702.queue.common.communication.MessageHandler; + +public class QueueHandler extends MessageHandler { + private final IBaseCommand moveCommand; + + public QueueHandler(QueueMain main) { + super(main); + moveCommand = main.getPlatformMethods().getCommands().get(0); + } + + @Override + public ComResponse handleMessage(AdaptedPlayer player, String data) { + String[] args = new String[1]; + args[0] = data; + moveCommand.execute(new PlayerSender(player), args); + return null; + } +} diff --git a/common/src/main/java/us/ajg0702/queue/common/communication/handlers/QueueNameHandler.java b/common/src/main/java/us/ajg0702/queue/common/communication/handlers/QueueNameHandler.java new file mode 100644 index 0000000..f9793c4 --- /dev/null +++ b/common/src/main/java/us/ajg0702/queue/common/communication/handlers/QueueNameHandler.java @@ -0,0 +1,31 @@ +package us.ajg0702.queue.common.communication.handlers; + +import us.ajg0702.queue.api.players.AdaptedPlayer; +import us.ajg0702.queue.api.queues.QueueServer; +import us.ajg0702.queue.common.QueueMain; +import us.ajg0702.queue.api.communication.ComResponse; +import us.ajg0702.queue.common.communication.MessageHandler; + +public class QueueNameHandler extends MessageHandler { + + public QueueNameHandler(QueueMain main) { + super(main); + } + + @Override + public ComResponse handleMessage(AdaptedPlayer player, String data) { + QueueServer server = main.getQueueManager().getSingleServer(player); + String name = null; + String none = null; + if(server != null) { + name = server.getAlias(); + } else { + none = main.getMessages().getString("placeholders.position.none"); + } + return ComResponse + .from("queuename") + .id(player.getUniqueId()) + .with(name) + .noneMessage(none); + } +} diff --git a/common/src/main/java/us/ajg0702/queue/common/communication/handlers/QueuedForHandler.java b/common/src/main/java/us/ajg0702/queue/common/communication/handlers/QueuedForHandler.java new file mode 100644 index 0000000..4f3e94d --- /dev/null +++ b/common/src/main/java/us/ajg0702/queue/common/communication/handlers/QueuedForHandler.java @@ -0,0 +1,29 @@ +package us.ajg0702.queue.common.communication.handlers; + +import us.ajg0702.queue.api.players.AdaptedPlayer; +import us.ajg0702.queue.api.queues.QueueServer; +import us.ajg0702.queue.common.QueueMain; +import us.ajg0702.queue.api.communication.ComResponse; +import us.ajg0702.queue.common.communication.MessageHandler; + +public class QueuedForHandler extends MessageHandler { + + public QueuedForHandler(QueueMain main) { + super(main); + } + + @Override + public ComResponse handleMessage(AdaptedPlayer player, String data) { + QueueServer server = main.getQueueManager().findServer(data); + if(server == null) { + return ComResponse + .from("queuedfor") + .id(data) + .with("invalid_server"); + } + return ComResponse + .from("queuedfor") + .id(data) + .with(server.getQueue().size()); + } +} diff --git a/common/src/main/java/us/ajg0702/queue/common/communication/handlers/StatusHandler.java b/common/src/main/java/us/ajg0702/queue/common/communication/handlers/StatusHandler.java new file mode 100644 index 0000000..11f65d9 --- /dev/null +++ b/common/src/main/java/us/ajg0702/queue/common/communication/handlers/StatusHandler.java @@ -0,0 +1,32 @@ +package us.ajg0702.queue.common.communication.handlers; + +import us.ajg0702.queue.api.players.AdaptedPlayer; +import us.ajg0702.queue.api.queues.QueueServer; +import us.ajg0702.queue.common.QueueMain; +import us.ajg0702.queue.api.communication.ComResponse; +import us.ajg0702.queue.common.communication.MessageHandler; + +public class StatusHandler extends MessageHandler { + public StatusHandler(QueueMain main) { + super(main); + } + + @Override + public ComResponse handleMessage(AdaptedPlayer player, String data) { + QueueServer server = main.getQueueManager().findServer(data); + if(server == null) { + return ComResponse + .from("status") + .id(data) + .with("invalid_server"); + } + return ComResponse + .from("status") + .id(data) + .with( + main.getMessages().getRawString( + "placeholders.status." + server.getStatus() + ) + ); + } +} diff --git a/common/src/main/java/us/ajg0702/queue/common/utils/MapBuilder.java b/common/src/main/java/us/ajg0702/queue/common/utils/MapBuilder.java new file mode 100644 index 0000000..e1f366a --- /dev/null +++ b/common/src/main/java/us/ajg0702/queue/common/utils/MapBuilder.java @@ -0,0 +1,12 @@ +package us.ajg0702.queue.common.utils; + +import java.util.LinkedHashMap; + +public class MapBuilder extends LinkedHashMap { + @SuppressWarnings("unchecked") + public MapBuilder(Object... entries) { + for (int i = 0; i < entries.length; i += 2) { + put((K) entries[i], (V) entries[i+1]); + } + } +} diff --git a/platforms/bungeecord/src/main/java/us/ajg0702/queue/platforms/bungeecord/BungeeMethods.java b/platforms/bungeecord/src/main/java/us/ajg0702/queue/platforms/bungeecord/BungeeMethods.java index 31da45b..453ea4a 100644 --- a/platforms/bungeecord/src/main/java/us/ajg0702/queue/platforms/bungeecord/BungeeMethods.java +++ b/platforms/bungeecord/src/main/java/us/ajg0702/queue/platforms/bungeecord/BungeeMethods.java @@ -39,7 +39,6 @@ public class BungeeMethods implements PlatformMethods { if(playerName == null) return; ByteArrayDataOutput out = ByteStreams.newDataOutput(); out.writeUTF(channel); - out.writeUTF(playerName); for (String s : data) { out.writeUTF(s); diff --git a/platforms/velocity/src/main/java/us/ajg0702/queue/platforms/velocity/VelocityMethods.java b/platforms/velocity/src/main/java/us/ajg0702/queue/platforms/velocity/VelocityMethods.java index b552710..c8106c8 100644 --- a/platforms/velocity/src/main/java/us/ajg0702/queue/platforms/velocity/VelocityMethods.java +++ b/platforms/velocity/src/main/java/us/ajg0702/queue/platforms/velocity/VelocityMethods.java @@ -44,7 +44,6 @@ public class VelocityMethods implements PlatformMethods { String playerName = player.getName(); if(playerName == null) return; out.writeUTF( channel ); - out.writeUTF(playerName); for(String s : data) { out.writeUTF( s ); } diff --git a/spigot/build.gradle.kts b/spigot/build.gradle.kts index d34eeff..39bbdf6 100644 --- a/spigot/build.gradle.kts +++ b/spigot/build.gradle.kts @@ -20,6 +20,7 @@ repositories { dependencies { implementation("net.kyori:adventure-api:4.13.1") + compileOnly(project(":api")) compileOnly("com.google.guava:guava:30.1.1-jre") compileOnly("org.spongepowered:configurate-yaml:4.1.2") diff --git a/spigot/src/main/java/us/ajg0702/queue/spigot/SpigotMain.java b/spigot/src/main/java/us/ajg0702/queue/spigot/SpigotMain.java index bb85f41..0fc8747 100644 --- a/spigot/src/main/java/us/ajg0702/queue/spigot/SpigotMain.java +++ b/spigot/src/main/java/us/ajg0702/queue/spigot/SpigotMain.java @@ -15,16 +15,25 @@ import org.bukkit.event.server.ServerListPingEvent; import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.messaging.PluginMessageListener; import org.jetbrains.annotations.NotNull; +import us.ajg0702.queue.api.AjQueueAPI; +import us.ajg0702.queue.api.communication.ComResponse; +import us.ajg0702.queue.api.spigot.AjQueueSpigotAPI; +import us.ajg0702.queue.spigot.api.SpigotAPI; +import us.ajg0702.queue.spigot.communication.ResponseManager; +import us.ajg0702.queue.spigot.placeholders.PlaceholderExpansion; import us.ajg0702.utils.common.ConfigFile; import java.io.File; import java.util.HashMap; +import java.util.logging.Level; @SuppressWarnings("UnstableApiUsage") public class SpigotMain extends JavaPlugin implements PluginMessageListener,Listener { private boolean papi = false; - private Placeholders placeholders; + private PlaceholderExpansion placeholders; + + private ResponseManager responseManager = new ResponseManager(); private ConfigFile config; @@ -34,6 +43,9 @@ public class SpigotMain extends JavaPlugin implements PluginMessageListener,List public void onEnable() { getServer().getMessenger().registerIncomingPluginChannel(this, "ajqueue:tospigot", this); getServer().getMessenger().registerOutgoingPluginChannel(this, "ajqueue:toproxy"); + + AjQueueAPI.SPIGOT_INSTANCE = new SpigotAPI(responseManager, this); + AjQueueSpigotAPI.INSTANCE = AjQueueAPI.SPIGOT_INSTANCE; this.getCommand("move").setExecutor(new Commands(this)); this.getCommand("leavequeue").setExecutor(new Commands(this)); @@ -43,7 +55,7 @@ public class SpigotMain extends JavaPlugin implements PluginMessageListener,List papi = Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null; if(papi) { - placeholders = new Placeholders(this); + placeholders = new PlaceholderExpansion(this); placeholders.register(); getLogger().info("Registered PlaceholderAPI placeholders"); } @@ -94,6 +106,7 @@ public class SpigotMain extends JavaPlugin implements PluginMessageListener,List if(subchannel.equals("ack")) { hasProxy = true; + return; } if(subchannel.equals("inqueueevent")) { @@ -102,95 +115,15 @@ public class SpigotMain extends JavaPlugin implements PluginMessageListener,List if(p == null) return; QueueScoreboardActivator e = new QueueScoreboardActivator(p); Bukkit.getPluginManager().callEvent(e); + return; } - if(subchannel.equals("queuename") && papi) { - String playername = in.readUTF(); - Player p = Bukkit.getPlayer(playername); - if(p == null) return; - if(!p.isOnline()) return; - - String data = in.readUTF(); - HashMap phs = placeholders.responseCache.get(p); - if(phs == null) phs = new HashMap<>(); - phs.put("queued", data); - placeholders.responseCache.put(p, phs); - } - if(subchannel.equals("position") && papi) { - String playername = in.readUTF(); - Player p = Bukkit.getPlayer(playername); - if(p == null) return; - if(!p.isOnline()) return; - - String data = in.readUTF(); - HashMap phs = placeholders.responseCache.get(p); - if(phs == null) phs = new HashMap<>(); - phs.put("position", data); - placeholders.responseCache.put(p, phs); - } - if(subchannel.equals("positionof") && papi) { - String playername = in.readUTF(); - Player p = Bukkit.getPlayer(playername); - if(p == null) return; - if(!p.isOnline()) return; - - String data = in.readUTF(); - HashMap phs = placeholders.responseCache.get(p); - if(phs == null) phs = new HashMap<>(); - phs.put("of", data); - placeholders.responseCache.put(p, phs); - } - if(subchannel.equals("inqueue") && papi) { - String playername = in.readUTF(); - Player p = Bukkit.getPlayer(playername); - if(p == null) return; - if(!p.isOnline()) return; - - String data = in.readUTF(); - HashMap phs = placeholders.responseCache.get(p); - if(phs == null) phs = new HashMap<>(); - phs.put("inqueue", data); - placeholders.responseCache.put(p, phs); - } - if(subchannel.equals("queuedfor")) { - String playername = in.readUTF(); - String queuename = in.readUTF(); - - Player p = Bukkit.getPlayer(playername); - if(p == null) return; - if(!p.isOnline()) return; - - int number = Integer.parseInt(in.readUTF()); - HashMap phs = placeholders.responseCache.get(p); - if(phs == null) phs = new HashMap<>(); - phs.put("queuedfor_"+queuename, number+""); - placeholders.responseCache.put(p, phs); - } - if(subchannel.equals("estimated_time")) { - String playername = in.readUTF(); - Player p = Bukkit.getPlayer(playername); - if(p == null) return; - if(!p.isOnline()) return; + try { + ComResponse response = ComResponse.from(subchannel, in); - String time = in.readUTF(); - HashMap phs = placeholders.responseCache.get(p); - if(phs == null) phs = new HashMap<>(); - phs.put("estimated_time", time); - placeholders.responseCache.put(p, phs); - } - if(subchannel.equals("status")) { - String playername = in.readUTF(); - String server = in.readUTF(); - - Player p = Bukkit.getPlayer(playername); - if(p == null) return; - if(!p.isOnline()) return; - - String status = in.readUTF(); - HashMap phs = placeholders.responseCache.get(p); - if(phs == null) phs = new HashMap<>(); - phs.put("status_"+server, status+""); - placeholders.responseCache.put(p, phs); + responseManager.executeResponse(response); + } catch (Exception e) { + getLogger().log(Level.SEVERE, "Error while processing proxy response " + subchannel + ": ", e); } } @@ -215,7 +148,7 @@ public class SpigotMain extends JavaPlugin implements PluginMessageListener,List @EventHandler public void onLeave(PlayerQuitEvent e) { if(!papi) return; - placeholders.cleanCache(); + placeholders.cleanCache(e.getPlayer()); } @EventHandler diff --git a/spigot/src/main/java/us/ajg0702/queue/spigot/api/SpigotAPI.java b/spigot/src/main/java/us/ajg0702/queue/spigot/api/SpigotAPI.java new file mode 100644 index 0000000..1a6607f --- /dev/null +++ b/spigot/src/main/java/us/ajg0702/queue/spigot/api/SpigotAPI.java @@ -0,0 +1,157 @@ +package us.ajg0702.queue.spigot.api; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import us.ajg0702.queue.api.spigot.AjQueueSpigotAPI; +import us.ajg0702.queue.api.spigot.MessagedResponse; +import us.ajg0702.queue.spigot.SpigotMain; +import us.ajg0702.queue.spigot.communication.ResponseManager; + +import java.util.UUID; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Future; + +public class SpigotAPI extends AjQueueSpigotAPI { + private final ResponseManager responseManager; + private final SpigotMain main; + + public SpigotAPI(ResponseManager responseManager, SpigotMain main) { + this.responseManager = responseManager; + this.main = main; + } + + @Override + public Future isInQueue(UUID player) { + Player p = Bukkit.getPlayer(player); + if(p == null) throw new IllegalArgumentException("Player must be online!"); + + CompletableFuture future = new CompletableFuture<>(); + + responseManager.awaitResponse(player.toString(), "inqueue", response -> { + future.complete(Boolean.valueOf(response.getResponse())); + }); + + main.sendMessage(p, "inqueue", ""); + + return future; + } + + @Override + public Future addToQueue(UUID player, String queueName) { + throw new UnsupportedOperationException("Not yet implemented!"); + } + + @Override + public Future> getQueueName(UUID player) { + Player p = Bukkit.getPlayer(player); + if(p == null) throw new IllegalArgumentException("Player must be online!"); + + CompletableFuture> future = new CompletableFuture<>(); + + responseManager.awaitResponse(player.toString(), "queuename", response -> { + future.complete(new MessagedResponse<>(response.getResponse(), response.getNoneMessage())); + }); + + main.sendMessage(p, "queuename", ""); + + return future; + } + + @Override + public Future> getPosition(UUID player) { + Player p = Bukkit.getPlayer(player); + if(p == null) throw new IllegalArgumentException("Player must be online!"); + + CompletableFuture> future = new CompletableFuture<>(); + + responseManager.awaitResponse(player.toString(), "position", response -> { + String r = response.getResponse(); + Integer i = r == null ? null : Integer.valueOf(r); + future.complete(new MessagedResponse<>(i, response.getNoneMessage())); + }); + + main.sendMessage(p, "position", ""); + + return future; + } + + @Override + public Future> getTotalPositions(UUID player) { + Player p = Bukkit.getPlayer(player); + if(p == null) throw new IllegalArgumentException("Player must be online!"); + + CompletableFuture> future = new CompletableFuture<>(); + + responseManager.awaitResponse(player.toString(), "positionof", response -> { + String r = response.getResponse(); + Integer i = r == null ? null : Integer.valueOf(r); + future.complete(new MessagedResponse<>(i, response.getNoneMessage())); + }); + + main.sendMessage(p, "positionof", ""); + + return future; + } + + @Override + public Future getPlayersInQueue(String queueName) { + Player p = Bukkit.getOnlinePlayers().iterator().next(); + + CompletableFuture future = new CompletableFuture<>(); + + responseManager.awaitResponse(queueName, "queuedfor", response -> { + String responseString = response.getResponse(); + if(responseString.equals("invalid_server")) { + future.completeExceptionally(new IllegalArgumentException(queueName + " does not exist!")); + } + future.complete(Integer.valueOf(responseString)); + }); + + main.sendMessage(p, "queuedfor", queueName); + + return future; + } + + @Override + public Future getServerStatusString(String queueName) { + return getServerStatusString(queueName, null); + } + + @Override + public Future getServerStatusString(String queueName, UUID player) { + Player p = player == null ? Bukkit.getOnlinePlayers().iterator().next() : Bukkit.getPlayer(player); + if(p == null) throw new IllegalArgumentException("Player must be online!"); + + String channel = player == null ? "status" : "playerstatus"; + + CompletableFuture future = new CompletableFuture<>(); + + responseManager.awaitResponse(queueName, channel, response -> { + String responseString = response.getResponse(); + if(responseString.equals("invalid_server")) { + future.completeExceptionally(new IllegalArgumentException(queueName + " does not exist!")); + } + future.complete(responseString); + }); + + main.sendMessage(p, channel, queueName); + + return future; + } + + @Override + public Future> getEstimatedTime(UUID player) { + Player p = Bukkit.getPlayer(player); + if(p == null) throw new IllegalArgumentException("Player must be online!"); + + CompletableFuture> future = new CompletableFuture<>(); + + responseManager.awaitResponse(player.toString(), "estimated_time", response -> { + future.complete(new MessagedResponse<>(response.getResponse(), response.getNoneMessage())); + }); + + main.sendMessage(p, "estimated_time", ""); + + return future; + } +} diff --git a/spigot/src/main/java/us/ajg0702/queue/spigot/communication/ResponseKey.java b/spigot/src/main/java/us/ajg0702/queue/spigot/communication/ResponseKey.java new file mode 100644 index 0000000..7ac0cba --- /dev/null +++ b/spigot/src/main/java/us/ajg0702/queue/spigot/communication/ResponseKey.java @@ -0,0 +1,34 @@ +package us.ajg0702.queue.spigot.communication; + +import java.util.Objects; + +public class ResponseKey { + private final String id; + private final String from; + + public ResponseKey(String id, String from) { + this.id = id; + this.from = from; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ResponseKey that = (ResponseKey) o; + return id.equals(that.id) && from.equals(that.from); + } + + @Override + public int hashCode() { + return Objects.hash(id, from); + } + + @Override + public String toString() { + return "ResponseKey{" + + "id='" + id + '\'' + + ", from='" + from + '\'' + + '}'; + } +} diff --git a/spigot/src/main/java/us/ajg0702/queue/spigot/communication/ResponseManager.java b/spigot/src/main/java/us/ajg0702/queue/spigot/communication/ResponseManager.java new file mode 100644 index 0000000..b8ed6a8 --- /dev/null +++ b/spigot/src/main/java/us/ajg0702/queue/spigot/communication/ResponseManager.java @@ -0,0 +1,31 @@ +package us.ajg0702.queue.spigot.communication; + +import us.ajg0702.queue.api.communication.ComResponse; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Consumer; + + +public class ResponseManager { + private final Map> responseMap = new ConcurrentHashMap<>(); + + public synchronized void awaitResponse(String id, String from, Consumer callback) { + ResponseKey key = new ResponseKey(id, from); + responseMap.merge(key, callback, (a, b) -> r -> { + b.accept(r); + a.accept(r); + }); + } + + public void executeResponse(ComResponse response) { + ResponseKey key = new ResponseKey(response.getIdentifier(), response.getFrom()); + Consumer callback = responseMap.get(key); + if(callback == null) { + System.out.println("[ajQueue] No callback for " + key + " with " + response); + return; + } + responseMap.remove(key); + callback.accept(response); + } +} diff --git a/spigot/src/main/java/us/ajg0702/queue/spigot/placeholders/CachedPlaceholder.java b/spigot/src/main/java/us/ajg0702/queue/spigot/placeholders/CachedPlaceholder.java new file mode 100644 index 0000000..73c223d --- /dev/null +++ b/spigot/src/main/java/us/ajg0702/queue/spigot/placeholders/CachedPlaceholder.java @@ -0,0 +1,21 @@ +package us.ajg0702.queue.spigot.placeholders; + +import java.util.regex.Matcher; + +public class CachedPlaceholder { + private final Matcher matcher; + private final Placeholder placeholder; + + public CachedPlaceholder(Matcher matcher, Placeholder placeholder) { + this.matcher = matcher; + this.placeholder = placeholder; + } + + public Matcher getMatcher() { + return matcher; + } + + public Placeholder getPlaceholder() { + return placeholder; + } +} diff --git a/spigot/src/main/java/us/ajg0702/queue/spigot/placeholders/Placeholder.java b/spigot/src/main/java/us/ajg0702/queue/spigot/placeholders/Placeholder.java new file mode 100644 index 0000000..03e943f --- /dev/null +++ b/spigot/src/main/java/us/ajg0702/queue/spigot/placeholders/Placeholder.java @@ -0,0 +1,32 @@ +package us.ajg0702.queue.spigot.placeholders; + +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; +import us.ajg0702.queue.spigot.SpigotMain; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public abstract class Placeholder { + + protected final SpigotMain plugin; + + private Pattern pattern; + + public Placeholder(SpigotMain plugin) { + this.plugin = plugin; + } + + public abstract String getRegex(); + + public Pattern getPattern() { + if(pattern == null) { + pattern = Pattern.compile(getRegex()); + } + return pattern; + } + + public abstract String parse(Matcher matcher, OfflinePlayer p); + + public abstract void cleanCache(Player player); +} diff --git a/spigot/src/main/java/us/ajg0702/queue/spigot/placeholders/PlaceholderExpansion.java b/spigot/src/main/java/us/ajg0702/queue/spigot/placeholders/PlaceholderExpansion.java new file mode 100644 index 0000000..374024c --- /dev/null +++ b/spigot/src/main/java/us/ajg0702/queue/spigot/placeholders/PlaceholderExpansion.java @@ -0,0 +1,88 @@ +package us.ajg0702.queue.spigot.placeholders; + +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import us.ajg0702.queue.spigot.SpigotMain; +import us.ajg0702.queue.spigot.placeholders.placeholders.*; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; + +public class PlaceholderExpansion extends me.clip.placeholderapi.expansion.PlaceholderExpansion { + + private final List placeholders = new ArrayList<>(); + + private final SpigotMain plugin; + + @SuppressWarnings("deprecated") + public PlaceholderExpansion(SpigotMain plugin) { + + this.plugin = plugin; + + placeholders.add(new EstimatedTime(plugin)); + placeholders.add(new InQueue(plugin)); + placeholders.add(new Position(plugin)); + placeholders.add(new PositionOf(plugin)); + placeholders.add(new Queued(plugin)); + placeholders.add(new QueuedFor(plugin)); + placeholders.add(new Status(plugin)); + + } + + Map placeholderCache = new HashMap<>(); + + @Override + public String onRequest(OfflinePlayer p, @NotNull String params) { + + if(p == null || !p.isOnline()) { + return "No player"; + } + + CachedPlaceholder cachedPlaceholder = placeholderCache.computeIfAbsent(params, s -> { + for(Placeholder placeholder : placeholders) { + Matcher matcher = placeholder.getPattern().matcher(params); + if(!matcher.matches()) continue; + return new CachedPlaceholder(matcher, placeholder); + } + return null; + }); + if(cachedPlaceholder == null) return null; + + return cachedPlaceholder.getPlaceholder().parse(cachedPlaceholder.getMatcher(), p); + } + + + + @Override + public @NotNull String getIdentifier() { + return "ajqueue"; + } + + @Override + public @NotNull String getAuthor() { + return "ajgeiss0702"; + } + + @Override + public @NotNull String getVersion() { + return plugin.getDescription().getVersion(); + } + + @Override + public boolean persist(){ + return true; + } + + @Override + public boolean canRegister() { + return true; + } + + public void cleanCache(Player player) { + placeholders.forEach(p -> p.cleanCache(player)); + } +} \ No newline at end of file diff --git a/spigot/src/main/java/us/ajg0702/queue/spigot/placeholders/placeholders/EstimatedTime.java b/spigot/src/main/java/us/ajg0702/queue/spigot/placeholders/placeholders/EstimatedTime.java new file mode 100644 index 0000000..a07b022 --- /dev/null +++ b/spigot/src/main/java/us/ajg0702/queue/spigot/placeholders/placeholders/EstimatedTime.java @@ -0,0 +1,55 @@ +package us.ajg0702.queue.spigot.placeholders.placeholders; + +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; +import us.ajg0702.queue.api.spigot.AjQueueSpigotAPI; +import us.ajg0702.queue.api.spigot.MessagedResponse; +import us.ajg0702.queue.spigot.SpigotMain; +import us.ajg0702.queue.spigot.placeholders.Placeholder; + +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.logging.Level; +import java.util.regex.Matcher; + +public class EstimatedTime extends Placeholder { + public EstimatedTime(SpigotMain plugin) { + super(plugin); + } + + private final Map cache = new ConcurrentHashMap<>(); + + @Override + public String getRegex() { + return "estimated_time"; + } + + @Override + public String parse(Matcher matcher, OfflinePlayer p) { + Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { + try { + MessagedResponse response = AjQueueSpigotAPI.getInstance() + .getEstimatedTime(p.getUniqueId()) + .get(30, TimeUnit.SECONDS); + + cache.put(p.getUniqueId(), response.getEither()); + } catch (InterruptedException | ExecutionException e) { + throw new RuntimeException(e); + } catch (TimeoutException e) { + plugin.getLogger().log(Level.WARNING, "Timed out while trying to get placeholder data from proxy: ", e); + } + }); + + return cache.getOrDefault(p.getUniqueId(), "..."); + } + + @Override + public void cleanCache(Player player) { + cache.remove(player.getUniqueId()); + } +} diff --git a/spigot/src/main/java/us/ajg0702/queue/spigot/placeholders/placeholders/InQueue.java b/spigot/src/main/java/us/ajg0702/queue/spigot/placeholders/placeholders/InQueue.java new file mode 100644 index 0000000..9b83582 --- /dev/null +++ b/spigot/src/main/java/us/ajg0702/queue/spigot/placeholders/placeholders/InQueue.java @@ -0,0 +1,54 @@ +package us.ajg0702.queue.spigot.placeholders.placeholders; + +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; +import us.ajg0702.queue.api.spigot.AjQueueSpigotAPI; +import us.ajg0702.queue.spigot.SpigotMain; +import us.ajg0702.queue.spigot.placeholders.Placeholder; + +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.logging.Level; +import java.util.regex.Matcher; + +public class InQueue extends Placeholder { + public InQueue(SpigotMain plugin) { + super(plugin); + } + + private final Map cache = new ConcurrentHashMap<>(); + + @Override + public String getRegex() { + return "inqueue"; + } + + @Override + public String parse(Matcher matcher, OfflinePlayer p) { + Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { + try { + Boolean response = AjQueueSpigotAPI.getInstance() + .isInQueue(p.getUniqueId()) + .get(30, TimeUnit.SECONDS); + + cache.put(p.getUniqueId(), response + ""); + } catch (InterruptedException | ExecutionException e) { + throw new RuntimeException(e); + } catch (TimeoutException e) { + plugin.getLogger().log(Level.WARNING, "Timed out while trying to get placeholder data from proxy: ", e); + } + }); + + return cache.getOrDefault(p.getUniqueId(), "..."); + } + + @Override + public void cleanCache(Player player) { + cache.remove(player.getUniqueId()); + } +} diff --git a/spigot/src/main/java/us/ajg0702/queue/spigot/placeholders/placeholders/Position.java b/spigot/src/main/java/us/ajg0702/queue/spigot/placeholders/placeholders/Position.java new file mode 100644 index 0000000..037420f --- /dev/null +++ b/spigot/src/main/java/us/ajg0702/queue/spigot/placeholders/placeholders/Position.java @@ -0,0 +1,55 @@ +package us.ajg0702.queue.spigot.placeholders.placeholders; + +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; +import us.ajg0702.queue.api.spigot.AjQueueSpigotAPI; +import us.ajg0702.queue.api.spigot.MessagedResponse; +import us.ajg0702.queue.spigot.SpigotMain; +import us.ajg0702.queue.spigot.placeholders.Placeholder; + +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.logging.Level; +import java.util.regex.Matcher; + +public class Position extends Placeholder { + public Position(SpigotMain plugin) { + super(plugin); + } + + private final Map cache = new ConcurrentHashMap<>(); + + @Override + public String getRegex() { + return "position"; + } + + @Override + public String parse(Matcher matcher, OfflinePlayer p) { + Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { + try { + MessagedResponse response = AjQueueSpigotAPI.getInstance() + .getPosition(p.getUniqueId()) + .get(30, TimeUnit.SECONDS); + + cache.put(p.getUniqueId(), response.getEither()); + } catch (InterruptedException | ExecutionException e) { + throw new RuntimeException(e); + } catch (TimeoutException e) { + plugin.getLogger().log(Level.WARNING, "Timed out while trying to get placeholder data from proxy: ", e); + } + }); + + return cache.getOrDefault(p.getUniqueId(), "..."); + } + + @Override + public void cleanCache(Player player) { + cache.remove(player.getUniqueId()); + } +} diff --git a/spigot/src/main/java/us/ajg0702/queue/spigot/placeholders/placeholders/PositionOf.java b/spigot/src/main/java/us/ajg0702/queue/spigot/placeholders/placeholders/PositionOf.java new file mode 100644 index 0000000..a3c4cba --- /dev/null +++ b/spigot/src/main/java/us/ajg0702/queue/spigot/placeholders/placeholders/PositionOf.java @@ -0,0 +1,55 @@ +package us.ajg0702.queue.spigot.placeholders.placeholders; + +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; +import us.ajg0702.queue.api.spigot.AjQueueSpigotAPI; +import us.ajg0702.queue.api.spigot.MessagedResponse; +import us.ajg0702.queue.spigot.SpigotMain; +import us.ajg0702.queue.spigot.placeholders.Placeholder; + +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.logging.Level; +import java.util.regex.Matcher; + +public class PositionOf extends Placeholder { + public PositionOf(SpigotMain plugin) { + super(plugin); + } + + private final Map cache = new ConcurrentHashMap<>(); + + @Override + public String getRegex() { + return "of"; + } + + @Override + public String parse(Matcher matcher, OfflinePlayer p) { + Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { + try { + MessagedResponse response = AjQueueSpigotAPI.getInstance() + .getTotalPositions(p.getUniqueId()) + .get(30, TimeUnit.SECONDS); + + cache.put(p.getUniqueId(), response.getEither()); + } catch (InterruptedException | ExecutionException e) { + throw new RuntimeException(e); + } catch (TimeoutException e) { + plugin.getLogger().log(Level.WARNING, "Timed out while trying to get placeholder data from proxy: ", e); + } + }); + + return cache.getOrDefault(p.getUniqueId(), "..."); + } + + @Override + public void cleanCache(Player player) { + cache.remove(player.getUniqueId()); + } +} diff --git a/spigot/src/main/java/us/ajg0702/queue/spigot/placeholders/placeholders/Queued.java b/spigot/src/main/java/us/ajg0702/queue/spigot/placeholders/placeholders/Queued.java new file mode 100644 index 0000000..cf4d26a --- /dev/null +++ b/spigot/src/main/java/us/ajg0702/queue/spigot/placeholders/placeholders/Queued.java @@ -0,0 +1,55 @@ +package us.ajg0702.queue.spigot.placeholders.placeholders; + +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; +import us.ajg0702.queue.api.spigot.AjQueueSpigotAPI; +import us.ajg0702.queue.api.spigot.MessagedResponse; +import us.ajg0702.queue.spigot.SpigotMain; +import us.ajg0702.queue.spigot.placeholders.Placeholder; + +import java.util.Map; +import java.util.UUID; +import java.util.logging.Level; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.regex.Matcher; + +public class Queued extends Placeholder { + public Queued(SpigotMain plugin) { + super(plugin); + } + + private final Map cache = new ConcurrentHashMap<>(); + + @Override + public String getRegex() { + return "queued"; + } + + @Override + public String parse(Matcher matcher, OfflinePlayer p) { + Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { + try { + MessagedResponse response = AjQueueSpigotAPI.getInstance() + .getQueueName(p.getUniqueId()) + .get(30, TimeUnit.SECONDS); + + cache.put(p.getUniqueId(), response.getEither()); + } catch (InterruptedException | ExecutionException e) { + throw new RuntimeException(e); + } catch (TimeoutException e) { + plugin.getLogger().log(Level.WARNING, "Timed out while trying to get placeholder data from proxy: ", e); + } + }); + + return cache.getOrDefault(p.getUniqueId(), "..."); + } + + @Override + public void cleanCache(Player player) { + cache.remove(player.getUniqueId()); + } +} diff --git a/spigot/src/main/java/us/ajg0702/queue/spigot/placeholders/placeholders/QueuedFor.java b/spigot/src/main/java/us/ajg0702/queue/spigot/placeholders/placeholders/QueuedFor.java new file mode 100644 index 0000000..13259e5 --- /dev/null +++ b/spigot/src/main/java/us/ajg0702/queue/spigot/placeholders/placeholders/QueuedFor.java @@ -0,0 +1,62 @@ +package us.ajg0702.queue.spigot.placeholders.placeholders; + +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; +import us.ajg0702.queue.api.spigot.AjQueueSpigotAPI; +import us.ajg0702.queue.spigot.SpigotMain; +import us.ajg0702.queue.spigot.placeholders.Placeholder; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.logging.Level; +import java.util.regex.Matcher; + +public class QueuedFor extends Placeholder { + public QueuedFor(SpigotMain plugin) { + super(plugin); + } + + private final String invalidMessage = "Invalid queue name"; + + private final Map cache = new ConcurrentHashMap<>(); + + @Override + public String getRegex() { + return "queuedfor_(.*)"; + } + + @Override + public String parse(Matcher matcher, OfflinePlayer p) { + String queue = matcher.group(1); + String cached = cache.getOrDefault(queue, "..."); + + Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { + try { + Integer response = AjQueueSpigotAPI.getInstance() + .getPlayersInQueue(queue) + .get(30, TimeUnit.SECONDS); + + cache.put(queue, response + ""); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } catch (TimeoutException e) { + plugin.getLogger().log(Level.WARNING, "Timed out while trying to get placeholder data from proxy: ", e); + } catch (ExecutionException e) { + if(e.getCause() instanceof IllegalArgumentException) { + cache.put(queue, invalidMessage); + } else { + throw new RuntimeException(e); + } + } + }); + + return cached; + } + + @Override + public void cleanCache(Player player) {} +} diff --git a/spigot/src/main/java/us/ajg0702/queue/spigot/placeholders/placeholders/Status.java b/spigot/src/main/java/us/ajg0702/queue/spigot/placeholders/placeholders/Status.java new file mode 100644 index 0000000..af1848d --- /dev/null +++ b/spigot/src/main/java/us/ajg0702/queue/spigot/placeholders/placeholders/Status.java @@ -0,0 +1,62 @@ +package us.ajg0702.queue.spigot.placeholders.placeholders; + +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; +import us.ajg0702.queue.api.spigot.AjQueueSpigotAPI; +import us.ajg0702.queue.spigot.SpigotMain; +import us.ajg0702.queue.spigot.placeholders.Placeholder; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.logging.Level; +import java.util.regex.Matcher; + +public class Status extends Placeholder { + public Status(SpigotMain plugin) { + super(plugin); + } + + private final String invalidMessage = "Invalid queue name"; + + private final Map cache = new ConcurrentHashMap<>(); + + @Override + public String getRegex() { + return "status_(.*)"; + } + + @Override + public String parse(Matcher matcher, OfflinePlayer p) { + String queue = matcher.group(1); + String cached = cache.getOrDefault(queue, "..."); + + Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { + try { + String response = AjQueueSpigotAPI.getInstance() + .getServerStatusString(queue) + .get(30, TimeUnit.SECONDS); + + cache.put(queue, response); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } catch (TimeoutException e) { + plugin.getLogger().log(Level.WARNING, "Timed out while trying to get placeholder data from proxy: ", e); + } catch (ExecutionException e) { + if(e.getCause() instanceof IllegalArgumentException) { + cache.put(queue, invalidMessage); + } else { + throw new RuntimeException(e); + } + } + }); + + return cached; + } + + @Override + public void cleanCache(Player player) {} +}