Skip to content

Commit 884345c

Browse files
committed
feat: swap to counts and lists for game tracking
1 parent 24f5059 commit 884345c

File tree

6 files changed

+34
-66
lines changed

6 files changed

+34
-66
lines changed

build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ repositories {
1717
}
1818

1919
dependencies {
20-
api("dev.emortal.minestom:core:7b59658")
20+
api("dev.emortal.minestom:core:844abe4")
2121
}
2222

2323
java {

src/main/java/dev/emortal/minestom/gamesdk/MinestomGameServerImpl.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,11 +90,11 @@ static final class BuilderImpl implements Builder, Builder.EndStep {
9090

9191
MessagingModule messaging = moduleProvider.getModule(MessagingModule.class);
9292
KubernetesModule kubernetesModule = moduleProvider.getModule(KubernetesModule.class);
93-
boolean hasAgones = kubernetesModule != null && kubernetesModule.getSdk() != null;
93+
boolean hasAgones = kubernetesModule != null && kubernetesModule.getAgonesSdk() != null;
9494

9595
GameManager gameManager = new GameManager(config);
9696
if (!TEST_MODE && hasAgones) {
97-
gameManager.addGameStatusListener(new AgonesGameStatusListener(config, kubernetesModule.getSdk()));
97+
gameManager.addGameStatusListener(new AgonesGameStatusListener(gameManager, kubernetesModule));
9898
}
9999

100100
if (messaging != null) {

src/main/java/dev/emortal/minestom/gamesdk/config/GameSdkConfig.java

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,9 @@
88
* The configuration that the game manager will use to create and manage games.
99
*
1010
* @param minPlayers the minimum players required for a game to start
11-
* @param maxGames the maximum games that may run on the server at one time
1211
* @param gameCreator a function that can be called to create a game instance
1312
*/
14-
public record GameSdkConfig(int minPlayers, int maxGames, int minTrackingInterval, int maxTrackingInterval,
13+
public record GameSdkConfig(int minPlayers, int minTrackingInterval, int maxTrackingInterval,
1514
FinishBehaviour finishBehaviour, @NotNull GameCreator gameCreator) {
1615

1716
public static @NotNull Builder builder() {
@@ -20,12 +19,7 @@ public record GameSdkConfig(int minPlayers, int maxGames, int minTrackingInterva
2019

2120
public interface Builder {
2221

23-
@NotNull MaxGamesStep minPlayers(int minPlayers);
24-
25-
interface MaxGamesStep {
26-
27-
@NotNull GameCreatorStep maxGames(int maxGames);
28-
}
22+
@NotNull GameCreatorStep minPlayers(int minPlayers);
2923

3024
interface GameCreatorStep {
3125

@@ -44,27 +38,20 @@ interface EndStep {
4438
}
4539
}
4640

47-
private static final class BuilderImpl implements Builder, Builder.MaxGamesStep, Builder.GameCreatorStep, Builder.EndStep {
41+
private static final class BuilderImpl implements Builder, Builder.GameCreatorStep, Builder.EndStep {
4842

4943
private int minPlayers;
50-
private int maxGames;
5144
private int minTrackingInterval = GameTracker.DEFAULT_MIN_UPDATE_INTERVAL;
5245
private int maxTrackingInterval = GameTracker.DEFAULT_MAX_UPDATE_INTERVAL;
5346
private FinishBehaviour finishBehaviour = FinishBehaviour.LOBBY;
5447
private GameCreator gameCreator;
5548

5649
@Override
57-
public @NotNull MaxGamesStep minPlayers(int minPlayers) {
50+
public @NotNull GameCreatorStep minPlayers(int minPlayers) {
5851
this.minPlayers = minPlayers;
5952
return this;
6053
}
6154

62-
@Override
63-
public @NotNull GameCreatorStep maxGames(int maxGames) {
64-
this.maxGames = maxGames;
65-
return this;
66-
}
67-
6855
@Override
6956
public @NotNull GameCreatorStep minTrackingInterval(int interval) {
7057
this.minTrackingInterval = interval;
@@ -91,7 +78,7 @@ private static final class BuilderImpl implements Builder, Builder.MaxGamesStep,
9178

9279
@Override
9380
public @NotNull GameSdkConfig build() {
94-
return new GameSdkConfig(this.minPlayers, this.maxGames, this.minTrackingInterval, this.maxTrackingInterval,
81+
return new GameSdkConfig(this.minPlayers, this.minTrackingInterval, this.maxTrackingInterval,
9582
this.finishBehaviour, this.gameCreator);
9683
}
9784
}

src/main/java/dev/emortal/minestom/gamesdk/game/GameProvider.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,6 @@
77
public interface GameProvider {
88

99
@Nullable Game findGame(@NotNull Player player);
10+
11+
int getGameCount();
1012
}

src/main/java/dev/emortal/minestom/gamesdk/internal/GameManager.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,11 @@ private void kickAllRemainingPlayers(@NotNull Game game) {
151151
return null;
152152
}
153153

154+
@Override
155+
public int getGameCount() {
156+
return this.games.size();
157+
}
158+
154159
public @NotNull Set<Game> getGames() {
155160
return this.games;
156161
}

src/main/java/dev/emortal/minestom/gamesdk/internal/listener/AgonesGameStatusListener.java

Lines changed: 19 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,16 @@
22

33
import dev.agones.sdk.AgonesSDKProto;
44
import dev.agones.sdk.SDKGrpc;
5+
import dev.agones.sdk.beta.BetaAgonesSDKProto;
56
import dev.emortal.api.agonessdk.IgnoredStreamObserver;
7+
import dev.emortal.minestom.core.module.kubernetes.KubernetesModule;
68
import dev.emortal.minestom.gamesdk.config.GameSdkConfig;
79
import dev.emortal.minestom.gamesdk.game.Game;
10+
811
import java.util.concurrent.atomic.AtomicBoolean;
912
import java.util.concurrent.atomic.AtomicInteger;
1013

14+
import dev.emortal.minestom.gamesdk.game.GameProvider;
1115
import net.minestom.server.MinecraftServer;
1216
import org.jetbrains.annotations.NotNull;
1317
import org.slf4j.Logger;
@@ -16,56 +20,26 @@
1620
public final class AgonesGameStatusListener implements GameStatusListener {
1721
private static final Logger LOGGER = LoggerFactory.getLogger(AgonesGameStatusListener.class);
1822

19-
private final @NotNull GameSdkConfig config;
23+
private final @NotNull GameProvider gameProvider;
24+
private final @NotNull KubernetesModule kubeModule;
2025
private final @NotNull SDKGrpc.SDKStub sdk;
2126

22-
private final AtomicInteger gameCount = new AtomicInteger(0);
23-
private final AtomicBoolean shouldAllocate = new AtomicBoolean(false);
24-
25-
public AgonesGameStatusListener(@NotNull GameSdkConfig config, @NotNull SDKGrpc.SDKStub sdk) {
26-
this.config = config;
27-
this.sdk = sdk;
28-
}
29-
30-
@Override
31-
public void onGameAdded(@NotNull Game game) {
32-
int newGameCount = this.gameCount.incrementAndGet();
33-
this.updateShouldAllocate(newGameCount);
27+
public AgonesGameStatusListener(@NotNull GameProvider gameProvider, @NotNull KubernetesModule kubeModule) {
28+
this.kubeModule = kubeModule;
29+
this.gameProvider = gameProvider;
30+
this.sdk = kubeModule.getAgonesSdk();
3431
}
3532

3633
@Override
3734
public void onGameRemoved(@NotNull Game game) {
38-
int newGameCount = this.gameCount.decrementAndGet();
39-
this.updateShouldAllocate(newGameCount);
40-
this.updateReadyIfEmpty(newGameCount);
41-
}
42-
43-
private void updateShouldAllocate(int gameCount) {
44-
boolean allocate = gameCount < this.config.maxGames();
45-
46-
boolean changed = this.shouldAllocate.getAndSet(allocate) != allocate;
47-
// If the current value is the same as the new value, don't bother updating
48-
if (!changed) return;
49-
50-
LOGGER.info("Updating should allocate to {} (game count: {})", allocate, gameCount);
51-
52-
AgonesSDKProto.KeyValue keyValue = AgonesSDKProto.KeyValue.newBuilder()
53-
.setKey("should-allocate")
54-
.setValue(String.valueOf(allocate))
55-
.build();
56-
Thread.startVirtualThread(() -> this.sdk.setLabel(keyValue, new IgnoredStreamObserver<>()));
57-
}
58-
59-
private void updateReadyIfEmpty(int gameCount) {
60-
int playerCount = MinecraftServer.getConnectionManager().getOnlinePlayers().size();
61-
if (playerCount > 0) return;
62-
63-
if (gameCount > 0) {
64-
// This is really weird. This would only happen if a game didn't unregister itself properly.
65-
LOGGER.warn("No players online, but there are still games running.");
66-
}
67-
68-
LOGGER.info("Marking server as ready as no players are online.");
69-
Thread.startVirtualThread(() -> this.sdk.ready(AgonesSDKProto.Empty.getDefaultInstance(), new IgnoredStreamObserver<>()));
35+
Thread.startVirtualThread(() -> {
36+
this.kubeModule.updateAgonesCounter("games", -1);
37+
this.kubeModule.removeFromAgonesList("games", game.getCreationInfo().id());
38+
39+
if (this.gameProvider.getGameCount() == 0) {
40+
LOGGER.info("Marking server as ready as no players are online.");
41+
Thread.startVirtualThread(() -> this.sdk.ready(AgonesSDKProto.Empty.getDefaultInstance(), new IgnoredStreamObserver<>()));
42+
}
43+
});
7044
}
7145
}

0 commit comments

Comments
 (0)