diff --git a/src/main/java/com/github/hhhzzzsss/songplayer/CommandProcessor.java b/src/main/java/com/github/hhhzzzsss/songplayer/CommandProcessor.java index 122cda6..2f1177f 100644 --- a/src/main/java/com/github/hhhzzzsss/songplayer/CommandProcessor.java +++ b/src/main/java/com/github/hhhzzzsss/songplayer/CommandProcessor.java @@ -3,10 +3,17 @@ package com.github.hhhzzzsss.songplayer; import com.github.hhhzzzsss.songplayer.playing.SongHandler; import com.github.hhhzzzsss.songplayer.song.Note; import com.github.hhhzzzsss.songplayer.song.Song; +import com.mojang.brigadier.suggestion.Suggestions; +import com.mojang.brigadier.suggestion.SuggestionsBuilder; +import net.minecraft.command.CommandSource; import java.io.File; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.stream.Collectors; public class CommandProcessor { public static ArrayList commands = new ArrayList<>(); @@ -53,6 +60,9 @@ public class CommandProcessor { public abstract String getSyntax(); public abstract String getDescription(); public abstract boolean processCommand(String args); + public CompletableFuture getSuggestions(String args, SuggestionsBuilder suggestionsBuilder) { + return null; + } } private static class helpCommand extends Command { @@ -106,6 +116,13 @@ public class CommandProcessor { return false; } } + public CompletableFuture getSuggestions(String args, SuggestionsBuilder suggestionsBuilder) { + List filenames = Arrays.stream(SongPlayer.SONG_DIR.listFiles()) + .filter(File::isFile) + .map(File::getName) + .collect(Collectors.toList()); + return CommandSource.suggestMatching(filenames, suggestionsBuilder); + } } private static class stopCommand extends Command { @@ -464,4 +481,23 @@ public class CommandProcessor { } } } + + // $ prefix included in command string + public static CompletableFuture handleSuggestions(String text, SuggestionsBuilder suggestionsBuilder) { + if (!text.contains(" ")) { + List names = commands + .stream() + .map((command) -> "$"+command.getName()) + .collect(Collectors.toList()); + return CommandSource.suggestMatching(names, suggestionsBuilder); + } else { + String[] split = text.split(" "); + for (Command command : commands) { + if (split[0].equalsIgnoreCase("$"+command.getName())) { + return command.getSuggestions(split.length == 1 ? "" : split[1], suggestionsBuilder); + } + } + } + return null; + } } diff --git a/src/main/java/com/github/hhhzzzsss/songplayer/mixin/CommandSuggestorMixin.java b/src/main/java/com/github/hhhzzzsss/songplayer/mixin/CommandSuggestorMixin.java new file mode 100644 index 0000000..8e67627 --- /dev/null +++ b/src/main/java/com/github/hhhzzzsss/songplayer/mixin/CommandSuggestorMixin.java @@ -0,0 +1,53 @@ +package com.github.hhhzzzsss.songplayer.mixin; + +import com.github.hhhzzzsss.songplayer.CommandProcessor; +import com.mojang.brigadier.suggestion.Suggestions; +import com.mojang.brigadier.suggestion.SuggestionsBuilder; +import net.minecraft.client.gui.screen.CommandSuggestor; +import net.minecraft.client.gui.screen.CommandSuggestor.SuggestionWindow; +import net.minecraft.client.gui.widget.TextFieldWidget; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.concurrent.CompletableFuture; + +@Mixin(CommandSuggestor.class) +public class CommandSuggestorMixin { + @Shadow + CompletableFuture pendingSuggestions; + + @Shadow + private static int getStartOfCurrentWord(String input) { + return 0; + } + + @Shadow + public void showSuggestions(boolean narrateFirstSuggestion) {} + + @Shadow + final TextFieldWidget textField; + + public CommandSuggestorMixin() { + textField = null; + } + + @Inject(at = @At("TAIL"), method = "refresh()V") + public void onRefresh(CallbackInfo ci) { + String textStr = this.textField.getText(); + int cursorPos = this.textField.getCursor(); + String preStr = textStr.substring(0, cursorPos); + if (!preStr.startsWith("$")) { + return; + } + + int wordStart = getStartOfCurrentWord(preStr); + CompletableFuture suggestions = CommandProcessor.handleSuggestions(preStr, new SuggestionsBuilder(preStr, wordStart)); + if (suggestions != null) { + this.pendingSuggestions = suggestions; + this.showSuggestions(true); + } + } +} diff --git a/src/main/resources/songplayer.mixins.json b/src/main/resources/songplayer.mixins.json index b7d90e4..844a3cb 100644 --- a/src/main/resources/songplayer.mixins.json +++ b/src/main/resources/songplayer.mixins.json @@ -9,6 +9,7 @@ "ClientPlayerEntityMixin", "ClientPlayNetworkHandlerMixin", "ClientWorldMixin", + "CommandSuggestorMixin", "InGameHudMixin", "MinecraftClientMixin" ],