lots of progress

This commit is contained in:
ajgeiss0702
2021-07-06 17:31:21 -07:00
parent 726bb42bc8
commit ff9a2965c1
14 changed files with 543 additions and 35 deletions
@@ -1,4 +1,6 @@
package us.ajg0702.queue.common; package us.ajg0702.queue.api;
import us.ajg0702.queue.api.players.AdaptedPlayer;
public interface PlatformMethods { public interface PlatformMethods {
/** /**
@@ -10,4 +12,12 @@ public interface PlatformMethods {
*/ */
void sendJoinQueueChannelMessages(); void sendJoinQueueChannelMessages();
/**
* Sends a plugin message on the plugin messaging channel
* @param player The player to send the message through
* @param channel The (sub)channel
* @param data The data
*/
void sendPluginMessage(AdaptedPlayer player, String channel, String... data);
} }
@@ -75,9 +75,9 @@ public interface QueueManager {
/** /**
* Send a chat queue status message to a specific player in a specific queue * Send a chat queue status message to a specific player in a specific queue
* @param player The player that is in the queue * @param queuePlayer The player that is in the queue
*/ */
void sendMessage(QueuePlayer player); void sendMessage(QueuePlayer queuePlayer);
/** /**
* Find a server by its name * Find a server by its name
@@ -0,0 +1,12 @@
package us.ajg0702.queue.api;
import us.ajg0702.queue.api.queues.QueueServer;
import us.ajg0702.queue.api.server.AdaptedServer;
import java.util.List;
public interface ServerBuilder {
List<QueueServer> getServers();
QueueServer buildGroup(String name, List<AdaptedServer> servers);
}
@@ -1,6 +1,7 @@
package us.ajg0702.queue.api.players; package us.ajg0702.queue.api.players;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import us.ajg0702.queue.api.server.AdaptedServer;
import us.ajg0702.queue.api.util.Handle; import us.ajg0702.queue.api.util.Handle;
import java.util.UUID; import java.util.UUID;
@@ -22,6 +23,12 @@ public interface AdaptedPlayer extends Handle {
*/ */
void sendMessage(Component message); void sendMessage(Component message);
/**
* Sends an actionbar message to the player
* @param message The message to send
*/
void sendActionBar(Component message);
/** /**
* Send a player a message from a string * Send a player a message from a string
* Converted to Component internally * Converted to Component internally
@@ -47,4 +54,10 @@ public interface AdaptedPlayer extends Handle {
* @return The player's uuid * @return The player's uuid
*/ */
UUID getUniqueId(); UUID getUniqueId();
/**
* Sends the player to a different server.
* Does not use the queue.
*/
void connect(AdaptedServer server);
} }
@@ -3,6 +3,7 @@ package us.ajg0702.queue.api.queues;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import us.ajg0702.queue.api.players.AdaptedPlayer; import us.ajg0702.queue.api.players.AdaptedPlayer;
import us.ajg0702.queue.api.players.QueuePlayer; import us.ajg0702.queue.api.players.QueuePlayer;
import us.ajg0702.queue.api.server.AdaptedServer;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
@@ -163,7 +164,33 @@ public interface QueueServer {
*/ */
String getAlias(); String getAlias();
/**
* Get the servers that this QueueServer represents
* @return A list of servers that this QueueServer represents
*/
ImmutableList<AdaptedServer> getServers();
/**
* Gets the names of the servers in this group
* @return A list of names
*/
ImmutableList<String> getServerNames();
/**
* Returns if this server is a group
* @return True if this server is a group
*/
boolean isGroup();
/**
* Finds the player in this queue and returns the representative QueuePlayer
* @return The QueuePlayer representing the player, null if not found
*/
QueuePlayer findPlayer(AdaptedPlayer player);
AdaptedServer getIdealServer(AdaptedPlayer player);
/** /**
@@ -0,0 +1,30 @@
package us.ajg0702.queue.api.server;
import us.ajg0702.queue.api.players.AdaptedPlayer;
import java.util.concurrent.CompletableFuture;
public interface AdaptedServer {
/**
* Gets the ServerInfo for this server
* @return The AdaptedServerInfo for this server
*/
AdaptedServerInfo getServerInfo();
/**
* Pings the server and gets info back
* @return A CompletableFuture with the ServerPing
*/
CompletableFuture<AdaptedServerPing> ping();
/**
* If the player can access the server
* Uses bungeecord's restricted server feature
* Will always return true on other platforms
* @param player The player to check
* @return False if the server is restricted and the player does not have permission to join.
*/
boolean canAccess(AdaptedPlayer player);
}
@@ -0,0 +1,11 @@
package us.ajg0702.queue.api.server;
public interface AdaptedServerInfo {
/**
* Gets the name of the server
* @return The name of the server
*/
String getName();
}
@@ -0,0 +1,29 @@
package us.ajg0702.queue.api.server;
import net.kyori.adventure.text.Component;
public interface AdaptedServerPing {
/**
* Gets the component of the description (aka MOTD)
* @return A compoent of the description
*/
Component getDescriptionComponent();
/**
* Gets the description stripped of any color or styling
* @return The description, but no colors
*/
String getPlainDescription();
/**
* Gets the number of players currently online
* @return The number of players online
*/
int getPlayerCount();
/**
* Gets the maximum number of players that can join.
* @return The maximum number of players that can join
*/
int getMaxPlayers();
}
+1 -1
View File
@@ -13,7 +13,7 @@ repositories {
dependencies { dependencies {
compileOnly("net.kyori:adventure-api:4.8.1") compileOnly("net.kyori:adventure-api:4.8.1")
compileOnly("com.google.guava:guava:30.1.1-jre") compileOnly("com.google.guava:guava:30.1.1-jre")
compileOnly("us.ajg0702:ajUtils:1.1.4") compileOnly("us.ajg0702:ajUtils:1.1.5")
implementation(project(":api")) implementation(project(":api"))
} }
@@ -2,12 +2,21 @@ package us.ajg0702.queue.common;
import us.ajg0702.queue.api.AliasManager; import us.ajg0702.queue.api.AliasManager;
import us.ajg0702.queue.api.Logic; import us.ajg0702.queue.api.Logic;
import us.ajg0702.queue.api.PlatformMethods;
import us.ajg0702.queue.api.ServerBuilder;
import us.ajg0702.utils.common.Config; import us.ajg0702.utils.common.Config;
import us.ajg0702.utils.common.Messages; import us.ajg0702.utils.common.Messages;
import java.util.logging.Logger; import java.util.logging.Logger;
public class QueueMain { public class QueueMain {
private double timeBetweenPlayers;
public double getTimeBetweenPlayers() {
return timeBetweenPlayers;
}
private Config config; private Config config;
public Config getConfig() { public Config getConfig() {
return config; return config;
@@ -5,13 +5,14 @@ import us.ajg0702.queue.api.QueueManager;
import us.ajg0702.queue.api.players.AdaptedPlayer; import us.ajg0702.queue.api.players.AdaptedPlayer;
import us.ajg0702.queue.api.players.QueuePlayer; import us.ajg0702.queue.api.players.QueuePlayer;
import us.ajg0702.queue.api.queues.QueueServer; import us.ajg0702.queue.api.queues.QueueServer;
import us.ajg0702.queue.api.server.AdaptedServer;
import us.ajg0702.queue.api.server.AdaptedServerInfo;
import us.ajg0702.queue.common.players.QueuePlayerImpl; import us.ajg0702.queue.common.players.QueuePlayerImpl;
import us.ajg0702.utils.bungee.BungeeUtils; import us.ajg0702.utils.bungee.BungeeUtils;
import us.ajg0702.utils.common.Messages; import us.ajg0702.utils.common.Messages;
import us.ajg0702.utils.common.TimeUtils;
import java.util.ArrayList; import java.util.*;
import java.util.List;
import java.util.Map;
public class QueueManagerImpl implements QueueManager { public class QueueManagerImpl implements QueueManager {
@@ -93,7 +94,7 @@ public class QueueManagerImpl implements QueueManager {
int pos = queuePlayer.getPosition(); int pos = queuePlayer.getPosition();
int len = list.size(); int len = list.size();
boolean sendInstant = main.getConfig().getStringList("send-instantly").contains(server.getName()) || server.isJoinable(p); boolean sendInstant = main.getConfig().getStringList("send-instantly").contains(server.getName()) || server.isJoinable(player);
boolean sendInstantp = list.size() <= 1 && server.canAccess(player); boolean sendInstantp = list.size() <= 1 && server.canAccess(player);
boolean timeGood = !main.getConfig().getBoolean("check-last-player-sent-time") || System.currentTimeMillis() - server.getLastSentTime() > Math.floor(main.getConfig().getDouble("wait-time") * 1000); boolean timeGood = !main.getConfig().getBoolean("check-last-player-sent-time") || System.currentTimeMillis() - server.getLastSentTime() > Math.floor(main.getConfig().getDouble("wait-time") * 1000);
@@ -175,75 +176,253 @@ public class QueueManagerImpl implements QueueManager {
continue; continue;
} }
String groupname = groupraw.split(":")[0]; String groupName = groupraw.split(":")[0];
String[] serversraw = groupraw.split(":")[1].split(","); String[] serversraw = groupraw.split(":")[1].split(",");
if(findServer(groupname) != null) { if(findServer(groupName) != null) {
main.getLogger().warning("The name of a group ('"+groupname+"') cannot be the same as the name of a server!"); main.getLogger().warning("The name of a group ('"+groupName+"') cannot be the same as the name of a server!");
continue; continue;
} }
List<AdaptedServer> groupServers = new ArrayList<>();
for(String serverraw : serversraw) { for(String serverraw : serversraw) {
ServerInfo si = svs.get(serverraw); QueueServer found = findServer(serverraw);
if(si == null) { if(found == null) {
pl.getLogger().warning("Could not find server named '"+serverraw+"' in servergroup '"+groupname+"'!"); main.getLogger().warning("Could not find server named '"+serverraw+"' in servergroup '"+groupName+"'!");
continue; continue;
} }
servers.add(si); if(found.isGroup()) continue;
groupServers.add(found.getServers().get(0));
} }
if(servers.size() == 0) { if(servers.size() == 0) {
pl.getLogger().warning("Server group '"+groupname+"' has no servers! Ignoring it."); main.getLogger().warning("Server group '"+groupName+"' has no servers! Ignoring it.");
continue; continue;
} }
this.servers.add(new QueueServer(groupname, servers)); this.servers.add(main.getServerBuilder().buildGroup(groupName, groupServers));
} }
} }
@Override @Override
public void sendActionBars() { public void sendActionBars() {
if(!main.getConfig().getBoolean("send-actionbar")) return;
for(QueueServer server : servers) {
String status = server.getStatusString();
for(QueuePlayer queuePlayer : server.getQueue()) {
if(!getSingleServer(queuePlayer.getPlayer()).equals(server)) continue;
int pos = queuePlayer.getPosition();
if(pos == 0) {
server.removePlayer(queuePlayer);
continue;
}
AdaptedPlayer player = queuePlayer.getPlayer();
if(player == null) continue;
if(!server.isJoinable(player)) {
queuePlayer.getPlayer().sendActionBar(msgs.getComponent("spigot.actionbar.offline",
"POS:"+pos,
"LEN:"+server.getQueue().size(),
"SERVER:"+server.getAlias(),
"STATUS:"+status
));
} else {
int time = (int) Math.round(pos * main.getTimeBetweenPlayers());
player.sendActionBar(msgs.getComponent("spigot.actionbar.online",
"POS:"+pos,
"LEN:"+server.getQueue().size(),
"SERVER:"+server.getAlias(),
"TIME:"+ TimeUtils.timeString(time, msgs.getString("format.time.mins"), msgs.getString("format.time.secs"))
));
}
}
}
} }
@Override @Override
public void sendQueueEvents() { public void sendQueueEvents() {
for (QueueServer s : servers) {
for (QueuePlayer queuePlayer : s.getQueue()) {
AdaptedPlayer player = queuePlayer.getPlayer();
if (player == null || !player.isConnected()) continue;
main.getPlatformMethods().sendPluginMessage(player, "inqueueevent", "true");
}
}
} }
@Override @Override
public void sendMessages() { public void sendMessages() {
for(QueueServer server : servers) {
for(QueuePlayer queuePlayer : server.getQueue()) {
sendMessage(queuePlayer);
}
}
} }
@Override @Override
public void sendMessage(QueuePlayer player) { public void sendMessage(QueuePlayer queuePlayer) {
AdaptedPlayer player = queuePlayer.getPlayer();
if(player == null || !player.isConnected()) return;
QueueServer server = queuePlayer.getQueueServer();
int pos = queuePlayer.getPosition();
int len = server.getQueue().size();
if(server.isJoinable(player)) {
String status = server.getStatusString(player);
if(msgs.getString("status.offline.base").isEmpty()) return;
player.sendMessage(msgs.getComponent("status.offline.base",
"STATUS:"+status,
"POS:"+pos,
"LEN:"+len,
"SERVER:"+server.getAlias()
));
} else {
if(msgs.getString("status.online.base").isEmpty()) return;
int time = (int) Math.round(pos * main.getTimeBetweenPlayers());
player.sendMessage(msgs.getComponent("status.online.base",
"TIME:" + TimeUtils.timeString(time, msgs.getString("format.time.mins"), msgs.getString("format.time.secs")),
"POS:"+pos,
"LEN:"+len,
"SERVER:"+server.getAlias()
));
}
} }
@Override @Override
public QueueServer findServer(String name) { public QueueServer findServer(String name) {
for(QueueServer server : servers) {
if(server == null) continue;
if(server.getName().equalsIgnoreCase(name)) {
return server;
}
}
return null; return null;
} }
@Override @Override
public void sendPlayers() { public void sendPlayers() {
sendPlayers(null);
} }
@Override HashMap<AdaptedPlayer, Long> sendingNowAntiSpam = new HashMap<>();
public void sendPlayers(QueueServer server) { HashMap<QueuePlayer, Integer> sendingAttempts = new HashMap<>();
@Override
public void sendPlayers(QueueServer queueServer) {
List<QueueServer> sendingServers;
if(queueServer == null) {
sendingServers = new ArrayList<>(servers);
} else {
sendingServers = Collections.singletonList(queueServer);
}
for(QueueServer server : sendingServers) {
if(!server.isOnline()) continue;
if(server.getQueue().size() == 0) continue;
if(main.getConfig().getBoolean("send-all-when-back-online") && server.justWentOnline() && server.isOnline()) {
for(QueuePlayer p : server.getQueue()) {
AdaptedPlayer player = p.getPlayer();
if(player == null) continue;
if(server.isFull() && !p.getPlayer().hasPermission("ajqueue.joinfull")) continue;
AdaptedServer selected = server.getIdealServer(player);
if(selected == null) {
main.getLogger().severe("Could not find ideal server for server/group '"+server.getName()+"'!");
continue;
}
player.sendMessage(msgs.getComponent("status.sending-now", "SERVER:"+server.getAlias()));
player.connect(selected);
}
return;
}
QueuePlayer nextQueuePlayer = server.getQueue().get(0);
AdaptedPlayer nextPlayer = nextQueuePlayer.getPlayer();
// If the first person int the queue is offline or already in the server, find the next online player in the queue
int i = 0;
while((nextPlayer == null || server.getServerNames().contains(nextPlayer.getServerName())) && i < server.getQueue().size()) {
if(nextPlayer != null) { // Remove them if they are already in the server
server.removePlayer(nextQueuePlayer);
} else {
i++;
}
nextQueuePlayer = server.getQueue().get(i);
nextPlayer = nextQueuePlayer.getPlayer();
}
if(nextPlayer == null) continue; // None of the players in the queue are online
if(!server.canAccess(nextPlayer)) continue;
if(server.isFull() && !nextPlayer.hasPermission("ajqueue.joinfull")) continue;
if(main.getConfig().getBoolean("enable-bypasspaused-permission")) {
if(server.isPaused() && !nextPlayer.hasPermission("ajqueue.bypasspaused")) continue;
} else if(server.isPaused()) { continue; }
int tries = sendingAttempts.get(nextQueuePlayer) == null ? 0 : sendingAttempts.get(nextQueuePlayer);
int maxTries = main.getConfig().getInt("max-tries");
if(tries >= maxTries && maxTries > 0) {
server.removePlayer(nextQueuePlayer);
sendingAttempts.remove(nextQueuePlayer);
nextPlayer.sendMessage(msgs.getComponent("max-tries-reached", "SERVER:"+server.getAlias()));
continue;
}
tries++;
sendingAttempts.put(nextQueuePlayer, tries);
if(!sendingNowAntiSpam.containsKey(nextPlayer)) {
sendingNowAntiSpam.put(nextPlayer, (long) 0);
}
if(System.currentTimeMillis() - sendingNowAntiSpam.get(nextPlayer) >= 5000) {
nextPlayer.sendMessage(msgs.getComponent("status.sending-now", "SERVER:"+server.getAlias()));
sendingNowAntiSpam.put(nextPlayer, System.currentTimeMillis());
}
AdaptedServer selected = server.getIdealServer(nextPlayer);
if(selected == null) {
main.getLogger().severe("Could not find ideal server for server/group '"+server.getName()+"'");
continue;
}
nextPlayer.connect(selected);
}
} }
@Override @Override
public ImmutableList<QueuePlayer> findPlayerInQueues(AdaptedPlayer p) { public ImmutableList<QueuePlayer> findPlayerInQueues(AdaptedPlayer p) {
return null; List<QueuePlayer> srs = new ArrayList<>();
for(QueueServer s : servers) {
QueuePlayer player = s.findPlayer(p);
if(player != null) {
srs.add(player);
}
}
return ImmutableList.copyOf(srs);
} }
@Override @Override
public ImmutableList<QueueServer> getPlayerQueues(AdaptedPlayer p) { public ImmutableList<QueueServer> getPlayerQueues(AdaptedPlayer p) {
return null; List<QueueServer> srs = new ArrayList<>();
for(QueueServer s : servers) {
QueuePlayer player = s.findPlayer(p);
if(player != null) {
srs.add(s);
}
}
return ImmutableList.copyOf(srs);
} }
} }
@@ -1,9 +0,0 @@
package us.ajg0702.queue.common;
import us.ajg0702.queue.api.queues.QueueServer;
import java.util.List;
public interface ServerBuilder {
List<QueueServer> getServers();
}
@@ -50,7 +50,7 @@ public class QueuePlayerImpl implements QueuePlayer {
@Override @Override
public void setPlayer(AdaptedPlayer player) { public void setPlayer(AdaptedPlayer player) {
if(!player.getUniqueId().equals(getUniqueId())) { if(player != null && !player.getUniqueId().equals(getUniqueId())) {
throw new IllegalArgumentException("UUIDs do not match"); throw new IllegalArgumentException("UUIDs do not match");
} }
this.player = player; this.player = player;
@@ -0,0 +1,197 @@
package us.ajg0702.queue.common.queues;
import com.google.common.collect.ImmutableList;
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.common.QueueMain;
import us.ajg0702.utils.common.Messages;
import java.util.*;
public class QueueServerImpl implements QueueServer {
public QueueServerImpl(QueueMain main, AdaptedServer server) {
this(main, Collections.singletonList(server));
}
public QueueServerImpl(QueueMain main, List<AdaptedServer> servers) {
this.servers = servers;
this.main = main;
}
QueueMain main;
private List<AdaptedServer> servers;
private final List<QueuePlayer> queue = new ArrayList<>();
@Override
public ImmutableList<QueuePlayer> getQueue() {
return ImmutableList.copyOf(queue);
}
@Override
public String getStatusString(AdaptedPlayer p) {
Messages msgs = main.getMessages();
if(getOfflineTime() > main.getConfig().getInt("offline-time")) {
return msgs.getString("status.offline.offline");
}
if(!isOnline()) {
return msgs.getString("status.offline.restarting");
}
if(isPaused()) {
return msgs.getString("status.offline.paused");
}
if(isFull()) {
return msgs.getString("status.offline.full");
}
if(p != null && !canAccess(p)) {
return msgs.getString("status.offline.restricted");
}
return "online";
}
@Override
public String getStatusString() {
return getStatusString(null);
}
@Override
public void updatePing() {
}
@Override
public int getOfflineTime() {
return 0;
}
@Override
public int getLastSentTime() {
return 0;
}
@Override
public boolean isWhitelisted() {
return false;
}
@Override
public void setWhitelisted(boolean whitelisted) {
}
@Override
public ImmutableList<UUID> getWhitelistedPlayers() {
return null;
}
@Override
public void setWhitelistedPlayers(List<UUID> whitelistedPlayers) {
}
@Override
public boolean isJoinable(AdaptedPlayer p) {
return false;
}
@Override
public void setPaused(boolean paused) {
}
@Override
public boolean isPaused() {
return false;
}
@Override
public boolean isOnline() {
return false;
}
@Override
public boolean justWentOnline() {
return false;
}
@Override
public boolean isFull() {
return false;
}
@Override
public void removePlayer(QueuePlayer player) {
}
@Override
public void removePlayer(AdaptedPlayer player) {
}
@Override
public void addPlayer(QueuePlayer player) {
}
@Override
public void addPlayer(QueuePlayer player, int position) {
}
@Override
public void sendPlayer() {
}
@Override
public String getName() {
return null;
}
@Override
public boolean canAccess(AdaptedPlayer ply) {
return false;
}
@Override
public String getAlias() {
return null;
}
@Override
public ImmutableList<AdaptedServer> getServers() {
return null;
}
@Override
public ImmutableList<String> getServerNames() {
return null;
}
@Override
public boolean isGroup() {
return false;
}
@Override
public QueuePlayer findPlayer(AdaptedPlayer player) {
return null;
}
@Override
public AdaptedServer getIdealServer(AdaptedPlayer player) {
return null;
}
}