본문 바로가기
마인크래프트/플러그인 제작 강좌(코틀린)

[코틀린으로 마크 플러그인 개발하기] 이벤트 처리하기(플레이어 데이터 저장하기 2편)

by Zepelown 2023. 7. 8.

마인크래프트 1.20.1 버전 Spigot 기준으로 진행되고 있습니다.

 

이전 화

[코틀린으로 마크 플러그인 개발하기] 플레이어 데이터 저장하기 1편(플레이어 데이터 관리 및 패키지 구조화) (tistory.com)

 

[코틀린으로 마크 플러그인 개발하기] 플레이어 데이터 저장하기 1편(플레이어 데이터 관리 및

마인크래프트 1.20.1 버전 기준으로 진행되고 있습니다. 이전 화 [코틀린으로 마크 플러그인 개발하기] 개요 (tistory.com) [코틀린으로 마크 플러그인 개발하기] 개요 이전 화 [코틀린으로 마크 플러

zepelown.tistory.com


1. 시작 전 수정 사항

이전 강의에서 PlayerManager를 싱글톤으로 구현하기 위해 다음과 같이 작성하였습니다.

PlayerManager.kt

class PlayerManager {
    companion object{
        private var onlinePlayerData = HashMap<Player, OnlinePlayer>()
    }

    fun addPlayer(player: Player){
        val newOnlinePlayer = OnlinePlayer(player.uniqueId, player.displayName, "jobless","unranked","[뉴비]", 1000u)
        onlinePlayerData[player] = newOnlinePlayer
        Main.instance!!.logger.info("플레이어 데이터를 추가하였습니다.")
    }

    fun deletePlayer(player: Player){
        onlinePlayerData.remove(player)
        Main.instance!!.logger.info("플레이어 데이터를 삭제하였습니다.")
    }

    fun getPlayerData(player: Player) : OnlinePlayer?{
        return onlinePlayerData[player]
    }

}

Main.kt

class Main : JavaPlugin() {
    companion object{
        var playerManager : PlayerManager? = null
        var instance : Main? = null
    }

    override fun onEnable() {
        instance = this
        playerManager = PlayerManager()
    }

    override fun onDisable() {
    }


}

코틀린은 싱글톤 클래스의 구현에 편의성을 주기 위해 object 라는 것을 지원합니다.

 

따라서 다음과 같이 변경해 주세요.

PlayerManager.kt

package org.zepelown.kotlintestplugin.player.management

import org.bukkit.entity.Player
import org.zepelown.kotlintestplugin.Main

object PlayerManager {
    private var onlinePlayerData = HashMap<Player, OnlinePlayer>()

    fun addPlayer(player: Player){
        val newOnlinePlayer = OnlinePlayer(player.uniqueId, player.displayName, "jobless","unranked","[뉴비]", 1000u)
        onlinePlayerData[player] = newOnlinePlayer
        Main.instance!!.logger.info("플레이어 데이터를 추가하였습니다.")
    }

    fun deletePlayer(player: Player){
        onlinePlayerData.remove(player)
        Main.instance!!.logger.info("플레이어 데이터를 삭제하였습니다.")
    }

    fun getPlayerData(player: Player) : OnlinePlayer?{
        return onlinePlayerData[player]
    }

}

Main.kt

package org.zepelown.kotlintestplugin

import org.bukkit.plugin.java.JavaPlugin
import org.zepelown.kotlintestplugin.player.management.PlayerManager

class Main : JavaPlugin() {
    companion object{
        var instance : Main? = null
    }

    override fun onEnable() {
        instance = this
    }

    override fun onDisable() {
    }


}

PlayerManager를 class 에서 object로 변경하고 그에 따라 Main 코드도 변경해 주었습니다.


2. Event 처리하기

이전 강좌에서 만들었던 PlayerManager를 사용해 보도록 하겠습니다.

 

이 PlayerManager의 역할은 현재 접속 중인 플레이어의 정보를 저장 및 관리하는 용도입니다.

 

그렇기 때문에

 

플레이어가 서버에서 접속, 퇴장했을 때 PlayerManager에 정보를 알려줘야 합니다.

 

이를 Spigot과 같은 마크 서버 API에서는 '이벤트'라고 합니다.

먼저, 저번 강좌에서 만들었던 events 패키지에 다음과 같이 파일을 3개 만들어줍니다.

 

각각 이름에서 알 수 있듯이 Join, Kick, Quit 이벤트 발생 시 관리하는 겁니다.

 

Kick과 Quit 이벤트가 분리되어 있으니 각각 따로 처리해줘야 합니다.

 

Kick은 강퇴, Quit은 일반적인 퇴장을 의미합니다.

 

Kick은 인터넷, 버그 등의 각종 이유로 튕기는 것까지 포함합니다.

참고 API 링크(이벤트 관련 설명 링크)

더보기

PlayerJoinEvent.kt

import org.bukkit.event.EventHandler
import org.bukkit.event.Listener
import org.bukkit.event.player.PlayerJoinEvent
import org.zepelown.kotlintestplugin.player.management.PlayerManager

object PlayerJoinEvent : Listener{

    @EventHandler
    fun onPlayerJoinEvent(e : PlayerJoinEvent) {
        PlayerManager.addPlayer(e.player)
    }

}

PlayerKickEvent.kt

import org.bukkit.event.EventHandler
import org.bukkit.event.Listener
import org.bukkit.event.player.PlayerKickEvent
import org.zepelown.kotlintestplugin.player.management.PlayerManager

object PlayerKickEvent : Listener {

    @EventHandler
    fun onPlayerKickEvent(e: PlayerKickEvent){
        PlayerManager.deletePlayer(e.player)
    }
}

PlayerQuitEvent.kt

import org.bukkit.event.EventHandler
import org.bukkit.event.Listener
import org.bukkit.event.player.PlayerQuitEvent
import org.zepelown.kotlintestplugin.player.management.PlayerManager

object PlayerQuitEvent : Listener{
    @EventHandler
    fun onPlayerQuitEvent(e: PlayerQuitEvent){
        PlayerManager.deletePlayer(e.player)
    }

}

각 이벤트들도 object로 관리할 수 있습니다.

 

작동 방식은 간단합니다.

 

플레이어가 들어오면 PlayerManager에 데이터를 넣고

 

플레이어가 나가면 PlayerManager에서 데이터를 뺍니다.


3. Event 등록

이벤트 관련 object를 다 만들었습니다.

 

이제 이 object들을 서버 인스턴스에 등록을 해줘야 합니다.

 

이를 Main에 다 넣으면 나중에 Main이 매우 복잡해지므로 

 

중간에 등록을 해주는 object를 만들어줍니다.

 

EventManager.kt

package org.zepelown.kotlintestplugin

import org.zepelown.kotlintestplugin.player.management.events.PlayerJoinEvent
import org.zepelown.kotlintestplugin.player.management.events.PlayerKickEvent
import org.zepelown.kotlintestplugin.player.management.events.PlayerQuitEvent

object EventManager {
    fun registerEvents(){
        Main.instance?.let {
            it.server.pluginManager.run {
                registerEvents(PlayerJoinEvent, it)
                registerEvents(PlayerKickEvent, it)
                registerEvents(PlayerQuitEvent, it)
            }
        }
    }

}

 

Main에서 instance를 가져오고 

 

?.let을 통해 null을 체크하고

 

registerEvent를 해줍니다.

 

위 코드에서 it은 instance를 의미합니다.

 

이제 Main에서 EventManager의 메서드를 실행시켜 주면 끝납니다.

 

Main.kt

package org.zepelown.kotlintestplugin

import org.bukkit.plugin.java.JavaPlugin

class Main : JavaPlugin() {
    companion object{
        var instance : Main? = null
    }

    override fun onEnable() {
        instance = this
        EventManager.registerEvents()
    }

    override fun onDisable() {
    }


}

 


4. 결과

 

다음 강의에선 이렇게 추가한 정보를 명령어를 통해 확인하고 수정해 보도록 하겠습니다.

 

 

댓글