mirror of
https://github.com/EssentialsX/Essentials.git
synced 2024-12-22 17:18:37 +01:00
Rework Mail System (#3710)
* New `/mail sendtemp <time diff> <message>` command to send mail that will self-destruct after time diff. * New `/mail clear <number>` command to clear a specific mail item. * `/mail read` now tracks which mails you read and won't nag you about them. * A bunch of other flexibility since we store actual data instead of strings
This commit is contained in:
parent
55db6c2476
commit
9c451271e0
@ -6,6 +6,8 @@ import org.bukkit.Server;
|
|||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
import static com.earth2me.essentials.I18n.tl;
|
import static com.earth2me.essentials.I18n.tl;
|
||||||
|
|
||||||
public final class Console implements IMessageRecipient {
|
public final class Console implements IMessageRecipient {
|
||||||
@ -46,6 +48,11 @@ public final class Console implements IMessageRecipient {
|
|||||||
return Console.NAME;
|
return Console.NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UUID getUUID() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getDisplayName() {
|
public String getDisplayName() {
|
||||||
return Console.DISPLAY_NAME;
|
return Console.DISPLAY_NAME;
|
||||||
|
@ -82,6 +82,7 @@ import net.ess3.provider.providers.PaperRecipeBookListener;
|
|||||||
import net.ess3.provider.providers.PaperSerializationProvider;
|
import net.ess3.provider.providers.PaperSerializationProvider;
|
||||||
import net.ess3.provider.providers.PaperServerStateProvider;
|
import net.ess3.provider.providers.PaperServerStateProvider;
|
||||||
import net.essentialsx.api.v2.services.BalanceTop;
|
import net.essentialsx.api.v2.services.BalanceTop;
|
||||||
|
import net.essentialsx.api.v2.services.mail.MailService;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Server;
|
import org.bukkit.Server;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
@ -147,6 +148,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
|||||||
private transient UserMap userMap;
|
private transient UserMap userMap;
|
||||||
private transient BalanceTopImpl balanceTop;
|
private transient BalanceTopImpl balanceTop;
|
||||||
private transient ExecuteTimer execTimer;
|
private transient ExecuteTimer execTimer;
|
||||||
|
private transient MailService mail;
|
||||||
private transient I18n i18n;
|
private transient I18n i18n;
|
||||||
private transient MetricsWrapper metrics;
|
private transient MetricsWrapper metrics;
|
||||||
private transient EssentialsTimer timer;
|
private transient EssentialsTimer timer;
|
||||||
@ -204,6 +206,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
|||||||
LOGGER.log(Level.INFO, tl("usingTempFolderForTesting"));
|
LOGGER.log(Level.INFO, tl("usingTempFolderForTesting"));
|
||||||
LOGGER.log(Level.INFO, dataFolder.toString());
|
LOGGER.log(Level.INFO, dataFolder.toString());
|
||||||
settings = new Settings(this);
|
settings = new Settings(this);
|
||||||
|
mail = new MailServiceImpl(this);
|
||||||
userMap = new UserMap(this);
|
userMap = new UserMap(this);
|
||||||
balanceTop = new BalanceTopImpl(this);
|
balanceTop = new BalanceTopImpl(this);
|
||||||
permissionsHandler = new PermissionsHandler(this, false);
|
permissionsHandler = new PermissionsHandler(this, false);
|
||||||
@ -277,6 +280,9 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
|||||||
confList.add(settings);
|
confList.add(settings);
|
||||||
execTimer.mark("Settings");
|
execTimer.mark("Settings");
|
||||||
|
|
||||||
|
mail = new MailServiceImpl(this);
|
||||||
|
execTimer.mark("Init(Mail)");
|
||||||
|
|
||||||
userMap = new UserMap(this);
|
userMap = new UserMap(this);
|
||||||
confList.add(userMap);
|
confList.add(userMap);
|
||||||
execTimer.mark("Init(Usermap)");
|
execTimer.mark("Init(Usermap)");
|
||||||
@ -1159,6 +1165,11 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
|||||||
return timer;
|
return timer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MailService getMail() {
|
||||||
|
return mail;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> getVanishedPlayers() {
|
public List<String> getVanishedPlayers() {
|
||||||
return Collections.unmodifiableList(new ArrayList<>(vanishedPlayers));
|
return Collections.unmodifiableList(new ArrayList<>(vanishedPlayers));
|
||||||
|
@ -364,8 +364,7 @@ public class EssentialsPlayerListener implements Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!ess.getSettings().isCommandDisabled("mail") && user.isAuthorized("essentials.mail")) {
|
if (!ess.getSettings().isCommandDisabled("mail") && user.isAuthorized("essentials.mail")) {
|
||||||
final List<String> mail = user.getMails();
|
if (user.getUnreadMailAmount() == 0) {
|
||||||
if (mail.isEmpty()) {
|
|
||||||
if (ess.getSettings().isNotifyNoNewMail()) {
|
if (ess.getSettings().isNotifyNoNewMail()) {
|
||||||
user.sendMessage(tl("noNewMail")); // Only notify if they want us to.
|
user.sendMessage(tl("noNewMail")); // Only notify if they want us to.
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,9 @@ import com.earth2me.essentials.craftbukkit.BanLookup;
|
|||||||
import com.earth2me.essentials.utils.StringUtil;
|
import com.earth2me.essentials.utils.StringUtil;
|
||||||
import com.google.common.base.Charsets;
|
import com.google.common.base.Charsets;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
|
import com.google.gson.reflect.TypeToken;
|
||||||
import net.ess3.api.IEssentials;
|
import net.ess3.api.IEssentials;
|
||||||
|
import net.essentialsx.api.v2.services.mail.MailMessage;
|
||||||
import org.bukkit.BanList;
|
import org.bukkit.BanList;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
@ -146,6 +148,46 @@ public class EssentialsUpgrade {
|
|||||||
ess.getLogger().info("To rerun the conversion type /essentials uuidconvert");
|
ess.getLogger().info("To rerun the conversion type /essentials uuidconvert");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void convertMailList() {
|
||||||
|
if (doneFile.getBoolean("updateUsersMailList", false)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final File userdataFolder = new File(ess.getDataFolder(), "userdata");
|
||||||
|
if (!userdataFolder.exists() || !userdataFolder.isDirectory()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final File[] userFiles = userdataFolder.listFiles();
|
||||||
|
for (File file : userFiles) {
|
||||||
|
if (!file.isFile() || !file.getName().endsWith(".yml")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
final EssentialsConfiguration config = new EssentialsConfiguration(file);
|
||||||
|
try {
|
||||||
|
config.load();
|
||||||
|
if (config.hasProperty("mail") && config.isList("mail")) {
|
||||||
|
final ArrayList<MailMessage> messages = new ArrayList<>();
|
||||||
|
for (String mailStr : Collections.synchronizedList(config.getList("mail", String.class))) {
|
||||||
|
if (mailStr == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
messages.add(new MailMessage(false, true, null, null, 0L, 0L, mailStr));
|
||||||
|
}
|
||||||
|
|
||||||
|
config.removeProperty("mail");
|
||||||
|
config.setExplicitList("mail", messages, new TypeToken<List<MailMessage>>() {}.getType());
|
||||||
|
config.blockingSave();
|
||||||
|
}
|
||||||
|
} catch (RuntimeException ex) {
|
||||||
|
LOGGER.log(Level.INFO, "File: " + file);
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
doneFile.setProperty("updateUsersMailList", true);
|
||||||
|
doneFile.save();
|
||||||
|
LOGGER.info("Done converting mail list.");
|
||||||
|
}
|
||||||
|
|
||||||
public void convertStupidCamelCaseUserdataKeys() {
|
public void convertStupidCamelCaseUserdataKeys() {
|
||||||
if (doneFile.getBoolean("updateUsersLegacyPathNames", false)) {
|
if (doneFile.getBoolean("updateUsersLegacyPathNames", false)) {
|
||||||
return;
|
return;
|
||||||
@ -820,5 +862,6 @@ public class EssentialsUpgrade {
|
|||||||
repairUserMap();
|
repairUserMap();
|
||||||
convertIgnoreList();
|
convertIgnoreList();
|
||||||
convertStupidCamelCaseUserdataKeys();
|
convertStupidCamelCaseUserdataKeys();
|
||||||
|
convertMailList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ import net.ess3.provider.SpawnerBlockProvider;
|
|||||||
import net.ess3.provider.SpawnerItemProvider;
|
import net.ess3.provider.SpawnerItemProvider;
|
||||||
import net.ess3.provider.SyncCommandsProvider;
|
import net.ess3.provider.SyncCommandsProvider;
|
||||||
import net.essentialsx.api.v2.services.BalanceTop;
|
import net.essentialsx.api.v2.services.BalanceTop;
|
||||||
|
import net.essentialsx.api.v2.services.mail.MailService;
|
||||||
import org.bukkit.Server;
|
import org.bukkit.Server;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.command.Command;
|
import org.bukkit.command.Command;
|
||||||
@ -120,6 +121,8 @@ public interface IEssentials extends Plugin {
|
|||||||
|
|
||||||
EssentialsTimer getTimer();
|
EssentialsTimer getTimer();
|
||||||
|
|
||||||
|
MailService getMail();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a list of players who are vanished.
|
* Get a list of players who are vanished.
|
||||||
*
|
*
|
||||||
|
@ -6,12 +6,15 @@ import com.earth2me.essentials.config.entities.CommandCooldown;
|
|||||||
import net.ess3.api.ITeleport;
|
import net.ess3.api.ITeleport;
|
||||||
import net.ess3.api.MaxMoneyException;
|
import net.ess3.api.MaxMoneyException;
|
||||||
import net.ess3.api.events.AfkStatusChangeEvent;
|
import net.ess3.api.events.AfkStatusChangeEvent;
|
||||||
|
import net.essentialsx.api.v2.services.mail.MailMessage;
|
||||||
|
import net.essentialsx.api.v2.services.mail.MailSender;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -148,10 +151,22 @@ public interface IUser {
|
|||||||
|
|
||||||
String getFormattedJailTime();
|
String getFormattedJailTime();
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
List<String> getMails();
|
List<String> getMails();
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
void addMail(String mail);
|
void addMail(String mail);
|
||||||
|
|
||||||
|
void sendMail(MailSender sender, String message);
|
||||||
|
|
||||||
|
void sendMail(MailSender sender, String message, long expireAt);
|
||||||
|
|
||||||
|
ArrayList<MailMessage> getMailMessages();
|
||||||
|
|
||||||
|
void setMailList(ArrayList<MailMessage> messages);
|
||||||
|
|
||||||
|
int getMailAmount();
|
||||||
|
|
||||||
boolean isAfk();
|
boolean isAfk();
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
|
@ -0,0 +1,53 @@
|
|||||||
|
package com.earth2me.essentials;
|
||||||
|
|
||||||
|
import net.ess3.api.IUser;
|
||||||
|
import net.essentialsx.api.v2.services.mail.MailService;
|
||||||
|
import net.essentialsx.api.v2.services.mail.MailMessage;
|
||||||
|
import net.essentialsx.api.v2.services.mail.MailSender;
|
||||||
|
import org.bukkit.plugin.ServicePriority;
|
||||||
|
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import static com.earth2me.essentials.I18n.tl;
|
||||||
|
|
||||||
|
public class MailServiceImpl implements MailService {
|
||||||
|
private final transient ThreadLocal<SimpleDateFormat> df = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy/MM/dd HH:mm"));
|
||||||
|
|
||||||
|
public MailServiceImpl(IEssentials ess) {
|
||||||
|
ess.getServer().getServicesManager().register(MailService.class, this, ess, ServicePriority.Normal);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendMail(IUser recipient, MailSender sender, String message) {
|
||||||
|
sendMail(recipient, sender, message, 0L);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendMail(IUser recipient, MailSender sender, String message, long expireAt) {
|
||||||
|
sendMail(recipient, new MailMessage(false, false, sender.getName(), sender.getUUID(), System.currentTimeMillis(), expireAt, message));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendLegacyMail(IUser recipient, String message) {
|
||||||
|
sendMail(recipient, new MailMessage(false, true, null, null, 0L, 0L, message));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendMail(IUser recipient, MailMessage message) {
|
||||||
|
final ArrayList<MailMessage> messages = recipient.getMailMessages();
|
||||||
|
messages.add(0, message);
|
||||||
|
recipient.setMailList(messages);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getMailLine(MailMessage mail) {
|
||||||
|
final String message = mail.getMessage();
|
||||||
|
if (mail.isLegacy()) {
|
||||||
|
return tl("mailMessage", message);
|
||||||
|
}
|
||||||
|
|
||||||
|
final String expire = mail.getTimeExpire() != 0 ? "Timed" : "";
|
||||||
|
return tl((mail.isRead() ? "mailFormatNewRead" : "mailFormatNew") + expire, df.get().format(new Date(mail.getTimeSent())), mail.getSenderUsername(), message);
|
||||||
|
}
|
||||||
|
}
|
@ -5,11 +5,11 @@ import com.earth2me.essentials.economy.EconomyLayer;
|
|||||||
import com.earth2me.essentials.economy.EconomyLayers;
|
import com.earth2me.essentials.economy.EconomyLayers;
|
||||||
import com.earth2me.essentials.messaging.IMessageRecipient;
|
import com.earth2me.essentials.messaging.IMessageRecipient;
|
||||||
import com.earth2me.essentials.messaging.SimpleMessageRecipient;
|
import com.earth2me.essentials.messaging.SimpleMessageRecipient;
|
||||||
import com.earth2me.essentials.utils.TriState;
|
|
||||||
import com.earth2me.essentials.utils.DateUtil;
|
import com.earth2me.essentials.utils.DateUtil;
|
||||||
import com.earth2me.essentials.utils.EnumUtil;
|
import com.earth2me.essentials.utils.EnumUtil;
|
||||||
import com.earth2me.essentials.utils.FormatUtil;
|
import com.earth2me.essentials.utils.FormatUtil;
|
||||||
import com.earth2me.essentials.utils.NumberUtil;
|
import com.earth2me.essentials.utils.NumberUtil;
|
||||||
|
import com.earth2me.essentials.utils.TriState;
|
||||||
import com.earth2me.essentials.utils.VersionUtil;
|
import com.earth2me.essentials.utils.VersionUtil;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import net.ess3.api.IEssentials;
|
import net.ess3.api.IEssentials;
|
||||||
@ -19,6 +19,7 @@ import net.ess3.api.events.JailStatusChangeEvent;
|
|||||||
import net.ess3.api.events.MuteStatusChangeEvent;
|
import net.ess3.api.events.MuteStatusChangeEvent;
|
||||||
import net.ess3.api.events.UserBalanceUpdateEvent;
|
import net.ess3.api.events.UserBalanceUpdateEvent;
|
||||||
import net.essentialsx.api.v2.events.TransactionEvent;
|
import net.essentialsx.api.v2.events.TransactionEvent;
|
||||||
|
import net.essentialsx.api.v2.services.mail.MailSender;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.Statistic;
|
import org.bukkit.Statistic;
|
||||||
@ -987,6 +988,11 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
|||||||
return this.getBase().getName();
|
return this.getBase().getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UUID getUUID() {
|
||||||
|
return getBase().getUniqueId();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isReachable() {
|
public boolean isReachable() {
|
||||||
return getBase().isOnline();
|
return getBase().isOnline();
|
||||||
@ -1054,12 +1060,28 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendMail(MailSender sender, String message) {
|
||||||
|
sendMail(sender, message, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendMail(MailSender sender, String message, long expireAt) {
|
||||||
|
ess.getMail().sendMail(this, sender, message, expireAt);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public void addMail(String mail) {
|
||||||
|
ess.getMail().sendLegacyMail(this, mail);
|
||||||
|
}
|
||||||
|
|
||||||
public void notifyOfMail() {
|
public void notifyOfMail() {
|
||||||
final List<String> mails = getMails();
|
final int unread = getUnreadMailAmount();
|
||||||
if (mails != null && !mails.isEmpty()) {
|
if (unread != 0) {
|
||||||
final int notifyPlayerOfMailCooldown = ess.getSettings().getNotifyPlayerOfMailCooldown() * 1000;
|
final int notifyPlayerOfMailCooldown = ess.getSettings().getNotifyPlayerOfMailCooldown() * 1000;
|
||||||
if (System.currentTimeMillis() - lastNotifiedAboutMailsMs >= notifyPlayerOfMailCooldown) {
|
if (System.currentTimeMillis() - lastNotifiedAboutMailsMs >= notifyPlayerOfMailCooldown) {
|
||||||
sendMessage(tl("youHaveNewMail", mails.size()));
|
sendMessage(tl("youHaveNewMail", unread));
|
||||||
lastNotifiedAboutMailsMs = System.currentTimeMillis();
|
lastNotifiedAboutMailsMs = System.currentTimeMillis();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,8 @@ import com.earth2me.essentials.utils.StringUtil;
|
|||||||
import com.google.common.base.Charsets;
|
import com.google.common.base.Charsets;
|
||||||
import net.ess3.api.IEssentials;
|
import net.ess3.api.IEssentials;
|
||||||
import net.ess3.api.MaxMoneyException;
|
import net.ess3.api.MaxMoneyException;
|
||||||
|
import net.essentialsx.api.v2.services.mail.MailMessage;
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
@ -313,17 +315,59 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
|||||||
config.save();
|
config.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Mails are no longer just strings, this method is therefore misleading.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
public List<String> getMails() {
|
public List<String> getMails() {
|
||||||
return holder.mail();
|
final List<String> list = new ArrayList<>();
|
||||||
|
if (getMailAmount() != 0) {
|
||||||
|
for (MailMessage mail : getMailMessages()) {
|
||||||
|
// I hate this code btw
|
||||||
|
list.add(mail.isLegacy() ? mail.getMessage() : ChatColor.GOLD + "[" + ChatColor.RESET + mail.getSenderUsername() + ChatColor.GOLD + "] " + ChatColor.RESET + mail.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated This method does not support the new mail system and will fail at runtime.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
public void setMails(List<String> mails) {
|
public void setMails(List<String> mails) {
|
||||||
holder.mail(mails);
|
throw new UnsupportedOperationException("UserData#setMails(List<String>) is deprecated and can no longer be used. Please tell the plugin author to update this!");
|
||||||
config.save();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addMail(final String mail) {
|
public int getMailAmount() {
|
||||||
holder.mail().add(mail);
|
return holder.mail() == null ? 0 : holder.mail().size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getUnreadMailAmount() {
|
||||||
|
if (holder.mail() == null || holder.mail().isEmpty()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int unread = 0;
|
||||||
|
for (MailMessage element : holder.mail()) {
|
||||||
|
if (!element.isRead()) {
|
||||||
|
unread++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return unread;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated This method does not support the new mail system and should not be used.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
abstract void addMail(final String mail);
|
||||||
|
|
||||||
|
public ArrayList<MailMessage> getMailMessages() {
|
||||||
|
return new ArrayList<>(holder.mail());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMailList(ArrayList<MailMessage> messages) {
|
||||||
|
holder.mail(messages);
|
||||||
config.save();
|
config.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,18 +1,23 @@
|
|||||||
package com.earth2me.essentials.commands;
|
package com.earth2me.essentials.commands;
|
||||||
|
|
||||||
import com.earth2me.essentials.CommandSource;
|
import com.earth2me.essentials.CommandSource;
|
||||||
|
import com.earth2me.essentials.Console;
|
||||||
import com.earth2me.essentials.User;
|
import com.earth2me.essentials.User;
|
||||||
import com.earth2me.essentials.textreader.IText;
|
import com.earth2me.essentials.messaging.IMessageRecipient;
|
||||||
import com.earth2me.essentials.textreader.SimpleTextInput;
|
import com.earth2me.essentials.textreader.SimpleTextInput;
|
||||||
import com.earth2me.essentials.textreader.TextPager;
|
import com.earth2me.essentials.textreader.TextPager;
|
||||||
import com.earth2me.essentials.utils.DateUtil;
|
import com.earth2me.essentials.utils.DateUtil;
|
||||||
import com.earth2me.essentials.utils.FormatUtil;
|
import com.earth2me.essentials.utils.FormatUtil;
|
||||||
|
import com.earth2me.essentials.utils.NumberUtil;
|
||||||
import com.earth2me.essentials.utils.StringUtil;
|
import com.earth2me.essentials.utils.StringUtil;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
import net.essentialsx.api.v2.services.mail.MailMessage;
|
||||||
import org.bukkit.Server;
|
import org.bukkit.Server;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.ListIterator;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import static com.earth2me.essentials.I18n.tl;
|
import static com.earth2me.essentials.I18n.tl;
|
||||||
@ -28,17 +33,35 @@ public class Commandmail extends EssentialsCommand {
|
|||||||
@Override
|
@Override
|
||||||
public void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
|
public void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
|
||||||
if (args.length >= 1 && "read".equalsIgnoreCase(args[0])) {
|
if (args.length >= 1 && "read".equalsIgnoreCase(args[0])) {
|
||||||
final List<String> mail = user.getMails();
|
final ArrayList<MailMessage> mail = user.getMailMessages();
|
||||||
if (mail.isEmpty()) {
|
if (mail == null || mail.size() == 0) {
|
||||||
|
user.sendMessage(tl("noMail"));
|
||||||
|
throw new NoChargeException();
|
||||||
|
}
|
||||||
|
|
||||||
|
final SimpleTextInput input = new SimpleTextInput();
|
||||||
|
final ListIterator<MailMessage> iterator = mail.listIterator();
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
final MailMessage mailObj = iterator.next();
|
||||||
|
if (mailObj.isExpired()) {
|
||||||
|
iterator.remove();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
input.addLine(ess.getMail().getMailLine(mailObj));
|
||||||
|
iterator.set(new MailMessage(true, mailObj.isLegacy(), mailObj.getSenderUsername(),
|
||||||
|
mailObj.getSenderUUID(), mailObj.getTimeSent(), mailObj.getTimeExpire(), mailObj.getMessage()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (input.getLines().isEmpty()) {
|
||||||
user.sendMessage(tl("noMail"));
|
user.sendMessage(tl("noMail"));
|
||||||
throw new NoChargeException();
|
throw new NoChargeException();
|
||||||
}
|
}
|
||||||
|
|
||||||
final IText input = new SimpleTextInput(mail);
|
|
||||||
final TextPager pager = new TextPager(input);
|
final TextPager pager = new TextPager(input);
|
||||||
pager.showPage(args.length > 1 ? args[1] : null, null, commandLabel + " " + args[0], user.getSource());
|
pager.showPage(args.length > 1 ? args[1] : null, null, commandLabel + " " + args[0], user.getSource());
|
||||||
|
|
||||||
user.sendMessage(tl("mailClear"));
|
user.sendMessage(tl("mailClear"));
|
||||||
|
user.setMailList(mail);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (args.length >= 3 && "send".equalsIgnoreCase(args[0])) {
|
if (args.length >= 3 && "send".equalsIgnoreCase(args[0])) {
|
||||||
@ -61,8 +84,8 @@ public class Commandmail extends EssentialsCommand {
|
|||||||
throw new Exception(tl("playerNeverOnServer", args[1]));
|
throw new Exception(tl("playerNeverOnServer", args[1]));
|
||||||
}
|
}
|
||||||
|
|
||||||
final String mail = tl("mailFormat", user.getName(), FormatUtil.formatMessage(user, "essentials.mail", StringUtil.sanitizeString(FormatUtil.stripFormat(getFinalArg(args, 2)))));
|
final String msg = FormatUtil.formatMessage(user, "essentials.mail", StringUtil.sanitizeString(FormatUtil.stripFormat(getFinalArg(args, 2))));
|
||||||
if (mail.length() > 1000) {
|
if (msg.length() > 1000) {
|
||||||
throw new Exception(tl("mailTooLong"));
|
throw new Exception(tl("mailTooLong"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,29 +98,87 @@ public class Commandmail extends EssentialsCommand {
|
|||||||
if (mailsPerMinute > ess.getSettings().getMailsPerMinute()) {
|
if (mailsPerMinute > ess.getSettings().getMailsPerMinute()) {
|
||||||
throw new Exception(tl("mailDelay", ess.getSettings().getMailsPerMinute()));
|
throw new Exception(tl("mailDelay", ess.getSettings().getMailsPerMinute()));
|
||||||
}
|
}
|
||||||
u.addMail(tl("mailMessage", mail));
|
u.sendMail(user, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
user.sendMessage(tl("mailSentTo", u.getDisplayName(), u.getName()));
|
user.sendMessage(tl("mailSentTo", u.getDisplayName(), u.getName()));
|
||||||
user.sendMessage(mail);
|
user.sendMessage(msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (args.length >= 4 && "sendtemp".equalsIgnoreCase(args[0])) {
|
||||||
|
if (!user.isAuthorized("essentials.mail.sendtemp")) {
|
||||||
|
throw new Exception(tl("noPerm", "essentials.mail.sendtemp"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (user.isMuted()) {
|
||||||
|
final String dateDiff = user.getMuteTimeout() > 0 ? DateUtil.formatDateDiff(user.getMuteTimeout()) : null;
|
||||||
|
if (dateDiff == null) {
|
||||||
|
throw new Exception(user.hasMuteReason() ? tl("voiceSilencedReason", user.getMuteReason()) : tl("voiceSilenced"));
|
||||||
|
}
|
||||||
|
throw new Exception(user.hasMuteReason() ? tl("voiceSilencedReasonTime", dateDiff, user.getMuteReason()) : tl("voiceSilencedTime", dateDiff));
|
||||||
|
}
|
||||||
|
|
||||||
|
final User u;
|
||||||
|
try {
|
||||||
|
u = getPlayer(server, args[1], true, true);
|
||||||
|
} catch (final PlayerNotFoundException e) {
|
||||||
|
throw new Exception(tl("playerNeverOnServer", args[1]));
|
||||||
|
}
|
||||||
|
|
||||||
|
final long dateDiff = DateUtil.parseDateDiff(args[2], true);
|
||||||
|
|
||||||
|
final String msg = FormatUtil.formatMessage(user, "essentials.mail", StringUtil.sanitizeString(FormatUtil.stripFormat(getFinalArg(args, 3))));
|
||||||
|
if (msg.length() > 1000) {
|
||||||
|
throw new Exception(tl("mailTooLong"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!u.isIgnoredPlayer(user)) {
|
||||||
|
if (Math.abs(System.currentTimeMillis() - timestamp) > 60000) {
|
||||||
|
timestamp = System.currentTimeMillis();
|
||||||
|
mailsPerMinute = 0;
|
||||||
|
}
|
||||||
|
mailsPerMinute++;
|
||||||
|
if (mailsPerMinute > ess.getSettings().getMailsPerMinute()) {
|
||||||
|
throw new Exception(tl("mailDelay", ess.getSettings().getMailsPerMinute()));
|
||||||
|
}
|
||||||
|
u.sendMail(user, msg, dateDiff);
|
||||||
|
}
|
||||||
|
|
||||||
|
user.sendMessage(tl("mailSentToExpire", u.getDisplayName(), DateUtil.formatDateDiff(dateDiff), u.getName()));
|
||||||
|
user.sendMessage(msg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (args.length > 1 && "sendall".equalsIgnoreCase(args[0])) {
|
if (args.length > 1 && "sendall".equalsIgnoreCase(args[0])) {
|
||||||
if (!user.isAuthorized("essentials.mail.sendall")) {
|
if (!user.isAuthorized("essentials.mail.sendall")) {
|
||||||
throw new Exception(tl("noPerm", "essentials.mail.sendall"));
|
throw new Exception(tl("noPerm", "essentials.mail.sendall"));
|
||||||
}
|
}
|
||||||
ess.runTaskAsynchronously(new SendAll(tl("mailFormat", user.getName(),
|
ess.runTaskAsynchronously(new SendAll(user, FormatUtil.formatMessage(user, "essentials.mail", StringUtil.sanitizeString(FormatUtil.stripFormat(getFinalArg(args, 1))))));
|
||||||
FormatUtil.formatMessage(user, "essentials.mail", StringUtil.sanitizeString(FormatUtil.stripFormat(getFinalArg(args, 1)))))));
|
|
||||||
user.sendMessage(tl("mailSent"));
|
user.sendMessage(tl("mailSent"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (args.length >= 1 && "clear".equalsIgnoreCase(args[0])) {
|
if (args.length >= 1 && "clear".equalsIgnoreCase(args[0])) {
|
||||||
if (user.getMails() == null || user.getMails().isEmpty()) {
|
final ArrayList<MailMessage> mails = user.getMailMessages();
|
||||||
|
if (mails == null || mails.size() == 0) {
|
||||||
user.sendMessage(tl("noMail"));
|
user.sendMessage(tl("noMail"));
|
||||||
throw new NoChargeException();
|
throw new NoChargeException();
|
||||||
}
|
}
|
||||||
|
|
||||||
user.setMails(null);
|
if (args.length > 1) {
|
||||||
|
if (!NumberUtil.isPositiveInt(args[1])) {
|
||||||
|
throw new NotEnoughArgumentsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
final int toRemove = Integer.parseInt(args[1]);
|
||||||
|
if (toRemove > mails.size()) {
|
||||||
|
user.sendMessage(tl("mailClearIndex", mails.size()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mails.remove(toRemove - 1);
|
||||||
|
user.setMailList(mails);
|
||||||
|
} else {
|
||||||
|
user.setMailList(null);
|
||||||
|
}
|
||||||
|
|
||||||
user.sendMessage(tl("mailCleared"));
|
user.sendMessage(tl("mailCleared"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -117,11 +198,22 @@ public class Commandmail extends EssentialsCommand {
|
|||||||
} catch (final PlayerNotFoundException e) {
|
} catch (final PlayerNotFoundException e) {
|
||||||
throw new Exception(tl("playerNeverOnServer", args[1]));
|
throw new Exception(tl("playerNeverOnServer", args[1]));
|
||||||
}
|
}
|
||||||
u.addMail(tl("mailFormat", "Server", FormatUtil.replaceFormat(getFinalArg(args, 2))));
|
u.sendMail(Console.getInstance(), FormatUtil.replaceFormat(getFinalArg(args, 2)));
|
||||||
|
sender.sendMessage(tl("mailSent"));
|
||||||
|
return;
|
||||||
|
} else if (args.length >= 4 && "sendtemp".equalsIgnoreCase(args[0])) {
|
||||||
|
final User u;
|
||||||
|
try {
|
||||||
|
u = getPlayer(server, args[1], true, true);
|
||||||
|
} catch (final PlayerNotFoundException e) {
|
||||||
|
throw new Exception(tl("playerNeverOnServer", args[1]));
|
||||||
|
}
|
||||||
|
final long dateDiff = DateUtil.parseDateDiff(args[2], true);
|
||||||
|
u.sendMail(Console.getInstance(), FormatUtil.replaceFormat(getFinalArg(args, 3)), dateDiff);
|
||||||
sender.sendMessage(tl("mailSent"));
|
sender.sendMessage(tl("mailSent"));
|
||||||
return;
|
return;
|
||||||
} else if (args.length >= 2 && "sendall".equalsIgnoreCase(args[0])) {
|
} else if (args.length >= 2 && "sendall".equalsIgnoreCase(args[0])) {
|
||||||
ess.runTaskAsynchronously(new SendAll(tl("mailFormat", "Server", FormatUtil.replaceFormat(getFinalArg(args, 1)))));
|
ess.runTaskAsynchronously(new SendAll(Console.getInstance(), FormatUtil.replaceFormat(getFinalArg(args, 1))));
|
||||||
sender.sendMessage(tl("mailSent"));
|
sender.sendMessage(tl("mailSent"));
|
||||||
return;
|
return;
|
||||||
} else if (args.length >= 2) {
|
} else if (args.length >= 2) {
|
||||||
@ -132,13 +224,33 @@ public class Commandmail extends EssentialsCommand {
|
|||||||
} catch (final PlayerNotFoundException e) {
|
} catch (final PlayerNotFoundException e) {
|
||||||
throw new Exception(tl("playerNeverOnServer", args[0]));
|
throw new Exception(tl("playerNeverOnServer", args[0]));
|
||||||
}
|
}
|
||||||
u.addMail(tl("mailFormat", "Server", FormatUtil.replaceFormat(getFinalArg(args, 1))));
|
u.sendMail(Console.getInstance(), FormatUtil.replaceFormat(getFinalArg(args, 1)));
|
||||||
sender.sendMessage(tl("mailSent"));
|
sender.sendMessage(tl("mailSent"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
throw new NotEnoughArgumentsException();
|
throw new NotEnoughArgumentsException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class SendAll implements Runnable {
|
||||||
|
IMessageRecipient messageRecipient;
|
||||||
|
String message;
|
||||||
|
|
||||||
|
SendAll(IMessageRecipient messageRecipient, String message) {
|
||||||
|
this.messageRecipient = messageRecipient;
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
for (UUID userid : ess.getUserMap().getAllUniqueUsers()) {
|
||||||
|
final User user = ess.getUserMap().getUser(userid);
|
||||||
|
if (user != null) {
|
||||||
|
user.sendMail(messageRecipient, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<String> getTabCompleteOptions(final Server server, final User user, final String commandLabel, final String[] args) {
|
protected List<String> getTabCompleteOptions(final Server server, final User user, final String commandLabel, final String[] args) {
|
||||||
if (args.length == 1) {
|
if (args.length == 1) {
|
||||||
@ -146,15 +258,18 @@ public class Commandmail extends EssentialsCommand {
|
|||||||
if (user.isAuthorized("essentials.mail.send")) {
|
if (user.isAuthorized("essentials.mail.send")) {
|
||||||
options.add("send");
|
options.add("send");
|
||||||
}
|
}
|
||||||
|
if (user.isAuthorized("essentials.mail.sendtemp")) {
|
||||||
|
options.add("sendtemp");
|
||||||
|
}
|
||||||
if (user.isAuthorized("essentials.mail.sendall")) {
|
if (user.isAuthorized("essentials.mail.sendall")) {
|
||||||
options.add("sendall");
|
options.add("sendall");
|
||||||
}
|
}
|
||||||
return options;
|
return options;
|
||||||
} else if (args.length == 2 && args[0].equalsIgnoreCase("send") && user.isAuthorized("essentials.mail.send")) {
|
} else if (args.length == 2 && ((args[0].equalsIgnoreCase("send") && user.isAuthorized("essentials.mail.send")) || (args[0].equalsIgnoreCase("sendtemp") && user.isAuthorized("essentials.mail.sendtemp")))) {
|
||||||
return getPlayers(server, user);
|
return getPlayers(server, user);
|
||||||
} else if (args.length == 2 && args[0].equalsIgnoreCase("read")) {
|
} else if (args.length == 2 && args[0].equalsIgnoreCase("read")) {
|
||||||
final List<String> mail = user.getMails();
|
final ArrayList<MailMessage> mail = user.getMailMessages();
|
||||||
final int pages = mail.size() / 9 + (mail.size() % 9 > 0 ? 1 : 0);
|
final int pages = mail != null ? (mail.size() / 9 + (mail.size() % 9 > 0 ? 1 : 0)) : 0;
|
||||||
if (pages == 0) {
|
if (pages == 0) {
|
||||||
return Lists.newArrayList("0");
|
return Lists.newArrayList("0");
|
||||||
} else {
|
} else {
|
||||||
@ -164,8 +279,8 @@ public class Commandmail extends EssentialsCommand {
|
|||||||
}
|
}
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
} else if ((args.length > 2 && args[0].equalsIgnoreCase("send") && user.isAuthorized("essentials.mail.send")) || (args.length > 1 && args[0].equalsIgnoreCase("sendall") && user.isAuthorized("essentials.mail.sendall"))) {
|
} else if (args.length == 3 && args[0].equalsIgnoreCase("sendtemp") && user.isAuthorized("essentials.mail.sendtemp")) {
|
||||||
return null; // Use vanilla handler
|
return COMMON_DATE_DIFFS;
|
||||||
} else {
|
} else {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
@ -175,30 +290,14 @@ public class Commandmail extends EssentialsCommand {
|
|||||||
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
|
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
|
||||||
if (args.length == 1) {
|
if (args.length == 1) {
|
||||||
return Lists.newArrayList("send", "sendall");
|
return Lists.newArrayList("send", "sendall");
|
||||||
} else if (args.length == 2 && args[0].equalsIgnoreCase("send")) {
|
} else if (args.length == 2 && (args[0].equalsIgnoreCase("send") || args[0].equalsIgnoreCase("sendtemp"))) {
|
||||||
return getPlayers(server, sender);
|
return getPlayers(server, sender);
|
||||||
|
} else if (args.length == 3 && args[0].equalsIgnoreCase("sentemp")) {
|
||||||
|
return COMMON_DATE_DIFFS;
|
||||||
} else if ((args.length > 2 && args[0].equalsIgnoreCase("send")) || (args.length > 1 && args[0].equalsIgnoreCase("sendall"))) {
|
} else if ((args.length > 2 && args[0].equalsIgnoreCase("send")) || (args.length > 1 && args[0].equalsIgnoreCase("sendall"))) {
|
||||||
return null; // Use vanilla handler
|
return null; // Use vanilla handler
|
||||||
} else {
|
} else {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class SendAll implements Runnable {
|
|
||||||
final String message;
|
|
||||||
|
|
||||||
SendAll(final String message) {
|
|
||||||
this.message = message;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
for (final UUID userid : ess.getUserMap().getAllUniqueUsers()) {
|
|
||||||
final User user = ess.getUserMap().getUser(userid);
|
|
||||||
if (user != null) {
|
|
||||||
user.addMail(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -9,8 +9,10 @@ import com.earth2me.essentials.config.processors.DeleteOnEmptyProcessor;
|
|||||||
import com.earth2me.essentials.config.serializers.BigDecimalTypeSerializer;
|
import com.earth2me.essentials.config.serializers.BigDecimalTypeSerializer;
|
||||||
import com.earth2me.essentials.config.serializers.CommandCooldownSerializer;
|
import com.earth2me.essentials.config.serializers.CommandCooldownSerializer;
|
||||||
import com.earth2me.essentials.config.serializers.LocationTypeSerializer;
|
import com.earth2me.essentials.config.serializers.LocationTypeSerializer;
|
||||||
|
import com.earth2me.essentials.config.serializers.MailMessageSerializer;
|
||||||
import com.earth2me.essentials.config.serializers.MaterialTypeSerializer;
|
import com.earth2me.essentials.config.serializers.MaterialTypeSerializer;
|
||||||
import net.ess3.api.InvalidWorldException;
|
import net.ess3.api.InvalidWorldException;
|
||||||
|
import net.essentialsx.api.v2.services.mail.MailMessage;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.spongepowered.configurate.CommentedConfigurationNode;
|
import org.spongepowered.configurate.CommentedConfigurationNode;
|
||||||
@ -26,6 +28,7 @@ import org.spongepowered.configurate.yaml.YamlConfigurationLoader;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -58,6 +61,7 @@ public class EssentialsConfiguration {
|
|||||||
.register(LazyLocation.class, new LocationTypeSerializer())
|
.register(LazyLocation.class, new LocationTypeSerializer())
|
||||||
.register(Material.class, new MaterialTypeSerializer())
|
.register(Material.class, new MaterialTypeSerializer())
|
||||||
.register(CommandCooldown.class, new CommandCooldownSerializer())
|
.register(CommandCooldown.class, new CommandCooldownSerializer())
|
||||||
|
.register(MailMessage.class, new MailMessageSerializer())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
private final AtomicInteger pendingWrites = new AtomicInteger(0);
|
private final AtomicInteger pendingWrites = new AtomicInteger(0);
|
||||||
@ -139,6 +143,14 @@ public class EssentialsConfiguration {
|
|||||||
setInternal(path, list);
|
setInternal(path, list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public <T> void setExplicitList(final String path, final List<T> list, final Type type) {
|
||||||
|
try {
|
||||||
|
toSplitRoot(path, configurationNode).set(type, list);
|
||||||
|
} catch (SerializationException e) {
|
||||||
|
LOGGER.log(Level.SEVERE, e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public <T> List<T> getList(final String path, Class<T> type) {
|
public <T> List<T> getList(final String path, Class<T> type) {
|
||||||
final CommentedConfigurationNode node = getInternal(path);
|
final CommentedConfigurationNode node = getInternal(path);
|
||||||
if (node == null) {
|
if (node == null) {
|
||||||
|
@ -4,6 +4,7 @@ import com.earth2me.essentials.config.annotations.DeleteIfIncomplete;
|
|||||||
import com.earth2me.essentials.config.annotations.DeleteOnEmpty;
|
import com.earth2me.essentials.config.annotations.DeleteOnEmpty;
|
||||||
import com.earth2me.essentials.config.entities.CommandCooldown;
|
import com.earth2me.essentials.config.entities.CommandCooldown;
|
||||||
import com.earth2me.essentials.config.entities.LazyLocation;
|
import com.earth2me.essentials.config.entities.LazyLocation;
|
||||||
|
import net.essentialsx.api.v2.services.mail.MailMessage;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||||
@ -113,16 +114,16 @@ public class UserConfigHolder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@DeleteOnEmpty
|
@DeleteOnEmpty
|
||||||
private @MonotonicNonNull List<String> mail;
|
private @MonotonicNonNull ArrayList<MailMessage> mail;
|
||||||
|
|
||||||
public List<String> mail() {
|
public ArrayList<MailMessage> mail() {
|
||||||
if (this.mail == null) {
|
if (this.mail == null) {
|
||||||
this.mail = new ArrayList<>();
|
this.mail = new ArrayList<>();
|
||||||
}
|
}
|
||||||
return this.mail;
|
return this.mail;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void mail(final List<String> value) {
|
public void mail(final ArrayList<MailMessage> value) {
|
||||||
this.mail = value;
|
this.mail = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,44 @@
|
|||||||
|
package com.earth2me.essentials.config.serializers;
|
||||||
|
|
||||||
|
import net.essentialsx.api.v2.services.mail.MailMessage;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
import org.spongepowered.configurate.ConfigurationNode;
|
||||||
|
import org.spongepowered.configurate.serialize.SerializationException;
|
||||||
|
import org.spongepowered.configurate.serialize.TypeSerializer;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class MailMessageSerializer implements TypeSerializer<MailMessage> {
|
||||||
|
@Override
|
||||||
|
public MailMessage deserialize(Type type, ConfigurationNode node) throws SerializationException {
|
||||||
|
final boolean legacy = !node.node("legacy").isNull() && node.node("legacy").getBoolean(false);
|
||||||
|
|
||||||
|
return new MailMessage(node.node("read").getBoolean(false),
|
||||||
|
legacy,
|
||||||
|
!legacy ? node.node("sender-name").getString() : null,
|
||||||
|
!legacy ? UUID.fromString(Objects.requireNonNull(node.node("sender-uuid").getString())) : null,
|
||||||
|
!legacy ? node.node("timestamp").getLong() : 0L,
|
||||||
|
!legacy ? node.node("expire").getLong() : 0L,
|
||||||
|
node.node("message").getString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void serialize(Type type, @Nullable MailMessage obj, ConfigurationNode node) throws SerializationException {
|
||||||
|
if (obj == null) {
|
||||||
|
node.raw(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
node.node("legacy").set(Boolean.class, obj.isLegacy());
|
||||||
|
node.node("read").set(Boolean.class, obj.isRead());
|
||||||
|
node.node("message").set(String.class, obj.getMessage());
|
||||||
|
if (!obj.isLegacy()) {
|
||||||
|
node.node("sender-name").set(String.class, obj.getSenderUsername());
|
||||||
|
node.node("sender-uuid").set(String.class, obj.getSenderUUID().toString());
|
||||||
|
node.node("timestamp").set(Long.class, obj.getTimeSent());
|
||||||
|
node.node("expire").set(Long.class, obj.getTimeExpire());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,11 +1,12 @@
|
|||||||
package com.earth2me.essentials.messaging;
|
package com.earth2me.essentials.messaging;
|
||||||
|
|
||||||
|
import net.essentialsx.api.v2.services.mail.MailSender;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents an interface for message recipients.
|
* Represents an interface for message recipients.
|
||||||
*/
|
*/
|
||||||
public interface IMessageRecipient {
|
public interface IMessageRecipient extends MailSender {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends (prints) a message to this recipient.
|
* Sends (prints) a message to this recipient.
|
||||||
|
@ -8,6 +8,7 @@ import net.ess3.api.events.PrivateMessageSentEvent;
|
|||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
import static com.earth2me.essentials.I18n.tl;
|
import static com.earth2me.essentials.I18n.tl;
|
||||||
|
|
||||||
@ -60,6 +61,11 @@ public class SimpleMessageRecipient implements IMessageRecipient {
|
|||||||
return this.parent.getName();
|
return this.parent.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UUID getUUID() {
|
||||||
|
return this.parent.getUUID();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getDisplayName() {
|
public String getDisplayName() {
|
||||||
return this.parent.getDisplayName();
|
return this.parent.getDisplayName();
|
||||||
|
@ -2,8 +2,10 @@ package com.earth2me.essentials.signs;
|
|||||||
|
|
||||||
import com.earth2me.essentials.User;
|
import com.earth2me.essentials.User;
|
||||||
import net.ess3.api.IEssentials;
|
import net.ess3.api.IEssentials;
|
||||||
|
import net.essentialsx.api.v2.services.mail.MailMessage;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.ArrayList;
|
||||||
|
import java.util.ListIterator;
|
||||||
|
|
||||||
import static com.earth2me.essentials.I18n.tl;
|
import static com.earth2me.essentials.I18n.tl;
|
||||||
|
|
||||||
@ -14,14 +16,28 @@ public class SignMail extends EssentialsSign {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean onSignInteract(final ISign sign, final User player, final String username, final IEssentials ess) throws SignException {
|
protected boolean onSignInteract(final ISign sign, final User player, final String username, final IEssentials ess) throws SignException {
|
||||||
final List<String> mail = player.getMails();
|
final ArrayList<MailMessage> mail = player.getMailMessages();
|
||||||
if (mail.isEmpty()) {
|
|
||||||
|
final ListIterator<MailMessage> iterator = mail.listIterator();
|
||||||
|
boolean hadMail = false;
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
final MailMessage mailObj = iterator.next();
|
||||||
|
if (mailObj.isExpired()) {
|
||||||
|
iterator.remove();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
hadMail = true;
|
||||||
|
player.sendMessage(ess.getMail().getMailLine(mailObj));
|
||||||
|
iterator.set(new MailMessage(true, mailObj.isLegacy(), mailObj.getSenderUsername(),
|
||||||
|
mailObj.getSenderUUID(), mailObj.getTimeSent(), mailObj.getTimeExpire(), mailObj.getMessage()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hadMail) {
|
||||||
player.sendMessage(tl("noNewMail"));
|
player.sendMessage(tl("noNewMail"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (final String s : mail) {
|
player.setMailList(mail);
|
||||||
player.sendMessage(s);
|
|
||||||
}
|
|
||||||
player.sendMessage(tl("markMailAsRead"));
|
player.sendMessage(tl("markMailAsRead"));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -227,7 +227,7 @@ public class KeywordReplacer implements IText {
|
|||||||
break;
|
break;
|
||||||
case MAILS:
|
case MAILS:
|
||||||
if (user != null) {
|
if (user != null) {
|
||||||
replacer = Integer.toString(user.getMails().size());
|
replacer = Integer.toString(user.getMailAmount());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PLAYTIME:
|
case PLAYTIME:
|
||||||
|
@ -20,6 +20,10 @@ public class SimpleTextInput implements IText {
|
|||||||
public SimpleTextInput() {
|
public SimpleTextInput() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addLine(String line) {
|
||||||
|
lines.add(line);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> getLines() {
|
public List<String> getLines() {
|
||||||
return lines;
|
return lines;
|
||||||
|
@ -0,0 +1,98 @@
|
|||||||
|
package net.essentialsx.api.v2.services.mail;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An immutable representation of a message sent as mail.
|
||||||
|
*/
|
||||||
|
public class MailMessage {
|
||||||
|
private final boolean read;
|
||||||
|
private final boolean legacy;
|
||||||
|
private final String senderName;
|
||||||
|
private final UUID senderId;
|
||||||
|
private final long timestamp;
|
||||||
|
private final long expire;
|
||||||
|
private final String message;
|
||||||
|
|
||||||
|
public MailMessage(boolean read, boolean legacy, String sender, UUID uuid, long timestamp, long expire, String message) {
|
||||||
|
this.read = read;
|
||||||
|
this.legacy = legacy;
|
||||||
|
this.senderName = sender;
|
||||||
|
this.senderId = uuid;
|
||||||
|
this.timestamp = timestamp;
|
||||||
|
this.expire = expire;
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if this message has been read by its recipient yet.
|
||||||
|
* @return true if this message has been read.
|
||||||
|
*/
|
||||||
|
public boolean isRead() {
|
||||||
|
return read;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if this message was created via legacy api or converted from legacy format.
|
||||||
|
*
|
||||||
|
* A legacy messages only contains data for the read state and message.
|
||||||
|
* @see #isRead()
|
||||||
|
* @see #getMessage()
|
||||||
|
* @return true if this message is a legacy message.
|
||||||
|
*/
|
||||||
|
public boolean isLegacy() {
|
||||||
|
return legacy;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the sender's username at the time of sending the message.
|
||||||
|
* @return The sender's username.
|
||||||
|
*/
|
||||||
|
public String getSenderUsername() {
|
||||||
|
return senderName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the sender's {@link UUID} or null if the sender does not have a UUID.
|
||||||
|
* @return The sender's {@link UUID} or null.
|
||||||
|
*/
|
||||||
|
public UUID getSenderUUID() {
|
||||||
|
return senderId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the millisecond epoch time when the message was sent.
|
||||||
|
* @return The epoch time when message was sent.
|
||||||
|
*/
|
||||||
|
public long getTimeSent() {
|
||||||
|
return timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the millisecond epoch at which this message will expire and no longer been shown to the user.
|
||||||
|
* @return The epoch time when the message will expire.
|
||||||
|
*/
|
||||||
|
public long getTimeExpire() {
|
||||||
|
return expire;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the message content for normal mail or the entire mail format for legacy mail.
|
||||||
|
* @see #isLegacy()
|
||||||
|
* @return The mail content or format.
|
||||||
|
*/
|
||||||
|
public String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to check if this mail has expired and should not been shown to the recipient.
|
||||||
|
* @return true if this mail has expired.
|
||||||
|
*/
|
||||||
|
public boolean isExpired() {
|
||||||
|
if (getTimeExpire() == 0L) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return System.currentTimeMillis() >= getTimeExpire();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
package net.essentialsx.api.v2.services.mail;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An entity which is allowed to send mail to an {@link net.ess3.api.IUser IUser}.
|
||||||
|
*
|
||||||
|
* In Essentials, IUser and Console are the entities that implement this interface.
|
||||||
|
*/
|
||||||
|
public interface MailSender {
|
||||||
|
/**
|
||||||
|
* Gets the username of this {@link MailSender}.
|
||||||
|
* @return The sender's username.
|
||||||
|
*/
|
||||||
|
String getName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the {@link UUID} of this {@link MailSender} or null if this sender doesn't have a UUID.
|
||||||
|
* @return The sender's {@link UUID} or null if N/A.
|
||||||
|
*/
|
||||||
|
UUID getUUID();
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
package net.essentialsx.api.v2.services.mail;
|
||||||
|
|
||||||
|
import net.ess3.api.IUser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This interface provides access to core Essentials mailing functions, allowing API users to send messages to {@link IUser IUser's }.
|
||||||
|
*/
|
||||||
|
public interface MailService {
|
||||||
|
/**
|
||||||
|
* Sends a message from the specified {@link MailSender sender} to the specified {@link IUser recipient}.
|
||||||
|
* @param recipient The {@link IUser} which to send the message to.
|
||||||
|
* @param sender The {@link MailSender} which sent the message.
|
||||||
|
* @param message The message content.
|
||||||
|
*/
|
||||||
|
void sendMail(IUser recipient, MailSender sender, String message);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a message from the specified {@link MailSender sender} to the specified {@link IUser recipient}.
|
||||||
|
* @param recipient The {@link IUser} which to send the message to.
|
||||||
|
* @param sender The {@link MailSender} which sent the message.
|
||||||
|
* @param message The message content.
|
||||||
|
* @param expireAt The millisecond epoch at which this message expires, or 0 if the message doesn't expire.
|
||||||
|
*/
|
||||||
|
void sendMail(IUser recipient, MailSender sender, String message, long expireAt);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a legacy message to the user without any advanced features.
|
||||||
|
* @param recipient The {@link IUser} which to send the message to.
|
||||||
|
* @param message The message content.
|
||||||
|
* @see #sendMail(IUser, MailSender, String)
|
||||||
|
* @see #sendMail(IUser, MailSender, String, long)
|
||||||
|
* @deprecated This is only for maintaining backwards compatibility with old API, please use the newer {@link #sendMail(IUser, MailSender, String)} API.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
void sendLegacyMail(IUser recipient, String message);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates the message sent to the recipient of the given {@link MailMessage}.
|
||||||
|
* @param message The {@link MailMessage} to generate the message for.
|
||||||
|
* @return The formatted message to be sent to the recipient.
|
||||||
|
*/
|
||||||
|
String getMailLine(MailMessage message);
|
||||||
|
}
|
@ -647,21 +647,29 @@ loomCommandDescription=Opens up a loom.
|
|||||||
loomCommandUsage=/<command>
|
loomCommandUsage=/<command>
|
||||||
mailClear=\u00a76To clear your mail, type\u00a7c /mail clear\u00a76.
|
mailClear=\u00a76To clear your mail, type\u00a7c /mail clear\u00a76.
|
||||||
mailCleared=\u00a76Mail cleared\!
|
mailCleared=\u00a76Mail cleared\!
|
||||||
|
mailClearIndex=\u00a74You must specify a number between 1-{0}.
|
||||||
mailCommandDescription=Manages inter-player, intra-server mail.
|
mailCommandDescription=Manages inter-player, intra-server mail.
|
||||||
mailCommandUsage=/<command> [read|clear|send [to] [message]|sendall [message]]
|
mailCommandUsage=/<command> [read|clear|clear [number]|send [to] [message]|sendtemp [to] [expire time] [message]|sendall [message]]
|
||||||
mailCommandUsage1=/<command> read [page]
|
mailCommandUsage1=/<command> read [page]
|
||||||
mailCommandUsage1Description=Reads the first (or specified) page of your mail
|
mailCommandUsage1Description=Reads the first (or specified) page of your mail
|
||||||
mailCommandUsage2=/<command> clear
|
mailCommandUsage2=/<command> clear [number]
|
||||||
mailCommandUsage2Description=Clears your mail
|
mailCommandUsage2Description=Clears either all or the specified mail(s)
|
||||||
mailCommandUsage3=/<command> send <player> <message>
|
mailCommandUsage3=/<command> send <player> <message>
|
||||||
mailCommandUsage3Description=Sends the specified player the given message
|
mailCommandUsage3Description=Sends the specified player the given message
|
||||||
mailCommandUsage4=/<command> sendall <message>
|
mailCommandUsage4=/<command> sendall <message>
|
||||||
mailCommandUsage4Description=Sends all players the given message
|
mailCommandUsage4Description=Sends all players the given message
|
||||||
|
mailCommandUsage5=/<command> sendtemp <player> <expire time> <message>
|
||||||
|
mailCommandUsage5Description=Sends the specified player the given message which will expire in the specified time
|
||||||
mailDelay=Too many mails have been sent within the last minute. Maximum\: {0}
|
mailDelay=Too many mails have been sent within the last minute. Maximum\: {0}
|
||||||
|
mailFormatNew=\u00a76[\u00a7r{0}\u00a76] \u00a76[\u00a7r{1}\u00a76] \u00a7r{2}
|
||||||
|
mailFormatNewTimed=\u00a76[\u00a7e\u26a0\u00a76] \u00a76[\u00a7r{0}\u00a76] \u00a76[\u00a7r{1}\u00a76] \u00a7r{2}
|
||||||
|
mailFormatNewRead=\u00a76[\u00a7r{0}\u00a76] \u00a76[\u00a7r{1}\u00a76] \u00a77\u00a7o{2}
|
||||||
|
mailFormatNewReadTimed=\u00a76[\u00a7e\u26a0\u00a76] \u00a76[\u00a7r{0}\u00a76] \u00a76[\u00a7r{1}\u00a76] \u00a77\u00a7o{2}
|
||||||
mailFormat=\u00a76[\u00a7r{0}\u00a76] \u00a7r{1}
|
mailFormat=\u00a76[\u00a7r{0}\u00a76] \u00a7r{1}
|
||||||
mailMessage={0}
|
mailMessage={0}
|
||||||
mailSent=\u00a76Mail sent\!
|
mailSent=\u00a76Mail sent\!
|
||||||
mailSentTo=\u00a7c{0}\u00a76 has been sent the following mail\:
|
mailSentTo=\u00a7c{0}\u00a76 has been sent the following mail\:
|
||||||
|
mailSentToExpire=\u00a7c{0}\u00a76 has been sent the following mail which will expire in \u00a7c{1}\u00a76\:
|
||||||
mailTooLong=\u00a74Mail message too long. Try to keep it below 1000 characters.
|
mailTooLong=\u00a74Mail message too long. Try to keep it below 1000 characters.
|
||||||
markMailAsRead=\u00a76To mark your mail as read, type\u00a7c /mail clear\u00a76.
|
markMailAsRead=\u00a76To mark your mail as read, type\u00a7c /mail clear\u00a76.
|
||||||
matchingIPAddress=\u00a76The following players previously logged in from that IP address\:
|
matchingIPAddress=\u00a76The following players previously logged in from that IP address\:
|
||||||
|
@ -286,7 +286,7 @@ commands:
|
|||||||
aliases: [eloom]
|
aliases: [eloom]
|
||||||
mail:
|
mail:
|
||||||
description: Manages inter-player, intra-server mail.
|
description: Manages inter-player, intra-server mail.
|
||||||
usage: /<command> [read|clear|send [to] [message]|sendall [message]]
|
usage: /<command> [read|clear|clear [number]|send [to] [message]|sendtemp [to] [expire time] [message]|sendall [message]]
|
||||||
aliases: [email,eemail,memo,ememo]
|
aliases: [email,eemail,memo,ememo]
|
||||||
me:
|
me:
|
||||||
description: Describes an action in the context of the player.
|
description: Describes an action in the context of the player.
|
||||||
|
@ -5,6 +5,7 @@ import com.earth2me.essentials.utils.FormatUtil;
|
|||||||
import net.essentialsx.api.v2.services.discord.InteractionMember;
|
import net.essentialsx.api.v2.services.discord.InteractionMember;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
import static com.earth2me.essentials.I18n.tl;
|
import static com.earth2me.essentials.I18n.tl;
|
||||||
@ -48,6 +49,11 @@ public class DiscordMessageRecipient implements IMessageRecipient {
|
|||||||
return member.getTag();
|
return member.getTag();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UUID getUUID() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getDisplayName() {
|
public String getDisplayName() {
|
||||||
return member.getTag();
|
return member.getTag();
|
||||||
|
Loading…
Reference in New Issue
Block a user