diff --git a/src/main/java/net/thenextlvl/tweaks/TweaksPlugin.java b/src/main/java/net/thenextlvl/tweaks/TweaksPlugin.java index 024cabc..499316b 100644 --- a/src/main/java/net/thenextlvl/tweaks/TweaksPlugin.java +++ b/src/main/java/net/thenextlvl/tweaks/TweaksPlugin.java @@ -29,18 +29,22 @@ import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; import org.bukkit.command.TabCompleter; import org.bukkit.entity.Player; import org.bukkit.plugin.java.JavaPlugin; import java.io.File; import java.util.Locale; +import java.util.Map; +import java.util.WeakHashMap; @Getter @Accessors(fluent = true) @FieldsAreNotNullByDefault public class TweaksPlugin extends JavaPlugin { private final Metrics metrics = new Metrics(this, 19651); + private final Map conversations = new WeakHashMap<>(); private final FileIO configFile = new GsonFile<>( IO.of(getDataFolder(), "config.json"), new TweaksConfig( @@ -110,6 +114,8 @@ private void registerCommands() { registerCommand(new PingCommand(this)); registerCommand(new BackCommand(this)); registerCommand(new SeenCommand(this)); + registerCommand(new ReplyCommand(this)); + registerCommand(new MessageCommand(this)); registerCommand(new InventoryCommand(this)); registerCommand(new EnderChestCommand(this)); registerCommand(new SpeedCommand(this)); diff --git a/src/main/java/net/thenextlvl/tweaks/command/player/MessageCommand.java b/src/main/java/net/thenextlvl/tweaks/command/player/MessageCommand.java new file mode 100644 index 0000000..32f07a2 --- /dev/null +++ b/src/main/java/net/thenextlvl/tweaks/command/player/MessageCommand.java @@ -0,0 +1,65 @@ +package net.thenextlvl.tweaks.command.player; + +import lombok.RequiredArgsConstructor; +import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; +import net.thenextlvl.tweaks.TweaksPlugin; +import net.thenextlvl.tweaks.command.api.CommandInfo; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabExecutor; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.Nullable; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +@CommandInfo( + name = "msg", + aliases = {"tell", "w"}, + usage = "/msg [player] [message]", + description = "start a conversation with another player", + permission = "tweaks.command.msg" +) +@RequiredArgsConstructor +public class MessageCommand implements TabExecutor { + private final TweaksPlugin plugin; + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (args.length < 2) { + plugin.bundle().sendMessage(sender, "command.usage.msg"); + return true; + } + var player = Bukkit.getPlayer(args[0]); + if (player == null) { + plugin.bundle().sendMessage(sender, "player.not.online", Placeholder.parsed("player", args[0])); + return true; + } + if (player.equals(sender)) { + plugin.bundle().sendMessage(sender, "message.self"); + return true; + } + message(plugin, Arrays.copyOfRange(args, 1, args.length), sender, player); + return true; + } + + static void message(TweaksPlugin plugin, String[] args, CommandSender source, CommandSender target) { + var sender = Placeholder.parsed("sender", source.getName()); + var receiver = Placeholder.parsed("receiver", target.getName()); + var message = Placeholder.parsed("message", String.join(" ", args)); + plugin.bundle().sendMessage(source, "message.out", receiver, sender, message); + plugin.bundle().sendMessage(target, "message.in", receiver, sender, message); + plugin.conversations().put(target, source); + } + + @Override + public @Nullable List onTabComplete(CommandSender sender, Command command, String label, String[] args) { + return args.length <= 1 ? Bukkit.getOnlinePlayers().stream() + .filter(all -> !all.equals(sender)) + .map(Player::getName) + .filter(s -> s.contains(args[args.length - 1])) + .toList() : Collections.emptyList(); + } +} diff --git a/src/main/java/net/thenextlvl/tweaks/command/player/ReplyCommand.java b/src/main/java/net/thenextlvl/tweaks/command/player/ReplyCommand.java new file mode 100644 index 0000000..cd862fa --- /dev/null +++ b/src/main/java/net/thenextlvl/tweaks/command/player/ReplyCommand.java @@ -0,0 +1,35 @@ +package net.thenextlvl.tweaks.command.player; + +import lombok.RequiredArgsConstructor; +import net.thenextlvl.tweaks.TweaksPlugin; +import net.thenextlvl.tweaks.command.api.CommandInfo; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; + +@CommandInfo( + name = "reply", + aliases = "r", + usage = "/reply [message]", + description = "reply to the player you last chatted with", + permission = "tweaks.command.reply" +) +@RequiredArgsConstructor +public class ReplyCommand implements CommandExecutor { + private final TweaksPlugin plugin; + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (args.length < 1) { + plugin.bundle().sendMessage(sender, "command.usage.reply"); + return true; + } + var player = plugin.conversations().get(sender); + if (player == null) { + plugin.bundle().sendMessage(sender, "conversation.running"); + return true; + } + MessageCommand.message(plugin, args, sender, player); + return false; + } +} diff --git a/src/main/java/net/thenextlvl/tweaks/listener/ConnectionListener.java b/src/main/java/net/thenextlvl/tweaks/listener/ConnectionListener.java index fe49ad7..2491d00 100644 --- a/src/main/java/net/thenextlvl/tweaks/listener/ConnectionListener.java +++ b/src/main/java/net/thenextlvl/tweaks/listener/ConnectionListener.java @@ -10,6 +10,9 @@ import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerQuitEvent; +import java.util.ArrayList; +import java.util.Map; + @RequiredArgsConstructor public class ConnectionListener implements Listener { private final TweaksPlugin plugin; @@ -31,4 +34,12 @@ public void onQuit(PlayerQuitEvent event) { Placeholder.parsed("player", event.getPlayer().getName()))); event.quitMessage(null); } + + @EventHandler(priority = EventPriority.MONITOR) + public void cleanup(PlayerQuitEvent event) { + new ArrayList<>(plugin.conversations().entrySet()).stream() + .filter(entry -> entry.getValue().equals(event.getPlayer())) + .map(Map.Entry::getKey) + .forEach(plugin.conversations()::remove); + } } diff --git a/src/main/resources/tweaks.properties b/src/main/resources/tweaks.properties index c05ff4e..5cb097a 100644 --- a/src/main/resources/tweaks.properties +++ b/src/main/resources/tweaks.properties @@ -77,4 +77,10 @@ broadcast.format=Server | broadcast.footer= motd.changed= Changed motd to chat.format= '> » '>'> -chat.format.delete=[x] \ No newline at end of file +chat.format.delete=[x] +command.usage.msg= /msg [player] [message] +command.usage.reply= /reply [message] +message.out=You -> » +message.in= '> -> You » '>'> +message.self= You can't message yourself +conversation.running= You have no running conversation \ No newline at end of file diff --git a/src/main/resources/tweaks_german.properties b/src/main/resources/tweaks_german.properties index 8ee67d4..7947bb1 100644 --- a/src/main/resources/tweaks_german.properties +++ b/src/main/resources/tweaks_german.properties @@ -70,4 +70,8 @@ god.active.others= ist jetzt unverwundbar god.inactive.self= Du bist nicht länger unverwundbar god.inactive.others= ist nicht länger unverwundbar chat.format.delete=[x] -motd.changed= Die motd ist jetzt \ No newline at end of file +motd.changed= Die motd ist jetzt +message.out=Du -> » +message.in= '> -> Dir » '>'> +message.self= Du kannst dir nicht selber schreiben +conversation.running= Du hast keine laufende Konversation \ No newline at end of file