Migrate to Configurate (#4072)

Co-authored-by: MD <1917406+mdcfe@users.noreply.github.com>
Co-authored-by: Riley Park <riley.park@meino.net>
Co-authored-by: zml <zml@aoeu.xyz>

Migrates all uses of SnakeYAML and Bukkit's Configuration API to Sponge's Configurate.

Configurate enables us to the do the following stuff:
* Serialize YAML off the main thread
* (in the future) Automatically update our config
* (in the future) Manipulate comments in configs
* Be epic

This commit also *finally* strips out the 3.x storage/object mapping system in favour of Configurate's object mapper.
This commit is contained in:
Josh Roy 2021-06-07 08:49:33 -04:00 committed by GitHub
parent 19b4da07b9
commit 7653da0e4f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
57 changed files with 2091 additions and 2164 deletions

View File

@ -12,6 +12,10 @@ dependencies {
api 'org.bstats:bstats-bukkit:1.8'
implementation 'org.spongepowered:configurate-yaml:4.1.1'
implementation 'org.yaml:snakeyaml:1.+'
testImplementation 'org.checkerframework:checker-qual:3.7.1'
// Providers
api project(':providers:BaseProviders')
api project(':providers:PaperProvider')
@ -27,6 +31,10 @@ shadowJar {
dependencies {
include (dependency('io.papermc:paperlib'))
include (dependency('org.bstats:bstats-bukkit'))
include (dependency('org.spongepowered:configurate-yaml'))
include (dependency('org.spongepowered:configurate-core'))
include (dependency('org.yaml:snakeyaml'))
include (dependency('io.leangen.geantyref:geantyref'))
include (project(':providers:BaseProviders'))
include (project(':providers:PaperProvider'))
include (project(':providers:NMSReflectionProvider'))
@ -34,4 +42,7 @@ shadowJar {
}
relocate 'io.papermc.lib', 'com.earth2me.essentials.paperlib'
relocate 'org.bstats.bukkit', 'com.earth2me.essentials.metrics'
relocate 'org.spongepowered.configurate', 'com.earth2me.essentials.libs.configurate'
relocate 'org.yaml.snakeyaml', 'com.earth2me.essentials.libs.snakeyaml'
relocate 'io.leangen.geantyref', 'com.earth2me.essentials.libs.geantyref'
}

View File

@ -107,7 +107,6 @@ import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.plugin.java.JavaPluginLoader;
import org.bukkit.scheduler.BukkitScheduler;
import org.bukkit.scheduler.BukkitTask;
import org.yaml.snakeyaml.error.YAMLException;
import java.io.File;
import java.io.IOException;
@ -263,151 +262,141 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
}
}
try {
final EssentialsUpgrade upgrade = new EssentialsUpgrade(this);
upgrade.beforeSettings();
execTimer.mark("Upgrade");
final EssentialsUpgrade upgrade = new EssentialsUpgrade(this);
upgrade.beforeSettings();
execTimer.mark("Upgrade");
confList = new ArrayList<>();
settings = new Settings(this);
confList.add(settings);
execTimer.mark("Settings");
confList = new ArrayList<>();
settings = new Settings(this);
confList.add(settings);
execTimer.mark("Settings");
userMap = new UserMap(this);
confList.add(userMap);
execTimer.mark("Init(Usermap)");
userMap = new UserMap(this);
confList.add(userMap);
execTimer.mark("Init(Usermap)");
balanceTop = new BalanceTopImpl(this);
execTimer.mark("Init(BalanceTop)");
balanceTop = new BalanceTopImpl(this);
execTimer.mark("Init(BalanceTop)");
kits = new Kits(this);
confList.add(kits);
upgrade.convertKits();
execTimer.mark("Kits");
kits = new Kits(this);
confList.add(kits);
upgrade.convertKits();
execTimer.mark("Kits");
upgrade.afterSettings();
execTimer.mark("Upgrade2");
upgrade.afterSettings();
execTimer.mark("Upgrade2");
warps = new Warps(getServer(), this.getDataFolder());
confList.add(warps);
execTimer.mark("Init(Warp)");
warps = new Warps(this.getDataFolder());
confList.add(warps);
execTimer.mark("Init(Warp)");
worth = new Worth(this.getDataFolder());
confList.add(worth);
execTimer.mark("Init(Worth)");
worth = new Worth(this.getDataFolder());
confList.add(worth);
execTimer.mark("Init(Worth)");
itemDb = getItemDbFromConfig();
confList.add(itemDb);
execTimer.mark("Init(ItemDB)");
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)");
//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();
} 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);
}
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();
} catch (final YAMLException exception) {
if (pm.getPlugin("EssentialsUpdate") != null) {
LOGGER.log(Level.SEVERE, tl("essentialsHelp2"));
} else {
LOGGER.log(Level.SEVERE, tl("essentialsHelp1"));
}
handleCrash(exception);
return;
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)");
//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();
} 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);
}
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);
@ -1192,7 +1181,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
public void onWorldLoad(final WorldLoadEvent event) {
PermissionsDefaults.registerBackDefaultFor(event.getWorld());
ess.getJails().onReload();
ess.getJails().reloadConfig();
ess.getWarps().reloadConfig();
for (final IConf iConf : ((Essentials) ess).confList) {
if (iConf instanceof IEssentialsModule) {
@ -1203,7 +1192,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
@EventHandler(priority = EventPriority.LOW)
public void onWorldUnload(final WorldUnloadEvent event) {
ess.getJails().onReload();
ess.getJails().reloadConfig();
ess.getWarps().reloadConfig();
for (final IConf iConf : ((Essentials) ess).confList) {
if (iConf instanceof IEssentialsModule) {

View File

@ -1,8 +1,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.craftbukkit.BanLookup;
import com.earth2me.essentials.settings.Spawns;
import com.earth2me.essentials.storage.YamlStorageWriter;
import com.earth2me.essentials.utils.StringUtil;
import com.google.common.base.Charsets;
import com.google.common.collect.Maps;
@ -11,7 +12,7 @@ import org.bukkit.BanList;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.configuration.ConfigurationSection;
import org.spongepowered.configurate.CommentedConfigurationNode;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
@ -51,14 +52,14 @@ public class EssentialsUpgrade {
private static final String PATTERN_CONFIG_NAME_REGEX = "(?mi)^lastAccountName:\\s*[\"\']?(\\w+)[\"\']?\\s*$";
private static final Pattern PATTERN_CONFIG_NAME = Pattern.compile(PATTERN_CONFIG_NAME_REGEX);
private final transient IEssentials ess;
private final transient EssentialsConf doneFile;
private final transient EssentialsConfiguration doneFile;
EssentialsUpgrade(final IEssentials essentials) {
ess = essentials;
if (!ess.getDataFolder().exists()) {
ess.getDataFolder().mkdirs();
}
doneFile = new EssentialsConf(new File(ess.getDataFolder(), "upgrades-done.yml"));
doneFile = new EssentialsConfiguration(new File(ess.getDataFolder(), "upgrades-done.yml"));
doneFile.load();
}
@ -92,13 +93,13 @@ public class EssentialsUpgrade {
countFiles++;
final String name = string.substring(0, string.length() - 4);
final EssentialsUserConf config;
final EssentialsUserConfiguration config;
UUID uuid = null;
try {
uuid = UUID.fromString(name);
} catch (final IllegalArgumentException ex) {
final File file = new File(userdir, string);
final EssentialsConf conf = new EssentialsConf(file);
final EssentialsConfiguration conf = new EssentialsConfiguration(file);
conf.load();
conf.setProperty("lastAccountName", name);
conf.save();
@ -129,8 +130,8 @@ public class EssentialsUpgrade {
}
if (uuid != null) {
conf.forceSave();
config = new EssentialsUserConf(name, uuid, new File(userdir, uuid + ".yml"));
conf.blockingSave();
config = new EssentialsUserConfiguration(name, uuid, new File(userdir, uuid + ".yml"));
config.convertLegacyFile();
ess.getUserMap().trackUUID(uuid, name, false);
continue;
@ -145,6 +146,60 @@ public class EssentialsUpgrade {
ess.getLogger().info("To rerun the conversion type /essentials uuidconvert");
}
public void convertStupidCamelCaseUserdataKeys() {
if (doneFile.getBoolean("updateUsersLegacyPathNames", false)) {
return;
}
LOGGER.info("Attempting to migrate legacy userdata keys to Configurate");
final File userdataFolder = new File(ess.getDataFolder(), "userdata");
if (!userdataFolder.exists() || !userdataFolder.isDirectory()) {
return;
}
final File[] userFiles = userdataFolder.listFiles();
for (final File file : userFiles) {
if (!file.isFile() || !file.getName().endsWith(".yml")) {
continue;
}
final EssentialsConfiguration config = new EssentialsConfiguration(file);
try {
config.load();
if (config.hasProperty("muteReason")) {
final String reason = config.getString("muteReason", null);
config.removeProperty("muteReason");
config.setProperty("mute-reason", reason);
}
if (config.hasProperty("ipAddress")) {
final String ip = config.getString("ipAddress", null);
config.removeProperty("ipAddress");
config.setProperty("ip-address", ip);
}
if (config.hasProperty("lastAccountName")) {
final String name = config.getString("lastAccountName", null);
config.removeProperty("lastAccountName");
config.setProperty("last-account-name", name);
}
if (config.hasProperty("acceptingPay")) {
final boolean isPay = config.getBoolean("acceptingPay", true);
config.removeProperty("acceptingPay");
config.setProperty("accepting-pay", isPay);
}
} catch (final RuntimeException ex) {
LOGGER.log(Level.INFO, "File: " + file.toString());
throw ex;
}
}
doneFile.setProperty("updateUsersLegacyPathNames", true);
doneFile.save();
LOGGER.info("Done converting legacy userdata keys to Configurate.");
}
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)) {
@ -163,12 +218,12 @@ public class EssentialsUpgrade {
if (!file.isFile() || !file.getName().endsWith(".yml")) {
continue;
}
final EssentialsConf config = new EssentialsConf(file);
final EssentialsConfiguration config = new EssentialsConfiguration(file);
try {
config.load();
if (config.hasProperty("ignore")) {
final List<String> migratedIgnores = new ArrayList<>();
for (final String name : Collections.synchronizedList(config.getStringList("ignore"))) {
for (final String name : Collections.synchronizedList(config.getList("ignore", String.class))) {
if (name == null) {
continue;
}
@ -183,7 +238,7 @@ public class EssentialsUpgrade {
}
config.removeProperty("ignore");
config.setProperty("ignore", migratedIgnores);
config.forceSave();
config.blockingSave();
}
} catch (final RuntimeException ex) {
LOGGER.log(Level.INFO, "File: " + file.toString());
@ -197,24 +252,24 @@ public class EssentialsUpgrade {
public void convertKits() {
final Kits kits = ess.getKits();
final EssentialsConf config = kits.getConfig();
final EssentialsConfiguration config = kits.getConfig();
if (doneFile.getBoolean("kitsyml", false)) {
return;
}
LOGGER.info("Attempting to convert old kits in config.yml to new kits.yml");
final ConfigurationSection section = ess.getSettings().getKitSection();
final CommentedConfigurationNode section = ess.getSettings().getKitSection();
if (section == null) {
LOGGER.info("No kits found to migrate.");
return;
}
final Map<String, Object> legacyKits = ess.getSettings().getKitSection().getValues(true);
final Map<String, Object> legacyKits = ConfigurateUtil.getRawMap(section);
for (final Map.Entry<String, Object> entry : legacyKits.entrySet()) {
LOGGER.info("Converting " + entry.getKey());
config.set("kits." + entry.getKey(), entry.getValue());
config.setRaw("kits." + entry.getKey(), entry.getValue());
}
config.save();
@ -236,9 +291,9 @@ public class EssentialsUpgrade {
if (!configFile.exists()) {
return;
}
final EssentialsConf conf = new EssentialsConf(configFile);
final EssentialsConfiguration conf = new EssentialsConfiguration(configFile);
conf.load();
final List<String> lines = conf.getStringList(name);
final List<String> lines = conf.getList(name, String.class);
if (lines != null && !lines.isEmpty()) {
if (!file.createNewFile()) {
throw new IOException("Failed to create file " + file);
@ -312,12 +367,12 @@ public class EssentialsUpgrade {
if (!file.isFile() || !file.getName().endsWith(".yml")) {
continue;
}
final EssentialsConf config = new EssentialsConf(file);
final EssentialsConfiguration config = new EssentialsConfiguration(file);
try {
config.load();
if (config.hasProperty("powertools")) {
final Map<String, Object> powertools = config.getConfigurationSection("powertools").getValues(false);
if (powertools == null) {
final Map<String, Object> powertools = ConfigurateUtil.getRawMap(config.getSection("powertools"));
if (powertools.isEmpty()) {
continue;
}
for (final Map.Entry<String, Object> entry : powertools.entrySet()) {
@ -327,7 +382,8 @@ public class EssentialsUpgrade {
powertools.put(entry.getKey(), temp);
}
}
config.forceSave();
config.setRaw("powertools", powertools);
config.blockingSave();
}
} catch (final RuntimeException ex) {
LOGGER.log(Level.INFO, "File: " + file.toString());
@ -352,39 +408,37 @@ public class EssentialsUpgrade {
if (!file.isFile() || !file.getName().endsWith(".yml")) {
continue;
}
final EssentialsConf config = new EssentialsConf(file);
final EssentialsConfiguration config = new EssentialsConfiguration(file);
try {
config.load();
if (config.hasProperty("home") && config.hasProperty("home.default")) {
final String defworld = (String) config.getProperty("home.default");
final Location defloc = getFakeLocation(config, "home.worlds." + defworld);
final String defworld = config.getString("home.default", null);
final Location defloc = getFakeLocation(config.getRootNode(), "home.worlds." + defworld);
if (defloc != null) {
config.setProperty("homes.home", defloc);
}
final Set<String> worlds = config.getConfigurationSection("home.worlds").getKeys(false);
final Set<String> worlds = ConfigurateUtil.getKeys(config.getSection("home.worlds"));
Location loc;
String worldName;
if (worlds == null) {
if (worlds.isEmpty()) {
continue;
}
for (final String world : worlds) {
if (defworld.equalsIgnoreCase(world)) {
continue;
}
loc = getFakeLocation(config, "home.worlds." + world);
loc = getFakeLocation(config.getRootNode(), "home.worlds." + world);
if (loc == null) {
continue;
}
worldName = loc.getWorld().getName().toLowerCase(Locale.ENGLISH);
if (worldName != null && !worldName.isEmpty()) {
config.setProperty("homes." + worldName, loc);
}
config.setProperty("homes." + worldName, loc);
}
config.removeProperty("home");
config.forceSave();
config.blockingSave();
}
} catch (final RuntimeException ex) {
@ -441,7 +495,7 @@ public class EssentialsUpgrade {
return null;
}
public Location getFakeLocation(final EssentialsConf 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;
@ -450,7 +504,8 @@ public class EssentialsUpgrade {
if (world == null) {
return null;
}
return new Location(world, config.getDouble((path != null ? path + "." : "") + "x", 0), config.getDouble((path != null ? path + "." : "") + "y", 0), config.getDouble((path != null ? path + "." : "") + "z", 0), (float) config.getDouble((path != null ? path + "." : "") + "yaw", 0), (float) config.getDouble((path != null ? path + "." : "") + "pitch", 0));
return new Location(world, config.node("x").getDouble(0), config.node("y").getDouble(0),
config.node("z").getDouble(0), config.node("yaw").getFloat(0), config.node("pitch").getFloat(0));
}
private void deleteOldItemsCsv() {
@ -493,22 +548,18 @@ public class EssentialsUpgrade {
final File configFile = new File(ess.getDataFolder(), "spawn.yml");
if (configFile.exists()) {
final EssentialsConf config = new EssentialsConf(configFile);
final EssentialsConfiguration config = new EssentialsConfiguration(configFile);
try {
config.load();
if (!config.hasProperty("spawns")) {
final Spawns spawns = new Spawns();
final Set<String> keys = config.getKeys(false);
for (final String group : keys) {
final Location loc = getFakeLocation(config, group);
spawns.getSpawns().put(group.toLowerCase(Locale.ENGLISH), loc);
for (final Map.Entry<String, CommentedConfigurationNode> entry : config.getMap().entrySet()) {
final Location loc = getFakeLocation(entry.getValue(), entry.getKey());
config.setProperty(entry.getKey(), loc);
}
if (!configFile.renameTo(new File(ess.getDataFolder(), "spawn.yml.old"))) {
throw new Exception(tl("fileRenameError", "spawn.yml"));
}
try (final PrintWriter writer = new PrintWriter(configFile)) {
new YamlStorageWriter(writer).save(spawns);
}
config.blockingSave();
}
} catch (final Exception ex) {
Bukkit.getLogger().log(Level.SEVERE, ex.getMessage(), ex);
@ -525,22 +576,18 @@ public class EssentialsUpgrade {
final File configFile = new File(ess.getDataFolder(), "jail.yml");
if (configFile.exists()) {
final EssentialsConf config = new EssentialsConf(configFile);
final EssentialsConfiguration config = new EssentialsConfiguration(configFile);
try {
config.load();
if (!config.hasProperty("jails")) {
final com.earth2me.essentials.settings.Jails jails = new com.earth2me.essentials.settings.Jails();
final Set<String> keys = config.getKeys(false);
for (final String jailName : keys) {
final Location loc = getFakeLocation(config, jailName);
jails.getJails().put(jailName.toLowerCase(Locale.ENGLISH), loc);
for (final Map.Entry<String, CommentedConfigurationNode> entry : config.getMap().entrySet()) {
final Location loc = getFakeLocation(entry.getValue(), entry.getKey());
config.setProperty(entry.getKey(), loc);
}
if (!configFile.renameTo(new File(ess.getDataFolder(), "jail.yml.old"))) {
throw new Exception(tl("fileRenameError", "jail.yml"));
}
try (final PrintWriter writer = new PrintWriter(configFile)) {
new YamlStorageWriter(writer).save(jails);
}
config.blockingSave();
}
} catch (final Exception ex) {
Bukkit.getLogger().log(Level.SEVERE, ex.getMessage(), ex);
@ -641,23 +688,23 @@ public class EssentialsUpgrade {
countFiles++;
final File pFile = new File(userdir, string);
final EssentialsConf conf = new EssentialsConf(pFile);
final EssentialsConfiguration conf = new EssentialsConfiguration(pFile);
conf.load();
String banReason;
final String banReason;
long banTimeout;
try {
banReason = conf.getConfigurationSection("ban").getString("reason");
} catch (final NullPointerException n) {
if (conf.hasProperty("ban.reason")) {
banReason = conf.getString("ban.reason", null);
} else {
banReason = null;
}
final String playerName = conf.getString("lastAccountName");
final String playerName = conf.getString("lastAccountName", null);
if (playerName != null && playerName.length() > 1 && banReason != null && banReason.length() > 1) {
try {
if (conf.getConfigurationSection("ban").contains("timeout")) {
banTimeout = Long.parseLong(conf.getConfigurationSection("ban").getString("timeout"));
if (conf.hasProperty("ban.timeout")) {
banTimeout = Long.parseLong(conf.getString("ban.timeout", null));
} else {
banTimeout = 0L;
}
@ -772,5 +819,6 @@ public class EssentialsUpgrade {
warnMetrics();
repairUserMap();
convertIgnoreList();
convertStupidCamelCaseUserdataKeys();
}
}

View File

@ -4,8 +4,8 @@ import com.earth2me.essentials.commands.IEssentialsCommand;
import com.earth2me.essentials.signs.EssentialsSign;
import com.earth2me.essentials.textreader.IText;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.event.EventPriority;
import org.spongepowered.configurate.CommentedConfigurationNode;
import java.math.BigDecimal;
import java.text.NumberFormat;
@ -65,26 +65,8 @@ public interface ISettings extends IConf {
Set<String> getMuteCommands();
/**
* @Deprecated in favor of {@link Kits#getKits()}
*/
@Deprecated
ConfigurationSection getKits();
/**
* @Deprecated in favor of {@link Kits#getKit(String)}
*/
@Deprecated
Map<String, Object> getKit(String kit);
/**
* @Deprecated in favor of {@link Kits#addKit(String, List, long)}}
*/
@Deprecated
void addKit(String name, List<String> lines, long delay);
@Deprecated
ConfigurationSection getKitSection();
CommentedConfigurationNode getKitSection();
boolean isSkippingUsedOneTimeKitsFromKitList();

View File

@ -2,6 +2,7 @@ package com.earth2me.essentials;
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;
@ -160,6 +161,7 @@ public interface IUser {
void setIgnoreMsg(boolean ignoreMsg);
@Deprecated
void setConfigProperty(String node, Object object);
Set<String> getConfigKeys();
@ -168,8 +170,11 @@ public interface IUser {
Map<String, Object> getConfigMap(String node);
@Deprecated
Map<Pattern, Long> getCommandCooldowns();
List<CommandCooldown> getCooldownsList();
Date getCommandCooldownExpiry(String label);
void addCommandCooldown(Pattern pattern, Date expiresAt, boolean save);

View File

@ -1,10 +1,12 @@
package com.earth2me.essentials;
import com.earth2me.essentials.storage.AsyncStorageObjectHolder;
import com.earth2me.essentials.config.ConfigurateUtil;
import com.earth2me.essentials.config.EssentialsConfiguration;
import net.ess3.api.IEssentials;
import net.ess3.api.IUser;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
@ -23,28 +25,58 @@ import org.bukkit.event.player.PlayerRespawnEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.plugin.PluginManager;
import org.spongepowered.configurate.CommentedConfigurationNode;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.logging.Level;
import java.util.logging.Logger;
import static com.earth2me.essentials.I18n.tl;
public class Jails extends AsyncStorageObjectHolder<com.earth2me.essentials.settings.Jails> implements net.ess3.api.IJails {
private static final transient Logger LOGGER = Bukkit.getLogger();
public class Jails implements net.ess3.api.IJails {
private static final transient Logger LOGGER = Logger.getLogger("Essentials");
private static transient boolean enabled = false;
private final IEssentials ess;
private final EssentialsConfiguration config;
private final Map<String, Location> jails = new HashMap<>();
public Jails(final IEssentials ess) {
super(ess, com.earth2me.essentials.settings.Jails.class);
this.ess = ess;
this.config = new EssentialsConfiguration(new File(ess.getDataFolder(), "jail.yml"));
reloadConfig();
}
@Override
public void reloadConfig() {
synchronized (jails) {
config.load();
jails.clear();
final CommentedConfigurationNode jailsNode = config.getSection("jails");
for (final Map.Entry<String, CommentedConfigurationNode> entry : ConfigurateUtil.getMap(jailsNode).entrySet()) {
final CommentedConfigurationNode jailNode = entry.getValue();
final String worldName = jailNode.node("world").getString();
if (worldName == null || worldName.isEmpty()) {
continue;
}
final World world = Bukkit.getWorld(worldName);
if (world == null) {
LOGGER.log(Level.WARNING, "Invalid world name, " + worldName + ", for jail name " + entry.getKey());
continue;
}
jails.put(entry.getKey().toLowerCase(Locale.ENGLISH), new Location(world, jailNode.node("x").getDouble(), jailNode.node("y").getDouble(),
jailNode.node("z").getDouble(), jailNode.node("yaw").getFloat(), jailNode.node("pitch").getFloat()));
}
checkRegister();
}
}
private void registerListeners() {
enabled = true;
final PluginManager pluginManager = ess.getServer().getPluginManager();
@ -55,21 +87,6 @@ public class Jails extends AsyncStorageObjectHolder<com.earth2me.essentials.sett
}
}
@Override
public File getStorageFile() {
return new File(ess.getDataFolder(), "jail.yml");
}
@Override
public void finishRead() {
checkRegister();
}
@Override
public void finishWrite() {
checkRegister();
}
public void resetListener() {
enabled = false;
checkRegister();
@ -82,92 +99,100 @@ public class Jails extends AsyncStorageObjectHolder<com.earth2me.essentials.sett
}
@Override
public Location getJail(final String jailName) throws Exception {
acquireReadLock();
try {
if (getData().getJails() == null || jailName == null || !getData().getJails().containsKey(jailName.toLowerCase(Locale.ENGLISH))) {
public void startTransaction() {
config.startTransaction();
}
@Override
public void stopTransaction(final boolean blocking) {
config.stopTransaction(blocking);
}
@Override
public Location getJail(String jailName) throws Exception {
if (jailName == null) {
throw new Exception(tl("jailNotExist"));
}
jailName = jailName.toLowerCase(Locale.ENGLISH);
synchronized (jails) {
if (!jails.containsKey(jailName)) {
throw new Exception(tl("jailNotExist"));
}
final Location loc = getData().getJails().get(jailName.toLowerCase(Locale.ENGLISH));
if (loc == null || loc.getWorld() == null) {
throw new Exception(tl("jailNotExist"));
}
return loc;
} finally {
unlock();
return jails.get(jailName);
}
}
@Override
public Collection<String> getList() throws Exception {
acquireReadLock();
try {
if (getData().getJails() == null) {
return Collections.emptyList();
}
return new ArrayList<>(getData().getJails().keySet());
} finally {
unlock();
synchronized (jails) {
return new ArrayList<>(jails.keySet());
}
}
@Override
public void removeJail(final String jail) throws Exception {
acquireWriteLock();
try {
if (getData().getJails() == null) {
return;
public void removeJail(String jail) throws Exception {
if (jail == null) {
return;
}
jail = jail.toLowerCase(Locale.ENGLISH);
synchronized (jails) {
if (jails.remove(jail) != null) {
config.getSection("jails").node(jail).set(null);
config.save();
}
getData().getJails().remove(jail.toLowerCase(Locale.ENGLISH));
} finally {
unlock();
}
}
/**
* @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, final String jail) throws Exception {
acquireReadLock();
try {
if (user.getBase().isOnline()) {
final Location loc = getJail(jail);
user.getTeleport().now(loc, false, TeleportCause.COMMAND);
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(jails.get(jail), false, TeleportCause.COMMAND);
}
user.setJail(jail);
}
user.setJail(jail);
} finally {
unlock();
}
}
@Override
public void sendToJail(final IUser user, final String jail, final CompletableFuture<Boolean> future) throws Exception {
acquireReadLock();
try {
if (user.getBase().isOnline()) {
final Location loc = getJail(jail);
user.getAsyncTeleport().now(loc, false, TeleportCause.COMMAND, future);
future.thenAccept(success -> user.setJail(jail));
return;
public void sendToJail(final IUser user, final String jailName, final CompletableFuture<Boolean> future) throws Exception {
if (jailName == null || jailName.isEmpty()) {
return;
}
final String jail = jailName.toLowerCase(Locale.ENGLISH);
synchronized (jails) {
if (jails.containsKey(jail)) {
if (user.getBase().isOnline()) {
user.getAsyncTeleport().now(jails.get(jail), false, TeleportCause.COMMAND, future);
future.thenAccept(success -> user.setJail(jail));
return;
}
user.setJail(jail);
}
user.setJail(jail);
} finally {
unlock();
}
}
@Override
public void setJail(final String jailName, final Location loc) throws Exception {
acquireWriteLock();
try {
if (getData().getJails() == null) {
getData().setJails(new HashMap<>());
}
getData().getJails().put(jailName.toLowerCase(Locale.ENGLISH), loc);
} finally {
unlock();
public void setJail(String jailName, final Location loc) throws Exception {
jailName = jailName.toLowerCase(Locale.ENGLISH);
synchronized (jails) {
jails.put(jailName, loc);
config.setProperty("jails." + jailName, loc);
config.save();
}
}

View File

@ -1,8 +1,10 @@
package com.earth2me.essentials;
import com.earth2me.essentials.config.ConfigurateUtil;
import com.earth2me.essentials.config.EssentialsConfiguration;
import com.earth2me.essentials.utils.NumberUtil;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.MemoryConfiguration;
import org.spongepowered.configurate.CommentedConfigurationNode;
import org.spongepowered.configurate.serialize.SerializationException;
import java.io.File;
import java.math.BigDecimal;
@ -14,13 +16,11 @@ import static com.earth2me.essentials.I18n.capitalCase;
import static com.earth2me.essentials.I18n.tl;
public class Kits implements IConf {
private final EssentialsConf config;
private ConfigurationSection kits;
private final EssentialsConfiguration config;
private CommentedConfigurationNode kits;
public Kits(final IEssentials essentials) {
config = new EssentialsConf(new File(essentials.getDataFolder(), "kits.yml"));
config.setTemplateName("/kits.yml");
config = new EssentialsConfiguration(new File(essentials.getDataFolder(), "kits.yml"), "/kits.yml");
reloadConfig();
}
@ -31,13 +31,18 @@ public class Kits implements IConf {
kits = _getKits();
}
private ConfigurationSection _getKits() {
if (config.isConfigurationSection("kits")) {
final ConfigurationSection section = config.getConfigurationSection("kits");
final ConfigurationSection newSection = new MemoryConfiguration();
for (final String kitItem : section.getKeys(false)) {
if (section.isConfigurationSection(kitItem)) {
newSection.set(kitItem.toLowerCase(Locale.ENGLISH), section.getConfigurationSection(kitItem));
private CommentedConfigurationNode _getKits() {
final CommentedConfigurationNode section = config.getSection("kits");
if (section != null) {
final CommentedConfigurationNode newSection = config.newSection();
for (final String kitItem : ConfigurateUtil.getKeys(section)) {
final CommentedConfigurationNode kitSection = section.node(kitItem);
if (kitSection.isMap()) {
try {
newSection.node(kitItem.toLowerCase(Locale.ENGLISH)).set(kitSection);
} catch (SerializationException e) {
e.printStackTrace();
}
}
}
return newSection;
@ -45,25 +50,23 @@ public class Kits implements IConf {
return null;
}
public EssentialsConf getConfig() {
public EssentialsConfiguration getConfig() {
return config;
}
public ConfigurationSection getKits() {
public CommentedConfigurationNode getKits() {
return kits;
}
public Map<String, Object> getKit(String name) {
name = name.replace('.', '_').replace('/', '_');
if (getKits() != null) {
final ConfigurationSection kits = getKits();
// For some reason, YAML doesn't sees keys as always lowercase even if they aren't defined like that.
// Workaround is to toLowercase when getting from the config, but showing normally elsewhere.
// ODDLY ENOUGH when you get the configuration section for ALL kits, it will return the proper
// case of each kit. But when you check for each kit's configuration section, it won't return the kit
// you just found if you don't toLowercase it.
if (kits.isConfigurationSection(name.toLowerCase())) {
return kits.getConfigurationSection(name.toLowerCase()).getValues(true);
final CommentedConfigurationNode kits = getKits();
// Other parts of the codebase/3rd party plugins expect us to lowercase kit names here.
// This isn't strictly needed for the future of Essentials, but for compatibility it's here.
final CommentedConfigurationNode kitSection = kits.node(name.toLowerCase());
if (!kitSection.virtual() && kitSection.isMap()) {
return ConfigurateUtil.getRawMap(kitSection);
}
}
@ -72,13 +75,11 @@ public class Kits implements IConf {
// Tries to find an existing kit name that matches the given name, ignoring case. Returns null if no match.
public String matchKit(final String name) {
if (config.isConfigurationSection("kits")) {
final ConfigurationSection section = config.getConfigurationSection("kits");
if (section != null) {
for (final String kitName : section.getKeys(false)) {
if (kitName.equalsIgnoreCase(name)) {
return kitName;
}
final CommentedConfigurationNode section = config.getSection("kits");
if (section != null) {
for (final String kitName : ConfigurateUtil.getKeys(section)) {
if (kitName.equalsIgnoreCase(name)) {
return kitName;
}
}
}
@ -87,23 +88,23 @@ public class Kits implements IConf {
public void addKit(final String name, final List<String> lines, final long delay) {
// Will overwrite but w/e
config.set("kits." + name + ".delay", delay);
config.set("kits." + name + ".items", lines);
config.setProperty("kits." + name + ".delay", delay);
config.setProperty("kits." + name + ".items", lines);
kits = _getKits();
config.save();
}
public void removeKit(final String name) {
config.set("kits." + name, null);
config.removeProperty("kits." + name);
kits = _getKits();
config.save();
}
public String listKits(final net.ess3.api.IEssentials ess, final User user) throws Exception {
try {
final ConfigurationSection kits = config.getConfigurationSection("kits");
final CommentedConfigurationNode kits = config.getSection("kits");
final StringBuilder list = new StringBuilder();
for (final String kitItem : kits.getKeys(false)) {
for (final String kitItem : ConfigurateUtil.getKeys(kits)) {
if (user == null) {
list.append(" ").append(capitalCase(kitItem));
} else if (user.isAuthorized("essentials.kits." + kitItem.toLowerCase(Locale.ENGLISH))) {

View File

@ -1,5 +1,6 @@
package com.earth2me.essentials;
import com.earth2me.essentials.config.EssentialsConfiguration;
import com.earth2me.essentials.utils.LocationUtil;
import com.earth2me.essentials.utils.VersionUtil;
import io.papermc.lib.PaperLib;
@ -21,15 +22,13 @@ public class RandomTeleport implements IConf {
private static final Random RANDOM = new Random();
private static final int HIGHEST_BLOCK_Y_OFFSET = VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_15_R01) ? 1 : 0;
private final IEssentials essentials;
private final EssentialsConf config;
private final EssentialsConfiguration config;
private final ConcurrentLinkedQueue<Location> cachedLocations = new ConcurrentLinkedQueue<>();
public RandomTeleport(final IEssentials essentials) {
this.essentials = essentials;
final File file = new File(essentials.getDataFolder(), "tpr.yml");
config = new EssentialsConf(file);
config.setTemplateName("/tpr.yml");
config.options().copyHeader(true);
config = new EssentialsConfiguration(new File(essentials.getDataFolder(), "tpr.yml"), "/tpr.yml",
"Configuration for the random teleport command.\nSome settings may be defaulted, and can be changed via the /settpr command in-game.");
reloadConfig();
}
@ -41,7 +40,7 @@ public class RandomTeleport implements IConf {
public Location getCenter() {
try {
final Location center = config.getLocation("center", essentials.getServer());
final Location center = config.getLocation("center");
if (center != null) {
return center;
}
@ -77,7 +76,7 @@ public class RandomTeleport implements IConf {
}
public Set<Biome> getExcludedBiomes() {
final List<String> biomeNames = config.getStringList("excluded-biomes");
final List<String> biomeNames = config.getList("excluded-biomes", String.class);
final Set<Biome> excludedBiomes = new HashSet<>();
for (final String biomeName : biomeNames) {
try {

View File

@ -2,6 +2,8 @@ package com.earth2me.essentials;
import com.earth2me.essentials.api.IItemDb;
import com.earth2me.essentials.commands.IEssentialsCommand;
import com.earth2me.essentials.config.ConfigurateUtil;
import com.earth2me.essentials.config.EssentialsConfiguration;
import com.earth2me.essentials.signs.EssentialsSign;
import com.earth2me.essentials.signs.Signs;
import com.earth2me.essentials.textreader.IText;
@ -14,10 +16,9 @@ import net.ess3.api.IEssentials;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.command.Command;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.MemoryConfiguration;
import org.bukkit.event.EventPriority;
import org.bukkit.inventory.ItemStack;
import org.spongepowered.configurate.CommentedConfigurationNode;
import java.io.File;
import java.math.BigDecimal;
@ -49,7 +50,7 @@ public class Settings implements net.ess3.api.ISettings {
private static final Logger logger = Logger.getLogger("Essentials");
private static final BigDecimal MAXMONEY = new BigDecimal("10000000000000");
private static final BigDecimal MINMONEY = new BigDecimal("-10000000000000");
private final transient EssentialsConf config;
private final transient EssentialsConfiguration config;
private final transient IEssentials ess;
private final transient AtomicInteger reloadCount = new AtomicInteger(0);
private final Map<String, String> chatFormats = Collections.synchronizedMap(new HashMap<>());
@ -62,7 +63,7 @@ public class Settings implements net.ess3.api.ISettings {
private boolean forceDisableTeleportSafety;
private Set<String> disabledCommands = new HashSet<>();
private final transient Map<String, Command> disabledBukkitCommands = new HashMap<>();
private ConfigurationSection commandCosts;
private Map<String, BigDecimal> commandCosts;
private Set<String> socialSpyCommands = new HashSet<>();
private Set<String> muteCommands = new HashSet<>();
private String nicknamePrefix = "~";
@ -125,7 +126,6 @@ public class Settings implements net.ess3.api.ISettings {
private boolean isCompassTowardsHomePerm;
private boolean isAllowWorldInBroadcastworld;
private String itemDbType; // #EasterEgg - admins can manually switch items provider if they want
private boolean forceEnableRecipe; // https://github.com/EssentialsX/Essentials/issues/1397
private boolean allowOldIdSigns;
private boolean isWaterSafe;
private boolean isSafeUsermap;
@ -137,8 +137,7 @@ public class Settings implements net.ess3.api.ISettings {
public Settings(final IEssentials ess) {
this.ess = ess;
config = new EssentialsConf(new File(ess.getDataFolder(), "config.yml"));
config.setTemplateName("/config.yml");
config = new EssentialsConfiguration(new File(ess.getDataFolder(), "config.yml"), "/config.yml");
reloadConfig();
}
@ -159,8 +158,8 @@ public class Settings implements net.ess3.api.ISettings {
@Override
public Set<String> getMultipleHomes() {
final ConfigurationSection section = config.getConfigurationSection("sethome-multiple");
return section == null ? null : section.getKeys(false);
final CommentedConfigurationNode section = config.getSection("sethome-multiple");
return section == null ? null : ConfigurateUtil.getKeys(section);
}
@Override
@ -305,10 +304,10 @@ public class Settings implements net.ess3.api.ISettings {
private Set<String> _getDisabledCommands() {
final Set<String> disCommands = new HashSet<>();
for (final String c : config.getStringList("disabled-commands")) {
for (final String c : config.getList("disabled-commands", String.class)) {
disCommands.add(c.toLowerCase(Locale.ENGLISH));
}
for (final String c : config.getKeys(false)) {
for (final String c : config.getKeys()) {
if (c.startsWith("disable-")) {
disCommands.add(c.substring(8).toLowerCase(Locale.ENGLISH));
}
@ -318,7 +317,7 @@ public class Settings implements net.ess3.api.ISettings {
@Override
public boolean isPlayerCommand(final String label) {
for (final String c : config.getStringList("player-commands")) {
for (final String c : config.getList("player-commands", String.class)) {
if (!c.equalsIgnoreCase(label)) {
continue;
}
@ -329,7 +328,7 @@ public class Settings implements net.ess3.api.ISettings {
@Override
public boolean isCommandOverridden(final String name) {
for (final String c : config.getStringList("overridden-commands")) {
for (final String c : config.getList("overridden-commands", String.class)) {
if (!c.equalsIgnoreCase(name)) {
continue;
}
@ -343,32 +342,34 @@ public class Settings implements net.ess3.api.ISettings {
return getCommandCost(cmd.getName());
}
private ConfigurationSection _getCommandCosts() {
if (config.isConfigurationSection("command-costs")) {
final ConfigurationSection section = config.getConfigurationSection("command-costs");
final ConfigurationSection newSection = new MemoryConfiguration();
for (final String command : section.getKeys(false)) {
private Map<String, BigDecimal> _getCommandCosts() {
final Map<String, CommentedConfigurationNode> section = ConfigurateUtil.getMap(config.getSection("command-costs"));
if (!section.isEmpty()) {
final Map<String, BigDecimal> newMap = new HashMap<>();
for (Map.Entry<String, CommentedConfigurationNode> entry : section.entrySet()) {
final String command = entry.getKey();
final CommentedConfigurationNode node = entry.getValue();
if (command.charAt(0) == '/') {
ess.getLogger().warning("Invalid command cost. '" + command + "' should not start with '/'.");
}
if (section.isDouble(command)) {
newSection.set(command.toLowerCase(Locale.ENGLISH), section.getDouble(command));
} else if (section.isInt(command)) {
newSection.set(command.toLowerCase(Locale.ENGLISH), (double) section.getInt(command));
} else if (section.isString(command)) {
final String costString = section.getString(command);
try {
try {
if (ConfigurateUtil.isDouble(node)) {
newMap.put(command.toLowerCase(Locale.ENGLISH), BigDecimal.valueOf(node.getDouble()));
} else if (ConfigurateUtil.isInt(node)) {
newMap.put(command.toLowerCase(Locale.ENGLISH), BigDecimal.valueOf(node.getInt()));
} else if (ConfigurateUtil.isString(node)) {
final String costString = node.getString();
//noinspection ConstantConditions
final double cost = Double.parseDouble(costString.trim().replace("$", "").replace(getCurrencySymbol(), "").replaceAll("\\W", ""));
newSection.set(command.toLowerCase(Locale.ENGLISH), cost);
} catch (final NumberFormatException ex) {
ess.getLogger().warning("Invalid command cost for: " + command + " (" + costString + ")");
newMap.put(command.toLowerCase(Locale.ENGLISH), BigDecimal.valueOf(cost));
} else {
ess.getLogger().warning("Invalid command cost for: " + command);
}
} else {
} catch (final Exception ex) {
ess.getLogger().warning("Invalid command cost for: " + command);
}
}
return newSection;
return newMap;
}
return null;
}
@ -376,8 +377,8 @@ public class Settings implements net.ess3.api.ISettings {
@Override
public BigDecimal getCommandCost(String name) {
name = name.replace('.', '_').replace('/', '_');
if (commandCosts != null) {
return EssentialsConf.toBigDecimal(commandCosts.getString(name), BigDecimal.ZERO);
if (commandCosts != null && commandCosts.containsKey(name)) {
return commandCosts.get(name);
}
return BigDecimal.ZERO;
}
@ -386,7 +387,7 @@ public class Settings implements net.ess3.api.ISettings {
final Set<String> socialspyCommands = new HashSet<>();
if (config.isList("socialspy-commands")) {
for (final String c : config.getStringList("socialspy-commands")) {
for (final String c : config.getList("socialspy-commands", String.class)) {
socialspyCommands.add(c.toLowerCase(Locale.ENGLISH));
}
} else {
@ -414,7 +415,7 @@ public class Settings implements net.ess3.api.ISettings {
private Set<String> _getMuteCommands() {
final Set<String> muteCommands = new HashSet<>();
if (config.isList("mute-commands")) {
for (final String s : config.getStringList("mute-commands")) {
for (final String s : config.getList("mute-commands", String.class)) {
muteCommands.add(s.toLowerCase(Locale.ENGLISH));
}
}
@ -447,23 +448,8 @@ public class Settings implements net.ess3.api.ISettings {
}
@Override
public ConfigurationSection getKits() {
return ess.getKits().getKits();
}
@Override
public Map<String, Object> getKit(final String name) {
return ess.getKits().getKit(name);
}
@Override
public void addKit(final String name, final List<String> lines, final long delay) {
ess.getKits().addKit(name, lines, delay);
}
@Override
public ConfigurationSection getKitSection() {
return config.getConfigurationSection("kits");
public CommentedConfigurationNode getKitSection() {
return config.getSection("kits");
}
@Override
@ -577,13 +563,13 @@ public class Settings implements net.ess3.api.ISettings {
private Map<String, String> _getWorldAliases() {
final Map<String, String> map = new HashMap<>();
final ConfigurationSection section = config.getConfigurationSection("chat.world-aliases");
final CommentedConfigurationNode section = config.getSection("chat.world-aliases");
if (section == null) {
return map;
}
for (String world : section.getKeys(false)) {
map.put(world.toLowerCase(), FormatUtil.replaceFormat(section.getString(world)));
for (Map.Entry<String, CommentedConfigurationNode> entry : ConfigurateUtil.getMap(section).entrySet()) {
map.put(entry.getKey().toLowerCase(), FormatUtil.replaceFormat(entry.getValue().getString()));
}
return map;
}
@ -615,8 +601,9 @@ public class Settings implements net.ess3.api.ISettings {
@Override
public Map<String, Object> getListGroupConfig() {
if (config.isConfigurationSection("list")) {
final Map<String, Object> values = config.getConfigurationSection("list").getValues(false);
final CommentedConfigurationNode node = config.getSection("list");
if (node.isMap()) {
final Map<String, Object> values = ConfigurateUtil.getRawMap(node);
if (!values.isEmpty()) {
return values;
}
@ -633,7 +620,7 @@ public class Settings implements net.ess3.api.ISettings {
@Override
public void reloadConfig() {
config.load();
noGodWorlds = new HashSet<>(config.getStringList("no-god-in-worlds"));
noGodWorlds = new HashSet<>(config.getList("no-god-in-worlds", String.class));
enabledSigns = _getEnabledSigns();
teleportSafety = _isTeleportSafetyEnabled();
forceDisableTeleportSafety = _isForceDisableTeleportSafety();
@ -767,6 +754,7 @@ public class Settings implements net.ess3.api.ISettings {
private List<Material> _getItemSpawnBlacklist() {
final List<Material> epItemSpwn = new ArrayList<>();
//noinspection deprecation
final IItemDb itemDb = ess.getItemDb();
if (itemDb == null || !itemDb.isReady()) {
logger.log(Level.FINE, "Skipping item spawn blacklist read; item DB not yet loaded.");
@ -797,7 +785,7 @@ public class Settings implements net.ess3.api.ISettings {
final List<EssentialsSign> newSigns = new ArrayList<>();
for (String signName : config.getStringList("enabledSigns")) {
for (String signName : config.getList("enabledSigns", String.class)) {
signName = signName.trim().toUpperCase(Locale.ENGLISH);
if (signName.isEmpty()) {
continue;
@ -1463,12 +1451,12 @@ public class Settings implements net.ess3.api.ISettings {
public List<String> _getSpawnOnJoinGroups() {
final List<String> def = Collections.emptyList();
if (config.isSet("spawn-on-join")) {
if (config.hasProperty("spawn-on-join")) {
if (config.isList("spawn-on-join")) {
return new ArrayList<>(config.getStringList("spawn-on-join"));
return new ArrayList<>(config.getList("spawn-on-join", String.class));
} else if (config.isBoolean("spawn-on-join")) { // List of [*] to make all groups go to spawn on join.
// This also maintains backwards compatibility with initial impl of single boolean value.
return config.getBoolean("spawn-on-join") ? Collections.singletonList("*") : def;
return config.getBoolean("spawn-on-join", true) ? Collections.singletonList("*") : def;
}
// Take whatever the value is, convert to string and add it to a list as a single value.
final String val = config.get("spawn-on-join").toString();
@ -1484,7 +1472,7 @@ public class Settings implements net.ess3.api.ISettings {
}
@Override
public boolean isUserInSpawnOnJoinGroup(final IUser user) {
public boolean isUserInSpawnOnJoinGroup(@SuppressWarnings("deprecation") final IUser user) {
for (final String group : this.spawnOnJoinGroups) {
if (group.equals("*") || user.inGroup(group)) {
return true;
@ -1499,12 +1487,14 @@ public class Settings implements net.ess3.api.ISettings {
}
private Map<Pattern, Long> _getCommandCooldowns() {
if (!config.isConfigurationSection("command-cooldowns")) {
final CommentedConfigurationNode section = config.getSection("command-cooldowns");
if (section == null) {
return null;
}
final ConfigurationSection section = config.getConfigurationSection("command-cooldowns");
final Map<Pattern, Long> result = new LinkedHashMap<>();
for (String cmdEntry : section.getKeys(false)) {
for (Map.Entry<String, Object> entry : ConfigurateUtil.getRawMap(section).entrySet()) {
String cmdEntry = entry.getKey();
Object value = entry.getValue();
Pattern pattern = null;
/* ================================
@ -1522,14 +1512,13 @@ public class Settings implements net.ess3.api.ISettings {
cmdEntry = cmdEntry.substring(1);
}
final String cmd = cmdEntry
.replaceAll("\\*", ".*"); // Wildcards are accepted as asterisk * as known universally.
.replaceAll("\\*", ".*"); // Wildcards are accepted as asterisk * as known universally.
pattern = Pattern.compile(cmd + "( .*)?"); // This matches arguments, if present, to "ignore" them from the feature.
}
/* ================================
* >> Process cooldown value
* ================================ */
Object value = section.get(cmdEntry);
if (value instanceof String) {
try {
value = Double.parseDouble(value.toString());
@ -1597,7 +1586,7 @@ public class Settings implements net.ess3.api.ISettings {
private NumberFormat _getCurrencyFormat() {
final String currencyFormatString = config.getString("currency-format", "#,##0.00");
final String symbolLocaleString = config.getString("currency-symbol-format-locale");
final String symbolLocaleString = config.getString("currency-symbol-format-locale", null);
final DecimalFormatSymbols decimalFormatSymbols;
if (symbolLocaleString != null) {
decimalFormatSymbols = DecimalFormatSymbols.getInstance(Locale.forLanguageTag(symbolLocaleString));
@ -1627,7 +1616,7 @@ public class Settings implements net.ess3.api.ISettings {
private List<EssentialsSign> _getUnprotectedSign() {
final List<EssentialsSign> newSigns = new ArrayList<>();
for (String signName : config.getStringList("unprotected-sign-names")) {
for (String signName : config.getList("unprotected-sign-names", String.class)) {
signName = signName.trim().toUpperCase(Locale.ENGLISH);
if (signName.isEmpty()) {
continue;
@ -1697,7 +1686,7 @@ public class Settings implements net.ess3.api.ISettings {
}
private List<String> _getDefaultEnabledConfirmCommands() {
final List<String> commands = config.getStringList("default-enabled-confirm-commands");
final List<String> commands = config.getList("default-enabled-confirm-commands", String.class);
for (int i = 0; i < commands.size(); i++) {
commands.set(i, commands.get(i).toLowerCase());
}
@ -1797,7 +1786,7 @@ public class Settings implements net.ess3.api.ISettings {
private Set<Predicate<String>> _getNickBlacklist() {
final Set<Predicate<String>> blacklist = new HashSet<>();
config.getStringList("nick-blacklist").forEach(entry -> {
config.getList("nick-blacklist", String.class).forEach(entry -> {
try {
blacklist.add(Pattern.compile(entry).asPredicate());
} catch (final PatternSyntaxException e) {

View File

@ -1,14 +1,13 @@
package com.earth2me.essentials;
import com.earth2me.essentials.commands.WarpNotFoundException;
import com.earth2me.essentials.config.EssentialsConfiguration;
import com.earth2me.essentials.utils.StringUtil;
import net.ess3.api.InvalidNameException;
import net.ess3.api.InvalidWorldException;
import org.bukkit.Location;
import org.bukkit.Server;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
@ -23,12 +22,10 @@ import static com.earth2me.essentials.I18n.tl;
public class Warps implements IConf, net.ess3.api.IWarps {
private static final Logger logger = Logger.getLogger("Essentials");
private final Map<StringIgnoreCase, EssentialsConf> warpPoints = new HashMap<>();
private final Map<StringIgnoreCase, EssentialsConfiguration> warpPoints = new HashMap<>();
private final File warpsFolder;
private final Server server;
public Warps(final Server server, final File dataFolder) {
this.server = server;
public Warps(final File dataFolder) {
warpsFolder = new File(dataFolder, "warps");
if (!warpsFolder.exists()) {
warpsFolder.mkdirs();
@ -53,11 +50,11 @@ public class Warps implements IConf, net.ess3.api.IWarps {
@Override
public Location getWarp(final String warp) throws WarpNotFoundException, InvalidWorldException {
final EssentialsConf conf = warpPoints.get(new StringIgnoreCase(warp));
final EssentialsConfiguration conf = warpPoints.get(new StringIgnoreCase(warp));
if (conf == null) {
throw new WarpNotFoundException();
}
return conf.getLocation(null, server);
return conf.getLocation(null);
}
@Override
@ -68,34 +65,33 @@ public class Warps implements IConf, net.ess3.api.IWarps {
@Override
public void setWarp(final IUser user, final String name, final Location loc) throws Exception {
final String filename = StringUtil.sanitizeFileName(name);
EssentialsConf conf = warpPoints.get(new StringIgnoreCase(name));
EssentialsConfiguration conf = warpPoints.get(new StringIgnoreCase(name));
if (conf == null) {
final File confFile = new File(warpsFolder, filename + ".yml");
if (confFile.exists()) {
throw new Exception(tl("similarWarpExist"));
}
conf = new EssentialsConf(confFile);
conf = new EssentialsConfiguration(confFile);
conf.load();
warpPoints.put(new StringIgnoreCase(name), conf);
}
conf.setProperty(null, loc);
conf.setProperty("name", name);
if (user != null) conf.setProperty("lastowner", user.getBase().getUniqueId().toString());
try {
conf.saveWithError();
} catch (final IOException ex) {
throw new IOException(tl("invalidWarpName"));
if (user != null) {
conf.setProperty("lastowner", user.getBase().getUniqueId().toString());
}
conf.save();
}
@Override
public UUID getLastOwner(final String warp) throws WarpNotFoundException {
final EssentialsConf conf = warpPoints.get(new StringIgnoreCase(warp));
final EssentialsConfiguration conf = warpPoints.get(new StringIgnoreCase(warp));
if (conf == null) {
throw new WarpNotFoundException();
}
UUID uuid = null;
try {
uuid = UUID.fromString(conf.getString("lastowner"));
uuid = UUID.fromString(conf.getString("lastowner", null));
} catch (final Exception ignored) {
}
return uuid;
@ -103,7 +99,7 @@ public class Warps implements IConf, net.ess3.api.IWarps {
@Override
public void removeWarp(final String name) throws Exception {
final EssentialsConf conf = warpPoints.get(new StringIgnoreCase(name));
final EssentialsConfiguration conf = warpPoints.get(new StringIgnoreCase(name));
if (conf == null) {
throw new Exception(tl("warpNotExist"));
}
@ -122,9 +118,9 @@ public class Warps implements IConf, net.ess3.api.IWarps {
final String filename = listOfFile.getName();
if (listOfFile.isFile() && filename.endsWith(".yml")) {
try {
final EssentialsConf conf = new EssentialsConf(listOfFile);
final EssentialsConfiguration conf = new EssentialsConfiguration(listOfFile);
conf.load();
final String name = conf.getString("name");
final String name = conf.getString("name", null);
if (name != null) {
warpPoints.put(new StringIgnoreCase(name), conf);
}

View File

@ -1,10 +1,12 @@
package com.earth2me.essentials;
import com.earth2me.essentials.commands.NotEnoughArgumentsException;
import com.earth2me.essentials.config.ConfigurateUtil;
import com.earth2me.essentials.config.EssentialsConfiguration;
import com.earth2me.essentials.utils.VersionUtil;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.inventory.ItemStack;
import org.spongepowered.configurate.CommentedConfigurationNode;
import java.io.File;
import java.math.BigDecimal;
@ -13,11 +15,10 @@ import java.util.Locale;
import static com.earth2me.essentials.I18n.tl;
public class Worth implements IConf {
private final EssentialsConf config;
private final EssentialsConfiguration config;
public Worth(final File dataFolder) {
config = new EssentialsConf(new File(dataFolder, "worth.yml"));
config.setTemplateName("/worth.yml");
config = new EssentialsConfiguration(new File(dataFolder, "worth.yml"), "/worth.yml");
config.load();
}
@ -39,8 +40,8 @@ public class Worth implements IConf {
// Check for matches with data value 0
if (result.signum() < 0) {
final ConfigurationSection itemNameMatch = config.getConfigurationSection("worth." + itemname);
if (itemNameMatch != null && itemNameMatch.getKeys(false).size() == 1) {
final CommentedConfigurationNode itemNameMatch = config.getSection("worth." + itemname);
if (itemNameMatch != null && ConfigurateUtil.getKeys(itemNameMatch).size() == 1) {
result = config.getBigDecimal("worth." + itemname + ".0", BigDecimal.ONE.negate());
}
}

View File

@ -1,8 +1,8 @@
package com.earth2me.essentials.api;
import com.earth2me.essentials.EssentialsUserConf;
import com.earth2me.essentials.Trade;
import com.earth2me.essentials.User;
import com.earth2me.essentials.config.EssentialsUserConfiguration;
import com.earth2me.essentials.utils.NumberUtil;
import com.earth2me.essentials.utils.StringUtil;
import com.google.common.base.Charsets;
@ -57,12 +57,12 @@ public class Economy {
LOGGER.log(Level.SEVERE, MessageFormat.format(WARN_NPC_RECREATE_1, name, npcUUID.toString()), new RuntimeException());
LOGGER.log(Level.SEVERE, WARN_NPC_RECREATE_2);
}
final EssentialsUserConf npcConfig = new EssentialsUserConf(name, npcUUID, npcFile);
final EssentialsUserConfiguration npcConfig = new EssentialsUserConfiguration(name, npcUUID, npcFile);
npcConfig.load();
npcConfig.setProperty("npc", true);
npcConfig.setProperty("lastAccountName", name);
npcConfig.setProperty("money", ess.getSettings().getStartingBalance());
npcConfig.forceSave();
npcConfig.blockingSave();
ess.getUserMap().trackUUID(npcUUID, name, false);
}

View File

@ -1,5 +1,6 @@
package com.earth2me.essentials.api;
import com.earth2me.essentials.IConf;
import net.ess3.api.IUser;
import org.bukkit.Location;
@ -12,7 +13,7 @@ import java.util.concurrent.CompletableFuture;
* @deprecated External plugins should use {@link net.ess3.api.IJails} instead of this interface in case future APIs are added.
*/
@Deprecated
public interface IJails extends IReload {
public interface IJails extends IConf {
/**
* Gets the location of the jail with the given name
*
@ -74,4 +75,14 @@ public interface IJails extends IReload {
* @throws Exception
*/
void setJail(String jailName, Location loc) throws Exception;
/**
* Begins a transaction
*/
void startTransaction();
/**
* Ends the current transaction and saves the state
*/
void stopTransaction(boolean blocking);
}

View File

@ -1,15 +0,0 @@
package com.earth2me.essentials.api;
/**
* Represents a storage object that is reloadable.
*
* @deprecated This is a remnant of the abandoned 3.x storage system. Neither future 2.x code nor external plugins
* should use this interface.
*/
@Deprecated
public interface IReload {
/**
* Reloads the given storage object.
*/
void onReload();
}

View File

@ -10,18 +10,15 @@ import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import org.bukkit.Material;
import org.bukkit.Server;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.MemoryConfiguration;
import org.bukkit.configuration.file.YamlConstructor;
import org.bukkit.configuration.file.YamlRepresenter;
import org.bukkit.inventory.ItemStack;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.DumperOptions.FlowStyle;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.representer.Representer;
import org.spongepowered.configurate.ConfigurationNode;
import org.spongepowered.configurate.yaml.NodeStyle;
import org.spongepowered.configurate.yaml.YamlConfigurationLoader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.StringWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
@ -32,20 +29,14 @@ import java.util.concurrent.Executors;
import static com.earth2me.essentials.I18n.tl;
public class Commandcreatekit extends EssentialsCommand {
private static final String PASTE_URL = "https://paste.gg/";
private static final String PASTE_UPLOAD_URL = "https://api.paste.gg/v1/pastes";
private static final Gson GSON = new Gson();
private final ExecutorService executorService = Executors.newSingleThreadExecutor();
private final DumperOptions yamlOptions = new DumperOptions();
private final Representer yamlRepresenter = new YamlRepresenter();
private final YamlConstructor yamlConstructor = new YamlConstructor();
public Commandcreatekit() {
super("createkit");
yamlOptions.setDefaultFlowStyle(FlowStyle.BLOCK);
yamlRepresenter.setDefaultFlowStyle(FlowStyle.BLOCK);
}
// /createkit <name> <delay>
@ -71,21 +62,25 @@ public class Commandcreatekit extends EssentialsCommand {
ess.getKits().addKit(kitname, list, delay);
user.sendMessage(tl("createdKit", kitname, list.size(), delay));
} else {
final ConfigurationSection config = new MemoryConfiguration();
config.set("kits." + kitname + ".delay", delay);
config.set("kits." + kitname + ".items", list);
final Yaml yaml = new Yaml(yamlConstructor, yamlRepresenter, yamlOptions);
String fileContents = "# Copy the kit code below into the kits section in your config.yml file\n";
fileContents += yaml.dump(config.getValues(false));
uploadPaste(user.getSource(), kitname, delay, fileContents);
uploadPaste(user.getSource(), kitname, delay, list);
}
}
private void uploadPaste(final CommandSource sender, final String kitName, final long delay, final String contents) {
private void uploadPaste(final CommandSource sender, final String kitName, final long delay, final List<String> list) {
executorService.submit(() -> {
try {
final StringWriter sw = new StringWriter();
final YamlConfigurationLoader loader = YamlConfigurationLoader.builder().sink(() -> new BufferedWriter(sw)).indent(2).nodeStyle(NodeStyle.BLOCK).build();
final ConfigurationNode config = loader.createNode();
config.node("kits", kitName, "delay").set(delay);
config.node("kits", kitName, "items").set(list);
sw.append("# Copy the kit code below into the kits section in your config.yml file\n");
loader.save(config);
final String fileContents = sw.toString();
final HttpURLConnection connection = (HttpURLConnection) new URL(PASTE_UPLOAD_URL).openConnection();
connection.setRequestMethod("POST");
connection.setDoInput(true);
@ -97,7 +92,7 @@ public class Commandcreatekit extends EssentialsCommand {
final JsonObject file = new JsonObject();
final JsonObject content = new JsonObject();
content.addProperty("format", "text");
content.addProperty("value", contents);
content.addProperty("value", fileContents);
file.add("content", content);
files.add(file);
body.add("files", files);

View File

@ -2,6 +2,7 @@ package com.earth2me.essentials.commands;
import com.earth2me.essentials.CommandSource;
import com.earth2me.essentials.Kit;
import com.earth2me.essentials.config.ConfigurateUtil;
import com.google.common.collect.Lists;
import org.bukkit.Server;
@ -37,7 +38,7 @@ public class Commanddelkit extends EssentialsCommand {
@Override
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
if (args.length == 1) {
return Lists.newArrayList(ess.getKits().getKits().getKeys(false));
return Lists.newArrayList(ConfigurateUtil.getKeys(ess.getKits().getKits()));
}
return Collections.emptyList();
}

View File

@ -3,6 +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.config.ConfigurateUtil;
import com.earth2me.essentials.utils.StringUtil;
import org.bukkit.Server;
@ -100,7 +101,7 @@ public class Commandkit extends EssentialsCommand {
if (args.length == 1) {
final List<String> options = new ArrayList<>();
// TODO: Move all of this to its own method
for (final String kitName : ess.getKits().getKits().getKeys(false)) {
for (final String kitName : ConfigurateUtil.getKeys(ess.getKits().getKits())) {
if (!user.isAuthorized("essentials.kits." + kitName)) { // Only check perm, not time or money
continue;
}
@ -117,7 +118,7 @@ public class Commandkit extends EssentialsCommand {
@Override
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
if (args.length == 1) {
return new ArrayList<>(ess.getKits().getKits().getKeys(false)); // TODO: Move this to its own method
return new ArrayList<>(ConfigurateUtil.getKeys(ess.getKits().getKits())); // TODO: Move this to its own method
} else if (args.length == 2) {
return getPlayers(server, sender);
} else {

View File

@ -2,6 +2,7 @@ package com.earth2me.essentials.commands;
import com.earth2me.essentials.CommandSource;
import com.earth2me.essentials.User;
import com.earth2me.essentials.config.ConfigurateUtil;
import org.bukkit.Server;
import java.util.ArrayList;
@ -58,7 +59,7 @@ public class Commandkitreset extends EssentialsCommand {
@Override
protected List<String> getTabCompleteOptions(Server server, CommandSource sender, String commandLabel, String[] args) {
if (args.length == 1) {
return new ArrayList<>(ess.getKits().getKits().getKeys(false));
return new ArrayList<>(ConfigurateUtil.getKeys(ess.getKits().getKits()));
} else if (args.length == 2 && sender.isAuthorized("essentials.kitreset.others", ess)) {
return getPlayers(server, sender);
} else {

View File

@ -2,6 +2,7 @@ package com.earth2me.essentials.commands;
import com.earth2me.essentials.Kit;
import com.earth2me.essentials.User;
import com.earth2me.essentials.config.ConfigurateUtil;
import org.bukkit.Server;
import java.util.ArrayList;
@ -33,7 +34,7 @@ public class Commandshowkit extends EssentialsCommand {
@Override
protected List<String> getTabCompleteOptions(final Server server, final User user, final String commandLabel, final String[] args) {
if (args.length == 1) {
return new ArrayList<>(ess.getKits().getKits().getKeys(false)); // TODO: Move this to its own method
return new ArrayList<>(ConfigurateUtil.getKeys(ess.getKits().getKits())); // TODO: Move this to its own method
} else {
return Collections.emptyList();
}

View File

@ -0,0 +1,103 @@
package com.earth2me.essentials.config;
import org.spongepowered.configurate.CommentedConfigurationNode;
import org.spongepowered.configurate.serialize.SerializationException;
import java.math.BigDecimal;
import java.math.MathContext;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
public final class ConfigurateUtil {
private ConfigurateUtil() {
}
public static Set<String> getRootNodeKeys(final EssentialsConfiguration config) {
return getKeys(config.getRootNode());
}
public static Set<String> getKeys(final CommentedConfigurationNode node) {
if (node == null || !node.isMap()) {
return Collections.emptySet();
}
final Set<String> keys = new LinkedHashSet<>();
for (Object obj : node.childrenMap().keySet()) {
keys.add(String.valueOf(obj));
}
return keys;
}
public static Map<String, CommentedConfigurationNode> getMap(final CommentedConfigurationNode node) {
if (node == null || !node.isMap()) {
return Collections.emptyMap();
}
final Map<String, CommentedConfigurationNode> map = new LinkedHashMap<>();
for (Map.Entry<Object, CommentedConfigurationNode> entry : node.childrenMap().entrySet()) {
map.put(String.valueOf(entry.getKey()), entry.getValue());
}
return map;
}
public static Map<String, Object> getRawMap(final CommentedConfigurationNode node) {
if (node == null || !node.isMap()) {
return Collections.emptyMap();
}
final Map<String, Object> map = new LinkedHashMap<>();
for (Map.Entry<Object, CommentedConfigurationNode> entry : node.childrenMap().entrySet()) {
map.put(String.valueOf(entry.getKey()), entry.getValue().raw());
}
return map;
}
public static List<Map<?, ?>> getMapList(final CommentedConfigurationNode node) {
List<?> list = null;
try {
list = node.getList(Object.class);
} catch (SerializationException ignored) {
}
final List<Map<?, ?>> result = new ArrayList<>();
if (list == null) {
return result;
}
for (Object object : list) {
if (object instanceof Map) {
result.add((Map<?, ?>) object);
}
}
return result;
}
public static BigDecimal toBigDecimal(final String input, final BigDecimal def) {
if (input == null || input.isEmpty()) {
return def;
}
try {
return new BigDecimal(input, MathContext.DECIMAL128);
} catch (final NumberFormatException | ArithmeticException e) {
return def;
}
}
public static boolean isDouble(final CommentedConfigurationNode node) {
return node != null && node.raw() instanceof Double;
}
public static boolean isInt(final CommentedConfigurationNode node) {
return node != null && node.raw() instanceof Integer;
}
public static boolean isString(final CommentedConfigurationNode node) {
return node != null && node.raw() instanceof String;
}
}

View File

@ -0,0 +1,41 @@
package com.earth2me.essentials.config;
import org.spongepowered.configurate.CommentedConfigurationNode;
import org.spongepowered.configurate.ConfigurateException;
import org.spongepowered.configurate.yaml.YamlConfigurationLoader;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
import static com.earth2me.essentials.config.EssentialsConfiguration.LOGGER;
public class ConfigurationSaveTask implements Runnable {
private final YamlConfigurationLoader loader;
private final CommentedConfigurationNode node;
private final AtomicInteger pendingWrites;
public ConfigurationSaveTask(final YamlConfigurationLoader loader, final CommentedConfigurationNode node, final AtomicInteger pendingWrites) {
this.loader = loader;
this.node = node;
this.pendingWrites = pendingWrites;
}
@Override
public void run() {
synchronized (loader) {
// Check if there are more writes in queue.
// If that's the case, we shouldn't bother writing data which is already out-of-date.
if (pendingWrites.get() > 1) {
pendingWrites.decrementAndGet();
}
try {
loader.save(node);
} catch (ConfigurateException e) {
LOGGER.log(Level.SEVERE, e.getMessage(), e);
} finally {
pendingWrites.decrementAndGet();
}
}
}
}

View File

@ -0,0 +1,432 @@
package com.earth2me.essentials.config;
import com.earth2me.essentials.config.annotations.DeleteOnEmpty;
import com.earth2me.essentials.config.processors.DeleteOnEmptyProcessor;
import com.earth2me.essentials.config.serializers.BigDecimalTypeSerializer;
import com.earth2me.essentials.config.serializers.LocationTypeSerializer;
import com.earth2me.essentials.config.serializers.MaterialTypeSerializer;
import net.ess3.api.InvalidWorldException;
import org.bukkit.Location;
import org.bukkit.Material;
import org.spongepowered.configurate.CommentedConfigurationNode;
import org.spongepowered.configurate.ConfigurateException;
import org.spongepowered.configurate.loader.HeaderMode;
import org.spongepowered.configurate.loader.ParsingException;
import org.spongepowered.configurate.objectmapping.ObjectMapper;
import org.spongepowered.configurate.serialize.SerializationException;
import org.spongepowered.configurate.serialize.TypeSerializerCollection;
import org.spongepowered.configurate.yaml.NodeStyle;
import org.spongepowered.configurate.yaml.YamlConfigurationLoader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
import java.util.logging.Logger;
import static com.earth2me.essentials.I18n.tl;
public class EssentialsConfiguration {
protected static final Logger LOGGER = Logger.getLogger("Essentials");
private static final ExecutorService EXECUTOR_SERVICE = Executors.newSingleThreadExecutor();
private static final ObjectMapper.Factory MAPPER_FACTORY = ObjectMapper.factoryBuilder()
.addProcessor(DeleteOnEmpty.class, (data, value) -> new DeleteOnEmptyProcessor())
.build();
private static final TypeSerializerCollection SERIALIZERS = TypeSerializerCollection.defaults().childBuilder()
.registerAnnotatedObjects(MAPPER_FACTORY)
.register(BigDecimal.class, new BigDecimalTypeSerializer())
.register(Location.class, new LocationTypeSerializer())
.register(Material.class, new MaterialTypeSerializer())
.build();
private final AtomicInteger pendingWrites = new AtomicInteger(0);
private final AtomicBoolean transaction = new AtomicBoolean(false);
private Class<?> resourceClass = EssentialsConfiguration.class;
protected final File configFile;
private final YamlConfigurationLoader loader;
private final String templateName;
private CommentedConfigurationNode configurationNode;
private Runnable saveHook;
public EssentialsConfiguration(final File configFile) {
this(configFile, null);
}
public EssentialsConfiguration(final File configFile, final String templateName) {
this(configFile, templateName, (String) null);
}
public EssentialsConfiguration(final File configFile, final String templateName, final Class<?> resourceClass) {
this(configFile, templateName, (String) null);
this.resourceClass = resourceClass;
}
public EssentialsConfiguration(final File configFile, final String templateName, final String header) {
this.configFile = configFile;
this.loader = YamlConfigurationLoader.builder()
.defaultOptions(opts -> opts
.header(header)
.serializers(SERIALIZERS))
.headerMode(HeaderMode.PRESET)
.nodeStyle(NodeStyle.BLOCK)
.indent(2)
.file(configFile)
.build();
this.templateName = templateName;
}
public CommentedConfigurationNode getRootNode() {
return configurationNode;
}
public File getFile() {
return configFile;
}
public void setProperty(String path, final Location location) {
path = path == null ? "" : path;
setInternal(path, location);
}
public Location getLocation(final String path) throws InvalidWorldException {
final CommentedConfigurationNode node = path == null ? getRootNode() : getSection(path);
if (node == null) {
return null;
}
try {
return node.get(Location.class);
} catch (SerializationException e) {
return null;
}
}
public Map<String, Location> getLocationSectionMap(final String path) {
final CommentedConfigurationNode node = getSection(path);
final Map<String, Location> result = new HashMap<>();
for (final Map.Entry<String, CommentedConfigurationNode> entry : ConfigurateUtil.getMap(node).entrySet()) {
final CommentedConfigurationNode jailNode = entry.getValue();
try {
result.put(entry.getKey().toLowerCase(Locale.ENGLISH), jailNode.get(Location.class));
} catch (SerializationException e) {
LOGGER.log(Level.WARNING, "Error serializing key " + entry.getKey(), e);
}
}
return result;
}
public void setProperty(final String path, final List<?> list) {
setInternal(path, list);
}
public <T> List<T> getList(final String path, Class<T> type) {
final CommentedConfigurationNode node = getInternal(path);
if (node == null) {
return new ArrayList<>();
}
try {
final List<T> list = node.getList(type);
if (list == null) {
return new ArrayList<>();
}
return list;
} catch (SerializationException e) {
LOGGER.log(Level.SEVERE, e.getMessage(), e);
return new ArrayList<>();
}
}
public boolean isList(String path) {
final CommentedConfigurationNode node = getInternal(path);
return node != null && node.isList();
}
public void setProperty(final String path, final String value) {
setInternal(path, value);
}
public String getString(final String path, final String def) {
final CommentedConfigurationNode node = getInternal(path);
if (node == null) {
return def;
}
return node.getString();
}
public void setProperty(final String path, final boolean value) {
setInternal(path, value);
}
public boolean getBoolean(final String path, final boolean def) {
final CommentedConfigurationNode node = getInternal(path);
if (node == null) {
return def;
}
return node.getBoolean();
}
public boolean isBoolean(final String path) {
final CommentedConfigurationNode node = getInternal(path);
return node != null && node.raw() instanceof Boolean;
}
public void setProperty(final String path, final long value) {
setInternal(path, value);
}
public long getLong(final String path, final long def) {
final CommentedConfigurationNode node = getInternal(path);
if (node == null) {
return def;
}
return node.getLong();
}
public void setProperty(final String path, final int value) {
setInternal(path, value);
}
public int getInt(final String path, final int def) {
final CommentedConfigurationNode node = getInternal(path);
if (node == null) {
return def;
}
return node.getInt();
}
public void setProperty(final String path, final double value) {
setInternal(path, value);
}
public double getDouble(final String path, final double def) {
final CommentedConfigurationNode node = getInternal(path);
if (node == null) {
return def;
}
return node.getDouble();
}
public void setProperty(final String path, final float value) {
setInternal(path, value);
}
public float getFloat(final String path, final float def) {
final CommentedConfigurationNode node = getInternal(path);
if (node == null) {
return def;
}
return node.getFloat();
}
public void setProperty(final String path, final BigDecimal value) {
setInternal(path, value);
}
public BigDecimal getBigDecimal(final String path, final BigDecimal def) {
final CommentedConfigurationNode node = getInternal(path);
if (node == null) {
return def;
}
try {
return node.get(BigDecimal.class);
} catch (SerializationException e) {
return null;
}
}
public void setRaw(final String path, final Object value) {
setInternal(path, value);
}
public Object get(final String path) {
final CommentedConfigurationNode node = getInternal(path);
return node == null ? null : node.raw();
}
public CommentedConfigurationNode getSection(final String path) {
final CommentedConfigurationNode node = configurationNode.node(toSplitRoot(path));
if (node.virtual()) {
return null;
}
return node;
}
public CommentedConfigurationNode newSection() {
return loader.createNode();
}
public Set<String> getKeys() {
return ConfigurateUtil.getKeys(configurationNode);
}
public Map<String, CommentedConfigurationNode> getMap() {
return ConfigurateUtil.getMap(configurationNode);
}
public void removeProperty(String path) {
final CommentedConfigurationNode node = getInternal(path);
if (node != null) {
try {
node.set(null);
} catch (SerializationException e) {
LOGGER.log(Level.SEVERE, e.getMessage(), e);
}
}
}
private void setInternal(final String path, final Object value) {
try {
configurationNode.node(toSplitRoot(path)).set(value);
} catch (SerializationException e) {
LOGGER.log(Level.SEVERE, e.getMessage(), e);
}
}
private CommentedConfigurationNode getInternal(final String path) {
final CommentedConfigurationNode node = configurationNode.node(toSplitRoot(path));
if (node.virtual()) {
return null;
}
return node;
}
public boolean hasProperty(final String path) {
return !configurationNode.node(toSplitRoot(path)).isNull();
}
public Object[] toSplitRoot(String node) {
node = node.startsWith(".") ? node.substring(1) : node;
return node.contains(".") ? node.split("\\.") : new Object[]{node};
}
public synchronized void load() {
if (pendingWrites.get() != 0) {
LOGGER.log(Level.INFO, "Parsing config file {0} has been aborted due to {1} current pending write(s).", new Object[]{configFile, pendingWrites.get()});
return;
}
if (configFile.getParentFile() != null && !configFile.getParentFile().exists()) {
if (!configFile.getParentFile().mkdirs()) {
LOGGER.log(Level.SEVERE, tl("failedToCreateConfig", configFile.toString()));
return;
}
}
if (!configFile.exists()) {
if (legacyFileExists()) {
convertLegacyFile();
} else if (altFileExists()) {
convertAltFile();
} else if (templateName != null) {
try (final InputStream is = resourceClass.getResourceAsStream(templateName)) {
LOGGER.log(Level.INFO, tl("creatingConfigFromTemplate", configFile.toString()));
Files.copy(is, configFile.toPath());
} catch (IOException e) {
LOGGER.log(Level.SEVERE, tl("failedToWriteConfig", configFile.toString()), e);
}
}
}
try {
configurationNode = loader.load();
} catch (final ParsingException e) {
final File broken = new File(configFile.getAbsolutePath() + ".broken." + System.currentTimeMillis());
if (configFile.renameTo(broken)) {
LOGGER.log(Level.SEVERE, "The file " + configFile.toString() + " is broken, it has been renamed to " + broken.toString(), e.getCause());
return;
}
LOGGER.log(Level.SEVERE, "The file " + configFile.toString() + " is broken. A backup file has failed to be created", e.getCause());
} catch (final ConfigurateException e) {
LOGGER.log(Level.SEVERE, e.getMessage(), e);
} finally {
// Something is wrong! We need a node! I hope the backup worked!
if (configurationNode == null) {
configurationNode = loader.createNode();
}
}
}
public boolean legacyFileExists() {
return false;
}
public void convertLegacyFile() {
}
public boolean altFileExists() {
return false;
}
public void convertAltFile() {
}
/**
* Begins a transaction.
* <p>
* A transaction informs Essentials to pause the saving of data. This is should be used when
* bulk operations are being done and data shouldn't be saved until after the transaction has
* been completed.
*/
public void startTransaction() {
transaction.set(true);
}
public void stopTransaction() {
stopTransaction(false);
}
public void stopTransaction(final boolean blocking) {
transaction.set(false);
if (blocking) {
blockingSave();
} else {
save();
}
}
public void setSaveHook(Runnable saveHook) {
this.saveHook = saveHook;
}
public synchronized void save() {
if (!transaction.get()) {
delaySave();
}
}
public synchronized void blockingSave() {
try {
delaySave().get();
} catch (final InterruptedException | ExecutionException e) {
LOGGER.log(Level.SEVERE, e.getMessage(), e);
}
}
private Future<?> delaySave() {
if (saveHook != null) {
saveHook.run();
}
final CommentedConfigurationNode node = configurationNode.copy();
pendingWrites.incrementAndGet();
return EXECUTOR_SERVICE.submit(new ConfigurationSaveTask(loader, node, pendingWrites));
}
}

View File

@ -0,0 +1,74 @@
package com.earth2me.essentials.config;
import com.google.common.base.Charsets;
import com.google.common.io.Files;
import java.io.File;
import java.io.IOException;
import java.util.Locale;
import java.util.UUID;
import java.util.logging.Level;
public class EssentialsUserConfiguration extends EssentialsConfiguration {
private String username;
private final UUID uuid;
public EssentialsUserConfiguration(final String username, final UUID uuid, final File configFile) {
super(configFile);
this.username = username;
this.uuid = uuid;
}
public String getUsername() {
return username;
}
public UUID getUuid() {
return uuid;
}
public void setUsername(final String username) {
this.username = username;
}
@Override
public boolean legacyFileExists() {
return new File(configFile.getParentFile(), username + ".yml").exists();
}
@Override
public void convertLegacyFile() {
final File file = new File(configFile.getParentFile(), username + ".yml");
try {
//noinspection UnstableApiUsage
Files.move(file, new File(configFile.getParentFile(), uuid + ".yml"));
} catch (final IOException ex) {
LOGGER.log(Level.WARNING, "Failed to migrate user: " + username, ex);
}
setProperty("lastAccountName", username);
}
private File getAltFile() {
final UUID fn = UUID.nameUUIDFromBytes(("OfflinePlayer:" + username.toLowerCase(Locale.ENGLISH)).getBytes(Charsets.UTF_8));
return new File(configFile.getParentFile(), fn.toString() + ".yml");
}
@Override
public boolean altFileExists() {
if (username.equals(username.toLowerCase())) {
return false;
}
return getAltFile().exists();
}
@Override
public void convertAltFile() {
try {
//noinspection UnstableApiUsage
Files.move(getAltFile(), new File(configFile.getParentFile(), uuid + ".yml"));
} catch (final IOException ex) {
LOGGER.log(Level.WARNING, "Failed to migrate user: " + username, ex);
}
}
}

View File

@ -0,0 +1,15 @@
package com.earth2me.essentials.config.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Used to indicate to Configurate that the annotated field should be
* treated as null if it is a Collection, Map, or String that is empty.
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DeleteOnEmpty {
}

View File

@ -0,0 +1,28 @@
package com.earth2me.essentials.config.entities;
import org.spongepowered.configurate.objectmapping.ConfigSerializable;
import java.util.regex.Pattern;
@ConfigSerializable
public class CommandCooldown {
private Pattern pattern;
public Pattern pattern() {
return this.pattern;
}
public void pattern(final Pattern value) {
this.pattern = value;
}
private Long value;
public Long value() {
return this.value;
}
public void value(final Long value) {
this.value = value;
}
}

View File

@ -0,0 +1,428 @@
package com.earth2me.essentials.config.holders;
import com.earth2me.essentials.config.annotations.DeleteOnEmpty;
import com.earth2me.essentials.config.entities.CommandCooldown;
import org.bukkit.Location;
import org.bukkit.Material;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.spongepowered.configurate.objectmapping.ConfigSerializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
@ConfigSerializable
public class UserConfigHolder {
private @MonotonicNonNull BigDecimal money;
public BigDecimal money() {
return money;
}
public void money(final BigDecimal value) {
this.money = value;
}
@DeleteOnEmpty
private @MonotonicNonNull Map<String, Location> homes;
public Map<String, Location> homes() {
if (this.homes == null) {
this.homes = new HashMap<>();
}
return this.homes;
}
public void homes(final Map<String, Location> value) {
this.homes = value;
}
private @Nullable String nickname;
public String nickname() {
return nickname;
}
public void nickname(final String value) {
this.nickname = value;
}
@DeleteOnEmpty
private @MonotonicNonNull Set<Material> unlimited;
public Set<Material> unlimited() {
if (this.unlimited == null) {
this.unlimited = new HashSet<>();
}
return this.unlimited;
}
@DeleteOnEmpty
private @MonotonicNonNull Map<String, List<String>> powertools;
public Map<String, List<String>> powertools() {
if (this.powertools == null) {
this.powertools = new HashMap<>();
}
return this.powertools;
}
private @MonotonicNonNull Location lastlocation;
public Location lastLocation() {
return this.lastlocation;
}
public void lastLocation(final Location value) {
if (value == null || value.getWorld() == null) {
return;
}
this.lastlocation = value;
}
private @MonotonicNonNull Location logoutlocation;
public Location logoutLocation() {
return this.logoutlocation;
}
public void logoutLocation(final Location value) {
if (value == null || value.getWorld() == null) {
return;
}
this.logoutlocation = value;
}
private @Nullable String jail;
public String jail() {
return this.jail;
}
public void jail(final String value) {
this.jail = value;
}
@DeleteOnEmpty
private @MonotonicNonNull List<String> mails;
public List<String> mails() {
if (this.mails == null) {
this.mails = new ArrayList<>();
}
return this.mails;
}
public void mails(final List<String> value) {
this.mails = value;
}
private boolean teleportenabled = true;
public boolean teleportEnabled() {
return this.teleportenabled;
}
public void teleportEnabled(final boolean value) {
this.teleportenabled = value;
}
private boolean teleportauto = false;
public boolean teleportAuto() {
return this.teleportauto;
}
public void teleportAuto(final boolean value) {
this.teleportauto = value;
}
@DeleteOnEmpty
private @MonotonicNonNull List<UUID> ignore;
public List<UUID> ignore() {
if (this.ignore == null) {
this.ignore = new ArrayList<>();
}
return this.ignore;
}
public void ignore(final List<UUID> value) {
this.ignore = value;
}
private boolean godmode = false;
public boolean godMode() {
return this.godmode;
}
public void godMode(final boolean value) {
this.godmode = value;
}
private boolean muted = false;
public boolean muted() {
return this.muted;
}
public void muted(final boolean value) {
this.muted = value;
}
private @Nullable String muteReason;
public String muteReason() {
return this.muteReason;
}
public void muteReason(final String value) {
this.muteReason = value;
}
private boolean jailed = false;
public boolean jailed() {
return this.jailed;
}
public void jailed(final boolean value) {
this.jailed = value;
}
private @NonNull String ipAddress = "";
public String ipAddress() {
return this.ipAddress;
}
public void ipAddress(final String value) {
this.ipAddress = value;
}
private boolean afk = false;
public boolean afk() {
return this.afk;
}
public void afk(final boolean value) {
this.afk = value;
}
@DeleteOnEmpty
private @Nullable String geolocation;
public String geolocation() {
return this.geolocation;
}
public void geolocation(final String value) {
this.geolocation = value;
}
private boolean socialspy = false;
public boolean socialSpy() {
return this.socialspy;
}
public void socialSpy(final boolean value) {
this.socialspy = value;
}
private boolean npc = false;
public boolean npc() {
return this.npc;
}
public void npc(final boolean value) {
this.npc = value;
}
private @MonotonicNonNull String lastAccountName;
public String lastAccountName() {
return this.lastAccountName;
}
public void lastAccountName(final String value) {
this.lastAccountName = value;
}
private boolean powertoolsenabled = true;
public boolean powerToolsEnabled() {
return this.powertoolsenabled;
}
public void powerToolsEnabled(final boolean value) {
this.powertoolsenabled = value;
}
private boolean acceptingPay = true;
public boolean acceptingPay() {
return this.acceptingPay;
}
public void acceptingPay(final boolean value) {
this.acceptingPay = value;
}
private @Nullable Boolean confirmPay;
public Boolean confirmPay() {
return this.confirmPay;
}
public void confirmPay(final Boolean value) {
this.confirmPay = value;
}
private @Nullable Boolean confirmClear;
public Boolean confirmClear() {
return this.confirmClear;
}
public void confirmClear(final Boolean value) {
this.confirmClear = value;
}
private @Nullable Boolean lastMessageReplyRecipient;
public Boolean lastMessageReplyRecipient() {
return this.lastMessageReplyRecipient;
}
public void lastMessageReplyRecipient(final Boolean value) {
this.lastMessageReplyRecipient = value;
}
private boolean baltopExempt = false;
public boolean baltopExempt() {
return this.baltopExempt;
}
public void baltopExempt(final boolean value) {
this.baltopExempt = value;
}
private @NonNull Timestamps timestamps = new Timestamps();
public Timestamps timestamps() {
return this.timestamps;
}
@ConfigSerializable
public static class Timestamps {
private long lastteleport = 0L;
public long lastTeleport() {
return this.lastteleport;
}
public void lastTeleport(final long value) {
this.lastteleport = value;
}
private long lastheal = 0L;
public long lastHeal() {
return this.lastheal;
}
public void lastHeal(final long value) {
this.lastheal = value;
}
private long mute = 0L;
public long mute() {
return this.mute;
}
public void mute(final long value) {
this.mute = value;
}
private long jail = 0L;
public long jail() {
return this.jail;
}
public void jail(final long value) {
this.jail = value;
}
private long onlinejail = 0L;
public long onlineJail() {
return this.onlinejail;
}
public void onlineJail(final long value) {
this.onlinejail = value;
}
private long logout = 0L;
public long logout() {
return this.logout;
}
public void logout(final long value) {
this.logout = value;
}
private long login = 0L;
public long login() {
return this.login;
}
public void login(final long value) {
this.login = value;
}
@DeleteOnEmpty
private @MonotonicNonNull Map<String, Long> kits;
public Map<String, Long> kits() {
if (this.kits == null) {
this.kits = new HashMap<>();
}
return this.kits;
}
public void kits(final Map<String, Long> value) {
this.kits = value;
}
@DeleteOnEmpty
private @MonotonicNonNull List<CommandCooldown> commandCooldowns;
public List<CommandCooldown> commandCooldowns() {
if (this.commandCooldowns == null) {
this.commandCooldowns = new ArrayList<>();
}
return this.commandCooldowns;
}
public void commandCooldowns(final List<CommandCooldown> value) {
this.commandCooldowns = value;
}
}
}

View File

@ -0,0 +1,28 @@
package com.earth2me.essentials.config.processors;
import org.spongepowered.configurate.ConfigurationNode;
import org.spongepowered.configurate.objectmapping.meta.Processor;
import org.spongepowered.configurate.serialize.SerializationException;
import java.util.Collection;
import java.util.Map;
public class DeleteOnEmptyProcessor implements Processor<Object> {
@Override
public void process(final Object value, final ConfigurationNode destination) {
if (value == null) {
return;
}
try {
if (value instanceof Map && ((Map<?, ?>) value).isEmpty()) {
destination.set(null);
} else if (value instanceof Collection && ((Collection<?>) value).isEmpty()) {
destination.set(null);
} else if (value instanceof CharSequence && ((CharSequence) value).length() == 0) {
destination.set(null);
}
} catch (SerializationException e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,61 @@
package com.earth2me.essentials.config.serializers;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.spongepowered.configurate.ConfigurationOptions;
import org.spongepowered.configurate.serialize.ScalarSerializer;
import org.spongepowered.configurate.serialize.SerializationException;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.MathContext;
import java.util.function.Predicate;
/**
* A Configurate type serializer for {@link BigDecimal}s.
*/
public class BigDecimalTypeSerializer extends ScalarSerializer<BigDecimal> {
public BigDecimalTypeSerializer() {
super(BigDecimal.class);
}
@Override
public BigDecimal deserialize(Type type, Object obj) throws SerializationException {
if (obj instanceof Double) {
return BigDecimal.valueOf((double) obj);
}
if (obj instanceof Integer) {
return BigDecimal.valueOf((int) obj);
}
if (obj instanceof Long) {
return BigDecimal.valueOf((long) obj);
}
if (obj instanceof BigInteger) {
return new BigDecimal((BigInteger) obj);
}
if (obj instanceof String) {
try {
return new BigDecimal((String) obj, MathContext.DECIMAL128);
} catch (final NumberFormatException | ArithmeticException e) {
throw new SerializationException(type, "Failed to coerce input value of type " + obj.getClass() + " to BigDecimal", e);
}
}
throw new SerializationException(type, "Failed to coerce input value of type " + obj.getClass() + " to BigDecimal");
}
@Override
protected Object serialize(BigDecimal item, Predicate<Class<?>> typeSupported) {
return item.toString();
}
@Override
public @Nullable BigDecimal emptyValue(Type specificType, ConfigurationOptions options) {
return BigDecimal.ZERO;
}
}

View File

@ -0,0 +1,66 @@
package com.earth2me.essentials.config.serializers;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.spongepowered.configurate.ConfigurationNode;
import org.spongepowered.configurate.serialize.SerializationException;
import org.spongepowered.configurate.serialize.TypeSerializer;
import java.lang.reflect.Type;
import java.util.UUID;
/**
* A Configurate type serializer for {@link Location}s.
*
* Locations with a null or empty world will be considered invalid.
*/
public class LocationTypeSerializer implements TypeSerializer<Location> {
@Override
public Location deserialize(Type type, ConfigurationNode node) throws SerializationException {
final String worldValue = node.node("world").getString();
if (worldValue == null || worldValue.isEmpty()) {
throw new SerializationException("No world value present!");
}
World world = null;
try {
final UUID worldId = UUID.fromString(worldValue);
world = Bukkit.getWorld(worldId);
} catch (IllegalArgumentException ignored) {
}
if (world == null) {
world = Bukkit.getWorld(worldValue);
}
if (world == null) {
throw new SerializationException("No world value present!");
}
return new Location(
world,
node.node("x").getDouble(),
node.node("y").getDouble(),
node.node("z").getDouble(),
node.node("yaw").getFloat(),
node.node("pitch").getFloat());
}
@Override
public void serialize(Type type, @Nullable Location value, ConfigurationNode node) throws SerializationException {
if (value == null || value.getWorld() == null) {
node.raw(null);
return;
}
node.node("world").set(String.class, value.getWorld().getName());
node.node("x").set(Double.class, value.getX());
node.node("y").set(Double.class, value.getY());
node.node("z").set(Double.class, value.getZ());
node.node("yaw").set(Float.class, value.getYaw());
node.node("pitch").set(Float.class, value.getPitch());
}
}

View File

@ -0,0 +1,27 @@
package com.earth2me.essentials.config.serializers;
import org.bukkit.Material;
import org.spongepowered.configurate.serialize.ScalarSerializer;
import org.spongepowered.configurate.serialize.SerializationException;
import java.lang.reflect.Type;
import java.util.function.Predicate;
public class MaterialTypeSerializer extends ScalarSerializer<Material> {
public MaterialTypeSerializer() {
super(Material.class);
}
@Override
public Material deserialize(Type type, Object obj) throws SerializationException {
if (obj instanceof String) {
return Material.matchMaterial((String) obj);
}
return null;
}
@Override
protected Object serialize(Material item, Predicate<Class<?>> typeSupported) {
return item.name();
}
}

View File

@ -1,9 +1,9 @@
package com.earth2me.essentials.economy.vault;
import com.earth2me.essentials.Essentials;
import com.earth2me.essentials.EssentialsUserConf;
import com.earth2me.essentials.api.NoLoanPermittedException;
import com.earth2me.essentials.api.UserDoesNotExistException;
import com.earth2me.essentials.config.EssentialsUserConfiguration;
import com.earth2me.essentials.utils.NumberUtil;
import com.google.common.base.Charsets;
import net.ess3.api.MaxMoneyException;
@ -303,12 +303,12 @@ public class VaultEconomyProvider implements Economy {
LOGGER.log(Level.SEVERE, MessageFormat.format(WARN_NPC_RECREATE_1, player.getName(), player.getUniqueId().toString()), new RuntimeException());
LOGGER.log(Level.SEVERE, WARN_NPC_RECREATE_2);
}
final EssentialsUserConf npcConfig = new EssentialsUserConf(player.getName(), player.getUniqueId(), npcFile);
final EssentialsUserConfiguration npcConfig = new EssentialsUserConfiguration(player.getName(), player.getUniqueId(), npcFile);
npcConfig.load();
npcConfig.setProperty("npc", true);
npcConfig.setProperty("lastAccountName", player.getName());
npcConfig.setProperty("money", ess.getSettings().getStartingBalance());
npcConfig.forceSave();
npcConfig.blockingSave();
ess.getUserMap().trackUUID(player.getUniqueId(), player.getName(), false);
return true;
}

View File

@ -1,10 +1,10 @@
package com.earth2me.essentials.items;
import com.earth2me.essentials.Essentials;
import com.earth2me.essentials.EssentialsConf;
import com.earth2me.essentials.IConf;
import com.earth2me.essentials.config.ConfigurateUtil;
import com.earth2me.essentials.config.EssentialsConfiguration;
import net.ess3.api.IItemDb;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.inventory.ItemStack;
import java.io.File;
@ -15,14 +15,13 @@ import java.util.List;
import java.util.Map;
public class CustomItemResolver implements IItemDb.ItemResolver, IConf {
private final EssentialsConf config;
private final EssentialsConfiguration config;
private final Essentials ess;
private final HashMap<String, String> map = new HashMap<>();
public CustomItemResolver(final Essentials ess) {
config = new EssentialsConf(new File(ess.getDataFolder(), "custom_items.yml"));
config = new EssentialsConfiguration(new File(ess.getDataFolder(), "custom_items.yml"), "/custom_items.yml");
this.ess = ess;
config.setTemplateName("/custom_items.yml");
}
@Override
@ -57,18 +56,20 @@ public class CustomItemResolver implements IItemDb.ItemResolver, IConf {
map.clear();
config.load();
final ConfigurationSection section = config.getConfigurationSection("aliases");
if (section == null || section.getKeys(false).isEmpty()) {
final Map<String, Object> section = ConfigurateUtil.getRawMap(config.getSection("aliases"));
if (section.isEmpty()) {
ess.getLogger().warning("No aliases found in custom_items.yml.");
return;
}
for (final String alias : section.getKeys(false)) {
if (!section.isString(alias)) continue;
final String target = section.getString(alias);
for (final Map.Entry<String, Object> alias : section.entrySet()) {
if (!(alias.getValue() instanceof String)) {
continue;
}
final String target = (String) alias.getValue();
if (target != null && !section.contains(target) && existsInItemDb(target)) {
map.put(alias, target);
if (existsInItemDb(target)) {
map.put(alias.getKey(), target);
}
}
}
@ -89,7 +90,7 @@ public class CustomItemResolver implements IItemDb.ItemResolver, IConf {
}
private void save() {
config.setProperty("aliases", map);
config.setRaw("aliases", map);
config.save();
}

View File

@ -1,39 +0,0 @@
package com.earth2me.essentials.settings;
import com.earth2me.essentials.storage.MapValueType;
import com.earth2me.essentials.storage.StorageObject;
import org.bukkit.Location;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
public class Jails implements StorageObject {
@MapValueType(Location.class)
private Map<String, Location> jails = new HashMap<>();
public Map<String, Location> getJails() {
return jails;
}
public void setJails(final Map<String, Location> jails) {
this.jails = jails;
}
@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
final Jails jails1 = (Jails) o;
return Objects.equals(jails, jails1.jails);
}
@Override
public int hashCode() {
return Objects.hash(jails);
}
}

View File

@ -1,39 +0,0 @@
package com.earth2me.essentials.settings;
import com.earth2me.essentials.storage.MapValueType;
import com.earth2me.essentials.storage.StorageObject;
import org.bukkit.Location;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
public class Spawns implements StorageObject {
@MapValueType(Location.class)
private Map<String, Location> spawns = new HashMap<>();
public Map<String, Location> getSpawns() {
return spawns;
}
public void setSpawns(final Map<String, Location> spawns) {
this.spawns = spawns;
}
@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
final Spawns spawns1 = (Spawns) o;
return Objects.equals(spawns, spawns1.spawns);
}
@Override
public int hashCode() {
return Objects.hash(spawns);
}
}

View File

@ -1,56 +0,0 @@
package com.earth2me.essentials.storage;
import net.ess3.api.IEssentials;
import org.bukkit.Bukkit;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.logging.Level;
public abstract class AbstractDelayedYamlFileReader<T extends StorageObject> implements Runnable {
protected final transient IEssentials plugin;
private final transient File file;
private final transient Class<T> clazz;
public AbstractDelayedYamlFileReader(final IEssentials ess, final File file, final Class<T> clazz) {
this.file = file;
this.clazz = clazz;
this.plugin = ess;
ess.runTaskAsynchronously(this);
}
public abstract void onStart();
@Override
public void run() {
onStart();
try {
final FileReader reader = new FileReader(file);
try {
final T object = new YamlStorageReader(reader, plugin).load(clazz);
onSuccess(object);
} finally {
try {
reader.close();
} catch (final IOException ex) {
Bukkit.getLogger().log(Level.SEVERE, "File can't be closed: " + file.toString(), ex);
}
}
} catch (final FileNotFoundException ex) {
onException();
if (plugin.getSettings() == null || plugin.getSettings().isDebug()) {
Bukkit.getLogger().log(Level.INFO, "File not found: " + file.toString());
}
} catch (final ObjectLoadException ex) {
onException();
Bukkit.getLogger().log(Level.SEVERE, "File broken: " + file.toString(), ex.getCause());
}
}
public abstract void onSuccess(T object);
public abstract void onException();
}

View File

@ -1,44 +0,0 @@
package com.earth2me.essentials.storage;
import net.ess3.api.IEssentials;
import org.bukkit.Bukkit;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.logging.Level;
public abstract class AbstractDelayedYamlFileWriter implements Runnable {
private final transient File file;
public AbstractDelayedYamlFileWriter(final IEssentials ess, final File file) {
this.file = file;
ess.runTaskAsynchronously(this);
}
public abstract StorageObject getObject();
@Override
public void run() {
PrintWriter pw = null;
try {
final StorageObject object = getObject();
final File folder = file.getParentFile();
if (!folder.exists()) {
folder.mkdirs();
}
pw = new PrintWriter(file);
new YamlStorageWriter(pw).save(object);
} catch (final FileNotFoundException ex) {
Bukkit.getLogger().log(Level.SEVERE, file.toString(), ex);
} finally {
onFinish();
if (pw != null) {
pw.close();
}
}
}
public abstract void onFinish();
}

View File

@ -1,128 +0,0 @@
package com.earth2me.essentials.storage;
import com.earth2me.essentials.IConf;
import net.ess3.api.IEssentials;
import net.ess3.api.IReload;
import org.bukkit.Bukkit;
import java.io.File;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.logging.Level;
public abstract class AsyncStorageObjectHolder<T extends StorageObject> implements IConf, IStorageObjectHolder<T>, IReload {
protected final transient IEssentials ess;
private final transient ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
private final transient Class<T> clazz;
private transient T data;
public AsyncStorageObjectHolder(final IEssentials ess, final Class<T> clazz) {
this.ess = ess;
this.clazz = clazz;
try {
this.data = clazz.newInstance();
} catch (final IllegalAccessException | InstantiationException ex) {
Bukkit.getLogger().log(Level.SEVERE, ex.getMessage(), ex);
}
}
@Override
public T getData() {
return data;
}
@Override
public void acquireReadLock() {
rwl.readLock().lock();
}
@Override
public void acquireWriteLock() {
while (rwl.getReadHoldCount() > 0) {
rwl.readLock().unlock();
}
rwl.writeLock().lock();
rwl.readLock().lock();
}
@Override
public void close() {
unlock();
}
@Override
public void unlock() {
if (rwl.isWriteLockedByCurrentThread()) {
rwl.writeLock().unlock();
new StorageObjectDataWriter();
}
while (rwl.getReadHoldCount() > 0) {
rwl.readLock().unlock();
}
}
@Override
public void reloadConfig() {
new StorageObjectDataReader();
}
@Override
public void onReload() {
new StorageObjectDataReader();
}
public abstract void finishRead();
public abstract void finishWrite();
public abstract File getStorageFile();
private class StorageObjectDataWriter extends AbstractDelayedYamlFileWriter {
StorageObjectDataWriter() {
super(ess, getStorageFile());
}
@Override
public StorageObject getObject() {
acquireReadLock();
return getData();
}
@Override
public void onFinish() {
unlock();
finishWrite();
}
}
private class StorageObjectDataReader extends AbstractDelayedYamlFileReader<T> {
StorageObjectDataReader() {
super(ess, getStorageFile(), clazz);
}
@Override
public void onStart() {
rwl.writeLock().lock();
}
@Override
public void onSuccess(final T object) {
if (object != null) {
data = object;
}
rwl.writeLock().unlock();
finishRead();
}
@Override
public void onException() {
if (data == null) {
try {
data = clazz.newInstance();
} catch (final IllegalAccessException | InstantiationException ex) {
Bukkit.getLogger().log(Level.SEVERE, ex.getMessage(), ex);
}
}
rwl.writeLock().unlock();
}
}
}

View File

@ -1,214 +0,0 @@
package com.earth2me.essentials.storage;
import com.earth2me.essentials.Enchantments;
import com.earth2me.essentials.utils.NumberUtil;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.ItemStack;
import org.bukkit.material.MaterialData;
import org.bukkit.plugin.Plugin;
import org.yaml.snakeyaml.constructor.BaseConstructor;
import org.yaml.snakeyaml.constructor.CustomClassLoaderConstructor;
import org.yaml.snakeyaml.introspector.PropertyUtils;
import org.yaml.snakeyaml.nodes.MappingNode;
import org.yaml.snakeyaml.nodes.Node;
import org.yaml.snakeyaml.nodes.NodeId;
import org.yaml.snakeyaml.nodes.NodeTuple;
import org.yaml.snakeyaml.nodes.ScalarNode;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class BukkitConstructor extends CustomClassLoaderConstructor {
private Method constructScalarMethod = null;
public BukkitConstructor(final Class<?> clazz, final Plugin plugin) {
super(clazz, plugin.getClass().getClassLoader());
yamlClassConstructors.put(NodeId.scalar, new ConstructBukkitScalar());
yamlClassConstructors.put(NodeId.mapping, new ConstructBukkitMapping());
final PropertyUtils propertyUtils = getPropertyUtils();
propertyUtils.setSkipMissingProperties(true);
setPropertyUtils(propertyUtils);
}
protected String constructScalarRefl(final ScalarNode scalarNode) {
try {
if (constructScalarMethod == null) {
constructScalarMethod = BaseConstructor.class.getDeclaredMethod("constructScalar", ScalarNode.class);
}
return (String) constructScalarMethod.invoke(this, scalarNode);
} catch (final NoSuchMethodException
| SecurityException
| IllegalAccessException
| IllegalArgumentException
| InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
private class ConstructBukkitScalar extends ConstructScalar {
@Override
public Object construct(final Node node) {
if (node.getType().equals(Material.class)) {
final String val = constructScalarRefl((ScalarNode) node);
return Material.matchMaterial(val);
}
if (node.getType().equals(MaterialData.class)) {
final String val = constructScalarRefl((ScalarNode) node);
if (val.isEmpty()) {
return null;
}
final String[] split = val.split("[:+',;.]", 2);
if (split.length == 0) {
return null;
}
final Material mat = Material.matchMaterial(split[0]);
if (mat == null) {
return null;
}
byte data = 0;
if (split.length == 2 && NumberUtil.isInt(split[1])) {
data = Byte.parseByte(split[1]);
}
return new MaterialData(mat, data);
}
if (node.getType().equals(ItemStack.class)) {
final String val = constructScalarRefl((ScalarNode) node);
if (val.isEmpty()) {
return null;
}
final String[] split1 = val.split("\\W");
if (split1.length == 0) {
return null;
}
final String[] split2 = split1[0].split("[:+',;.]", 2);
if (split2.length == 0) {
return null;
}
final Material mat = Material.matchMaterial(split2[0]);
if (mat == null) {
return null;
}
short data = 0;
if (split2.length == 2 && NumberUtil.isInt(split2[1])) {
data = Short.parseShort(split2[1]);
}
int size = mat.getMaxStackSize();
if (split1.length > 1 && NumberUtil.isInt(split1[1])) {
size = Integer.parseInt(split1[1]);
}
final ItemStack stack = new ItemStack(mat, size, data);
if (split1.length > 2) {
for (int i = 2; i < split1.length; i++) {
final String[] split3 = split1[0].split("[:+',;.]", 2);
if (split3.length < 1) {
continue;
}
final Enchantment enchantment = Enchantments.getByName(split3[0]);
if (enchantment == null) {
continue;
}
int level = enchantment.getStartLevel();
if (split3.length == 2 && NumberUtil.isInt(split3[1])) {
level = Integer.parseInt(split3[1]);
}
if (level < enchantment.getStartLevel()) {
level = enchantment.getStartLevel();
}
if (level > enchantment.getMaxLevel()) {
level = enchantment.getMaxLevel();
}
stack.addUnsafeEnchantment(enchantment, level);
}
}
return stack;
}
if (node.getType().equals(EnchantmentLevel.class)) {
final String val = constructScalarRefl((ScalarNode) node);
if (val.isEmpty()) {
return null;
}
final String[] split = val.split("[:+',;.]", 2);
if (split.length == 0) {
return null;
}
final Enchantment enchant = Enchantments.getByName(split[0]);
if (enchant == null) {
return null;
}
int level = enchant.getStartLevel();
if (split.length == 2 && NumberUtil.isInt(split[1])) {
level = Integer.parseInt(split[1]);
}
if (level < enchant.getStartLevel()) {
level = enchant.getStartLevel();
}
if (level > enchant.getMaxLevel()) {
level = enchant.getMaxLevel();
}
return new EnchantmentLevel(enchant, level);
}
return super.construct(node);
}
}
private class ConstructBukkitMapping extends ConstructMapping {
@Override
public Object construct(final Node node) {
if (node.getType().equals(Location.class)) {
//TODO: NPE checks
final MappingNode mnode = (MappingNode) node;
String worldName = "";
double x = 0, y = 0, z = 0;
float yaw = 0, pitch = 0;
if (mnode.getValue().size() < 4) {
return null;
}
for (final NodeTuple nodeTuple : mnode.getValue()) {
final String key = constructScalarRefl((ScalarNode) nodeTuple.getKeyNode());
final ScalarNode snode = (ScalarNode) nodeTuple.getValueNode();
if (key.equalsIgnoreCase("world")) {
worldName = constructScalarRefl(snode);
}
if (key.equalsIgnoreCase("x")) {
x = Double.parseDouble(constructScalarRefl(snode));
}
if (key.equalsIgnoreCase("y")) {
y = Double.parseDouble(constructScalarRefl(snode));
}
if (key.equalsIgnoreCase("z")) {
z = Double.parseDouble(constructScalarRefl(snode));
}
if (key.equalsIgnoreCase("yaw")) {
yaw = Float.parseFloat(constructScalarRefl(snode));
}
if (key.equalsIgnoreCase("pitch")) {
pitch = Float.parseFloat(constructScalarRefl(snode));
}
}
if (worldName == null || worldName.isEmpty()) {
return null;
}
final World world = Bukkit.getWorld(worldName);
if (world == null) {
return null;
}
return new Location(world, x, y, z, yaw, pitch);
}
return super.construct(node);
}
}
}

View File

@ -1,14 +0,0 @@
package com.earth2me.essentials.storage;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface Comment {
String[] value() default "";
}

View File

@ -1,66 +0,0 @@
package com.earth2me.essentials.storage;
import org.bukkit.enchantments.Enchantment;
import java.util.Map.Entry;
public class EnchantmentLevel implements Entry<Enchantment, Integer> {
private Enchantment enchantment;
private int level;
public EnchantmentLevel(final Enchantment enchantment, final int level) {
this.enchantment = enchantment;
this.level = level;
}
public Enchantment getEnchantment() {
return enchantment;
}
public void setEnchantment(final Enchantment enchantment) {
this.enchantment = enchantment;
}
public int getLevel() {
return level;
}
public void setLevel(final int level) {
this.level = level;
}
@Override
public Enchantment getKey() {
return enchantment;
}
@Override
public Integer getValue() {
return level;
}
@Override
public Integer setValue(final Integer v) {
final int t = level;
level = v;
return t;
}
@Override
public int hashCode() {
return enchantment.hashCode() ^ level;
}
@Override
public boolean equals(final Object obj) {
if (obj instanceof Entry) {
final Entry entry = (Entry) obj;
if (entry.getKey() instanceof Enchantment && entry.getValue() instanceof Integer) {
final Enchantment enchant = (Enchantment) entry.getKey();
final Integer lvl = (Integer) entry.getValue();
return this.enchantment.equals(enchant) && this.level == lvl;
}
}
return false;
}
}

View File

@ -1,13 +0,0 @@
package com.earth2me.essentials.storage;
public interface IStorageObjectHolder<T extends StorageObject> {
T getData();
void acquireReadLock();
void acquireWriteLock();
void close();
void unlock();
}

View File

@ -1,5 +0,0 @@
package com.earth2me.essentials.storage;
public interface IStorageReader {
<T extends StorageObject> T load(final Class<? extends T> clazz) throws ObjectLoadException;
}

View File

@ -1,5 +0,0 @@
package com.earth2me.essentials.storage;
public interface IStorageWriter {
void save(final StorageObject object);
}

View File

@ -1,12 +0,0 @@
package com.earth2me.essentials.storage;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ListType {
Class value() default String.class;
}

View File

@ -1,12 +0,0 @@
package com.earth2me.essentials.storage;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MapKeyType {
Class value() default String.class;
}

View File

@ -1,12 +0,0 @@
package com.earth2me.essentials.storage;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MapValueType {
Class value() default String.class;
}

View File

@ -1,7 +0,0 @@
package com.earth2me.essentials.storage;
public class ObjectLoadException extends Exception {
public ObjectLoadException(final Throwable thrwbl) {
super(thrwbl);
}
}

View File

@ -1,4 +0,0 @@
package com.earth2me.essentials.storage;
public interface StorageObject {
}

View File

@ -1,97 +0,0 @@
package com.earth2me.essentials.storage;
import org.bukkit.plugin.Plugin;
import org.yaml.snakeyaml.TypeDescription;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.Constructor;
import java.io.Reader;
import java.lang.reflect.Field;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.locks.ReentrantLock;
public class YamlStorageReader implements IStorageReader {
private transient static final Map<Class, Yaml> PREPARED_YAMLS = Collections.synchronizedMap(new HashMap<>());
private transient static final Map<Class, ReentrantLock> LOCKS = new HashMap<>();
private transient final Reader reader;
private transient final Plugin plugin;
public YamlStorageReader(final Reader reader, final Plugin plugin) {
this.reader = reader;
this.plugin = plugin;
}
@Override
public <T extends StorageObject> T load(final Class<? extends T> clazz) throws ObjectLoadException {
Yaml yaml = PREPARED_YAMLS.get(clazz);
if (yaml == null) {
yaml = new Yaml(prepareConstructor(clazz));
PREPARED_YAMLS.put(clazz, yaml);
}
ReentrantLock lock;
synchronized (LOCKS) {
lock = LOCKS.get(clazz);
if (lock == null) {
lock = new ReentrantLock();
}
}
lock.lock();
try {
T object = yaml.load(reader);
if (object == null) {
object = clazz.newInstance();
}
return object;
} catch (final IllegalAccessException | InstantiationException ex) {
throw new ObjectLoadException(ex);
} finally {
lock.unlock();
}
}
private Constructor prepareConstructor(final Class<?> clazz) {
final Constructor constructor = new BukkitConstructor(clazz, plugin);
final Set<Class> classes = new HashSet<>();
prepareConstructor(constructor, classes, clazz);
return constructor;
}
private void prepareConstructor(final Constructor constructor, final Set<Class> classes, final Class clazz) {
classes.add(clazz);
final TypeDescription description = new TypeDescription(clazz);
for (final Field field : clazz.getDeclaredFields()) {
prepareList(field, description, classes, constructor);
prepareMap(field, description, classes, constructor);
if (StorageObject.class.isAssignableFrom(field.getType()) && !classes.contains(field.getType())) {
prepareConstructor(constructor, classes, field.getType());
}
}
constructor.addTypeDescription(description);
}
private void prepareList(final Field field, final TypeDescription description, final Set<Class> classes, final Constructor constructor) {
final ListType listType = field.getAnnotation(ListType.class);
if (listType != null) {
description.putListPropertyType(field.getName(), listType.value());
if (StorageObject.class.isAssignableFrom(listType.value()) && !classes.contains(listType.value())) {
prepareConstructor(constructor, classes, listType.value());
}
}
}
private void prepareMap(final Field field, final TypeDescription description, final Set<Class> classes, final Constructor constructor) {
final MapValueType mapType = field.getAnnotation(MapValueType.class);
if (mapType != null) {
final MapKeyType mapKeyType = field.getAnnotation(MapKeyType.class);
description.putMapPropertyType(field.getName(), mapKeyType == null ? String.class : mapKeyType.value(), mapType.value());
if (StorageObject.class.isAssignableFrom(mapType.value()) && !classes.contains(mapType.value())) {
prepareConstructor(constructor, classes, mapType.value());
}
}
}
}

View File

@ -1,254 +0,0 @@
package com.earth2me.essentials.storage;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.ItemStack;
import org.bukkit.material.MaterialData;
import org.yaml.snakeyaml.Yaml;
import java.io.PrintWriter;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Collection;
import java.util.Collections;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern;
public class YamlStorageWriter implements IStorageWriter {
private transient static final Pattern NON_WORD_PATTERN = Pattern.compile("\\W");
private transient static final Yaml YAML = new Yaml();
private transient final PrintWriter writer;
public YamlStorageWriter(final PrintWriter writer) {
this.writer = writer;
}
@Override
public void save(final StorageObject object) {
try {
writeToFile(object, 0, object.getClass());
} catch (final IllegalArgumentException | IllegalAccessException ex) {
Logger.getLogger(YamlStorageWriter.class.getName()).log(Level.SEVERE, null, ex);
}
}
private void writeToFile(final Object object, final int depth, final Class clazz) throws IllegalAccessException {
for (final Field field : clazz.getDeclaredFields()) {
final int modifier = field.getModifiers();
if (Modifier.isPrivate(modifier) && !Modifier.isTransient(modifier) && !Modifier.isStatic(modifier)) {
field.setAccessible(true);
final Object data = field.get(object);
if (writeKey(field, depth, data)) {
continue;
}
if (data instanceof StorageObject) {
writer.println();
writeToFile(data, depth + 1, data.getClass());
} else if (data instanceof Map) {
writeMap((Map<Object, Object>) data, depth + 1);
} else if (data instanceof Collection) {
writeCollection((Collection<Object>) data, depth + 1);
} else if (data instanceof Location) {
writeLocation((Location) data, depth + 1);
} else {
writeScalar(data);
writer.println();
}
}
}
}
private boolean writeKey(final Field field, final int depth, final Object data) {
final boolean commentPresent = writeComment(field, depth);
if (data == null && !commentPresent) {
return true;
}
writeIndention(depth);
if (data == null && commentPresent) {
writer.print('#');
}
final String name = field.getName();
writer.print(name);
writer.print(": ");
if (data == null && commentPresent) {
writer.println();
writer.println();
return true;
}
return false;
}
private boolean writeComment(final Field field, final int depth) {
final boolean commentPresent = field.isAnnotationPresent(Comment.class);
if (commentPresent) {
final Comment comments = field.getAnnotation(Comment.class);
for (final String comment : comments.value()) {
final String trimmed = comment.trim();
if (trimmed.isEmpty()) {
continue;
}
writeIndention(depth);
writer.print("# ");
writer.print(trimmed);
writer.println();
}
}
return commentPresent;
}
private void writeCollection(final Collection<Object> data, final int depth) throws IllegalAccessException {
writer.println();
if (data.isEmpty()) {
writer.println();
}
for (final Object entry : data) {
if (entry != null) {
writeIndention(depth);
writer.print("- ");
if (entry instanceof StorageObject) {
writer.println();
writeToFile(entry, depth + 1, entry.getClass());
} else if (entry instanceof Location) {
writeLocation((Location) entry, depth + 1);
} else {
writeScalar(entry);
}
}
}
writer.println();
}
private void writeMap(final Map<Object, Object> data, final int depth) throws IllegalArgumentException, IllegalAccessException {
writer.println();
if (data.isEmpty()) {
writer.println();
}
for (final Entry<Object, Object> entry : data.entrySet()) {
final Object value = entry.getValue();
if (value != null) {
writeIndention(depth);
writeKey(entry.getKey());
writer.print(": ");
if (value instanceof StorageObject) {
writer.println();
writeToFile(value, depth + 1, value.getClass());
} else if (value instanceof Collection) {
writeCollection((Collection<Object>) value, depth + 1);
} else if (value instanceof Location) {
writeLocation((Location) value, depth + 1);
} else {
writeScalar(value);
writer.println();
}
}
}
}
private void writeIndention(final int depth) {
for (int i = 0; i < depth; i++) {
writer.print(" ");
}
}
private void writeScalar(final Object data) {
if (data instanceof String || data instanceof Boolean || data instanceof Number) {
synchronized (YAML) {
YAML.dumpAll(Collections.singletonList(data).iterator(), writer);
}
} else if (data instanceof Material) {
writeMaterial(data);
writer.println();
} else if (data instanceof MaterialData) {
writeMaterialData(data);
writer.println();
} else if (data instanceof ItemStack) {
writeItemStack(data);
writer.println();
} else if (data instanceof EnchantmentLevel) {
writeEnchantmentLevel(data);
writer.println();
} else {
throw new UnsupportedOperationException();
}
}
private void writeKey(final Object data) {
if (data instanceof String || data instanceof Boolean || data instanceof Number) {
final String output = data.toString();
if (NON_WORD_PATTERN.matcher(output).find()) {
writer.print('"');
writer.print(output.replace("\"", "\\\""));
writer.print('"');
} else {
writer.print(output);
}
} else if (data instanceof Material) {
writeMaterial(data);
} else if (data instanceof MaterialData) {
writeMaterialData(data);
} else if (data instanceof EnchantmentLevel) {
writeEnchantmentLevel(data);
} else {
throw new UnsupportedOperationException();
}
}
private void writeMaterial(final Object data) {
writer.print(data.toString().toLowerCase(Locale.ENGLISH));
}
private void writeMaterialData(final Object data) {
final MaterialData matData = (MaterialData) data;
writeMaterial(matData.getItemType());
if (matData.getData() > 0) {
writer.print(':');
writer.print(matData.getData());
}
}
private void writeItemStack(final Object data) {
final ItemStack itemStack = (ItemStack) data;
writeMaterialData(itemStack.getData());
writer.print(' ');
writer.print(itemStack.getAmount());
for (final Entry<Enchantment, Integer> entry : itemStack.getEnchantments().entrySet()) {
writer.print(' ');
writeEnchantmentLevel(entry);
}
}
private void writeEnchantmentLevel(final Object data) {
final Entry<Enchantment, Integer> enchLevel = (Entry<Enchantment, Integer>) data;
writer.print(enchLevel.getKey().getName().toLowerCase(Locale.ENGLISH));
writer.print(':');
writer.print(enchLevel.getValue());
}
private void writeLocation(final Location entry, final int depth) {
writer.println();
writeIndention(depth);
writer.print("world: ");
writeScalar(entry.getWorld().getName());
writeIndention(depth);
writer.print("x: ");
writeScalar(entry.getX());
writeIndention(depth);
writer.print("y: ");
writeScalar(entry.getY());
writeIndention(depth);
writer.print("z: ");
writeScalar(entry.getZ());
writeIndention(depth);
writer.print("yaw: ");
writeScalar(entry.getYaw());
writeIndention(depth);
writer.print("pitch: ");
writeScalar(entry.getPitch());
}
}

View File

@ -1,12 +0,0 @@
package net.ess3.api;
/**
* Represents a storage object that is reloadable.
*
* @deprecated This is a remnant of the abandoned 3.x storage system. Neither future 2.x code nor external plugins
* should use this interface.
*/
@Deprecated
public interface IReload extends com.earth2me.essentials.api.IReload {
}

View File

@ -1,8 +1,8 @@
package com.earth2me.essentials.geoip;
import com.earth2me.essentials.EssentialsConf;
import com.earth2me.essentials.IConf;
import com.earth2me.essentials.User;
import com.earth2me.essentials.config.EssentialsConfiguration;
import com.ice.tar.TarEntry;
import com.ice.tar.TarInputStream;
import com.maxmind.geoip2.DatabaseReader;
@ -39,7 +39,7 @@ import static com.earth2me.essentials.I18n.tl;
public class EssentialsGeoIPPlayerListener implements Listener, IConf {
private static final Logger logger = Logger.getLogger("EssentialsGeoIP");
private final File dataFolder;
private final EssentialsConf config;
private final EssentialsConfiguration config;
private final transient IEssentials ess;
private DatabaseReader mmreader = null; // initialize maxmind geoip2 reader
private File databaseFile;
@ -47,8 +47,7 @@ public class EssentialsGeoIPPlayerListener implements Listener, IConf {
EssentialsGeoIPPlayerListener(final File dataFolder, final IEssentials ess) {
this.ess = ess;
this.dataFolder = dataFolder;
this.config = new EssentialsConf(new File(dataFolder, "config.yml"));
config.setTemplateName("/config.yml", EssentialsGeoIP.class);
this.config = new EssentialsConfiguration(new File(dataFolder, "config.yml"), "/config.yml", EssentialsGeoIP.class);
reloadConfig();
}
@ -130,13 +129,13 @@ public class EssentialsGeoIPPlayerListener implements Listener, IConf {
config.load();
// detect and update the old config.yml. migrate from legacy GeoIP to GeoIP2.
if (!config.isSet("enable-locale")) {
config.set("database.download-url", "https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-Country&license_key={LICENSEKEY}&suffix=tar.gz");
config.set("database.download-url-city", "https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-City&license_key={LICENSEKEY}&suffix=tar.gz");
config.set("database.license-key", "");
config.set("database.update.enable", true);
config.set("database.update.by-every-x-days", 30);
config.set("enable-locale", true);
if (!config.hasProperty("enable-locale")) {
config.setProperty("database.download-url", "https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-Country&license_key={LICENSEKEY}&suffix=tar.gz");
config.setProperty("database.download-url-city", "https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-City&license_key={LICENSEKEY}&suffix=tar.gz");
config.setProperty("database.license-key", "");
config.setProperty("database.update.enable", true);
config.setProperty("database.update.by-every-x-days", 30);
config.setProperty("enable-locale", true);
config.save();
// delete old GeoIP.dat fiiles
final File oldDatFile = new File(dataFolder, "GeoIP.dat");
@ -166,7 +165,7 @@ public class EssentialsGeoIPPlayerListener implements Listener, IConf {
}
try {
// locale setting
if (config.getBoolean("enable-locale")) {
if (config.getBoolean("enable-locale", false)) {
// Get geolocation based on Essentials' locale. If the locale is not avaliable, use "en".
String locale = ess.getI18n().getCurrentLocale().toString().replace('_', '-');
// This fixes an inconsistency where Essentials uses "zh" but MaxMind expects "zh-CN".
@ -186,9 +185,9 @@ public class EssentialsGeoIPPlayerListener implements Listener, IConf {
try {
String url;
if (config.getBoolean("database.show-cities", false)) {
url = config.getString("database.download-url-city");
url = config.getString("database.download-url-city", null);
} else {
url = config.getString("database.download-url");
url = config.getString("database.download-url", null);
}
if (url == null || url.isEmpty()) {
logger.log(Level.SEVERE, tl("geoIpUrlEmpty"));

View File

@ -1,8 +1,8 @@
package com.earth2me.essentials.spawn;
import com.earth2me.essentials.IConf;
import com.earth2me.essentials.IEssentialsModule;
import com.earth2me.essentials.settings.Spawns;
import com.earth2me.essentials.storage.AsyncStorageObjectHolder;
import com.earth2me.essentials.config.EssentialsConfiguration;
import net.ess3.api.IEssentials;
import org.bukkit.Location;
import org.bukkit.World;
@ -12,58 +12,47 @@ import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
public class SpawnStorage extends AsyncStorageObjectHolder<Spawns> implements IEssentialsModule {
public class SpawnStorage implements IEssentialsModule, IConf {
private final IEssentials ess;
private final EssentialsConfiguration config;
private final Map<String, Location> spawns = new HashMap<>();
SpawnStorage(final IEssentials ess) {
super(ess, Spawns.class);
this.ess = ess;
this.config = new EssentialsConfiguration(new File(ess.getDataFolder(), "spawn.yml"));
reloadConfig();
}
@Override
public File getStorageFile() {
return new File(ess.getDataFolder(), "spawn.yml");
}
@Override
public void finishRead() {
}
@Override
public void finishWrite() {
}
void setSpawn(final Location loc, final String group) {
acquireWriteLock();
try {
if (getData().getSpawns() == null) {
getData().setSpawns(new HashMap<>());
}
getData().getSpawns().put(group.toLowerCase(Locale.ENGLISH), loc);
} finally {
unlock();
}
if ("default".equalsIgnoreCase(group)) {
loc.getWorld().setSpawnLocation(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
public void reloadConfig() {
synchronized (spawns) {
config.load();
spawns.clear();
// need to outsource this because transitive relocations :)
spawns.putAll(config.getLocationSectionMap("spawns"));
}
}
Location getSpawn(final String group) {
acquireReadLock();
try {
if (getData().getSpawns() == null || group == null) {
void setSpawn(final Location loc, String group) {
group = group.toLowerCase(Locale.ENGLISH);
synchronized (spawns) {
spawns.put(group, loc);
config.setProperty("spawns." + group, loc);
config.save();
}
}
Location getSpawn(String group) {
if (group == null) {
return getWorldSpawn();
}
group = group.toLowerCase(Locale.ENGLISH);
synchronized (spawns) {
if (!spawns.containsKey(group)) {
return getWorldSpawn();
}
final Map<String, Location> spawnMap = getData().getSpawns();
String groupName = group.toLowerCase(Locale.ENGLISH);
if (!spawnMap.containsKey(groupName)) {
groupName = "default";
}
if (!spawnMap.containsKey(groupName)) {
return getWorldSpawn();
}
return spawnMap.get(groupName);
} finally {
unlock();
return spawns.get(group);
}
}

View File

@ -1,7 +1,8 @@
package com.earth2me.essentials.xmpp;
import com.earth2me.essentials.EssentialsConf;
import com.earth2me.essentials.IConf;
import com.earth2me.essentials.config.ConfigurateUtil;
import com.earth2me.essentials.config.EssentialsConfiguration;
import java.io.File;
import java.util.ArrayList;
@ -15,11 +16,11 @@ import java.util.Set;
public class UserManager implements IConf {
private static final String ADDRESS = "address";
private static final String SPY = "spy";
private final transient EssentialsConf users;
private final transient EssentialsConfiguration users;
private final transient List<String> spyusers = Collections.synchronizedList(new ArrayList<>());
UserManager(final File folder) {
users = new EssentialsConf(new File(folder, "users.yml"));
users = new EssentialsConfiguration(new File(folder, "users.yml"));
reloadConfig();
}
@ -36,7 +37,7 @@ public class UserManager implements IConf {
}
final String getUserByAddress(final String search) {
final Set<String> usernames = users.getKeys(false);
final Set<String> usernames = ConfigurateUtil.getRootNodeKeys(users);
for (final String username : usernames) {
final String address = users.getString(username + "." + ADDRESS, null);
if (search.equalsIgnoreCase(address)) {
@ -58,7 +59,7 @@ public class UserManager implements IConf {
final Map<String, Object> userdata = new HashMap<>();
userdata.put(ADDRESS, address);
userdata.put(SPY, spy);
users.setProperty(username, userdata);
users.setRaw(username, userdata);
users.save();
reloadConfig();
}
@ -67,7 +68,7 @@ public class UserManager implements IConf {
public final void reloadConfig() {
users.load();
spyusers.clear();
final Set<String> keys = users.getKeys(false);
final Set<String> keys = ConfigurateUtil.getRootNodeKeys(users);
for (final String key : keys) {
if (isSpy(key)) {
final String address = getAddress(key);

View File

@ -1,8 +1,8 @@
package com.earth2me.essentials.xmpp;
import com.earth2me.essentials.Console;
import com.earth2me.essentials.EssentialsConf;
import com.earth2me.essentials.IConf;
import com.earth2me.essentials.config.EssentialsConfiguration;
import com.earth2me.essentials.utils.FormatUtil;
import net.ess3.api.IUser;
import org.bukkit.entity.Player;
@ -37,7 +37,7 @@ import static com.earth2me.essentials.I18n.tl;
public class XMPPManager extends Handler implements MessageListener, ChatManagerListener, IConf {
private static final Logger logger = Logger.getLogger("EssentialsXMPP");
private static final SimpleFormatter formatter = new SimpleFormatter();
private final transient EssentialsConf config;
private final transient EssentialsConfiguration config;
private final transient Map<String, Chat> chats = Collections.synchronizedMap(new HashMap<>());
private final transient Set<LogRecord> logrecords = Collections.synchronizedSet(new HashSet<>());
private final transient IEssentialsXMPP parent;
@ -52,8 +52,7 @@ public class XMPPManager extends Handler implements MessageListener, ChatManager
XMPPManager(final IEssentialsXMPP parent) {
super();
this.parent = parent;
config = new EssentialsConf(new File(parent.getDataFolder(), "config.yml"));
config.setTemplateName("/config.yml", EssentialsXMPP.class);
config = new EssentialsConfiguration(new File(parent.getDataFolder(), "config.yml"), "/config.yml", EssentialsXMPP.class);
reloadConfig();
}
@ -102,15 +101,15 @@ public class XMPPManager extends Handler implements MessageListener, ChatManager
}
private boolean connect() {
final String server = config.getString("xmpp.server");
final String server = config.getString("xmpp.server", null);
if (server == null || server.equals("example.com")) {
logger.log(Level.WARNING, tl("xmppNotConfigured"));
return false;
}
final int port = config.getInt("xmpp.port", 5222);
final String serviceName = config.getString("xmpp.servicename", server);
final String xmppuser = config.getString("xmpp.user");
final String password = config.getString("xmpp.password");
final String xmppuser = config.getString("xmpp.user", null);
final String password = config.getString("xmpp.password", null);
final boolean requireTLS = config.getBoolean("xmpp.require-server-tls", false);
final ConnectionConfiguration connConf = new ConnectionConfiguration(server, port, serviceName);
final String stringBuilder = "Connecting to xmpp server " + server + ":" + port + " as user " + xmppuser + ".";
@ -207,7 +206,7 @@ public class XMPPManager extends Handler implements MessageListener, ChatManager
}
if (config.getBoolean("log-enabled", false)) {
logger.addHandler(this);
logUsers = config.getStringList("log-users");
logUsers = config.getList("log-users", String.class);
final String level = config.getString("log-level", "info");
try {
logLevel = Level.parse(level.toUpperCase(Locale.ENGLISH));
@ -328,7 +327,7 @@ public class XMPPManager extends Handler implements MessageListener, ChatManager
}
private void sendCommand(final Chat chat, final String message) {
if (config.getStringList("op-users").contains(StringUtils.parseBareAddress(chat.getParticipant()))) {
if (config.getList("op-users", String.class).contains(StringUtils.parseBareAddress(chat.getParticipant()))) {
parent.getServer().getScheduler().runTask(parent, () -> {
try {
parent.getServer().dispatchCommand(Console.getInstance().getCommandSender(), message.substring(1));
@ -348,7 +347,7 @@ public class XMPPManager extends Handler implements MessageListener, ChatManager
}
public boolean isConfigValid() {
final String server = config.getString("xmpp.server");
final String server = config.getString("xmpp.server", null);
return server != null && !server.equals("example.com");
}
}

View File

@ -18,7 +18,9 @@ dependencies {
testImplementation("org.mockito", "mockito-core", mockitoVersion)
if (project.name != "1_8Provider" && project.name != "PaperProvider" && project.name != "NMSReflectionProvider") { // These providers use their own bukkit versions
api("org.spigotmc", "spigot-api", spigotVersion)
api("org.spigotmc", "spigot-api", spigotVersion) {
exclude(group = "org.yaml", module = "snakeyaml")
}
}
}