From bb4f94af756459b53581170b40e30cfbab477cec Mon Sep 17 00:00:00 2001 From: FluxCapacitor2 <31071265+FluxCapacitor2@users.noreply.github.com> Date: Tue, 24 Dec 2024 23:57:01 -0500 Subject: [PATCH] Wait 2 minutes before forcefully removing inactive instances --- .../kotlin/com/bluedragonmc/server/Game.kt | 25 ++++++++++++++++--- .../server/utils/InstanceUtils.kt | 10 +++----- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/common/src/main/kotlin/com/bluedragonmc/server/Game.kt b/common/src/main/kotlin/com/bluedragonmc/server/Game.kt index b152ea4..f1e9d40 100644 --- a/common/src/main/kotlin/com/bluedragonmc/server/Game.kt +++ b/common/src/main/kotlin/com/bluedragonmc/server/Game.kt @@ -41,6 +41,7 @@ import net.minestom.server.event.server.ServerTickMonitorEvent import net.minestom.server.event.trait.InstanceEvent import net.minestom.server.event.trait.PlayerEvent import net.minestom.server.instance.Instance +import net.minestom.server.tag.Tag import net.minestom.server.timer.ExecutionType import net.minestom.server.utils.async.AsyncUtils import org.slf4j.Logger @@ -378,6 +379,16 @@ abstract class Game(val name: String, val mapName: String, val mode: String? = n */ private val INSTANCE_CLEANUP_PERIOD = System.getenv("SERVER_INSTANCE_CLEANUP_PERIOD")?.toLongOrNull() ?: 10_000L + /** + * Instances must be inactive for at least 2 minutes + * to be cleaned up (by default). + */ + private val CLEANUP_MIN_INACTIVE_TIME = + System.getenv("SERVER_INSTANCE_MIN_INACTIVE_TIME")?.toLongOrNull() ?: 120_000L + + private val INACTIVE_SINCE_TAG = Tag.Long("instance_inactive_since") + + fun findGame(player: Player): Game? = games.find { player in it.players || it.ownsInstance(player.instance ?: return@find false) } @@ -407,10 +418,18 @@ abstract class Game(val name: String, val mapName: String, val mode: String? = n instances.forEach { instance -> val owner = games.find { it.ownsInstance(instance) } - if (owner == null && games.none { it.getRequiredInstances().contains(instance) }) { - logger.info("Removing orphan instance ${instance.uniqueId} (${instance})") - InstanceUtils.forceUnregisterInstance(instance) + if (owner != null || games.any { instance in it.getRequiredInstances() }) { + return@forEach + } + if (!instance.hasTag(INACTIVE_SINCE_TAG)) { + instance.setTag(INACTIVE_SINCE_TAG, System.currentTimeMillis()) + return@forEach } + if (System.currentTimeMillis() - instance.getTag(INACTIVE_SINCE_TAG) <= CLEANUP_MIN_INACTIVE_TIME) { + return@forEach + } + logger.info("Removing orphan instance ${instance.uniqueId} (${instance})") + InstanceUtils.forceUnregisterInstance(instance) } } } diff --git a/common/src/main/kotlin/com/bluedragonmc/server/utils/InstanceUtils.kt b/common/src/main/kotlin/com/bluedragonmc/server/utils/InstanceUtils.kt index 7b17ec4..5350da7 100644 --- a/common/src/main/kotlin/com/bluedragonmc/server/utils/InstanceUtils.kt +++ b/common/src/main/kotlin/com/bluedragonmc/server/utils/InstanceUtils.kt @@ -4,8 +4,6 @@ import com.bluedragonmc.api.grpc.CommonTypes.GameType.GameTypeFieldSelector import com.bluedragonmc.api.grpc.gameType import com.bluedragonmc.server.Game import com.bluedragonmc.server.api.Environment -import com.bluedragonmc.server.module.instance.InstanceModule -import com.bluedragonmc.server.module.minigame.SpawnpointModule import net.kyori.adventure.text.Component import net.minestom.server.MinecraftServer import net.minestom.server.event.EventNode @@ -52,12 +50,10 @@ object InstanceUtils { // If the instance is not empty, attempt to send all players to a lobby val lobby = Game.games.find { it.name == Environment.defaultGameName } if (lobby != null) { - val lobbyInstanceOf = lobby.getModule()::getSpawningInstance - val spawnpointOf = lobby.getModule().spawnpointProvider::getSpawnpoint return CompletableFuture.allOf( - *instance.players - .map { it.setInstance(lobbyInstanceOf(it), spawnpointOf(it)) } - .toTypedArray() + *instance.players.map { + lobby.addPlayer(it, sendPlayer = true) + }.toTypedArray() ) } else { // If there's no lobby, repeatedly queue players for a lobby on another server