5 편에서는 Plugin 튜토리얼의 Listener 에 대해 알아보았고
PlayerLoginEvent 를 활용해 유저가 서버에 로그인 할 경우 서버에 로그을 띄우는 것까지 해봤습니다.
하지만 서버의 로그에 뜨는 정보는 어떤 유저인지도 모르겠고 유저에게 환영한다는 메세지도 보내고 싶고 서버의 로그가 아닌 서버의 모든 인원에게 이 유저가 접속했다는 사실을 알려주고 싶습니다.
5 편에서 앞으로 플러그인을 만들 때는 무엇을 만들것인지 분석하고 제작해보겠다고 이야기 했습니다.
우리가 만들고싶은 플러그인은
서버의 로그에 어떤 유저가 접속했는지 알 수 있고
서버에 접근 한 유저에게 환영한다는 메세지를 보내고
서버의 모든 인원에게 이 유저가 접속했다는 사실을 알려주는
플러그인을 개발하는 것입니다.
해당 실습은 이전 5편에서 만든 플러그인을 토대로 개발할 예정입니다.
우선 서버의 로그에 어떤 유저가 접속했는지 알 수 있게 로깅을 강화하는 작업 먼저 해보도록 하겠습니다.
막상 시작하려하면 getLogger 를 통해 로깅은 할 수 있는데, 유저의 정보는 어떻게 가져올 수 있지 ? 궁금합니다.
3편에서 커스텀 서버를 구성할 때 SPIGOT 의 장점 중 하나는 큰 커뮤니티라고 했습니다.
우선 우리는 PlayerLoginEvent 만 알고 있는 상황이니, 구글에 PlayerLoginEvent 를 검색해 봅니다.
spigot playerLoginEvent 를 검색해보면 가장 최상단에 SpigotMC 라는 사이트에
PlayerLoginEvent 가 존재합니다.
PlayerLoginEvent (Spigot-API 1.21.1-R0.1-SNAPSHOT API) (spigotmc.org)
PlayerLoginEvent (Spigot-API 1.21.1-R0.1-SNAPSHOT API)
Stores details for players attempting to log in. Note that this event is called early in the player initialization process. It is recommended that most options involving the Player entity be postponed to the PlayerJoinEvent instead. Nested Class Summary Ne
hub.spigotmc.org
들어가면 PlayerLoginEvent 의 구성정보들을 자세하게 알 수 있습니다.
가장 상단의 정보를 조금 살펴보면
org.bukket.event.player 이라는 패키지에 있고
PlayerLoginEvent 는 Class 라고 합니다.
설명을 보면 플레이어들이 로그인을 시도할 때의 상세를 저장하고 있다고 합니다.
우리는 여러 영역 중 Method Summary 영역을 집중적으로 봐야 합니다.
PlayerLoginEvent 는 앞서 Class 라고 이야기 했습니다.
Method 는 5편에서 Class 라는 상자안에 들어있는 것들이고
Method 는 함수라고 소개했었습니다.
사이에 org.bukkiet.event.player.PlayerEvent 라는 클래스로부터 상속받은 getPlayer 라는 메서드가 있다는 것을 알았습니다.
이 getPlayer 라는 메서드의 상세를 보면
이벤트를 발생시킨 플레이어를 돌려준다고 합니다.
유일하게 Player 만 클릭해서 이동할 수 있는 것 같아 이동해보도록 하겠습니다.
이 Player 는
org.bukkit.entity 에 존재하는 것이고
Interface라는 것이라고 합니다.
상세를 읽어보면 player 라는 것을 나타낸다고 합니다.
아래 Method Summary 부분을 살펴보면 엄청나게 많은 Method 들이 존재하고 있습니다.
내용중에 getName() 이라는 아주 흥미로운 메서드가 보입니다.
이 getName() 은 플레이어의 이름을 OUTPUT 으로 돌려준다고 합니다.
그러면 서버의 로그에 어떤 유저가 접속했는지 알 수 있게 하기 위해서는
event 로 부터 getPlayer() 메서드를 통해 플레이어의 정보를 가져오고
이 플레이어의 정보로부터 getName() 메서드를 통해 플레이어의 이름을 가져와
getLogger 를 통해 접속한 플레이어의 이름을 알려주는 작업을 해보도록 하겠습니다.
Eclipse IDE 는 이렇게 친절하게 메서드에 대해 어디에 속해있는지 어떤 OUTPUT 을 돌려 주는지와 같은 많은 정보들을 알려주고 있습니다.
getName() 메서드도 위와 같은 방법으로 호출할 수 있습니다.
이렇게 Logger 에 접속하는 플레이어의 정보를 노출하도록 변경했습니다.
그런데 이렇게 되면 접속하는 플레이어의 이름만 로깅될 것 같습니다.
로깅을 하나 더 추가해서 문구를 조금 다듬어주도록 하겠습니다.
@EventHandler
public void onLogin(PlayerLoginEvent event) {
getLogger().info(event.getPlayer().getName());
getLogger().info(" 님이 서버에 접속했습니다.");
}
우선 정상적으로 작동하는지 버전을 하나 올리고 플러그인으로 만들어 테스트해보도록 하겠습니다.
서버의 로그에 성공적으로 플레이어의 이름과 " 님이 서버에 접속했습니다." 라는 문구가 노출되는 것을 확인할 수 있습니다.
헌데, 플레이어의 이름과 " 님이 서버에 접속했습니다." 라는 문구가 두 줄에 노출되는 것이 신경쓰입니다.
한 줄에 넣을 수 있는 방법이 없는지 검색해보도록 하겠습니다.
구글에 spigot log concat 이라는 것으로 검색하니 가장 최상단에
현재 ChatColor 와는상관이 없지만 String Concatenation 에 대해서 이야기하고 있는 글인 것 같습니다.
Performance of String Concatenation with ChatColor | SpigotMC - High Performance Minecraft
뭔가 어떤 방식으로 String Concatenation 을 해야 성능이 좋아지는지에 대한 글인 것 같습니다.
해당 글을 통해 우리는 몇 가지 정보를 얻을 수 있습니다.
String 이라는 것을 Concatenation 하기 위해서는 + 라는 것을 통해 연결지을 수 있다.
ChatColor 라는 것을 통해 채팅을 색을 변경할 수 있는 것 같다.
player 의 sendMessage 라는 것을 통해 플레이어에게 메세지를 보낼 수 있는 것 같다.
우선 지금 우리에게 필요한 정보인 String Concatenation 과 관련된 것만 발췌하도록 합니다.
문자열 - 위키백과, 우리 모두의 백과사전 (wikipedia.org)
문자열 - 위키백과, 우리 모두의 백과사전
위키백과, 우리 모두의 백과사전. 문자열의 예와 문자열의 구성 컴퓨터 프로그래밍과 형식 언어 이론에서 문자열(文字列)은 기호의 순차 수열을 말한다. 스트링(string)이라고도 한다. 이러한 기
ko.wikipedia.org
이 String 이 무엇인가 하니 컴퓨터 프로그래밍에서 사용하는 문자열 이라는 것을 의미한다고 합니다.
위의 getName() 이라는 메서드를 보면 String 이라는 것을 돌려준다고 되어 있는데, 문자열을 돌려준다는 의미였던 것 같습니다.
또한 무언가를 입력할 때 큰 따옴표("") 사이에 들어가는 말들도 문자열이라고 추측할 수 있습니다.
그러면 위의 질문글을 통해 String Concatenation 을 하려면 + 를 사용해 합칠 수 있다는 것을 알았습니다.
서버의 로그를 한 줄로 변경하기 위해 + 를 사용하여 합쳐보도록 하겠습니다.
@EventHandler
public void onLogin(PlayerLoginEvent event) {
getLogger().info(event.getPlayer().getName() + " 님이 서버에 접속했습니다.");
}
위와 같이 변경했을 때 다행히 오류가 뜨는 것 같지는 않습니다.
버전을 하나 더 올리고 플러그인을 만들어보도록 하겠습니다.
처음 의도했던 것 같이 한 줄로 플레이어의 이름과 " 님이 서버에 접속했습니다." 라는 문구가 합쳐진 것을 확인할 수 있습니다.
두 번째는 서버에 접근 한 유저에게 환영한다는 메세지를 보내보도록 하겠습니다.
위의 질문 글에서 player 의 sendMessage 라는 것을 통해 메세지를 보낼 수 있는 것 같습니다.
해당 기능을 통해 <플레이어의 이름> "님이 서버에 오신 것을 환영합니다." 라는 메세지를 보내보도록 하겠습니다.
해당 Eclipse IDE 에서 알려주는 sendMessage 의 내용을 보면
message 라는 것을 INPUT 으로 받고 void 라는 것을 OUTPUT 으로 돌려주고
메세지를 전송한다는 것 같습니다.
@EventHandler
public void onLogin(PlayerLoginEvent event) {
getLogger().info(event.getPlayer().getName() + " 님이 서버에 접속했습니다.");
event.getPlayer().sendMessage(event.getPlayer().getName() + " 님이 서버에 오신것을 환영합니다.");
}
위에 작성한 내용을 잘 복사 붙여넣기 해서 sendMessage 로직을 적용시킵니다.
버전을 올려 플러그인으로 만들어 적용시켜보도록 하겠습니다.
이상하게 코드도 정상적으로 만들고 플러그인은 정상적으로 탑재되어 있는 것 같은데 원하는 로그가 뜨지 않습니다.
이럴때는 검색을 통해 해결하는 것이 아주 빠른 해결 방법 중 하나인데요.
playerLoginEvent sendMessage doesn't work 로 구글에 검색하면
sendMessage not working under PlayerLoginEvent | Bukkit Forums
sendMessage not working under PlayerLoginEvent | Bukkit Forums
bukkit.org
저와 같은 이슈를 겪는 사람들이 종종 있는 것 같았습니다.
관련된 질문의 답변을 살펴보면 PlayerLoginEvent 는 실제로 유저가 서버에 접속하기 이전에 발동된다고 합니다.
sendMessage 기능을 활용하고 싶으면 PlayerJoinEvent 를 사용하라고 합니다.
PlayerJoinEvent 라는 것을 활용하기 위해 onJoin 이라는 메서드를 하나 더 추가하고 이벤트 핸들링을 해보도록 하겠습니다.
PlayerJoinEvent (Spigot-API 1.21.1-R0.1-SNAPSHOT API) (spigotmc.org)
@EventHandler
public void onLogin(PlayerLoginEvent event) {
getLogger().info(event.getPlayer().getName() + " 님이 서버에 접속했습니다.");
}
@EventHandler
public void onJoin(PlayerJoinEvent event) {
event.getPlayer().sendMessage(event.getPlayer().getName() + " 님이 서버에 오신것을 환영합니다.");
}
다시 버전을 하나 더 올리고 플러그인을 적용시켜보도록 하겠습니다.
서버에 로깅도 성공적으로 되고 플레이어가 접속했을 때 환영 메세지도 전달된 것을 확인할 수 있었습니다.
이렇게 코드 단위의 수정이 있을 때에는 기존에 적용시킨 기능이 정상적으로 작동하는지 테스트하는 습관은 아주 좋은 습관입니다.
마지막으로는 서버의 모든 인원에게 이 유저가 접속했다는 사실을 알려주는 기능입니다.
구글에 관련된 내용을 검색해 보도록 하겠습니다.
저와 같은 기능이 궁금한 사람들이 많은지 상단에 위치하는군요.
spigot send message to all players 를 검색해보도록 하겠습니다.
Solved - Send a message to all online players. | SpigotMC - High Performance Minecraft
질문의 내용과 답변을 살펴보면
Bukkit 의 broadcastMessage 를 통해 서버 안에 있는 모든 유저에게 메세지를 보낼 수 있다는 것 같습니다.
Bukkit 의 broadcastMessage 의 경우에는 INPUT 으로 String 타입의 message 라는 것을 받고
OUTPUT 으로는 int 라는 타입을 돌려주는 것 같습니다.
돌려주는 값으로는 전달한 플레이어의 수를 알려주는 것 같습니다.
@EventHandler
public void onJoin(PlayerJoinEvent event) {
event.getPlayer().sendMessage(event.getPlayer().getName() + " 님이 서버에 오신것을 환영합니다.");
Bukkit.broadcastMessage(event.getPlayer().getName() + " 님이 서버에 접속했습니다.");
}
onJoin 메서드에 broadcastMessage 기능을 활용해 <플레이어 이름> " 님이 서버에 접속했습니다." 라는 문구를 서버에 접속하고 있는 모든 유저에게 전달해보도록 하겠습니다.
개인으로 보내지는 메세지와 서버의 전체적으로 보내지는 메세지를 구분하기 위해 [개인], [전체] 라는 문자열을 합쳐서 보내보도록 하겠습니다.
package com.tistory.beingb.testplugin;
import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerLoginEvent;
import org.bukkit.plugin.java.JavaPlugin;
public final class TestPlugin extends JavaPlugin implements Listener {
@Override
public void onEnable() {
getLogger().info("[서버]" + "onEnable has been invoked!");
getServer().getPluginManager().registerEvents(this, this);
}
@Override
public void onDisable() {
getLogger().info("[서버]" + "onDisable has been invoked!");
}
@Override
public void onLoad() {
getLogger().info("[서버]" + "onLoad has been invoked!");
}
@EventHandler
public void onLogin(PlayerLoginEvent event) {
getLogger().info("[서버]" + event.getPlayer().getName() + " 님이 서버에 접속했습니다.");
}
@EventHandler
public void onJoin(PlayerJoinEvent event) {
event.getPlayer().sendMessage("[개인]" + event.getPlayer().getName() + " 님이 서버에 오신것을 환영합니다.");
Bukkit.broadcastMessage("[전체]" + event.getPlayer().getName() + " 님이 서버에 접속했습니다.");
}
}
버전을 올리고 플러그인을 만들어 적용시켜보도록 하겠습니다.
sendMessage 와 broadcastMessage 가 성공적으로 작동한 것을 확인할 수 있었습니다.
서버의 로깅도 성공적으로 된 것을 확인할 수 있었습니다.
우리가 만들고 싶었던 플러그인인
서버의 로그에 어떤 유저가 접속했는지 알 수 있고
서버에 접근 한 유저에게 환영한다는 메세지를 보내고
서버의 모든 인원에게 이 유저가 접속했다는 사실을 알려주는
플러그인 개발을 성공적으로 했고
이걸로 6. 마인크래프트 플러그인 개발 - Listener 활용 은 마치도록 하겠습니다.
'마인크래프트' 카테고리의 다른 글
9. 마인크래프트 플러그인 개발 - 챗컬러 플러그인 개발 (0) | 2024.08.24 |
---|---|
7. 마인크래프트 플러그인 개발 - 데미지 디스플레이 플러그인 개발 (0) | 2024.08.16 |
5. 마인크래프트 플러그인 개발 - Listener (0) | 2024.08.15 |
4. 마인크래프트 플러그인 개발 - 기초 플러그인 개발 (0) | 2024.08.15 |
3. 마인크래프트 플러그인 개발 - 커스텀 서버 제작 및 이클립스 설치 (0) | 2024.08.14 |