Merge remote-tracking branch 'upstream/2.x' into rework/providers

# Conflicts:
#	Essentials/src/main/java/com/earth2me/essentials/Essentials.java
#	Essentials/src/main/java/com/earth2me/essentials/IEssentials.java
#	Essentials/src/main/java/com/earth2me/essentials/RandomTeleport.java
#	Essentials/src/main/java/com/earth2me/essentials/commands/EssentialsCommand.java
#	Essentials/src/main/java/com/earth2me/essentials/items/FlatItemDb.java
#	providers/BaseProviders/src/main/java/net/ess3/provider/providers/BasePotionDataProvider.java
#	providers/BaseProviders/src/main/java/net/ess3/provider/providers/LegacyPotionMetaProvider.java
This commit is contained in:
JRoy 2024-07-23 17:39:16 -04:00
commit 0dcdb8bebb
No known key found for this signature in database
GPG Key ID: FAD510B503869E7D
88 changed files with 5448 additions and 681 deletions

View File

@ -70,10 +70,13 @@ body:
validations:
required: true
- type: markdown
- type: textarea
attributes:
value: |
In the text box below, you can attach any relevant screenshots, files and links to Timings/spark profiler reports.
label: Additional Information
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.
If you suspect this issue is related to a prior issue/PR/commit, please mention it here.
validations:
required: false

View File

@ -16,26 +16,32 @@ jobs:
steps:
- name: Checkout Git repo
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up JDK 17
uses: actions/setup-java@v3
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: 17
- name: Setup Gradle
uses: gradle/gradle-build-action@v2
uses: gradle/gradle-build-action@v3
- name: Build with Gradle
run: |
chmod +x gradlew
./gradlew build --stacktrace
- name: Publish JUnit report
uses: mikepenz/action-junit-report@v4
if: success() || failure() # Run even if the previous step fails
with:
report_paths: '**/build/test-results/test*/TEST-*.xml'
- name: Archive plugin jars on GitHub
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: EssentialsX plugin jars
path: jars/
@ -61,7 +67,7 @@ jobs:
cp -r EssentialsXMPP/build/docs/javadoc/ javadocs/EssentialsXMPP/
- name: Archive Javadocs
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: javadocs
path: javadocs/
@ -74,12 +80,12 @@ jobs:
steps:
- name: Setup Node
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: 16
- name: Download Javadocs
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: javadocs
path: javadocs/

View File

@ -18,26 +18,32 @@ jobs:
steps:
- name: Checkout Git repo
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up JDK 17
uses: actions/setup-java@v3
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: 17
- name: Setup Gradle
uses: gradle/gradle-build-action@v2
uses: gradle/gradle-build-action@v3
- name: Build with Gradle
run: |
chmod +x gradlew
./gradlew build --stacktrace
- name: Publish JUnit report
uses: mikepenz/action-junit-report@v4
if: success() || failure() # Run even if the previous step fails
with:
report_paths: '**/build/test-results/test*/TEST-*.xml'
- name: Archive plugin jars on GitHub
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: EssentialsX plugin jars
path: jars/

View File

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

View File

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

View File

@ -36,7 +36,9 @@ public class CommandSource {
}
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) {

View File

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

View File

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

View File

@ -110,6 +110,7 @@ import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.world.WorldLoadEvent;
import org.bukkit.inventory.InventoryView;
import org.bukkit.plugin.InvalidDescriptionException;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginDescriptionFile;
@ -142,6 +143,7 @@ import static com.earth2me.essentials.I18n.tlLocale;
public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
private static final Logger BUKKIT_LOGGER = Logger.getLogger("Essentials");
private static Logger LOGGER = null;
public static boolean TESTING = false;
private final transient TNTExplodeListener tntListener = new TNTExplodeListener();
private final transient Set<String> vanishedPlayers = new LinkedHashSet<>();
private final transient Map<String, IEssentialsCommand> commandMap = new HashMap<>();
@ -192,6 +194,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
}
public void setupForTesting(final Server server) throws IOException, InvalidDescriptionException {
TESTING = true;
LOGGER = new BaseLoggerProvider(this, BUKKIT_LOGGER);
final File dataFolder = File.createTempFile("essentialstest", "");
if (!dataFolder.delete()) {
@ -359,8 +362,21 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
// Spawn Egg Providers
providerFactory.registerProvider(LegacySpawnEggProvider.class, ReflSpawnEggProvider.class, FlatSpawnEggProvider.class);
// Potion Meta Provider
providerFactory.registerProvider(LegacyPotionMetaProvider.class, BasePotionDataProvider.class);
//Potion Meta Provider
if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_20_6_R01)) {
potionMetaProvider = new ModernPotionMetaProvider();
} else if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_9_R01)) {
potionMetaProvider = new PrehistoricPotionMetaProvider();
} else {
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
providerFactory.registerProvider(ReflServerStateProvider.class, PaperServerStateProvider.class);
@ -419,6 +435,72 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
}
}
//Known Commands Provider
if (PaperLib.isPaper() && VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_11_2_R01)) {
knownCommandsProvider = new PaperKnownCommandsProvider();
} else {
knownCommandsProvider = new ReflKnownCommandsProvider();
}
// Command aliases provider
formattedCommandAliasProvider = new ReflFormattedCommandAliasProvider(PaperLib.isPaper());
// Material Tag Providers
if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_13_0_R01)) {
materialTagProvider = PaperLib.isPaper() ? new PaperMaterialTagProvider() : new BukkitMaterialTagProvider();
}
// Sync Commands Provider
syncCommandsProvider = new ReflSyncCommandsProvider();
if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_14_4_R01)) {
persistentDataProvider = new ModernPersistentDataProvider(this);
} else {
persistentDataProvider = new ReflPersistentDataProvider(this);
}
onlineModeProvider = new ReflOnlineModeProvider();
if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_11_2_R01)) {
unbreakableProvider = new ModernItemUnbreakableProvider();
} else {
unbreakableProvider = new LegacyItemUnbreakableProvider();
}
if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_17_1_R01)) {
worldInfoProvider = new ModernDataWorldInfoProvider();
} else if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_16_5_R01)) {
worldInfoProvider = new ReflDataWorldInfoProvider();
} else {
worldInfoProvider = new FixedHeightWorldInfoProvider();
}
if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_14_4_R01)) {
signDataProvider = new ModernSignDataProvider(this);
}
if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_12_2_R01)) {
playerLocaleProvider = new ModernPlayerLocaleProvider();
} else {
playerLocaleProvider = new LegacyPlayerLocaleProvider();
}
if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_20_4_R01)) {
damageEventProvider = new ModernDamageEventProvider();
} else {
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)) {
biomeKeyProvider = new PaperBiomeKeyProvider();
}
execTimer.mark("Init(Providers)");
reload();
@ -574,6 +656,11 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
public void reload() {
Trade.closeLog();
if (bukkitAudience != null) {
bukkitAudience.close();
bukkitAudience = null;
}
for (final IConf iConf : confList) {
iConf.reloadConfig();
execTimer.mark("Reload(" + iConf.getClass().getSimpleName() + ")");
@ -591,6 +678,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
final PluginManager pm = getServer().getPluginManager();
registerListeners(pm);
AdventureUtil.setEss(this);
bukkitAudience = BukkitAudiences.create(this);
}
@ -813,7 +901,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
sender.sendMessage(command.getUsage().replace("<command>", commandLabel));
}
if (!ex.getMessage().isEmpty()) {
sender.sendMessage(ex.getMessage());
sender.sendComponent(AdventureUtil.miniMessage().deserialize(ex.getMessage()));
}
if (ex.getCause() != null && settings.isDebug()) {
ex.getCause().printStackTrace();
@ -839,12 +927,14 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
public void cleanupOpenInventories() {
for (final User user : getOnlineUsers()) {
if (user.isRecipeSee()) {
user.getBase().getOpenInventory().getTopInventory().clear();
user.getBase().getOpenInventory().close();
final InventoryView view = user.getBase().getOpenInventory();
inventoryViewProvider.getTopInventory(view).clear();
inventoryViewProvider.close(view);
user.setRecipeSee(false);
}
if (user.isInvSee() || user.isEnderSee()) {
user.getBase().getOpenInventory().close();
inventoryViewProvider.close(user.getBase().getOpenInventory());
user.setInvSee(false);
user.setEnderSee(false);
}
@ -1127,7 +1217,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
@Override
public void broadcastTl(final String tlKey, final Object... args) {
broadcastTl(null, null, true, tlKey, args);
broadcastTl(null, null, false, tlKey, args);
}
@Override

View File

@ -301,7 +301,7 @@ public class EssentialsPlayerListener implements Listener, FakeAccessor {
}
user.setLogoutLocation();
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());
@ -547,14 +547,14 @@ public class EssentialsPlayerListener implements Listener, FakeAccessor {
final Date banExpiry = banEntry.getExpiration();
if (banExpiry != null) {
final String expiry = DateUtil.formatDateDiff(banExpiry.getTime());
event.setKickMessage(tlLiteral("tempbanJoin", expiry, banEntry.getReason()));
event.setKickMessage(AdventureUtil.miniToLegacy(tlLiteral("tempbanJoin", expiry, banEntry.getReason())));
} else {
event.setKickMessage(tlLiteral("banJoin", banEntry.getReason()));
event.setKickMessage(AdventureUtil.miniToLegacy(tlLiteral("banJoin", banEntry.getReason())));
}
} else {
banEntry = ess.getServer().getBanList(BanList.Type.IP).getBanEntry(event.getAddress().getHostAddress());
if (banEntry != null) {
event.setKickMessage(tlLiteral("banIpJoin", banEntry.getReason()));
event.setKickMessage(AdventureUtil.miniToLegacy(tlLiteral("banIpJoin", banEntry.getReason())));
}
}
}
@ -642,12 +642,13 @@ public class EssentialsPlayerListener implements Listener, FakeAccessor {
|| (!pluginCommand.getName().equals("msg") && !pluginCommand.getName().equals("r"))) { // /msg and /r are handled in SimpleMessageRecipient
final User user = ess.getUser(player);
if (!user.isAuthorized("essentials.chat.spy.exempt")) {
final String playerName = ess.getSettings().isSocialSpyDisplayNames() ? player.getDisplayName() : player.getName();
for (final User spyer : ess.getOnlineUsers()) {
if (spyer.isSocialSpyEnabled() && !player.equals(spyer.getBase())) {
final Component base = (user.isMuted() && ess.getSettings().getSocialSpyListenMutedPlayers())
? spyer.tlComponent("socialSpyMutedPrefix")
: 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())));
}
}
}
@ -898,14 +899,14 @@ public class EssentialsPlayerListener implements Listener, FakeAccessor {
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onInventoryClickEvent(final InventoryClickEvent event) {
Player refreshPlayer = null;
final Inventory top = event.getView().getTopInventory();
final Inventory top = ess.getInventoryViewProvider().getTopInventory(event.getView());
final InventoryType type = top.getType();
final Inventory clickedInventory;
if (event.getRawSlot() < 0) {
clickedInventory = null;
} 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());
@ -964,7 +965,7 @@ public class EssentialsPlayerListener implements Listener, FakeAccessor {
@EventHandler(priority = EventPriority.MONITOR)
public void onInventoryCloseEvent(final InventoryCloseEvent event) {
Player refreshPlayer = null;
final Inventory top = event.getView().getTopInventory();
final Inventory top = ess.getInventoryViewProvider().getTopInventory(event.getView());
final InventoryType type = top.getType();
if (type == InventoryType.PLAYER) {
final User user = ess.getUser((Player) event.getPlayer());
@ -978,7 +979,7 @@ public class EssentialsPlayerListener implements Listener, FakeAccessor {
final User user = ess.getUser((Player) event.getPlayer());
if (user.isRecipeSee()) {
user.setRecipeSee(false);
event.getView().getTopInventory().clear();
ess.getInventoryViewProvider().getTopInventory(event.getView()).clear();
refreshPlayer = user.getBase();
}
} else if (type == InventoryType.CHEST && top.getSize() == 9) {

View File

@ -182,8 +182,10 @@ public class I18n implements net.ess3.api.II18n {
}
final Object[] processedArgs = mutateArgs(objects, arg -> {
final String str = arg instanceof AdventureUtil.ParsedPlaceholder ? arg.toString() : AdventureUtil.miniMessage().escapeTags(arg.toString());
return AdventureUtil.legacyToMini(str);
if (arg instanceof AdventureUtil.ParsedPlaceholder) {
return arg.toString();
}
return AdventureUtil.legacyToMini(AdventureUtil.miniMessage().escapeTags(arg.toString()));
});
return messageFormat.format(processedArgs).replace(' ', ' '); // replace nbsp with a space

View File

@ -73,6 +73,8 @@ public interface ISettings extends IConf {
boolean isSocialSpyMessages();
boolean isSocialSpyDisplayNames();
Set<String> getMuteCommands();
@Deprecated

View File

@ -31,7 +31,6 @@ import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.LeatherArmorMeta;
import org.bukkit.inventory.meta.PotionMeta;
import org.bukkit.inventory.meta.SkullMeta;
import org.bukkit.potion.Potion;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
@ -131,21 +130,30 @@ public class MetaItemStack {
}
public boolean canSpawn(final IEssentials ess) {
try {
ess.getServer().getUnsafe().modifyItemStack(stack.clone(), "{}");
return true;
} catch (final NoSuchMethodError nsme) {
return true;
} catch (final Throwable npe) {
if (ess.getSettings().isDebug()) {
ess.getLogger().log(Level.INFO, "Itemstack is invalid", npe);
if (VersionUtil.PRE_FLATTENING) {
try {
ess.getServer().getUnsafe().modifyItemStack(stack.clone(), "{}");
return true;
} catch (final NoSuchMethodError nsme) {
return true;
} catch (final Throwable 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 {
final boolean nbtIsKill = VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_20_6_R01);
if (string[fromArg].startsWith("{") && hasMetaPermission(sender, "vanilla", false, true, ess)) {
if (nbtIsKill) {
throw new TranslatableException("noMetaNbtKill");
}
try {
stack = ess.getServer().getUnsafe().modifyItemStack(stack, Joiner.on(' ').join(Arrays.asList(string).subList(fromArg, string.length)));
} catch (final NullPointerException npe) {
@ -157,6 +165,22 @@ public class MetaItemStack {
} catch (final Throwable 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 {
for (int i = fromArg; i < string.length; i++) {
addStringMeta(sender, allowUnsafe, string[i], ess);
@ -542,17 +566,7 @@ public class MetaItemStack {
}
pmeta.addCustomEffect(pEffect, true);
stack.setItemMeta(pmeta);
if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_9_R01)) {
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);
}
ess.getPotionMetaProvider().setSplashPotion(stack, isSplashPotion);
resetPotionMeta();
}
}
@ -563,7 +577,7 @@ public class MetaItemStack {
if (enchantment == null) {
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;
if (split.length > 1) {
try {
@ -606,7 +620,7 @@ public class MetaItemStack {
}
}
} catch (final Exception ex) {
throw new Exception("Enchantment " + enchantment.getName() + ": " + ex.getMessage(), ex);
throw new Exception("Enchantment " + Enchantments.getRealName(enchantment) + ": " + ex.getMessage(), ex);
}
}
@ -616,7 +630,7 @@ public class MetaItemStack {
return null;
}
final String enchantmentName = enchantment.getName().toLowerCase(Locale.ENGLISH);
final String enchantmentName = Enchantments.getRealName(enchantment);
if (!hasMetaPermission(user, "enchantments." + enchantmentName, true, false)) {
throw new TranslatableException("enchantmentPerm", enchantmentName);
@ -634,16 +648,18 @@ public class MetaItemStack {
PatternType patternType = null;
try {
patternType = PatternType.valueOf(split[0]);
//noinspection removal
patternType = PatternType.getByIdentifier(split[0]);
} catch (final Exception ignored) {
}
final BannerMeta meta = (BannerMeta) stack.getItemMeta();
if (split[0].equalsIgnoreCase("basecolor")) {
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) {
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 org.bukkit.block.banner.Pattern pattern = new org.bukkit.block.banner.Pattern(color, type);
meta.addPattern(pattern);
@ -659,7 +675,8 @@ public class MetaItemStack {
PatternType patternType = null;
try {
patternType = PatternType.valueOf(split[0]);
//noinspection removal
patternType = PatternType.getByIdentifier(split[0]);
} catch (final Exception ignored) {
}
@ -670,7 +687,8 @@ public class MetaItemStack {
final Color color = Color.fromRGB(Integer.parseInt(split[1]));
banner.setBaseColor(DyeColor.getByColor(color));
} 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 org.bukkit.block.banner.Pattern pattern = new org.bukkit.block.banner.Pattern(color, type);
banner.addPattern(pattern);

View File

@ -42,9 +42,9 @@ public enum Mob {
ENDERDRAGON("EnderDragon", Enemies.ENEMY, EntityType.ENDER_DRAGON),
VILLAGER("Villager", Enemies.FRIENDLY, EntityType.VILLAGER),
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),
SNOWMAN("Snowman", Enemies.FRIENDLY, "", EntityType.SNOWMAN),
SNOWMAN("Snowman", Enemies.FRIENDLY, "", MobCompat.SNOW_GOLEM),
OCELOT("Ocelot", Enemies.NEUTRAL, EntityType.OCELOT),
IRONGOLEM("IronGolem", Enemies.NEUTRAL, EntityType.IRON_GOLEM),
WITHER("Wither", Enemies.ENEMY, EntityType.WITHER),
@ -52,12 +52,12 @@ public enum Mob {
WITCH("Witch", Enemies.ENEMY, EntityType.WITCH),
BOAT("Boat", Enemies.NEUTRAL, EntityType.BOAT),
MINECART("Minecart", Enemies.NEUTRAL, EntityType.MINECART),
MINECART_CHEST("ChestMinecart", Enemies.NEUTRAL, EntityType.MINECART_CHEST),
MINECART_FURNACE("FurnaceMinecart", Enemies.NEUTRAL, EntityType.MINECART_FURNACE),
MINECART_TNT("TNTMinecart", Enemies.NEUTRAL, EntityType.MINECART_TNT),
MINECART_HOPPER("HopperMinecart", Enemies.NEUTRAL, EntityType.MINECART_HOPPER),
MINECART_MOB_SPAWNER("SpawnerMinecart", Enemies.NEUTRAL, EntityType.MINECART_MOB_SPAWNER),
ENDERCRYSTAL("EnderCrystal", Enemies.NEUTRAL, EntityType.ENDER_CRYSTAL),
MINECART_CHEST("ChestMinecart", Enemies.NEUTRAL, MobCompat.CHEST_MINECART),
MINECART_FURNACE("FurnaceMinecart", Enemies.NEUTRAL, MobCompat.FURNACE_MINECART),
MINECART_TNT("TNTMinecart", Enemies.NEUTRAL, MobCompat.TNT_MINECART),
MINECART_HOPPER("HopperMinecart", Enemies.NEUTRAL, MobCompat.HOPPER_MINECART),
MINECART_MOB_SPAWNER("SpawnerMinecart", Enemies.NEUTRAL, MobCompat.SPAWNER_MINECART),
ENDERCRYSTAL("EnderCrystal", Enemies.NEUTRAL, MobCompat.END_CRYSTAL),
EXPERIENCEORB("ExperienceOrb", Enemies.NEUTRAL, "EXPERIENCE_ORB"),
ARMOR_STAND("ArmorStand", Enemies.NEUTRAL, "ARMOR_STAND"),
ENDERMITE("Endermite", Enemies.ENEMY, "ENDERMITE"),
@ -112,6 +112,9 @@ public enum Mob {
CHEST_BOAT("ChestBoat", Enemies.NEUTRAL, "CHEST_BOAT"),
CAMEL("Camel", Enemies.FRIENDLY, "CAMEL"),
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<>();

View File

@ -1,6 +1,7 @@
package com.earth2me.essentials;
import com.earth2me.essentials.utils.EnumUtil;
import com.earth2me.essentials.utils.RegistryUtil;
import com.earth2me.essentials.utils.VersionUtil;
import net.ess3.nms.refl.ReflUtil;
import org.bukkit.Material;
@ -20,6 +21,7 @@ import org.bukkit.entity.Parrot;
import org.bukkit.entity.Player;
import org.bukkit.entity.TropicalFish;
import org.bukkit.entity.Villager;
import org.bukkit.entity.Wolf;
import org.bukkit.inventory.ItemStack;
import java.lang.reflect.Method;
@ -50,6 +52,15 @@ public final class MobCompat {
// Constants for mobs that have changed since earlier versions
public static final EntityType CAT = getEntityType("CAT", "OCELOT");
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");
private MobCompat() {
}
@ -213,6 +224,18 @@ 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 enum CatType {
// These are (loosely) Mojang names for the cats
SIAMESE("SIAMESE", "SIAMESE_CAT"),
@ -273,7 +296,7 @@ public final class MobCompat {
}
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),
BETTY_TROPICAL_FISH("betty", MobCompat.TROPICAL_FISH, "tropicalfish:BETTY", true),
CLAYFISH_TROPICAL_FISH("clayfish", MobCompat.TROPICAL_FISH, "tropicalfish:CLAYFISH", true),
BROWN_MUSHROOM_COW("brown", EntityType.MUSHROOM_COW, "mooshroom:BROWN", true),
RED_MUSHROOM_COW("red", EntityType.MUSHROOM_COW, "mooshroom:RED", true),
BROWN_MUSHROOM_COW("brown", MobCompat.MOOSHROOM, "mooshroom:BROWN", true),
RED_MUSHROOM_COW("red", MobCompat.MOOSHROOM, "mooshroom:RED", true),
AGGRESSIVE_PANDA_MAIN("aggressive", MobCompat.PANDA, "pandamain:AGGRESSIVE", true),
LAZY_PANDA_MAIN("lazy", MobCompat.PANDA, "pandamain:LAZY", true),
WORRIED_PANDA_MAIN("worried", MobCompat.PANDA, "pandamain:WORRIED", true),
@ -209,6 +209,15 @@ public enum MobData {
OAK_BOAT("oak", Boat.class, MobCompat.BoatVariant.OAK, true),
SPRUCE_BOAT("spruce", Boat.class, MobCompat.BoatVariant.SPRUCE, 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),
;
final private String nickname;
@ -424,6 +433,9 @@ public enum MobData {
case "frog":
MobCompat.setFrogVariant(spawned, split[1]);
break;
case "wolf":
MobCompat.setWolfVariant(spawned, split[1]);
break;
}
} else {
Essentials.getWrappedLogger().warning("Unknown mob data type: " + this.toString());

View File

@ -1,6 +1,7 @@
package com.earth2me.essentials;
import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
import org.bukkit.Server;
import org.bukkit.World;
import org.bukkit.entity.Player;
@ -31,4 +32,11 @@ public class PlayerExtension {
public Location getLocation() {
return base.getLocation();
}
public OfflinePlayer getOffline() {
if (base instanceof OfflinePlayerStub) {
return ((OfflinePlayerStub) base).base;
}
return base;
}
}

View File

@ -1,6 +1,7 @@
package com.earth2me.essentials;
import com.earth2me.essentials.utils.NumberUtil;
import com.earth2me.essentials.utils.RegistryUtil;
import org.bukkit.potion.PotionEffectType;
import java.util.HashMap;
@ -21,50 +22,68 @@ public final class Potions {
ALIASPOTIONS.put("sprint", PotionEffectType.SPEED);
ALIASPOTIONS.put("swift", PotionEffectType.SPEED);
POTIONS.put("slowness", PotionEffectType.SLOW);
ALIASPOTIONS.put("slow", PotionEffectType.SLOW);
ALIASPOTIONS.put("sluggish", PotionEffectType.SLOW);
final PotionEffectType SLOWNESS = RegistryUtil.valueOf(PotionEffectType.class, "SLOW", "SLOWNESS");
POTIONS.put("haste", PotionEffectType.FAST_DIGGING);
ALIASPOTIONS.put("superpick", PotionEffectType.FAST_DIGGING);
ALIASPOTIONS.put("quickmine", PotionEffectType.FAST_DIGGING);
ALIASPOTIONS.put("digspeed", PotionEffectType.FAST_DIGGING);
ALIASPOTIONS.put("digfast", PotionEffectType.FAST_DIGGING);
ALIASPOTIONS.put("sharp", PotionEffectType.FAST_DIGGING);
POTIONS.put("slowness", SLOWNESS);
ALIASPOTIONS.put("slow", SLOWNESS);
ALIASPOTIONS.put("sluggish", SLOWNESS);
POTIONS.put("fatigue", PotionEffectType.SLOW_DIGGING);
ALIASPOTIONS.put("slow", PotionEffectType.SLOW_DIGGING);
ALIASPOTIONS.put("dull", PotionEffectType.SLOW_DIGGING);
final PotionEffectType HASTE = RegistryUtil.valueOf(PotionEffectType.class, "FAST_DIGGING", "HASTE");
POTIONS.put("strength", PotionEffectType.INCREASE_DAMAGE);
ALIASPOTIONS.put("strong", PotionEffectType.INCREASE_DAMAGE);
ALIASPOTIONS.put("bull", PotionEffectType.INCREASE_DAMAGE);
ALIASPOTIONS.put("attack", PotionEffectType.INCREASE_DAMAGE);
POTIONS.put("haste", HASTE);
ALIASPOTIONS.put("superpick", HASTE);
ALIASPOTIONS.put("quickmine", HASTE);
ALIASPOTIONS.put("digspeed", HASTE);
ALIASPOTIONS.put("digfast", HASTE);
ALIASPOTIONS.put("sharp", HASTE);
POTIONS.put("heal", PotionEffectType.HEAL);
ALIASPOTIONS.put("healthy", PotionEffectType.HEAL);
ALIASPOTIONS.put("instaheal", PotionEffectType.HEAL);
final PotionEffectType MINING_FATIGUE = RegistryUtil.valueOf(PotionEffectType.class, "SLOW_DIGGING", "MINING_FATIGUE");
POTIONS.put("harm", PotionEffectType.HARM);
ALIASPOTIONS.put("harming", PotionEffectType.HARM);
ALIASPOTIONS.put("injure", PotionEffectType.HARM);
ALIASPOTIONS.put("damage", PotionEffectType.HARM);
ALIASPOTIONS.put("inflict", PotionEffectType.HARM);
POTIONS.put("fatigue", MINING_FATIGUE);
ALIASPOTIONS.put("slow", MINING_FATIGUE);
ALIASPOTIONS.put("dull", MINING_FATIGUE);
POTIONS.put("jump", PotionEffectType.JUMP);
ALIASPOTIONS.put("leap", PotionEffectType.JUMP);
final PotionEffectType STRENGTH = RegistryUtil.valueOf(PotionEffectType.class, "INCREASE_DAMAGE", "STRENGTH");
POTIONS.put("nausea", PotionEffectType.CONFUSION);
ALIASPOTIONS.put("sick", PotionEffectType.CONFUSION);
ALIASPOTIONS.put("sickness", PotionEffectType.CONFUSION);
ALIASPOTIONS.put("confusion", PotionEffectType.CONFUSION);
POTIONS.put("strength", STRENGTH);
ALIASPOTIONS.put("strong", STRENGTH);
ALIASPOTIONS.put("bull", STRENGTH);
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);
ALIASPOTIONS.put("regen", PotionEffectType.REGENERATION);
POTIONS.put("resistance", PotionEffectType.DAMAGE_RESISTANCE);
ALIASPOTIONS.put("dmgresist", PotionEffectType.DAMAGE_RESISTANCE);
ALIASPOTIONS.put("armor", PotionEffectType.DAMAGE_RESISTANCE);
final PotionEffectType RESISTANCE = RegistryUtil.valueOf(PotionEffectType.class, "DAMAGE_RESISTANCE", "RESISTANCE");
POTIONS.put("resistance", RESISTANCE);
ALIASPOTIONS.put("dmgresist", RESISTANCE);
ALIASPOTIONS.put("armor", RESISTANCE);
POTIONS.put("fireresist", PotionEffectType.FIRE_RESISTANCE);
ALIASPOTIONS.put("fireresistance", PotionEffectType.FIRE_RESISTANCE);
@ -125,6 +144,23 @@ public final class Potions {
POTIONS.put("unluck", PotionEffectType.UNLUCK);
} 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() {

View File

@ -6,14 +6,13 @@ import com.earth2me.essentials.utils.LocationUtil;
import com.earth2me.essentials.utils.VersionUtil;
import io.papermc.lib.PaperLib;
import net.ess3.api.InvalidWorldException;
import net.ess3.provider.BiomeKeyProvider;
import net.ess3.provider.WorldInfoProvider;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.block.Biome;
import java.io.File;
import java.util.HashSet;
import java.util.List;
import java.util.Queue;
import java.util.Random;
import java.util.Set;
@ -78,14 +77,10 @@ public class RandomTeleport implements IConf {
config.save();
}
public Set<Biome> getExcludedBiomes() {
final List<String> biomeNames = config.getList("excluded-biomes", String.class);
final Set<Biome> excludedBiomes = new HashSet<>();
for (final String biomeName : biomeNames) {
try {
excludedBiomes.add(Biome.valueOf(biomeName.toUpperCase()));
} catch (final IllegalArgumentException ignored) {
}
public Set<String> getExcludedBiomes() {
final Set<String> excludedBiomes = new HashSet<>();
for (final String key : config.getList("excluded-biomes", String.class)) {
excludedBiomes.add(key.toLowerCase());
}
return excludedBiomes;
}
@ -206,7 +201,31 @@ public class RandomTeleport implements IConf {
}
private boolean isValidRandomLocation(final Location location) {
return location.getBlockY() > worldInfoProvider.getMinHeight(location.getWorld()) && !this.getExcludedBiomes().contains(location.getBlock().getBiome());
return location.getBlockY() > worldInfoProvider.getMinHeight(location.getWorld()) && !isExcludedBiome(location);
}
// Exclude biome if enum or namespaced key matches
private boolean isExcludedBiome(final Location location) {
final Set<String> excluded = getExcludedBiomes();
final String enumKey = location.getBlock().getBiome().name().toLowerCase();
// Try with good old bukkit enum
if (excluded.contains(enumKey)) {
return true;
}
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_14_4_R01)) {
// No way to get the biome key on versions below this
return false;
}
final String biomeKey;
final BiomeKeyProvider biomeKeyProvider = ess.getBiomeKeyProvider();
if (biomeKeyProvider != null) {
// Works with custom biome keys
biomeKey = biomeKeyProvider.getBiomeKey(location.getBlock()).toString();
} else {
// Custom biome keys resolve as "minecraft:custom" which is unfortunate
biomeKey = location.getBlock().getBiome().getKey().toString();
}
return excluded.contains(biomeKey);
}
public File getFile() {

View File

@ -55,6 +55,8 @@ import static com.earth2me.essentials.I18n.tlLiteral;
public class Settings implements net.ess3.api.ISettings {
private static final BigDecimal DEFAULT_MAX_MONEY = new BigDecimal("10000000000000");
private static final BigDecimal DEFAULT_MIN_MONEY = new BigDecimal("-10000000000000");
private static final Tag DEFAULT_PRIMARY_COLOR = Tag.styling(NamedTextColor.GOLD);
private static final Tag DEFAULT_SECONDARY_COLOR = Tag.styling(NamedTextColor.RED);
private final transient EssentialsConfiguration config;
private final transient IEssentials ess;
private final transient AtomicInteger reloadCount = new AtomicInteger(0);
@ -143,8 +145,8 @@ public class Settings implements net.ess3.api.ISettings {
private double maxProjectileSpeed;
private boolean removeEffectsOnHeal;
private Map<String, String> worldAliases;
private Tag primaryColor = Tag.styling(NamedTextColor.GOLD);
private Tag secondaryColor = Tag.styling(NamedTextColor.RED);
private Tag primaryColor = DEFAULT_PRIMARY_COLOR;
private Tag secondaryColor = DEFAULT_SECONDARY_COLOR;
public Settings(final IEssentials ess) {
this.ess = ess;
@ -458,6 +460,11 @@ public class Settings implements net.ess3.api.ISettings {
return config.getBoolean("socialspy-messages", true);
}
@Override
public boolean isSocialSpyDisplayNames() {
return config.getBoolean("socialspy-uses-displaynames", true);
}
private Set<String> _getMuteCommands() {
final Set<String> muteCommands = new HashSet<>();
if (config.isList("mute-commands")) {
@ -1978,7 +1985,8 @@ public class Settings implements net.ess3.api.ISettings {
private Tag _getPrimaryColor() {
final String color = config.getString("message-colors.primary", "#ffaa00");
return Tag.styling(_getTagColor(color, NamedTextColor.GOLD));
final TextColor textColor = _getTagColor(color);
return textColor != null ? Tag.styling(textColor) : DEFAULT_PRIMARY_COLOR;
}
@Override
@ -1988,24 +1996,23 @@ public class Settings implements net.ess3.api.ISettings {
private Tag _getSecondaryColor() {
final String color = config.getString("message-colors.secondary", "#ff5555");
return Tag.styling(_getTagColor(color, NamedTextColor.RED));
final TextColor textColor = _getTagColor(color);
return textColor != null ? Tag.styling(textColor) : DEFAULT_SECONDARY_COLOR;
}
private TextColor _getTagColor(final String color, final TextColor def) {
private TextColor _getTagColor(final String color) {
try {
if (color.startsWith("#") && color.length() == 7 && NumberUtil.isNumeric(color.substring(1))) {
if (color.startsWith("#") && color.length() == 7 && NumberUtil.isHexadecimal(color.substring(1))) {
return TextColor.color(Color.fromRGB(Integer.decode(color)).asRGB());
}
if (color.length() == 1) {
final NamedTextColor named = AdventureUtil.fromChar(color.charAt(0));
return named != null ? named : def;
return AdventureUtil.fromChar(color.charAt(0));
}
final NamedTextColor named = NamedTextColor.NAMES.value(color.toLowerCase(Locale.ENGLISH));
return named != null ? named : def;
return NamedTextColor.NAMES.value(color.toLowerCase(Locale.ENGLISH));
} catch (IllegalArgumentException ignored) {
}
return def;
return null;
}
}

View File

@ -191,23 +191,23 @@ public class Trade {
}
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;
}
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;
}
final BigDecimal 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;
}
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());
}
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;
}
user.takeMoney(getMoney());
@ -295,7 +295,7 @@ public class Trade {
ess.getLogger().log(Level.INFO, "charging user " + user.getName() + " itemstack " + getItemStack().toString());
}
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;
}
Inventories.removeItemAmount(user.getBase(), getItemStack(), getItemStack().getAmount());
@ -304,7 +304,7 @@ public class Trade {
if (command != null) {
final BigDecimal cost = getCommandCost(user);
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;
}
user.takeMoney(cost);
@ -315,7 +315,7 @@ public class Trade {
}
final int experience = SetExpFix.getTotalExperience(user.getBase());
if (experience < getExperience() && getExperience() > 0) {
future.completeExceptionally(new ChargeException(user.playerTl("notEnoughExperience")));
future.completeExceptionally(new ChargeException("notEnoughExperience"));
return;
}
SetExpFix.setTotalExperience(user.getBase(), experience - getExperience());

View File

@ -16,6 +16,7 @@ import com.earth2me.essentials.utils.VersionUtil;
import com.google.common.collect.Lists;
import net.ess3.api.IEssentials;
import net.ess3.api.MaxMoneyException;
import net.ess3.api.TranslatableException;
import net.ess3.api.events.AfkStatusChangeEvent;
import net.ess3.api.events.JailStatusChangeEvent;
import net.ess3.api.events.MuteStatusChangeEvent;
@ -226,7 +227,7 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
cooldownTime.add(Calendar.SECOND, (int) cooldown);
cooldownTime.add(Calendar.MILLISECOND, (int) ((cooldown * 1000.0) % 1000.0));
if (cooldownTime.after(now) && !isAuthorized("essentials.heal.cooldown.bypass")) {
throw new Exception(playerTl("timeBeforeHeal", DateUtil.formatDateDiff(cooldownTime.getTimeInMillis())));
throw new TranslatableException("timeBeforeHeal", DateUtil.formatDateDiff(cooldownTime.getTimeInMillis()));
}
}
setLastHealTimestamp(now.getTimeInMillis());
@ -271,7 +272,7 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
final TransactionEvent transactionEvent = new TransactionEvent(this.getSource(), reciever, value);
ess.getServer().getPluginManager().callEvent(transactionEvent);
} else {
throw new ChargeException(tlLocale(playerLocale, "notEnoughMoney", NumberUtil.displayCurrency(value, ess)));
throw new ChargeException("notEnoughMoney", NumberUtil.displayCurrency(value, ess));
}
}

View File

@ -19,13 +19,13 @@ public class Commandbroadcastworld extends EssentialsCommand {
@Override
public 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();
}
World world = user.getWorld();
String message = getFinalArg(args, 0);
if (args.length > 1 && ess.getSettings().isAllowWorldInBroadcastworld()) {
if (ess.getSettings().isAllowWorldInBroadcastworld()) {
final World argWorld = ess.getWorld(args[0]);
if (argWorld != null) {
world = argWorld;
@ -39,7 +39,7 @@ public class Commandbroadcastworld extends EssentialsCommand {
@Override
public void run(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
if (args.length < 2) {
throw new NotEnoughArgumentsException("world");
throw new NotEnoughArgumentsException();
}
final World world = ess.getWorld(args[0]);
@ -53,7 +53,7 @@ public class Commandbroadcastworld extends EssentialsCommand {
if (message.isEmpty()) {
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", message, AdventureUtil.parsed(AdventureUtil.legacyToMini(name)));
}
@Override

View File

@ -14,7 +14,6 @@ import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
@ -35,7 +34,7 @@ public class Commandenchant extends EssentialsCommand {
if (args.length == 0) {
final Set<String> usableEnchants = new TreeSet<>();
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))) {
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);
stack.setItemMeta(metaStack.getItemStack().getItemMeta());
user.getBase().updateInventory();
final String enchantName = enchantment.getName().toLowerCase(Locale.ENGLISH).replace('_', ' ');
final String enchantName = Enchantments.getRealName(enchantment).replace('_', ' ');
if (level == 0) {
user.sendTl("enchantmentRemoved", enchantName);
} else {

View File

@ -1,6 +1,7 @@
package com.earth2me.essentials.commands;
import com.earth2me.essentials.MetaItemStack;
import com.earth2me.essentials.MobCompat;
import com.earth2me.essentials.User;
import com.earth2me.essentials.utils.MaterialUtil;
import com.earth2me.essentials.utils.NumberUtil;
@ -9,7 +10,6 @@ import net.ess3.api.TranslatableException;
import org.bukkit.DyeColor;
import org.bukkit.FireworkEffect;
import org.bukkit.Server;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Firework;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.FireworkMeta;
@ -81,7 +81,7 @@ public class Commandfirework extends EssentialsCommand {
}
}
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();
if (direction) {
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)) {
user.sendTl("cantGamemode", gameMode.name());
user.sendTl("cantGamemode", user.playerTl(gameMode.toString().toLowerCase(Locale.ENGLISH)));
return;
}

View File

@ -51,6 +51,11 @@ public class Commandhelpop extends EssentialsCommand {
final HelpopMessageSendEvent sendEvent = new HelpopMessageSendEvent(from, recipients, message);
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()) {
recipient.sendTl("helpOp", from.getDisplayName(), message);
}

View File

@ -17,8 +17,6 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
import static com.earth2me.essentials.I18n.tlLiteral;
public class Commandme extends EssentialsCommand {
public Commandme() {
super("me");
@ -109,7 +107,7 @@ public class Commandme extends EssentialsCommand {
String message = getFinalArg(args, 0);
message = FormatUtil.replaceFormat(message);
ess.getServer().broadcastMessage(tlLiteral("action", "@", message));
ess.broadcastTl("action", "@", message);
}
@Override

View File

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

View File

@ -131,7 +131,7 @@ public class Commandrecipe extends EssentialsCommand {
if (VersionUtil.PRE_FLATTENING && item.getDurability() == Short.MAX_VALUE) {
item.setDurability((short) 0);
}
view.getTopInventory().setItem(j * 3 + k + 1, item);
ess.getInventoryViewProvider().getTopInventory(view).setItem(j * 3 + k + 1, item);
}
}
} else {
@ -174,7 +174,7 @@ public class Commandrecipe extends EssentialsCommand {
if (VersionUtil.PRE_FLATTENING && item.getDurability() == Short.MAX_VALUE) {
item.setDurability((short) 0);
}
view.setItem(i + 1, item);
ess.getInventoryViewProvider().setItem(view, i + 1, item);
}
} else {

View File

@ -6,6 +6,7 @@ import com.earth2me.essentials.IUser;
import com.earth2me.essentials.User;
import com.earth2me.essentials.utils.AdventureUtil;
import com.earth2me.essentials.utils.DateUtil;
import com.earth2me.essentials.utils.FormatUtil;
import org.bukkit.BanList;
import org.bukkit.Server;
@ -36,7 +37,7 @@ public class Commandtempban extends EssentialsCommand {
}
final String time = getFinalArg(args, 1);
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;
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 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;
if (maxBanLength > 0 && ((banTimestamp - GregorianCalendar.getInstance().getTimeInMillis()) > maxBanLength) && sender.isPlayer() && !ess.getUser(sender.getPlayer()).isAuthorized("essentials.tempban.unlimited")) {

View File

@ -83,7 +83,7 @@ public class Commandtogglejail extends EssentialsCommand {
if (args.length > 2) {
player.setJailTimeout(timeDiff);
// 50 MSPT (milliseconds per tick)
player.setOnlineJailedTime(ess.getSettings().isJailOnlineTime() ? ((player.getBase().getStatistic(PLAY_ONE_TICK)) + (timeDiff / 50)) : 0);
player.setOnlineJailedTime(ess.getSettings().isJailOnlineTime() ? ((player.getOffline().getStatistic(PLAY_ONE_TICK)) + (timeDiff / 50)) : 0);
}
final String tlKey;
@ -121,7 +121,7 @@ public class Commandtogglejail extends EssentialsCommand {
final long displayTimeDiff = DateUtil.parseDateDiff(unparsedTime, true);
final long timeDiff = DateUtil.parseDateDiff(unparsedTime, true, ess.getSettings().isJailOnlineTime());
player.setJailTimeout(timeDiff);
player.setOnlineJailedTime(ess.getSettings().isJailOnlineTime() ? ((player.getBase().getStatistic(PLAY_ONE_TICK)) + (timeDiff / 50)) : 0);
player.setOnlineJailedTime(ess.getSettings().isJailOnlineTime() ? ((player.getOffline().getStatistic(PLAY_ONE_TICK)) + (timeDiff / 50)) : 0);
sender.sendTl("jailSentenceExtended", DateUtil.formatDateDiff(displayTimeDiff));
final String tlKey = "jailNotifySentenceExtended";

View File

@ -10,7 +10,7 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import net.ess3.api.IEssentials;
import net.ess3.provider.KnownCommandsProvider;
import net.ess3.api.TranslatableException;
import org.bukkit.Server;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
@ -181,7 +181,7 @@ public abstract class EssentialsCommand implements IEssentialsCommand {
}
protected void run(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
throw new Exception(tlLiteral("onlyPlayers", commandLabel));
throw new TranslatableException("onlyPlayers", commandLabel);
}
@Override

View File

@ -6,6 +6,7 @@ import com.earth2me.essentials.User;
import com.earth2me.essentials.utils.FormatUtil;
import com.earth2me.essentials.utils.StringUtil;
import net.ess3.api.MaxMoneyException;
import net.ess3.api.TranslatableException;
import org.bukkit.Server;
import org.bukkit.entity.Player;
@ -18,11 +19,11 @@ public abstract class EssentialsLoopCommand extends EssentialsCommand {
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));
}
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()) {
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));
}
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()) {
throw new PlayerNotFoundException();
}
@ -143,6 +144,6 @@ public abstract class EssentialsLoopCommand extends EssentialsCommand {
}
public interface UserConsumer {
void accept(User user) throws PlayerNotFoundException, NotEnoughArgumentsException, PlayerExemptException, ChargeException, MaxMoneyException;
void accept(User user) throws NotEnoughArgumentsException, TranslatableException;
}
}

View File

@ -1,5 +1,6 @@
package com.earth2me.essentials.items;
import com.earth2me.essentials.Enchantments;
import com.earth2me.essentials.IConf;
import com.earth2me.essentials.User;
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.ItemMeta;
import org.bukkit.inventory.meta.LeatherArmorMeta;
import org.bukkit.inventory.meta.PotionMeta;
import org.bukkit.inventory.meta.SkullMeta;
import org.bukkit.plugin.Plugin;
import org.bukkit.potion.Potion;
import org.bukkit.potion.PotionEffect;
import java.util.ArrayList;
@ -220,7 +219,7 @@ public abstract class AbstractItemDb implements IConf, net.ess3.api.IItemDb {
if (meta.hasEnchants()) {
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:
final EnchantmentStorageMeta enchantmentStorageMeta = (EnchantmentStorageMeta) is.getItemMeta();
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;
}
@ -285,16 +284,8 @@ public abstract class AbstractItemDb implements IConf, net.ess3.api.IItemDb {
serializeEffectMeta(sb, fireworkEffectMeta.getEffect());
}
} else if (MaterialUtil.isPotion(material)) {
final boolean splash;
final Collection<PotionEffect> effects;
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();
}
final boolean splash = ess.getPotionMetaProvider().isSplashPotion(is);
final Collection<PotionEffect> effects = ess.getPotionMetaProvider().getCustomEffects(is);
for (final PotionEffect e : effects) {
// 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(" ");
}
for (final org.bukkit.block.banner.Pattern p : shieldBannerMeta.getPatterns()) {
//noinspection removal
final String type = p.getPattern().getIdentifier();
final int color = p.getColor().getColor().asRGB();
sb.append(type).append(",").append(color).append(" ");
@ -324,7 +316,7 @@ public abstract class AbstractItemDb implements IConf, net.ess3.api.IItemDb {
} else {
final BannerMeta bannerMeta = (BannerMeta) is.getItemMeta();
if (bannerMeta != null) {
DyeColor baseDyeColor = bannerMeta.getBaseColor();
DyeColor baseDyeColor = ess.getBannerDataProvider().getBaseColor(is);
if (baseDyeColor == null) {
baseDyeColor = MaterialUtil.getColorOf(material);
}
@ -335,6 +327,7 @@ public abstract class AbstractItemDb implements IConf, net.ess3.api.IItemDb {
sb.append("basecolor:").append(basecolor).append(" ");
}
for (final org.bukkit.block.banner.Pattern p : bannerMeta.getPatterns()) {
//noinspection removal
final String type = p.getPattern().getIdentifier();
final int color = p.getColor().getColor().asRGB();
sb.append(type).append(",").append(color).append(" ");

View File

@ -9,15 +9,13 @@ import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import net.ess3.api.IEssentials;
import net.ess3.api.TranslatableException;
import net.ess3.provider.PersistentDataProvider;
import net.ess3.provider.SpawnerItemProvider;
import org.bukkit.Material;
import org.bukkit.entity.EntityType;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.Damageable;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.PotionMeta;
import org.bukkit.potion.PotionData;
import org.bukkit.potion.PotionType;
import java.util.ArrayList;
import java.util.Collection;
@ -25,6 +23,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
@ -129,14 +128,14 @@ public class FlatItemDb extends AbstractItemDb {
final ItemStack stack = new ItemStack(material);
stack.setAmount(material.getMaxStackSize());
final PotionData potionData = data.getPotionData();
final ItemMeta meta = stack.getItemMeta();
final ItemData.EssentialPotionData potionData = data.getPotionData();
if (potionData != null && meta instanceof PotionMeta) {
final PotionMeta potionMeta = (PotionMeta) meta;
potionMeta.setBasePotionData(potionData);
if (potionData != null && stack.getItemMeta() instanceof PotionMeta) {
ess.getPotionMetaProvider().setBasePotionType(stack, potionData.getType(), potionData.isExtended(), potionData.isUpgraded());
}
final ItemMeta meta = stack.getItemMeta();
// 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.
if (split.length > 1 && meta instanceof Damageable) {
@ -202,14 +201,14 @@ public class FlatItemDb extends AbstractItemDb {
throw new UnsupportedOperationException("Legacy IDs aren't supported on this version.");
}
private ItemData lookup(final ItemStack item) {
final Material type = item.getType();
private ItemData lookup(final ItemStack is) {
final Material type = is.getType();
if (MaterialUtil.isPotion(type) && item.getItemMeta() instanceof PotionMeta) {
final PotionData potion = ((PotionMeta) item.getItemMeta()).getBasePotionData();
return new ItemData(type, potion);
if (MaterialUtil.isPotion(type) && is.getItemMeta() instanceof PotionMeta) {
final PotionMetaProvider provider = ess.getPotionMetaProvider();
return new ItemData(type, new ItemData.EssentialPotionData(provider.getBasePotionType(is), provider.isUpgraded(is), provider.isExtended(is)));
} else if (type.toString().contains("SPAWNER")) {
final EntityType entity = ess.provider(SpawnerItemProvider.class).getEntityType(item);
final EntityType entity = ess.provider(SpawnerItemProvider.class).getEntityType(is);
return new ItemData(type, entity);
} else {
return new ItemData(type);
@ -226,14 +225,14 @@ public class FlatItemDb extends AbstractItemDb {
public static class ItemData {
private Material material;
private String[] fallbacks = null;
private PotionData potionData = null;
private EssentialPotionData potionData = null;
private EntityType entity = null;
ItemData(final Material material) {
this.material = material;
}
ItemData(final Material material, final PotionData potionData) {
ItemData(final Material material, final EssentialPotionData potionData) {
this.material = material;
this.potionData = potionData;
}
@ -269,7 +268,7 @@ public class FlatItemDb extends AbstractItemDb {
return material;
}
public PotionData getPotionData() {
public EssentialPotionData getPotionData() {
return this.potionData;
}
@ -296,5 +295,51 @@ public class FlatItemDb extends AbstractItemDb {
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
&& !senderUser.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()) {
if (onlineUser.isSocialSpyEnabled()
// Don't send socialspy messages to message sender/receiver to prevent spam
&& !onlineUser.equals(senderUser)
&& !onlineUser.equals(recipient)) {
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 {
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

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

View File

@ -46,7 +46,7 @@ public class SignBuy extends EssentialsSign {
charge.isAffordableFor(player);
if (!items.pay(player)) {
throw new ChargeException("Inventory full"); //TODO: TL
throw new ChargeException("inventoryFull");
}
charge.charge(player);
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());
}
final String enchantmentName = enchantment.getName().toLowerCase(Locale.ENGLISH);
final String enchantmentName = Enchantments.getRealName(enchantment);
if (level == 0) {
player.sendTl("enchantmentRemoved", enchantmentName.replace('_', ' '));
} else {

View File

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

View File

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

View File

@ -4,40 +4,55 @@ import net.ess3.api.IEssentials;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.flattener.ComponentFlattener;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.TextDecoration;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.tag.Tag;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import net.kyori.adventure.text.serializer.legacy.CharacterAndFormat;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.bukkit.ChatColor;
import net.kyori.adventure.text.serializer.legacy.Reset;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public final class AdventureUtil {
private static final LegacyComponentSerializer LEGACY_SERIALIZER;
private static final MiniMessage MINI_MESSAGE_INSTANCE;
private static IEssentials ess;
private static final Pattern NAMED_PATTERN = Pattern.compile(ChatColor.COLOR_CHAR + "[0-9a-fk-orA-FK-OR]");
private static final Pattern HEX_PATTERN = Pattern.compile(ChatColor.COLOR_CHAR + "x((?:" + ChatColor.COLOR_CHAR + "[0-9a-fA-F]){6})");
private static final MiniMessage MINI_MESSAGE_NO_TAGS;
private static final String LOOKUP = "0123456789abcdefklmnor";
private static final String[] MINI_TAGS = new String[] {"black", "dark_blue", "dark_green", "dark_aqua", "dark_red", "dark_purple", "gold", "gray", "dark_gray", "blue", "green", "aqua", "red", "light_purple", "yellow", "white", "obf", "b", "st", "u", "i", "reset"};
private static final NamedTextColor[] COLORS = new NamedTextColor[] {NamedTextColor.BLACK, NamedTextColor.DARK_BLUE, NamedTextColor.DARK_GREEN, NamedTextColor.DARK_AQUA, NamedTextColor.DARK_RED, NamedTextColor.DARK_PURPLE, NamedTextColor.GOLD, NamedTextColor.GRAY, NamedTextColor.DARK_GRAY, NamedTextColor.BLUE, NamedTextColor.GREEN, NamedTextColor.AQUA, NamedTextColor.RED, NamedTextColor.LIGHT_PURPLE, NamedTextColor.YELLOW, NamedTextColor.WHITE};
private static final NamedTextColor[] COLORS = new NamedTextColor[]{NamedTextColor.BLACK, NamedTextColor.DARK_BLUE, NamedTextColor.DARK_GREEN, NamedTextColor.DARK_AQUA, NamedTextColor.DARK_RED, NamedTextColor.DARK_PURPLE, NamedTextColor.GOLD, NamedTextColor.GRAY, NamedTextColor.DARK_GRAY, NamedTextColor.BLUE, NamedTextColor.GREEN, NamedTextColor.AQUA, NamedTextColor.RED, NamedTextColor.LIGHT_PURPLE, NamedTextColor.YELLOW, NamedTextColor.WHITE};
private static IEssentials ess;
private static MiniMessage miniMessageInstance;
static {
final LegacyComponentSerializer.Builder builder = LegacyComponentSerializer.builder().flattener(ComponentFlattener.basic()).useUnusualXRepeatedCharacterHexFormat();
final List<CharacterAndFormat> formats = new ArrayList<>();
formats.addAll(CharacterAndFormat.defaults());
formats.addAll(Arrays.asList(
CharacterAndFormat.characterAndFormat('A', NamedTextColor.GREEN),
CharacterAndFormat.characterAndFormat('B', NamedTextColor.AQUA),
CharacterAndFormat.characterAndFormat('C', NamedTextColor.RED),
CharacterAndFormat.characterAndFormat('D', NamedTextColor.LIGHT_PURPLE),
CharacterAndFormat.characterAndFormat('E', NamedTextColor.YELLOW),
CharacterAndFormat.characterAndFormat('F', NamedTextColor.WHITE),
CharacterAndFormat.characterAndFormat('K', TextDecoration.OBFUSCATED),
CharacterAndFormat.characterAndFormat('L', TextDecoration.BOLD),
CharacterAndFormat.characterAndFormat('M', TextDecoration.STRIKETHROUGH),
CharacterAndFormat.characterAndFormat('N', TextDecoration.UNDERLINED),
CharacterAndFormat.characterAndFormat('O', TextDecoration.ITALIC),
CharacterAndFormat.characterAndFormat('R', Reset.INSTANCE)
));
final LegacyComponentSerializer.Builder builder = LegacyComponentSerializer.builder()
.flattener(ComponentFlattener.basic())
.formats(formats)
.useUnusualXRepeatedCharacterHexFormat();
if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_16_1_R01)) {
builder.hexColors();
}
LEGACY_SERIALIZER = builder.build();
MINI_MESSAGE_INSTANCE = MiniMessage.builder()
.tags(TagResolver.builder()
.resolvers(TagResolver.standard())
.resolver(TagResolver.resolver("primary", supplyTag(true)))
.resolver(TagResolver.resolver("secondary", supplyTag(false)))
.build())
.build();
MINI_MESSAGE_NO_TAGS = MiniMessage.builder().strict(true).build();
miniMessageInstance = createMiniMessageInstance();
}
private AdventureUtil() {
@ -45,10 +60,21 @@ public final class AdventureUtil {
public static void setEss(final IEssentials ess) {
AdventureUtil.ess = ess;
miniMessageInstance = createMiniMessageInstance();
}
private static MiniMessage createMiniMessageInstance() {
return MiniMessage.builder()
.tags(TagResolver.builder()
.resolvers(TagResolver.standard())
.resolver(TagResolver.resolver("primary", supplyTag(true)))
.resolver(TagResolver.resolver("secondary", supplyTag(false)))
.build())
.build();
}
public static MiniMessage miniMessage() {
return MINI_MESSAGE_INSTANCE;
return miniMessageInstance;
}
/**
@ -81,37 +107,16 @@ public final class AdventureUtil {
/**
* Converts a section sign legacy string to a MiniMessage string.
*
* @param useCustomTags true if gold and red colors should use primary and secondary tags instead.
*/
public static String legacyToMini(String text, boolean useCustomTags) {
StringBuffer buffer = new StringBuffer();
Matcher matcher = HEX_PATTERN.matcher(text);
while (matcher.find()) {
final String code = matcher.group(1).replace(String.valueOf(ChatColor.COLOR_CHAR), "");
matcher.appendReplacement(buffer, "<#" + code + ">");
final Component deserializedText = LEGACY_SERIALIZER.deserialize(text);
if (useCustomTags) {
return miniMessageInstance.serialize(deserializedText);
} else {
return MINI_MESSAGE_NO_TAGS.serialize(deserializedText);
}
matcher.appendTail(buffer);
matcher = NAMED_PATTERN.matcher(buffer.toString());
buffer = new StringBuffer();
while (matcher.find()) {
final int format = LOOKUP.indexOf(Character.toLowerCase(matcher.group().charAt(1)));
if (format != -1) {
String tagName = MINI_TAGS[format];
if (useCustomTags) {
if (tagName.equals("gold")) {
tagName = "primary";
} else if (tagName.equals("red")) {
tagName = "secondary";
}
}
matcher.appendReplacement(buffer, "<" + tagName + ">");
}
}
matcher.appendTail(buffer);
return buffer.toString();
}
/**

View File

@ -40,6 +40,13 @@ public final class FormatUtil {
return ChatColor.stripColor(input);
}
public static String stripMiniFormat(final String input) {
if (input == null) {
return null;
}
return AdventureUtil.miniMessage().stripTags(input);
}
//This method is used to simply strip the & convention colour codes
public static String stripEssentialsFormat(final String input) {
if (input == null) {

View File

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

View File

@ -129,6 +129,15 @@ public final class NumberUtil {
return true;
}
public static boolean isHexadecimal(final String sNum) {
try {
Integer.parseInt(sNum, 16);
return true;
} catch (final NumberFormatException e) {
return false;
}
}
/**
* Backport from Guava.
*/

View File

@ -0,0 +1,32 @@
package com.earth2me.essentials.utils;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Table;
public final class RegistryUtil {
private static final Table<Class<?>, String, Object> registryCache = HashBasedTable.create();
private RegistryUtil() {
}
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,10 @@ 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_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_6_R01 = BukkitVersion.fromString("1.20.6-R0.1-SNAPSHOT");
public static final BukkitVersion v1_21_R01 = BukkitVersion.fromString("1.21-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_R01);
public static final boolean PRE_FLATTENING = VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_13_0_R01);

View File

@ -213,6 +213,10 @@ socialspy-listen-muted-players: true
# If false, social spy will only monitor commands from the list above.
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.
# If you use another plugin to control speed and flight, you should change these to false.

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
#Sat Feb 03 17:34:46 GMT 2024
action=<dark_purple>* {0} <dark_purple>{1}
addedToAccount=<green>{0} has been added to your account.
addedToOthersAccount=<green>{0} added to {1}<green> account. New balance\: {2}
addedToAccount=<yellow>{0}<green> has been added to your account.
addedToOthersAccount=<yellow>{0}<green> added to<yellow> {1}<green> account. New balance\:<yellow> {2}
adventure=adventure
afkCommandDescription=Marks you as away-from-keyboard.
afkCommandUsage=/<command> [player/message...]
@ -561,6 +561,7 @@ inventoryClearingAllArmor=<primary>Cleared all inventory items and armor from<se
inventoryClearingAllItems=<primary>Cleared all inventory items from<secondary> {0}<primary>.
inventoryClearingFromAll=<primary>Clearing the inventory of all users...
inventoryClearingStack=<primary>Removed<secondary> {0} <primary>of<secondary> {1} <primary>from<secondary> {2}<primary>.
inventoryFull=<dark_red>Your inventory is full.
invseeCommandDescription=See the inventory of other players.
invseeCommandUsage=/<command> <player>
invseeCommandUsage1=/<command> <player>
@ -862,8 +863,10 @@ noLocationFound=<dark_red>No valid location found.
noMail=<primary>You do not have any mail.
noMailOther=<secondary>{0} <primary>does not have any mail.
noMatchingPlayers=<primary>No matching players found.
noMetaComponents=Data Components are not supported in this version of Bukkit. Please use JSON NBT metadata.
noMetaFirework=<dark_red>You do not have permission to apply firework meta.
noMetaJson=JSON Metadata is not supported in this version of Bukkit.
noMetaNbtKill=JSON NBT metadata is no longer supported. You must manually convert your defined items to data components. You can convert JSON NBT to data components here: https://docs.papermc.io/misc/tools/item-command-converter
noMetaPerm=<dark_red>You do not have permission to apply <secondary>{0}<dark_red> meta to this item.
none=none
noNewMail=<primary>You have no new mail.

View File

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

View File

@ -10,6 +10,13 @@ public interface InteractionEvent {
*/
void reply(String message);
/**
* Appends the given string to the initial response message and creates one if it doesn't exist.
* @param tlKey The tlKey of the message to append.
* @param args The args for the message to append.
*/
void replyTl(String tlKey, Object... args);
/**
* Gets the member which caused this event.
* @return the member which caused the event.

View File

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

View File

@ -61,7 +61,7 @@ public class InteractionControllerImpl extends ListenerAdapter implements Intera
final InteractionEvent interactionEvent = new InteractionEventImpl(event);
final List<String> commandSnowflakes = jda.getSettings().getCommandSnowflakes(command.getName());
if (commandSnowflakes != null && !DiscordUtil.hasRoles(event.getMember(), commandSnowflakes)) {
interactionEvent.reply(tlLiteral("noAccessCommand"));
interactionEvent.replyTl("noAccessCommand");
return;
}
jda.getPlugin().getEss().scheduleSyncDelayedTask(() -> command.onCommand(interactionEvent));

View File

@ -1,5 +1,6 @@
package net.essentialsx.discord.interactions;
import com.earth2me.essentials.utils.AdventureUtil;
import com.earth2me.essentials.utils.FormatUtil;
import com.google.common.base.Joiner;
import net.dv8tion.jda.api.entities.Message;
@ -18,6 +19,8 @@ import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import static com.earth2me.essentials.I18n.tlLiteral;
/**
* A class which provides information about what triggered an interaction event.
*/
@ -45,6 +48,11 @@ public class InteractionEventImpl implements InteractionEvent {
.queue(null, error -> logger.log(Level.SEVERE, "Error while editing command interaction response", error));
}
@Override
public void replyTl(String tlKey, Object... args) {
reply(AdventureUtil.miniToLegacy(tlLiteral(tlKey, args)));
}
@Override
public InteractionMember getMember() {
return member;

View File

@ -21,7 +21,7 @@ public class ExecuteCommand extends InteractionCommandImpl {
@Override
public void onCommand(final InteractionEvent event) {
final String command = event.getStringArgument("command");
event.reply(tlLiteral("discordCommandExecuteReply", command));
event.replyTl("discordCommandExecuteReply", command);
Bukkit.getScheduler().runTask(jda.getPlugin(), () -> {
try {
Bukkit.dispatchCommand(new DiscordCommandSender(jda, Bukkit.getConsoleSender(), message -> event.reply(MessageUtil.sanitizeDiscordMarkdown(message))).getSender(), command);

View File

@ -3,6 +3,7 @@ package net.essentialsx.discord.interactions.commands;
import com.earth2me.essentials.IEssentials;
import com.earth2me.essentials.PlayerList;
import com.earth2me.essentials.User;
import com.earth2me.essentials.utils.FormatUtil;
import net.essentialsx.api.v2.services.discord.InteractionCommandArgument;
import net.essentialsx.api.v2.services.discord.InteractionCommandArgumentType;
import net.essentialsx.api.v2.services.discord.InteractionEvent;
@ -45,8 +46,8 @@ public class ListCommand extends InteractionCommandImpl {
final StringBuilder stringBuilder = new StringBuilder();
for (final String str : output) {
stringBuilder.append(str).append("\n");
stringBuilder.append(FormatUtil.stripMiniFormat(str)).append("\n");
}
event.reply(MessageUtil.sanitizeDiscordMarkdown(stringBuilder.substring(0, stringBuilder.length() - 2)));
event.reply(MessageUtil.sanitizeDiscordMarkdown(stringBuilder.substring(0, stringBuilder.length() - 1)));
}
}

View File

@ -2,6 +2,7 @@ package net.essentialsx.discord.interactions.commands;
import com.earth2me.essentials.User;
import com.earth2me.essentials.commands.PlayerNotFoundException;
import com.earth2me.essentials.utils.AdventureUtil;
import com.earth2me.essentials.utils.FormatUtil;
import net.essentialsx.api.v2.services.discord.InteractionCommandArgument;
import net.essentialsx.api.v2.services.discord.InteractionCommandArgumentType;
@ -30,28 +31,28 @@ public class MessageCommand extends InteractionCommandImpl {
try {
user = jda.getPlugin().getEss().matchUser(Bukkit.getServer(), null, event.getStringArgument("username"), getHidden, false);
} catch (PlayerNotFoundException e) {
event.reply(tlLiteral("errorWithMessage", e.getMessage()));
event.replyTl("errorWithMessage", e.getMessage());
return;
}
if (!getHidden && user.isIgnoreMsg()) {
event.reply(tlLiteral("msgIgnore", MessageUtil.sanitizeDiscordMarkdown(user.getDisplayName())));
event.replyTl("msgIgnore", MessageUtil.sanitizeDiscordMarkdown(user.getDisplayName()));
return;
}
if (user.isAfk()) {
if (user.getAfkMessage() != null) {
event.reply(tlLiteral("userAFKWithMessage", MessageUtil.sanitizeDiscordMarkdown(user.getDisplayName()), MessageUtil.sanitizeDiscordMarkdown(user.getAfkMessage())));
event.replyTl("userAFKWithMessage", MessageUtil.sanitizeDiscordMarkdown(user.getDisplayName()), MessageUtil.sanitizeDiscordMarkdown(user.getAfkMessage()));
} else {
event.reply(tlLiteral("userAFK", MessageUtil.sanitizeDiscordMarkdown(user.getDisplayName())));
event.replyTl("userAFK", MessageUtil.sanitizeDiscordMarkdown(user.getDisplayName()));
}
}
final String message = event.getMember().hasRoles(jda.getSettings().getPermittedFormattingRoles()) ?
FormatUtil.replaceFormat(event.getStringArgument("message")) : FormatUtil.stripFormat(event.getStringArgument("message"));
event.reply(tlLiteral("msgFormat", tlLiteral("meSender"), MessageUtil.sanitizeDiscordMarkdown(user.getDisplayName()), MessageUtil.sanitizeDiscordMarkdown(message)));
event.replyTl("msgFormat", tlLiteral("meSender"), MessageUtil.sanitizeDiscordMarkdown(user.getDisplayName()), MessageUtil.sanitizeDiscordMarkdown(message));
user.sendMessage(tlLiteral("msgFormat", event.getMember().getTag(), user.playerTl("meRecipient"), message));
user.sendTl("msgFormat", event.getMember().getTag(), AdventureUtil.parsed(user.playerTl("meRecipient")), message);
// We use an atomic reference here so that java will garbage collect the recipient
final AtomicReference<DiscordMessageRecipient> ref = new AtomicReference<>(new DiscordMessageRecipient(event.getMember()));
jda.getPlugin().getEss().runTaskLaterAsynchronously(() -> ref.set(null), 6000); // Expires after 5 minutes

View File

@ -53,14 +53,14 @@ public class AccountInteractionCommand implements InteractionCommand {
final InteractionMember effectiveUser = userArg == null ? event.getMember() : userArg;
final IUser user = accounts.getUser(effectiveUser.getId());
if (user == null) {
event.reply(tlLiteral(event.getMember().getId().equals(effectiveUser.getId()) ? "discordCommandAccountResponseNotLinked" : "discordCommandAccountResponseNotLinkedOther", effectiveUser.getAsMention()));
event.replyTl(event.getMember().getId().equals(effectiveUser.getId()) ? "discordCommandAccountResponseNotLinked" : "discordCommandAccountResponseNotLinkedOther", effectiveUser.getAsMention());
return;
}
if (event.getMember().getId().equals(effectiveUser.getId())) {
event.reply(tlLiteral("discordCommandAccountResponseLinked", user.getName()));
event.replyTl("discordCommandAccountResponseLinked", user.getName());
return;
}
event.reply(tlLiteral("discordCommandAccountResponseLinkedOther", effectiveUser.getAsMention(), user.getName()));
event.replyTl("discordCommandAccountResponseLinkedOther", effectiveUser.getAsMention(), user.getName());
}
}

View File

@ -25,18 +25,18 @@ public class LinkInteractionCommand implements InteractionCommand {
@Override
public void onCommand(InteractionEvent event) {
if (accounts.isLinked(event.getMember().getId())) {
event.reply(tlLiteral("discordCommandLinkHasAccount"));
event.replyTl("discordCommandLinkHasAccount");
return;
}
final UUID uuid = accounts.getPendingUUID(event.getStringArgument("code"));
if (uuid == null) {
event.reply(tlLiteral("discordCommandLinkInvalidCode"));
event.replyTl("discordCommandLinkInvalidCode");
return;
}
accounts.registerAccount(uuid, event.getMember(), DiscordLinkStatusChangeEvent.Cause.SYNC_PLAYER);
event.reply(tlLiteral("discordCommandLinkLinked"));
event.replyTl("discordCommandLinkLinked");
}
@Override

View File

@ -20,10 +20,10 @@ public class UnlinkInteractionCommand implements InteractionCommand {
@Override
public void onCommand(InteractionEvent event) {
if (!accounts.removeAccount(event.getMember(), DiscordLinkStatusChangeEvent.Cause.UNSYNC_PLAYER)) {
event.reply(tlLiteral("discordCommandUnlinkInvalidCode"));
event.replyTl("discordCommandUnlinkInvalidCode");
return;
}
event.reply(tlLiteral("discordCommandUnlinkUnlinked"));
event.replyTl("discordCommandUnlinkUnlinked");
}
@Override

View File

@ -60,7 +60,7 @@ public class LinkBukkitListener implements Listener {
} catch (IllegalArgumentException e) {
code = e.getMessage();
}
event.disallow(AsyncPlayerPreLoginEvent.Result.KICK_OTHER, tlLiteral("discordLinkLoginKick", "/link " + code, ess.getApi().getInviteUrl()));
event.disallow(AsyncPlayerPreLoginEvent.Result.KICK_OTHER, AdventureUtil.miniToLegacy(tlLiteral("discordLinkLoginKick", "/link " + code, ess.getApi().getInviteUrl())));
}
}

View File

@ -1,13 +1,10 @@
package com.earth2me.essentials.xmpp;
import com.earth2me.essentials.ChargeException;
import com.earth2me.essentials.CommandSource;
import com.earth2me.essentials.User;
import com.earth2me.essentials.commands.EssentialsLoopCommand;
import com.earth2me.essentials.commands.NotEnoughArgumentsException;
import com.earth2me.essentials.commands.PlayerExemptException;
import com.earth2me.essentials.commands.PlayerNotFoundException;
import net.ess3.api.MaxMoneyException;
import net.ess3.api.TranslatableException;
import org.bukkit.Server;
public class Commandxmppspy extends EssentialsLoopCommand {
@ -16,7 +13,7 @@ public class Commandxmppspy extends EssentialsLoopCommand {
}
@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) {
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
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,
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.**
* **EssentialsX currently requires Java 8 or higher.** We recommend using the latest Java version supported by your
server software.
* **EssentialsX requires [Vault](http://dev.bukkit.org/bukkit-plugins/vault/) to enable using chat prefix/suffixes and

View File

@ -9,5 +9,5 @@ repositories {
dependencies {
implementation("net.kyori", "indra-common", "3.1.3")
implementation("com.github.johnrengelman", "shadow", "8.1.1")
implementation("xyz.jpenilla", "run-task", "2.2.3")
implementation("xyz.jpenilla", "run-task", "2.3.0")
}

View File

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

View File

@ -10,7 +10,7 @@ plugins {
val baseExtension = extensions.create<EssentialsBaseExtension>("essentials", project)
val checkstyleVersion = "8.36.2"
val spigotVersion = "1.20.4-R0.1-SNAPSHOT"
val spigotVersion = "1.21-R0.1-SNAPSHOT"
val junit5Version = "5.10.2"
val mockitoVersion = "3.12.4"
@ -75,6 +75,9 @@ tasks {
}
withType<Jar> {
archiveVersion.set(rootProject.ext["FULL_VERSION"] as String)
manifest {
attributes("paperweight-mappings-namespace" to "mojang")
}
}
withType<Sign> {
onlyIf { project.hasProperty("forceSign") }
@ -122,7 +125,7 @@ indra {
javaVersions {
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
strictVersions(false)
}

View File

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

View File

@ -64,8 +64,8 @@ import java.util.Set;
import java.util.UUID;
public class OfflinePlayerStub implements Player {
protected final transient org.bukkit.OfflinePlayer base;
private final transient Server server;
private final transient org.bukkit.OfflinePlayer base;
private transient Location location = new Location(null, 0, 0, 0, 0, 0);
private transient World world;
private boolean allowFlight = false;

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,8 @@
package net.ess3.provider;
import org.bukkit.NamespacedKey;
import org.bukkit.block.Block;
public interface BiomeKeyProvider extends Provider {
NamespacedKey getBiomeKey(Block block);
}

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.inventory.ItemStack;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionType;
import java.util.Collection;
public interface PotionMetaProvider extends Provider {
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,79 +0,0 @@
package net.ess3.provider.providers;
import com.google.common.collect.ImmutableMap;
import net.ess3.provider.PotionMetaProvider;
import net.essentialsx.providers.ProviderData;
import net.essentialsx.providers.ProviderTest;
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;
@ProviderData(description = "1.9+ Potion Meta Provider", weight = 1)
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;
}
@ProviderTest
public static boolean test() {
try {
Class.forName("org.bukkit.potion.PotionData");
return true;
} catch (final ClassNotFoundException ignored) {
return false;
}
}
}

View File

@ -1,17 +0,0 @@
package net.ess3.provider.providers;
import net.ess3.provider.PotionMetaProvider;
import net.essentialsx.providers.ProviderData;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
@SuppressWarnings("deprecation")
@ProviderData(description = "1.8 Potion Meta Provider")
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;
}
}

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_19_R1 = NMSVersion.fromString("v1_19_R1");
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 Table<Class<?>, String, Method> methodCache = HashBasedTable.create();
private static final Table<Class<?>, MethodParams, Method> methodParamCache = HashBasedTable.create();

View File

@ -18,7 +18,9 @@ public class ReflServerStateProvider implements ServerStateProvider {
MethodHandle isRunning = null;
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";
} else if (ReflUtil.getNmsVersionObject().isHigherThanOrEqualTo(ReflUtil.V1_19_R1)) {
MDFIVEMAGICLETTER = "u";

View File

@ -11,8 +11,8 @@ dependencies {
implementation(project(':providers:BaseProviders')) {
exclude(module: 'spigot-api')
}
compileOnly 'io.papermc.paper:paper-api:1.18.2-R0.1-SNAPSHOT'
compileOnly 'io.papermc.paper:paper-mojangapi:1.18.2-R0.1-SNAPSHOT'
compileOnly 'io.papermc.paper:paper-api:1.20.4-R0.1-SNAPSHOT'
compileOnly 'io.papermc.paper:paper-mojangapi:1.20.4-R0.1-SNAPSHOT'
}
essentials {

View File

@ -0,0 +1,19 @@
package net.ess3.provider.providers;
import net.ess3.provider.BiomeKeyProvider;
import org.bukkit.Bukkit;
import org.bukkit.NamespacedKey;
import org.bukkit.block.Block;
@SuppressWarnings("deprecation")
public class PaperBiomeKeyProvider implements BiomeKeyProvider {
@Override
public NamespacedKey getBiomeKey(final Block block) {
return Bukkit.getUnsafe().getBiomeKey(block.getWorld(), block.getX(), block.getY(), block.getZ());
}
@Override
public String getDescription() {
return "Paper Biome Key Provider";
}
}