SendMailCommand.java 10.7 KB
Newer Older
1
2
package emu.grasscutter.command.commands;

3
import emu.grasscutter.Grasscutter;
4
5
import emu.grasscutter.command.Command;
import emu.grasscutter.command.CommandHandler;
Benjamin Elsdon's avatar
Benjamin Elsdon committed
6
import emu.grasscutter.database.DatabaseHelper;
7
import emu.grasscutter.game.GenshinPlayer;
8
import emu.grasscutter.game.Mail;
9
10
import emu.grasscutter.server.packet.send.PacketMailChangeNotify;

11
12
import java.time.Instant;
import java.util.ArrayList;
Benjamin Elsdon's avatar
Benjamin Elsdon committed
13
import java.util.HashMap;
14
import java.util.List;
Benjamin Elsdon's avatar
Benjamin Elsdon committed
15
import java.util.Locale;
16

Benjamin Elsdon's avatar
Benjamin Elsdon committed
17
18
@Command(label = "sendmail", usage = "sendmail <userId|all|help> [templateId]",
        description = "Sends mail to the specified user. The usage of this command changes based on it's composition state.", permission = "server.sendmail")
19
20
public class SendMailCommand implements CommandHandler {

Benjamin Elsdon's avatar
Benjamin Elsdon committed
21
22
23
24
25
26
27
28
    // TODO: You should be able to do /sendmail and then just send subsequent messages until you finish
    //  However, due to the current nature of the command system, I don't think this is possible without rewriting
    //  the command system (again). For now this will do

    // Key = User that is constructing the mail.
    private static HashMap<Integer, MailBuilder> mailBeingConstructed = new HashMap<Integer, MailBuilder>();

    // Yes this is awful and I hate it.
29
30
    @Override
    public void execute(GenshinPlayer sender, List<String> args) {
Benjamin Elsdon's avatar
Benjamin Elsdon committed
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
        int senderId;
        if(sender != null) {
            senderId = sender.getUid();
        } else {
            senderId = -1;
        }

        if (!mailBeingConstructed.containsKey(senderId)) {
            switch (args.size()) {
                case 1:
                    MailBuilder mailBuilder;
                    switch (args.get(0).toLowerCase()) {
                        case "help":
                            CommandHandler.sendMessage(sender, this.getClass().getAnnotation(Command.class).description() + "\nUsage: " + this.getClass().getAnnotation(Command.class).usage());
                            return;
                        case "all":
                            mailBuilder = new MailBuilder(true, new Mail());
                            break;
                        default:
                            if (DatabaseHelper.getPlayerById(Integer.parseInt(args.get(0))) != null) {
                                mailBuilder = new MailBuilder(Integer.parseInt(args.get(0)), new Mail());
                                break;
                            } else {
                                CommandHandler.sendMessage(sender, "The user with an id of '" + args.get(0) + "' does not exist");
                                return;
                            }
                    }
                    mailBeingConstructed.put(senderId, mailBuilder);
                    CommandHandler.sendMessage(sender, "Starting composition of message.\nPlease use `/sendmail <title>` to continue.\nYou can use `/sendmail stop` at any time");
                    break;
                case 2:
                    CommandHandler.sendMessage(sender, "Mail templates coming soon implemented...");
                    return;
                default:
                    CommandHandler.sendMessage(sender, "Invalid arguments.\nUsage `/sendmail <userId|all|help> [templateId]`");
                    return;
            }
        } else {
            MailBuilder mailBuilder = mailBeingConstructed.get(senderId);

            if (args.size() >= 1) {
                switch (args.get(0).toLowerCase()) {
                    case "stop":
                        mailBeingConstructed.remove(senderId);
                        CommandHandler.sendMessage(sender, "Message sending cancelled");
                        return;
                    case "finish":
                        if (mailBuilder.constructionStage == 3) {
                            if(mailBuilder.sendToAll == false) {
                                Grasscutter.getGameServer().getPlayerByUid(mailBuilder.recipient, true).sendMail(mailBuilder.mail);
                                CommandHandler.sendMessage(sender, "Message sent to user " + mailBuilder.recipient + "!");
                            } else {
                                // TODO: More testing required. This probably won't work for online players if DatabaseHelper.getPlayerById(string) didn't work.
                                for (GenshinPlayer player : DatabaseHelper.getAllPlayers()) {
                                    player.sendMail(mailBuilder.mail);
                                }
                                CommandHandler.sendMessage(sender, "Message sent to all users!");
                            }
                            mailBeingConstructed.remove(senderId);
                        } else {
                            CommandHandler.sendMessage(sender, "Message composition not at final stage.\nPlease use `/sendmail " + getConstructionArgs(mailBuilder.constructionStage) + "` or `/sendmail stop` to cancel");
                        }
                        return;
                    case "help":
                        CommandHandler.sendMessage(sender, "Please use `/sendmail " + getConstructionArgs(mailBuilder.constructionStage) + "`");
                        return;
                    default:
                        switch (mailBuilder.constructionStage) {
                            case 0:
                                String title = String.join(" ", args.subList(0, args.size()));
                                mailBuilder.mail.mailContent.title = title;
                                CommandHandler.sendMessage(sender, "Message title set as '" + title + "'.\nUse '/sendmail <content>' to continue.");
                                mailBuilder.constructionStage++;
                                break;
                            case 1:
                                String contents = String.join(" ", args.subList(0, args.size()));
                                mailBuilder.mail.mailContent.content = contents;
                                CommandHandler.sendMessage(sender, "Message contents set as '" + contents + "'.\nUse '/sendmail <sender>' to continue.");
                                mailBuilder.constructionStage++;
                                break;
                            case 2:
                                String msgSender = String.join(" ", args.subList(0, args.size()));
                                mailBuilder.mail.mailContent.sender = msgSender;
                                CommandHandler.sendMessage(sender, "Message sender set as '" + msgSender + "'.\nUse '/sendmail <itemId|itemName|finish> [amount] [level]' to continue.");
                                mailBuilder.constructionStage++;
                                break;
                            case 3:
                                // Literally just copy-pasted from the give command lol.
                                int item, lvl, amount = 1;
                                switch (args.size()) {
                                    default: // *No args*
                                        CommandHandler.sendMessage(sender, "Usage: give [player] <itemId|itemName> [amount]");
                                        return;
                                    case 1: // <itemId|itemName>
                                        try {
                                            item = Integer.parseInt(args.get(0));
                                            lvl = 1;
                                        } catch (NumberFormatException ignored) {
                                            // TODO: Parse from item name using GM Handbook.
                                            CommandHandler.sendMessage(sender, "Invalid item id.");
                                            return;
                                        }
                                        break;
                                    case 2: // <itemId|itemName> [amount]
                                        lvl = 1;
                                        item = Integer.parseInt(args.get(0));
                                        amount = Integer.parseInt(args.get(1));
                                        break;
                                    case 3: // <itemId|itemName> [amount] [level]
                                        try {
                                            item = Integer.parseInt(args.get(0));
                                            amount = Integer.parseInt(args.get(1));
                                            lvl = Integer.parseInt(args.get(2));

                                        } catch (NumberFormatException ignored) {
                                            // TODO: Parse from item name using GM Handbook.
                                            CommandHandler.sendMessage(sender, "Invalid item or player ID.");
                                            return;
                                        }
                                        break;
                                }
                                mailBuilder.mail.itemList.add(new Mail.MailItem(item, amount, lvl));
                                CommandHandler.sendMessage(sender, String.format("Attached %s of %s (level %s) to the message.\nContinue adding more items or use `/sendmail finish` to send the message.", amount, item, lvl));
                        }
                        break;
                }
            } else {
                CommandHandler.sendMessage(sender, "Invalid arguments \n Please use `/sendmail " + getConstructionArgs(mailBuilder.constructionStage));
            }
        }
    }

    public String getConstructionArgs(int stage) {
        switch (stage) {
            case 0:
                return "<title>";
            case 1:
                return "<message>";
            case 2:
                return "<sender>";
            case 3:
                return "<itemId|itemName|finish> [amount] [level]";
            default:
                Thread.dumpStack();
                return "ERROR: invalid construction stage " + stage + ". Check console for stacktrace.";
176
        }
Benjamin Elsdon's avatar
Benjamin Elsdon committed
177
178
179
180
181
182
183
    }

    public static class MailBuilder {
        public int recipient;
        public boolean sendToAll;
        public int constructionStage;
        public Mail mail;
184

Benjamin Elsdon's avatar
Benjamin Elsdon committed
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
        public MailBuilder(int recipient, Mail mail) {
            this.recipient = recipient;
            this.sendToAll = false;
            this.constructionStage = 0;
            this.mail = mail;
        }

        public MailBuilder(boolean sendToAll, Mail mail) {
            if (sendToAll) {
                this.recipient = 0;
                this.sendToAll = true;
                this.constructionStage = 0;
                this.mail = mail;
            } else {
                Grasscutter.getLogger().error("Please use MailBuilder(int, mail) when not sending to all");
                Thread.dumpStack();
            }
        }
203
204
    }
}