Kobins 7e61baba5cec465d89e9b4c5615ae13e
강좌 자바 에디션(JE) 플러그인 개발
[마시자] 마인크래프트로 시작하는 Java 1강 - Paper/Spigot/Bukkit 기본
분야 | 플러그인 |
---|---|
게임버전 | 모든버전 |
마인크래프트로 시작하는 Java 1강 목차
Paper/Spigot/Bukkit 기본
대체 이 녀석은 어떻게 돌아가는가?
다른 콘솔 프로그래밍 강좌에 비해 첫 번째 기본 세팅 강의가 정말 화려합니다. C/C++의 경우는 그냥 간단하게 Visual Studio만 깔아도 알아서 다 해주는데...
게다가 이 Paper(앞으로 Spigot, Bukkit, CraftBukkit을 포함합니다)라는 녀석은 프로그래밍을 배우기 위해 만들어진 것도 아니라서 그렇게 초보자에게 친절하지 않습니다.
그저 'Java 좀 알고, 마인크래프트 좀 아는 사람'에게 자기가 원하는 것을 만들기 쉽게 만들어진 라이브러리에 불과합니다.
따라서 강좌가 없으면 대체 이 Paper라는 친구가 어떻게 우리의 플러그인을 만지작거리는지 알 수가 없습니다. 하지만 저라고 해서 완전히 Paper의 모든 정보를 다 아는 것도 아니라서, 간략하게 어떤 과정으로 우리의 플러그인이 동작하게 되는지 알아보겠습니다.
이번 편은 이론 강의에 더 가깝습니다.
플러그인 초기화, 진입점(Entry Point), 비활성화
앞에서 했던 plugin.yml 작업들 기억나시나요?
거기에 main: me.kobins.Main
이라고 적었던 부분, 이것이 Paper가 우리가 만든 것을 플러그인이라고 인식하게 해주는 중요한 매개체입니다.
Paper는 우리의 jar 파일에서 저 경로를 찾아 따라 들어가, JavaPlugin을 상속한 메인 클래스를 Paper의 플러그인 목록에 넣게 됩니다.
이 사진에서 빨간 줄의 부분이 바로 플러그인을 일단 인식하는 데에는 성공했다는 증표입니다.
그리고 페이퍼는 월드 설정을 불러옵니다. 바로 밑의 Preparing level "world"부터 시작해서 월드의 spawn area를 로딩합니다.
그리고 그 다음, 아까 등록해둔 플러그인들을 활성화시킵니다.
바로 여기서 이전 강의에서 했던 onEnable()
부분이 여기서 실행됩니다.
우리는 이전 강의에서 저기서 고작 MSJ 플러그인 활성화라는 문자열을 콘솔에 출력하는 데에 그쳤지만, 사실 저기가 플러그인의 진입점(Entry Point)입니다.
- 사실 이전에 Loading에서 onLoad()라는 메소드가 존재합니다만, 월드 로드 전에 하는 데다가 만약에 reload를 통해 서버가 다시 시작하게 된다면 플러그인 내부의 설정에는 그렇게 적합하지 않습니다. 고수분들 여기 추가의견좀...
플러그인의 시작점에서 플러그인 내부에 사용할 여러가지 요소들을 초기화합니다.
또한 플러그인의 가장 핵심인 명령어(Command)와 이벤트(Event)들을 초기화하는 구간이기도 합니다.
서버를 꺼버리면 MSJ 플러그인 비활성화라는 문자열을 콘솔에 출력합니다.
이는 onDisable()에서 실행되며, 메모리 관리를 할 필요가 없는 Java에서는 메모리 할당 해제보다는 만약에 저장이 필요한 데이터의 관리, 다시 onEnable() 할 때를 대비해 (리로드) 특정 기능 해제하기 등에 사용됩니다.
플러그인은 어떤 식으로 동작하는가?
Paper API 안에서 플러그인이 코드를 실행할 수 있는 순간은 크게 4가지로 나뉩니다.
- 플러그인 초기화(onEnable(), onLoad()) 및 플러그인 비활성화(onDisable())
- 이벤트(Event)
- 명령어(Command)
- 위 3가지 중에서 스케줄러(Scheduler)를 통해 버킷 전용 쓰레드(Thread) 생성하여 동작
이게 끝이냐구요? 네!
자체적으로 외부에서 패킷 신호를 받아 실행한다거나 하는 경우를 제외한다면 사실상 Paper 플러그인이 코드를 실행하는 순간/장소는 저 4가지가 진짜로 전부 다입니다.
플러그인 초기화 Initialize
위에서 말했듯 Paper가 플러그인을 가져올 때 onLoad(), onEnable(), 그리고 플러그인이 비활성화될 때 onDisable()에서 코드가 실행됩니다.
이벤트 Event
사실상 플러그인 개발의 핵심입니다. Paper에선 온갖 종류의 행동/사건/작업 등을 이벤트(Event)라는 이름으로 관리합니다.
만약에 플레이어가 서버에 들어왔을 때, PlayerJoinEvent
라는 이벤트를 호출하여 등록된 수신자(Listener)들에게 이벤트 핸들러(Event Handler)를 이용하여 수신자 클래스 내부의 메소드들에게 전달하여 이벤트 내용을 가공(이벤트에 대한 반응, 이벤트 내용 수정)하게 됩니다.
또한, 플레이어가 블록을 설치하는 BlockPlaceEvent
같은 경우는 특정 조건을 만족하여 블록 설치를 취소해야 한다면 e.setCancelled(true);
라는 구문을 이벤트 수신 메소드에 넣어 블록이 설치되는 것을 막을 수 있습니다.
이벤트에 대한 자세한 내용은 다음 강의에서 다룰 예정입니다.
명령어 Command
플레이어가 문자를 통해 플러그인의 기능에 대해 어떠한 작업을 하고 싶을 때, 가장 적절한 것이 명령어입니다.
물론 위에서 설명한 Event를 통해 채팅의 내용을 받는 AsyncPlayerChatEvent
(구 PlayerChatEvent
)를 사용할 수도 있겠지만, 이는 플러그인에 대해 말하려는 건지 그냥 대화를 하려는 건지 구분하는 데에 애로사항이 있습니다.
따라서 플러그인별로 구분할 수 있고, 일정한 단위로 정보를 나누어 받아 유저 또는 관리자가 원하는 기능을 잘 실행하도록 만드는 기능이 바로 명령어(Command)입니다.
명령어는 /(슬래시, slash)로 시작하며, 플레이어가 채팅을 칠 때 만약에 맨 앞에 슬래시가 들어가 있다면 이는 무조건 명령어로 인식됩니다.
또, 슬래시 직후에 들어가는 문자는 명령어의 이름(label)을 의미하며, 유저가 어떤 명령어를 사용하는 지 구분하게 됩니다.
(단, 항상 명령어의 이름인 것은 아니며 별명(alias) 기능을 통해 같은 명령어라도 다른 여러가지의 이름을 가질 수 있다.)
그 다음부터 띄어쓰기 단위로 인자(Arguments, args)를 기록합니다. 명령어 이름 이후로 입력되는 모든 문자열은 띄어쓰기로 인해 나뉘어져 배열(Array)로 나뉘어져 들어갑니다.
정리해보면 다음과 같습니다. /<label> <arg:0> <arg:1> <arg:2> <arg:3>...
명령어에 대한 자세한 내용은 추후 강의에서 다룰 예정입니다.
스케줄러 Scheduler
특정한 명령을 일정한 시간을 두고 실행하고 싶다구요? 당신이 찾던 것이 바로 이겁니다!
하지만 이것은 명령을 실행하는 중 단순하게 pause(10); 하며 멈출 수 있는 것이 아닙니다. 이전에 VariableTriggers, Skript 등을 하면서 @PAUSE 1, wait 1 seconds 등을 자주 이용하셨다면 유감입니다. 우리의 Paper에서 이벤트나 명령어에 그런 짓을 했다가는(Thread.sleep() 등을 통해) 서버 자체가 그 시간동안 멈춰버립니다!
그 대신, Paper에서는 서버 메인 스레드와는 별개로 동시에 다른 작업을 할 수 있게 스케줄러(Scheduler)라는 기능을 지원합니다.
스케줄러에 대한 자세한 내용은 추후 강의에서 다룰 예정입니다.\
하... 뭐가 이리 많죠? 너무 두려운데요?
그럴 수 있습니다. 사실 초보 강좌 치고는 너무 많은 정보를 담고 있는 것이 사실입니다. 하지만 저 4가지를 이해할 수 있다면 Paper API 내에서 할 수 있는 것은 전부 할 수 있는 것도 사실입니다.
아직 위에서 설명한 것들을 전부 이해할 필요도 없습니다! 사실 간단하게 Paper API에서 무엇이 어떻게 돌아가는지 감을 잡으라는 용도로 작성한 글이니까요.
이러한 것들을 처음 봐서 이해가 하나도 안된다구요? 정상입니다! 제가 제대로 설명도 안하고 그냥 쑤셔박았는데 어떻게 이해하겠어요. 이제부터 천천히 다음 강좌 이벤트부터 시작해서 알아갈 예정이니 너무 겁먹지 마세요!
윈초
2020.02.27감사합니다 :D
SAHYUN
2020.03.28좋은 글 감사합니다!