Untitled

 avatar
unknown
kotlin
a month ago
2.9 kB
3
Indexable
class LoadBalancerListener(private val proxyServer: ProxyServer) {

    @Subscribe
    fun onPlayerChooseInitial(event: PlayerChooseInitialServerEvent) = runBlocking {
        val player = event.player
        println("Preparing to choose initial server for ${player.username}")

        val bestServer = singularityClient.servers.listAll()
            .asSequence()
            .filter { it.pipeline == StatePipeline.READY_TO_USE }
            .filter { it.blueprint.containerProps.containsKey("initial-server") }
            .minByOrNull { it.report?.onlineCount ?: Int.MAX_VALUE }

        println("Found best server: $bestServer")

        if (bestServer == null) {
            val message = Language.get("singularity.proxy.load-balancer.no-servers-found")
            return@runBlocking player.disconnect(Component.text(message))
        }

        proxyServer.getServer(bestServer.serverId).ifPresent {
            println("Found server: $it")
            event.setInitialServer(it)
        }

        println("Finished!")
    }

    @Subscribe
    fun onPlayerKickedFromServer(event: KickedFromServerEvent) = runBlocking {
        val message = Language.get("singularity.proxy.load-balancer.kicked-no-servers-found")
        val servers = singularityClient.servers.listAll()
        if (servers.isEmpty()) {
            event.result = KickedFromServerEvent.DisconnectPlayer.create(Component.text(message))
            return@runBlocking
        }

        val gameServerKicked = servers.firstOrNull { it.serverPort == event.server.serverInfo.address.port }
            ?: return@runBlocking redirectToBestLobbyOrDisconnect(servers, event, message)

        gameServerKicked.blueprint.containerProps["fallback-blueprint"]?.let { fallbackBlueprintId ->
            val gameServerFallback = servers.firstOrNull { server -> server.blueprint.id == fallbackBlueprintId }
            gameServerFallback?.let {
                return@runBlocking proxyServer.getServer(it.serverId).ifPresent { server ->
                    event.result = KickedFromServerEvent.RedirectPlayer.create(server)
                }
            }
        }

        redirectToBestLobbyOrDisconnect(servers, event, message)
    }

    private fun redirectToBestLobbyOrDisconnect(
        servers: List<GameServer>,
        event: KickedFromServerEvent,
        message: String
    ) {
        val bestLobby = servers
            .filter { it.blueprint.id == "lobby" }
            .minByOrNull { it.report?.onlineCount ?: Int.MAX_VALUE }

        if (bestLobby == null) {
            event.result = KickedFromServerEvent.DisconnectPlayer.create(Component.text(message))
        } else {
            proxyServer.getServer(bestLobby.serverId).ifPresent {
                event.result = KickedFromServerEvent.RedirectPlayer.create(it)
            }
        }
    }
}
Leave a Comment