반응형

https://github.com/gloomn/blogMCPluginProjects

 

GitHub - gloomn/blogMCPluginProjects

Contribute to gloomn/blogMCPluginProjects development by creating an account on GitHub.

github.com

 

플러그인 코드들은 모두 여기 있으니 코드가 필요하시면 다운로드 하시면 됩니다!

마인크래프트 긴 커맨드 구현

2강에서는 기본적인 커맨드 구현을 해보았다.

예를 들어 /test 같은 단일 커맨드 같은 것 말이다.

https://syntaxack.tistory.com/entry/minecraftplugin2

 

마인크래프트 플러그인 강좌 2강 - 커스텀 커맨드 구현

이전 강의https://syntaxack.tistory.com/entry/minecraftplugin1 마인크래프트 플러그인 강좌 1강 - 첫 플러그인 만들기이전 강의https://syntaxack.tistory.com/entry/minecraftplugin0 마인크래프트 플러그인 강좌 0강 - 준비

syntaxack.tistory.com

 

이번에는 긴 커맨드를 만들어 볼 것이다.

예를 들어 /w sun 하면 날씨가 맑음으로 바뀌고, /w rain 이라고 하면 비가 내리게 할 수 있다.

 

프로젝트 만들기

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 버전이 안 맞는다는 오류가 뜨면 위의 포스트를 보면 된다.

 

Gradle build 설정

우리는 jar 파일로 빌드할 때 빌드 위치를 바로 플러그인 폴더로 빌드되게 설정할 것이다.

build.gradle 파일을 열어준다.

tasks.jar{
    archiveFileName = 'weatherPlugin.jar'
    destinationDirectory = file('C:\\Users\\kijoon\\Desktop\\Server\\plugins')
}

 

destinationDirectory에 여러분의 plugins 폴더로 설정하면 된다.

 

코드 작성

package org.blog.weather;

import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.World;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;

public final class Weather extends JavaPlugin {

    @Override
    public void onEnable() {
        // Plugin startup logic
        getLogger().info("플러그인이 활성화됐습니다.");
    }

    @Override
    public void onDisable() {
        // Plugin shutdown logic
        getLogger().info("플러그인이 비활성화됐습니다.");
    }

    public boolean onCommand(CommandSender cs, Command c, String[] a) {
        Player player = (Player) cs;
        if (c.getName().equalsIgnoreCase("w")) {
            if (a.length > 0) {
                World world = player.getWorld();
                if (a[0].equalsIgnoreCase("sun")) {
                    world.setStorm(false);
                    world.setThundering(false);
                } else if (a[0].equalsIgnoreCase("rain")) {
                    world.setStorm(true);
                    world.setThundering(false);
                } else if (a[0].equalsIgnoreCase("storm")) {
                    world.setStorm(true);
                    world.setThundering(true);
                } else {
                    // 잘못된 입력에 대한 처리
                    player.sendMessage(Component.text("올바른 날씨를 입력하시오! (sun, rain, storm)").color(NamedTextColor.RED));
                    return false;  // 명령어 처리 실패
                }
            } else {
                player.sendMessage(Component.text("날씨를 입력하시오!").color(NamedTextColor.RED));
                return false;  // 인자가 없을 때 처리
            }
        } else {
            return false;  // 다른 명령어 처리
        }
        return true;  // 정상적으로 명령어가 처리된 경우
    }

}

여기서 우리가 주목할 부분은 onCommand 부분이다.

 

onCommand

이 메서드는 명령어가 실행될 때마다 호출된다.

CommandSender은 명령어를 실행한 사람을 나타낸다. player일 수도 있고 console일 수도 있다.

Command는 실행된 명령어 자체를 나타낸다.

String s는 명령어가 들어 있는 변수이다.

String[] a는 명령어에 전달된 인자들이 들어 있는 배열이다.

 

예를 들어서 /w sun을 하면 s에는 w가 들어가고, a에는 sun이 들어간다.

Command에는 plugin.yml에 정의된 명령어 자체의 정보가 들어있다.

plugin.yml에 w라고 정의했으면 이름이 w가 된다.

Player player = (Player) cs;

Command sender은 Player 객체일 수 있기 떄문에 Player 타입으로 형변환을 한다.

 

if (c.getName().equalsIgnoreCase("w"))

실행된 명령어 "w" 일 경우에만 이 조건문이 실행된다. equalsIgnoreCase는 대소문자 구분 없이 비교한다.

 

if(a.length > 0)

명령어에 인자가 포함되어 있는지 확인한다. 인자가 없으면 "날씨를 입력하시오!" 메시지가 출력된다.

World world = player.getWorld();

player가 속한 월드를 가져온다. 날씨를 설정하려면 월드 객체가 필요하다.

 

if (a[0].equalsIgnoreCase("sun"))

첫 번째 인자가 "sun"인지 확인한다. "sun"이면 맑은 날씨로 설정된다.

 

world.setStorm(false);
world.setThundering(false);

푹풍을 비활성화하고, 천둥을 비활성화한다. 그럼 맑은 날씨가 된다.

 

player.sendMessage(Component.text("올바른 날씨를 입력하시오! (sun, rain, storm)").color(NamedTextColor.RED));

원래 전 강의에서 ChatColor을 사용했는데 사실 이 문법은 이제 deprecated 됐다. 더 이상 사용되는 문법이 아니다.

paper에서는 adventure api를 사용하는데 이제 Component.text를 사용해서 메세지를 출력하게 된다.

ChatColor에서는 글씨의 색, 굵기 등이 제한적이었는데, Component.text를 사용하면 더 유연한 메세지를 사용할 수 있다.

 

plugin.yml 작성하기

name: weather
version: '1.0-SNAPSHOT'
main: org.blog.weather.Weather
api-version: '1.21'
description: 날씨를 변경하는 플러그인입니다.

commands:
  w:
    description: 날씨를 변경합니다. (sun, rain, storm)

이렇게 명령어 w를 등록해주면 된다.

plugin.yml은 resources 폴더 안에 있다.

 

Gradle 빌드하기

이제 Gradle 탭에서 jar을 두번 클릭하면 빌드가 된다.

 

마인크래프트에서 확인하기

/w를 치면 날씨를 입력하라고 뜨고,

/w sdfsf를 치면 올바른 날씨를 입력하라고 뜨고,

/w rain이라고 치면 비가 내린다.

 

마무리

코드에서 궁금한 점이나 질문 사항들은 댓글로 ㄱㄱ

반응형