1458 lines
56 KiB
Java
1458 lines
56 KiB
Java
/*
|
|
* Essentials - a bukkit plugin
|
|
* Copyright (C) 2011 Essentials Team
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
package com.earth2me.essentials;
|
|
|
|
import com.earth2me.essentials.commands.EssentialsCommand;
|
|
import com.earth2me.essentials.commands.IEssentialsCommand;
|
|
import com.earth2me.essentials.commands.NoChargeException;
|
|
import com.earth2me.essentials.commands.NotEnoughArgumentsException;
|
|
import com.earth2me.essentials.commands.PlayerNotFoundException;
|
|
import com.earth2me.essentials.commands.QuietAbortException;
|
|
import com.earth2me.essentials.economy.EconomyLayers;
|
|
import com.earth2me.essentials.economy.vault.VaultEconomyProvider;
|
|
import com.earth2me.essentials.items.AbstractItemDb;
|
|
import com.earth2me.essentials.items.CustomItemResolver;
|
|
import com.earth2me.essentials.items.FlatItemDb;
|
|
import com.earth2me.essentials.items.LegacyItemDb;
|
|
import com.earth2me.essentials.metrics.MetricsWrapper;
|
|
import com.earth2me.essentials.perm.PermissionsDefaults;
|
|
import com.earth2me.essentials.perm.PermissionsHandler;
|
|
import com.earth2me.essentials.signs.SignBlockListener;
|
|
import com.earth2me.essentials.signs.SignEntityListener;
|
|
import com.earth2me.essentials.signs.SignPlayerListener;
|
|
import com.earth2me.essentials.textreader.IText;
|
|
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 net.ess3.api.IEssentials;
|
|
import net.ess3.api.IItemDb;
|
|
import net.ess3.api.IJails;
|
|
import net.ess3.api.ISettings;
|
|
import net.ess3.api.TranslatableException;
|
|
import net.ess3.nms.refl.providers.ReflDataWorldInfoProvider;
|
|
import net.ess3.nms.refl.providers.ReflFormattedCommandAliasProvider;
|
|
import net.ess3.nms.refl.providers.ReflKnownCommandsProvider;
|
|
import net.ess3.nms.refl.providers.ReflOnlineModeProvider;
|
|
import net.ess3.nms.refl.providers.ReflPersistentDataProvider;
|
|
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.ContainerProvider;
|
|
import net.ess3.provider.FormattedCommandAliasProvider;
|
|
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.BaseLoggerProvider;
|
|
import net.ess3.provider.providers.BasePotionDataProvider;
|
|
import net.ess3.provider.providers.BlockMetaSpawnerItemProvider;
|
|
import net.ess3.provider.providers.BukkitMaterialTagProvider;
|
|
import net.ess3.provider.providers.BukkitSpawnerBlockProvider;
|
|
import net.ess3.provider.providers.FixedHeightWorldInfoProvider;
|
|
import net.ess3.provider.providers.FlatSpawnEggProvider;
|
|
import net.ess3.provider.providers.LegacyItemUnbreakableProvider;
|
|
import net.ess3.provider.providers.LegacyPlayerLocaleProvider;
|
|
import net.ess3.provider.providers.LegacyPotionMetaProvider;
|
|
import net.ess3.provider.providers.LegacySpawnEggProvider;
|
|
import net.ess3.provider.providers.ModernDataWorldInfoProvider;
|
|
import net.ess3.provider.providers.ModernItemUnbreakableProvider;
|
|
import net.ess3.provider.providers.ModernPersistentDataProvider;
|
|
import net.ess3.provider.providers.ModernPlayerLocaleProvider;
|
|
import net.ess3.provider.providers.ModernSignDataProvider;
|
|
import net.ess3.provider.providers.PaperContainerProvider;
|
|
import net.ess3.provider.providers.PaperKnownCommandsProvider;
|
|
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.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;
|
|
import org.bukkit.block.Block;
|
|
import org.bukkit.command.BlockCommandSender;
|
|
import org.bukkit.command.Command;
|
|
import org.bukkit.command.CommandSender;
|
|
import org.bukkit.command.PluginCommand;
|
|
import org.bukkit.command.PluginIdentifiableCommand;
|
|
import org.bukkit.command.TabCompleter;
|
|
import org.bukkit.entity.Player;
|
|
import org.bukkit.event.Cancellable;
|
|
import org.bukkit.event.EventHandler;
|
|
import org.bukkit.event.EventPriority;
|
|
import org.bukkit.event.HandlerList;
|
|
import org.bukkit.event.Listener;
|
|
import org.bukkit.event.player.PlayerEvent;
|
|
import org.bukkit.event.player.PlayerJoinEvent;
|
|
import org.bukkit.event.world.WorldLoadEvent;
|
|
import org.bukkit.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;
|
|
import java.util.HashMap;
|
|
import java.util.LinkedHashSet;
|
|
import java.util.List;
|
|
import java.util.Locale;
|
|
import java.util.Map;
|
|
import java.util.Set;
|
|
import java.util.UUID;
|
|
import java.util.function.Predicate;
|
|
import java.util.logging.Level;
|
|
import java.util.logging.Logger;
|
|
|
|
import static com.earth2me.essentials.I18n.tlLiteral;
|
|
import static com.earth2me.essentials.I18n.tlLocale;
|
|
|
|
public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
|
private static final Logger BUKKIT_LOGGER = Logger.getLogger("Essentials");
|
|
private static Logger LOGGER = null;
|
|
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 transient ISettings settings;
|
|
private transient Jails jails;
|
|
private transient Warps warps;
|
|
private transient Worth worth;
|
|
private transient List<IConf> confList;
|
|
private transient Backup backup;
|
|
private transient AbstractItemDb itemDb;
|
|
private transient CustomItemResolver customItemResolver;
|
|
private transient PermissionsHandler permissionsHandler;
|
|
private transient AlternativeCommandsHandler alternativeCommandsHandler;
|
|
@Deprecated
|
|
private transient UserMap legacyUserMap;
|
|
private transient ModernUserMap userMap;
|
|
private transient BalanceTopImpl balanceTop;
|
|
private transient ExecuteTimer execTimer;
|
|
private transient MailService mail;
|
|
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 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 Kits kits;
|
|
private transient RandomTeleport randomTeleport;
|
|
private transient UpdateChecker updateChecker;
|
|
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 {
|
|
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 {
|
|
// Vault registers their Essentials provider at low priority, so we have to use normal priority here
|
|
Class.forName("net.milkbowl.vault.economy.Economy");
|
|
getServer().getServicesManager().register(net.milkbowl.vault.economy.Economy.class, new VaultEconomyProvider(this), this, ServicePriority.Normal);
|
|
} catch (final ClassNotFoundException ignored) {
|
|
// Probably safer than fetching for the plugin as bukkit may not have marked it as enabled at this point in time
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onEnable() {
|
|
try {
|
|
if (BUKKIT_LOGGER != super.getLogger()) {
|
|
BUKKIT_LOGGER.setParent(super.getLogger());
|
|
}
|
|
LOGGER = EssentialsLogger.getLoggerProvider(this);
|
|
EssentialsLogger.updatePluginLogger(this);
|
|
|
|
execTimer = new ExecuteTimer();
|
|
execTimer.start();
|
|
|
|
final EssentialsUpgrade upgrade = new EssentialsUpgrade(this);
|
|
upgrade.upgradeLang();
|
|
execTimer.mark("AdventureUpgrade");
|
|
|
|
i18n = new I18n(this);
|
|
i18n.onEnable();
|
|
execTimer.mark("I18n1");
|
|
|
|
Console.setInstance(this);
|
|
|
|
switch (VersionUtil.getServerSupportStatus()) {
|
|
case NMS_CLEANROOM:
|
|
getLogger().severe(AdventureUtil.miniToLegacy(tlLiteral("serverUnsupportedCleanroom")));
|
|
break;
|
|
case DANGEROUS_FORK:
|
|
getLogger().severe(AdventureUtil.miniToLegacy(tlLiteral("serverUnsupportedDangerous")));
|
|
break;
|
|
case STUPID_PLUGIN:
|
|
getLogger().severe(AdventureUtil.miniToLegacy(tlLiteral("serverUnsupportedDumbPlugins")));
|
|
break;
|
|
case UNSTABLE:
|
|
getLogger().severe(AdventureUtil.miniToLegacy(tlLiteral("serverUnsupportedMods")));
|
|
break;
|
|
case OUTDATED:
|
|
getLogger().severe(AdventureUtil.miniToLegacy(tlLiteral("serverUnsupported")));
|
|
break;
|
|
case LIMITED:
|
|
getLogger().info(AdventureUtil.miniToLegacy(tlLiteral("serverUnsupportedLimitedApi")));
|
|
break;
|
|
}
|
|
|
|
if (VersionUtil.getSupportStatusClass() != null) {
|
|
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(AdventureUtil.miniToLegacy(tlLiteral("versionMismatch", plugin.getDescription().getName())));
|
|
}
|
|
}
|
|
|
|
upgrade.beforeSettings();
|
|
execTimer.mark("Upgrade");
|
|
|
|
confList = new ArrayList<>();
|
|
settings = new Settings(this);
|
|
confList.add(settings);
|
|
execTimer.mark("Settings");
|
|
|
|
upgrade.preModules();
|
|
execTimer.mark("Upgrade2");
|
|
|
|
mail = new MailServiceImpl(this);
|
|
execTimer.mark("Init(Mail)");
|
|
|
|
userMap = new ModernUserMap(this);
|
|
legacyUserMap = new UserMap(userMap);
|
|
execTimer.mark("Init(Usermap)");
|
|
|
|
balanceTop = new BalanceTopImpl(this);
|
|
execTimer.mark("Init(BalanceTop)");
|
|
|
|
kits = new Kits(this);
|
|
confList.add(kits);
|
|
upgrade.convertKits();
|
|
execTimer.mark("Kits");
|
|
|
|
upgrade.afterSettings();
|
|
execTimer.mark("Upgrade3");
|
|
|
|
warps = new Warps(this.getDataFolder());
|
|
confList.add(warps);
|
|
execTimer.mark("Init(Warp)");
|
|
|
|
worth = new Worth(this.getDataFolder());
|
|
confList.add(worth);
|
|
execTimer.mark("Init(Worth)");
|
|
|
|
itemDb = getItemDbFromConfig();
|
|
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);
|
|
confList.add(customItemResolver);
|
|
} catch (final Exception e) {
|
|
e.printStackTrace();
|
|
customItemResolver = null;
|
|
}
|
|
execTimer.mark("Init(CustomItemResolver)");
|
|
|
|
jails = new Jails(this);
|
|
confList.add(jails);
|
|
execTimer.mark("Init(Jails)");
|
|
|
|
EconomyLayers.onEnable(this);
|
|
|
|
//Spawner item provider only uses one but it's here for legacy...
|
|
spawnerItemProvider = new BlockMetaSpawnerItemProvider();
|
|
|
|
//Spawner block providers
|
|
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_12_0_R01)) {
|
|
spawnerBlockProvider = new ReflSpawnerBlockProvider();
|
|
} else {
|
|
spawnerBlockProvider = new BukkitSpawnerBlockProvider();
|
|
}
|
|
|
|
//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().isLowerThan(VersionUtil.v1_9_R01)) {
|
|
potionMetaProvider = new LegacyPotionMetaProvider();
|
|
} else {
|
|
potionMetaProvider = new BasePotionDataProvider();
|
|
}
|
|
|
|
//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");
|
|
recipeBookEventProvider = new PaperRecipeBookListener(event -> {
|
|
if (this.getUser(((PlayerEvent) event).getPlayer()).isRecipeSee()) {
|
|
((Cancellable) event).setCancelled(true);
|
|
}
|
|
});
|
|
} 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();
|
|
}
|
|
|
|
execTimer.mark("Init(Providers)");
|
|
reload();
|
|
|
|
// The item spawn blacklist is loaded with all other settings, before the item
|
|
// DB, but it depends on the item DB, so we need to reload it again here:
|
|
((Settings) settings)._lateLoadItemSpawnBlacklist();
|
|
backup = new Backup(this);
|
|
permissionsHandler = new PermissionsHandler(this, settings.useBukkitPermissions());
|
|
alternativeCommandsHandler = new AlternativeCommandsHandler(this);
|
|
|
|
timer = new EssentialsTimer(this);
|
|
scheduleSyncRepeatingTask(timer, 1000, 50);
|
|
|
|
Economy.setEss(this);
|
|
execTimer.mark("RegHandler");
|
|
|
|
// Register /hat and /back default permissions
|
|
PermissionsDefaults.registerAllBackDefaults();
|
|
PermissionsDefaults.registerAllHatDefaults();
|
|
|
|
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);
|
|
|
|
execTimer.mark("Init(External)");
|
|
|
|
final String timeroutput = execTimer.end();
|
|
if (getSettings().isDebug()) {
|
|
LOGGER.log(Level.INFO, "Essentials load " + timeroutput);
|
|
}
|
|
} catch (final NumberFormatException ex) {
|
|
handleCrash(ex);
|
|
} catch (final Error ex) {
|
|
handleCrash(ex);
|
|
throw ex;
|
|
}
|
|
getBackup().setPendingShutdown(false);
|
|
}
|
|
|
|
// Returns our provider logger if available
|
|
public static Logger getWrappedLogger() {
|
|
if (LOGGER != null) {
|
|
return LOGGER;
|
|
}
|
|
|
|
return BUKKIT_LOGGER;
|
|
}
|
|
|
|
@Override
|
|
public void saveConfig() {
|
|
// We don't use any of the bukkit config writing, as this breaks our config file formatting.
|
|
}
|
|
|
|
private void registerListeners(final PluginManager pm) {
|
|
HandlerList.unregisterAll(this);
|
|
|
|
if (getSettings().isDebug()) {
|
|
LOGGER.log(Level.INFO, "Registering Listeners");
|
|
}
|
|
|
|
final EssentialsPluginListener pluginListener = new EssentialsPluginListener(this);
|
|
pm.registerEvents(pluginListener, this);
|
|
confList.add(pluginListener);
|
|
|
|
final EssentialsPlayerListener playerListener = new EssentialsPlayerListener(this);
|
|
playerListener.registerEvents();
|
|
|
|
final EssentialsBlockListener blockListener = new EssentialsBlockListener(this);
|
|
pm.registerEvents(blockListener, this);
|
|
|
|
final SignBlockListener signBlockListener = new SignBlockListener(this);
|
|
pm.registerEvents(signBlockListener, this);
|
|
|
|
final SignPlayerListener signPlayerListener = new SignPlayerListener(this);
|
|
pm.registerEvents(signPlayerListener, this);
|
|
|
|
final SignEntityListener signEntityListener = new SignEntityListener(this);
|
|
pm.registerEvents(signEntityListener, this);
|
|
|
|
final EssentialsEntityListener entityListener = new EssentialsEntityListener(this);
|
|
pm.registerEvents(entityListener, this);
|
|
|
|
final EssentialsWorldListener worldListener = new EssentialsWorldListener(this);
|
|
pm.registerEvents(worldListener, this);
|
|
|
|
final EssentialsServerListener serverListener = new EssentialsServerListener(this);
|
|
pm.registerEvents(serverListener, this);
|
|
|
|
pm.registerEvents(tntListener, this);
|
|
|
|
if (recipeBookEventProvider != null) {
|
|
pm.registerEvents(recipeBookEventProvider, this);
|
|
}
|
|
|
|
jails.resetListener();
|
|
}
|
|
|
|
@Override
|
|
public void onDisable() {
|
|
final boolean stopping = getServerStateProvider().isStopping();
|
|
if (!stopping) {
|
|
LOGGER.log(Level.SEVERE, AdventureUtil.miniToLegacy(tlLiteral("serverReloading")));
|
|
}
|
|
getBackup().setPendingShutdown(true);
|
|
for (final User user : getOnlineUsers()) {
|
|
if (user.isVanished()) {
|
|
user.setVanished(false);
|
|
user.sendTl("unvanishedReload");
|
|
}
|
|
if (stopping) {
|
|
user.setLogoutLocation();
|
|
if (!user.isHidden()) {
|
|
user.setLastLogout(System.currentTimeMillis());
|
|
}
|
|
user.cleanup();
|
|
} else {
|
|
user.stopTransaction();
|
|
}
|
|
}
|
|
cleanupOpenInventories();
|
|
if (getBackup().getTaskLock() != null && !getBackup().getTaskLock().isDone()) {
|
|
LOGGER.log(Level.SEVERE, AdventureUtil.miniToLegacy(tlLiteral("backupInProgress")));
|
|
getBackup().getTaskLock().join();
|
|
}
|
|
if (i18n != null) {
|
|
i18n.onDisable();
|
|
}
|
|
if (backup != null) {
|
|
backup.stopTask();
|
|
}
|
|
|
|
this.getPermissionsHandler().unregisterContexts();
|
|
|
|
Economy.setEss(null);
|
|
Trade.closeLog();
|
|
getUsers().shutdown();
|
|
|
|
HandlerList.unregisterAll(this);
|
|
}
|
|
|
|
@Override
|
|
public void reload() {
|
|
Trade.closeLog();
|
|
|
|
for (final IConf iConf : confList) {
|
|
iConf.reloadConfig();
|
|
execTimer.mark("Reload(" + iConf.getClass().getSimpleName() + ")");
|
|
}
|
|
|
|
i18n.updateLocale(settings.getLocale());
|
|
for (final String commandName : this.getDescription().getCommands().keySet()) {
|
|
final Command command = this.getCommand(commandName);
|
|
if (command != null) {
|
|
command.setDescription(tlLiteral(commandName + "CommandDescription"));
|
|
command.setUsage(tlLiteral(commandName + "CommandUsage"));
|
|
}
|
|
}
|
|
|
|
final PluginManager pm = getServer().getPluginManager();
|
|
registerListeners(pm);
|
|
|
|
bukkitAudience = BukkitAudiences.create(this);
|
|
}
|
|
|
|
private IEssentialsCommand loadCommand(final String path, final String name, final IEssentialsModule module, final ClassLoader classLoader) throws Exception {
|
|
if (commandMap.containsKey(name)) {
|
|
return commandMap.get(name);
|
|
}
|
|
final IEssentialsCommand cmd = (IEssentialsCommand) classLoader.loadClass(path + name).getDeclaredConstructor().newInstance();
|
|
cmd.setEssentials(this);
|
|
cmd.setEssentialsModule(module);
|
|
commandMap.put(name, cmd);
|
|
return cmd;
|
|
}
|
|
|
|
public Map<String, IEssentialsCommand> getCommandMap() {
|
|
return commandMap;
|
|
}
|
|
|
|
@Override
|
|
public List<String> onTabComplete(final CommandSender sender, final Command command, final String commandLabel, final String[] args) {
|
|
return onTabCompleteEssentials(sender, command, commandLabel, args, Essentials.class.getClassLoader(),
|
|
"com.earth2me.essentials.commands.Command", "essentials.", null);
|
|
}
|
|
|
|
@Override
|
|
public List<String> onTabCompleteEssentials(final CommandSender cSender, final Command command, final String commandLabel, final String[] args,
|
|
final ClassLoader classLoader, final String commandPath, final String permissionPrefix,
|
|
final IEssentialsModule module) {
|
|
if (!getSettings().isCommandOverridden(command.getName()) && (!commandLabel.startsWith("e") || commandLabel.equalsIgnoreCase(command.getName()))) {
|
|
final Command pc = alternativeCommandsHandler.getAlternative(commandLabel);
|
|
if (pc instanceof PluginCommand) {
|
|
try {
|
|
final TabCompleter completer = ((PluginCommand) pc).getTabCompleter();
|
|
if (completer != null) {
|
|
return completer.onTabComplete(cSender, command, commandLabel, args);
|
|
}
|
|
} catch (final Exception ex) {
|
|
LOGGER.log(Level.SEVERE, ex.getMessage(), ex);
|
|
}
|
|
}
|
|
}
|
|
|
|
try {
|
|
// Note: The tab completer is always a player, even when tab-completing in a command block
|
|
User user = null;
|
|
if (cSender instanceof Player) {
|
|
user = getUser((Player) cSender);
|
|
}
|
|
|
|
final CommandSource sender = new CommandSource(this, cSender);
|
|
|
|
// Check for disabled commands
|
|
if (getSettings().isCommandDisabled(commandLabel)) {
|
|
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();
|
|
}
|
|
|
|
final IEssentialsCommand cmd;
|
|
try {
|
|
cmd = loadCommand(commandPath, command.getName(), module, classLoader);
|
|
} catch (final Exception ex) {
|
|
sender.sendTl("commandNotLoaded", commandLabel);
|
|
LOGGER.log(Level.SEVERE, AdventureUtil.miniToLegacy(tlLiteral("commandNotLoaded", commandLabel)), ex);
|
|
return Collections.emptyList();
|
|
}
|
|
|
|
// Check authorization
|
|
if (user != null && !user.isAuthorized(cmd, permissionPrefix)) {
|
|
return Collections.emptyList();
|
|
}
|
|
|
|
if (user != null && user.isJailed() && !user.isAuthorized(cmd, "essentials.jail.allow.")) {
|
|
return Collections.emptyList();
|
|
}
|
|
|
|
// Run the command
|
|
try {
|
|
if (user == null) {
|
|
return cmd.tabComplete(getServer(), sender, commandLabel, command, args);
|
|
} else {
|
|
return cmd.tabComplete(getServer(), user, commandLabel, command, args);
|
|
}
|
|
} catch (final Exception ex) {
|
|
showError(sender, ex, commandLabel);
|
|
// Tab completion shouldn't fail
|
|
LOGGER.log(Level.SEVERE, AdventureUtil.miniToLegacy(tlLiteral("commandFailed", commandLabel)), ex);
|
|
return Collections.emptyList();
|
|
}
|
|
} catch (final Throwable ex) {
|
|
LOGGER.log(Level.SEVERE, AdventureUtil.miniToLegacy(tlLiteral("commandFailed", commandLabel)), ex);
|
|
return Collections.emptyList();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public boolean onCommand(final CommandSender sender, final Command command, final String commandLabel, final String[] args) {
|
|
metrics.markCommand(command.getName(), true);
|
|
return onCommandEssentials(sender, command, commandLabel, args, Essentials.class.getClassLoader(), "com.earth2me.essentials.commands.Command", "essentials.", null);
|
|
}
|
|
|
|
@Override
|
|
public boolean onCommandEssentials(final CommandSender cSender, final Command command, final String commandLabel, final String[] args, final ClassLoader classLoader, final String commandPath, final String permissionPrefix, final IEssentialsModule module) {
|
|
// Allow plugins to override the command via onCommand
|
|
if (!getSettings().isCommandOverridden(command.getName()) && (!commandLabel.startsWith("e") || commandLabel.equalsIgnoreCase(command.getName()))) {
|
|
if (getSettings().isDebug()) {
|
|
LOGGER.log(Level.INFO, "Searching for alternative to: " + commandLabel);
|
|
}
|
|
final Command pc = alternativeCommandsHandler.getAlternative(commandLabel);
|
|
if (pc != null) {
|
|
alternativeCommandsHandler.executed(commandLabel, pc);
|
|
try {
|
|
pc.execute(cSender, commandLabel, args);
|
|
} catch (final Exception ex) {
|
|
LOGGER.log(Level.SEVERE, ex.getMessage(), ex);
|
|
if (cSender instanceof Player) {
|
|
cSender.sendMessage(tlLocale(I18n.getLocale(getPlayerLocaleProvider().getLocale((Player) cSender)), "internalError"));
|
|
} else {
|
|
cSender.sendMessage(tlLiteral("internalError"));
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
|
|
try {
|
|
|
|
User user = null;
|
|
Block bSenderBlock = null;
|
|
if (cSender instanceof Player) {
|
|
user = getUser((Player) cSender);
|
|
} else if (cSender instanceof BlockCommandSender) {
|
|
final BlockCommandSender bsender = (BlockCommandSender) cSender;
|
|
bSenderBlock = bsender.getBlock();
|
|
}
|
|
|
|
if (bSenderBlock != null) {
|
|
if (getSettings().logCommandBlockCommands()) {
|
|
LOGGER.log(Level.INFO, "CommandBlock at " + bSenderBlock.getX() + "," + bSenderBlock.getY() + "," + bSenderBlock.getZ() + " issued server command: /" + commandLabel + " " + EssentialsCommand.getFinalArg(args, 0));
|
|
}
|
|
} else if (user == null) {
|
|
LOGGER.log(Level.INFO, cSender.getName()+ " issued server command: /" + commandLabel + " " + EssentialsCommand.getFinalArg(args, 0));
|
|
}
|
|
|
|
final CommandSource sender = new CommandSource(this, cSender);
|
|
|
|
// New mail notification
|
|
if (user != null && !getSettings().isCommandDisabled("mail") && !command.getName().equals("mail") && user.isAuthorized("essentials.mail")) {
|
|
user.notifyOfMail();
|
|
}
|
|
|
|
//Print version even if admin command is not available #easteregg
|
|
if (commandLabel.equalsIgnoreCase("essversion")) {
|
|
sender.sendMessage("This server is running Essentials " + getDescription().getVersion());
|
|
return true;
|
|
}
|
|
|
|
// Check for disabled commands
|
|
if (getSettings().isCommandDisabled(commandLabel)) {
|
|
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;
|
|
}
|
|
|
|
final IEssentialsCommand cmd;
|
|
try {
|
|
cmd = loadCommand(commandPath, command.getName(), module, classLoader);
|
|
} catch (final Exception ex) {
|
|
sender.sendTl("commandNotLoaded", commandLabel);
|
|
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, AdventureUtil.miniToLegacy(tlLiteral("deniedAccessCommand", user.getName())));
|
|
user.sendTl("noAccessCommand");
|
|
return true;
|
|
}
|
|
|
|
if (user != null && user.isJailed() && !user.isAuthorized(cmd, "essentials.jail.allow.")) {
|
|
if (user.getJailTimeout() > 0) {
|
|
user.sendTl("playerJailedFor", user.getName(), user.getFormattedJailTime());
|
|
} else {
|
|
user.sendTl("jailMessage");
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// Run the command
|
|
try {
|
|
if (user == null) {
|
|
cmd.run(getServer(), sender, commandLabel, command, args);
|
|
} else {
|
|
cmd.run(getServer(), user, commandLabel, command, args);
|
|
}
|
|
return true;
|
|
} catch (final NoChargeException | QuietAbortException ex) {
|
|
return true;
|
|
} catch (final NotEnoughArgumentsException ex) {
|
|
if (getSettings().isVerboseCommandUsages() && !cmd.getUsageStrings().isEmpty()) {
|
|
sender.sendTl("commandHelpLine1", commandLabel);
|
|
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(usage.getValue()));
|
|
}
|
|
} else {
|
|
sender.sendMessage(command.getDescription());
|
|
sender.sendMessage(command.getUsage().replace("<command>", commandLabel));
|
|
}
|
|
if (!ex.getMessage().isEmpty()) {
|
|
sender.sendMessage(ex.getMessage());
|
|
}
|
|
if (ex.getCause() != null && settings.isDebug()) {
|
|
ex.getCause().printStackTrace();
|
|
}
|
|
return true;
|
|
} catch (final Exception ex) {
|
|
showError(sender, ex, commandLabel);
|
|
if (settings.isDebug()) {
|
|
ex.printStackTrace();
|
|
}
|
|
return true;
|
|
}
|
|
} catch (final Throwable ex) {
|
|
LOGGER.log(Level.SEVERE, AdventureUtil.miniToLegacy(tlLiteral("commandFailed", commandLabel)), ex);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
private boolean isEssentialsPlugin(Plugin plugin) {
|
|
return plugin.getDescription().getMain().contains("com.earth2me.essentials") || plugin.getDescription().getMain().contains("net.essentialsx");
|
|
}
|
|
|
|
public void cleanupOpenInventories() {
|
|
for (final User user : getOnlineUsers()) {
|
|
if (user.isRecipeSee()) {
|
|
user.getBase().getOpenInventory().getTopInventory().clear();
|
|
user.getBase().getOpenInventory().close();
|
|
user.setRecipeSee(false);
|
|
}
|
|
if (user.isInvSee() || user.isEnderSee()) {
|
|
user.getBase().getOpenInventory().close();
|
|
user.setInvSee(false);
|
|
user.setEnderSee(false);
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void showError(final CommandSource sender, final Throwable exception, final String commandLabel) {
|
|
if (exception instanceof TranslatableException) {
|
|
final String tlMessage = sender.tl(((TranslatableException) exception).getTlKey(), ((TranslatableException) exception).getArgs());
|
|
sender.sendTl("errorWithMessage", AdventureUtil.parsed(tlMessage));
|
|
} else {
|
|
sender.sendTl("errorWithMessage", exception.getMessage());
|
|
}
|
|
if (getSettings().isDebug()) {
|
|
LOGGER.log(Level.INFO, AdventureUtil.miniToLegacy(tlLiteral("errorCallingCommand", commandLabel)), exception);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public BukkitScheduler getScheduler() {
|
|
return this.getServer().getScheduler();
|
|
}
|
|
|
|
@Override
|
|
public IJails getJails() {
|
|
return jails;
|
|
}
|
|
|
|
@Override
|
|
public Warps getWarps() {
|
|
return warps;
|
|
}
|
|
|
|
@Override
|
|
public Worth getWorth() {
|
|
return worth;
|
|
}
|
|
|
|
@Override
|
|
public Backup getBackup() {
|
|
return backup;
|
|
}
|
|
|
|
@Override
|
|
public Kits getKits() {
|
|
return kits;
|
|
}
|
|
|
|
@Override
|
|
public RandomTeleport getRandomTeleport() {
|
|
return randomTeleport;
|
|
}
|
|
|
|
@Override
|
|
public UpdateChecker getUpdateChecker() {
|
|
return updateChecker;
|
|
}
|
|
|
|
@Deprecated
|
|
@Override
|
|
public User getUser(final Object base) {
|
|
if (base instanceof Player) {
|
|
return getUser((Player) base);
|
|
}
|
|
if (base instanceof org.bukkit.OfflinePlayer) {
|
|
return getUser(((org.bukkit.OfflinePlayer) base).getUniqueId());
|
|
}
|
|
if (base instanceof UUID) {
|
|
return getUser((UUID) base);
|
|
}
|
|
if (base instanceof String) {
|
|
return getOfflineUser((String) base);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
//This will return null if there is not a match.
|
|
@Override
|
|
public User getUser(final String base) {
|
|
return getOfflineUser(base);
|
|
}
|
|
|
|
//This will return null if there is not a match.
|
|
@Override
|
|
public User getUser(final UUID base) {
|
|
return userMap.getUser(base);
|
|
}
|
|
|
|
//This will return null if there is not a match.
|
|
@Override
|
|
public User getOfflineUser(final String name) {
|
|
return userMap.getUser(name);
|
|
}
|
|
|
|
@Override
|
|
public User matchUser(final Server server, final User sourceUser, final String searchTerm, final Boolean getHidden, final boolean getOffline) throws PlayerNotFoundException {
|
|
final User user;
|
|
Player exPlayer;
|
|
|
|
try {
|
|
exPlayer = server.getPlayer(UUID.fromString(searchTerm));
|
|
} catch (final IllegalArgumentException ex) {
|
|
if (getOffline) {
|
|
exPlayer = server.getPlayerExact(searchTerm);
|
|
} else {
|
|
exPlayer = server.getPlayer(searchTerm);
|
|
}
|
|
}
|
|
|
|
if (exPlayer != null) {
|
|
user = getUser(exPlayer);
|
|
} else {
|
|
user = getUser(searchTerm);
|
|
}
|
|
|
|
if (user != null) {
|
|
if (!getOffline && !user.getBase().isOnline()) {
|
|
throw new PlayerNotFoundException();
|
|
}
|
|
|
|
if (getHidden || canInteractWith(sourceUser, user)) {
|
|
return user;
|
|
} else { // not looking for hidden and cannot interact (i.e is hidden)
|
|
if (getOffline && user.getName().equalsIgnoreCase(searchTerm)) { // if looking for offline and got an exact match
|
|
return user;
|
|
}
|
|
}
|
|
throw new PlayerNotFoundException();
|
|
}
|
|
final List<Player> matches = server.matchPlayer(searchTerm);
|
|
|
|
if (matches.isEmpty()) {
|
|
final String matchText = searchTerm.toLowerCase(Locale.ENGLISH);
|
|
for (final User userMatch : getOnlineUsers()) {
|
|
if (getHidden || canInteractWith(sourceUser, userMatch)) {
|
|
final String displayName = FormatUtil.stripFormat(userMatch.getDisplayName()).toLowerCase(Locale.ENGLISH);
|
|
if (displayName.contains(matchText)) {
|
|
return userMatch;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
for (final Player player : matches) {
|
|
final User userMatch = getUser(player);
|
|
if (userMatch.getDisplayName().startsWith(searchTerm) && (getHidden || canInteractWith(sourceUser, userMatch))) {
|
|
return userMatch;
|
|
}
|
|
}
|
|
final User userMatch = getUser(matches.get(0));
|
|
if (getHidden || canInteractWith(sourceUser, userMatch)) {
|
|
return userMatch;
|
|
}
|
|
}
|
|
throw new PlayerNotFoundException();
|
|
}
|
|
|
|
@Override
|
|
public boolean canInteractWith(final CommandSource interactor, final User interactee) {
|
|
if (interactor == null) {
|
|
return !interactee.isHidden();
|
|
}
|
|
|
|
if (interactor.isPlayer()) {
|
|
return canInteractWith(getUser(interactor.getPlayer()), interactee);
|
|
}
|
|
|
|
return true; // console
|
|
}
|
|
|
|
@Override
|
|
public boolean canInteractWith(final User interactor, final User interactee) {
|
|
if (interactor == null) {
|
|
return !interactee.isHidden();
|
|
}
|
|
|
|
if (interactor.equals(interactee)) {
|
|
return true;
|
|
}
|
|
|
|
return !interactee.isHiddenFrom(interactor.getBase());
|
|
}
|
|
|
|
//This will create a new user if there is not a match.
|
|
@Override
|
|
public User getUser(final Player base) {
|
|
if (base == null) {
|
|
return null;
|
|
}
|
|
|
|
if (userMap == null) {
|
|
LOGGER.log(Level.WARNING, "Essentials userMap not initialized");
|
|
return null;
|
|
}
|
|
|
|
final User user = userMap.getUser(base);
|
|
|
|
if (base.getClass() != UUIDPlayer.class || user.getBase() == null) {
|
|
user.update(base);
|
|
}
|
|
return user;
|
|
}
|
|
|
|
private void handleCrash(final Throwable exception) {
|
|
final PluginManager pm = getServer().getPluginManager();
|
|
getWrappedLogger().log(Level.SEVERE, exception.toString(), exception);
|
|
pm.registerEvents(new Listener() {
|
|
@EventHandler(priority = EventPriority.LOW)
|
|
public void onPlayerJoin(final PlayerJoinEvent event) {
|
|
event.getPlayer().sendMessage("Essentials failed to load, read the log file.");
|
|
}
|
|
}, this);
|
|
for (final Player player : getOnlinePlayers()) {
|
|
player.sendMessage("Essentials failed to load, read the log file.");
|
|
}
|
|
this.setEnabled(false);
|
|
}
|
|
|
|
@Override
|
|
public World getWorld(final String name) {
|
|
if (name.matches("[0-9]+")) {
|
|
final int worldId = Integer.parseInt(name);
|
|
if (worldId < getServer().getWorlds().size()) {
|
|
return getServer().getWorlds().get(worldId);
|
|
}
|
|
}
|
|
return getServer().getWorld(name);
|
|
}
|
|
|
|
@Override
|
|
public void addReloadListener(final IConf listener) {
|
|
confList.add(listener);
|
|
}
|
|
|
|
@Override
|
|
public int broadcastMessage(final String message) {
|
|
return broadcastMessage(null, null, message, true, null);
|
|
}
|
|
|
|
@Override
|
|
public int broadcastMessage(final IUser sender, final String message) {
|
|
return broadcastMessage(sender, null, message, false, null);
|
|
}
|
|
|
|
@Override
|
|
public int broadcastMessage(final IUser sender, final String message, final Predicate<IUser> shouldExclude) {
|
|
return broadcastMessage(sender, null, message, false, shouldExclude);
|
|
}
|
|
|
|
@Override
|
|
public int broadcastMessage(final String permission, final String message) {
|
|
return broadcastMessage(null, permission, message, false, null);
|
|
}
|
|
|
|
private int broadcastMessage(final IUser sender, final String permission, final String message, final boolean keywords, final Predicate<IUser> shouldExclude) {
|
|
if (sender != null && sender.isHidden()) {
|
|
return 0;
|
|
}
|
|
|
|
IText broadcast = new SimpleTextInput(message);
|
|
|
|
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 (shouldExclude != null && shouldExclude.test(user)) {
|
|
continue;
|
|
}
|
|
if (keywords) {
|
|
broadcast = new KeywordReplacer(broadcast, new CommandSource(this, player), this, false);
|
|
}
|
|
for (final String messageText : broadcast.getLines()) {
|
|
user.sendMessage(messageText);
|
|
}
|
|
}
|
|
}
|
|
|
|
return players.size();
|
|
}
|
|
|
|
@Override
|
|
public void broadcastTl(final String tlKey, final Object... args) {
|
|
broadcastTl(null, null, true, tlKey, args);
|
|
}
|
|
|
|
@Override
|
|
public void broadcastTl(final IUser sender, final String tlKey, final Object... args) {
|
|
broadcastTl(sender, null, false, tlKey, args);
|
|
}
|
|
|
|
@Override
|
|
public void broadcastTl(final IUser sender, final String permission, final String tlKey, final Object... args) {
|
|
broadcastTl(sender, u -> !u.isAuthorized(permission), false, tlKey, args);
|
|
}
|
|
|
|
@Override
|
|
public void broadcastTl(IUser sender, Predicate<IUser> shouldExclude, String tlKey, Object... args) {
|
|
broadcastTl(sender, shouldExclude, false, tlKey, args);
|
|
}
|
|
|
|
@Override
|
|
public void broadcastTl(final IUser sender, final Predicate<IUser> shouldExclude, final boolean parseKeywords, final String tlKey, final Object... args) {
|
|
if (sender != null && sender.isHidden()) {
|
|
return;
|
|
}
|
|
|
|
for (final User user : getOnlineUsers()) {
|
|
if (sender != null && user.isIgnoredPlayer(sender)) {
|
|
continue;
|
|
}
|
|
|
|
if (shouldExclude != null && shouldExclude.test(user)) {
|
|
continue;
|
|
}
|
|
|
|
final Object[] processedArgs;
|
|
if (parseKeywords) {
|
|
processedArgs = I18n.mutateArgs(args, s -> new KeywordReplacer(new SimpleTextInput(s.toString()), new CommandSource(this, user.getBase()), this, false).getLines().get(0));
|
|
} else {
|
|
processedArgs = args;
|
|
}
|
|
|
|
user.sendTl(tlKey, processedArgs);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public BukkitTask runTaskAsynchronously(final Runnable run) {
|
|
return this.getScheduler().runTaskAsynchronously(this, run);
|
|
}
|
|
|
|
@Override
|
|
public BukkitTask runTaskLaterAsynchronously(final Runnable run, final long delay) {
|
|
return this.getScheduler().runTaskLaterAsynchronously(this, run, delay);
|
|
}
|
|
|
|
@Override
|
|
public BukkitTask runTaskTimerAsynchronously(final Runnable run, final long delay, final long period) {
|
|
return this.getScheduler().runTaskTimerAsynchronously(this, run, delay, period);
|
|
}
|
|
|
|
@Override
|
|
public int scheduleSyncDelayedTask(final Runnable run) {
|
|
return this.getScheduler().scheduleSyncDelayedTask(this, run);
|
|
}
|
|
|
|
@Override
|
|
public int scheduleSyncDelayedTask(final Runnable run, final long delay) {
|
|
return this.getScheduler().scheduleSyncDelayedTask(this, run, delay);
|
|
}
|
|
|
|
@Override
|
|
public int scheduleSyncRepeatingTask(final Runnable run, final long delay, final long period) {
|
|
return this.getScheduler().scheduleSyncRepeatingTask(this, run, delay, period);
|
|
}
|
|
|
|
@Override
|
|
public PermissionsHandler getPermissionsHandler() {
|
|
return permissionsHandler;
|
|
}
|
|
|
|
@Override
|
|
public AlternativeCommandsHandler getAlternativeCommandsHandler() {
|
|
return alternativeCommandsHandler;
|
|
}
|
|
|
|
@Override
|
|
public IItemDb getItemDb() {
|
|
return itemDb;
|
|
}
|
|
|
|
@Override
|
|
@Deprecated
|
|
public UserMap getUserMap() {
|
|
return legacyUserMap;
|
|
}
|
|
|
|
@Override
|
|
public ModernUserMap getUsers() {
|
|
return userMap;
|
|
}
|
|
|
|
@Override
|
|
public BalanceTop getBalanceTop() {
|
|
return balanceTop;
|
|
}
|
|
|
|
@Override
|
|
public I18n getI18n() {
|
|
return i18n;
|
|
}
|
|
|
|
@Override
|
|
public EssentialsTimer getTimer() {
|
|
return timer;
|
|
}
|
|
|
|
@Override
|
|
public MailService getMail() {
|
|
return mail;
|
|
}
|
|
|
|
@Override
|
|
public List<String> getVanishedPlayers() {
|
|
return Collections.unmodifiableList(new ArrayList<>(vanishedPlayers));
|
|
}
|
|
|
|
@Override
|
|
public Collection<String> getVanishedPlayersNew() {
|
|
return vanishedPlayers;
|
|
}
|
|
|
|
@Override
|
|
public Collection<Player> getOnlinePlayers() {
|
|
return (Collection<Player>) getServer().getOnlinePlayers();
|
|
}
|
|
|
|
@Override
|
|
public Iterable<User> getOnlineUsers() {
|
|
final List<User> onlineUsers = new ArrayList<>();
|
|
for (final Player player : getOnlinePlayers()) {
|
|
onlineUsers.add(getUser(player));
|
|
}
|
|
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 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 SignDataProvider getSignDataProvider() {
|
|
return signDataProvider;
|
|
}
|
|
|
|
@Override
|
|
public PluginCommand getPluginCommand(final String cmd) {
|
|
return this.getCommand(cmd);
|
|
}
|
|
|
|
public BukkitAudiences getBukkitAudience() {
|
|
return bukkitAudience;
|
|
}
|
|
|
|
private AbstractItemDb getItemDbFromConfig() {
|
|
final String setting = settings.getItemDbType();
|
|
|
|
if (setting.equalsIgnoreCase("json")) {
|
|
return new FlatItemDb(this);
|
|
} else if (setting.equalsIgnoreCase("csv")) {
|
|
return new LegacyItemDb(this);
|
|
} else {
|
|
final VersionUtil.BukkitVersion version = VersionUtil.getServerBukkitVersion();
|
|
|
|
if (version.isHigherThanOrEqualTo(VersionUtil.v1_13_0_R01)) {
|
|
return new FlatItemDb(this);
|
|
} else {
|
|
return new LegacyItemDb(this);
|
|
}
|
|
}
|
|
}
|
|
|
|
private static class EssentialsWorldListener implements Listener, Runnable {
|
|
private transient final IEssentials ess;
|
|
|
|
EssentialsWorldListener(final IEssentials ess) {
|
|
this.ess = ess;
|
|
}
|
|
|
|
@EventHandler(priority = EventPriority.LOW)
|
|
public void onWorldLoad(final WorldLoadEvent event) {
|
|
PermissionsDefaults.registerBackDefaultFor(event.getWorld());
|
|
}
|
|
|
|
@Override
|
|
public void run() {
|
|
ess.reload();
|
|
}
|
|
}
|
|
}
|