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 eu.m724.tweaks.Language;
|
||||||
import net.md_5.bungee.api.ChatColor;
|
import net.md_5.bungee.api.ChatColor;
|
||||||
import net.md_5.bungee.api.chat.BaseComponent;
|
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.Bukkit;
|
||||||
import org.bukkit.command.Command;
|
import org.bukkit.command.Command;
|
||||||
import org.bukkit.command.CommandExecutor;
|
import org.bukkit.command.CommandExecutor;
|
||||||
|
@ -64,7 +68,11 @@ public class ChatCommands implements CommandExecutor {
|
||||||
authenticated = true;
|
authenticated = true;
|
||||||
}
|
}
|
||||||
} else {
|
} 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) {
|
if (authenticated) {
|
||||||
|
@ -84,110 +92,153 @@ public class ChatCommands implements CommandExecutor {
|
||||||
ChatRoom chatRoom = manager.getPlayerChatRoom(player);
|
ChatRoom chatRoom = manager.getPlayerChatRoom(player);
|
||||||
boolean isOwner = player.equals(chatRoom.owner);
|
boolean isOwner = player.equals(chatRoom.owner);
|
||||||
|
|
||||||
if (args.length > 1) {
|
String action = args.length > 0 ? args[0] : null;
|
||||||
String action = args[0];
|
String argument = args.length > 1 ? args[1] : null;
|
||||||
String argument = args[1];
|
|
||||||
|
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case "create" -> {
|
case "create" -> {
|
||||||
try {
|
if (argument == null) {
|
||||||
ChatRoom newRoom = manager.createChatRoom(argument, null, player);
|
sender.sendMessage("Please pass a room name as an argument. The room name can contain only characters and digits.");
|
||||||
sender.sendMessage("Created a chat room. Join it: /c " + newRoom.id);
|
return true;
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
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 (argument.equals(chatRoom.id)) {
|
||||||
if (isOwner) {
|
manager.deleteChatRoom(chatRoom);
|
||||||
manager.deleteChatRoom(chatRoom);
|
sender.sendMessage("Room %s deleted".formatted(chatRoom.id));
|
||||||
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));
|
|
||||||
}
|
|
||||||
} else {
|
} 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) {
|
case "setowner" -> {
|
||||||
Player newOwner = Bukkit.getPlayer(argument);
|
if (isOwner) {
|
||||||
if (newOwner != null && newOwner.isOnline()) {
|
if (argument == null) {
|
||||||
chatRoom.owner = newOwner;
|
sender.sendMessage("To transfer ownership of room %s, pass the new owner name as an argument for this action.".formatted(chatRoom.id));
|
||||||
try {
|
return true;
|
||||||
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 "setpassword" -> {
|
Player newOwner = Bukkit.getPlayer(argument);
|
||||||
if (isOwner) {
|
if (newOwner != null && newOwner.isOnline()) {
|
||||||
chatRoom.password = Arrays.stream(args).skip(1).collect(Collectors.joining(" "));
|
chatRoom.owner = newOwner;
|
||||||
try {
|
try {
|
||||||
manager.saveChatRoom(chatRoom);
|
manager.saveChatRoom(chatRoom);
|
||||||
sender.sendMessage("Password changed");
|
sender.sendMessage("Owner changed to " + newOwner.getName());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
sender.sendMessage("Error changing password");
|
sender.sendMessage("Error changing owner");
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
} else {
|
} 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) {
|
case "setpassword" -> {
|
||||||
ChatColor newColor = ChatColor.of(argument);
|
if (isOwner) {
|
||||||
if (newColor != null) {
|
if (argument == null) {
|
||||||
chatRoom.color = newColor;
|
sender.sendMessage("To change the password of room %s, pass the new password as an argument for this action.".formatted(chatRoom.id));
|
||||||
try {
|
return true;
|
||||||
manager.saveChatRoom(chatRoom);
|
}
|
||||||
sender.sendMessage("Message color changed to " + newColor.getName());
|
|
||||||
} catch (IOException e) {
|
chatRoom.password = Arrays.stream(args).skip(1).collect(Collectors.joining(" "));
|
||||||
sender.sendMessage("Error changing color");
|
try {
|
||||||
throw new RuntimeException(e);
|
manager.saveChatRoom(chatRoom);
|
||||||
}
|
|
||||||
} else {
|
var component = new ComponentBuilder("Password changed to ").color(ChatColor.GREEN)
|
||||||
sender.sendMessage("Invalid color");
|
.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 {
|
} 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");
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
default -> {
|
sender.sendMessage("You're not the owner of %s, please enter the room you want to make changes in".formatted(chatRoom.id));
|
||||||
sender.sendMessage("Actions: create, delete, setowner, setpassword, setcolor");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (args.length > 0) {
|
case null, default -> {
|
||||||
switch (args[0]) {
|
sender.sendMessage("Actions: create, delete, setowner, setpassword, unsetpassword, setcolor");
|
||||||
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");
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
sender.sendMessage("Actions: create, delete, setowner, setpassword, setcolor");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -153,11 +153,11 @@ public class ChatModule extends TweaksModule {
|
||||||
case 0:
|
case 0:
|
||||||
break;
|
break;
|
||||||
case 1:
|
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:
|
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:
|
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)
|
if (getById(id) != null)
|
||||||
|
|
|
@ -29,7 +29,7 @@ public class ChatRoomLoader {
|
||||||
*/
|
*/
|
||||||
static File getFile(String id) {
|
static File getFile(String id) {
|
||||||
if (validateId(id) != 0)
|
if (validateId(id) != 0)
|
||||||
throw new RuntimeException("Invalid id: " + id);
|
return null;
|
||||||
|
|
||||||
return new File(chatRoomsDir, id + ".yml");
|
return new File(chatRoomsDir, id + ".yml");
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,8 @@ public class ChatRoomLoader {
|
||||||
*/
|
*/
|
||||||
static ChatRoom load(String id) {
|
static ChatRoom load(String id) {
|
||||||
File chatRoomFile = getFile(id);
|
File chatRoomFile = getFile(id);
|
||||||
if (!chatRoomFile.exists()) return null;
|
if (chatRoomFile == null || !chatRoomFile.exists())
|
||||||
|
return null;
|
||||||
|
|
||||||
YamlConfiguration configuration = YamlConfiguration.loadConfiguration(chatRoomFile);
|
YamlConfiguration configuration = YamlConfiguration.loadConfiguration(chatRoomFile);
|
||||||
|
|
||||||
|
|
|
@ -13,17 +13,18 @@ languageEnglish = English
|
||||||
updateAvailableNotice = Available updates (%d):
|
updateAvailableNotice = Available updates (%d):
|
||||||
|
|
||||||
# Used in /updates
|
# Used in /updates
|
||||||
updatesNotChecked = Not checked yet
|
updatesNotChecked = Not checked yet.
|
||||||
# %s is time as HH:mm
|
# %s is time as HH:mm
|
||||||
updatesNoUpdates = No available updates. Last checked: %s
|
updatesNoUpdates = No available updates. Last checked: %s
|
||||||
# %s is update title
|
# %s is update title
|
||||||
updatesClickToOpen = Click to open on SpigotMC "%s"
|
updatesClickToOpen = Click to open on SpigotMC "%s"
|
||||||
|
|
||||||
# Used in /chat
|
# Used in /chat
|
||||||
chatPasswordProtected = This room is password protected
|
chatPasswordProtected = This room is password protected.
|
||||||
chatWrongPassword = Wrong password
|
chatWrongPassword = Wrong password.
|
||||||
chatNoSuchRoom = No room named %s
|
chatNoSuchRoom = Room %s doesn't exist.
|
||||||
chatAlreadyHere = You're already in this room
|
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
|
# 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.
|
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
|
redstoneGatewayItem = Redstone gateway
|
||||||
|
|
||||||
clickToCopy = Click to copy to clipboard
|
clickToCopy = Click to copy to clipboard
|
||||||
|
clickToExecuteCommand = Click to execute command
|
||||||
|
|
||||||
durabilityEnabled = Enabled durability alert
|
durabilityEnabled = Enabled durability alert
|
||||||
durabilityDisabled = Disabled durability alert
|
durabilityDisabled = Disabled durability alert
|
Loading…
Add table
Reference in a new issue