diff --git a/src/main/java/pw/kaboom/extras/Main.java b/src/main/java/pw/kaboom/extras/Main.java index 7b5ce72..b5381dd 100644 --- a/src/main/java/pw/kaboom/extras/Main.java +++ b/src/main/java/pw/kaboom/extras/Main.java @@ -36,6 +36,7 @@ import pw.kaboom.extras.modules.player.PlayerInteract; import pw.kaboom.extras.modules.player.PlayerRecipe; import pw.kaboom.extras.modules.player.PlayerTeleport; import pw.kaboom.extras.modules.server.ServerCommand; +import pw.kaboom.extras.modules.server.ServerTabComplete; import pw.kaboom.extras.modules.server.ServerTick; public final class Main extends JavaPlugin { @@ -97,6 +98,7 @@ public final class Main extends JavaPlugin { /* Server-related modules */ this.getServer().getPluginManager().registerEvents(new ServerCommand(), this); + this.getServer().getPluginManager().registerEvents(new ServerTabComplete(), this); this.getServer().getPluginManager().registerEvents(new ServerTick(), this); } diff --git a/src/main/java/pw/kaboom/extras/modules/player/PlayerConnection.java b/src/main/java/pw/kaboom/extras/modules/player/PlayerConnection.java index 2ab3ab1..236d829 100644 --- a/src/main/java/pw/kaboom/extras/modules/player/PlayerConnection.java +++ b/src/main/java/pw/kaboom/extras/modules/player/PlayerConnection.java @@ -20,6 +20,7 @@ import com.destroystokyo.paper.profile.ProfileProperty; import com.google.common.base.Charsets; import pw.kaboom.extras.Main; +import pw.kaboom.extras.modules.server.ServerTabComplete; public final class PlayerConnection implements Listener { @EventHandler @@ -61,6 +62,8 @@ public final class PlayerConnection implements Listener { fadeOut ); } + + ServerTabComplete.getLoginNameList().put(player.getUniqueId(), player.getName()); } @EventHandler @@ -105,6 +108,7 @@ public final class PlayerConnection implements Listener { void onPlayerQuit(final PlayerQuitEvent event) { PlayerCommand.getCommandMillisList().remove(event.getPlayer().getUniqueId()); //PlayerInteract.interactMillisList.remove(event.getPlayer().getUniqueId()); + ServerTabComplete.getLoginNameList().remove(event.getPlayer().getUniqueId()); } @EventHandler diff --git a/src/main/java/pw/kaboom/extras/modules/server/ServerTabComplete.java b/src/main/java/pw/kaboom/extras/modules/server/ServerTabComplete.java new file mode 100644 index 0000000..38573cf --- /dev/null +++ b/src/main/java/pw/kaboom/extras/modules/server/ServerTabComplete.java @@ -0,0 +1,75 @@ +package pw.kaboom.extras.modules.server; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; + +import com.destroystokyo.paper.event.server.AsyncTabCompleteEvent; + +public final class ServerTabComplete implements Listener { + private static HashMap loginNameList = new HashMap(); + + @EventHandler + void onAsyncTabComplete(final AsyncTabCompleteEvent event) { + final String[] arr = event.getBuffer().split(" ", 2); + + // Vanilla clients will not send tab complete requests on the first word, but modified or bot clients may + if (arr.length < 2) { + return; + } + + String command = arr[0]; + String argsFragment = arr[1]; + if (command.startsWith("/")) { + command = command.substring(1); + } + + if (command.equalsIgnoreCase("op")) { + event.setCompletions(getOpCompletions(argsFragment)); + } else if (command.equalsIgnoreCase("deop")) { + event.setCompletions(getDeopCompletions(argsFragment)); + } else { + return; + } + + if (event.getCompletions().size() == 0) { + event.setCancelled(true); + } + } + + static List getOpCompletions(final String argsFragment) { + ArrayList deops = new ArrayList(); + for (Player player : Bukkit.getOnlinePlayers()) { + if (!player.isOp()) { + String loginName = loginNameList.get(player.getUniqueId()); + if (loginName != null && loginName.startsWith(argsFragment)) { + deops.add(loginName); + } + } + } + return deops; + } + + static List getDeopCompletions(final String argsFragment) { + ArrayList ops = new ArrayList(); + for (Player player : Bukkit.getOnlinePlayers()) { + if (player.isOp()) { + String loginName = loginNameList.get(player.getUniqueId()); + if (loginName != null && loginName.startsWith(argsFragment)) { + ops.add(loginName); + } + } + } + return ops; + } + + public static HashMap getLoginNameList() { + return loginNameList; + } +}