https://github.com/gloomn/blogMCPluginProjects
GitHub - gloomn/blogMCPluginProjects
Contribute to gloomn/blogMCPluginProjects development by creating an account on GitHub.
github.com
플러그인 코드들은 모두 여기 있으니 코드가 필요하시면 다운로드 하시면 됩니다!
이전 강의
https://syntaxack.tistory.com/entry/minecraftplugin12
마인크래프트 플러그인 강좌 12강 - [config.yml] getString, getInt, getBoolean 값 읽기 실습
이전 강의https://syntaxack.tistory.com/entry/minecraftplugin11 마인크래프트 플러그인 강좌 11강 - [config.yml] saveDefaultConfig(), saveConfig(), reloadConfig() 차이와 실시이전 강의https://syntaxack.tistory.com/entry/minecraftplugi
syntaxack.tistory.com
이번 강의 목표
- config.yml에서 여러 줄짜리 문자열 목록(List<String>)을 불러오기
- getStringList("key") 메서드 사용법 이해
- 반복문으로 목록 출력하기
1. 프로젝트 생성하기
Intellij를 실행해서 새로운 마인크래프트 프로젝트를 만들어준다.
프로젝트 생성 방법을 모르면 아래 링크를 눌러 한 번만 보면 된다.
https://syntaxack.tistory.com/entry/minecraftplugin1
마인크래프트 플러그인 강좌 1강 - 첫 플러그인 만들기
이전 강의https://syntaxack.tistory.com/entry/minecraftplugin0 마인크래프트 플러그인 강좌 0강 - 준비하기마인크래프트 플러그인이란?마인크래프트 플러그인은 마인크래프트 내에서 기능을 확장할 수 있도
syntaxack.tistory.com
1. paper/spigot/sponge 템플릿에서 여러분이 사용하는 버킷 플러그인을 선택한다.
2. 빌드 시스템은 Gradle를 선택한다.
3. 언어는 자바를 선택한다.
4. 마인크래프트 버전은 여러분이 플러그인을 적용항 버전과 paper 버전이 일치하도록 선택한다.
예를 들어서 마인크래프트 버전 1.21.4, paper 버전 1.21.4 이면 1.21.4를 선택한다.
5. 플러그인 이름과 클래스 이름을 적는다.
생성을 눌러준다.
https://syntaxack.tistory.com/entry/minecraftpluginproblem1
마인크래프트 플러그인 강좌 - 잘못된 Gradle JVM 구성을 발견했습니다.
IntelliJ를 사용해서 마인크래프트 플러그인 프로젝트를 만들었을 때 잘못된 Gradle JVM 설정이라는 알람이 뜰 때가 있다.이는 JDK와 Gradle이 호환되지 않아서 발생하는 문제이다.이때는 인터넷 검색
syntaxack.tistory.com
만약 Gradle과 JVM 버전이 안 맞는다는 오류가 뜨면 위의 포스트를 보면 된다.
2. Gradle build 설정
우리는 jar 파일로 빌드할 때 빌드 위치를 바로 플러그인 폴더로 빌드되게 설정할 것이다.
build.gradle 파일을 열어준다.
tasks.jar{
archiveFileName = 'configTest4.jar'
destinationDirectory = file('C:\\Users\\kijoon\\Desktop\\Server\\plugins')
}
3. config.yml 파일 만들기
resource 폴더에 만들어준다.
4. config.yml 작성하기
banned-words:
- 바보
- 멍청이
- 욕설1
- 욕설2
5. ConfigTest4.java 작성하기
package org.blog.configTest4;
import io.papermc.paper.event.player.AsyncChatEvent;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.NotNull;
import java.util.List;
public final class ConfigTest4 extends JavaPlugin implements Listener {
@Override
public void onEnable() {
getLogger().info("플러그인이 활성화됐습니다.");
saveDefaultConfig();
Bukkit.getPluginManager().registerEvents(this, this);
}
@Override
public void onDisable() {
// Nothing to do
}
@Override
public boolean onCommand(@NotNull CommandSender sender, Command command, @NotNull String label, String @NotNull [] args) {
if (command.getName().equalsIgnoreCase("bannedlist")) {
List<String> bannedWords = getConfig().getStringList("banned-words");
if (bannedWords.isEmpty()) {
sender.sendMessage("🚫 금지어가 설정되어 있지 않습니다.");
return true;
}
sender.sendMessage("📛 금지어 목록:");
for (String word : bannedWords) {
sender.sendMessage("❌ " + word);
}
return true;
}
return false;
}
@EventHandler
public void onChat(AsyncChatEvent event) {
String rawMessage = PlainTextComponentSerializer.plainText().serialize(event.message()).toLowerCase();
String normalized = rawMessage.replaceAll("\\s+", "");
normalized = normalized.replaceAll("[^가-힣a-z0-9]", "");
List<String> bannedWords = getConfig().getStringList("banned-words");
for (String word : bannedWords) {
if (normalized.contains(word.toLowerCase())) {
event.setCancelled(true);
event.getPlayer().sendMessage(
Component.text("🚫 금지어가 포함되어 있어 채팅이 취소되었습니다.", NamedTextColor.RED)
);
return;
}
}
}
}
6. 코드 설명
@Override
public void onEnable() {
getLogger().info("플러그인이 활성화됐습니다.");
saveDefaultConfig();
Bukkit.getPluginManager().registerEvents(this, this);
}
@Override
public void onDisable() {
// Nothing to do
}
onEnable이랑 onDisable은 2강에 있으니 찾아보길 바란다.
Bukkit.getPluginManager().registerEvents는 onChat() 함수를 EventListener에 등록을 했기 때문에 감지를 하기위해 적은 것이다.
@Override
public boolean onCommand(@NotNull CommandSender sender, Command command, @NotNull String label, String @NotNull [] args) {
if (command.getName().equalsIgnoreCase("bannedlist")) {
List<String> bannedWords = getConfig().getStringList("banned-words");
if (bannedWords.isEmpty()) {
sender.sendMessage("🚫 금지어가 설정되어 있지 않습니다.");
return true;
}
sender.sendMessage("📛 금지어 목록:");
for (String word : bannedWords) {
sender.sendMessage("❌ " + word);
}
return true;
}
return false;
}
onCommand 부분도 2강 또는 3강에 적어 놓았으니 찾아보길 바란다.
- /bannedlist 명령어를 처리하는 부분이다. 이 명령어를 입력하면 설정된 금지어 목록을 출력한다.
- getConfig().getStringList("banned-words"): config.yml에 설정된 금지어 목록을 불러온다.
- if (bannedWords.isEmpty()): 금지어 목록이 비어 있으면 사용자에게 금지어가 설정되지 않았다고 알려준다.
- sender.sendMessage("❌ " + word): 금지어 목록을 한 줄씩 출력한다.
@EventHandler
public void onChat(AsyncChatEvent event) {
String rawMessage = PlainTextComponentSerializer.plainText().serialize(event.message()).toLowerCase();
String normalized = rawMessage.replaceAll("\\s+", "");
normalized = normalized.replaceAll("[^가-힣a-z0-9]", "");
List<String> bannedWords = getConfig().getStringList("banned-words");
for (String word : bannedWords) {
if (normalized.contains(word.toLowerCase())) {
event.setCancelled(true);
event.getPlayer().sendMessage(
Component.text("🚫 금지어가 포함되어 있어 채팅이 취소되었습니다.", NamedTextColor.RED)
);
return;
}
}
}
- 채팅 이벤트 처리 메서드이다.
- AsyncChatEvent 이벤트가 발생할 때마다 호출되며, 사용자가 입력한 메시지에 금지어가 포함되어 있으면 메시지를 차단한다.
- String rawMessage = PlainTextComponentSerializer.plainText().serialize(event.message()).toLowerCase();: 메시지를 소문자로 변환하고, 플레인 텍스트 형태로 변환한다.
- event.message()는 net.kyori.adventure.text.Component 객체인데, 이를 PlainTextComponentSerializer로 텍스트로 변환한다.
- String normalized = rawMessage.replaceAll("\\s+", "");: 메시지에서 모든 공백을 제거한다.. 예를 들어 바 보는 바보로 변환된다.
- normalized = normalized.replaceAll("[^가-힣a-z0-9]", "");: 메시지에서 한글, 알파벳, 숫자 외의 특수문자를 모두 제거한다. 예를 들어 바#보는 바보로 변환된다.
- List<String> bannedWords = getConfig().getStringList("banned-words");: config.yml에서 금지어 목록을 불러온다.
- for (String word : bannedWords): 금지어 목록을 순차적으로 검사하여, 메시지에 금지어가 포함되었는지 확인한다.
- if (normalized.contains(word.toLowerCase())): 금지어가 메시지에 포함되었으면, event.setCancelled(true)로 채팅을 취소한다.
- event.getPlayer().sendMessage(...): 사용자에게 금지어가 포함되어 있어 채팅이 취소되었다는 메시지를 알림으로 보낸다.
7. 동작 설명
- 채팅 시 사용자가 입력한 메시지가 onChat 메서드에서 처리된다.
- 입력된 메시지는 공백, 특수문자가 제거되고 소문자로 변환된다.
- 금지어 목록에 포함된 단어가 메시지에 있으면, 해당 메시지는 차단되고 플레이어에게 경고 메시지가 전송된다.
- /bannedlist 명령어로 설정된 금지어 목록을 확인할 수 있다.
8. plugin.yml 작성하기
name: configTest4
version: '1.0-SNAPSHOT'
main: org.blog.configTest4.ConfigTest4
api-version: '1.21'
commands:
bannedlist:
description: 금지어 목록 출력
9. jar 파일로 빌드하기
10. 테스트하기
정상적으로 명령어가 작동한다.
이제 욕설을 해보겠다.
정상적으로 작동한다.
이버에는 바보를 띄어쓰기랑 바%보 이렇게 적어보겠다.
정상적으로 막힌다.
이제 특수문자를 바보 사이에 넣겠다.
정상적으로 작동한다.
11.다음 강의
NPC와 상호작용의 기초
- NPC(Entity와의 상호작용을 처리하는 방법
- 우클릭 이벤트를 사용하여 플레이어가 NPC와 상호작용할 때 발생할 이벤트 정의하기
'마인크래프트 플러그인' 카테고리의 다른 글
마인크래프트 플러그인 강좌 14강 - NPC와 우클릭 이벤트로 상호작용 처리하기 (2) | 2025.07.14 |
---|---|
마인크래프트 플러그인 강좌 12강 - [config.yml] getString, getInt, getBoolean 값 읽기 실습 (0) | 2025.06.22 |
마인크래프트 플러그인 강좌 11강 - [config.yml] saveDefaultConfig(), saveConfig(), reloadConfig() 차이와 실시간 적용 방법 (2) | 2025.06.22 |
마인크래프트 플러그인 강좌 10강 - config.yml이란? 생성과 구조 이해하기 (0) | 2025.06.21 |
마인크래프트 플러그인 강좌 9강 - GUI 투표 시스템 만들기(paper) (6) | 2025.06.21 |