Skip to content

Commit

Permalink
- fixed a bug where a player disconnects and and is still queued
Browse files Browse the repository at this point in the history
- code readability
  • Loading branch information
bierdosenhalter committed Oct 1, 2024
1 parent c00b17b commit 016c714
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 45 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
plugin_version=3.0.0-INDEV
plugin_version=3.0.1-INDEV
velocity_api_version=3.3.0-SNAPSHOT
minecraft_version=1.20.6
13 changes: 9 additions & 4 deletions src/main/java/org/zeroBzeroT/anarchyqueue/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,24 @@
import java.nio.file.Path;

public class Config {

public static String serverMain = null;

public static String serverQueue = null;

public static String name = null; // TODO: not in use, implement or remove this

public static int maxPlayers = 0;

public static String messagePosition = null;

public static String messageConnecting = null;

public static String messageFull = null;

public static String messageOffline = null;

public static boolean kick = true; // TODO: not in use, implement or remove this

public static int waitOnKick = 0; // TODO: not in use, implement or remove this

/**
Expand All @@ -27,7 +35,6 @@ public class Config {
* @param path Path to the plugin data folder
*/
static void loadConfig(Path path) throws IOException {

File file = new File(path.toFile(), "config.toml");

if (!file.getParentFile().exists()) {
Expand Down Expand Up @@ -58,7 +65,5 @@ static void loadConfig(Path path) throws IOException {
messageOffline = toml.getString("message-offline", "Server is currently down!");
kick = toml.getBoolean("kick", true);
waitOnKick = toml.getLong("wait-on-kick", 16L).intValue();

}

}
9 changes: 6 additions & 3 deletions src/main/java/org/zeroBzeroT/anarchyqueue/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,14 @@
url = "https://github.com/zeroBzeroT/AnarchyQueue",
authors = {"bierdosenhalter", "nothub"}
)
public class Main {

public class Main {
private static Main instance;

public final Logger log;

private final ProxyServer server;

private final Path dataDir;

@Inject
Expand All @@ -37,7 +38,9 @@ public Main(ProxyServer server, CommandManager commandManager, Logger logger, @D
}

public static Main getInstance() {
if (instance == null) throw new IllegalStateException("instance was null!");
if (instance == null)
throw new IllegalStateException("instance was null!");

return instance;
}

Expand All @@ -51,9 +54,9 @@ public void onProxyInitialize(ProxyInitializeEvent event) {
server.shutdown();
return;
}

// Register queue
Queue queue = new Queue(server);
server.getEventManager().register(this, queue);
}

}
98 changes: 61 additions & 37 deletions src/main/java/org/zeroBzeroT/anarchyqueue/Queue.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,110 +21,134 @@
// https://jd.papermc.io/velocity/3.3.0/com/velocitypowered/api/event/package-summary.html

public class Queue {

private final Logger log;

private final ProxyServer proxyServer;

/**
* We dont use ConcurrentLinkedQueue for this because we want index based access to players.
* We don't use ConcurrentLinkedQueue for this because we want index-based access to players.
*/
private final List<Player> queuedPlayers = new CopyOnWriteArrayList<>();

public Queue(ProxyServer proxyServer) {
this.log = Main.getInstance().log;
this.proxyServer = proxyServer;

// process queue
proxyServer.getScheduler()
.buildTask(Main.getInstance(), this::process)
.delay(Duration.ofSeconds(1))
.repeat(Duration.ofSeconds(1))
.schedule();
.buildTask(Main.getInstance(), this::process)
.delay(Duration.ofSeconds(1))
.repeat(Duration.ofSeconds(1))
.schedule();
}

@Subscribe
public void onServerConnectedEvent(ServerConnectedEvent e) {
if (!e.getServer().getServerInfo().getName().equals(Config.serverQueue)) return;
log.info("queuing " + e.getPlayer().getUsername() + " (" + e.getPlayer().getUniqueId().toString() + ")");
if (!e.getServer().getServerInfo().getName().equals(Config.serverQueue))
return;

log.info("Queuing " + e.getPlayer().getUsername() + " (" + e.getPlayer().getUniqueId().toString() + ")");
queuedPlayers.add(e.getPlayer());
}

public void process() {
// check queue server reachability
final RegisteredServer serverQueue;

try {
serverQueue = getServer(Config.serverQueue);
} catch (ServerNotReachableException e) {
log.warn(e.getMessage());
return;
}

// skip if no players queued
if (queuedPlayers.isEmpty()) return;
// check main server reachability
if (queuedPlayers.isEmpty())
return;

// check the main server reachability
final RegisteredServer serverMain;

try {
serverMain = getServer(Config.serverMain);
} catch (ServerNotReachableException e) {
if (Instant.now().getEpochSecond() % 10 == 0) {
serverQueue.getPlayersConnected().forEach(queuedPlayer ->
queuedPlayer.sendMessage(Identity.nil(), Component.text(
Config.messageOffline
)));
queuedPlayer.sendMessage(Identity.nil(), Component.text(
Config.messageOffline
)));
}
return;
}

// check main server full
boolean full = serverMain.getPlayersConnected().size() >= Config.maxPlayers;
// send infos every 10 seconds

// send info every 10 seconds
if (Instant.now().getEpochSecond() % 10 == 0) {
sendInfos(serverQueue, full);
sendInfo(serverQueue, full);
}
if (full) return;

if (full)
return;

// connect next player
UUID uuid = queuedPlayers.get(0).getUniqueId();
log.info("processing " + uuid.toString());
UUID uuid = queuedPlayers.getFirst().getUniqueId();

log.info("Processing " + uuid.toString());

// lookup player from queue server and ping to be safe the player is connected
serverQueue.getPlayersConnected().stream()
.filter(p -> p.getUniqueId().equals(uuid))
.findAny().ifPresent(p -> {
p.sendMessage(Identity.nil(), Component.text(Config.messageConnecting));
try {
if (p.createConnectionRequest(serverMain).connect().get().isSuccessful()) queuedPlayers.remove(0);
} catch (InterruptedException | ExecutionException e) {
log.error("unable to connect " + p.getUsername() + "(" + p.getUniqueId().toString() + ") to " + Config.serverMain + ": " + e.getMessage());
}
});
.filter(p -> p.getUniqueId().equals(uuid))
.findAny().ifPresentOrElse(p -> {
p.sendMessage(Identity.nil(), Component.text(Config.messageConnecting));
try {
if (p.createConnectionRequest(serverMain).connect().get().isSuccessful()) queuedPlayers.removeFirst();
} catch (InterruptedException | ExecutionException e) {
log.error("Unable to connect " + p.getUsername() + "(" + p.getUniqueId().toString() + ") to " + Config.serverMain + ": " + e.getMessage());
}
},
() -> {
log.error("Unable to connect " + queuedPlayers.getFirst().getUsername() + "(" + queuedPlayers.getFirst().getUniqueId().toString() + ") to " + Config.serverMain + ": player is not connected to " + serverQueue.getServerInfo().getName());
queuedPlayers.removeFirst();
}
);
}

private void sendInfos(RegisteredServer serverQueue, boolean full) {
private void sendInfo(RegisteredServer serverQueue, boolean full) {
for (int i = 0; i < queuedPlayers.size(); i++) {
queuedPlayers
.get(i)
.sendMessage(Identity.nil(), Component.text(
Config.messagePosition + (i + 1) + "/" + queuedPlayers.size()
));
.get(i)
.sendMessage(Identity.nil(), Component.text(
Config.messagePosition + (i + 1) + "/" + queuedPlayers.size()
));
}

if (full) {
serverQueue.getPlayersConnected().forEach(queuedPlayer ->
queuedPlayer.sendMessage(Identity.nil(), Component.text(
Config.messageFull
)));
queuedPlayer.sendMessage(Identity.nil(), Component.text(
Config.messageFull
)));
}
}

private RegisteredServer getServer(String name) throws ServerNotReachableException {
// get server configured in velocity.toml by name
Optional<RegisteredServer> serverOpt = proxyServer.getServer(name);
if (!serverOpt.isPresent()) {

if (serverOpt.isEmpty()) {
throw new ServerNotReachableException("Server " + name + " is not configured!");
}

final RegisteredServer server = serverOpt.get();

// test server availability by pinging
try {
server.ping().get();
} catch (InterruptedException | ExecutionException e) {
throw new ServerNotReachableException("Server " + name + " is not reachable: " + e.getMessage());
}

return server;
}

}

0 comments on commit 016c714

Please sign in to comment.