From 47911aa16e4a3cefcb3c79dc31ce5ab3ba8ab7be Mon Sep 17 00:00:00 2001
From: jie65535 <jie65535@qq.com>
Date: Sun, 30 Oct 2022 17:33:30 +0800
Subject: [PATCH] Fix Mail SendToAll Freeze (#1913)

* Avoid iterating over every offline player

* getAllPlayers by stream

* Use the new method without changing the old signature

* Annotate deprecated `getAllPlayers`
---
 .../emu/grasscutter/command/commands/SendMailCommand.java | 8 +++++---
 .../java/emu/grasscutter/database/DatabaseHelper.java     | 6 ++++++
 2 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/src/main/java/emu/grasscutter/command/commands/SendMailCommand.java b/src/main/java/emu/grasscutter/command/commands/SendMailCommand.java
index 458ac598..02d04445 100644
--- a/src/main/java/emu/grasscutter/command/commands/SendMailCommand.java
+++ b/src/main/java/emu/grasscutter/command/commands/SendMailCommand.java
@@ -9,6 +9,7 @@ import emu.grasscutter.game.player.Player;
 
 import java.util.HashMap;
 import java.util.List;
+import java.util.Objects;
 
 import static emu.grasscutter.utils.Language.translate;
 
@@ -78,9 +79,10 @@ public final class SendMailCommand implements CommandHandler {
                                 Grasscutter.getGameServer().getPlayerByUid(mailBuilder.recipient, true).sendMail(mailBuilder.mail);
                                 CommandHandler.sendMessage(sender, translate(sender, "commands.sendMail.send_done", mailBuilder.recipient));
                             } else {
-                                for (Player player : DatabaseHelper.getAllPlayers()) {
-                                    Grasscutter.getGameServer().getPlayerByUid(player.getUid(), true).sendMail(mailBuilder.mail);
-                                }
+                                DatabaseHelper.getByGameClass(Player.class).forEach(player -> {
+                                    var onlinePlayer = Grasscutter.getGameServer().getPlayerByUid(player.getUid(), false);
+                                    Objects.requireNonNullElse(onlinePlayer, player).sendMail(mailBuilder.mail);
+                                });
                                 CommandHandler.sendMessage(sender, translate(sender, "commands.sendMail.send_all_done"));
                             }
                             mailBeingConstructed.remove(senderId);
diff --git a/src/main/java/emu/grasscutter/database/DatabaseHelper.java b/src/main/java/emu/grasscutter/database/DatabaseHelper.java
index 98d7bf81..c0c5e92b 100644
--- a/src/main/java/emu/grasscutter/database/DatabaseHelper.java
+++ b/src/main/java/emu/grasscutter/database/DatabaseHelper.java
@@ -1,6 +1,7 @@
 package emu.grasscutter.database;
 
 import java.util.List;
+import java.util.stream.Stream;
 
 import com.mongodb.client.result.DeleteResult;
 
@@ -154,6 +155,11 @@ public final class DatabaseHelper {
         DatabaseManager.getAccountDatastore().find(Account.class).filter(Filters.eq("id", target.getId())).delete();
     }
 
+    public static <T> Stream<T> getByGameClass(Class<T> classType) {
+        return DatabaseManager.getGameDatastore().find(classType).stream();
+    }
+
+    @Deprecated(forRemoval = true)
     public static List<Player> getAllPlayers() {
         return DatabaseManager.getGameDatastore().find(Player.class).stream().toList();
     }
-- 
GitLab