개인 자료란 (JE)

  서버 커뮤니티

Profile cch 대표칭호 없음
Profile

강좌 자바 에디션(JE) 플러그인 개발

[마인크래프트 플러그인 제작 강의] 7강 command (명령어) 클래스 작성과 조건문

2020.07.22 조회 수 854 추천 수 0
분야 플러그인 
장르 개발자 툴 
게임버전 모든버전 
API 스피곳, 페이퍼 

이 글은 개인 블로그에 작성한 내용을 공유하는 글 입니다.

( 해당 블로그에서 원본을 보실 수 있습니다.  https://cchplugin.tistory.com/ )


안녕하세요. 오랜만에 강의를 올립니다! 

 

이번 강의에서는 command 클래스에 대해서 자세하게 알려드리면서 조건문의 개념과 사용방법에 대해서 알려드리겠습니다.

 

https://cchplugin.tistory.com/13 에서 작성된 코드를 기준으로 강의를 시작하겠습니다.

Command 클래스를 작성만 해놓고 다른 작업들은 하지 않은 상태입니다.

 

저희가 할 작업은 크게 3가지로 나뉩니다.

 

1. Main클래스에 등록.

2. command() 클래스 코드 작성

3. plugin.yml 작성

 

 

 

먼저 Main클래스에서 명령어등록을 해보겠습니다.

 


53509cfc93800dd751c63c4b8c614129.jpeg


 

위 코드는 test 라는 명령어를 CchCommand() 라는 클래스로 사용하겠다! 라고 선언하는 과정입니다.

마인크래프트 내에서 /test 라는 명령어를 사용하게 되면 CchCommand() 클래스에서 작성한 내용에 따라 특정 명령어가 발동되게 됩니다.

 

 

 

두번째로 CchCommand() 클래스를 작성해보겠습니다.

 

3b4663d8a44b9e024ef7d9e8d30d3999.png


먼저 sender , command , s , args 라는 인자들에 대한 설명을 드리겠습니다.

 

만약, Hello_OvO 라는 플레이어가 /test Hello_ovo 3

이라는 명령어를 입력했다고 가정합시다.

여기서 sender는 Hello_OvO라는 플레이어를 의미합니다.
command는 발동되는 커맨드를 의미합니다.

s 는 명령어 test를 의미합니다

args는 명령어 인자 hello_ovo와 3 을 의미합니다.

 

이 인자들을 이용하여 코드를 작성해보겠습니다.

 

우리가 작성할 명령어는

" /test 공지 할말  " 입력시 서버 전체에 공지사항을 전송.

" /test op 플레이어이름  " 입력시 플레이어를 op로 지정.

" /test 초기화  " 입력시 입장횟수 초기화
3가지이고 OP들만 사용 할 수 있도록 해보겠습니다.

 

 

먼저 플레이어의 OP 유무에 따라 사용, 사용불가능을 나누어보겠습니다.


e10fb302820b9f0c429dfe8a245a3705.jpeg


여기서 조건문 중의 하나인 if문에 대해서 잠시 알아보고 가겠습니다.

if문의 기본적인 구조는 아래와 같습니다.

if( 조건 ) { 조건 만족시 실행 될 내용 }
else { 조건 만족하지 않을 시 실행 될 내용 }

우리가 작성한 코드의 내용을 보면 player가 OP일때 "명령어를 사용 했습니다." 메시지를 보내고,

player가 OP가 아닐때 "명령어를 사용 할 권한이 없습니다!" 라는 메시지를 보냅니다.

 

이 처럼 특정한 조건에 따라 다른 결과가 실행 되기를 원할때 조건문을 사용하면 됩니다.

 

작동이 잘 되는지 지금까지 작성된 내용을 서버에 적용하여 실행해보겠습니다.

 

적용을 하기전에 plugin.yml에 commands 라는 항목을 추가해야 합니다.

 


d914a2b38c97c11ed2f5ab68e7d5baee.jpeg


main : com.tistory.cchplugin.cchlecture.Main
name : cchLecture001
version : 1.0.0
author : cch
description : cchLecture
commands :
test:
description: test
usage: /test

이미 작성되어 있으신 plugin.yml 파일에 commands : 아래 부분만 복사해서 적용하시면 됩니다.

새로운 command를 추가 할 때 마다 작성해주셔야 합니다. 만약 작성을 하지 않으면  

 


9ff01badafbbf81fb76aaad48ef498ef.png





이런 에러가 발생하니 꼭 작성해주셔야 합니다.

 

만약 작성을 하셨다고 하더라도 yml 형식에 맞지 않으면 에러가 발생하니, 띄워쓰기와 : 기호를 추가적으로 사용하지 않도록 신경써주세요.

 

실행 결과 저희가 의도 했던대로 player가 OP일때 "명령어를 사용 했습니다." 메시지가,

player가 OP가 아닐때 "명령어를 사용 할 권한이 없습니다!" 라는 메시지가 출력되는 것을 확인 하실수 있습니다. 

 


ec0206426291bdc8b15f2f6d8550ff60.jpeg


 

 

이제 다른 3가지 명령어를 완성시켜보도록 하겠습니다.

" /test 공지 [할말]  " 입력시 서버 전체에 공지사항을 전송.

" /test op [플레이어이름]  " 입력시 플레이어를 op로 지정.

" /test 초기화 [플레이어이름]  " 입력시 입장 횟수 초기화

 

 

우리가 /test 입력후 공지, op, 초기화를 입력했을때 다른 결과가 나와야 하니 조건문을 사용 할 수 있습니다.

 

if문을 이용한다면 


if (args[0].equals("공지")) {
                player.sendMessage("/test 공지 를 입력했습니다");
            } else if (args[0].equals("op")) {
                player.sendMessage("/test op 를 입력했습니다");
            } else if (args[0].equals("초기화")) {
                player.sendMessage("/test 초기화 를 입력했습니다");
            } else {
                player.sendMessage("등록되지 않은 명령어를 입력했습니다");
            }

라고 작성 할 수 있습니다.

 

하지만 우리는 if문이 아닌 다른 조건문인 switch문에 대해서 알아보고 switch문을 사용하겠습니다.

 

switch문의 기본적인 형태는
switch(인자) {
case 상황1 : { 상황1일때 실행될 코드; break; }

case 상황2 : { 상황2일때 실행될 코드; break; }

case 상황3 : { 상황3일때 실행될 코드; break; }

~~~~

default : { 상황1~3이 아닐때 실행될 코드; break; }
}

 

형태로 이루어져 있습니다.

 

우리가 작성하려 했던 코드를 switch문으로 표현한다면

            switch (args[0]) {

            case "공지": {
                player.sendMessage("/test 공지 를 입력했습니다");
                break;
            }
            case "op": {
                player.sendMessage("/test op 를 입력했습니다");
                break;
            }
            case "초기화": {
                player.sendMessage("/test 초기화 를 입력했습니다");
                break;
            }
            default: {
                player.sendMessage("등록되지 않은 명령어를 입력했습니다");
                break;
            }
            }

 

위와 같습니다. 

저는 switch문이 if문보다 가독성이 더 좋다고 생각하여 switch문을 자주 이용합니다.

 

 CchCommand.java 클래스를

import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;

public class CchCommand implements CommandExecutor {

    @Override
    public boolean onCommand(CommandSender sender, Command command, String s, String[] args) {

        Player player = (Player) sender;

        if (player.isOp()) {

            if (args.length == 0)
                return false;

            switch (args[0]) {

            case "공지": {
                player.sendMessage("/test 공지 를 입력했습니다");
                break;
            }
            case "op": {
                player.sendMessage("/test op 를 입력했습니다");
                break;
            }
            case "초기화": {
                player.sendMessage("/test 초기화 를 입력했습니다");
                break;
            }
            default: {
                player.sendMessage("등록되지 않은 명령어를 입력했습니다");
                break;
            }
            }

        } else {

            player.sendMessage("명령어를 사용 할 권한이 없습니다!");

        }

        return true;
    }

}

 

위와 같이 작성하고 어떻게 작동되는지 실행을 해보겠습니다! 

 


32bd790075064c419bf8a5c185f33824.jpeg 


 

위와 같이 잘 실행되실겁니다!

 

먄약 /test 뒤에 인자가 하나도 없어 args.length == 0이 된다면 false가 return 될 것입니다.

 

false가 return 되면 plugin.yml에 작성된 usage 부분이 출력됩니다. 

 

우리는


d914a2b38c97c11ed2f5ab68e7d5baee.jpeg


이와 같이 plugin.yml을 작성했기에 


66b537930ee5e4aab57514a178b0c33c.jpeg 


 

이와 같이 출력 됩니다.

plugin.yml의 usage 부분은 /test의 사용법에 대해
사용법  - /test 공지 [할말]  /test op [플레이어]  /test 초기화 [플레이어] 와 같이 작성해놓으면 되겠죠?

 

true가 return 되면 아무일도 일어나지 않습니다.

 

그럼 나머지 명령어 코드작성을 마무리 해보겠습니다.

 


public class CchCommand implements CommandExecutor {

    @Override
    public boolean onCommand(CommandSender sender, Command command, String s, String[] args) {

        Player player = (Player) sender;

        if (player.isOp()) {

            if (args.length == 0)
                return false;

            switch (args[0]) {

            case "공지": {
                if (args.length == 1) {
                    player.sendMessage("[할말]을 입력하세요.");
                } else {

                    String message = "";
                    for (int i = 1; args.length > i; i++) {
                        message += args[i] + " ";
                    }

                    Bukkit.broadcastMessage("§4공지사항 : §f" + message);
                }

                break;
            }
            case "op": {
                if (args.length == 1) {
                    player.sendMessage("[플레이어]를 입력하세요.");
                } else {
                    Player tragetPlayer = Bukkit.getPlayer(args[1]);
                    tragetPlayer.setOp(true);

                    player.sendMessage(tragetPlayer.getName() + "님을 OP로 설정 했습니다!");
                    tragetPlayer.sendMessage("OP로 설정 되셨습니다.");
                }
                break;
            }
            case "초기화": {

                if (args.length == 1) {
                    player.sendMessage("[플레이어]를 입력하세요.");
                } else {
                    Player tragetPlayer = Bukkit.getPlayer(args[1]);

                    CchEvent.map.put(tragetPlayer.getUniqueId(), 0);

                    player.sendMessage(tragetPlayer.getName() + "님의 입장 횟수를 초기화 했습니다!");
                    tragetPlayer.sendMessage("입장횟수가 초기화 되었습니다.");
                }
                break;
            }
            default: {
                player.sendMessage("등록되지 않은 명령어를 입력했습니다");
                break;
            }
            }

        } else {

            player.sendMessage("명령어를 사용 할 권한이 없습니다!");

        }

        return true;
    }

}

onCommand() 함수의 내용을 다음과 같이 바꿔주신 후 

 

CchEvent() 클래스의 

    public HashMap<UUID, Integer> map = new HashMap<UUID, Integer>();

 이 부분을 

    public static HashMap<UUID, Integer> map = new HashMap<UUID, Integer>();

 

다음과 같이 바꿔주세요.

 

성공적으로 수정하셨다면 아래와 같이 실행이 잘 작동이 될 것입니다.


2ea55f2ce4fb7f1f5aa7fcef426158bd.jpeg


 

 

https://cchplugin.tistory.com/4?category=844035 이 포스팅을 참고하시면 명령어 사용시
클릭가능한 채팅이 나오고, 클릭을 하여 명령어를 실행 시킬 수 있게 응용하실 수 있습니다.




Warning
댓글이 없습니다.

새로운 댓글을 등록해 주세요!

뉴스 및 창작물
/files/thumbnails/761/908/003/262x150.crop.jpg?20241025153749

건축

서울 숭례문(崇禮門) 4

KHC

2024-10-25

2

/files/thumbnails/578/899/003/262x150.crop.jpg?20241010142350

건축

경주 월정교 1

KHC

2024-10-10

2

/files/thumbnails/219/899/003/262x150.crop.jpg?20241009200950

건축

송전탑+도시 2

dbasd12

2024-10-09

2

/files/thumbnails/246/898/003/262x150.crop.jpg?20241008102328

레드스톤

단다단 - 오토노케(オトノケ) | 마인크래프트 노트블럭 커버

노트블럭전문가

2024-10-08

1

/files/thumbnails/348/896/003/262x150.crop.jpg?20241006103035

디도스/봇테러등등을 낚는 방법 4

물귀신

2024-10-06

3

/files/thumbnails/839/895/003/262x150.crop.jpg?20241006021227

SRV레코드는 보안도메인이 아닙니다. [서버오픈시 필독]

물귀신

2024-10-05

4

/files/thumbnails/648/892/003/262x150.crop.jpg?20241002184058

아티클

마인크래프트 라이브 2024 후기: 무성의가 느껴졌던 '절망편' 라이브

라비

2024-10-02

4