Compare commits

..
Author SHA1 Message Date
MD d8244dbd80 Do not treat Material as an enum 2024-07-19 20:08:38 +01:00
424 changed files with 11296 additions and 23267 deletions

No files matched your search

+2 -3
View File
@@ -1,7 +1,6 @@
name: Report bug
description: Report a bug in EssentialsX.
labels: 'bug: unconfirmed'
type: Bug
body:
- type: markdown
attributes:
@@ -32,8 +31,8 @@ body:
- type: input
attributes:
label: Error log (if applicable)
description: If you are reporting a console error, upload any relevant log excerpts to either https://pastes.dev or https://gist.github.com, save and the paste the link in this box. If you included those files in the same paste as your startup log, paste the same link here.
placeholder: "Example: https://pastes.dev/UYL3ASLsee"
description: If you are reporting a console error, upload any relevant log excerpts to either https://paste.gg or https://gist.github.com, save and the paste the link in this box. If you included those files in the same paste as your startup log, paste the same link here.
placeholder: "Example: https://paste.gg/p/anonymous/109dd6a10a734a3aa430d5a351ea5210"
- type: textarea
attributes:
@@ -1,7 +1,6 @@
name: Request a feature
description: Suggest a feature you want to see in EssentialsX!
labels: 'type: enhancement'
type: Feature
body:
- type: markdown
attributes:
+6 -60
View File
@@ -27,7 +27,7 @@ jobs:
java-version: 17
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
uses: gradle/gradle-build-action@v3
- name: Build with Gradle
run: |
@@ -35,71 +35,17 @@ jobs:
./gradlew build --stacktrace
- name: Publish JUnit report
uses: mikepenz/action-junit-report@v5
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@v7
uses: actions/upload-artifact@v4
with:
name: EssentialsX plugin jars
path: jars/
- name: Upload EssentialsX jar
uses: actions/upload-artifact@v7
with:
path: jars/EssentialsX-*.jar
archive: false
- name: Upload EssentialsXAntiBuild jar
uses: actions/upload-artifact@v7
with:
path: jars/EssentialsXAntiBuild-*.jar
archive: false
- name: Upload EssentialsXChat jar
uses: actions/upload-artifact@v7
with:
path: jars/EssentialsXChat-*.jar
archive: false
- name: Upload EssentialsXDiscord jar
uses: actions/upload-artifact@v7
with:
path: jars/EssentialsXDiscord-*.jar
archive: false
- name: Upload EssentialsXDiscordLink jar
uses: actions/upload-artifact@v7
with:
path: jars/EssentialsXDiscordLink-*.jar
archive: false
- name: Upload EssentialsXGeoIP jar
uses: actions/upload-artifact@v7
with:
path: jars/EssentialsXGeoIP-*.jar
archive: false
- name: Upload EssentialsXProtect jar
uses: actions/upload-artifact@v7
with:
path: jars/EssentialsXProtect-*.jar
archive: false
- name: Upload EssentialsXSpawn jar
uses: actions/upload-artifact@v7
with:
path: jars/EssentialsXSpawn-*.jar
archive: false
- name: Upload EssentialsXXMPP jar
uses: actions/upload-artifact@v7
with:
path: jars/EssentialsXXMPP-*.jar
archive: false
- name: Deploy to Maven repo
if: ${{ success() && github.event_name == 'push' && github.repository == 'EssentialsX/Essentials' && github.ref == 'refs/heads/2.x' }}
env:
@@ -121,7 +67,7 @@ jobs:
cp -r EssentialsXMPP/build/docs/javadoc/ javadocs/EssentialsXMPP/
- name: Archive Javadocs
uses: actions/upload-artifact@v7
uses: actions/upload-artifact@v4
with:
name: javadocs
path: javadocs/
@@ -136,10 +82,10 @@ jobs:
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 22
node-version: 16
- name: Download Javadocs
uses: actions/download-artifact@v8
uses: actions/download-artifact@v4
with:
name: javadocs
path: javadocs/
+2 -61
View File
@@ -10,11 +10,6 @@ on:
- 2.x
- mc/*
- dev/*
merge_group:
types: [checks_requested]
permissions:
checks: write
jobs:
build:
@@ -34,7 +29,7 @@ jobs:
java-version: 17
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
uses: gradle/gradle-build-action@v3
- name: Build with Gradle
run: |
@@ -48,61 +43,7 @@ jobs:
report_paths: '**/build/test-results/test*/TEST-*.xml'
- name: Archive plugin jars on GitHub
uses: actions/upload-artifact@v7
uses: actions/upload-artifact@v4
with:
name: EssentialsX plugin jars
path: jars/
- name: Upload EssentialsX jar
uses: actions/upload-artifact@v7
with:
path: jars/EssentialsX-*.jar
archive: false
- name: Upload EssentialsXAntiBuild jar
uses: actions/upload-artifact@v7
with:
path: jars/EssentialsXAntiBuild-*.jar
archive: false
- name: Upload EssentialsXChat jar
uses: actions/upload-artifact@v7
with:
path: jars/EssentialsXChat-*.jar
archive: false
- name: Upload EssentialsXDiscord jar
uses: actions/upload-artifact@v7
with:
path: jars/EssentialsXDiscord-*.jar
archive: false
- name: Upload EssentialsXDiscordLink jar
uses: actions/upload-artifact@v7
with:
path: jars/EssentialsXDiscordLink-*.jar
archive: false
- name: Upload EssentialsXGeoIP jar
uses: actions/upload-artifact@v7
with:
path: jars/EssentialsXGeoIP-*.jar
archive: false
- name: Upload EssentialsXProtect jar
uses: actions/upload-artifact@v7
with:
path: jars/EssentialsXProtect-*.jar
archive: false
- name: Upload EssentialsXSpawn jar
uses: actions/upload-artifact@v7
with:
path: jars/EssentialsXSpawn-*.jar
archive: false
- name: Upload EssentialsXXMPP jar
uses: actions/upload-artifact@v7
with:
path: jars/EssentialsXXMPP-*.jar
archive: false
-105
View File
@@ -1,105 +0,0 @@
name: Mirror EssentialsX dumps to Gist
on:
issues:
types: [opened, edited, closed]
issue_comment:
types: [created]
permissions:
issues: write
contents: read
env:
DUMP_REGEX: 'https?://essentialsx\.net/dump\?bytebin=([A-Za-z0-9_-]+)'
GIST_LINK_FMT: 'https://essentialsx.net/dump?gist='
jobs:
handle-dump:
if: github.event.action != 'closed'
runs-on: ubuntu-latest
steps:
- name: Mirror dump to a private Gist
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GIST_TOKEN }}
script: |
const issue = context.payload.issue ?? context.payload.comment.issue;
const bodySrc = context.payload.comment ? context.payload.comment.body : issue.body || '';
const regex = new RegExp(process.env.DUMP_REGEX);
const m = bodySrc.match(regex);
if (!m) {
core.info('No EssentialsX dump link found – abort.');
return;
}
const key = m[1];
const dump = await fetch(`https://api.pastes.dev/${key}`);
if (!dump.ok) throw new Error(`pastes.dev fetch failed (${dump.status})`);
const text = await dump.text();
const { data: gist } = await github.rest.gists.create({
files: { [`${key}.txt`]: { content: text } },
description: `EssentialsX dump for issue #${issue.number}`,
public: false
});
const link = `${process.env.GIST_LINK_FMT}${gist.id}`;
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
body: `📋 Essentials Dump Backup → ${link}`
});
cleanup-gist:
if: github.event_name == 'issues' && github.event.action == 'closed'
runs-on: ubuntu-latest
steps:
- name: Delete gist and hide bot comment
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GIST_TOKEN }}
script: |
const issue = context.payload.issue;
const comments = await github.paginate(
github.rest.issues.listComments,
{ owner: context.repo.owner, repo: context.repo.repo, issue_number: issue.number, per_page: 100 }
);
const re = /https?:\/\/essentialsx\.net\/dump\?gist=([A-Za-z0-9]+)/;
const hit = comments.reverse().find(c => re.test(c.body || ''));
if (!hit) {
core.info('No gist link comment found – nothing to clean up.');
return;
}
const gistId = (hit.body.match(re))[1];
const commentNodeId = hit.node_id;
try {
await github.request('DELETE /gists/{gist_id}', { gist_id: gistId });
core.info(`Deleted Gist ${gistId}`);
} catch (err) {
core.warning(`Could not delete Gist ${gistId}: ${err.message}`);
}
try {
await github.graphql(
`mutation($id:ID!){
minimizeComment(input:{subjectId:$id, classifier:OUTDATED}) {
minimizedComment { id }
}
}`,
{ id: commentNodeId }
);
core.info(`Minimised comment ${hit.id} as OUTDATED`);
} catch (err) {
core.warning(`Could not minimise comment: ${err.message}`);
}
-43
View File
@@ -1,43 +0,0 @@
name: Command and Permissions Data
on:
push:
branches:
- 2.x
jobs:
data:
name: Generate and Upload
runs-on: ubuntu-latest
steps:
- name: Checkout Git Repo
uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: 17
- name: Set up Gradle
uses: gradle/actions/setup-gradle@v4
- name: Generate Data
run: |
chmod +x gradlew
./gradlew commandData
./gradlew versionData
- name: Upload Data
uses: ryand56/r2-upload-action@v1
with:
r2-account-id: ${{ secrets.R2_ACCOUNT_ID }}
r2-access-key-id: ${{ secrets.R2_ACCESS_KEY_ID }}
r2-secret-access-key: ${{ secrets.R2_SECRET_ACCESS_KEY }}
r2-bucket: ${{ secrets.R2_BUCKET }}
source-dir: generated
destination-dir: ./
-5
View File
@@ -21,15 +21,10 @@
# Build files
.gradle/
/jars/
generated/
out/
build/
target/
*.class
build-logic/.kotlin/
build-logic/bin/
bin/
test-tmp/
# Run directory
/run/
+12 -31
View File
@@ -3,36 +3,32 @@ plugins {
}
dependencies {
compileOnly('net.essentialsx.deps:VaultAPI:1.7') {
compileOnly('com.github.milkbowl:VaultAPI:1.7') {
exclude group: "org.bukkit", module: "bukkit"
}
compileOnly 'net.luckperms:api:5.3'
api 'io.papermc:paperlib:1.0.6'
implementation 'org.spongepowered:configurate-yaml:4.2.0'
implementation 'org.checkerframework:checker-qual:3.49.0'
implementation 'org.spongepowered:configurate-yaml:4.1.2'
implementation 'org.checkerframework:checker-qual:3.21.0'
implementation 'nu.studer:java-ordered-properties:1.0.4'
implementation 'net.kyori:adventure-api:4.25.0'
implementation 'net.kyori:adventure-text-minimessage:4.25.0'
implementation 'net.kyori:adventure-platform-bukkit:4.4.1'
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')) {
exclude(module: 'spigot-api')
}
api(project(path: ':providers:PaperProvider', configuration: 'shadow')){
exclude(module: 'paper-api')
}
api project(':providers:BaseProviders')
api project(path: ':providers:PaperProvider', configuration: 'shadow')
api(project(':providers:NMSReflectionProvider')) {
exclude(module: 'bukkit')
exclude group: "org.bukkit", module: "bukkit"
}
api(project(':providers:1_8Provider')) {
exclude(module: 'spigot-api')
exclude group: "org.spigotmc", module: "spigot"
}
api(project(':providers:1_12Provider')) {
exclude(module: 'bukkit')
exclude group: "org.bukkit", module: "bukkit"
}
}
@@ -40,10 +36,6 @@ test {
testLogging.showStandardStreams = true
}
tasks.register('versionData', VersionDataTask) {
destination.set(rootProject.layout.projectDirectory.dir("generated").file("version-data.json"))
}
shadowJar {
dependencies {
include (dependency('io.papermc:paperlib'))
@@ -76,17 +68,6 @@ shadowJar {
include (project(':providers:NMSReflectionProvider'))
include (project(':providers:1_8Provider'))
include (project(':providers:1_12Provider'))
// Paper in-dev adventure versions (for snapshot/pre-releases)
include (dependency('io.papermc.adventure:adventure-api'))
include (dependency('io.papermc.adventure:adventure-key'))
include (dependency('io.papermc.adventure:adventure-nbt'))
include (dependency('io.papermc.adventure:adventure-text-serializer-gson'))
include (dependency('io.papermc.adventure:adventure-text-serializer-gson-legacy-impl'))
include (dependency('io.papermc.adventure:adventure-text-serializer-json'))
include (dependency('io.papermc.adventure:adventure-text-serializer-json-legacy-impl'))
include (dependency('io.papermc.adventure:adventure-text-serializer-legacy'))
include (dependency('io.papermc.adventure:adventure-text-minimessage'))
}
relocate 'io.papermc.lib', 'com.earth2me.essentials.paperlib'
relocate 'org.bstats', 'com.earth2me.essentials.libs.bstats'
@@ -95,7 +76,7 @@ shadowJar {
relocate 'io.leangen.geantyref', 'com.earth2me.essentials.libs.geantyref'
relocate 'org.checkerframework', 'com.earth2me.essentials.libs.checkerframework'
relocate 'net.kyori', 'com.earth2me.essentials.libs.kyori'
relocate 'net.essentialsx.temp.adventure', 'net.kyori.adventure' // Undo temporary relocation for Paper Provider
relocate 'net.essentialsx.temp.adventure', 'net.kyori.adventure'
minimize {
include(dependency('org.checkerframework:checker-qual'))
@@ -1,7 +1,5 @@
package com.earth2me.essentials;
import java.util.stream.Collectors;
import net.ess3.provider.KnownCommandsProvider;
import org.bukkit.command.Command;
import org.bukkit.command.PluginIdentifiableCommand;
import org.bukkit.plugin.Plugin;
@@ -33,7 +31,7 @@ public class AlternativeCommandsHandler {
if (plugin.getDescription().getMain().contains("com.earth2me.essentials") || plugin.getDescription().getMain().contains("net.essentialsx")) {
return;
}
for (final Map.Entry<String, Command> entry : getPluginCommands(plugin)) {
for (final Map.Entry<String, Command> entry : getPluginCommands(plugin).entrySet()) {
final String[] commandSplit = entry.getKey().split(":", 2);
final String commandName = commandSplit.length > 1 ? commandSplit[1] : entry.getKey();
final Command command = entry.getValue();
@@ -66,23 +64,14 @@ public class AlternativeCommandsHandler {
}
}
private List<Map.Entry<String, Command>> getPluginCommands(Plugin plugin) {
private Map<String, Command> getPluginCommands(Plugin plugin) {
final Map<String, Command> commands = new HashMap<>();
for (final Map.Entry<String, Command> entry : ess.provider(KnownCommandsProvider.class).getKnownCommands().entrySet()) {
for (final Map.Entry<String, Command> entry : ess.getKnownCommandsProvider().getKnownCommands().entrySet()) {
if (entry.getValue() instanceof PluginIdentifiableCommand && ((PluginIdentifiableCommand) entry.getValue()).getPlugin().equals(plugin)) {
commands.put(entry.getKey(), entry.getValue());
}
}
// Try to use non-namespaced commands first if we can, some Commands may not like being registered under a
// different label than their getName() returns, so avoid doing that when we can
return commands.entrySet().stream().sorted((o1, o2) -> {
if (o1.getKey().contains(":") && !o2.getKey().contains(":")) {
return 1;
} else if (!o1.getKey().contains(":") && o2.getKey().contains(":")) {
return -1;
}
return 0;
}).collect(Collectors.toList());
return commands;
}
public void removePlugin(final Plugin plugin) {
@@ -7,6 +7,7 @@ import com.earth2me.essentials.utils.LocationUtil;
import io.papermc.lib.PaperLib;
import net.ess3.api.IEssentials;
import net.ess3.api.IUser;
import net.ess3.api.InvalidWorldException;
import net.ess3.api.TranslatableException;
import net.ess3.api.events.UserWarpEvent;
import net.ess3.api.events.teleport.PreTeleportEvent;
@@ -423,7 +424,7 @@ public class AsyncTeleport implements IAsyncTeleport {
final Location loc;
try {
loc = ess.getWarps().getWarp(warp);
} catch (final WarpNotFoundException e) {
} catch (final WarpNotFoundException | InvalidWorldException e) {
future.completeExceptionally(e);
return;
}
@@ -457,10 +458,6 @@ public class AsyncTeleport implements IAsyncTeleport {
nowAsync(teleportOwner, new LocationTarget(teleportOwner.getLastLocation()), TeleportCause.COMMAND, future);
}
public TeleportType getTpType() {
return this.tpType;
}
public void setTpType(final TeleportType tpType) {
this.tpType = tpType;
}
@@ -1,15 +1,12 @@
package com.earth2me.essentials;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import org.bukkit.Location;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import net.ess3.api.IEssentials;
import net.ess3.api.IUser;
import net.essentialsx.api.v2.events.TeleportWarmupCancelledEvent;
import net.essentialsx.api.v2.events.TeleportWarmupCancelledEvent.CancelReason;
import org.bukkit.Location;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
public class AsyncTimedTeleport implements Runnable {
private static final double MOVE_CONSTANT = 0.3;
@@ -152,14 +149,6 @@ public class AsyncTimedTeleport implements Runnable {
}
try {
ess.getServer().getScheduler().cancelTask(timer_task);
final IUser teleportUser = ess.getUser(this.timer_teleportee);
if (teleportUser != null && teleportUser.getBase() != null) {
final TeleportWarmupCancelledEvent.CancelReason cancelReason = teleportUser.getBase().isOnline() ? CancelReason.MOVE : CancelReason.LEAVE;
final TeleportWarmupCancelledEvent event = new TeleportWarmupCancelledEvent(teleportUser.getBase(), this.teleport.getTpType(), cancelReason, notifyUser);
ess.getServer().getPluginManager().callEvent(event);
}
if (notifyUser) {
teleportOwner.sendTl("pendingTeleportCancelled");
if (timer_teleportee != null && !timer_teleportee.equals(teleportOwner.getBase().getUniqueId())) {
@@ -1,5 +1,6 @@
package com.earth2me.essentials;
import com.earth2me.essentials.utils.AdventureUtil;
import net.ess3.api.IEssentials;
import org.bukkit.Server;
import org.bukkit.command.CommandSender;
@@ -79,7 +80,7 @@ public class Backup implements Runnable {
taskLock.complete(new Object());
return;
}
ess.getLogger().log(Level.INFO, ess.getAdventureFacet().miniToLegacy(tlLiteral("backupStarted")));
ess.getLogger().log(Level.INFO, AdventureUtil.miniToLegacy(tlLiteral("backupStarted")));
final CommandSender cs = server.getConsoleSender();
server.dispatchCommand(cs, "save-all");
server.dispatchCommand(cs, "save-off");
@@ -118,7 +119,7 @@ public class Backup implements Runnable {
}
active = false;
taskLock.complete(new Object());
ess.getLogger().log(Level.INFO, ess.getAdventureFacet().miniToLegacy(tlLiteral("backupFinished")));
ess.getLogger().log(Level.INFO, AdventureUtil.miniToLegacy(tlLiteral("backupFinished")));
}
}
@@ -53,10 +53,7 @@ public class BalanceTopImpl implements BalanceTop {
}
final LinkedHashMap<UUID, Entry> sortedMap = new LinkedHashMap<>();
entries.sort((entry1, entry2) -> entry2.getBalance().compareTo(entry1.getBalance()));
final int entryLimit = ess.getSettings().getBaltopEntryLimit();
final int limit = entryLimit == -1 ? entries.size() : Math.min(entryLimit, entries.size());
for (int i = 0; i < limit; i++) {
final Entry entry = entries.get(i);
for (Entry entry : entries) {
sortedMap.put(entry.getUuid(), entry);
}
topCache = sortedMap;
@@ -1,6 +1,8 @@
package com.earth2me.essentials;
import com.earth2me.essentials.adventure.ComponentHolder;
import com.earth2me.essentials.utils.AdventureUtil;
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import net.kyori.adventure.text.Component;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@@ -35,7 +37,7 @@ public class CommandSource {
final String translation = tlLiteral(tlKey, args);
if (!translation.isEmpty()) {
sendComponent(ess.getAdventureFacet().deserializeMiniMessage(translation));
sendComponent(AdventureUtil.miniMessage().deserialize(translation));
}
}
@@ -47,17 +49,18 @@ public class CommandSource {
return tlLiteral(tlKey, args);
}
public ComponentHolder tlComponent(final String tlKey, final Object... args) {
public Component tlComponent(final String tlKey, final Object... args) {
if (isPlayer()) {
//noinspection ConstantConditions
return getUser().tlComponent(tlKey, args);
}
final String translation = tlLiteral(tlKey, args);
return ess.getAdventureFacet().deserializeMiniMessage(translation);
return AdventureUtil.miniMessage().deserialize(translation);
}
public void sendComponent(final ComponentHolder component) {
ess.getAdventureFacet().send(sender, component);
public void sendComponent(final Component component) {
final BukkitAudiences audiences = ess.getBukkitAudience();
audiences.sender(sender).sendMessage(component);
}
public final net.ess3.api.IUser getUser() {
@@ -1,8 +1,10 @@
package com.earth2me.essentials;
import com.earth2me.essentials.adventure.AdventureFacet;
import com.earth2me.essentials.messaging.IMessageRecipient;
import com.earth2me.essentials.messaging.SimpleMessageRecipient;
import com.earth2me.essentials.utils.AdventureUtil;
import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.text.Component;
import org.bukkit.Server;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@@ -13,11 +15,7 @@ import static com.earth2me.essentials.I18n.tlLiteral;
public final class Console implements IMessageRecipient {
public static final String NAME = "Console";
public static String displayName() {
return tlLiteral("consoleName");
}
public static final String DISPLAY_NAME = tlLiteral("consoleName");
private static Console instance; // Set in essentials
private final IEssentials ess;
@@ -60,7 +58,7 @@ public final class Console implements IMessageRecipient {
@Override
public String getDisplayName() {
return displayName();
return Console.DISPLAY_NAME;
}
@Override
@@ -75,8 +73,10 @@ public final class Console implements IMessageRecipient {
return;
}
final AdventureFacet adventureFacet = ess.getAdventureFacet();
adventureFacet.send(getCommandSender(), adventureFacet.deserializeMiniMessage(translation));
final Audience consoleAudience = ((Essentials) ess).getBukkitAudience().sender(getCommandSender());
final Component component = AdventureUtil.miniMessage()
.deserialize(translation);
consoleAudience.sendMessage(component);
}
@Override
@@ -17,13 +17,13 @@ public final class Enchantments {
static {
final Enchantment SHARPNESS = RegistryUtil.valueOf(Enchantment.class, "DAMAGE_ALL", "SHARPNESS");
ENCHANTMENTS.put("alldamage", SHARPNESS);
ALIASENCHANTMENTS.put("alldmg", SHARPNESS);
ENCHANTMENTS.put("sharpness", SHARPNESS);
ALIASENCHANTMENTS.put("sharp", SHARPNESS);
ALIASENCHANTMENTS.put("dal", SHARPNESS);
final Enchantment BANE_OF_ARTHROPODS = RegistryUtil.valueOf(Enchantment.class, "DAMAGE_ARTHROPODS", "BANE_OF_ARTHROPODS");
ENCHANTMENTS.put("ardmg", BANE_OF_ARTHROPODS);
@@ -31,13 +31,13 @@ public final class Enchantments {
ALIASENCHANTMENTS.put("baneofarthropod", BANE_OF_ARTHROPODS);
ALIASENCHANTMENTS.put("arthropod", BANE_OF_ARTHROPODS);
ALIASENCHANTMENTS.put("dar", BANE_OF_ARTHROPODS);
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);
@@ -46,7 +46,7 @@ public final class Enchantments {
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);
@@ -70,21 +70,21 @@ public final class Enchantments {
ALIASENCHANTMENTS.put("kback", Enchantment.KNOCKBACK);
ALIASENCHANTMENTS.put("kb", Enchantment.KNOCKBACK);
ALIASENCHANTMENTS.put("k", Enchantment.KNOCKBACK);
final Enchantment FORTUNE = RegistryUtil.valueOf(Enchantment.class, "LOOT_BONUS_BLOCKS", "FORTUNE");
ALIASENCHANTMENTS.put("blockslootbonus", FORTUNE);
ENCHANTMENTS.put("fortune", FORTUNE);
ALIASENCHANTMENTS.put("fort", FORTUNE);
ALIASENCHANTMENTS.put("lbb", FORTUNE);
final Enchantment LOOTING = RegistryUtil.valueOf(Enchantment.class, "LOOT_BONUS_MOBS", "LOOTING");
ALIASENCHANTMENTS.put("mobslootbonus", LOOTING);
ENCHANTMENTS.put("mobloot", LOOTING);
ENCHANTMENTS.put("looting", LOOTING);
ALIASENCHANTMENTS.put("lbm", LOOTING);
final Enchantment RESPIRATION = RegistryUtil.valueOf(Enchantment.class, "OXYGEN", "RESPIRATION");
ALIASENCHANTMENTS.put("oxygen", RESPIRATION);
@@ -92,14 +92,14 @@ public final class Enchantments {
ALIASENCHANTMENTS.put("breathing", RESPIRATION);
ENCHANTMENTS.put("breath", RESPIRATION);
ALIASENCHANTMENTS.put("o", RESPIRATION);
final Enchantment PROTECTION = RegistryUtil.valueOf(Enchantment.class, "PROTECTION_ENVIRONMENTAL", "PROTECTION");
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);
@@ -110,7 +110,7 @@ public final class Enchantments {
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);
@@ -118,7 +118,7 @@ public final class Enchantments {
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);
@@ -128,7 +128,7 @@ public final class Enchantments {
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);
@@ -138,28 +138,28 @@ public final class Enchantments {
ENCHANTMENTS.put("silktouch", Enchantment.SILK_TOUCH);
ALIASENCHANTMENTS.put("softtouch", Enchantment.SILK_TOUCH);
ALIASENCHANTMENTS.put("st", Enchantment.SILK_TOUCH);
final Enchantment AQUA_AFFINITY = RegistryUtil.valueOf(Enchantment.class, "WATER_WORKER", "AQUA_AFFINITY");
ENCHANTMENTS.put("waterworker", AQUA_AFFINITY);
ENCHANTMENTS.put("aquaaffinity", AQUA_AFFINITY);
ALIASENCHANTMENTS.put("watermine", AQUA_AFFINITY);
ALIASENCHANTMENTS.put("ww", AQUA_AFFINITY);
final Enchantment FLAME = RegistryUtil.valueOf(Enchantment.class, "ARROW_FIRE", "FLAME");
ALIASENCHANTMENTS.put("firearrow", FLAME);
ENCHANTMENTS.put("flame", FLAME);
ENCHANTMENTS.put("flamearrow", FLAME);
ALIASENCHANTMENTS.put("af", FLAME);
final Enchantment POWER = RegistryUtil.valueOf(Enchantment.class, "ARROW_DAMAGE", "POWER");
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);
@@ -167,7 +167,7 @@ public final class Enchantments {
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);
@@ -177,7 +177,7 @@ public final class Enchantments {
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);
@@ -321,14 +321,6 @@ public final class Enchantments {
} catch (final IllegalArgumentException ignored) {
}
try { // 1.21.11
final Enchantment lunge = Enchantment.getByName("LUNGE");
if (lunge != null) {
ENCHANTMENTS.put("lunge", lunge);
}
} catch (final IllegalArgumentException ignored) {
}
try {
final Class<?> namespacedKeyClass = Class.forName("org.bukkit.NamespacedKey");
final Class<?> enchantmentClass = Class.forName("org.bukkit.enchantments.Enchantment");
@@ -17,11 +17,6 @@
*/
package com.earth2me.essentials;
import com.earth2me.essentials.adventure.AdventureFacet;
import com.earth2me.essentials.adventure.AdventureUtil;
import com.earth2me.essentials.adventure.ComponentHolder;
import com.earth2me.essentials.adventure.PaperAdventureFacet;
import com.earth2me.essentials.adventure.SpigotAdventureFacet;
import com.earth2me.essentials.commands.EssentialsCommand;
import com.earth2me.essentials.commands.IEssentialsCommand;
import com.earth2me.essentials.commands.NoChargeException;
@@ -45,11 +40,11 @@ import com.earth2me.essentials.textreader.KeywordReplacer;
import com.earth2me.essentials.textreader.SimpleTextInput;
import com.earth2me.essentials.updatecheck.UpdateChecker;
import com.earth2me.essentials.userstorage.ModernUserMap;
import com.earth2me.essentials.utils.AdventureUtil;
import com.earth2me.essentials.utils.FormatUtil;
import com.earth2me.essentials.utils.VersionUtil;
import io.papermc.lib.PaperLib;
import net.ess3.api.Economy;
import com.earth2me.essentials.config.EssentialsConfiguration;
import net.ess3.api.IEssentials;
import net.ess3.api.IItemDb;
import net.ess3.api.IJails;
@@ -64,21 +59,36 @@ import net.ess3.nms.refl.providers.ReflServerStateProvider;
import net.ess3.nms.refl.providers.ReflSpawnEggProvider;
import net.ess3.nms.refl.providers.ReflSpawnerBlockProvider;
import net.ess3.nms.refl.providers.ReflSyncCommandsProvider;
import net.ess3.provider.BannerDataProvider;
import net.ess3.provider.BiomeKeyProvider;
import net.ess3.provider.ContainerProvider;
import net.ess3.provider.DamageEventProvider;
import net.ess3.provider.FormattedCommandAliasProvider;
import net.ess3.provider.InventoryViewProvider;
import net.ess3.provider.ItemUnbreakableProvider;
import net.ess3.provider.KnownCommandsProvider;
import net.ess3.provider.MaterialTagProvider;
import net.ess3.provider.PersistentDataProvider;
import net.ess3.provider.PlayerLocaleProvider;
import net.ess3.provider.PotionMetaProvider;
import net.ess3.provider.ProviderListener;
import net.ess3.provider.SerializationProvider;
import net.ess3.provider.ServerStateProvider;
import net.ess3.provider.SignDataProvider;
import net.ess3.provider.SpawnEggProvider;
import net.ess3.provider.SpawnerBlockProvider;
import net.ess3.provider.SpawnerItemProvider;
import net.ess3.provider.SyncCommandsProvider;
import net.ess3.provider.WorldInfoProvider;
import net.ess3.provider.providers.BaseBannerDataProvider;
import net.ess3.provider.providers.BaseInventoryViewProvider;
import net.ess3.provider.providers.BaseLoggerProvider;
import net.ess3.provider.providers.BlockMetaSpawnerItemProvider;
import net.ess3.provider.providers.BukkitMaterialTagProvider;
import net.ess3.provider.providers.BukkitSpawnerBlockProvider;
import net.ess3.provider.providers.BukkitTileEntityProvider;
import net.ess3.provider.providers.FixedHeightWorldInfoProvider;
import net.ess3.provider.providers.FlatSpawnEggProvider;
import net.ess3.provider.providers.LegacyBannerDataProvider;
import net.ess3.provider.providers.LegacyBiomeNameProvider;
import net.ess3.provider.providers.LegacyDamageEventProvider;
import net.ess3.provider.providers.LegacyInventoryViewProvider;
import net.ess3.provider.providers.LegacyItemUnbreakableProvider;
@@ -92,7 +102,6 @@ import net.ess3.provider.providers.ModernPersistentDataProvider;
import net.ess3.provider.providers.ModernPlayerLocaleProvider;
import net.ess3.provider.providers.ModernPotionMetaProvider;
import net.ess3.provider.providers.ModernSignDataProvider;
import net.ess3.provider.providers.ModernSyncCommandsProvider;
import net.ess3.provider.providers.PaperBiomeKeyProvider;
import net.ess3.provider.providers.PaperContainerProvider;
import net.ess3.provider.providers.PaperKnownCommandsProvider;
@@ -100,11 +109,11 @@ import net.ess3.provider.providers.PaperMaterialTagProvider;
import net.ess3.provider.providers.PaperRecipeBookListener;
import net.ess3.provider.providers.PaperSerializationProvider;
import net.ess3.provider.providers.PaperServerStateProvider;
import net.ess3.provider.providers.PaperTickCountProvider;
import net.ess3.provider.providers.PaperTileEntityProvider;
import net.ess3.provider.providers.PrehistoricPotionMetaProvider;
import net.essentialsx.api.v2.services.BalanceTop;
import net.essentialsx.api.v2.services.mail.MailService;
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import net.kyori.adventure.text.Component;
import org.bukkit.Bukkit;
import org.bukkit.Server;
import org.bukkit.World;
@@ -125,13 +134,18 @@ 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;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.ServicePriority;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.plugin.java.JavaPluginLoader;
import org.bukkit.scheduler.BukkitScheduler;
import org.bukkit.scheduler.BukkitTask;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -140,14 +154,11 @@ import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.Set;
import java.util.UUID;
import java.util.function.Predicate;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.Objects;
import java.util.stream.Collectors;
import static com.earth2me.essentials.I18n.tlLiteral;
import static com.earth2me.essentials.I18n.tlLocale;
@@ -159,7 +170,6 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
private final transient TNTExplodeListener tntListener = new TNTExplodeListener();
private final transient Set<String> vanishedPlayers = new LinkedHashSet<>();
private final transient Map<String, IEssentialsCommand> commandMap = new HashMap<>();
private final transient ProviderFactory providerFactory = new ProviderFactory(this);
private transient ISettings settings;
private transient Jails jails;
private transient Warps warps;
@@ -179,21 +189,83 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
private transient I18n i18n;
private transient MetricsWrapper metrics;
private transient EssentialsTimer timer;
private transient SpawnerItemProvider spawnerItemProvider;
private transient SpawnerBlockProvider spawnerBlockProvider;
private transient SpawnEggProvider spawnEggProvider;
private transient PotionMetaProvider potionMetaProvider;
private transient BannerDataProvider bannerDataProvider;
private transient ServerStateProvider serverStateProvider;
private transient ContainerProvider containerProvider;
private transient SerializationProvider serializationProvider;
private transient KnownCommandsProvider knownCommandsProvider;
private transient FormattedCommandAliasProvider formattedCommandAliasProvider;
private transient ProviderListener recipeBookEventProvider;
private transient MaterialTagProvider materialTagProvider;
private transient SyncCommandsProvider syncCommandsProvider;
private transient PersistentDataProvider persistentDataProvider;
private transient ReflOnlineModeProvider onlineModeProvider;
private transient ItemUnbreakableProvider unbreakableProvider;
private transient WorldInfoProvider worldInfoProvider;
private transient PlayerLocaleProvider playerLocaleProvider;
private transient SignDataProvider signDataProvider;
private transient DamageEventProvider damageEventProvider;
private transient BiomeKeyProvider biomeKeyProvider;
private transient InventoryViewProvider inventoryViewProvider;
private transient Kits kits;
private transient RandomTeleport randomTeleport;
private transient UpdateChecker updateChecker;
private transient AdventureFacet adventureFacet;
private transient BukkitAudiences bukkitAudience;
static {
EconomyLayers.init();
}
public Essentials() {
}
protected Essentials(final JavaPluginLoader loader, final PluginDescriptionFile description, final File dataFolder, final File file) {
super(loader, description, dataFolder, file);
}
public Essentials(final Server server) {
super(new JavaPluginLoader(server), new PluginDescriptionFile("Essentials", "", "com.earth2me.essentials.Essentials"), null, null);
}
@Override
public ISettings getSettings() {
return settings;
}
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()) {
throw new IOException();
}
if (!dataFolder.mkdir()) {
throw new IOException();
}
i18n = new I18n(this);
i18n.onEnable();
i18n.updateLocale("en");
Console.setInstance(this);
LOGGER.log(Level.INFO, AdventureUtil.miniToLegacy(tlLiteral("usingTempFolderForTesting")));
LOGGER.log(Level.INFO, dataFolder.toString());
settings = new Settings(this);
mail = new MailServiceImpl(this);
userMap = new ModernUserMap(this);
balanceTop = new BalanceTopImpl(this);
permissionsHandler = new PermissionsHandler(this, false);
Economy.setEss(this);
confList = new ArrayList<>();
jails = new Jails(this);
registerListeners(server.getPluginManager());
kits = new Kits(this);
bukkitAudience = BukkitAudiences.create(this);
}
@Override
public void onLoad() {
try {
@@ -214,8 +286,6 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
LOGGER = EssentialsLogger.getLoggerProvider(this);
EssentialsLogger.updatePluginLogger(this);
initAdventureFacet();
execTimer = new ExecuteTimer();
execTimer.start();
@@ -231,37 +301,33 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
switch (VersionUtil.getServerSupportStatus()) {
case NMS_CLEANROOM:
getLogger().severe(getAdventureFacet().miniToLegacy(tlLiteral("serverUnsupportedCleanroom")));
getLogger().severe(AdventureUtil.miniToLegacy(tlLiteral("serverUnsupportedCleanroom")));
break;
case DANGEROUS_FORK:
getLogger().severe(getAdventureFacet().miniToLegacy(tlLiteral("serverUnsupportedDangerous")));
getLogger().severe(AdventureUtil.miniToLegacy(tlLiteral("serverUnsupportedDangerous")));
break;
case STUPID_PLUGIN:
getLogger().severe(getAdventureFacet().miniToLegacy(tlLiteral("serverUnsupportedDumbPlugins")));
getLogger().severe(AdventureUtil.miniToLegacy(tlLiteral("serverUnsupportedDumbPlugins")));
break;
case UNSTABLE:
getLogger().severe(getAdventureFacet().miniToLegacy(tlLiteral("serverUnsupportedMods")));
getLogger().severe(AdventureUtil.miniToLegacy(tlLiteral("serverUnsupportedMods")));
break;
case OUTDATED:
getLogger().severe(getAdventureFacet().miniToLegacy(tlLiteral("serverUnsupported")));
getLogger().severe(AdventureUtil.miniToLegacy(tlLiteral("serverUnsupported")));
break;
case LIMITED:
getLogger().info(getAdventureFacet().miniToLegacy(tlLiteral("serverUnsupportedLimitedApi")));
getLogger().info(AdventureUtil.miniToLegacy(tlLiteral("serverUnsupportedLimitedApi")));
break;
}
if (VersionUtil.getSupportStatusClass() != null) {
getLogger().info(getAdventureFacet().miniToLegacy(tlLiteral("serverUnsupportedClass", VersionUtil.getSupportStatusClass())));
}
if (VersionUtil.getServerBukkitVersion().isSnapshot()) {
getLogger().severe(getAdventureFacet().miniToLegacy(tlLiteral("serverSnapshot")));
getLogger().info(AdventureUtil.miniToLegacy(tlLiteral("serverUnsupportedClass", VersionUtil.getSupportStatusClass())));
}
final PluginManager pm = getServer().getPluginManager();
for (final Plugin plugin : pm.getPlugins()) {
if (plugin.getDescription().getName().startsWith("Essentials") && !plugin.getDescription().getVersion().equals(this.getDescription().getVersion()) && !plugin.getDescription().getName().equals("EssentialsAntiCheat")) {
getLogger().warning(getAdventureFacet().miniToLegacy(tlLiteral("versionMismatch", plugin.getDescription().getName())));
getLogger().warning(AdventureUtil.miniToLegacy(tlLiteral("versionMismatch", plugin.getDescription().getName())));
}
}
@@ -291,10 +357,6 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
upgrade.convertKits();
execTimer.mark("Kits");
randomTeleport = new RandomTeleport(this);
confList.add(randomTeleport);
execTimer.mark("Init(RandomTeleport)");
upgrade.afterSettings();
execTimer.mark("Upgrade3");
@@ -310,6 +372,13 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
confList.add(itemDb);
execTimer.mark("Init(ItemDB)");
randomTeleport = new RandomTeleport(this);
if (randomTeleport.getPreCache()) {
randomTeleport.cacheRandomLocations(randomTeleport.getCenter(), randomTeleport.getMinRange(), randomTeleport.getMaxRange());
}
confList.add(randomTeleport);
execTimer.mark("Init(RandomTeleport)");
customItemResolver = new CustomItemResolver(this);
try {
itemDb.registerResolver(this, "custom_items", customItemResolver);
@@ -325,85 +394,53 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
execTimer.mark("Init(Jails)");
EconomyLayers.onEnable(this);
execTimer.mark("Init(EconomyLayers)");
// Spawner item provider only uses one, but it's here for legacy...
providerFactory.registerProvider(BlockMetaSpawnerItemProvider.class);
//Spawner item provider only uses one but it's here for legacy...
spawnerItemProvider = new BlockMetaSpawnerItemProvider();
// Spawner block providers
providerFactory.registerProvider(ReflSpawnerBlockProvider.class, BukkitSpawnerBlockProvider.class);
// Spawn Egg Providers
providerFactory.registerProvider(LegacySpawnEggProvider.class, ReflSpawnEggProvider.class, FlatSpawnEggProvider.class);
//Potion Meta Provider
providerFactory.registerProvider(PrehistoricPotionMetaProvider.class, LegacyPotionMetaProvider.class, ModernPotionMetaProvider.class);
//Banner Meta Provider
providerFactory.registerProvider(LegacyBannerDataProvider.class, BaseBannerDataProvider.class);
// Server State Provider
providerFactory.registerProvider(ReflServerStateProvider.class, PaperServerStateProvider.class);
// Container Provider
providerFactory.registerProvider(PaperContainerProvider.class);
// Serialization Provider
providerFactory.registerProvider(PaperSerializationProvider.class);
// Known Commands Provider
providerFactory.registerProvider(ReflKnownCommandsProvider.class, PaperKnownCommandsProvider.class);
// Command Aliases Provider
providerFactory.registerProvider(ReflFormattedCommandAliasProvider.class);
// Material Tag Providers
providerFactory.registerProvider(BukkitMaterialTagProvider.class, PaperMaterialTagProvider.class);
// Sync Commands Provider
providerFactory.registerProvider(ReflSyncCommandsProvider.class, ModernSyncCommandsProvider.class);
// Persistent Data Provider
providerFactory.registerProvider(ReflPersistentDataProvider.class, ModernPersistentDataProvider.class);
// Online Mode Provider
providerFactory.registerProvider(ReflOnlineModeProvider.class);
// Unbreakable Provider
providerFactory.registerProvider(LegacyItemUnbreakableProvider.class, ModernItemUnbreakableProvider.class);
// World Info Provider
providerFactory.registerProvider(FixedHeightWorldInfoProvider.class, ReflDataWorldInfoProvider.class, ModernDataWorldInfoProvider.class);
// Sign Data Provider
providerFactory.registerProvider(ModernSignDataProvider.class);
// Player Locale Provider
providerFactory.registerProvider(ModernPlayerLocaleProvider.class, LegacyPlayerLocaleProvider.class);
// Damage Event Provider
providerFactory.registerProvider(ModernDamageEventProvider.class, LegacyDamageEventProvider.class);
// Inventory View Provider
providerFactory.registerProvider(LegacyInventoryViewProvider.class, BaseInventoryViewProvider.class);
// Biome Name Provider
providerFactory.registerProvider(LegacyBiomeNameProvider.class);
// Biome Key Provider
providerFactory.registerProvider(PaperBiomeKeyProvider.class);
// Tile Entity Provider
providerFactory.registerProvider(BukkitTileEntityProvider.class, PaperTileEntityProvider.class);
// Tick Count Provider
providerFactory.registerProvider(PaperTickCountProvider.class);
if (!TESTING) {
providerFactory.finalizeRegistration();
//Spawner block providers
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_12_0_R01)) {
spawnerBlockProvider = new ReflSpawnerBlockProvider();
} else {
spawnerBlockProvider = new BukkitSpawnerBlockProvider();
}
// Event Providers
//Spawn Egg Providers
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_9_R01)) {
spawnEggProvider = new LegacySpawnEggProvider();
} else if (VersionUtil.getServerBukkitVersion().isLowerThanOrEqualTo(VersionUtil.v1_12_2_R01)) {
spawnEggProvider = new ReflSpawnEggProvider();
} else {
spawnEggProvider = new FlatSpawnEggProvider();
}
//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
//Container Provider
if (PaperLib.isPaper() && VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_15_2_R01)) {
serverStateProvider = new PaperServerStateProvider();
containerProvider = new PaperContainerProvider();
serializationProvider = new PaperSerializationProvider();
} else {
serverStateProvider = new ReflServerStateProvider();
}
//Event Providers
if (PaperLib.isPaper()) {
try {
Class.forName("com.destroystokyo.paper.event.player.PlayerRecipeBookClickEvent");
@@ -412,13 +449,76 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
((Cancellable) event).setCancelled(true);
}
});
if (getSettings().isDebug()) {
LOGGER.log(Level.INFO, "Registered Paper Recipe Book Event Listener");
}
} catch (final ClassNotFoundException ignored) {
}
}
//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();
@@ -439,17 +539,15 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
PermissionsDefaults.registerAllBackDefaults();
PermissionsDefaults.registerAllHatDefaults();
if (!TESTING) {
updateChecker = new UpdateChecker(this);
runTaskAsynchronously(() -> {
getLogger().log(Level.INFO, getAdventureFacet().miniToLegacy(tlLiteral("versionFetching")));
for (final ComponentHolder component : updateChecker.getVersionMessages(false, true, new CommandSource(this, Bukkit.getConsoleSender()))) {
getLogger().log(getSettings().isUpdateCheckEnabled() ? Level.WARNING : Level.INFO, getAdventureFacet().adventureToLegacy(component));
}
});
updateChecker = new UpdateChecker(this);
runTaskAsynchronously(() -> {
getLogger().log(Level.INFO, AdventureUtil.miniToLegacy(tlLiteral("versionFetching")));
for (final Component component : updateChecker.getVersionMessages(false, true, new CommandSource(this, Bukkit.getConsoleSender()))) {
getLogger().log(getSettings().isUpdateCheckEnabled() ? Level.WARNING : Level.INFO, AdventureUtil.adventureToLegacy(component));
}
});
metrics = new MetricsWrapper(this, 858, true);
}
metrics = new MetricsWrapper(this, 858, true);
execTimer.mark("Init(External)");
@@ -463,9 +561,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
handleCrash(ex);
throw ex;
}
if (!TESTING) {
getBackup().setPendingShutdown(false);
}
getBackup().setPendingShutdown(false);
}
// Returns our provider logger if available
@@ -526,26 +622,13 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
jails.resetListener();
}
@Override
public ProviderFactory getProviders() {
return providerFactory;
}
@Override
public void onDisable() {
if (adventureFacet != null) {
adventureFacet.close();
}
final boolean stopping = TESTING || provider(ServerStateProvider.class).isStopping();
final boolean stopping = getServerStateProvider().isStopping();
if (!stopping) {
LOGGER.log(Level.SEVERE, getAdventureFacet().miniToLegacy(tlLiteral("serverReloading")));
LOGGER.log(Level.SEVERE, AdventureUtil.miniToLegacy(tlLiteral("serverReloading")));
}
if (!TESTING) {
getBackup().setPendingShutdown(true);
}
getBackup().setPendingShutdown(true);
for (final User user : getOnlineUsers()) {
if (user.isVanished()) {
user.setVanished(false);
@@ -562,8 +645,8 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
}
}
cleanupOpenInventories();
if (!TESTING && getBackup().getTaskLock() != null && !getBackup().getTaskLock().isDone()) {
LOGGER.log(Level.SEVERE, getAdventureFacet().miniToLegacy(tlLiteral("backupInProgress")));
if (getBackup().getTaskLock() != null && !getBackup().getTaskLock().isDone()) {
LOGGER.log(Level.SEVERE, AdventureUtil.miniToLegacy(tlLiteral("backupInProgress")));
getBackup().getTaskLock().join();
}
if (i18n != null) {
@@ -573,16 +656,12 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
backup.stopTask();
}
if (!TESTING) {
this.getPermissionsHandler().unregisterContexts();
}
this.getPermissionsHandler().unregisterContexts();
Economy.setEss(null);
Trade.closeLog();
getUsers().shutdown();
EssentialsConfiguration.shutdownExecutor();
HandlerList.unregisterAll(this);
}
@@ -590,6 +669,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() + ")");
@@ -599,29 +683,16 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
for (final String commandName : this.getDescription().getCommands().keySet()) {
final Command command = this.getCommand(commandName);
if (command != null) {
command.setDescription(getAdventureFacet().miniToLegacy(tlLiteral(commandName + "CommandDescription")));
command.setUsage(getAdventureFacet().miniToLegacy(tlLiteral(commandName + "CommandUsage")));
command.setDescription(tlLiteral(commandName + "CommandDescription"));
command.setUsage(tlLiteral(commandName + "CommandUsage"));
}
}
final PluginManager pm = getServer().getPluginManager();
registerListeners(pm);
initAdventureFacet();
}
private void initAdventureFacet() {
if (adventureFacet != null) {
adventureFacet.close();
}
if (VersionUtil.isPaper() && VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_16_5_R01)) {
adventureFacet = new PaperAdventureFacet(getSettings() != null ? getSettings().getPrimaryColor() : null, getSettings() != null ? getSettings().getSecondaryColor() : null);
} else {
adventureFacet = new SpigotAdventureFacet(this);
}
AdventureUtil.setAdventureFacet(adventureFacet);
AdventureUtil.setEss(this);
bukkitAudience = BukkitAudiences.create(this);
}
private IEssentialsCommand loadCommand(final String path, final String name, final IEssentialsModule module, final ClassLoader classLoader) throws Exception {
@@ -674,9 +745,11 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
// Check for disabled commands
if (getSettings().isCommandDisabled(commandLabel)) {
final Command newCmd = provider(KnownCommandsProvider.class).getKnownCommands().get(commandLabel);
if (newCmd != null && (!(newCmd instanceof PluginIdentifiableCommand) || ((PluginIdentifiableCommand) newCmd).getPlugin() != this)) {
return newCmd.tabComplete(cSender, commandLabel, args);
if (getKnownCommandsProvider().getKnownCommands().containsKey(commandLabel)) {
final Command newCmd = getKnownCommandsProvider().getKnownCommands().get(commandLabel);
if (!(newCmd instanceof PluginIdentifiableCommand) || ((PluginIdentifiableCommand) newCmd).getPlugin() != this) {
return newCmd.tabComplete(cSender, commandLabel, args);
}
}
return Collections.emptyList();
}
@@ -686,7 +759,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
cmd = loadCommand(commandPath, command.getName(), module, classLoader);
} catch (final Exception ex) {
sender.sendTl("commandNotLoaded", commandLabel);
LOGGER.log(Level.SEVERE, getAdventureFacet().miniToLegacy(tlLiteral("commandNotLoaded", commandLabel)), ex);
LOGGER.log(Level.SEVERE, AdventureUtil.miniToLegacy(tlLiteral("commandNotLoaded", commandLabel)), ex);
return Collections.emptyList();
}
@@ -709,11 +782,11 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
} catch (final Exception ex) {
showError(sender, ex, commandLabel);
// Tab completion shouldn't fail
LOGGER.log(Level.SEVERE, getAdventureFacet().miniToLegacy(tlLiteral("commandFailed", commandLabel)), ex);
LOGGER.log(Level.SEVERE, AdventureUtil.miniToLegacy(tlLiteral("commandFailed", commandLabel)), ex);
return Collections.emptyList();
}
} catch (final Throwable ex) {
LOGGER.log(Level.SEVERE, getAdventureFacet().miniToLegacy(tlLiteral("commandFailed", commandLabel)), ex);
LOGGER.log(Level.SEVERE, AdventureUtil.miniToLegacy(tlLiteral("commandFailed", commandLabel)), ex);
return Collections.emptyList();
}
}
@@ -739,9 +812,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
} catch (final Exception ex) {
LOGGER.log(Level.SEVERE, ex.getMessage(), ex);
if (cSender instanceof Player) {
final PlayerLocaleProvider localeProvider = provider(PlayerLocaleProvider.class);
final String miniMessageStr = tlLocale(I18n.getLocale(localeProvider.getLocale((Player) cSender)), "internalError");
getAdventureFacet().send(cSender, getAdventureFacet().deserializeMiniMessage(miniMessageStr));
cSender.sendMessage(tlLocale(I18n.getLocale(getPlayerLocaleProvider().getLocale((Player) cSender)), "internalError"));
} else {
cSender.sendMessage(tlLiteral("internalError"));
}
@@ -766,9 +837,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
LOGGER.log(Level.INFO, "CommandBlock at " + bSenderBlock.getX() + "," + bSenderBlock.getY() + "," + bSenderBlock.getZ() + " issued server command: /" + commandLabel + " " + EssentialsCommand.getFinalArg(args, 0));
}
} else if (user == null) {
if (getSettings().logConsoleCommands()) {
LOGGER.log(Level.INFO, cSender.getName()+ " issued server command: /" + commandLabel + " " + EssentialsCommand.getFinalArg(args, 0));
}
LOGGER.log(Level.INFO, cSender.getName()+ " issued server command: /" + commandLabel + " " + EssentialsCommand.getFinalArg(args, 0));
}
final CommandSource sender = new CommandSource(this, cSender);
@@ -786,9 +855,11 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
// Check for disabled commands
if (getSettings().isCommandDisabled(commandLabel)) {
final Command newCmd = provider(KnownCommandsProvider.class).getKnownCommands().get(commandLabel);
if (newCmd != null && (!(newCmd instanceof PluginIdentifiableCommand) || !isEssentialsPlugin(((PluginIdentifiableCommand) newCmd).getPlugin()))) {
return newCmd.execute(cSender, commandLabel, args);
if (getKnownCommandsProvider().getKnownCommands().containsKey(commandLabel)) {
final Command newCmd = getKnownCommandsProvider().getKnownCommands().get(commandLabel);
if (!(newCmd instanceof PluginIdentifiableCommand) || !isEssentialsPlugin(((PluginIdentifiableCommand) newCmd).getPlugin())) {
return newCmd.execute(cSender, commandLabel, args);
}
}
sender.sendTl("commandDisabled", commandLabel);
return true;
@@ -799,13 +870,13 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
cmd = loadCommand(commandPath, command.getName(), module, classLoader);
} catch (final Exception ex) {
sender.sendTl("commandNotLoaded", commandLabel);
LOGGER.log(Level.SEVERE, getAdventureFacet().miniToLegacy(tlLiteral("commandNotLoaded", commandLabel)), ex);
LOGGER.log(Level.SEVERE, AdventureUtil.miniToLegacy(tlLiteral("commandNotLoaded", commandLabel)), ex);
return true;
}
// Check authorization
if (user != null && !user.isAuthorized(cmd, permissionPrefix)) {
LOGGER.log(Level.INFO, getAdventureFacet().miniToLegacy(tlLiteral("deniedAccessCommand", user.getName())));
LOGGER.log(Level.INFO, AdventureUtil.miniToLegacy(tlLiteral("deniedAccessCommand", user.getName())));
user.sendTl("noAccessCommand");
return true;
}
@@ -832,21 +903,17 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
} catch (final NotEnoughArgumentsException ex) {
if (getSettings().isVerboseCommandUsages() && !cmd.getUsageStrings().isEmpty()) {
sender.sendTl("commandHelpLine1", commandLabel);
String description = command.getDescription();
try {
description = sender.tl(command.getName() + "CommandDescription");
} catch (MissingResourceException ignored) {}
sender.sendTl("commandHelpLine2", description);
sender.sendTl("commandHelpLine2", command.getDescription());
sender.sendTl("commandHelpLine3");
for (Map.Entry<String, String> usage : cmd.getUsageStrings().entrySet()) {
sender.sendTl("commandHelpLineUsage", AdventureUtil.parsed(usage.getKey().replace("<command>", commandLabel)), AdventureUtil.parsed(sender.tl(usage.getValue())));
sender.sendTl("commandHelpLineUsage", AdventureUtil.parsed(usage.getKey().replace("<command>", commandLabel)), AdventureUtil.parsed(usage.getValue()));
}
} else {
sender.sendMessage(command.getDescription());
sender.sendMessage(command.getUsage().replace("<command>", commandLabel));
}
if (!ex.getMessage().isEmpty()) {
sender.sendComponent(getAdventureFacet().deserializeMiniMessage(ex.getMessage()));
sender.sendComponent(AdventureUtil.miniMessage().deserialize(ex.getMessage()));
}
if (ex.getCause() != null && settings.isDebug()) {
ex.getCause().printStackTrace();
@@ -860,7 +927,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
return true;
}
} catch (final Throwable ex) {
LOGGER.log(Level.SEVERE, getAdventureFacet().miniToLegacy(tlLiteral("commandFailed", commandLabel)), ex);
LOGGER.log(Level.SEVERE, AdventureUtil.miniToLegacy(tlLiteral("commandFailed", commandLabel)), ex);
return true;
}
}
@@ -870,17 +937,16 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
}
public void cleanupOpenInventories() {
final InventoryViewProvider provider = provider(InventoryViewProvider.class);
for (final User user : getOnlineUsers()) {
if (user.isRecipeSee()) {
final InventoryView view = user.getBase().getOpenInventory();
provider.getTopInventory(view).clear();
provider.close(view);
inventoryViewProvider.getTopInventory(view).clear();
inventoryViewProvider.close(view);
user.setRecipeSee(false);
}
if (user.isInvSee() || user.isEnderSee()) {
provider.close(user.getBase().getOpenInventory());
inventoryViewProvider.close(user.getBase().getOpenInventory());
user.setInvSee(false);
user.setEnderSee(false);
}
@@ -896,7 +962,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
sender.sendTl("errorWithMessage", exception.getMessage());
}
if (getSettings().isDebug()) {
LOGGER.log(Level.INFO, getAdventureFacet().miniToLegacy(tlLiteral("errorCallingCommand", commandLabel)), exception);
LOGGER.log(Level.INFO, AdventureUtil.miniToLegacy(tlLiteral("errorCallingCommand", commandLabel)), exception);
}
}
@@ -905,11 +971,6 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
return this.getServer().getScheduler();
}
@Override
public List<Player> getJailedPlayers() {
return getUsers().getAllUserUUIDs().stream().map(this::getUser).filter(Objects::nonNull).filter(User::isJailed).map(User::getBase).filter(Objects::nonNull).collect(Collectors.toList());
}
@Override
public IJails getJails() {
return jails;
@@ -986,23 +1047,13 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
final User user;
Player exPlayer;
if (sourceUser != null && (searchTerm.equals("@p") || searchTerm.equals("@s"))) {
return sourceUser;
}
try {
exPlayer = server.getPlayer(UUID.fromString(searchTerm));
} catch (final IllegalArgumentException ex) {
// Prefer exact online name match first always
if (getOffline) {
// When offline lookups are allowed, do not pick partial online matches here; allow exact offline match later
exPlayer = server.getPlayerExact(searchTerm);
} else {
exPlayer = server.getPlayerExact(searchTerm);
if (exPlayer == null) {
// Only consider partial/prefix online match when not explicitly doing an offline-capable lookup
exPlayer = server.getPlayer(searchTerm);
}
exPlayer = server.getPlayer(searchTerm);
}
}
@@ -1039,16 +1090,6 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
}
}
} else {
// Prefer exact username match among the matched players
for (final Player player : matches) {
if (player.getName().equalsIgnoreCase(searchTerm)) {
final User userMatch = getUser(player);
if (getHidden || canInteractWith(sourceUser, userMatch)) {
return userMatch;
}
}
}
// Then prefer display name/prefix match as before
for (final Player player : matches) {
final User userMatch = getUser(player);
if (userMatch.getDisplayName().startsWith(searchTerm) && (getHidden || canInteractWith(sourceUser, userMatch))) {
@@ -1170,7 +1211,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
final Collection<Player> players = getOnlinePlayers();
for (final Player player : players) {
final User user = getUser(player);
if (permission == null && (sender == null || !user.isIgnoredPlayer(sender)) || permission != null && user.isAuthorized(permission)) {
if ((permission == null && (sender == null || !user.isIgnoredPlayer(sender))) || (permission != null && user.isAuthorized(permission))) {
if (shouldExclude != null && shouldExclude.test(user)) {
continue;
}
@@ -1332,19 +1373,122 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
return onlineUsers;
}
@Override
public SpawnerItemProvider getSpawnerItemProvider() {
return spawnerItemProvider;
}
@Override
public SpawnerBlockProvider getSpawnerBlockProvider() {
return spawnerBlockProvider;
}
@Override
public SpawnEggProvider getSpawnEggProvider() {
return spawnEggProvider;
}
@Override
public PotionMetaProvider getPotionMetaProvider() {
return potionMetaProvider;
}
@Override
public BannerDataProvider getBannerDataProvider() {
return bannerDataProvider;
}
@Override
public InventoryViewProvider getInventoryViewProvider() {
return inventoryViewProvider;
}
@Override
public CustomItemResolver getCustomItemResolver() {
return customItemResolver;
}
@Override
public ServerStateProvider getServerStateProvider() {
return serverStateProvider;
}
public MaterialTagProvider getMaterialTagProvider() {
return materialTagProvider;
}
@Override
public ContainerProvider getContainerProvider() {
return containerProvider;
}
@Override
public KnownCommandsProvider getKnownCommandsProvider() {
return knownCommandsProvider;
}
@Override
public SerializationProvider getSerializationProvider() {
return serializationProvider;
}
@Override
public FormattedCommandAliasProvider getFormattedCommandAliasProvider() {
return formattedCommandAliasProvider;
}
@Override
public SyncCommandsProvider getSyncCommandsProvider() {
return syncCommandsProvider;
}
@Override
public PersistentDataProvider getPersistentDataProvider() {
return persistentDataProvider;
}
@Override
public ReflOnlineModeProvider getOnlineModeProvider() {
return onlineModeProvider;
}
@Override
public ItemUnbreakableProvider getItemUnbreakableProvider() {
return unbreakableProvider;
}
@Override
public WorldInfoProvider getWorldInfoProvider() {
return worldInfoProvider;
}
@Override
public PlayerLocaleProvider getPlayerLocaleProvider() {
return playerLocaleProvider;
}
@Override
public DamageEventProvider getDamageEventProvider() {
return damageEventProvider;
}
@Override
public BiomeKeyProvider getBiomeKeyProvider() {
return biomeKeyProvider;
}
@Override
public SignDataProvider getSignDataProvider() {
return signDataProvider;
}
@Override
public PluginCommand getPluginCommand(final String cmd) {
return this.getCommand(cmd);
}
@Override
public AdventureFacet getAdventureFacet() {
return adventureFacet;
public BukkitAudiences getBukkitAudience() {
return bukkitAudience;
}
private AbstractItemDb getItemDbFromConfig() {
@@ -3,8 +3,6 @@ package com.earth2me.essentials;
import com.earth2me.essentials.craftbukkit.Inventories;
import com.earth2me.essentials.utils.MaterialUtil;
import net.ess3.api.IEssentials;
import net.ess3.provider.PersistentDataProvider;
import net.ess3.provider.SpawnerItemProvider;
import org.bukkit.GameMode;
import org.bukkit.block.BlockState;
import org.bukkit.block.CreatureSpawner;
@@ -28,11 +26,11 @@ public class EssentialsBlockListener implements Listener {
public void onBlockPlace(final BlockPlaceEvent event) {
final ItemStack is = event.getItemInHand();
if (is.getType() == MaterialUtil.SPAWNER && ess.provider(PersistentDataProvider.class).getString(is, "convert") != null) {
if (is.getType() == MaterialUtil.SPAWNER && ess.getPersistentDataProvider().getString(is, "convert") != null) {
final BlockState blockState = event.getBlockPlaced().getState();
if (blockState instanceof CreatureSpawner) {
final CreatureSpawner spawner = (CreatureSpawner) blockState;
final EntityType type = ess.provider(SpawnerItemProvider.class).getEntityType(event.getItemInHand());
final EntityType type = ess.getSpawnerItemProvider().getEntityType(event.getItemInHand());
if (type != null && Mob.fromBukkitType(type) != null) {
if (ess.getUser(event.getPlayer()).isAuthorized("essentials.spawnerconvert." + Mob.fromBukkitType(type).name().toLowerCase(Locale.ENGLISH))) {
spawner.setSpawnedType(type);
@@ -156,7 +156,7 @@ public class EssentialsEntityListener implements Listener {
}
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
@EventHandler(priority = EventPriority.LOWEST)
public void onPlayerDeathEvent(final PlayerDeathEvent event) {
final Entity entity = event.getEntity();
if (entity.hasMetadata("NPC")) {
@@ -190,15 +190,7 @@ public class EssentialsEntityListener implements Listener {
final User user = ess.getUser(event.getEntity());
if (user.isAuthorized("essentials.keepinv")) {
event.setKeepInventory(true);
// We don't do getDrops().clear() here because it would remove any loot tables that were added by other plugins/datapacks.
// Instead, we remove the items from the drops that are in the player's inventory. This way, the loot tables can still drop items.
// This is the same behavior as the vanilla /gamerule keepInventory.
final ItemStack[] inventory = Inventories.getInventory(event.getEntity(), true);
for (final ItemStack item : inventory) {
if (item != null) {
event.getDrops().remove(item);
}
}
event.getDrops().clear();
final ISettings.KeepInvPolicy vanish = ess.getSettings().getVanishingItemsPolicy();
final ISettings.KeepInvPolicy bind = ess.getSettings().getBindingItemsPolicy();
if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_11_2_R01) && (vanish != ISettings.KeepInvPolicy.KEEP || bind != ISettings.KeepInvPolicy.KEEP)) {
@@ -1,14 +1,12 @@
package com.earth2me.essentials;
import com.destroystokyo.paper.ClientOption;
import com.earth2me.essentials.adventure.ComponentHolder;
import com.earth2me.essentials.commands.Commandfireball;
import com.earth2me.essentials.craftbukkit.Inventories;
import com.earth2me.essentials.textreader.IText;
import com.earth2me.essentials.textreader.KeywordReplacer;
import com.earth2me.essentials.textreader.TextInput;
import com.earth2me.essentials.textreader.TextPager;
import com.earth2me.essentials.userstorage.ModernUserMap;
import com.earth2me.essentials.utils.AdventureUtil;
import com.earth2me.essentials.utils.CommonPlaceholders;
import com.earth2me.essentials.utils.DateUtil;
import com.earth2me.essentials.utils.FormatUtil;
@@ -16,20 +14,13 @@ import com.earth2me.essentials.utils.LocationUtil;
import com.earth2me.essentials.utils.MaterialUtil;
import com.earth2me.essentials.utils.VersionUtil;
import io.papermc.lib.PaperLib;
import io.papermc.paper.ban.BanListType;
import io.papermc.paper.event.connection.configuration.AsyncPlayerConnectionConfigureEvent;
import io.papermc.paper.event.player.PlayerServerFullCheckEvent;
import net.ess3.api.IEssentials;
import net.ess3.api.events.AfkStatusChangeEvent;
import net.ess3.provider.CommandSendListenerProvider;
import net.ess3.provider.FormattedCommandAliasProvider;
import net.ess3.provider.InventoryViewProvider;
import net.ess3.provider.KnownCommandsProvider;
import net.ess3.provider.TickCountProvider;
import net.ess3.provider.providers.BukkitCommandSendListenerProvider;
import net.ess3.provider.providers.PaperCommandSendListenerProvider;
import net.essentialsx.PaperAdventureSmuggler;
import net.essentialsx.api.v2.events.AsyncUserDataLoadEvent;
import net.kyori.adventure.text.Component;
import org.bukkit.BanEntry;
import org.bukkit.BanList;
import org.bukkit.GameMode;
@@ -48,19 +39,17 @@ import org.bukkit.event.Listener;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.event.inventory.InventoryDragEvent;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.event.player.AsyncPlayerPreLoginEvent;
import org.bukkit.event.player.PlayerBucketEmptyEvent;
import org.bukkit.event.player.PlayerChangedWorldEvent;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.player.PlayerEggThrowEvent;
import org.bukkit.event.player.PlayerFishEvent;
import org.bukkit.event.player.PlayerGameModeChangeEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerLoginEvent;
import org.bukkit.event.player.PlayerLoginEvent.Result;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerRespawnEvent;
@@ -76,23 +65,22 @@ import java.lang.management.ManagementFactory;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.logging.Level;
import java.util.regex.Pattern;
import static com.earth2me.essentials.I18n.tlLiteral;
public class EssentialsPlayerListener implements Listener {
public class EssentialsPlayerListener implements Listener, FakeAccessor {
private final transient IEssentials ess;
private final ConcurrentHashMap<UUID, Integer> pendingMotdTasks = new ConcurrentHashMap<>();
@@ -167,14 +155,6 @@ public class EssentialsPlayerListener implements Listener {
} else if (isCommandSendEvent()) {
ess.getServer().getPluginManager().registerEvents(new BukkitCommandSendListenerProvider(new CommandSendFilter()), ess);
}
if (VersionUtil.isPaper() && VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_21_8_R01)) {
ess.getServer().getPluginManager().registerEvents(new LoginListener1_21(), ess);
ess.getServer().getPluginManager().registerEvents(new JoinListener1_21(), ess);
} else {
ess.getServer().getPluginManager().registerEvents(new LoginListenerPre1_21(), ess);
ess.getServer().getPluginManager().registerEvents(new JoinListenerPre1_21(), ess);
}
}
@EventHandler(priority = EventPriority.NORMAL)
@@ -209,7 +189,7 @@ public class EssentialsPlayerListener implements Listener {
}
}
ess.getLogger().info(ess.getAdventureFacet().miniToLegacy(tlLiteral("mutedUserSpeaks", user.getName(), event.getMessage())));
ess.getLogger().info(AdventureUtil.miniToLegacy(tlLiteral("mutedUserSpeaks", user.getName(), event.getMessage())));
}
try {
final Iterator<Player> it = event.getRecipients().iterator();
@@ -294,7 +274,7 @@ public class EssentialsPlayerListener implements Listener {
ess.getScheduler().cancelTask(pendingId);
}
if (hideJoinQuitMessages() || ess.getSettings().allowSilentJoinQuit() && user.isAuthorized("essentials.silentquit")) {
if (hideJoinQuitMessages() || (ess.getSettings().allowSilentJoinQuit() && user.isAuthorized("essentials.silentquit"))) {
event.setQuitMessage(null);
} else if (ess.getSettings().isCustomQuitMessage() && event.getQuitMessage() != null) {
final Player player = event.getPlayer();
@@ -319,7 +299,7 @@ public class EssentialsPlayerListener implements Listener {
}
user.setLogoutLocation();
if (user.isRecipeSee()) {
ess.provider(InventoryViewProvider.class).getTopInventory(user.getBase().getOpenInventory()).clear();
ess.getInventoryViewProvider().getTopInventory(user.getBase().getOpenInventory()).clear();
}
final ArrayList<HumanEntity> viewers = new ArrayList<>(user.getBase().getInventory().getViewers());
@@ -341,72 +321,8 @@ public class EssentialsPlayerListener implements Listener {
user.dispose();
}
@SuppressWarnings("UnstableApiUsage")
private final class JoinListener1_21 implements Listener {
private final Map<UUID, String> newUserLocales = new ConcurrentHashMap<>();
@EventHandler
public void onPlayerConfigure(final AsyncPlayerConnectionConfigureEvent event) {
ess.getBackup().onPlayerJoin();
final User dUser = ess.getUser(event.getConnection().getProfile().getId());
// Force loading of the locale bundle while we are async to ensure it's ready when the player joins.
final String locale = event.getConnection().getClientOption(ClientOption.LOCALE);
ess.getI18n().blockingLoadBundle(I18n.getLocale(locale));
// This is a first time join, we have to wait until the bukkit Player object is created to create the User object.
// So we store the locale here and apply it when the PlayerJoinEvent is fired.
if (dUser == null) {
newUserLocales.put(event.getConnection().getProfile().getId(), locale);
return;
}
// Set the locale for player to preload the language bundle.
dUser.getPlayerLocale(locale);
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onPlayerJoin(final PlayerJoinEvent event) {
final User user = ess.getUser(event.getPlayer());
if (user == null) {
legacyJoinFlow(event);
return;
}
user.update(event.getPlayer());
// If this is a new user, we set their locale that we stored earlier.
final String locale = newUserLocales.remove(user.getUUID());
if (locale != null) {
user.getPlayerLocale(locale);
}
final long currentTime = System.currentTimeMillis();
user.startTransaction();
if (user.isNPC()) {
user.setNPC(false);
}
user.checkMuteTimeout(currentTime);
user.updateActivity(false, AfkStatusChangeEvent.Cause.JOIN);
user.stopTransaction();
joinFlow(user, currentTime, event.getJoinMessage(), event::setJoinMessage);
}
}
private final class JoinListenerPre1_21 implements Listener {
@EventHandler(priority = EventPriority.HIGHEST)
public void onPlayerJoin(final PlayerJoinEvent event) {
legacyJoinFlow(event);
}
}
private boolean hideJoinQuitMessages() {
return ess.getSettings().hasJoinQuitMessagePlayerCount() && ess.getServer().getOnlinePlayers().size() > ess.getSettings().getJoinQuitMessagePlayerCount();
}
private void legacyJoinFlow(final PlayerJoinEvent event) {
@EventHandler(priority = EventPriority.HIGHEST)
public void onPlayerJoin(final PlayerJoinEvent event) {
final String joinMessage = event.getJoinMessage();
ess.runTaskAsynchronously(() -> delayedJoin(event.getPlayer(), joinMessage));
@@ -415,179 +331,17 @@ public class EssentialsPlayerListener implements Listener {
}
}
private void joinFlow(final User user, final long currentTime, final String message, final Consumer<String> joinMessageConsumer) {
user.startTransaction();
final String lastAccountName = user.getLastAccountName(); // For comparison
user.setLastAccountName(user.getBase().getName());
final boolean newUsername = lastAccountName != null && !lastAccountName.equals(user.getBase().getName());
// If the Minecraft account name changed, reset the nickname so the old one doesn't persist
if (ess.getSettings().isResetNickOnNameChange() && newUsername && user.getNickname() != null) {
user.setNickname(null);
}
user.setLastLogin(currentTime);
user.setDisplayNick();
updateCompass(user);
user.setLeavingHidden(false);
if (!ess.getVanishedPlayersNew().isEmpty() && !user.isAuthorized("essentials.vanish.see")) {
for (final String p : ess.getVanishedPlayersNew()) {
final Player toVanish = ess.getServer().getPlayerExact(p);
if (toVanish != null && toVanish.isOnline()) {
user.getBase().hidePlayer(toVanish);
if (ess.getSettings().isDebug()) {
ess.getLogger().info("Hiding vanished player: " + p);
}
}
}
}
if (user.isAuthorized("essentials.sleepingignored")) {
user.getBase().setSleepingIgnored(true);
}
final String effectiveMessage;
if (ess.getSettings().allowSilentJoinQuit() && (user.isAuthorized("essentials.silentjoin") || user.isAuthorized("essentials.silentjoin.vanish"))) {
if (user.isAuthorized("essentials.silentjoin.vanish")) {
user.setVanished(true);
}
effectiveMessage = null;
} else if (message == null || hideJoinQuitMessages()) {
effectiveMessage = null;
} else if (ess.getSettings().isCustomJoinMessage()) {
final String msg = (newUsername && ess.getSettings().isCustomNewUsernameMessage() ? ess.getSettings().getCustomNewUsernameMessage() : ess.getSettings().getCustomJoinMessage())
.replace("{PLAYER}", user.getDisplayName()).replace("{USERNAME}", user.getName())
.replace("{UNIQUE}", NumberFormat.getInstance().format(ess.getUsers().getUserCount()))
.replace("{ONLINE}", NumberFormat.getInstance().format(ess.getOnlinePlayers().size()))
.replace("{UPTIME}", DateUtil.formatDateDiff(ManagementFactory.getRuntimeMXBean().getStartTime()))
.replace("{PREFIX}", FormatUtil.replaceFormat(ess.getPermissionsHandler().getPrefix(user.getBase())))
.replace("{SUFFIX}", FormatUtil.replaceFormat(ess.getPermissionsHandler().getSuffix(user.getBase())))
.replace("{OLDUSERNAME}", lastAccountName == null ? "" : lastAccountName);
effectiveMessage = msg.isEmpty() ? null : msg;
} else if (ess.getSettings().allowSilentJoinQuit()) {
effectiveMessage = message;
} else {
effectiveMessage = message;
}
// Only change the vanilla join message if it's different to avoid nuking client translation
if (effectiveMessage != null && !effectiveMessage.equals(message) || message != null && effectiveMessage == null) {
joinMessageConsumer.accept(effectiveMessage);
}
ess.runTaskAsynchronously(() -> ess.getServer().getPluginManager().callEvent(new AsyncUserDataLoadEvent(user, effectiveMessage)));
if (ess.getSettings().getMotdDelay() >= 0) {
final int motdDelay = ess.getSettings().getMotdDelay() / 50;
final Runnable motdTask = () -> motdFlow(user);
if (motdDelay > 0) {
pendingMotdTasks.put(user.getUUID(), ess.scheduleSyncDelayedTask(motdTask, motdDelay));
} else {
motdTask.run();
}
}
if (!ess.getSettings().isCommandDisabled("mail") && user.isAuthorized("essentials.mail")) {
if (user.getUnreadMailAmount() == 0) {
if (ess.getSettings().isNotifyNoNewMail()) {
user.sendTl("noNewMail"); // Only notify if they want us to.
}
} else {
user.notifyOfMail();
}
}
if (user.isAuthorized("essentials.updatecheck")) {
ess.runTaskAsynchronously(() -> {
for (final ComponentHolder component : ess.getUpdateChecker().getVersionMessages(false, false, user.getSource())) {
user.sendComponent(component);
}
});
}
final boolean restoreFly = user.isFlyModeEnabled() && user.isAuthorized("essentials.fly");
if (restoreFly) {
user.getBase().setAllowFlight(true);
if (ess.getSettings().isSendFlyEnableOnJoin()) {
user.sendTl("flyMode", CommonPlaceholders.enableDisable(user.getSource(), true), user.getDisplayName());
}
}
if (user.isAuthorized("essentials.fly.safelogin")) {
user.getBase().setFallDistance(0);
final boolean inWater = VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_17_R01) && user.getBase().isInWater();
if (!inWater && LocationUtil.shouldFly(ess, user.getLocation())) {
user.getBase().setAllowFlight(true);
user.getBase().setFlying(true);
if (!restoreFly && ess.getSettings().isSendFlyEnableOnJoin()) {
user.sendTl("flyMode", CommonPlaceholders.enableDisable(user.getSource(), true), user.getDisplayName());
}
}
}
if (!user.isAuthorized("essentials.speed")) {
user.getBase().setFlySpeed(0.1f);
user.getBase().setWalkSpeed(0.2f);
}
if (user.isSocialSpyEnabled() && !user.isAuthorized("essentials.socialspy")) {
user.setSocialSpyEnabled(false);
ess.getLogger().log(Level.INFO, "Set socialspy to false for {0} because they had it enabled without permission.", user.getName());
}
if (user.isFlyModeEnabled() && !user.isAuthorized("essentials.fly")) {
user.setFlyModeEnabled(false);
ess.getLogger().log(Level.INFO, "Set fly mode to false for {0} because they had it enabled without permission.", user.getName());
}
if (user.isGodModeEnabled() && !user.isAuthorized("essentials.god")) {
user.setGodModeEnabled(false);
ess.getLogger().log(Level.INFO, "Set god mode to false for {0} because they had it enabled without permission.", user.getName());
}
user.setConfirmingClearCommand(null);
user.getConfirmingPayments().clear();
user.stopTransaction();
private boolean hideJoinQuitMessages() {
return ess.getSettings().hasJoinQuitMessagePlayerCount() && ess.getServer().getOnlinePlayers().size() > ess.getSettings().getJoinQuitMessagePlayerCount();
}
private void motdFlow(final User user) {
pendingMotdTasks.remove(user.getUUID());
IText tempInput = null;
if (!ess.getSettings().isCommandDisabled("motd")) {
try {
tempInput = new TextInput(user.getSource(), "motd", true, ess);
} catch (final IOException ex) {
if (ess.getSettings().isDebug()) {
ess.getLogger().log(Level.WARNING, ex.getMessage(), ex);
} else {
ess.getLogger().log(Level.WARNING, ex.getMessage());
}
}
}
final IText input = tempInput;
if (input != null && !input.getLines().isEmpty() && user.isAuthorized("essentials.motd")) {
final IText output = new KeywordReplacer(input, user.getSource(), ess);
final TextPager pager = new TextPager(output, true);
pager.showPage("1", null, "motd", user.getSource());
}
}
private void delayedJoin(final Player player, final String message) {
public void delayedJoin(final Player player, final String message) {
if (!player.isOnline()) {
return;
}
ess.getBackup().onPlayerJoin();
final User dUser = ess.getUser(player);
((ModernUserMap) ess.getUsers()).getOnlineUserCache().put(player.getUniqueId(), dUser);
dUser.update(player);
dUser.startTransaction();
@@ -600,19 +354,170 @@ public class EssentialsPlayerListener implements Listener {
dUser.updateActivity(false, AfkStatusChangeEvent.Cause.JOIN);
dUser.stopTransaction();
ess.scheduleSyncDelayedTask(() -> {
final User user = ess.getUser(player);
class DelayJoinTask implements Runnable {
@Override
public void run() {
final User user = ess.getUser(player);
if (!user.getBase().isOnline()) {
return;
if (!user.getBase().isOnline()) {
return;
}
user.startTransaction();
final String lastAccountName = user.getLastAccountName(); // For comparison
user.setLastAccountName(user.getBase().getName());
user.setLastLogin(currentTime);
user.setDisplayNick();
updateCompass(user);
user.setLeavingHidden(false);
// Check for new username. If they don't want the message, let's just say it's false.
final boolean newUsername = ess.getSettings().isCustomNewUsernameMessage() && lastAccountName != null && !lastAccountName.equals(user.getBase().getName());
if (!ess.getVanishedPlayersNew().isEmpty() && !user.isAuthorized("essentials.vanish.see")) {
for (final String p : ess.getVanishedPlayersNew()) {
final Player toVanish = ess.getServer().getPlayerExact(p);
if (toVanish != null && toVanish.isOnline()) {
user.getBase().hidePlayer(toVanish);
if (ess.getSettings().isDebug()) {
ess.getLogger().info("Hiding vanished player: " + p);
}
}
}
}
if (user.isAuthorized("essentials.sleepingignored")) {
user.getBase().setSleepingIgnored(true);
}
final String effectiveMessage;
if (ess.getSettings().allowSilentJoinQuit() && (user.isAuthorized("essentials.silentjoin") || user.isAuthorized("essentials.silentjoin.vanish"))) {
if (user.isAuthorized("essentials.silentjoin.vanish")) {
user.setVanished(true);
}
effectiveMessage = null;
} else if (message == null || hideJoinQuitMessages()) {
effectiveMessage = null;
} else if (ess.getSettings().isCustomJoinMessage()) {
final String msg = (newUsername ? ess.getSettings().getCustomNewUsernameMessage() : ess.getSettings().getCustomJoinMessage())
.replace("{PLAYER}", player.getDisplayName()).replace("{USERNAME}", player.getName())
.replace("{UNIQUE}", NumberFormat.getInstance().format(ess.getUsers().getUserCount()))
.replace("{ONLINE}", NumberFormat.getInstance().format(ess.getOnlinePlayers().size()))
.replace("{UPTIME}", DateUtil.formatDateDiff(ManagementFactory.getRuntimeMXBean().getStartTime()))
.replace("{PREFIX}", FormatUtil.replaceFormat(ess.getPermissionsHandler().getPrefix(player)))
.replace("{SUFFIX}", FormatUtil.replaceFormat(ess.getPermissionsHandler().getSuffix(player)))
.replace("{OLDUSERNAME}", lastAccountName == null ? "" : lastAccountName);
if (!msg.isEmpty()) {
ess.getServer().broadcastMessage(msg);
}
effectiveMessage = msg.isEmpty() ? null : msg;
} else if (ess.getSettings().allowSilentJoinQuit()) {
ess.getServer().broadcastMessage(message);
effectiveMessage = message;
} else {
effectiveMessage = message;
}
ess.runTaskAsynchronously(() -> ess.getServer().getPluginManager().callEvent(new AsyncUserDataLoadEvent(user, effectiveMessage)));
if (ess.getSettings().getMotdDelay() >= 0) {
final int motdDelay = ess.getSettings().getMotdDelay() / 50;
final DelayMotdTask motdTask = new DelayMotdTask(user);
if (motdDelay > 0) {
pendingMotdTasks.put(user.getUUID(), ess.scheduleSyncDelayedTask(motdTask, motdDelay));
} else {
motdTask.run();
}
}
if (!ess.getSettings().isCommandDisabled("mail") && user.isAuthorized("essentials.mail")) {
if (user.getUnreadMailAmount() == 0) {
if (ess.getSettings().isNotifyNoNewMail()) {
user.sendTl("noNewMail"); // Only notify if they want us to.
}
} else {
user.notifyOfMail();
}
}
if (user.isAuthorized("essentials.updatecheck")) {
ess.runTaskAsynchronously(() -> {
for (final Component component : ess.getUpdateChecker().getVersionMessages(false, false, user.getSource())) {
user.sendComponent(component);
}
});
}
if (user.isAuthorized("essentials.fly.safelogin")) {
user.getBase().setFallDistance(0);
if (LocationUtil.shouldFly(ess, user.getLocation())) {
user.getBase().setAllowFlight(true);
user.getBase().setFlying(true);
if (ess.getSettings().isSendFlyEnableOnJoin()) {
user.sendTl("flyMode", CommonPlaceholders.enableDisable(user.getSource(), true), user.getDisplayName());
}
}
}
if (!user.isAuthorized("essentials.speed")) {
user.getBase().setFlySpeed(0.1f);
user.getBase().setWalkSpeed(0.2f);
}
if (user.isSocialSpyEnabled() && !user.isAuthorized("essentials.socialspy")) {
user.setSocialSpyEnabled(false);
ess.getLogger().log(Level.INFO, "Set socialspy to false for {0} because they had it enabled without permission.", user.getName());
}
if (user.isGodModeEnabled() && !user.isAuthorized("essentials.god")) {
user.setGodModeEnabled(false);
ess.getLogger().log(Level.INFO, "Set god mode to false for {0} because they had it enabled without permission.", user.getName());
}
user.setConfirmingClearCommand(null);
user.getConfirmingPayments().clear();
user.stopTransaction();
}
joinFlow(user, currentTime, message, msg -> {
if (msg != null && !msg.isEmpty()) {
ess.getServer().broadcastMessage(msg);
class DelayMotdTask implements Runnable {
private final User user;
DelayMotdTask(final User user) {
this.user = user;
}
});
});
@Override
public void run() {
pendingMotdTasks.remove(user.getUUID());
IText tempInput = null;
if (!ess.getSettings().isCommandDisabled("motd")) {
try {
tempInput = new TextInput(user.getSource(), "motd", true, ess);
} catch (final IOException ex) {
if (ess.getSettings().isDebug()) {
ess.getLogger().log(Level.WARNING, ex.getMessage(), ex);
} else {
ess.getLogger().log(Level.WARNING, ex.getMessage());
}
}
}
final IText input = tempInput;
if (input != null && !input.getLines().isEmpty() && user.isAuthorized("essentials.motd")) {
final IText output = new KeywordReplacer(input, user.getSource(), ess);
final TextPager pager = new TextPager(output, true);
pager.showPage("1", null, "motd", user.getSource());
}
}
}
}
ess.scheduleSyncDelayedTask(new DelayJoinTask());
}
// Makes the compass item ingame always point to the first essentials home. #EasterEgg
@@ -632,95 +537,38 @@ public class EssentialsPlayerListener implements Listener {
user.getBase().setCompassTarget(loc);
}
private final class LoginListenerPre1_21 implements Listener {
@EventHandler(priority = EventPriority.LOW)
public void onPlayerLoginBanned(final PlayerLoginEvent event) {
if (event.getResult() == PlayerLoginEvent.Result.KICK_BANNED) {
BanEntry banEntry = ess.getServer().getBanList(BanList.Type.NAME).getBanEntry(event.getPlayer().getName());
if (banEntry != null) {
final Date banExpiry = banEntry.getExpiration();
if (banExpiry != null) {
final String expiry = DateUtil.formatDateDiff(banExpiry.getTime());
event.setKickMessage(ess.getAdventureFacet().miniToLegacy(tlLiteral("tempbanJoin", expiry, banEntry.getReason())));
} else {
event.setKickMessage(ess.getAdventureFacet().miniToLegacy(tlLiteral("banJoin", banEntry.getReason())));
}
@EventHandler(priority = EventPriority.LOW)
public void onPlayerLoginBanned(final PlayerLoginEvent event) {
if (event.getResult() == Result.KICK_BANNED) {
BanEntry banEntry = ess.getServer().getBanList(BanList.Type.NAME).getBanEntry(event.getPlayer().getName());
if (banEntry != null) {
final Date banExpiry = banEntry.getExpiration();
if (banExpiry != null) {
final String expiry = DateUtil.formatDateDiff(banExpiry.getTime());
event.setKickMessage(AdventureUtil.miniToLegacy(tlLiteral("tempbanJoin", expiry, banEntry.getReason())));
} else {
banEntry = ess.getServer().getBanList(BanList.Type.IP).getBanEntry(event.getAddress().getHostAddress());
if (banEntry != null) {
final Date banExpiry = banEntry.getExpiration();
if (banExpiry != null) {
final String expiry = DateUtil.formatDateDiff(banExpiry.getTime());
event.setKickMessage(ess.getAdventureFacet().miniToLegacy(tlLiteral("tempbanIpJoin", expiry, banEntry.getReason())));
} else {
event.setKickMessage(ess.getAdventureFacet().miniToLegacy(tlLiteral("banIpJoin", banEntry.getReason())));
}
}
event.setKickMessage(AdventureUtil.miniToLegacy(tlLiteral("banJoin", banEntry.getReason())));
}
}
}
@EventHandler(priority = EventPriority.HIGH)
public void onPlayerLogin(final PlayerLoginEvent event) {
if (event.getResult() == PlayerLoginEvent.Result.KICK_FULL) {
final User kfuser = ess.getUser(event.getPlayer());
kfuser.update(event.getPlayer());
if (kfuser.isAuthorized("essentials.joinfullserver")) {
event.allow();
return;
}
if (ess.getSettings().isCustomServerFullMessage()) {
event.disallow(PlayerLoginEvent.Result.KICK_FULL, tlLiteral("serverFull"));
} else {
banEntry = ess.getServer().getBanList(BanList.Type.IP).getBanEntry(event.getAddress().getHostAddress());
if (banEntry != null) {
event.setKickMessage(AdventureUtil.miniToLegacy(tlLiteral("banIpJoin", banEntry.getReason())));
}
}
}
}
private final class LoginListener1_21 implements Listener {
@EventHandler(priority = EventPriority.HIGH)
public void onPlayerListFull(final PlayerServerFullCheckEvent event) {
if (ess.getPermissionsHandler().isOfflinePermissionSet(event.getPlayerProfile().getId(), "essentials.joinfullserver")) {
event.allow(true);
@EventHandler(priority = EventPriority.HIGH)
public void onPlayerLogin(final PlayerLoginEvent event) {
if (event.getResult() == Result.KICK_FULL) {
final User kfuser = ess.getUser(event.getPlayer());
kfuser.update(event.getPlayer());
if (kfuser.isAuthorized("essentials.joinfullserver")) {
event.allow();
return;
}
if (!event.isAllowed() && ess.getSettings().isCustomServerFullMessage()) {
PaperAdventureSmuggler.smugglePlayerServerFullCheckEvent(event, ess.getAdventureFacet().miniToLegacy(tlLiteral("serverFull")));
}
}
@EventHandler(priority = EventPriority.LOW)
public void onPlayerKickBanned(final AsyncPlayerPreLoginEvent event) {
if (event.getLoginResult() == AsyncPlayerPreLoginEvent.Result.KICK_BANNED) {
BanEntry<?> banEntry = ess.getServer().getBanList(BanListType.PROFILE).getBanEntry(event.getPlayerProfile());
if (banEntry != null) {
final Date banExpiry = banEntry.getExpiration();
if (banExpiry != null) {
final String expiry = DateUtil.formatDateDiff(banExpiry.getTime());
event.setKickMessage(ess.getAdventureFacet().miniToLegacy(tlLiteral("tempbanJoin", expiry, banEntry.getReason())));
} else {
event.setKickMessage(ess.getAdventureFacet().miniToLegacy(tlLiteral("banJoin", banEntry.getReason())));
}
} else {
banEntry = ess.getServer().getBanList(BanListType.IP).getBanEntry(event.getAddress());
if (banEntry != null) {
final Date banExpiry = banEntry.getExpiration();
if (banExpiry != null) {
final String expiry = DateUtil.formatDateDiff(banExpiry.getTime());
event.setKickMessage(ess.getAdventureFacet().miniToLegacy(tlLiteral("tempbanIpJoin", expiry, banEntry.getReason())));
} else {
event.setKickMessage(ess.getAdventureFacet().miniToLegacy(tlLiteral("banIpJoin", banEntry.getReason())));
}
}
}
} else if (event.getLoginResult() == AsyncPlayerPreLoginEvent.Result.KICK_WHITELIST) {
if (ess.getPermissionsHandler().isOfflinePermissionSet(event.getUniqueId(), "essentials.whitelist.bypass")) {
event.allow();
return;
}
if (ess.getSettings().isCustomWhitelistMessage()) {
event.setKickMessage(ess.getAdventureFacet().miniToLegacy(tlLiteral("whitelistKick")));
}
if (ess.getSettings().isCustomServerFullMessage()) {
event.disallow(Result.KICK_FULL, tlLiteral("serverFull"));
}
}
}
@@ -738,21 +586,6 @@ public class EssentialsPlayerListener implements Listener {
if (ess.getSettings().isTeleportInvulnerability()) {
user.enableInvulnerabilityAfterTeleport();
}
// Mitigation for https://github.com/EssentialsX/Essentials/issues/4325
final TickCountProvider tickCountProvider = ess.provider(TickCountProvider.class);
if (tickCountProvider != null && ess.getSettings().isWorldChangePreserveFlying() && VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_17_R01)) {
if (user.isAuthorized("essentials.fly")) {
//noinspection DataFlowIssue - not real
if (event.getFrom().getWorld() != event.getTo().getWorld() && player.getAllowFlight()) {
// If the player is not flying but has the ability to fly, we set the sign of the tick count to -1
// Later on in the PlayerChangedWorldEvent, we will set the player's flying state to true if the tick count is positive.
// If the tick count is negative, we simply just set the player's flight ability to true.
final int tick = player.isFlying() ? tickCountProvider.getTickCount() : -tickCountProvider.getTickCount();
user.setFlightTick(tick);
}
}
}
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
@@ -776,17 +609,17 @@ public class EssentialsPlayerListener implements Listener {
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onPlayerCommandPreprocess(final PlayerCommandPreprocessEvent event) {
final String cmd = event.getMessage().split(" ")[0].replace("/", "").toLowerCase(Locale.ENGLISH);
final String cmd = event.getMessage().toLowerCase(Locale.ENGLISH).split(" ")[0].replace("/", "").toLowerCase(Locale.ENGLISH);
final int argStartIndex = event.getMessage().indexOf(" ");
final String args = argStartIndex == -1 ? "" // No arguments present
: event.getMessage().substring(argStartIndex); // arguments start at argStartIndex; substring from there.
// If the plugin command does not exist, check if it is an alias from commands.yml
if (ess.getServer().getPluginCommand(cmd) == null) {
final Command knownCommand = ess.provider(KnownCommandsProvider.class).getKnownCommands().get(cmd);
final Command knownCommand = ess.getKnownCommandsProvider().getKnownCommands().get(cmd);
if (knownCommand instanceof FormattedCommandAlias) {
final FormattedCommandAlias command = (FormattedCommandAlias) knownCommand;
for (String fullCommand : ess.provider(FormattedCommandAliasProvider.class).createCommands(command, event.getPlayer(), args.split(" "))) {
for (String fullCommand : ess.getFormattedCommandAliasProvider().createCommands(command, event.getPlayer(), args.split(" "))) {
handlePlayerCommandPreprocess(event, fullCommand);
}
return;
@@ -799,23 +632,21 @@ public class EssentialsPlayerListener implements Listener {
public void handlePlayerCommandPreprocess(final PlayerCommandPreprocessEvent event, final String effectiveCommand) {
final Player player = event.getPlayer();
final String cmd = effectiveCommand.split(" ")[0].replace("/", "").toLowerCase(Locale.ENGLISH);
final String cmd = effectiveCommand.toLowerCase(Locale.ENGLISH).split(" ")[0].replace("/", "").toLowerCase(Locale.ENGLISH);
final PluginCommand pluginCommand = ess.getServer().getPluginCommand(cmd);
if (ess.getSettings().getSocialSpyCommands().contains(cmd) || ess.getSettings().getSocialSpyCommands().contains("*")) {
if (pluginCommand == null
|| !pluginCommand.getName().equals("msg") && !pluginCommand.getName().equals("r")) { // /msg and /r are handled in SimpleMessageRecipient
|| (!pluginCommand.getName().equals("msg") && !pluginCommand.getName().equals("r"))) { // /msg and /r are handled in SimpleMessageRecipient
final User user = ess.getUser(player);
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 ComponentHolder base = (user.isMuted() && ess.getSettings().getSocialSpyListenMutedPlayers())
final Component base = (user.isMuted() && ess.getSettings().getSocialSpyListenMutedPlayers())
? spyer.tlComponent("socialSpyMutedPrefix")
: spyer.tlComponent("socialSpyPrefix");
final ComponentHolder formatted = ess.getAdventureFacet().deserializeMiniMessage(spyer.playerTl("socialSpyCmdFormat", playerName, event.getMessage()));
spyer.sendComponent(ess.getAdventureFacet().append(base, formatted));
spyer.sendComponent(base.append(AdventureUtil.legacyToAdventure(playerName)).append(Component.text(": " + event.getMessage())));
}
}
}
@@ -839,7 +670,7 @@ public class EssentialsPlayerListener implements Listener {
user.sendTl("voiceSilencedTime", dateDiff);
}
}
ess.getLogger().info(ess.getAdventureFacet().miniToLegacy(tlLiteral("mutedUserSpeaks", player.getName(), event.getMessage())));
ess.getLogger().info(AdventureUtil.miniToLegacy(tlLiteral("mutedUserSpeaks", player.getName(), event.getMessage())));
return;
}
@@ -874,17 +705,21 @@ public class EssentialsPlayerListener implements Listener {
// If so, no need to check for (and write) new ones.
boolean cooldownFound = false;
for (final Entry<Pattern, Long> entry : user.getCommandCooldowns().entrySet()) {
// Iterate over a copy of getCommandCooldowns in case of concurrent modifications
for (final Entry<Pattern, Long> entry : new HashMap<>(user.getCommandCooldowns()).entrySet()) {
// Remove any expired cooldowns
if (entry.getValue() <= System.currentTimeMillis()) {
user.clearCommandCooldown(entry.getKey());
// Don't break in case there are other command cooldowns left to clear.
} else if (entry.getKey().matcher(fullCommand).matches()) {
// User's current cooldown hasn't expired, inform and terminate cooldown code.
final String commandCooldownTime = DateUtil.formatDateDiff(entry.getValue());
user.sendTl("commandCooldown", commandCooldownTime);
cooldownFound = true;
event.setCancelled(true);
if (entry.getValue() > System.currentTimeMillis()) {
final String commandCooldownTime = DateUtil.formatDateDiff(entry.getValue());
user.sendTl("commandCooldown", commandCooldownTime);
cooldownFound = true;
event.setCancelled(true);
break;
}
}
}
@@ -908,7 +743,8 @@ public class EssentialsPlayerListener implements Listener {
if (ess.getSettings().isWorldChangeFlyResetEnabled()) {
if (user.getBase().getGameMode() != GameMode.CREATIVE
&& user.getBase().getGameMode() != GameMode.SPECTATOR
// COMPAT: String compare for 1.7.10
&& !user.getBase().getGameMode().name().equals("SPECTATOR")
&& !user.isAuthorized("essentials.fly")) {
user.getBase().setFallDistance(0f);
user.getBase().setAllowFlight(false);
@@ -931,16 +767,6 @@ public class EssentialsPlayerListener implements Listener {
}
}
}
final TickCountProvider tickCountProvider = ess.provider(TickCountProvider.class);
final int flightTick = user.getFlightTick();
if (tickCountProvider != null && Math.abs(flightTick) == tickCountProvider.getTickCount() && user.isAuthorized("essentials.fly")) {
user.getBase().setAllowFlight(true);
if (flightTick > 0) {
user.getBase().setFlying(true);
}
}
user.setFlightTick(-1);
}
@EventHandler(priority = EventPriority.MONITOR)
@@ -1071,15 +897,14 @@ public class EssentialsPlayerListener implements Listener {
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onInventoryClickEvent(final InventoryClickEvent event) {
Player refreshPlayer = null;
final InventoryViewProvider provider = ess.provider(InventoryViewProvider.class);
final Inventory top = provider.getTopInventory(event.getView());
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 : provider.getBottomInventory(event.getView());
clickedInventory = event.getRawSlot() < top.getSize() ? top : ess.getInventoryViewProvider().getBottomInventory(event.getView());
}
final User user = ess.getUser((Player) event.getWhoClicked());
@@ -1135,31 +960,10 @@ public class EssentialsPlayerListener implements Listener {
return false;
}
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onInventoryDragEvent(final InventoryDragEvent event) {
final InventoryViewProvider provider = ess.provider(InventoryViewProvider.class);
final Inventory top = provider.getTopInventory(event.getView());
if (top.getType() != InventoryType.PLAYER) {
return;
}
final User user = ess.getUser((Player) event.getWhoClicked());
if (!user.isInvSee()) {
return;
}
for (int slot : event.getNewItems().keySet()) {
if (Inventories.isBottomInventorySlot(slot)) {
event.setCancelled(true);
break;
}
}
}
@EventHandler(priority = EventPriority.MONITOR)
public void onInventoryCloseEvent(final InventoryCloseEvent event) {
Player refreshPlayer = null;
final InventoryViewProvider provider = ess.provider(InventoryViewProvider.class);
final Inventory top = provider.getTopInventory(event.getView());
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());
@@ -1173,7 +977,7 @@ public class EssentialsPlayerListener implements Listener {
final User user = ess.getUser((Player) event.getPlayer());
if (user.isRecipeSee()) {
user.setRecipeSee(false);
provider.getTopInventory(event.getView()).clear();
ess.getInventoryViewProvider().getTopInventory(event.getView()).clear();
refreshPlayer = user.getBase();
}
} else if (type == InventoryType.CHEST && top.getSize() == 9) {
@@ -1192,35 +996,10 @@ public class EssentialsPlayerListener implements Listener {
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onPlayerFishEvent(final PlayerFishEvent event) {
if (!ess.getSettings().cancelAfkOnFish()) {
return;
}
final User user = ess.getUser(event.getPlayer());
user.updateActivityOnInteract(true);
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onPlayerGameModeChange(final PlayerGameModeChangeEvent event) {
if (!ess.getSettings().isGamemodeChangePreserveFlying()) {
return;
}
final User user = ess.getUser(event.getPlayer());
if (!user.isAuthorized("essentials.fly")) {
return;
}
final Player player = event.getPlayer();
if (player.isFlying() && player.getAllowFlight() && user.isAuthorized("essentials.fly")) {
// The gamemode change happens after the event, so we need to delay the flight enable
ess.scheduleSyncDelayedTask(() -> {
player.setAllowFlight(true);
player.setFlying(true);
}, 1);
}
}
private static final class ArrowPickupListener implements Listener {
@EventHandler(priority = EventPriority.LOW)
public void onArrowPickup(final org.bukkit.event.player.PlayerPickupArrowEvent event) {
@@ -1235,12 +1014,10 @@ public class EssentialsPlayerListener implements Listener {
public void onPlayerPickupItem(final org.bukkit.event.player.PlayerPickupItemEvent event) {
if (event.getItem().hasMetadata(Commandfireball.FIREBALL_META_KEY)) {
event.setCancelled(true);
return;
}
final User user = ess.getUser(event.getPlayer());
if ((ess.getSettings().getDisableItemPickupWhileAfk() && user.isAfk())
|| (user.isVanished() && !user.isAuthorizedCached("essentials.vanish.pickup"))) {
event.setCancelled(true);
} else if (ess.getSettings().getDisableItemPickupWhileAfk()) {
if (ess.getUser(event.getPlayer()).isAfk()) {
event.setCancelled(true);
}
}
}
}
@@ -1248,10 +1025,8 @@ public class EssentialsPlayerListener implements Listener {
private final class PickupListener1_12 implements Listener {
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onPlayerPickupItem(final org.bukkit.event.entity.EntityPickupItemEvent event) {
if (event.getEntity() instanceof Player) {
final User user = ess.getUser((Player) event.getEntity());
if ((ess.getSettings().getDisableItemPickupWhileAfk() && user.isAfk())
|| (user.isVanished() && !user.isAuthorizedCached("essentials.vanish.pickup"))) {
if (ess.getSettings().getDisableItemPickupWhileAfk() && event.getEntity() instanceof Player) {
if (ess.getUser((Player) event.getEntity()).isAfk()) {
event.setCancelled(true);
}
}
@@ -1270,10 +1045,6 @@ public class EssentialsPlayerListener implements Listener {
private final class CommandSendFilter implements CommandSendListenerProvider.Filter {
@Override
public Predicate<String> apply(Player player) {
// There is no event for op status changes, but the command list is resent when
// a player is opped/deopped, so we invalidate cached permissions here.
ess.getPermissionsHandler().invalidatePermissionCache(player.getUniqueId());
final User user = ess.getUser(player);
final Set<PluginCommand> checked = new HashSet<>();
final Set<PluginCommand> toRemove = new HashSet<>();
@@ -1304,7 +1075,12 @@ public class EssentialsPlayerListener implements Listener {
return command != null
&& (command.getPlugin() == ess || command.getPlugin().getClass().getName().startsWith("com.earth2me.essentials") || command.getPlugin().getClass().getName().startsWith("net.essentialsx"))
&& (ess.getSettings().isCommandOverridden(label) || ess.getAlternativeCommandsHandler().getAlternative(label) == null);
&& (ess.getSettings().isCommandOverridden(label) || (ess.getAlternativeCommandsHandler().getAlternative(label) == null));
}
}
@Override
public void getUser(Player player) {
ess.getUser(player);
}
}
@@ -3,9 +3,9 @@ package com.earth2me.essentials;
import com.earth2me.essentials.config.ConfigurateUtil;
import com.earth2me.essentials.config.EssentialsConfiguration;
import com.earth2me.essentials.config.EssentialsUserConfiguration;
import com.earth2me.essentials.config.entities.LazyLocation;
import com.earth2me.essentials.craftbukkit.BanLookup;
import com.earth2me.essentials.userstorage.ModernUUIDCache;
import com.earth2me.essentials.utils.AdventureUtil;
import com.earth2me.essentials.utils.StringUtil;
import com.google.common.base.Charsets;
import com.google.common.io.Files;
@@ -71,7 +71,7 @@ public class EssentialsUpgrade {
doneFile.load();
}
private static void uuidFileConvert(final IEssentials ess, final Boolean ignoreUFCache) {
public static void uuidFileConvert(final IEssentials ess, final Boolean ignoreUFCache) {
ess.getLogger().info("Starting Essentials UUID userdata conversion");
final File userdir = new File(ess.getDataFolder(), "userdata");
@@ -156,42 +156,7 @@ public class EssentialsUpgrade {
ess.getLogger().info("To rerun the conversion type /essentials uuidconvert");
}
private void updateRandomTeleport() {
if (doneFile.getBoolean("updateRandomTeleport", false)) {
return;
}
final EssentialsConfiguration config = ess.getRandomTeleport().getConfig();
if (config.getRootNode() != null) {
final LazyLocation center = config.getLocation("center");
final Location centerLoc = center != null ? center.location() : null;
if (center != null && centerLoc != null) {
final double minRange = config.getDouble("min-range", Double.MIN_VALUE);
final double maxRange = config.getDouble("max-range", Double.MIN_VALUE);
for (final World world : ess.getServer().getWorlds()) {
final String propPrefix = "locations." + world.getName() + ".";
config.setProperty(propPrefix + "center", centerLoc);
if (minRange != Double.MIN_VALUE) {
config.setProperty(propPrefix + "min-range", minRange);
}
if (maxRange != Double.MIN_VALUE) {
config.setProperty(propPrefix + "max-range", maxRange);
}
}
}
config.removeProperty("center");
config.blockingSave();
}
doneFile.setProperty("updateRandomTeleport", true);
doneFile.save();
ess.getLogger().info("Done converting random teleport config.");
}
private void convertMailList() {
public void convertMailList() {
if (doneFile.getBoolean("updateUsersMailList", false)) {
return;
}
@@ -231,7 +196,7 @@ public class EssentialsUpgrade {
ess.getLogger().info("Done converting mail list.");
}
private void convertStupidCamelCaseUserdataKeys() {
public void convertStupidCamelCaseUserdataKeys() {
if (doneFile.getBoolean("updateUsersStupidLegacyPathNames", false)) {
return;
}
@@ -311,7 +276,7 @@ public class EssentialsUpgrade {
* horrible economy code, as any operation which loads all user data into memory will load all these NPC accounts
* and spam the console with warnings."
*/
private void purgeBrokenNpcAccounts() {
public void purgeBrokenNpcAccounts() {
if (doneFile.getBoolean("updatePurgeBrokenNpcAccounts", false)) {
return;
}
@@ -422,7 +387,7 @@ public class EssentialsUpgrade {
ess.getLogger().info("#===========================================================================#");
}
private void convertIgnoreList() {
public void convertIgnoreList() {
final Pattern pattern = Pattern.compile("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$");
if (doneFile.getBoolean("updateUsersIgnoreListUUID", false)) {
return;
@@ -473,10 +438,6 @@ public class EssentialsUpgrade {
}
public void convertKits() {
if (Essentials.TESTING) {
return;
}
final Kits kits = ess.getKits();
final EssentialsConfiguration config = kits.getRootConfig();
if (doneFile.getBoolean("kitsyml", false)) {
@@ -534,7 +495,7 @@ public class EssentialsUpgrade {
doneFile.setProperty("move" + name + "ToFile", true);
doneFile.save();
} catch (final IOException e) {
ess.getLogger().log(Level.SEVERE, ess.getAdventureFacet().miniToLegacy(tlLiteral("upgradingFilesError")), e);
ess.getLogger().log(Level.SEVERE, AdventureUtil.miniToLegacy(tlLiteral("upgradingFilesError")), e);
}
}
@@ -697,15 +658,15 @@ public class EssentialsUpgrade {
final File tmpFile = new File(listOfFile.getParentFile(), sanitizedFilename + ".tmp");
final File newFile = new File(listOfFile.getParentFile(), sanitizedFilename);
if (!listOfFile.renameTo(tmpFile)) {
ess.getLogger().log(Level.WARNING, ess.getAdventureFacet().miniToLegacy(tlLiteral("userdataMoveError", filename, sanitizedFilename)));
ess.getLogger().log(Level.WARNING, AdventureUtil.miniToLegacy(tlLiteral("userdataMoveError", filename, sanitizedFilename)));
continue;
}
if (newFile.exists()) {
ess.getLogger().log(Level.WARNING, ess.getAdventureFacet().miniToLegacy(tlLiteral("duplicatedUserdata", filename, sanitizedFilename)));
ess.getLogger().log(Level.WARNING, AdventureUtil.miniToLegacy(tlLiteral("duplicatedUserdata", filename, sanitizedFilename)));
continue;
}
if (!tmpFile.renameTo(newFile)) {
ess.getLogger().log(Level.WARNING, ess.getAdventureFacet().miniToLegacy(tlLiteral("userdataMoveBackError", sanitizedFilename, sanitizedFilename)));
ess.getLogger().log(Level.WARNING, AdventureUtil.miniToLegacy(tlLiteral("userdataMoveBackError", sanitizedFilename, sanitizedFilename)));
}
}
doneFile.setProperty("sanitizeAllUserFilenames", true);
@@ -721,7 +682,7 @@ public class EssentialsUpgrade {
return null;
}
private Location getFakeLocation(final CommentedConfigurationNode config, final String path) {
public Location getFakeLocation(final CommentedConfigurationNode config, final String path) {
final String worldName = config.getString((path != null ? path + "." : "") + "world");
if (worldName == null || worldName.isEmpty()) {
return null;
@@ -885,7 +846,7 @@ public class EssentialsUpgrade {
doneFile.save();
}
private void banFormatChange() {
public void banFormatChange() {
if (doneFile.getBoolean("banFormatChange", false)) {
return;
}
@@ -955,7 +916,7 @@ public class EssentialsUpgrade {
Bukkit.getBanList(BanList.Type.NAME).addBan(playerName, banReason, banTimeout == 0 ? null : new Date(banTimeout), Console.NAME);
}
private void generateUidCache() {
public void generateUidCache() {
if (doneFile.getBoolean("newUidCacheBuilt", false)) {
return;
}
@@ -995,7 +956,7 @@ public class EssentialsUpgrade {
if (name != null) {
if (nameToUuidMap.containsKey(name)) {
final UUID oldUuid = nameToUuidMap.get(name);
if (oldUuid.version() < uuid.version() || oldUuid.version() == uuid.version() && uuids.get(oldUuid) < time) {
if (oldUuid.version() < uuid.version() || (oldUuid.version() == uuid.version() && uuids.get(oldUuid) < time)) {
ess.getLogger().warning("New UUID found for " + name + ": " + uuid + " (old: " + oldUuid + "). Replacing.");
uuids.remove(oldUuid);
} else {
@@ -1063,7 +1024,7 @@ public class EssentialsUpgrade {
properties.load(Files.newReader(backup, Charsets.UTF_8));
for (final String key : properties.stringPropertyNames()) {
final String value = properties.getProperty(key);
properties.setProperty(key, ess.getAdventureFacet().legacyToMini(ess.getAdventureFacet().escapeTags(value), true));
properties.setProperty(key, AdventureUtil.legacyToMini(AdventureUtil.miniMessage().escapeTags(value), true));
}
properties.store(Files.newWriter(newFile, Charsets.UTF_8), null);
}
@@ -1082,10 +1043,6 @@ public class EssentialsUpgrade {
}
public void beforeSettings() {
if (Essentials.TESTING) {
return;
}
if (!ess.getDataFolder().exists()) {
ess.getDataFolder().mkdirs();
}
@@ -1094,17 +1051,10 @@ public class EssentialsUpgrade {
}
public void preModules() {
if (Essentials.TESTING) {
return;
}
generateUidCache();
}
public void afterSettings() {
if (Essentials.TESTING) {
return;
}
sanitizeAllUserFilenames();
updateUsersPowerToolsFormat();
updateUsersHomesFormat();
@@ -1118,6 +1068,5 @@ public class EssentialsUpgrade {
convertStupidCamelCaseUserdataKeys();
convertMailList();
purgeBrokenNpcAccounts();
updateRandomTeleport();
}
}
@@ -1,6 +1,6 @@
package com.earth2me.essentials;
import com.earth2me.essentials.adventure.AdventureUtil;
import com.earth2me.essentials.utils.AdventureUtil;
import net.ess3.api.IEssentials;
import org.jetbrains.annotations.NotNull;
@@ -92,7 +92,7 @@ public class I18n implements net.ess3.api.II18n {
if (objects.length == 0) {
return NODOUBLEMARK.matcher(instance.translate(locale, tlKey)).replaceAll("'");
} else {
return instance.format(locale, tlKey, objects);
return instance.format(tlKey, objects);
}
}
@@ -125,7 +125,18 @@ public class I18n implements net.ess3.api.II18n {
if (!loadingBundles.contains(locale)) {
loadingBundles.add(locale);
BUNDLE_LOADER_EXECUTOR.submit(() -> {
blockingLoadBundle(locale);
ResourceBundle bundle;
try {
bundle = ResourceBundle.getBundle(MESSAGES, locale, new FileResClassLoader(I18n.class.getClassLoader(), ess), new UTF8PropertiesControl());
} catch (MissingResourceException ex) {
try {
bundle = ResourceBundle.getBundle(MESSAGES, locale, new UTF8PropertiesControl());
} catch (MissingResourceException ex2) {
bundle = NULL_BUNDLE;
}
}
loadedBundles.put(locale, bundle);
synchronized (loadingBundles) {
loadingBundles.remove(locale);
}
@@ -136,23 +147,6 @@ public class I18n implements net.ess3.api.II18n {
}
}
public void blockingLoadBundle(final Locale locale) {
if (!loadedBundles.containsKey(locale)) {
ResourceBundle bundle;
try {
bundle = ResourceBundle.getBundle(MESSAGES, locale, new FileResClassLoader(I18n.class.getClassLoader(), ess), new UTF8PropertiesControl());
} catch (MissingResourceException ex) {
try {
bundle = ResourceBundle.getBundle(MESSAGES, locale, new UTF8PropertiesControl());
} catch (MissingResourceException ex2) {
bundle = NULL_BUNDLE;
}
}
loadedBundles.put(locale, bundle);
}
}
private String translate(final Locale locale, final String string) {
try {
try {
@@ -168,6 +162,10 @@ public class I18n implements net.ess3.api.II18n {
}
}
private String format(final String string, final Object... objects) {
return format(currentLocale, string, objects);
}
private String format(final Locale locale, final String string, final Object... objects) {
String format = translate(locale, string);
@@ -187,7 +185,7 @@ public class I18n implements net.ess3.api.II18n {
if (arg instanceof AdventureUtil.ParsedPlaceholder) {
return arg.toString();
}
return ess.getAdventureFacet().legacyToMini(ess.getAdventureFacet().escapeTags(arg.toString()));
return AdventureUtil.legacyToMini(AdventureUtil.miniMessage().escapeTags(arg.toString()));
});
return messageFormat.format(processedArgs).replace(' ', ' '); // replace nbsp with a space
@@ -283,7 +281,7 @@ public class I18n implements net.ess3.api.II18n {
* Reads .properties files as UTF-8 instead of ISO-8859-1, which is the default on Java 8/below.
* Java 9 fixes this by defaulting to UTF-8 for .properties files.
*/
private static final class UTF8PropertiesControl extends ResourceBundle.Control {
private static class UTF8PropertiesControl extends ResourceBundle.Control {
public ResourceBundle newBundle(final String baseName, final Locale locale, final String format, final ClassLoader loader, final boolean reload) throws IOException {
final String resourceName = toResourceName(toBundleName(baseName, locale), "properties");
ResourceBundle bundle = null;
@@ -1,6 +1,5 @@
package com.earth2me.essentials;
import com.earth2me.essentials.adventure.AdventureFacet;
import com.earth2me.essentials.api.IItemDb;
import com.earth2me.essentials.api.IJails;
import com.earth2me.essentials.api.IWarps;
@@ -9,7 +8,25 @@ import com.earth2me.essentials.commands.PlayerNotFoundException;
import com.earth2me.essentials.perm.PermissionsHandler;
import com.earth2me.essentials.updatecheck.UpdateChecker;
import com.earth2me.essentials.userstorage.IUserMap;
import net.ess3.provider.Provider;
import net.ess3.nms.refl.providers.ReflOnlineModeProvider;
import net.ess3.provider.BannerDataProvider;
import net.ess3.provider.BiomeKeyProvider;
import net.ess3.provider.ContainerProvider;
import net.ess3.provider.DamageEventProvider;
import net.ess3.provider.FormattedCommandAliasProvider;
import net.ess3.provider.InventoryViewProvider;
import net.ess3.provider.ItemUnbreakableProvider;
import net.ess3.provider.KnownCommandsProvider;
import net.ess3.provider.MaterialTagProvider;
import net.ess3.provider.PersistentDataProvider;
import net.ess3.provider.PlayerLocaleProvider;
import net.ess3.provider.SerializationProvider;
import net.ess3.provider.ServerStateProvider;
import net.ess3.provider.SignDataProvider;
import net.ess3.provider.SpawnerBlockProvider;
import net.ess3.provider.SpawnerItemProvider;
import net.ess3.provider.SyncCommandsProvider;
import net.ess3.provider.WorldInfoProvider;
import net.essentialsx.api.v2.services.BalanceTop;
import net.essentialsx.api.v2.services.mail.MailService;
import org.bukkit.Server;
@@ -82,8 +99,6 @@ public interface IEssentials extends Plugin {
BukkitScheduler getScheduler();
List<Player> getJailedPlayers();
IJails getJails();
IWarps getWarps();
@@ -142,13 +157,43 @@ public interface IEssentials extends Plugin {
Iterable<User> getOnlineUsers();
SpawnerItemProvider getSpawnerItemProvider();
SpawnerBlockProvider getSpawnerBlockProvider();
ServerStateProvider getServerStateProvider();
MaterialTagProvider getMaterialTagProvider();
ContainerProvider getContainerProvider();
KnownCommandsProvider getKnownCommandsProvider();
SerializationProvider getSerializationProvider();
FormattedCommandAliasProvider getFormattedCommandAliasProvider();
SyncCommandsProvider getSyncCommandsProvider();
PersistentDataProvider getPersistentDataProvider();
ReflOnlineModeProvider getOnlineModeProvider();
ItemUnbreakableProvider getItemUnbreakableProvider();
WorldInfoProvider getWorldInfoProvider();
SignDataProvider getSignDataProvider();
PlayerLocaleProvider getPlayerLocaleProvider();
DamageEventProvider getDamageEventProvider();
BiomeKeyProvider getBiomeKeyProvider();
BannerDataProvider getBannerDataProvider();
InventoryViewProvider getInventoryViewProvider();
PluginCommand getPluginCommand(String cmd);
ProviderFactory getProviders();
default <P extends Provider> P provider(final Class<P> providerClass) {
return getProviders().get(providerClass);
}
AdventureFacet getAdventureFacet();
}
@@ -3,7 +3,7 @@ package com.earth2me.essentials;
import com.earth2me.essentials.commands.IEssentialsCommand;
import com.earth2me.essentials.signs.EssentialsSign;
import com.earth2me.essentials.textreader.IText;
import net.essentialsx.api.v2.ChatType;
import net.kyori.adventure.text.minimessage.tag.Tag;
import org.bukkit.Material;
import org.bukkit.event.EventPriority;
import org.spongepowered.configurate.CommentedConfigurationNode;
@@ -37,8 +37,6 @@ public interface ISettings extends IConf {
String getChatFormat(String group);
String getChatFormat(String group, ChatType chatType);
String getWorldAlias(String world);
int getChatRadius();
@@ -55,8 +53,6 @@ public interface ISettings extends IConf {
boolean isChatQuestionEnabled();
boolean isUsePaperChatEvent();
BigDecimal getCommandCost(IEssentialsCommand cmd);
BigDecimal getCommandCost(String label);
@@ -94,8 +90,6 @@ public interface ISettings extends IConf {
String getNicknamePrefix();
boolean isResetNickOnNameChange();
String getOperatorColor() throws Exception;
boolean getPerWarpPermission();
@@ -106,18 +100,12 @@ public interface ISettings extends IConf {
List<Material> getProtectList(final String configName);
List<String> getProtectListRaw(final String configName);
boolean getProtectPreventSpawn(final String creatureName);
String getProtectString(final String configName);
boolean getRespawnAtHome();
String getRandomSpawnLocation();
String getRandomRespawnLocation();
boolean isRespawnAtAnchor();
Set getMultipleHomes();
@@ -185,8 +173,6 @@ public interface ISettings extends IConf {
boolean isEcoLogEnabled();
boolean isEcoLogUUIDEnabled();
boolean isEcoLogUpdateEnabled();
boolean realNamesOnList();
@@ -211,9 +197,7 @@ public interface ISettings extends IConf {
long getAutoAfk();
long getAutoAfkTimeout();
List<String> getAfkTimeoutCommands();
long getAutoAfkKick();
boolean getFreezeAfkPlayers();
@@ -223,8 +207,6 @@ public interface ISettings extends IConf {
boolean cancelAfkOnChat();
boolean cancelAfkOnFish();
boolean sleepIgnoresAfkPlayers();
boolean sleepIgnoresVanishedPlayers();
@@ -323,8 +305,6 @@ public interface ISettings extends IConf {
boolean isCustomServerFullMessage();
boolean isCustomWhitelistMessage();
boolean isNotifyNoNewMail();
boolean isDropItemsIfFull();
@@ -357,10 +337,6 @@ public interface ISettings extends IConf {
boolean isWorldChangeFlyResetEnabled();
boolean isWorldChangePreserveFlying();
boolean isGamemodeChangePreserveFlying();
boolean isWorldChangeSpeedResetEnabled();
long getCommandCooldownMs(String label);
@@ -417,8 +393,6 @@ public interface ISettings extends IConf {
boolean logCommandBlockCommands();
boolean logConsoleCommands();
Set<Predicate<String>> getNickBlacklist();
double getMaxProjectileSpeed();
@@ -437,21 +411,11 @@ public interface ISettings extends IConf {
boolean showZeroBaltop();
String getNickRegex();
BigDecimal getMultiplier(final User user);
int getMaxItemLore();
String getPrimaryColor();
Tag getPrimaryColor();
String getSecondaryColor();
BigDecimal getBaltopMinBalance();
long getBaltopMinPlaytime();
int getBaltopEntryLimit();
Tag getSecondaryColor();
enum KeepInvPolicy {
KEEP,
@@ -1,13 +1,15 @@
package com.earth2me.essentials;
import com.earth2me.essentials.adventure.ComponentHolder;
import com.earth2me.essentials.api.IAsyncTeleport;
import com.earth2me.essentials.commands.IEssentialsCommand;
import com.earth2me.essentials.config.entities.CommandCooldown;
import net.ess3.api.ITeleport;
import net.ess3.api.MaxMoneyException;
import net.ess3.api.events.AfkStatusChangeEvent;
import net.essentialsx.api.v2.services.mail.MailMessage;
import net.essentialsx.api.v2.services.mail.MailSender;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.ComponentLike;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
@@ -32,8 +34,6 @@ import java.util.regex.Pattern;
public interface IUser {
boolean isAuthorized(String node);
boolean isAuthorizedCached(String node);
boolean isAuthorized(IEssentialsCommand cmd);
boolean isAuthorized(IEssentialsCommand cmd, String permissionPrefix);
@@ -70,9 +70,13 @@ public interface IUser {
* @return whether there is a teleport request
*/
@Deprecated
default boolean hasOutstandingTeleportRequest() {
return getNextTpaRequest(false, false, false) != null;
}
boolean hasOutstandingTeleportRequest();
/**
* @deprecated This API is not asynchronous. Use {@link com.earth2me.essentials.api.IAsyncTeleport IAsyncTeleport} with {@link IUser#getAsyncTeleport()}
*/
@Deprecated
ITeleport getTeleport();
IAsyncTeleport getAsyncTeleport();
@@ -139,9 +143,9 @@ public interface IUser {
void sendMessage(String message);
void sendComponent(ComponentHolder component);
void sendComponent(ComponentLike component);
ComponentHolder tlComponent(String tlKey, Object... args);
Component tlComponent(String tlKey, Object... args);
String playerTl(String tlKey, Object... args);
@@ -178,17 +182,6 @@ public interface IUser {
String getFormattedJailTime();
/**
* Returns last activity time.
* <p>
* It is used internally to determine if user's afk status should be set to
* true because of ACTIVITY {@link AfkStatusChangeEvent.Cause}, or the player
* should be kicked for being afk too long.
*
* @return Last activity time (Epoch Milliseconds)
*/
long getLastActivityTime();
@Deprecated
List<String> getMails();
@@ -3,6 +3,7 @@ package com.earth2me.essentials;
import com.earth2me.essentials.config.ConfigurateUtil;
import com.earth2me.essentials.config.EssentialsConfiguration;
import com.earth2me.essentials.config.entities.LazyLocation;
import com.earth2me.essentials.utils.AdventureUtil;
import net.ess3.api.IEssentials;
import net.ess3.api.IUser;
import net.ess3.api.TranslatableException;
@@ -39,7 +40,7 @@ import java.util.logging.Level;
import static com.earth2me.essentials.I18n.tlLiteral;
public class Jails implements net.ess3.api.IJails {
private static boolean enabled = false;
private static transient boolean enabled = false;
private final IEssentials ess;
private final EssentialsConfiguration config;
private final Map<String, LazyLocation> jails = new HashMap<>();
@@ -141,6 +142,28 @@ public class Jails implements net.ess3.api.IJails {
}
}
/**
* @deprecated This method does not use asynchronous teleportation. Use {@link Jails#sendToJail(IUser, String, CompletableFuture)}
*/
@SuppressWarnings("deprecation")
@Override
@Deprecated
public void sendToJail(final IUser user, String jail) throws Exception {
if (jail == null || jail.isEmpty()) {
return;
}
jail = jail.toLowerCase(Locale.ENGLISH);
synchronized (jails) {
if (jails.containsKey(jail)) {
if (user.getBase().isOnline()) {
user.getTeleport().now(getJail(jail), false, TeleportCause.COMMAND);
}
user.setJail(jail);
}
}
}
@Override
public void sendToJail(final IUser user, final String jailName, final CompletableFuture<Boolean> future) throws Exception {
if (jailName == null || jailName.isEmpty()) {
@@ -272,9 +295,9 @@ public class Jails implements net.ess3.api.IJails {
event.setRespawnLocation(getJail(user.getJail()));
} catch (final Exception ex) {
if (ess.getSettings().isDebug()) {
ess.getLogger().log(Level.INFO, ess.getAdventureFacet().miniToLegacy(tlLiteral("returnPlayerToJailError", user.getName(), ex.getLocalizedMessage())), ex);
ess.getLogger().log(Level.INFO, AdventureUtil.miniToLegacy(tlLiteral("returnPlayerToJailError", user.getName(), ex.getLocalizedMessage())), ex);
} else {
ess.getLogger().log(Level.INFO, ess.getAdventureFacet().miniToLegacy(tlLiteral("returnPlayerToJailError", user.getName(), ex.getLocalizedMessage())));
ess.getLogger().log(Level.INFO, AdventureUtil.miniToLegacy(tlLiteral("returnPlayerToJailError", user.getName(), ex.getLocalizedMessage())));
}
}
}
@@ -294,9 +317,9 @@ public class Jails implements net.ess3.api.IJails {
event.setTo(getJail(user.getJail()));
} catch (final Exception ex) {
if (ess.getSettings().isDebug()) {
ess.getLogger().log(Level.INFO, ess.getAdventureFacet().miniToLegacy(tlLiteral("returnPlayerToJailError", user.getName(), ex.getLocalizedMessage())), ex);
ess.getLogger().log(Level.INFO, AdventureUtil.miniToLegacy(tlLiteral("returnPlayerToJailError", user.getName(), ex.getLocalizedMessage())), ex);
} else {
ess.getLogger().log(Level.INFO, ess.getAdventureFacet().miniToLegacy(tlLiteral("returnPlayerToJailError", user.getName(), ex.getLocalizedMessage())));
ess.getLogger().log(Level.INFO, AdventureUtil.miniToLegacy(tlLiteral("returnPlayerToJailError", user.getName(), ex.getLocalizedMessage())));
}
}
user.sendTl("jailMessage");
@@ -318,9 +341,9 @@ public class Jails implements net.ess3.api.IJails {
final CompletableFuture<Boolean> future = new CompletableFuture<>();
future.exceptionally(ex -> {
if (ess.getSettings().isDebug()) {
ess.getLogger().log(Level.INFO, ess.getAdventureFacet().miniToLegacy(tlLiteral("returnPlayerToJailError", user.getName(), ex.getLocalizedMessage())), ex);
ess.getLogger().log(Level.INFO, AdventureUtil.miniToLegacy(tlLiteral("returnPlayerToJailError", user.getName(), ex.getLocalizedMessage())), ex);
} else {
ess.getLogger().log(Level.INFO, ess.getAdventureFacet().miniToLegacy(tlLiteral("returnPlayerToJailError", user.getName(), ex.getLocalizedMessage())));
ess.getLogger().log(Level.INFO, AdventureUtil.miniToLegacy(tlLiteral("returnPlayerToJailError", user.getName(), ex.getLocalizedMessage())));
}
return false;
});
@@ -6,12 +6,12 @@ import com.earth2me.essentials.craftbukkit.Inventories;
import com.earth2me.essentials.textreader.IText;
import com.earth2me.essentials.textreader.KeywordReplacer;
import com.earth2me.essentials.textreader.SimpleTextInput;
import com.earth2me.essentials.utils.AdventureUtil;
import com.earth2me.essentials.utils.DateUtil;
import com.earth2me.essentials.utils.NumberUtil;
import net.ess3.api.IEssentials;
import net.ess3.api.TranslatableException;
import net.ess3.api.events.KitClaimEvent;
import net.ess3.provider.SerializationProvider;
import net.essentialsx.api.v2.events.KitPreExpandItemsEvent;
import org.bukkit.Bukkit;
import org.bukkit.Material;
@@ -25,7 +25,6 @@ import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.logging.Level;
import static com.earth2me.essentials.I18n.tlLiteral;
@@ -174,11 +173,10 @@ public class Kit {
final boolean allowUnsafe = ess.getSettings().allowUnsafeEnchantments();
final boolean autoEquip = ess.getSettings().isKitAutoEquip();
final List<ItemStack> itemList = new ArrayList<>();
final Map<Integer, ItemStack> itemsWithSlot = new HashMap<>();
final List<String> commandQueue = new ArrayList<>();
final List<String> moneyQueue = new ArrayList<>();
final String currencySymbol = ess.getSettings().getCurrencySymbol().isEmpty() ? "$" : ess.getSettings().getCurrencySymbol();
for (String kitItem : output.getLines()) {
for (final String kitItem : output.getLines()) {
if (kitItem.startsWith("$") || kitItem.startsWith(currencySymbol)) {
moneyQueue.add(NumberUtil.sanitizeCurrencyString(kitItem, ess));
continue;
@@ -192,25 +190,14 @@ public class Kit {
continue;
}
int itemSlot = -1;
if (kitItem.startsWith("slot:")) {
final int spaceIndex = kitItem.indexOf(" ");
if (spaceIndex != -1) {
final String slotStr = kitItem.substring("slot:".length(), spaceIndex);
itemSlot = NumberUtil.isInt(slotStr) ? Integer.parseInt(slotStr) : -1;
kitItem = kitItem.substring(spaceIndex + 1);
}
}
final ItemStack stack;
final SerializationProvider serializationProvider = ess.provider(SerializationProvider.class);
if (kitItem.startsWith("@")) {
if (serializationProvider == null) {
ess.getLogger().log(Level.WARNING, ess.getAdventureFacet().miniToLegacy(tlLiteral("kitError3", kitName, user.getName())));
if (ess.getSerializationProvider() == null) {
ess.getLogger().log(Level.WARNING, AdventureUtil.miniToLegacy(tlLiteral("kitError3", kitName, user.getName())));
continue;
}
stack = serializationProvider.deserializeItem(Base64Coder.decodeLines(kitItem.substring(1)));
stack = ess.getSerializationProvider().deserializeItem(Base64Coder.decodeLines(kitItem.substring(1)));
} else {
final String[] parts = kitItem.split(" +");
final ItemStack parseStack = ess.getItemDb().get(parts[0], parts.length > 1 ? Integer.parseInt(parts[1]) : 1);
@@ -229,35 +216,22 @@ public class Kit {
stack = metaStack.getItemStack();
}
if (itemSlot == -1 || itemsWithSlot.containsKey(itemSlot)) {
itemList.add(stack);
} else {
itemsWithSlot.put(itemSlot, stack);
}
itemList.add(stack);
}
final int maxStackSize = user.isAuthorized("essentials.oversizedstacks") ? ess.getSettings().getOversizedStackSize() : 0;
final boolean isDropItemsIfFull = ess.getSettings().isDropItemsIfFull();
final List<ItemStack> totalItems = new ArrayList<>(itemList);
totalItems.addAll(itemsWithSlot.values());
final KitPreExpandItemsEvent itemsEvent = new KitPreExpandItemsEvent(user, kitName, totalItems);
final KitPreExpandItemsEvent itemsEvent = new KitPreExpandItemsEvent(user, kitName, itemList);
Bukkit.getPluginManager().callEvent(itemsEvent);
final ItemStack[] totalItemsArray = totalItems.toArray(new ItemStack[0]);
if (!isDropItemsIfFull && !Inventories.hasSpace(user.getBase(), maxStackSize, autoEquip, totalItemsArray)) {
final ItemStack[] itemArray = itemList.toArray(new ItemStack[0]);
if (!isDropItemsIfFull && !Inventories.hasSpace(user.getBase(), maxStackSize, autoEquip, itemArray)) {
user.sendTl("kitInvFullNoDrop");
return false;
}
for (Map.Entry<Integer, ItemStack> itemWithSlot : itemsWithSlot.entrySet()) {
final ItemStack leftover = Inventories.addItem(user.getBase(), maxStackSize, itemWithSlot.getValue(), itemWithSlot.getKey());
if (leftover != null) {
itemList.add(leftover);
}
}
final ItemStack[] itemArray = itemList.toArray(new ItemStack[0]);
final Map<Integer, ItemStack> leftover = Inventories.addItem(user.getBase(), maxStackSize, autoEquip, itemArray);
if (!isDropItemsIfFull && !leftover.isEmpty()) {
// Inventories#hasSpace should prevent this state from EVER being reached; If it does, something has gone terribly wrong, and we should just give up and hope people report it :(
@@ -266,10 +240,10 @@ public class Kit {
for (final ItemStack itemStack : leftover.values()) {
int spillAmount = itemStack.getAmount();
if (maxStackSize != 0) {
itemStack.setAmount(Math.min(spillAmount, itemStack.getMaxStackSize()));
}
while (spillAmount > 0) {
if (maxStackSize != 0) {
itemStack.setAmount(Math.min(spillAmount, itemStack.getMaxStackSize()));
}
user.getWorld().dropItemNaturally(user.getLocation(), itemStack);
spillAmount -= itemStack.getAmount();
}
@@ -1,5 +1,6 @@
package com.earth2me.essentials;
import com.earth2me.essentials.utils.AdventureUtil;
import net.ess3.api.IEssentials;
import java.io.BufferedInputStream;
@@ -45,7 +46,7 @@ public class ManagedFile {
try {
copyResourceAscii("/" + filename, file);
} catch (final IOException ex) {
Essentials.getWrappedLogger().log(Level.SEVERE, ess.getAdventureFacet().miniToLegacy(tlLiteral("itemsCsvNotLoaded", filename)), ex);
Essentials.getWrappedLogger().log(Level.SEVERE, AdventureUtil.miniToLegacy(tlLiteral("itemsCsvNotLoaded", filename)), ex);
}
}
}
@@ -1,9 +1,9 @@
package com.earth2me.essentials;
import com.earth2me.essentials.items.transform.PluginItemTransformer;
import com.earth2me.essentials.textreader.BookInput;
import com.earth2me.essentials.textreader.BookPager;
import com.earth2me.essentials.textreader.IText;
import com.earth2me.essentials.utils.EnumUtil;
import com.earth2me.essentials.utils.FormatUtil;
import com.earth2me.essentials.utils.MaterialUtil;
import com.earth2me.essentials.utils.NumberUtil;
@@ -11,9 +11,6 @@ import com.earth2me.essentials.utils.VersionUtil;
import com.google.common.base.Joiner;
import net.ess3.api.IEssentials;
import net.ess3.api.TranslatableException;
import net.ess3.provider.BannerDataProvider;
import net.ess3.provider.ItemUnbreakableProvider;
import net.ess3.provider.PotionMetaProvider;
import org.bukkit.Color;
import org.bukkit.DyeColor;
import org.bukkit.FireworkEffect;
@@ -21,8 +18,6 @@ import org.bukkit.Material;
import org.bukkit.block.Banner;
import org.bukkit.block.banner.PatternType;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.Registry;
import org.bukkit.NamespacedKey;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.BannerMeta;
@@ -35,10 +30,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.inventory.meta.ArmorMeta;
import org.bukkit.inventory.meta.trim.ArmorTrim;
import org.bukkit.inventory.meta.trim.TrimMaterial;
import org.bukkit.inventory.meta.trim.TrimPattern;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
@@ -54,7 +45,6 @@ import java.util.regex.Pattern;
public class MetaItemStack {
private static final Map<String, DyeColor> colorMap = new HashMap<>();
private static final Map<String, FireworkEffect.Type> fireworkShape = new HashMap<>();
private static final transient Map<String, PluginItemTransformer> itemTransformers = new HashMap<>();
private static boolean useNewSkullMethod = true;
static {
@@ -86,32 +76,6 @@ public class MetaItemStack {
this.stack = stack.clone();
}
/**
* Registers an item transformer, belonging to a plugin, that can manipulate certain item metadata.
* @param key the key for the transformer.
* @param itemTransformer the actual transformer.
*/
public static void registerItemTransformer(final String key, final PluginItemTransformer itemTransformer) {
//Warn people if they're trying to register over top of someone else.
if (itemTransformers.containsKey(key)) {
Essentials.getWrappedLogger().log(Level.WARNING, String.format("Plugin transformer registered to \"%s\" attempted to register already existing item transformer \"%s\" belonging to \"%s\"!",
itemTransformer.getPlugin().getName(),
key,
itemTransformers.get(key).getPlugin().getName()));
return;
}
itemTransformers.put(key, itemTransformer);
}
/**
* Unregisters a certain item transformer under key "key".
* @param key the transformer key.
*/
public static void unregisterItemTransformer(final String key) {
itemTransformers.remove(key);
}
private static void setSkullOwner(final IEssentials ess, final ItemStack stack, final String owner) {
if (!(stack.getItemMeta() instanceof SkullMeta)) return;
@@ -250,6 +214,8 @@ public class MetaItemStack {
return;
}
final Material WRITTEN_BOOK = EnumUtil.getMaterial("WRITTEN_BOOK");
if (split.length > 1 && split[0].equalsIgnoreCase("name") && hasMetaPermission(sender, "name", false, true, ess)) {
final String displayName = FormatUtil.replaceFormat(split[1].replaceAll("(?<!\\\\)_", " ").replace("\\_", "_"));
final ItemMeta meta = stack.getItemMeta();
@@ -285,7 +251,7 @@ public class MetaItemStack {
final IText input = new BookInput("book", true, ess);
final BookPager pager = new BookPager(input);
// This fix only applies to written books - which require an author and a title. https://bugs.mojang.com/browse/MC-59153
if (stack.getType() == Material.WRITTEN_BOOK) {
if (stack.getType() == WRITTEN_BOOK) {
if (!meta.hasAuthor()) {
// The sender can be null when this method is called from {@link com.earth2me.essentials.signs.EssentialsSign#getItemMeta(ItemStack, String, IEssentials)}
meta.setAuthor(sender == null ? Console.getInstance().getDisplayName() : sender.getPlayer().getName());
@@ -298,24 +264,18 @@ public class MetaItemStack {
final List<String> pages = pager.getPages(split[1]);
meta.setPages(pages);
stack.setItemMeta(meta);
} else if (split.length > 1 && split[0].equalsIgnoreCase("author") && stack.getType() == Material.WRITTEN_BOOK && hasMetaPermission(sender, "author", false, true, ess)) {
} else if (split.length > 1 && split[0].equalsIgnoreCase("author") && stack.getType() == WRITTEN_BOOK && hasMetaPermission(sender, "author", false, true, ess)) {
final String author = FormatUtil.replaceFormat(split[1]);
final BookMeta meta = (BookMeta) stack.getItemMeta();
meta.setAuthor(author);
stack.setItemMeta(meta);
} else if (split.length > 1 && split[0].equalsIgnoreCase("title") && stack.getType() == Material.WRITTEN_BOOK && hasMetaPermission(sender, "title", false, true, ess)) {
} else if (split.length > 1 && split[0].equalsIgnoreCase("title") && stack.getType() == WRITTEN_BOOK && hasMetaPermission(sender, "title", false, true, ess)) {
final String title = FormatUtil.replaceFormat(split[1].replaceAll("(?<!\\\\)_", " ").replace("\\_", "_"));
final BookMeta meta = (BookMeta) stack.getItemMeta();
meta.setTitle(title);
stack.setItemMeta(meta);
} else if (split.length > 1 && split[0].startsWith("page") && split[0].length() > 4
&& MaterialUtil.isEditableBook(stack.getType())
&& hasMetaPermission(sender, "page", false, true, ess)) {
final int page = NumberUtil.isInt(split[0].substring(4)) ? (Integer.parseInt(split[0].substring(4)) - 1)
: 0;
if (page > 100) {
throw new TranslatableException("pageLimitExceeded");
}
} else if (split.length > 1 && split[0].startsWith("page") && split[0].length() > 4 && MaterialUtil.isEditableBook(stack.getType()) && hasMetaPermission(sender, "page", false, true, ess)) {
final int page = NumberUtil.isInt(split[0].substring(4)) ? (Integer.parseInt(split[0].substring(4)) - 1) : 0;
final BookMeta meta = (BookMeta) stack.getItemMeta();
final List<String> pages = meta.hasPages() ? new ArrayList<>(meta.getPages()) : new ArrayList<>();
final List<String> lines = new ArrayList<>();
@@ -383,37 +343,11 @@ public class MetaItemStack {
} else {
throw new TranslatableException("leatherSyntax");
}
} else if (MaterialUtil.isArmor(stack.getType()) && split.length > 1 && split[0].equalsIgnoreCase("trim")) {
final ArmorMeta armorMeta = (ArmorMeta) stack.getItemMeta();
final String[] trimData = split[1].split("\\|");
final TrimPattern pattern = Registry.TRIM_PATTERN.getOrThrow(NamespacedKey.minecraft(trimData[0].toLowerCase()));
final TrimMaterial material = Registry.TRIM_MATERIAL.getOrThrow(NamespacedKey.minecraft(trimData[1].toLowerCase()));
armorMeta.setTrim(new ArmorTrim(material, pattern));
stack.setItemMeta(armorMeta);
} else if (split.length > 1 && itemTransformers.containsKey(split[0])) {
transformItem(split[0], split[1]);
} else {
parseEnchantmentStrings(sender, allowUnsafe, split, ess);
}
}
private void transformItem(final String key, final String data){
final PluginItemTransformer transformer = itemTransformers.get(key);
//Ignore, the plugin is disabled.
if (!transformer.getPlugin().isEnabled()) {
return;
}
try {
stack = transformer.apply(data, stack);
} catch(final Throwable thr) {
Essentials.getWrappedLogger().log(Level.SEVERE, String.format("Error applying data \"%s\" to itemstack! Plugin: %s, Key: %s", data, transformer.getPlugin().getName(), key), thr);
}
}
public void addItemFlags(final String string) throws Exception {
final String[] separate = splitPattern.split(string, 2);
if (separate.length != 2) {
@@ -615,8 +549,7 @@ public class MetaItemStack {
} else if (split[0].equalsIgnoreCase("duration") || (allowShortName && split[0].equalsIgnoreCase("d"))) {
if (NumberUtil.isInt(split[1])) {
validPotionDuration = true;
final int parsed = Integer.parseInt(split[1]);
duration = parsed == -1 ? -1 : parsed * 20; //Duration is in ticks by default, converted to seconds
duration = Integer.parseInt(split[1]) * 20; //Duration is in ticks by default, converted to seconds
} else {
throw new TranslatableException("invalidPotionMeta", split[1]);
}
@@ -632,7 +565,7 @@ public class MetaItemStack {
}
pmeta.addCustomEffect(pEffect, true);
stack.setItemMeta(pmeta);
ess.provider(PotionMetaProvider.class).setSplashPotion(stack, isSplashPotion);
ess.getPotionMetaProvider().setSplashPotion(stack, isSplashPotion);
resetPotionMeta();
}
}
@@ -722,7 +655,7 @@ public class MetaItemStack {
final BannerMeta meta = (BannerMeta) stack.getItemMeta();
if (split[0].equalsIgnoreCase("basecolor")) {
final Color color = Color.fromRGB(Integer.parseInt(split[1]));
ess.provider(BannerDataProvider.class).setBaseColor(stack, DyeColor.getByColor(color));
ess.getBannerDataProvider().setBaseColor(stack, DyeColor.getByColor(color));
} else if (patternType != null) {
//noinspection removal
final PatternType type = PatternType.getByIdentifier(split[0]);
@@ -785,7 +718,7 @@ public class MetaItemStack {
private void setUnbreakable(final IEssentials ess, final ItemStack is, final boolean unbreakable) {
final ItemMeta meta = is.getItemMeta();
ess.provider(ItemUnbreakableProvider.class).setUnbreakable(meta, unbreakable);
ess.getItemUnbreakableProvider().setUnbreakable(meta, unbreakable);
is.setItemMeta(meta);
}
}
@@ -1,6 +1,6 @@
package com.earth2me.essentials;
import com.earth2me.essentials.adventure.AdventureUtil;
import com.earth2me.essentials.utils.AdventureUtil;
import com.earth2me.essentials.utils.EnumUtil;
import org.bukkit.Location;
import org.bukkit.Server;
@@ -50,16 +50,7 @@ public enum Mob {
WITHER("Wither", Enemies.ENEMY, EntityType.WITHER),
BAT("Bat", Enemies.FRIENDLY, EntityType.BAT),
WITCH("Witch", Enemies.ENEMY, EntityType.WITCH),
BOAT("Boat", Enemies.NEUTRAL, MobCompat.OAK_BOAT),
ACACIA_BOAT("AcaciaBoat", Enemies.NEUTRAL, "ACACIA_BOAT"),
DARK_OAK_BOAT("DarkOakBoat", Enemies.NEUTRAL, "DARK_OAK_BOAT"),
BIRCH_BOAT("BirchBoat", Enemies.NEUTRAL, "BIRCH_BOAT"),
JUNGLE_BOAT("JungleBoat", Enemies.NEUTRAL, "JUNGLE_BOAT"),
SPRUCE_BOAT("SpruceBoat", Enemies.NEUTRAL, "SPRUCE_BOAT"),
MANGROVE_BOAT("MangroveBoat", Enemies.NEUTRAL, "MANGROVE_BOAT"),
CHERRY_BOAT("CherryBoat", Enemies.NEUTRAL, "CHERRY_BOAT"),
BAMBOO_RAFT("BambooRaft", Enemies.NEUTRAL, "BAMBOO_RAFT"),
PALE_OAK_BOAT("PaleOakBoat", Enemies.NEUTRAL, "PALE_OAK_BOAT"),
BOAT("Boat", Enemies.NEUTRAL, EntityType.BOAT),
MINECART("Minecart", Enemies.NEUTRAL, EntityType.MINECART),
MINECART_CHEST("ChestMinecart", Enemies.NEUTRAL, MobCompat.CHEST_MINECART),
MINECART_FURNACE("FurnaceMinecart", Enemies.NEUTRAL, MobCompat.FURNACE_MINECART),
@@ -124,13 +115,6 @@ public enum Mob {
ARMADILLO("Armadillo", Enemies.FRIENDLY, "ARMADILLO"),
BREEZE("Breeze", Enemies.ENEMY, "BREEZE"),
BOGGED("Bogged", Enemies.ENEMY, "BOGGED"),
CREAKING("Creaking", Enemies.ENEMY, "CREAKING"),
HAPPY_GHAST("HappyGhast", Enemies.FRIENDLY, "HAPPY_GHAST"),
COPPER_GOLEM("CopperGolem", Enemies.FRIENDLY, "COPPER_GOLEM"),
CAMEL_HUSK("CamelHusk", Enemies.NEUTRAL, "CAMEL_HUSK"),
NAUTILUS("Nautilus", Enemies.NEUTRAL, "NAUTILUS"),
ZOMBIE_NAUTILUS("ZombieNautilus", Enemies.NEUTRAL, "ZOMBIE_NAUTILUS"),
PARCHED("Parched", Enemies.ENEMY, "PARCHED"),
;
private static final Map<String, Mob> hashMap = new HashMap<>();
@@ -191,7 +175,7 @@ public enum Mob {
public Entity spawn(final World world, final Server server, final Location loc) throws MobException {
final Entity entity = world.spawn(loc, this.bukkitType.getEntityClass());
if (entity == null) {
Essentials.getWrappedLogger().log(Level.WARNING, AdventureUtil.getAdventureFacet().miniToLegacy(tlLiteral("unableToSpawnMob")));
Essentials.getWrappedLogger().log(Level.WARNING, AdventureUtil.miniToLegacy(tlLiteral("unableToSpawnMob")));
throw new MobException();
}
return entity;
@@ -6,12 +6,9 @@ import com.earth2me.essentials.utils.VersionUtil;
import net.ess3.nms.refl.ReflUtil;
import org.bukkit.Material;
import org.bukkit.TreeSpecies;
import org.bukkit.entity.AbstractNautilus;
import org.bukkit.entity.Axolotl;
import org.bukkit.entity.Boat;
import org.bukkit.entity.Camel;
import org.bukkit.entity.Chicken;
import org.bukkit.entity.Cow;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Fox;
@@ -21,18 +18,12 @@ import org.bukkit.entity.MushroomCow;
import org.bukkit.entity.Ocelot;
import org.bukkit.entity.Panda;
import org.bukkit.entity.Parrot;
import org.bukkit.entity.Pig;
import org.bukkit.entity.Player;
import org.bukkit.entity.Salmon;
import org.bukkit.entity.TropicalFish;
import org.bukkit.entity.Villager;
import org.bukkit.entity.Wolf;
import org.bukkit.entity.ZombieNautilus;
import org.bukkit.inventory.ItemStack;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.reflect.Method;
import static com.earth2me.essentials.utils.EnumUtil.getEntityType;
@@ -40,21 +31,8 @@ import static com.earth2me.essentials.utils.EnumUtil.getEntityType;
public final class MobCompat {
// Constants for mob interfaces added in later versions
public static final Class<?> RAIDER = ReflUtil.getClassCached("org.bukkit.entity.Raider");
// Stupid hacks to avoid Commodore rewrites.
private static final Class<?> COW = ReflUtil.getClassCached("org.bukkit.entity.Cow");
private static final Class<?> COW_VARIANT = ReflUtil.getClassCached("org.bukkit.entity.Cow$Variant");
private static final MethodHandle COW_VARIANT_HANDLE;
static {
MethodHandle handle = null;
try {
handle = MethodHandles.lookup().findVirtual(COW, "setVariant", MethodType.methodType(void.class, COW_VARIANT));
} catch (final Throwable ignored) {
}
COW_VARIANT_HANDLE = handle;
}
@SuppressWarnings("rawtypes")
public static final Class RAIDER = ReflUtil.getClassCached("org.bukkit.entity.Raider");
// Constants for mobs added in later versions
public static final EntityType LLAMA = getEntityType("LLAMA");
@@ -70,10 +48,6 @@ public final class MobCompat {
public static final EntityType GOAT = getEntityType("GOAT");
public static final EntityType FROG = getEntityType("FROG");
public static final EntityType CAMEL = getEntityType("CAMEL");
public static final EntityType SALMON = getEntityType("SALMON");
public static final EntityType CAMEL_HUSK = getEntityType("CAMEL_HUSK");
public static final EntityType NAUTILUS = getEntityType("NAUTILUS");
public static final EntityType ZOMBIE_NAUTILUS = getEntityType("ZOMBIE_NAUTILUS");
// Constants for mobs that have changed since earlier versions
public static final EntityType CAT = getEntityType("CAT", "OCELOT");
@@ -87,7 +61,6 @@ public final class MobCompat {
public static final EntityType SPAWNER_MINECART = getEntityType("SPAWNER_MINECART", "MINECART_MOB_SPAWNER");
public static final EntityType END_CRYSTAL = getEntityType("END_CRYSTAL", "ENDER_CRYSTAL");
public static final EntityType FIREWORK_ROCKET = getEntityType("FIREWORK_ROCKET", "FIREWORK");
public static final EntityType OAK_BOAT = getEntityType("BOAT", "OAK_BOAT");
private MobCompat() {
}
@@ -221,7 +194,7 @@ public final class MobCompat {
}
public static void setBoatVariant(final Entity entity, final BoatVariant variant) {
if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_21_3_R01) || VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_9_R01)) {
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_9_R01)) {
return;
}
final Boat boat;
@@ -234,7 +207,6 @@ public final class MobCompat {
//noinspection deprecation
boat.setWoodType(TreeSpecies.valueOf(variant.getTreeSpecies()));
} else {
//noinspection deprecation
boat.setBoatType(Boat.Type.valueOf(variant.getBoatType()));
}
}
@@ -264,75 +236,6 @@ public final class MobCompat {
}
}
public static void setSalmonSize(Entity spawned, String s) {
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_21_3_R01)) {
return;
}
if (spawned instanceof org.bukkit.entity.Salmon) {
((Salmon) spawned).setVariant(Salmon.Variant.valueOf(s));
}
}
public static void setCowVariant(final Entity spawned, final String variant) {
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_21_5_R01) || COW_VARIANT_HANDLE == null) {
return;
}
if (spawned instanceof Cow) {
try {
COW_VARIANT_HANDLE.invoke(spawned, RegistryUtil.valueOf(COW_VARIANT, variant));
} catch (Throwable ignored) {
}
}
}
public static void setChickenVariant(final Entity spawned, final String variant) {
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_21_5_R01)) {
return;
}
if (spawned instanceof Chicken) {
//noinspection DataFlowIssue
((Chicken) spawned).setVariant(RegistryUtil.valueOf(Chicken.Variant.class, variant));
}
}
public static void setPigVariant(final Entity spawned, final String variant) {
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_21_5_R01)) {
return;
}
if (spawned instanceof Pig) {
//noinspection DataFlowIssue
((Pig) spawned).setVariant(RegistryUtil.valueOf(Pig.Variant.class, variant));
}
}
public static void setZombieNautilusVariant(final Entity spawned, final String variant) {
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_21_11_R01)) {
return;
}
if (spawned instanceof ZombieNautilus) {
//noinspection DataFlowIssue
((ZombieNautilus) spawned).setVariant(RegistryUtil.valueOf(ZombieNautilus.Variant.class, variant));
}
}
public static void setNautilusSaddle(final Entity entity, final Player target) {
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_21_11_R01)) {
return;
}
if (entity instanceof AbstractNautilus) {
final AbstractNautilus nautilus = (AbstractNautilus) entity;
nautilus.setTamed(true);
nautilus.setOwner(target);
nautilus.getInventory().setSaddle(new ItemStack(Material.SADDLE, 1));
}
}
public enum CatType {
// These are (loosely) Mojang names for the cats
SIAMESE("SIAMESE", "SIAMESE_CAT"),
@@ -10,7 +10,6 @@ import org.bukkit.Material;
import org.bukkit.entity.Ageable;
import org.bukkit.entity.Boat;
import org.bukkit.entity.ChestedHorse;
import org.bukkit.entity.Chicken;
import org.bukkit.entity.Creeper;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
@@ -82,7 +81,6 @@ public enum MobData {
SADDLE_HORSE("saddle", EntityType.HORSE, Data.HORSESADDLE, true),
GOLD_ARMOR_HORSE("goldarmor", EntityType.HORSE, EnumUtil.getMaterial("GOLDEN_HORSE_ARMOR", "GOLD_BARDING"), true),
DIAMOND_ARMOR_HORSE("diamondarmor", EntityType.HORSE, EnumUtil.getMaterial("DIAMOND_HORSE_ARMOR", "DIAMOND_BARDING"), true),
NETHERITE_HORSE_ARMOR("netheritearmor", EntityType.HORSE, EnumUtil.getMaterial("NETHERITE_HORSE_ARMOR"), true),
ARMOR_HORSE("armor", EntityType.HORSE, EnumUtil.getMaterial("IRON_HORSE_ARMOR", "IRON_BARDING"), true),
SIAMESE_CAT("siamese", MobCompat.CAT, MobCompat.CatType.SIAMESE, true),
WHITE_CAT("white", MobCompat.CAT, MobCompat.CatType.WHITE, false),
@@ -220,23 +218,6 @@ public enum MobData {
WOODS_WOLF("woods", EntityType.WOLF, "wolf:WOODS", true),
CHESTNUT_WOLF("chestnut", EntityType.WOLF, "wolf:CHESTNUT", true),
STRIPED_WOLF("striped", EntityType.WOLF, "wolf:STRIPED", true),
SMALL_SALMON("small", MobCompat.SALMON, "salmon:SMALL", true),
MEDIUM_SALMON("medium", MobCompat.SALMON, "salmon:MEDIUM", true),
LARGE_SALMON("large", MobCompat.SALMON, "salmon:LARGE", true),
TEMPERATE_COW("temperate", EntityType.COW.getEntityClass(), "cow:TEMPERATE", true),
WARM_COW("warm", EntityType.COW.getEntityClass(), "cow:WARM", true),
COLD_COW("cold", EntityType.COW.getEntityClass(), "cow:COLD", true),
TEMPERATE_CHICKEN("temperate", Chicken.class, "chicken:TEMPERATE", true),
WARM_CHICKEN("warm", Chicken.class, "chicken:WARM", true),
COLD_CHICKEN("cold", Chicken.class, "chicken:COLD", true),
TEMPERATE_PIG("temperate", Pig.class, "pig:TEMPERATE", true),
WARM_PIG("warm", Pig.class, "pig:WARM", true),
COLD_PIG("cold", Pig.class, "pig:COLD", true),
SADDLE_CAMEL_HUSK("saddle", MobCompat.CAMEL_HUSK, Data.CAMELHUSKSADDLE, true),
TEMPERATE_ZOMBIE_NAUTILUS("temperate", MobCompat.ZOMBIE_NAUTILUS, "zombienautilus:TEMPERATE", true),
WARM_ZOMBIE_NAUTILUS("warm", MobCompat.ZOMBIE_NAUTILUS, "zombienautilus:WARM", true),
SADDLE_NAUTILUS("saddle", MobCompat.NAUTILUS, Data.NAUTILUSSADDLE, true),
SADDLE_ZOMBIE_NAUTILUS("saddle", MobCompat.ZOMBIE_NAUTILUS, Data.NAUTILUSSADDLE, true)
;
final private String nickname;
@@ -417,12 +398,6 @@ public enum MobData {
((Goat) spawned).setScreaming(true);
} else if (this.value.equals(Data.CAMELSADDLE)) {
MobCompat.setCamelSaddle(spawned, target);
} else if (this.value.equals(Data.CAMELHUSKSADDLE)) {
MobCompat.setCamelSaddle(spawned, target);
} else if (this.value.equals(Data.NAUTILUSSADDLE)) {
MobCompat.setNautilusSaddle(spawned, target);
} else if (this.value.equals(Data.ZOMBIENAUTILUSSADDLE)) {
MobCompat.setNautilusSaddle(spawned, target);
} else if (this.value instanceof MobCompat.BoatVariant) {
MobCompat.setBoatVariant(spawned, (MobCompat.BoatVariant) this.value);
} else if (this.value instanceof String) {
@@ -461,21 +436,6 @@ public enum MobData {
case "wolf":
MobCompat.setWolfVariant(spawned, split[1]);
break;
case "salmon":
MobCompat.setSalmonSize(spawned, split[1]);
break;
case "cow":
MobCompat.setCowVariant(spawned, split[1]);
break;
case "chicken":
MobCompat.setChickenVariant(spawned, split[1]);
break;
case "pig":
MobCompat.setPigVariant(spawned, split[1]);
break;
case "zombienautilus":
MobCompat.setZombieNautilusVariant(spawned, split[1]);
break;
}
} else {
Essentials.getWrappedLogger().warning("Unknown mob data type: " + this.toString());
@@ -501,8 +461,5 @@ public enum MobData {
FISH_PATTERN_COLOR,
GOAT_SCREAMING,
CAMELSADDLE,
CAMELHUSKSADDLE,
NAUTILUSSADDLE,
ZOMBIENAUTILUSSADDLE,
}
}
@@ -1,5 +1,6 @@
package com.earth2me.essentials;
import com.earth2me.essentials.utils.AdventureUtil;
import com.earth2me.essentials.utils.FormatUtil;
import com.earth2me.essentials.utils.NumberUtil;
import net.ess3.api.TranslatableException;
@@ -38,7 +39,7 @@ public final class PlayerList {
groupString.append(tlLiteral("listHiddenTag"));
}
user.setDisplayNick();
groupString.append(ess.getAdventureFacet().legacyToMini(user.getDisplayName()));
groupString.append(AdventureUtil.legacyToMini(user.getDisplayName()));
final String strippedNick = FormatUtil.stripFormat(user.getNickname());
if (ess.getSettings().realNamesOnList() && strippedNick != null && !strippedNick.equals(user.getName())) {
@@ -161,14 +161,6 @@ public final class Potions {
ALIASPOTIONS.put("wind", PotionEffectType.WIND_CHARGED);
} catch (final Throwable ignored) {
}
// 1.21.11
try {
POTIONS.put("breathofthenautilus", PotionEffectType.BREATH_OF_THE_NAUTILUS);
ALIASPOTIONS.put("nautilusbreath", PotionEffectType.BREATH_OF_THE_NAUTILUS);
ALIASPOTIONS.put("nautilus", PotionEffectType.BREATH_OF_THE_NAUTILUS);
} catch (final Throwable ignored) {
}
}
private Potions() {
@@ -1,137 +0,0 @@
package com.earth2me.essentials;
import io.papermc.lib.PaperLib;
import net.ess3.provider.Provider;
import net.essentialsx.providers.NullableProvider;
import net.essentialsx.providers.ProviderData;
import net.essentialsx.providers.ProviderTest;
import org.bukkit.plugin.Plugin;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
public class ProviderFactory {
private final Map<Class<? extends Provider>, Provider> providers = new HashMap<>();
private final Map<Class<? extends Provider>, List<Class<? extends Provider>>> registeredProviders = new HashMap<>();
private final Essentials essentials;
public ProviderFactory(final Essentials essentials) {
this.essentials = essentials;
}
/**
* Gets the provider which has been selected for the given type.
* @param providerClass The provider type.
* @return the provider or null if no provider could be selected for that type.
*/
public <P extends Provider> P get(final Class<P> providerClass) {
final Provider provider = providers.get(providerClass);
if (provider == null) {
return null;
}
//noinspection unchecked
return (P) provider;
}
@SafeVarargs
public final void registerProvider(final Class<? extends Provider>... toRegister) {
for (final Class<? extends Provider> provider : toRegister) {
final Class<?> superclass = provider.getInterfaces().length > 0 ? provider.getInterfaces()[0] : provider.getSuperclass();
if (Provider.class.isAssignableFrom(superclass)) {
//noinspection unchecked
registeredProviders.computeIfAbsent((Class<? extends Provider>) superclass, k -> new ArrayList<>()).add(provider);
if (essentials.getSettings().isDebug()) {
essentials.getLogger().info("Registered provider " + provider.getSimpleName() + " for " + superclass.getSimpleName());
}
}
}
}
public void finalizeRegistration() {
for (final Map.Entry<Class<? extends Provider>, List<Class<? extends Provider>>> entry : registeredProviders.entrySet()) {
final Class<? extends Provider> providerClass = entry.getKey();
final boolean nullable = providerClass.isAnnotationPresent(NullableProvider.class);
Class<? extends Provider> highestProvider = null;
ProviderData highestProviderData = null;
int highestWeight = -1;
for (final Class<? extends Provider> provider : entry.getValue()) {
try {
final ProviderData providerData = provider.getAnnotation(ProviderData.class);
if (providerData.weight() > highestWeight && testProvider(provider)) {
highestWeight = providerData.weight();
highestProvider = provider;
highestProviderData = providerData;
}
} catch (final Throwable e) {
essentials.getLogger().log(Level.SEVERE, "Failed to initialize provider " + provider.getName(), e);
}
}
if (highestProvider != null) {
essentials.getLogger().info("Selected " + highestProviderData.description() + " as the provider for " + providerClass.getSimpleName());
providers.put(providerClass, getProviderInstance(highestProvider));
} else if (!nullable) {
throw new IllegalStateException("No provider found for " + providerClass.getName());
} else {
essentials.getLogger().info("No provider found for " + providerClass.getSimpleName() + ", but it is nullable");
}
}
registeredProviders.clear();
}
private boolean testProvider(final Class<?> providerClass) throws InvocationTargetException, IllegalAccessException {
try {
for (final Method method : providerClass.getMethods()) {
if (method.isAnnotationPresent(ProviderTest.class)) {
return (Boolean) method.invoke(null);
}
}
return true;
} catch (final NoClassDefFoundError ignored) {
return false;
}
}
private <P extends Provider> P getProviderInstance(final Class<P> provider) {
try {
final Constructor<?> constructor = provider.getConstructors()[0];
if (constructor.getParameterTypes().length == 0) {
//noinspection unchecked
return (P) constructor.newInstance();
}
final Object[] args = new Object[constructor.getParameterTypes().length];
/*
Providers can have constructors with any of the following types, and this code will automatically supply them;
- Plugin - The Essentials instance will be passed
- boolean - True will be passed if this server is running Paper, otherwise false.
*/
for (int i = 0; i < args.length; i++) {
final Class<?> paramType = constructor.getParameterTypes()[i];
if (paramType.isAssignableFrom(Plugin.class)) {
args[i] = essentials;
} else if (paramType.isAssignableFrom(boolean.class)) {
args[i] = PaperLib.isPaper();
} else {
throw new IllegalArgumentException("Unsupported parameter type " + paramType.getName());
}
}
//noinspection unchecked
return (P) constructor.newInstance(args);
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
try {
return provider.getConstructor().newInstance();
} catch (NoSuchMethodException | InvocationTargetException | InstantiationException | IllegalAccessException ex) {
e.printStackTrace();
throw new RuntimeException(ex);
}
}
}
}
@@ -1,24 +1,17 @@
package com.earth2me.essentials;
import com.earth2me.essentials.config.ConfigurateUtil;
import com.earth2me.essentials.config.EssentialsConfiguration;
import com.earth2me.essentials.config.entities.LazyLocation;
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.BiomeNameProvider;
import net.ess3.provider.WorldInfoProvider;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.Random;
import java.util.Set;
@@ -30,77 +23,56 @@ public class RandomTeleport implements IConf {
private static final int HIGHEST_BLOCK_Y_OFFSET = VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_15_R01) ? 1 : 0;
private final IEssentials ess;
private final EssentialsConfiguration config;
private final Map<String, ConcurrentLinkedQueue<Location>> cachedLocations = new HashMap<>();
private WorldInfoProvider worldInfoProvider;
private final ConcurrentLinkedQueue<Location> cachedLocations = new ConcurrentLinkedQueue<>();
public RandomTeleport(final IEssentials essentials) {
this.ess = essentials;
config = new EssentialsConfiguration(new File(essentials.getDataFolder(), "tpr.yml"), "/tpr.yml",
"Configuration for the random teleport command.\nUse the /settpr command in-game to set random teleport locations.");
}
public EssentialsConfiguration getConfig() {
return config;
"Configuration for the random teleport command.\nSome settings may be defaulted, and can be changed via the /settpr command in-game.");
reloadConfig();
}
@Override
public void reloadConfig() {
worldInfoProvider = ess.provider(WorldInfoProvider.class);
config.load();
cachedLocations.clear();
}
public boolean hasLocation(final String name) {
return config.hasProperty("locations." + name);
}
public Location getCenter(final String name) {
final LazyLocation center = config.getLocation(locationKey(name, "center"));
if (center != null && center.location() != null) {
return center.location();
public Location getCenter() {
try {
final LazyLocation center = config.getLocation("center");
if (center != null && center.location() != null) {
return center.location();
}
} catch (final InvalidWorldException ignored) {
}
final Location worldCenter = ess.getServer().getWorlds().get(0).getWorldBorder().getCenter();
worldCenter.setY(worldCenter.getWorld().getHighestBlockYAt(worldCenter) + HIGHEST_BLOCK_Y_OFFSET);
setCenter(name, worldCenter);
return worldCenter;
final Location center = ess.getServer().getWorlds().get(0).getWorldBorder().getCenter();
center.setY(center.getWorld().getHighestBlockYAt(center) + HIGHEST_BLOCK_Y_OFFSET);
setCenter(center);
return center;
}
public void setCenter(final String name, final Location center) {
config.setProperty(locationKey(name, "center"), center);
public void setCenter(final Location center) {
config.setProperty("center", center);
config.save();
// Clear cached locations since center changed
this.getCachedLocations(name).clear();
}
public double getMinRange(final String name) {
return config.getDouble(locationKey(name, "min-range"), 0d);
public double getMinRange() {
return config.getDouble("min-range", 0d);
}
public void setMinRange(final String name, final double minRange) {
config.setProperty(locationKey(name, "min-range"), minRange);
public void setMinRange(final double minRange) {
config.setProperty("min-range", minRange);
config.save();
// Clear cached locations since min range changed
this.getCachedLocations(name).clear();
}
public double getMaxRange(final String name) {
return config.getDouble(locationKey(name, "max-range"), getCenter(name).getWorld().getWorldBorder().getSize() / 2);
public double getMaxRange() {
return config.getDouble("max-range", getCenter().getWorld().getWorldBorder().getSize() / 2);
}
public void setMaxRange(final String name, final double maxRange) {
config.setProperty(locationKey(name, "max-range"), maxRange);
public void setMaxRange(final double maxRange) {
config.setProperty("max-range", maxRange);
config.save();
// Clear cached locations since max range changed
this.getCachedLocations(name).clear();
}
public String getDefaultLocation() {
return config.getString("default-location", "{world}");
}
public boolean isPerLocationPermission() {
return config.getBoolean("per-location-permission", false);
}
public Set<String> getExcludedBiomes() {
@@ -119,48 +91,39 @@ public class RandomTeleport implements IConf {
return config.getInt("cache-threshold", 10);
}
public List<String> listLocations() {
return new ArrayList<>(ConfigurateUtil.getKeys(config.getRootNode().node("locations")));
public boolean getPreCache() {
return config.getBoolean("pre-cache", false);
}
public Queue<Location> getCachedLocations(final String name) {
this.cachedLocations.computeIfAbsent(name, x -> new ConcurrentLinkedQueue<>());
return cachedLocations.get(name);
public Queue<Location> getCachedLocations() {
return cachedLocations;
}
// Get a named random teleport location; cached if possible, otherwise on demand.
public CompletableFuture<Location> getRandomLocation(final String name) {
final Queue<Location> cached = this.getCachedLocations(name);
// Get a random location; cached if possible. Otherwise on demand.
public CompletableFuture<Location> getRandomLocation(final Location center, final double minRange, final double maxRange) {
final int findAttempts = this.getFindAttempts();
final Queue<Location> cachedLocations = this.getCachedLocations();
// Try to build up the cache if it is below the threshold
if (cached.size() < this.getCacheThreshold()) {
cacheRandomLocations(name);
if (cachedLocations.size() < this.getCacheThreshold()) {
cacheRandomLocations(center, minRange, maxRange);
}
final CompletableFuture<Location> future = new CompletableFuture<>();
// Return a random location immediately if one is available, otherwise try to find one now
if (cached.isEmpty()) {
final int findAttempts = this.getFindAttempts();
final Location center = this.getCenter(name);
final double minRange = this.getMinRange(name);
final double maxRange = this.getMaxRange(name);
if (cachedLocations.isEmpty()) {
attemptRandomLocation(findAttempts, center, minRange, maxRange).thenAccept(future::complete);
} else {
future.complete(cached.poll());
future.complete(cachedLocations.poll());
}
return future;
}
// Get a random location with specific parameters (note: not cached).
public CompletableFuture<Location> getRandomLocation(final Location center, final double minRange, final double maxRange) {
return attemptRandomLocation(this.getFindAttempts(), center, minRange, maxRange);
}
// Prompts caching random valid locations, up to a maximum number of attempts.
public void cacheRandomLocations(final String name) {
// Prompts caching random valid locations, up to a maximum number of attempts
public void cacheRandomLocations(final Location center, final double minRange, final double maxRange) {
ess.getServer().getScheduler().scheduleSyncDelayedTask(ess, () -> {
for (int i = 0; i < this.getFindAttempts(); ++i) {
calculateRandomLocation(getCenter(name), getMinRange(name), getMaxRange(name)).thenAccept(location -> {
calculateRandomLocation(center, minRange, maxRange).thenAccept(location -> {
if (isValidRandomLocation(location)) {
this.getCachedLocations(name).add(location);
this.getCachedLocations().add(location);
}
});
}
@@ -209,7 +172,7 @@ public class RandomTeleport implements IConf {
final Location location = new Location(
center.getWorld(),
center.getX() + offsetX,
worldInfoProvider.getMaxHeight(center.getWorld()),
ess.getWorldInfoProvider().getMaxHeight(center.getWorld()),
center.getZ() + offsetZ,
360 * RANDOM.nextFloat() - 180,
0
@@ -225,29 +188,24 @@ public class RandomTeleport implements IConf {
return future;
}
// Returns an appropriate elevation for a given location in the nether, or MIN_VALUE if none is found
// Returns an appropriate elevation for a given location in the nether, or -1 if none is found
private double getNetherYAt(final Location location) {
final World world = location.getWorld();
for (int y = 32; y < worldInfoProvider.getMaxHeight(world); ++y) {
if (Material.BEDROCK.equals(world.getBlockAt(location.getBlockX(), y, location.getBlockZ()).getType())) {
break;
}
if (!LocationUtil.isBlockUnsafe(ess, world, location.getBlockX(), y, location.getBlockZ())) {
for (int y = 32; y < ess.getWorldInfoProvider().getMaxHeight(location.getWorld()); ++y) {
if (!LocationUtil.isBlockUnsafe(ess, location.getWorld(), location.getBlockX(), y, location.getBlockZ())) {
return y;
}
}
return Double.MIN_VALUE;
return -1;
}
private boolean isValidRandomLocation(final Location location) {
return location.getBlockY() > worldInfoProvider.getMinHeight(location.getWorld()) && !isExcludedBiome(location);
return location.getBlockY() > ess.getWorldInfoProvider().getMinHeight(location.getWorld()) && !isExcludedBiome(location);
}
// Exclude biome if enum or namespaced key matches
private boolean isExcludedBiome(final Location location) {
final BiomeNameProvider biomeNameProvider = ess.provider(BiomeNameProvider.class);
final Set<String> excluded = getExcludedBiomes();
final String enumKey = biomeNameProvider.getBiomeName(location.getBlock());
final String enumKey = location.getBlock().getBiome().name().toLowerCase();
// Try with good old bukkit enum
if (excluded.contains(enumKey)) {
return true;
@@ -257,7 +215,7 @@ public class RandomTeleport implements IConf {
return false;
}
final String biomeKey;
final BiomeKeyProvider biomeKeyProvider = ess.provider(BiomeKeyProvider.class);
final BiomeKeyProvider biomeKeyProvider = ess.getBiomeKeyProvider();
if (biomeKeyProvider != null) {
// Works with custom biome keys
biomeKey = biomeKeyProvider.getBiomeKey(location.getBlock()).toString();
@@ -268,10 +226,6 @@ public class RandomTeleport implements IConf {
return excluded.contains(biomeKey);
}
private String locationKey(final String name, final String key) {
return "locations." + name + "." + key;
}
public File getFile() {
return config.getFile();
}
@@ -1,6 +1,5 @@
package com.earth2me.essentials;
import com.earth2me.essentials.adventure.AdventureUtil;
import com.earth2me.essentials.api.IItemDb;
import com.earth2me.essentials.commands.IEssentialsCommand;
import com.earth2me.essentials.config.ConfigurateUtil;
@@ -9,22 +8,21 @@ import com.earth2me.essentials.signs.EssentialsSign;
import com.earth2me.essentials.signs.Signs;
import com.earth2me.essentials.textreader.IText;
import com.earth2me.essentials.textreader.SimpleTextInput;
import com.earth2me.essentials.utils.AdventureUtil;
import com.earth2me.essentials.utils.EnumUtil;
import com.earth2me.essentials.utils.FormatUtil;
import com.earth2me.essentials.utils.LocationUtil;
import com.earth2me.essentials.utils.NumberUtil;
import net.ess3.api.IEssentials;
import net.ess3.provider.KnownCommandsProvider;
import net.ess3.provider.SyncCommandsProvider;
import net.essentialsx.api.v2.ChatType;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.TextColor;
import net.kyori.adventure.text.minimessage.tag.Tag;
import org.bukkit.ChatColor;
import org.bukkit.Color;
import org.bukkit.Material;
import org.bukkit.command.Command;
import org.bukkit.event.EventPriority;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.Plugin;
import org.spongepowered.configurate.CommentedConfigurationNode;
import java.io.File;
@@ -36,7 +34,6 @@ import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
@@ -44,11 +41,9 @@ import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.logging.Level;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
@@ -58,12 +53,12 @@ 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 String DEFAULT_PRIMARY_COLOR = NamedTextColor.GOLD.toString();
private static final String DEFAULT_SECONDARY_COLOR = NamedTextColor.RED.toString();
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);
private final ChatFormats chatFormats = new ChatFormats();
private final Map<String, String> chatFormats = Collections.synchronizedMap(new HashMap<>());
private int chatRadius = 0;
// #easteregg
private char chatShout = '!';
@@ -91,7 +86,6 @@ public class Settings implements net.ess3.api.ISettings {
private BigDecimal maxMoney = DEFAULT_MAX_MONEY;
private BigDecimal minMoney = DEFAULT_MIN_MONEY;
private boolean economyLog = false;
private boolean economyLogUUID = false;
// #easteregg
private boolean economyLogUpdate = false;
private boolean changeDisplayName = true;
@@ -145,17 +139,12 @@ public class Settings implements net.ess3.api.ISettings {
private boolean isWaterSafe;
private boolean isSafeUsermap;
private boolean logCommandBlockCommands;
private boolean logConsoleCommands;
private Set<Predicate<String>> nickBlacklist;
private boolean resetNickOnNameChange;
private double maxProjectileSpeed;
private boolean removeEffectsOnHeal;
private Map<String, String> worldAliases;
private String primaryColor = DEFAULT_PRIMARY_COLOR;
private String secondaryColor = DEFAULT_SECONDARY_COLOR;
private Set<String> multiplierPerms;
private BigDecimal defaultMultiplier;
private List<String> afkTimeoutCommands = Collections.emptyList();
private Tag primaryColor = DEFAULT_PRIMARY_COLOR;
private Tag secondaryColor = DEFAULT_SECONDARY_COLOR;
public Settings(final IEssentials ess) {
this.ess = ess;
@@ -173,16 +162,6 @@ public class Settings implements net.ess3.api.ISettings {
return config.getBoolean("respawn-at-home", false);
}
@Override
public String getRandomSpawnLocation() {
return config.getString("random-spawn-location", "none");
}
@Override
public String getRandomRespawnLocation() {
return config.getString("random-respawn-location", "none");
}
@Override
public boolean isRespawnAtAnchor() {
return config.getBoolean("respawn-at-anchor", false);
@@ -209,7 +188,7 @@ public class Settings implements net.ess3.api.ISettings {
final Set<String> homeList = getMultipleHomes();
if (homeList != null) {
for (final String set : homeList) {
if (user.isAuthorized("essentials.sethome.multiple." + set) && limit < getHomeLimit(set)) {
if (user.isAuthorized("essentials.sethome.multiple." + set) && (limit < getHomeLimit(set))) {
limit = getHomeLimit(set);
}
}
@@ -269,11 +248,6 @@ public class Settings implements net.ess3.api.ISettings {
return config.getBoolean("chat.question-enabled", true);
}
@Override
public boolean isUsePaperChatEvent() {
return config.getBoolean("chat.paper-chat-events", true);
}
public boolean _isTeleportSafetyEnabled() {
return config.getBoolean("teleport-safety", true);
}
@@ -348,11 +322,9 @@ public class Settings implements net.ess3.api.ISettings {
}
private void _addAlternativeCommand(final String label, final Command current) {
final KnownCommandsProvider knownCommandsProvider = ess.provider(KnownCommandsProvider.class);
Command cmd = ess.getAlternativeCommandsHandler().getAlternative(label);
if (cmd == null) {
for (final Map.Entry<String, Command> entry : knownCommandsProvider.getKnownCommands().entrySet()) {
for (final Map.Entry<String, Command> entry : ess.getKnownCommandsProvider().getKnownCommands().entrySet()) {
final String[] split = entry.getKey().split(":");
if (entry.getValue() != current && split[split.length - 1].equals(label)) {
cmd = entry.getValue();
@@ -362,7 +334,7 @@ public class Settings implements net.ess3.api.ISettings {
}
if (cmd != null) {
knownCommandsProvider.getKnownCommands().put(label, cmd);
ess.getKnownCommandsProvider().getKnownCommands().put(label, cmd);
}
}
@@ -509,20 +481,11 @@ public class Settings implements net.ess3.api.ISettings {
return config.getString("nickname-prefix", "~");
}
private boolean _resetNickOnNameChange() {
return config.getBoolean("reset-nick-on-name-change", false);
}
@Override
public String getNicknamePrefix() {
return nicknamePrefix;
}
@Override
public boolean isResetNickOnNameChange() {
return resetNickOnNameChange;
}
@Override
public double getTeleportCooldown() {
return config.getDouble("teleport-cooldown", 0);
@@ -616,132 +579,32 @@ public class Settings implements net.ess3.api.ISettings {
@Override
public String getChatFormat(final String group) {
return getChatFormat(group, null);
}
@Override
public String getChatFormat(final String group, final ChatType chatType) {
final String mFormat = chatFormats.getFormat(group, chatType, new ChatFormatConfigSupplier(group, chatType));
String mFormat = chatFormats.get(group);
if (mFormat == null) {
mFormat = config.getString("chat.group-formats." + (group == null ? "Default" : group), config.getString("chat.format", "&7[{GROUP}]&r {DISPLAYNAME}&7:&r {MESSAGE}"));
mFormat = FormatUtil.replaceFormat(mFormat);
mFormat = mFormat.replace("{DISPLAYNAME}", "%1$s");
mFormat = mFormat.replace("{MESSAGE}", "%2$s");
mFormat = mFormat.replace("{GROUP}", "{0}");
mFormat = mFormat.replace("{WORLD}", "{1}");
mFormat = mFormat.replace("{WORLDNAME}", "{1}");
mFormat = mFormat.replace("{SHORTWORLDNAME}", "{2}");
mFormat = mFormat.replace("{TEAMPREFIX}", "{3}");
mFormat = mFormat.replace("{TEAMSUFFIX}", "{4}");
mFormat = mFormat.replace("{TEAMNAME}", "{5}");
mFormat = mFormat.replace("{PREFIX}", "{6}");
mFormat = mFormat.replace("{SUFFIX}", "{7}");
mFormat = mFormat.replace("{USERNAME}", "{8}");
mFormat = mFormat.replace("{NICKNAME}", "{9}");
mFormat = "§r".concat(mFormat);
chatFormats.put(group, mFormat);
}
if (isDebug()) {
ess.getLogger().info(String.format("Found format '%s' for group '%s'", mFormat, group));
}
return mFormat;
}
private class ChatFormatConfigSupplier implements Supplier<String> {
private final String group;
private final ChatType chatType;
ChatFormatConfigSupplier(String group, ChatType chatType) {
this.group = group;
this.chatType = chatType;
}
@Override
public String get() {
final String chatKey = chatType.key();
final String groupPath = "chat.group-formats." + (group == null ? "Default" : group);
String configFormat = config.getString(groupPath + "." + chatKey, null);
if (configFormat == null) {
configFormat = config.getString(groupPath, null);
}
final String formatPath = "chat.format";
if (configFormat == null) {
configFormat = config.getString(formatPath + "." + chatKey, null);
}
if (configFormat == null) {
configFormat = config.getString(formatPath, null);
}
if (configFormat == null) {
configFormat = "&7[{GROUP}]&r {DISPLAYNAME}&7:&r {MESSAGE}";
}
configFormat = FormatUtil.replaceFormat(configFormat);
configFormat = configFormat.replace("{DISPLAYNAME}", "%1$s");
configFormat = configFormat.replace("{MESSAGE}", "%2$s");
configFormat = configFormat.replace("{GROUP}", "{0}");
configFormat = configFormat.replace("{WORLD}", "{1}");
configFormat = configFormat.replace("{WORLDNAME}", "{1}");
configFormat = configFormat.replace("{SHORTWORLDNAME}", "{2}");
configFormat = configFormat.replace("{TEAMPREFIX}", "{3}");
configFormat = configFormat.replace("{TEAMSUFFIX}", "{4}");
configFormat = configFormat.replace("{TEAMNAME}", "{5}");
configFormat = configFormat.replace("{PREFIX}", "{6}");
configFormat = configFormat.replace("{SUFFIX}", "{7}");
configFormat = configFormat.replace("{USERNAME}", "{8}");
configFormat = configFormat.replace("{NICKNAME}", "{9}");
configFormat = "§r".concat(configFormat);
return configFormat;
}
}
private static class ChatFormats {
private final Map<String, TypedChatFormat> groupFormats;
private TypedChatFormat defaultFormat;
ChatFormats() {
defaultFormat = null;
groupFormats = new HashMap<>();
}
public String getFormat(String group, ChatType type, Supplier<String> configSupplier) {
// With such a large synchronize block, we synchronize a potential config deserialization
// It does not matter as it needs to be done. It's even better as we ensure to do it once
// TypedChatFormat is also synchronized
synchronized (this) {
final TypedChatFormat typedChatFormat;
if (group == null) {
if (defaultFormat == null) {
defaultFormat = new TypedChatFormat();
}
typedChatFormat = defaultFormat;
} else {
typedChatFormat = groupFormats.computeIfAbsent(group, s -> new TypedChatFormat());
}
return typedChatFormat.getFormat(type, configSupplier);
}
}
public void clear() {
synchronized (this) {
defaultFormat = null;
groupFormats.clear();
}
}
}
private static class TypedChatFormat {
private final Map<ChatType, String> typedFormats;
private String defaultFormat;
TypedChatFormat() {
defaultFormat = null;
typedFormats = new EnumMap<>(ChatType.class);
}
public String getFormat(ChatType type, Supplier<String> configSupplier) {
final String format;
if (type == null) {
if (defaultFormat == null) {
defaultFormat = configSupplier.get();
}
format = defaultFormat;
} else {
format = typedFormats.computeIfAbsent(type, c -> configSupplier.get());
}
return format;
}
}
@Override
public String getWorldAlias(String world) {
return worldAliases.getOrDefault(world.toLowerCase(), world);
@@ -830,32 +693,18 @@ public class Settings implements net.ess3.api.ISettings {
overriddenCommands = _getOverriddenCommands();
playerCommands = _getPlayerCommands();
final KnownCommandsProvider knownCommandsProvider = ess.provider(KnownCommandsProvider.class);
// This will be late loaded
if (knownCommandsProvider != null) {
if (ess.getKnownCommandsProvider() != null) {
boolean mapModified = false;
if (!disabledBukkitCommands.isEmpty()) {
if (isDebug()) {
ess.getLogger().log(Level.INFO, "Re-adding " + disabledBukkitCommands.size() + " disabled commands!");
}
knownCommandsProvider.getKnownCommands().putAll(disabledBukkitCommands);
ess.getKnownCommandsProvider().getKnownCommands().putAll(disabledBukkitCommands);
disabledBukkitCommands.clear();
mapModified = true;
}
if (reloadCount.get() < 2) {
// on startup: add plugins again in case they registered commands with the new API
// we need to schedule this task before any of the below tasks using _addAlternativeCommand.
ess.scheduleSyncDelayedTask(() -> {
for (final Plugin plugin : ess.getServer().getPluginManager().getPlugins()) {
if (plugin.isEnabled()) {
ess.getAlternativeCommandsHandler().addPlugin(plugin);
}
}
});
}
for (final String command : disabledCommands) {
final String effectiveAlias = command.toLowerCase(Locale.ENGLISH);
final Command toDisable = ess.getPluginCommand(effectiveAlias);
@@ -863,7 +712,7 @@ public class Settings implements net.ess3.api.ISettings {
if (isDebug()) {
ess.getLogger().log(Level.INFO, "Attempting removal of " + effectiveAlias);
}
final Command removed = knownCommandsProvider.getKnownCommands().remove(effectiveAlias);
final Command removed = ess.getKnownCommandsProvider().getKnownCommands().remove(effectiveAlias);
if (removed != null) {
if (isDebug()) {
ess.getLogger().log(Level.INFO, "Adding command " + effectiveAlias + " to disabled map!");
@@ -881,22 +730,19 @@ public class Settings implements net.ess3.api.ISettings {
}
}
final SyncCommandsProvider syncCommandsProvider = ess.provider(SyncCommandsProvider.class);
if (mapModified) {
if (isDebug()) {
ess.getLogger().log(Level.INFO, "Syncing commands");
}
if (reloadCount.get() < 2) {
ess.scheduleSyncDelayedTask(syncCommandsProvider::syncCommands);
ess.scheduleSyncDelayedTask(() -> ess.getSyncCommandsProvider().syncCommands());
} else {
syncCommandsProvider.syncCommands();
ess.getSyncCommandsProvider().syncCommands();
}
}
}
nicknamePrefix = _getNicknamePrefix();
resetNickOnNameChange = _resetNickOnNameChange();
operatorColor = _getOperatorColor();
changePlayerListName = _changePlayerListName();
configDebug = _isDebug();
@@ -916,7 +762,6 @@ public class Settings implements net.ess3.api.ISettings {
permissionsLagWarning = _getPermissionsLagWarning();
economyLagWarning = _getEconomyLagWarning();
economyLog = _isEcoLogEnabled();
economyLogUUID = _isEcoLogUUIDEnabled();
economyLogUpdate = _isEcoLogUpdateEnabled();
economyDisabled = _isEcoDisabled();
allowSilentJoin = _allowSilentJoinQuit();
@@ -941,7 +786,6 @@ public class Settings implements net.ess3.api.ISettings {
isWaterSafe = _isWaterSafe();
isSafeUsermap = _isSafeUsermap();
logCommandBlockCommands = _logCommandBlockCommands();
logConsoleCommands = _logConsoleCommands();
nickBlacklist = _getNickBlacklist();
maxProjectileSpeed = _getMaxProjectileSpeed();
removeEffectsOnHeal = _isRemovingEffectsOnHeal();
@@ -951,9 +795,6 @@ public class Settings implements net.ess3.api.ISettings {
worldAliases = _getWorldAliases();
primaryColor = _getPrimaryColor();
secondaryColor = _getSecondaryColor();
multiplierPerms = _getMultiplierPerms();
defaultMultiplier = _getDefaultMultiplier();
afkTimeoutCommands = _getAfkTimeoutCommands();
reloadCount.incrementAndGet();
}
@@ -984,7 +825,7 @@ public class Settings implements net.ess3.api.ISettings {
final ItemStack iStack = itemDb.get(itemName);
epItemSpwn.add(iStack.getType());
} catch (final Exception ex) {
ess.getLogger().log(Level.SEVERE, ess.getAdventureFacet().miniToLegacy(tlLiteral("unknownItemInList", itemName, "item-spawn-blacklist")), ex);
ess.getLogger().log(Level.SEVERE, AdventureUtil.miniToLegacy(tlLiteral("unknownItemInList", itemName, "item-spawn-blacklist")), ex);
}
}
return epItemSpwn;
@@ -1012,7 +853,7 @@ public class Settings implements net.ess3.api.ISettings {
try {
newSigns.add(Signs.valueOf(signName).getSign());
} catch (final Exception ex) {
ess.getLogger().log(Level.SEVERE, ess.getAdventureFacet().miniToLegacy(tlLiteral("unknownItemInList", signName, "enabledSigns")));
ess.getLogger().log(Level.SEVERE, AdventureUtil.miniToLegacy(tlLiteral("unknownItemInList", signName, "enabledSigns")));
continue;
}
signsEnabled = true;
@@ -1112,23 +953,14 @@ public class Settings implements net.ess3.api.ISettings {
}
@Override
public List<String> getProtectListRaw(String configName) {
final List<String> list = new ArrayList<>();
public List<Material> getProtectList(final String configName) {
final List<Material> list = new ArrayList<>();
for (String itemName : config.getString(configName, "").split(",")) {
itemName = itemName.trim();
if (itemName.isEmpty()) {
continue;
}
list.add(itemName);
}
return list;
}
@Override
public List<Material> getProtectList(final String configName) {
final List<Material> list = new ArrayList<>();
for (String itemName : getProtectListRaw(configName)) {
Material mat = EnumUtil.getMaterial(itemName.toUpperCase());
if (mat == null) {
@@ -1140,7 +972,7 @@ public class Settings implements net.ess3.api.ISettings {
}
if (mat == null) {
ess.getLogger().log(Level.SEVERE, ess.getAdventureFacet().miniToLegacy(tlLiteral("unknownItemInList", itemName, configName)));
ess.getLogger().log(Level.SEVERE, AdventureUtil.miniToLegacy(tlLiteral("unknownItemInList", itemName, configName)));
} else {
list.add(mat);
}
@@ -1189,14 +1021,6 @@ public class Settings implements net.ess3.api.ISettings {
return config.getBoolean("economy-log-enabled", false);
}
public boolean _isEcoLogUUIDEnabled() {
return config.getBoolean("economy-log-uuids", false);
}
public boolean isEcoLogUUIDEnabled() {
return economyLogUUID;
}
@Override
public boolean isEcoLogUpdateEnabled() {
return economyLogUpdate;
@@ -1286,17 +1110,8 @@ public class Settings implements net.ess3.api.ISettings {
}
@Override
public long getAutoAfkTimeout() {
return config.getLong("auto-afk-timeout", config.getLong("auto-afk-kick", -1));
}
private List<String> _getAfkTimeoutCommands() {
return new ArrayList<>(config.getList("afk-timeout-commands", String.class));
}
@Override
public List<String> getAfkTimeoutCommands() {
return afkTimeoutCommands;
public long getAutoAfkKick() {
return config.getLong("auto-afk-kick", -1);
}
@Override
@@ -1331,11 +1146,6 @@ public class Settings implements net.ess3.api.ISettings {
return config.getBoolean("cancel-afk-on-chat", true);
}
@Override
public boolean cancelAfkOnFish() {
return config.getBoolean("cancel-afk-on-fish", true);
}
@Override
public boolean sleepIgnoresAfkPlayers() {
return sleepIgnoresAfkPlayers;
@@ -1657,11 +1467,6 @@ public class Settings implements net.ess3.api.ISettings {
return config.getBoolean("use-custom-server-full-message", true);
}
@Override
public boolean isCustomWhitelistMessage() {
return config.getBoolean("use-custom-whitelist-message", true);
}
@Override
public int getJoinQuitMessagePlayerCount() {
return config.getInt("hide-join-quit-messages-above", -1);
@@ -1915,7 +1720,7 @@ public class Settings implements net.ess3.api.ISettings {
try {
newSigns.add(Signs.valueOf(signName).getSign());
} catch (final Exception ex) {
ess.getLogger().log(Level.SEVERE, ess.getAdventureFacet().miniToLegacy(tlLiteral("unknownItemInList", signName, "unprotected-sign-names")));
ess.getLogger().log(Level.SEVERE, AdventureUtil.miniToLegacy(tlLiteral("unknownItemInList", signName, "unprotected-sign-names")));
}
}
return newSigns;
@@ -1976,16 +1781,6 @@ public class Settings implements net.ess3.api.ISettings {
return config.getBoolean("world-change-fly-reset", true);
}
@Override
public boolean isWorldChangePreserveFlying() {
return config.getBoolean("world-change-preserve-flying", true);
}
@Override
public boolean isGamemodeChangePreserveFlying() {
return config.getBoolean("gamemode-change-preserve-flying", false);
}
@Override
public boolean isWorldChangeSpeedResetEnabled() {
return config.getBoolean("world-change-speed-reset", true);
@@ -1993,7 +1788,9 @@ public class Settings implements net.ess3.api.ISettings {
private List<String> _getDefaultEnabledConfirmCommands() {
final List<String> commands = config.getList("default-enabled-confirm-commands", String.class);
commands.replaceAll(String::toLowerCase);
for (int i = 0; i < commands.size(); i++) {
commands.set(i, commands.get(i).toLowerCase());
}
return commands;
}
@@ -2101,15 +1898,6 @@ public class Settings implements net.ess3.api.ISettings {
return logCommandBlockCommands;
}
private boolean _logConsoleCommands() {
return config.getBoolean("log-console-commands", true);
}
@Override
public boolean logConsoleCommands() {
return logConsoleCommands;
}
private Set<Predicate<String>> _getNickBlacklist() {
final Set<Predicate<String>> blacklist = new HashSet<>();
@@ -2178,93 +1966,45 @@ public class Settings implements net.ess3.api.ISettings {
}
@Override
public String getNickRegex() {
return config.getString("allowed-nicks-regex", "^[a-zA-Z_0-9§]+$");
}
@Override
public BigDecimal getMultiplier(final User user) {
BigDecimal multiplier = defaultMultiplier;
if (multiplierPerms == null) {
return defaultMultiplier;
}
for (final String multiplierPerm : multiplierPerms) {
if (user.isAuthorized("essentials.sell.multiplier." + multiplierPerm)) {
final BigDecimal value = config.getBigDecimal("sell-multipliers." + multiplierPerm, BigDecimal.ZERO);
if (value.compareTo(multiplier) > 0) {
multiplier = value;
}
}
}
return multiplier;
}
private BigDecimal _getDefaultMultiplier() {
return config.getBigDecimal("sell-multipliers.default", BigDecimal.ONE);
}
private Set<String> _getMultiplierPerms() {
final CommentedConfigurationNode section = config.getSection("sell-multipliers");
return section == null ? null : ConfigurateUtil.getKeys(section);
}
public int getMaxItemLore() {
return config.getInt("max-itemlore-lines", 10);
}
@Override
public String getPrimaryColor() {
public Tag getPrimaryColor() {
return primaryColor;
}
private String _getPrimaryColor() {
private Tag _getPrimaryColor() {
final String color = config.getString("message-colors.primary", "#ffaa00");
final String textColor = _getTagColor(color);
return textColor != null ? textColor : DEFAULT_PRIMARY_COLOR;
final TextColor textColor = _getTagColor(color);
return textColor != null ? Tag.styling(textColor) : DEFAULT_PRIMARY_COLOR;
}
@Override
public String getSecondaryColor() {
public Tag getSecondaryColor() {
return secondaryColor;
}
private String _getSecondaryColor() {
private Tag _getSecondaryColor() {
final String color = config.getString("message-colors.secondary", "#ff5555");
final String textColor = _getTagColor(color);
return textColor != null ? textColor : DEFAULT_SECONDARY_COLOR;
final TextColor textColor = _getTagColor(color);
return textColor != null ? Tag.styling(textColor) : DEFAULT_SECONDARY_COLOR;
}
private String _getTagColor(final String color) {
private TextColor _getTagColor(final String color) {
try {
if (color.startsWith("#") && color.length() == 7 && NumberUtil.isHexadecimal(color.substring(1))) {
Color.fromRGB(Integer.decode(color));
return color;
return TextColor.color(Color.fromRGB(Integer.decode(color)).asRGB());
}
if (color.length() == 1) {
return Objects.requireNonNull(AdventureUtil.fromChar(color.charAt(0))).toString();
return AdventureUtil.fromChar(color.charAt(0));
}
return Objects.requireNonNull(NamedTextColor.NAMES.value(color.toLowerCase(Locale.ENGLISH))).toString();
} catch (NullPointerException | IllegalArgumentException ignored) {
return NamedTextColor.NAMES.value(color.toLowerCase(Locale.ENGLISH));
} catch (IllegalArgumentException ignored) {
}
return null;
}
@Override
public BigDecimal getBaltopMinBalance() {
return config.getBigDecimal("baltop-requirements.minimum-balance", BigDecimal.ZERO);
}
@Override
public int getBaltopEntryLimit() {
return config.getInt("baltop-entry-limit", -1);
}
@Override
public long getBaltopMinPlaytime() {
return config.getLong("baltop-requirements.minimum-playtime", 0);
}
}
@@ -0,0 +1,402 @@
package com.earth2me.essentials;
import com.earth2me.essentials.utils.DateUtil;
import com.earth2me.essentials.utils.LocationUtil;
import io.papermc.lib.PaperLib;
import net.ess3.api.IEssentials;
import net.ess3.api.ITeleport;
import net.ess3.api.IUser;
import net.ess3.api.TranslatableException;
import net.ess3.api.events.UserWarpEvent;
import net.ess3.api.events.teleport.PreTeleportEvent;
import net.ess3.api.events.teleport.TeleportWarmupEvent;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerRespawnEvent;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import java.math.BigDecimal;
import java.util.Calendar;
import java.util.GregorianCalendar;
/**
* @deprecated This API is not asynchronous. Use {@link com.earth2me.essentials.AsyncTeleport AsyncTeleport}
*/
@Deprecated
public class Teleport implements ITeleport {
private final IUser teleportOwner;
private final IEssentials ess;
private TimedTeleport timedTeleport;
private TeleportType tpType;
@Deprecated
public Teleport(final IUser user, final IEssentials ess) {
this.teleportOwner = user;
this.ess = ess;
tpType = TeleportType.NORMAL;
}
@Deprecated
public void cooldown(final boolean check) throws Exception {
final Calendar time = new GregorianCalendar();
if (teleportOwner.getLastTeleportTimestamp() > 0) {
// Take the current time, and remove the delay from it.
final double cooldown = ess.getSettings().getTeleportCooldown();
final Calendar earliestTime = new GregorianCalendar();
earliestTime.add(Calendar.SECOND, -(int) cooldown);
earliestTime.add(Calendar.MILLISECOND, -(int) ((cooldown * 1000.0) % 1000.0));
// This value contains the most recent time a teleportPlayer could have been used that would allow another use.
final long earliestLong = earliestTime.getTimeInMillis();
// When was the last teleportPlayer used?
final long lastTime = teleportOwner.getLastTeleportTimestamp();
if (lastTime > time.getTimeInMillis()) {
// This is to make sure time didn't get messed up on last teleportPlayer use.
// If this happens, let's give the user the benifit of the doubt.
teleportOwner.setLastTeleportTimestamp(time.getTimeInMillis());
return;
} else if (lastTime > earliestLong
&& cooldownApplies()) {
time.setTimeInMillis(lastTime);
time.add(Calendar.SECOND, (int) cooldown);
time.add(Calendar.MILLISECOND, (int) ((cooldown * 1000.0) % 1000.0));
throw new TranslatableException("timeBeforeTeleport", DateUtil.formatDateDiff(time.getTimeInMillis()));
}
}
// if justCheck is set, don't update lastTeleport; we're just checking
if (!check) {
teleportOwner.setLastTeleportTimestamp(time.getTimeInMillis());
}
}
@Deprecated
private boolean cooldownApplies() {
boolean applies = true;
final String globalBypassPerm = "essentials.teleport.cooldown.bypass";
switch (tpType) {
case NORMAL:
applies = !teleportOwner.isAuthorized(globalBypassPerm);
break;
case BACK:
applies = !(teleportOwner.isAuthorized(globalBypassPerm) &&
teleportOwner.isAuthorized("essentials.teleport.cooldown.bypass.back"));
break;
case TPA:
applies = !(teleportOwner.isAuthorized(globalBypassPerm) &&
teleportOwner.isAuthorized("essentials.teleport.cooldown.bypass.tpa"));
break;
}
return applies;
}
@Deprecated
private void warnUser(final IUser user, final double delay) {
final Calendar c = new GregorianCalendar();
c.add(Calendar.SECOND, (int) delay);
c.add(Calendar.MILLISECOND, (int) ((delay * 1000.0) % 1000.0));
user.sendTl("dontMoveMessage", DateUtil.formatDateDiff(c.getTimeInMillis()));
}
//The now function is used when you want to skip tp delay when teleporting someone to a location or player.
@Override
@Deprecated
public void now(final Location loc, final boolean cooldown, final TeleportCause cause) throws Exception {
if (cooldown) {
cooldown(false);
}
final ITarget target = new LocationTarget(loc);
now(teleportOwner, target, cause);
}
@Override
@Deprecated
public void now(final Player entity, final boolean cooldown, final TeleportCause cause) throws Exception {
if (cooldown) {
cooldown(false);
}
final ITarget target = new PlayerTarget(entity);
now(teleportOwner, target, cause);
teleportOwner.sendTl("teleporting", target.getLocation().getWorld().getName(), target.getLocation().getBlockX(), target.getLocation().getBlockY(), target.getLocation().getBlockZ());
}
@Deprecated
protected void now(final IUser teleportee, final ITarget target, final TeleportCause cause) throws Exception {
cancel(false);
Location loc = target.getLocation();
final PreTeleportEvent event = new PreTeleportEvent(teleportee, cause, target);
Bukkit.getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
return;
}
if (teleportee.isAuthorized("essentials.back.onteleport")) {
teleportee.setLastLocation();
}
if (!teleportee.getBase().isEmpty()) {
if (!ess.getSettings().isTeleportPassengerDismount()) {
throw new TranslatableException("passengerTeleportFail");
}
teleportee.getBase().eject();
}
if (LocationUtil.isBlockUnsafeForUser(ess, teleportee, loc.getWorld(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ())) {
if (ess.getSettings().isTeleportSafetyEnabled()) {
if (ess.getSettings().isForceDisableTeleportSafety()) {
PaperLib.teleportAsync(teleportee.getBase(), loc, cause);
} else {
PaperLib.teleportAsync(teleportee.getBase(), LocationUtil.getSafeDestination(ess, teleportee, loc), cause);
}
} else {
throw new TranslatableException("unsafeTeleportDestination", loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
}
} else {
if (ess.getSettings().isForceDisableTeleportSafety()) {
PaperLib.teleportAsync(teleportee.getBase(), loc, cause);
} else {
if (ess.getSettings().isTeleportToCenterLocation()) {
loc = LocationUtil.getRoundedDestination(loc);
}
PaperLib.teleportAsync(teleportee.getBase(), loc, cause);
}
}
}
//The teleportPlayer function is used when you want to normally teleportPlayer someone to a location or player.
//This method is nolonger used internally and will be removed.
@Deprecated
@Override
public void teleport(final Location loc, final Trade chargeFor) throws Exception {
teleport(loc, chargeFor, TeleportCause.PLUGIN);
}
@Override
@Deprecated
public void teleport(final Location loc, final Trade chargeFor, final TeleportCause cause) throws Exception {
teleport(teleportOwner, new LocationTarget(loc), chargeFor, cause);
}
//This is used when teleporting to a player
@Override
@Deprecated
public void teleport(final Player entity, final Trade chargeFor, final TeleportCause cause) throws Exception {
final ITarget target = new PlayerTarget(entity);
teleportOwner.sendTl("teleportToPlayer", entity.getDisplayName());
teleport(teleportOwner, target, chargeFor, cause);
}
//This is used when teleporting to stored location
@Override
@Deprecated
public void teleportPlayer(final IUser teleportee, final Location loc, final Trade chargeFor, final TeleportCause cause) throws Exception {
teleport(teleportee, new LocationTarget(loc), chargeFor, cause);
}
//This is used on /tphere
@Override
@Deprecated
public void teleportPlayer(final IUser teleportee, final Player entity, final Trade chargeFor, final TeleportCause cause) throws Exception {
final ITarget target = new PlayerTarget(entity);
teleport(teleportee, target, chargeFor, cause);
teleportee.sendTl("teleporting", target.getLocation().getWorld().getName(), target.getLocation().getBlockX(), target.getLocation().getBlockY(), target.getLocation().getBlockZ());
teleportOwner.sendTl("teleporting", target.getLocation().getWorld().getName(), target.getLocation().getBlockX(), target.getLocation().getBlockY(), target.getLocation().getBlockZ());
}
@Deprecated
private void teleport(final IUser teleportee, final ITarget target, final Trade chargeFor, final TeleportCause cause) throws Exception {
double delay = ess.getSettings().getTeleportDelay();
final TeleportWarmupEvent event = new TeleportWarmupEvent(teleportee, cause, target, delay);
Bukkit.getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
return;
}
delay = event.getDelay();
Trade cashCharge = chargeFor;
if (chargeFor != null) {
chargeFor.isAffordableFor(teleportOwner);
//This code is to make sure that commandcosts are checked in the initial world, and not in the resulting world.
if (!chargeFor.getCommandCost(teleportOwner).equals(BigDecimal.ZERO)) {
//By converting a command cost to a regular cost, the command cost permission isn't checked when executing the charge after teleport.
cashCharge = new Trade(chargeFor.getCommandCost(teleportOwner), ess);
}
}
cooldown(true);
if (delay <= 0 || teleportOwner.isAuthorized("essentials.teleport.timer.bypass") || teleportee.isAuthorized("essentials.teleport.timer.bypass")) {
cooldown(false);
now(teleportee, target, cause);
if (cashCharge != null) {
cashCharge.charge(teleportOwner);
}
return;
}
cancel(false);
warnUser(teleportee, delay);
initTimer((long) (delay * 1000.0), teleportee, target, cashCharge, cause, false);
}
@Deprecated
private void teleportOther(final IUser teleporter, final IUser teleportee, final ITarget target, final Trade chargeFor, final TeleportCause cause) throws Exception {
double delay = ess.getSettings().getTeleportDelay();
final TeleportWarmupEvent event = new TeleportWarmupEvent(teleporter, teleportee, cause, target, delay);
Bukkit.getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
return;
}
delay = event.getDelay();
Trade cashCharge = chargeFor;
if (teleporter != null && chargeFor != null) {
chargeFor.isAffordableFor(teleporter);
//This code is to make sure that commandcosts are checked in the initial world, and not in the resulting world.
if (!chargeFor.getCommandCost(teleporter).equals(BigDecimal.ZERO)) {
//By converting a command cost to a regular cost, the command cost permission isn't checked when executing the charge after teleport.
cashCharge = new Trade(chargeFor.getCommandCost(teleporter), ess);
}
}
cooldown(true);
if (delay <= 0 || teleporter == null
|| teleporter.isAuthorized("essentials.teleport.timer.bypass")
|| teleportOwner.isAuthorized("essentials.teleport.timer.bypass")
|| teleportee.isAuthorized("essentials.teleport.timer.bypass")) {
cooldown(false);
now(teleportee, target, cause);
if (teleporter != null && cashCharge != null) {
cashCharge.charge(teleporter);
}
return;
}
cancel(false);
warnUser(teleportee, delay);
initTimer((long) (delay * 1000.0), teleportee, target, cashCharge, cause, false);
}
//The respawn function is a wrapper used to handle tp fallback, on /jail and /home
@Override
@Deprecated
public void respawn(final Trade chargeFor, final TeleportCause cause) throws Exception {
double delay = ess.getSettings().getTeleportDelay();
final TeleportWarmupEvent event = new TeleportWarmupEvent(teleportOwner, cause, null, delay);
Bukkit.getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
return;
}
delay = event.getDelay();
if (chargeFor != null) {
chargeFor.isAffordableFor(teleportOwner);
}
cooldown(true);
if (delay <= 0 || teleportOwner.isAuthorized("essentials.teleport.timer.bypass")) {
cooldown(false);
respawnNow(teleportOwner, cause);
if (chargeFor != null) {
chargeFor.charge(teleportOwner);
}
return;
}
cancel(false);
warnUser(teleportOwner, delay);
initTimer((long) (delay * 1000.0), teleportOwner, null, chargeFor, cause, true);
}
@Deprecated
void respawnNow(final IUser teleportee, final TeleportCause cause) throws Exception {
final Player player = teleportee.getBase();
final Location bed = player.getBedSpawnLocation();
if (bed != null) {
now(teleportee, new LocationTarget(bed), cause);
} else {
if (ess.getSettings().isDebug()) {
ess.getLogger().info("Could not find bed spawn, forcing respawn event.");
}
final PlayerRespawnEvent pre = new PlayerRespawnEvent(player, player.getWorld().getSpawnLocation(), false);
ess.getServer().getPluginManager().callEvent(pre);
now(teleportee, new LocationTarget(pre.getRespawnLocation()), cause);
}
}
//The warp function is a wrapper used to teleportPlayer a player to a /warp
@Override
@Deprecated
public void warp(final IUser teleportee, String warp, final Trade chargeFor, final TeleportCause cause) throws Exception {
final UserWarpEvent event = new UserWarpEvent(teleportee, warp, chargeFor);
Bukkit.getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
return;
}
warp = event.getWarp();
final Location loc = ess.getWarps().getWarp(warp);
teleportee.sendTl("warpingTo", warp, loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
if (!teleportee.equals(teleportOwner)) {
teleportOwner.sendTl("warpingTo", warp, loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
}
teleport(teleportee, new LocationTarget(loc), chargeFor, cause);
}
//The back function is a wrapper used to teleportPlayer a player /back to their previous location.
@Override
@Deprecated
public void back(final Trade chargeFor) throws Exception {
back(teleportOwner, chargeFor);
}
//This function is a wrapper over the other back function for cases where another player performs back for them
@Override
@Deprecated
public void back(final IUser teleporter, final Trade chargeFor) throws Exception {
tpType = TeleportType.BACK;
final Location loc = teleportOwner.getLastLocation();
teleportOwner.sendTl("backUsageMsg", loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
teleportOther(teleporter, teleportOwner, new LocationTarget(loc), chargeFor, TeleportCause.COMMAND);
}
//This function is used to throw a user back after a jail sentence
@Override
@Deprecated
public void back() throws Exception {
now(teleportOwner, new LocationTarget(teleportOwner.getLastLocation()), TeleportCause.COMMAND);
}
@Deprecated
public void setTpType(final TeleportType tpType) {
this.tpType = tpType;
}
//If we need to cancelTimer a pending teleportPlayer call this method
@Deprecated
private void cancel(final boolean notifyUser) {
if (timedTeleport != null) {
timedTeleport.cancelTimer(notifyUser);
timedTeleport = null;
}
}
@Deprecated
private void initTimer(final long delay, final IUser teleportUser, final ITarget target, final Trade chargeFor, final TeleportCause cause, final boolean respawn) {
timedTeleport = new TimedTeleport(teleportOwner, ess, this, delay, teleportUser, target, chargeFor, cause, respawn);
}
public enum TeleportType {
TPA,
BACK,
NORMAL
}
}
@@ -0,0 +1,138 @@
package com.earth2me.essentials;
import net.ess3.api.IEssentials;
import net.ess3.api.IUser;
import org.bukkit.Location;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import java.util.UUID;
@Deprecated
public class TimedTeleport implements Runnable {
private static final double MOVE_CONSTANT = 0.3;
private final IUser teleportOwner;
private final IEssentials ess;
private final Teleport teleport;
private final UUID timer_teleportee;
private final long timer_started; // time this task was initiated
private final long timer_delay; // how long to delay the teleportPlayer
// note that I initially stored a clone of the location for reference, but...
// when comparing locations, I got incorrect mismatches (rounding errors, looked like)
// so, the X/Y/Z values are stored instead and rounded off
private final long timer_initX;
private final long timer_initY;
private final long timer_initZ;
private final ITarget timer_teleportTarget;
private final boolean timer_respawn;
private final boolean timer_canMove;
private final Trade timer_chargeFor;
private final TeleportCause timer_cause;
private int timer_task;
private double timer_health;
TimedTeleport(final IUser user, final IEssentials ess, final Teleport teleport, final long delay, final IUser teleportUser, final ITarget target, final Trade chargeFor, final TeleportCause cause, final boolean respawn) {
this.teleportOwner = user;
this.ess = ess;
this.teleport = teleport;
this.timer_started = System.currentTimeMillis();
this.timer_delay = delay;
this.timer_health = teleportUser.getBase().getHealth();
this.timer_initX = Math.round(teleportUser.getBase().getLocation().getX() * MOVE_CONSTANT);
this.timer_initY = Math.round(teleportUser.getBase().getLocation().getY() * MOVE_CONSTANT);
this.timer_initZ = Math.round(teleportUser.getBase().getLocation().getZ() * MOVE_CONSTANT);
this.timer_teleportee = teleportUser.getBase().getUniqueId();
this.timer_teleportTarget = target;
this.timer_chargeFor = chargeFor;
this.timer_cause = cause;
this.timer_respawn = respawn;
this.timer_canMove = user.isAuthorized("essentials.teleport.timer.move");
timer_task = ess.runTaskTimerAsynchronously(this, 20, 20).getTaskId();
}
@Override
public void run() {
if (teleportOwner == null || !teleportOwner.getBase().isOnline() || teleportOwner.getBase().getLocation() == null) {
cancelTimer(false);
return;
}
final IUser teleportUser = ess.getUser(this.timer_teleportee);
if (teleportUser == null || !teleportUser.getBase().isOnline()) {
cancelTimer(false);
return;
}
final Location currLocation = teleportUser.getBase().getLocation();
if (currLocation == null) {
cancelTimer(false);
return;
}
if (!timer_canMove && (Math.round(currLocation.getX() * MOVE_CONSTANT) != timer_initX || Math.round(currLocation.getY() * MOVE_CONSTANT) != timer_initY || Math.round(currLocation.getZ() * MOVE_CONSTANT) != timer_initZ || teleportUser.getBase().getHealth() < timer_health)) {
// user moved, cancelTimer teleportPlayer
cancelTimer(true);
return;
}
class DelayedTeleportTask implements Runnable {
@Override
public void run() {
timer_health = teleportUser.getBase().getHealth(); // in case user healed, then later gets injured
final long now = System.currentTimeMillis();
if (now > timer_started + timer_delay) {
try {
teleport.cooldown(false);
} catch (final Exception ex) {
teleportOwner.sendTl("cooldownWithMessage", ex.getMessage());
if (teleportOwner != teleportUser) {
teleportUser.sendTl("cooldownWithMessage", ex.getMessage());
}
}
try {
cancelTimer(false);
teleportUser.sendTl("teleportationCommencing");
if (timer_chargeFor != null) {
timer_chargeFor.isAffordableFor(teleportOwner);
}
if (timer_respawn) {
teleport.respawnNow(teleportUser, timer_cause);
} else {
teleport.now(teleportUser, timer_teleportTarget, timer_cause);
}
if (timer_chargeFor != null) {
timer_chargeFor.charge(teleportOwner);
}
} catch (final Exception ex) {
ess.showError(teleportOwner.getSource(), ex, "\\ teleport");
}
}
}
}
ess.scheduleSyncDelayedTask(new DelayedTeleportTask());
}
//If we need to cancelTimer a pending teleportPlayer call this method
void cancelTimer(final boolean notifyUser) {
if (timer_task == -1) {
return;
}
try {
ess.getServer().getScheduler().cancelTask(timer_task);
if (notifyUser) {
teleportOwner.sendTl("pendingTeleportCancelled");
if (timer_teleportee != null && !timer_teleportee.equals(teleportOwner.getBase().getUniqueId())) {
ess.getUser(timer_teleportee).sendTl("pendingTeleportCancelled");
}
}
} finally {
timer_task = -1;
}
}
}
@@ -2,7 +2,6 @@ package com.earth2me.essentials;
import com.earth2me.essentials.craftbukkit.Inventories;
import com.earth2me.essentials.craftbukkit.SetExpFix;
import com.earth2me.essentials.adventure.AdventureUtil;
import com.earth2me.essentials.utils.NumberUtil;
import com.earth2me.essentials.utils.VersionUtil;
import net.ess3.api.IEssentials;
@@ -20,7 +19,6 @@ import java.util.Collections;
import java.util.Date;
import java.util.Locale;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
@@ -87,14 +85,7 @@ public class Trade {
sb.append(DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL).format(new Date()));
sb.append("\",\"");
if (sender != null) {
String senderIdentifier = sender;
if (ess.getSettings().isEcoLogUUIDEnabled()) {
final UUID uuid = ess.getUsers().getNameCache().get(sender);
if (uuid != null) {
senderIdentifier = uuid.toString();
}
}
sb.append(senderIdentifier);
sb.append(sender);
}
sb.append("\",");
if (charge == null) {
@@ -120,14 +111,7 @@ public class Trade {
}
sb.append(",\"");
if (receiver != null) {
String receiverIdentifier = receiver;
if (ess.getSettings().isEcoLogUUIDEnabled()) {
final UUID uuid = ess.getUsers().getNameCache().get(receiver);
if (uuid != null) {
receiverIdentifier = uuid.toString();
}
}
sb.append(receiverIdentifier);
sb.append(receiver);
}
sb.append("\",");
if (pay == null) {
@@ -160,7 +144,7 @@ public class Trade {
sb.append(loc.getBlockY()).append(",");
sb.append(loc.getBlockZ()).append(",");
}
if (endBalance == null) {
sb.append(",");
} else {
@@ -207,7 +191,7 @@ public class Trade {
}
if (getMoney() != null && getMoney().signum() > 0 && !user.canAfford(getMoney())) {
future.completeExceptionally(new ChargeException("notEnoughMoney", AdventureUtil.parsed(NumberUtil.displayCurrency(getMoney(), ess))));
future.completeExceptionally(new ChargeException("notEnoughMoney", NumberUtil.displayCurrency(getMoney(), ess)));
return;
}
@@ -218,7 +202,7 @@ public class Trade {
final BigDecimal money;
if (command != null && !command.isEmpty() && (money = getCommandCost(user)).signum() > 0 && !user.canAfford(money)) {
future.completeExceptionally(new ChargeException("notEnoughMoney", AdventureUtil.parsed(NumberUtil.displayCurrency(money, ess))));
future.completeExceptionally(new ChargeException("notEnoughMoney", NumberUtil.displayCurrency(money, ess)));
return;
}
@@ -257,8 +241,8 @@ public class Trade {
} else {
for (final ItemStack itemStack : leftover.values()) {
int spillAmount = itemStack.getAmount();
itemStack.setAmount(Math.min(spillAmount, itemStack.getMaxStackSize()));
while (spillAmount > 0) {
itemStack.setAmount(Math.min(spillAmount, itemStack.getMaxStackSize()));
user.getBase().getWorld().dropItemNaturally(user.getBase().getLocation(), itemStack);
spillAmount -= itemStack.getAmount();
}
@@ -301,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("notEnoughMoney", AdventureUtil.parsed(NumberUtil.displayCurrency(getMoney(), ess))));
future.completeExceptionally(new ChargeException("notEnoughMoney", NumberUtil.displayCurrency(getMoney(), ess)));
return;
}
user.takeMoney(getMoney());
@@ -320,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("notEnoughMoney", AdventureUtil.parsed(NumberUtil.displayCurrency(cost, ess))));
future.completeExceptionally(new ChargeException("notEnoughMoney", NumberUtil.displayCurrency(cost, ess)));
return;
}
user.takeMoney(cost);
@@ -1,13 +1,12 @@
package com.earth2me.essentials;
import com.earth2me.essentials.adventure.AdventureUtil;
import com.earth2me.essentials.adventure.ComponentHolder;
import com.earth2me.essentials.commands.IEssentialsCommand;
import com.earth2me.essentials.craftbukkit.Inventories;
import com.earth2me.essentials.economy.EconomyLayer;
import com.earth2me.essentials.economy.EconomyLayers;
import com.earth2me.essentials.messaging.IMessageRecipient;
import com.earth2me.essentials.messaging.SimpleMessageRecipient;
import com.earth2me.essentials.utils.AdventureUtil;
import com.earth2me.essentials.utils.DateUtil;
import com.earth2me.essentials.utils.EnumUtil;
import com.earth2me.essentials.utils.FormatUtil;
@@ -22,10 +21,10 @@ import net.ess3.api.events.AfkStatusChangeEvent;
import net.ess3.api.events.JailStatusChangeEvent;
import net.ess3.api.events.MuteStatusChangeEvent;
import net.ess3.api.events.UserBalanceUpdateEvent;
import net.ess3.provider.PlayerLocaleProvider;
import net.essentialsx.api.v2.events.PreTransactionEvent;
import net.essentialsx.api.v2.events.TransactionEvent;
import net.essentialsx.api.v2.services.mail.MailSender;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.ComponentLike;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Statistic;
@@ -63,6 +62,8 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
// User modules
private final IMessageRecipient messageRecipient;
private transient final AsyncTeleport teleport;
@SuppressWarnings("deprecation")
private transient final Teleport legacyTeleport;
// User command confirmation strings
private final Map<User, BigDecimal> confirmingPayments = new WeakHashMap<>();
@@ -100,13 +101,14 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
// Misc
private transient final List<String> signCopy = Lists.newArrayList("", "", "", "");
private transient long lastVanishTime = System.currentTimeMillis();
private transient int flightTick = -1;
private String lastLocaleString;
private Locale playerLocale;
public User(final Player base, final IEssentials ess) {
super(base, ess);
teleport = new AsyncTeleport(this, ess);
//noinspection deprecation
legacyTeleport = new Teleport(this, ess);
if (isAfk()) {
afkPosition = this.getLocation();
}
@@ -136,10 +138,6 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
@Override
public boolean isAuthorized(final String node) {
if (Essentials.TESTING) {
return false;
}
final boolean result = isAuthorizedCheck(node);
if (ess.getSettings().isDebug()) {
ess.getLogger().log(Level.INFO, "checking if " + base.getName() + " has " + node + " - " + result);
@@ -147,25 +145,8 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
return result;
}
@Override
public boolean isAuthorizedCached(final String node) {
if (Essentials.TESTING) {
return false;
}
final boolean result = isAuthorizedCachedCheck(node);
if (ess.getSettings().isDebug()) {
ess.getLogger().log(Level.INFO, "checking if " + base.getName() + " has " + node + " (cached) - " + result);
}
return result;
}
@Override
public boolean isPermissionSet(final String node) {
if (Essentials.TESTING) {
return false;
}
final boolean result = isPermSetCheck(node);
if (ess.getSettings().isDebug()) {
ess.getLogger().log(Level.INFO, "checking if " + base.getName() + " has " + node + " (set-explicit) - " + result);
@@ -199,24 +180,6 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
}
}
private boolean isAuthorizedCachedCheck(final String node) {
if (base instanceof OfflinePlayerStub) {
return false;
}
try {
return ess.getPermissionsHandler().hasPermissionCached(base, node);
} catch (final Exception ex) {
if (ess.getSettings().isDebug()) {
ess.getLogger().log(Level.SEVERE, "Permission System Error: " + ess.getPermissionsHandler().getName() + " returned: " + ex.getMessage(), ex);
} else {
ess.getLogger().log(Level.SEVERE, "Permission System Error: " + ess.getPermissionsHandler().getName() + " returned: " + ex.getMessage());
}
return false;
}
}
private boolean isPermSetCheck(final String node) {
if (base instanceof OfflinePlayerStub) {
return false;
@@ -284,9 +247,9 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
return;
}
setMoney(getMoney().add(value), cause);
sendTl("addedToAccount", AdventureUtil.parsed(NumberUtil.displayCurrency(value, ess)));
sendTl("addedToAccount", NumberUtil.displayCurrency(value, ess));
if (initiator != null) {
initiator.sendTl("addedToOthersAccount", AdventureUtil.parsed(NumberUtil.displayCurrency(value, ess)), getDisplayName(), AdventureUtil.parsed(NumberUtil.displayCurrency(getMoney(), ess)));
initiator.sendTl("addedToOthersAccount", NumberUtil.displayCurrency(value, ess), getDisplayName(), NumberUtil.displayCurrency(getMoney(), ess));
}
}
@@ -295,28 +258,20 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
payUser(reciever, value, UserBalanceUpdateEvent.Cause.UNKNOWN);
}
public void payUser(final User reciever, BigDecimal value, final UserBalanceUpdateEvent.Cause cause) throws Exception {
public void payUser(final User reciever, final BigDecimal value, final UserBalanceUpdateEvent.Cause cause) throws Exception {
if (value.compareTo(BigDecimal.ZERO) < 1) {
throw new Exception(tlLocale(playerLocale, "payMustBePositive"));
}
if (canAfford(value)) {
// Call an event for pre-transaction
final PreTransactionEvent preTransactionEvent = new PreTransactionEvent(this.getSource(), reciever, value);
ess.getServer().getPluginManager().callEvent(preTransactionEvent);
if (preTransactionEvent.isCancelled()) {
return;
}
value = preTransactionEvent.getAmount();
setMoney(getMoney().subtract(value), cause);
reciever.setMoney(reciever.getMoney().add(value), cause);
sendTl("moneySentTo", AdventureUtil.parsed(NumberUtil.displayCurrency(value, ess)), reciever.getDisplayName());
reciever.sendTl("moneyRecievedFrom", AdventureUtil.parsed(NumberUtil.displayCurrency(value, ess)), getDisplayName());
sendTl("moneySentTo", NumberUtil.displayCurrency(value, ess), reciever.getDisplayName());
reciever.sendTl("moneyRecievedFrom", NumberUtil.displayCurrency(value, ess), getDisplayName());
final TransactionEvent transactionEvent = new TransactionEvent(this.getSource(), reciever, value);
ess.getServer().getPluginManager().callEvent(transactionEvent);
} else {
throw new ChargeException("notEnoughMoney", AdventureUtil.parsed(NumberUtil.displayCurrency(value, ess)));
throw new ChargeException("notEnoughMoney", NumberUtil.displayCurrency(value, ess));
}
}
@@ -339,9 +294,9 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
} catch (final MaxMoneyException ex) {
ess.getLogger().log(Level.WARNING, "Invalid call to takeMoney, total balance can't be more than the max-money limit.", ex);
}
sendTl("takenFromAccount", AdventureUtil.parsed(NumberUtil.displayCurrency(value, ess)));
sendTl("takenFromAccount", NumberUtil.displayCurrency(value, ess));
if (initiator != null) {
initiator.sendTl("takenFromOthersAccount", AdventureUtil.parsed(NumberUtil.displayCurrency(value, ess)), getDisplayName(), AdventureUtil.parsed(NumberUtil.displayCurrency(getMoney(), ess)));
initiator.sendTl("takenFromOthersAccount", NumberUtil.displayCurrency(value, ess), getDisplayName(), NumberUtil.displayCurrency(getMoney(), ess));
}
}
@@ -420,6 +375,13 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
teleportRequestQueue.put(request.getName(), request);
}
@SuppressWarnings("deprecation")
@Override
@Deprecated
public boolean hasOutstandingTeleportRequest() {
return getNextTpaRequest(false, false, false) != null;
}
public Collection<String> getPendingTpaKeys() {
return teleportRequestQueue.keySet();
}
@@ -603,6 +565,16 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
return teleport;
}
/**
* @deprecated This API is not asynchronous. Use {@link User#getAsyncTeleport()}
*/
@SuppressWarnings("deprecation")
@Override
@Deprecated
public Teleport getTeleport() {
return legacyTeleport;
}
public long getLastOnlineActivity() {
return lastOnlineActivity;
}
@@ -687,7 +659,7 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
return;
}
this.getBase().setSleepingIgnored(this.isAuthorized("essentials.sleepingignored") || set && ess.getSettings().sleepIgnoresAfkPlayers());
this.getBase().setSleepingIgnored(this.isAuthorized("essentials.sleepingignored") || (set && ess.getSettings().sleepIgnoresAfkPlayers()));
if (set && !isAfk()) {
afkPosition = this.getLocation();
this.afkSince = System.currentTimeMillis();
@@ -822,11 +794,6 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
return false;
}
@Override
public long getLastActivityTime() {
return this.lastActivity;
}
@Deprecated
public void updateActivity(final boolean broadcast) {
updateActivity(broadcast, AfkStatusChangeEvent.Cause.UNKNOWN);
@@ -871,39 +838,24 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
return;
}
final long autoafktimeout = ess.getSettings().getAutoAfkTimeout();
// Checks if the player has been inactive for longer than the configured auto-afk-timeout time.
if (autoafktimeout > 0
&& lastActivity > 0 && (lastActivity + (autoafktimeout * 1000)) < System.currentTimeMillis()
final long autoafkkick = ess.getSettings().getAutoAfkKick();
if (autoafkkick > 0
&& lastActivity > 0 && (lastActivity + (autoafkkick * 1000)) < System.currentTimeMillis()
&& !isAuthorized("essentials.kick.exempt")
&& !isAuthorized("essentials.afk.kickexempt")) {
lastActivity = 0;
final double kickTime = autoafktimeout / 60.0;
final double kickTime = autoafkkick / 60.0;
// If `afk-timeout-command` in config.yml is empty, use default Essentials kicking behaviour instead of executing a command.
if (ess.getSettings().getAfkTimeoutCommands().isEmpty()) {
this.getBase().kickPlayer(ess.getAdventureFacet().miniToLegacy(playerTl("autoAfkKickReason", kickTime)));
this.getBase().kickPlayer(AdventureUtil.miniToLegacy(playerTl("autoAfkKickReason", kickTime)));
for (final User user : ess.getOnlineUsers()) {
if (user.isAuthorized("essentials.kick.notify")) {
user.sendTl("playerKicked", Console.displayName(), getName(), user.playerTl("autoAfkKickReason", kickTime));
}
}
} else {
// If `afk-timeout-commands` in config.yml is populated, execute the command(s) instead of kicking the player.
for (final String command : ess.getSettings().getAfkTimeoutCommands()) {
if (command == null || command.isEmpty()){
continue;
}
// Replace placeholders in the command with actual values.
final String cmd = command.replace("{USERNAME}", getName()).replace("{KICKTIME}", String.valueOf(kickTime));
ess.getServer().dispatchCommand(ess.getServer().getConsoleSender(), cmd);
for (final User user : ess.getOnlineUsers()) {
if (user.isAuthorized("essentials.kick.notify")) {
user.sendTl("playerKicked", Console.DISPLAY_NAME, getName(), user.playerTl("autoAfkKickReason", kickTime));
}
}
}
final long autoafk = ess.getSettings().getAutoAfk();
if (!isAfk() && autoafk > 0 && lastActivity + autoafk * 1000 < System.currentTimeMillis() && isAuthorizedCached("essentials.afk.auto")) {
if (!isAfk() && autoafk > 0 && lastActivity + autoafk * 1000 < System.currentTimeMillis() && isAuthorized("essentials.afk.auto")) {
setAfk(true, AfkStatusChangeEvent.Cause.ACTIVITY);
if (isAfk() && !isHidden()) {
setDisplayNick();
@@ -1113,14 +1065,14 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
}
@Override
public void sendComponent(ComponentHolder component) {
ess.getAdventureFacet().send(base, component);
public void sendComponent(ComponentLike component) {
ess.getBukkitAudience().player(base).sendMessage(component);
}
@Override
public ComponentHolder tlComponent(String tlKey, Object... args) {
public Component tlComponent(String tlKey, Object... args) {
final String translation = playerTl(tlKey, args);
return ess.getAdventureFacet().deserializeMiniMessage(translation);
return AdventureUtil.miniMessage().deserialize(translation);
}
@Override
@@ -1130,17 +1082,13 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
return;
}
sendComponent(ess.getAdventureFacet().deserializeMiniMessage(translation));
sendComponent(AdventureUtil.miniMessage().deserialize(translation));
}
@Override
public String playerTl(String tlKey, Object... args) {
if (ess.getSettings().isPerPlayerLocale()) {
final PlayerLocaleProvider provider = ess.provider(PlayerLocaleProvider.class);
final Locale locale = base != null ? getPlayerLocale(provider.getLocale(base)) : playerLocale;
if (locale != null) {
return tlLocale(locale, tlKey, args);
}
return tlLocale(getPlayerLocale(ess.getPlayerLocaleProvider().getLocale(base)), tlKey, args);
}
return tlLiteral(tlKey, args);
}
@@ -1151,7 +1099,7 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
}
public Locale getPlayerLocale(final String locale) {
if (locale == null || locale.equals(lastLocaleString)) {
if (locale.equals(lastLocaleString)) {
return playerLocale;
}
lastLocaleString = locale;
@@ -1349,12 +1297,4 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
}
return toggleShout == null ? toggleShout = ess.getSettings().isShoutDefault() : toggleShout;
}
public int getFlightTick() {
return flightTick;
}
public void setFlightTick(int flightTick) {
this.flightTick = flightTick;
}
}
@@ -74,7 +74,6 @@ public abstract class UserData extends PlayerExtension implements IConf {
public final void cleanup() {
config.blockingSave();
ess.getUsers().removeCache(getConfigUUID());
}
@Override
@@ -272,10 +271,6 @@ public abstract class UserData extends PlayerExtension implements IConf {
return !holder.powertools().isEmpty();
}
public Map<String, List<String>> getAllPowertools() {
return holder.powertools();
}
public Location getLastLocation() {
final LazyLocation lastLocation = holder.lastLocation();
return lastLocation != null ? lastLocation.location() : null;
@@ -353,17 +348,7 @@ public abstract class UserData extends PlayerExtension implements IConf {
}
public int getMailAmount() {
if (holder.mail() == null) {
return 0;
}
int amount = 0;
for (MailMessage element : holder.mail()) {
if (!element.isExpired()) {
amount++;
}
}
return amount;
return holder.mail() == null ? 0 : holder.mail().size();
}
public int getUnreadMailAmount() {
@@ -373,7 +358,7 @@ public abstract class UserData extends PlayerExtension implements IConf {
int unread = 0;
for (MailMessage element : holder.mail()) {
if (!element.isRead() && !element.isExpired()) {
if (!element.isRead()) {
unread++;
}
}
@@ -469,15 +454,6 @@ public abstract class UserData extends PlayerExtension implements IConf {
config.save();
}
public boolean isFlyModeEnabled() {
return holder.flyMode();
}
public void setFlyModeEnabled(final boolean set) {
holder.flyMode(set);
config.save();
}
public boolean getMuted() {
return holder.muted();
}
@@ -1,10 +1,11 @@
package com.earth2me.essentials;
import com.earth2me.essentials.adventure.AdventureUtil;
import com.earth2me.essentials.commands.WarpNotFoundException;
import com.earth2me.essentials.config.EssentialsConfiguration;
import com.earth2me.essentials.utils.AdventureUtil;
import com.earth2me.essentials.utils.StringUtil;
import net.ess3.api.InvalidNameException;
import net.ess3.api.InvalidWorldException;
import net.ess3.api.TranslatableException;
import org.bukkit.Location;
@@ -53,7 +54,7 @@ public class Warps implements IConf, net.ess3.api.IWarps {
}
@Override
public Location getWarp(final String warp) throws WarpNotFoundException {
public Location getWarp(final String warp) throws WarpNotFoundException, InvalidWorldException {
final EssentialsConfiguration conf = warpPoints.get(new StringIgnoreCase(warp));
if (conf == null) {
throw new WarpNotFoundException();
@@ -78,7 +79,7 @@ public class Warps implements IConf, net.ess3.api.IWarps {
if (conf == null) {
final File confFile = new File(warpsFolder, filename + ".yml");
if (confFile.exists()) {
throw new TranslatableException("similarWarpExist");
throw new Exception(user == null ? tlLiteral("similarWarpExist") : user.playerTl("similarWarpExist"));
}
conf = new EssentialsConfiguration(confFile);
conf.load();
@@ -134,7 +135,7 @@ public class Warps implements IConf, net.ess3.api.IWarps {
warpPoints.put(new StringIgnoreCase(name), conf);
}
} catch (final Exception ex) {
Essentials.getWrappedLogger().log(Level.WARNING, AdventureUtil.getAdventureFacet().miniToLegacy(tlLiteral("loadWarpError", filename)), ex);
Essentials.getWrappedLogger().log(Level.WARNING, AdventureUtil.miniToLegacy(tlLiteral("loadWarpError", filename)), ex);
}
}
}
@@ -1,62 +0,0 @@
package com.earth2me.essentials.adventure;
import net.kyori.adventure.text.format.NamedTextColor;
public final class AdventureUtil {
private static final String LOOKUP = "0123456789abcdefklmnor";
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 AdventureFacet ADVENTURE_FACET_INSTANCE = null;
private AdventureUtil() {
}
public static void setAdventureFacet(AdventureFacet adventureFacetInstance) {
ADVENTURE_FACET_INSTANCE = adventureFacetInstance;
}
public static AdventureFacet getAdventureFacet() {
return ADVENTURE_FACET_INSTANCE;
}
/**
* Get the {@link NamedTextColor} from its associated section sign char.
*/
public static NamedTextColor fromChar(final char c) {
final int index = LOOKUP.indexOf(c);
if (index == -1 || index > 15) {
return null;
}
return COLORS[index];
}
public static String fromCharName(final char c) {
final NamedTextColor namedTextColor = fromChar(c);
if (namedTextColor == null) {
return null;
}
return namedTextColor.toString();
}
/**
* Parameters for a translation message are not parsed for MiniMessage by default to avoid injection. If you want
* a parameter to be parsed for MiniMessage you must wrap it in a ParsedPlaceholder by using this method.
*/
public static ParsedPlaceholder parsed(final String literal) {
return new ParsedPlaceholder(literal);
}
public static class ParsedPlaceholder {
private final String value;
protected ParsedPlaceholder(String value) {
this.value = value;
}
@Override
public String toString() {
return value;
}
}
}
@@ -1,155 +0,0 @@
package com.earth2me.essentials.adventure;
import com.earth2me.essentials.Essentials;
import com.earth2me.essentials.utils.NumberUtil;
import com.earth2me.essentials.utils.VersionUtil;
import net.ess3.provider.AbstractChatEvent;
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
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.TextColor;
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.LegacyComponentSerializer;
import org.bukkit.Color;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.Locale;
public class SpigotAdventureFacet implements AdventureFacet {
private static final LegacyComponentSerializer LEGACY_SERIALIZER;
private static final LegacyComponentSerializer LEGACY_SERIALIZER_URLS;
private static final MiniMessage MINI_MESSAGE_NO_TAGS;
static {
final LegacyComponentSerializer.Builder builder = LegacyComponentSerializer.builder()
.flattener(ComponentFlattener.basic())
.useUnusualXRepeatedCharacterHexFormat();
if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_16_1_R01)) {
builder.hexColors();
}
LEGACY_SERIALIZER = builder.build();
LEGACY_SERIALIZER_URLS = builder.extractUrls(AbstractChatEvent.URL_PATTERN).build();
MINI_MESSAGE_NO_TAGS = MiniMessage.builder().strict(true).build();
}
private final Essentials ess;
private final BukkitAudiences bukkitAudiences;
private final MiniMessage miniMessageInstance;
public SpigotAdventureFacet(final Essentials ess) {
this.ess = ess.getSettings() == null ? null : ess;
bukkitAudiences = BukkitAudiences.create(ess);
miniMessageInstance = MiniMessage.builder()
.tags(TagResolver.builder()
.resolvers(TagResolver.standard())
.resolver(TagResolver.resolver("primary", supplyTag(true)))
.resolver(TagResolver.resolver("secondary", supplyTag(false)))
.build())
.build();
}
private Tag supplyTag(final boolean primary) {
final String color = primary ? (ess != null ? ess.getSettings().getPrimaryColor() : "gold") : (ess != null ? ess.getSettings().getSecondaryColor() : "red");
final TextColor textColor;
if (color.startsWith("#") && color.length() == 7 && NumberUtil.isHexadecimal(color.substring(1))) {
textColor = TextColor.color(Color.fromRGB(Integer.decode(color)).asRGB());
} else if (color.length() == 1) {
textColor = AdventureUtil.fromChar(color.charAt(0));
} else {
textColor = NamedTextColor.NAMES.value(color.toLowerCase(Locale.ENGLISH));
}
return ess != null && textColor != null ? Tag.styling(textColor) : Tag.styling(primary ? NamedTextColor.GOLD : NamedTextColor.RED);
}
@Override
public ComponentHolder deserializeMiniMessage(String message) {
return new ComponentHolder(miniMessageInstance.deserialize(message));
}
@Override
public String legacyToMini(String message) {
return legacyToMini(message, true);
}
@Override
public void send(CommandSender sender, ComponentHolder component) {
bukkitAudiences.sender(sender).sendMessage((Component) component.getComponent());
}
@Override
public void send(Player player, ComponentHolder component) {
bukkitAudiences.player(player).sendMessage((Component) component.getComponent());
}
@Override
public String adventureToLegacy(ComponentHolder component) {
return adventureToLegacy((Component) component.getComponent());
}
private String adventureToLegacy(Component component) {
return LEGACY_SERIALIZER.serialize(component);
}
@Override
public ComponentHolder legacyToAdventure(String message) {
return new ComponentHolder(LEGACY_SERIALIZER.deserialize(message));
}
@Override
public ComponentHolder text(String message) {
return new ComponentHolder(Component.text(message));
}
@Override
public String legacyToMini(String message, boolean useCustomTags) {
final Component deserializedText = LEGACY_SERIALIZER.deserialize(message);
if (useCustomTags) {
return miniMessageInstance.serialize(deserializedText);
} else {
return MINI_MESSAGE_NO_TAGS.serialize(deserializedText);
}
}
@Override
public String miniToLegacy(String message) {
return adventureToLegacy(miniMessageInstance.deserialize(message));
}
@Override
public String stripTags(String input) {
return miniMessageInstance.stripTags(input);
}
@Override
public String legacyToMiniWithUrls(String message) {
return miniMessageInstance.serialize(LEGACY_SERIALIZER_URLS.deserialize(message));
}
@Override
public String escapeTags(String input) {
return miniMessageInstance.escapeTags(input);
}
@Override
public ComponentHolder append(ComponentHolder base, ComponentHolder... addition) {
Component baseComponent = (Component) base.getComponent();
for (ComponentHolder holder : addition) {
final Component additionComponent = (Component) holder.getComponent();
baseComponent = baseComponent.append(additionComponent);
}
return new ComponentHolder(baseComponent);
}
@Override
public void close() {
bukkitAudiences.close();
}
}
@@ -323,13 +323,7 @@ public class Economy {
throw new IllegalArgumentException("Economy user cannot be null");
}
final BigDecimal result = getMoneyExact(user).add(amount, MATH_CONTEXT);
// Deposits (positive amounts) always improve the balance, so minMoney and
// loan checks don't apply — they exist to prevent the balance from dropping.
if (amount.signum() <= 0) {
setMoney(user, result);
} else {
user.setMoney(result, UserBalanceUpdateEvent.Cause.API);
}
setMoney(user, result);
Trade.log("API", "Add", "API", user.getName(), new Trade(amount, ess), null, null, null, result, ess);
}
@@ -46,6 +46,17 @@ public interface IJails extends IConf {
*/
void removeJail(String jail) throws Exception;
/**
* Attempts to send the given user to the given jail
*
* @param user the user to send to jail
* @param jail the jail to send the user to
* @throws Exception if the user is offline or jail does not exist
* @deprecated Use {@link IJails#sendToJail(IUser, String, CompletableFuture)}
*/
@Deprecated
void sendToJail(IUser user, String jail) throws Exception;
/**
* Attempts to send the given user to the given jail
*
@@ -22,8 +22,9 @@ public interface IWarps extends IConf {
* @param warp - Warp name
* @return - Location the warp is set to
* @throws WarpNotFoundException When the warp is not found
* @throws net.ess3.api.InvalidWorldException When the world the warp is in is not found
*/
Location getWarp(String warp) throws WarpNotFoundException;
Location getWarp(String warp) throws WarpNotFoundException, net.ess3.api.InvalidWorldException;
/**
* Checks if the provided name is a warp.
@@ -106,7 +106,7 @@ public class Commandafk extends EssentialsCommand {
@Override
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
if (args.length == 1 && sender.isAuthorized("essentials.afk.others")) {
return getPlayers(sender);
return getPlayers(server, sender);
} else {
return Collections.emptyList();
}
@@ -1,7 +1,6 @@
package com.earth2me.essentials.commands;
import com.earth2me.essentials.User;
import net.ess3.provider.ContainerProvider;
import org.bukkit.Server;
public class Commandanvil extends EssentialsCommand {
@@ -12,13 +11,11 @@ public class Commandanvil extends EssentialsCommand {
@Override
protected void run(Server server, User user, String commandLabel, String[] args) throws Exception {
final ContainerProvider containerProvider = ess.provider(ContainerProvider.class);
if (containerProvider == null) {
if (ess.getContainerProvider() == null) {
user.sendTl("unsupportedBrand");
return;
}
containerProvider.openAnvil(user.getBase());
ess.getContainerProvider().openAnvil(user.getBase());
}
}
@@ -77,7 +77,7 @@ public class Commandback extends EssentialsCommand {
@Override
protected List<String> getTabCompleteOptions(final Server server, final User user, final String commandLabel, final String[] args) {
if (user.isAuthorized("essentials.back.others") && args.length == 1) {
return getPlayers(user);
return getPlayers(server, user);
} else {
return Collections.emptyList();
}
@@ -2,7 +2,6 @@ package com.earth2me.essentials.commands;
import com.earth2me.essentials.CommandSource;
import com.earth2me.essentials.User;
import com.earth2me.essentials.adventure.AdventureUtil;
import com.earth2me.essentials.utils.NumberUtil;
import org.bukkit.Server;
@@ -20,17 +19,17 @@ public class Commandbalance extends EssentialsCommand {
throw new NotEnoughArgumentsException();
}
final User target = getPlayer(server, args, 0, true, true);
sender.sendTl("balanceOther", target.isHidden() ? target.getName() : target.getDisplayName(), AdventureUtil.parsed(NumberUtil.displayCurrency(target.getMoney(), ess)));
final User target = getPlayer(server, args, 0, false, true);
sender.sendTl("balanceOther", target.isHidden() ? target.getName() : target.getDisplayName(), NumberUtil.displayCurrency(target.getMoney(), ess));
}
@Override
public void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
if (args.length == 1 && user.isAuthorized("essentials.balance.others")) {
final User target = getPlayer(server, args, 0, false, true);
user.sendTl("balanceOther", target.isHidden() ? target.getName() : target.getDisplayName(), AdventureUtil.parsed(NumberUtil.displayCurrency(target.getMoney(), ess)));
final User target = getPlayer(server, args, 0, true, true);
user.sendTl("balanceOther", target.isHidden() ? target.getName() : target.getDisplayName(), NumberUtil.displayCurrency(target.getMoney(), ess));
} else if (args.length < 2) {
user.sendTl("balance", AdventureUtil.parsed(NumberUtil.displayCurrency(user.getMoney(), ess)));
user.sendTl("balance", NumberUtil.displayCurrency(user.getMoney(), ess));
} else {
throw new NotEnoughArgumentsException();
}
@@ -39,7 +38,7 @@ public class Commandbalance extends EssentialsCommand {
@Override
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
if (args.length == 1 && sender.isAuthorized("essentials.balance.others")) {
return getPlayers(sender);
return getPlayers(server, sender);
} else {
return Collections.emptyList();
}
@@ -1,18 +1,13 @@
package com.earth2me.essentials.commands;
import com.earth2me.essentials.CommandSource;
import com.earth2me.essentials.User;
import com.earth2me.essentials.textreader.SimpleTextInput;
import com.earth2me.essentials.textreader.TextPager;
import com.earth2me.essentials.adventure.AdventureUtil;
import com.earth2me.essentials.utils.EnumUtil;
import com.earth2me.essentials.utils.AdventureUtil;
import com.earth2me.essentials.utils.NumberUtil;
import com.earth2me.essentials.utils.VersionUtil;
import com.google.common.collect.Lists;
import net.essentialsx.api.v2.services.BalanceTop;
import org.bukkit.Bukkit;
import org.bukkit.Server;
import org.bukkit.Statistic;
import org.bukkit.command.BlockCommandSender;
import java.math.BigDecimal;
@@ -115,38 +110,17 @@ public class Commandbalancetop extends EssentialsCommand {
future.thenRun(() -> {
if (fresh) {
final SimpleTextInput newCache = new SimpleTextInput();
newCache.getLines().add(ess.getAdventureFacet().miniToLegacy(tlLiteral("serverTotal", AdventureUtil.parsed(NumberUtil.displayCurrency(ess.getBalanceTop().getBalanceTopTotal(), ess)))));
newCache.getLines().add(AdventureUtil.miniToLegacy(tlLiteral("serverTotal", NumberUtil.displayCurrency(ess.getBalanceTop().getBalanceTopTotal(), ess))));
int pos = 1;
for (final Map.Entry<UUID, BalanceTop.Entry> entry : ess.getBalanceTop().getBalanceTopCache().entrySet()) {
final BigDecimal balance = entry.getValue().getBalance();
final User user = ess.getUser(entry.getKey());
final Statistic PLAY_ONE_TICK = EnumUtil.getStatistic("PLAY_ONE_MINUTE", "PLAY_ONE_TICK");
final boolean offlineStatisticSupported = VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_15_2_R01);
final long playtime;
if (user.getBase() == null || !user.getBase().isOnline()) {
if (offlineStatisticSupported) {
playtime = Bukkit.getServer().getOfflinePlayer(entry.getKey()).getStatistic(PLAY_ONE_TICK);
} else {
playtime = -1;
}
} else {
playtime = user.getBase().getStatistic(PLAY_ONE_TICK);
}
// Play time in seconds
final long playTimeSecs = Math.max(playtime / 20, 0);
// Checking if player meets the requirements of minimum balance and minimum playtime to be listed in baltop list
if ((ess.getSettings().showZeroBaltop() || balance.compareTo(BigDecimal.ZERO) > 0)
&& balance.compareTo(ess.getSettings().getBaltopMinBalance()) >= 0 &&
// Skip playtime check for offline players on versions below 1.15.2
(playtime == -1 || playTimeSecs >= ess.getSettings().getBaltopMinPlaytime())) {
newCache.getLines().add(ess.getAdventureFacet().miniToLegacy(tlLiteral("balanceTopLine", pos, entry.getValue().getDisplayName(), AdventureUtil.parsed(NumberUtil.displayCurrency(balance, ess)))));
if (ess.getSettings().showZeroBaltop() || entry.getValue().getBalance().compareTo(BigDecimal.ZERO) > 0) {
newCache.getLines().add(AdventureUtil.miniToLegacy(tlLiteral("balanceTopLine", pos, entry.getValue().getDisplayName(), NumberUtil.displayCurrency(entry.getValue().getBalance(), ess))));
}
pos++;
}
cache = newCache;
}
outputCache(sender, page);
});
}
@@ -4,6 +4,7 @@ import com.earth2me.essentials.CommandSource;
import com.earth2me.essentials.Console;
import com.earth2me.essentials.OfflinePlayerStub;
import com.earth2me.essentials.User;
import com.earth2me.essentials.utils.AdventureUtil;
import com.earth2me.essentials.utils.FormatUtil;
import net.ess3.api.TranslatableException;
import org.bukkit.BanList;
@@ -42,7 +43,7 @@ public class Commandban extends EssentialsCommand {
}
final String senderName = sender.isPlayer() ? sender.getPlayer().getDisplayName() : Console.NAME;
final String senderDisplayName = sender.isPlayer() ? sender.getPlayer().getDisplayName() : Console.displayName();
final String senderDisplayName = sender.isPlayer() ? sender.getPlayer().getDisplayName() : Console.DISPLAY_NAME;
final String banReason;
if (args.length > 1) {
banReason = FormatUtil.replaceFormat(getFinalArg(args, 1).replace("\\n", "\n").replace("|", "\n"));
@@ -54,8 +55,8 @@ public class Commandban extends EssentialsCommand {
final String banDisplay = tlLiteral("banFormat", banReason, senderDisplayName);
user.getBase().kickPlayer(ess.getAdventureFacet().miniToLegacy(banDisplay));
ess.getLogger().log(Level.INFO, ess.getAdventureFacet().miniToLegacy(tlLiteral("playerBanned", senderDisplayName, user.getName(), banDisplay)));
user.getBase().kickPlayer(AdventureUtil.miniToLegacy(banDisplay));
ess.getLogger().log(Level.INFO, AdventureUtil.miniToLegacy(tlLiteral("playerBanned", senderDisplayName, user.getName(), banDisplay)));
if (nomatch) {
sender.sendTl("userUnknown", user.getName());
@@ -67,7 +68,7 @@ public class Commandban extends EssentialsCommand {
@Override
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
if (args.length == 1) {
return getPlayers(sender);
return getPlayers(server, sender);
} else {
return Collections.emptyList();
}
@@ -3,6 +3,7 @@ package com.earth2me.essentials.commands;
import com.earth2me.essentials.CommandSource;
import com.earth2me.essentials.Console;
import com.earth2me.essentials.User;
import com.earth2me.essentials.utils.AdventureUtil;
import com.earth2me.essentials.utils.FormatUtil;
import org.bukkit.BanList;
import org.bukkit.Server;
@@ -26,7 +27,7 @@ public class Commandbanip extends EssentialsCommand {
}
final String senderName = sender.isPlayer() ? sender.getPlayer().getDisplayName() : Console.NAME;
final String senderDisplayName = sender.isPlayer() ? sender.getPlayer().getDisplayName() : Console.displayName();
final String senderDisplayName = sender.isPlayer() ? sender.getPlayer().getDisplayName() : Console.DISPLAY_NAME;
String ipAddress;
if (FormatUtil.validIP(args[0])) {
@@ -51,10 +52,10 @@ public class Commandbanip extends EssentialsCommand {
banReason = tlLiteral("defaultBanReason");
}
final String banDisplay = ess.getAdventureFacet().miniToLegacy(tlLiteral("banFormat", banReason, senderDisplayName));
final String banDisplay = AdventureUtil.miniToLegacy(tlLiteral("banFormat", banReason, senderDisplayName));
ess.getServer().getBanList(BanList.Type.IP).addBan(ipAddress, banReason, null, senderName);
ess.getLogger().log(Level.INFO, ess.getAdventureFacet().miniToLegacy(tlLiteral("playerBanIpAddress", senderDisplayName, ipAddress, banReason)));
ess.getLogger().log(Level.INFO, AdventureUtil.miniToLegacy(tlLiteral("playerBanIpAddress", senderDisplayName, ipAddress, banReason)));
for (final Player player : ess.getServer().getOnlinePlayers()) {
if (player.getAddress().getAddress().getHostAddress().equalsIgnoreCase(ipAddress)) {
@@ -69,7 +70,7 @@ public class Commandbanip extends EssentialsCommand {
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
if (args.length == 1) {
// TODO: Also list IP addresses?
return getPlayers(sender);
return getPlayers(server, sender);
} else {
return Collections.emptyList();
}
@@ -4,14 +4,12 @@ import com.earth2me.essentials.User;
import com.earth2me.essentials.craftbukkit.Inventories;
import com.earth2me.essentials.utils.EnumUtil;
import com.earth2me.essentials.utils.FormatUtil;
import com.earth2me.essentials.utils.VersionUtil;
import com.google.common.collect.Lists;
import net.ess3.api.TranslatableException;
import org.bukkit.Material;
import org.bukkit.Server;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.BookMeta;
import org.bukkit.inventory.meta.WritableBookMeta;
import java.util.Collections;
import java.util.List;
@@ -52,14 +50,7 @@ public class Commandbook extends EssentialsCommand {
} else {
if (isAuthor(bmeta, player) || user.isAuthorized("essentials.book.others")) {
final ItemStack newItem = new ItemStack(WRITABLE_BOOK, item.getAmount());
if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_20_6_R01)) {
final WritableBookMeta wbmeta = (WritableBookMeta) newItem.getItemMeta();
//noinspection DataFlowIssue
wbmeta.setPages(bmeta.getPages());
newItem.setItemMeta(wbmeta);
} else {
newItem.setItemMeta(bmeta);
}
newItem.setItemMeta(bmeta);
Inventories.setItemInMainHand(user.getBase(), newItem);
user.sendTl("editBookContents");
} else {
@@ -72,15 +63,7 @@ public class Commandbook extends EssentialsCommand {
bmeta.setAuthor(player);
}
final ItemStack newItem = new ItemStack(Material.WRITTEN_BOOK, item.getAmount());
if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_20_6_R01)) {
final BookMeta real = (BookMeta) newItem.getItemMeta();
real.setAuthor(bmeta.getAuthor());
real.setTitle(bmeta.getTitle());
real.setPages(bmeta.getPages());
newItem.setItemMeta(real);
} else {
newItem.setItemMeta(bmeta);
}
newItem.setItemMeta(bmeta);
Inventories.setItemInMainHand(user.getBase(), newItem);
user.sendTl("bookLocked");
} else {
@@ -106,7 +89,7 @@ public class Commandbook extends EssentialsCommand {
}
return options;
} else if (args.length == 2 && args[0].equalsIgnoreCase("author") && user.isAuthorized("essentials.book.author")) {
final List<String> options = getPlayers(user);
final List<String> options = getPlayers(server, user);
options.add("Herobrine"); // #EasterEgg
return options;
} else {
@@ -3,7 +3,6 @@ package com.earth2me.essentials.commands;
import com.earth2me.essentials.Trade;
import com.earth2me.essentials.User;
import com.earth2me.essentials.utils.LocationUtil;
import net.ess3.provider.WorldInfoProvider;
import org.bukkit.Location;
import org.bukkit.Server;
import org.bukkit.event.player.PlayerTeleportEvent;
@@ -22,7 +21,7 @@ public class Commandbottom extends EssentialsCommand {
final int bottomZ = user.getLocation().getBlockZ();
final float pitch = user.getLocation().getPitch();
final float yaw = user.getLocation().getYaw();
final Location unsafe = new Location(user.getWorld(), bottomX, ess.provider(WorldInfoProvider.class).getMinHeight(user.getWorld()), bottomZ, yaw, pitch);
final Location unsafe = new Location(user.getWorld(), bottomX, ess.getWorldInfoProvider().getMinHeight(user.getWorld()), bottomZ, yaw, pitch);
final Location safe = LocationUtil.getSafeDestination(ess, unsafe);
final CompletableFuture<Boolean> future = getNewExceptionFuture(user.getSource(), commandLabel);
future.thenAccept(success -> {
@@ -1,7 +1,6 @@
package com.earth2me.essentials.commands;
import com.earth2me.essentials.CommandSource;
import com.earth2me.essentials.adventure.AdventureUtil;
import com.earth2me.essentials.utils.FormatUtil;
import org.bukkit.Server;
@@ -16,9 +15,6 @@ public class Commandbroadcast extends EssentialsCommand {
throw new NotEnoughArgumentsException();
}
final String message = FormatUtil.replaceFormat(getFinalArg(args, 0)).replace("\\n", "\n");
ess.broadcastTl("broadcast",
AdventureUtil.parsed(ess.getAdventureFacet().legacyToMiniWithUrls(ess.getAdventureFacet().escapeTags(message))),
sender.getDisplayName());
ess.broadcastTl("broadcast", FormatUtil.replaceFormat(getFinalArg(args, 0)).replace("\\n", "\n"), sender.getDisplayName());
}
}
@@ -2,8 +2,7 @@ package com.earth2me.essentials.commands;
import com.earth2me.essentials.CommandSource;
import com.earth2me.essentials.User;
import com.earth2me.essentials.adventure.AdventureUtil;
import com.earth2me.essentials.utils.FormatUtil;
import com.earth2me.essentials.utils.AdventureUtil;
import com.google.common.collect.Lists;
import net.ess3.api.TranslatableException;
import org.bukkit.Server;
@@ -54,11 +53,7 @@ public class Commandbroadcastworld extends EssentialsCommand {
if (message.isEmpty()) {
throw new NotEnoughArgumentsException();
}
final String formatted = FormatUtil.replaceFormat(message).replace("\\n", "\n");
ess.broadcastTl(null, u -> !u.getBase().getWorld().equals(world), true, "broadcast",
AdventureUtil.parsed(
ess.getAdventureFacet().legacyToMiniWithUrls(ess.getAdventureFacet().escapeTags(formatted))),
AdventureUtil.parsed(ess.getAdventureFacet().legacyToMini(name)));
ess.broadcastTl(null, u -> !u.getBase().getWorld().equals(world), true, "broadcast", message, AdventureUtil.parsed(AdventureUtil.legacyToMini(name)));
}
@Override
@@ -19,18 +19,14 @@ public class Commandburn extends EssentialsCommand {
}
final User user = getPlayer(server, sender, args, 0);
final int seconds = Integer.parseInt(args[1]);
final int fireTicks = (int) Math.max(0L, Math.min((long) seconds * 20, Integer.MAX_VALUE));
user.getBase().setFireTicks(fireTicks);
sender.sendTl("burnMsg", user.getDisplayName(), Math.max(0, seconds));
user.getBase().setFireTicks(Integer.parseInt(args[1]) * 20);
sender.sendTl("burnMsg", user.getDisplayName(), Integer.parseInt(args[1]));
}
@Override
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
if (args.length == 1) {
return getPlayers(sender);
return getPlayers(server, sender);
} else if (args.length == 2) {
return COMMON_DURATIONS;
} else {
@@ -1,7 +1,6 @@
package com.earth2me.essentials.commands;
import com.earth2me.essentials.User;
import net.ess3.provider.ContainerProvider;
import org.bukkit.Server;
public class Commandcartographytable extends EssentialsCommand {
@@ -12,13 +11,11 @@ public class Commandcartographytable extends EssentialsCommand {
@Override
public void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
final ContainerProvider containerProvider = ess.provider(ContainerProvider.class);
if (containerProvider == null) {
if (ess.getContainerProvider() == null) {
user.sendTl("unsupportedBrand");
return;
}
containerProvider.openCartographyTable(user.getBase());
ess.getContainerProvider().openCartographyTable(user.getBase());
}
}
@@ -6,7 +6,6 @@ import com.earth2me.essentials.craftbukkit.Inventories;
import com.earth2me.essentials.utils.NumberUtil;
import com.earth2me.essentials.utils.StringUtil;
import com.earth2me.essentials.utils.VersionUtil;
import net.ess3.api.TranslatableException;
import org.bukkit.Material;
import org.bukkit.Server;
import org.bukkit.entity.Player;
@@ -81,7 +80,7 @@ public class Commandclearinventory extends EssentialsCommand {
}
}
protected void clearHandler(final CommandSource sender, final Player player, final String[] args, final int offset, final boolean showExtended) throws TranslatableException {
protected void clearHandler(final CommandSource sender, final Player player, final String[] args, final int offset, final boolean showExtended) {
ClearHandlerType type = ClearHandlerType.ALL_EXCEPT_ARMOR;
final Set<Item> items = new HashSet<>();
int amount = -1;
@@ -125,11 +124,6 @@ public class Commandclearinventory extends EssentialsCommand {
stack.setDurability(item.getData());
}
// can't remove a negative amount of items. (it adds them)
if (amount < -1) {
throw new TranslatableException("cannotRemoveNegativeItems");
}
// amount -1 means all items will be cleared
if (amount == -1) {
final int removedAmount = Inventories.removeItemSimilar(player, stack, true);
@@ -137,6 +131,7 @@ public class Commandclearinventory extends EssentialsCommand {
sender.sendTl("inventoryClearingStack", removedAmount, stack.getType().toString().toLowerCase(Locale.ENGLISH), player.getDisplayName());
}
} else {
stack.setAmount(amount < 0 ? 1 : amount);
if (Inventories.removeItemAmount(player, stack, amount)) {
sender.sendTl("inventoryClearingStack", amount, stack.getType().toString().toLowerCase(Locale.ENGLISH), player.getDisplayName());
} else {
@@ -153,7 +148,7 @@ public class Commandclearinventory extends EssentialsCommand {
protected List<String> getTabCompleteOptions(final Server server, final User user, final String commandLabel, final String[] args) {
if (user.isAuthorized("essentials.clearinventory.others")) {
if (args.length == 1) {
final List<String> options = getPlayers(user);
final List<String> options = getPlayers(server, user);
if (user.isAuthorized("essentials.clearinventory.all") || user.isAuthorized("essentials.clearinventory.multiple")) {
// Assume that nobody will have the 'all' permission without the 'others' permission
options.add("*");
@@ -182,7 +177,7 @@ public class Commandclearinventory extends EssentialsCommand {
@Override
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
if (args.length == 1) {
final List<String> options = getPlayers(sender);
final List<String> options = getPlayers(server, sender);
options.add("*");
return options;
} else if (args.length == 2) {
@@ -196,9 +191,6 @@ public class Commandclearinventory extends EssentialsCommand {
}
private String formatCommand(final String commandLabel, final String[] args) {
if (args == null || args.length == 0) {
return "/" + commandLabel;
}
return "/" + commandLabel + " " + StringUtil.joinList(" ", (Object[]) args);
}
@@ -6,7 +6,6 @@ import com.earth2me.essentials.craftbukkit.Inventories;
import com.earth2me.essentials.utils.DateUtil;
import com.earth2me.essentials.utils.PasteUtil;
import net.ess3.api.TranslatableException;
import net.ess3.provider.SerializationProvider;
import org.bukkit.Material;
import org.bukkit.Server;
import org.bukkit.inventory.ItemStack;
@@ -43,22 +42,20 @@ public class Commandcreatekit extends EssentialsCommand {
final ItemStack[] items = Inventories.getInventory(user.getBase(), true);
final List<String> list = new ArrayList<>();
final SerializationProvider serializationProvider = ess.provider(SerializationProvider.class);
boolean useSerializationProvider = ess.getSettings().isUseBetterKits();
if (useSerializationProvider && serializationProvider == null) {
if (useSerializationProvider && ess.getSerializationProvider() == null) {
ess.showError(user.getSource(), new TranslatableException("createKitUnsupported"), commandLabel);
useSerializationProvider = false;
}
for (int i = 0; i < items.length; i++) {
final ItemStack is = items[i];
for (ItemStack is : items) {
if (is != null && is.getType() != null && is.getType() != Material.AIR) {
final String serialized;
if (useSerializationProvider) {
serialized = "slot:" + i + " @" + Base64Coder.encodeLines(serializationProvider.serializeItem(is));
serialized = "@" + Base64Coder.encodeLines(ess.getSerializationProvider().serializeItem(is));
} else {
serialized = "slot:" + i + " " + ess.getItemDb().serialize(is);
serialized = ess.getItemDb().serialize(is);
}
list.add(serialized);
}
@@ -18,24 +18,6 @@ public class Commanddelhome extends EssentialsCommand {
super("delhome");
}
private void deleteHome(CommandSource sender, User user, String home) {
final HomeModifyEvent event = new HomeModifyEvent(sender.getUser(), user, home, user.getHome(home), false);
Bukkit.getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
if (ess.getSettings().isDebug()) {
ess.getLogger().info("HomeModifyEvent canceled for /delhome execution by " + sender.getDisplayName());
}
return;
}
try {
user.delHome(home);
sender.sendTl("deleteHome", home);
} catch (Exception e) {
sender.sendTl("invalidHome", home);
}
}
@Override
public void run(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
if (args.length < 1) {
@@ -63,19 +45,21 @@ public class Commanddelhome extends EssentialsCommand {
name = expandedArg[0].toLowerCase(Locale.ENGLISH);
}
switch (name) {
case "bed":
throw new TranslatableException("invalidHomeName");
case "*":
final List<String> homes = user.getHomes();
for (String home : homes) {
deleteHome(sender, user, home);
}
break;
default:
deleteHome(sender, user, name);
break;
if (name.equals("bed")) {
throw new TranslatableException("invalidHomeName");
}
final HomeModifyEvent event = new HomeModifyEvent(sender.getUser(), user, name, user.getHome(name), false);
Bukkit.getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
if (ess.getSettings().isDebug()) {
ess.getLogger().info("HomeModifyEvent canceled for /delhome execution by " + sender.getDisplayName());
}
return;
}
user.delHome(name);
sender.sendTl("deleteHome", name);
}
@Override
@@ -87,7 +71,7 @@ public class Commanddelhome extends EssentialsCommand {
if (canDelOthers) {
final int sepIndex = args[0].indexOf(':');
if (sepIndex < 0) {
getPlayers(sender).forEach(player -> homes.add(player + ":"));
getPlayers(server, sender).forEach(player -> homes.add(player + ":"));
} else {
final String namePart = args[0].substring(0, sepIndex);
final User otherUser;
@@ -97,7 +81,6 @@ public class Commanddelhome extends EssentialsCommand {
return homes;
}
otherUser.getHomes().forEach(home -> homes.add(namePart + ":" + home));
homes.add(namePart + ":" + "*");
}
}
return homes;
@@ -3,13 +3,11 @@ package com.earth2me.essentials.commands;
import com.earth2me.essentials.ChargeException;
import com.earth2me.essentials.CommandSource;
import com.earth2me.essentials.User;
import com.earth2me.essentials.adventure.AdventureUtil;
import com.earth2me.essentials.utils.NumberUtil;
import com.google.common.collect.Lists;
import net.ess3.api.MaxMoneyException;
import net.ess3.api.TranslatableException;
import net.ess3.api.events.UserBalanceUpdateEvent;
import net.ess3.provider.PlayerLocaleProvider;
import org.bukkit.Server;
import java.math.BigDecimal;
@@ -35,14 +33,7 @@ public class Commandeco extends EssentialsLoopCommand {
try {
cmd = EcoCommands.valueOf(args[0].toUpperCase(Locale.ENGLISH));
isPercent = cmd != EcoCommands.RESET && args[2].endsWith("%");
if (cmd == EcoCommands.RESET) {
amount = ess.getSettings().getStartingBalance();
} else if (sender.isPlayer() && ess.getSettings().isPerPlayerLocale()) {
final String playerLocale = ess.provider(PlayerLocaleProvider.class).getLocale(sender.getPlayer());
amount = NumberUtil.parseStringToBDecimal(args[2], ess.getUser(sender.getPlayer()).getPlayerLocale(playerLocale));
} else {
amount = NumberUtil.parseStringToBDecimal(args[2]);
}
amount = (cmd == EcoCommands.RESET) ? ess.getSettings().getStartingBalance() : new BigDecimal(args[2].replaceAll("[^0-9\\.]", ""));
} catch (final Exception ex) {
throw new NotEnoughArgumentsException(ex);
}
@@ -62,7 +53,7 @@ public class Commandeco extends EssentialsLoopCommand {
if (player.getMoney().subtract(userAmount).compareTo(ess.getSettings().getMinMoney()) >= 0) {
player.takeMoney(userAmount, sender, UserBalanceUpdateEvent.Cause.COMMAND_ECO);
} else {
ess.showError(sender, new TranslatableException("minimumBalanceError", AdventureUtil.parsed(NumberUtil.displayCurrency(ess.getSettings().getMinMoney(), ess))), commandLabel);
ess.showError(sender, new TranslatableException("minimumBalanceError", NumberUtil.displayCurrency(ess.getSettings().getMinMoney(), ess)), commandLabel);
}
break;
}
@@ -73,8 +64,8 @@ public class Commandeco extends EssentialsLoopCommand {
final boolean underMin = userAmount.compareTo(minBal) < 0;
final boolean aboveMax = userAmount.compareTo(maxBal) > 0;
player.setMoney(underMin ? minBal : aboveMax ? maxBal : userAmount, UserBalanceUpdateEvent.Cause.COMMAND_ECO);
player.sendTl("setBal", AdventureUtil.parsed(NumberUtil.displayCurrency(player.getMoney(), ess)));
sender.sendTl("setBalOthers", player.getDisplayName(), AdventureUtil.parsed(NumberUtil.displayCurrency(player.getMoney(), ess)));
player.sendTl("setBal", NumberUtil.displayCurrency(player.getMoney(), ess));
sender.sendTl("setBalOthers", player.getDisplayName(), NumberUtil.displayCurrency(player.getMoney(), ess));
break;
}
}
@@ -95,7 +86,7 @@ public class Commandeco extends EssentialsLoopCommand {
}
return options;
} else if (args.length == 2) {
return getPlayers(sender);
return getPlayers(server, sender);
} else if (args.length == 3 && !args[0].equalsIgnoreCase(EcoCommands.RESET.name())) {
if (args[0].equalsIgnoreCase(EcoCommands.SET.name())) {
return Lists.newArrayList("0", ess.getSettings().getStartingBalance().toString());
@@ -17,6 +17,7 @@ import org.bukkit.block.data.type.HangingSign;
import org.bukkit.block.data.type.WallHangingSign;
import org.bukkit.block.data.type.WallSign;
import org.bukkit.block.sign.Side;
import org.bukkit.entity.Player;
import org.bukkit.event.block.SignChangeEvent;
import org.bukkit.util.Vector;
@@ -48,7 +49,7 @@ public class Commandeditsign extends EssentialsCommand {
throw new TranslatableException("editsignCommandLimit");
}
existingLines[line] = text;
if (callSignEvent(sign, user, existingLines)) {
if (callSignEvent(sign, user.getBase(), existingLines)) {
return;
}
@@ -60,7 +61,7 @@ public class Commandeditsign extends EssentialsCommand {
existingLines[i] = "";
}
if (callSignEvent(sign, user, existingLines)) {
if (callSignEvent(sign, user.getBase(), existingLines)) {
return;
}
@@ -70,7 +71,7 @@ public class Commandeditsign extends EssentialsCommand {
final int line = Integer.parseInt(args[1]) - 1;
existingLines[line] = "";
if (callSignEvent(sign, user, existingLines)) {
if (callSignEvent(sign, user.getBase(), existingLines)) {
return;
}
@@ -99,17 +100,13 @@ public class Commandeditsign extends EssentialsCommand {
for (int i = 0; i < 4; i++) {
existingLines[i] = FormatUtil.formatString(user, "essentials.editsign", user.getSignCopy().get(i));
}
if (callSignEvent(sign, user, existingLines)) {
return;
}
user.sendTl("editsignPaste", commandLabel);
} else {
existingLines[line] = FormatUtil.formatString(user, "essentials.editsign", user.getSignCopy().get(line));
if (callSignEvent(sign, user, existingLines)) {
return;
}
user.sendTl("editsignPasteLine", line + 1, commandLabel);
}
callSignEvent(sign, user.getBase(), existingLines);
} else {
throw new NotEnoughArgumentsException();
}
@@ -118,22 +115,22 @@ public class Commandeditsign extends EssentialsCommand {
}
}
private boolean callSignEvent(final ModifiableSign sign, final User user, final String[] lines) {
private boolean callSignEvent(final ModifiableSign sign, final Player player, final String[] lines) {
final SignChangeEvent event;
if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_20_1_R01)) {
if (sign.isWaxed() && !user.isAuthorized("essentials.editsign.waxed.exempt")) {
if (sign.isWaxed() && !player.hasPermission("essentials.editsign.waxed.exempt")) {
return true;
}
event = new SignChangeEvent(sign.getBlock(), user.getBase(), lines, sign.isFront() ? Side.FRONT : Side.BACK);
event = new SignChangeEvent(sign.getBlock(), player, lines, sign.isFront() ? Side.FRONT : Side.BACK);
} else {
//noinspection deprecation
event = new SignChangeEvent(sign.getBlock(), user.getBase(), lines);
event = new SignChangeEvent(sign.getBlock(), player, lines);
}
Bukkit.getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
if (ess.getSettings().isDebug()) {
ess.getLogger().info("SignChangeEvent canceled for /editsign execution by " + user.getName());
ess.getLogger().info("SignChangeEvent canceled for /editsign execution by " + player.getName());
}
return true;
}
@@ -26,7 +26,7 @@ public class Commandenderchest extends EssentialsCommand {
@Override
protected List<String> getTabCompleteOptions(final Server server, final User user, final String commandLabel, final String[] args) {
if (args.length == 1 && user.isAuthorized("essentials.enderchest.others")) {
return getPlayers(user);
return getPlayers(server, user);
} else {
return Collections.emptyList();
}
@@ -1,31 +1,958 @@
package com.earth2me.essentials.commands;
import com.earth2me.essentials.commands.essentials.CleanupCommand;
import com.earth2me.essentials.commands.essentials.CommandMapCommand;
import com.earth2me.essentials.commands.essentials.DebugCommand;
import com.earth2me.essentials.commands.essentials.DumpCommand;
import com.earth2me.essentials.commands.essentials.HomesCommand;
import com.earth2me.essentials.commands.essentials.ItemTestCommand;
import com.earth2me.essentials.commands.essentials.MooCommand;
import com.earth2me.essentials.commands.essentials.NyanCommand;
import com.earth2me.essentials.commands.essentials.ReloadCommand;
import com.earth2me.essentials.commands.essentials.UsermapCommand;
import com.earth2me.essentials.commands.essentials.VersionCommand;
import com.earth2me.essentials.CommandSource;
import com.earth2me.essentials.EssentialsUpgrade;
import com.earth2me.essentials.User;
import com.earth2me.essentials.craftbukkit.Inventories;
import com.earth2me.essentials.economy.EconomyLayer;
import com.earth2me.essentials.economy.EconomyLayers;
import com.earth2me.essentials.userstorage.ModernUserMap;
import com.earth2me.essentials.utils.AdventureUtil;
import com.earth2me.essentials.utils.CommandMapUtil;
import com.earth2me.essentials.utils.DateUtil;
import com.earth2me.essentials.utils.EnumUtil;
import com.earth2me.essentials.utils.FloatUtil;
import com.earth2me.essentials.utils.NumberUtil;
import com.earth2me.essentials.utils.PasteUtil;
import com.earth2me.essentials.utils.VersionUtil;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.gson.JsonArray;
import com.google.gson.JsonNull;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import net.ess3.api.TranslatableException;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Server;
import org.bukkit.Sound;
import org.bukkit.World;
import org.bukkit.command.Command;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.plugin.PluginManager;
import org.bukkit.scheduler.BukkitRunnable;
import java.io.File;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.function.Supplier;
import java.util.logging.Level;
import java.util.stream.Collectors;
import static com.earth2me.essentials.I18n.tlLiteral;
// This command has 4 undocumented behaviours #EasterEgg
public class Commandessentials extends EssentialsTreeCommand {
public class Commandessentials extends EssentialsCommand {
private static final Sound NOTE_HARP = EnumUtil.valueOf(Sound.class, "BLOCK_NOTE_BLOCK_HARP", "BLOCK_NOTE_HARP", "NOTE_PIANO");
private static final Sound MOO_SOUND = EnumUtil.valueOf(Sound.class, "COW_IDLE", "ENTITY_COW_MILK");
private static final String HOMES_USAGE = "/<command> homes (fix | delete [world])";
private static final String NYAN_TUNE = "1D#,1E,2F#,,2A#,1E,1D#,1E,2F#,2B,2D#,2E,2D#,2A#,2B,,2F#,,1D#,1E,2F#,2B,2C#,2A#,2B,2C#,2E,2D#,2E,2C#,,2F#,,2G#,,1D,1D#,,1C#,1D,1C#,1B,,1B,,1C#,,1D,,1D,1C#,1B,1C#,1D#,2F#,2G#,1D#,2F#,1C#,1D#,1B,1C#,1B,1D#,,2F#,,2G#,1D#,2F#,1C#,1D#,1B,1D,1D#,1D,1C#,1B,1C#,1D,,1B,1C#,1D#,2F#,1C#,1D,1C#,1B,1C#,,1B,,1C#,,2F#,,2G#,,1D,1D#,,1C#,1D,1C#,1B,,1B,,1C#,,1D,,1D,1C#,1B,1C#,1D#,2F#,2G#,1D#,2F#,1C#,1D#,1B,1C#,1B,1D#,,2F#,,2G#,1D#,2F#,1C#,1D#,1B,1D,1D#,1D,1C#,1B,1C#,1D,,1B,1C#,1D#,2F#,1C#,1D,1C#,1B,1C#,,1B,,1B,,1B,,1F#,1G#,1B,,1F#,1G#,1B,1C#,1D#,1B,1E,1D#,1E,2F#,1B,,1B,,1F#,1G#,1B,1E,1D#,1C#,1B,,,,1F#,1B,,1F#,1G#,1B,,1F#,1G#,1B,1B,1C#,1D#,1B,1F#,1G#,1F#,1B,,1B,1A#,1B,1F#,1G#,1B,1E,1D#,1E,2F#,1B,,1A#,,1B,,1F#,1G#,1B,,1F#,1G#,1B,1C#,1D#,1B,1E,1D#,1E,2F#,1B,,1B,,1F#,1G#,1B,1F#,1E,1D#,1C#,1B,,,,1F#,1B,,1F#,1G#,1B,,1F#,1G#,1B,1B,1C#,1D#,1B,1F#,1G#,1F#,1B,,1B,1A#,1B,1F#,1G#,1B,1E,1D#,1E,2F#,1B,,1A#,,1B,,1F#,1G#,1B,,1F#,1G#,1B,1C#,1D#,1B,1E,1D#,1E,2F#,1B,,1B,,1F#,1G#,1B,1F#,1E,1D#,1C#,1B,,,,1F#,1B,,1F#,1G#,1B,,1F#,1G#,1B,1B,1C#,1D#,1B,1F#,1G#,1F#,1B,,1B,1A#,1B,1F#,1G#,1B,1E,1D#,1E,2F#,1B,,1A#,,1B,,1F#,1G#,1B,,1F#,1G#,1B,1C#,1D#,1B,1E,1D#,1E,2F#,1B,,1B,,1F#,1G#,1B,1F#,1E,1D#,1C#,1B,,,,1F#,1B,,1F#,1G#,1B,,1F#,1G#,1B,1B,1C#,1D#,1B,1F#,1G#,1F#,1B,,1B,1A#,1B,1F#,1G#,1B,1E,1D#,1E,2F#,1B,,1A#,,1B,,1F#,1G#,1B,,1F#,1G#,1B,1C#,1D#,1B,1E,1D#,1E,2F#,1B,,1B,,1F#,1G#,1B,1F#,1E,1D#,1C#,1B,,,,1F#,1B,,1F#,1G#,1B,,1F#,1G#,1B,1B,1C#,1D#,1B,1F#,1G#,1F#,1B,,1B,1A#,1B,1F#,1G#,1B,1E,1D#,1E,2F#,1B,,1B,,";
private static final String[] CONSOLE_MOO = new String[] {" (__)", " (oo)", " /------\\/", " / | ||", " * /\\---/\\", " ~~ ~~", "....\"Have you mooed today?\"..."};
private static final String[] PLAYER_MOO = new String[] {" (__)", " (oo)", " /------\\/", " / | | |", " * /\\---/\\", " ~~ ~~", "....\"Have you mooed today?\"..."};
private static final List<String> versionPlugins = Arrays.asList(
"Vault", // API
"Reserve", // API
"PlaceholderAPI", // API
"CMI", // potential for issues
"Towny", // past issues; admins should ensure latest
"ChestShop", // past issues; admins should ensure latest
"Citizens", // fires player events
"LuckPerms", // permissions (recommended)
"UltraPermissions",
"PermissionsEx", // permissions (unsupported)
"GroupManager", // permissions (unsupported)
"bPermissions", // permissions (unsupported)
"DiscordSRV", // potential for issues if EssentialsXDiscord is installed
// Chat signing bypass plugins that can potentially break EssentialsChat
"AntiPopup",
"NoChatReports",
"NoEncryption"
);
private static final List<String> officialPlugins = Arrays.asList(
"EssentialsAntiBuild",
"EssentialsChat",
"EssentialsDiscord",
"EssentialsDiscordLink",
"EssentialsGeoIP",
"EssentialsProtect",
"EssentialsSpawn",
"EssentialsXMPP"
);
private static final List<String> warnPlugins = Arrays.asList(
"PermissionsEx",
"GroupManager",
"bPermissions",
// Brain-dead chat signing bypass that break EssentialsChat
"NoChatReports",
"NoEncryption"
);
private transient TuneRunnable currentTune = null;
public Commandessentials() {
super("essentials");
registerNode(new VersionCommand());
registerNode(new DebugCommand());
registerNode(new CommandMapCommand());
registerNode(new DumpCommand());
registerNode(new ReloadCommand());
registerNode(new CleanupCommand());
registerNode(new HomesCommand());
registerNode(new UsermapCommand());
registerNode(new ItemTestCommand());
registerNode(new NyanCommand());
registerNode(new MooCommand());
}
@Override
public void run(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
if (args.length == 0) {
showUsage(sender);
}
switch (args[0]) {
// Info commands
case "debug":
case "verbose":
runDebug(server, sender, commandLabel, args);
break;
case "ver":
case "version":
runVersion(server, sender, commandLabel, args);
break;
case "cmd":
case "commands":
runCommands(server, sender, commandLabel, args);
break;
case "dump":
runDump(server, sender, commandLabel, args);
break;
// Data commands
case "reload":
runReload(server, sender, commandLabel, args);
break;
case "reset":
runReset(server, sender, commandLabel, args);
break;
case "cleanup":
runCleanup(server, sender, commandLabel, args);
break;
case "homes":
runHomes(server, sender, commandLabel, args);
break;
case "usermap":
runUserMap(sender, args);
break;
case "itemtest":
runItemTest(server, sender, commandLabel, args);
break;
// "#EasterEgg"
case "nya":
case "nyan":
runNya(server, sender, commandLabel, args);
break;
case "moo":
runMoo(server, sender, commandLabel, args);
break;
default:
showUsage(sender);
break;
}
}
public void runItemTest(Server server, CommandSource sender, String commandLabel, String[] args) {
if (!sender.isAuthorized("essentials.itemtest") || args.length < 2 || !sender.isPlayer()) {
return;
}
final Player player = sender.getPlayer();
assert player != null;
switch (args[1]) {
case "slot": {
if (args.length < 3) {
return;
}
player.getInventory().setItem(Integer.parseInt(args[2]), new ItemStack(Material.DIRT));
break;
}
case "overfill": {
sender.sendMessage(Inventories.addItem(player, 42, false, new ItemStack(Material.DIAMOND_SWORD, 1), new ItemStack(Material.DIRT, 32), new ItemStack(Material.DIRT, 32)).toString());
break;
}
case "overfill2": {
if (args.length < 4) {
return;
}
final boolean armor = Boolean.parseBoolean(args[2]);
final boolean add = Boolean.parseBoolean(args[3]);
final ItemStack[] items = new ItemStack[]{new ItemStack(Material.DIAMOND_SWORD, 1), new ItemStack(Material.DIRT, 32), new ItemStack(Material.DIRT, 32), new ItemStack(Material.DIAMOND_HELMET, 4), new ItemStack(Material.CHAINMAIL_LEGGINGS, 1)};
if (Inventories.hasSpace(player, 0, armor, items)) {
if (add) {
sender.sendMessage(Inventories.addItem(player, 0, armor, items).toString());
}
sender.sendMessage("SO MUCH SPACE!");
} else {
sender.sendMessage("No space!");
}
break;
}
case "remove": {
if (args.length < 3) {
return;
}
Inventories.removeItemExact(player, new ItemStack(Material.PUMPKIN, 1), Boolean.parseBoolean(args[2]));
break;
}
default: {
break;
}
}
}
// Displays the command's usage.
private void showUsage(final CommandSource sender) throws Exception {
throw new NotEnoughArgumentsException();
}
// Lists commands that are being handed over to other plugins.
private void runCommands(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
if (ess.getAlternativeCommandsHandler().disabledCommands().size() == 0) {
sender.sendTl("blockListEmpty");
return;
}
sender.sendTl("blockList");
for (final Map.Entry<String, String> entry : ess.getAlternativeCommandsHandler().disabledCommands().entrySet()) {
sender.sendMessage(entry.getKey() + " => " + entry.getValue());
}
}
// Generates a paste of useful information
private void runDump(Server server, CommandSource sender, String commandLabel, String[] args) {
sender.sendTl("dumpCreating");
final JsonObject dump = new JsonObject();
final JsonObject meta = new JsonObject();
meta.addProperty("timestamp", Instant.now().toEpochMilli());
meta.addProperty("sender", sender.getPlayer() != null ? sender.getPlayer().getName() : null);
meta.addProperty("senderUuid", sender.getPlayer() != null ? sender.getPlayer().getUniqueId().toString() : null);
dump.add("meta", meta);
final JsonObject serverData = new JsonObject();
serverData.addProperty("bukkit-version", Bukkit.getBukkitVersion());
serverData.addProperty("server-version", Bukkit.getVersion());
serverData.addProperty("server-brand", Bukkit.getName());
serverData.addProperty("online-mode", ess.getOnlineModeProvider().getOnlineModeString());
final JsonObject supportStatus = new JsonObject();
final VersionUtil.SupportStatus status = VersionUtil.getServerSupportStatus();
supportStatus.addProperty("status", status.name());
supportStatus.addProperty("supported", status.isSupported());
supportStatus.addProperty("trigger", VersionUtil.getSupportStatusClass());
serverData.add("support-status", supportStatus);
dump.add("server-data", serverData);
final JsonObject environment = new JsonObject();
environment.addProperty("java-version", System.getProperty("java.version"));
environment.addProperty("operating-system", System.getProperty("os.name"));
environment.addProperty("uptime", DateUtil.formatDateDiff(ManagementFactory.getRuntimeMXBean().getStartTime()));
environment.addProperty("allocated-memory", (Runtime.getRuntime().totalMemory() / 1024 / 1024) + "MB");
dump.add("environment", environment);
final JsonObject essData = new JsonObject();
essData.addProperty("version", ess.getDescription().getVersion());
final JsonObject updateData = new JsonObject();
updateData.addProperty("id", ess.getUpdateChecker().getVersionIdentifier());
updateData.addProperty("branch", ess.getUpdateChecker().getVersionBranch());
updateData.addProperty("dev", ess.getUpdateChecker().isDevBuild());
essData.add("update-data", updateData);
final JsonObject econLayer = new JsonObject();
econLayer.addProperty("enabled", !ess.getSettings().isEcoDisabled());
econLayer.addProperty("selected-layer", EconomyLayers.isLayerSelected());
final EconomyLayer layer = EconomyLayers.getSelectedLayer();
econLayer.addProperty("name", layer == null ? "null" : layer.getName());
econLayer.addProperty("layer-version", layer == null ? "null" : layer.getPluginVersion());
econLayer.addProperty("backend-name", layer == null ? "null" : layer.getBackendName());
essData.add("economy-layer", econLayer);
final JsonArray addons = new JsonArray();
final JsonArray plugins = new JsonArray();
final ArrayList<Plugin> alphabetical = new ArrayList<>();
Collections.addAll(alphabetical, Bukkit.getPluginManager().getPlugins());
alphabetical.sort(Comparator.comparing(o -> o.getName().toUpperCase(Locale.ENGLISH)));
for (final Plugin plugin : alphabetical) {
final JsonObject pluginData = new JsonObject();
final PluginDescriptionFile info = plugin.getDescription();
final String name = info.getName();
pluginData.addProperty("name", name);
pluginData.addProperty("version", info.getVersion());
pluginData.addProperty("description", info.getDescription());
pluginData.addProperty("main", info.getMain());
pluginData.addProperty("enabled", plugin.isEnabled());
pluginData.addProperty("official", plugin == ess || officialPlugins.contains(name));
pluginData.addProperty("unsupported", warnPlugins.contains(name));
final JsonArray authors = new JsonArray();
for (final String author : info.getAuthors()) {
authors.add(author == null ? JsonNull.INSTANCE : new JsonPrimitive(author));
}
pluginData.add("authors", authors);
if (name.startsWith("Essentials") && !name.equals("Essentials")) {
addons.add(pluginData);
}
plugins.add(pluginData);
}
essData.add("addons", addons);
dump.add("ess-data", essData);
dump.add("plugins", plugins);
final List<PasteUtil.PasteFile> files = new ArrayList<>();
files.add(new PasteUtil.PasteFile("dump.json", dump.toString()));
final Plugin essDiscord = Bukkit.getPluginManager().getPlugin("EssentialsDiscord");
final Plugin essDiscordLink = Bukkit.getPluginManager().getPlugin("EssentialsDiscordLink");
final Plugin essSpawn = Bukkit.getPluginManager().getPlugin("EssentialsSpawn");
final Map<String, Command> knownCommandsCopy = new HashMap<>(ess.getKnownCommandsProvider().getKnownCommands());
final Map<String, String> disabledCommandsCopy = new HashMap<>(ess.getAlternativeCommandsHandler().disabledCommands());
// Further operations will be heavy IO
ess.runTaskAsynchronously(() -> {
boolean config = false;
boolean discord = false;
boolean kits = false;
boolean log = false;
boolean worth = false;
boolean tpr = false;
boolean spawns = false;
boolean commands = false;
for (final String arg : args) {
if (arg.equals("*") || arg.equalsIgnoreCase("all")) {
config = true;
discord = true;
kits = true;
log = true;
worth = true;
tpr = true;
spawns = true;
commands = true;
break;
} else if (arg.equalsIgnoreCase("config")) {
config = true;
} else if (arg.equalsIgnoreCase("discord")) {
discord = true;
} else if (arg.equalsIgnoreCase("kits")) {
kits = true;
} else if (arg.equalsIgnoreCase("log")) {
log = true;
} else if (arg.equalsIgnoreCase("worth")) {
worth = true;
} else if (arg.equalsIgnoreCase("tpr")) {
tpr = true;
} else if (arg.equalsIgnoreCase("spawns")) {
spawns = true;
} else if (arg.equalsIgnoreCase("commands")) {
commands = true;
}
}
if (config) {
try {
files.add(new PasteUtil.PasteFile("config.yml", new String(Files.readAllBytes(ess.getSettings().getConfigFile().toPath()), StandardCharsets.UTF_8)));
} catch (IOException e) {
sender.sendTl("dumpErrorUpload", "config.yml", e.getMessage());
}
}
if (discord && essDiscord != null) {
try {
files.add(new PasteUtil.PasteFile("discord-config.yml",
new String(Files.readAllBytes(essDiscord.getDataFolder().toPath().resolve("config.yml")), StandardCharsets.UTF_8)
.replaceAll("[A-Za-z\\d]{24}\\.[\\w-]{6}\\.[\\w-]{27}", "<censored token>")));
} catch (IOException e) {
sender.sendTl("dumpErrorUpload", "discord-config.yml", e.getMessage());
}
if (essDiscordLink != null) {
try {
files.add(new PasteUtil.PasteFile("discord-link-config.yml",
new String(Files.readAllBytes(essDiscordLink.getDataFolder().toPath().resolve("config.yml")), StandardCharsets.UTF_8)));
} catch (IOException e) {
sender.sendTl("dumpErrorUpload", "discord-link-config.yml", e.getMessage());
}
}
}
if (kits) {
try {
files.add(new PasteUtil.PasteFile("kits.yml", new String(Files.readAllBytes(ess.getKits().getFile().toPath()), StandardCharsets.UTF_8)));
} catch (IOException e) {
sender.sendTl("dumpErrorUpload", "kits.yml", e.getMessage());
}
}
if (log) {
try {
files.add(new PasteUtil.PasteFile("latest.log", new String(Files.readAllBytes(Paths.get("logs", "latest.log")), StandardCharsets.UTF_8)
.replaceAll("(?m)^\\[\\d\\d:\\d\\d:\\d\\d] \\[.+/(?:DEBUG|TRACE)]: .+\\s(?:[A-Za-z.]+:.+\\s(?:\\t.+\\s)*)?\\s*(?:\"[A-Za-z]+\" : .+[\\s}\\]]+)*", "")
.replaceAll("(?:[0-9]{1,3}\\.){3}[0-9]{1,3}", "<censored ip address>")));
} catch (IOException e) {
sender.sendTl("dumpErrorUpload", "latest.log", e.getMessage());
}
}
if (worth) {
try {
files.add(new PasteUtil.PasteFile("worth.yml", new String(Files.readAllBytes(ess.getWorth().getFile().toPath()), StandardCharsets.UTF_8)));
} catch (IOException e) {
sender.sendTl("dumpErrorUpload", "worth.yml", e.getMessage());
}
}
if (tpr) {
try {
files.add(new PasteUtil.PasteFile("tpr.yml", new String(Files.readAllBytes(ess.getRandomTeleport().getFile().toPath()), StandardCharsets.UTF_8)));
} catch (IOException e) {
sender.sendTl("dumpErrorUpload", "tpr.yml", e.getMessage());
}
}
if (spawns && essSpawn != null) {
try {
files.add(new PasteUtil.PasteFile("spawn.yml", new String(Files.readAllBytes(ess.getDataFolder().toPath().resolve("spawn.yml")), StandardCharsets.UTF_8)));
} catch (IOException e) {
sender.sendTl("dumpErrorUpload", "spawn.yml", e.getMessage());
}
}
if (commands) {
try {
files.add(new PasteUtil.PasteFile("commands.yml", new String(Files.readAllBytes(Paths.get("commands.yml")), StandardCharsets.UTF_8)));
files.add(new PasteUtil.PasteFile("commandmap.json", CommandMapUtil.toJsonPretty(ess, knownCommandsCopy)));
files.add(new PasteUtil.PasteFile("commandoverride.json", disabledCommandsCopy.toString()));
} catch (IOException e) {
sender.sendTl("dumpErrorUpload", "commands.yml", e.getMessage());
}
}
final CompletableFuture<PasteUtil.PasteResult> future = PasteUtil.createPaste(files);
future.thenAccept(result -> {
if (result != null) {
final String dumpUrl = "https://essentialsx.net/dump.html?id=" + result.getPasteId();
sender.sendTl("dumpUrl", dumpUrl);
sender.sendTl("dumpDeleteKey", result.getDeletionKey());
if (sender.isPlayer()) {
ess.getLogger().info(AdventureUtil.miniToLegacy(tlLiteral("dumpConsoleUrl", dumpUrl)));
ess.getLogger().info(AdventureUtil.miniToLegacy(tlLiteral("dumpDeleteKey", result.getDeletionKey())));
}
}
files.clear();
});
future.exceptionally(throwable -> {
sender.sendTl("dumpError", throwable.getMessage());
return null;
});
});
}
// Resets the given player's user data.
private void runReset(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
if (args.length < 2) {
throw new Exception("/<command> reset <player>");
}
final User user = getPlayer(server, args, 1, true, true);
user.reset();
sender.sendMessage("Reset Essentials userdata for player: " + user.getDisplayName());
}
// Toggles debug mode.
private void runDebug(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
ess.getSettings().setDebug(!ess.getSettings().isDebug());
sender.sendMessage("Essentials " + ess.getDescription().getVersion() + " debug mode " + (ess.getSettings().isDebug() ? "enabled" : "disabled"));
}
// Reloads all reloadable configs.
private void runReload(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
ess.reload();
sender.sendTl("essentialsReload", ess.getDescription().getVersion());
}
// Pop tarts.
private void runNya(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
if (currentTune != null) {
currentTune.cancel();
}
currentTune = new TuneRunnable(NYAN_TUNE, NOTE_HARP, ess::getOnlinePlayers);
currentTune.runTaskTimer(ess, 20, 2);
}
// Cow farts.
private void runMoo(final Server server, final CommandSource sender, final String command, final String[] args) {
if (args.length == 2 && args[1].equals("moo")) {
for (final String s : CONSOLE_MOO) {
ess.getLogger().info(s);
}
for (final Player player : ess.getOnlinePlayers()) {
player.sendMessage(PLAYER_MOO);
player.playSound(player.getLocation(), MOO_SOUND, 1, 1.0f);
}
} else {
if (sender.isPlayer()) {
sender.getSender().sendMessage(PLAYER_MOO);
final Player player = sender.getPlayer();
player.playSound(player.getLocation(), MOO_SOUND, 1, 1.0f);
} else {
sender.getSender().sendMessage(CONSOLE_MOO);
}
}
}
// Cleans up inactive users.
private void runCleanup(final Server server, final CommandSource sender, final String command, final String[] args) throws Exception {
if (args.length < 2 || !NumberUtil.isInt(args[1])) {
sender.sendMessage("This sub-command will delete users who haven't logged in in the last <days> days.");
sender.sendMessage("Optional parameters define the minimum amount required to prevent deletion.");
sender.sendMessage("Unless you define larger default values, this command will ignore people who have more than 0 money/homes.");
throw new Exception("/<command> cleanup <days> [money] [homes]");
}
sender.sendTl("cleaning");
final long daysArg = Long.parseLong(args[1]);
final double moneyArg = args.length >= 3 ? FloatUtil.parseDouble(args[2].replaceAll("[^0-9.]", "")) : 0;
final int homesArg = args.length >= 4 && NumberUtil.isInt(args[3]) ? Integer.parseInt(args[3]) : 0;
ess.runTaskAsynchronously(() -> {
final long currTime = System.currentTimeMillis();
for (final UUID u : ess.getUsers().getAllUserUUIDs()) {
final User user = ess.getUsers().loadUncachedUser(u);
if (user == null) {
continue;
}
long lastLog = user.getLastLogout();
if (lastLog == 0) {
lastLog = user.getLastLogin();
}
if (lastLog == 0) {
user.setLastLogin(currTime);
}
if (user.isNPC()) {
continue;
}
final long timeDiff = currTime - lastLog;
final long milliDays = daysArg * 24L * 60L * 60L * 1000L;
final int homeCount = user.getHomes().size();
final double moneyCount = user.getMoney().doubleValue();
if ((lastLog == 0) || (timeDiff < milliDays) || (homeCount > homesArg) || (moneyCount > moneyArg)) {
continue;
}
if (ess.getSettings().isDebug()) {
ess.getLogger().info("Deleting user: " + user.getName() + " Money: " + moneyCount + " Homes: " + homeCount + " Last seen: " + DateUtil.formatDateDiff(lastLog));
}
user.reset();
}
sender.sendTl("cleaned");
});
}
private void runHomes(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
if (args.length < 2) {
sender.sendMessage("This sub-command provides a utility to mass-delete homes based on user options:");
sender.sendMessage("Use \"fix\" to delete all homes inside non-existent or unloaded worlds.");
sender.sendMessage("Use \"delete\" to delete all existing homes.");
sender.sendMessage("Use \"delete <worldname>\" to delete all homes inside a specific world.");
throw new Exception(HOMES_USAGE);
}
switch (args[1]) {
case "fix":
sender.sendTl("fixingHomes");
ess.runTaskAsynchronously(() -> {
for (final UUID u : ess.getUsers().getAllUserUUIDs()) {
final User user = ess.getUsers().loadUncachedUser(u);
if (user == null) {
continue;
}
for (String homeName : user.getHomes()) {
try {
if (user.getHome(homeName) == null) {
user.delHome(homeName);
}
} catch (Exception e) {
ess.getLogger().info("Unable to delete home " + homeName + " for " + user.getName());
}
}
}
sender.sendTl("fixedHomes");
});
break;
case "delete":
final boolean filterByWorld = args.length >= 3;
if (filterByWorld && server.getWorld(args[2]) == null) {
throw new TranslatableException("invalidWorld");
}
if (filterByWorld) {
sender.sendTl("deletingHomesWorld", args[2]);
} else {
sender.sendTl("deletingHomes");
}
ess.runTaskAsynchronously(() -> {
for (final UUID u : ess.getUsers().getAllUserUUIDs()) {
final User user = ess.getUsers().loadUncachedUser(u);
if (user == null) {
continue;
}
for (String homeName : user.getHomes()) {
try {
final Location home = user.getHome(homeName);
if (!filterByWorld || (home != null && home.getWorld() != null && home.getWorld().getName().equals(args[2]))) {
user.delHome(homeName);
}
} catch (Exception e) {
ess.getLogger().info("Unable to delete home " + homeName + " for " + user.getName());
}
}
}
if (filterByWorld) {
sender.sendTl("deletedHomesWorld", args[2]);
} else {
sender.sendTl("deletedHomes");
}
});
break;
default:
throw new Exception(HOMES_USAGE);
}
}
// Gets information about cached users
private void runUserMap(final CommandSource sender, final String[] args) {
if (!sender.isAuthorized("essentials.usermap")) {
return;
}
final ModernUserMap userMap = (ModernUserMap) ess.getUsers();
sender.sendTl("usermapSize", userMap.getCachedCount(), userMap.getUserCount(), ess.getSettings().getMaxUserCacheCount());
if (args.length > 1) {
if (args[1].equals("full")) {
for (final Map.Entry<String, UUID> entry : userMap.getNameCache().entrySet()) {
sender.sendTl("usermapEntry", entry.getKey(), entry.getValue().toString());
}
} else if (args[1].equals("purge")) {
final boolean seppuku = args.length > 2 && args[2].equals("iknowwhatimdoing");
sender.sendTl("usermapPurge", String.valueOf(seppuku));
final Set<UUID> uuids = new HashSet<>(ess.getUsers().getAllUserUUIDs());
ess.runTaskAsynchronously(() -> {
final File userdataFolder = new File(ess.getDataFolder(), "userdata");
final File backupFolder = new File(ess.getDataFolder(), "userdata-npc-backup-boogaloo-" + System.currentTimeMillis());
if (!userdataFolder.isDirectory()) {
ess.getLogger().warning("Missing userdata folder, aborting usermap purge.");
return;
}
if (seppuku && !backupFolder.mkdir()) {
ess.getLogger().warning("Unable to create backup folder, aborting usermap purge.");
return;
}
int total = 0;
final File[] files = userdataFolder.listFiles(EssentialsUpgrade.YML_FILTER);
if (files != null) {
for (final File file : files) {
try {
final String fileName = file.getName();
final UUID uuid = UUID.fromString(fileName.substring(0, fileName.length() - 4));
if (!uuids.contains(uuid)) {
total++;
ess.getLogger().warning("Found orphaned userdata file: " + file.getName());
if (seppuku) {
try {
com.google.common.io.Files.move(file, new File(backupFolder, file.getName()));
} catch (IOException e) {
ess.getLogger().log(Level.WARNING, "Unable to move orphaned userdata file: " + file.getName(), e);
}
}
}
} catch (IllegalArgumentException ignored) {
}
}
}
ess.getLogger().info("Found " + total + " orphaned userdata files.");
});
} else if (args[1].equalsIgnoreCase("cache")) {
sender.sendTl("usermapKnown", ess.getUsers().getAllUserUUIDs().size(), ess.getUsers().getNameCache().size());
} else {
try {
final UUID uuid = UUID.fromString(args[1]);
for (final Map.Entry<String, UUID> entry : userMap.getNameCache().entrySet()) {
if (entry.getValue().equals(uuid)) {
sender.sendTl("usermapEntry", entry.getKey(), args[1]);
}
}
} catch (IllegalArgumentException ignored) {
final String sanitizedName = userMap.getSanitizedName(args[1]);
sender.sendTl("usermapEntry", sanitizedName, userMap.getNameCache().get(sanitizedName).toString());
}
}
}
}
// Displays versions of EssentialsX and related plugins.
private void runVersion(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
if (sender.isPlayer() && !ess.getUser(sender.getPlayer()).isAuthorized("essentials.version")) return;
boolean isMismatched = false;
boolean isVaultInstalled = false;
boolean isUnsupported = false;
final VersionUtil.SupportStatus supportStatus = VersionUtil.getServerSupportStatus();
final PluginManager pm = server.getPluginManager();
final String essVer = pm.getPlugin("Essentials").getDescription().getVersion();
final String serverMessageKey;
if (supportStatus.isSupported()) {
serverMessageKey = "versionOutputFine";
} else if (supportStatus == VersionUtil.SupportStatus.UNSTABLE) {
serverMessageKey = "versionOutputUnsupported";
} else {
serverMessageKey = "versionOutputWarn";
}
sender.sendTl(serverMessageKey, "Server", server.getBukkitVersion() + " " + server.getVersion());
sender.sendTl(serverMessageKey, "Brand", server.getName());
sender.sendTl("versionOutputFine", "EssentialsX", essVer);
for (final Plugin plugin : pm.getPlugins()) {
final PluginDescriptionFile desc = plugin.getDescription();
String name = desc.getName();
final String version = desc.getVersion();
if (name.startsWith("Essentials") && !name.equalsIgnoreCase("Essentials")) {
if (officialPlugins.contains(name)) {
name = name.replace("Essentials", "EssentialsX");
if (!version.equalsIgnoreCase(essVer)) {
isMismatched = true;
sender.sendTl("versionOutputWarn", name, version);
} else {
sender.sendTl("versionOutputFine", name, version);
}
} else {
sender.sendTl("versionOutputUnsupported", name, version);
isUnsupported = true;
}
}
if (versionPlugins.contains(name)) {
if (warnPlugins.contains(name)) {
sender.sendTl("versionOutputUnsupported", name, version);
isUnsupported = true;
} else {
sender.sendTl("versionOutputFine", name, version);
}
}
if (name.equals("Vault")) isVaultInstalled = true;
}
final String layer;
if (ess.getSettings().isEcoDisabled()) {
layer = "Disabled";
} else if (EconomyLayers.isLayerSelected()) {
final EconomyLayer economyLayer = EconomyLayers.getSelectedLayer();
layer = economyLayer.getName() + " (" + economyLayer.getBackendName() + ")";
} else {
layer = "None";
}
sender.sendTl("versionOutputEconLayer", layer);
if (isMismatched) {
sender.sendTl("versionMismatchAll");
}
if (!isVaultInstalled) {
sender.sendTl("versionOutputVaultMissing");
}
if (isUnsupported) {
sender.sendTl("versionOutputUnsupportedPlugins");
}
switch (supportStatus) {
case NMS_CLEANROOM:
sender.sendComponent(sender.tlComponent("serverUnsupportedCleanroom").color(NamedTextColor.DARK_RED));
break;
case DANGEROUS_FORK:
sender.sendComponent(sender.tlComponent("serverUnsupportedDangerous").color(NamedTextColor.DARK_RED));
break;
case STUPID_PLUGIN:
sender.sendComponent(sender.tlComponent("serverUnsupportedDumbPlugins").color(NamedTextColor.DARK_RED));
break;
case UNSTABLE:
sender.sendComponent(sender.tlComponent("serverUnsupportedMods").color(NamedTextColor.DARK_RED));
break;
case OUTDATED:
sender.sendComponent(sender.tlComponent("serverUnsupported").color(NamedTextColor.RED));
break;
case LIMITED:
sender.sendComponent(sender.tlComponent("serverUnsupportedLimitedApi").color(NamedTextColor.RED));
break;
}
if (VersionUtil.getSupportStatusClass() != null) {
sender.sendComponent(sender.tlComponent("serverUnsupportedClass").color(NamedTextColor.RED));
}
sender.sendTl("versionFetching");
ess.runTaskAsynchronously(() -> {
for (final Component component : ess.getUpdateChecker().getVersionMessages(true, true, sender)) {
sender.sendComponent(component);
}
});
}
@Override
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
if (args.length == 1) {
final List<String> options = Lists.newArrayList();
options.add("reload");
options.add("version");
options.add("dump");
options.add("commands");
options.add("debug");
options.add("reset");
options.add("cleanup");
options.add("homes");
//options.add("uuidconvert");
//options.add("nya");
//options.add("moo");
return options;
}
switch (args[0]) {
case "moo":
if (args.length == 2) {
return Lists.newArrayList("moo");
}
break;
case "reset":
if (args.length == 2) {
return getPlayers(server, sender);
}
break;
case "cleanup":
if (args.length == 2) {
return COMMON_DURATIONS;
} else if (args.length == 3 || args.length == 4) {
return Lists.newArrayList("-1", "0");
}
break;
case "homes":
if (args.length == 2) {
return Lists.newArrayList("fix", "delete");
} else if (args.length == 3 && args[1].equalsIgnoreCase("delete")) {
return server.getWorlds().stream().map(World::getName).collect(Collectors.toList());
}
break;
case "dump":
final List<String> list = Lists.newArrayList("config", "kits", "log", "discord", "worth", "tpr", "spawns", "commands", "all");
for (String arg : args) {
if (arg.equals("*") || arg.equalsIgnoreCase("all")) {
list.clear();
return list;
}
list.remove(arg.toLowerCase(Locale.ENGLISH));
}
return list;
}
return Collections.emptyList();
}
private static class TuneRunnable extends BukkitRunnable {
private static final Map<String, Float> noteMap = ImmutableMap.<String, Float>builder()
.put("1F#", 0.5f)
.put("1G", 0.53f)
.put("1G#", 0.56f)
.put("1A", 0.6f)
.put("1A#", 0.63f)
.put("1B", 0.67f)
.put("1C", 0.7f)
.put("1C#", 0.76f)
.put("1D", 0.8f)
.put("1D#", 0.84f)
.put("1E", 0.9f)
.put("1F", 0.94f)
.put("2F#", 1.0f)
.put("2G", 1.06f)
.put("2G#", 1.12f)
.put("2A", 1.18f)
.put("2A#", 1.26f)
.put("2B", 1.34f)
.put("2C", 1.42f)
.put("2C#", 1.5f)
.put("2D", 1.6f)
.put("2D#", 1.68f)
.put("2E", 1.78f)
.put("2F", 1.88f)
.build();
private final String[] tune;
private final Sound sound;
private final Supplier<Collection<Player>> players;
private int i = 0;
TuneRunnable(final String tuneStr, final Sound sound, final Supplier<Collection<Player>> players) {
this.tune = tuneStr.split(",");
this.sound = sound;
this.players = players;
}
@Override
public void run() {
final String note = tune[i];
i++;
if (i >= tune.length) {
cancel();
}
if (note == null || note.isEmpty()) {
return;
}
for (final Player onlinePlayer : players.get()) {
onlinePlayer.playSound(onlinePlayer.getLocation(), sound, 1, noteMap.get(note));
}
}
}
}
@@ -154,7 +154,7 @@ public class Commandexp extends EssentialsLoopCommand {
}
}
if (user.isAuthorized("essentials.exp.others")) {
return getPlayers(user);
return getPlayers(server, user);
}
} else if (args.length == 3 && !(args[0].equalsIgnoreCase("show") || args[0].equalsIgnoreCase("reset"))) {
final String levellessArg = args[2].toLowerCase(Locale.ENGLISH).replaceAll("l", "");
@@ -182,10 +182,10 @@ public class Commandexp extends EssentialsLoopCommand {
return Collections.emptyList();
}
} else { // even without 'show'
return getPlayers(sender);
return getPlayers(server, sender);
}
} else if (args.length == 3 && (args[0].equalsIgnoreCase("set") || args[0].equalsIgnoreCase("give"))) {
return getPlayers(sender);
return getPlayers(server, sender);
} else {
return Collections.emptyList();
}
@@ -46,7 +46,7 @@ public class Commandext extends EssentialsLoopCommand {
@Override
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
if (args.length == 1) {
return getPlayers(sender);
return getPlayers(server, sender);
} else {
return Collections.emptyList();
}
@@ -65,7 +65,7 @@ public class Commandfeed extends EssentialsLoopCommand {
@Override
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
if (args.length == 1 && sender.isAuthorized("essentials.feed.others")) {
return getPlayers(sender);
return getPlayers(server, sender);
} else {
return Collections.emptyList();
}
@@ -19,7 +19,6 @@ import org.bukkit.entity.Snowball;
import org.bukkit.entity.SplashPotion;
import org.bukkit.entity.ThrownExpBottle;
import org.bukkit.entity.Trident;
import org.bukkit.entity.WindCharge;
import org.bukkit.entity.WitherSkull;
import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.util.Vector;
@@ -56,10 +55,6 @@ public class Commandfireball extends EssentialsCommand {
builder.put("trident", Trident.class);
}
if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_21_R01)) {
builder.put("windcharge", WindCharge.class);
}
types = builder.build();
}
@@ -34,8 +34,6 @@ public class Commandfly extends EssentialsToggleCommand {
user.getBase().setFallDistance(0f);
user.getBase().setAllowFlight(enabled);
user.setFlyModeEnabled(enabled);
if (!user.getBase().getAllowFlight()) {
user.getBase().setFlying(false);
}
@@ -105,12 +105,12 @@ public class Commandgamemode extends EssentialsLoopCommand {
try {
// Direct command? Don't ask for the mode
matchGameMode(commandLabel);
return getPlayers(sender);
return getPlayers(server, sender);
} catch (final NotEnoughArgumentsException e) {
return STANDARD_OPTIONS;
}
} else if (args.length == 2) {
return getPlayers(sender);
return getPlayers(server, sender);
} else {
return Collections.emptyList();
}
@@ -128,12 +128,12 @@ public class Commandgamemode extends EssentialsLoopCommand {
}
if (args.length == 1) {
if (user.isAuthorized("essentials.gamemode.others") && isDirectGamemodeCommand) {
return getPlayers(user);
return getPlayers(server, user);
} else {
return STANDARD_OPTIONS;
}
} else if (args.length == 2 && user.isAuthorized("essentials.gamemode.others") && !isDirectGamemodeCommand) {
return getPlayers(user);
return getPlayers(server, user);
} else {
return Collections.emptyList();
}
@@ -3,7 +3,6 @@ package com.earth2me.essentials.commands;
import com.earth2me.essentials.CommandSource;
import com.earth2me.essentials.utils.DateUtil;
import com.earth2me.essentials.utils.NumberUtil;
import net.ess3.provider.TileEntityProvider;
import org.bukkit.ChatColor;
import org.bukkit.Chunk;
import org.bukkit.Server;
@@ -37,7 +36,6 @@ public class Commandgc extends EssentialsCommand {
sender.sendTl("gcfree", Runtime.getRuntime().freeMemory() / 1024 / 1024);
final List<World> worlds = server.getWorlds();
final TileEntityProvider tileEntityProvider = ess.provider(TileEntityProvider.class);
for (final World w : worlds) {
String worldType = "World";
switch (w.getEnvironment()) {
@@ -53,7 +51,7 @@ public class Commandgc extends EssentialsCommand {
try {
for (final Chunk chunk : w.getLoadedChunks()) {
tileEntities += tileEntityProvider.getTileEntities(chunk).length;
tileEntities += chunk.getTileEntities().length;
}
} catch (final java.lang.ClassCastException ex) {
ess.getLogger().log(Level.SEVERE, "Corrupted chunk data on world " + w, ex);
@@ -47,7 +47,7 @@ public class Commandgetpos extends EssentialsCommand {
@Override
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
if (args.length == 1 && sender.isAuthorized("essentials.getpos.others")) {
return getPlayers(sender);
return getPlayers(server, sender);
} else {
return Collections.emptyList();
}
@@ -99,7 +99,7 @@ public class Commandgive extends EssentialsLoopCommand {
@Override
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
if (args.length == 1) {
return getPlayers(sender);
return getPlayers(server, sender);
} else if (args.length == 2) {
return getItems();
} else if (args.length == 3) {
@@ -1,7 +1,6 @@
package com.earth2me.essentials.commands;
import com.earth2me.essentials.User;
import net.ess3.provider.ContainerProvider;
import org.bukkit.Server;
public class Commandgrindstone extends EssentialsCommand {
@@ -12,13 +11,11 @@ public class Commandgrindstone extends EssentialsCommand {
@Override
public void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
final ContainerProvider containerProvider = ess.provider(ContainerProvider.class);
if (containerProvider == null) {
if (ess.getContainerProvider() == null) {
user.sendTl("unsupportedBrand");
return;
}
containerProvider.openGrindstone(user.getBase());
ess.getContainerProvider().openGrindstone(user.getBase());
}
}
@@ -63,16 +63,13 @@ public class Commandheal extends EssentialsLoopCommand {
player.setHealth(newAmount);
player.setFoodLevel(20);
player.setFireTicks(0);
player.setRemainingAir(player.getMaximumAir());
user.sendTl("heal");
if (ess.getSettings().isRemovingEffectsOnHeal()) {
for (final PotionEffect effect : player.getActivePotionEffects()) {
player.removePotionEffect(effect.getType());
}
}
if (!sender.isPlayer() || !user.getBase().equals(sender.getPlayer())) {
sender.sendTl("healOther", user.getDisplayName());
}
sender.sendTl("healOther", user.getDisplayName());
} catch (final QuietAbortException e) {
//Handle Quietly
}
@@ -81,7 +78,7 @@ public class Commandheal extends EssentialsLoopCommand {
@Override
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
if (args.length == 1 && sender.isAuthorized("essentials.heal.others")) {
return getPlayers(sender);
return getPlayers(server, sender);
} else {
return Collections.emptyList();
@@ -7,9 +7,8 @@ import com.earth2me.essentials.textreader.IText;
import com.earth2me.essentials.textreader.KeywordReplacer;
import com.earth2me.essentials.textreader.TextInput;
import com.earth2me.essentials.textreader.TextPager;
import com.earth2me.essentials.adventure.AdventureUtil;
import com.earth2me.essentials.utils.AdventureUtil;
import com.earth2me.essentials.utils.NumberUtil;
import net.ess3.provider.KnownCommandsProvider;
import org.bukkit.Server;
import org.bukkit.command.Command;
import org.bukkit.command.PluginIdentifiableCommand;
@@ -19,7 +18,6 @@ import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.MissingResourceException;
public class Commandhelp extends EssentialsCommand {
public Commandhelp() {
@@ -37,27 +35,20 @@ public class Commandhelp extends EssentialsCommand {
if (input.getLines().isEmpty()) {
if (pageStr != null && pageStr.startsWith("/")) {
final String cmd = pageStr.substring(1);
for (final Map.Entry<String, Command> knownCmd : ess.provider(KnownCommandsProvider.class).getKnownCommands().entrySet()) {
for (final Map.Entry<String, Command> knownCmd : ess.getKnownCommandsProvider().getKnownCommands().entrySet()) {
if (knownCmd.getKey().equalsIgnoreCase(cmd)) {
final Command bukkit = knownCmd.getValue();
final boolean isEssCommand = bukkit instanceof PluginIdentifiableCommand && ((PluginIdentifiableCommand) bukkit).getPlugin().equals(ess);
final IEssentialsCommand essCommand = isEssCommand ? ess.getCommandMap().get(bukkit.getName()) : null;
user.sendTl("commandHelpLine1", cmd);
String description = bukkit.getDescription();
if (essCommand != null) {
try {
description = user.playerTl(bukkit.getName() + "CommandDescription");
} catch (MissingResourceException ignored) {}
}
user.sendTl("commandHelpLine2", description);
user.sendTl("commandHelpLine4", bukkit.getAliases().toString());
user.sendTl("commandHelpLine2", knownCmd.getValue().getDescription());
user.sendTl("commandHelpLine4", knownCmd.getValue().getAliases().toString());
user.sendTl("commandHelpLine3");
final boolean isEssCommand = knownCmd.getValue() instanceof PluginIdentifiableCommand && ((PluginIdentifiableCommand) knownCmd.getValue()).getPlugin().equals(ess);
final IEssentialsCommand essCommand = isEssCommand ? ess.getCommandMap().get(knownCmd.getValue().getName()) : null;
if (essCommand != null && !essCommand.getUsageStrings().isEmpty()) {
for (Map.Entry<String, String> usage : essCommand.getUsageStrings().entrySet()) {
user.sendTl("commandHelpLineUsage", AdventureUtil.parsed(usage.getKey().replace("<command>", cmd)), AdventureUtil.parsed(user.playerTl(usage.getValue())));
user.sendTl("commandHelpLineUsage", AdventureUtil.parsed(usage.getKey().replace("<command>", cmd)), AdventureUtil.parsed(usage.getValue()));
}
} else {
user.sendMessage(bukkit.getUsage());
user.sendMessage(knownCmd.getValue().getUsage());
}
return;
}
@@ -4,6 +4,7 @@ import com.earth2me.essentials.CommandSource;
import com.earth2me.essentials.Console;
import com.earth2me.essentials.User;
import com.earth2me.essentials.messaging.IMessageRecipient;
import com.earth2me.essentials.utils.AdventureUtil;
import com.earth2me.essentials.utils.FormatUtil;
import net.ess3.api.IUser;
import net.essentialsx.api.v2.events.HelpopMessageSendEvent;
@@ -38,11 +39,11 @@ public class Commandhelpop extends EssentialsCommand {
}
final String message = FormatUtil.stripFormat(getFinalArg(args, 0));
ess.getLogger().log(Level.INFO, ess.getAdventureFacet().miniToLegacy(tlLiteral("helpOp", from.getDisplayName(), message)));
ess.getLogger().log(Level.INFO, AdventureUtil.miniToLegacy(tlLiteral("helpOp", from.getDisplayName(), message)));
final List<IUser> recipients = new ArrayList<>();
for (IUser user : ess.getOnlineUsers()) {
if (user.isAuthorized("essentials.helpop.receive")) {
if (user.getBase().hasPermission("essentials.helpop.receive")) {
recipients.add(user);
}
}
@@ -50,11 +51,9 @@ public class Commandhelpop extends EssentialsCommand {
final HelpopMessageSendEvent sendEvent = new HelpopMessageSendEvent(from, recipients, message);
ess.getServer().getPluginManager().callEvent(sendEvent);
if (from instanceof IUser) {
final IUser sender = (IUser) from;
if (!recipients.contains(sender)) {
from.sendTl("helpOp", from.getDisplayName(), message);
}
final IUser sender = (IUser) from;
if(!recipients.contains(sender)){
from.sendTl("helpOp", from.getDisplayName(), message);
}
for (IUser recipient : sendEvent.getRecipients()) {
@@ -3,7 +3,7 @@ package com.earth2me.essentials.commands;
import com.earth2me.essentials.OfflinePlayerStub;
import com.earth2me.essentials.Trade;
import com.earth2me.essentials.User;
import com.earth2me.essentials.adventure.AdventureUtil;
import com.earth2me.essentials.utils.AdventureUtil;
import com.earth2me.essentials.utils.StringUtil;
import io.papermc.lib.PaperLib;
import net.ess3.api.TranslatableException;
@@ -41,10 +41,7 @@ public class Commandhome extends EssentialsCommand {
}
}
try {
if ("bed".equalsIgnoreCase(homeName)) {
if (!user.isAuthorized("essentials.home.bed")) {
throw new TranslatableException("noAccessCommand");
}
if ("bed".equalsIgnoreCase(homeName) && user.isAuthorized("essentials.home.bed")) {
if (!player.getBase().isOnline() || player.getBase() instanceof OfflinePlayerStub) {
throw new TranslatableException("bedOffline");
}
@@ -76,15 +73,10 @@ public class Commandhome extends EssentialsCommand {
final List<String> homes = finalPlayer.getHomes();
if (homes.isEmpty() && finalPlayer.equals(user)) {
if (ess.getSettings().isSpawnIfNoHome()) {
final boolean useBed = bed != null && user.isAuthorized("essentials.home.bed");
final UserTeleportHomeEvent event = new UserTeleportHomeEvent(user, null, useBed ? bed : finalPlayer.getWorld().getSpawnLocation(), useBed ? UserTeleportHomeEvent.HomeType.BED : UserTeleportHomeEvent.HomeType.SPAWN);
final UserTeleportHomeEvent event = new UserTeleportHomeEvent(user, null, bed != null ? bed : finalPlayer.getWorld().getSpawnLocation(), bed != null ? UserTeleportHomeEvent.HomeType.BED : UserTeleportHomeEvent.HomeType.SPAWN);
server.getPluginManager().callEvent(event);
if (!event.isCancelled()) {
if (useBed) {
user.getAsyncTeleport().respawn(charge, TeleportCause.COMMAND, getNewExceptionFuture(user.getSource(), commandLabel));
} else {
user.getAsyncTeleport().teleport(finalPlayer.getWorld().getSpawnLocation(), charge, TeleportCause.COMMAND, getNewExceptionFuture(user.getSource(), commandLabel));
}
user.getAsyncTeleport().respawn(charge, TeleportCause.COMMAND, getNewExceptionFuture(user.getSource(), commandLabel));
}
} else {
showError(user.getBase(), new TranslatableException("noHomeSetPlayer"), commandLabel);
@@ -163,7 +155,7 @@ public class Commandhome extends EssentialsCommand {
if (canVisitOthers) {
final int sepIndex = args[0].indexOf(':');
if (sepIndex < 0) {
getPlayers(user).forEach(player -> homes.add(player + ":"));
getPlayers(server, user).forEach(player -> homes.add(player + ":"));
} else {
final String namePart = args[0].substring(0, sepIndex);
final User otherUser;
@@ -49,7 +49,7 @@ public class Commandice extends EssentialsLoopCommand {
@Override
protected List<String> getTabCompleteOptions(Server server, CommandSource sender, String commandLabel, String[] args) {
if (args.length == 1 && sender.isAuthorized("essentials.ice.others")) {
return getPlayers(sender);
return getPlayers(server, sender);
} else {
return Collections.emptyList();
}
@@ -27,7 +27,15 @@ public class Commandignore extends EssentialsCommand {
return;
}
final User player = getPlayer(server, args, 0, false, true);
User player;
try {
player = getPlayer(server, args, 0, true, true);
} catch (final PlayerNotFoundException ex) {
player = ess.getOfflineUser(args[0]);
}
if (player == null) {
throw new PlayerNotFoundException();
}
if (player.isIgnoreExempt()) {
user.sendTl("ignoreExempt");
@@ -45,7 +53,7 @@ public class Commandignore extends EssentialsCommand {
@Override
protected List<String> getTabCompleteOptions(final Server server, final User user, final String commandLabel, final String[] args) {
if (args.length == 1) {
return getPlayers(user);
return getPlayers(server, user);
} else {
return Collections.emptyList();
}
@@ -45,7 +45,7 @@ public class Commandinvsee extends EssentialsCommand {
@Override
protected List<String> getTabCompleteOptions(final Server server, final User user, final String commandLabel, final String[] args) {
if (args.length == 1) {
final List<String> suggestions = getPlayers(user);
final List<String> suggestions = getPlayers(server, user);
suggestions.remove(user.getName());
return suggestions;
} else {
@@ -1,23 +0,0 @@
package com.earth2me.essentials.commands;
import com.earth2me.essentials.CommandSource;
import com.earth2me.essentials.utils.StringUtil;
import org.bukkit.Server;
import org.bukkit.entity.Player;
import java.util.stream.Collectors;
public class Commandjailedplayers extends EssentialsCommand {
public Commandjailedplayers() {
super("jailedplayers");
}
@Override
protected void run(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
if (ess.getJailedPlayers() != null && !ess.getJailedPlayers().isEmpty()) {
sender.sendTl("jailedPlayersList", StringUtil.joinList(", ", ess.getJailedPlayers().stream().map(Player::getName).collect(Collectors.toList())));
} else {
sender.sendTl("jailedPlayersEmpty");
}
}
}
@@ -3,6 +3,7 @@ package com.earth2me.essentials.commands;
import com.earth2me.essentials.CommandSource;
import com.earth2me.essentials.Console;
import com.earth2me.essentials.User;
import com.earth2me.essentials.utils.AdventureUtil;
import com.earth2me.essentials.utils.FormatUtil;
import net.ess3.api.TranslatableException;
import net.essentialsx.api.v2.events.UserKickEvent;
@@ -38,7 +39,7 @@ public class Commandkick extends EssentialsCommand {
}
}
String kickReason = args.length > 1 ? getFinalArg(args, 1) : ess.getAdventureFacet().miniToLegacy(tlLiteral("kickDefault"));
String kickReason = args.length > 1 ? getFinalArg(args, 1) : AdventureUtil.miniToLegacy(tlLiteral("kickDefault"));
kickReason = FormatUtil.replaceFormat(kickReason.replace("\\n", "\n").replace("|", "\n"));
final UserKickEvent event = new UserKickEvent(user, target, kickReason);
@@ -50,18 +51,18 @@ public class Commandkick extends EssentialsCommand {
kickReason = event.getReason();
target.getBase().kickPlayer(kickReason);
final String senderDisplayName = sender.isPlayer() ? sender.getPlayer().getDisplayName() : Console.displayName();
final String senderDisplayName = sender.isPlayer() ? sender.getPlayer().getDisplayName() : Console.DISPLAY_NAME;
final String tlKey = "playerKicked";
final Object[] objects = {senderDisplayName, target.getName(), kickReason};
ess.getLogger().log(Level.INFO, ess.getAdventureFacet().miniToLegacy(tlLiteral(tlKey, objects)));
ess.getLogger().log(Level.INFO, AdventureUtil.miniToLegacy(tlLiteral(tlKey, objects)));
ess.broadcastTl(null, "essentials.kick.notify", tlKey, objects);
}
@Override
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
if (args.length == 1) {
return getPlayers(sender);
return getPlayers(server, sender);
} else {
return Collections.emptyList();
}
@@ -1,6 +1,7 @@
package com.earth2me.essentials.commands;
import com.earth2me.essentials.CommandSource;
import com.earth2me.essentials.utils.AdventureUtil;
import com.earth2me.essentials.utils.FormatUtil;
import org.bukkit.Server;
import org.bukkit.entity.Player;
@@ -14,7 +15,7 @@ public class Commandkickall extends EssentialsCommand {
@Override
public void run(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
String kickReason = args.length > 0 ? getFinalArg(args, 0) : ess.getAdventureFacet().miniToLegacy(tlLiteral("kickDefault"));
String kickReason = args.length > 0 ? getFinalArg(args, 0) : AdventureUtil.miniToLegacy(tlLiteral("kickDefault"));
kickReason = FormatUtil.replaceFormat(kickReason.replace("\\n", "\n").replace("|", "\n"));
for (final Player onlinePlayer : ess.getOnlinePlayers()) {
@@ -2,7 +2,6 @@ package com.earth2me.essentials.commands;
import com.earth2me.essentials.CommandSource;
import com.earth2me.essentials.User;
import net.ess3.provider.DamageEventProvider;
import org.bukkit.Server;
import org.bukkit.entity.Player;
import org.bukkit.event.entity.EntityDamageEvent;
@@ -30,9 +29,7 @@ public class Commandkill extends EssentialsLoopCommand {
if (sender.isPlayer() && user.isAuthorized("essentials.kill.exempt") && !ess.getUser(sender.getPlayer()).isAuthorized("essentials.kill.force")) {
throw new PlayerExemptException("killExempt", matchPlayer.getDisplayName());
}
final DamageEventProvider provider = ess.provider(DamageEventProvider.class);
final EntityDamageEvent ede = provider.callDamageEvent(matchPlayer, sender.isPlayer() && sender.getPlayer().getName().equals(matchPlayer.getName()) ? EntityDamageEvent.DamageCause.SUICIDE : EntityDamageEvent.DamageCause.CUSTOM, Float.MAX_VALUE);
final EntityDamageEvent ede = ess.getDamageEventProvider().callDamageEvent(matchPlayer, sender.isPlayer() && sender.getPlayer().getName().equals(matchPlayer.getName()) ? EntityDamageEvent.DamageCause.SUICIDE : EntityDamageEvent.DamageCause.CUSTOM, Float.MAX_VALUE);
if (ede.isCancelled() && sender.isPlayer() && !ess.getUser(sender.getPlayer()).isAuthorized("essentials.kill.force")) {
return;
}
@@ -44,7 +41,7 @@ public class Commandkill extends EssentialsLoopCommand {
@Override
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
if (args.length == 1) {
return getPlayers(sender);
return getPlayers(server, sender);
} else {
return Collections.emptyList();
}
@@ -3,7 +3,7 @@ package com.earth2me.essentials.commands;
import com.earth2me.essentials.CommandSource;
import com.earth2me.essentials.Kit;
import com.earth2me.essentials.User;
import com.earth2me.essentials.adventure.AdventureUtil;
import com.earth2me.essentials.utils.AdventureUtil;
import com.earth2me.essentials.utils.StringUtil;
import net.ess3.api.TranslatableException;
import org.bukkit.Server;
@@ -108,7 +108,7 @@ public class Commandkit extends EssentialsCommand {
}
return options;
} else if (args.length == 2 && user.isAuthorized("essentials.kit.others")) {
return getPlayers(user);
return getPlayers(server, user);
} else {
return Collections.emptyList();
}
@@ -119,7 +119,7 @@ public class Commandkit extends EssentialsCommand {
if (args.length == 1) {
return new ArrayList<>(ess.getKits().getKitKeys()); // TODO: Move this to its own method
} else if (args.length == 2) {
return getPlayers(sender);
return getPlayers(server, sender);
} else {
return Collections.emptyList();
}
@@ -59,7 +59,7 @@ public class Commandkitreset extends EssentialsCommand {
if (args.length == 1) {
return new ArrayList<>(ess.getKits().getKitKeys());
} else if (args.length == 2 && sender.isAuthorized("essentials.kitreset.others")) {
return getPlayers(sender);
return getPlayers(server, sender);
} else {
return Collections.emptyList();
}
@@ -2,7 +2,6 @@ package com.earth2me.essentials.commands;
import com.earth2me.essentials.Mob;
import com.earth2me.essentials.User;
import com.earth2me.essentials.utils.RegistryUtil;
import org.bukkit.Location;
import org.bukkit.Server;
import org.bukkit.entity.Cat;
@@ -22,12 +21,8 @@ public class Commandkittycannon extends EssentialsCommand {
private static Ocelot spawnOcelot(final Server server, final User user) throws Mob.MobException {
final Ocelot ocelot = (Ocelot) Mob.OCELOT.spawn(user.getWorld(), server, user.getBase().getEyeLocation());
//noinspection deprecation
final Object[] values = RegistryUtil.values(Ocelot.Type.class);
final int i = random.nextInt(values.length);
//noinspection deprecation
ocelot.setCatType((Ocelot.Type) values[i]);
final int i = random.nextInt(Ocelot.Type.values().length);
ocelot.setCatType(Ocelot.Type.values()[i]);
((Tameable) ocelot).setTamed(true);
ocelot.setBaby();
ocelot.setVelocity(user.getBase().getEyeLocation().getDirection().multiply(2));
@@ -36,10 +31,8 @@ public class Commandkittycannon extends EssentialsCommand {
private static Entity spawnCat(final Server server, final User user) throws Mob.MobException {
final Cat cat = (Cat) Mob.CAT.spawn(user.getWorld(), server, user.getBase().getEyeLocation());
final Object[] values = RegistryUtil.values(Cat.Type.class);
final int i = random.nextInt(values.length);
cat.setCatType((Cat.Type) values[i]);
final int i = random.nextInt(Cat.Type.values().length);
cat.setCatType(Cat.Type.values()[i]);
cat.setTamed(true);
cat.setBaby();
cat.setVelocity(user.getBase().getEyeLocation().getDirection().multiply(2));
@@ -63,7 +63,7 @@ public class Commandlightning extends EssentialsLoopCommand {
@Override
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
if (args.length == 1) {
return getPlayers(sender);
return getPlayers(server, sender);
} else if (args.length == 2) {
return Lists.newArrayList("5");
} else {
@@ -3,6 +3,7 @@ package com.earth2me.essentials.commands;
import com.earth2me.essentials.CommandSource;
import com.earth2me.essentials.PlayerList;
import com.earth2me.essentials.User;
import com.earth2me.essentials.utils.AdventureUtil;
import org.bukkit.Server;
import java.util.ArrayList;
@@ -23,11 +24,11 @@ public class Commandlist extends EssentialsCommand {
user = ess.getUser(sender.getPlayer());
showHidden = user.isAuthorized("essentials.list.hidden") || user.canInteractVanished();
}
sender.sendComponent(ess.getAdventureFacet().deserializeMiniMessage(PlayerList.listSummary(ess, user, showHidden)));
sender.sendComponent(AdventureUtil.miniMessage().deserialize(PlayerList.listSummary(ess, user, showHidden)));
final Map<String, List<User>> playerList = PlayerList.getPlayerLists(ess, user, showHidden);
if (args.length > 0) {
sender.sendComponent(ess.getAdventureFacet().deserializeMiniMessage(PlayerList.listGroupUsers(ess, playerList, args[0].toLowerCase())));
sender.sendComponent(AdventureUtil.miniMessage().deserialize(PlayerList.listGroupUsers(ess, playerList, args[0].toLowerCase())));
} else {
sendGroupedList(sender, commandLabel, playerList);
}
@@ -36,7 +37,7 @@ public class Commandlist extends EssentialsCommand {
// Output the standard /list output, when no group is specified
private void sendGroupedList(final CommandSource sender, final String commandLabel, final Map<String, List<User>> playerList) {
for (final String str : PlayerList.prepareGroupedList(ess, sender, commandLabel, playerList)) {
sender.sendComponent(ess.getAdventureFacet().deserializeMiniMessage(str));
sender.sendComponent(AdventureUtil.miniMessage().deserialize(str));
}
}
@@ -1,7 +1,6 @@
package com.earth2me.essentials.commands;
import com.earth2me.essentials.User;
import net.ess3.provider.ContainerProvider;
import org.bukkit.Server;
public class Commandloom extends EssentialsCommand {
@@ -12,13 +11,11 @@ public class Commandloom extends EssentialsCommand {
@Override
public void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
final ContainerProvider containerProvider = ess.provider(ContainerProvider.class);
if (containerProvider == null) {
if (ess.getContainerProvider() == null) {
user.sendTl("unsupportedBrand");
return;
}
containerProvider.openLoom(user.getBase());
ess.getContainerProvider().openLoom(user.getBase());
}
}
@@ -334,7 +334,7 @@ public class Commandmail extends EssentialsCommand {
return options;
} else if (args.length == 2) {
if ((args[0].equalsIgnoreCase("send") && user.isAuthorized("essentials.mail.send")) || (args[0].equalsIgnoreCase("sendtemp") && user.isAuthorized("essentials.mail.sendtemp")) || ((args[0].equalsIgnoreCase("clear"))&& user.isAuthorized("essentials.mail.clear.others"))) {
return getPlayers(user);
return getPlayers(server, user);
} else if (args[0].equalsIgnoreCase("sendtempall") && user.isAuthorized("essentials.mail.sendtempall")) {
return COMMON_DATE_DIFFS;
} else if (args[0].equalsIgnoreCase("read")) {
@@ -374,7 +374,7 @@ public class Commandmail extends EssentialsCommand {
return Lists.newArrayList("send", "sendall", "sendtemp", "sendtempall", "clearall", "clear");
} else if (args.length == 2) {
if (args[0].equalsIgnoreCase("send") || args[0].equalsIgnoreCase("sendtemp") || args[0].equalsIgnoreCase("clear")) {
return getPlayers(sender);
return getPlayers(server, sender);
} else if (args[0].equalsIgnoreCase("sendtempall")) {
return COMMON_DATE_DIFFS;
}
@@ -36,13 +36,11 @@ public class Commandmore extends EssentialsCommand {
if (!NumberUtil.isPositiveInt(args[0])) {
throw new TranslatableException("nonZeroPosNumber");
}
final int cap = canOversized ? ess.getSettings().getOversizedStackSize() : stack.getMaxStackSize();
final long newSizeLong = (long) stack.getAmount() + Integer.parseInt(args[0]);
if (newSizeLong > cap) {
user.sendTl(canOversized ? "fullStackDefaultOversize" : "fullStackDefault", cap);
newStackSize = cap;
} else {
newStackSize = (int) newSizeLong;
newStackSize += Integer.parseInt(args[0]);
if (newStackSize > (canOversized ? ess.getSettings().getOversizedStackSize() : stack.getMaxStackSize())) {
user.sendTl(canOversized ? "fullStackDefaultOversize" : "fullStackDefault", canOversized ? ess.getSettings().getOversizedStackSize() : stack.getMaxStackSize());
newStackSize = canOversized ? ess.getSettings().getOversizedStackSize() : stack.getMaxStackSize();
}
} else if (canOversized) {
newStackSize = ess.getSettings().getOversizedStackSize();
@@ -40,7 +40,7 @@ public class Commandmsg extends EssentialsLoopCommand {
}
// Sending messages to console
if (args[0].equalsIgnoreCase(Console.NAME) || args[0].equalsIgnoreCase(Console.displayName())) {
if (args[0].equalsIgnoreCase(Console.NAME) || args[0].equalsIgnoreCase(Console.DISPLAY_NAME)) {
final IMessageRecipient messageSender = sender.isPlayer() ? ess.getUser(sender.getPlayer()) : Console.getInstance();
messageSender.sendMessage(Console.getInstance(), message);
return;
@@ -58,7 +58,7 @@ public class Commandmsg extends EssentialsLoopCommand {
@Override
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
if (args.length == 1) {
return getPlayers(sender);
return getPlayers(server, sender);
} else {
return Collections.emptyList(); // It's a chat message, send an empty list.
}
@@ -3,6 +3,7 @@ package com.earth2me.essentials.commands;
import com.earth2me.essentials.CommandSource;
import com.earth2me.essentials.OfflinePlayerStub;
import com.earth2me.essentials.User;
import com.earth2me.essentials.utils.AdventureUtil;
import com.earth2me.essentials.utils.DateUtil;
import net.ess3.api.TranslatableException;
import net.ess3.api.events.MuteStatusChangeEvent;
@@ -21,7 +22,6 @@ public class Commandmute extends EssentialsCommand {
@Override
public void run(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
final boolean isUnmute = commandLabel.toLowerCase(java.util.Locale.ENGLISH).contains("unmute");
boolean nomatch = false;
if (args.length < 1) {
throw new NotEnoughArgumentsException();
@@ -33,17 +33,11 @@ public class Commandmute extends EssentialsCommand {
nomatch = true;
user = ess.getUser(new OfflinePlayerStub(args[0], ess.getServer()));
}
if (isUnmute && !user.getMuted()) {
sender.sendTl("playerNotMuted", user.getDisplayName());
return;
}
if (!user.getBase().isOnline() && sender.isPlayer()) {
if (!sender.isAuthorized("essentials.mute.offline")) {
throw new TranslatableException("muteExemptOffline");
}
} else if (!isUnmute && user.isAuthorized("essentials.mute.exempt")) {
} else if (user.isAuthorized("essentials.mute.exempt")) {
throw new TranslatableException("muteExempt");
}
@@ -51,7 +45,7 @@ public class Commandmute extends EssentialsCommand {
final String time;
String muteReason = null;
if (!isUnmute && args.length > 1) {
if (args.length > 1) {
time = args[1];
try {
muteTimestamp = DateUtil.parseDateDiff(time, true);
@@ -66,7 +60,7 @@ public class Commandmute extends EssentialsCommand {
}
}
final boolean willMute = !isUnmute && ((args.length > 1) || !user.getMuted());
final boolean willMute = (args.length > 1) || !user.getMuted();
final User controller = sender.isPlayer() ? ess.getUser(sender.getPlayer()) : null;
final MuteStatusChangeEvent event = new MuteStatusChangeEvent(user, controller, willMute, muteTimestamp, muteReason);
ess.getServer().getPluginManager().callEvent(event);
@@ -123,13 +117,11 @@ public class Commandmute extends EssentialsCommand {
objects = new Object[]{sender.getSender().getName(), user.getName(), muteTime};
}
ess.getLogger().log(Level.INFO, ess.getAdventureFacet().miniToLegacy(tlLiteral(tlKey, objects)));
ess.getLogger().log(Level.INFO, AdventureUtil.miniToLegacy(tlLiteral(tlKey, objects)));
ess.broadcastTl(null, "essentials.mute.notify", tlKey, objects);
} else {
sender.sendTl("unmutedPlayer", user.getDisplayName());
user.sendTl("playerUnmuted");
ess.getLogger().log(Level.INFO, ess.getAdventureFacet().miniToLegacy(tlLiteral("unmuteNotify", sender.getSender().getName(), user.getName())));
ess.broadcastTl(null, "essentials.mute.notify", "unmuteNotify", new Object[]{sender.getSender().getName(), user.getName()});
}
}
}
@@ -137,7 +129,7 @@ public class Commandmute extends EssentialsCommand {
@Override
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
if (args.length == 1) {
return getPlayers(sender);
return getPlayers(server, sender);
} else {
return COMMON_DATE_DIFFS; // Date diff can span multiple words
}
@@ -2,7 +2,7 @@ package com.earth2me.essentials.commands;
import com.earth2me.essentials.CommandSource;
import com.earth2me.essentials.User;
import com.earth2me.essentials.adventure.AdventureUtil;
import com.earth2me.essentials.utils.AdventureUtil;
import com.google.common.collect.Lists;
import org.bukkit.Location;
import org.bukkit.Server;
@@ -117,7 +117,7 @@ public class Commandnear extends EssentialsCommand {
protected List<String> getTabCompleteOptions(final Server server, final User user, final String commandLabel, final String[] args) {
if (user.isAuthorized("essentials.near.others")) {
if (args.length == 1) {
return getPlayers(user);
return getPlayers(server, user);
} else if (args.length == 2) {
return Lists.newArrayList(Integer.toString(ess.getSettings().getNearRadius()));
} else {
@@ -135,7 +135,7 @@ public class Commandnear extends EssentialsCommand {
@Override
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
if (args.length == 1) {
return getPlayers(sender);
return getPlayers(server, sender);
} else if (args.length == 2) {
return Lists.newArrayList(Integer.toString(ess.getSettings().getNearRadius()));
} else {
Loaded 100 of 424 files, more files were not shown because too many files have changed in this diff. Show more