Refactor startup logic.
This commit re-implements and rearranges a lot of the logic in the main plugin class. It also removes the ConfigCommand class and moves its functionality into the CommandHandler to allow for reloads to be a bit more special than normal commands. In the refactoring of the main class, the startup logic is broken up into two phases, setup and (re)load: - In the setup phase, we create the data folder, and the command handler, config serializer(s), plugin integrations, boss abilities, the global event listener, and metrics are initialized. The ArenaMaster is instantiated, but it isn't initialized. These are things that need to be set up just once and don't change on reloads. - In the (re)load phase, the config-file is loaded from disk, the global messenger is instantiated, the arena master is initialized (loads settings, classes, and arenas), the announcements file is loaded from disk along with the sign data/templates. These are things that we want to be reloadable. If anything goes wrong during these phases, we store the exception thrown. This puts MobArena into a state where it prints the exception message to anyone who types a non-reload MobArena command to bring attention to the error so it can be fixed.
This commit is contained in:
@@ -16,6 +16,9 @@ These changes will (most likely) be included in the next version.
|
|||||||
- Right-clicking is now allowed in the lobby. This makes it possible to activate blocks like buttons and levers.
|
- Right-clicking is now allowed in the lobby. This makes it possible to activate blocks like buttons and levers.
|
||||||
- Snow and ice no longer melts in arenas.
|
- Snow and ice no longer melts in arenas.
|
||||||
- Much of the parsing logic has been rewritten so that MobArena now logs more user-friendly errors when it encounters invalid values in the config-file.
|
- Much of the parsing logic has been rewritten so that MobArena now logs more user-friendly errors when it encounters invalid values in the config-file.
|
||||||
|
- If MobArena fails to load due to config-file errors, it now enters a type of "error state". In this state, it responds to all commands (except for the reload command) with a short message explaining why it's disabled.
|
||||||
|
- It is now possible to reload config-files with `/ma reload`.
|
||||||
|
- The reload command now also reloads global settings, e.g. the global messenger prefix.
|
||||||
|
|
||||||
Thanks to:
|
Thanks to:
|
||||||
- PrinceIonia and Nesseley for help with test of dev builds
|
- PrinceIonia and Nesseley for help with test of dev builds
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ import java.util.stream.Collectors;
|
|||||||
public class ArenaMasterImpl implements ArenaMaster
|
public class ArenaMasterImpl implements ArenaMaster
|
||||||
{
|
{
|
||||||
private MobArena plugin;
|
private MobArena plugin;
|
||||||
private FileConfiguration config;
|
|
||||||
|
|
||||||
private List<Arena> arenas;
|
private List<Arena> arenas;
|
||||||
private Map<Player, Arena> arenaMap;
|
private Map<Player, Arena> arenaMap;
|
||||||
@@ -53,7 +52,6 @@ public class ArenaMasterImpl implements ArenaMaster
|
|||||||
*/
|
*/
|
||||||
public ArenaMasterImpl(MobArena plugin) {
|
public ArenaMasterImpl(MobArena plugin) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
this.config = plugin.getConfig();
|
|
||||||
|
|
||||||
this.arenas = new ArrayList<>();
|
this.arenas = new ArrayList<>();
|
||||||
this.arenaMap = new HashMap<>();
|
this.arenaMap = new HashMap<>();
|
||||||
@@ -63,8 +61,6 @@ public class ArenaMasterImpl implements ArenaMaster
|
|||||||
this.allowedCommands = new HashSet<>();
|
this.allowedCommands = new HashSet<>();
|
||||||
this.spawnsPets = new SpawnsPets(Material.BONE, Material.RAW_FISH);
|
this.spawnsPets = new SpawnsPets(Material.BONE, Material.RAW_FISH);
|
||||||
|
|
||||||
this.enabled = config.getBoolean("global-settings.enabled", true);
|
|
||||||
|
|
||||||
this.joinInterruptTimer = new JoinInterruptTimer();
|
this.joinInterruptTimer = new JoinInterruptTimer();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,16 +80,21 @@ public class ArenaMasterImpl implements ArenaMaster
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isEnabled() {
|
public boolean isEnabled() {
|
||||||
return enabled;
|
return plugin.getLastFailureCause() == null && enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setEnabled(boolean value) {
|
public void setEnabled(boolean value) {
|
||||||
enabled = value;
|
enabled = value;
|
||||||
|
FileConfiguration config = plugin.getConfig();
|
||||||
|
if (config != null) {
|
||||||
config.set("global-settings.enabled", enabled);
|
config.set("global-settings.enabled", enabled);
|
||||||
|
plugin.saveConfig();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean notifyOnUpdates() {
|
public boolean notifyOnUpdates() {
|
||||||
return config.getBoolean("global-settings.update-notification", false);
|
FileConfiguration config = plugin.getConfig();
|
||||||
|
return config != null && config.getBoolean("global-settings.update-notification", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Arena> getArenas() {
|
public List<Arena> getArenas() {
|
||||||
@@ -257,6 +258,8 @@ public class ArenaMasterImpl implements ArenaMaster
|
|||||||
ConfigurationSection section = plugin.getConfig().getConfigurationSection("global-settings");
|
ConfigurationSection section = plugin.getConfig().getConfigurationSection("global-settings");
|
||||||
ConfigUtils.addMissingRemoveObsolete(plugin, "global-settings.yml", section);
|
ConfigUtils.addMissingRemoveObsolete(plugin, "global-settings.yml", section);
|
||||||
|
|
||||||
|
enabled = section.getBoolean("enabled", true);
|
||||||
|
|
||||||
// Grab the commands string
|
// Grab the commands string
|
||||||
String cmds = section.getString("allowed-commands", "");
|
String cmds = section.getString("allowed-commands", "");
|
||||||
|
|
||||||
@@ -316,6 +319,7 @@ public class ArenaMasterImpl implements ArenaMaster
|
|||||||
* Helper method for loading a single class.
|
* Helper method for loading a single class.
|
||||||
*/
|
*/
|
||||||
private ArenaClass loadClass(String classname) {
|
private ArenaClass loadClass(String classname) {
|
||||||
|
FileConfiguration config = plugin.getConfig();
|
||||||
ConfigurationSection section = config.getConfigurationSection("classes." + classname);
|
ConfigurationSection section = config.getConfigurationSection("classes." + classname);
|
||||||
String lowercase = classname.toLowerCase().replace(" ", "");
|
String lowercase = classname.toLowerCase().replace(" ", "");
|
||||||
|
|
||||||
@@ -490,6 +494,7 @@ public class ArenaMasterImpl implements ArenaMaster
|
|||||||
* Load all arena-related stuff.
|
* Load all arena-related stuff.
|
||||||
*/
|
*/
|
||||||
public void loadArenas() {
|
public void loadArenas() {
|
||||||
|
FileConfiguration config = plugin.getConfig();
|
||||||
ConfigurationSection section = makeSection(config, "arenas");
|
ConfigurationSection section = makeSection(config, "arenas");
|
||||||
Set<String> arenanames = section.getKeys(false);
|
Set<String> arenanames = section.getKeys(false);
|
||||||
|
|
||||||
@@ -505,6 +510,7 @@ public class ArenaMasterImpl implements ArenaMaster
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void loadArenasInWorld(String worldName) {
|
public void loadArenasInWorld(String worldName) {
|
||||||
|
FileConfiguration config = plugin.getConfig();
|
||||||
Set<String> arenaNames = config.getConfigurationSection("arenas").getKeys(false);
|
Set<String> arenaNames = config.getConfigurationSection("arenas").getKeys(false);
|
||||||
if (arenaNames == null || arenaNames.isEmpty()) {
|
if (arenaNames == null || arenaNames.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
@@ -521,6 +527,7 @@ public class ArenaMasterImpl implements ArenaMaster
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void unloadArenasInWorld(String worldName) {
|
public void unloadArenasInWorld(String worldName) {
|
||||||
|
FileConfiguration config = plugin.getConfig();
|
||||||
Set<String> arenaNames = config.getConfigurationSection("arenas").getKeys(false);
|
Set<String> arenaNames = config.getConfigurationSection("arenas").getKeys(false);
|
||||||
if (arenaNames == null || arenaNames.isEmpty()) {
|
if (arenaNames == null || arenaNames.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
@@ -539,6 +546,7 @@ public class ArenaMasterImpl implements ArenaMaster
|
|||||||
|
|
||||||
// Load an already existing arena node
|
// Load an already existing arena node
|
||||||
private Arena loadArena(String arenaname) {
|
private Arena loadArena(String arenaname) {
|
||||||
|
FileConfiguration config = plugin.getConfig();
|
||||||
ConfigurationSection section = makeSection(config, "arenas." + arenaname);
|
ConfigurationSection section = makeSection(config, "arenas." + arenaname);
|
||||||
ConfigurationSection settings = makeSection(section, "settings");
|
ConfigurationSection settings = makeSection(section, "settings");
|
||||||
String worldName = settings.getString("world", "");
|
String worldName = settings.getString("world", "");
|
||||||
@@ -573,7 +581,6 @@ public class ArenaMasterImpl implements ArenaMaster
|
|||||||
arenas.remove(arena);
|
arenas.remove(arena);
|
||||||
|
|
||||||
plugin.reloadConfig();
|
plugin.reloadConfig();
|
||||||
config = plugin.getConfig();
|
|
||||||
|
|
||||||
loadArena(name);
|
loadArena(name);
|
||||||
return true;
|
return true;
|
||||||
@@ -582,6 +589,7 @@ public class ArenaMasterImpl implements ArenaMaster
|
|||||||
// Create and load a new arena node
|
// Create and load a new arena node
|
||||||
@Override
|
@Override
|
||||||
public Arena createArenaNode(String arenaName, World world) {
|
public Arena createArenaNode(String arenaName, World world) {
|
||||||
|
FileConfiguration config = plugin.getConfig();
|
||||||
ConfigurationSection section = makeSection(config, "arenas");
|
ConfigurationSection section = makeSection(config, "arenas");
|
||||||
return createArenaNode(section, arenaName, world, true);
|
return createArenaNode(section, arenaName, world, true);
|
||||||
}
|
}
|
||||||
@@ -607,6 +615,7 @@ public class ArenaMasterImpl implements ArenaMaster
|
|||||||
public void removeArenaNode(Arena arena) {
|
public void removeArenaNode(Arena arena) {
|
||||||
arenas.remove(arena);
|
arenas.remove(arena);
|
||||||
|
|
||||||
|
FileConfiguration config = plugin.getConfig();
|
||||||
config.set("arenas." + arena.configName(), null);
|
config.set("arenas." + arena.configName(), null);
|
||||||
plugin.saveConfig();
|
plugin.saveConfig();
|
||||||
}
|
}
|
||||||
@@ -616,17 +625,7 @@ public class ArenaMasterImpl implements ArenaMaster
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void reloadConfig() {
|
public void reloadConfig() {
|
||||||
boolean wasEnabled = isEnabled();
|
plugin.reload();
|
||||||
if (wasEnabled) setEnabled(false);
|
|
||||||
for (Arena a : arenas) {
|
|
||||||
a.forceEnd();
|
|
||||||
}
|
|
||||||
plugin.reloadConfig();
|
|
||||||
config = plugin.getConfig();
|
|
||||||
initialize();
|
|
||||||
plugin.reloadSigns();
|
|
||||||
plugin.reloadAnnouncementsFile();
|
|
||||||
if (wasEnabled) setEnabled(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void saveConfig() {
|
public void saveConfig() {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.garbagemule.MobArena;
|
package com.garbagemule.MobArena;
|
||||||
|
|
||||||
import com.garbagemule.MobArena.commands.CommandHandler;
|
import com.garbagemule.MobArena.commands.CommandHandler;
|
||||||
|
import com.garbagemule.MobArena.config.LoadsConfigFile;
|
||||||
import com.garbagemule.MobArena.framework.Arena;
|
import com.garbagemule.MobArena.framework.Arena;
|
||||||
import com.garbagemule.MobArena.framework.ArenaMaster;
|
import com.garbagemule.MobArena.framework.ArenaMaster;
|
||||||
import com.garbagemule.MobArena.listeners.MAGlobalListener;
|
import com.garbagemule.MobArena.listeners.MAGlobalListener;
|
||||||
@@ -35,10 +36,8 @@ import org.bukkit.plugin.java.JavaPlugin;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MobArena
|
* MobArena
|
||||||
@@ -47,13 +46,13 @@ import java.util.Random;
|
|||||||
public class MobArena extends JavaPlugin
|
public class MobArena extends JavaPlugin
|
||||||
{
|
{
|
||||||
private ArenaMaster arenaMaster;
|
private ArenaMaster arenaMaster;
|
||||||
private CommandHandler commandHandler;
|
|
||||||
|
|
||||||
// Vault
|
// Vault
|
||||||
private Economy economy;
|
private Economy economy;
|
||||||
|
|
||||||
private File configFile;
|
|
||||||
private FileConfiguration config;
|
private FileConfiguration config;
|
||||||
|
private LoadsConfigFile loadsConfigFile;
|
||||||
|
private Throwable lastFailureCause;
|
||||||
|
|
||||||
public static final double MIN_PLAYER_DISTANCE_SQUARED = 225D;
|
public static final double MIN_PLAYER_DISTANCE_SQUARED = 225D;
|
||||||
public static Random random = new Random();
|
public static Random random = new Random();
|
||||||
@@ -70,141 +69,155 @@ public class MobArena extends JavaPlugin
|
|||||||
|
|
||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
ServerVersionCheck.check(getServer());
|
ServerVersionCheck.check(getServer());
|
||||||
|
try {
|
||||||
|
setup();
|
||||||
|
reload();
|
||||||
|
checkForUpdates();
|
||||||
|
} catch (ConfigError e) {
|
||||||
|
getLogger().log(Level.SEVERE, "You have an error in your config-file!\n\n " + e.getMessage() + "\n");
|
||||||
|
getLogger().log(Level.SEVERE, "Fix it, then run /ma load");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize config-file
|
public void onDisable() {
|
||||||
configFile = new File(getDataFolder(), "config.yml");
|
if (arenaMaster != null) {
|
||||||
config = new YamlConfiguration();
|
arenaMaster.getArenas().forEach(Arena::forceEnd);
|
||||||
|
arenaMaster.resetArenaMap();
|
||||||
|
arenaMaster = null;
|
||||||
|
}
|
||||||
|
loadsConfigFile = null;
|
||||||
|
ConfigurationSerialization.unregisterClass(ArenaSign.class);
|
||||||
|
VersionChecker.shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setup() {
|
||||||
|
try {
|
||||||
|
createDataFolder();
|
||||||
|
setupArenaMaster();
|
||||||
|
setupCommandHandler();
|
||||||
|
|
||||||
|
registerConfigurationSerializers();
|
||||||
|
setupVault();
|
||||||
|
setupMagicSpells();
|
||||||
|
setupBossAbilities();
|
||||||
|
setupListeners();
|
||||||
|
setupMetrics();
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
setLastFailureCauseAndRethrow(e);
|
||||||
|
}
|
||||||
|
lastFailureCause = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createDataFolder() {
|
||||||
|
File dir = getDataFolder();
|
||||||
|
if (!dir.exists()) {
|
||||||
|
if (dir.mkdir()) {
|
||||||
|
getLogger().info("Data folder plugins/MobArena created.");
|
||||||
|
} else {
|
||||||
|
getLogger().warning("Failed to create data folder plugins/MobArena!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupArenaMaster() {
|
||||||
|
arenaMaster = new ArenaMasterImpl(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupCommandHandler() {
|
||||||
|
CommandHandler handler = new CommandHandler(this);
|
||||||
|
getCommand("ma").setExecutor(handler);
|
||||||
|
getCommand("mobarena").setExecutor(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void registerConfigurationSerializers() {
|
||||||
ConfigurationSerialization.registerClass(ArenaSign.class);
|
ConfigurationSerialization.registerClass(ArenaSign.class);
|
||||||
reloadConfig();
|
}
|
||||||
|
|
||||||
// Initialize global messenger
|
private void setupVault() {
|
||||||
|
Plugin vaultPlugin = this.getServer().getPluginManager().getPlugin("Vault");
|
||||||
|
if (vaultPlugin == null) {
|
||||||
|
getLogger().info("Vault was not found. Economy rewards will not work.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ServicesManager manager = this.getServer().getServicesManager();
|
||||||
|
RegisteredServiceProvider<Economy> e = manager.getRegistration(net.milkbowl.vault.economy.Economy.class);
|
||||||
|
|
||||||
|
if (e != null) {
|
||||||
|
economy = e.getProvider();
|
||||||
|
getLogger().info("Vault found; economy rewards enabled.");
|
||||||
|
} else {
|
||||||
|
getLogger().warning("Vault found, but no economy plugin detected. Economy rewards will not work!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupMagicSpells() {
|
||||||
|
Plugin spells = this.getServer().getPluginManager().getPlugin("MagicSpells");
|
||||||
|
if (spells == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
getLogger().info("MagicSpells found, loading config-file.");
|
||||||
|
this.getServer().getPluginManager().registerEvents(new MagicSpellsListener(this), this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupBossAbilities() {
|
||||||
|
AbilityManager.loadCoreAbilities();
|
||||||
|
AbilityManager.loadCustomAbilities(getDataFolder());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupListeners() {
|
||||||
|
PluginManager pm = this.getServer().getPluginManager();
|
||||||
|
pm.registerEvents(new MAGlobalListener(this, arenaMaster), this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupMetrics() {
|
||||||
|
Metrics metrics = new Metrics(this);
|
||||||
|
metrics.addCustomChart(new VaultChart(this));
|
||||||
|
metrics.addCustomChart(new ArenaCountChart(this));
|
||||||
|
metrics.addCustomChart(new ClassCountChart(this));
|
||||||
|
metrics.addCustomChart(new ClassChestsChart(this));
|
||||||
|
metrics.addCustomChart(new FoodRegenChart(this));
|
||||||
|
metrics.addCustomChart(new IsolatedChatChart(this));
|
||||||
|
metrics.addCustomChart(new MonsterInfightChart(this));
|
||||||
|
metrics.addCustomChart(new PvpEnabledChart(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reload() {
|
||||||
|
try {
|
||||||
|
reloadConfig();
|
||||||
|
reloadGlobalMessenger();
|
||||||
|
reloadArenaMaster();
|
||||||
|
reloadAnnouncementsFile();
|
||||||
|
reloadSigns();
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
setLastFailureCauseAndRethrow(e);
|
||||||
|
}
|
||||||
|
lastFailureCause = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reloadConfig() {
|
||||||
|
if (loadsConfigFile == null) {
|
||||||
|
loadsConfigFile = new LoadsConfigFile(this);
|
||||||
|
}
|
||||||
|
config = loadsConfigFile.load();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void reloadGlobalMessenger() {
|
||||||
String prefix = config.getString("global-settings.prefix", "");
|
String prefix = config.getString("global-settings.prefix", "");
|
||||||
if (prefix.isEmpty()) {
|
if (prefix.isEmpty()) {
|
||||||
prefix = ChatColor.GREEN + "[MobArena] ";
|
prefix = ChatColor.GREEN + "[MobArena] ";
|
||||||
}
|
}
|
||||||
messenger = new Messenger(prefix);
|
messenger = new Messenger(prefix);
|
||||||
|
}
|
||||||
|
|
||||||
// Set the header and save
|
private void reloadArenaMaster() {
|
||||||
getConfig().options().header(getHeader());
|
arenaMaster.getArenas().forEach(Arena::forceEnd);
|
||||||
saveConfig();
|
|
||||||
|
|
||||||
// Initialize announcements-file
|
|
||||||
reloadAnnouncementsFile();
|
|
||||||
|
|
||||||
// Load boss abilities
|
|
||||||
loadAbilities();
|
|
||||||
|
|
||||||
// Set up soft dependencies
|
|
||||||
setupVault();
|
|
||||||
setupMagicSpells();
|
|
||||||
|
|
||||||
// Set up the ArenaMaster
|
|
||||||
arenaMaster = new ArenaMasterImpl(this);
|
|
||||||
try {
|
|
||||||
arenaMaster.initialize();
|
arenaMaster.initialize();
|
||||||
} catch (ConfigError e) {
|
|
||||||
getLogger().severe(e.getMessage());
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load signs after Messenger and ArenaMaster
|
private void reloadAnnouncementsFile() {
|
||||||
reloadSigns();
|
|
||||||
|
|
||||||
// Register event listeners
|
|
||||||
registerListeners();
|
|
||||||
|
|
||||||
// Setup bStats metrics
|
|
||||||
setupMetrics();
|
|
||||||
|
|
||||||
// Announce enable!
|
|
||||||
getLogger().info("v" + this.getDescription().getVersion() + " enabled.");
|
|
||||||
|
|
||||||
// Check for updates
|
|
||||||
if (getConfig().getBoolean("global-settings.update-notification", false)) {
|
|
||||||
VersionChecker.checkForUpdates(this, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onDisable() {
|
|
||||||
// Force all arenas to end.
|
|
||||||
if (arenaMaster == null) return;
|
|
||||||
for (Arena arena : arenaMaster.getArenas()) {
|
|
||||||
arena.forceEnd();
|
|
||||||
}
|
|
||||||
arenaMaster.resetArenaMap();
|
|
||||||
VersionChecker.shutdown();
|
|
||||||
ConfigurationSerialization.unregisterClass(ArenaSign.class);
|
|
||||||
|
|
||||||
getLogger().info("disabled.");
|
|
||||||
}
|
|
||||||
|
|
||||||
public File getPluginFile() {
|
|
||||||
return getFile();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FileConfiguration getConfig() {
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reloadConfig() {
|
|
||||||
// Make sure the data folder exists
|
|
||||||
File data = new File(getDataFolder(), "data");
|
|
||||||
if (!data.exists()) {
|
|
||||||
boolean created = data.mkdirs();
|
|
||||||
if (!created) {
|
|
||||||
throw new IllegalStateException("Failed to create data folder!");
|
|
||||||
}
|
|
||||||
getLogger().info("Created data folder.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the config-file exists
|
|
||||||
if (!configFile.exists()) {
|
|
||||||
getLogger().info("No config-file found, creating default...");
|
|
||||||
saveDefaultConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for tab characters in config-file
|
|
||||||
try {
|
|
||||||
Path path = getDataFolder().toPath().resolve("config.yml");
|
|
||||||
List<String> lines = Files.readAllLines(path);
|
|
||||||
for (int i = 0; i < lines.size(); i++) {
|
|
||||||
String line = lines.get(i);
|
|
||||||
int index = line.indexOf('\t');
|
|
||||||
if (index != -1) {
|
|
||||||
String indent = new String(new char[index]).replace('\0', ' ');
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"Found tab in config-file on line " + (i + 1) + "! NEVER use tabs! ALWAYS use spaces!\n\n" +
|
|
||||||
line + "\n" +
|
|
||||||
indent + "^"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException("There was an error reading the config-file:\n" + e.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reload the config-file
|
|
||||||
try {
|
|
||||||
config.load(configFile);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException("There was an error reading the config-file:\n" + e.getMessage());
|
|
||||||
} catch (InvalidConfigurationException e) {
|
|
||||||
throw new RuntimeException("\n\n>>>\n>>> There is an error in your config-file! Handle it!\n>>> Here is what snakeyaml says:\n>>>\n\n" + e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void reloadSigns() {
|
|
||||||
if (signListeners != null) {
|
|
||||||
signListeners.unregister();
|
|
||||||
}
|
|
||||||
SignBootstrap bootstrap = SignBootstrap.create(this);
|
|
||||||
signListeners = new SignListeners();
|
|
||||||
signListeners.register(bootstrap);
|
|
||||||
}
|
|
||||||
|
|
||||||
void reloadAnnouncementsFile() {
|
|
||||||
// Create if missing
|
// Create if missing
|
||||||
File file = new File(getDataFolder(), "announcements.yml");
|
File file = new File(getDataFolder(), "announcements.yml");
|
||||||
try {
|
try {
|
||||||
@@ -231,86 +244,46 @@ public class MobArena extends JavaPlugin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void reloadSigns() {
|
||||||
|
if (signListeners != null) {
|
||||||
|
signListeners.unregister();
|
||||||
|
}
|
||||||
|
SignBootstrap bootstrap = SignBootstrap.create(this);
|
||||||
|
signListeners = new SignListeners();
|
||||||
|
signListeners.register(bootstrap);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkForUpdates() {
|
||||||
|
if (getConfig().getBoolean("global-settings.update-notification", false)) {
|
||||||
|
VersionChecker.checkForUpdates(this, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setLastFailureCauseAndRethrow(RuntimeException up) {
|
||||||
|
lastFailureCause = up;
|
||||||
|
throw up;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Throwable getLastFailureCause() {
|
||||||
|
return lastFailureCause;
|
||||||
|
}
|
||||||
|
|
||||||
|
public File getPluginFile() {
|
||||||
|
return getFile();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void saveConfig() {
|
public FileConfiguration getConfig() {
|
||||||
try {
|
if (config == null) {
|
||||||
config.save(configFile);
|
reloadConfig();
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
return config;
|
||||||
|
|
||||||
private void registerListeners() {
|
|
||||||
// Bind the /ma, /mobarena commands to MACommands.
|
|
||||||
commandHandler = new CommandHandler(this);
|
|
||||||
getCommand("ma").setExecutor(commandHandler);
|
|
||||||
getCommand("mobarena").setExecutor(commandHandler);
|
|
||||||
|
|
||||||
PluginManager pm = this.getServer().getPluginManager();
|
|
||||||
pm.registerEvents(new MAGlobalListener(this, arenaMaster), this);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setupVault() {
|
|
||||||
Plugin vaultPlugin = this.getServer().getPluginManager().getPlugin("Vault");
|
|
||||||
if (vaultPlugin == null) {
|
|
||||||
getLogger().info("Vault was not found. Economy rewards will not work.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ServicesManager manager = this.getServer().getServicesManager();
|
|
||||||
RegisteredServiceProvider<Economy> e = manager.getRegistration(net.milkbowl.vault.economy.Economy.class);
|
|
||||||
|
|
||||||
if (e != null) {
|
|
||||||
economy = e.getProvider();
|
|
||||||
getLogger().info("Vault found; economy rewards enabled.");
|
|
||||||
} else {
|
|
||||||
getLogger().warning("Vault found, but no economy plugin detected. Economy rewards will not work!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setupMagicSpells() {
|
|
||||||
Plugin spells = this.getServer().getPluginManager().getPlugin("MagicSpells");
|
|
||||||
if (spells == null) return;
|
|
||||||
|
|
||||||
getLogger().info("MagicSpells found, loading config-file.");
|
|
||||||
this.getServer().getPluginManager().registerEvents(new MagicSpellsListener(this), this);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setupMetrics() {
|
|
||||||
Metrics metrics = new Metrics(this);
|
|
||||||
metrics.addCustomChart(new VaultChart(this));
|
|
||||||
metrics.addCustomChart(new ArenaCountChart(this));
|
|
||||||
metrics.addCustomChart(new ClassCountChart(this));
|
|
||||||
metrics.addCustomChart(new ClassChestsChart(this));
|
|
||||||
metrics.addCustomChart(new FoodRegenChart(this));
|
|
||||||
metrics.addCustomChart(new IsolatedChatChart(this));
|
|
||||||
metrics.addCustomChart(new MonsterInfightChart(this));
|
|
||||||
metrics.addCustomChart(new PvpEnabledChart(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void loadAbilities() {
|
|
||||||
File dir = new File(this.getDataFolder(), "abilities");
|
|
||||||
if (!dir.exists()) dir.mkdir();
|
|
||||||
|
|
||||||
AbilityManager.loadCoreAbilities();
|
|
||||||
AbilityManager.loadCustomAbilities(dir);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArenaMaster getArenaMaster() {
|
public ArenaMaster getArenaMaster() {
|
||||||
return arenaMaster;
|
return arenaMaster;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CommandHandler getCommandHandler() {
|
|
||||||
return commandHandler;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getHeader() {
|
|
||||||
String sep = System.getProperty("line.separator");
|
|
||||||
return "MobArena v" + this.getDescription().getVersion() + " - Config-file" + sep +
|
|
||||||
"Read the Wiki for details on how to set up this file: http://goo.gl/F5TTc" + sep +
|
|
||||||
"Note: You -must- use spaces instead of tabs!";
|
|
||||||
}
|
|
||||||
|
|
||||||
public Economy getEconomy() {
|
public Economy getEconomy() {
|
||||||
return economy;
|
return economy;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package com.garbagemule.MobArena.commands;
|
package com.garbagemule.MobArena.commands;
|
||||||
|
|
||||||
|
import com.garbagemule.MobArena.ConfigError;
|
||||||
|
import com.garbagemule.MobArena.Messenger;
|
||||||
import com.garbagemule.MobArena.MobArena;
|
import com.garbagemule.MobArena.MobArena;
|
||||||
import com.garbagemule.MobArena.Msg;
|
import com.garbagemule.MobArena.Msg;
|
||||||
import com.garbagemule.MobArena.commands.admin.DisableCommand;
|
import com.garbagemule.MobArena.commands.admin.DisableCommand;
|
||||||
@@ -12,7 +14,6 @@ import com.garbagemule.MobArena.commands.setup.AutoGenerateCommand;
|
|||||||
import com.garbagemule.MobArena.commands.setup.CheckDataCommand;
|
import com.garbagemule.MobArena.commands.setup.CheckDataCommand;
|
||||||
import com.garbagemule.MobArena.commands.setup.CheckSpawnsCommand;
|
import com.garbagemule.MobArena.commands.setup.CheckSpawnsCommand;
|
||||||
import com.garbagemule.MobArena.commands.setup.ClassChestCommand;
|
import com.garbagemule.MobArena.commands.setup.ClassChestCommand;
|
||||||
import com.garbagemule.MobArena.commands.setup.ConfigCommand;
|
|
||||||
import com.garbagemule.MobArena.commands.setup.EditArenaCommand;
|
import com.garbagemule.MobArena.commands.setup.EditArenaCommand;
|
||||||
import com.garbagemule.MobArena.commands.setup.ListClassesCommand;
|
import com.garbagemule.MobArena.commands.setup.ListClassesCommand;
|
||||||
import com.garbagemule.MobArena.commands.setup.RemoveArenaCommand;
|
import com.garbagemule.MobArena.commands.setup.RemoveArenaCommand;
|
||||||
@@ -44,13 +45,13 @@ import java.util.Map.Entry;
|
|||||||
public class CommandHandler implements CommandExecutor
|
public class CommandHandler implements CommandExecutor
|
||||||
{
|
{
|
||||||
private MobArena plugin;
|
private MobArena plugin;
|
||||||
private ArenaMaster am;
|
private Messenger fallbackMessenger;
|
||||||
|
|
||||||
private Map<String,Command> commands;
|
private Map<String,Command> commands;
|
||||||
|
|
||||||
public CommandHandler(MobArena plugin) {
|
public CommandHandler(MobArena plugin) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
this.am = plugin.getArenaMaster();
|
this.fallbackMessenger = new Messenger("&a[MobArena] ");
|
||||||
|
|
||||||
registerCommands();
|
registerCommands();
|
||||||
}
|
}
|
||||||
@@ -68,7 +69,17 @@ public class CommandHandler implements CommandExecutor
|
|||||||
|
|
||||||
// If there's no base argument, show a helpful message.
|
// If there's no base argument, show a helpful message.
|
||||||
if (base.equals("")) {
|
if (base.equals("")) {
|
||||||
am.getGlobalMessenger().tell(sender, Msg.MISC_HELP);
|
return safeTell(sender, Msg.MISC_HELP);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reloads are special
|
||||||
|
if (base.equals("reload") || (base.equals("config") && args.length > 1 && args[1].equals("reload"))) {
|
||||||
|
return reload(sender);
|
||||||
|
}
|
||||||
|
|
||||||
|
Throwable lastFailureCause = plugin.getLastFailureCause();
|
||||||
|
if (lastFailureCause != null) {
|
||||||
|
fallbackMessenger.tell(sender, "MobArena is disabled, because:\n" + ChatColor.RED + lastFailureCause.getMessage());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,6 +89,8 @@ public class CommandHandler implements CommandExecutor
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ArenaMaster am = plugin.getArenaMaster();
|
||||||
|
|
||||||
// Get all commands that match the base.
|
// Get all commands that match the base.
|
||||||
List<Command> matches = getMatchingCommands(base);
|
List<Command> matches = getMatchingCommands(base);
|
||||||
|
|
||||||
@@ -120,6 +133,31 @@ public class CommandHandler implements CommandExecutor
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean reload(CommandSender sender) {
|
||||||
|
if (!sender.hasPermission("mobarena.setup.load") && !sender.hasPermission("mobarena.setup.config")) {
|
||||||
|
return safeTell(sender, Msg.MISC_NO_ACCESS);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
plugin.reload();
|
||||||
|
plugin.getArenaMaster().getGlobalMessenger().tell(sender, "Reload complete.");
|
||||||
|
} catch (ConfigError e) {
|
||||||
|
fallbackMessenger.tell(sender, "Reload failed due to config-file error:\n" + ChatColor.RED + e.getMessage());
|
||||||
|
} catch (Exception e) {
|
||||||
|
fallbackMessenger.tell(sender, "Reload failed:\n" + ChatColor.RED + e.getMessage());
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean safeTell(CommandSender sender, Msg msg) {
|
||||||
|
ArenaMaster am = plugin.getArenaMaster();
|
||||||
|
if (am != null) {
|
||||||
|
am.getGlobalMessenger().tell(sender, msg);
|
||||||
|
} else {
|
||||||
|
fallbackMessenger.tell(sender, msg);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all commands that match a given string.
|
* Get all commands that match a given string.
|
||||||
* @param arg the given string
|
* @param arg the given string
|
||||||
@@ -187,6 +225,8 @@ public class CommandHandler implements CommandExecutor
|
|||||||
.append(ChatColor.YELLOW).append(info.desc());
|
.append(ChatColor.YELLOW).append(info.desc());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ArenaMaster am = plugin.getArenaMaster();
|
||||||
|
|
||||||
if (admin.length() == 0 && setup.length() == 0) {
|
if (admin.length() == 0 && setup.length() == 0) {
|
||||||
am.getGlobalMessenger().tell(sender, "Available commands: " + user.toString());
|
am.getGlobalMessenger().tell(sender, "Available commands: " + user.toString());
|
||||||
} else {
|
} else {
|
||||||
@@ -221,7 +261,6 @@ public class CommandHandler implements CommandExecutor
|
|||||||
register(RestoreCommand.class);
|
register(RestoreCommand.class);
|
||||||
|
|
||||||
// mobarena.setup
|
// mobarena.setup
|
||||||
register(ConfigCommand.class);
|
|
||||||
register(SetupCommand.class);
|
register(SetupCommand.class);
|
||||||
register(SettingCommand.class);
|
register(SettingCommand.class);
|
||||||
|
|
||||||
|
|||||||
@@ -1,40 +0,0 @@
|
|||||||
package com.garbagemule.MobArena.commands.setup;
|
|
||||||
|
|
||||||
import com.garbagemule.MobArena.commands.Command;
|
|
||||||
import com.garbagemule.MobArena.commands.CommandInfo;
|
|
||||||
import com.garbagemule.MobArena.framework.ArenaMaster;
|
|
||||||
import org.bukkit.ChatColor;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
|
|
||||||
@CommandInfo(
|
|
||||||
name = "config",
|
|
||||||
pattern = "config|cfg",
|
|
||||||
usage = "/ma config reload|save",
|
|
||||||
desc = "reload or save the config-file",
|
|
||||||
permission = "mobarena.setup.config"
|
|
||||||
)
|
|
||||||
public class ConfigCommand implements Command
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public boolean execute(ArenaMaster am, CommandSender sender, String... args) {
|
|
||||||
// Require reload/save
|
|
||||||
if (args.length != 1) return false;
|
|
||||||
|
|
||||||
if (args[0].equals("reload")) {
|
|
||||||
try {
|
|
||||||
am.reloadConfig();
|
|
||||||
am.getGlobalMessenger().tell(sender, "Config reloaded.");
|
|
||||||
} catch (Exception e) {
|
|
||||||
am.getGlobalMessenger().tell(sender, ChatColor.RED + "ERROR:" + ChatColor.RESET + "\n" + e.getMessage());
|
|
||||||
am.getGlobalMessenger().tell(sender, "MobArena has been " + ChatColor.RED + "disabled" + ChatColor.RESET + ".");
|
|
||||||
am.getGlobalMessenger().tell(sender, "Fix the config-file, then reload it again, and then type " + ChatColor.YELLOW + "/ma enable" + ChatColor.RESET + " to re-enable MobArena.");
|
|
||||||
}
|
|
||||||
} else if (args[0].equals("save")) {
|
|
||||||
am.saveConfig();
|
|
||||||
am.getGlobalMessenger().tell(sender, "Config saved.");
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
package com.garbagemule.MobArena.config;
|
||||||
|
|
||||||
|
import com.garbagemule.MobArena.MobArena;
|
||||||
|
import org.bukkit.configuration.InvalidConfigurationException;
|
||||||
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class LoadsConfigFile {
|
||||||
|
|
||||||
|
private final MobArena plugin;
|
||||||
|
|
||||||
|
public LoadsConfigFile(MobArena plugin) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FileConfiguration load() {
|
||||||
|
try {
|
||||||
|
return loadConfiguration();
|
||||||
|
} catch (IOException | InvalidConfigurationException e) {
|
||||||
|
throw new IllegalStateException("Failed to load config-file", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private FileConfiguration loadConfiguration() throws IOException, InvalidConfigurationException {
|
||||||
|
File folder = createDataFolder();
|
||||||
|
File file = new File(folder, "config.yml");
|
||||||
|
if (!file.exists()) {
|
||||||
|
plugin.getLogger().info("No config-file found. Creating default...");
|
||||||
|
plugin.saveDefaultConfig();
|
||||||
|
}
|
||||||
|
YamlConfiguration yaml = new YamlConfiguration();
|
||||||
|
yaml.load(file);
|
||||||
|
return yaml;
|
||||||
|
}
|
||||||
|
|
||||||
|
private File createDataFolder() {
|
||||||
|
File folder = plugin.getDataFolder();
|
||||||
|
if (!folder.exists()) {
|
||||||
|
if (!folder.mkdirs()) {
|
||||||
|
throw new IllegalStateException("Failed to create data folder");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return folder;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -93,11 +93,16 @@ public class AbilityManager
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Load the custom abilities from the specified directory.
|
* Load the custom abilities from the specified directory.
|
||||||
* @param classDir a directory of .class (and/or .java) files
|
* @param dataDir main plugin data folder
|
||||||
*/
|
*/
|
||||||
public static void loadCustomAbilities(File classDir) {
|
public static void loadCustomAbilities(File dataDir) {
|
||||||
if (abilities == null) abilities = new HashMap<>();
|
if (abilities == null) abilities = new HashMap<>();
|
||||||
|
|
||||||
|
File classDir = new File(dataDir, "abilities");
|
||||||
|
if (!classDir.exists()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Grab the source directory.
|
// Grab the source directory.
|
||||||
File javaDir = new File(classDir, "src");
|
File javaDir = new File(classDir, "src");
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user