Merge branch '2.x' into l10n_2.x

This commit is contained in:
Josh Roy 2024-11-24 18:20:20 -05:00 committed by GitHub
commit 9a5f748783
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
94 changed files with 5835 additions and 739 deletions

View File

@ -70,10 +70,13 @@ body:
validations: validations:
required: true required: true
- type: markdown - type: textarea
attributes: attributes:
value: | label: Additional Information
In the text box below, you can attach any relevant screenshots, files and links to Timings/spark profiler reports. description: |
In this box, you can attach any relevant screenshots, files and links to Timings/spark profiler reports.
You can also include a link to a heapdump if necessary, but please make sure you don't include any private player data in the heapdump. You can also include a link to a heapdump if necessary, but please make sure you don't include any private player data in the heapdump.
If you suspect this issue is related to a prior issue/PR/commit, please mention it here. If you suspect this issue is related to a prior issue/PR/commit, please mention it here.
validations:
required: false

View File

@ -14,9 +14,9 @@ dependencies {
implementation 'org.checkerframework:checker-qual:3.21.0' implementation 'org.checkerframework:checker-qual:3.21.0'
implementation 'nu.studer:java-ordered-properties:1.0.4' implementation 'nu.studer:java-ordered-properties:1.0.4'
implementation 'net.kyori:adventure-api:4.15.0' implementation 'net.kyori:adventure-api:4.17.0'
implementation 'net.kyori:adventure-text-minimessage:4.15.0' implementation 'net.kyori:adventure-text-minimessage:4.17.0'
implementation 'net.kyori:adventure-platform-bukkit:4.3.2' implementation 'net.kyori:adventure-platform-bukkit:4.3.3'
// Providers // Providers
api project(':providers:BaseProviders') api project(':providers:BaseProviders')

View File

@ -1,5 +1,6 @@
package com.earth2me.essentials; package com.earth2me.essentials;
import java.util.stream.Collectors;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.PluginIdentifiableCommand; import org.bukkit.command.PluginIdentifiableCommand;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
@ -31,7 +32,7 @@ public class AlternativeCommandsHandler {
if (plugin.getDescription().getMain().contains("com.earth2me.essentials") || plugin.getDescription().getMain().contains("net.essentialsx")) { if (plugin.getDescription().getMain().contains("com.earth2me.essentials") || plugin.getDescription().getMain().contains("net.essentialsx")) {
return; return;
} }
for (final Map.Entry<String, Command> entry : getPluginCommands(plugin).entrySet()) { for (final Map.Entry<String, Command> entry : getPluginCommands(plugin)) {
final String[] commandSplit = entry.getKey().split(":", 2); final String[] commandSplit = entry.getKey().split(":", 2);
final String commandName = commandSplit.length > 1 ? commandSplit[1] : entry.getKey(); final String commandName = commandSplit.length > 1 ? commandSplit[1] : entry.getKey();
final Command command = entry.getValue(); final Command command = entry.getValue();
@ -64,14 +65,23 @@ public class AlternativeCommandsHandler {
} }
} }
private Map<String, Command> getPluginCommands(Plugin plugin) { private List<Map.Entry<String, Command>> getPluginCommands(Plugin plugin) {
final Map<String, Command> commands = new HashMap<>(); final Map<String, Command> commands = new HashMap<>();
for (final Map.Entry<String, Command> entry : ess.getKnownCommandsProvider().getKnownCommands().entrySet()) { for (final Map.Entry<String, Command> entry : ess.getKnownCommandsProvider().getKnownCommands().entrySet()) {
if (entry.getValue() instanceof PluginIdentifiableCommand && ((PluginIdentifiableCommand) entry.getValue()).getPlugin().equals(plugin)) { if (entry.getValue() instanceof PluginIdentifiableCommand && ((PluginIdentifiableCommand) entry.getValue()).getPlugin().equals(plugin)) {
commands.put(entry.getKey(), entry.getValue()); commands.put(entry.getKey(), entry.getValue());
} }
} }
return commands; // Try to use non-namespaced commands first if we can, some Commands may not like being registered under a
// different label than their getName() returns, so avoid doing that when we can
return commands.entrySet().stream().sorted((o1, o2) -> {
if (o1.getKey().contains(":") && !o2.getKey().contains(":")) {
return 1;
} else if (!o1.getKey().contains(":") && o2.getKey().contains(":")) {
return -1;
}
return 0;
}).collect(Collectors.toList());
} }
public void removePlugin(final Plugin plugin) { public void removePlugin(final Plugin plugin) {

View File

@ -7,7 +7,6 @@ import com.earth2me.essentials.utils.LocationUtil;
import io.papermc.lib.PaperLib; import io.papermc.lib.PaperLib;
import net.ess3.api.IEssentials; import net.ess3.api.IEssentials;
import net.ess3.api.IUser; import net.ess3.api.IUser;
import net.ess3.api.InvalidWorldException;
import net.ess3.api.TranslatableException; import net.ess3.api.TranslatableException;
import net.ess3.api.events.UserWarpEvent; import net.ess3.api.events.UserWarpEvent;
import net.ess3.api.events.teleport.PreTeleportEvent; import net.ess3.api.events.teleport.PreTeleportEvent;
@ -424,7 +423,7 @@ public class AsyncTeleport implements IAsyncTeleport {
final Location loc; final Location loc;
try { try {
loc = ess.getWarps().getWarp(warp); loc = ess.getWarps().getWarp(warp);
} catch (final WarpNotFoundException | InvalidWorldException e) { } catch (final WarpNotFoundException e) {
future.completeExceptionally(e); future.completeExceptionally(e);
return; return;
} }

View File

@ -1,11 +1,9 @@
package com.earth2me.essentials; package com.earth2me.essentials;
public class ChargeException extends Exception { import net.ess3.api.TranslatableException;
public ChargeException(final String message) {
super(message);
}
public ChargeException(final String message, final Throwable throwable) { public class ChargeException extends TranslatableException {
super(message, throwable); public ChargeException(String tlKey, Object... args) {
super(tlKey, args);
} }
} }

View File

@ -36,7 +36,9 @@ public class CommandSource {
} }
final String translation = tlLiteral(tlKey, args); final String translation = tlLiteral(tlKey, args);
sendComponent(AdventureUtil.miniMessage().deserialize(translation)); if (!translation.isEmpty()) {
sendComponent(AdventureUtil.miniMessage().deserialize(translation));
}
} }
public String tl(final String tlKey, final Object... args) { public String tl(final String tlKey, final Object... args) {

View File

@ -69,6 +69,9 @@ public final class Console implements IMessageRecipient {
@Override @Override
public void sendTl(String tlKey, Object... args) { public void sendTl(String tlKey, Object... args) {
final String translation = tlLiteral(tlKey, args); final String translation = tlLiteral(tlKey, args);
if (translation.isEmpty()) {
return;
}
final Audience consoleAudience = ((Essentials) ess).getBukkitAudience().sender(getCommandSender()); final Audience consoleAudience = ((Essentials) ess).getBukkitAudience().sender(getCommandSender());
final Component component = AdventureUtil.miniMessage() final Component component = AdventureUtil.miniMessage()

View File

@ -1,5 +1,6 @@
package com.earth2me.essentials; package com.earth2me.essentials;
import com.earth2me.essentials.utils.RegistryUtil;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
import org.bukkit.enchantments.Enchantment; import org.bukkit.enchantments.Enchantment;
@ -15,33 +16,43 @@ public final class Enchantments {
private static boolean isFlat; private static boolean isFlat;
static { static {
ENCHANTMENTS.put("alldamage", Enchantment.DAMAGE_ALL); final Enchantment SHARPNESS = RegistryUtil.valueOf(Enchantment.class, "DAMAGE_ALL", "SHARPNESS");
ALIASENCHANTMENTS.put("alldmg", Enchantment.DAMAGE_ALL);
ENCHANTMENTS.put("sharpness", Enchantment.DAMAGE_ALL); ENCHANTMENTS.put("alldamage", SHARPNESS);
ALIASENCHANTMENTS.put("sharp", Enchantment.DAMAGE_ALL); ALIASENCHANTMENTS.put("alldmg", SHARPNESS);
ALIASENCHANTMENTS.put("dal", Enchantment.DAMAGE_ALL); ENCHANTMENTS.put("sharpness", SHARPNESS);
ALIASENCHANTMENTS.put("sharp", SHARPNESS);
ALIASENCHANTMENTS.put("dal", SHARPNESS);
final Enchantment BANE_OF_ARTHROPODS = RegistryUtil.valueOf(Enchantment.class, "DAMAGE_ARTHROPODS", "BANE_OF_ARTHROPODS");
ENCHANTMENTS.put("ardmg", Enchantment.DAMAGE_ARTHROPODS); ENCHANTMENTS.put("ardmg", BANE_OF_ARTHROPODS);
ENCHANTMENTS.put("baneofarthropods", Enchantment.DAMAGE_ARTHROPODS); ENCHANTMENTS.put("baneofarthropods", BANE_OF_ARTHROPODS);
ALIASENCHANTMENTS.put("baneofarthropod", Enchantment.DAMAGE_ARTHROPODS); ALIASENCHANTMENTS.put("baneofarthropod", BANE_OF_ARTHROPODS);
ALIASENCHANTMENTS.put("arthropod", Enchantment.DAMAGE_ARTHROPODS); ALIASENCHANTMENTS.put("arthropod", BANE_OF_ARTHROPODS);
ALIASENCHANTMENTS.put("dar", Enchantment.DAMAGE_ARTHROPODS); ALIASENCHANTMENTS.put("dar", BANE_OF_ARTHROPODS);
final Enchantment SMITE = RegistryUtil.valueOf(Enchantment.class, "DAMAGE_UNDEAD", "SMITE");
ENCHANTMENTS.put("undeaddamage", Enchantment.DAMAGE_UNDEAD); ENCHANTMENTS.put("undeaddamage", SMITE);
ENCHANTMENTS.put("smite", Enchantment.DAMAGE_UNDEAD); ENCHANTMENTS.put("smite", SMITE);
ALIASENCHANTMENTS.put("du", Enchantment.DAMAGE_UNDEAD); ALIASENCHANTMENTS.put("du", SMITE);
final Enchantment EFFICIENCY = RegistryUtil.valueOf(Enchantment.class, "DIG_SPEED", "EFFICIENCY");
ENCHANTMENTS.put("digspeed", Enchantment.DIG_SPEED); ENCHANTMENTS.put("digspeed", EFFICIENCY);
ENCHANTMENTS.put("efficiency", Enchantment.DIG_SPEED); ENCHANTMENTS.put("efficiency", EFFICIENCY);
ALIASENCHANTMENTS.put("minespeed", Enchantment.DIG_SPEED); ALIASENCHANTMENTS.put("minespeed", EFFICIENCY);
ALIASENCHANTMENTS.put("cutspeed", Enchantment.DIG_SPEED); ALIASENCHANTMENTS.put("cutspeed", EFFICIENCY);
ALIASENCHANTMENTS.put("ds", Enchantment.DIG_SPEED); ALIASENCHANTMENTS.put("ds", EFFICIENCY);
ALIASENCHANTMENTS.put("eff", Enchantment.DIG_SPEED); ALIASENCHANTMENTS.put("eff", EFFICIENCY);
final Enchantment UNBREAKING = RegistryUtil.valueOf(Enchantment.class, "DURABILITY", "UNBREAKING");
ENCHANTMENTS.put("durability", Enchantment.DURABILITY); ENCHANTMENTS.put("durability", UNBREAKING);
ALIASENCHANTMENTS.put("dura", Enchantment.DURABILITY); ALIASENCHANTMENTS.put("dura", UNBREAKING);
ENCHANTMENTS.put("unbreaking", Enchantment.DURABILITY); ENCHANTMENTS.put("unbreaking", UNBREAKING);
ALIASENCHANTMENTS.put("d", Enchantment.DURABILITY); ALIASENCHANTMENTS.put("d", UNBREAKING);
ENCHANTMENTS.put("thorns", Enchantment.THORNS); ENCHANTMENTS.put("thorns", Enchantment.THORNS);
ENCHANTMENTS.put("highcrit", Enchantment.THORNS); ENCHANTMENTS.put("highcrit", Enchantment.THORNS);
@ -59,106 +70,127 @@ public final class Enchantments {
ALIASENCHANTMENTS.put("kback", Enchantment.KNOCKBACK); ALIASENCHANTMENTS.put("kback", Enchantment.KNOCKBACK);
ALIASENCHANTMENTS.put("kb", Enchantment.KNOCKBACK); ALIASENCHANTMENTS.put("kb", Enchantment.KNOCKBACK);
ALIASENCHANTMENTS.put("k", Enchantment.KNOCKBACK); ALIASENCHANTMENTS.put("k", Enchantment.KNOCKBACK);
final Enchantment FORTUNE = RegistryUtil.valueOf(Enchantment.class, "LOOT_BONUS_BLOCKS", "FORTUNE");
ALIASENCHANTMENTS.put("blockslootbonus", Enchantment.LOOT_BONUS_BLOCKS); ALIASENCHANTMENTS.put("blockslootbonus", FORTUNE);
ENCHANTMENTS.put("fortune", Enchantment.LOOT_BONUS_BLOCKS); ENCHANTMENTS.put("fortune", FORTUNE);
ALIASENCHANTMENTS.put("fort", Enchantment.LOOT_BONUS_BLOCKS); ALIASENCHANTMENTS.put("fort", FORTUNE);
ALIASENCHANTMENTS.put("lbb", Enchantment.LOOT_BONUS_BLOCKS); ALIASENCHANTMENTS.put("lbb", FORTUNE);
final Enchantment LOOTING = RegistryUtil.valueOf(Enchantment.class, "LOOT_BONUS_MOBS", "LOOTING");
ALIASENCHANTMENTS.put("mobslootbonus", Enchantment.LOOT_BONUS_MOBS); ALIASENCHANTMENTS.put("mobslootbonus", LOOTING);
ENCHANTMENTS.put("mobloot", Enchantment.LOOT_BONUS_MOBS); ENCHANTMENTS.put("mobloot", LOOTING);
ENCHANTMENTS.put("looting", Enchantment.LOOT_BONUS_MOBS); ENCHANTMENTS.put("looting", LOOTING);
ALIASENCHANTMENTS.put("lbm", Enchantment.LOOT_BONUS_MOBS); ALIASENCHANTMENTS.put("lbm", LOOTING);
final Enchantment RESPIRATION = RegistryUtil.valueOf(Enchantment.class, "OXYGEN", "RESPIRATION");
ALIASENCHANTMENTS.put("oxygen", Enchantment.OXYGEN); ALIASENCHANTMENTS.put("oxygen", RESPIRATION);
ENCHANTMENTS.put("respiration", Enchantment.OXYGEN); ENCHANTMENTS.put("respiration", RESPIRATION);
ALIASENCHANTMENTS.put("breathing", Enchantment.OXYGEN); ALIASENCHANTMENTS.put("breathing", RESPIRATION);
ENCHANTMENTS.put("breath", Enchantment.OXYGEN); ENCHANTMENTS.put("breath", RESPIRATION);
ALIASENCHANTMENTS.put("o", Enchantment.OXYGEN); ALIASENCHANTMENTS.put("o", RESPIRATION);
final Enchantment PROTECTION = RegistryUtil.valueOf(Enchantment.class, "PROTECTION_ENVIRONMENTAL", "PROTECTION");
ENCHANTMENTS.put("protection", Enchantment.PROTECTION_ENVIRONMENTAL); ENCHANTMENTS.put("protection", PROTECTION);
ALIASENCHANTMENTS.put("prot", Enchantment.PROTECTION_ENVIRONMENTAL); ALIASENCHANTMENTS.put("prot", PROTECTION);
ENCHANTMENTS.put("protect", Enchantment.PROTECTION_ENVIRONMENTAL); ENCHANTMENTS.put("protect", PROTECTION);
ALIASENCHANTMENTS.put("p", Enchantment.PROTECTION_ENVIRONMENTAL); ALIASENCHANTMENTS.put("p", PROTECTION);
final Enchantment BLAST_PROTECTION = RegistryUtil.valueOf(Enchantment.class, "PROTECTION_EXPLOSIONS", "BLAST_PROTECTION");
ALIASENCHANTMENTS.put("explosionsprotection", Enchantment.PROTECTION_EXPLOSIONS); ALIASENCHANTMENTS.put("explosionsprotection", BLAST_PROTECTION);
ALIASENCHANTMENTS.put("explosionprotection", Enchantment.PROTECTION_EXPLOSIONS); ALIASENCHANTMENTS.put("explosionprotection", BLAST_PROTECTION);
ALIASENCHANTMENTS.put("expprot", Enchantment.PROTECTION_EXPLOSIONS); ALIASENCHANTMENTS.put("expprot", BLAST_PROTECTION);
ALIASENCHANTMENTS.put("blastprotection", Enchantment.PROTECTION_EXPLOSIONS); ALIASENCHANTMENTS.put("blastprotection", BLAST_PROTECTION);
ALIASENCHANTMENTS.put("bprotection", Enchantment.PROTECTION_EXPLOSIONS); ALIASENCHANTMENTS.put("bprotection", BLAST_PROTECTION);
ALIASENCHANTMENTS.put("bprotect", Enchantment.PROTECTION_EXPLOSIONS); ALIASENCHANTMENTS.put("bprotect", BLAST_PROTECTION);
ENCHANTMENTS.put("blastprotect", Enchantment.PROTECTION_EXPLOSIONS); ENCHANTMENTS.put("blastprotect", BLAST_PROTECTION);
ALIASENCHANTMENTS.put("pe", Enchantment.PROTECTION_EXPLOSIONS); ALIASENCHANTMENTS.put("pe", BLAST_PROTECTION);
final Enchantment FEATHER_FALLING = RegistryUtil.valueOf(Enchantment.class, "PROTECTION_FALL", "FEATHER_FALLING");
ALIASENCHANTMENTS.put("fallprotection", Enchantment.PROTECTION_FALL); ALIASENCHANTMENTS.put("fallprotection", FEATHER_FALLING);
ENCHANTMENTS.put("fallprot", Enchantment.PROTECTION_FALL); ENCHANTMENTS.put("fallprot", FEATHER_FALLING);
ENCHANTMENTS.put("featherfall", Enchantment.PROTECTION_FALL); ENCHANTMENTS.put("featherfall", FEATHER_FALLING);
ALIASENCHANTMENTS.put("featherfalling", Enchantment.PROTECTION_FALL); ALIASENCHANTMENTS.put("featherfalling", FEATHER_FALLING);
ALIASENCHANTMENTS.put("pfa", Enchantment.PROTECTION_FALL); ALIASENCHANTMENTS.put("pfa", FEATHER_FALLING);
final Enchantment FIRE_PROTECTION = RegistryUtil.valueOf(Enchantment.class, "PROTECTION_FIRE", "FIRE_PROTECTION");
ALIASENCHANTMENTS.put("fireprotection", Enchantment.PROTECTION_FIRE); ALIASENCHANTMENTS.put("fireprotection", FIRE_PROTECTION);
ALIASENCHANTMENTS.put("flameprotection", Enchantment.PROTECTION_FIRE); ALIASENCHANTMENTS.put("flameprotection", FIRE_PROTECTION);
ENCHANTMENTS.put("fireprotect", Enchantment.PROTECTION_FIRE); ENCHANTMENTS.put("fireprotect", FIRE_PROTECTION);
ALIASENCHANTMENTS.put("flameprotect", Enchantment.PROTECTION_FIRE); ALIASENCHANTMENTS.put("flameprotect", FIRE_PROTECTION);
ENCHANTMENTS.put("fireprot", Enchantment.PROTECTION_FIRE); ENCHANTMENTS.put("fireprot", FIRE_PROTECTION);
ALIASENCHANTMENTS.put("flameprot", Enchantment.PROTECTION_FIRE); ALIASENCHANTMENTS.put("flameprot", FIRE_PROTECTION);
ALIASENCHANTMENTS.put("pf", Enchantment.PROTECTION_FIRE); ALIASENCHANTMENTS.put("pf", FIRE_PROTECTION);
final Enchantment PROJECTILE_PROTECTION = RegistryUtil.valueOf(Enchantment.class, "PROTECTION_PROJECTILE", "PROJECTILE_PROTECTION");
ENCHANTMENTS.put("projectileprotection", Enchantment.PROTECTION_PROJECTILE); ENCHANTMENTS.put("projectileprotection", PROJECTILE_PROTECTION);
ENCHANTMENTS.put("projprot", Enchantment.PROTECTION_PROJECTILE); ENCHANTMENTS.put("projprot", PROJECTILE_PROTECTION);
ALIASENCHANTMENTS.put("pp", Enchantment.PROTECTION_PROJECTILE); ALIASENCHANTMENTS.put("pp", PROJECTILE_PROTECTION);
ENCHANTMENTS.put("silktouch", Enchantment.SILK_TOUCH); ENCHANTMENTS.put("silktouch", Enchantment.SILK_TOUCH);
ALIASENCHANTMENTS.put("softtouch", Enchantment.SILK_TOUCH); ALIASENCHANTMENTS.put("softtouch", Enchantment.SILK_TOUCH);
ALIASENCHANTMENTS.put("st", Enchantment.SILK_TOUCH); ALIASENCHANTMENTS.put("st", Enchantment.SILK_TOUCH);
final Enchantment AQUA_AFFINITY = RegistryUtil.valueOf(Enchantment.class, "WATER_WORKER", "AQUA_AFFINITY");
ENCHANTMENTS.put("waterworker", Enchantment.WATER_WORKER); ENCHANTMENTS.put("waterworker", AQUA_AFFINITY);
ENCHANTMENTS.put("aquaaffinity", Enchantment.WATER_WORKER); ENCHANTMENTS.put("aquaaffinity", AQUA_AFFINITY);
ALIASENCHANTMENTS.put("watermine", Enchantment.WATER_WORKER); ALIASENCHANTMENTS.put("watermine", AQUA_AFFINITY);
ALIASENCHANTMENTS.put("ww", Enchantment.WATER_WORKER); ALIASENCHANTMENTS.put("ww", AQUA_AFFINITY);
final Enchantment FLAME = RegistryUtil.valueOf(Enchantment.class, "ARROW_FIRE", "FLAME");
ALIASENCHANTMENTS.put("firearrow", Enchantment.ARROW_FIRE); ALIASENCHANTMENTS.put("firearrow", FLAME);
ENCHANTMENTS.put("flame", Enchantment.ARROW_FIRE); ENCHANTMENTS.put("flame", FLAME);
ENCHANTMENTS.put("flamearrow", Enchantment.ARROW_FIRE); ENCHANTMENTS.put("flamearrow", FLAME);
ALIASENCHANTMENTS.put("af", Enchantment.ARROW_FIRE); ALIASENCHANTMENTS.put("af", FLAME);
final Enchantment POWER = RegistryUtil.valueOf(Enchantment.class, "ARROW_DAMAGE", "POWER");
ENCHANTMENTS.put("arrowdamage", Enchantment.ARROW_DAMAGE); ENCHANTMENTS.put("arrowdamage", POWER);
ENCHANTMENTS.put("power", Enchantment.ARROW_DAMAGE); ENCHANTMENTS.put("power", POWER);
ALIASENCHANTMENTS.put("arrowpower", Enchantment.ARROW_DAMAGE); ALIASENCHANTMENTS.put("arrowpower", POWER);
ALIASENCHANTMENTS.put("ad", Enchantment.ARROW_DAMAGE); ALIASENCHANTMENTS.put("ad", POWER);
final Enchantment PUNCH = RegistryUtil.valueOf(Enchantment.class, "ARROW_KNOCKBACK", "PUNCH");
ENCHANTMENTS.put("arrowknockback", Enchantment.ARROW_KNOCKBACK); ENCHANTMENTS.put("arrowknockback", PUNCH);
ALIASENCHANTMENTS.put("arrowkb", Enchantment.ARROW_KNOCKBACK); ALIASENCHANTMENTS.put("arrowkb", PUNCH);
ENCHANTMENTS.put("punch", Enchantment.ARROW_KNOCKBACK); ENCHANTMENTS.put("punch", PUNCH);
ALIASENCHANTMENTS.put("arrowpunch", Enchantment.ARROW_KNOCKBACK); ALIASENCHANTMENTS.put("arrowpunch", PUNCH);
ALIASENCHANTMENTS.put("ak", Enchantment.ARROW_KNOCKBACK); ALIASENCHANTMENTS.put("ak", PUNCH);
final Enchantment INFINITY = RegistryUtil.valueOf(Enchantment.class, "ARROW_INFINITE", "INFINITY");
ALIASENCHANTMENTS.put("infinitearrows", Enchantment.ARROW_INFINITE); ALIASENCHANTMENTS.put("infinitearrows", INFINITY);
ENCHANTMENTS.put("infarrows", Enchantment.ARROW_INFINITE); ENCHANTMENTS.put("infarrows", INFINITY);
ENCHANTMENTS.put("infinity", Enchantment.ARROW_INFINITE); ENCHANTMENTS.put("infinity", INFINITY);
ALIASENCHANTMENTS.put("infinite", Enchantment.ARROW_INFINITE); ALIASENCHANTMENTS.put("infinite", INFINITY);
ALIASENCHANTMENTS.put("unlimited", Enchantment.ARROW_INFINITE); ALIASENCHANTMENTS.put("unlimited", INFINITY);
ALIASENCHANTMENTS.put("unlimitedarrows", Enchantment.ARROW_INFINITE); ALIASENCHANTMENTS.put("unlimitedarrows", INFINITY);
ALIASENCHANTMENTS.put("ai", Enchantment.ARROW_INFINITE); ALIASENCHANTMENTS.put("ai", INFINITY);
final Enchantment LUCK_OF_THE_SEA = RegistryUtil.valueOf(Enchantment.class, "LUCK", "LUCK_OF_THE_SEA");
ENCHANTMENTS.put("luck", Enchantment.LUCK); ENCHANTMENTS.put("luck", LUCK_OF_THE_SEA);
ALIASENCHANTMENTS.put("luckofsea", Enchantment.LUCK); ALIASENCHANTMENTS.put("luckofsea", LUCK_OF_THE_SEA);
ALIASENCHANTMENTS.put("luckofseas", Enchantment.LUCK); ALIASENCHANTMENTS.put("luckofseas", LUCK_OF_THE_SEA);
ALIASENCHANTMENTS.put("rodluck", Enchantment.LUCK); ALIASENCHANTMENTS.put("rodluck", LUCK_OF_THE_SEA);
ENCHANTMENTS.put("lure", Enchantment.LURE); ENCHANTMENTS.put("lure", Enchantment.LURE);
ALIASENCHANTMENTS.put("rodlure", Enchantment.LURE); ALIASENCHANTMENTS.put("rodlure", Enchantment.LURE);
// 1.8 ENCHANTMENTS.put("depthstrider", Enchantment.DEPTH_STRIDER);
try { ALIASENCHANTMENTS.put("depth", Enchantment.DEPTH_STRIDER);
final Enchantment depthStrider = Enchantment.getByName("DEPTH_STRIDER"); ALIASENCHANTMENTS.put("strider", Enchantment.DEPTH_STRIDER);
if (depthStrider != null) {
ENCHANTMENTS.put("depthstrider", depthStrider);
ALIASENCHANTMENTS.put("depth", depthStrider);
ALIASENCHANTMENTS.put("strider", depthStrider);
}
} catch (final IllegalArgumentException ignored) {
}
// 1.9 // 1.9
try { try {
@ -271,6 +303,24 @@ public final class Enchantments {
} catch (final IllegalArgumentException ignored) { } catch (final IllegalArgumentException ignored) {
} }
try { // 1.21
final Enchantment breach = Enchantment.getByName("BREACH");
if (breach != null) {
ENCHANTMENTS.put("breach", breach);
}
final Enchantment density = Enchantment.getByName("DENSITY");
if (density != null) {
ENCHANTMENTS.put("density", density);
}
final Enchantment windBurst = Enchantment.getByName("WIND_BURST");
if (breach != null) {
ENCHANTMENTS.put("windburst", windBurst);
ALIASENCHANTMENTS.put("wind", windBurst);
ALIASENCHANTMENTS.put("burst", windBurst);
}
} catch (final IllegalArgumentException ignored) {
}
try { try {
final Class<?> namespacedKeyClass = Class.forName("org.bukkit.NamespacedKey"); final Class<?> namespacedKeyClass = Class.forName("org.bukkit.NamespacedKey");
final Class<?> enchantmentClass = Class.forName("org.bukkit.enchantments.Enchantment"); final Class<?> enchantmentClass = Class.forName("org.bukkit.enchantments.Enchantment");
@ -284,6 +334,17 @@ public final class Enchantments {
private Enchantments() { private Enchantments() {
} }
public static String getRealName(final Enchantment enchantment) {
if (enchantment == null) {
return null;
}
if (isFlat) { // 1.13+ only
return enchantment.getKey().getKey();
}
return enchantment.getName().toLowerCase(Locale.ENGLISH);
}
public static Enchantment getByName(final String name) { public static Enchantment getByName(final String name) {
if (name == null || name.isEmpty()) { if (name == null || name.isEmpty()) {
return null; return null;

View File

@ -59,10 +59,12 @@ import net.ess3.nms.refl.providers.ReflServerStateProvider;
import net.ess3.nms.refl.providers.ReflSpawnEggProvider; import net.ess3.nms.refl.providers.ReflSpawnEggProvider;
import net.ess3.nms.refl.providers.ReflSpawnerBlockProvider; import net.ess3.nms.refl.providers.ReflSpawnerBlockProvider;
import net.ess3.nms.refl.providers.ReflSyncCommandsProvider; import net.ess3.nms.refl.providers.ReflSyncCommandsProvider;
import net.ess3.provider.BannerDataProvider;
import net.ess3.provider.BiomeKeyProvider; import net.ess3.provider.BiomeKeyProvider;
import net.ess3.provider.ContainerProvider; import net.ess3.provider.ContainerProvider;
import net.ess3.provider.DamageEventProvider; import net.ess3.provider.DamageEventProvider;
import net.ess3.provider.FormattedCommandAliasProvider; import net.ess3.provider.FormattedCommandAliasProvider;
import net.ess3.provider.InventoryViewProvider;
import net.ess3.provider.ItemUnbreakableProvider; import net.ess3.provider.ItemUnbreakableProvider;
import net.ess3.provider.KnownCommandsProvider; import net.ess3.provider.KnownCommandsProvider;
import net.ess3.provider.MaterialTagProvider; import net.ess3.provider.MaterialTagProvider;
@ -78,14 +80,17 @@ 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.ess3.provider.WorldInfoProvider; import net.ess3.provider.WorldInfoProvider;
import net.ess3.provider.providers.BaseBannerDataProvider;
import net.ess3.provider.providers.BaseInventoryViewProvider;
import net.ess3.provider.providers.BaseLoggerProvider; import net.ess3.provider.providers.BaseLoggerProvider;
import net.ess3.provider.providers.BasePotionDataProvider;
import net.ess3.provider.providers.BlockMetaSpawnerItemProvider; import net.ess3.provider.providers.BlockMetaSpawnerItemProvider;
import net.ess3.provider.providers.BukkitMaterialTagProvider; import net.ess3.provider.providers.BukkitMaterialTagProvider;
import net.ess3.provider.providers.BukkitSpawnerBlockProvider; import net.ess3.provider.providers.BukkitSpawnerBlockProvider;
import net.ess3.provider.providers.FixedHeightWorldInfoProvider; import net.ess3.provider.providers.FixedHeightWorldInfoProvider;
import net.ess3.provider.providers.FlatSpawnEggProvider; import net.ess3.provider.providers.FlatSpawnEggProvider;
import net.ess3.provider.providers.LegacyBannerDataProvider;
import net.ess3.provider.providers.LegacyDamageEventProvider; import net.ess3.provider.providers.LegacyDamageEventProvider;
import net.ess3.provider.providers.LegacyInventoryViewProvider;
import net.ess3.provider.providers.LegacyItemUnbreakableProvider; import net.ess3.provider.providers.LegacyItemUnbreakableProvider;
import net.ess3.provider.providers.LegacyPlayerLocaleProvider; import net.ess3.provider.providers.LegacyPlayerLocaleProvider;
import net.ess3.provider.providers.LegacyPotionMetaProvider; import net.ess3.provider.providers.LegacyPotionMetaProvider;
@ -95,6 +100,7 @@ import net.ess3.provider.providers.ModernDataWorldInfoProvider;
import net.ess3.provider.providers.ModernItemUnbreakableProvider; import net.ess3.provider.providers.ModernItemUnbreakableProvider;
import net.ess3.provider.providers.ModernPersistentDataProvider; import net.ess3.provider.providers.ModernPersistentDataProvider;
import net.ess3.provider.providers.ModernPlayerLocaleProvider; import net.ess3.provider.providers.ModernPlayerLocaleProvider;
import net.ess3.provider.providers.ModernPotionMetaProvider;
import net.ess3.provider.providers.ModernSignDataProvider; import net.ess3.provider.providers.ModernSignDataProvider;
import net.ess3.provider.providers.PaperBiomeKeyProvider; import net.ess3.provider.providers.PaperBiomeKeyProvider;
import net.ess3.provider.providers.PaperContainerProvider; import net.ess3.provider.providers.PaperContainerProvider;
@ -103,6 +109,7 @@ import net.ess3.provider.providers.PaperMaterialTagProvider;
import net.ess3.provider.providers.PaperRecipeBookListener; 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.ess3.provider.providers.PrehistoricPotionMetaProvider;
import net.essentialsx.api.v2.services.BalanceTop; import net.essentialsx.api.v2.services.BalanceTop;
import net.essentialsx.api.v2.services.mail.MailService; import net.essentialsx.api.v2.services.mail.MailService;
import net.kyori.adventure.platform.bukkit.BukkitAudiences; import net.kyori.adventure.platform.bukkit.BukkitAudiences;
@ -126,6 +133,7 @@ import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerEvent; import org.bukkit.event.player.PlayerEvent;
import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.world.WorldLoadEvent; import org.bukkit.event.world.WorldLoadEvent;
import org.bukkit.inventory.InventoryView;
import org.bukkit.plugin.InvalidDescriptionException; import org.bukkit.plugin.InvalidDescriptionException;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.plugin.PluginDescriptionFile;
@ -146,6 +154,7 @@ import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.MissingResourceException;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.function.Predicate; import java.util.function.Predicate;
@ -158,6 +167,7 @@ import static com.earth2me.essentials.I18n.tlLocale;
public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials { public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
private static final Logger BUKKIT_LOGGER = Logger.getLogger("Essentials"); private static final Logger BUKKIT_LOGGER = Logger.getLogger("Essentials");
private static Logger LOGGER = null; private static Logger LOGGER = null;
public static boolean TESTING = false;
private final transient TNTExplodeListener tntListener = new TNTExplodeListener(); private final transient TNTExplodeListener tntListener = new TNTExplodeListener();
private final transient Set<String> vanishedPlayers = new LinkedHashSet<>(); private final transient Set<String> vanishedPlayers = new LinkedHashSet<>();
private final transient Map<String, IEssentialsCommand> commandMap = new HashMap<>(); private final transient Map<String, IEssentialsCommand> commandMap = new HashMap<>();
@ -184,6 +194,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
private transient SpawnerBlockProvider spawnerBlockProvider; private transient SpawnerBlockProvider spawnerBlockProvider;
private transient SpawnEggProvider spawnEggProvider; private transient SpawnEggProvider spawnEggProvider;
private transient PotionMetaProvider potionMetaProvider; private transient PotionMetaProvider potionMetaProvider;
private transient BannerDataProvider bannerDataProvider;
private transient ServerStateProvider serverStateProvider; private transient ServerStateProvider serverStateProvider;
private transient ContainerProvider containerProvider; private transient ContainerProvider containerProvider;
private transient SerializationProvider serializationProvider; private transient SerializationProvider serializationProvider;
@ -200,6 +211,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
private transient SignDataProvider signDataProvider; private transient SignDataProvider signDataProvider;
private transient DamageEventProvider damageEventProvider; private transient DamageEventProvider damageEventProvider;
private transient BiomeKeyProvider biomeKeyProvider; private transient BiomeKeyProvider biomeKeyProvider;
private transient InventoryViewProvider inventoryViewProvider;
private transient Kits kits; private transient Kits kits;
private transient RandomTeleport randomTeleport; private transient RandomTeleport randomTeleport;
private transient UpdateChecker updateChecker; private transient UpdateChecker updateChecker;
@ -226,6 +238,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
} }
public void setupForTesting(final Server server) throws IOException, InvalidDescriptionException { public void setupForTesting(final Server server) throws IOException, InvalidDescriptionException {
TESTING = true;
LOGGER = new BaseLoggerProvider(this, BUKKIT_LOGGER); LOGGER = new BaseLoggerProvider(this, BUKKIT_LOGGER);
final File dataFolder = File.createTempFile("essentialstest", ""); final File dataFolder = File.createTempFile("essentialstest", "");
if (!dataFolder.delete()) { if (!dataFolder.delete()) {
@ -345,6 +358,10 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
upgrade.convertKits(); upgrade.convertKits();
execTimer.mark("Kits"); execTimer.mark("Kits");
randomTeleport = new RandomTeleport(this);
confList.add(randomTeleport);
execTimer.mark("Init(RandomTeleport)");
upgrade.afterSettings(); upgrade.afterSettings();
execTimer.mark("Upgrade3"); execTimer.mark("Upgrade3");
@ -360,13 +377,6 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
confList.add(itemDb); confList.add(itemDb);
execTimer.mark("Init(ItemDB)"); execTimer.mark("Init(ItemDB)");
randomTeleport = new RandomTeleport(this);
if (randomTeleport.getPreCache()) {
randomTeleport.cacheRandomLocations(randomTeleport.getCenter(), randomTeleport.getMinRange(), randomTeleport.getMaxRange());
}
confList.add(randomTeleport);
execTimer.mark("Init(RandomTeleport)");
customItemResolver = new CustomItemResolver(this); customItemResolver = new CustomItemResolver(this);
try { try {
itemDb.registerResolver(this, "custom_items", customItemResolver); itemDb.registerResolver(this, "custom_items", customItemResolver);
@ -403,10 +413,19 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
} }
//Potion Meta Provider //Potion Meta Provider
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_9_R01)) { if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_20_6_R01)) {
potionMetaProvider = new LegacyPotionMetaProvider(); potionMetaProvider = new ModernPotionMetaProvider();
} else if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_9_R01)) {
potionMetaProvider = new PrehistoricPotionMetaProvider();
} else { } else {
potionMetaProvider = new BasePotionDataProvider(); potionMetaProvider = new LegacyPotionMetaProvider();
}
//Banner Meta Provider
if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_20_6_R01)) {
bannerDataProvider = new BaseBannerDataProvider();
} else {
bannerDataProvider = new LegacyBannerDataProvider();
} }
//Server State Provider //Server State Provider
@ -488,6 +507,12 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
damageEventProvider = new LegacyDamageEventProvider(); damageEventProvider = new LegacyDamageEventProvider();
} }
if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_21_R01)) {
inventoryViewProvider = new BaseInventoryViewProvider();
} else {
inventoryViewProvider = new LegacyInventoryViewProvider();
}
if (PaperLib.isPaper() && VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_19_4_R01)) { if (PaperLib.isPaper() && VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_19_4_R01)) {
biomeKeyProvider = new PaperBiomeKeyProvider(); biomeKeyProvider = new PaperBiomeKeyProvider();
} }
@ -785,7 +810,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
} catch (final Exception ex) { } catch (final Exception ex) {
LOGGER.log(Level.SEVERE, ex.getMessage(), ex); LOGGER.log(Level.SEVERE, ex.getMessage(), ex);
if (cSender instanceof Player) { if (cSender instanceof Player) {
cSender.sendMessage(tlLocale(I18n.getLocale(getPlayerLocaleProvider().getLocale((Player) cSender)), "internalError")); getBukkitAudience().sender(cSender).sendMessage(AdventureUtil.miniMessage().deserialize(tlLocale(I18n.getLocale(getPlayerLocaleProvider().getLocale((Player) cSender)), "internalError")));
} else { } else {
cSender.sendMessage(tlLiteral("internalError")); cSender.sendMessage(tlLiteral("internalError"));
} }
@ -876,7 +901,11 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
} catch (final NotEnoughArgumentsException ex) { } catch (final NotEnoughArgumentsException ex) {
if (getSettings().isVerboseCommandUsages() && !cmd.getUsageStrings().isEmpty()) { if (getSettings().isVerboseCommandUsages() && !cmd.getUsageStrings().isEmpty()) {
sender.sendTl("commandHelpLine1", commandLabel); sender.sendTl("commandHelpLine1", commandLabel);
sender.sendTl("commandHelpLine2", command.getDescription()); String description = command.getDescription();
try {
description = sender.tl(command.getName() + "CommandDescription");
} catch (MissingResourceException ignored) {}
sender.sendTl("commandHelpLine2", description);
sender.sendTl("commandHelpLine3"); sender.sendTl("commandHelpLine3");
for (Map.Entry<String, String> usage : cmd.getUsageStrings().entrySet()) { for (Map.Entry<String, String> usage : cmd.getUsageStrings().entrySet()) {
sender.sendTl("commandHelpLineUsage", AdventureUtil.parsed(usage.getKey().replace("<command>", commandLabel)), AdventureUtil.parsed(usage.getValue())); sender.sendTl("commandHelpLineUsage", AdventureUtil.parsed(usage.getKey().replace("<command>", commandLabel)), AdventureUtil.parsed(usage.getValue()));
@ -912,12 +941,14 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
public void cleanupOpenInventories() { public void cleanupOpenInventories() {
for (final User user : getOnlineUsers()) { for (final User user : getOnlineUsers()) {
if (user.isRecipeSee()) { if (user.isRecipeSee()) {
user.getBase().getOpenInventory().getTopInventory().clear(); final InventoryView view = user.getBase().getOpenInventory();
user.getBase().getOpenInventory().close();
inventoryViewProvider.getTopInventory(view).clear();
inventoryViewProvider.close(view);
user.setRecipeSee(false); user.setRecipeSee(false);
} }
if (user.isInvSee() || user.isEnderSee()) { if (user.isInvSee() || user.isEnderSee()) {
user.getBase().getOpenInventory().close(); inventoryViewProvider.close(user.getBase().getOpenInventory());
user.setInvSee(false); user.setInvSee(false);
user.setEnderSee(false); user.setEnderSee(false);
} }
@ -1200,7 +1231,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
@Override @Override
public void broadcastTl(final String tlKey, final Object... args) { public void broadcastTl(final String tlKey, final Object... args) {
broadcastTl(null, null, true, tlKey, args); broadcastTl(null, null, false, tlKey, args);
} }
@Override @Override
@ -1364,6 +1395,16 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
return potionMetaProvider; return potionMetaProvider;
} }
@Override
public BannerDataProvider getBannerDataProvider() {
return bannerDataProvider;
}
@Override
public InventoryViewProvider getInventoryViewProvider() {
return inventoryViewProvider;
}
@Override @Override
public CustomItemResolver getCustomItemResolver() { public CustomItemResolver getCustomItemResolver() {
return customItemResolver; return customItemResolver;

View File

@ -299,7 +299,7 @@ public class EssentialsPlayerListener implements Listener, FakeAccessor {
} }
user.setLogoutLocation(); user.setLogoutLocation();
if (user.isRecipeSee()) { if (user.isRecipeSee()) {
user.getBase().getOpenInventory().getTopInventory().clear(); ess.getInventoryViewProvider().getTopInventory(user.getBase().getOpenInventory()).clear();
} }
final ArrayList<HumanEntity> viewers = new ArrayList<>(user.getBase().getInventory().getViewers()); final ArrayList<HumanEntity> viewers = new ArrayList<>(user.getBase().getInventory().getViewers());
@ -545,14 +545,14 @@ public class EssentialsPlayerListener implements Listener, FakeAccessor {
final Date banExpiry = banEntry.getExpiration(); final Date banExpiry = banEntry.getExpiration();
if (banExpiry != null) { if (banExpiry != null) {
final String expiry = DateUtil.formatDateDiff(banExpiry.getTime()); final String expiry = DateUtil.formatDateDiff(banExpiry.getTime());
event.setKickMessage(tlLiteral("tempbanJoin", expiry, banEntry.getReason())); event.setKickMessage(AdventureUtil.miniToLegacy(tlLiteral("tempbanJoin", expiry, banEntry.getReason())));
} else { } else {
event.setKickMessage(tlLiteral("banJoin", banEntry.getReason())); event.setKickMessage(AdventureUtil.miniToLegacy(tlLiteral("banJoin", banEntry.getReason())));
} }
} else { } else {
banEntry = ess.getServer().getBanList(BanList.Type.IP).getBanEntry(event.getAddress().getHostAddress()); banEntry = ess.getServer().getBanList(BanList.Type.IP).getBanEntry(event.getAddress().getHostAddress());
if (banEntry != null) { if (banEntry != null) {
event.setKickMessage(tlLiteral("banIpJoin", banEntry.getReason())); event.setKickMessage(AdventureUtil.miniToLegacy(tlLiteral("banIpJoin", banEntry.getReason())));
} }
} }
} }
@ -609,7 +609,7 @@ public class EssentialsPlayerListener implements Listener, FakeAccessor {
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onPlayerCommandPreprocess(final PlayerCommandPreprocessEvent event) { public void onPlayerCommandPreprocess(final PlayerCommandPreprocessEvent event) {
final String cmd = event.getMessage().toLowerCase(Locale.ENGLISH).split(" ")[0].replace("/", "").toLowerCase(Locale.ENGLISH); final String cmd = event.getMessage().split(" ")[0].replace("/", "").toLowerCase(Locale.ENGLISH);
final int argStartIndex = event.getMessage().indexOf(" "); final int argStartIndex = event.getMessage().indexOf(" ");
final String args = argStartIndex == -1 ? "" // No arguments present final String args = argStartIndex == -1 ? "" // No arguments present
: event.getMessage().substring(argStartIndex); // arguments start at argStartIndex; substring from there. : event.getMessage().substring(argStartIndex); // arguments start at argStartIndex; substring from there.
@ -632,7 +632,7 @@ public class EssentialsPlayerListener implements Listener, FakeAccessor {
public void handlePlayerCommandPreprocess(final PlayerCommandPreprocessEvent event, final String effectiveCommand) { public void handlePlayerCommandPreprocess(final PlayerCommandPreprocessEvent event, final String effectiveCommand) {
final Player player = event.getPlayer(); final Player player = event.getPlayer();
final String cmd = effectiveCommand.toLowerCase(Locale.ENGLISH).split(" ")[0].replace("/", "").toLowerCase(Locale.ENGLISH); final String cmd = effectiveCommand.split(" ")[0].replace("/", "").toLowerCase(Locale.ENGLISH);
final PluginCommand pluginCommand = ess.getServer().getPluginCommand(cmd); final PluginCommand pluginCommand = ess.getServer().getPluginCommand(cmd);
if (ess.getSettings().getSocialSpyCommands().contains(cmd) || ess.getSettings().getSocialSpyCommands().contains("*")) { if (ess.getSettings().getSocialSpyCommands().contains(cmd) || ess.getSettings().getSocialSpyCommands().contains("*")) {
@ -640,12 +640,13 @@ public class EssentialsPlayerListener implements Listener, FakeAccessor {
|| (!pluginCommand.getName().equals("msg") && !pluginCommand.getName().equals("r"))) { // /msg and /r are handled in SimpleMessageRecipient || (!pluginCommand.getName().equals("msg") && !pluginCommand.getName().equals("r"))) { // /msg and /r are handled in SimpleMessageRecipient
final User user = ess.getUser(player); final User user = ess.getUser(player);
if (!user.isAuthorized("essentials.chat.spy.exempt")) { if (!user.isAuthorized("essentials.chat.spy.exempt")) {
final String playerName = ess.getSettings().isSocialSpyDisplayNames() ? player.getDisplayName() : player.getName();
for (final User spyer : ess.getOnlineUsers()) { for (final User spyer : ess.getOnlineUsers()) {
if (spyer.isSocialSpyEnabled() && !player.equals(spyer.getBase())) { if (spyer.isSocialSpyEnabled() && !player.equals(spyer.getBase())) {
final Component base = (user.isMuted() && ess.getSettings().getSocialSpyListenMutedPlayers()) final Component base = (user.isMuted() && ess.getSettings().getSocialSpyListenMutedPlayers())
? spyer.tlComponent("socialSpyMutedPrefix") ? spyer.tlComponent("socialSpyMutedPrefix")
: spyer.tlComponent("socialSpyPrefix"); : spyer.tlComponent("socialSpyPrefix");
spyer.sendComponent(base.append(AdventureUtil.legacyToAdventure(player.getDisplayName())).append(Component.text(": " + event.getMessage()))); spyer.sendComponent(base.append(AdventureUtil.legacyToAdventure(playerName)).append(Component.text(": " + event.getMessage())));
} }
} }
} }
@ -896,14 +897,14 @@ public class EssentialsPlayerListener implements Listener, FakeAccessor {
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onInventoryClickEvent(final InventoryClickEvent event) { public void onInventoryClickEvent(final InventoryClickEvent event) {
Player refreshPlayer = null; Player refreshPlayer = null;
final Inventory top = event.getView().getTopInventory(); final Inventory top = ess.getInventoryViewProvider().getTopInventory(event.getView());
final InventoryType type = top.getType(); final InventoryType type = top.getType();
final Inventory clickedInventory; final Inventory clickedInventory;
if (event.getRawSlot() < 0) { if (event.getRawSlot() < 0) {
clickedInventory = null; clickedInventory = null;
} else { } else {
clickedInventory = event.getRawSlot() < top.getSize() ? top : event.getView().getBottomInventory(); clickedInventory = event.getRawSlot() < top.getSize() ? top : ess.getInventoryViewProvider().getBottomInventory(event.getView());
} }
final User user = ess.getUser((Player) event.getWhoClicked()); final User user = ess.getUser((Player) event.getWhoClicked());
@ -962,7 +963,7 @@ public class EssentialsPlayerListener implements Listener, FakeAccessor {
@EventHandler(priority = EventPriority.MONITOR) @EventHandler(priority = EventPriority.MONITOR)
public void onInventoryCloseEvent(final InventoryCloseEvent event) { public void onInventoryCloseEvent(final InventoryCloseEvent event) {
Player refreshPlayer = null; Player refreshPlayer = null;
final Inventory top = event.getView().getTopInventory(); final Inventory top = ess.getInventoryViewProvider().getTopInventory(event.getView());
final InventoryType type = top.getType(); final InventoryType type = top.getType();
if (type == InventoryType.PLAYER) { if (type == InventoryType.PLAYER) {
final User user = ess.getUser((Player) event.getPlayer()); final User user = ess.getUser((Player) event.getPlayer());
@ -976,7 +977,7 @@ public class EssentialsPlayerListener implements Listener, FakeAccessor {
final User user = ess.getUser((Player) event.getPlayer()); final User user = ess.getUser((Player) event.getPlayer());
if (user.isRecipeSee()) { if (user.isRecipeSee()) {
user.setRecipeSee(false); user.setRecipeSee(false);
event.getView().getTopInventory().clear(); ess.getInventoryViewProvider().getTopInventory(event.getView()).clear();
refreshPlayer = user.getBase(); refreshPlayer = user.getBase();
} }
} else if (type == InventoryType.CHEST && top.getSize() == 9) { } else if (type == InventoryType.CHEST && top.getSize() == 9) {

View File

@ -3,6 +3,7 @@ package com.earth2me.essentials;
import com.earth2me.essentials.config.ConfigurateUtil; import com.earth2me.essentials.config.ConfigurateUtil;
import com.earth2me.essentials.config.EssentialsConfiguration; import com.earth2me.essentials.config.EssentialsConfiguration;
import com.earth2me.essentials.config.EssentialsUserConfiguration; import com.earth2me.essentials.config.EssentialsUserConfiguration;
import com.earth2me.essentials.config.entities.LazyLocation;
import com.earth2me.essentials.craftbukkit.BanLookup; import com.earth2me.essentials.craftbukkit.BanLookup;
import com.earth2me.essentials.userstorage.ModernUUIDCache; import com.earth2me.essentials.userstorage.ModernUUIDCache;
import com.earth2me.essentials.utils.AdventureUtil; import com.earth2me.essentials.utils.AdventureUtil;
@ -156,6 +157,39 @@ 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 updateRandomTeleport() {
if (doneFile.getBoolean("updateRandomTeleport", false)) {
return;
}
final EssentialsConfiguration config = ess.getRandomTeleport().getConfig();
final LazyLocation center = config.getLocation("center");
final Location centerLoc = center != null ? center.location() : null;
if (center != null && centerLoc != null) {
final double minRange = config.getDouble("min-range", Double.MIN_VALUE);
final double maxRange = config.getDouble("max-range", Double.MIN_VALUE);
for (final World world : ess.getServer().getWorlds()) {
final String propPrefix = "locations." + world.getName() + ".";
config.setProperty(propPrefix + "center", centerLoc);
if (minRange != Double.MIN_VALUE) {
config.setProperty(propPrefix + "min-range", minRange);
}
if (maxRange != Double.MIN_VALUE) {
config.setProperty(propPrefix + "max-range", maxRange);
}
}
}
config.removeProperty("center");
config.blockingSave();
doneFile.setProperty("updateRandomTeleport", true);
doneFile.save();
ess.getLogger().info("Done converting random teleport config.");
}
public void convertMailList() { public void convertMailList() {
if (doneFile.getBoolean("updateUsersMailList", false)) { if (doneFile.getBoolean("updateUsersMailList", false)) {
return; return;
@ -1068,5 +1102,6 @@ public class EssentialsUpgrade {
convertStupidCamelCaseUserdataKeys(); convertStupidCamelCaseUserdataKeys();
convertMailList(); convertMailList();
purgeBrokenNpcAccounts(); purgeBrokenNpcAccounts();
updateRandomTeleport();
} }
} }

View File

@ -9,10 +9,12 @@ import com.earth2me.essentials.perm.PermissionsHandler;
import com.earth2me.essentials.updatecheck.UpdateChecker; import com.earth2me.essentials.updatecheck.UpdateChecker;
import com.earth2me.essentials.userstorage.IUserMap; import com.earth2me.essentials.userstorage.IUserMap;
import net.ess3.nms.refl.providers.ReflOnlineModeProvider; import net.ess3.nms.refl.providers.ReflOnlineModeProvider;
import net.ess3.provider.BannerDataProvider;
import net.ess3.provider.BiomeKeyProvider; import net.ess3.provider.BiomeKeyProvider;
import net.ess3.provider.ContainerProvider; import net.ess3.provider.ContainerProvider;
import net.ess3.provider.DamageEventProvider; import net.ess3.provider.DamageEventProvider;
import net.ess3.provider.FormattedCommandAliasProvider; import net.ess3.provider.FormattedCommandAliasProvider;
import net.ess3.provider.InventoryViewProvider;
import net.ess3.provider.ItemUnbreakableProvider; import net.ess3.provider.ItemUnbreakableProvider;
import net.ess3.provider.KnownCommandsProvider; import net.ess3.provider.KnownCommandsProvider;
import net.ess3.provider.MaterialTagProvider; import net.ess3.provider.MaterialTagProvider;
@ -189,5 +191,9 @@ public interface IEssentials extends Plugin {
BiomeKeyProvider getBiomeKeyProvider(); BiomeKeyProvider getBiomeKeyProvider();
BannerDataProvider getBannerDataProvider();
InventoryViewProvider getInventoryViewProvider();
PluginCommand getPluginCommand(String cmd); PluginCommand getPluginCommand(String cmd);
} }

View File

@ -73,6 +73,8 @@ public interface ISettings extends IConf {
boolean isSocialSpyMessages(); boolean isSocialSpyMessages();
boolean isSocialSpyDisplayNames();
Set<String> getMuteCommands(); Set<String> getMuteCommands();
@Deprecated @Deprecated
@ -104,6 +106,10 @@ public interface ISettings extends IConf {
boolean getRespawnAtHome(); boolean getRespawnAtHome();
String getRandomSpawnLocation();
String getRandomRespawnLocation();
boolean isRespawnAtAnchor(); boolean isRespawnAtAnchor();
Set getMultipleHomes(); Set getMultipleHomes();

View File

@ -30,7 +30,6 @@ import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.LeatherArmorMeta; import org.bukkit.inventory.meta.LeatherArmorMeta;
import org.bukkit.inventory.meta.PotionMeta; import org.bukkit.inventory.meta.PotionMeta;
import org.bukkit.inventory.meta.SkullMeta; import org.bukkit.inventory.meta.SkullMeta;
import org.bukkit.potion.Potion;
import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType; import org.bukkit.potion.PotionEffectType;
@ -130,21 +129,30 @@ public class MetaItemStack {
} }
public boolean canSpawn(final IEssentials ess) { public boolean canSpawn(final IEssentials ess) {
try { if (VersionUtil.PRE_FLATTENING) {
ess.getServer().getUnsafe().modifyItemStack(stack.clone(), "{}"); try {
return true; ess.getServer().getUnsafe().modifyItemStack(stack.clone(), "{}");
} catch (final NoSuchMethodError nsme) { return true;
return true; } catch (final NoSuchMethodError nsme) {
} catch (final Throwable npe) { return true;
if (ess.getSettings().isDebug()) { } catch (final Throwable npe) {
ess.getLogger().log(Level.INFO, "Itemstack is invalid", npe); if (ess.getSettings().isDebug()) {
ess.getLogger().log(Level.INFO, "Itemstack is invalid", npe);
}
return false;
} }
return false;
} }
return stack.getType().isItem();
} }
public void parseStringMeta(final CommandSource sender, final boolean allowUnsafe, final String[] string, final int fromArg, final IEssentials ess) throws Exception { public void parseStringMeta(final CommandSource sender, final boolean allowUnsafe, final String[] string, final int fromArg, final IEssentials ess) throws Exception {
final boolean nbtIsKill = VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_20_6_R01);
if (string[fromArg].startsWith("{") && hasMetaPermission(sender, "vanilla", false, true, ess)) { if (string[fromArg].startsWith("{") && hasMetaPermission(sender, "vanilla", false, true, ess)) {
if (nbtIsKill) {
throw new TranslatableException("noMetaNbtKill");
}
try { try {
stack = ess.getServer().getUnsafe().modifyItemStack(stack, Joiner.on(' ').join(Arrays.asList(string).subList(fromArg, string.length))); stack = ess.getServer().getUnsafe().modifyItemStack(stack, Joiner.on(' ').join(Arrays.asList(string).subList(fromArg, string.length)));
} catch (final NullPointerException npe) { } catch (final NullPointerException npe) {
@ -156,6 +164,22 @@ public class MetaItemStack {
} catch (final Throwable throwable) { } catch (final Throwable throwable) {
throw new Exception(throwable.getMessage(), throwable); throw new Exception(throwable.getMessage(), throwable);
} }
} else if (string[fromArg].startsWith("[") && hasMetaPermission(sender, "vanilla", false, true, ess)) {
if (!nbtIsKill) {
throw new TranslatableException("noMetaComponents");
}
try {
final String components = Joiner.on(' ').join(Arrays.asList(string).subList(fromArg, string.length));
// modifyItemStack requires that the item namespaced key is prepended to the components for some reason
stack = ess.getServer().getUnsafe().modifyItemStack(stack, stack.getType().getKey() + components);
} catch (final NullPointerException npe) {
if (ess.getSettings().isDebug()) {
ess.getLogger().log(Level.INFO, "Itemstack is invalid", npe);
}
} catch (final Throwable throwable) {
throw new Exception(throwable.getMessage(), throwable);
}
} else { } else {
for (int i = fromArg; i < string.length; i++) { for (int i = fromArg; i < string.length; i++) {
addStringMeta(sender, allowUnsafe, string[i], ess); addStringMeta(sender, allowUnsafe, string[i], ess);
@ -541,17 +565,7 @@ public class MetaItemStack {
} }
pmeta.addCustomEffect(pEffect, true); pmeta.addCustomEffect(pEffect, true);
stack.setItemMeta(pmeta); stack.setItemMeta(pmeta);
if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_9_R01)) { ess.getPotionMetaProvider().setSplashPotion(stack, isSplashPotion);
if (isSplashPotion && stack.getType() == Material.POTION) {
stack.setType(Material.SPLASH_POTION);
} else if (!isSplashPotion && stack.getType() == Material.SPLASH_POTION) {
stack.setType(Material.POTION);
}
} else {
final Potion potion = Potion.fromDamage(stack.getDurability());
potion.setSplash(isSplashPotion);
potion.apply(stack);
}
resetPotionMeta(); resetPotionMeta();
} }
} }
@ -562,7 +576,7 @@ public class MetaItemStack {
if (enchantment == null) { if (enchantment == null) {
return false; return false;
} }
if (hasMetaPermission(sender, "enchantments." + enchantment.getName().toLowerCase(Locale.ENGLISH), false, false, ess)) { if (hasMetaPermission(sender, "enchantments." + Enchantments.getRealName(enchantment), false, false, ess)) {
int level = -1; int level = -1;
if (split.length > 1) { if (split.length > 1) {
try { try {
@ -605,7 +619,7 @@ public class MetaItemStack {
} }
} }
} catch (final Exception ex) { } catch (final Exception ex) {
throw new Exception("Enchantment " + enchantment.getName() + ": " + ex.getMessage(), ex); throw new Exception("Enchantment " + Enchantments.getRealName(enchantment) + ": " + ex.getMessage(), ex);
} }
} }
@ -615,7 +629,7 @@ public class MetaItemStack {
return null; return null;
} }
final String enchantmentName = enchantment.getName().toLowerCase(Locale.ENGLISH); final String enchantmentName = Enchantments.getRealName(enchantment);
if (!hasMetaPermission(user, "enchantments." + enchantmentName, true, false)) { if (!hasMetaPermission(user, "enchantments." + enchantmentName, true, false)) {
throw new TranslatableException("enchantmentPerm", enchantmentName); throw new TranslatableException("enchantmentPerm", enchantmentName);
@ -633,16 +647,18 @@ public class MetaItemStack {
PatternType patternType = null; PatternType patternType = null;
try { try {
patternType = PatternType.valueOf(split[0]); //noinspection removal
patternType = PatternType.getByIdentifier(split[0]);
} catch (final Exception ignored) { } catch (final Exception ignored) {
} }
final BannerMeta meta = (BannerMeta) stack.getItemMeta(); final BannerMeta meta = (BannerMeta) stack.getItemMeta();
if (split[0].equalsIgnoreCase("basecolor")) { if (split[0].equalsIgnoreCase("basecolor")) {
final Color color = Color.fromRGB(Integer.parseInt(split[1])); final Color color = Color.fromRGB(Integer.parseInt(split[1]));
meta.setBaseColor(DyeColor.getByColor(color)); ess.getBannerDataProvider().setBaseColor(stack, DyeColor.getByColor(color));
} else if (patternType != null) { } else if (patternType != null) {
final PatternType type = PatternType.valueOf(split[0]); //noinspection removal
final PatternType type = PatternType.getByIdentifier(split[0]);
final DyeColor color = DyeColor.getByColor(Color.fromRGB(Integer.parseInt(split[1]))); final DyeColor color = DyeColor.getByColor(Color.fromRGB(Integer.parseInt(split[1])));
final org.bukkit.block.banner.Pattern pattern = new org.bukkit.block.banner.Pattern(color, type); final org.bukkit.block.banner.Pattern pattern = new org.bukkit.block.banner.Pattern(color, type);
meta.addPattern(pattern); meta.addPattern(pattern);
@ -658,7 +674,8 @@ public class MetaItemStack {
PatternType patternType = null; PatternType patternType = null;
try { try {
patternType = PatternType.valueOf(split[0]); //noinspection removal
patternType = PatternType.getByIdentifier(split[0]);
} catch (final Exception ignored) { } catch (final Exception ignored) {
} }
@ -669,7 +686,8 @@ public class MetaItemStack {
final Color color = Color.fromRGB(Integer.parseInt(split[1])); final Color color = Color.fromRGB(Integer.parseInt(split[1]));
banner.setBaseColor(DyeColor.getByColor(color)); banner.setBaseColor(DyeColor.getByColor(color));
} else if (patternType != null) { } else if (patternType != null) {
final PatternType type = PatternType.valueOf(split[0]); //noinspection removal
final PatternType type = PatternType.getByIdentifier(split[0]);
final DyeColor color = DyeColor.getByColor(Color.fromRGB(Integer.parseInt(split[1]))); final DyeColor color = DyeColor.getByColor(Color.fromRGB(Integer.parseInt(split[1])));
final org.bukkit.block.banner.Pattern pattern = new org.bukkit.block.banner.Pattern(color, type); final org.bukkit.block.banner.Pattern pattern = new org.bukkit.block.banner.Pattern(color, type);
banner.addPattern(pattern); banner.addPattern(pattern);

View File

@ -42,22 +42,30 @@ public enum Mob {
ENDERDRAGON("EnderDragon", Enemies.ENEMY, EntityType.ENDER_DRAGON), ENDERDRAGON("EnderDragon", Enemies.ENEMY, EntityType.ENDER_DRAGON),
VILLAGER("Villager", Enemies.FRIENDLY, EntityType.VILLAGER), VILLAGER("Villager", Enemies.FRIENDLY, EntityType.VILLAGER),
BLAZE("Blaze", Enemies.ENEMY, EntityType.BLAZE), BLAZE("Blaze", Enemies.ENEMY, EntityType.BLAZE),
MUSHROOMCOW("MushroomCow", Enemies.FRIENDLY, EntityType.MUSHROOM_COW), MUSHROOMCOW("MushroomCow", Enemies.FRIENDLY, MobCompat.MOOSHROOM),
MAGMACUBE("MagmaCube", Enemies.ENEMY, EntityType.MAGMA_CUBE), MAGMACUBE("MagmaCube", Enemies.ENEMY, EntityType.MAGMA_CUBE),
SNOWMAN("Snowman", Enemies.FRIENDLY, "", EntityType.SNOWMAN), SNOWMAN("Snowman", Enemies.FRIENDLY, "", MobCompat.SNOW_GOLEM),
OCELOT("Ocelot", Enemies.NEUTRAL, EntityType.OCELOT), OCELOT("Ocelot", Enemies.NEUTRAL, EntityType.OCELOT),
IRONGOLEM("IronGolem", Enemies.NEUTRAL, EntityType.IRON_GOLEM), IRONGOLEM("IronGolem", Enemies.NEUTRAL, EntityType.IRON_GOLEM),
WITHER("Wither", Enemies.ENEMY, EntityType.WITHER), WITHER("Wither", Enemies.ENEMY, EntityType.WITHER),
BAT("Bat", Enemies.FRIENDLY, EntityType.BAT), BAT("Bat", Enemies.FRIENDLY, EntityType.BAT),
WITCH("Witch", Enemies.ENEMY, EntityType.WITCH), WITCH("Witch", Enemies.ENEMY, EntityType.WITCH),
BOAT("Boat", Enemies.NEUTRAL, EntityType.BOAT), BOAT("Boat", Enemies.NEUTRAL, MobCompat.OAK_BOAT),
ACACIA_BOAT("AcaciaBoat", Enemies.NEUTRAL, "ACACIA_BOAT"),
DARK_OAK_BOAT("DarkOakBoat", Enemies.NEUTRAL, "DARK_OAK_BOAT"),
BIRCH_BOAT("BirchBoat", Enemies.NEUTRAL, "BIRCH_BOAT"),
JUNGLE_BOAT("JungleBoat", Enemies.NEUTRAL, "JUNGLE_BOAT"),
SPRUCE_BOAT("SpruceBoat", Enemies.NEUTRAL, "SPRUCE_BOAT"),
MANGROVE_BOAT("MangroveBoat", Enemies.NEUTRAL, "MANGROVE_BOAT"),
CHERRY_BOAT("CherryBoat", Enemies.NEUTRAL, "CHERRY_BOAT"),
BAMBOO_RAFT("BambooRaft", Enemies.NEUTRAL, "BAMBOO_RAFT"),
MINECART("Minecart", Enemies.NEUTRAL, EntityType.MINECART), MINECART("Minecart", Enemies.NEUTRAL, EntityType.MINECART),
MINECART_CHEST("ChestMinecart", Enemies.NEUTRAL, EntityType.MINECART_CHEST), MINECART_CHEST("ChestMinecart", Enemies.NEUTRAL, MobCompat.CHEST_MINECART),
MINECART_FURNACE("FurnaceMinecart", Enemies.NEUTRAL, EntityType.MINECART_FURNACE), MINECART_FURNACE("FurnaceMinecart", Enemies.NEUTRAL, MobCompat.FURNACE_MINECART),
MINECART_TNT("TNTMinecart", Enemies.NEUTRAL, EntityType.MINECART_TNT), MINECART_TNT("TNTMinecart", Enemies.NEUTRAL, MobCompat.TNT_MINECART),
MINECART_HOPPER("HopperMinecart", Enemies.NEUTRAL, EntityType.MINECART_HOPPER), MINECART_HOPPER("HopperMinecart", Enemies.NEUTRAL, MobCompat.HOPPER_MINECART),
MINECART_MOB_SPAWNER("SpawnerMinecart", Enemies.NEUTRAL, EntityType.MINECART_MOB_SPAWNER), MINECART_MOB_SPAWNER("SpawnerMinecart", Enemies.NEUTRAL, MobCompat.SPAWNER_MINECART),
ENDERCRYSTAL("EnderCrystal", Enemies.NEUTRAL, EntityType.ENDER_CRYSTAL), ENDERCRYSTAL("EnderCrystal", Enemies.NEUTRAL, MobCompat.END_CRYSTAL),
EXPERIENCEORB("ExperienceOrb", Enemies.NEUTRAL, "EXPERIENCE_ORB"), EXPERIENCEORB("ExperienceOrb", Enemies.NEUTRAL, "EXPERIENCE_ORB"),
ARMOR_STAND("ArmorStand", Enemies.NEUTRAL, "ARMOR_STAND"), ARMOR_STAND("ArmorStand", Enemies.NEUTRAL, "ARMOR_STAND"),
ENDERMITE("Endermite", Enemies.ENEMY, "ENDERMITE"), ENDERMITE("Endermite", Enemies.ENEMY, "ENDERMITE"),
@ -112,6 +120,9 @@ public enum Mob {
CHEST_BOAT("ChestBoat", Enemies.NEUTRAL, "CHEST_BOAT"), CHEST_BOAT("ChestBoat", Enemies.NEUTRAL, "CHEST_BOAT"),
CAMEL("Camel", Enemies.FRIENDLY, "CAMEL"), CAMEL("Camel", Enemies.FRIENDLY, "CAMEL"),
SNIFFER("Sniffer", Enemies.FRIENDLY, "SNIFFER"), SNIFFER("Sniffer", Enemies.FRIENDLY, "SNIFFER"),
ARMADILLO("Armadillo", Enemies.FRIENDLY, "ARMADILLO"),
BREEZE("Breeze", Enemies.ENEMY, "BREEZE"),
BOGGED("Bogged", Enemies.ENEMY, "BOGGED"),
; ;
private static final Map<String, Mob> hashMap = new HashMap<>(); private static final Map<String, Mob> hashMap = new HashMap<>();

View File

@ -1,6 +1,7 @@
package com.earth2me.essentials; package com.earth2me.essentials;
import com.earth2me.essentials.utils.EnumUtil; import com.earth2me.essentials.utils.EnumUtil;
import com.earth2me.essentials.utils.RegistryUtil;
import com.earth2me.essentials.utils.VersionUtil; import com.earth2me.essentials.utils.VersionUtil;
import net.ess3.nms.refl.ReflUtil; import net.ess3.nms.refl.ReflUtil;
import org.bukkit.Material; import org.bukkit.Material;
@ -18,8 +19,10 @@ import org.bukkit.entity.Ocelot;
import org.bukkit.entity.Panda; import org.bukkit.entity.Panda;
import org.bukkit.entity.Parrot; import org.bukkit.entity.Parrot;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.entity.Salmon;
import org.bukkit.entity.TropicalFish; import org.bukkit.entity.TropicalFish;
import org.bukkit.entity.Villager; import org.bukkit.entity.Villager;
import org.bukkit.entity.Wolf;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import java.lang.reflect.Method; import java.lang.reflect.Method;
@ -46,10 +49,21 @@ public final class MobCompat {
public static final EntityType GOAT = getEntityType("GOAT"); public static final EntityType GOAT = getEntityType("GOAT");
public static final EntityType FROG = getEntityType("FROG"); public static final EntityType FROG = getEntityType("FROG");
public static final EntityType CAMEL = getEntityType("CAMEL"); public static final EntityType CAMEL = getEntityType("CAMEL");
public static final EntityType SALMON = getEntityType("SALMON");
// Constants for mobs that have changed since earlier versions // Constants for mobs that have changed since earlier versions
public static final EntityType CAT = getEntityType("CAT", "OCELOT"); public static final EntityType CAT = getEntityType("CAT", "OCELOT");
public static final EntityType ZOMBIFIED_PIGLIN = getEntityType("ZOMBIFIED_PIGLIN", "PIG_ZOMBIE"); public static final EntityType ZOMBIFIED_PIGLIN = getEntityType("ZOMBIFIED_PIGLIN", "PIG_ZOMBIE");
public static final EntityType MOOSHROOM = getEntityType("MOOSHROOM", "MUSHROOM_COW");
public static final EntityType SNOW_GOLEM = getEntityType("SNOW_GOLEM", "SNOWMAN");
public static final EntityType CHEST_MINECART = getEntityType("CHEST_MINECART", "MINECART_CHEST");
public static final EntityType FURNACE_MINECART = getEntityType("FURNACE_MINECART", "MINECART_FURNACE");
public static final EntityType TNT_MINECART = getEntityType("TNT_MINECART", "MINECART_TNT");
public static final EntityType HOPPER_MINECART = getEntityType("HOPPER_MINECART", "MINECART_HOPPER");
public static final EntityType SPAWNER_MINECART = getEntityType("SPAWNER_MINECART", "MINECART_MOB_SPAWNER");
public static final EntityType END_CRYSTAL = getEntityType("END_CRYSTAL", "ENDER_CRYSTAL");
public static final EntityType FIREWORK_ROCKET = getEntityType("FIREWORK_ROCKET", "FIREWORK");
public static final EntityType OAK_BOAT = getEntityType("BOAT", "OAK_BOAT");
private MobCompat() { private MobCompat() {
} }
@ -183,7 +197,7 @@ public final class MobCompat {
} }
public static void setBoatVariant(final Entity entity, final BoatVariant variant) { public static void setBoatVariant(final Entity entity, final BoatVariant variant) {
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_9_R01)) { if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_21_3_R01) || VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_9_R01)) {
return; return;
} }
final Boat boat; final Boat boat;
@ -196,6 +210,7 @@ public final class MobCompat {
//noinspection deprecation //noinspection deprecation
boat.setWoodType(TreeSpecies.valueOf(variant.getTreeSpecies())); boat.setWoodType(TreeSpecies.valueOf(variant.getTreeSpecies()));
} else { } else {
//noinspection deprecation
boat.setBoatType(Boat.Type.valueOf(variant.getBoatType())); boat.setBoatType(Boat.Type.valueOf(variant.getBoatType()));
} }
} }
@ -213,6 +228,28 @@ public final class MobCompat {
} }
} }
public static void setWolfVariant(final Entity entity, final String variant) {
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_20_6_R01)) {
return;
}
if (entity instanceof Wolf) {
final Wolf wolf = (Wolf) entity;
//noinspection DataFlowIssue
wolf.setVariant(RegistryUtil.valueOf(Wolf.Variant.class, variant));
}
}
public static void setSalmonSize(Entity spawned, String s) {
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_21_3_R01)) {
return;
}
if (spawned instanceof org.bukkit.entity.Salmon) {
((Salmon) spawned).setVariant(Salmon.Variant.valueOf(s));
}
}
public enum CatType { public enum CatType {
// These are (loosely) Mojang names for the cats // These are (loosely) Mojang names for the cats
SIAMESE("SIAMESE", "SIAMESE_CAT"), SIAMESE("SIAMESE", "SIAMESE_CAT"),
@ -273,7 +310,7 @@ public final class MobCompat {
} }
private Villager.Profession asEnum() { private Villager.Profession asEnum() {
return EnumUtil.valueOf(Villager.Profession.class, newProfession, oldProfession); return RegistryUtil.valueOf(Villager.Profession.class, newProfession, oldProfession);
} }
} }

View File

@ -157,8 +157,8 @@ public enum MobData {
BLOCKFISH_TROPICAL_FISH("blockfish", MobCompat.TROPICAL_FISH, "tropicalfish:BLOCKFISH", true), BLOCKFISH_TROPICAL_FISH("blockfish", MobCompat.TROPICAL_FISH, "tropicalfish:BLOCKFISH", true),
BETTY_TROPICAL_FISH("betty", MobCompat.TROPICAL_FISH, "tropicalfish:BETTY", true), BETTY_TROPICAL_FISH("betty", MobCompat.TROPICAL_FISH, "tropicalfish:BETTY", true),
CLAYFISH_TROPICAL_FISH("clayfish", MobCompat.TROPICAL_FISH, "tropicalfish:CLAYFISH", true), CLAYFISH_TROPICAL_FISH("clayfish", MobCompat.TROPICAL_FISH, "tropicalfish:CLAYFISH", true),
BROWN_MUSHROOM_COW("brown", EntityType.MUSHROOM_COW, "mooshroom:BROWN", true), BROWN_MUSHROOM_COW("brown", MobCompat.MOOSHROOM, "mooshroom:BROWN", true),
RED_MUSHROOM_COW("red", EntityType.MUSHROOM_COW, "mooshroom:RED", true), RED_MUSHROOM_COW("red", MobCompat.MOOSHROOM, "mooshroom:RED", true),
AGGRESSIVE_PANDA_MAIN("aggressive", MobCompat.PANDA, "pandamain:AGGRESSIVE", true), AGGRESSIVE_PANDA_MAIN("aggressive", MobCompat.PANDA, "pandamain:AGGRESSIVE", true),
LAZY_PANDA_MAIN("lazy", MobCompat.PANDA, "pandamain:LAZY", true), LAZY_PANDA_MAIN("lazy", MobCompat.PANDA, "pandamain:LAZY", true),
WORRIED_PANDA_MAIN("worried", MobCompat.PANDA, "pandamain:WORRIED", true), WORRIED_PANDA_MAIN("worried", MobCompat.PANDA, "pandamain:WORRIED", true),
@ -209,6 +209,18 @@ public enum MobData {
OAK_BOAT("oak", Boat.class, MobCompat.BoatVariant.OAK, true), OAK_BOAT("oak", Boat.class, MobCompat.BoatVariant.OAK, true),
SPRUCE_BOAT("spruce", Boat.class, MobCompat.BoatVariant.SPRUCE, true), SPRUCE_BOAT("spruce", Boat.class, MobCompat.BoatVariant.SPRUCE, true),
SADDLE_CAMEL("saddle", MobCompat.CAMEL, Data.CAMELSADDLE, true), SADDLE_CAMEL("saddle", MobCompat.CAMEL, Data.CAMELSADDLE, true),
PALE_WOLF("pale", EntityType.WOLF, "wolf:PALE", true),
SPOTTED_WOLF("spotted", EntityType.WOLF, "wolf:PALE", true),
SNOWY_WOLF("snowy", EntityType.WOLF, "wolf:PALE", true),
BLACK_WOLF("black", EntityType.WOLF, "wolf:BLACK", true),
ASHEN_WOLF("ashen", EntityType.WOLF, "wolf:ASHEN", true),
RUSTY_WOLF("rusty", EntityType.WOLF, "wolf:RUSTY", true),
WOODS_WOLF("woods", EntityType.WOLF, "wolf:WOODS", true),
CHESTNUT_WOLF("chestnut", EntityType.WOLF, "wolf:CHESTNUT", true),
STRIPED_WOLF("striped", EntityType.WOLF, "wolf:STRIPED", true),
SMALL_SALMON("small", MobCompat.SALMON, "salmon:SMALL", true),
MEDIUM_SALMON("medium", MobCompat.SALMON, "salmon:MEDIUM", true),
LARGE_SALMON("large", MobCompat.SALMON, "salmon:LARGE", true),
; ;
final private String nickname; final private String nickname;
@ -424,6 +436,12 @@ public enum MobData {
case "frog": case "frog":
MobCompat.setFrogVariant(spawned, split[1]); MobCompat.setFrogVariant(spawned, split[1]);
break; break;
case "wolf":
MobCompat.setWolfVariant(spawned, split[1]);
break;
case "salmon":
MobCompat.setSalmonSize(spawned, split[1]);
break;
} }
} else { } else {
Essentials.getWrappedLogger().warning("Unknown mob data type: " + this.toString()); Essentials.getWrappedLogger().warning("Unknown mob data type: " + this.toString());

View File

@ -1,6 +1,7 @@
package com.earth2me.essentials; package com.earth2me.essentials;
import com.earth2me.essentials.utils.NumberUtil; import com.earth2me.essentials.utils.NumberUtil;
import com.earth2me.essentials.utils.RegistryUtil;
import org.bukkit.potion.PotionEffectType; import org.bukkit.potion.PotionEffectType;
import java.util.HashMap; import java.util.HashMap;
@ -21,50 +22,68 @@ public final class Potions {
ALIASPOTIONS.put("sprint", PotionEffectType.SPEED); ALIASPOTIONS.put("sprint", PotionEffectType.SPEED);
ALIASPOTIONS.put("swift", PotionEffectType.SPEED); ALIASPOTIONS.put("swift", PotionEffectType.SPEED);
POTIONS.put("slowness", PotionEffectType.SLOW); final PotionEffectType SLOWNESS = RegistryUtil.valueOf(PotionEffectType.class, "SLOW", "SLOWNESS");
ALIASPOTIONS.put("slow", PotionEffectType.SLOW);
ALIASPOTIONS.put("sluggish", PotionEffectType.SLOW);
POTIONS.put("haste", PotionEffectType.FAST_DIGGING); POTIONS.put("slowness", SLOWNESS);
ALIASPOTIONS.put("superpick", PotionEffectType.FAST_DIGGING); ALIASPOTIONS.put("slow", SLOWNESS);
ALIASPOTIONS.put("quickmine", PotionEffectType.FAST_DIGGING); ALIASPOTIONS.put("sluggish", SLOWNESS);
ALIASPOTIONS.put("digspeed", PotionEffectType.FAST_DIGGING);
ALIASPOTIONS.put("digfast", PotionEffectType.FAST_DIGGING);
ALIASPOTIONS.put("sharp", PotionEffectType.FAST_DIGGING);
POTIONS.put("fatigue", PotionEffectType.SLOW_DIGGING); final PotionEffectType HASTE = RegistryUtil.valueOf(PotionEffectType.class, "FAST_DIGGING", "HASTE");
ALIASPOTIONS.put("slow", PotionEffectType.SLOW_DIGGING);
ALIASPOTIONS.put("dull", PotionEffectType.SLOW_DIGGING);
POTIONS.put("strength", PotionEffectType.INCREASE_DAMAGE); POTIONS.put("haste", HASTE);
ALIASPOTIONS.put("strong", PotionEffectType.INCREASE_DAMAGE); ALIASPOTIONS.put("superpick", HASTE);
ALIASPOTIONS.put("bull", PotionEffectType.INCREASE_DAMAGE); ALIASPOTIONS.put("quickmine", HASTE);
ALIASPOTIONS.put("attack", PotionEffectType.INCREASE_DAMAGE); ALIASPOTIONS.put("digspeed", HASTE);
ALIASPOTIONS.put("digfast", HASTE);
ALIASPOTIONS.put("sharp", HASTE);
POTIONS.put("heal", PotionEffectType.HEAL); final PotionEffectType MINING_FATIGUE = RegistryUtil.valueOf(PotionEffectType.class, "SLOW_DIGGING", "MINING_FATIGUE");
ALIASPOTIONS.put("healthy", PotionEffectType.HEAL);
ALIASPOTIONS.put("instaheal", PotionEffectType.HEAL);
POTIONS.put("harm", PotionEffectType.HARM); POTIONS.put("fatigue", MINING_FATIGUE);
ALIASPOTIONS.put("harming", PotionEffectType.HARM); ALIASPOTIONS.put("slow", MINING_FATIGUE);
ALIASPOTIONS.put("injure", PotionEffectType.HARM); ALIASPOTIONS.put("dull", MINING_FATIGUE);
ALIASPOTIONS.put("damage", PotionEffectType.HARM);
ALIASPOTIONS.put("inflict", PotionEffectType.HARM);
POTIONS.put("jump", PotionEffectType.JUMP); final PotionEffectType STRENGTH = RegistryUtil.valueOf(PotionEffectType.class, "INCREASE_DAMAGE", "STRENGTH");
ALIASPOTIONS.put("leap", PotionEffectType.JUMP);
POTIONS.put("nausea", PotionEffectType.CONFUSION); POTIONS.put("strength", STRENGTH);
ALIASPOTIONS.put("sick", PotionEffectType.CONFUSION); ALIASPOTIONS.put("strong", STRENGTH);
ALIASPOTIONS.put("sickness", PotionEffectType.CONFUSION); ALIASPOTIONS.put("bull", STRENGTH);
ALIASPOTIONS.put("confusion", PotionEffectType.CONFUSION); ALIASPOTIONS.put("attack", STRENGTH);
final PotionEffectType INSTANT_HEALTH = RegistryUtil.valueOf(PotionEffectType.class, "HEAL", "INSTANT_HEALTH");
POTIONS.put("heal", INSTANT_HEALTH);
ALIASPOTIONS.put("healthy", INSTANT_HEALTH);
ALIASPOTIONS.put("instaheal", INSTANT_HEALTH);
final PotionEffectType INSTANT_DAMAGE = RegistryUtil.valueOf(PotionEffectType.class, "HARM", "INSTANT_DAMAGE");
POTIONS.put("harm", INSTANT_DAMAGE);
ALIASPOTIONS.put("harming", INSTANT_DAMAGE);
ALIASPOTIONS.put("injure", INSTANT_DAMAGE);
ALIASPOTIONS.put("damage", INSTANT_DAMAGE);
ALIASPOTIONS.put("inflict", INSTANT_DAMAGE);
final PotionEffectType JUMP_BOOST = RegistryUtil.valueOf(PotionEffectType.class, "JUMP", "JUMP_BOOST");
POTIONS.put("jump", JUMP_BOOST);
ALIASPOTIONS.put("leap", JUMP_BOOST);
final PotionEffectType NAUSEA = RegistryUtil.valueOf(PotionEffectType.class, "CONFUSION", "NAUSEA");
POTIONS.put("nausea", NAUSEA);
ALIASPOTIONS.put("sick", NAUSEA);
ALIASPOTIONS.put("sickness", NAUSEA);
ALIASPOTIONS.put("confusion", NAUSEA);
POTIONS.put("regeneration", PotionEffectType.REGENERATION); POTIONS.put("regeneration", PotionEffectType.REGENERATION);
ALIASPOTIONS.put("regen", PotionEffectType.REGENERATION); ALIASPOTIONS.put("regen", PotionEffectType.REGENERATION);
POTIONS.put("resistance", PotionEffectType.DAMAGE_RESISTANCE); final PotionEffectType RESISTANCE = RegistryUtil.valueOf(PotionEffectType.class, "DAMAGE_RESISTANCE", "RESISTANCE");
ALIASPOTIONS.put("dmgresist", PotionEffectType.DAMAGE_RESISTANCE);
ALIASPOTIONS.put("armor", PotionEffectType.DAMAGE_RESISTANCE); POTIONS.put("resistance", RESISTANCE);
ALIASPOTIONS.put("dmgresist", RESISTANCE);
ALIASPOTIONS.put("armor", RESISTANCE);
POTIONS.put("fireresist", PotionEffectType.FIRE_RESISTANCE); POTIONS.put("fireresist", PotionEffectType.FIRE_RESISTANCE);
ALIASPOTIONS.put("fireresistance", PotionEffectType.FIRE_RESISTANCE); ALIASPOTIONS.put("fireresistance", PotionEffectType.FIRE_RESISTANCE);
@ -125,6 +144,23 @@ public final class Potions {
POTIONS.put("unluck", PotionEffectType.UNLUCK); POTIONS.put("unluck", PotionEffectType.UNLUCK);
} catch (final Throwable ignored) { } catch (final Throwable ignored) {
} }
// 1.21
try {
POTIONS.put("infested", PotionEffectType.INFESTED);
ALIASPOTIONS.put("silverfish", PotionEffectType.INFESTED);
POTIONS.put("oozing", PotionEffectType.OOZING);
ALIASPOTIONS.put("ooze", PotionEffectType.OOZING);
POTIONS.put("weaving", PotionEffectType.WEAVING);
ALIASPOTIONS.put("weave", PotionEffectType.WEAVING);
POTIONS.put("windcharged", PotionEffectType.WIND_CHARGED);
ALIASPOTIONS.put("windcharge", PotionEffectType.WIND_CHARGED);
ALIASPOTIONS.put("wind", PotionEffectType.WIND_CHARGED);
} catch (final Throwable ignored) {
}
} }
private Potions() { private Potions() {

View File

@ -1,17 +1,22 @@
package com.earth2me.essentials; package com.earth2me.essentials;
import com.earth2me.essentials.config.ConfigurateUtil;
import com.earth2me.essentials.config.EssentialsConfiguration; import com.earth2me.essentials.config.EssentialsConfiguration;
import com.earth2me.essentials.config.entities.LazyLocation; import com.earth2me.essentials.config.entities.LazyLocation;
import com.earth2me.essentials.utils.LocationUtil; import com.earth2me.essentials.utils.LocationUtil;
import com.earth2me.essentials.utils.VersionUtil; import com.earth2me.essentials.utils.VersionUtil;
import io.papermc.lib.PaperLib; import io.papermc.lib.PaperLib;
import net.ess3.api.InvalidWorldException;
import net.ess3.provider.BiomeKeyProvider; import net.ess3.provider.BiomeKeyProvider;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World; import org.bukkit.World;
import java.io.File; import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Queue; import java.util.Queue;
import java.util.Random; import java.util.Random;
import java.util.Set; import java.util.Set;
@ -23,58 +28,72 @@ public class RandomTeleport implements IConf {
private static final int HIGHEST_BLOCK_Y_OFFSET = VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_15_R01) ? 1 : 0; private static final int HIGHEST_BLOCK_Y_OFFSET = VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_15_R01) ? 1 : 0;
private final IEssentials ess; private final IEssentials ess;
private final EssentialsConfiguration config; private final EssentialsConfiguration config;
private final ConcurrentLinkedQueue<Location> cachedLocations = new ConcurrentLinkedQueue<>(); private final Map<String, ConcurrentLinkedQueue<Location>> cachedLocations = new HashMap<>();
public RandomTeleport(final IEssentials essentials) { public RandomTeleport(final IEssentials essentials) {
this.ess = essentials; this.ess = essentials;
config = new EssentialsConfiguration(new File(essentials.getDataFolder(), "tpr.yml"), "/tpr.yml", config = new EssentialsConfiguration(new File(essentials.getDataFolder(), "tpr.yml"), "/tpr.yml",
"Configuration for the random teleport command.\nSome settings may be defaulted, and can be changed via the /settpr command in-game."); "Configuration for the random teleport command.\nUse the /settpr command in-game to set random teleport locations.");
reloadConfig(); reloadConfig();
} }
public EssentialsConfiguration getConfig() {
return config;
}
@Override @Override
public void reloadConfig() { public void reloadConfig() {
config.load(); config.load();
cachedLocations.clear(); cachedLocations.clear();
} }
public Location getCenter() { public boolean hasLocation(final String name) {
try { return config.hasProperty("locations." + name);
final LazyLocation center = config.getLocation("center"); }
if (center != null && center.location() != null) {
return center.location(); public Location getCenter(final String name) {
} final LazyLocation center = config.getLocation(locationKey(name, "center"));
} catch (final InvalidWorldException ignored) { if (center != null && center.location() != null) {
return center.location();
} }
final Location center = ess.getServer().getWorlds().get(0).getWorldBorder().getCenter();
center.setY(center.getWorld().getHighestBlockYAt(center) + HIGHEST_BLOCK_Y_OFFSET); final Location worldCenter = ess.getServer().getWorlds().get(0).getWorldBorder().getCenter();
setCenter(center); worldCenter.setY(worldCenter.getWorld().getHighestBlockYAt(worldCenter) + HIGHEST_BLOCK_Y_OFFSET);
return center; setCenter(name, worldCenter);
return worldCenter;
} }
public void setCenter(final Location center) { public void setCenter(final String name, final Location center) {
config.setProperty("center", center); config.setProperty(locationKey(name, "center"), center);
config.save(); config.save();
} }
public double getMinRange() { public double getMinRange(final String name) {
return config.getDouble("min-range", 0d); return config.getDouble(locationKey(name, "min-range"), 0d);
} }
public void setMinRange(final double minRange) { public void setMinRange(final String name, final double minRange) {
config.setProperty("min-range", minRange); config.setProperty(locationKey(name, "min-range"), minRange);
config.save(); config.save();
} }
public double getMaxRange() { public double getMaxRange(final String name) {
return config.getDouble("max-range", getCenter().getWorld().getWorldBorder().getSize() / 2); return config.getDouble(locationKey(name, "max-range"), getCenter(name).getWorld().getWorldBorder().getSize() / 2);
} }
public void setMaxRange(final double maxRange) { public void setMaxRange(final String name, final double maxRange) {
config.setProperty("max-range", maxRange); config.setProperty(locationKey(name, "max-range"), maxRange);
config.save(); config.save();
} }
public String getDefaultLocation() {
return config.getString("default-location", "{world}");
}
public boolean isPerLocationPermission() {
return config.getBoolean("per-location-permission", false);
}
public Set<String> getExcludedBiomes() { public Set<String> getExcludedBiomes() {
final Set<String> excludedBiomes = new HashSet<>(); final Set<String> excludedBiomes = new HashSet<>();
for (final String key : config.getList("excluded-biomes", String.class)) { for (final String key : config.getList("excluded-biomes", String.class)) {
@ -91,39 +110,48 @@ public class RandomTeleport implements IConf {
return config.getInt("cache-threshold", 10); return config.getInt("cache-threshold", 10);
} }
public boolean getPreCache() { public List<String> listLocations() {
return config.getBoolean("pre-cache", false); return new ArrayList<>(ConfigurateUtil.getKeys(config.getRootNode().node("locations")));
} }
public Queue<Location> getCachedLocations() { public Queue<Location> getCachedLocations(final String name) {
return cachedLocations; this.cachedLocations.computeIfAbsent(name, x -> new ConcurrentLinkedQueue<>());
return cachedLocations.get(name);
} }
// Get a random location; cached if possible. Otherwise on demand. // Get a named random teleport location; cached if possible, otherwise on demand.
public CompletableFuture<Location> getRandomLocation(final Location center, final double minRange, final double maxRange) { public CompletableFuture<Location> getRandomLocation(final String name) {
final int findAttempts = this.getFindAttempts(); final Queue<Location> cached = this.getCachedLocations(name);
final Queue<Location> cachedLocations = this.getCachedLocations();
// Try to build up the cache if it is below the threshold // Try to build up the cache if it is below the threshold
if (cachedLocations.size() < this.getCacheThreshold()) { if (cached.size() < this.getCacheThreshold()) {
cacheRandomLocations(center, minRange, maxRange); cacheRandomLocations(name);
} }
final CompletableFuture<Location> future = new CompletableFuture<>(); final CompletableFuture<Location> future = new CompletableFuture<>();
// Return a random location immediately if one is available, otherwise try to find one now // Return a random location immediately if one is available, otherwise try to find one now
if (cachedLocations.isEmpty()) { if (cached.isEmpty()) {
final int findAttempts = this.getFindAttempts();
final Location center = this.getCenter(name);
final double minRange = this.getMinRange(name);
final double maxRange = this.getMaxRange(name);
attemptRandomLocation(findAttempts, center, minRange, maxRange).thenAccept(future::complete); attemptRandomLocation(findAttempts, center, minRange, maxRange).thenAccept(future::complete);
} else { } else {
future.complete(cachedLocations.poll()); future.complete(cached.poll());
} }
return future; return future;
} }
// Prompts caching random valid locations, up to a maximum number of attempts // Get a random location with specific parameters (note: not cached).
public void cacheRandomLocations(final Location center, final double minRange, final double maxRange) { public CompletableFuture<Location> getRandomLocation(final Location center, final double minRange, final double maxRange) {
return attemptRandomLocation(this.getFindAttempts(), center, minRange, maxRange);
}
// Prompts caching random valid locations, up to a maximum number of attempts.
public void cacheRandomLocations(final String name) {
ess.getServer().getScheduler().scheduleSyncDelayedTask(ess, () -> { ess.getServer().getScheduler().scheduleSyncDelayedTask(ess, () -> {
for (int i = 0; i < this.getFindAttempts(); ++i) { for (int i = 0; i < this.getFindAttempts(); ++i) {
calculateRandomLocation(center, minRange, maxRange).thenAccept(location -> { calculateRandomLocation(getCenter(name), getMinRange(name), getMaxRange(name)).thenAccept(location -> {
if (isValidRandomLocation(location)) { if (isValidRandomLocation(location)) {
this.getCachedLocations().add(location); this.getCachedLocations(name).add(location);
} }
}); });
} }
@ -188,14 +216,18 @@ public class RandomTeleport implements IConf {
return future; return future;
} }
// Returns an appropriate elevation for a given location in the nether, or -1 if none is found // Returns an appropriate elevation for a given location in the nether, or MIN_VALUE if none is found
private double getNetherYAt(final Location location) { private double getNetherYAt(final Location location) {
for (int y = 32; y < ess.getWorldInfoProvider().getMaxHeight(location.getWorld()); ++y) { final World world = location.getWorld();
if (!LocationUtil.isBlockUnsafe(ess, location.getWorld(), location.getBlockX(), y, location.getBlockZ())) { for (int y = 32; y < ess.getWorldInfoProvider().getMaxHeight(world); ++y) {
if (Material.BEDROCK.equals(world.getBlockAt(location.getBlockX(), y, location.getBlockZ()).getType())) {
break;
}
if (!LocationUtil.isBlockUnsafe(ess, world, location.getBlockX(), y, location.getBlockZ())) {
return y; return y;
} }
} }
return -1; return Double.MIN_VALUE;
} }
private boolean isValidRandomLocation(final Location location) { private boolean isValidRandomLocation(final Location location) {
@ -226,6 +258,10 @@ public class RandomTeleport implements IConf {
return excluded.contains(biomeKey); return excluded.contains(biomeKey);
} }
private String locationKey(final String name, final String key) {
return "locations." + name + "." + key;
}
public File getFile() { public File getFile() {
return config.getFile(); return config.getFile();
} }

View File

@ -23,6 +23,7 @@ import org.bukkit.Material;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.Plugin;
import org.spongepowered.configurate.CommentedConfigurationNode; import org.spongepowered.configurate.CommentedConfigurationNode;
import java.io.File; import java.io.File;
@ -162,6 +163,16 @@ public class Settings implements net.ess3.api.ISettings {
return config.getBoolean("respawn-at-home", false); return config.getBoolean("respawn-at-home", false);
} }
@Override
public String getRandomSpawnLocation() {
return config.getString("random-spawn-location", "none");
}
@Override
public String getRandomRespawnLocation() {
return config.getString("random-respawn-location", "none");
}
@Override @Override
public boolean isRespawnAtAnchor() { public boolean isRespawnAtAnchor() {
return config.getBoolean("respawn-at-anchor", false); return config.getBoolean("respawn-at-anchor", false);
@ -456,6 +467,11 @@ public class Settings implements net.ess3.api.ISettings {
return config.getBoolean("socialspy-messages", true); return config.getBoolean("socialspy-messages", true);
} }
@Override
public boolean isSocialSpyDisplayNames() {
return config.getBoolean("socialspy-uses-displaynames", true);
}
private Set<String> _getMuteCommands() { private Set<String> _getMuteCommands() {
final Set<String> muteCommands = new HashSet<>(); final Set<String> muteCommands = new HashSet<>();
if (config.isList("mute-commands")) { if (config.isList("mute-commands")) {
@ -700,6 +716,18 @@ public class Settings implements net.ess3.api.ISettings {
mapModified = true; mapModified = true;
} }
if (reloadCount.get() < 2) {
// on startup: add plugins again in case they registered commands with the new API
// we need to schedule this task before any of the below tasks using _addAlternativeCommand.
ess.scheduleSyncDelayedTask(() -> {
for (final Plugin plugin : ess.getServer().getPluginManager().getPlugins()) {
if (plugin.isEnabled()) {
ess.getAlternativeCommandsHandler().addPlugin(plugin);
}
}
});
}
for (final String command : disabledCommands) { for (final String command : disabledCommands) {
final String effectiveAlias = command.toLowerCase(Locale.ENGLISH); final String effectiveAlias = command.toLowerCase(Locale.ENGLISH);
final Command toDisable = ess.getPluginCommand(effectiveAlias); final Command toDisable = ess.getPluginCommand(effectiveAlias);

View File

@ -191,23 +191,23 @@ public class Trade {
} }
if (getMoney() != null && getMoney().signum() > 0 && !user.canAfford(getMoney())) { if (getMoney() != null && getMoney().signum() > 0 && !user.canAfford(getMoney())) {
future.completeExceptionally(new ChargeException(user.playerTl("notEnoughMoney", NumberUtil.displayCurrency(getMoney(), ess)))); future.completeExceptionally(new ChargeException("notEnoughMoney", NumberUtil.displayCurrency(getMoney(), ess)));
return; return;
} }
if (getItemStack() != null && !Inventories.containsAtLeast(user.getBase(), itemStack, itemStack.getAmount())) { if (getItemStack() != null && !Inventories.containsAtLeast(user.getBase(), itemStack, itemStack.getAmount())) {
future.completeExceptionally(new ChargeException(user.playerTl("missingItems", getItemStack().getAmount(), ess.getItemDb().name(getItemStack())))); future.completeExceptionally(new ChargeException("missingItems", getItemStack().getAmount(), ess.getItemDb().name(getItemStack())));
return; return;
} }
final BigDecimal money; final BigDecimal money;
if (command != null && !command.isEmpty() && (money = getCommandCost(user)).signum() > 0 && !user.canAfford(money)) { if (command != null && !command.isEmpty() && (money = getCommandCost(user)).signum() > 0 && !user.canAfford(money)) {
future.completeExceptionally(new ChargeException(user.playerTl("notEnoughMoney", NumberUtil.displayCurrency(money, ess)))); future.completeExceptionally(new ChargeException("notEnoughMoney", NumberUtil.displayCurrency(money, ess)));
return; return;
} }
if (exp != null && exp > 0 && SetExpFix.getTotalExperience(user.getBase()) < exp) { if (exp != null && exp > 0 && SetExpFix.getTotalExperience(user.getBase()) < exp) {
future.completeExceptionally(new ChargeException(user.playerTl("notEnoughExperience"))); future.completeExceptionally(new ChargeException("notEnoughExperience"));
} }
} }
@ -285,7 +285,7 @@ public class Trade {
ess.getLogger().log(Level.INFO, "charging user " + user.getName() + " money " + getMoney().toPlainString()); ess.getLogger().log(Level.INFO, "charging user " + user.getName() + " money " + getMoney().toPlainString());
} }
if (!user.canAfford(getMoney()) && getMoney().signum() > 0) { if (!user.canAfford(getMoney()) && getMoney().signum() > 0) {
future.completeExceptionally(new ChargeException(user.playerTl("notEnoughMoney", NumberUtil.displayCurrency(getMoney(), ess)))); future.completeExceptionally(new ChargeException("notEnoughMoney", NumberUtil.displayCurrency(getMoney(), ess)));
return; return;
} }
user.takeMoney(getMoney()); user.takeMoney(getMoney());
@ -295,7 +295,7 @@ public class Trade {
ess.getLogger().log(Level.INFO, "charging user " + user.getName() + " itemstack " + getItemStack().toString()); ess.getLogger().log(Level.INFO, "charging user " + user.getName() + " itemstack " + getItemStack().toString());
} }
if (!Inventories.containsAtLeast(user.getBase(), getItemStack(), getItemStack().getAmount())) { if (!Inventories.containsAtLeast(user.getBase(), getItemStack(), getItemStack().getAmount())) {
future.completeExceptionally(new ChargeException(user.playerTl("missingItems", getItemStack().getAmount(), getItemStack().getType().toString().toLowerCase(Locale.ENGLISH).replace("_", " ")))); future.completeExceptionally(new ChargeException("missingItems", getItemStack().getAmount(), getItemStack().getType().toString().toLowerCase(Locale.ENGLISH).replace("_", " ")));
return; return;
} }
Inventories.removeItemAmount(user.getBase(), getItemStack(), getItemStack().getAmount()); Inventories.removeItemAmount(user.getBase(), getItemStack(), getItemStack().getAmount());
@ -304,7 +304,7 @@ public class Trade {
if (command != null) { if (command != null) {
final BigDecimal cost = getCommandCost(user); final BigDecimal cost = getCommandCost(user);
if (!user.canAfford(cost) && cost.signum() > 0) { if (!user.canAfford(cost) && cost.signum() > 0) {
future.completeExceptionally(new ChargeException(user.playerTl("notEnoughMoney", NumberUtil.displayCurrency(cost, ess)))); future.completeExceptionally(new ChargeException("notEnoughMoney", NumberUtil.displayCurrency(cost, ess)));
return; return;
} }
user.takeMoney(cost); user.takeMoney(cost);
@ -315,7 +315,7 @@ public class Trade {
} }
final int experience = SetExpFix.getTotalExperience(user.getBase()); final int experience = SetExpFix.getTotalExperience(user.getBase());
if (experience < getExperience() && getExperience() > 0) { if (experience < getExperience() && getExperience() > 0) {
future.completeExceptionally(new ChargeException(user.playerTl("notEnoughExperience"))); future.completeExceptionally(new ChargeException("notEnoughExperience"));
return; return;
} }
SetExpFix.setTotalExperience(user.getBase(), experience - getExperience()); SetExpFix.setTotalExperience(user.getBase(), experience - getExperience());

View File

@ -271,7 +271,7 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
final TransactionEvent transactionEvent = new TransactionEvent(this.getSource(), reciever, value); final TransactionEvent transactionEvent = new TransactionEvent(this.getSource(), reciever, value);
ess.getServer().getPluginManager().callEvent(transactionEvent); ess.getServer().getPluginManager().callEvent(transactionEvent);
} else { } else {
throw new ChargeException(tlLocale(playerLocale, "notEnoughMoney", NumberUtil.displayCurrency(value, ess))); throw new ChargeException("notEnoughMoney", NumberUtil.displayCurrency(value, ess));
} }
} }

View File

@ -5,7 +5,6 @@ import com.earth2me.essentials.config.EssentialsConfiguration;
import com.earth2me.essentials.utils.AdventureUtil; import com.earth2me.essentials.utils.AdventureUtil;
import com.earth2me.essentials.utils.StringUtil; import com.earth2me.essentials.utils.StringUtil;
import net.ess3.api.InvalidNameException; import net.ess3.api.InvalidNameException;
import net.ess3.api.InvalidWorldException;
import net.ess3.api.TranslatableException; import net.ess3.api.TranslatableException;
import org.bukkit.Location; import org.bukkit.Location;
@ -54,7 +53,7 @@ public class Warps implements IConf, net.ess3.api.IWarps {
} }
@Override @Override
public Location getWarp(final String warp) throws WarpNotFoundException, InvalidWorldException { public Location getWarp(final String warp) throws WarpNotFoundException {
final EssentialsConfiguration conf = warpPoints.get(new StringIgnoreCase(warp)); final EssentialsConfiguration conf = warpPoints.get(new StringIgnoreCase(warp));
if (conf == null) { if (conf == null) {
throw new WarpNotFoundException(); throw new WarpNotFoundException();
@ -79,7 +78,7 @@ public class Warps implements IConf, net.ess3.api.IWarps {
if (conf == null) { if (conf == null) {
final File confFile = new File(warpsFolder, filename + ".yml"); final File confFile = new File(warpsFolder, filename + ".yml");
if (confFile.exists()) { if (confFile.exists()) {
throw new Exception(user == null ? tlLiteral("similarWarpExist") : user.playerTl("similarWarpExist")); throw new TranslatableException("similarWarpExist");
} }
conf = new EssentialsConfiguration(confFile); conf = new EssentialsConfiguration(confFile);
conf.load(); conf.load();

View File

@ -22,9 +22,8 @@ public interface IWarps extends IConf {
* @param warp - Warp name * @param warp - Warp name
* @return - Location the warp is set to * @return - Location the warp is set to
* @throws WarpNotFoundException When the warp is not found * @throws WarpNotFoundException When the warp is not found
* @throws net.ess3.api.InvalidWorldException When the world the warp is in is not found
*/ */
Location getWarp(String warp) throws WarpNotFoundException, net.ess3.api.InvalidWorldException; Location getWarp(String warp) throws WarpNotFoundException;
/** /**
* Checks if the provided name is a warp. * Checks if the provided name is a warp.

View File

@ -1,20 +0,0 @@
package com.earth2me.essentials.api;
import net.ess3.api.TranslatableException;
/**
* @deprecated This exception is unused. Use {@link net.ess3.api.InvalidWorldException} instead.
*/
@Deprecated
public class InvalidWorldException extends TranslatableException {
private final String world;
public InvalidWorldException(final String world) {
super("invalidWorld");
this.world = world;
}
public String getWorld() {
return this.world;
}
}

View File

@ -3,6 +3,7 @@ package com.earth2me.essentials.commands;
import com.earth2me.essentials.CommandSource; import com.earth2me.essentials.CommandSource;
import com.earth2me.essentials.User; import com.earth2me.essentials.User;
import com.earth2me.essentials.utils.AdventureUtil; import com.earth2me.essentials.utils.AdventureUtil;
import com.earth2me.essentials.utils.FormatUtil;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import net.ess3.api.TranslatableException; import net.ess3.api.TranslatableException;
import org.bukkit.Server; import org.bukkit.Server;
@ -53,7 +54,7 @@ public class Commandbroadcastworld extends EssentialsCommand {
if (message.isEmpty()) { if (message.isEmpty()) {
throw new NotEnoughArgumentsException(); throw new NotEnoughArgumentsException();
} }
ess.broadcastTl(null, u -> !u.getBase().getWorld().equals(world), true, "broadcast", message, AdventureUtil.parsed(AdventureUtil.legacyToMini(name))); ess.broadcastTl(null, u -> !u.getBase().getWorld().equals(world), true, "broadcast", FormatUtil.replaceFormat(message).replace("\\n", "\n"), AdventureUtil.parsed(AdventureUtil.legacyToMini(name)));
} }
@Override @Override

View File

@ -6,6 +6,7 @@ import com.earth2me.essentials.craftbukkit.Inventories;
import com.earth2me.essentials.utils.NumberUtil; import com.earth2me.essentials.utils.NumberUtil;
import com.earth2me.essentials.utils.StringUtil; import com.earth2me.essentials.utils.StringUtil;
import com.earth2me.essentials.utils.VersionUtil; import com.earth2me.essentials.utils.VersionUtil;
import net.ess3.api.TranslatableException;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.Server; import org.bukkit.Server;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -80,7 +81,7 @@ public class Commandclearinventory extends EssentialsCommand {
} }
} }
protected void clearHandler(final CommandSource sender, final Player player, final String[] args, final int offset, final boolean showExtended) { protected void clearHandler(final CommandSource sender, final Player player, final String[] args, final int offset, final boolean showExtended) throws TranslatableException {
ClearHandlerType type = ClearHandlerType.ALL_EXCEPT_ARMOR; ClearHandlerType type = ClearHandlerType.ALL_EXCEPT_ARMOR;
final Set<Item> items = new HashSet<>(); final Set<Item> items = new HashSet<>();
int amount = -1; int amount = -1;
@ -124,6 +125,11 @@ public class Commandclearinventory extends EssentialsCommand {
stack.setDurability(item.getData()); stack.setDurability(item.getData());
} }
// can't remove a negative amount of items. (it adds them)
if (amount < -1) {
throw new TranslatableException("cannotRemoveNegativeItems");
}
// amount -1 means all items will be cleared // amount -1 means all items will be cleared
if (amount == -1) { if (amount == -1) {
final int removedAmount = Inventories.removeItemSimilar(player, stack, true); final int removedAmount = Inventories.removeItemSimilar(player, stack, true);
@ -131,7 +137,6 @@ public class Commandclearinventory extends EssentialsCommand {
sender.sendTl("inventoryClearingStack", removedAmount, stack.getType().toString().toLowerCase(Locale.ENGLISH), player.getDisplayName()); sender.sendTl("inventoryClearingStack", removedAmount, stack.getType().toString().toLowerCase(Locale.ENGLISH), player.getDisplayName());
} }
} else { } else {
stack.setAmount(amount < 0 ? 1 : amount);
if (Inventories.removeItemAmount(player, stack, amount)) { if (Inventories.removeItemAmount(player, stack, amount)) {
sender.sendTl("inventoryClearingStack", amount, stack.getType().toString().toLowerCase(Locale.ENGLISH), player.getDisplayName()); sender.sendTl("inventoryClearingStack", amount, stack.getType().toString().toLowerCase(Locale.ENGLISH), player.getDisplayName());
} else { } else {

View File

@ -18,6 +18,24 @@ public class Commanddelhome extends EssentialsCommand {
super("delhome"); super("delhome");
} }
private void deleteHome(CommandSource sender, User user, String home) {
final HomeModifyEvent event = new HomeModifyEvent(sender.getUser(), user, home, user.getHome(home), false);
Bukkit.getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
if (ess.getSettings().isDebug()) {
ess.getLogger().info("HomeModifyEvent canceled for /delhome execution by " + sender.getDisplayName());
}
return;
}
try {
user.delHome(home);
} catch (Exception e) {
sender.sendTl("invalidHome", home);
}
sender.sendTl("deleteHome", home);
}
@Override @Override
public void run(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception { public void run(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
if (args.length < 1) { if (args.length < 1) {
@ -45,21 +63,19 @@ public class Commanddelhome extends EssentialsCommand {
name = expandedArg[0].toLowerCase(Locale.ENGLISH); name = expandedArg[0].toLowerCase(Locale.ENGLISH);
} }
if (name.equals("bed")) { switch (name) {
throw new TranslatableException("invalidHomeName"); case "bed":
throw new TranslatableException("invalidHomeName");
case "*":
final List<String> homes = user.getHomes();
for (String home : homes) {
deleteHome(sender, user, home);
}
break;
default:
deleteHome(sender, user, name);
break;
} }
final HomeModifyEvent event = new HomeModifyEvent(sender.getUser(), user, name, user.getHome(name), false);
Bukkit.getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
if (ess.getSettings().isDebug()) {
ess.getLogger().info("HomeModifyEvent canceled for /delhome execution by " + sender.getDisplayName());
}
return;
}
user.delHome(name);
sender.sendTl("deleteHome", name);
} }
@Override @Override
@ -81,6 +97,7 @@ public class Commanddelhome extends EssentialsCommand {
return homes; return homes;
} }
otherUser.getHomes().forEach(home -> homes.add(namePart + ":" + home)); otherUser.getHomes().forEach(home -> homes.add(namePart + ":" + home));
homes.add(namePart + ":" + "*");
} }
} }
return homes; return homes;

View File

@ -14,7 +14,6 @@ import org.bukkit.inventory.ItemStack;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.TreeSet; import java.util.TreeSet;
@ -35,7 +34,7 @@ public class Commandenchant extends EssentialsCommand {
if (args.length == 0) { if (args.length == 0) {
final Set<String> usableEnchants = new TreeSet<>(); final Set<String> usableEnchants = new TreeSet<>();
for (final Map.Entry<String, Enchantment> entry : Enchantments.entrySet()) { for (final Map.Entry<String, Enchantment> entry : Enchantments.entrySet()) {
final String name = entry.getValue().getName().toLowerCase(Locale.ENGLISH); final String name = Enchantments.getRealName(entry.getValue());
if (usableEnchants.contains(name) || (user.isAuthorized("essentials.enchantments." + name) && entry.getValue().canEnchantItem(stack))) { if (usableEnchants.contains(name) || (user.isAuthorized("essentials.enchantments." + name) && entry.getValue().canEnchantItem(stack))) {
usableEnchants.add(entry.getKey()); usableEnchants.add(entry.getKey());
} }
@ -57,7 +56,7 @@ public class Commandenchant extends EssentialsCommand {
metaStack.addEnchantment(user.getSource(), ess.getSettings().allowUnsafeEnchantments() && user.isAuthorized("essentials.enchantments.allowunsafe"), enchantment, level); metaStack.addEnchantment(user.getSource(), ess.getSettings().allowUnsafeEnchantments() && user.isAuthorized("essentials.enchantments.allowunsafe"), enchantment, level);
stack.setItemMeta(metaStack.getItemStack().getItemMeta()); stack.setItemMeta(metaStack.getItemStack().getItemMeta());
user.getBase().updateInventory(); user.getBase().updateInventory();
final String enchantName = enchantment.getName().toLowerCase(Locale.ENGLISH).replace('_', ' '); final String enchantName = Enchantments.getRealName(enchantment).replace('_', ' ');
if (level == 0) { if (level == 0) {
user.sendTl("enchantmentRemoved", enchantName); user.sendTl("enchantmentRemoved", enchantName);
} else { } else {

View File

@ -10,10 +10,10 @@ import com.earth2me.essentials.userstorage.ModernUserMap;
import com.earth2me.essentials.utils.AdventureUtil; import com.earth2me.essentials.utils.AdventureUtil;
import com.earth2me.essentials.utils.CommandMapUtil; import com.earth2me.essentials.utils.CommandMapUtil;
import com.earth2me.essentials.utils.DateUtil; import com.earth2me.essentials.utils.DateUtil;
import com.earth2me.essentials.utils.EnumUtil;
import com.earth2me.essentials.utils.FloatUtil; import com.earth2me.essentials.utils.FloatUtil;
import com.earth2me.essentials.utils.NumberUtil; import com.earth2me.essentials.utils.NumberUtil;
import com.earth2me.essentials.utils.PasteUtil; import com.earth2me.essentials.utils.PasteUtil;
import com.earth2me.essentials.utils.RegistryUtil;
import com.earth2me.essentials.utils.VersionUtil; import com.earth2me.essentials.utils.VersionUtil;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
@ -67,8 +67,8 @@ import static com.earth2me.essentials.I18n.tlLiteral;
// This command has 4 undocumented behaviours #EasterEgg // This command has 4 undocumented behaviours #EasterEgg
public class Commandessentials extends EssentialsCommand { public class Commandessentials extends EssentialsCommand {
private static final Sound NOTE_HARP = EnumUtil.valueOf(Sound.class, "BLOCK_NOTE_BLOCK_HARP", "BLOCK_NOTE_HARP", "NOTE_PIANO"); private static final Sound NOTE_HARP = RegistryUtil.valueOf(Sound.class, "BLOCK_NOTE_BLOCK_HARP", "BLOCK_NOTE_HARP", "NOTE_PIANO");
private static final Sound MOO_SOUND = EnumUtil.valueOf(Sound.class, "COW_IDLE", "ENTITY_COW_MILK"); private static final Sound MOO_SOUND = RegistryUtil.valueOf(Sound.class, "COW_IDLE", "ENTITY_COW_MILK");
private static final String HOMES_USAGE = "/<command> homes (fix | delete [world])"; private static final String HOMES_USAGE = "/<command> homes (fix | delete [world])";

View File

@ -19,6 +19,7 @@ import org.bukkit.entity.Snowball;
import org.bukkit.entity.SplashPotion; import org.bukkit.entity.SplashPotion;
import org.bukkit.entity.ThrownExpBottle; import org.bukkit.entity.ThrownExpBottle;
import org.bukkit.entity.Trident; import org.bukkit.entity.Trident;
import org.bukkit.entity.WindCharge;
import org.bukkit.entity.WitherSkull; import org.bukkit.entity.WitherSkull;
import org.bukkit.metadata.FixedMetadataValue; import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
@ -55,6 +56,10 @@ public class Commandfireball extends EssentialsCommand {
builder.put("trident", Trident.class); builder.put("trident", Trident.class);
} }
if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_21_R01)) {
builder.put("windcharge", WindCharge.class);
}
types = builder.build(); types = builder.build();
} }

View File

@ -1,6 +1,7 @@
package com.earth2me.essentials.commands; package com.earth2me.essentials.commands;
import com.earth2me.essentials.MetaItemStack; import com.earth2me.essentials.MetaItemStack;
import com.earth2me.essentials.MobCompat;
import com.earth2me.essentials.User; import com.earth2me.essentials.User;
import com.earth2me.essentials.utils.MaterialUtil; import com.earth2me.essentials.utils.MaterialUtil;
import com.earth2me.essentials.utils.NumberUtil; import com.earth2me.essentials.utils.NumberUtil;
@ -9,7 +10,6 @@ import net.ess3.api.TranslatableException;
import org.bukkit.DyeColor; import org.bukkit.DyeColor;
import org.bukkit.FireworkEffect; import org.bukkit.FireworkEffect;
import org.bukkit.Server; import org.bukkit.Server;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Firework; import org.bukkit.entity.Firework;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.FireworkMeta; import org.bukkit.inventory.meta.FireworkMeta;
@ -81,7 +81,7 @@ public class Commandfirework extends EssentialsCommand {
} }
} }
for (int i = 0; i < amount; i++) { for (int i = 0; i < amount; i++) {
final Firework firework = (Firework) user.getWorld().spawnEntity(user.getLocation(), EntityType.FIREWORK); final Firework firework = (Firework) user.getWorld().spawnEntity(user.getLocation(), MobCompat.FIREWORK_ROCKET);
final FireworkMeta fmeta = (FireworkMeta) stack.getItemMeta(); final FireworkMeta fmeta = (FireworkMeta) stack.getItemMeta();
if (direction) { if (direction) {
final Vector vector = user.getBase().getEyeLocation().getDirection().multiply(0.070); final Vector vector = user.getBase().getEyeLocation().getDirection().multiply(0.070);

View File

@ -55,7 +55,7 @@ public class Commandgamemode extends EssentialsLoopCommand {
} }
if (isProhibitedChange(user, gameMode)) { if (isProhibitedChange(user, gameMode)) {
user.sendTl("cantGamemode", gameMode.name()); user.sendTl("cantGamemode", user.playerTl(gameMode.toString().toLowerCase(Locale.ENGLISH)));
return; return;
} }

View File

@ -18,6 +18,7 @@ import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.MissingResourceException;
public class Commandhelp extends EssentialsCommand { public class Commandhelp extends EssentialsCommand {
public Commandhelp() { public Commandhelp() {
@ -37,18 +38,25 @@ public class Commandhelp extends EssentialsCommand {
final String cmd = pageStr.substring(1); final String cmd = pageStr.substring(1);
for (final Map.Entry<String, Command> knownCmd : ess.getKnownCommandsProvider().getKnownCommands().entrySet()) { for (final Map.Entry<String, Command> knownCmd : ess.getKnownCommandsProvider().getKnownCommands().entrySet()) {
if (knownCmd.getKey().equalsIgnoreCase(cmd)) { if (knownCmd.getKey().equalsIgnoreCase(cmd)) {
final Command bukkit = knownCmd.getValue();
final boolean isEssCommand = bukkit instanceof PluginIdentifiableCommand && ((PluginIdentifiableCommand) bukkit).getPlugin().equals(ess);
final IEssentialsCommand essCommand = isEssCommand ? ess.getCommandMap().get(bukkit.getName()) : null;
user.sendTl("commandHelpLine1", cmd); user.sendTl("commandHelpLine1", cmd);
user.sendTl("commandHelpLine2", knownCmd.getValue().getDescription()); String description = bukkit.getDescription();
user.sendTl("commandHelpLine4", knownCmd.getValue().getAliases().toString()); if (essCommand != null) {
try {
description = user.playerTl(bukkit.getName() + "CommandDescription");
} catch (MissingResourceException ignored) {}
}
user.sendTl("commandHelpLine2", description);
user.sendTl("commandHelpLine4", bukkit.getAliases().toString());
user.sendTl("commandHelpLine3"); user.sendTl("commandHelpLine3");
final boolean isEssCommand = knownCmd.getValue() instanceof PluginIdentifiableCommand && ((PluginIdentifiableCommand) knownCmd.getValue()).getPlugin().equals(ess);
final IEssentialsCommand essCommand = isEssCommand ? ess.getCommandMap().get(knownCmd.getValue().getName()) : null;
if (essCommand != null && !essCommand.getUsageStrings().isEmpty()) { if (essCommand != null && !essCommand.getUsageStrings().isEmpty()) {
for (Map.Entry<String, String> usage : essCommand.getUsageStrings().entrySet()) { for (Map.Entry<String, String> usage : essCommand.getUsageStrings().entrySet()) {
user.sendTl("commandHelpLineUsage", AdventureUtil.parsed(usage.getKey().replace("<command>", cmd)), AdventureUtil.parsed(usage.getValue())); user.sendTl("commandHelpLineUsage", AdventureUtil.parsed(usage.getKey().replace("<command>", cmd)), AdventureUtil.parsed(usage.getValue()));
} }
} else { } else {
user.sendMessage(knownCmd.getValue().getUsage()); user.sendMessage(bukkit.getUsage());
} }
return; return;
} }

View File

@ -51,6 +51,11 @@ public class Commandhelpop extends EssentialsCommand {
final HelpopMessageSendEvent sendEvent = new HelpopMessageSendEvent(from, recipients, message); final HelpopMessageSendEvent sendEvent = new HelpopMessageSendEvent(from, recipients, message);
ess.getServer().getPluginManager().callEvent(sendEvent); ess.getServer().getPluginManager().callEvent(sendEvent);
final IUser sender = (IUser) from;
if(!recipients.contains(sender)){
from.sendTl("helpOp", from.getDisplayName(), message);
}
for (IUser recipient : sendEvent.getRecipients()) { for (IUser recipient : sendEvent.getRecipients()) {
recipient.sendTl("helpOp", from.getDisplayName(), message); recipient.sendTl("helpOp", from.getDisplayName(), message);
} }

View File

@ -2,6 +2,7 @@ package com.earth2me.essentials.commands;
import com.earth2me.essentials.Mob; import com.earth2me.essentials.Mob;
import com.earth2me.essentials.User; import com.earth2me.essentials.User;
import com.earth2me.essentials.utils.RegistryUtil;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Server; import org.bukkit.Server;
import org.bukkit.entity.Cat; import org.bukkit.entity.Cat;
@ -21,8 +22,12 @@ public class Commandkittycannon extends EssentialsCommand {
private static Ocelot spawnOcelot(final Server server, final User user) throws Mob.MobException { private static Ocelot spawnOcelot(final Server server, final User user) throws Mob.MobException {
final Ocelot ocelot = (Ocelot) Mob.OCELOT.spawn(user.getWorld(), server, user.getBase().getEyeLocation()); final Ocelot ocelot = (Ocelot) Mob.OCELOT.spawn(user.getWorld(), server, user.getBase().getEyeLocation());
final int i = random.nextInt(Ocelot.Type.values().length); //noinspection deprecation
ocelot.setCatType(Ocelot.Type.values()[i]); final Object[] values = RegistryUtil.values(Ocelot.Type.class);
final int i = random.nextInt(values.length);
//noinspection deprecation
ocelot.setCatType((Ocelot.Type) values[i]);
((Tameable) ocelot).setTamed(true); ((Tameable) ocelot).setTamed(true);
ocelot.setBaby(); ocelot.setBaby();
ocelot.setVelocity(user.getBase().getEyeLocation().getDirection().multiply(2)); ocelot.setVelocity(user.getBase().getEyeLocation().getDirection().multiply(2));
@ -31,8 +36,10 @@ public class Commandkittycannon extends EssentialsCommand {
private static Entity spawnCat(final Server server, final User user) throws Mob.MobException { private static Entity spawnCat(final Server server, final User user) throws Mob.MobException {
final Cat cat = (Cat) Mob.CAT.spawn(user.getWorld(), server, user.getBase().getEyeLocation()); final Cat cat = (Cat) Mob.CAT.spawn(user.getWorld(), server, user.getBase().getEyeLocation());
final int i = random.nextInt(Cat.Type.values().length); final Object[] values = RegistryUtil.values(Cat.Type.class);
cat.setCatType(Cat.Type.values()[i]);
final int i = random.nextInt(values.length);
cat.setCatType((Cat.Type) values[i]);
cat.setTamed(true); cat.setTamed(true);
cat.setBaby(); cat.setBaby();
cat.setVelocity(user.getBase().getEyeLocation().getDirection().multiply(2)); cat.setVelocity(user.getBase().getEyeLocation().getDirection().multiply(2));

View File

@ -109,8 +109,10 @@ public class Commandpay extends EssentialsLoopCommand {
user.setMoney(user.getMoney().add(amount)); user.setMoney(user.getMoney().add(amount));
} catch (final MaxMoneyException ignored) { } catch (final MaxMoneyException ignored) {
} }
} catch (final TranslatableException e) {
throw e;
} catch (final Exception e) { } catch (final Exception e) {
user.sendMessage(e.getMessage()); throw new TranslatableException("errorWithMessage", e.getMessage());
} }
}); });
if (informToConfirm.get()) { if (informToConfirm.get()) {

View File

@ -3,10 +3,12 @@ package com.earth2me.essentials.commands;
import com.earth2me.essentials.CommandSource; import com.earth2me.essentials.CommandSource;
import com.earth2me.essentials.User; import com.earth2me.essentials.User;
import com.earth2me.essentials.craftbukkit.Inventories; import com.earth2me.essentials.craftbukkit.Inventories;
import com.earth2me.essentials.utils.AdventureUtil;
import com.earth2me.essentials.utils.EnumUtil; import com.earth2me.essentials.utils.EnumUtil;
import com.earth2me.essentials.utils.NumberUtil; import com.earth2me.essentials.utils.NumberUtil;
import com.earth2me.essentials.utils.VersionUtil; import com.earth2me.essentials.utils.VersionUtil;
import net.ess3.api.TranslatableException; import net.ess3.api.TranslatableException;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.Server; import org.bukkit.Server;
import org.bukkit.inventory.FurnaceRecipe; import org.bukkit.inventory.FurnaceRecipe;
@ -131,7 +133,7 @@ public class Commandrecipe extends EssentialsCommand {
if (VersionUtil.PRE_FLATTENING && item.getDurability() == Short.MAX_VALUE) { if (VersionUtil.PRE_FLATTENING && item.getDurability() == Short.MAX_VALUE) {
item.setDurability((short) 0); item.setDurability((short) 0);
} }
view.getTopInventory().setItem(j * 3 + k + 1, item); ess.getInventoryViewProvider().getTopInventory(view).setItem(j * 3 + k + 1, item);
} }
} }
} else { } else {
@ -150,18 +152,28 @@ public class Commandrecipe extends EssentialsCommand {
materials[j][k] = item == null ? null : item.getType(); materials[j][k] = item == null ? null : item.getType();
} }
} }
sender.sendTl("recipeGrid", colorMap.get(materials[0][0]), colorMap.get(materials[0][1]), colorMap.get(materials[0][2])); sender.sendTl("recipeGrid", colorTag(colorMap, materials, 0, 0), colorTag(colorMap, materials, 0, 1), colorTag(colorMap, materials, 0, 2));
sender.sendTl("recipeGrid", colorMap.get(materials[1][0]), colorMap.get(materials[1][1]), colorMap.get(materials[1][2])); sender.sendTl("recipeGrid", colorTag(colorMap, materials, 1, 0), colorTag(colorMap, materials, 1, 1), colorTag(colorMap, materials, 1, 2));
sender.sendTl("recipeGrid", colorMap.get(materials[2][0]), colorMap.get(materials[2][1]), colorMap.get(materials[2][2])); sender.sendTl("recipeGrid", colorTag(colorMap, materials, 2, 0), colorTag(colorMap, materials, 2, 1), colorTag(colorMap, materials, 2, 2));
final StringBuilder s = new StringBuilder(); final StringBuilder s = new StringBuilder();
for (final Material items : colorMap.keySet().toArray(new Material[0])) { for (final Material items : colorMap.keySet().toArray(new Material[0])) {
s.append(sender.tl("recipeGridItem", colorMap.get(items), getMaterialName(sender, items))); s.append(sender.tl("recipeGridItem", colorMap.get(items), getMaterialName(sender, items))).append(" ");
} }
sender.sendTl("recipeWhere", s.toString()); sender.sendTl("recipeWhere", AdventureUtil.parsed(s.toString()));
} }
} }
private AdventureUtil.ParsedPlaceholder colorTag(final Map<Material, String> colorMap, final Material[][] materials, final int x, final int y) {
final char colorChar = colorMap.get(materials[x][y]).charAt(0);
final NamedTextColor namedTextColor = AdventureUtil.fromChar(colorChar);
if (namedTextColor == null) {
throw new IllegalStateException("Illegal amount of materials in recipe");
}
return AdventureUtil.parsed("<" + namedTextColor + ">" + colorChar);
}
public void shapelessRecipe(final CommandSource sender, final ShapelessRecipe recipe, final boolean showWindow) { public void shapelessRecipe(final CommandSource sender, final ShapelessRecipe recipe, final boolean showWindow) {
final List<ItemStack> ingredients = recipe.getIngredientList(); final List<ItemStack> ingredients = recipe.getIngredientList();
if (showWindow) { if (showWindow) {
@ -174,7 +186,7 @@ public class Commandrecipe extends EssentialsCommand {
if (VersionUtil.PRE_FLATTENING && item.getDurability() == Short.MAX_VALUE) { if (VersionUtil.PRE_FLATTENING && item.getDurability() == Short.MAX_VALUE) {
item.setDurability((short) 0); item.setDurability((short) 0);
} }
view.setItem(i + 1, item); ess.getInventoryViewProvider().setItem(view, i + 1, item);
} }
} else { } else {

View File

@ -3,10 +3,12 @@ package com.earth2me.essentials.commands;
import com.earth2me.essentials.RandomTeleport; import com.earth2me.essentials.RandomTeleport;
import com.earth2me.essentials.User; import com.earth2me.essentials.User;
import org.bukkit.Server; import org.bukkit.Server;
import org.bukkit.World;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
public class Commandsettpr extends EssentialsCommand { public class Commandsettpr extends EssentialsCommand {
public Commandsettpr() { public Commandsettpr() {
@ -15,22 +17,20 @@ public class Commandsettpr extends EssentialsCommand {
@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 {
if (args.length == 0) { if (args.length < 2) {
throw new NotEnoughArgumentsException(); throw new NotEnoughArgumentsException();
} }
final RandomTeleport randomTeleport = ess.getRandomTeleport(); final RandomTeleport randomTeleport = ess.getRandomTeleport();
randomTeleport.getCachedLocations().clear(); if ("center".equalsIgnoreCase(args[1])) {
if ("center".equalsIgnoreCase(args[0])) { randomTeleport.setCenter(args[0], user.getLocation());
randomTeleport.setCenter(user.getLocation());
user.sendTl("settpr"); user.sendTl("settpr");
} else if (args.length > 1) { } else if (args.length > 2) {
if ("minrange".equalsIgnoreCase(args[0])) { if ("minrange".equalsIgnoreCase(args[1])) {
randomTeleport.setMinRange(Double.parseDouble(args[1])); randomTeleport.setMinRange(args[0], Double.parseDouble(args[2]));
} else if ("maxrange".equalsIgnoreCase(args[0])) { } else if ("maxrange".equalsIgnoreCase(args[1])) {
randomTeleport.setMaxRange(Double.parseDouble(args[1])); randomTeleport.setMaxRange(args[0], Double.parseDouble(args[2]));
} }
user.sendTl("settprValue", args[0].toLowerCase(), args[1].toLowerCase()); user.sendTl("settprValue", args[1].toLowerCase(), args[2].toLowerCase());
} else { } else {
throw new NotEnoughArgumentsException(); throw new NotEnoughArgumentsException();
} }
@ -39,6 +39,8 @@ public class Commandsettpr extends EssentialsCommand {
@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) {
return user.getServer().getWorlds().stream().map(World::getName).collect(Collectors.toList());
} else if (args.length == 2) {
return Arrays.asList("center", "minrange", "maxrange"); return Arrays.asList("center", "minrange", "maxrange");
} }
return Collections.emptyList(); return Collections.emptyList();

View File

@ -4,7 +4,6 @@ import com.earth2me.essentials.User;
import com.earth2me.essentials.api.IWarps; import com.earth2me.essentials.api.IWarps;
import com.earth2me.essentials.utils.NumberUtil; import com.earth2me.essentials.utils.NumberUtil;
import com.earth2me.essentials.utils.StringUtil; import com.earth2me.essentials.utils.StringUtil;
import net.ess3.api.InvalidWorldException;
import net.ess3.api.TranslatableException; import net.ess3.api.TranslatableException;
import net.essentialsx.api.v2.events.WarpModifyEvent; import net.essentialsx.api.v2.events.WarpModifyEvent;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@ -31,7 +30,7 @@ public class Commandsetwarp extends EssentialsCommand {
try { try {
warpLoc = warps.getWarp(args[0]); warpLoc = warps.getWarp(args[0]);
} catch (final WarpNotFoundException | InvalidWorldException ignored) { } catch (final WarpNotFoundException ignored) {
} }
if (warpLoc == null) { if (warpLoc == null) {
final WarpModifyEvent event = new WarpModifyEvent(user, args[0], null, user.getLocation(), WarpModifyEvent.WarpModifyCause.CREATE); final WarpModifyEvent event = new WarpModifyEvent(user, args[0], null, user.getLocation(), WarpModifyEvent.WarpModifyCause.CREATE);

View File

@ -6,6 +6,7 @@ import com.earth2me.essentials.IUser;
import com.earth2me.essentials.User; import com.earth2me.essentials.User;
import com.earth2me.essentials.utils.AdventureUtil; import com.earth2me.essentials.utils.AdventureUtil;
import com.earth2me.essentials.utils.DateUtil; import com.earth2me.essentials.utils.DateUtil;
import com.earth2me.essentials.utils.FormatUtil;
import org.bukkit.BanList; import org.bukkit.BanList;
import org.bukkit.Server; import org.bukkit.Server;
@ -36,7 +37,7 @@ public class Commandtempban extends EssentialsCommand {
} }
final String time = getFinalArg(args, 1); final String time = getFinalArg(args, 1);
final long banTimestamp = DateUtil.parseDateDiff(time, true); final long banTimestamp = DateUtil.parseDateDiff(time, true);
String banReason = DateUtil.removeTimePattern(time); String banReason = FormatUtil.replaceFormat(DateUtil.removeTimePattern(time));
final long maxBanLength = ess.getSettings().getMaxTempban() * 1000; final long maxBanLength = ess.getSettings().getMaxTempban() * 1000;
if (maxBanLength > 0 && ((banTimestamp - GregorianCalendar.getInstance().getTimeInMillis()) > maxBanLength) && sender.isPlayer() && !ess.getUser(sender.getPlayer()).isAuthorized("essentials.tempban.unlimited")) { if (maxBanLength > 0 && ((banTimestamp - GregorianCalendar.getInstance().getTimeInMillis()) > maxBanLength) && sender.isPlayer() && !ess.getUser(sender.getPlayer()).isAuthorized("essentials.tempban.unlimited")) {

View File

@ -49,7 +49,7 @@ public class Commandtempbanip extends EssentialsCommand {
final String time = getFinalArg(args, 1); final String time = getFinalArg(args, 1);
final long banTimestamp = DateUtil.parseDateDiff(time, true); final long banTimestamp = DateUtil.parseDateDiff(time, true);
String banReason = DateUtil.removeTimePattern(time); String banReason = FormatUtil.replaceFormat(DateUtil.removeTimePattern(time));
final long maxBanLength = ess.getSettings().getMaxTempban() * 1000; final long maxBanLength = ess.getSettings().getMaxTempban() * 1000;
if (maxBanLength > 0 && ((banTimestamp - GregorianCalendar.getInstance().getTimeInMillis()) > maxBanLength) && sender.isPlayer() && !ess.getUser(sender.getPlayer()).isAuthorized("essentials.tempban.unlimited")) { if (maxBanLength > 0 && ((banTimestamp - GregorianCalendar.getInstance().getTimeInMillis()) > maxBanLength) && sender.isPlayer() && !ess.getUser(sender.getPlayer()).isAuthorized("essentials.tempban.unlimited")) {

View File

@ -1,8 +1,10 @@
package com.earth2me.essentials.commands; package com.earth2me.essentials.commands;
import com.earth2me.essentials.CommandSource;
import com.earth2me.essentials.RandomTeleport; import com.earth2me.essentials.RandomTeleport;
import com.earth2me.essentials.Trade; import com.earth2me.essentials.Trade;
import com.earth2me.essentials.User; import com.earth2me.essentials.User;
import net.ess3.api.TranslatableException;
import net.ess3.api.events.UserRandomTeleportEvent; import net.ess3.api.events.UserRandomTeleportEvent;
import org.bukkit.Server; import org.bukkit.Server;
import org.bukkit.event.player.PlayerTeleportEvent; import org.bukkit.event.player.PlayerTeleportEvent;
@ -10,6 +12,7 @@ import org.bukkit.event.player.PlayerTeleportEvent;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
public class Commandtpr extends EssentialsCommand { public class Commandtpr extends EssentialsCommand {
@ -22,25 +25,67 @@ public class Commandtpr extends EssentialsCommand {
final Trade charge = new Trade(this.getName(), ess); final Trade charge = new Trade(this.getName(), ess);
charge.isAffordableFor(user); charge.isAffordableFor(user);
final RandomTeleport randomTeleport = ess.getRandomTeleport(); final RandomTeleport randomTeleport = ess.getRandomTeleport();
final UserRandomTeleportEvent event = new UserRandomTeleportEvent(user, randomTeleport.getCenter(), randomTeleport.getMinRange(), randomTeleport.getMaxRange()); final String defaultLocation = randomTeleport.getDefaultLocation().replace("{world}", user.getLocation().getWorld().getName());
final String name = args.length > 0 ? args[0] : defaultLocation;
final User userToTeleport = args.length > 1 && user.isAuthorized("essentials.tpr.others") ? getPlayer(server, user, args, 1) : user;
if (randomTeleport.isPerLocationPermission() && !user.isAuthorized("essentials.tpr.location." + name)) {
throw new TranslatableException("warpUsePermission");
}
final UserRandomTeleportEvent event = new UserRandomTeleportEvent(userToTeleport, name, randomTeleport.getCenter(name), randomTeleport.getMinRange(name), randomTeleport.getMaxRange(name));
server.getPluginManager().callEvent(event); server.getPluginManager().callEvent(event);
if (event.isCancelled()) { if (event.isCancelled()) {
return; return;
} }
randomTeleport.getRandomLocation(event.getCenter(), event.getMinRange(), event.getMaxRange()).thenAccept(location -> { (event.isModified() ? randomTeleport.getRandomLocation(event.getCenter(), event.getMinRange(), event.getMaxRange()) : randomTeleport.getRandomLocation(name))
final CompletableFuture<Boolean> future = getNewExceptionFuture(user.getSource(), commandLabel); .thenAccept(location -> {
user.getAsyncTeleport().teleport(location, charge, PlayerTeleportEvent.TeleportCause.COMMAND, future); final CompletableFuture<Boolean> future = getNewExceptionFuture(user.getSource(), commandLabel);
future.thenAccept(success -> { future.thenAccept(success -> {
if (success) { if (success) {
user.sendTl("tprSuccess"); userToTeleport.sendTl("tprSuccess");
} }
}); });
}); userToTeleport.getAsyncTeleport().teleport(location, charge, PlayerTeleportEvent.TeleportCause.COMMAND, future);
});
throw new NoChargeException(); throw new NoChargeException();
} }
@Override @Override
protected List<String> getTabCompleteOptions(final Server server, final User user, final String commandLabel, final String[] args) { protected void run(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
if (args.length < 2) {
throw new NotEnoughArgumentsException();
}
final RandomTeleport randomTeleport = ess.getRandomTeleport();
final User userToTeleport = getPlayer(server, sender, args, 1);
final String name = args[0];
final UserRandomTeleportEvent event = new UserRandomTeleportEvent(userToTeleport, name, randomTeleport.getCenter(name), randomTeleport.getMinRange(name), randomTeleport.getMaxRange(name));
server.getPluginManager().callEvent(event);
if (event.isCancelled()) {
return;
}
(event.isModified() ? randomTeleport.getRandomLocation(event.getCenter(), event.getMinRange(), event.getMaxRange()) : randomTeleport.getRandomLocation(name))
.thenAccept(location -> {
final CompletableFuture<Boolean> future = getNewExceptionFuture(sender, commandLabel);
future.thenAccept(success -> {
if (success) {
userToTeleport.sendTl("tprSuccess");
}
});
userToTeleport.getAsyncTeleport().now(location, false, PlayerTeleportEvent.TeleportCause.COMMAND, future);
});
}
@Override
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
final RandomTeleport randomTeleport = ess.getRandomTeleport();
if (args.length == 1) {
if (randomTeleport.isPerLocationPermission()) {
return randomTeleport.listLocations().stream().filter(name -> sender.isAuthorized("essentials.tpr.location." + name)).collect(Collectors.toList());
} else {
return randomTeleport.listLocations();
}
} else if (args.length == 2 && sender.isAuthorized("essentials.tpr.others")) {
return getPlayers(server, sender);
}
return Collections.emptyList(); return Collections.emptyList();
} }
} }

View File

@ -6,6 +6,7 @@ import com.earth2me.essentials.User;
import com.earth2me.essentials.utils.FormatUtil; import com.earth2me.essentials.utils.FormatUtil;
import com.earth2me.essentials.utils.StringUtil; import com.earth2me.essentials.utils.StringUtil;
import net.ess3.api.MaxMoneyException; import net.ess3.api.MaxMoneyException;
import net.ess3.api.TranslatableException;
import org.bukkit.Server; import org.bukkit.Server;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -18,11 +19,11 @@ public abstract class EssentialsLoopCommand extends EssentialsCommand {
super(command); super(command);
} }
protected void loopOfflinePlayers(final Server server, final CommandSource sender, final boolean multipleStringMatches, final boolean matchWildcards, final String searchTerm, final String[] commandArgs) throws PlayerNotFoundException, NotEnoughArgumentsException, PlayerExemptException, ChargeException, MaxMoneyException { protected void loopOfflinePlayers(final Server server, final CommandSource sender, final boolean multipleStringMatches, final boolean matchWildcards, final String searchTerm, final String[] commandArgs) throws TranslatableException, NotEnoughArgumentsException {
loopOfflinePlayersConsumer(server, sender, multipleStringMatches, matchWildcards, searchTerm, user -> updatePlayer(server, sender, user, commandArgs)); loopOfflinePlayersConsumer(server, sender, multipleStringMatches, matchWildcards, searchTerm, user -> updatePlayer(server, sender, user, commandArgs));
} }
protected void loopOfflinePlayersConsumer(final Server server, final CommandSource sender, final boolean multipleStringMatches, final boolean matchWildcards, final String searchTerm, final UserConsumer userConsumer) throws PlayerNotFoundException, NotEnoughArgumentsException, PlayerExemptException, ChargeException, MaxMoneyException { protected void loopOfflinePlayersConsumer(final Server server, final CommandSource sender, final boolean multipleStringMatches, final boolean matchWildcards, final String searchTerm, final UserConsumer userConsumer) throws TranslatableException, NotEnoughArgumentsException {
if (searchTerm.isEmpty()) { if (searchTerm.isEmpty()) {
throw new PlayerNotFoundException(); throw new PlayerNotFoundException();
} }
@ -68,11 +69,11 @@ public abstract class EssentialsLoopCommand extends EssentialsCommand {
} }
} }
protected void loopOnlinePlayers(final Server server, final CommandSource sender, final boolean multipleStringMatches, final boolean matchWildcards, final String searchTerm, final String[] commandArgs) throws PlayerNotFoundException, NotEnoughArgumentsException, PlayerExemptException, ChargeException, MaxMoneyException { protected void loopOnlinePlayers(final Server server, final CommandSource sender, final boolean multipleStringMatches, final boolean matchWildcards, final String searchTerm, final String[] commandArgs) throws TranslatableException, NotEnoughArgumentsException {
loopOnlinePlayersConsumer(server, sender, multipleStringMatches, matchWildcards, searchTerm, user -> updatePlayer(server, sender, user, commandArgs)); loopOnlinePlayersConsumer(server, sender, multipleStringMatches, matchWildcards, searchTerm, user -> updatePlayer(server, sender, user, commandArgs));
} }
protected void loopOnlinePlayersConsumer(final Server server, final CommandSource sender, final boolean multipleStringMatches, final boolean matchWildcards, final String searchTerm, final UserConsumer userConsumer) throws PlayerNotFoundException, NotEnoughArgumentsException, PlayerExemptException, ChargeException, MaxMoneyException { protected void loopOnlinePlayersConsumer(final Server server, final CommandSource sender, final boolean multipleStringMatches, final boolean matchWildcards, final String searchTerm, final UserConsumer userConsumer) throws NotEnoughArgumentsException, TranslatableException {
if (searchTerm.isEmpty()) { if (searchTerm.isEmpty()) {
throw new PlayerNotFoundException(); throw new PlayerNotFoundException();
} }
@ -143,6 +144,6 @@ public abstract class EssentialsLoopCommand extends EssentialsCommand {
} }
public interface UserConsumer { public interface UserConsumer {
void accept(User user) throws PlayerNotFoundException, NotEnoughArgumentsException, PlayerExemptException, ChargeException, MaxMoneyException; void accept(User user) throws NotEnoughArgumentsException, TranslatableException;
} }
} }

View File

@ -13,7 +13,6 @@ import com.earth2me.essentials.config.serializers.LocationTypeSerializer;
import com.earth2me.essentials.config.serializers.MailMessageSerializer; import com.earth2me.essentials.config.serializers.MailMessageSerializer;
import com.earth2me.essentials.config.serializers.MaterialTypeSerializer; import com.earth2me.essentials.config.serializers.MaterialTypeSerializer;
import com.earth2me.essentials.utils.AdventureUtil; import com.earth2me.essentials.utils.AdventureUtil;
import net.ess3.api.InvalidWorldException;
import net.essentialsx.api.v2.services.mail.MailMessage; import net.essentialsx.api.v2.services.mail.MailMessage;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
@ -123,7 +122,7 @@ public class EssentialsConfiguration {
setInternal(path, LazyLocation.fromLocation(location)); setInternal(path, LazyLocation.fromLocation(location));
} }
public LazyLocation getLocation(final String path) throws InvalidWorldException { public LazyLocation getLocation(final String path) {
final CommentedConfigurationNode node = path == null ? getRootNode() : getSection(path); final CommentedConfigurationNode node = path == null ? getRootNode() : getSection(path);
if (node == null) { if (node == null) {
return null; return null;

View File

@ -243,6 +243,10 @@ public final class Inventories {
} }
public static boolean removeItemAmount(final Player player, final ItemStack toRemove, int amount) { public static boolean removeItemAmount(final Player player, final ItemStack toRemove, int amount) {
if (amount < 0) {
throw new IllegalArgumentException("Amount cannot be negative.");
}
final List<Integer> clearSlots = new ArrayList<>(); final List<Integer> clearSlots = new ArrayList<>();
final ItemStack[] items = player.getInventory().getContents(); final ItemStack[] items = player.getInventory().getContents();

View File

@ -1,5 +1,6 @@
package com.earth2me.essentials.items; package com.earth2me.essentials.items;
import com.earth2me.essentials.Enchantments;
import com.earth2me.essentials.IConf; import com.earth2me.essentials.IConf;
import com.earth2me.essentials.User; import com.earth2me.essentials.User;
import com.earth2me.essentials.craftbukkit.Inventories; import com.earth2me.essentials.craftbukkit.Inventories;
@ -24,10 +25,8 @@ import org.bukkit.inventory.meta.FireworkEffectMeta;
import org.bukkit.inventory.meta.FireworkMeta; import org.bukkit.inventory.meta.FireworkMeta;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.LeatherArmorMeta; import org.bukkit.inventory.meta.LeatherArmorMeta;
import org.bukkit.inventory.meta.PotionMeta;
import org.bukkit.inventory.meta.SkullMeta; import org.bukkit.inventory.meta.SkullMeta;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import org.bukkit.potion.Potion;
import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffect;
import java.util.ArrayList; import java.util.ArrayList;
@ -220,7 +219,7 @@ public abstract class AbstractItemDb implements IConf, net.ess3.api.IItemDb {
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(Enchantments.getRealName(e)).append(":").append(meta.getEnchantLevel(e)).append(" ");
} }
} }
@ -265,7 +264,7 @@ public abstract class AbstractItemDb implements IConf, net.ess3.api.IItemDb {
case ENCHANTED_BOOK: case ENCHANTED_BOOK:
final EnchantmentStorageMeta enchantmentStorageMeta = (EnchantmentStorageMeta) is.getItemMeta(); final EnchantmentStorageMeta enchantmentStorageMeta = (EnchantmentStorageMeta) is.getItemMeta();
for (final Enchantment e : enchantmentStorageMeta.getStoredEnchants().keySet()) { for (final Enchantment e : enchantmentStorageMeta.getStoredEnchants().keySet()) {
sb.append(e.getName().toLowerCase()).append(":").append(enchantmentStorageMeta.getStoredEnchantLevel(e)).append(" "); sb.append(Enchantments.getRealName(e)).append(":").append(enchantmentStorageMeta.getStoredEnchantLevel(e)).append(" ");
} }
break; break;
} }
@ -285,16 +284,8 @@ public abstract class AbstractItemDb implements IConf, net.ess3.api.IItemDb {
serializeEffectMeta(sb, fireworkEffectMeta.getEffect()); serializeEffectMeta(sb, fireworkEffectMeta.getEffect());
} }
} else if (MaterialUtil.isPotion(material)) { } else if (MaterialUtil.isPotion(material)) {
final boolean splash; final boolean splash = ess.getPotionMetaProvider().isSplashPotion(is);
final Collection<PotionEffect> effects; final Collection<PotionEffect> effects = ess.getPotionMetaProvider().getCustomEffects(is);
if (VersionUtil.PRE_FLATTENING) {
final Potion potion = Potion.fromDamage(is.getDurability());
splash = potion.isSplash();
effects = potion.getEffects();
} else {
splash = is.getType() == Material.SPLASH_POTION;
effects = ((PotionMeta) is.getItemMeta()).getCustomEffects();
}
for (final PotionEffect e : effects) { for (final PotionEffect e : effects) {
// long but needs to be effect:speed power:2 duration:120 in that order. // long but needs to be effect:speed power:2 duration:120 in that order.
@ -317,6 +308,7 @@ public abstract class AbstractItemDb implements IConf, net.ess3.api.IItemDb {
sb.append("basecolor:").append(basecolor).append(" "); sb.append("basecolor:").append(basecolor).append(" ");
} }
for (final org.bukkit.block.banner.Pattern p : shieldBannerMeta.getPatterns()) { for (final org.bukkit.block.banner.Pattern p : shieldBannerMeta.getPatterns()) {
//noinspection removal
final String type = p.getPattern().getIdentifier(); final String type = p.getPattern().getIdentifier();
final int color = p.getColor().getColor().asRGB(); final int color = p.getColor().getColor().asRGB();
sb.append(type).append(",").append(color).append(" "); sb.append(type).append(",").append(color).append(" ");
@ -324,7 +316,7 @@ public abstract class AbstractItemDb implements IConf, net.ess3.api.IItemDb {
} else { } else {
final BannerMeta bannerMeta = (BannerMeta) is.getItemMeta(); final BannerMeta bannerMeta = (BannerMeta) is.getItemMeta();
if (bannerMeta != null) { if (bannerMeta != null) {
DyeColor baseDyeColor = bannerMeta.getBaseColor(); DyeColor baseDyeColor = ess.getBannerDataProvider().getBaseColor(is);
if (baseDyeColor == null) { if (baseDyeColor == null) {
baseDyeColor = MaterialUtil.getColorOf(material); baseDyeColor = MaterialUtil.getColorOf(material);
} }
@ -335,6 +327,7 @@ public abstract class AbstractItemDb implements IConf, net.ess3.api.IItemDb {
sb.append("basecolor:").append(basecolor).append(" "); sb.append("basecolor:").append(basecolor).append(" ");
} }
for (final org.bukkit.block.banner.Pattern p : bannerMeta.getPatterns()) { for (final org.bukkit.block.banner.Pattern p : bannerMeta.getPatterns()) {
//noinspection removal
final String type = p.getPattern().getIdentifier(); final String type = p.getPattern().getIdentifier();
final int color = p.getColor().getColor().asRGB(); final int color = p.getColor().getColor().asRGB();
sb.append(type).append(",").append(color).append(" "); sb.append(type).append(",").append(color).append(" ");

View File

@ -9,13 +9,14 @@ import com.google.gson.JsonObject;
import com.google.gson.JsonParser; import com.google.gson.JsonParser;
import net.ess3.api.IEssentials; import net.ess3.api.IEssentials;
import net.ess3.api.TranslatableException; import net.ess3.api.TranslatableException;
import net.ess3.provider.PotionMetaProvider;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.entity.EntityType; import org.bukkit.entity.EntityType;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.Damageable; import org.bukkit.inventory.meta.Damageable;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.PotionMeta; import org.bukkit.inventory.meta.PotionMeta;
import org.bukkit.potion.PotionData; import org.bukkit.potion.PotionType;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
@ -23,6 +24,7 @@ import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -127,14 +129,14 @@ public class FlatItemDb extends AbstractItemDb {
final ItemStack stack = new ItemStack(material); final ItemStack stack = new ItemStack(material);
stack.setAmount(material.getMaxStackSize()); stack.setAmount(material.getMaxStackSize());
final PotionData potionData = data.getPotionData(); final ItemData.EssentialPotionData potionData = data.getPotionData();
final ItemMeta meta = stack.getItemMeta();
if (potionData != null && meta instanceof PotionMeta) { if (potionData != null && stack.getItemMeta() instanceof PotionMeta) {
final PotionMeta potionMeta = (PotionMeta) meta; ess.getPotionMetaProvider().setBasePotionType(stack, potionData.getType(), potionData.isExtended(), potionData.isUpgraded());
potionMeta.setBasePotionData(potionData);
} }
final ItemMeta meta = stack.getItemMeta();
// For some reason, Damageable doesn't extend ItemMeta but CB implements them in the same // For some reason, Damageable doesn't extend ItemMeta but CB implements them in the same
// class. As to why, your guess is as good as mine. // class. As to why, your guess is as good as mine.
if (split.length > 1 && meta instanceof Damageable) { if (split.length > 1 && meta instanceof Damageable) {
@ -200,14 +202,14 @@ public class FlatItemDb extends AbstractItemDb {
throw new UnsupportedOperationException("Legacy IDs aren't supported on this version."); throw new UnsupportedOperationException("Legacy IDs aren't supported on this version.");
} }
private ItemData lookup(final ItemStack item) { private ItemData lookup(final ItemStack is) {
final Material type = item.getType(); final Material type = is.getType();
if (MaterialUtil.isPotion(type) && item.getItemMeta() instanceof PotionMeta) { if (MaterialUtil.isPotion(type) && is.getItemMeta() instanceof PotionMeta) {
final PotionData potion = ((PotionMeta) item.getItemMeta()).getBasePotionData(); final PotionMetaProvider provider = ess.getPotionMetaProvider();
return new ItemData(type, potion); return new ItemData(type, new ItemData.EssentialPotionData(provider.getBasePotionType(is), provider.isUpgraded(is), provider.isExtended(is)));
} else if (type.toString().contains("SPAWNER")) { } else if (type.toString().contains("SPAWNER")) {
final EntityType entity = ess.getSpawnerItemProvider().getEntityType(item); final EntityType entity = ess.getSpawnerItemProvider().getEntityType(is);
return new ItemData(type, entity); return new ItemData(type, entity);
} else { } else {
return new ItemData(type); return new ItemData(type);
@ -224,14 +226,14 @@ public class FlatItemDb extends AbstractItemDb {
public static class ItemData { public static class ItemData {
private Material material; private Material material;
private String[] fallbacks = null; private String[] fallbacks = null;
private PotionData potionData = null; private EssentialPotionData potionData = null;
private EntityType entity = null; private EntityType entity = null;
ItemData(final Material material) { ItemData(final Material material) {
this.material = material; this.material = material;
} }
ItemData(final Material material, final PotionData potionData) { ItemData(final Material material, final EssentialPotionData potionData) {
this.material = material; this.material = material;
this.potionData = potionData; this.potionData = potionData;
} }
@ -267,7 +269,7 @@ public class FlatItemDb extends AbstractItemDb {
return material; return material;
} }
public PotionData getPotionData() { public EssentialPotionData getPotionData() {
return this.potionData; return this.potionData;
} }
@ -294,5 +296,51 @@ public class FlatItemDb extends AbstractItemDb {
return false; return false;
} }
} }
public static class EssentialPotionData {
private PotionType type;
private String fallbackType;
private final boolean upgraded;
private final boolean extended;
EssentialPotionData(PotionType type, boolean upgraded, boolean extended) {
this.type = type;
this.upgraded = upgraded;
this.extended = extended;
}
public PotionType getType() {
if (type == null && fallbackType != null) {
type = EnumUtil.valueOf(PotionType.class, fallbackType);
fallbackType = null; // If fallback fails, don't keep trying to look up fallbacks
}
return type;
}
public boolean isUpgraded() {
return upgraded;
}
public boolean isExtended() {
return extended;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final EssentialPotionData that = (EssentialPotionData) o;
return upgraded == that.upgraded &&
extended == that.extended &&
// Use the getters here to ensure the fallbacks are being used
getType() == that.getType();
}
@Override
public int hashCode() {
return Objects.hash(getType(), upgraded, extended);
}
}
} }
} }

View File

@ -121,15 +121,17 @@ public class SimpleMessageRecipient implements IMessageRecipient {
// Dont spy on chats involving socialspy exempt players // Dont spy on chats involving socialspy exempt players
&& !senderUser.isAuthorized("essentials.chat.spy.exempt") && !senderUser.isAuthorized("essentials.chat.spy.exempt")
&& recipientUser != null && !recipientUser.isAuthorized("essentials.chat.spy.exempt")) { && recipientUser != null && !recipientUser.isAuthorized("essentials.chat.spy.exempt")) {
final String senderName = ess.getSettings().isSocialSpyDisplayNames() ? getDisplayName() : getName();
final String recipientName = ess.getSettings().isSocialSpyDisplayNames() ? recipient.getDisplayName() : recipient.getName();
for (final User onlineUser : ess.getOnlineUsers()) { for (final User onlineUser : ess.getOnlineUsers()) {
if (onlineUser.isSocialSpyEnabled() if (onlineUser.isSocialSpyEnabled()
// Don't send socialspy messages to message sender/receiver to prevent spam // Don't send socialspy messages to message sender/receiver to prevent spam
&& !onlineUser.equals(senderUser) && !onlineUser.equals(senderUser)
&& !onlineUser.equals(recipient)) { && !onlineUser.equals(recipient)) {
if (senderUser.isMuted() && ess.getSettings().getSocialSpyListenMutedPlayers()) { if (senderUser.isMuted() && ess.getSettings().getSocialSpyListenMutedPlayers()) {
onlineUser.sendComponent(AdventureUtil.miniMessage().deserialize(tlSender("socialSpyMutedPrefix") + tlLiteral("socialSpyMsgFormat", getDisplayName(), recipient.getDisplayName(), message))); onlineUser.sendComponent(AdventureUtil.miniMessage().deserialize(tlSender("socialSpyMutedPrefix") + tlLiteral("socialSpyMsgFormat", senderName, recipientName, message)));
} else { } else {
onlineUser.sendComponent(AdventureUtil.miniMessage().deserialize(tlLiteral("socialSpyPrefix") + tlLiteral("socialSpyMsgFormat", getDisplayName(), recipient.getDisplayName(), message))); onlineUser.sendComponent(AdventureUtil.miniMessage().deserialize(tlLiteral("socialSpyPrefix") + tlLiteral("socialSpyMsgFormat", senderName, recipientName, message)));
} }
} }
} }

View File

@ -550,9 +550,11 @@ public class EssentialsSign {
static class BlockSign implements ISign { static class BlockSign implements ISign {
private final transient Block block; private final transient Block block;
private transient Sign sign;
BlockSign(final Block block) { BlockSign(final Block block) {
this.block = block; this.block = block;
this.sign = getSign();
} }
@Override @Override
@ -569,7 +571,7 @@ public class EssentialsSign {
@Override @Override
public final void setLine(final int index, final String text) { public final void setLine(final int index, final String text) {
getSign().setLine(index, text); sign.setLine(index, text);
updateSign(); updateSign();
} }
@ -586,7 +588,8 @@ public class EssentialsSign {
@Override @Override
public final void updateSign() { public final void updateSign() {
getSign().update(); sign.update();
sign = getSign();
} }
} }
} }

View File

@ -46,7 +46,7 @@ public class SignBuy extends EssentialsSign {
charge.isAffordableFor(player); charge.isAffordableFor(player);
if (!items.pay(player)) { if (!items.pay(player)) {
throw new ChargeException("Inventory full"); //TODO: TL throw new ChargeException("inventoryFull");
} }
charge.charge(player); charge.charge(player);
Trade.log("Sign", "Buy", "Interact", username, charge, username, items, sign.getBlock().getLocation(), player.getMoney(), ess); Trade.log("Sign", "Buy", "Interact", username, charge, username, items, sign.getBlock().getLocation(), player.getMoney(), ess);

View File

@ -106,7 +106,7 @@ public class SignEnchant extends EssentialsSign {
throw new SignException(ex, "errorWithMessage", ex.getMessage()); throw new SignException(ex, "errorWithMessage", ex.getMessage());
} }
final String enchantmentName = enchantment.getName().toLowerCase(Locale.ENGLISH); final String enchantmentName = Enchantments.getRealName(enchantment);
if (level == 0) { if (level == 0) {
player.sendTl("enchantmentRemoved", enchantmentName.replace('_', ' ')); player.sendTl("enchantmentRemoved", enchantmentName.replace('_', ' '));
} else { } else {

View File

@ -21,9 +21,10 @@ public class SignHeal extends EssentialsSign {
if (player.getBase().getHealth() == 0) { if (player.getBase().getHealth() == 0) {
throw new SignException("healDead"); throw new SignException("healDead");
} }
final double amount = player.getBase().getMaxHealth();
final Trade charge = getTrade(sign, 1, ess); final Trade charge = getTrade(sign, 1, ess);
charge.isAffordableFor(player); charge.isAffordableFor(player);
player.getBase().setHealth(20); player.getBase().setHealth(amount);
player.getBase().setFoodLevel(20); player.getBase().setFoodLevel(20);
player.getBase().setFireTicks(0); player.getBase().setFireTicks(0);
player.sendTl("youAreHealed"); player.sendTl("youAreHealed");

View File

@ -0,0 +1,32 @@
package com.earth2me.essentials.signs;
import com.earth2me.essentials.ChargeException;
import com.earth2me.essentials.RandomTeleport;
import com.earth2me.essentials.User;
import net.ess3.api.IEssentials;
import net.ess3.api.MaxMoneyException;
import org.bukkit.event.player.PlayerTeleportEvent;
import java.util.concurrent.CompletableFuture;
public class SignRandomTeleport extends EssentialsSign {
public SignRandomTeleport() {
super("RandomTeleport");
}
@Override
protected boolean onSignInteract(ISign sign, User player, String username, IEssentials ess) throws SignException, ChargeException, MaxMoneyException {
final String name = sign.getLine(1);
final RandomTeleport randomTeleport = ess.getRandomTeleport();
randomTeleport.getRandomLocation(name).thenAccept(location -> {
final CompletableFuture<Boolean> future = new CompletableFuture<>();
future.thenAccept(success -> {
if (success) {
player.sendTl("tprSuccess");
}
});
player.getAsyncTeleport().now(location, false, PlayerTeleportEvent.TeleportCause.COMMAND, future);
});
return true;
}
}

View File

@ -6,6 +6,7 @@ import com.earth2me.essentials.User;
import com.earth2me.essentials.commands.Commandrepair; import com.earth2me.essentials.commands.Commandrepair;
import com.earth2me.essentials.commands.NotEnoughArgumentsException; import com.earth2me.essentials.commands.NotEnoughArgumentsException;
import net.ess3.api.IEssentials; import net.ess3.api.IEssentials;
import net.ess3.api.TranslatableException;
public class SignRepair extends EssentialsSign { public class SignRepair extends EssentialsSign {
public SignRepair() { public SignRepair() {
@ -42,6 +43,8 @@ public class SignRepair extends EssentialsSign {
throw new NotEnoughArgumentsException(); throw new NotEnoughArgumentsException();
} }
} catch (final TranslatableException ex) {
throw new SignException(ex.getTlKey(), ex.getArgs());
} catch (final Exception ex) { } catch (final Exception ex) {
throw new SignException(ex, "errorWithMessage", ex.getMessage()); throw new SignException(ex, "errorWithMessage", ex.getMessage());
} }

View File

@ -72,7 +72,7 @@ public class SignTrade extends EssentialsSign {
if (!trade.pay(player)) { if (!trade.pay(player)) {
subtractAmount(sign, 1, charge, ess); subtractAmount(sign, 1, charge, ess);
addAmount(sign, 2, trade, ess); addAmount(sign, 2, trade, ess);
throw new ChargeException("Full inventory"); throw new ChargeException("inventoryFull");
} }
charge.charge(player); charge.charge(player);
Trade.log("Sign", "Trade", "Interact", sign.getLine(3).substring(2), charge, username, trade, sign.getBlock().getLocation(), player.getMoney(), ess); Trade.log("Sign", "Trade", "Interact", sign.getLine(3).substring(2), charge, username, trade, sign.getBlock().getLocation(), player.getMoney(), ess);

View File

@ -4,6 +4,7 @@ import com.earth2me.essentials.ChargeException;
import com.earth2me.essentials.Trade; import com.earth2me.essentials.Trade;
import com.earth2me.essentials.User; import com.earth2me.essentials.User;
import net.ess3.api.IEssentials; import net.ess3.api.IEssentials;
import net.ess3.api.TranslatableException;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
@ -25,6 +26,10 @@ public class SignWarp extends EssentialsSign {
try { try {
ess.getWarps().getWarp(warpName); ess.getWarps().getWarp(warpName);
} catch (final Exception ex) { } catch (final Exception ex) {
if (ex instanceof TranslatableException) {
final TranslatableException te = (TranslatableException) ex;
throw new SignException(ex, te.getTlKey(), te.getArgs());
}
throw new SignException(ex, "errorWithMessage", ex.getMessage()); throw new SignException(ex, "errorWithMessage", ex.getMessage());
} }
final String group = sign.getLine(2); final String group = sign.getLine(2);

View File

@ -25,7 +25,8 @@ public enum Signs {
TRADE(new SignTrade()), TRADE(new SignTrade()),
WARP(new SignWarp()), WARP(new SignWarp()),
WEATHER(new SignWeather()), WEATHER(new SignWeather()),
WORKBENCH(new SignWorkbench()); WORKBENCH(new SignWorkbench()),
RANDOMTELEPORT(new SignRandomTeleport());
private final EssentialsSign sign; private final EssentialsSign sign;
Signs(final EssentialsSign sign) { Signs(final EssentialsSign sign) {

View File

@ -50,7 +50,7 @@ public final class AdventureUtil {
} }
LEGACY_SERIALIZER = builder.build(); LEGACY_SERIALIZER = builder.build();
MINI_MESSAGE_NO_TAGS = MiniMessage.miniMessage(); MINI_MESSAGE_NO_TAGS = MiniMessage.builder().strict(true).build();
miniMessageInstance = createMiniMessageInstance(); miniMessageInstance = createMiniMessageInstance();
} }

View File

@ -1,5 +1,6 @@
package com.earth2me.essentials.utils; package com.earth2me.essentials.utils;
import com.earth2me.essentials.Essentials;
import com.earth2me.essentials.IEssentials; import com.earth2me.essentials.IEssentials;
import net.ess3.api.IUser; import net.ess3.api.IUser;
import net.ess3.api.TranslatableException; import net.ess3.api.TranslatableException;
@ -40,10 +41,14 @@ public final class LocationUtil {
private static final Set<Material> TRANSPARENT_MATERIALS = EnumSet.noneOf(Material.class); private static final Set<Material> TRANSPARENT_MATERIALS = EnumSet.noneOf(Material.class);
static { static {
// Materials from Material.isTransparent() // If the server is running in a test environment, the isTransparent() method will blow up since
for (final Material mat : Material.values()) { // it requires the registry to be initialized. This is a workaround to prevent that from happening.
if (mat.isTransparent()) { if (!Essentials.TESTING) {
HOLLOW_MATERIALS.add(mat); // Materials from Material.isTransparent()
for (final Material mat : Material.values()) {
if (mat.isTransparent()) {
HOLLOW_MATERIALS.add(mat);
}
} }
} }

View File

@ -0,0 +1,70 @@
package com.earth2me.essentials.utils;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Table;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
public final class RegistryUtil {
private static final Table<Class<?>, String, Object> registryCache = HashBasedTable.create();
private RegistryUtil() {
}
public static <T> Object[] values(Class<T> registry) {
if (registry.getEnumConstants() != null) {
return registry.getEnumConstants();
}
//noinspection unchecked
final T[] values = (T[]) registryCache.get(registry, "$values");
if (values != null) {
return values;
}
final List<T> set = new ArrayList<>();
for (final Field field : registry.getDeclaredFields()) {
try {
final Object value = field.get(null);
if (value != null && registry.isAssignableFrom(value.getClass())) {
//noinspection unchecked
set.add((T) value);
}
} catch (NullPointerException | IllegalAccessException ignored) {
}
}
//noinspection unchecked
final T[] array = (T[]) new Object[set.size()];
for (int i = 0; i < set.size(); i++) {
array[i] = set.get(i);
}
registryCache.put(registry, "$values", array);
return array;
}
public static <T> T valueOf(Class<T> registry, String... names) {
for (final String name : names) {
//noinspection unchecked
T value = (T) registryCache.get(registry, name);
if (value != null) {
return value;
}
try {
//noinspection unchecked
value = (T) registry.getDeclaredField(name).get(null);
if (value != null) {
registryCache.put(registry, name, value);
return value;
}
} catch (NoSuchFieldException | IllegalAccessException ignored) {
}
}
return null;
}
}

View File

@ -39,8 +39,11 @@ public final class VersionUtil {
public static final BukkitVersion v1_19_4_R01 = BukkitVersion.fromString("1.19.4-R0.1-SNAPSHOT"); public static final BukkitVersion v1_19_4_R01 = BukkitVersion.fromString("1.19.4-R0.1-SNAPSHOT");
public static final BukkitVersion v1_20_1_R01 = BukkitVersion.fromString("1.20.1-R0.1-SNAPSHOT"); public static final BukkitVersion v1_20_1_R01 = BukkitVersion.fromString("1.20.1-R0.1-SNAPSHOT");
public static final BukkitVersion v1_20_4_R01 = BukkitVersion.fromString("1.20.4-R0.1-SNAPSHOT"); public static final BukkitVersion v1_20_4_R01 = BukkitVersion.fromString("1.20.4-R0.1-SNAPSHOT");
public static final BukkitVersion v1_20_6_R01 = BukkitVersion.fromString("1.20.6-R0.1-SNAPSHOT");
public static final BukkitVersion v1_21_R01 = BukkitVersion.fromString("1.21-R0.1-SNAPSHOT");
public static final BukkitVersion v1_21_3_R01 = BukkitVersion.fromString("1.21.3-R0.1-SNAPSHOT");
private static final Set<BukkitVersion> supportedVersions = ImmutableSet.of(v1_8_8_R01, v1_9_4_R01, v1_10_2_R01, v1_11_2_R01, v1_12_2_R01, v1_13_2_R01, v1_14_4_R01, v1_15_2_R01, v1_16_5_R01, v1_17_1_R01, v1_18_2_R01, v1_19_4_R01, v1_20_4_R01); private static final Set<BukkitVersion> supportedVersions = ImmutableSet.of(v1_8_8_R01, v1_9_4_R01, v1_10_2_R01, v1_11_2_R01, v1_12_2_R01, v1_13_2_R01, v1_14_4_R01, v1_15_2_R01, v1_16_5_R01, v1_17_1_R01, v1_18_2_R01, v1_19_4_R01, v1_20_6_R01, v1_21_3_R01);
public static final boolean PRE_FLATTENING = VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_13_0_R01); public static final boolean PRE_FLATTENING = VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_13_0_R01);

View File

@ -1,18 +0,0 @@
package net.ess3.api;
/**
* Fired when trying to teleport a user to an invalid world. This usually only occurs if a world has been removed from
* the server and a player tries to teleport to a warp or home in that world.
*/
public class InvalidWorldException extends TranslatableException {
private final String world;
public InvalidWorldException(final String world) {
super("invalidWorld");
this.world = world;
}
public String getWorld() {
return this.world;
}
}

View File

@ -14,14 +14,17 @@ public class UserRandomTeleportEvent extends Event implements Cancellable {
private static final HandlerList handlers = new HandlerList(); private static final HandlerList handlers = new HandlerList();
private final IUser user; private final IUser user;
private String name;
private Location center; private Location center;
private double minRange; private double minRange;
private double maxRange; private double maxRange;
private boolean cancelled = false; private boolean cancelled = false;
private boolean modified = false;
public UserRandomTeleportEvent(final IUser user, final Location center, final double minRange, final double maxRange) { public UserRandomTeleportEvent(final IUser user, final String name, final Location center, final double minRange, final double maxRange) {
super(!Bukkit.isPrimaryThread()); super(!Bukkit.isPrimaryThread());
this.user = user; this.user = user;
this.name = name;
this.center = center; this.center = center;
this.minRange = minRange; this.minRange = minRange;
this.maxRange = maxRange; this.maxRange = maxRange;
@ -35,11 +38,23 @@ public class UserRandomTeleportEvent extends Event implements Cancellable {
return user; return user;
} }
public String getName() {
return name;
}
public Location getCenter() { public Location getCenter() {
return center; return center;
} }
/**
* Sets the center location to teleport from.
*
* @param center Center location.
*/
public void setCenter(final Location center) { public void setCenter(final Location center) {
if (!this.center.equals(center)) {
modified = true;
}
this.center = center; this.center = center;
} }
@ -47,7 +62,15 @@ public class UserRandomTeleportEvent extends Event implements Cancellable {
return minRange; return minRange;
} }
/**
* Sets the minimum range for the teleport.
*
* @param minRange Minimum range.
*/
public void setMinRange(final double minRange) { public void setMinRange(final double minRange) {
if (this.minRange != minRange) {
modified = true;
}
this.minRange = minRange; this.minRange = minRange;
} }
@ -55,7 +78,15 @@ public class UserRandomTeleportEvent extends Event implements Cancellable {
return maxRange; return maxRange;
} }
/**
* Sets the maximum range for the teleport.
*
* @param maxRange Maximum range.
*/
public void setMaxRange(final double maxRange) { public void setMaxRange(final double maxRange) {
if (this.maxRange != maxRange) {
modified = true;
}
this.maxRange = maxRange; this.maxRange = maxRange;
} }
@ -69,6 +100,10 @@ public class UserRandomTeleportEvent extends Event implements Cancellable {
cancelled = b; cancelled = b;
} }
public boolean isModified() {
return modified;
}
@Override @Override
public HandlerList getHandlers() { public HandlerList getHandlers() {
return handlers; return handlers;

View File

@ -213,6 +213,10 @@ socialspy-listen-muted-players: true
# If false, social spy will only monitor commands from the list above. # If false, social spy will only monitor commands from the list above.
socialspy-messages: true socialspy-messages: true
# Whether social spy should use formatted display names which may include color.
# If false, social spy will use only the actual player names.
socialspy-uses-displaynames: true
# The following settings listen for when a player changes worlds. # The following settings listen for when a player changes worlds.
# If you use another plugin to control speed and flight, you should change these to false. # If you use another plugin to control speed and flight, you should change these to false.
@ -383,6 +387,7 @@ enabledSigns:
#- loom #- loom
#- smithing #- smithing
#- workbench #- workbench
#- randomteleport
# How many times per second can Essentials signs be interacted with per player. # How many times per second can Essentials signs be interacted with per player.
# Values should be between 1-20, 20 being virtually no lag protection. # Values should be between 1-20, 20 being virtually no lag protection.
@ -931,7 +936,7 @@ chat:
# If you are using group formats make sure to remove the '#' to allow the setting to be read. # If you are using group formats make sure to remove the '#' to allow the setting to be read.
# Note: Group names are case-sensitive so you must match them up with your permission plugin. # Note: Group names are case-sensitive so you must match them up with your permission plugin.
# You can use permissions to control whether players can use formatting codes in their chat messages. # You can use permissions to control whether players can use formatting codes in their chat messages.
# See https://essentialsx.net/wiki/Color-Permissions.html for more information. # See https://essentialsx.net/wiki/Color-Permissions.html for more information.
@ -1193,6 +1198,12 @@ respawn-at-home-bed: true
# When users die, should EssentialsSpawn respect users' respawn anchors? # When users die, should EssentialsSpawn respect users' respawn anchors?
respawn-at-anchor: false respawn-at-anchor: false
# If configured, users will spawn at the random spawn location instead of the newbies spawnpoint.
random-spawn-location: "none"
# If configured, when users die, they will respawn at the random respawn location.
random-respawn-location: "none"
# Teleport all joining players to the spawnpoint # Teleport all joining players to the spawnpoint
spawn-on-join: false spawn-on-join: false
# The following value of `guests` states that all players in group `guests` will be teleported to spawn when joining. # The following value of `guests` states that all players in group `guests` will be teleported to spawn when joining.

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
# Configuration for the random teleport command. # Configuration for the random teleport command.
# Some settings may be defaulted, and can be changed via the /settpr command in-game. # Some settings may be defaulted, and can be changed via the /settpr command in-game.
min-range: 0.0 default-location: '{world}'
excluded-biomes: excluded-biomes:
- cold_ocean - cold_ocean
- deep_cold_ocean - deep_cold_ocean

View File

@ -218,7 +218,7 @@ public abstract class AbstractChatHandler {
// Strip local chat prefix to preserve API behaviour // Strip local chat prefix to preserve API behaviour
final String localPrefix = AdventureUtil.miniToLegacy(tlLiteral("chatTypeLocal")); final String localPrefix = AdventureUtil.miniToLegacy(tlLiteral("chatTypeLocal"));
String baseFormat = event.getFormat(); String baseFormat = AdventureUtil.legacyToMini(event.getFormat());
if (event.getFormat().startsWith(localPrefix)) { if (event.getFormat().startsWith(localPrefix)) {
baseFormat = baseFormat.substring(localPrefix.length()); baseFormat = baseFormat.substring(localPrefix.length());
} }

View File

@ -4,15 +4,15 @@ plugins {
dependencies { dependencies {
compileOnly project(':EssentialsX') compileOnly project(':EssentialsX')
implementation('net.dv8tion:JDA:5.0.0-beta.12') { implementation('net.dv8tion:JDA:5.1.2') {
exclude(module: 'opus-java') exclude(module: 'opus-java')
} }
implementation 'com.github.MinnDevelopment:emoji-java:v6.1.0' implementation 'com.github.MinnDevelopment:emoji-java:v6.1.0'
implementation('club.minnced:discord-webhooks:0.8.2') { implementation('club.minnced:discord-webhooks:0.8.4') {
exclude(module: 'okhttp') exclude(module: 'okhttp')
} }
compileOnly 'org.apache.logging.log4j:log4j-core:2.17.1' compileOnly 'org.apache.logging.log4j:log4j-core:2.17.1'
compileOnly 'me.clip:placeholderapi:2.10.9' compileOnly 'me.clip:placeholderapi:2.11.6'
} }
shadowJar { shadowJar {
@ -24,7 +24,7 @@ shadowJar {
include(dependency('com.squareup.okio:okio')) include(dependency('com.squareup.okio:okio'))
include(dependency('com.squareup.okio:okio-jvm')) include(dependency('com.squareup.okio:okio-jvm'))
include(dependency('org.apache.commons:commons-collections4')) include(dependency('org.apache.commons:commons-collections4'))
include(dependency('net.sf.trove4j:trove4j')) include(dependency('net.sf.trove4j:core'))
include(dependency('com.fasterxml.jackson.core:jackson-databind')) include(dependency('com.fasterxml.jackson.core:jackson-databind'))
include(dependency('com.fasterxml.jackson.core:jackson-core')) include(dependency('com.fasterxml.jackson.core:jackson-core'))
include(dependency('com.fasterxml.jackson.core:jackson-annotations')) include(dependency('com.fasterxml.jackson.core:jackson-annotations'))

View File

@ -383,11 +383,10 @@ public class JDADiscordService implements DiscordService, IEssentialsModule {
final Webhook webhook = DiscordUtil.getOrCreateWebhook(channel, DiscordUtil.ADVANCED_RELAY_NAME).join(); final Webhook webhook = DiscordUtil.getOrCreateWebhook(channel, DiscordUtil.ADVANCED_RELAY_NAME).join();
if (webhook == null) { if (webhook == null) {
final WrappedWebhookClient current = channelIdToWebhook.get(channel.getId()); final WrappedWebhookClient current = channelIdToWebhook.remove(channel.getId());
if (current != null) { if (current != null) {
current.close(); current.close();
} }
channelIdToWebhook.remove(channel.getId()).close();
continue; continue;
} }
typeToChannelId.put(type, channel.getId()); typeToChannelId.put(type, channel.getId());

View File

@ -12,6 +12,7 @@ import org.bukkit.entity.Player;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerRespawnEvent; import org.bukkit.event.player.PlayerRespawnEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import java.util.List; import java.util.List;
@ -64,6 +65,9 @@ class EssentialsSpawnPlayerListener implements Listener {
return; return;
} }
} }
if (tryRandomTeleport(user, ess.getSettings().getRandomRespawnLocation())) {
return;
}
final Location spawn = spawns.getSpawn(user.getGroup()); final Location spawn = spawns.getSpawn(user.getGroup());
if (spawn != null) { if (spawn != null) {
event.setRespawnLocation(spawn); event.setRespawnLocation(spawn);
@ -102,7 +106,9 @@ class EssentialsSpawnPlayerListener implements Listener {
final User user = ess.getUser(player); final User user = ess.getUser(player);
if (!"none".equalsIgnoreCase(ess.getSettings().getNewbieSpawn())) { final boolean spawnRandomly = tryRandomTeleport(user, ess.getSettings().getRandomSpawnLocation());
if (!spawnRandomly && !"none".equalsIgnoreCase(ess.getSettings().getNewbieSpawn())) {
ess.scheduleSyncDelayedTask(new NewPlayerTeleport(user), 1L); ess.scheduleSyncDelayedTask(new NewPlayerTeleport(user), 1L);
} }
@ -158,4 +164,15 @@ class EssentialsSpawnPlayerListener implements Listener {
} }
} }
} }
private boolean tryRandomTeleport(final User user, final String name) {
if (!ess.getRandomTeleport().hasLocation(name)) {
return false;
}
ess.getRandomTeleport().getRandomLocation(name).thenAccept(location -> {
final CompletableFuture<Boolean> future = new CompletableFuture<>();
user.getAsyncTeleport().now(location, false, PlayerTeleportEvent.TeleportCause.PLUGIN, future);
});
return true;
}
} }

View File

@ -1,13 +1,10 @@
package com.earth2me.essentials.xmpp; package com.earth2me.essentials.xmpp;
import com.earth2me.essentials.ChargeException;
import com.earth2me.essentials.CommandSource; import com.earth2me.essentials.CommandSource;
import com.earth2me.essentials.User; import com.earth2me.essentials.User;
import com.earth2me.essentials.commands.EssentialsLoopCommand; import com.earth2me.essentials.commands.EssentialsLoopCommand;
import com.earth2me.essentials.commands.NotEnoughArgumentsException; import com.earth2me.essentials.commands.NotEnoughArgumentsException;
import com.earth2me.essentials.commands.PlayerExemptException; import net.ess3.api.TranslatableException;
import com.earth2me.essentials.commands.PlayerNotFoundException;
import net.ess3.api.MaxMoneyException;
import org.bukkit.Server; import org.bukkit.Server;
public class Commandxmppspy extends EssentialsLoopCommand { public class Commandxmppspy extends EssentialsLoopCommand {
@ -16,7 +13,7 @@ public class Commandxmppspy extends EssentialsLoopCommand {
} }
@Override @Override
protected void run(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws NotEnoughArgumentsException, PlayerExemptException, MaxMoneyException, ChargeException, PlayerNotFoundException { protected void run(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws NotEnoughArgumentsException, TranslatableException {
if (args.length == 0) { if (args.length == 0) {
throw new NotEnoughArgumentsException(); throw new NotEnoughArgumentsException();
} }

View File

@ -26,7 +26,7 @@ however, have some new requirements:
* **EssentialsX requires CraftBukkit, Spigot or Paper to run.** Other server software may work, but these are not tested * **EssentialsX requires CraftBukkit, Spigot or Paper to run.** Other server software may work, but these are not tested
by the team and we may not be able to help with any issues that occur. by the team and we may not be able to help with any issues that occur.
* **EssentialsX currently supports Minecraft versions 1.8.8, 1.9.4, 1.10.2, 1.11.2, 1.12.2, 1.13.2, 1.14.4, 1.15.2, * **EssentialsX currently supports Minecraft versions 1.8.8, 1.9.4, 1.10.2, 1.11.2, 1.12.2, 1.13.2, 1.14.4, 1.15.2,
1.16.5, 1.17.1, 1.18.2, 1.19.4, and 1.20.4.** 1.16.5, 1.17.1, 1.18.2, 1.19.4, 1.20.6, and 1.21.3.**
* **EssentialsX currently requires Java 8 or higher.** We recommend using the latest Java version supported by your * **EssentialsX currently requires Java 8 or higher.** We recommend using the latest Java version supported by your
server software. server software.
* **EssentialsX requires [Vault](http://dev.bukkit.org/bukkit-plugins/vault/) to enable using chat prefix/suffixes and * **EssentialsX requires [Vault](http://dev.bukkit.org/bukkit-plugins/vault/) to enable using chat prefix/suffixes and

View File

@ -8,6 +8,6 @@ repositories {
dependencies { dependencies {
implementation("net.kyori", "indra-common", "3.1.3") implementation("net.kyori", "indra-common", "3.1.3")
implementation("com.github.johnrengelman", "shadow", "8.1.1") implementation("com.gradleup.shadow", "shadow-gradle-plugin", "8.3.3")
implementation("xyz.jpenilla", "run-task", "2.2.3") implementation("xyz.jpenilla", "run-task", "2.3.1")
} }

View File

@ -1 +1 @@
const val RUN_PAPER_MINECRAFT_VERSION = "1.20.4" const val RUN_PAPER_MINECRAFT_VERSION = "1.21.1"

View File

@ -10,7 +10,7 @@ plugins {
val baseExtension = extensions.create<EssentialsBaseExtension>("essentials", project) val baseExtension = extensions.create<EssentialsBaseExtension>("essentials", project)
val checkstyleVersion = "8.36.2" val checkstyleVersion = "8.36.2"
val spigotVersion = "1.20.4-R0.1-SNAPSHOT" val spigotVersion = "1.21.3-R0.1-SNAPSHOT"
val junit5Version = "5.10.2" val junit5Version = "5.10.2"
val mockitoVersion = "3.12.4" val mockitoVersion = "3.12.4"
@ -75,6 +75,9 @@ tasks {
} }
withType<Jar> { withType<Jar> {
archiveVersion.set(rootProject.ext["FULL_VERSION"] as String) archiveVersion.set(rootProject.ext["FULL_VERSION"] as String)
manifest {
attributes("paperweight-mappings-namespace" to "mojang")
}
} }
withType<Sign> { withType<Sign> {
onlyIf { project.hasProperty("forceSign") } onlyIf { project.hasProperty("forceSign") }
@ -122,7 +125,7 @@ indra {
javaVersions { javaVersions {
target(8) target(8)
minimumToolchain(17) minimumToolchain(21)
// Don't enforce running tests on Java 8; we only care about the release for compiling, not running tests // Don't enforce running tests on Java 8; we only care about the release for compiling, not running tests
strictVersions(false) strictVersions(false)
} }

View File

@ -1,6 +1,6 @@
plugins { plugins {
id("essentials.module-conventions") id("essentials.module-conventions")
id("com.github.johnrengelman.shadow") id("com.gradleup.shadow")
} }
tasks { tasks {
@ -8,7 +8,7 @@ tasks {
archiveClassifier.set("unshaded") archiveClassifier.set("unshaded")
} }
shadowJar { shadowJar {
archiveClassifier.set(null) archiveClassifier.set(null as String?)
} }
} }

View File

@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
networkTimeout=10000 networkTimeout=10000
validateDistributionUrl=true validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME

View File

@ -3,6 +3,9 @@ plugins {
} }
dependencies { dependencies {
implementation(project(':providers:BaseProviders')) {
exclude group: "org.spigotmc", module: "spigot-api"
}
api project(':providers:NMSReflectionProvider') api project(':providers:NMSReflectionProvider')
} }

View File

@ -0,0 +1,26 @@
package net.ess3.provider.providers;
import net.ess3.provider.BannerDataProvider;
import org.bukkit.DyeColor;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.BannerMeta;
public class LegacyBannerDataProvider implements BannerDataProvider {
@Override
public DyeColor getBaseColor(ItemStack stack) {
final BannerMeta bannerMeta = (BannerMeta) stack.getItemMeta();
return bannerMeta.getBaseColor();
}
@Override
public void setBaseColor(ItemStack stack, DyeColor color) {
final BannerMeta bannerMeta = (BannerMeta) stack.getItemMeta();
bannerMeta.setBaseColor(color);
stack.setItemMeta(bannerMeta);
}
@Override
public String getDescription() {
return "Legacy Banner Meta Provider";
}
}

View File

@ -0,0 +1,33 @@
package net.ess3.provider.providers;
import net.ess3.provider.InventoryViewProvider;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryView;
import org.bukkit.inventory.ItemStack;
public class LegacyInventoryViewProvider implements InventoryViewProvider {
@Override
public Inventory getTopInventory(InventoryView view) {
return view.getTopInventory();
}
@Override
public Inventory getBottomInventory(InventoryView view) {
return view.getBottomInventory();
}
@Override
public void setItem(InventoryView view, int slot, ItemStack item) {
view.setItem(slot, item);
}
@Override
public void close(InventoryView view) {
view.close();
}
@Override
public String getDescription() {
return "Legacy InventoryView Abstract Class ABI Provider";
}
}

View File

@ -0,0 +1,134 @@
package net.ess3.provider.providers;
import com.google.common.collect.ImmutableMap;
import net.ess3.provider.PotionMetaProvider;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.PotionMeta;
import org.bukkit.potion.PotionData;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionType;
import java.util.Collection;
import java.util.Map;
public class LegacyPotionMetaProvider implements PotionMetaProvider {
private static final Map<Integer, PotionType> damageValueToType = ImmutableMap.<Integer, PotionType>builder()
.put(1, PotionType.REGEN)
.put(2, PotionType.SPEED)
.put(3, PotionType.FIRE_RESISTANCE)
.put(4, PotionType.POISON)
.put(5, PotionType.INSTANT_HEAL)
.put(6, PotionType.NIGHT_VISION)
// Skip 7
.put(8, PotionType.WEAKNESS)
.put(9, PotionType.STRENGTH)
.put(10, PotionType.SLOWNESS)
.put(11, PotionType.JUMP)
.put(12, PotionType.INSTANT_DAMAGE)
.put(13, PotionType.WATER_BREATHING)
.put(14, PotionType.INVISIBILITY)
.build();
private static int getBit(final int n, final int k) {
return (n >> k) & 1;
}
@Override
public ItemStack createPotionItem(final Material initial, final int effectId) {
ItemStack potion = new ItemStack(initial, 1);
if (effectId == 0) {
return potion;
}
final int damageValue = getBit(effectId, 0) +
2 * getBit(effectId, 1) +
4 * getBit(effectId, 2) +
8 * getBit(effectId, 3);
final PotionType type = damageValueToType.get(damageValue);
if (type == null) {
throw new IllegalArgumentException("Unable to process potion effect ID " + effectId + " with damage value " + damageValue);
}
//getBit is splash here
if (getBit(effectId, 14) == 1 && initial == Material.POTION) {
potion = new ItemStack(Material.SPLASH_POTION, 1);
}
final PotionMeta meta = (PotionMeta) potion.getItemMeta();
//getBit(s) are extended and upgraded respectfully
final PotionData data = new PotionData(type, getBit(effectId, 6) == 1, getBit(effectId, 5) == 1);
meta.setBasePotionData(data); // this method is exclusive to recent 1.9+
potion.setItemMeta(meta);
return potion;
}
@Override
public void setSplashPotion(final ItemStack stack, final boolean isSplash) {
if (stack == null) {
throw new IllegalArgumentException("ItemStack cannot be null");
}
if (isSplash && stack.getType() == Material.POTION) {
stack.setType(Material.SPLASH_POTION);
} else if (!isSplash && stack.getType() == Material.SPLASH_POTION) {
stack.setType(Material.POTION);
}
}
@Override
public boolean isSplashPotion(final ItemStack stack) {
return stack != null && stack.getType() == Material.SPLASH_POTION;
}
@Override
public Collection<PotionEffect> getCustomEffects(final ItemStack stack) {
final PotionMeta meta = (PotionMeta) stack.getItemMeta();
return meta.getCustomEffects();
}
@Override
public boolean isExtended(final ItemStack stack) {
final PotionMeta meta = (PotionMeta) stack.getItemMeta();
final PotionData data = meta.getBasePotionData();
return data.isExtended();
}
@Override
public boolean isUpgraded(final ItemStack stack) {
final PotionMeta meta = (PotionMeta) stack.getItemMeta();
final PotionData data = meta.getBasePotionData();
return data.isUpgraded();
}
@Override
public PotionType getBasePotionType(final ItemStack stack) {
final PotionMeta meta = (PotionMeta) stack.getItemMeta();
final PotionData data = meta.getBasePotionData();
return data.getType();
}
@Override
public void setBasePotionType(final ItemStack stack, final PotionType type, final boolean extended, final boolean upgraded) {
if (stack == null) {
throw new IllegalArgumentException("ItemStack cannot be null");
}
if (extended && upgraded) {
throw new IllegalArgumentException("Potion cannot be both extended and upgraded");
}
final PotionData data = new PotionData(type, extended, upgraded);
final PotionMeta meta = (PotionMeta) stack.getItemMeta();
meta.setBasePotionData(data);
stack.setItemMeta(meta);
}
@Override
public String getDescription() {
return "1.9-1.20.4 Potion Meta Provider";
}
}

View File

@ -0,0 +1,85 @@
package net.ess3.provider.providers;
import net.ess3.provider.PotionMetaProvider;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.Potion;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionType;
import java.util.Collection;
public class PrehistoricPotionMetaProvider implements PotionMetaProvider {
@Override
public ItemStack createPotionItem(final Material initial, final int effectId) {
final ItemStack potion = new ItemStack(initial, 1);
potion.setDurability((short) effectId);
return potion;
}
@Override
public void setSplashPotion(final ItemStack stack, final boolean isSplash) {
if (stack == null) {
throw new IllegalArgumentException("ItemStack cannot be null");
}
final Potion potion = Potion.fromItemStack(stack);
potion.setSplash(isSplash);
potion.apply(stack);
}
@Override
public boolean isSplashPotion(ItemStack stack) {
return Potion.fromItemStack(stack).isSplash();
}
@Override
public Collection<PotionEffect> getCustomEffects(ItemStack stack) {
return Potion.fromItemStack(stack).getEffects();
}
@Override
public boolean isExtended(final ItemStack stack) {
throw new UnsupportedOperationException();
}
@Override
public boolean isUpgraded(final ItemStack stack) {
throw new UnsupportedOperationException();
}
@Override
public PotionType getBasePotionType(final ItemStack stack) {
throw new UnsupportedOperationException();
}
@Override
public void setBasePotionType(final ItemStack stack, final PotionType type, final boolean extended, final boolean upgraded) {
if (stack == null) {
throw new IllegalArgumentException("ItemStack cannot be null");
}
if (extended && upgraded) {
throw new IllegalArgumentException("Potion cannot be both extended and upgraded");
}
final Potion potion = Potion.fromItemStack(stack);
if (extended && !potion.getType().isInstant()) {
potion.setHasExtendedDuration(true);
potion.setLevel(Math.min(potion.getLevel(), 1));
}
if (upgraded && type.getMaxLevel() == 2) {
potion.setLevel(2);
potion.setHasExtendedDuration(false);
}
potion.apply(stack);
}
@Override
public String getDescription() {
return "Legacy 1.8 Potion Meta Provider";
}
}

View File

@ -0,0 +1,10 @@
package net.ess3.provider;
import org.bukkit.DyeColor;
import org.bukkit.inventory.ItemStack;
public interface BannerDataProvider extends Provider {
DyeColor getBaseColor(ItemStack stack);
void setBaseColor(ItemStack stack, DyeColor color);
}

View File

@ -0,0 +1,19 @@
package net.ess3.provider;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryView;
import org.bukkit.inventory.ItemStack;
/**
* Bukkit changed InventoryView to an interface in 1.21. We need to use providers
* to avoid breaking ABI compatibility with earlier versions of Bukkit.
*/
public interface InventoryViewProvider extends Provider {
Inventory getTopInventory(InventoryView view);
void close(InventoryView view);
Inventory getBottomInventory(InventoryView view);
void setItem(InventoryView view, int slot, ItemStack item);
}

View File

@ -2,7 +2,25 @@ package net.ess3.provider;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionType;
import java.util.Collection;
public interface PotionMetaProvider extends Provider { public interface PotionMetaProvider extends Provider {
ItemStack createPotionItem(Material initial, int effectId); ItemStack createPotionItem(Material initial, int effectId);
void setSplashPotion(ItemStack stack, boolean isSplash);
boolean isSplashPotion(ItemStack stack);
Collection<PotionEffect> getCustomEffects(ItemStack stack);
boolean isExtended(ItemStack stack);
boolean isUpgraded(ItemStack stack);
PotionType getBasePotionType(ItemStack stack);
void setBasePotionType(ItemStack stack, PotionType type, boolean extended, boolean upgraded);
} }

View File

@ -0,0 +1,49 @@
package net.ess3.provider.providers;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import net.ess3.provider.BannerDataProvider;
import org.bukkit.DyeColor;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
public class BaseBannerDataProvider implements BannerDataProvider {
private final BiMap<Material, DyeColor> materialToDyeMap = HashBiMap.create();
public BaseBannerDataProvider() {
materialToDyeMap.put(Material.WHITE_BANNER, DyeColor.WHITE);
materialToDyeMap.put(Material.LIGHT_GRAY_BANNER, DyeColor.LIGHT_GRAY);
materialToDyeMap.put(Material.GRAY_BANNER, DyeColor.GRAY);
materialToDyeMap.put(Material.BLACK_BANNER, DyeColor.BLACK);
materialToDyeMap.put(Material.RED_BANNER, DyeColor.RED);
materialToDyeMap.put(Material.ORANGE_BANNER, DyeColor.ORANGE);
materialToDyeMap.put(Material.YELLOW_BANNER, DyeColor.YELLOW);
materialToDyeMap.put(Material.LIME_BANNER, DyeColor.LIME);
materialToDyeMap.put(Material.GREEN_BANNER, DyeColor.GREEN);
materialToDyeMap.put(Material.CYAN_BANNER, DyeColor.CYAN);
materialToDyeMap.put(Material.LIGHT_BLUE_BANNER, DyeColor.LIGHT_BLUE);
materialToDyeMap.put(Material.BLUE_BANNER, DyeColor.BLUE);
materialToDyeMap.put(Material.PURPLE_BANNER, DyeColor.PURPLE);
materialToDyeMap.put(Material.MAGENTA_BANNER, DyeColor.MAGENTA);
materialToDyeMap.put(Material.PINK_BANNER, DyeColor.PINK);
materialToDyeMap.put(Material.BROWN_BANNER, DyeColor.BROWN);
}
@Override
public DyeColor getBaseColor(ItemStack stack) {
return materialToDyeMap.get(stack.getType());
}
@Override
public void setBaseColor(ItemStack stack, DyeColor color) {
final Material material = materialToDyeMap.inverse().get(color);
if (material != null) {
stack.setType(material);
}
}
@Override
public String getDescription() {
return "1.20.5+ Banner Data Provider.";
}
}

View File

@ -0,0 +1,33 @@
package net.ess3.provider.providers;
import net.ess3.provider.InventoryViewProvider;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryView;
import org.bukkit.inventory.ItemStack;
public class BaseInventoryViewProvider implements InventoryViewProvider {
@Override
public Inventory getTopInventory(InventoryView view) {
return view.getTopInventory();
}
@Override
public Inventory getBottomInventory(InventoryView view) {
return view.getBottomInventory();
}
@Override
public void setItem(InventoryView view, int slot, ItemStack item) {
view.setItem(slot, item);
}
@Override
public void close(InventoryView view) {
view.close();
}
@Override
public String getDescription() {
return "1.21+ InventoryView Interface ABI Provider";
}
}

View File

@ -1,71 +0,0 @@
package net.ess3.provider.providers;
import com.google.common.collect.ImmutableMap;
import net.ess3.provider.PotionMetaProvider;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.PotionMeta;
import org.bukkit.potion.PotionData;
import org.bukkit.potion.PotionType;
import java.util.Map;
public class BasePotionDataProvider implements PotionMetaProvider {
private static final Map<Integer, PotionType> damageValueToType = ImmutableMap.<Integer, PotionType>builder()
.put(1, PotionType.REGEN)
.put(2, PotionType.SPEED)
.put(3, PotionType.FIRE_RESISTANCE)
.put(4, PotionType.POISON)
.put(5, PotionType.INSTANT_HEAL)
.put(6, PotionType.NIGHT_VISION)
// Skip 7
.put(8, PotionType.WEAKNESS)
.put(9, PotionType.STRENGTH)
.put(10, PotionType.SLOWNESS)
.put(11, PotionType.JUMP)
.put(12, PotionType.INSTANT_DAMAGE)
.put(13, PotionType.WATER_BREATHING)
.put(14, PotionType.INVISIBILITY)
.build();
private static int getBit(final int n, final int k) {
return (n >> k) & 1;
}
@Override
public ItemStack createPotionItem(final Material initial, final int effectId) {
ItemStack potion = new ItemStack(initial, 1);
if (effectId == 0) {
return potion;
}
final int damageValue = getBit(effectId, 0) +
2 * getBit(effectId, 1) +
4 * getBit(effectId, 2) +
8 * getBit(effectId, 3);
final PotionType type = damageValueToType.get(damageValue);
if (type == null) {
throw new IllegalArgumentException("Unable to process potion effect ID " + effectId + " with damage value " + damageValue);
}
//getBit is splash here
if (getBit(effectId, 14) == 1 && initial == Material.POTION) {
potion = new ItemStack(Material.SPLASH_POTION, 1);
}
final PotionMeta meta = (PotionMeta) potion.getItemMeta();
//getBit(s) are extended and upgraded respectfully
final PotionData data = new PotionData(type, getBit(effectId, 6) == 1, getBit(effectId, 5) == 1);
meta.setBasePotionData(data); // this method is exclusive to recent 1.9+
potion.setItemMeta(meta);
return potion;
}
@Override
public String getDescription() {
return "1.9+ Potion Meta Provider";
}
}

View File

@ -1,20 +0,0 @@
package net.ess3.provider.providers;
import net.ess3.provider.PotionMetaProvider;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
@SuppressWarnings("deprecation")
public class LegacyPotionMetaProvider implements PotionMetaProvider {
@Override
public ItemStack createPotionItem(final Material initial, final int effectId) {
final ItemStack potion = new ItemStack(initial, 1);
potion.setDurability((short) effectId);
return potion;
}
@Override
public String getDescription() {
return "Legacy 1.8 Potion Meta Provider";
}
}

View File

@ -0,0 +1,107 @@
package net.ess3.provider.providers;
import net.ess3.provider.PotionMetaProvider;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.PotionMeta;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionType;
import java.util.Collection;
public class ModernPotionMetaProvider implements PotionMetaProvider {
@Override
public ItemStack createPotionItem(Material initial, int effectId) {
throw new UnsupportedOperationException("This should never happen, if this happens please submit a bug report!");
}
@Override
public void setBasePotionType(final ItemStack stack, PotionType type, final boolean extended, final boolean upgraded) {
if (stack == null) {
throw new IllegalArgumentException("ItemStack cannot be null");
}
if (extended && upgraded) {
throw new IllegalArgumentException("Potion cannot be both extended and upgraded");
}
final String name = type.name();
if (name.startsWith("LONG_")) {
type = PotionType.valueOf(name.substring(5));
} else if (name.startsWith("STRONG_")) {
type = PotionType.valueOf(name.substring(7));
}
if (extended && type.isExtendable()) {
type = PotionType.valueOf("LONG_" + type.name());
}
if (upgraded && type.isUpgradeable()) {
type = PotionType.valueOf("STRONG_" + type.name());
}
final PotionMeta meta = (PotionMeta) stack.getItemMeta();
//noinspection DataFlowIssue
meta.setBasePotionType(type);
stack.setItemMeta(meta);
}
@Override
public Collection<PotionEffect> getCustomEffects(ItemStack stack) {
final PotionMeta meta = (PotionMeta) stack.getItemMeta();
//noinspection DataFlowIssue
return meta.getCustomEffects();
}
@Override
public boolean isSplashPotion(ItemStack stack) {
return stack != null && stack.getType() == Material.SPLASH_POTION;
}
@Override
public boolean isExtended(ItemStack stack) {
final PotionMeta meta = (PotionMeta) stack.getItemMeta();
//noinspection DataFlowIssue
return meta.getBasePotionType().name().startsWith("LONG_");
}
@Override
public boolean isUpgraded(ItemStack stack) {
final PotionMeta meta = (PotionMeta) stack.getItemMeta();
//noinspection DataFlowIssue
return meta.getBasePotionType().name().startsWith("STRONG_");
}
@Override
public PotionType getBasePotionType(ItemStack stack) {
final PotionMeta meta = (PotionMeta) stack.getItemMeta();
//noinspection DataFlowIssue
PotionType type = meta.getBasePotionType();
//noinspection DataFlowIssue
final String name = type.name();
if (name.startsWith("LONG_")) {
type = PotionType.valueOf(name.substring(5));
} else if (name.startsWith("STRONG_")) {
type = PotionType.valueOf(name.substring(7));
}
return type;
}
@Override
public void setSplashPotion(ItemStack stack, boolean isSplash) {
if (stack == null) {
throw new IllegalArgumentException("ItemStack cannot be null");
}
if (isSplash && stack.getType() == Material.POTION) {
stack.setType(Material.SPLASH_POTION);
} else if (!isSplash && stack.getType() == Material.SPLASH_POTION) {
stack.setType(Material.POTION);
}
}
@Override
public String getDescription() {
return "1.20.5+ Potion Meta Provider";
}
}

View File

@ -22,6 +22,7 @@ public final class ReflUtil {
public static final NMSVersion V1_18_R1 = NMSVersion.fromString("v1_18_R1"); public static final NMSVersion V1_18_R1 = NMSVersion.fromString("v1_18_R1");
public static final NMSVersion V1_19_R1 = NMSVersion.fromString("v1_19_R1"); public static final NMSVersion V1_19_R1 = NMSVersion.fromString("v1_19_R1");
public static final NMSVersion V1_19_R2 = NMSVersion.fromString("v1_19_R2"); public static final NMSVersion V1_19_R2 = NMSVersion.fromString("v1_19_R2");
public static final NMSVersion V1_20_R4 = NMSVersion.fromString("v1_20_R4");
private static final Map<String, Class<?>> classCache = new HashMap<>(); private static final Map<String, Class<?>> classCache = new HashMap<>();
private static final Table<Class<?>, String, Method> methodCache = HashBasedTable.create(); private static final Table<Class<?>, String, Method> methodCache = HashBasedTable.create();
private static final Table<Class<?>, MethodParams, Method> methodParamCache = HashBasedTable.create(); private static final Table<Class<?>, MethodParams, Method> methodParamCache = HashBasedTable.create();

View File

@ -16,7 +16,9 @@ public class ReflServerStateProvider implements ServerStateProvider {
MethodHandle isRunning = null; MethodHandle isRunning = null;
final String MDFIVEMAGICLETTER; final String MDFIVEMAGICLETTER;
if (ReflUtil.getNmsVersionObject().isHigherThanOrEqualTo(ReflUtil.V1_19_R2)) { if (ReflUtil.getNmsVersionObject().isHigherThanOrEqualTo(ReflUtil.V1_20_R4)) {
MDFIVEMAGICLETTER = "x";
} else if (ReflUtil.getNmsVersionObject().isHigherThanOrEqualTo(ReflUtil.V1_19_R2)) {
MDFIVEMAGICLETTER = "v"; MDFIVEMAGICLETTER = "v";
} else if (ReflUtil.getNmsVersionObject().isHigherThanOrEqualTo(ReflUtil.V1_19_R1)) { } else if (ReflUtil.getNmsVersionObject().isHigherThanOrEqualTo(ReflUtil.V1_19_R1)) {
MDFIVEMAGICLETTER = "u"; MDFIVEMAGICLETTER = "u";

View File

@ -1,6 +1,6 @@
plugins { plugins {
id("essentials.base-conventions") id("essentials.base-conventions")
id("com.github.johnrengelman.shadow") id("com.gradleup.shadow")
} }
java { java {