From c40227d15d05cda11ff1bb049555c54f1c486efd Mon Sep 17 00:00:00 2001 From: md678685 <1917406+md678685@users.noreply.github.com> Date: Wed, 29 May 2019 20:52:17 +0100 Subject: [PATCH 1/3] Implement nicknames I'm not convinced about the command syntax - should this be split into separate commands? --- .../neutron/api/locale/LocaleMessage.java | 5 ++ .../me/crypnotic/neutron/api/user/User.java | 67 ++++++++++++++++++- .../manager/user/holder/ConsoleUser.java | 15 +++++ .../manager/user/holder/PlayerData.java | 7 +- .../manager/user/holder/PlayerUser.java | 24 +++++-- .../neutron/module/command/Commands.java | 1 + .../command/options/NicknameCommand.java | 45 +++++++++++++ src/main/resources/config.conf | 7 +- 8 files changed, 161 insertions(+), 10 deletions(-) create mode 100644 src/main/java/me/crypnotic/neutron/module/command/options/NicknameCommand.java diff --git a/src/main/java/me/crypnotic/neutron/api/locale/LocaleMessage.java b/src/main/java/me/crypnotic/neutron/api/locale/LocaleMessage.java index 217891c..446de12 100644 --- a/src/main/java/me/crypnotic/neutron/api/locale/LocaleMessage.java +++ b/src/main/java/me/crypnotic/neutron/api/locale/LocaleMessage.java @@ -49,6 +49,11 @@ public enum LocaleMessage { MESSAGE_SENDER("&b&lme \u00bb {0} &7> &o"), MESSAGE_RECEIVER("&b&l{0} \u00bb me &7> &o"), + NICKNAME_CLEAR("&aYou nickname has been cleared."), + NICKNAME_CURRENT("&aCurrent nickname: &r{0}"), + NICKNAME_NONE("&aYou don't have a nickname."), + NICKNAME_SET("&aYou nickname is now &r{0}&r&a."), + NO_PERMISSION("&cYou don't have permission to execute this command."), NOT_CONNECTED_TO_SERVER("&cYou must be connected to a server to use this subcommand."), diff --git a/src/main/java/me/crypnotic/neutron/api/user/User.java b/src/main/java/me/crypnotic/neutron/api/user/User.java index 1db8c89..37b7682 100644 --- a/src/main/java/me/crypnotic/neutron/api/user/User.java +++ b/src/main/java/me/crypnotic/neutron/api/user/User.java @@ -8,20 +8,83 @@ public interface User { + /** + * Load the user's data from disk. + * + * @throws Exception if the data cannot be loaded. + */ void load() throws Exception; + /** + * Save the user's data to disk, if applicable. + * + * @throws Exception if the data cannot be saved. + */ void save() throws Exception; - + + /** + * Get the base CommandSource this user is associated with. + * + * @return the base CommandSource + */ Optional getBase(); + /** + * Get the name used to refer to the user. This may be their username or nickname. + * The console's preferred name is set in the config. + * + * @return the user's username or nickname + */ String getName(); + /** + * Get the nickname the user has set, if any. + * + * @return the nickname set, if any + */ + String getNickname(); + + /** + * Get the CommandSource that the user will send a private message to when using /reply. + * + * @return the relevant CommandSource + */ CommandSource getReplyRecipient(); - + + /** + * Get the user's username. This is undefined for non-player users. + * + * @return the username, if applicable + */ + String getUsername(); + + /** + * Get the user's UUID. + * + * @return the user's UUID + */ Optional getUUID(); + /** + * Set the user's nickname. + * This is ignored for the console user. + * + * @param nickname The nickname of the user. + */ + void setNickname(String nickname); + + /** + * Set the CommandSource that the user will send a private message to when using /reply. + * + * @param source the CommandSource to reply to + */ void setReplyRecipient(CommandSource source); + /** + * Determine whether the user is a player or not. + * + * @return whether or not the user is a player + */ default boolean isPlayer() { return getBase().isPresent() && getBase().get() instanceof Player; } diff --git a/src/main/java/me/crypnotic/neutron/manager/user/holder/ConsoleUser.java b/src/main/java/me/crypnotic/neutron/manager/user/holder/ConsoleUser.java index d82b3b6..5d18228 100644 --- a/src/main/java/me/crypnotic/neutron/manager/user/holder/ConsoleUser.java +++ b/src/main/java/me/crypnotic/neutron/manager/user/holder/ConsoleUser.java @@ -28,6 +28,16 @@ public Optional getBase() { return Optional.of(Neutron.getNeutron().getProxy().getConsoleCommandSource()); } + @Override + public String getNickname() { + return null; + } + + @Override + public String getUsername() { + return null; + } + @Override public void load() throws Exception { /* noop */ @@ -42,4 +52,9 @@ public void save() throws Exception { public Optional getUUID() { return Optional.empty(); } + + @Override + public void setNickname(String nickname) { + /* noop */ + } } diff --git a/src/main/java/me/crypnotic/neutron/manager/user/holder/PlayerData.java b/src/main/java/me/crypnotic/neutron/manager/user/holder/PlayerData.java index 2dec920..4428f6b 100644 --- a/src/main/java/me/crypnotic/neutron/manager/user/holder/PlayerData.java +++ b/src/main/java/me/crypnotic/neutron/manager/user/holder/PlayerData.java @@ -19,15 +19,18 @@ class PlayerData { @Setting(comment = "The player's last known username.") private String username; + @Setting(comment = "The player's nickname.") + private String nickname; + // Non-persisted data - this is not saved when the user is unloaded. private WeakReference replyRecipient = null; - public CommandSource getReplyRecipient() { + CommandSource getReplyRecipient() { return replyRecipient != null ? replyRecipient.get() : null; } - public void setReplyRecipient(CommandSource replyRecipient) { + void setReplyRecipient(CommandSource replyRecipient) { this.replyRecipient = new WeakReference<>(replyRecipient); } } diff --git a/src/main/java/me/crypnotic/neutron/manager/user/holder/PlayerUser.java b/src/main/java/me/crypnotic/neutron/manager/user/holder/PlayerUser.java index c09fc55..a8d7c50 100644 --- a/src/main/java/me/crypnotic/neutron/manager/user/holder/PlayerUser.java +++ b/src/main/java/me/crypnotic/neutron/manager/user/holder/PlayerUser.java @@ -50,12 +50,14 @@ public void save() throws Exception { @Override public String getName() { - Optional base = getBase(); - if (base.isPresent()) { - return base.get().getUsername(); - } + String nickname = getNickname(); + return nickname == null ? getUsername() : "~" + nickname; + } - return data.getUsername(); + @Override + public String getNickname() { + String nickname = data.getNickname(); + return nickname == null || nickname.isEmpty() ? null : nickname; } @Override @@ -63,10 +65,22 @@ public Optional getUUID() { return Optional.of(uuid); } + @Override + public void setNickname(String nickname) { + data.setNickname(nickname); + } + public CommandSource getReplyRecipient() { return data.getReplyRecipient(); } + @Override + public String getUsername() { + Optional base = getBase(); + return base.isPresent() ? base.get().getUsername() : data.getUsername(); + + } + public void setReplyRecipient(CommandSource source) { data.setReplyRecipient(source); } diff --git a/src/main/java/me/crypnotic/neutron/module/command/Commands.java b/src/main/java/me/crypnotic/neutron/module/command/Commands.java index 69d369c..318de65 100644 --- a/src/main/java/me/crypnotic/neutron/module/command/Commands.java +++ b/src/main/java/me/crypnotic/neutron/module/command/Commands.java @@ -38,6 +38,7 @@ public enum Commands { INFO("info", InfoCommand::new), GLIST("glist", GlistCommand::new), MESSAGE("message", MessageCommand::new), + NICKNAME("nickname", NicknameCommand::new), REPLY("reply", ReplyCommand::new), SEND("send", SendCommand::new); diff --git a/src/main/java/me/crypnotic/neutron/module/command/options/NicknameCommand.java b/src/main/java/me/crypnotic/neutron/module/command/options/NicknameCommand.java new file mode 100644 index 0000000..f139451 --- /dev/null +++ b/src/main/java/me/crypnotic/neutron/module/command/options/NicknameCommand.java @@ -0,0 +1,45 @@ +package me.crypnotic.neutron.module.command.options; + +import com.velocitypowered.api.command.CommandSource; +import me.crypnotic.neutron.api.command.CommandContext; +import me.crypnotic.neutron.api.command.CommandWrapper; +import me.crypnotic.neutron.api.locale.LocaleMessage; +import me.crypnotic.neutron.api.user.User; + +public class NicknameCommand extends CommandWrapper { + @Override + public void handle(CommandSource source, CommandContext context) throws CommandExitException { + assertPermission(source, "neutron.command.nickname"); + assertUsage(source, context.size() > 0); + + User user = getUser(source).orElseThrow(CommandExitException::new); + + assertCustom(source, user.isPlayer(), LocaleMessage.PLAYER_ONLY_COMMAND); + + switch (context.get(0)) { + case "get": + if (user.getNickname() != null) { + source.sendMessage(getMessage(source, LocaleMessage.NICKNAME_CURRENT, user.getNickname())); + } else { + source.sendMessage(getMessage(source, LocaleMessage.NICKNAME_NONE)); + } + break; + case "clear": + user.setNickname(null); + source.sendMessage(getMessage(source, LocaleMessage.NICKNAME_CLEAR)); + break; + case "set": + assertUsage(source, context.size() > 1); + user.setNickname(context.get(1)); + source.sendMessage(getMessage(source, LocaleMessage.NICKNAME_SET, user.getNickname())); + break; + default: + assertUsage(source, false); + } + } + + @Override + public String getUsage() { + return "/nickname >"; + } +} diff --git a/src/main/resources/config.conf b/src/main/resources/config.conf index 65533f7..3f5def6 100644 --- a/src/main/resources/config.conf +++ b/src/main/resources/config.conf @@ -25,12 +25,17 @@ command { enabled = false aliases = ["glist"] } - + message { enabled = true aliases = ["message", "msg", "tell", "whisper"] } + nickname { + enabled = true + aliases = ["nickname", "nick"] + } + reply { enabled = true aliases = ["reply", "r"] From 3d2c49f89f7309b432645cc4d4a07a3a2ed882b2 Mon Sep 17 00:00:00 2001 From: md678685 <1917406+md678685@users.noreply.github.com> Date: Wed, 29 May 2019 20:55:39 +0100 Subject: [PATCH 2/3] Improved javadoc --- src/main/java/me/crypnotic/neutron/api/user/User.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/me/crypnotic/neutron/api/user/User.java b/src/main/java/me/crypnotic/neutron/api/user/User.java index 37b7682..d2cfcc9 100644 --- a/src/main/java/me/crypnotic/neutron/api/user/User.java +++ b/src/main/java/me/crypnotic/neutron/api/user/User.java @@ -30,8 +30,8 @@ public interface User { Optional getBase(); /** - * Get the name used to refer to the user. This may be their username or nickname. - * The console's preferred name is set in the config. + * Get the display name to refer to the user. This may be their username or nickname. + * The console's display name is set in the config. * * @return the user's username or nickname */ From db6a59be7ffe9960694e6bfb4146215b01f1fab8 Mon Sep 17 00:00:00 2001 From: md678685 <1917406+md678685@users.noreply.github.com> Date: Fri, 31 May 2019 11:12:04 +0100 Subject: [PATCH 3/3] Update /nickname to use CommandWrapper#message --- .../neutron/module/command/options/NicknameCommand.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/me/crypnotic/neutron/module/command/options/NicknameCommand.java b/src/main/java/me/crypnotic/neutron/module/command/options/NicknameCommand.java index f139451..9ab6d97 100644 --- a/src/main/java/me/crypnotic/neutron/module/command/options/NicknameCommand.java +++ b/src/main/java/me/crypnotic/neutron/module/command/options/NicknameCommand.java @@ -19,19 +19,19 @@ public void handle(CommandSource source, CommandContext context) throws CommandE switch (context.get(0)) { case "get": if (user.getNickname() != null) { - source.sendMessage(getMessage(source, LocaleMessage.NICKNAME_CURRENT, user.getNickname())); + message(source, LocaleMessage.NICKNAME_CURRENT, user.getNickname()); } else { - source.sendMessage(getMessage(source, LocaleMessage.NICKNAME_NONE)); + message(source, LocaleMessage.NICKNAME_NONE); } break; case "clear": user.setNickname(null); - source.sendMessage(getMessage(source, LocaleMessage.NICKNAME_CLEAR)); + message(source, LocaleMessage.NICKNAME_CLEAR); break; case "set": assertUsage(source, context.size() > 1); user.setNickname(context.get(1)); - source.sendMessage(getMessage(source, LocaleMessage.NICKNAME_SET, user.getNickname())); + message(source, LocaleMessage.NICKNAME_SET, user.getNickname()); break; default: assertUsage(source, false);