Skip to content

Commit

Permalink
semaphore fix and some console output (still without colors)
Browse files Browse the repository at this point in the history
  • Loading branch information
bierdosenhalter committed Oct 5, 2024
1 parent 0078768 commit 2fe79bb
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 37 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.2-INDEV
plugin_version=3.0.3-INDEV
velocity_api_version=3.3.0-SNAPSHOT
minecraft_version=1.20.6
114 changes: 79 additions & 35 deletions src/main/java/org/zeroBzeroT/anarchyqueue/Queue.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import com.velocitypowered.api.event.Subscribe;
import com.velocitypowered.api.event.player.ServerConnectedEvent;
import com.velocitypowered.api.proxy.Player;
import com.velocitypowered.api.proxy.ProxyServer;
import com.velocitypowered.api.proxy.server.RegisteredServer;
import net.kyori.adventure.identity.Identity;
Expand All @@ -26,37 +25,58 @@ public class Queue {

private final ProxyServer proxyServer;

private final Semaphore processSemaphore = new Semaphore(1);
private final Semaphore queueSemaphore = new Semaphore(1);

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

/**
* Initializes a queue
*/
public Queue(ProxyServer proxyServer) {
this.log = Main.getInstance().log;
this.proxyServer = proxyServer;

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

/**
* This event is called once a connection to a server is fully operational.
* Add a Player to the queue if they join the queue server.
*/
@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() + ")");
queuedPlayers.add(new QueuedPlayer(e.getPlayer(), System.currentTimeMillis()));
}
var queuedPlayer = new QueuedPlayer(e.getPlayer(), System.currentTimeMillis());

public void process() {
if (!processSemaphore.tryAcquire()) return;
if (queuedPlayers.contains(queuedPlayer))
return;

// Add Player to queue
try {
queueSemaphore.acquire();
queuedPlayers.add(queuedPlayer);
log.info("\u00A7f" + e.getPlayer().getUsername() + "\u00A73 was added to the §dplayer queue\u00A73. Queue count is " + queuedPlayers.size() + ".");
} catch (InterruptedException e1) {
e1.printStackTrace();
} finally {
queueSemaphore.release();
}
}

/**
* Try to connect one player to the server
*/
public void flushQueue() {
// check queue server reachability
final RegisteredServer serverQueue;

Expand All @@ -67,7 +87,7 @@ public void process() {
return;
}

// skip if no players queued
// Ignore if queue is empty
if (queuedPlayers.isEmpty())
return;

Expand Down Expand Up @@ -97,35 +117,59 @@ public void process() {
if (full)
return;

QueuedPlayer currPlayer = queuedPlayers.getFirst();
try {
queueSemaphore.acquire();

//wait till delay has passed
if (currPlayer.joinTime() + Config.joinDelay > System.currentTimeMillis())
return;
QueuedPlayer currPlayer = null;

// connect next player
UUID uuid = currPlayer.player().getUniqueId();
// try to find the first player that got not kicked recently
for (QueuedPlayer testPlayer : queuedPlayers) {
if (testPlayer.queueTime() + Config.joinDelay > System.currentTimeMillis())
continue;

log.info("Processing " + uuid.toString());
currPlayer = testPlayer;
break;
}

if (currPlayer == null) {
queueSemaphore.release();
return;
}

// lookup player from queue server and ping to be safe the player is connected
serverQueue.getPlayersConnected().stream()
.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());
// connect next player
UUID uuid = currPlayer.player().getUniqueId();

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

// lookup player from queue server and ping to be safe the player is connected
QueuedPlayer finalCurrPlayer = currPlayer;

serverQueue.getPlayersConnected().stream()
.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();
log.info("\u00A7f" + p.getUsername() + "\u00A73 connected to server §b" + serverMain.getServerInfo().getName() + "\u00A73. Queue count is " + serverQueue.getPlayersConnected().size() + ". Main count is " + (serverMain.getPlayersConnected().size()) + " of " + Config.maxPlayers + ".");
}
} catch (InterruptedException | ExecutionException e) {
log.error("\u00A7f" + p.getUsername() + "s\u00A7c connection to server §b" + Config.serverMain + "\u00A7c failed: " + e.getMessage());
// FIXME: requeue
queuedPlayers.removeFirst();
queuedPlayers.add(new QueuedPlayer(finalCurrPlayer.player(), System.currentTimeMillis()));
}
},
() -> {
log.error("\u00A7f" + finalCurrPlayer.player().getUsername() + "s\u00A7c connection to server §b" + Config.serverMain + "\u00A7c failed: player is not connected to " + serverQueue.getServerInfo().getName());
queuedPlayers.removeFirst();
}
},
() -> {
log.error("Unable to connect " + currPlayer.player().getUsername() + "(" + currPlayer.player().getUniqueId().toString() + ") to " + Config.serverMain + ": player is not connected to " + serverQueue.getServerInfo().getName());
queuedPlayers.removeFirst();
}
);

processSemaphore.release();
);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
queueSemaphore.release();
}
}

private void sendInfo(RegisteredServer serverQueue, boolean full) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@

import com.velocitypowered.api.proxy.Player;

public record QueuedPlayer(Player player, long joinTime) {
public record QueuedPlayer(Player player, long queueTime) {
}

0 comments on commit 2fe79bb

Please sign in to comment.