Commit 99daf973 by Jonathan Thomas

New command `/creaturechat chatbubbles set <on | off>` to show or hide player…

New command `/creaturechat chatbubbles set <on | off>` to show or hide player chat messages in bubbles
parent b210e7c4
Pipeline #13274 passed with stages
in 2 minutes 19 seconds
...@@ -11,6 +11,7 @@ All notable changes to **CreatureChat** are documented in this file. The format ...@@ -11,6 +11,7 @@ All notable changes to **CreatureChat** are documented in this file. The format
- New Step-by-Step **Icon** Tutorial: [ICON.md](ICONS.md) - New Step-by-Step **Icon** Tutorial: [ICON.md](ICONS.md)
- New mixin to extend PlayerSkinTexture to make a copy of the NativeImage + pixel toggle to enable - New mixin to extend PlayerSkinTexture to make a copy of the NativeImage + pixel toggle to enable
- Chat messages are now displayed in chat bubbles above players heads - Chat messages are now displayed in chat bubbles above players heads
- New command `/creaturechat chatbubbles set <on | off>` to show or hide player chat messages in bubbles
- Improved LLM Unit tests (to prevent rate limit issues from certain providers when running all tests) - Improved LLM Unit tests (to prevent rate limit issues from certain providers when running all tests)
- Check friendship direction (+ or -) in LLM unit tests (to verify friendship direction is output correctly) - Check friendship direction (+ or -) in LLM unit tests (to verify friendship direction is output correctly)
......
...@@ -71,6 +71,7 @@ public class ConfigurationHandler { ...@@ -71,6 +71,7 @@ public class ConfigurationHandler {
private int maxOutputTokens = 200; private int maxOutputTokens = 200;
private double percentOfContext = 0.75; private double percentOfContext = 0.75;
private int timeout = 10; private int timeout = 10;
private boolean chatBubbles = true;
private List<String> whitelist = new ArrayList<>(); private List<String> whitelist = new ArrayList<>();
private List<String> blacklist = new ArrayList<>(); private List<String> blacklist = new ArrayList<>();
private String story = ""; private String story = "";
...@@ -114,5 +115,9 @@ public class ConfigurationHandler { ...@@ -114,5 +115,9 @@ public class ConfigurationHandler {
public String getStory() { return story; } public String getStory() { return story; }
public void setStory(String story) { this.story = story; } public void setStory(String story) { this.story = story; }
// Add getter and setter
public boolean getChatBubbles() { return chatBubbles; }
public void setChatBubbles(boolean chatBubblesEnabled) { this.chatBubbles = chatBubblesEnabled; }
} }
} }
...@@ -49,6 +49,7 @@ public class CreatureChatCommands { ...@@ -49,6 +49,7 @@ public class CreatureChatCommands {
.then(registerStoryCommand()) .then(registerStoryCommand())
.then(registerWhitelistCommand()) .then(registerWhitelistCommand())
.then(registerBlacklistCommand()) .then(registerBlacklistCommand())
.then(registerChatBubbleCommand())
.then(registerHelpCommand())); .then(registerHelpCommand()));
} }
...@@ -95,6 +96,35 @@ public class CreatureChatCommands { ...@@ -95,6 +96,35 @@ public class CreatureChatCommands {
.map(Identifier::toString) .map(Identifier::toString)
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
private static LiteralArgumentBuilder<ServerCommandSource> registerChatBubbleCommand() {
return CommandManager.literal("chatbubble")
.requires(source -> source.hasPermissionLevel(4))
.then(CommandManager.literal("set")
.then(CommandManager.literal("on")
.then(addConfigArgs((context, useServerConfig) -> setChatBubbleEnabled(context, true, useServerConfig)))
.executes(context -> setChatBubbleEnabled(context, true, false)))
.then(CommandManager.literal("off")
.then(addConfigArgs((context, useServerConfig) -> setChatBubbleEnabled(context, false, useServerConfig)))
.executes(context -> setChatBubbleEnabled(context, false, false))));
}
private static int setChatBubbleEnabled(CommandContext<ServerCommandSource> context, boolean enabled, boolean useServerConfig) {
ServerCommandSource source = context.getSource();
ConfigurationHandler configHandler = new ConfigurationHandler(source.getServer());
ConfigurationHandler.Config config = configHandler.loadConfig();
config.setChatBubbles(enabled);
if (configHandler.saveConfig(config, useServerConfig)) {
Text feedbackMessage = Text.literal("Player chat bubbles have been " + (enabled ? "enabled" : "disabled") + ".").formatted(Formatting.GREEN);
source.sendFeedback(() -> feedbackMessage, true);
return 1;
} else {
Text feedbackMessage = Text.literal("Failed to update player chat bubble setting.").formatted(Formatting.RED);
source.sendFeedback(() -> feedbackMessage, false);
return 0;
}
}
private static LiteralArgumentBuilder<ServerCommandSource> registerWhitelistCommand() { private static LiteralArgumentBuilder<ServerCommandSource> registerWhitelistCommand() {
return CommandManager.literal("whitelist") return CommandManager.literal("whitelist")
...@@ -135,6 +165,7 @@ public class CreatureChatCommands { ...@@ -135,6 +165,7 @@ public class CreatureChatCommands {
+ "/creaturechat model set <model> - Sets the model\n" + "/creaturechat model set <model> - Sets the model\n"
+ "/creaturechat timeout set <seconds> - Sets the API timeout\n" + "/creaturechat timeout set <seconds> - Sets the API timeout\n"
+ "/creaturechat story set \"<story>\" - Sets a custom story\n" + "/creaturechat story set \"<story>\" - Sets a custom story\n"
+ "/creaturechat chatbubbles set <on | off> - Show player chat bubbles\n"
+ "/creaturechat whitelist <entityType | all | clear> - Show chat bubbles\n" + "/creaturechat whitelist <entityType | all | clear> - Show chat bubbles\n"
+ "/creaturechat blacklist <entityType | all | clear> - Hide chat bubbles\n" + "/creaturechat blacklist <entityType | all | clear> - Hide chat bubbles\n"
+ "\n" + "\n"
...@@ -151,43 +182,42 @@ public class CreatureChatCommands { ...@@ -151,43 +182,42 @@ public class CreatureChatCommands {
.requires(source -> source.hasPermissionLevel(4)) .requires(source -> source.hasPermissionLevel(4))
.then(CommandManager.literal("set") .then(CommandManager.literal("set")
.then(CommandManager.argument("value", StringArgumentType.string()) .then(CommandManager.argument("value", StringArgumentType.string())
.executes(context -> { .then(addConfigArgs((context, useServerConfig) -> {
String story = StringArgumentType.getString(context, "value"); String story = StringArgumentType.getString(context, "value");
ConfigurationHandler.Config config = new ConfigurationHandler(context.getSource().getServer()).loadConfig(); ConfigurationHandler.Config config = new ConfigurationHandler(context.getSource().getServer()).loadConfig();
config.setStory(story); // Assuming Config has a `setStory` method config.setStory(story);
if (new ConfigurationHandler(context.getSource().getServer()).saveConfig(config, true)) { if (new ConfigurationHandler(context.getSource().getServer()).saveConfig(config, useServerConfig)) {
context.getSource().sendFeedback(() -> Text.literal("Story set successfully: " + story).formatted(Formatting.GREEN), true); context.getSource().sendFeedback(() -> Text.literal("Story set successfully: " + story).formatted(Formatting.GREEN), true);
return 1; return 1;
} else { } else {
context.getSource().sendFeedback(() -> Text.literal("Failed to set story!").formatted(Formatting.RED), false); context.getSource().sendFeedback(() -> Text.literal("Failed to set story!").formatted(Formatting.RED), false);
return 0; return 0;
} }
}) }))))
))
.then(CommandManager.literal("clear") .then(CommandManager.literal("clear")
.executes(context -> { .then(addConfigArgs((context, useServerConfig) -> {
ConfigurationHandler.Config config = new ConfigurationHandler(context.getSource().getServer()).loadConfig(); ConfigurationHandler.Config config = new ConfigurationHandler(context.getSource().getServer()).loadConfig();
config.setStory(""); // Clear the story config.setStory("");
if (new ConfigurationHandler(context.getSource().getServer()).saveConfig(config, true)) { if (new ConfigurationHandler(context.getSource().getServer()).saveConfig(config, useServerConfig)) {
context.getSource().sendFeedback(() -> Text.literal("Story cleared successfully!").formatted(Formatting.GREEN), true); context.getSource().sendFeedback(() -> Text.literal("Story cleared successfully!").formatted(Formatting.GREEN), true);
return 1; return 1;
} else { } else {
context.getSource().sendFeedback(() -> Text.literal("Failed to clear story!").formatted(Formatting.RED), false); context.getSource().sendFeedback(() -> Text.literal("Failed to clear story!").formatted(Formatting.RED), false);
return 0; return 0;
} }
})) })))
.then(CommandManager.literal("display") .then(CommandManager.literal("display")
.executes(context -> { .executes(context -> {
ConfigurationHandler.Config config = new ConfigurationHandler(context.getSource().getServer()).loadConfig(); ConfigurationHandler.Config config = new ConfigurationHandler(context.getSource().getServer()).loadConfig();
String story = config.getStory(); // Assuming Config has a `getStory` method String story = config.getStory();
if (story == null || story.isEmpty()) { if (story == null || story.isEmpty()) {
context.getSource().sendFeedback(() -> Text.literal("No story is currently set.").formatted(Formatting.RED), false); context.getSource().sendFeedback(() -> Text.literal("No story is currently set.").formatted(Formatting.RED), false);
return 0; return 0;
} else { } else {
context.getSource().sendFeedback(() -> Text.literal("Current story: " + story).formatted(Formatting.AQUA), false); context.getSource().sendFeedback(() -> Text.literal("Current story: " + story).formatted(Formatting.AQUA), false);
return 1; return 1;
} }
})); }));
} }
private static <T> int setConfig(ServerCommandSource source, String settingName, T value, boolean useServerConfig, String settingDescription) { private static <T> int setConfig(ServerCommandSource source, String settingName, T value, boolean useServerConfig, String settingDescription) {
......
package com.owlmaddie.mixin; package com.owlmaddie.mixin;
import com.owlmaddie.chat.EntityChatData; import com.owlmaddie.chat.EntityChatData;
import com.owlmaddie.commands.ConfigurationHandler;
import com.owlmaddie.network.ServerPackets;
import net.minecraft.network.packet.c2s.play.ChatMessageC2SPacket; import net.minecraft.network.packet.c2s.play.ChatMessageC2SPacket;
import net.minecraft.server.network.ServerPlayNetworkHandler; import net.minecraft.server.network.ServerPlayNetworkHandler;
import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.network.ServerPlayerEntity;
...@@ -19,19 +21,23 @@ public abstract class MixinOnChat { ...@@ -19,19 +21,23 @@ public abstract class MixinOnChat {
@Inject(method = "onChatMessage", at = @At("HEAD"), cancellable = true) @Inject(method = "onChatMessage", at = @At("HEAD"), cancellable = true)
private void onChatMessage(ChatMessageC2SPacket packet, CallbackInfo ci) { private void onChatMessage(ChatMessageC2SPacket packet, CallbackInfo ci) {
// Get the player who sent the message ConfigurationHandler.Config config = new ConfigurationHandler(ServerPackets.serverInstance).loadConfig();
ServerPlayNetworkHandler handler = (ServerPlayNetworkHandler) (Object) this; if (config.getChatBubbles()) {
ServerPlayerEntity player = handler.player;
// Get the chat message // Get the player who sent the message
String chatMessage = packet.chatMessage(); ServerPlayNetworkHandler handler = (ServerPlayNetworkHandler) (Object) this;
ServerPlayerEntity player = handler.player;
// Example: Call your broadcast function // Get the chat message
EntityChatData chatData = new EntityChatData(player.getUuidAsString()); String chatMessage = packet.chatMessage();
chatData.currentMessage = chatMessage;
BroadcastPlayerMessage(chatData, player);
// Optionally, cancel the event to prevent the default behavior // Example: Call your broadcast function
//ci.cancel(); EntityChatData chatData = new EntityChatData(player.getUuidAsString());
chatData.currentMessage = chatMessage;
BroadcastPlayerMessage(chatData, player);
// Optionally, cancel the event to prevent the default behavior
//ci.cancel();
}
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment