mirror of
https://github.com/EssentialsX/Essentials.git
synced 2024-12-22 17:18:37 +01:00
Merge remote-tracking branch 'upstream/2.x' into refactor/folia
# Conflicts: # Essentials/src/main/java/com/earth2me/essentials/commands/Commandskull.java
This commit is contained in:
commit
d0493ccd2a
@ -958,17 +958,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
|||||||
//This will return null if there is not a match.
|
//This will return null if there is not a match.
|
||||||
@Override
|
@Override
|
||||||
public User getOfflineUser(final String name) {
|
public User getOfflineUser(final String name) {
|
||||||
final User user = userMap.getUser(name);
|
return userMap.getUser(name);
|
||||||
if (user != null && user.getBase() instanceof OfflinePlayerStub) {
|
|
||||||
//This code should attempt to use the last known name of a user, if Bukkit returns name as null.
|
|
||||||
final String lastName = user.getLastAccountName();
|
|
||||||
if (lastName != null) {
|
|
||||||
((OfflinePlayerStub) user.getBase()).setName(lastName);
|
|
||||||
} else {
|
|
||||||
((OfflinePlayerStub) user.getBase()).setName(name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return user;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -1056,7 +1046,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return interactor.getBase().canSee(interactee.getBase());
|
return !interactee.isHiddenFrom(interactor.getBase());
|
||||||
}
|
}
|
||||||
|
|
||||||
//This will create a new user if there is not a match.
|
//This will create a new user if there is not a match.
|
||||||
@ -1071,19 +1061,9 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
User user = userMap.getUser(base.getUniqueId());
|
final User user = userMap.getUser(base);
|
||||||
|
|
||||||
if (user == null) {
|
if (base.getClass() != UUIDPlayer.class || user.getBase() == null) {
|
||||||
if (getSettings().isDebug()) {
|
|
||||||
LOGGER.log(Level.INFO, "Constructing new userfile from base player " + base.getName());
|
|
||||||
}
|
|
||||||
user = userMap.loadUncachedUser(base);
|
|
||||||
|
|
||||||
// The above method will end up creating a new user, but it will not be added to the cache.
|
|
||||||
// Since we already call UserMap#getUser() above, we are already okay with adding the user to the cache,
|
|
||||||
// so we need to manually add the user to the cache in order to avoid a memory leak and maintain behavior.
|
|
||||||
userMap.addCachedUser(user);
|
|
||||||
} else if (base.getClass() != UUIDPlayer.class || user.getBase() == null) {
|
|
||||||
user.update(base);
|
user.update(base);
|
||||||
}
|
}
|
||||||
return user;
|
return user;
|
||||||
|
@ -963,7 +963,7 @@ public class EssentialsUpgrade {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uuids.put(uuid, config.getLong("timestamps.logout", 0L));
|
uuids.put(uuid, time);
|
||||||
nameToUuidMap.put(name, uuid);
|
nameToUuidMap.put(name, uuid);
|
||||||
}
|
}
|
||||||
} catch (IllegalArgumentException | IndexOutOfBoundsException ignored) {
|
} catch (IllegalArgumentException | IndexOutOfBoundsException ignored) {
|
||||||
|
@ -87,7 +87,7 @@ public class I18n implements net.ess3.api.II18n {
|
|||||||
return localeBundle.getString(string);
|
return localeBundle.getString(string);
|
||||||
}
|
}
|
||||||
} catch (final MissingResourceException ex) {
|
} catch (final MissingResourceException ex) {
|
||||||
if (ess == null || ess.getSettings().isDebug()) {
|
if (ess != null && ess.getSettings().isDebug()) {
|
||||||
ess.getLogger().log(Level.WARNING, String.format("Missing translation key \"%s\" in translation file %s", ex.getKey(), localeBundle.getLocale().toString()), ex);
|
ess.getLogger().log(Level.WARNING, String.format("Missing translation key \"%s\" in translation file %s", ex.getKey(), localeBundle.getLocale().toString()), ex);
|
||||||
}
|
}
|
||||||
return defaultBundle.getString(string);
|
return defaultBundle.getString(string);
|
||||||
|
@ -406,6 +406,8 @@ public interface ISettings extends IConf {
|
|||||||
|
|
||||||
boolean showZeroBaltop();
|
boolean showZeroBaltop();
|
||||||
|
|
||||||
|
int getMaxItemLore();
|
||||||
|
|
||||||
enum KeepInvPolicy {
|
enum KeepInvPolicy {
|
||||||
KEEP,
|
KEEP,
|
||||||
DELETE,
|
DELETE,
|
||||||
|
@ -206,6 +206,13 @@ public class MetaItemStack {
|
|||||||
final ItemMeta meta = stack.getItemMeta();
|
final ItemMeta meta = stack.getItemMeta();
|
||||||
meta.setLore(lore);
|
meta.setLore(lore);
|
||||||
stack.setItemMeta(meta);
|
stack.setItemMeta(meta);
|
||||||
|
} else if ((split[0].equalsIgnoreCase("custom-model-data") || split[0].equalsIgnoreCase("cmd")) && hasMetaPermission(sender, "custom-model-data", false, true, ess)) {
|
||||||
|
if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_14_R01)) {
|
||||||
|
final int value = split.length <= 1 ? 0 : Integer.parseInt(split[1]);
|
||||||
|
final ItemMeta meta = stack.getItemMeta();
|
||||||
|
meta.setCustomModelData(value);
|
||||||
|
stack.setItemMeta(meta);
|
||||||
|
}
|
||||||
} else if (split[0].equalsIgnoreCase("unbreakable") && hasMetaPermission(sender, "unbreakable", false, true, ess)) {
|
} else if (split[0].equalsIgnoreCase("unbreakable") && hasMetaPermission(sender, "unbreakable", false, true, ess)) {
|
||||||
final boolean value = split.length <= 1 || Boolean.parseBoolean(split[1]);
|
final boolean value = split.length <= 1 || Boolean.parseBoolean(split[1]);
|
||||||
setUnbreakable(ess, stack, value);
|
setUnbreakable(ess, stack, value);
|
||||||
@ -216,11 +223,21 @@ public class MetaItemStack {
|
|||||||
} else {
|
} else {
|
||||||
throw new Exception(tl("onlyPlayerSkulls"));
|
throw new Exception(tl("onlyPlayerSkulls"));
|
||||||
}
|
}
|
||||||
} else if (split.length > 1 && split[0].equalsIgnoreCase("book") && MaterialUtil.isEditableBook(stack.getType()) && (hasMetaPermission(sender, "book",true, true, ess) || hasMetaPermission(sender, "chapter-" + split[1].toLowerCase(Locale.ENGLISH), true, true, ess))) {
|
} else if (split.length > 1 && split[0].equalsIgnoreCase("book") && MaterialUtil.isEditableBook(stack.getType()) && (hasMetaPermission(sender, "book", true, true, ess) || hasMetaPermission(sender, "chapter-" + split[1].toLowerCase(Locale.ENGLISH), true, true, ess))) {
|
||||||
final BookMeta meta = (BookMeta) stack.getItemMeta();
|
final BookMeta meta = (BookMeta) stack.getItemMeta();
|
||||||
final IText input = new BookInput("book", true, ess);
|
final IText input = new BookInput("book", true, ess);
|
||||||
final BookPager pager = new BookPager(input);
|
final BookPager pager = new BookPager(input);
|
||||||
|
// This fix only applies to written books - which require an author and a title. https://bugs.mojang.com/browse/MC-59153
|
||||||
|
if (stack.getType() == WRITTEN_BOOK) {
|
||||||
|
if (!meta.hasAuthor()) {
|
||||||
|
// The sender can be null when this method is called from {@link com.earth2me.essentials.signs.EssentialsSign#getItemMeta(ItemStack, String, IEssentials)}
|
||||||
|
meta.setAuthor(sender == null ? Console.getInstance().getDisplayName() : sender.getPlayer().getName());
|
||||||
|
}
|
||||||
|
if (!meta.hasTitle()) {
|
||||||
|
final String title = FormatUtil.replaceFormat(split[1].replace('_', ' '));
|
||||||
|
meta.setTitle(title.length() > 32 ? title.substring(0, 32) : title);
|
||||||
|
}
|
||||||
|
}
|
||||||
final List<String> pages = pager.getPages(split[1]);
|
final List<String> pages = pager.getPages(split[1]);
|
||||||
meta.setPages(pages);
|
meta.setPages(pages);
|
||||||
stack.setItemMeta(meta);
|
stack.setItemMeta(meta);
|
||||||
|
@ -55,9 +55,9 @@ public final class PlayerList {
|
|||||||
int playerHidden = 0;
|
int playerHidden = 0;
|
||||||
int hiddenCount = 0;
|
int hiddenCount = 0;
|
||||||
for (final User onlinePlayer : ess.getOnlineUsers()) {
|
for (final User onlinePlayer : ess.getOnlineUsers()) {
|
||||||
if (onlinePlayer.isHidden() || (user != null && !user.getBase().canSee(onlinePlayer.getBase()))) {
|
if (onlinePlayer.isHidden() || (user != null && onlinePlayer.isHiddenFrom(user.getBase()))) {
|
||||||
playerHidden++;
|
playerHidden++;
|
||||||
if (showHidden || user != null && user.getBase().canSee(onlinePlayer.getBase())) {
|
if (showHidden || user != null && !onlinePlayer.isHiddenFrom(user.getBase())) {
|
||||||
hiddenCount++;
|
hiddenCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -75,7 +75,7 @@ public final class PlayerList {
|
|||||||
public static Map<String, List<User>> getPlayerLists(final IEssentials ess, final IUser sender, final boolean showHidden) {
|
public static Map<String, List<User>> getPlayerLists(final IEssentials ess, final IUser sender, final boolean showHidden) {
|
||||||
final Map<String, List<User>> playerList = new HashMap<>();
|
final Map<String, List<User>> playerList = new HashMap<>();
|
||||||
for (final User onlineUser : ess.getOnlineUsers()) {
|
for (final User onlineUser : ess.getOnlineUsers()) {
|
||||||
if ((sender == null && !showHidden && onlineUser.isHidden()) || (sender != null && !showHidden && !sender.getBase().canSee(onlineUser.getBase()))) {
|
if ((sender == null && !showHidden && onlineUser.isHidden()) || (sender != null && !showHidden && onlineUser.isHiddenFrom(sender.getBase()))) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
final String group = FormatUtil.stripFormat(FormatUtil.stripEssentialsFormat(onlineUser.getGroup().toLowerCase()));
|
final String group = FormatUtil.stripFormat(FormatUtil.stripEssentialsFormat(onlineUser.getGroup().toLowerCase()));
|
||||||
|
@ -1943,4 +1943,9 @@ public class Settings implements net.ess3.api.ISettings {
|
|||||||
public boolean showZeroBaltop() {
|
public boolean showZeroBaltop() {
|
||||||
return config.getBoolean("show-zero-baltop", true);
|
return config.getBoolean("show-zero-baltop", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxItemLore() {
|
||||||
|
return config.getInt("max-itemlore-lines", 10);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -698,7 +698,7 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isHidden(final Player player) {
|
public boolean isHidden(final Player player) {
|
||||||
return hidden || !player.canSee(getBase());
|
return hidden || isHiddenFrom(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -700,6 +700,8 @@ public class Commandessentials extends EssentialsCommand {
|
|||||||
}
|
}
|
||||||
ess.getLogger().info("Found " + total + " orphaned userdata files.");
|
ess.getLogger().info("Found " + total + " orphaned userdata files.");
|
||||||
});
|
});
|
||||||
|
} else if (args[1].equalsIgnoreCase("cache")) {
|
||||||
|
sender.sendMessage(tl("usermapKnown", ess.getUsers().getAllUserUUIDs().size(), ess.getUsers().getNameCache().size()));
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
final UUID uuid = UUID.fromString(args[1]);
|
final UUID uuid = UUID.fromString(args[1]);
|
||||||
|
@ -35,7 +35,12 @@ public class Commanditemlore extends EssentialsCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final ItemMeta im = item.getItemMeta();
|
final ItemMeta im = item.getItemMeta();
|
||||||
|
final int loreSize = im.hasLore() ? im.getLore().size() : 0;
|
||||||
if (args[0].equalsIgnoreCase("add") && args.length > 1) {
|
if (args[0].equalsIgnoreCase("add") && args.length > 1) {
|
||||||
|
if (loreSize >= ess.getSettings().getMaxItemLore() && !user.isAuthorized("essentials.itemlore.bypass")) {
|
||||||
|
throw new Exception(tl("itemloreMaxLore"));
|
||||||
|
}
|
||||||
|
|
||||||
final String line = FormatUtil.formatString(user, "essentials.itemlore", getFinalArg(args, 1)).trim();
|
final String line = FormatUtil.formatString(user, "essentials.itemlore", getFinalArg(args, 1)).trim();
|
||||||
final List<String> lore = im.hasLore() ? im.getLore() : new ArrayList<>();
|
final List<String> lore = im.hasLore() ? im.getLore() : new ArrayList<>();
|
||||||
lore.add(line);
|
lore.add(line);
|
||||||
|
@ -28,7 +28,7 @@ public class Commandkick extends EssentialsCommand {
|
|||||||
final User user = sender.isPlayer() ? ess.getUser(sender.getPlayer()) : null;
|
final User user = sender.isPlayer() ? ess.getUser(sender.getPlayer()) : null;
|
||||||
|
|
||||||
if (user != null) {
|
if (user != null) {
|
||||||
if (target.isHidden(sender.getPlayer()) && !user.canInteractVanished() && !sender.getPlayer().canSee(target.getBase())) {
|
if (target.isHidden(sender.getPlayer()) && !user.canInteractVanished() && target.isHiddenFrom(sender.getPlayer())) {
|
||||||
throw new PlayerNotFoundException();
|
throw new PlayerNotFoundException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,31 +169,50 @@ public class Commandmail extends EssentialsCommand {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (args.length >= 1 && "clear".equalsIgnoreCase(args[0])) {
|
if (args.length >= 1 && "clear".equalsIgnoreCase(args[0])) {
|
||||||
final ArrayList<MailMessage> mails = user.getMailMessages();
|
User mailUser = user;
|
||||||
if (mails == null || mails.size() == 0) {
|
int toRemove = -1;
|
||||||
user.sendMessage(tl("noMail"));
|
if (args.length > 1) {
|
||||||
|
if (NumberUtil.isPositiveInt(args[1])) {
|
||||||
|
toRemove = Integer.parseInt(args[1]);
|
||||||
|
} else if (!user.isAuthorized("essentials.mail.clear.others")) {
|
||||||
|
throw new Exception(tl("noPerm", "essentials.mail.clear.others"));
|
||||||
|
} else {
|
||||||
|
mailUser = getPlayer(ess.getServer(), user, args, 1, true);
|
||||||
|
if (args.length > 2 && NumberUtil.isPositiveInt(args[2])) {
|
||||||
|
toRemove = Integer.parseInt(args[2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final ArrayList<MailMessage> mails = mailUser.getMailMessages();
|
||||||
|
if (mails == null || mails.isEmpty()) {
|
||||||
|
user.sendMessage(tl(mailUser == user ? "noMail" : "noMailOther", mailUser.getDisplayName()));
|
||||||
throw new NoChargeException();
|
throw new NoChargeException();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args.length > 1) {
|
if (toRemove > 0) {
|
||||||
if (!NumberUtil.isPositiveInt(args[1])) {
|
|
||||||
throw new NotEnoughArgumentsException();
|
|
||||||
}
|
|
||||||
|
|
||||||
final int toRemove = Integer.parseInt(args[1]);
|
|
||||||
if (toRemove > mails.size()) {
|
if (toRemove > mails.size()) {
|
||||||
user.sendMessage(tl("mailClearIndex", mails.size()));
|
user.sendMessage(tl("mailClearIndex", mails.size()));
|
||||||
return;
|
throw new NoChargeException();
|
||||||
}
|
}
|
||||||
mails.remove(toRemove - 1);
|
mails.remove(toRemove - 1);
|
||||||
user.setMailList(mails);
|
mailUser.setMailList(mails);
|
||||||
} else {
|
} else {
|
||||||
user.setMailList(null);
|
mailUser.setMailList(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
user.sendMessage(tl("mailCleared"));
|
user.sendMessage(tl("mailCleared"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (args.length >= 1 && "clearall".equalsIgnoreCase(args[0])){
|
||||||
|
if (!user.isAuthorized("essentials.mail.clearall")) {
|
||||||
|
throw new Exception(tl("noPerm", "essentials.mail.clearall"));
|
||||||
|
}
|
||||||
|
|
||||||
|
ess.runTaskAsynchronously(new ClearAll());
|
||||||
|
user.sendMessage(tl("mailClearedAll"));
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
throw new NotEnoughArgumentsException();
|
throw new NotEnoughArgumentsException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -201,8 +220,32 @@ public class Commandmail extends EssentialsCommand {
|
|||||||
protected void run(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
protected void run(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
||||||
if (args.length >= 1 && "read".equalsIgnoreCase(args[0])) {
|
if (args.length >= 1 && "read".equalsIgnoreCase(args[0])) {
|
||||||
throw new Exception(tl("onlyPlayers", commandLabel + " read"));
|
throw new Exception(tl("onlyPlayers", commandLabel + " read"));
|
||||||
} else if (args.length >= 1 && "clear".equalsIgnoreCase(args[0])) {
|
} else if (args.length > 1 && "clear".equalsIgnoreCase(args[0])) {
|
||||||
throw new Exception(tl("onlyPlayers", commandLabel + " clear"));
|
final User mailUser = getPlayer(server, args[1], true, true);
|
||||||
|
final int toRemove = args.length > 2 ? NumberUtil.isPositiveInt(args[2]) ? Integer.parseInt(args[2]) : -1 : -1;
|
||||||
|
|
||||||
|
final ArrayList<MailMessage> mails = mailUser.getMailMessages();
|
||||||
|
if (mails == null || mails.isEmpty()) {
|
||||||
|
sender.sendMessage(tl("noMailOther", mailUser.getDisplayName()));
|
||||||
|
throw new NoChargeException();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (toRemove > 0) {
|
||||||
|
if (toRemove > mails.size()) {
|
||||||
|
sender.sendMessage(tl("mailClearIndex", mails.size()));
|
||||||
|
throw new NoChargeException();
|
||||||
|
}
|
||||||
|
mails.remove(toRemove - 1);
|
||||||
|
mailUser.setMailList(mails);
|
||||||
|
} else {
|
||||||
|
mailUser.setMailList(null);
|
||||||
|
}
|
||||||
|
sender.sendMessage(tl("mailCleared"));
|
||||||
|
return;
|
||||||
|
} else if (args.length >= 1 && "clearall".equalsIgnoreCase(args[0])){
|
||||||
|
ess.runTaskAsynchronously(new ClearAll());
|
||||||
|
sender.sendMessage(tl("mailClearedAll"));
|
||||||
|
return;
|
||||||
} else if (args.length >= 3 && "send".equalsIgnoreCase(args[0])) {
|
} else if (args.length >= 3 && "send".equalsIgnoreCase(args[0])) {
|
||||||
final User u;
|
final User u;
|
||||||
try {
|
try {
|
||||||
@ -286,9 +329,12 @@ public class Commandmail extends EssentialsCommand {
|
|||||||
if (user.isAuthorized("essentials.mail.sendtempall")) {
|
if (user.isAuthorized("essentials.mail.sendtempall")) {
|
||||||
options.add("sendtempall");
|
options.add("sendtempall");
|
||||||
}
|
}
|
||||||
|
if (user.isAuthorized("essentials.mail.clearall")){
|
||||||
|
options.add("clearall");
|
||||||
|
}
|
||||||
return options;
|
return options;
|
||||||
} else if (args.length == 2) {
|
} else if (args.length == 2) {
|
||||||
if ((args[0].equalsIgnoreCase("send") && user.isAuthorized("essentials.mail.send")) || (args[0].equalsIgnoreCase("sendtemp") && user.isAuthorized("essentials.mail.sendtemp"))) {
|
if ((args[0].equalsIgnoreCase("send") && user.isAuthorized("essentials.mail.send")) || (args[0].equalsIgnoreCase("sendtemp") && user.isAuthorized("essentials.mail.sendtemp")) || ((args[0].equalsIgnoreCase("clear"))&& user.isAuthorized("essentials.mail.clear.others"))) {
|
||||||
return getPlayers(server, user);
|
return getPlayers(server, user);
|
||||||
} else if (args[0].equalsIgnoreCase("sendtempall") && user.isAuthorized("essentials.mail.sendtempall")) {
|
} else if (args[0].equalsIgnoreCase("sendtempall") && user.isAuthorized("essentials.mail.sendtempall")) {
|
||||||
return COMMON_DATE_DIFFS;
|
return COMMON_DATE_DIFFS;
|
||||||
@ -326,9 +372,9 @@ public class Commandmail extends EssentialsCommand {
|
|||||||
@Override
|
@Override
|
||||||
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", "sendtemp", "sendtempall");
|
return Lists.newArrayList("send", "sendall", "sendtemp", "sendtempall", "clearall", "clear");
|
||||||
} else if (args.length == 2) {
|
} else if (args.length == 2) {
|
||||||
if (args[0].equalsIgnoreCase("send") || args[0].equalsIgnoreCase("sendtemp")) {
|
if (args[0].equalsIgnoreCase("send") || args[0].equalsIgnoreCase("sendtemp") || args[0].equalsIgnoreCase("clear")) {
|
||||||
return getPlayers(server, sender);
|
return getPlayers(server, sender);
|
||||||
} else if (args[0].equalsIgnoreCase("sendtempall")) {
|
} else if (args[0].equalsIgnoreCase("sendtempall")) {
|
||||||
return COMMON_DATE_DIFFS;
|
return COMMON_DATE_DIFFS;
|
||||||
@ -338,4 +384,16 @@ public class Commandmail extends EssentialsCommand {
|
|||||||
}
|
}
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class ClearAll implements Runnable {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
for (UUID u : ess.getUsers().getAllUserUUIDs()) {
|
||||||
|
final User user = ess.getUsers().loadUncachedUser(u);
|
||||||
|
if (user != null) {
|
||||||
|
user.setMailList(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -87,7 +87,7 @@ public class Commandnear extends EssentialsCommand {
|
|||||||
final Queue<User> nearbyPlayers = new PriorityQueue<>((o1, o2) -> (int) (o1.getLocation().distanceSquared(loc) - o2.getLocation().distanceSquared(loc)));
|
final Queue<User> nearbyPlayers = new PriorityQueue<>((o1, o2) -> (int) (o1.getLocation().distanceSquared(loc) - o2.getLocation().distanceSquared(loc)));
|
||||||
|
|
||||||
for (final User player : ess.getOnlineUsers()) {
|
for (final User player : ess.getOnlineUsers()) {
|
||||||
if (!player.equals(user) && !player.isAuthorized("essentials.near.exclude") && (!player.isHidden(user.getBase()) || showHidden || user.getBase().canSee(player.getBase()))) {
|
if (!player.equals(user) && !player.isAuthorized("essentials.near.exclude") && (!player.isHidden(user.getBase()) || showHidden || !player.isHiddenFrom(user.getBase()))) {
|
||||||
final Location playerLoc = player.getLocation();
|
final Location playerLoc = player.getLocation();
|
||||||
if (playerLoc.getWorld() != world) {
|
if (playerLoc.getWorld() != world) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -18,6 +18,11 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||||||
import static com.earth2me.essentials.I18n.tl;
|
import static com.earth2me.essentials.I18n.tl;
|
||||||
|
|
||||||
public class Commandpay extends EssentialsLoopCommand {
|
public class Commandpay extends EssentialsLoopCommand {
|
||||||
|
private static final BigDecimal THOUSAND = new BigDecimal(1000);
|
||||||
|
private static final BigDecimal MILLION = new BigDecimal(1_000_000);
|
||||||
|
private static final BigDecimal BILLION = new BigDecimal(1_000_000_000);
|
||||||
|
private static final BigDecimal TRILLION = new BigDecimal(1_000_000_000_000L);
|
||||||
|
|
||||||
public Commandpay() {
|
public Commandpay() {
|
||||||
super("pay");
|
super("pay");
|
||||||
}
|
}
|
||||||
@ -28,17 +33,43 @@ public class Commandpay extends EssentialsLoopCommand {
|
|||||||
throw new NotEnoughArgumentsException();
|
throw new NotEnoughArgumentsException();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args[1].contains("-")) {
|
final String ogStr = args[1];
|
||||||
|
|
||||||
|
if (ogStr.contains("-")) {
|
||||||
throw new Exception(tl("payMustBePositive"));
|
throw new Exception(tl("payMustBePositive"));
|
||||||
}
|
}
|
||||||
|
|
||||||
final String stringAmount = args[1].replaceAll("[^0-9\\.]", "");
|
final String sanitizedString = ogStr.replaceAll("[^0-9.]", "");
|
||||||
|
|
||||||
if (stringAmount.length() < 1) {
|
if (sanitizedString.isEmpty()) {
|
||||||
throw new NotEnoughArgumentsException();
|
throw new NotEnoughArgumentsException();
|
||||||
}
|
}
|
||||||
|
|
||||||
final BigDecimal amount = new BigDecimal(stringAmount);
|
BigDecimal tempAmount = new BigDecimal(sanitizedString);
|
||||||
|
switch (Character.toLowerCase(ogStr.charAt(ogStr.length() - 1))) {
|
||||||
|
case 'k': {
|
||||||
|
tempAmount = tempAmount.multiply(THOUSAND);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'm': {
|
||||||
|
tempAmount = tempAmount.multiply(MILLION);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'b': {
|
||||||
|
tempAmount = tempAmount.multiply(BILLION);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 't': {
|
||||||
|
tempAmount = tempAmount.multiply(TRILLION);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final BigDecimal amount = tempAmount;
|
||||||
|
|
||||||
if (amount.compareTo(ess.getSettings().getMinimumPayAmount()) < 0) { // Check if amount is less than minimum-pay-amount
|
if (amount.compareTo(ess.getSettings().getMinimumPayAmount()) < 0) { // Check if amount is less than minimum-pay-amount
|
||||||
throw new Exception(tl("minimumPayAmount", NumberUtil.displayCurrencyExactly(ess.getSettings().getMinimumPayAmount(), ess)));
|
throw new Exception(tl("minimumPayAmount", NumberUtil.displayCurrencyExactly(ess.getSettings().getMinimumPayAmount(), ess)));
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ public class Commandrealname extends EssentialsCommand {
|
|||||||
final boolean skipHidden = sender.isPlayer() && !ess.getUser(sender.getPlayer()).canInteractVanished();
|
final boolean skipHidden = sender.isPlayer() && !ess.getUser(sender.getPlayer()).canInteractVanished();
|
||||||
boolean foundUser = false;
|
boolean foundUser = false;
|
||||||
for (final User u : ess.getOnlineUsers()) {
|
for (final User u : ess.getOnlineUsers()) {
|
||||||
if (skipHidden && u.isHidden(sender.getPlayer()) && !sender.getPlayer().canSee(u.getBase())) {
|
if (skipHidden && u.isHidden(sender.getPlayer()) && u.isHiddenFrom(sender.getPlayer())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
u.setDisplayNick();
|
u.setDisplayNick();
|
||||||
|
@ -5,13 +5,20 @@ import com.earth2me.essentials.craftbukkit.Inventories;
|
|||||||
import com.earth2me.essentials.utils.EnumUtil;
|
import com.earth2me.essentials.utils.EnumUtil;
|
||||||
import com.earth2me.essentials.utils.MaterialUtil;
|
import com.earth2me.essentials.utils.MaterialUtil;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.google.gson.JsonParser;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.Server;
|
import org.bukkit.Server;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.inventory.meta.SkullMeta;
|
import org.bukkit.inventory.meta.SkullMeta;
|
||||||
|
import org.bukkit.profile.PlayerProfile;
|
||||||
|
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.Base64;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import static com.earth2me.essentials.I18n.tl;
|
import static com.earth2me.essentials.I18n.tl;
|
||||||
@ -19,20 +26,53 @@ import static com.earth2me.essentials.I18n.tl;
|
|||||||
public class Commandskull extends EssentialsCommand {
|
public class Commandskull extends EssentialsCommand {
|
||||||
|
|
||||||
private static final Pattern NAME_PATTERN = Pattern.compile("^[A-Za-z0-9_]+$");
|
private static final Pattern NAME_PATTERN = Pattern.compile("^[A-Za-z0-9_]+$");
|
||||||
|
private static final Pattern URL_VALUE_PATTERN = Pattern.compile("^[0-9a-fA-F]{64}$");
|
||||||
|
private static final Pattern BASE_64_PATTERN = Pattern.compile("^[A-Za-z0-9+/=]{180}$");
|
||||||
|
|
||||||
private static final Material SKULL_ITEM = EnumUtil.getMaterial("PLAYER_HEAD", "SKULL_ITEM");
|
private static final Material SKULL_ITEM = EnumUtil.getMaterial("PLAYER_HEAD", "SKULL_ITEM");
|
||||||
|
|
||||||
|
private final boolean playerProfileSupported;
|
||||||
|
|
||||||
public Commandskull() {
|
public Commandskull() {
|
||||||
super("skull");
|
super("skull");
|
||||||
|
|
||||||
|
// The player profile API is only available in newer versions of Spigot 1.18.1 and above
|
||||||
|
boolean playerProfileSupported = true;
|
||||||
|
try {
|
||||||
|
Class.forName("org.bukkit.profile.PlayerProfile");
|
||||||
|
} catch (final ClassNotFoundException e) {
|
||||||
|
playerProfileSupported = false;
|
||||||
|
}
|
||||||
|
this.playerProfileSupported = playerProfileSupported;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
|
protected void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
|
||||||
final String owner;
|
final String owner;
|
||||||
if (args.length > 0 && user.isAuthorized("essentials.skull.others")) {
|
if (args.length > 0 && user.isAuthorized("essentials.skull.others")) {
|
||||||
if (!NAME_PATTERN.matcher(args[0]).matches()) {
|
if (BASE_64_PATTERN.matcher(args[0]).matches()) {
|
||||||
throw new IllegalArgumentException(tl("alphaNames"));
|
try {
|
||||||
|
final String decoded = new String(Base64.getDecoder().decode(args[0]));
|
||||||
|
final JsonObject jsonObject = JsonParser.parseString(decoded).getAsJsonObject();
|
||||||
|
final String url = jsonObject
|
||||||
|
.getAsJsonObject("textures")
|
||||||
|
.getAsJsonObject("SKIN")
|
||||||
|
.get("url")
|
||||||
|
.getAsString();
|
||||||
|
owner = url.substring(url.lastIndexOf("/") + 1);
|
||||||
|
} catch (final Exception e) {
|
||||||
|
// Any exception that can realistically happen here is caused by an invalid texture value
|
||||||
|
throw new IllegalArgumentException(tl("skullInvalidBase64"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!URL_VALUE_PATTERN.matcher(owner).matches()) {
|
||||||
|
throw new IllegalArgumentException(tl("skullInvalidBase64"));
|
||||||
|
}
|
||||||
|
} else if (!NAME_PATTERN.matcher(args[0]).matches()) {
|
||||||
|
throw new IllegalArgumentException(tl("alphaNames"));
|
||||||
|
} else {
|
||||||
owner = args[0];
|
owner = args[0];
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
owner = user.getName();
|
owner = user.getName();
|
||||||
}
|
}
|
||||||
@ -60,18 +100,43 @@ public class Commandskull extends EssentialsCommand {
|
|||||||
|
|
||||||
private void editSkull(final User user, final ItemStack stack, final SkullMeta skullMeta, final String owner, final boolean spawn) {
|
private void editSkull(final User user, final ItemStack stack, final SkullMeta skullMeta, final String owner, final boolean spawn) {
|
||||||
ess.runTaskAsynchronously(() -> {
|
ess.runTaskAsynchronously(() -> {
|
||||||
//Run this stuff async because SkullMeta#setOwner causes a http request.
|
// Run this stuff async because it causes an HTTP request
|
||||||
skullMeta.setDisplayName("§fSkull of " + owner);
|
|
||||||
|
final String shortOwnerName;
|
||||||
|
if (URL_VALUE_PATTERN.matcher(owner).matches()) {
|
||||||
|
if (!playerProfileSupported) {
|
||||||
|
user.sendMessage(tl("unsupportedFeature"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final URL url;
|
||||||
|
try {
|
||||||
|
url = new URL("https://textures.minecraft.net/texture/" + owner);
|
||||||
|
} catch (final MalformedURLException e) {
|
||||||
|
// The URL should never be malformed
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
final PlayerProfile profile = ess.getServer().createPlayerProfile(UUID.randomUUID());
|
||||||
|
profile.getTextures().setSkin(url);
|
||||||
|
skullMeta.setOwnerProfile(profile);
|
||||||
|
|
||||||
|
shortOwnerName = owner.substring(0, 7);
|
||||||
|
} else {
|
||||||
//noinspection deprecation
|
//noinspection deprecation
|
||||||
skullMeta.setOwner(owner);
|
skullMeta.setOwner(owner);
|
||||||
|
shortOwnerName = owner;
|
||||||
|
}
|
||||||
|
skullMeta.setDisplayName("§fSkull of " + shortOwnerName);
|
||||||
|
|
||||||
ess.scheduleEntityDelayedTask(user.getBase(), () -> {
|
ess.scheduleEntityDelayedTask(user.getBase(), () -> {
|
||||||
stack.setItemMeta(skullMeta);
|
stack.setItemMeta(skullMeta);
|
||||||
if (spawn) {
|
if (spawn) {
|
||||||
Inventories.addItem(user.getBase(), stack);
|
Inventories.addItem(user.getBase(), stack);
|
||||||
user.sendMessage(tl("givenSkull", owner));
|
user.sendMessage(tl("givenSkull", shortOwnerName));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
user.sendMessage(tl("skullChanged", owner));
|
user.sendMessage(tl("skullChanged", shortOwnerName));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,7 @@ public class Commandspeed extends EssentialsCommand {
|
|||||||
final List<Player> matchedPlayers = server.matchPlayer(name);
|
final List<Player> matchedPlayers = server.matchPlayer(name);
|
||||||
for (final Player matchPlayer : matchedPlayers) {
|
for (final Player matchPlayer : matchedPlayers) {
|
||||||
final User player = ess.getUser(matchPlayer);
|
final User player = ess.getUser(matchPlayer);
|
||||||
if (skipHidden && player.isHidden(sender.getPlayer()) && !sender.getPlayer().canSee(matchPlayer)) {
|
if (skipHidden && player.isHidden(sender.getPlayer()) && player.isHiddenFrom(sender.getPlayer())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
foundUser = true;
|
foundUser = true;
|
||||||
|
@ -44,7 +44,7 @@ public abstract class EssentialsLoopCommand extends EssentialsCommand {
|
|||||||
} else if (matchWildcards && searchTerm.contentEquals("*")) {
|
} else if (matchWildcards && searchTerm.contentEquals("*")) {
|
||||||
final boolean skipHidden = sender.isPlayer() && !ess.getUser(sender.getPlayer()).canInteractVanished();
|
final boolean skipHidden = sender.isPlayer() && !ess.getUser(sender.getPlayer()).canInteractVanished();
|
||||||
for (final User onlineUser : ess.getOnlineUsers()) {
|
for (final User onlineUser : ess.getOnlineUsers()) {
|
||||||
if (skipHidden && onlineUser.isHidden(sender.getPlayer()) && !sender.getPlayer().canSee(onlineUser.getBase())) {
|
if (skipHidden && onlineUser.isHidden(sender.getPlayer()) && onlineUser.isHiddenFrom(sender.getPlayer())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
userConsumer.accept(onlineUser);
|
userConsumer.accept(onlineUser);
|
||||||
@ -81,7 +81,7 @@ public abstract class EssentialsLoopCommand extends EssentialsCommand {
|
|||||||
|
|
||||||
if (matchWildcards && (searchTerm.contentEquals("**") || searchTerm.contentEquals("*"))) {
|
if (matchWildcards && (searchTerm.contentEquals("**") || searchTerm.contentEquals("*"))) {
|
||||||
for (final User onlineUser : ess.getOnlineUsers()) {
|
for (final User onlineUser : ess.getOnlineUsers()) {
|
||||||
if (skipHidden && onlineUser.isHidden(sender.getPlayer()) && !sender.getPlayer().canSee(onlineUser.getBase())) {
|
if (skipHidden && onlineUser.isHidden(sender.getPlayer()) && onlineUser.isHiddenFrom(sender.getPlayer())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
userConsumer.accept(onlineUser);
|
userConsumer.accept(onlineUser);
|
||||||
@ -96,7 +96,7 @@ public abstract class EssentialsLoopCommand extends EssentialsCommand {
|
|||||||
if (matchedPlayers.isEmpty()) {
|
if (matchedPlayers.isEmpty()) {
|
||||||
final String matchText = searchTerm.toLowerCase(Locale.ENGLISH);
|
final String matchText = searchTerm.toLowerCase(Locale.ENGLISH);
|
||||||
for (final User player : ess.getOnlineUsers()) {
|
for (final User player : ess.getOnlineUsers()) {
|
||||||
if (skipHidden && player.isHidden(sender.getPlayer()) && !sender.getPlayer().canSee(player.getBase())) {
|
if (skipHidden && player.isHidden(sender.getPlayer()) && player.isHiddenFrom(sender.getPlayer())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
final String displayName = FormatUtil.stripFormat(player.getDisplayName()).toLowerCase(Locale.ENGLISH);
|
final String displayName = FormatUtil.stripFormat(player.getDisplayName()).toLowerCase(Locale.ENGLISH);
|
||||||
@ -108,7 +108,7 @@ public abstract class EssentialsLoopCommand extends EssentialsCommand {
|
|||||||
} else {
|
} else {
|
||||||
for (final Player matchPlayer : matchedPlayers) {
|
for (final Player matchPlayer : matchedPlayers) {
|
||||||
final User player = ess.getUser(matchPlayer);
|
final User player = ess.getUser(matchPlayer);
|
||||||
if (skipHidden && player.isHidden(sender.getPlayer()) && !sender.getPlayer().canSee(matchPlayer)) {
|
if (skipHidden && player.isHidden(sender.getPlayer()) && player.isHiddenFrom(sender.getPlayer())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
foundUser = true;
|
foundUser = true;
|
||||||
|
@ -51,7 +51,7 @@ public abstract class EssentialsToggleCommand extends EssentialsCommand {
|
|||||||
final List<Player> matchedPlayers = server.matchPlayer(args[0]);
|
final List<Player> matchedPlayers = server.matchPlayer(args[0]);
|
||||||
for (final Player matchPlayer : matchedPlayers) {
|
for (final Player matchPlayer : matchedPlayers) {
|
||||||
final User player = ess.getUser(matchPlayer);
|
final User player = ess.getUser(matchPlayer);
|
||||||
if (skipHidden && player.isHidden(sender.getPlayer()) && !sender.getPlayer().canSee(matchPlayer)) {
|
if (skipHidden && player.isHidden(sender.getPlayer()) && player.isHiddenFrom(sender.getPlayer())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
foundUser = true;
|
foundUser = true;
|
||||||
|
@ -214,6 +214,12 @@ public abstract class AbstractItemDb implements IConf, net.ess3.api.IItemDb {
|
|||||||
sb.append("lore:").append(serializeLines(meta.getLore())).append(" ");
|
sb.append("lore:").append(serializeLines(meta.getLore())).append(" ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_14_R01)) {
|
||||||
|
if (meta.hasCustomModelData()) {
|
||||||
|
sb.append("custom-model-data:").append(meta.getCustomModelData()).append(" ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (meta.hasEnchants()) {
|
if (meta.hasEnchants()) {
|
||||||
for (final Enchantment e : meta.getEnchants().keySet()) {
|
for (final Enchantment e : meta.getEnchants().keySet()) {
|
||||||
sb.append(e.getName().toLowerCase()).append(":").append(meta.getEnchantLevel(e)).append(" ");
|
sb.append(e.getName().toLowerCase()).append(":").append(meta.getEnchantLevel(e)).append(" ");
|
||||||
|
@ -412,12 +412,16 @@ public class EssentialsSign {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected final ItemStack getItemMeta(final ItemStack item, final String meta, final IEssentials ess) throws SignException {
|
protected final ItemStack getItemMeta(final ItemStack item, final String meta, final IEssentials ess) throws SignException {
|
||||||
|
return this.getItemMeta(null, item, meta, ess);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final ItemStack getItemMeta(final CommandSource source, final ItemStack item, final String meta, final IEssentials ess) throws SignException {
|
||||||
ItemStack stack = item;
|
ItemStack stack = item;
|
||||||
try {
|
try {
|
||||||
if (!meta.isEmpty()) {
|
if (!meta.isEmpty()) {
|
||||||
final MetaItemStack metaStack = new MetaItemStack(stack);
|
final MetaItemStack metaStack = new MetaItemStack(stack);
|
||||||
final boolean allowUnsafe = ess.getSettings().allowUnsafeEnchantments();
|
final boolean allowUnsafe = ess.getSettings().allowUnsafeEnchantments();
|
||||||
metaStack.addStringMeta(null, allowUnsafe, meta, ess);
|
metaStack.addStringMeta(source, allowUnsafe, meta, ess);
|
||||||
stack = metaStack.getItemStack();
|
stack = metaStack.getItemStack();
|
||||||
}
|
}
|
||||||
} catch (final Exception ex) {
|
} catch (final Exception ex) {
|
||||||
|
@ -31,8 +31,8 @@ public class SignFree 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 {
|
||||||
ItemStack itemStack = getItemStack(sign.getLine(1), 1, ess);
|
ItemStack itemStack = getItemStack(sign.getLine(1), 1, ess);
|
||||||
itemStack = getItemMeta(itemStack, sign.getLine(2), ess);
|
itemStack = getItemMeta(player.getSource(), itemStack, sign.getLine(2), ess);
|
||||||
final ItemStack item = getItemMeta(itemStack, sign.getLine(3), ess);
|
final ItemStack item = getItemMeta(player.getSource(), itemStack, sign.getLine(3), ess);
|
||||||
|
|
||||||
if (item.getType() == Material.AIR) {
|
if (item.getType() == Material.AIR) {
|
||||||
throw new SignException(tl("cantSpawnItem", "Air"));
|
throw new SignException(tl("cantSpawnItem", "Air"));
|
||||||
|
@ -166,19 +166,29 @@ public class ModernUserMap extends CacheLoader<UUID, User> implements IUserMap {
|
|||||||
if (userFile.exists()) {
|
if (userFile.exists()) {
|
||||||
player = new OfflinePlayerStub(uuid, ess.getServer());
|
player = new OfflinePlayerStub(uuid, ess.getServer());
|
||||||
user = new User(player, ess);
|
user = new User(player, ess);
|
||||||
((OfflinePlayerStub) player).setName(user.getLastAccountName());
|
final String accName = user.getLastAccountName();
|
||||||
uuidCache.updateCache(uuid, null);
|
((OfflinePlayerStub) player).setName(accName);
|
||||||
|
// Check to see if there is already a UUID mapping for the name in the name cache before updating it.
|
||||||
|
// Since this code is ran for offline players, there's a chance we could be overriding the mapping
|
||||||
|
// for a player who changed their name to an older player's name, let that be handled during join.
|
||||||
|
//
|
||||||
|
// Here is a senerio which could take place if didn't do the containsKey check;
|
||||||
|
// "JRoyLULW" joins the server - "JRoyLULW" is mapped to 86f39a70-eda7-44a2-88f8-0ade4e1ec8c0
|
||||||
|
// "JRoyLULW" changes their name to "mbax" - Nothing happens, they are yet to join the server
|
||||||
|
// "mdcfe" changes their name to "JRoyLULW" - Nothing happens, they are yet to join the server
|
||||||
|
// "JRoyLULW" (formally "mdcfe") joins the server - "JRoyLULW" is mapped to 62a6a4bb-a2b8-4796-bfe6-63067250990a
|
||||||
|
// The /baltop command is ran, iterating over all players.
|
||||||
|
//
|
||||||
|
// During the baltop iteration, two uuids have the `last-account-name` of "JRoyLULW" creating the
|
||||||
|
// potential that "JRoyLULW" is mapped back to 86f39a70-eda7-44a2-88f8-0ade4e1ec8c0 when the true
|
||||||
|
// bearer of that name is now 62a6a4bb-a2b8-4796-bfe6-63067250990a.
|
||||||
|
uuidCache.updateCache(uuid, (accName == null || uuidCache.getNameCache().containsKey(accName)) ? null : accName);
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addCachedUser(final User user) {
|
|
||||||
userCache.put(user.getUUID(), user);
|
|
||||||
debugLogCache(user);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, UUID> getNameCache() {
|
public Map<String, UUID> getNameCache() {
|
||||||
return uuidCache.getNameCache();
|
return uuidCache.getNameCache();
|
||||||
|
@ -81,10 +81,12 @@ public final class VersionUtil {
|
|||||||
builder.put("io.akarin.server.Config", SupportStatus.DANGEROUS_FORK);
|
builder.put("io.akarin.server.Config", SupportStatus.DANGEROUS_FORK);
|
||||||
|
|
||||||
// Forge - Doesn't support Bukkit
|
// Forge - Doesn't support Bukkit
|
||||||
builder.put("net.minecraftforge.common.MinecraftForge", SupportStatus.UNSTABLE);
|
// The below translates to net.minecraftforge.common.MinecraftForge
|
||||||
|
builder.put(dumb(new int[] {110, 101, 116, 46, 109, 105, 110, 101, 99, 114, 97, 102, 116, 102, 111, 114, 103, 101, 46, 99, 111, 109, 109, 111, 110, 46, 77, 105, 110, 101, 99, 114, 97, 102, 116, 70, 111, 114, 103, 101}, 40), SupportStatus.UNSTABLE);
|
||||||
|
|
||||||
// Fabric - Doesn't support Bukkit
|
// Fabric - Doesn't support Bukkit
|
||||||
builder.put("net.fabricmc.loader.launch.knot.KnotServer", SupportStatus.UNSTABLE);
|
// The below translates to net.fabricmc.loader.launch.knot.KnotServer
|
||||||
|
builder.put(dumb(new int[] {110, 101, 116, 46, 102, 97, 98, 114, 105, 99, 109, 99, 46, 108, 111, 97, 100, 101, 114, 46, 108, 97, 117, 110, 99, 104, 46, 107, 110, 111, 116, 46, 75, 110, 111, 116, 83, 101, 114, 118, 101, 114}, 42), SupportStatus.UNSTABLE);
|
||||||
|
|
||||||
// Misc translation layers that do not add NMS will be caught by this
|
// Misc translation layers that do not add NMS will be caught by this
|
||||||
if (ReflUtil.getNmsVersionObject().isHigherThanOrEqualTo(ReflUtil.V1_17_R1)) {
|
if (ReflUtil.getNmsVersionObject().isHigherThanOrEqualTo(ReflUtil.V1_17_R1)) {
|
||||||
@ -355,4 +357,21 @@ public final class VersionUtil {
|
|||||||
return supported;
|
return supported;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String dumb(final int[] clazz, final int len) {
|
||||||
|
final char[] chars = new char[clazz.length];
|
||||||
|
|
||||||
|
for (int i = 0; i < clazz.length; i++) {
|
||||||
|
chars[i] = (char) clazz[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
final String decode = String.valueOf(chars);
|
||||||
|
|
||||||
|
if (decode.length() != len) {
|
||||||
|
System.exit(1);
|
||||||
|
return "why do hybrids try to bypass this?";
|
||||||
|
}
|
||||||
|
|
||||||
|
return decode;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -732,6 +732,10 @@ log-command-block-commands: true
|
|||||||
# Set the maximum speed for projectiles spawned with /fireball.
|
# Set the maximum speed for projectiles spawned with /fireball.
|
||||||
max-projectile-speed: 8
|
max-projectile-speed: 8
|
||||||
|
|
||||||
|
# Set the maximum amount of lore lines a user can set with the /itemlore command.
|
||||||
|
# Users with the essentials.itemlore.bypass permission will be able to bypass this limit.
|
||||||
|
max-itemlore-lines: 10
|
||||||
|
|
||||||
# Should EssentialsX check for updates?
|
# Should EssentialsX check for updates?
|
||||||
# If set to true, EssentialsX will show notifications when a new version is available.
|
# If set to true, EssentialsX will show notifications when a new version is available.
|
||||||
# This uses the public GitHub API and no identifying information is sent or stored.
|
# This uses the public GitHub API and no identifying information is sent or stored.
|
||||||
|
@ -586,6 +586,7 @@ itemloreCommandUsage2Description=Sets the specified line of the held item's lore
|
|||||||
itemloreCommandUsage3=/<command> clear
|
itemloreCommandUsage3=/<command> clear
|
||||||
itemloreCommandUsage3Description=Clears the held item's lore
|
itemloreCommandUsage3Description=Clears the held item's lore
|
||||||
itemloreInvalidItem=\u00a74You need to hold an item to edit its lore.
|
itemloreInvalidItem=\u00a74You need to hold an item to edit its lore.
|
||||||
|
itemloreMaxLore=\u00a74You cannot add any more lore lines to this item.
|
||||||
itemloreNoLine=\u00a74Your held item does not have lore text on line \u00a7c{0}\u00a74.
|
itemloreNoLine=\u00a74Your held item does not have lore text on line \u00a7c{0}\u00a74.
|
||||||
itemloreNoLore=\u00a74Your held item does not have any lore text.
|
itemloreNoLore=\u00a74Your held item does not have any lore text.
|
||||||
itemloreSuccess=\u00a76You have added "\u00a7c{0}\u00a76" to your held item''s lore.
|
itemloreSuccess=\u00a76You have added "\u00a7c{0}\u00a76" to your held item''s lore.
|
||||||
@ -711,21 +712,26 @@ 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\!
|
||||||
|
mailClearedAll=\u00a76Mail cleared for all players\!
|
||||||
mailClearIndex=\u00a74You must specify a number between 1-{0}.
|
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|clear [number]|send [to] [message]|sendtemp [to] [expire time] [message]|sendall [message]]
|
mailCommandUsage=/<command> [read|clear|clear [number]|clear <player> [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 [number]
|
mailCommandUsage2=/<command> clear [number]
|
||||||
mailCommandUsage2Description=Clears either all or the specified mail(s)
|
mailCommandUsage2Description=Clears either all or the specified mail(s)
|
||||||
mailCommandUsage3=/<command> send <player> <message>
|
mailCommandUsage3=/<command> clear <player> [number]
|
||||||
mailCommandUsage3Description=Sends the specified player the given message
|
mailCommandUsage3Description=Clears either all or the specified mail(s) for the given player
|
||||||
mailCommandUsage4=/<command> sendall <message>
|
mailCommandUsage4=/<command> clearall
|
||||||
mailCommandUsage4Description=Sends all players the given message
|
mailCommandUsage4Description=Clears all mail for the all players
|
||||||
mailCommandUsage5=/<command> sendtemp <player> <expire time> <message>
|
mailCommandUsage5=/<command> send <player> <message>
|
||||||
mailCommandUsage5Description=Sends the specified player the given message which will expire in the specified time
|
mailCommandUsage5Description=Sends the specified player the given message
|
||||||
mailCommandUsage6=/<command> sendtempall <expire time> <message>
|
mailCommandUsage6=/<command> sendall <message>
|
||||||
mailCommandUsage6Description=Sends all players the given message which will expire in the specified time
|
mailCommandUsage6Description=Sends all players the given message
|
||||||
|
mailCommandUsage7=/<command> sendtemp <player> <expire time> <message>
|
||||||
|
mailCommandUsage7Description=Sends the specified player the given message which will expire in the specified time
|
||||||
|
mailCommandUsage8=/<command> sendtempall <expire time> <message>
|
||||||
|
mailCommandUsage8Description=Sends all players 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}
|
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}
|
mailFormatNewTimed=\u00a76[\u00a7e\u26a0\u00a76] \u00a76[\u00a7r{0}\u00a76] \u00a76[\u00a7r{1}\u00a76] \u00a7r{2}
|
||||||
@ -853,6 +859,7 @@ noKitPermission=\u00a74You need the \u00a7c{0}\u00a74 permission to use that kit
|
|||||||
noKits=\u00a76There are no kits available yet.
|
noKits=\u00a76There are no kits available yet.
|
||||||
noLocationFound=\u00a74No valid location found.
|
noLocationFound=\u00a74No valid location found.
|
||||||
noMail=\u00a76You do not have any mail.
|
noMail=\u00a76You do not have any mail.
|
||||||
|
noMailOther=\u00a7c{0} \u00a76does not have any mail.
|
||||||
noMatchingPlayers=\u00a76No matching players found.
|
noMatchingPlayers=\u00a76No matching players found.
|
||||||
noMetaFirework=\u00a74You do not have permission to apply firework meta.
|
noMetaFirework=\u00a74You do not have permission to apply firework meta.
|
||||||
noMetaJson=JSON Metadata is not supported in this version of Bukkit.
|
noMetaJson=JSON Metadata is not supported in this version of Bukkit.
|
||||||
@ -1201,6 +1208,9 @@ skullCommandUsage1=/<command>
|
|||||||
skullCommandUsage1Description=Gets your own skull
|
skullCommandUsage1Description=Gets your own skull
|
||||||
skullCommandUsage2=/<command> <player>
|
skullCommandUsage2=/<command> <player>
|
||||||
skullCommandUsage2Description=Gets the skull of the specified player
|
skullCommandUsage2Description=Gets the skull of the specified player
|
||||||
|
skullCommandUsage3=/<command> <texture>
|
||||||
|
skullCommandUsage3Description=Gets a skull with the specified texture (either the hash from a texture URL or a Base64 texture value)
|
||||||
|
skullInvalidBase64=\u00a74The texture value is invalid.
|
||||||
slimeMalformedSize=\u00a74Malformed size.
|
slimeMalformedSize=\u00a74Malformed size.
|
||||||
smithingtableCommandDescription=Opens up a smithing table.
|
smithingtableCommandDescription=Opens up a smithing table.
|
||||||
smithingtableCommandUsage=/<command>
|
smithingtableCommandUsage=/<command>
|
||||||
@ -1462,6 +1472,7 @@ userIsAwaySelfWithMessage=\u00a77You are now AFK.
|
|||||||
userIsNotAwaySelf=\u00a77You are no longer AFK.
|
userIsNotAwaySelf=\u00a77You are no longer AFK.
|
||||||
userJailed=\u00a76You have been jailed\!
|
userJailed=\u00a76You have been jailed\!
|
||||||
usermapEntry=\u00a7c{0} \u00a76is mapped to \u00a7c{1}\u00a76.
|
usermapEntry=\u00a7c{0} \u00a76is mapped to \u00a7c{1}\u00a76.
|
||||||
|
usermapKnown=\u00a76There are \u00a7c{0} \u00a76known users to the user cache with \u00a7c{1} \u00a76name to UUID pairs.
|
||||||
usermapPurge=\u00a76Checking for files in userdata that are not mapped, results will be logged to console. Destructive Mode: {0}
|
usermapPurge=\u00a76Checking for files in userdata that are not mapped, results will be logged to console. Destructive Mode: {0}
|
||||||
usermapSize=\u00a76Current cached users in user map is \u00a7c{0}\u00a76/\u00a7c{1}\u00a76/\u00a7c{2}\u00a76.
|
usermapSize=\u00a76Current cached users in user map is \u00a7c{0}\u00a76/\u00a7c{1}\u00a76/\u00a7c{2}\u00a76.
|
||||||
userUnknown=\u00a74Warning\: The user ''\u00a7c{0}\u00a74'' has never joined this server.
|
userUnknown=\u00a74Warning\: The user ''\u00a7c{0}\u00a74'' has never joined this server.
|
||||||
|
@ -291,7 +291,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|clear [number]|send [to] [message]|sendtemp [to] [expire time] [message]|sendall [message]]
|
usage: /<command> [read|clear|clear [number]|clear <player> [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.
|
||||||
|
@ -6,6 +6,7 @@ import com.earth2me.essentials.config.EssentialsConfiguration;
|
|||||||
import com.earth2me.essentials.utils.FormatUtil;
|
import com.earth2me.essentials.utils.FormatUtil;
|
||||||
import net.dv8tion.jda.api.OnlineStatus;
|
import net.dv8tion.jda.api.OnlineStatus;
|
||||||
import net.dv8tion.jda.api.entities.Activity;
|
import net.dv8tion.jda.api.entities.Activity;
|
||||||
|
import net.dv8tion.jda.api.entities.Role;
|
||||||
import net.essentialsx.api.v2.ChatType;
|
import net.essentialsx.api.v2.ChatType;
|
||||||
import org.apache.logging.log4j.Level;
|
import org.apache.logging.log4j.Level;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
@ -33,6 +34,7 @@ public class DiscordSettings implements IConf {
|
|||||||
private Activity statusActivity;
|
private Activity statusActivity;
|
||||||
|
|
||||||
private List<Pattern> discordFilter;
|
private List<Pattern> discordFilter;
|
||||||
|
private Map<String, String> roleAliases;
|
||||||
|
|
||||||
private MessageFormat consoleFormat;
|
private MessageFormat consoleFormat;
|
||||||
private Level consoleLogLevel;
|
private Level consoleLogLevel;
|
||||||
@ -92,6 +94,18 @@ public class DiscordSettings implements IConf {
|
|||||||
return config.getBoolean("show-discord-attachments", true);
|
return config.getBoolean("show-discord-attachments", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<String> getDiscordRolesBlacklist() {
|
||||||
|
return config.getList("discord-role-blacklist", String.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getInvertDiscordRoleBlacklist() {
|
||||||
|
return config.getBoolean("invert-discord-role-blacklist", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRoleAlias(final Role role) {
|
||||||
|
return roleAliases.getOrDefault(role.getId(), roleAliases.getOrDefault(role.getName(), role.getName()));
|
||||||
|
}
|
||||||
|
|
||||||
public List<String> getPermittedFormattingRoles() {
|
public List<String> getPermittedFormattingRoles() {
|
||||||
return config.getList("permit-formatting-roles", String.class);
|
return config.getList("permit-formatting-roles", String.class);
|
||||||
}
|
}
|
||||||
@ -508,6 +522,13 @@ public class DiscordSettings implements IConf {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final Map<String, String> roleAliases = new HashMap<>();
|
||||||
|
|
||||||
|
for (Map.Entry<String, String> entry : config.getStringMap("discord-roles-aliases").entrySet()) {
|
||||||
|
roleAliases.put(entry.getKey(), FormatUtil.replaceFormat(entry.getValue()));
|
||||||
|
}
|
||||||
|
this.roleAliases = roleAliases;
|
||||||
|
|
||||||
consoleLogLevel = Level.toLevel(config.getString("console.log-level", null), Level.INFO);
|
consoleLogLevel = Level.toLevel(config.getString("console.log-level", null), Level.INFO);
|
||||||
|
|
||||||
if (config.isList("console.console-filter")) {
|
if (config.isList("console.console-filter")) {
|
||||||
|
@ -102,7 +102,7 @@ public class DiscordListener extends ListenerAdapter {
|
|||||||
|
|
||||||
String formattedMessage = EmojiParser.parseToAliases(MessageUtil.formatMessage(plugin.getPlugin().getSettings().getDiscordToMcFormat(),
|
String formattedMessage = EmojiParser.parseToAliases(MessageUtil.formatMessage(plugin.getPlugin().getSettings().getDiscordToMcFormat(),
|
||||||
event.getChannel().getName(), user.getName(), user.getDiscriminator(), user.getAsTag(),
|
event.getChannel().getName(), user.getName(), user.getDiscriminator(), user.getAsTag(),
|
||||||
effectiveName, DiscordUtil.getRoleColorFormat(member), finalMessage, DiscordUtil.getRoleFormat(member)), EmojiParser.FitzpatrickAction.REMOVE);
|
effectiveName, DiscordUtil.getRoleColorFormat(plugin, member), finalMessage, DiscordUtil.getRoleFormat(plugin, member)), EmojiParser.FitzpatrickAction.REMOVE);
|
||||||
|
|
||||||
for (final String group : keys) {
|
for (final String group : keys) {
|
||||||
if (plugin.getSettings().getRelayToConsoleList().contains(group)) {
|
if (plugin.getSettings().getRelayToConsoleList().contains(group)) {
|
||||||
|
@ -4,7 +4,6 @@ import club.minnced.discord.webhook.WebhookClient;
|
|||||||
import club.minnced.discord.webhook.send.AllowedMentions;
|
import club.minnced.discord.webhook.send.AllowedMentions;
|
||||||
import com.earth2me.essentials.utils.DownsampleUtil;
|
import com.earth2me.essentials.utils.DownsampleUtil;
|
||||||
import com.earth2me.essentials.utils.FormatUtil;
|
import com.earth2me.essentials.utils.FormatUtil;
|
||||||
import com.earth2me.essentials.utils.NumberUtil;
|
|
||||||
import com.earth2me.essentials.utils.VersionUtil;
|
import com.earth2me.essentials.utils.VersionUtil;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import net.dv8tion.jda.api.Permission;
|
import net.dv8tion.jda.api.Permission;
|
||||||
@ -21,10 +20,12 @@ import okhttp3.OkHttpClient;
|
|||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
public final class DiscordUtil {
|
public final class DiscordUtil {
|
||||||
public final static String ADVANCED_RELAY_NAME = "EssX Advanced Relay";
|
public final static String ADVANCED_RELAY_NAME = "EssX Advanced Relay";
|
||||||
@ -126,20 +127,36 @@ public final class DiscordUtil {
|
|||||||
return future;
|
return future;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Role getHighestRole(final JDADiscordService jda, final Member member, final Predicate<Role> fail) {
|
||||||
|
final List<Role> roles = member == null ? Collections.emptyList() : member.getRoles();
|
||||||
|
final List<String> blacklist = jda.getPlugin().getSettings().getDiscordRolesBlacklist();
|
||||||
|
final boolean invert = jda.getPlugin().getSettings().getInvertDiscordRoleBlacklist();
|
||||||
|
|
||||||
|
for (final Role role : roles) {
|
||||||
|
final boolean blacklisted = blacklist.contains(role.getName()) || blacklist.contains(role.getId());
|
||||||
|
if ((blacklisted && !invert) || (!blacklisted && invert)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fail != null && fail.test(role)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return role;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the highest role of a given member or an empty string if the member has no roles.
|
* Gets the highest role of a given member or an empty string if the member has no roles.
|
||||||
*
|
*
|
||||||
* @param member The target member.
|
* @param member The target member.
|
||||||
* @return The highest role or blank string.
|
* @return The highest role or blank string.
|
||||||
*/
|
*/
|
||||||
public static String getRoleFormat(Member member) {
|
public static String getRoleFormat(final JDADiscordService jda, Member member) {
|
||||||
final List<Role> roles = member == null ? null : member.getRoles();
|
final Role role = getHighestRole(jda, member, null);
|
||||||
|
return role != null ? jda.getSettings().getRoleAlias(role) : "";
|
||||||
if (roles == null || roles.isEmpty()) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
return roles.get(0).getName();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -148,11 +165,13 @@ public final class DiscordUtil {
|
|||||||
* @param member The target member.
|
* @param member The target member.
|
||||||
* @return The bukkit color code or blank string.
|
* @return The bukkit color code or blank string.
|
||||||
*/
|
*/
|
||||||
public static String getRoleColorFormat(Member member) {
|
public static String getRoleColorFormat(final JDADiscordService jda, Member member) {
|
||||||
if (member == null || member.getColorRaw() == Role.DEFAULT_COLOR_RAW) {
|
final Role topRole = getHighestRole(jda, member, role -> role.getColorRaw() == Role.DEFAULT_COLOR_RAW);
|
||||||
|
if (topRole == null || topRole.getColorRaw() == Role.DEFAULT_COLOR_RAW) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
final int rawColor = 0xff000000 | member.getColorRaw();
|
|
||||||
|
final int rawColor = 0xff000000 | topRole.getColorRaw();
|
||||||
|
|
||||||
if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_16_1_R01)) {
|
if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_16_1_R01)) {
|
||||||
// Essentials' FormatUtil allows us to not have to use bungee's chatcolor since bukkit's own one doesn't support rgb
|
// Essentials' FormatUtil allows us to not have to use bungee's chatcolor since bukkit's own one doesn't support rgb
|
||||||
@ -176,14 +195,13 @@ public final class DiscordUtil {
|
|||||||
final List<Role> roles = member.getRoles();
|
final List<Role> roles = member.getRoles();
|
||||||
for (String roleDefinition : roleDefinitions) {
|
for (String roleDefinition : roleDefinitions) {
|
||||||
roleDefinition = roleDefinition.trim();
|
roleDefinition = roleDefinition.trim();
|
||||||
final boolean id = NumberUtil.isNumeric(roleDefinition);
|
|
||||||
|
|
||||||
if (roleDefinition.equals("*") || member.getId().equals(roleDefinition)) {
|
if (roleDefinition.equals("*") || member.getId().equals(roleDefinition)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (final Role role : roles) {
|
for (final Role role : roles) {
|
||||||
if (role.getId().equals(roleDefinition) || (!id && role.getName().equalsIgnoreCase(roleDefinition))) {
|
if (matchesRole(role, roleDefinition)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -191,6 +209,15 @@ public final class DiscordUtil {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the provided role matches the provided role definition (string representation of id or the role's name)
|
||||||
|
*
|
||||||
|
* @return true if the provided definition matches the provided role.
|
||||||
|
*/
|
||||||
|
public static boolean matchesRole(Role role, String roleDefinition) {
|
||||||
|
return role.getId().equals(roleDefinition) || role.getName().equalsIgnoreCase(roleDefinition);
|
||||||
|
}
|
||||||
|
|
||||||
public static String getAvatarUrl(final JDADiscordService jda, final Player player) {
|
public static String getAvatarUrl(final JDADiscordService jda, final Player player) {
|
||||||
return jda.getSettings().getAvatarURL().replace("{uuid}", player.getUniqueId().toString()).replace("{name}", player.getName());
|
return jda.getSettings().getAvatarURL().replace("{uuid}", player.getUniqueId().toString()).replace("{name}", player.getName());
|
||||||
}
|
}
|
||||||
|
@ -224,6 +224,18 @@ commands:
|
|||||||
# If this is set to false and a message from Discord only contains an image/file and not any text, nothing will be sent.
|
# If this is set to false and a message from Discord only contains an image/file and not any text, nothing will be sent.
|
||||||
show-discord-attachments: true
|
show-discord-attachments: true
|
||||||
|
|
||||||
|
# A list of roles which should be ignored by the {color} and {role} placeholders.
|
||||||
|
# for the Discord->MC chat format.
|
||||||
|
discord-role-blacklist:
|
||||||
|
- "123456789012345678"
|
||||||
|
- "Members"
|
||||||
|
|
||||||
|
# Role aliases allow you to replace the role names with something different in the Discord->MC chat relay format.
|
||||||
|
# If you are using role aliases, make sure to remove the '#' at the start to allow the setting to be read.
|
||||||
|
discord-roles-aliases:
|
||||||
|
# "123456789012345678": "&c&lAdmin"
|
||||||
|
# "Members": "Member"
|
||||||
|
|
||||||
# A list of roles allowed to send Minecraft color/formatting codes from Discord to MC.
|
# A list of roles allowed to send Minecraft color/formatting codes from Discord to MC.
|
||||||
# This applies to all aspects such as that Discord->MC chat relay as well as commands.
|
# This applies to all aspects such as that Discord->MC chat relay as well as commands.
|
||||||
# You can either use '*' (for everyone), a role name/ID, or a user ID.
|
# You can either use '*' (for everyone), a role name/ID, or a user ID.
|
||||||
|
@ -76,8 +76,8 @@ To add EssentialsX to your build system, you should use the following artifacts:
|
|||||||
|
|
||||||
| Type | Group ID | Artifact ID | Version |
|
| Type | Group ID | Artifact ID | Version |
|
||||||
|:---------------|:------------------|:--------------|:------------------|
|
|:---------------|:------------------|:--------------|:------------------|
|
||||||
| Latest release | `net.essentialsx` | `EssentialsX` | `2.20.0` |
|
| Latest release | `net.essentialsx` | `EssentialsX` | `2.20.1` |
|
||||||
| Snapshots | `net.essentialsx` | `EssentialsX` | `2.20.1-SNAPSHOT` |
|
| Snapshots | `net.essentialsx` | `EssentialsX` | `2.21.0-SNAPSHOT` |
|
||||||
| Older releases | `net.ess3` | `EssentialsX` | `2.18.2` |
|
| Older releases | `net.ess3` | `EssentialsX` | `2.18.2` |
|
||||||
|
|
||||||
Note: until version `2.18.2`, EssentialsX used the `net.ess3` group ID.
|
Note: until version `2.18.2`, EssentialsX used the `net.ess3` group ID.
|
||||||
|
@ -3,7 +3,7 @@ plugins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
group = "net.essentialsx"
|
group = "net.essentialsx"
|
||||||
version = "2.20.1-SNAPSHOT"
|
version = "2.21.0-SNAPSHOT"
|
||||||
|
|
||||||
project.ext {
|
project.ext {
|
||||||
GIT_COMMIT = !indraGit.isPresent() ? "unknown" : indraGit.commit().abbreviate(7).name()
|
GIT_COMMIT = !indraGit.isPresent() ? "unknown" : indraGit.commit().abbreviate(7).name()
|
||||||
|
Loading…
Reference in New Issue
Block a user