이해도 | 입문자 |
---|---|
게임버전 (JE) | 관련없음 |
게임버전 (BE) | 관련없음 |
플러그인을 이용하여 크리에이티브인 플레이어를 제외한, 온라인 플레이어들에게 양털을 지급하려 합니다.
온라인 플레이어들에게 아이템을 지급하는 코드까지 짠 상태이고, 게임모드가 크리에이티브인 플레이어만 제외하는 방법을 알고 싶습니다.
아래는 코드입니다.
package me.pandal.randomwool; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.GameMode; import org.bukkit.Material; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; import org.bukkit.command.ConsoleCommandSender; import org.bukkit.entity.Player; import org.bukkit.event.Listener; import org.bukkit.inventory.ItemStack; import org.bukkit.plugin.java.JavaPlugin; import java.util.ArrayList; import java.util.List; import static org.bukkit.Material.*; public final class Randomwool extends JavaPlugin implements Listener, CommandExecutor { public static void randomwool(String[] args) { List<String> wools = new ArrayList<String>(); wools.add("red_wool"); wools.add("orange_wool"); wools.add("yellow_wool"); wools.add("green_wool"); wools.add("blue_wool"); System.out.println("red_woll, orange_wool, yellow_wool, green_wool, blue_wool:"); for (String wool : wools) { System.out.println(wool); } int size = wools.size(); System.out.println("5:" + size); } public void onEnable() { getLogger().info("랜덤양털 정상작동"); getServer().getPluginManager().registerEvents(this, this); this.getCommand("랜덤게임").setExecutor(this); } @Override public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { Player player = (Player) sender; ItemStack red_wool = new ItemStack(Material.RED_WOOL); ItemStack orange_wool = new ItemStack(ORANGE_WOOL); ItemStack yellow_wool = new ItemStack(YELLOW_WOOL); ItemStack green_wool = new ItemStack(GREEN_WOOL); ItemStack blue_wool = new ItemStack(BLUE_WOOL); blue_wool.setAmount(8); for (Player all : Bukkit.getOnlinePlayers()) if (cmd.getName().equalsIgnoreCase("랜덤게임")) { if (args.length == 0) { player.sendMessage(ChatColor.GREEN + "양털 색 확인!!"); } else if (args[0].equalsIgnoreCase("random")) { int random = (int) (Math.random() * 5); switch (random) { case 0: all.getInventory().addItem(red_wool); player.sendMessage(ChatColor.GREEN + "양털 색 확인!!"); break; case 1: all.getInventory().addItem(orange_wool); player.sendMessage(ChatColor.GREEN + "양털 색 확인!!"); break; case 2: all.getInventory().addItem(yellow_wool); player.sendMessage(ChatColor.GREEN + "양털 색 확인!!"); break; case 3: all.getInventory().addItem(green_wool); player.sendMessage(ChatColor.GREEN + "양털 색 확인!!"); break; default: all.sendMessage(String.valueOf(ChatColor.RED) + "WARNING 오류 발생!!"); } } } return false; } }
qsef1256
2024.07.27player.getGameMode()
를 사용하시면 됩니다.팬달03
2024.07.27도와주셔서 정말 감사드립니다만... 위 코드 중 어디에 넣어야 하는지 알 수 있을까요?
이 코드를 어디에 넣어봐도 그저 case 하나가 더 추가되었을 뿐 제가 원하는 효과를 얻지 못하였습니다.
저는 크리에이티브의 플레이어는 양털을 아예 받지 않기를 원합니다.
qsef1256
2024.07.28문제는 지금 올려주신 코드에 있지 않습니다, for (Player all : Bukkit.getOnlinePlayers()), 즉 all을 대상으로 반복을 하셨으니 체크도 all을 대상으로 하셔야 합니다. 여기 player는 명령어를 보낸 사람, 즉 sender니까 그걸 체크하시면 안됩니다.
qsef1256
2024.07.28이 문제의 원인은 변수 이름을 잘못 지은 것에 있습니다. sender를 지금 반복을 돌리는 all와 착각해서 벌어진 문제죠. 이름을 잘 짓는데 거의 절반의 유지보수 비용 절감 효과가 있다는 것은 빈말이 아닙니다. player 대신 sender를 사용하셔야 했고 (파라미터와 겹치는 경우 그냥 sender를 commandSender로 바꾸셔도 될 것 같네요), 반복을 돌리는 all은 player 또는 nowPlayer 등으로 바꾸시는 게 좋습니다.
qsef1256
2024.07.28그리고 다른 문제도 있는데, 지금 cmd.getName().equalsIgnoreCase를 반복문 안에서 하고 있으시네요, 이 체크는 한번만 해도 됩니다. 근데 지금 불필요하게 플레이어 수 만큼 체크를 하게 만들고 있는 것 같네요.
qsef1256
2024.07.28또한 자바에서 변수 이름을 짓는 컨벤션, 즉 표준은 camelCase 입니다. snake_case는 id 문자열 같은 거로는 자주 사용하지만 자바 코드 자체에서는 거의 안 씁니다.
qsef1256
2024.07.28또 지금 "양털 색 확인!"을 sender에게 계속 보내고 있으신데 이걸로 채팅창이 도배가 될 껍니다, 의도한 동작인지 궁금하네요.
qsef1256
2024.07.28그리고 switch 문에 있는 반복 코드는 장기적으로 정리 되어야 합니다. 메서드 화 하거나 비슷한 종류의 리팩토링 으로 해결 가능할 것으로 보입니다.
qsef1256
2024.07.28사실 지금 JavaPlugin이 Domain의 역할도 하고, Listener의 역할도 하고, CommandExecutor의 역할도 하는 건 좋지 못합니다, 전부 다른 클래스로 쪼개져야 하는 부분입니다. 사실 Listener나 CommandExecutor는 저는 라이브러리를 써서 간단하게 쓰고 있습니다, 관련해서 찾아보는 게 생산성에 더 도움이 될 것으로 생각하고요.
qsef1256
2024.07.28randomWool 메서드는 아예 사용이 안된 것 같아요, 필요 없는 코드라면 바로바로 지우는 게 좋습니다.
qsef1256
2024.07.28또 지금 if 문으로 들여쓰기가 너무 중첩이 된 상태인데, Guard Clause 방법을 써서 조건 체크하고 안 맞으면 return을 하는 식으로 짜면 중첩을 좀 줄일 수 있습니다. 그러면 가독성과 유지보수성에 도움이 됩니다. 어려운 개념은 아니니 해보시는 걸 추천하고요
qsef1256
2024.07.28switch 자체도 최신 Java 에서는 줄여서 쓸 수 있는 문법이 많이 있습니다, enhanced switch 라고 알아보시면 될 것 같고요
qsef1256
2024.07.28랜덤을 뽑는 것 자체도 숫자로 뽑기보다 뽑고 싶은 Material 내지 ItemStack 들을 모아둔 List를 만들고 거기 안에 있는 요소들을 대상으로 랜덤을 돌려서 뽑는 게 더 직관적이고 오류가 없을 것 같네요.
qsef1256
2024.07.28또 ChatColor는 최신 Paper에서 deprecated로 알고 있습니다, Paper Adventure Api 등을 알아보시는 게 도움이 될 것 같고요
qsef1256
2024.07.28equalsIgnoreCase도 한글 대상으로는 쓰는 의미가 별로 없습니다, 영어 대문자 소문자를 얘기하는 거니까요
qsef1256
2024.07.28오류 발생을 안내하는 부분에서도 왜 오류가 발생했는지 구체적인 정보를 포함하는 것이 디버깅에 좋습니다. 지금 문제는 예상하지 않은 숫자가 나온거니 그 내용을 그대로 쓰거나 아니면 의도한 부분인 "양털을 찾지 못했습니다" 정도로 쓰는 것이 맞습니다 (다만 저는 전자를 추천합니다, 지금은 사용자한테 오류 내용이 달 되는거니 사용자 입장을 고려해서 오류 메시지를 썼지만 기본적으로 오류 메시지는 개발자가 봐야 하는 것이니 개발자한테 도움이 될만한 내용을 쓰는 게 맞고요, 숫자가 양털 색을 나타낸다는 것 자체는 또 변경될 수 있으니까 의미 그대로 쓰는 게 제일 좋을 것으로 보입니다)
qsef1256
2024.07.28int random = (int) (Math.random() * 4); 이거도 사실 좀 복잡한 부분이라 계속 이렇게 쓰기 보다는 유틸리티 클래스를 하나 만들어서 좀 더 직관적으로 RandomUtil.getRandom(1, 4) 처럼 쓸 수 있도록 만드는 게 더 좋습니다 (혹은 이런 기능을 제공하는 라이브러리를 찾아보는 것이 더 좋을 수도 있습니다)
qsef1256
2024.07.28String을 결합하는 것도 + 를 쓰기 보단 .formatted를 쓰는 게 가독성과 수정 할 때 편합니다
qsef1256
2024.07.28그리고 onEnable에 @Override 안 달린 것 같네요
qsef1256
2024.07.28지금 command도 return false; 만 하는 것 같은데 아마도 이러면 알 수 없는 명령어 입니다 내지 명령어 실패로 처리될 껍니다, 명령어가 성공한 경우 return true를 해야 이런 안내문이 안 뜹니다.
qsef1256
2024.07.28그리고 크리에이티브 인 경우 "관리자 입니다" 라는 안내문이 뜨게 되어 있는데, 크리에이티브 이지만 관리자가 아닌 경우도 있을 수 있습니다, 해당 안내문은 정말 op나 특정 펄미션을 가지고 있을 때만 쓰는 것이 좋습니다. 나중에 그냥 적혀진 안내문을 보고 착각할 가능성이 있으니까요
qsef1256
2024.07.28그리고 tab complete (탭 누르면 자동완성) 기능도 추가를 하면 명령어 사용하기에 더 편할껍니다.
qsef1256
2024.07.28안내 문들 자체도 시스템을 따로 만들어서 안내 문을 설정 파일로 변경할 수 있게 만들면 사용할 때 편할 수도 있는데 이거는 필요에 따라서 알아보시면 될 것 같네요
qsef1256
2024.07.28음 그리고 다소 주제에 벗어날 수는 있지만 랜덤 양털 뽑기 자체는 마크 자체에서 그냥 공급기를 써도 될 것 같은 부분이거든요, 플러그인 개발은 원래 이렇게 어렵고 시간이 많이 드는 일이기에 다른 방법을 쓸 수 있다면 그걸 쓰는 게 더 나을 수도 있습니다. 생각해보시는 게 좋을 것 같아요
qsef1256
2024.07.28그리고 혹시나 해서 얘기를 드리는 건데, 그냥 어디서 보고 복사해서 가져오거나 아무렇게나 넣어보고 안되면 다시 해보는 코딩을 하고 있으시다면 바꾸시는 게 좋습니다, 그건 내가 이 코드를 알고서 코딩을 하는 게 아니거든요. 문제가 더 심각해질 수 있습니다. 개발자는 그런 사람이 아니거든요.
물론 그냥 제 착각이고 아닐 수도 있어요, 근데 지금 코드 자체가 인터넷에 많이 돌아다니는 형식이기도 하고, 정확히 이해를 하고서 코딩을 하는 건 아닌 느낌이 있어서 얘기 드려요.
팬달03
2024.07.28헤헤 진심으로 신경써주셔서 고맙습니다!
굳이 플러그인으로 양털을 지급하려는 이유는 플러그인 공부를 어디서부터 시작해야 할지 몰라 간단할 것 같은 것부터 만들어보자 였습니다.
코드는, 기본적으로 스피갓 클래스를 참고하며 만들고 있으며, 근데도 모르겠다 싶을 때는 주로 해외 사례들을 찾아보는 편입니다!
다시 한번 고맙습니다!