diff --git a/src/main/kotlin/cc/lixou/stracciatella/Stracciatella.kt b/src/main/kotlin/cc/lixou/stracciatella/Stracciatella.kt index 4a42cc6..026096d 100644 --- a/src/main/kotlin/cc/lixou/stracciatella/Stracciatella.kt +++ b/src/main/kotlin/cc/lixou/stracciatella/Stracciatella.kt @@ -1,7 +1,9 @@ package cc.lixou.stracciatella +import cc.lixou.stracciatella.game.GameManager import net.minestom.server.MinecraftServer import net.minestom.server.coordinate.Pos +import net.minestom.server.event.player.PlayerDisconnectEvent import net.minestom.server.event.player.PlayerLoginEvent import net.minestom.server.instance.block.Block @@ -19,6 +21,9 @@ class Stracciatella { } val eventHandler = MinecraftServer.getGlobalEventHandler() + eventHandler.addListener(PlayerDisconnectEvent::class.java) { event -> + GameManager.unregisterPlayer(event.player) + } eventHandler.addListener(PlayerLoginEvent::class.java) { event -> val player = event.player event.setSpawningInstance(instanceContainer) diff --git a/src/main/kotlin/cc/lixou/stracciatella/game/Game.kt b/src/main/kotlin/cc/lixou/stracciatella/game/Game.kt new file mode 100644 index 0000000..fc0b46e --- /dev/null +++ b/src/main/kotlin/cc/lixou/stracciatella/game/Game.kt @@ -0,0 +1,48 @@ +package cc.lixou.stracciatella.game + +import net.minestom.server.entity.Player +import net.minestom.server.event.EventFilter +import net.minestom.server.event.EventNode +import net.minestom.server.event.trait.PlayerEvent +import net.minestom.server.instance.Instance +import world.cepi.kstom.Manager +import java.util.* + +abstract class Game { + + protected val players = ArrayList() + protected lateinit var instance: Instance + protected val uuid: UUID = UUID.randomUUID() + protected val eventNode = + EventNode.type("${this.javaClass.simpleName}-${uuid}", EventFilter.INSTANCE) { event, instance -> + if (event is PlayerEvent) { + return@type players.contains(event.player) + } else { + return@type this.instance.uniqueId.equals(instance) + } + } + + init { + Manager.globalEvent.addChild(eventNode) + } + + /** + * @param players the players that should join + * @return false if game is full, then creates new instance + */ + abstract fun canJoin(players: Array): Boolean + + abstract fun onJoin(player: Player) + abstract fun onLeave(player: Player) + + fun addPlayers(players: Array) { + this.players.addAll(players) + players.forEach { onJoin(it) } + } + + fun removePlayer(player: Player) { + this.players.remove(player) + onLeave(player) + } + +} \ No newline at end of file diff --git a/src/main/kotlin/cc/lixou/stracciatella/game/GameManager.kt b/src/main/kotlin/cc/lixou/stracciatella/game/GameManager.kt new file mode 100644 index 0000000..be0bdfd --- /dev/null +++ b/src/main/kotlin/cc/lixou/stracciatella/game/GameManager.kt @@ -0,0 +1,44 @@ +package cc.lixou.stracciatella.game + +import net.minestom.server.entity.Player +import java.util.concurrent.ConcurrentHashMap +import kotlin.reflect.KClass +import kotlin.reflect.full.primaryConstructor + +object GameManager { + + private val playerGame: ConcurrentHashMap = ConcurrentHashMap() + private val games: ConcurrentHashMap, ArrayList> = ConcurrentHashMap() + + fun unregisterPlayer(player: Player) { + playerGame[player]?.removePlayer(player) + playerGame.remove(player) + } + + inline fun joinGame(players: Array) = joinGame(T::class, players) + + fun joinGame(clazz: KClass, players: Array) { + val game: Game = games[clazz]?.find { it.canJoin(players) } + ?: createGame(clazz) + players.forEach { + playerGame[it]?.removePlayer(it) + playerGame[it] = game + } + game.addPlayers(players) + } + + private fun createGame(clazz: KClass): Game { + val game: T = clazz.primaryConstructor?.call() + ?: throw java.lang.IllegalArgumentException("Game ${clazz.simpleName} has wrong constructor as a Game") + games[clazz]?.add(game) + return game + } + + inline fun registerGame() = registerGame(T::class) + + fun registerGame(clazz: KClass) { + if (games.containsKey(clazz)) return + games[clazz] = ArrayList() + } + +} \ No newline at end of file