Fixed bug where worlds were not existing when islands loaded.

If islands are loaded before the world exists the island's world becomes
null. If an addon is creating an island then it must be loaded before
islands.

Also refactored some of the addon loading code.
This commit is contained in:
tastybento 2018-05-29 16:59:52 -07:00
parent 3b7b7fa557
commit 6b6ec4c697
7 changed files with 47 additions and 79 deletions

View File

@ -4,7 +4,6 @@ import org.bukkit.World;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;
import us.tastybento.bskyblock.api.addons.Addon;
import us.tastybento.bskyblock.api.configuration.WorldSettings;
import us.tastybento.bskyblock.api.placeholders.PlaceholderHandler;
import us.tastybento.bskyblock.api.user.Notifier;
@ -112,28 +111,27 @@ public class BSkyBlock extends JavaPlugin {
// Set up commands
new IslandCommand();
new AdminCommand();
// Locales manager must be loaded before addons
localesManager = new LocalesManager(instance);
PlaceholderHandler.register(instance);
// Load addons. Addons may load worlds, so they must go before islands are loaded.
addonsManager = new AddonsManager(instance);
addonsManager.loadAddons();
// Enable addons
addonsManager.enableAddons();
getServer().getScheduler().runTask(instance, () -> {
// Load Flags
flagsManager = new FlagsManager(instance);
// Load islands from database
islandsManager.load();
localesManager = new LocalesManager(instance);
PlaceholderHandler.register(instance);
// Register Listeners
registerListeners();
// Load addons
addonsManager = new AddonsManager(instance);
addonsManager.loadAddons();
// Enable addons
addonsManager.enableAddons();
// Load islands from database - need to wait until all the worlds are loaded
islandsManager.load();
// Save islands & players data asynchronously every X minutes
getSettings().setDatabaseBackupPeriod(10 * 60 * 20);
instance.getServer().getScheduler().runTaskTimer(instance, () -> {

View File

@ -104,9 +104,9 @@ public class AddonClassLoader extends URLClassLoader {
* @param checkGlobal
* @return Class
*/
public Class<?> findClass(String name, boolean checkGlobal) throws ClassNotFoundException {
public Class<?> findClass(String name, boolean checkGlobal) {
if (name.startsWith("us.tastybento.")) {
throw new ClassNotFoundException(name);
return null;
}
Class<?> result = classes.get(name);
if (result == null) {
@ -114,7 +114,11 @@ public class AddonClassLoader extends URLClassLoader {
result = loader.getClassByName(name);
}
if (result == null) {
result = super.findClass(name);
try {
result = super.findClass(name);
} catch (ClassNotFoundException e) {
return null;
}
if (result != null) {
loader.setClass(name, result);
}

View File

@ -44,6 +44,7 @@ public class BSBDatabase<T> {
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException
| InvocationTargetException | ClassNotFoundException | IntrospectionException e) {
logger.severe(() -> "Could not load objects from database! Error: " + e.getMessage());
e.printStackTrace();
}
return result;
}

View File

@ -470,6 +470,9 @@ public class Island implements DataObject {
* @param center the center to set
*/
public void setCenter(Location center) {
if (center != null) {
this.world = center.getWorld();
}
this.center = center;
}
@ -684,7 +687,7 @@ public class Island implements DataObject {
}
return true;
}
/**
* Shows the members of this island
* @param plugin
@ -704,6 +707,6 @@ public class Island implements DataObject {
});
}
}
}

View File

@ -16,8 +16,6 @@ import java.util.jar.JarFile;
import org.bukkit.Bukkit;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.bukkit.configuration.serialization.ConfigurationSerialization;
import org.bukkit.plugin.InvalidDescriptionException;
import us.tastybento.bskyblock.BSkyBlock;
@ -84,16 +82,7 @@ public class AddonsManager {
* @return Optional addon object
*/
public Optional<Addon> getAddonByName(String name){
if(name.equals("")) {
return Optional.empty();
}
for(Addon addon : addons){
if(addon.getDescription().getName().contains(name)) {
return Optional.of(addon);
}
}
return Optional.empty();
return Optional.ofNullable(addons.stream().filter(a -> a.getDescription().getName().contains(name)).findFirst().orElse(null));
}
private void loadAddon(File f) throws InvalidAddonFormatException, InvalidAddonInheritException, InvalidDescriptionException {
@ -101,10 +90,9 @@ public class AddonsManager {
Addon addon = null;
// Check that this is a jar
if (!f.getName().endsWith(".jar")) {
return;
throw new IOException("Filename must end in .jar. Name is '" + f.getName() + "'");
}
try (JarFile jar = new JarFile(f)) {
// Obtain the addon.yml file
JarEntry entry = jar.getJarEntry("addon.yml");
if (entry == null) {
@ -133,15 +121,13 @@ public class AddonsManager {
addon.saveResource(localeFile, localeDir, false, true);
}
plugin.getLocalesManager().loadLocales(addon.getDescription().getName());
// Fire the load event
Bukkit.getPluginManager().callEvent(AddonEvent.builder().addon(addon).reason(AddonEvent.Reason.LOAD).build());
// Add it to the list of addons
addons.add(addon);
// Inform the console
plugin.log("Loading BSkyBlock addon " + addon.getDescription().getName() + "...");
plugin.log("Loaded BSkyBlock addon " + addon.getDescription().getName() + "...");
}
} catch (Exception e) {
@ -149,7 +135,6 @@ public class AddonsManager {
plugin.log(f.getName() + "is not a jarfile, ignoring...");
}
}
}
/**
@ -166,9 +151,7 @@ public class AddonsManager {
loader.forEach(l -> {
try {
l.close();
} catch (IOException e) {
// Do nothing
}
} catch (IOException ignore) {}
});
}
@ -190,22 +173,8 @@ public class AddonsManager {
* @param name - name of the class
* @return Class - the class
*/
public Class<?> getClassByName(final String name) {
Class<?> cachedClass = classes.get(name);
if (cachedClass != null) {
return cachedClass;
} else {
for (AddonClassLoader l : loader) {
try {
cachedClass = l.findClass(name, false);
} catch (ClassNotFoundException cnfe) {}
if (cachedClass != null) {
return cachedClass;
}
}
}
return null;
public Class<?> getClassByName(final String name) {
return classes.getOrDefault(name, loader.stream().map(l -> l.findClass(name, false)).filter(c -> c != null).findFirst().orElse(null));
}
/**
@ -216,14 +185,16 @@ public class AddonsManager {
* @param clazz - the class
*/
public void setClass(final String name, final Class<?> clazz) {
classes.putIfAbsent(name, clazz);
/*
if (!classes.containsKey(name)) {
classes.put(name, clazz);
if (ConfigurationSerializable.class.isAssignableFrom(clazz)) {
Class<? extends ConfigurationSerializable> serializable = clazz.asSubclass(ConfigurationSerializable.class);
ConfigurationSerialization.registerClass(serializable);
}
}
}*/
}
/**

View File

@ -281,7 +281,7 @@ public class IslandsManager {
public Island getIsland(World world, User user){
return islandCache.get(world, user.getUniqueId());
}
/**
* Gets the island for this player. If they are in a team, the team island is returned
* @param world - world to check
@ -467,7 +467,7 @@ public class IslandsManager {
public boolean hasIsland(World world, User user) {
return islandCache.hasIsland(world, user.getUniqueId());
}
/**
* Checks if a player has an island in the world
* @param world - world to check
@ -477,7 +477,7 @@ public class IslandsManager {
public boolean hasIsland(World world, UUID uuid) {
return islandCache.hasIsland(world, uuid);
}
/**
* This teleports player to their island. If not safe place can be found
* then the player is sent to spawn via /spawn command
@ -619,14 +619,7 @@ public class IslandsManager {
*/
public void load(){
islandCache.clear();
spawn = null;
try {
for (Island island : handler.loadObjects()) {
islandCache.addIsland(island);
}
} catch (Exception e) {
plugin.logError("Could not load islands to cache! " + e.getMessage());
}
handler.loadObjects().forEach(islandCache::addIsland);
}
/**
@ -684,7 +677,7 @@ public class IslandsManager {
public void removePlayer(World world, User user) {
islandCache.removePlayer(world, user.getUniqueId());
}
/**
* Removes this player from any and all islands in world
* @param world - world
@ -793,7 +786,7 @@ public class IslandsManager {
public boolean inTeam(World world, UUID playerUUID) {
return getMembers(world, playerUUID).size() > 1;
}
/**
* Makes a new leader for an island
@ -804,7 +797,7 @@ public class IslandsManager {
public void makeLeader(World world, User user, UUID targetUUID, String permPrefix) {
makeLeader(user, targetUUID, getIsland(world, targetUUID), permPrefix);
}
/**
* Makes a new leader for an island
* @param user - requester
@ -813,7 +806,7 @@ public class IslandsManager {
*/
public void makeLeader(User user, UUID targetUUID, Island island, String permPrefix) {
islandCache.setOwner(island, targetUUID);
user.sendMessage("commands.island.team.setowner.name-is-the-owner", "[name]", plugin.getPlayers().getName(targetUUID));
// Check if online
@ -832,7 +825,7 @@ public class IslandsManager {
island.setProtectionRange(range);
}
}
}

View File

@ -39,12 +39,10 @@ public class IslandCache {
* @return true if successfully added, false if not
*/
public boolean addIsland(Island island) {
islandsByLocation.put(island.getCenter(), island);
islandsByLocation.put(island.getCenter(), island);
islandsByUUID.putIfAbsent(island.getWorld(), new HashMap<>());
islandsByUUID.get(island.getWorld()).put(island.getOwner(), island);
for (UUID member: island.getMemberSet()) {
islandsByUUID.get(island.getWorld()).put(member, island);
}
island.getMemberSet().forEach(member -> islandsByUUID.get(island.getWorld()).put(member, island));
return addToGrid(island);
}