33import org .bukkit .ChatColor ;
44import org .bukkit .command .Command ;
55import org .bukkit .command .CommandSender ;
6+ import org .bukkit .command .TabCompleter ;
67import org .bukkit .Chunk ;
78import org .bukkit .GameMode ;
89import org .bukkit .Location ;
3132import java .io .DataOutputStream ;
3233import java .io .IOException ;
3334import java .nio .charset .StandardCharsets ;
35+ import java .util .ArrayList ;
3436import java .util .Collections ;
37+ import java .util .List ;
3538import java .util .Set ;
3639import java .util .UUID ;
3740import java .util .concurrent .ConcurrentHashMap ;
41+ import java .util .stream .Collectors ;
3842
39- public class TuffX extends JavaPlugin implements Listener , PluginMessageListener {
43+ public class TuffX extends JavaPlugin implements Listener , PluginMessageListener , TabCompleter {
4044
4145 public static final String CHANNEL = "eagler:below_y0" ;
4246 private final Set <ChunkSectionKey > sentSections = Collections .newSetFromMap (new ConcurrentHashMap <>());
@@ -49,26 +53,120 @@ public void onEnable() {
4953 getServer ().getMessenger ().registerIncomingPluginChannel (this , CHANNEL , this );
5054 getServer ().getPluginManager ().registerEvents (this , this );
5155 this .getCommand ("tuffx" ).setExecutor (this );
56+ this .getCommand ("tuffx" ).setTabCompleter (this );
5257 logFancyEnable ();
5358 }
5459
5560 @ Override
5661 public boolean onCommand (CommandSender sender , Command command , String label , String [] args ) {
62+ if (!command .getName ().equalsIgnoreCase ("tuffx" )) {
63+ return false ;
64+ }
65+
66+ if (args .length == 0 ) {
67+ handleHelpCommand (sender );
68+ return true ;
69+ }
70+
71+ switch (args [0 ].toLowerCase ()) {
72+ case "mute" :
73+ handleMuteCommand (sender );
74+ break ;
75+ case "reload" :
76+ handleReloadCommand (sender );
77+ break ;
78+ case "reloadchunks" :
79+ handleReloadChunksCommand (sender );
80+ break ;
81+ case "help" :
82+ handleHelpCommand (sender );
83+ break ;
84+ default :
85+ sender .sendMessage (ChatColor .GOLD + "[TuffX] " + ChatColor .RED + "Unknown subcommand. Use /tuffx help." );
86+ break ;
87+ }
88+ return true ;
89+ }
90+
91+ @ Override
92+ public List <String > onTabComplete (CommandSender sender , Command command , String alias , String [] args ) {
5793 if (command .getName ().equalsIgnoreCase ("tuffx" )) {
58- if (args .length > 0 && args [0 ].equalsIgnoreCase ("mute" )) {
59- if (!sender .hasPermission ("tuffx.mute" )) {
60- sender .sendMessage (ChatColor .RED + "You don't have permission to use this command." );
61- return true ;
94+ if (args .length == 1 ) {
95+ List <String > subcommands = new ArrayList <>();
96+ if (sender .hasPermission ("tuffx.mute" )) subcommands .add ("mute" );
97+ if (sender .hasPermission ("tuffx.reload" )) subcommands .add ("reload" );
98+ if (sender .hasPermission ("tuffx.reloadchunks" )) subcommands .add ("reloadchunks" );
99+ if (sender .hasPermission ("tuffx.help" )) subcommands .add ("help" );
100+
101+ return subcommands .stream ()
102+ .filter (s -> s .toLowerCase ().startsWith (args [0 ].toLowerCase ()))
103+ .collect (Collectors .toList ());
104+ }
105+ }
106+ return Collections .emptyList ();
107+ }
108+
109+ private void handleMuteCommand (CommandSender sender ) {
110+ if (!sender .hasPermission ("tuffx.mute" )) {
111+ sender .sendMessage (ChatColor .RED + "You don't have permission to use this command." );
112+ return ;
113+ }
114+ isMuted = !isMuted ;
115+ String status = isMuted ? ChatColor .RED + "MUTED" : ChatColor .GREEN + "UNMUTED" ;
116+ sender .sendMessage (ChatColor .GOLD + "[TuffX] " + ChatColor .YELLOW + "Console output is now " + status + "." );
117+ }
118+
119+ private void handleReloadCommand (CommandSender sender ) {
120+ if (!sender .hasPermission ("tuffx.reload" )) {
121+ sender .sendMessage (ChatColor .RED + "You don't have permission to use this command." );
122+ return ;
123+ }
124+ sender .sendMessage (ChatColor .GOLD + "[TuffX] " + ChatColor .YELLOW + "Reloading TuffX..." );
125+ onDisable ();
126+ onEnable ();
127+ sender .sendMessage (ChatColor .GOLD + "[TuffX] " + ChatColor .GREEN + "Reload complete." );
128+ }
129+
130+ private void handleReloadChunksCommand (CommandSender sender ) {
131+ if (!sender .hasPermission ("tuffx.reloadchunks" )) {
132+ sender .sendMessage (ChatColor .RED + "You don't have permission to use this command." );
133+ return ;
134+ }
135+ sender .sendMessage (ChatColor .GOLD + "[TuffX] " + ChatColor .YELLOW + "Clearing chunk cache and resending to all players..." );
136+ sentSections .clear ();
137+
138+ for (Player player : getServer ().getOnlinePlayers ()) {
139+ Chunk playerChunk = player .getLocation ().getChunk ();
140+ int viewDistance = getServer ().getViewDistance ();
141+ World world = player .getWorld ();
142+
143+ for (int x = -viewDistance ; x <= viewDistance ; x ++) {
144+ for (int z = -viewDistance ; z <= viewDistance ; z ++) {
145+ if (world .isChunkLoaded (playerChunk .getX () + x , playerChunk .getZ () + z )) {
146+ Chunk chunk = world .getChunkAt (playerChunk .getX () + x , playerChunk .getZ () + z );
147+ sendChunkSectionsAsync (player , chunk );
148+ }
62149 }
63- isMuted = !isMuted ;
64- String status = isMuted ? ChatColor .RED + "MUTED" : ChatColor .GREEN + "UNMUTED" ;
65- sender .sendMessage (ChatColor .GOLD + "[TuffX] " + ChatColor .YELLOW + "Console output is now " + status + "." );
66- return true ;
67150 }
68- sender .sendMessage (ChatColor .GOLD + "[TuffX] Usage: /tuffx mute" );
69- return true ;
70151 }
71- return false ;
152+ sender .sendMessage (ChatColor .GOLD + "[TuffX] " + ChatColor .GREEN + "Chunk reload initiated for all online players. Reload is complete." );
153+ }
154+
155+ private void handleHelpCommand (CommandSender sender ) {
156+ sender .sendMessage (ChatColor .GOLD + "--- TuffX Commands ---" );
157+ if (sender .hasPermission ("tuffx.help" )) {
158+ sender .sendMessage (ChatColor .YELLOW + "/tuffx help" + ChatColor .GRAY + " - Shows this help message." );
159+ }
160+ if (sender .hasPermission ("tuffx.mute" )) {
161+ sender .sendMessage (ChatColor .YELLOW + "/tuffx mute" + ChatColor .GRAY + " - Toggles console logging for the plugin." );
162+ }
163+ if (sender .hasPermission ("tuffx.reload" )) {
164+ sender .sendMessage (ChatColor .YELLOW + "/tuffx reload" + ChatColor .GRAY + " - Reloads the TuffX plugin." );
165+ }
166+ if (sender .hasPermission ("tuffx.reloadchunks" )) {
167+ sender .sendMessage (ChatColor .YELLOW + "/tuffx reloadchunks" + ChatColor .GRAY + " - Resends below y0 chunks to players." );
168+ }
169+ sender .sendMessage (ChatColor .GOLD + "----------------------" );
72170 }
73171
74172 private void logFancyEnable () {
@@ -94,7 +192,9 @@ public void onDisable() {
94192
95193 @ Override
96194 public void onPluginMessageReceived (String channel , Player player , byte [] message ) {
97- if (!channel .equals (CHANNEL )) { return ; }
195+ if (!channel .equals (CHANNEL )) {
196+ return ;
197+ }
98198
99199 try (ByteArrayInputStream bin = new ByteArrayInputStream (message ); DataInputStream in = new DataInputStream (bin )) {
100200 int x = in .readInt ();
@@ -112,7 +212,8 @@ public void run() {
112212 }
113213 }.runTask (this );
114214 } catch (IOException e ) {
115- if (!isMuted ) getLogger ().warning ("Failed to parse plugin message from " + player .getName () + ": " + e .getMessage ());
215+ if (!isMuted )
216+ getLogger ().warning ("Failed to parse plugin message from " + player .getName () + ": " + e .getMessage ());
116217 }
117218 }
118219
@@ -301,12 +402,14 @@ public void run() {
301402 }
302403 }.runTask (TuffX .this );
303404 } catch (IOException e ) {
304- if (!isMuted ) getLogger ().severe ("Failed to create payload for chunk section: " + key + " | " + e .getMessage ());
405+ if (!isMuted )
406+ getLogger ().severe ("Failed to create payload for chunk section: " + key + " | " + e .getMessage ());
305407 }
306408 }
307409 }
308410 }.runTaskAsynchronously (this );
309411 }
310412
311- private record ChunkSectionKey (UUID playerId , String worldName , int cx , int cz , int sectionY ) {}
312- }
413+ private record ChunkSectionKey (UUID playerId , String worldName , int cx , int cz , int sectionY ) {
414+ }
415+ }
0 commit comments