From 577e99fcfc263434687a16d6eb3b113800da288c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20M=C3=BCller?= Date: Wed, 28 Aug 2024 19:32:07 +0200 Subject: [PATCH 1/8] added basic reply --- .../java/eu/mhsl/craftattack/spawn/Main.java | 4 +- .../chatMention/ChatMentionListener.java | 12 ++- .../appliances/chatMessages/ChatMessages.java | 10 +- .../privateMessage/PrivateMessage.java | 93 +++++++++++++++++++ .../commands/PrivateMessageCommand.java | 18 ++++ .../commands/PrivateReplyCommand.java | 18 ++++ .../spawn/appliances/whitelist/Whitelist.java | 17 ++-- .../spawn/util/LimitedSizedList.java | 27 ++++++ .../spawn/util/statistics/NetworkMonitor.java | 5 +- src/main/resources/config.yml | 3 +- src/main/resources/plugin.yml | 4 +- 11 files changed, 193 insertions(+), 18 deletions(-) create mode 100644 src/main/java/eu/mhsl/craftattack/spawn/appliances/privateMessage/PrivateMessage.java create mode 100644 src/main/java/eu/mhsl/craftattack/spawn/appliances/privateMessage/commands/PrivateMessageCommand.java create mode 100644 src/main/java/eu/mhsl/craftattack/spawn/appliances/privateMessage/commands/PrivateReplyCommand.java create mode 100644 src/main/java/eu/mhsl/craftattack/spawn/util/LimitedSizedList.java diff --git a/src/main/java/eu/mhsl/craftattack/spawn/Main.java b/src/main/java/eu/mhsl/craftattack/spawn/Main.java index 692b58f..4d948cf 100644 --- a/src/main/java/eu/mhsl/craftattack/spawn/Main.java +++ b/src/main/java/eu/mhsl/craftattack/spawn/Main.java @@ -19,6 +19,7 @@ import eu.mhsl.craftattack.spawn.appliances.outlawed.Outlawed; import eu.mhsl.craftattack.spawn.appliances.panicBan.PanicBan; import eu.mhsl.craftattack.spawn.appliances.playerlimit.PlayerLimit; import eu.mhsl.craftattack.spawn.appliances.portableCrafting.PortableCrafting; +import eu.mhsl.craftattack.spawn.appliances.privateMessage.PrivateMessage; import eu.mhsl.craftattack.spawn.appliances.projectStart.ProjectStart; import eu.mhsl.craftattack.spawn.appliances.report.Report; import eu.mhsl.craftattack.spawn.appliances.restart.Restart; @@ -75,7 +76,8 @@ public final class Main extends JavaPlugin { new AutoShulker(), new AntiSignEdit(), new HotbarRefill(), - new ChatMention() + new ChatMention(), + new PrivateMessage() ); Main.logger.info("Loading appliances..."); diff --git a/src/main/java/eu/mhsl/craftattack/spawn/appliances/chatMention/ChatMentionListener.java b/src/main/java/eu/mhsl/craftattack/spawn/appliances/chatMention/ChatMentionListener.java index db27a13..182cf69 100644 --- a/src/main/java/eu/mhsl/craftattack/spawn/appliances/chatMention/ChatMentionListener.java +++ b/src/main/java/eu/mhsl/craftattack/spawn/appliances/chatMention/ChatMentionListener.java @@ -1,6 +1,8 @@ package eu.mhsl.craftattack.spawn.appliances.chatMention; +import eu.mhsl.craftattack.spawn.Main; import eu.mhsl.craftattack.spawn.appliance.ApplianceListener; +import eu.mhsl.craftattack.spawn.appliances.chatMessages.ChatMessages; import eu.mhsl.craftattack.spawn.appliances.settings.Settings; import eu.mhsl.craftattack.spawn.appliances.settings.settings.ChatMentionSetting; import io.papermc.paper.event.player.AsyncChatDecorateEvent; @@ -8,6 +10,7 @@ import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerJoinEvent; import java.util.ArrayList; import java.util.List; @@ -22,6 +25,7 @@ public class ChatMentionListener extends ApplianceListener { ChatMentionSetting.ChatMentionConfig config = Settings.instance() .getSetting(event.player(), Settings.Key.ChatMentions, ChatMentionSetting.ChatMentionConfig.class); + ChatMessages chatMessages = Main.instance().getAppliance(ChatMessages.class); Component result = words.stream() .map(word -> { @@ -29,10 +33,11 @@ public class ChatMentionListener extends ApplianceListener { boolean isPlayer = getAppliance().getPlayerNames().contains(wordWithoutAnnotation); if(isPlayer && config.applyMentions()) { mentioned.add(wordWithoutAnnotation); - return Component.text( + Component mention = Component.text( getAppliance().formatPlayer(wordWithoutAnnotation), NamedTextColor.GOLD ); + return chatMessages.addReportActions(mention, wordWithoutAnnotation); } else { return Component.text(word); } @@ -43,4 +48,9 @@ public class ChatMentionListener extends ApplianceListener { getAppliance().notifyPlayers(mentioned); event.result(result); } + + @EventHandler + public void onJoin(PlayerJoinEvent event) { + getAppliance().refreshPlayers(); + } } diff --git a/src/main/java/eu/mhsl/craftattack/spawn/appliances/chatMessages/ChatMessages.java b/src/main/java/eu/mhsl/craftattack/spawn/appliances/chatMessages/ChatMessages.java index 53108ec..eb5652f 100644 --- a/src/main/java/eu/mhsl/craftattack/spawn/appliances/chatMessages/ChatMessages.java +++ b/src/main/java/eu/mhsl/craftattack/spawn/appliances/chatMessages/ChatMessages.java @@ -13,11 +13,13 @@ import java.util.List; public class ChatMessages extends Appliance { public Component getReportablePlayerName(Player player) { - return Component - .text("") - .append(player.displayName()) + return addReportActions(player.displayName(), player.getName()); + } + + public Component addReportActions(Component message, String username) { + return message .hoverEvent(HoverEvent.showText(Component.text("Klicke, um diesen Spieler zu reporten").color(NamedTextColor.GOLD))) - .clickEvent(ClickEvent.clickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/report " + player.getName() + " ")); + .clickEvent(ClickEvent.clickEvent(ClickEvent.Action.SUGGEST_COMMAND, String.format("/report %s ", username))); } @Override diff --git a/src/main/java/eu/mhsl/craftattack/spawn/appliances/privateMessage/PrivateMessage.java b/src/main/java/eu/mhsl/craftattack/spawn/appliances/privateMessage/PrivateMessage.java new file mode 100644 index 0000000..ce9922c --- /dev/null +++ b/src/main/java/eu/mhsl/craftattack/spawn/appliances/privateMessage/PrivateMessage.java @@ -0,0 +1,93 @@ +package eu.mhsl.craftattack.spawn.appliances.privateMessage; + +import eu.mhsl.craftattack.spawn.Main; +import eu.mhsl.craftattack.spawn.appliance.Appliance; +import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand; +import eu.mhsl.craftattack.spawn.appliances.chatMessages.ChatMessages; +import eu.mhsl.craftattack.spawn.appliances.privateMessage.commands.PrivateMessageCommand; +import eu.mhsl.craftattack.spawn.appliances.privateMessage.commands.PrivateReplyCommand; +import eu.mhsl.craftattack.spawn.util.LimitedSizedList; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.event.ClickEvent; +import net.kyori.adventure.text.format.NamedTextColor; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +import java.util.*; +import java.util.stream.Collectors; + +public class PrivateMessage extends Appliance { + public final int targetChangeTimeout = 30; + + private record Conversation(UUID target, Long lastSet) {} + private final Map> replyMapping = new WeakHashMap<>(); + + public void reply(Player sender, String message) { + Conversation senderConversation = this.replyMapping.get(sender).getLast(); + if(senderConversation == null) throw new ApplianceCommand.Error("Du kannst nicht auf eine konversation antworten, da keine vorhanden ist."); +// if(!senderConversation.isChecked && senderConversation.lastSet > System.currentTimeMillis() - targetChangeTimeout) { +// throw new ApplianceCommand.Error("ziel geändedrt......."); +// } + Player target = Bukkit.getPlayer(senderConversation.target); + if(target == null) throw new ApplianceCommand.Error("Der Spieler ist nicht mehr verfügbar."); + sendWhisper(sender, new ResolvedPmUserArguments(target, message)); + } + + public void sendWhisper(Player sender, ResolvedPmUserArguments userArguments) { +// this.replyMapping.put( +// sender, +// new Conversation( +// userArguments.receiver.getUniqueId(), +// System.currentTimeMillis() +// ) +// ); +// this.replyMapping.put( +// userArguments.receiver, +// new Conversation( +// sender.getUniqueId(), +// System.currentTimeMillis() +// ) +// ); + + ChatMessages chatMessages = Main.instance().getAppliance(ChatMessages.class); + Component privatePrefix = Component.text("[Privat] ", NamedTextColor.LIGHT_PURPLE); + + sender.sendMessage( + Component.text() + .append(privatePrefix.clickEvent(ClickEvent.suggestCommand(String.format("/msg %s ", userArguments.receiver.getName())))) + .append(sender.displayName()) + .append(Component.text(" zu ", NamedTextColor.GRAY)) + .append(chatMessages.getReportablePlayerName(userArguments.receiver)) + .append(Component.text(" > ", NamedTextColor.GRAY)) + .append(Component.text(userArguments.message)) + ); + userArguments.receiver.sendMessage( + Component.text() + .append(privatePrefix.clickEvent(ClickEvent.suggestCommand(String.format("/msg %s ", sender.getName())))) + .append(chatMessages.getReportablePlayerName(sender)) + .append(Component.text(" zu ", NamedTextColor.GRAY)) + .append(userArguments.receiver.displayName()) + .append(Component.text(" > ", NamedTextColor.GRAY)) + .append(Component.text(userArguments.message)) + ); + } + + public record ResolvedPmUserArguments(Player receiver, String message) {} + public ResolvedPmUserArguments resolveImplicit(String[] args) { + if(args.length < 2) throw new ApplianceCommand.Error("Es muss ein Spieler sowie eine Nachricht angegeben werden."); + List arguments = List.of(args); + Player targetPlayer = Bukkit.getPlayer(arguments.getFirst()); + if(targetPlayer == null) throw new ApplianceCommand.Error(String.format("Der Spieler %s konnte nicht gefunden werden.", arguments.getFirst())); + String message = arguments.stream().skip(1).collect(Collectors.joining(" ")); + return new ResolvedPmUserArguments(targetPlayer, message); + } + + @Override + protected @NotNull List> commands() { + return List.of( + new PrivateMessageCommand(), + new PrivateReplyCommand() + ); + } +} diff --git a/src/main/java/eu/mhsl/craftattack/spawn/appliances/privateMessage/commands/PrivateMessageCommand.java b/src/main/java/eu/mhsl/craftattack/spawn/appliances/privateMessage/commands/PrivateMessageCommand.java new file mode 100644 index 0000000..711bbe3 --- /dev/null +++ b/src/main/java/eu/mhsl/craftattack/spawn/appliances/privateMessage/commands/PrivateMessageCommand.java @@ -0,0 +1,18 @@ +package eu.mhsl.craftattack.spawn.appliances.privateMessage.commands; + +import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand; +import eu.mhsl.craftattack.spawn.appliances.privateMessage.PrivateMessage; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; + +public class PrivateMessageCommand extends ApplianceCommand.PlayerChecked { + public PrivateMessageCommand() { + super("msg"); + } + + @Override + protected void execute(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) throws Exception { + getAppliance().sendWhisper(getPlayer(), getAppliance().resolveImplicit(args)); + } +} diff --git a/src/main/java/eu/mhsl/craftattack/spawn/appliances/privateMessage/commands/PrivateReplyCommand.java b/src/main/java/eu/mhsl/craftattack/spawn/appliances/privateMessage/commands/PrivateReplyCommand.java new file mode 100644 index 0000000..fd7de78 --- /dev/null +++ b/src/main/java/eu/mhsl/craftattack/spawn/appliances/privateMessage/commands/PrivateReplyCommand.java @@ -0,0 +1,18 @@ +package eu.mhsl.craftattack.spawn.appliances.privateMessage.commands; + +import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand; +import eu.mhsl.craftattack.spawn.appliances.privateMessage.PrivateMessage; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; + +public class PrivateReplyCommand extends ApplianceCommand.PlayerChecked { + public PrivateReplyCommand() { + super("r"); + } + + @Override + protected void execute(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) throws Exception { + getAppliance().reply(getPlayer(), String.join(" ", args)); + } +} diff --git a/src/main/java/eu/mhsl/craftattack/spawn/appliances/whitelist/Whitelist.java b/src/main/java/eu/mhsl/craftattack/spawn/appliances/whitelist/Whitelist.java index abfd06a..920c2c6 100644 --- a/src/main/java/eu/mhsl/craftattack/spawn/appliances/whitelist/Whitelist.java +++ b/src/main/java/eu/mhsl/craftattack/spawn/appliances/whitelist/Whitelist.java @@ -43,7 +43,10 @@ public class Whitelist extends Appliance { public void integrityCheck(Player player) throws DisconnectInfo.Throwable { try { Main.instance().getLogger().info(String.format("Running integrityCheck for %s", player.getName())); - UserData user = this.fetchUserData(player.getUniqueId()); + boolean overrideCheck = localConfig().getBoolean("overrideIntegrityCheck", false); + UserData user = overrideCheck + ? new UserData(player.getUniqueId(), player.getName(), "", "", 0L, 0L) + : this.fetchUserData(player.getUniqueId()); if(timestampRelevant(user.banned_until)) { Instant bannedDate = new Date(user.banned_until * 1000L) @@ -63,12 +66,9 @@ public class Whitelist extends Appliance { Main.instance().getAppliance(Outlawed.class).updateForcedStatus(player, timestampRelevant(user.outlawed_until)); - String purePlayerName; - if(Floodgate.isBedrock(player)) { - purePlayerName = Floodgate.getBedrockPlayer(player).getUsername(); - } else { - purePlayerName = player.getName(); - } + String purePlayerName = Floodgate.isBedrock(player) + ? Floodgate.getBedrockPlayer(player).getUsername() + : player.getName(); if(!user.username.trim().equalsIgnoreCase(purePlayerName)) throw new DisconnectInfo.Throwable( @@ -100,8 +100,7 @@ public class Whitelist extends Appliance { URIBuilder uriBuilder = new URIBuilder(apiEndpoint); uriBuilder.addParameter("uuid", uuid.toString()); - try { - HttpClient client = HttpClient.newHttpClient(); + try(HttpClient client = HttpClient.newHttpClient()) { HttpRequest httpRequest = HttpRequest.newBuilder() .uri(uriBuilder.build()) .header("Content-Type", "application/json") diff --git a/src/main/java/eu/mhsl/craftattack/spawn/util/LimitedSizedList.java b/src/main/java/eu/mhsl/craftattack/spawn/util/LimitedSizedList.java new file mode 100644 index 0000000..1b03907 --- /dev/null +++ b/src/main/java/eu/mhsl/craftattack/spawn/util/LimitedSizedList.java @@ -0,0 +1,27 @@ +package eu.mhsl.craftattack.spawn.util; + +import java.util.ArrayList; + +public class LimitedSizedList extends ArrayList { + private final int maxSize; + + public LimitedSizedList(int size){ + this.maxSize = size; + } + + public boolean add(T element){ + boolean r = super.add(element); + if (size() > maxSize){ + removeRange(0, size() - maxSize); + } + return r; + } + + public T getYoungest() { + return get(size() - 1); + } + + public T getOldest() { + return get(0); + } +} diff --git a/src/main/java/eu/mhsl/craftattack/spawn/util/statistics/NetworkMonitor.java b/src/main/java/eu/mhsl/craftattack/spawn/util/statistics/NetworkMonitor.java index 4604e31..88719e2 100644 --- a/src/main/java/eu/mhsl/craftattack/spawn/util/statistics/NetworkMonitor.java +++ b/src/main/java/eu/mhsl/craftattack/spawn/util/statistics/NetworkMonitor.java @@ -9,6 +9,7 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.time.Duration; +import java.util.logging.Level; public class NetworkMonitor { private long previousRxBytes = 0; @@ -78,7 +79,9 @@ public class NetworkMonitor { String content = new String(Files.readAllBytes(Paths.get(path))); return Long.parseLong(content.trim()); } catch(IOException e) { - throw new RuntimeException("Failed recieving Network statistic", e); + Main.logger().log(Level.SEVERE, "Statistics are only supported on Linux! Is tablist.interface config set correctly?"); + this.stop(); + throw new RuntimeException("Failed reading network statistic", e); } } } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index af22dde..1e2a49f 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -42,9 +42,10 @@ help: spawn: "Der Weltspawn befindet sich bei x:0 y:0 z:0" playerLimit: - maxPlayers: 0 + maxPlayers: 100 whitelist: + overrideIntegrityCheck: false api: https://mhsl.eu/craftattack/api/user tablist: diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index a9e385b..9e86bca 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -36,4 +36,6 @@ commands: kick: panicBan: vogelfrei: - settings: \ No newline at end of file + settings: + msg: + r: \ No newline at end of file -- 2.30.2 From 26b9fd5e0f65e1b264cc217e279c561eff5574bf Mon Sep 17 00:00:00 2001 From: lars Date: Sun, 29 Sep 2024 22:43:55 +0200 Subject: [PATCH 2/8] changed basic reply logic --- .../privateMessage/PrivateMessage.java | 110 ++++++++++++++---- 1 file changed, 85 insertions(+), 25 deletions(-) diff --git a/src/main/java/eu/mhsl/craftattack/spawn/appliances/privateMessage/PrivateMessage.java b/src/main/java/eu/mhsl/craftattack/spawn/appliances/privateMessage/PrivateMessage.java index ce9922c..2f265aa 100644 --- a/src/main/java/eu/mhsl/craftattack/spawn/appliances/privateMessage/PrivateMessage.java +++ b/src/main/java/eu/mhsl/craftattack/spawn/appliances/privateMessage/PrivateMessage.java @@ -6,7 +6,6 @@ import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand; import eu.mhsl.craftattack.spawn.appliances.chatMessages.ChatMessages; import eu.mhsl.craftattack.spawn.appliances.privateMessage.commands.PrivateMessageCommand; import eu.mhsl.craftattack.spawn.appliances.privateMessage.commands.PrivateReplyCommand; -import eu.mhsl.craftattack.spawn.util.LimitedSizedList; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.event.ClickEvent; import net.kyori.adventure.text.format.NamedTextColor; @@ -18,37 +17,98 @@ import java.util.*; import java.util.stream.Collectors; public class PrivateMessage extends Appliance { - public final int targetChangeTimeout = 30; + public final int targetChangeTimeoutSeconds = 30; private record Conversation(UUID target, Long lastSet) {} - private final Map> replyMapping = new WeakHashMap<>(); + private final Map> replyMapping = new WeakHashMap<>(); public void reply(Player sender, String message) { - Conversation senderConversation = this.replyMapping.get(sender).getLast(); - if(senderConversation == null) throw new ApplianceCommand.Error("Du kannst nicht auf eine konversation antworten, da keine vorhanden ist."); -// if(!senderConversation.isChecked && senderConversation.lastSet > System.currentTimeMillis() - targetChangeTimeout) { -// throw new ApplianceCommand.Error("ziel geändedrt......."); -// } - Player target = Bukkit.getPlayer(senderConversation.target); - if(target == null) throw new ApplianceCommand.Error("Der Spieler ist nicht mehr verfügbar."); - sendWhisper(sender, new ResolvedPmUserArguments(target, message)); + if(this.replyMapping.get(sender) == null || this.replyMapping.get(sender).isEmpty()) throw new ApplianceCommand.Error("Du kannst nicht auf eine Konversation antworten, da keine vorhanden ist."); + + Conversation youngestEntry = this.replyMapping.get(sender).stream() + .max(Comparator.comparingLong(o -> o.lastSet)) + .orElse(this.replyMapping.get(sender).getLast()); + + if(youngestEntry.lastSet < System.currentTimeMillis() - (targetChangeTimeoutSeconds*1000) || this.replyMapping.get(sender).size() == 1) { + Player target = Bukkit.getPlayer(youngestEntry.target()); + if(target == null) throw new ApplianceCommand.Error("Der Spieler " + Bukkit.getOfflinePlayer(youngestEntry.target()).getName() + " ist nicht mehr verfügbar."); + + this.replyMapping.get(sender).clear(); + sendWhisper(sender, new ResolvedPmUserArguments(target, message)); + return; + } + + List oldConversations = this.replyMapping.get(sender).stream() + .filter(conversation -> conversation.lastSet < System.currentTimeMillis() - (targetChangeTimeoutSeconds*1000)) + .toList(); + this.replyMapping.get(sender).removeAll(oldConversations); + + List playerNames = this.replyMapping.get(sender).stream() + .map(conversation -> { + if(Bukkit.getPlayer(conversation.target()) != null) { + return Objects.requireNonNull(Bukkit.getPlayer(conversation.target())).getName(); + } else { + return Bukkit.getOfflinePlayer(conversation.target()).getName(); + } + }) + .toList(); + + sender.sendMessage( + Component.text() + .append(Component.text("Das Ziel für /r hat sich bei dir in den letzten ")) + .append(Component.text(String.valueOf(this.targetChangeTimeoutSeconds))) + .append(Component.text(" Sekunden geändert. Wer soll deine Nachricht bekommen? ")) + ); + // TODO: add options to click on with the players names +// sender.sendMessage( +// Component.text() +// .append(Component.text()) +// ); + } public void sendWhisper(Player sender, ResolvedPmUserArguments userArguments) { -// this.replyMapping.put( -// sender, -// new Conversation( -// userArguments.receiver.getUniqueId(), -// System.currentTimeMillis() -// ) -// ); -// this.replyMapping.put( -// userArguments.receiver, -// new Conversation( -// sender.getUniqueId(), -// System.currentTimeMillis() -// ) -// ); + + // Ältere Einträge bei replyMapping für den receiver entfernen + if(!(this.replyMapping.get(userArguments.receiver) == null)) { + List oldEntries = this.replyMapping.get(userArguments.receiver).stream() + .filter(conversation -> conversation.target() == sender.getUniqueId()) + .toList(); + this.replyMapping.get(userArguments.receiver).removeAll(oldEntries); + } + + // Neuen Eintrag bei replyMapping für den receiver + Conversation newReceiverConversation = new Conversation( + sender.getUniqueId(), + System.currentTimeMillis() + ); + + if(this.replyMapping.get(userArguments.receiver) == null) { + List receiverConversationList = new ArrayList<>(); + receiverConversationList.add(newReceiverConversation); + + this.replyMapping.put( + userArguments.receiver, + receiverConversationList + ); + } else { + this.replyMapping.get(userArguments.receiver).add(newReceiverConversation); + } + + // Einträge für sender bei replyMapping überschreiben mit receiver + List senderConversationList = new ArrayList<>(); + senderConversationList.add( + new Conversation( + userArguments.receiver.getUniqueId(), + System.currentTimeMillis() + ) + ); + + this.replyMapping.put( + sender, + senderConversationList + ); + ChatMessages chatMessages = Main.instance().getAppliance(ChatMessages.class); Component privatePrefix = Component.text("[Privat] ", NamedTextColor.LIGHT_PURPLE); -- 2.30.2 From f96356b620686404b77e27fd13f7f4627f2276e2 Mon Sep 17 00:00:00 2001 From: lars Date: Mon, 30 Sep 2024 16:23:32 +0200 Subject: [PATCH 3/8] added choose options --- .../privateMessage/PrivateMessage.java | 34 ++++++++++++++++--- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/src/main/java/eu/mhsl/craftattack/spawn/appliances/privateMessage/PrivateMessage.java b/src/main/java/eu/mhsl/craftattack/spawn/appliances/privateMessage/PrivateMessage.java index 2f265aa..b732f87 100644 --- a/src/main/java/eu/mhsl/craftattack/spawn/appliances/privateMessage/PrivateMessage.java +++ b/src/main/java/eu/mhsl/craftattack/spawn/appliances/privateMessage/PrivateMessage.java @@ -59,11 +59,35 @@ public class PrivateMessage extends Appliance { .append(Component.text(String.valueOf(this.targetChangeTimeoutSeconds))) .append(Component.text(" Sekunden geändert. Wer soll deine Nachricht bekommen? ")) ); - // TODO: add options to click on with the players names -// sender.sendMessage( -// Component.text() -// .append(Component.text()) -// ); + + + Component newTextComponent = Component.text(""); + + String firstTargetName; + if(Bukkit.getPlayer(youngestEntry.target()) == null) { + firstTargetName = Bukkit.getOfflinePlayer(youngestEntry.target()).getName(); + } else { + firstTargetName = Objects.requireNonNull(Bukkit.getPlayer(youngestEntry.target())).getName(); + } + + if(firstTargetName != null) { + Component nameComponent = Component.text(""); + nameComponent.append(Component.text(firstTargetName, NamedTextColor.LIGHT_PURPLE)); + + newTextComponent + .append(nameComponent.clickEvent(ClickEvent.runCommand("/msg " + firstTargetName + " " + message))); + newTextComponent.append(Component.text(" ")); + } + + + playerNames.forEach(playerName -> { + Component nameComponent = Component.text(playerName, NamedTextColor.LIGHT_PURPLE); + newTextComponent + .append(nameComponent.clickEvent(ClickEvent.runCommand("/msg " + playerName + " " + message))); + newTextComponent.append(Component.text(" ")); + }); + + sender.sendMessage(newTextComponent); } -- 2.30.2 From 471cd8e610562ae4fe8a1a5d29cdcc52b945e8f3 Mon Sep 17 00:00:00 2001 From: lars Date: Wed, 2 Oct 2024 22:27:16 +0200 Subject: [PATCH 4/8] finished logic for reply command --- .../privateMessage/PrivateMessage.java | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/main/java/eu/mhsl/craftattack/spawn/appliances/privateMessage/PrivateMessage.java b/src/main/java/eu/mhsl/craftattack/spawn/appliances/privateMessage/PrivateMessage.java index b732f87..f497fec 100644 --- a/src/main/java/eu/mhsl/craftattack/spawn/appliances/privateMessage/PrivateMessage.java +++ b/src/main/java/eu/mhsl/craftattack/spawn/appliances/privateMessage/PrivateMessage.java @@ -8,6 +8,7 @@ import eu.mhsl.craftattack.spawn.appliances.privateMessage.commands.PrivateMessa import eu.mhsl.craftattack.spawn.appliances.privateMessage.commands.PrivateReplyCommand; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.event.ClickEvent; +import net.kyori.adventure.text.event.HoverEvent; import net.kyori.adventure.text.format.NamedTextColor; import org.bukkit.Bukkit; import org.bukkit.entity.Player; @@ -51,8 +52,10 @@ public class PrivateMessage extends Appliance { return Bukkit.getOfflinePlayer(conversation.target()).getName(); } }) + .distinct() .toList(); + sender.sendMessage(""); sender.sendMessage( Component.text() .append(Component.text("Das Ziel für /r hat sich bei dir in den letzten ")) @@ -60,8 +63,8 @@ public class PrivateMessage extends Appliance { .append(Component.text(" Sekunden geändert. Wer soll deine Nachricht bekommen? ")) ); - - Component newTextComponent = Component.text(""); + + final Component[] finalComponent = {Component.text("")}; String firstTargetName; if(Bukkit.getPlayer(youngestEntry.target()) == null) { @@ -70,24 +73,21 @@ public class PrivateMessage extends Appliance { firstTargetName = Objects.requireNonNull(Bukkit.getPlayer(youngestEntry.target())).getName(); } - if(firstTargetName != null) { - Component nameComponent = Component.text(""); - nameComponent.append(Component.text(firstTargetName, NamedTextColor.LIGHT_PURPLE)); - - newTextComponent - .append(nameComponent.clickEvent(ClickEvent.runCommand("/msg " + firstTargetName + " " + message))); - newTextComponent.append(Component.text(" ")); + if(firstTargetName != null && !playerNames.contains(firstTargetName)) { + finalComponent[0] = finalComponent[0].append(Component.text(firstTargetName, NamedTextColor.GOLD) + .clickEvent(ClickEvent.runCommand("/msg " + firstTargetName + " " + message)) + .hoverEvent(HoverEvent.showText(Component.text("Klicke, um diesem Spieler zu schreiben.").color(NamedTextColor.GOLD)))) + .append(Component.text(" ")); } + playerNames.forEach(playerName -> finalComponent[0] = finalComponent[0].append(Component.text(playerName, NamedTextColor.GOLD) + .clickEvent(ClickEvent.runCommand("/msg " + playerName + " " + message)) + .hoverEvent(HoverEvent.showText(Component.text("Klicke, um diesem Spieler zu schreiben.").color(NamedTextColor.GOLD)))) + .append(Component.text(" "))); - playerNames.forEach(playerName -> { - Component nameComponent = Component.text(playerName, NamedTextColor.LIGHT_PURPLE); - newTextComponent - .append(nameComponent.clickEvent(ClickEvent.runCommand("/msg " + playerName + " " + message))); - newTextComponent.append(Component.text(" ")); - }); - - sender.sendMessage(newTextComponent); + sender.sendMessage(""); + sender.sendMessage(finalComponent[0]); + sender.sendMessage(""); } -- 2.30.2 From 497c5ad749d072d8ceda87be2f47a2c039cc0e53 Mon Sep 17 00:00:00 2001 From: lars Date: Wed, 2 Oct 2024 23:37:45 +0200 Subject: [PATCH 5/8] too old conversations get deleted, added prefix, changed some logic --- .../privateMessage/PrivateMessage.java | 86 ++++++++++++++----- 1 file changed, 66 insertions(+), 20 deletions(-) diff --git a/src/main/java/eu/mhsl/craftattack/spawn/appliances/privateMessage/PrivateMessage.java b/src/main/java/eu/mhsl/craftattack/spawn/appliances/privateMessage/PrivateMessage.java index f497fec..407019e 100644 --- a/src/main/java/eu/mhsl/craftattack/spawn/appliances/privateMessage/PrivateMessage.java +++ b/src/main/java/eu/mhsl/craftattack/spawn/appliances/privateMessage/PrivateMessage.java @@ -19,17 +19,52 @@ import java.util.stream.Collectors; public class PrivateMessage extends Appliance { public final int targetChangeTimeoutSeconds = 30; + public final int conversationTimeoutMinutes = 30; private record Conversation(UUID target, Long lastSet) {} private final Map> replyMapping = new WeakHashMap<>(); public void reply(Player sender, String message) { - if(this.replyMapping.get(sender) == null || this.replyMapping.get(sender).isEmpty()) throw new ApplianceCommand.Error("Du kannst nicht auf eine Konversation antworten, da keine vorhanden ist."); + if(this.replyMapping.get(sender) != null) { + List tooOldConversations = this.replyMapping.get(sender).stream() + .filter(conversation -> conversation.lastSet < System.currentTimeMillis() - (conversationTimeoutMinutes*60*1000)) + .toList(); + this.replyMapping.get(sender).removeAll(tooOldConversations); + } + + if(this.replyMapping.get(sender) == null || this.replyMapping.get(sender).isEmpty()) throw new ApplianceCommand.Error("Du führst aktuell keine Konversation."); + + + Component privatePrefix = Component.text("[Privat] ", NamedTextColor.LIGHT_PURPLE); + ChatMessages chatMessages = Main.instance().getAppliance(ChatMessages.class); Conversation youngestEntry = this.replyMapping.get(sender).stream() .max(Comparator.comparingLong(o -> o.lastSet)) .orElse(this.replyMapping.get(sender).getLast()); + String youngestTargetName; + if(Bukkit.getPlayer(youngestEntry.target()) == null) { + youngestTargetName = Bukkit.getOfflinePlayer(youngestEntry.target()).getName(); + } else { + youngestTargetName = Objects.requireNonNull(Bukkit.getPlayer(youngestEntry.target())).getName(); + } + + + if(message.isBlank() && youngestTargetName != null) { + sender.sendMessage( + privatePrefix + .append(Component.text("Du schreibst aktuell mit ", NamedTextColor.GRAY)) + .append(chatMessages.getReportablePlayerName(sender)) + ); + return; + } else if(message.isBlank()) { + sender.sendMessage( + privatePrefix + .append(Component.text("Du schreibst aktuell mit niemandem.", NamedTextColor.GRAY)) + ); + return; + } + if(youngestEntry.lastSet < System.currentTimeMillis() - (targetChangeTimeoutSeconds*1000) || this.replyMapping.get(sender).size() == 1) { Player target = Bukkit.getPlayer(youngestEntry.target()); if(target == null) throw new ApplianceCommand.Error("Der Spieler " + Bukkit.getOfflinePlayer(youngestEntry.target()).getName() + " ist nicht mehr verfügbar."); @@ -42,7 +77,14 @@ public class PrivateMessage extends Appliance { List oldConversations = this.replyMapping.get(sender).stream() .filter(conversation -> conversation.lastSet < System.currentTimeMillis() - (targetChangeTimeoutSeconds*1000)) .toList(); - this.replyMapping.get(sender).removeAll(oldConversations); + + Conversation youngestOldConversation = null; + if(!oldConversations.isEmpty()) { + youngestOldConversation = oldConversations.stream() + .max(Comparator.comparingLong(o -> o.lastSet)) + .orElse(oldConversations.getLast()); + this.replyMapping.get(sender).removeAll(oldConversations); + } List playerNames = this.replyMapping.get(sender).stream() .map(conversation -> { @@ -55,34 +97,41 @@ public class PrivateMessage extends Appliance { .distinct() .toList(); + sender.sendMessage(""); sender.sendMessage( Component.text() - .append(Component.text("Das Ziel für /r hat sich bei dir in den letzten ")) - .append(Component.text(String.valueOf(this.targetChangeTimeoutSeconds))) - .append(Component.text(" Sekunden geändert. Wer soll deine Nachricht bekommen? ")) + .append(privatePrefix) + .append(Component.text("Das Ziel für /r hat sich bei dir in den letzten ", NamedTextColor.RED)) + .append(Component.text(String.valueOf(this.targetChangeTimeoutSeconds), NamedTextColor.RED)) + .append(Component.text(" Sekunden geändert. Wer soll deine Nachricht bekommen? ", NamedTextColor.RED)) ); - final Component[] finalComponent = {Component.text("")}; - String firstTargetName; - if(Bukkit.getPlayer(youngestEntry.target()) == null) { - firstTargetName = Bukkit.getOfflinePlayer(youngestEntry.target()).getName(); - } else { - firstTargetName = Objects.requireNonNull(Bukkit.getPlayer(youngestEntry.target())).getName(); + String firstTargetName = null; + if(youngestOldConversation != null && Bukkit.getPlayer(youngestOldConversation.target()) == null) { + firstTargetName = Bukkit.getOfflinePlayer(youngestOldConversation.target()).getName(); + } else if(youngestOldConversation != null){ + firstTargetName = Objects.requireNonNull(Bukkit.getPlayer(youngestOldConversation.target())).getName(); } if(firstTargetName != null && !playerNames.contains(firstTargetName)) { - finalComponent[0] = finalComponent[0].append(Component.text(firstTargetName, NamedTextColor.GOLD) - .clickEvent(ClickEvent.runCommand("/msg " + firstTargetName + " " + message)) - .hoverEvent(HoverEvent.showText(Component.text("Klicke, um diesem Spieler zu schreiben.").color(NamedTextColor.GOLD)))) + finalComponent[0] = finalComponent[0].append( + Component.text("[") + .append(Component.text(firstTargetName, NamedTextColor.GOLD)) + .append(Component.text("]")) + .clickEvent(ClickEvent.runCommand("/msg " + firstTargetName + " " + message)) + .hoverEvent(HoverEvent.showText(Component.text("Klicke, um diesem Spieler zu schreiben.").color(NamedTextColor.GOLD)))) .append(Component.text(" ")); } - playerNames.forEach(playerName -> finalComponent[0] = finalComponent[0].append(Component.text(playerName, NamedTextColor.GOLD) - .clickEvent(ClickEvent.runCommand("/msg " + playerName + " " + message)) - .hoverEvent(HoverEvent.showText(Component.text("Klicke, um diesem Spieler zu schreiben.").color(NamedTextColor.GOLD)))) + playerNames.forEach(playerName -> finalComponent[0] = finalComponent[0].append( + Component.text("[") + .append(Component.text(playerName, NamedTextColor.GOLD)) + .append(Component.text("]")) + .clickEvent(ClickEvent.runCommand("/msg " + playerName + " " + message)) + .hoverEvent(HoverEvent.showText(Component.text("Klicke, um diesem Spieler zu schreiben.").color(NamedTextColor.GOLD)))) .append(Component.text(" "))); sender.sendMessage(""); @@ -93,7 +142,6 @@ public class PrivateMessage extends Appliance { public void sendWhisper(Player sender, ResolvedPmUserArguments userArguments) { - // Ältere Einträge bei replyMapping für den receiver entfernen if(!(this.replyMapping.get(userArguments.receiver) == null)) { List oldEntries = this.replyMapping.get(userArguments.receiver).stream() .filter(conversation -> conversation.target() == sender.getUniqueId()) @@ -101,7 +149,6 @@ public class PrivateMessage extends Appliance { this.replyMapping.get(userArguments.receiver).removeAll(oldEntries); } - // Neuen Eintrag bei replyMapping für den receiver Conversation newReceiverConversation = new Conversation( sender.getUniqueId(), System.currentTimeMillis() @@ -119,7 +166,6 @@ public class PrivateMessage extends Appliance { this.replyMapping.get(userArguments.receiver).add(newReceiverConversation); } - // Einträge für sender bei replyMapping überschreiben mit receiver List senderConversationList = new ArrayList<>(); senderConversationList.add( new Conversation( -- 2.30.2 From d69089a0ebe13d7123a35923f89205dbe5be8515 Mon Sep 17 00:00:00 2001 From: lars Date: Sun, 6 Oct 2024 12:32:20 +0200 Subject: [PATCH 6/8] cleaned up the code --- .../privateMessage/PrivateMessage.java | 83 ++++++------------- 1 file changed, 25 insertions(+), 58 deletions(-) diff --git a/src/main/java/eu/mhsl/craftattack/spawn/appliances/privateMessage/PrivateMessage.java b/src/main/java/eu/mhsl/craftattack/spawn/appliances/privateMessage/PrivateMessage.java index 407019e..205b977 100644 --- a/src/main/java/eu/mhsl/craftattack/spawn/appliances/privateMessage/PrivateMessage.java +++ b/src/main/java/eu/mhsl/craftattack/spawn/appliances/privateMessage/PrivateMessage.java @@ -34,33 +34,23 @@ public class PrivateMessage extends Appliance { if(this.replyMapping.get(sender) == null || this.replyMapping.get(sender).isEmpty()) throw new ApplianceCommand.Error("Du führst aktuell keine Konversation."); - Component privatePrefix = Component.text("[Privat] ", NamedTextColor.LIGHT_PURPLE); - ChatMessages chatMessages = Main.instance().getAppliance(ChatMessages.class); Conversation youngestEntry = this.replyMapping.get(sender).stream() .max(Comparator.comparingLong(o -> o.lastSet)) .orElse(this.replyMapping.get(sender).getLast()); - String youngestTargetName; - if(Bukkit.getPlayer(youngestEntry.target()) == null) { - youngestTargetName = Bukkit.getOfflinePlayer(youngestEntry.target()).getName(); - } else { - youngestTargetName = Objects.requireNonNull(Bukkit.getPlayer(youngestEntry.target())).getName(); - } + if(message.isBlank()) { + Component currentTargetComponent = Component.text("niemandem."); + Player currentTargetPlayer = Bukkit.getPlayer(youngestEntry.target()); + if(currentTargetPlayer != null) { + currentTargetComponent = Main.instance().getAppliance(ChatMessages.class).getReportablePlayerName(currentTargetPlayer); + } - - if(message.isBlank() && youngestTargetName != null) { sender.sendMessage( privatePrefix .append(Component.text("Du schreibst aktuell mit ", NamedTextColor.GRAY)) - .append(chatMessages.getReportablePlayerName(sender)) - ); - return; - } else if(message.isBlank()) { - sender.sendMessage( - privatePrefix - .append(Component.text("Du schreibst aktuell mit niemandem.", NamedTextColor.GRAY)) + .append(currentTargetComponent) ); return; } @@ -74,30 +64,6 @@ public class PrivateMessage extends Appliance { return; } - List oldConversations = this.replyMapping.get(sender).stream() - .filter(conversation -> conversation.lastSet < System.currentTimeMillis() - (targetChangeTimeoutSeconds*1000)) - .toList(); - - Conversation youngestOldConversation = null; - if(!oldConversations.isEmpty()) { - youngestOldConversation = oldConversations.stream() - .max(Comparator.comparingLong(o -> o.lastSet)) - .orElse(oldConversations.getLast()); - this.replyMapping.get(sender).removeAll(oldConversations); - } - - List playerNames = this.replyMapping.get(sender).stream() - .map(conversation -> { - if(Bukkit.getPlayer(conversation.target()) != null) { - return Objects.requireNonNull(Bukkit.getPlayer(conversation.target())).getName(); - } else { - return Bukkit.getOfflinePlayer(conversation.target()).getName(); - } - }) - .distinct() - .toList(); - - sender.sendMessage(""); sender.sendMessage( Component.text() @@ -107,25 +73,26 @@ public class PrivateMessage extends Appliance { .append(Component.text(" Sekunden geändert. Wer soll deine Nachricht bekommen? ", NamedTextColor.RED)) ); + List oldConversations = this.replyMapping.get(sender).stream() + .filter(conversation -> conversation.lastSet < System.currentTimeMillis() - (targetChangeTimeoutSeconds*1000)) + .toList(); + + Conversation youngestOldConversation; + if(!oldConversations.isEmpty()) { + youngestOldConversation = oldConversations.stream() + .max(Comparator.comparingLong(o -> o.lastSet)) + .orElse(oldConversations.getLast()); + this.replyMapping.get(sender).removeAll(oldConversations); + this.replyMapping.get(sender).add(youngestOldConversation); + } + + List playerNames = this.replyMapping.get(sender).stream() + .map(conversation -> Bukkit.getOfflinePlayer(conversation.target()).getName()) + .distinct() + .toList(); + final Component[] finalComponent = {Component.text("")}; - String firstTargetName = null; - if(youngestOldConversation != null && Bukkit.getPlayer(youngestOldConversation.target()) == null) { - firstTargetName = Bukkit.getOfflinePlayer(youngestOldConversation.target()).getName(); - } else if(youngestOldConversation != null){ - firstTargetName = Objects.requireNonNull(Bukkit.getPlayer(youngestOldConversation.target())).getName(); - } - - if(firstTargetName != null && !playerNames.contains(firstTargetName)) { - finalComponent[0] = finalComponent[0].append( - Component.text("[") - .append(Component.text(firstTargetName, NamedTextColor.GOLD)) - .append(Component.text("]")) - .clickEvent(ClickEvent.runCommand("/msg " + firstTargetName + " " + message)) - .hoverEvent(HoverEvent.showText(Component.text("Klicke, um diesem Spieler zu schreiben.").color(NamedTextColor.GOLD)))) - .append(Component.text(" ")); - } - playerNames.forEach(playerName -> finalComponent[0] = finalComponent[0].append( Component.text("[") .append(Component.text(playerName, NamedTextColor.GOLD)) -- 2.30.2 From 985b36ddc814777612dc90c48f281879bf5333c6 Mon Sep 17 00:00:00 2001 From: lars Date: Sun, 6 Oct 2024 15:23:37 +0200 Subject: [PATCH 7/8] solved pr comments except making chatMessages an object variable --- .../privateMessage/PrivateMessage.java | 98 +++++++++---------- .../spawn/util/LimitedSizedList.java | 27 ----- 2 files changed, 48 insertions(+), 77 deletions(-) delete mode 100644 src/main/java/eu/mhsl/craftattack/spawn/util/LimitedSizedList.java diff --git a/src/main/java/eu/mhsl/craftattack/spawn/appliances/privateMessage/PrivateMessage.java b/src/main/java/eu/mhsl/craftattack/spawn/appliances/privateMessage/PrivateMessage.java index 205b977..62e6883 100644 --- a/src/main/java/eu/mhsl/craftattack/spawn/appliances/privateMessage/PrivateMessage.java +++ b/src/main/java/eu/mhsl/craftattack/spawn/appliances/privateMessage/PrivateMessage.java @@ -7,6 +7,8 @@ import eu.mhsl.craftattack.spawn.appliances.chatMessages.ChatMessages; import eu.mhsl.craftattack.spawn.appliances.privateMessage.commands.PrivateMessageCommand; import eu.mhsl.craftattack.spawn.appliances.privateMessage.commands.PrivateReplyCommand; import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.ComponentBuilder; +import net.kyori.adventure.text.TextComponent; import net.kyori.adventure.text.event.ClickEvent; import net.kyori.adventure.text.event.HoverEvent; import net.kyori.adventure.text.format.NamedTextColor; @@ -25,27 +27,29 @@ public class PrivateMessage extends Appliance { private final Map> replyMapping = new WeakHashMap<>(); public void reply(Player sender, String message) { - if(this.replyMapping.get(sender) != null) { - List tooOldConversations = this.replyMapping.get(sender).stream() - .filter(conversation -> conversation.lastSet < System.currentTimeMillis() - (conversationTimeoutMinutes*60*1000)) - .toList(); - this.replyMapping.get(sender).removeAll(tooOldConversations); - } + this.replyMapping.computeIfAbsent(sender, player -> new ArrayList<>()); - if(this.replyMapping.get(sender) == null || this.replyMapping.get(sender).isEmpty()) throw new ApplianceCommand.Error("Du führst aktuell keine Konversation."); + List tooOldConversations = this.replyMapping.get(sender).stream() + .filter(conversation -> conversation.lastSet < System.currentTimeMillis() - (conversationTimeoutMinutes*60*1000)) + .toList(); + this.replyMapping.get(sender).removeAll(tooOldConversations); + + List replyMap = this.replyMapping.get(sender); + + if(replyMap.isEmpty()) throw new ApplianceCommand.Error("Du führst aktuell keine Konversation."); Component privatePrefix = Component.text("[Privat] ", NamedTextColor.LIGHT_PURPLE); - Conversation youngestEntry = this.replyMapping.get(sender).stream() + Conversation youngestEntry = replyMap.stream() .max(Comparator.comparingLong(o -> o.lastSet)) - .orElse(this.replyMapping.get(sender).getLast()); + .orElse(replyMap.getLast()); if(message.isBlank()) { - Component currentTargetComponent = Component.text("niemandem."); Player currentTargetPlayer = Bukkit.getPlayer(youngestEntry.target()); - if(currentTargetPlayer != null) { - currentTargetComponent = Main.instance().getAppliance(ChatMessages.class).getReportablePlayerName(currentTargetPlayer); - } + + Component currentTargetComponent = currentTargetPlayer != null + ? Main.instance().getAppliance(ChatMessages.class).getReportablePlayerName(currentTargetPlayer) + : Component.text("niemandem."); sender.sendMessage( privatePrefix @@ -55,84 +59,79 @@ public class PrivateMessage extends Appliance { return; } - if(youngestEntry.lastSet < System.currentTimeMillis() - (targetChangeTimeoutSeconds*1000) || this.replyMapping.get(sender).size() == 1) { + List oldConversations = replyMap.stream() + .filter(conversation -> conversation.lastSet < System.currentTimeMillis() - (targetChangeTimeoutSeconds*1000)) + .toList(); + + if(oldConversations.contains(youngestEntry) || replyMap.size() == 1) { Player target = Bukkit.getPlayer(youngestEntry.target()); if(target == null) throw new ApplianceCommand.Error("Der Spieler " + Bukkit.getOfflinePlayer(youngestEntry.target()).getName() + " ist nicht mehr verfügbar."); this.replyMapping.get(sender).clear(); - sendWhisper(sender, new ResolvedPmUserArguments(target, message)); + this.sendWhisper(sender, new ResolvedPmUserArguments(target, message)); return; } - sender.sendMessage(""); - sender.sendMessage( - Component.text() + ComponentBuilder component = Component.text(); + + component.append( + Component.newline() .append(privatePrefix) .append(Component.text("Das Ziel für /r hat sich bei dir in den letzten ", NamedTextColor.RED)) .append(Component.text(String.valueOf(this.targetChangeTimeoutSeconds), NamedTextColor.RED)) - .append(Component.text(" Sekunden geändert. Wer soll deine Nachricht bekommen? ", NamedTextColor.RED)) + .append(Component.text(" Sekunden geändert. Wer soll deine Nachricht erhalten? ", NamedTextColor.RED)) + .appendNewline() + .appendNewline() ); - List oldConversations = this.replyMapping.get(sender).stream() - .filter(conversation -> conversation.lastSet < System.currentTimeMillis() - (targetChangeTimeoutSeconds*1000)) - .toList(); - - Conversation youngestOldConversation; if(!oldConversations.isEmpty()) { - youngestOldConversation = oldConversations.stream() + Conversation youngestOldConversation = oldConversations.stream() .max(Comparator.comparingLong(o -> o.lastSet)) .orElse(oldConversations.getLast()); this.replyMapping.get(sender).removeAll(oldConversations); this.replyMapping.get(sender).add(youngestOldConversation); + replyMap = this.replyMapping.get(sender); } - List playerNames = this.replyMapping.get(sender).stream() + List playerNames = replyMap.stream() .map(conversation -> Bukkit.getOfflinePlayer(conversation.target()).getName()) .distinct() .toList(); - final Component[] finalComponent = {Component.text("")}; - - playerNames.forEach(playerName -> finalComponent[0] = finalComponent[0].append( + playerNames.forEach(playerName -> component.append( Component.text("[") .append(Component.text(playerName, NamedTextColor.GOLD)) .append(Component.text("]")) - .clickEvent(ClickEvent.runCommand("/msg " + playerName + " " + message)) + .clickEvent(ClickEvent.runCommand(String.format("/msg %s %s", playerName, message))) .hoverEvent(HoverEvent.showText(Component.text("Klicke, um diesem Spieler zu schreiben.").color(NamedTextColor.GOLD)))) - .append(Component.text(" "))); + .append(Component.text(" ")) + ); + component.appendNewline(); - sender.sendMessage(""); - sender.sendMessage(finalComponent[0]); - sender.sendMessage(""); + sender.sendMessage(component.build()); } public void sendWhisper(Player sender, ResolvedPmUserArguments userArguments) { - - if(!(this.replyMapping.get(userArguments.receiver) == null)) { - List oldEntries = this.replyMapping.get(userArguments.receiver).stream() - .filter(conversation -> conversation.target() == sender.getUniqueId()) - .toList(); - this.replyMapping.get(userArguments.receiver).removeAll(oldEntries); - } - Conversation newReceiverConversation = new Conversation( sender.getUniqueId(), System.currentTimeMillis() ); - if(this.replyMapping.get(userArguments.receiver) == null) { - List receiverConversationList = new ArrayList<>(); - receiverConversationList.add(newReceiverConversation); - + if(this.replyMapping.get(userArguments.receiver) != null) { + List oldEntries = this.replyMapping.get(userArguments.receiver).stream() + .filter(conversation -> conversation.target() == sender.getUniqueId()) + .toList(); + this.replyMapping.get(userArguments.receiver).removeAll(oldEntries); + } else { this.replyMapping.put( userArguments.receiver, - receiverConversationList + new ArrayList<>() ); - } else { - this.replyMapping.get(userArguments.receiver).add(newReceiverConversation); } + this.replyMapping.get(userArguments.receiver).add(newReceiverConversation); + List senderConversationList = new ArrayList<>(); senderConversationList.add( new Conversation( @@ -146,7 +145,6 @@ public class PrivateMessage extends Appliance { senderConversationList ); - ChatMessages chatMessages = Main.instance().getAppliance(ChatMessages.class); Component privatePrefix = Component.text("[Privat] ", NamedTextColor.LIGHT_PURPLE); diff --git a/src/main/java/eu/mhsl/craftattack/spawn/util/LimitedSizedList.java b/src/main/java/eu/mhsl/craftattack/spawn/util/LimitedSizedList.java deleted file mode 100644 index 1b03907..0000000 --- a/src/main/java/eu/mhsl/craftattack/spawn/util/LimitedSizedList.java +++ /dev/null @@ -1,27 +0,0 @@ -package eu.mhsl.craftattack.spawn.util; - -import java.util.ArrayList; - -public class LimitedSizedList extends ArrayList { - private final int maxSize; - - public LimitedSizedList(int size){ - this.maxSize = size; - } - - public boolean add(T element){ - boolean r = super.add(element); - if (size() > maxSize){ - removeRange(0, size() - maxSize); - } - return r; - } - - public T getYoungest() { - return get(size() - 1); - } - - public T getOldest() { - return get(0); - } -} -- 2.30.2 From 8462e43e89842d4d9b95e5b8dc1d05c363a323e8 Mon Sep 17 00:00:00 2001 From: lars Date: Sun, 6 Oct 2024 15:50:17 +0200 Subject: [PATCH 8/8] replaced replyMapping.get(sender) with variable replyList --- .../privateMessage/PrivateMessage.java | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/src/main/java/eu/mhsl/craftattack/spawn/appliances/privateMessage/PrivateMessage.java b/src/main/java/eu/mhsl/craftattack/spawn/appliances/privateMessage/PrivateMessage.java index 62e6883..6ab32d1 100644 --- a/src/main/java/eu/mhsl/craftattack/spawn/appliances/privateMessage/PrivateMessage.java +++ b/src/main/java/eu/mhsl/craftattack/spawn/appliances/privateMessage/PrivateMessage.java @@ -29,20 +29,20 @@ public class PrivateMessage extends Appliance { public void reply(Player sender, String message) { this.replyMapping.computeIfAbsent(sender, player -> new ArrayList<>()); - List tooOldConversations = this.replyMapping.get(sender).stream() + List replyList = this.replyMapping.get(sender); + + List tooOldConversations = replyList.stream() .filter(conversation -> conversation.lastSet < System.currentTimeMillis() - (conversationTimeoutMinutes*60*1000)) .toList(); - this.replyMapping.get(sender).removeAll(tooOldConversations); + replyList.removeAll(tooOldConversations); - List replyMap = this.replyMapping.get(sender); - - if(replyMap.isEmpty()) throw new ApplianceCommand.Error("Du führst aktuell keine Konversation."); + if(replyList.isEmpty()) throw new ApplianceCommand.Error("Du führst aktuell keine Konversation."); Component privatePrefix = Component.text("[Privat] ", NamedTextColor.LIGHT_PURPLE); - Conversation youngestEntry = replyMap.stream() + Conversation youngestEntry = replyList.stream() .max(Comparator.comparingLong(o -> o.lastSet)) - .orElse(replyMap.getLast()); + .orElse(replyList.getLast()); if(message.isBlank()) { Player currentTargetPlayer = Bukkit.getPlayer(youngestEntry.target()); @@ -59,15 +59,15 @@ public class PrivateMessage extends Appliance { return; } - List oldConversations = replyMap.stream() + List oldConversations = replyList.stream() .filter(conversation -> conversation.lastSet < System.currentTimeMillis() - (targetChangeTimeoutSeconds*1000)) .toList(); - if(oldConversations.contains(youngestEntry) || replyMap.size() == 1) { + if(oldConversations.contains(youngestEntry) || replyList.size() == 1) { Player target = Bukkit.getPlayer(youngestEntry.target()); if(target == null) throw new ApplianceCommand.Error("Der Spieler " + Bukkit.getOfflinePlayer(youngestEntry.target()).getName() + " ist nicht mehr verfügbar."); - this.replyMapping.get(sender).clear(); + replyList.clear(); this.sendWhisper(sender, new ResolvedPmUserArguments(target, message)); return; } @@ -88,12 +88,11 @@ public class PrivateMessage extends Appliance { Conversation youngestOldConversation = oldConversations.stream() .max(Comparator.comparingLong(o -> o.lastSet)) .orElse(oldConversations.getLast()); - this.replyMapping.get(sender).removeAll(oldConversations); - this.replyMapping.get(sender).add(youngestOldConversation); - replyMap = this.replyMapping.get(sender); + replyList.removeAll(oldConversations); + replyList.add(youngestOldConversation); } - List playerNames = replyMap.stream() + List playerNames = replyList.stream() .map(conversation -> Bukkit.getOfflinePlayer(conversation.target()).getName()) .distinct() .toList(); -- 2.30.2