fully implement the mail command

This commit is contained in:
Hiro
2025-11-15 11:29:40 +02:00
parent 66b2d84945
commit 33babe3405

View File

@@ -1,20 +1,152 @@
package emu.nebula.command.commands; package emu.nebula.command.commands;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import emu.nebula.command.Command; import emu.nebula.command.Command;
import emu.nebula.command.CommandArgs; import emu.nebula.command.CommandArgs;
import emu.nebula.command.CommandHandler; import emu.nebula.command.CommandHandler;
import emu.nebula.game.mail.GameMail; import emu.nebula.game.mail.GameMail;
import emu.nebula.util.Utils;
@Command(label = "mail", aliases = {"m"}, permission = "player.mail", requireTarget = true, desc = "/mail [content]. Sends the targeted player a system mail.") @Command(
label = "mail",
aliases = {"m"},
permission = "player.mail",
requireTarget = true,
desc = "/mail \"subject\" \"body\" [itemId xQty | itemId:qty ...]. Sends the targeted player a system mail."
)
public class MailCommand implements CommandHandler { public class MailCommand implements CommandHandler {
private static final Pattern QUOTED_TEXT = Pattern.compile("\"([^\"]*)\"");
@Override @Override
public void execute(CommandArgs args) { public void execute(CommandArgs args) {
// Setup mail var target = args.getTarget();
var mail = new GameMail("System", "Test", "This is a test mail"); if (target == null) {
args.sendMessage("Error: Targeted player not found or offline");
return;
}
String rawInput = args.getRaw() == null ? "" : args.getRaw().trim();
if (rawInput.isEmpty()) {
sendUsage(args);
return;
}
Matcher matcher = QUOTED_TEXT.matcher(rawInput);
if (!matcher.find()) {
sendUsage(args);
return;
}
String subject = matcher.group(1).trim();
if (!matcher.find()) {
args.sendMessage("Mail body must be wrapped in quotes after the subject.");
return;
}
String body = matcher.group(1).trim();
int attachmentStartIndex = matcher.end();
if (subject.isEmpty()) {
args.sendMessage("Mail subject cannot be empty.");
return;
}
if (body.isEmpty()) {
body = " "; // just for safety, so the client won't complain
}
String author = args.getSender() != null ? args.getSender().getName() : "System";
var mail = new GameMail(author, subject, body);
String attachmentSection = rawInput.length() > attachmentStartIndex
? rawInput.substring(attachmentStartIndex).trim()
: "";
parseAttachments(attachmentSection, mail, args);
// Add mail target.getMailbox().sendMail(mail);
args.getTarget().getMailbox().sendMail(mail); args.sendMessage("Mail sent to " + target.getName() + " with subject \"" + subject + "\".");
} }
private void parseAttachments(String attachmentSection, GameMail mail, CommandArgs args) {
if (attachmentSection == null || attachmentSection.isBlank()) {
return;
}
Integer pendingItemId = null;
for (String token : attachmentSection.split("\\s+")) {
if (token.isBlank()) {
continue;
}
if (token.contains(":") || token.contains(",")) {
String[] split = token.split("[:,]", 2);
int itemId = Utils.parseSafeInt(split[0]);
int qty = split.length > 1 ? Utils.parseSafeInt(split[1]) : 1;
addAttachment(mail, args, itemId, qty);
pendingItemId = null;
continue;
}
if (token.startsWith("x") && token.length() > 1) {
if (pendingItemId == null) {
args.sendMessage("Quantity token '" + token + "' must follow an item id.");
continue;
}
int qty = Utils.parseSafeInt(token.substring(1));
addAttachment(mail, args, pendingItemId, qty);
pendingItemId = null;
continue;
}
if (isIntegerToken(token)) {
if (pendingItemId != null) {
addAttachment(mail, args, pendingItemId, 1);
}
int itemId = Utils.parseSafeInt(token);
if (itemId <= 0) {
args.sendMessage("Invalid item id '" + token + "'.");
pendingItemId = null;
continue;
}
pendingItemId = itemId;
continue;
}
args.sendMessage("Ignoring attachment token '" + token + "'.");
}
if (pendingItemId != null) {
addAttachment(mail, args, pendingItemId, 1);
}
}
private void addAttachment(GameMail mail, CommandArgs args, int itemId, int quantity) {
if (itemId <= 0) {
args.sendMessage("Item id must be positive.");
return;
}
int qty = Math.max(quantity, 1);
mail.addAttachment(itemId, qty);
}
private boolean isIntegerToken(String token) {
for (int i = 0; i < token.length(); i++) {
if (!Character.isDigit(token.charAt(i))) {
return false;
}
}
return !token.isEmpty();
}
private void sendUsage(CommandArgs args) {
args.sendMessage("Usage: /mail \"subject\" \"body\" [itemId xQty | itemId:qty ...]");
}
} }