diff --git a/pom.xml b/pom.xml index 07f83fb..b47b8ae 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.loohp Limbo Limbo - 0.6.3-ALPHA + 0.6.4-ALPHA Standalone Limbo Minecraft Server. https://github.com/LOOHP/Limbo diff --git a/src/main/java/com/loohp/limbo/Limbo.java b/src/main/java/com/loohp/limbo/Limbo.java index f2b2fa4..dbd76f0 100644 --- a/src/main/java/com/loohp/limbo/Limbo.java +++ b/src/main/java/com/loohp/limbo/Limbo.java @@ -37,7 +37,7 @@ import org.json.simple.parser.ParseException; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.loohp.limbo.commands.CommandSender; -import com.loohp.limbo.commands.Defaults; +import com.loohp.limbo.commands.DefaultCommands; import com.loohp.limbo.consolegui.GUI; import com.loohp.limbo.events.EventsManager; import com.loohp.limbo.file.ServerProperties; @@ -291,17 +291,8 @@ public class Limbo { pluginFolder = new File("plugins"); pluginFolder.mkdirs(); - -// File defaultCommandsJar = new File(pluginFolder, "LimboDefaultCmd.jar"); -// defaultCommandsJar.delete(); -// console.sendMessage("Loading limbo default commands module..."); -// try (InputStream in = Limbo.class.getClassLoader().getResourceAsStream("LimboDefaultCmd.jar")) { -// Files.copy(in, defaultCommandsJar.toPath()); -// } catch (IOException e) { -// e.printStackTrace(); -// } - pluginManager = new PluginManager(pluginFolder); + pluginManager = new PluginManager(new DefaultCommands(), pluginFolder); try { Method loadPluginsMethod = PluginManager.class.getDeclaredMethod("loadPlugins"); loadPluginsMethod.setAccessible(true); @@ -323,9 +314,7 @@ public class Limbo { Runtime.getRuntime().addShutdownHook(new Thread(() -> { Limbo.getInstance().terminate(); })); - console.sendMessage("Enabling Commands"); - registerDefaultCommands(); - console.sendMessage("Default Commands Enabled"); + console.run(); } @@ -415,11 +404,6 @@ public class Limbo { } } - public void registerDefaultCommands() { - LimboPlugin plug = new LimboPlugin(); - getPluginManager().registerCommands(plug, new Defaults()); - } - public ServerProperties getServerProperties() { return properties; } diff --git a/src/main/java/com/loohp/limbo/commands/DefaultCommands.java b/src/main/java/com/loohp/limbo/commands/DefaultCommands.java new file mode 100644 index 0000000..b013a4f --- /dev/null +++ b/src/main/java/com/loohp/limbo/commands/DefaultCommands.java @@ -0,0 +1,222 @@ +package com.loohp.limbo.commands; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import com.loohp.limbo.Console; +import com.loohp.limbo.Limbo; +import com.loohp.limbo.player.Player; +import com.loohp.limbo.utils.GameMode; + +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.api.chat.TextComponent; +import net.md_5.bungee.api.chat.TranslatableComponent; + +public class DefaultCommands implements CommandExecutor, TabCompletor { + + @Override + public void execute(CommandSender sender, String[] args) { + if (args.length == 0) { + return; + } + if (args[0].equalsIgnoreCase("spawn")) { + if (sender.hasPermission("limboserver.spawn")) { + if (args.length == 1 && sender instanceof Player) { + Player player = (Player) sender; + player.teleport(Limbo.getInstance().getServerProperties().getWorldSpawn()); + player.sendMessage(ChatColor.GOLD + "Teleporting you to spawn!"); + } else if (args.length == 2) { + Player player = Limbo.getInstance().getPlayer(args[1]); + if (player != null) { + player.teleport(Limbo.getInstance().getServerProperties().getWorldSpawn()); + sender.sendMessage(ChatColor.GOLD + "Teleporting " + player.getName() + " to spawn!"); + } else { + sender.sendMessage(ChatColor.RED + "Player not found!"); + } + } else { + sender.sendMessage(ChatColor.RED + "Invalid command usage!"); + } + } else { + sender.sendMessage(ChatColor.RED + "You do not have permission to use that command!"); + } + return; + } + + if (args[0].equalsIgnoreCase("stop")) { + if (sender.hasPermission("limboserver.stop")) { + Limbo.getInstance().stopServer(); + } else { + sender.sendMessage(ChatColor.RED + "You do not have permission to use that command!"); + } + return; + } + + if (args[0].equalsIgnoreCase("kick")) { + if (sender.hasPermission("limboserver.kick")) { + BaseComponent reason = new TranslatableComponent("multiplayer.disconnect.kicked"); + boolean customReason = false; + Player player = args.length > 1 ? Limbo.getInstance().getPlayer(args[1]) : null; + if (player != null) { + if (args.length < 2) { + player.disconnect(reason); + } else { + reason = new TextComponent(String.join(" ", Arrays.copyOfRange(args, 2, args.length))); + customReason = true; + player.disconnect(reason); + } + if (customReason) { + sender.sendMessage(ChatColor.RED + "Kicked the player " + player.getName() + " for the reason: " + reason.toLegacyText()); + } else { + sender.sendMessage(ChatColor.RED + "Kicked the player " + player.getName()); + } + } else { + sender.sendMessage(ChatColor.RED + "Player is not online!"); + } + } else { + sender.sendMessage(ChatColor.RED + "You do not have permission to use that command!"); + } + return; + } + + if (args[0].equalsIgnoreCase("gamemode")) { + if (sender.hasPermission("limboserver.gamemode")) { + if (args.length > 1) { + Player player = args.length > 2 ? Limbo.getInstance().getPlayer(args[2]) : (sender instanceof Player ? (Player) sender : null); + if (!(sender instanceof Player)) { + sender.sendMessage(ChatColor.RED + "You have to specifiy a player!"); + } else if (player != null) { + try { + player.setGamemode(GameMode.fromId(Integer.parseInt(args[1]))); + } catch (Exception e) { + try { + player.setGamemode(GameMode.fromName(args[1])); + } catch (Exception e1) { + sender.sendMessage(ChatColor.RED + "Invalid usage!"); + return; + } + } + sender.sendMessage(ChatColor.GOLD + "Updated gamemode to " + player.getGamemode().getName()); + } else { + sender.sendMessage(ChatColor.RED + "Player is not online!"); + } + } else { + sender.sendMessage(ChatColor.RED + "Invalid usage!"); + } + } else { + sender.sendMessage(ChatColor.RED + "You do not have permission to use that command!"); + } + return; + } + + if (args[0].equalsIgnoreCase("say")) { + if (sender.hasPermission("limboserver.say")) { + if (sender instanceof Console) { + if (args.length > 1) { + String message = "[Server] " + String.join(" ", Arrays.copyOfRange(args, 1, args.length)); + Limbo.getInstance().getConsole().sendMessage(message); + for (Player each : Limbo.getInstance().getPlayers()) { + each.sendMessage(message); + } + } + } else { + if (args.length > 1) { + String message = "[" + sender.getName() + "] " + String.join(" ", Arrays.copyOfRange(args, 1, args.length)); + Limbo.getInstance().getConsole().sendMessage(message); + for (Player each : Limbo.getInstance().getPlayers()) { + each.sendMessage(message); + } + } + } + } else { + sender.sendMessage(ChatColor.RED + "You do not have permission to use that command!"); + } + return; + } + } + + @Override + public List tabComplete(CommandSender sender, String[] args) { + List tab = new ArrayList<>(); + switch (args.length) { + case 0: + if (sender.hasPermission("limboserver.spawn")) { + tab.add("spawn"); + } + if (sender.hasPermission("limboserver.kick")) { + tab.add("kick"); + } + if (sender.hasPermission("limboserver.stop")) { + tab.add("stop"); + } + if (sender.hasPermission("limboserver.say")) { + tab.add("say"); + } + if (sender.hasPermission("limboserver.gamemode")) { + tab.add("gamemode"); + } + break; + case 1: + if (sender.hasPermission("limboserver.spawn")) { + if ("spawn".startsWith(args[0].toLowerCase())) { + tab.add("spawn"); + } + } + if (sender.hasPermission("limboserver.kick")) { + if ("kick".startsWith(args[0].toLowerCase())) { + tab.add("kick"); + } + } + if (sender.hasPermission("limboserver.stop")) { + if ("stop".startsWith(args[0].toLowerCase())) { + tab.add("stop"); + } + } + if (sender.hasPermission("limboserver.say")) { + if ("say".startsWith(args[0].toLowerCase())) { + tab.add("say"); + } + } + if (sender.hasPermission("limboserver.gamemode")) { + if ("gamemode".startsWith(args[0].toLowerCase())) { + tab.add("gamemode"); + } + } + break; + case 2: + if (sender.hasPermission("limboserver.kick")) { + if (args[0].equalsIgnoreCase("kick")) { + for (Player player : Limbo.getInstance().getPlayers()) { + if (player.getName().toLowerCase().startsWith(args[1].toLowerCase())) { + tab.add(player.getName()); + } + } + } + } + if (sender.hasPermission("limboserver.gamemode")) { + if (args[0].equalsIgnoreCase("gamemode")) { + for (GameMode mode : GameMode.values()) { + if (mode.getName().toLowerCase().startsWith(args[1].toLowerCase())) { + tab.add(mode.getName()); + } + } + } + } + break; + case 3: + if (sender.hasPermission("limboserver.gamemode")) { + if (args[0].equalsIgnoreCase("gamemode")) { + for (Player player : Limbo.getInstance().getPlayers()) { + if (player.getName().toLowerCase().startsWith(args[2].toLowerCase())) { + tab.add(player.getName()); + } + } + } + } + break; + } + return tab; + } + +} diff --git a/src/main/java/com/loohp/limbo/commands/Defaults.java b/src/main/java/com/loohp/limbo/commands/Defaults.java deleted file mode 100644 index 9bbb1cc..0000000 --- a/src/main/java/com/loohp/limbo/commands/Defaults.java +++ /dev/null @@ -1,179 +0,0 @@ -package com.loohp.limbo.commands; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import com.loohp.limbo.Limbo; -import com.loohp.limbo.player.Player; -import com.loohp.limbo.utils.GameMode; - -import net.md_5.bungee.api.ChatColor; - -public class Defaults implements CommandExecutor, TabCompletor { - public List tabComplete(CommandSender sender, String[] args) { - List tab = new ArrayList<>(); - switch (args.length) { - case 0: - if (sender.hasPermission("limboserver.spawn")) - tab.add("spawn"); - if (sender.hasPermission("limboserver.kick")) - tab.add("kick"); - if (sender.hasPermission("limboserver.stop")) - tab.add("stop"); - if (sender.hasPermission("limboserver.say")) - tab.add("say"); - if (sender.hasPermission("limboserver.gamemode")) - tab.add("gamemode"); - break; - case 1: - if (sender.hasPermission("limboserver.spawn") && - "spawn".startsWith(args[0].toLowerCase())) - tab.add("spawn"); - if (sender.hasPermission("limboserver.kick") && - "kick".startsWith(args[0].toLowerCase())) - tab.add("kick"); - if (sender.hasPermission("limboserver.stop") && - "stop".startsWith(args[0].toLowerCase())) - tab.add("stop"); - if (sender.hasPermission("limboserver.say") && - "say".startsWith(args[0].toLowerCase())) - tab.add("say"); - if (sender.hasPermission("limboserver.gamemode") && - "gamemode".startsWith(args[0].toLowerCase())) - tab.add("gamemode"); - break; - case 2: - if (sender.hasPermission("limboserver.kick") && - args[0].equalsIgnoreCase("kick")) - for (Player player : Limbo.getInstance().getPlayers()) { - if (player.getName().toLowerCase().startsWith(args[1].toLowerCase())) - tab.add(player.getName()); - } - if (sender.hasPermission("limboserver.gamemode") && - args[0].equalsIgnoreCase("gamemode")) { - byte b; - int i; - GameMode[] arrayOfGameMode; - for (i = (arrayOfGameMode = GameMode.values()).length, b = 0; b < i; ) { - GameMode mode = arrayOfGameMode[b]; - if (mode.getName().toLowerCase().startsWith(args[1].toLowerCase())) - tab.add(mode.getName()); - b++; - } - } - break; - case 3: - if (sender.hasPermission("limboserver.gamemode") && - args[0].equalsIgnoreCase("gamemode")) - for (Player player : Limbo.getInstance().getPlayers()) { - if (player.getName().toLowerCase().startsWith(args[2].toLowerCase())) - tab.add(player.getName()); - } - break; - } - return tab; - } - - public void execute(CommandSender sender, String[] args) { - if (args.length == 0) - return; - if (args[0].equalsIgnoreCase("spawn")) { - if (sender.hasPermission("limboserver.spawn")) { - if (args.length == 1 && sender instanceof Player) { - Player player = (Player)sender; - player.teleport(Limbo.getInstance().getServerProperties().getWorldSpawn()); - player.sendMessage(ChatColor.GOLD + "Teleporting you to spawn!"); - } else if (args.length == 2) { - Player player = Limbo.getInstance().getPlayer(args[1]); - if (player != null) { - player.teleport(Limbo.getInstance().getServerProperties().getWorldSpawn()); - sender.sendMessage(ChatColor.GOLD + "Teleporting " + player.getName() + " to spawn!"); - } else { - sender.sendMessage(ChatColor.RED + "Player not found!"); - } - } else { - sender.sendMessage(ChatColor.RED + "Invalid command usage!"); - } - } else { - sender.sendMessage(ChatColor.RED + "You do not have permission to use that command!"); - } - return; - } - if (args[0].equalsIgnoreCase("stop")) { - if (sender.hasPermission("limboserver.stop")) { - Limbo.getInstance().stopServer(); - } else { - sender.sendMessage(ChatColor.RED + "You do not have permission to use that command!"); - } - return; - } - if (args[0].equalsIgnoreCase("kick")) { - if (sender.hasPermission("limboserver.kick")) { - String reason = "Disconnected!"; - Player player = (args.length > 1) ? Limbo.getInstance().getPlayer(args[1]) : null; - if (player != null) { - if (args.length < 2) { - player.disconnect(); - } else { - reason = String.join(" ", Arrays.copyOfRange((CharSequence[])args, 2, args.length)); - player.disconnect(reason); - } - sender.sendMessage(ChatColor.RED + "Kicked the player " + args[1] + " for the reason: " + reason); - } else { - sender.sendMessage(ChatColor.RED + "Player is not online!"); - } - } else { - sender.sendMessage(ChatColor.RED + "You do not have permission to use that command!"); - } - return; - } - if (args[0].equalsIgnoreCase("gamemode")) { - if (sender.hasPermission("limboserver.gamemode")) { - if (args.length > 1) { - Player player = (args.length > 2) ? Limbo.getInstance().getPlayer(args[2]) : ((sender instanceof Player) ? (Player)sender : null); - if (player != null) { - try { - player.setGamemode(GameMode.fromId(Integer.parseInt(args[1]))); - } catch (Exception e) { - try { - player.setGamemode(GameMode.fromName(args[1])); - } catch (Exception e1) { - sender.sendMessage(ChatColor.RED + "Invalid usage!"); - return; - } - } - sender.sendMessage(ChatColor.GOLD + "Updated gamemode to " + player.getGamemode().getName()); - } else { - sender.sendMessage(ChatColor.RED + "Player is not online!"); - } - } else { - sender.sendMessage(ChatColor.RED + "Invalid usage!"); - } - } else { - sender.sendMessage(ChatColor.RED + "You do not have permission to use that command!"); - } - return; - } - if (args[0].equalsIgnoreCase("say")) { - if (sender.hasPermission("limboserver.say")) { - if (sender instanceof com.loohp.limbo.Console) { - if (args.length > 1) { - String message = "[Server] " + String.join(" ", Arrays.copyOfRange((CharSequence[])args, 1, args.length)); - Limbo.getInstance().getConsole().sendMessage(message); - for (Player each : Limbo.getInstance().getPlayers()) - each.sendMessage(message); - } - } else if (args.length > 1) { - String message = "[" + sender.getName() + "] " + String.join(" ", Arrays.copyOfRange((CharSequence[])args, 1, args.length)); - Limbo.getInstance().getConsole().sendMessage(message); - for (Player each : Limbo.getInstance().getPlayers()) - each.sendMessage(message); - } - } else { - sender.sendMessage(ChatColor.RED + "You do not have permission to use that command!"); - } - return; - } - } -} diff --git a/src/main/java/com/loohp/limbo/file/ServerProperties.java b/src/main/java/com/loohp/limbo/file/ServerProperties.java index 0dcb547..6f7d8b5 100644 --- a/src/main/java/com/loohp/limbo/file/ServerProperties.java +++ b/src/main/java/com/loohp/limbo/file/ServerProperties.java @@ -23,10 +23,15 @@ import com.loohp.limbo.utils.GameMode; import com.loohp.limbo.utils.NamespacedKey; import com.loohp.limbo.world.World; +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.api.chat.TextComponent; +import net.md_5.bungee.chat.ComponentSerializer; + public class ServerProperties { public static final String COMMENT = "For explaination of what each of the options does, please visit:\nhttps://github.com/LOOHP/Limbo/blob/master/src/main/resources/server.properties"; - + public static final BaseComponent[] EMPTY_CHAT_COMPONENT = new BaseComponent[] {new TextComponent("")}; + private File file; private int maxPlayers; private int serverPort; @@ -39,7 +44,7 @@ public class ServerProperties { private boolean reducedDebugInfo; private boolean allowFlight; private boolean allowChat; - private String motdJson; + private BaseComponent[] motd; private String versionString; private int protocol; private boolean bungeecord; @@ -53,10 +58,10 @@ public class ServerProperties { private String resourcePackSHA1; private String resourcePackLink; private boolean resourcePackRequired; - private String resourcePackPromptJson; + private BaseComponent[] resourcePackPrompt; - private String tabHeader; - private String tabFooter; + private BaseComponent[] tabHeader; + private BaseComponent[] tabFooter; Optional favicon; @@ -103,7 +108,8 @@ public class ServerProperties { reducedDebugInfo = Boolean.parseBoolean(prop.getProperty("reduced-debug-info")); allowFlight = Boolean.parseBoolean(prop.getProperty("allow-flight")); allowChat = Boolean.parseBoolean(prop.getProperty("allow-chat")); - motdJson = prop.getProperty("motd"); + String motdJson = prop.getProperty("motd"); + motd = motdJson.equals("") ? EMPTY_CHAT_COMPONENT : ComponentSerializer.parse(motdJson); versionString = prop.getProperty("version"); bungeecord = Boolean.parseBoolean(prop.getProperty("bungeecord")); velocityModern = Boolean.parseBoolean(prop.getProperty("velocity-modern")); @@ -134,10 +140,13 @@ public class ServerProperties { resourcePackLink = prop.getProperty("resource-pack"); resourcePackSHA1 = prop.getProperty("resource-pack-sha1"); resourcePackRequired = Boolean.parseBoolean(prop.getProperty("required-resource-pack")); - resourcePackPromptJson = prop.getProperty("resource-pack-prompt"); + String resourcePackPromptJson = prop.getProperty("resource-pack-prompt"); + resourcePackPrompt = resourcePackPromptJson.equals("") ? null : ComponentSerializer.parse(resourcePackPromptJson); - tabHeader = prop.getProperty("tab-header"); - tabFooter = prop.getProperty("tab-footer"); + String tabHeaderJson = prop.getProperty("tab-header"); + tabHeader = tabHeaderJson.equals("") ? EMPTY_CHAT_COMPONENT : ComponentSerializer.parse(tabHeaderJson); + String tabFooterJson = prop.getProperty("tab-footer"); + tabFooter = tabFooterJson.equals("") ? EMPTY_CHAT_COMPONENT : ComponentSerializer.parse(tabFooterJson); File png = new File("server-icon.png"); if (png.exists()) { @@ -235,8 +244,8 @@ public class ServerProperties { return this.allowChat; } - public String getMotdJson() { - return motdJson; + public BaseComponent[] getMotd() { + return motd; } public String getVersionString() { @@ -271,15 +280,15 @@ public class ServerProperties { return resourcePackRequired; } - public String getResourcePackPromptJson() { - return resourcePackPromptJson; + public BaseComponent[] getResourcePackPrompt() { + return resourcePackPrompt; } - public String getTabHeader() { + public BaseComponent[] getTabHeader() { return tabHeader; } - public String getTabFooter() { + public BaseComponent[] getTabFooter() { return tabFooter; } diff --git a/src/main/java/com/loohp/limbo/player/Player.java b/src/main/java/com/loohp/limbo/player/Player.java index 5887273..7cf206e 100644 --- a/src/main/java/com/loohp/limbo/player/Player.java +++ b/src/main/java/com/loohp/limbo/player/Player.java @@ -23,14 +23,15 @@ import com.loohp.limbo.server.packets.PacketPlayOutResourcePackSend; import com.loohp.limbo.server.packets.PacketPlayOutRespawn; import com.loohp.limbo.utils.GameMode; +import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.TextComponent; import net.md_5.bungee.api.chat.TranslatableComponent; -import net.md_5.bungee.chat.ComponentSerializer; public class Player extends LivingEntity implements CommandSender { public static final String CHAT_DEFAULT_FORMAT = "<%name%> %message%"; + public static final BaseComponent[] EMPTY_CHAT_COMPONENT = new BaseComponent[] {new TextComponent("")}; public final ClientConnection clientConnection; public final PlayerInteractManager playerInteractManager; @@ -210,7 +211,7 @@ public class Player extends LivingEntity implements CommandSender { @Override public void sendMessage(BaseComponent[] component, UUID uuid) { try { - PacketPlayOutChat chat = new PacketPlayOutChat(ComponentSerializer.toString(component), 0, uuid); + PacketPlayOutChat chat = new PacketPlayOutChat(component, 0, uuid); clientConnection.sendPacket(chat); } catch (IOException e) { e.printStackTrace(); @@ -228,7 +229,7 @@ public class Player extends LivingEntity implements CommandSender { @Override public void sendMessage(BaseComponent[] component) { try { - PacketPlayOutChat chat = new PacketPlayOutChat(ComponentSerializer.toString(component), 0, new UUID(0, 0)); + PacketPlayOutChat chat = new PacketPlayOutChat(component, 0, new UUID(0, 0)); clientConnection.sendPacket(chat); } catch (IOException e) { e.printStackTrace(); @@ -252,32 +253,44 @@ public class Player extends LivingEntity implements CommandSender { } public void chat(String message) { + chat(message, false); + } + + public void chat(String message, boolean verbose) { if (Limbo.getInstance().getServerProperties().isAllowChat()) { PlayerChatEvent event = (PlayerChatEvent) Limbo.getInstance().getEventsManager().callEvent(new PlayerChatEvent(this, CHAT_DEFAULT_FORMAT, message, false)); - if (!event.isCancelled() && this.hasPermission("limboserver.chat")) { - String chat = event.getFormat().replace("%name%", username).replace("%message%", event.getMessage()); - Limbo.getInstance().getConsole().sendMessage(chat); - if (event.getFormat().equals(CHAT_DEFAULT_FORMAT)) { - TranslatableComponent translatable = new TranslatableComponent("chat.type.text", username, event.getMessage()); - for (Player each : Limbo.getInstance().getPlayers()) { - each.sendMessage(translatable, uuid); - } - } else { - for (Player each : Limbo.getInstance().getPlayers()) { - each.sendMessage(chat, uuid); + if (!event.isCancelled()) { + if (hasPermission("limboserver.chat")) { + String chat = event.getFormat().replace("%name%", username).replace("%message%", event.getMessage()); + Limbo.getInstance().getConsole().sendMessage(chat); + if (event.getFormat().equals(CHAT_DEFAULT_FORMAT)) { + TranslatableComponent translatable = new TranslatableComponent("chat.type.text", username, event.getMessage()); + for (Player each : Limbo.getInstance().getPlayers()) { + each.sendMessage(translatable, uuid); + } + } else { + for (Player each : Limbo.getInstance().getPlayers()) { + each.sendMessage(chat, uuid); + } } + } else if (verbose) { + sendMessage(ChatColor.RED + "You do not have permission to chat!"); } } } } + public void setResourcePack(String url, String hash, boolean forced) { + setResourcePack(url, hash, forced, (BaseComponent[]) null); + } + public void setResourcePack(String url, String hash, boolean forced, BaseComponent promptmessage) { setResourcePack(url, hash, forced, new BaseComponent[] {promptmessage}); } public void setResourcePack(String url, String hash, boolean forced, BaseComponent[] promptmessage) { try { - PacketPlayOutResourcePackSend packsend = new PacketPlayOutResourcePackSend(url, hash, forced, promptmessage != null, promptmessage != null ? promptmessage : null); + PacketPlayOutResourcePackSend packsend = new PacketPlayOutResourcePackSend(url, hash, forced, promptmessage != null, promptmessage); clientConnection.sendPacket(packsend); } catch (IOException e) { e.printStackTrace(); @@ -286,35 +299,19 @@ public class Player extends LivingEntity implements CommandSender { public void setPlayerListHeaderFooter(BaseComponent[] header, BaseComponent[] footer) { try { - PacketPlayOutPlayerListHeaderFooter packsend = new PacketPlayOutPlayerListHeaderFooter( - ComponentSerializer.toString(header), - ComponentSerializer.toString(footer)); - clientConnection.sendPacket(packsend); - } catch (IOException e) { - e.printStackTrace(); - } - } - - public void setPlayerListHeader(BaseComponent[] header) { - try { - PacketPlayOutPlayerListHeaderFooter packsend = new PacketPlayOutPlayerListHeaderFooter( - ComponentSerializer.toString(header), - null); - clientConnection.sendPacket(packsend); - } catch (IOException e) { - e.printStackTrace(); - } - } - - public void setPlayerListFooter(BaseComponent[] footer) { - try { - PacketPlayOutPlayerListHeaderFooter packsend = new PacketPlayOutPlayerListHeaderFooter( - null, - ComponentSerializer.toString(footer)); + PacketPlayOutPlayerListHeaderFooter packsend = new PacketPlayOutPlayerListHeaderFooter(header == null ? EMPTY_CHAT_COMPONENT : header, footer == null ? EMPTY_CHAT_COMPONENT : footer); clientConnection.sendPacket(packsend); } catch (IOException e) { e.printStackTrace(); } } + public void setPlayerListHeaderFooter(BaseComponent header, BaseComponent footer) { + setPlayerListHeaderFooter(header == null ? EMPTY_CHAT_COMPONENT : new BaseComponent[] {header}, footer == null ? EMPTY_CHAT_COMPONENT : new BaseComponent[] {footer}); + } + + public void setPlayerListHeaderFooter(String header, String footer) { + setPlayerListHeaderFooter(header == null ? EMPTY_CHAT_COMPONENT : new BaseComponent[] {new TextComponent(header)}, footer == null ? EMPTY_CHAT_COMPONENT : new BaseComponent[] {new TextComponent(footer)}); + } + } diff --git a/src/main/java/com/loohp/limbo/plugins/PluginManager.java b/src/main/java/com/loohp/limbo/plugins/PluginManager.java index 462419c..95b5935 100644 --- a/src/main/java/com/loohp/limbo/plugins/PluginManager.java +++ b/src/main/java/com/loohp/limbo/plugins/PluginManager.java @@ -15,16 +15,19 @@ import java.util.zip.ZipInputStream; import com.loohp.limbo.Limbo; import com.loohp.limbo.commands.CommandExecutor; import com.loohp.limbo.commands.CommandSender; +import com.loohp.limbo.commands.DefaultCommands; import com.loohp.limbo.commands.TabCompletor; import com.loohp.limbo.file.FileConfiguration; public class PluginManager { private Map plugins; + private DefaultCommands defaultExecutor; private List executors; private File pluginFolder; - public PluginManager(File pluginFolder) { + public PluginManager(DefaultCommands defaultExecutor, File pluginFolder) { + this.defaultExecutor = defaultExecutor; this.pluginFolder = pluginFolder; this.executors = new ArrayList<>(); this.plugins = new LinkedHashMap<>(); @@ -83,6 +86,12 @@ public class PluginManager { public void fireExecutors(CommandSender sender, String[] args) throws Exception { Limbo.getInstance().getConsole().sendMessage(sender.getName() + " executed server command: /" + String.join(" ", args)); + try { + defaultExecutor.execute(sender, args); + } catch (Exception e) { + System.err.println("Error while running default command \"" + args[0] + "\""); + e.printStackTrace(); + } for (Executor entry : executors) { try { entry.executor.execute(sender, args); @@ -95,12 +104,18 @@ public class PluginManager { public List getTabOptions(CommandSender sender, String[] args) { List options = new ArrayList<>(); + try { + options.addAll(defaultExecutor.tabComplete(sender, args)); + } catch (Exception e) { + System.err.println("Error while getting default command tab completions"); + e.printStackTrace(); + } for (Executor entry : executors) { if (entry.tab.isPresent()) { try { options.addAll(entry.tab.get().tabComplete(sender, args)); } catch (Exception e) { - System.err.println("Error while passing tab completion to the plugin \"" + entry.plugin.getName() + "\""); + System.err.println("Error while getting tab completions to the plugin \"" + entry.plugin.getName() + "\""); e.printStackTrace(); } } diff --git a/src/main/java/com/loohp/limbo/server/ClientConnection.java b/src/main/java/com/loohp/limbo/server/ClientConnection.java index 8a68656..96d3dd4 100644 --- a/src/main/java/com/loohp/limbo/server/ClientConnection.java +++ b/src/main/java/com/loohp/limbo/server/ClientConnection.java @@ -79,7 +79,6 @@ import com.loohp.limbo.utils.ForwardingUtils; import com.loohp.limbo.utils.GameMode; import com.loohp.limbo.utils.MojangAPIUtils; import com.loohp.limbo.utils.MojangAPIUtils.SkinResponse; -import com.loohp.limbo.utils.NamespacedKey; import com.loohp.limbo.world.BlockPosition; import com.loohp.limbo.world.World; @@ -87,7 +86,6 @@ import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.TextComponent; import net.md_5.bungee.api.chat.TranslatableComponent; -import net.md_5.bungee.chat.ComponentSerializer; public class ClientConnection extends Thread { @@ -165,7 +163,7 @@ public class ClientConnection extends Thread { public void disconnect(BaseComponent[] reason) { try { - PacketPlayOutDisconnect packet = new PacketPlayOutDisconnect(ComponentSerializer.toString(reason)); + PacketPlayOutDisconnect packet = new PacketPlayOutDisconnect(reason); sendPacket(packet); } catch (IOException e) {} try { @@ -175,7 +173,7 @@ public class ClientConnection extends Thread { private void disconnectDuringLogin(BaseComponent[] reason) { try { - PacketLoginOutDisconnect packet = new PacketLoginOutDisconnect(ComponentSerializer.toString(reason)); + PacketLoginOutDisconnect packet = new PacketLoginOutDisconnect(reason); sendPacket(packet); } catch (IOException e) {} try { @@ -201,7 +199,7 @@ public class ClientConnection extends Thread { String str = inetAddress.getHostName() + ":" + client_socket.getPort(); Limbo.getInstance().getConsole().sendMessage("[/" + str + "] <-> Legacy Status has pinged"); ServerProperties p = Limbo.getInstance().getServerProperties(); - StatusPingEvent event = Limbo.getInstance().getEventsManager().callEvent(new StatusPingEvent(this, p.getVersionString(), p.getProtocol(), ComponentSerializer.parse(p.getMotdJson()), p.getMaxPlayers(), Limbo.getInstance().getPlayers().size(), p.getFavicon().orElse(null))); + StatusPingEvent event = Limbo.getInstance().getEventsManager().callEvent(new StatusPingEvent(this, p.getVersionString(), p.getProtocol(), p.getMotd(), p.getMaxPlayers(), Limbo.getInstance().getPlayers().size(), p.getFavicon().orElse(null))); String response = Limbo.getInstance().buildLegacyPingResponse(event.getVersion(), event.getMotd(), event.getMaxPlayers(), event.getPlayersOnline()); byte[] bytes = response.getBytes(StandardCharsets.UTF_16BE); output.writeShort(response.length()); @@ -239,7 +237,7 @@ public class ClientConnection extends Thread { Limbo.getInstance().getConsole().sendMessage("[/" + str + "] <-> Handshake Status has pinged"); } ServerProperties p = Limbo.getInstance().getServerProperties(); - StatusPingEvent event = Limbo.getInstance().getEventsManager().callEvent(new StatusPingEvent(this, p.getVersionString(), p.getProtocol(), ComponentSerializer.parse(p.getMotdJson()), p.getMaxPlayers(), Limbo.getInstance().getPlayers().size(), p.getFavicon().orElse(null))); + StatusPingEvent event = Limbo.getInstance().getEventsManager().callEvent(new StatusPingEvent(this, p.getVersionString(), p.getProtocol(), p.getMotd(), p.getMaxPlayers(), Limbo.getInstance().getPlayers().size(), p.getFavicon().orElse(null))); PacketStatusOutResponse packet = new PacketStatusOutResponse(Limbo.getInstance().buildServerListResponseJson(event.getVersion(), event.getProtocol(), event.getMotd(), event.getMaxPlayers(), event.getPlayersOnline(), event.getFavicon())); sendPacket(packet); } else if (packetType.equals(PacketStatusInPing.class)) { @@ -376,7 +374,7 @@ public class ClientConnection extends Thread { worldSpawn = joinEvent.getSpawnLocation(); World world = worldSpawn.getWorld(); - PacketPlayOutLogin join = new PacketPlayOutLogin(player.getEntityId(), false, properties.getDefaultGamemode(), Limbo.getInstance().getWorlds().stream().map(each -> new NamespacedKey(each.getName()).toString()).collect(Collectors.toList()).toArray(new String[Limbo.getInstance().getWorlds().size()]), Limbo.getInstance().getDimensionRegistry().getCodec(), world, 0, (byte) properties.getMaxPlayers(), 8, properties.isReducedDebugInfo(), true, false, true); + PacketPlayOutLogin join = new PacketPlayOutLogin(player.getEntityId(), false, properties.getDefaultGamemode(), Limbo.getInstance().getWorlds(), Limbo.getInstance().getDimensionRegistry().getCodec(), world, 0, (byte) properties.getMaxPlayers(), 8, properties.isReducedDebugInfo(), true, false, true); sendPacket(join); Limbo.getInstance().getUnsafe().setPlayerGameModeSilently(player, properties.getDefaultGamemode()); @@ -421,14 +419,11 @@ public class ClientConnection extends Thread { sendPacket(state); } - // RESOURCEPACK CODE ADDED BY GAMERDUCK123 - - if (properties.getResourcePackLink() != null && !properties.getResourcePackLink().equalsIgnoreCase("")) { - if (properties.getResourcePackSHA1() != null && !properties.getResourcePackSHA1().equalsIgnoreCase("")) { + // RESOURCEPACK CODE CONRIBUTED BY GAMERDUCK123 + if (!properties.getResourcePackLink().equalsIgnoreCase("")) { + if (!properties.getResourcePackSHA1().equalsIgnoreCase("")) { //SEND RESOURCEPACK - player.setResourcePack(properties.getResourcePackLink(), - properties.getResourcePackSHA1(), properties.getResourcePackRequired(), - ComponentSerializer.parse(properties.getResourcePackPromptJson())); + player.setResourcePack(properties.getResourcePackLink(), properties.getResourcePackSHA1(), properties.getResourcePackRequired(), properties.getResourcePackPrompt()); } else { //NO SHA Limbo.getInstance().getConsole().sendMessage("ResourcePacks require SHA1s"); @@ -437,19 +432,8 @@ public class ClientConnection extends Thread { //RESOURCEPACK NOT ENABLED } - // PLAYER LIST HEADER AND FOOTER CODE ADDED BY GAMERDUCK123 - // Sadly due to the limitations of minecraft (?) I cannot get the footer to work alone, it needs a header to have a footer, BUT - // You can have just a header with no footer (which is weird!) - String tabHeader = ""; - String tabFooter = ""; - if (properties.getTabHeader() != null && !properties.getTabHeader().equalsIgnoreCase("")) { - tabHeader = properties.getTabHeader(); - } - if (properties.getTabFooter() != null && !properties.getTabFooter().equalsIgnoreCase("")) { - tabFooter = properties.getTabFooter(); - } - player.setPlayerListHeaderFooter(ComponentSerializer.parse(tabHeader), - ComponentSerializer.parse(tabFooter)); + // PLAYER LIST HEADER AND FOOTER CODE CONRIBUTED BY GAMERDUCK123 + player.setPlayerListHeaderFooter(properties.getTabHeader(), properties.getTabFooter()); ready = true; @@ -529,7 +513,7 @@ public class ClientConnection extends Thread { if (chat.getMessage().startsWith("/")) { Limbo.getInstance().dispatchCommand(player, chat.getMessage()); } else { - player.chat(chat.getMessage()); + player.chat(chat.getMessage(), true); } } else if (packetType.equals(PacketPlayInHeldItemChange.class)) { PacketPlayInHeldItemChange change = new PacketPlayInHeldItemChange(input); diff --git a/src/main/java/com/loohp/limbo/server/packets/PacketLoginOutDisconnect.java b/src/main/java/com/loohp/limbo/server/packets/PacketLoginOutDisconnect.java index a7ee14e..0c4ed12 100644 --- a/src/main/java/com/loohp/limbo/server/packets/PacketLoginOutDisconnect.java +++ b/src/main/java/com/loohp/limbo/server/packets/PacketLoginOutDisconnect.java @@ -7,16 +7,19 @@ import java.nio.charset.StandardCharsets; import com.loohp.limbo.utils.DataTypeIO; +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.chat.ComponentSerializer; + public class PacketLoginOutDisconnect extends PacketOut { - private String jsonReason; + private BaseComponent[] reason; - public PacketLoginOutDisconnect(String jsonReason) { - this.jsonReason = jsonReason; + public PacketLoginOutDisconnect(BaseComponent[] reason) { + this.reason = reason; } - public String getJsonReason() { - return jsonReason; + public BaseComponent[] getReason() { + return reason; } @Override @@ -25,7 +28,7 @@ public class PacketLoginOutDisconnect extends PacketOut { DataOutputStream output = new DataOutputStream(buffer); output.writeByte(Packet.getLoginOut().get(getClass())); - DataTypeIO.writeString(output, jsonReason, StandardCharsets.UTF_8); + DataTypeIO.writeString(output, ComponentSerializer.toString(reason), StandardCharsets.UTF_8); return buffer.toByteArray(); } diff --git a/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutChat.java b/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutChat.java index 3377332..f7062b7 100644 --- a/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutChat.java +++ b/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutChat.java @@ -8,20 +8,23 @@ import java.util.UUID; import com.loohp.limbo.utils.DataTypeIO; +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.chat.ComponentSerializer; + public class PacketPlayOutChat extends PacketOut { - private String json; + private BaseComponent[] message; private int position; private UUID sender; - public PacketPlayOutChat(String json, int position, UUID sender) { - this.json = json; + public PacketPlayOutChat(BaseComponent[] message, int position, UUID sender) { + this.message = message; this.position = position; this.sender = sender; } - public String getJson() { - return json; + public BaseComponent[] getMessage() { + return message; } public int getPosition() { @@ -38,7 +41,7 @@ public class PacketPlayOutChat extends PacketOut { DataOutputStream output = new DataOutputStream(buffer); output.writeByte(Packet.getPlayOut().get(getClass())); - DataTypeIO.writeString(output, json, StandardCharsets.UTF_8); + DataTypeIO.writeString(output, ComponentSerializer.toString(message), StandardCharsets.UTF_8); output.writeByte(position); DataTypeIO.writeUUID(output, sender); diff --git a/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutDisconnect.java b/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutDisconnect.java index 0eb0659..875d241 100644 --- a/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutDisconnect.java +++ b/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutDisconnect.java @@ -7,16 +7,19 @@ import java.nio.charset.StandardCharsets; import com.loohp.limbo.utils.DataTypeIO; +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.chat.ComponentSerializer; + public class PacketPlayOutDisconnect extends PacketOut { - private String jsonReason; + private BaseComponent[] reason; - public PacketPlayOutDisconnect(String jsonReason) { - this.jsonReason = jsonReason; + public PacketPlayOutDisconnect(BaseComponent[] reason) { + this.reason = reason; } - public String getJsonReason() { - return jsonReason; + public BaseComponent[] getReason() { + return reason; } @Override @@ -25,7 +28,7 @@ public class PacketPlayOutDisconnect extends PacketOut { DataOutputStream output = new DataOutputStream(buffer); output.writeByte(Packet.getPlayOut().get(getClass())); - DataTypeIO.writeString(output, jsonReason, StandardCharsets.UTF_8); + DataTypeIO.writeString(output, ComponentSerializer.toString(reason), StandardCharsets.UTF_8); return buffer.toByteArray(); } diff --git a/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutKeepAlive.java b/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutKeepAlive.java index 2f98f81..a8f9341 100644 --- a/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutKeepAlive.java +++ b/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutKeepAlive.java @@ -6,7 +6,7 @@ import java.io.IOException; public class PacketPlayOutKeepAlive extends PacketOut { - long payload; + private long payload; public PacketPlayOutKeepAlive(long payload) { this.payload = payload; diff --git a/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutLogin.java b/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutLogin.java index 706a005..d6eee67 100644 --- a/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutLogin.java +++ b/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutLogin.java @@ -4,6 +4,7 @@ import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; +import java.util.List; import com.loohp.limbo.utils.DataTypeIO; import com.loohp.limbo.utils.GameMode; @@ -19,10 +20,10 @@ public class PacketPlayOutLogin extends PacketOut { private int entityId; private boolean isHardcore; private GameMode gamemode; - private String[] worldsNames; + private List worlds; private CompoundTag dimensionCodec; private Environment dimension; - private String worldName; + private World world; private long hashedSeed; private byte maxPlayers; private int viewDistance; @@ -31,14 +32,14 @@ public class PacketPlayOutLogin extends PacketOut { private boolean isDebug; private boolean isFlat; - public PacketPlayOutLogin(int entityId, boolean isHardcore, GameMode gamemode, String[] worldsNames, CompoundTag dimensionCodec, World world, long hashedSeed, byte maxPlayers, int viewDistance, boolean reducedDebugInfo, boolean enableRespawnScreen, boolean isDebug, boolean isFlat) { + public PacketPlayOutLogin(int entityId, boolean isHardcore, GameMode gamemode, List worlds, CompoundTag dimensionCodec, World world, long hashedSeed, byte maxPlayers, int viewDistance, boolean reducedDebugInfo, boolean enableRespawnScreen, boolean isDebug, boolean isFlat) { this.entityId = entityId; this.isHardcore = isHardcore; this.gamemode = gamemode; - this.worldsNames = worldsNames; + this.worlds = worlds; this.dimensionCodec = dimensionCodec; this.dimension = world.getEnvironment(); - this.worldName = new NamespacedKey(world.getName()).toString(); + this.world = world; this.hashedSeed = hashedSeed; this.maxPlayers = maxPlayers; this.viewDistance = viewDistance; @@ -60,8 +61,8 @@ public class PacketPlayOutLogin extends PacketOut { return gamemode; } - public String[] getWorldsNames() { - return worldsNames; + public List getWorldsNames() { + return worlds; } public CompoundTag getDimensionCodec() { @@ -72,8 +73,8 @@ public class PacketPlayOutLogin extends PacketOut { return dimension; } - public String getWorldName() { - return worldName; + public World getWorld() { + return world; } public long getHashedSeed() { @@ -114,9 +115,9 @@ public class PacketPlayOutLogin extends PacketOut { output.writeBoolean(isHardcore); output.writeByte((byte) gamemode.getId()); output.writeByte((byte) gamemode.getId()); - DataTypeIO.writeVarInt(output, worldsNames.length); - for (int u = 0; u < worldsNames.length; u++) { - DataTypeIO.writeString(output, worldsNames[u], StandardCharsets.UTF_8); + DataTypeIO.writeVarInt(output, worlds.size()); + for (int u = 0; u < worlds.size(); u++) { + DataTypeIO.writeString(output, new NamespacedKey(worlds.get(u).getName()).toString(), StandardCharsets.UTF_8); } DataTypeIO.writeCompoundTag(output, dimensionCodec); CompoundTag tag = null; @@ -128,7 +129,7 @@ public class PacketPlayOutLogin extends PacketOut { } } DataTypeIO.writeCompoundTag(output, tag != null ? tag : list.get(0).getCompoundTag("element")); - DataTypeIO.writeString(output, worldName, StandardCharsets.UTF_8); + DataTypeIO.writeString(output, new NamespacedKey(world.getName()).toString(), StandardCharsets.UTF_8); output.writeLong(hashedSeed); DataTypeIO.writeVarInt(output, maxPlayers); DataTypeIO.writeVarInt(output, viewDistance); diff --git a/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutPlayerListHeaderFooter.java b/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutPlayerListHeaderFooter.java index 76c4e91..c69c383 100644 --- a/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutPlayerListHeaderFooter.java +++ b/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutPlayerListHeaderFooter.java @@ -7,21 +7,24 @@ import java.nio.charset.StandardCharsets; import com.loohp.limbo.utils.DataTypeIO; +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.chat.ComponentSerializer; + public class PacketPlayOutPlayerListHeaderFooter extends PacketOut{ - private String header; - private String footer; + private BaseComponent[] header; + private BaseComponent[] footer; - public PacketPlayOutPlayerListHeaderFooter(String header, String footer) { + public PacketPlayOutPlayerListHeaderFooter(BaseComponent[] header, BaseComponent[] footer) { this.header = header; this.footer = footer; } - public String getHeader() { + public BaseComponent[] getHeader() { return header; } - public String getFooter() { + public BaseComponent[] getFooter() { return footer; } @@ -32,8 +35,8 @@ public class PacketPlayOutPlayerListHeaderFooter extends PacketOut{ DataOutputStream output = new DataOutputStream(buffer); output.writeByte(Packet.getPlayOut().get(getClass())); - DataTypeIO.writeString(output, header, StandardCharsets.UTF_8); - DataTypeIO.writeString(output, footer, StandardCharsets.UTF_8); + DataTypeIO.writeString(output, ComponentSerializer.toString(header), StandardCharsets.UTF_8); + DataTypeIO.writeString(output, ComponentSerializer.toString(footer), StandardCharsets.UTF_8); return buffer.toByteArray(); }