diff options
author | Wyvest <45589059+Wyvest@users.noreply.github.com> | 2021-12-23 16:50:27 +0700 |
---|---|---|
committer | Wyvest <45589059+Wyvest@users.noreply.github.com> | 2021-12-23 16:50:27 +0700 |
commit | 1cd878614130057e61e085e7ef791629b1ca9cbe (patch) | |
tree | 24bdb1065523c3feda507452a658569ad7c38b52 | |
parent | de0341400abcfca65afe5d65053ab520aa20844c (diff) | |
download | Chatting-1cd878614130057e61e085e7ef791629b1ca9cbe.tar.gz Chatting-1cd878614130057e61e085e7ef791629b1ca9cbe.tar.bz2 Chatting-1cd878614130057e61e085e7ef791629b1ca9cbe.zip |
chat shortcuts gui + tab autocomplete for shortcuts
8 files changed, 303 insertions, 7 deletions
diff --git a/src/main/java/com/raeids/stratus/mixin/ClientCommandHandlerMixin.java b/src/main/java/com/raeids/stratus/mixin/ClientCommandHandlerMixin.java new file mode 100644 index 0000000..3082b88 --- /dev/null +++ b/src/main/java/com/raeids/stratus/mixin/ClientCommandHandlerMixin.java @@ -0,0 +1,33 @@ +package com.raeids.stratus.mixin; + +import com.raeids.stratus.config.StratusConfig; +import com.raeids.stratus.hook.ChatShortcuts; +import kotlin.Pair; +import net.minecraft.client.Minecraft; +import net.minecraft.command.CommandHandler; +import net.minecraft.command.ICommandSender; +import net.minecraft.util.BlockPos; +import net.minecraftforge.client.ClientCommandHandler; +import net.minecraftforge.fml.client.FMLClientHandler; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +import java.util.List; + +@Mixin(value = ClientCommandHandler.class, remap = false) +public class ClientCommandHandlerMixin extends CommandHandler { + @Redirect(method = "autoComplete", at = @At(value = "INVOKE", target = "Lnet/minecraftforge/client/ClientCommandHandler;getTabCompletionOptions(Lnet/minecraft/command/ICommandSender;Ljava/lang/String;Lnet/minecraft/util/BlockPos;)Ljava/util/List;")) + private List<String> addChatShortcuts(ClientCommandHandler instance, ICommandSender iCommandSender, String leftOfCursor, BlockPos blockPos) { + Minecraft mc = FMLClientHandler.instance().getClient(); + List<String> autocompleteList = instance.getTabCompletionOptions(mc.thePlayer, leftOfCursor, mc.thePlayer.getPosition()); + if (StratusConfig.INSTANCE.getChatShortcuts()) { + for (Pair<String, String> pair : ChatShortcuts.INSTANCE.getShortcuts()) { + if (pair.getFirst().startsWith(leftOfCursor)) { + autocompleteList.add(pair.getFirst()); + } + } + } + return autocompleteList; + } +} diff --git a/src/main/java/com/raeids/stratus/mixin/GuiChatMixin.java b/src/main/java/com/raeids/stratus/mixin/GuiChatMixin.java index 350f000..397cb06 100644 --- a/src/main/java/com/raeids/stratus/mixin/GuiChatMixin.java +++ b/src/main/java/com/raeids/stratus/mixin/GuiChatMixin.java @@ -7,6 +7,7 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiChat; import net.minecraft.client.gui.GuiScreen; import net.minecraft.util.MathHelper; +import org.apache.commons.lang3.StringUtils; import org.lwjgl.input.Mouse; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -80,13 +81,14 @@ public abstract class GuiChatMixin extends GuiScreen { } } } - @ModifyArg(method = "keyTyped", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/GuiChat;sendChatMessage(Ljava/lang/String;)V"), index = 0) - private String modifySentMessage(String original){ - if(original.equalsIgnoreCase ("/pw")){ - return "/p warp"; + @ModifyArg(method = "keyTyped", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/GuiChat;sendChatMessage(Ljava/lang/String;)V"), index = 0) + private String modifySentMessage(String original) { + if (StratusConfig.INSTANCE.getChatShortcuts()) { + if (original.startsWith("/")) { + return "/" + ChatShortcuts.INSTANCE.handleSentCommand(StringUtils.substringAfter(original, "/")); + } } return original; - } } diff --git a/src/main/kotlin/com/raeids/stratus/Stratus.kt b/src/main/kotlin/com/raeids/stratus/Stratus.kt index 6559cc5..eafff31 100644 --- a/src/main/kotlin/com/raeids/stratus/Stratus.kt +++ b/src/main/kotlin/com/raeids/stratus/Stratus.kt @@ -2,6 +2,7 @@ package com.raeids.stratus import com.raeids.stratus.command.StratusCommand import com.raeids.stratus.config.StratusConfig +import com.raeids.stratus.hook.ChatShortcuts import com.raeids.stratus.hook.ChatTabs import com.raeids.stratus.mixin.GuiNewChatAccessor import com.raeids.stratus.updater.Updater @@ -65,6 +66,7 @@ object Stratus { ClientRegistry.registerKeyBinding(keybind) EVENT_BUS.register(this) ChatTabs.initialize() + ChatShortcuts.initialize() Updater.update() } diff --git a/src/main/kotlin/com/raeids/stratus/config/StratusConfig.kt b/src/main/kotlin/com/raeids/stratus/config/StratusConfig.kt index 905f847..8841700 100644 --- a/src/main/kotlin/com/raeids/stratus/config/StratusConfig.kt +++ b/src/main/kotlin/com/raeids/stratus/config/StratusConfig.kt @@ -1,6 +1,7 @@ package com.raeids.stratus.config import com.raeids.stratus.Stratus +import com.raeids.stratus.gui.ChatShortcutViewGui import com.raeids.stratus.hook.ChatTab import com.raeids.stratus.hook.ChatTabs import com.raeids.stratus.updater.DownloadGui @@ -39,7 +40,7 @@ object StratusConfig : Vigilant(File(Stratus.modDir, "${Stratus.ID}.toml"), Stra @Property( type = PropertyType.SWITCH, - name = "Enable Only on Hypixel", + name = "Enable Tabs Only on Hypixel", description = "Enable chat tabs only in Hypixel.", category = "Tabs" ) @@ -47,6 +48,40 @@ object StratusConfig : Vigilant(File(Stratus.modDir, "${Stratus.ID}.toml"), Stra @Property( type = PropertyType.SWITCH, + name = "Chat Shortcuts", + description = "Add chat shortcuts.", + category = "Shortcuts" + ) + var chatShortcuts = false + get() { + if (!field) return false + return if (hypixelOnlyChatShortcuts) { + EssentialAPI.getMinecraftUtil().isHypixel() + } else { + true + } + } + + @Property( + type = PropertyType.SWITCH, + name = "Enable Shortcuts Only on Hypixel", + description = "Enable chat shortcuts only in Hypixel.", + category = "Shortcuts" + ) + var hypixelOnlyChatShortcuts = true + + @Property( + type = PropertyType.BUTTON, + name = "Edit Chat Shortcuts", + description = "Edit chat shortcuts.", + category = "Shortcuts" + ) + fun openChatShortcutsGUI() { + EssentialAPI.getGuiUtil().openScreen(ChatShortcutViewGui()) + } + + @Property( + type = PropertyType.SWITCH, name = "Show Update Notification", description = "Show a notification when you start Minecraft informing you of new updates.", category = "Updater" diff --git a/src/main/kotlin/com/raeids/stratus/gui/ChatShortcutEditGui.kt b/src/main/kotlin/com/raeids/stratus/gui/ChatShortcutEditGui.kt new file mode 100644 index 0000000..fd04f26 --- /dev/null +++ b/src/main/kotlin/com/raeids/stratus/gui/ChatShortcutEditGui.kt @@ -0,0 +1,85 @@ +package com.raeids.stratus.gui + +import com.raeids.stratus.hook.ChatShortcuts +import gg.essential.api.EssentialAPI +import gg.essential.api.gui.buildConfirmationModal +import gg.essential.elementa.WindowScreen +import gg.essential.elementa.components.UIBlock +import gg.essential.elementa.constraints.CenterConstraint +import gg.essential.elementa.constraints.SiblingConstraint +import gg.essential.elementa.dsl.childOf +import gg.essential.elementa.dsl.constrain +import gg.essential.elementa.dsl.percent +import gg.essential.elementa.dsl.pixels +import gg.essential.vigilance.gui.VigilancePalette +import gg.essential.vigilance.gui.settings.ButtonComponent +import gg.essential.vigilance.gui.settings.TextComponent + +class ChatShortcutEditGui(private var alias: String, private var command: String, private val editing: Boolean): WindowScreen() { + + private val initialAlias = alias + private val initialCommand = command + + override fun initScreen(width: Int, height: Int) { + super.initScreen(width, height) + val block = UIBlock(VigilancePalette.getBackground()).constrain { + this.x = CenterConstraint() + this.y = CenterConstraint() + this.width = 100.pixels() + this.height = 100.pixels() + } childOf window + TextComponent(initialAlias, "Alias", wrap = false, protected = false).constrain { + x = CenterConstraint() + y = 10.percent() + }.childOf(block).onValueChange { + if (it is String) alias = it + } + TextComponent(initialCommand, "Command", wrap = false, protected = false).constrain { + x = CenterConstraint() + y = SiblingConstraint() + }.childOf(block).onValueChange { + if (it is String) command = it + } + if (editing) { + ButtonComponent("Reset") { + EssentialAPI.getGuiUtil().openScreen(ChatShortcutEditGui(initialAlias, initialCommand, editing)) + } constrain { + x = CenterConstraint() + y = 70.percent() + } childOf window + } + ButtonComponent("Save") { + if (editing) { + ChatShortcuts.removeShortcut(initialAlias) + } + if (alias.isBlank() || command.isBlank()) { + return@ButtonComponent + } + if (ChatShortcuts.shortcuts.any { it.first == alias }) { + EssentialAPI.getGuiUtil().openScreen(ChatShortcutConfirmGui(alias, command)) + return@ButtonComponent + } + ChatShortcuts.writeShortcut(alias, command) + restorePreviousScreen() + } constrain { + x = CenterConstraint() + y = 80.percent() + } childOf window + } + + inner class ChatShortcutConfirmGui(var alias: String, var command: String): WindowScreen(restoreCurrentGuiOnClose = true) { + override fun initScreen(width: Int, height: Int) { + super.initScreen(width, height) + EssentialAPI.getEssentialComponentFactory().buildConfirmationModal { + text = "An alias with this name already exists, are you sure you want to overwrite it?" + onConfirm = { + ChatShortcuts.writeShortcut(alias, command) + EssentialAPI.getGuiUtil().openScreen(null) + } + onDeny = { + restorePreviousScreen() + } + } childOf this@ChatShortcutConfirmGui.window + } + } +}
\ No newline at end of file diff --git a/src/main/kotlin/com/raeids/stratus/gui/ChatShortcutViewGui.kt b/src/main/kotlin/com/raeids/stratus/gui/ChatShortcutViewGui.kt new file mode 100644 index 0000000..fe5737c --- /dev/null +++ b/src/main/kotlin/com/raeids/stratus/gui/ChatShortcutViewGui.kt @@ -0,0 +1,87 @@ +package com.raeids.stratus.gui + +import com.raeids.stratus.hook.ChatShortcuts +import gg.essential.api.EssentialAPI +import gg.essential.elementa.WindowScreen +import gg.essential.elementa.components.UIBlock +import gg.essential.elementa.components.UIText +import gg.essential.elementa.constraints.CenterConstraint +import gg.essential.elementa.constraints.ChildBasedSizeConstraint +import gg.essential.elementa.constraints.RelativeWindowConstraint +import gg.essential.elementa.constraints.SiblingConstraint +import gg.essential.elementa.dsl.* +import gg.essential.elementa.effects.OutlineEffect +import gg.essential.elementa.state.BasicState +import gg.essential.vigilance.gui.VigilancePalette +import gg.essential.vigilance.gui.settings.ButtonComponent +import gg.essential.vigilance.gui.settings.SettingComponent + +class ChatShortcutViewGui : WindowScreen(true) { + override fun initScreen(width: Int, height: Int) { + super.initScreen(width, height) + for ((yes, shortcut) in ChatShortcuts.shortcuts.withIndex()) { + val block = UIBlock(VigilancePalette.getBackground()).constrain { + x = 3.percent() + y = (yes * 12).percent() + this.width = 94.percent() + this.height = 25.pixels() + } childOf this.window + TextBlock(shortcut.first).constrain { + x = RelativeWindowConstraint(0.05F) + y = CenterConstraint() + } childOf block + TextBlock(shortcut.second).constrain { + x = SiblingConstraint(10F) + y = CenterConstraint() + } childOf block + ButtonComponent("Edit") { + println("${shortcut.first} ${shortcut.second}") + EssentialAPI.getGuiUtil().openScreen(ChatShortcutEditGui(shortcut.first, shortcut.second, true)) + } constrain { + x = SiblingConstraint(20F) + y = CenterConstraint() + } childOf block + ButtonComponent("Delete") { + println("${shortcut.first} ${shortcut.second}") + ChatShortcuts.removeShortcut(shortcut.first) + EssentialAPI.getGuiUtil().openScreen(ChatShortcutViewGui()) + } constrain { + x = SiblingConstraint(5F) + y = CenterConstraint() + } childOf block + } + ButtonComponent("New") { + EssentialAPI.getGuiUtil().openScreen(ChatShortcutEditGui("", "", false)) + } constrain { + x = CenterConstraint() + y = 80.percent() + } childOf window + } +} + +class TextBlock( + text: String +) : SettingComponent() { + private val textHolder = UIBlock().constrain { + width = ChildBasedSizeConstraint() + 6.pixels() + height = ChildBasedSizeConstraint() + 6.pixels() + color = VigilancePalette.getDarkHighlight().toConstraint() + } childOf this effect OutlineEffect( + VigilancePalette.getDivider(), + 1f + ).bindColor(BasicState(VigilancePalette.getDivider())) + + private val textInput: UIText = UIText(text).constrain { + x = 3.pixels() + y = 3.pixels() + } + + init { + textInput childOf textHolder + + constrain { + width = ChildBasedSizeConstraint() + height = ChildBasedSizeConstraint() + } + } +}
\ No newline at end of file diff --git a/src/main/kotlin/com/raeids/stratus/hook/ChatShortcuts.kt b/src/main/kotlin/com/raeids/stratus/hook/ChatShortcuts.kt new file mode 100644 index 0000000..dfea873 --- /dev/null +++ b/src/main/kotlin/com/raeids/stratus/hook/ChatShortcuts.kt @@ -0,0 +1,51 @@ +package com.raeids.stratus.hook + +import com.google.gson.JsonObject +import com.google.gson.JsonParser +import com.raeids.stratus.Stratus +import java.io.File + +object ChatShortcuts { + private val shortcutsFile = File(Stratus.modDir, "chatshortcuts.json") + private val PARSER = JsonParser() + + val shortcuts = mutableSetOf<Pair<String, String>>() + + + fun initialize() { + if (!shortcutsFile.exists()) { + shortcutsFile.createNewFile() + shortcutsFile.writeText( + JsonObject().toString() + ) + } else { + val jsonObj = PARSER.parse(shortcutsFile.readText()).asJsonObject + for (shortcut in jsonObj.entrySet()) { + shortcuts.add(shortcut.key to shortcut.value.asString) + } + } + } + + fun removeShortcut(key: String) { + shortcuts.removeIf { it.first == key } + val jsonObj = PARSER.parse(shortcutsFile.readText()).asJsonObject + jsonObj.remove(key) + shortcutsFile.writeText(jsonObj.toString()) + } + + fun writeShortcut(key: String, value: String) { + shortcuts.add(key to value) + val jsonObj = PARSER.parse(shortcutsFile.readText()).asJsonObject + jsonObj.addProperty(key, value) + shortcutsFile.writeText(jsonObj.toString()) + } + + fun handleSentCommand(command: String): String { + shortcuts.forEach { + if (command == it.first || (command.startsWith(it.first) && command.substringAfter(it.first).startsWith(" "))) { + return command.replaceFirst(it.first, it.second) + } + } + return command + } +}
\ No newline at end of file diff --git a/src/main/resources/mixins.stratus.json b/src/main/resources/mixins.stratus.json index 5388c40..16489b4 100644 --- a/src/main/resources/mixins.stratus.json +++ b/src/main/resources/mixins.stratus.json @@ -4,9 +4,10 @@ "package": "com.raeids.stratus.mixin", "refmap": "mixins.${id}.refmap.json", "mixins": [ + "ClientCommandHandlerMixin", + "EntityPlayerSPMixin", "GuiChatMixin", "GuiNewChatAccessor", - "EntityPlayerSPMixin", "GuiNewChatMixin" ], "verbose": true |