feat(chat): improve chat room management UX
- Added hover and click actions to chat commands for better interaction. - Enhanced error and confirmation messages for clarity. - Introduced validation for room IDs and improved handling of invalid IDs. Signed-off-by: Minecon724 <git@m724.eu>
This commit is contained in:
parent
6ff6ec9d6b
commit
316d479fd8
4 changed files with 148 additions and 94 deletions
|
@ -9,6 +9,10 @@ package eu.m724.tweaks.module.chat;
|
|||
import eu.m724.tweaks.Language;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import net.md_5.bungee.api.chat.BaseComponent;
|
||||
import net.md_5.bungee.api.chat.ClickEvent;
|
||||
import net.md_5.bungee.api.chat.ComponentBuilder;
|
||||
import net.md_5.bungee.api.chat.HoverEvent;
|
||||
import net.md_5.bungee.api.chat.hover.content.Text;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
|
@ -64,7 +68,11 @@ public class ChatCommands implements CommandExecutor {
|
|||
authenticated = true;
|
||||
}
|
||||
} else {
|
||||
component = Language.getComponent("chatNoSuchRoom", ChatColor.RED, id);
|
||||
if (ChatRoomLoader.validateId(id) == 0) {
|
||||
component = Language.getComponent("chatNoSuchRoom", ChatColor.RED, id);
|
||||
} else {
|
||||
component = Language.getComponent("chatNoSuchRoomInvalidId", ChatColor.RED, id);
|
||||
}
|
||||
}
|
||||
|
||||
if (authenticated) {
|
||||
|
@ -84,110 +92,153 @@ public class ChatCommands implements CommandExecutor {
|
|||
ChatRoom chatRoom = manager.getPlayerChatRoom(player);
|
||||
boolean isOwner = player.equals(chatRoom.owner);
|
||||
|
||||
if (args.length > 1) {
|
||||
String action = args[0];
|
||||
String argument = args[1];
|
||||
String action = args.length > 0 ? args[0] : null;
|
||||
String argument = args.length > 1 ? args[1] : null;
|
||||
|
||||
switch (action) {
|
||||
case "create" -> {
|
||||
try {
|
||||
ChatRoom newRoom = manager.createChatRoom(argument, null, player);
|
||||
sender.sendMessage("Created a chat room. Join it: /c " + newRoom.id);
|
||||
sender.sendMessage("You might also want to protect it with a password: /cm setpassword");
|
||||
} catch (ChatModule.InvalidIdException e) {
|
||||
sender.sendMessage("ID is invalid: " + e.getMessage());
|
||||
} catch (ChatModule.ChatRoomExistsException e) {
|
||||
sender.sendMessage("Room %s already exists".formatted(argument));
|
||||
} catch (IOException e) {
|
||||
sender.sendMessage("Error creating room");
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
switch (action) {
|
||||
case "create" -> {
|
||||
if (argument == null) {
|
||||
sender.sendMessage("Please pass a room name as an argument. The room name can contain only characters and digits.");
|
||||
return true;
|
||||
}
|
||||
case "delete" -> {
|
||||
|
||||
try {
|
||||
ChatRoom newRoom = manager.createChatRoom(argument, null, player);
|
||||
|
||||
var component = new ComponentBuilder("Created a chat room. Join it: ").color(ChatColor.GOLD)
|
||||
.append("/c " + newRoom.id).color(ChatColor.AQUA)
|
||||
.event(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/c " + newRoom.id))
|
||||
.event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(Language.getString("clickToExecuteCommand"))))
|
||||
.append("\n")
|
||||
.append("To protect it with a password, join it and use ").color(ChatColor.GRAY)
|
||||
.append("/cm setpassword <password>").color(ChatColor.DARK_PURPLE)
|
||||
.event(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/cm setpassword "))
|
||||
.event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(Language.getString("clickToExecuteCommand"))));
|
||||
|
||||
sender.spigot().sendMessage(component.build());
|
||||
} catch (ChatModule.InvalidIdException e) {
|
||||
var component = new ComponentBuilder("ID is invalid: ").color(ChatColor.GRAY)
|
||||
.append(e.getMessage()).color(ChatColor.RED);
|
||||
|
||||
sender.spigot().sendMessage(component.build());
|
||||
} catch (ChatModule.ChatRoomExistsException e) {
|
||||
sender.sendMessage("Room %s already exists".formatted(argument));
|
||||
} catch (IOException e) {
|
||||
sender.sendMessage("Error creating room");
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
case "delete" -> {
|
||||
if (isOwner) {
|
||||
if (argument == null) {
|
||||
sender.sendMessage("You want to delete room \"%s\". Confirm by passing the ID as an argument.".formatted(chatRoom.id));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (argument.equals(chatRoom.id)) {
|
||||
if (isOwner) {
|
||||
manager.deleteChatRoom(chatRoom);
|
||||
sender.sendMessage("Room %s deleted".formatted(chatRoom.id));
|
||||
} else {
|
||||
sender.sendMessage("You're not the owner of %s, please enter the room you want to make changes in".formatted(chatRoom.id));
|
||||
}
|
||||
manager.deleteChatRoom(chatRoom);
|
||||
sender.sendMessage("Room %s deleted".formatted(chatRoom.id));
|
||||
} else {
|
||||
sender.sendMessage("Pass %s as an argument to confirm".formatted(chatRoom.id));
|
||||
sender.sendMessage("Pass \"%s\" as an argument to confirm".formatted(chatRoom.id));
|
||||
}
|
||||
} else {
|
||||
sender.sendMessage("You're not the owner of %s, please enter the room you want to make changes in".formatted(chatRoom.id));
|
||||
}
|
||||
case "setowner" -> {
|
||||
if (isOwner) {
|
||||
Player newOwner = Bukkit.getPlayer(argument);
|
||||
if (newOwner != null && newOwner.isOnline()) {
|
||||
chatRoom.owner = newOwner;
|
||||
try {
|
||||
manager.saveChatRoom(chatRoom);
|
||||
sender.sendMessage("Owner changed to " + newOwner.getName());
|
||||
} catch (IOException e) {
|
||||
sender.sendMessage("Error changing owner");
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
} else {
|
||||
sender.sendMessage("Player must be online");
|
||||
}
|
||||
} else {
|
||||
sender.sendMessage("You're not the owner of %s, please enter the room you want to make changes in".formatted(chatRoom.id));
|
||||
}
|
||||
case "setowner" -> {
|
||||
if (isOwner) {
|
||||
if (argument == null) {
|
||||
sender.sendMessage("To transfer ownership of room %s, pass the new owner name as an argument for this action.".formatted(chatRoom.id));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
case "setpassword" -> {
|
||||
if (isOwner) {
|
||||
chatRoom.password = Arrays.stream(args).skip(1).collect(Collectors.joining(" "));
|
||||
|
||||
Player newOwner = Bukkit.getPlayer(argument);
|
||||
if (newOwner != null && newOwner.isOnline()) {
|
||||
chatRoom.owner = newOwner;
|
||||
try {
|
||||
manager.saveChatRoom(chatRoom);
|
||||
sender.sendMessage("Password changed");
|
||||
sender.sendMessage("Owner changed to " + newOwner.getName());
|
||||
} catch (IOException e) {
|
||||
sender.sendMessage("Error changing password");
|
||||
sender.sendMessage("Error changing owner");
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
} else {
|
||||
sender.sendMessage("You're not the owner of %s, please enter the room you want to make changes in".formatted(chatRoom.id));
|
||||
sender.sendMessage("Player must be online");
|
||||
}
|
||||
} else {
|
||||
sender.sendMessage("You're not the owner of %s, please enter the room you want to make changes in".formatted(chatRoom.id));
|
||||
}
|
||||
case "setcolor" -> {
|
||||
if (isOwner) {
|
||||
ChatColor newColor = ChatColor.of(argument);
|
||||
if (newColor != null) {
|
||||
chatRoom.color = newColor;
|
||||
try {
|
||||
manager.saveChatRoom(chatRoom);
|
||||
sender.sendMessage("Message color changed to " + newColor.getName());
|
||||
} catch (IOException e) {
|
||||
sender.sendMessage("Error changing color");
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
} else {
|
||||
sender.sendMessage("Invalid color");
|
||||
}
|
||||
case "setpassword" -> {
|
||||
if (isOwner) {
|
||||
if (argument == null) {
|
||||
sender.sendMessage("To change the password of room %s, pass the new password as an argument for this action.".formatted(chatRoom.id));
|
||||
return true;
|
||||
}
|
||||
|
||||
chatRoom.password = Arrays.stream(args).skip(1).collect(Collectors.joining(" "));
|
||||
try {
|
||||
manager.saveChatRoom(chatRoom);
|
||||
|
||||
var component = new ComponentBuilder("Password changed to ").color(ChatColor.GREEN)
|
||||
.append("(hover to view)").color(ChatColor.AQUA)
|
||||
.event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(chatRoom.password)))
|
||||
.append("\n")
|
||||
.append("To unset, ").color(ChatColor.GRAY)
|
||||
.append("/cm unsetpassword").color(ChatColor.DARK_PURPLE)
|
||||
.event(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/cm unsetpassword"))
|
||||
.event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(Language.getString("clickToExecuteCommand"))));
|
||||
|
||||
sender.spigot().sendMessage(component.build());
|
||||
} catch (IOException e) {
|
||||
sender.sendMessage("Error changing password");
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
} else {
|
||||
sender.sendMessage("You're not the owner of %s, please enter the room you want to make changes in".formatted(chatRoom.id));
|
||||
}
|
||||
}
|
||||
case "unsetpassword" -> {
|
||||
if (isOwner) {
|
||||
chatRoom.password = null;
|
||||
try {
|
||||
manager.saveChatRoom(chatRoom);
|
||||
sender.sendMessage("Password removed from " + chatRoom.id);
|
||||
} catch (IOException e) {
|
||||
sender.sendMessage("Error removing password");
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
} else {
|
||||
sender.sendMessage("You're not the owner of %s, please enter the room you want to make changes in".formatted(chatRoom.id));
|
||||
}
|
||||
}
|
||||
case "setcolor" -> {
|
||||
if (isOwner) {
|
||||
if (argument == null) {
|
||||
sender.sendMessage("To change the message color of room %s, pass the new color as an argument for this action. #hex or color name.".formatted(chatRoom.id));
|
||||
return true;
|
||||
}
|
||||
|
||||
ChatColor newColor = ChatColor.of(argument);
|
||||
if (newColor != null) {
|
||||
chatRoom.color = newColor;
|
||||
try {
|
||||
manager.saveChatRoom(chatRoom);
|
||||
sender.sendMessage("Message color changed to " + newColor.getName());
|
||||
} catch (IOException e) {
|
||||
sender.sendMessage("Error changing color");
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
} else {
|
||||
sender.sendMessage("You're not the owner of %s, please enter the room you want to make changes in".formatted(chatRoom.id));
|
||||
sender.sendMessage("Invalid color");
|
||||
}
|
||||
}
|
||||
default -> {
|
||||
sender.sendMessage("Actions: create, delete, setowner, setpassword, setcolor");
|
||||
} else {
|
||||
sender.sendMessage("You're not the owner of %s, please enter the room you want to make changes in".formatted(chatRoom.id));
|
||||
}
|
||||
}
|
||||
} else if (args.length > 0) {
|
||||
switch (args[0]) {
|
||||
case "create" ->
|
||||
sender.sendMessage("Please pass a room name as an argument. The room name must be of characters and digits.");
|
||||
case "delete" ->
|
||||
sender.sendMessage("You want to delete room %s. Confirm by passing its name as an argument for this action.".formatted(chatRoom.id));
|
||||
case "setowner" ->
|
||||
sender.sendMessage("To transfer ownership of room %s, pass the new owner name as an argument for this action.".formatted(chatRoom.id));
|
||||
case "setpassword" ->
|
||||
sender.sendMessage("To change the password of room %s, pass the new password as an argument for this action.".formatted(chatRoom.id));
|
||||
case "setcolor" ->
|
||||
sender.sendMessage("To change the message color of room %s, pass the new color as an argument for this action. #hex or color name.".formatted(chatRoom.id));
|
||||
default ->
|
||||
sender.sendMessage("Actions: create, delete, setowner, setpassword, setcolor");
|
||||
case null, default -> {
|
||||
sender.sendMessage("Actions: create, delete, setowner, setpassword, unsetpassword, setcolor");
|
||||
}
|
||||
} else {
|
||||
sender.sendMessage("Actions: create, delete, setowner, setpassword, setcolor");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -153,11 +153,11 @@ public class ChatModule extends TweaksModule {
|
|||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
throw new InvalidIdException("ID is too short, make it at least 2 chars");
|
||||
throw new InvalidIdException("ID is too short, it must be at least 2 chars long");
|
||||
case 2:
|
||||
throw new InvalidIdException("ID is too long, make it 20 chars or shorter");
|
||||
throw new InvalidIdException("ID is too long, it mustn't be longer than 20 chars");
|
||||
case 4:
|
||||
throw new InvalidIdException("ID must be composed from characters a-z and numbers 0-9");
|
||||
throw new InvalidIdException("ID must be of characters a-z and numbers 0-9");
|
||||
}
|
||||
|
||||
if (getById(id) != null)
|
||||
|
|
|
@ -29,7 +29,7 @@ public class ChatRoomLoader {
|
|||
*/
|
||||
static File getFile(String id) {
|
||||
if (validateId(id) != 0)
|
||||
throw new RuntimeException("Invalid id: " + id);
|
||||
return null;
|
||||
|
||||
return new File(chatRoomsDir, id + ".yml");
|
||||
}
|
||||
|
@ -66,7 +66,8 @@ public class ChatRoomLoader {
|
|||
*/
|
||||
static ChatRoom load(String id) {
|
||||
File chatRoomFile = getFile(id);
|
||||
if (!chatRoomFile.exists()) return null;
|
||||
if (chatRoomFile == null || !chatRoomFile.exists())
|
||||
return null;
|
||||
|
||||
YamlConfiguration configuration = YamlConfiguration.loadConfiguration(chatRoomFile);
|
||||
|
||||
|
|
|
@ -13,17 +13,18 @@ languageEnglish = English
|
|||
updateAvailableNotice = Available updates (%d):
|
||||
|
||||
# Used in /updates
|
||||
updatesNotChecked = Not checked yet
|
||||
updatesNotChecked = Not checked yet.
|
||||
# %s is time as HH:mm
|
||||
updatesNoUpdates = No available updates. Last checked: %s
|
||||
# %s is update title
|
||||
updatesClickToOpen = Click to open on SpigotMC "%s"
|
||||
|
||||
# Used in /chat
|
||||
chatPasswordProtected = This room is password protected
|
||||
chatWrongPassword = Wrong password
|
||||
chatNoSuchRoom = No room named %s
|
||||
chatAlreadyHere = You're already in this room
|
||||
chatPasswordProtected = This room is password protected.
|
||||
chatWrongPassword = Wrong password.
|
||||
chatNoSuchRoom = Room %s doesn't exist.
|
||||
chatNoSuchRoomInvalidId = Room %s doesn't exist, because the ID is invalid.
|
||||
chatAlreadyHere = You're already in this room.
|
||||
|
||||
# Used when a player joins using the wrong key or no key
|
||||
authKickWrongKey = You're connecting to the wrong server address. You must connect to the one you're registered to.
|
||||
|
@ -34,6 +35,7 @@ authKickError = An error occured. Please try again. If this persists, contact an
|
|||
redstoneGatewayItem = Redstone gateway
|
||||
|
||||
clickToCopy = Click to copy to clipboard
|
||||
clickToExecuteCommand = Click to execute command
|
||||
|
||||
durabilityEnabled = Enabled durability alert
|
||||
durabilityDisabled = Disabled durability alert
|
Loading…
Add table
Reference in a new issue