2018-10-31 14:09:56 +01:00
|
|
|
package world.bentobox.level;
|
2017-10-21 20:32:32 +02:00
|
|
|
|
2020-04-19 19:46:41 +02:00
|
|
|
import java.io.File;
|
|
|
|
import java.io.IOException;
|
2017-10-25 01:24:43 +02:00
|
|
|
import java.util.HashMap;
|
2018-02-19 22:06:58 +01:00
|
|
|
import java.util.Map;
|
2020-02-02 05:24:08 +01:00
|
|
|
import java.util.Objects;
|
2017-10-22 04:52:11 +02:00
|
|
|
import java.util.UUID;
|
2017-10-21 20:32:32 +02:00
|
|
|
|
2020-02-02 04:56:28 +01:00
|
|
|
import org.bukkit.Bukkit;
|
2018-05-26 04:59:44 +02:00
|
|
|
import org.bukkit.World;
|
2020-04-20 00:17:34 +02:00
|
|
|
import org.bukkit.configuration.ConfigurationSection;
|
2020-04-19 19:46:41 +02:00
|
|
|
import org.bukkit.configuration.InvalidConfigurationException;
|
|
|
|
import org.bukkit.configuration.file.YamlConfiguration;
|
2019-12-01 03:30:08 +01:00
|
|
|
import org.eclipse.jdt.annotation.NonNull;
|
2019-08-09 01:30:10 +02:00
|
|
|
import org.eclipse.jdt.annotation.Nullable;
|
2018-05-26 04:59:44 +02:00
|
|
|
|
2019-01-03 19:27:20 +01:00
|
|
|
import world.bentobox.bentobox.api.addons.Addon;
|
2020-04-19 23:02:45 +02:00
|
|
|
import world.bentobox.bentobox.api.addons.GameModeAddon;
|
2020-04-19 19:46:41 +02:00
|
|
|
import world.bentobox.bentobox.api.configuration.Config;
|
2019-01-03 19:27:20 +01:00
|
|
|
import world.bentobox.bentobox.api.user.User;
|
|
|
|
import world.bentobox.bentobox.database.Database;
|
|
|
|
import world.bentobox.bentobox.database.objects.Island;
|
2020-01-28 17:32:52 +01:00
|
|
|
import world.bentobox.level.calculators.CalcIslandLevel;
|
2018-12-23 21:03:08 +01:00
|
|
|
import world.bentobox.level.commands.admin.AdminLevelCommand;
|
|
|
|
import world.bentobox.level.commands.admin.AdminTopCommand;
|
|
|
|
import world.bentobox.level.commands.island.IslandLevelCommand;
|
|
|
|
import world.bentobox.level.commands.island.IslandTopCommand;
|
2019-02-27 23:13:17 +01:00
|
|
|
import world.bentobox.level.commands.island.IslandValueCommand;
|
2020-04-19 19:46:41 +02:00
|
|
|
import world.bentobox.level.config.BlockConfig;
|
|
|
|
import world.bentobox.level.config.ConfigSettings;
|
2019-02-03 05:44:15 +01:00
|
|
|
import world.bentobox.level.listeners.IslandTeamListeners;
|
2019-02-03 06:43:27 +01:00
|
|
|
import world.bentobox.level.listeners.JoinLeaveListener;
|
2019-01-03 19:27:20 +01:00
|
|
|
import world.bentobox.level.objects.LevelsData;
|
2018-12-23 21:20:15 +01:00
|
|
|
import world.bentobox.level.requests.LevelRequestHandler;
|
2019-02-27 23:14:20 +01:00
|
|
|
import world.bentobox.level.requests.TopTenRequestHandler;
|
|
|
|
|
2017-10-25 01:24:43 +02:00
|
|
|
/**
|
2018-12-23 21:03:08 +01:00
|
|
|
* Addon to BSkyBlock/AcidIsland that enables island level scoring and top ten functionality
|
2017-10-25 01:24:43 +02:00
|
|
|
* @author tastybento
|
|
|
|
*
|
|
|
|
*/
|
2017-12-28 17:43:07 +01:00
|
|
|
public class Level extends Addon {
|
2018-04-16 02:32:09 +02:00
|
|
|
|
2020-04-19 19:46:41 +02:00
|
|
|
private static Addon addon;
|
|
|
|
|
2018-02-14 05:48:27 +01:00
|
|
|
// Settings
|
2020-04-19 19:46:41 +02:00
|
|
|
private ConfigSettings settings;
|
|
|
|
private Config<ConfigSettings> configObject = new Config<>(this, ConfigSettings.class);
|
2017-10-22 08:09:21 +02:00
|
|
|
|
2020-04-19 23:02:45 +02:00
|
|
|
/**
|
|
|
|
* @param settings the settings to set
|
|
|
|
*/
|
|
|
|
public void setSettings(ConfigSettings settings) {
|
|
|
|
this.settings = settings;
|
|
|
|
}
|
|
|
|
|
2017-10-25 01:24:43 +02:00
|
|
|
// Database handler for level data
|
2018-08-06 16:43:17 +02:00
|
|
|
private Database<LevelsData> handler;
|
2017-10-22 08:09:21 +02:00
|
|
|
|
2018-07-28 22:38:04 +02:00
|
|
|
// A cache of island levels.
|
2018-05-26 04:59:44 +02:00
|
|
|
private Map<UUID, LevelsData> levelsCache;
|
2017-10-25 01:24:43 +02:00
|
|
|
|
|
|
|
// The Top Ten object
|
|
|
|
private TopTen topTen;
|
2018-04-16 02:32:09 +02:00
|
|
|
|
2017-12-26 17:41:37 +01:00
|
|
|
// Level calculator
|
2019-08-09 02:12:12 +02:00
|
|
|
private LevelPresenter levelPresenter;
|
2017-10-22 08:09:21 +02:00
|
|
|
|
2020-04-19 19:46:41 +02:00
|
|
|
|
|
|
|
|
|
|
|
private BlockConfig blockConfig;
|
|
|
|
|
2018-02-19 22:06:58 +01:00
|
|
|
/**
|
|
|
|
* Calculates a user's island
|
2018-07-28 22:38:04 +02:00
|
|
|
* @param world - the world where this island is
|
|
|
|
* @param user - the user who is asking, or null if none
|
|
|
|
* @param playerUUID - the target island member's UUID
|
2018-02-19 22:06:58 +01:00
|
|
|
*/
|
2019-12-01 03:30:08 +01:00
|
|
|
public void calculateIslandLevel(World world, @Nullable User user, @NonNull UUID playerUUID) {
|
2019-08-09 02:12:12 +02:00
|
|
|
levelPresenter.calculateIslandLevel(world, user, playerUUID);
|
2018-02-19 22:06:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2019-12-01 03:30:08 +01:00
|
|
|
* Get level from cache for a player.
|
|
|
|
* @param targetPlayer - target player UUID
|
|
|
|
* @return Level of player or zero if player is unknown or UUID is null
|
2018-02-19 22:06:58 +01:00
|
|
|
*/
|
2019-12-01 03:30:08 +01:00
|
|
|
public long getIslandLevel(World world, @Nullable UUID targetPlayer) {
|
|
|
|
if (targetPlayer == null) return 0L;
|
2018-05-26 04:59:44 +02:00
|
|
|
LevelsData ld = getLevelsData(targetPlayer);
|
|
|
|
return ld == null ? 0L : ld.getLevel(world);
|
|
|
|
}
|
2018-05-27 03:20:33 +02:00
|
|
|
|
2018-08-05 00:55:21 +02:00
|
|
|
/**
|
|
|
|
* Load a player from the cache or database
|
|
|
|
* @param targetPlayer - UUID of target player
|
|
|
|
* @return LevelsData object or null if not found
|
|
|
|
*/
|
2020-04-19 23:02:45 +02:00
|
|
|
@Nullable
|
2019-12-01 03:30:08 +01:00
|
|
|
public LevelsData getLevelsData(@NonNull UUID targetPlayer) {
|
2018-08-05 00:55:21 +02:00
|
|
|
// Get from database if not in cache
|
|
|
|
if (!levelsCache.containsKey(targetPlayer) && handler.objectExists(targetPlayer.toString())) {
|
2020-02-02 05:24:08 +01:00
|
|
|
LevelsData ld = handler.loadObject(targetPlayer.toString());
|
|
|
|
if (ld != null) {
|
|
|
|
levelsCache.put(targetPlayer, ld);
|
|
|
|
} else {
|
|
|
|
handler.deleteID(targetPlayer.toString());
|
|
|
|
}
|
2018-08-05 00:55:21 +02:00
|
|
|
}
|
|
|
|
// Return cached value or null
|
|
|
|
return levelsCache.get(targetPlayer);
|
2018-02-19 22:06:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return the settings
|
|
|
|
*/
|
2020-04-19 19:46:41 +02:00
|
|
|
public ConfigSettings getSettings() {
|
2018-02-19 22:06:58 +01:00
|
|
|
return settings;
|
|
|
|
}
|
2018-04-16 02:32:09 +02:00
|
|
|
|
2018-02-19 22:06:58 +01:00
|
|
|
public TopTen getTopTen() {
|
|
|
|
return topTen;
|
|
|
|
}
|
|
|
|
|
2019-08-09 02:12:12 +02:00
|
|
|
/**
|
|
|
|
* @return the levelPresenter
|
|
|
|
*/
|
|
|
|
public LevelPresenter getLevelPresenter() {
|
|
|
|
return levelPresenter;
|
|
|
|
}
|
|
|
|
|
2018-02-19 22:06:58 +01:00
|
|
|
@Override
|
|
|
|
public void onDisable(){
|
|
|
|
// Save the cache
|
|
|
|
if (levelsCache != null) {
|
2018-08-26 17:21:41 +02:00
|
|
|
save();
|
2018-02-19 22:06:58 +01:00
|
|
|
}
|
2018-05-27 03:20:33 +02:00
|
|
|
if (topTen != null) {
|
|
|
|
topTen.saveTopTen();
|
|
|
|
}
|
2018-02-19 22:06:58 +01:00
|
|
|
}
|
|
|
|
|
2020-04-19 19:46:41 +02:00
|
|
|
@Override
|
|
|
|
public void onLoad() {
|
|
|
|
// Save the default config from config.yml
|
|
|
|
saveDefaultConfig();
|
|
|
|
// Load settings from config.yml. This will check if there are any issues with it too.
|
2020-04-20 00:17:34 +02:00
|
|
|
if (loadSettings()) {
|
|
|
|
configObject.saveConfigObject(settings);
|
|
|
|
}
|
2020-04-19 19:46:41 +02:00
|
|
|
}
|
|
|
|
|
2020-04-20 00:17:34 +02:00
|
|
|
private boolean loadSettings() {
|
2020-04-19 19:46:41 +02:00
|
|
|
// Load settings again to get worlds
|
|
|
|
settings = configObject.loadConfigObject();
|
|
|
|
if (settings == null) {
|
|
|
|
// Disable
|
|
|
|
logError("Level settings could not load! Addon disabled.");
|
|
|
|
setState(State.DISABLED);
|
2020-04-20 00:17:34 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
// Check for legacy blocks and limits etc.
|
|
|
|
if (getConfig().isConfigurationSection("blocks")
|
|
|
|
|| getConfig().isConfigurationSection("limits")
|
|
|
|
|| getConfig().isConfigurationSection("worlds")) {
|
|
|
|
logWarning("Converting old config.yml format - shifting blocks, limits and worlds to blockconfig.yml");
|
|
|
|
File blockConfigFile = new File(this.getDataFolder(), "blockconfig.yml");
|
|
|
|
if (blockConfigFile.exists()) {
|
|
|
|
logError("blockconfig.yml already exists! Saving config as blockconfig.yml.2");
|
|
|
|
blockConfigFile = new File(this.getDataFolder(), "blockconfig.yml.2");
|
|
|
|
}
|
|
|
|
YamlConfiguration blockConfig = new YamlConfiguration();
|
|
|
|
copyConfigSection(blockConfig, "limits");
|
|
|
|
copyConfigSection(blockConfig, "blocks");
|
|
|
|
copyConfigSection(blockConfig, "worlds");
|
|
|
|
try {
|
|
|
|
blockConfig.save(blockConfigFile);
|
|
|
|
} catch (IOException e) {
|
|
|
|
logError("Could not save! " + e.getMessage());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
private void copyConfigSection(YamlConfiguration blockConfig, String sectionName) {
|
|
|
|
ConfigurationSection section = getConfig().getConfigurationSection(sectionName);
|
|
|
|
for (String k:section.getKeys(true)) {
|
|
|
|
blockConfig.set(sectionName + "." + k, section.get(k));
|
2020-04-19 19:46:41 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void loadBlockSettings() {
|
|
|
|
// Save the default blockconfig.yml
|
|
|
|
this.saveResource("blockconfig.yml", false);
|
|
|
|
|
|
|
|
YamlConfiguration blockValues = new YamlConfiguration();
|
|
|
|
try {
|
2020-04-20 00:17:34 +02:00
|
|
|
File file = new File(this.getDataFolder(), "blockconfig.yml");
|
|
|
|
blockValues.load(file);
|
|
|
|
// Load the block config class
|
|
|
|
blockConfig = new BlockConfig(this, blockValues, file);
|
2020-04-19 19:46:41 +02:00
|
|
|
} catch (IOException | InvalidConfigurationException e) {
|
|
|
|
// Disable
|
|
|
|
logError("Level blockconfig.yml settings could not load! Addon disabled.");
|
|
|
|
setState(State.DISABLED);
|
|
|
|
return;
|
|
|
|
}
|
2020-04-20 00:17:34 +02:00
|
|
|
|
2020-04-19 19:46:41 +02:00
|
|
|
}
|
|
|
|
|
2017-10-21 20:32:32 +02:00
|
|
|
@Override
|
2017-10-22 04:52:11 +02:00
|
|
|
public void onEnable() {
|
2020-04-19 19:46:41 +02:00
|
|
|
addon = this;
|
|
|
|
loadBlockSettings();
|
2017-10-25 01:24:43 +02:00
|
|
|
// Get the BSkyBlock database
|
2017-10-22 08:09:21 +02:00
|
|
|
// Set up the database handler to store and retrieve Island classes
|
2017-10-23 04:09:59 +02:00
|
|
|
// Note that these are saved by the BSkyBlock database
|
2018-08-06 16:43:17 +02:00
|
|
|
handler = new Database<>(this, LevelsData.class);
|
2017-10-25 01:24:43 +02:00
|
|
|
// Initialize the cache
|
|
|
|
levelsCache = new HashMap<>();
|
2017-12-26 17:41:37 +01:00
|
|
|
// Load the calculator
|
2019-08-09 02:12:12 +02:00
|
|
|
levelPresenter = new LevelPresenter(this, this.getPlugin());
|
2017-10-25 01:24:43 +02:00
|
|
|
// Start the top ten and register it for clicks
|
|
|
|
topTen = new TopTen(this);
|
2017-12-28 04:17:44 +01:00
|
|
|
registerListener(topTen);
|
2020-04-19 23:02:45 +02:00
|
|
|
// Register commands for GameModes
|
2019-01-16 04:35:08 +01:00
|
|
|
getPlugin().getAddonsManager().getGameModeAddons().stream()
|
2020-04-19 23:02:45 +02:00
|
|
|
.filter(gm -> settings
|
|
|
|
.getGameModes()
|
|
|
|
.contains(gm
|
|
|
|
.getDescription()
|
|
|
|
.getName()))
|
2019-01-16 04:35:08 +01:00
|
|
|
.forEach(gm -> {
|
2019-02-04 07:30:27 +01:00
|
|
|
log("Level hooking into " + gm.getDescription().getName());
|
2020-04-19 23:02:45 +02:00
|
|
|
registerCommands(gm);
|
2019-02-02 21:31:14 +01:00
|
|
|
// Register placeholders
|
|
|
|
if (getPlugin().getPlaceholdersManager() != null) {
|
2020-04-19 23:02:45 +02:00
|
|
|
registerPlaceholders(gm);
|
2019-02-02 21:31:14 +01:00
|
|
|
}
|
2018-05-27 03:20:33 +02:00
|
|
|
});
|
2018-07-29 06:42:29 +02:00
|
|
|
|
2018-07-28 22:38:04 +02:00
|
|
|
// Register new island listener
|
2019-02-03 05:44:15 +01:00
|
|
|
registerListener(new IslandTeamListeners(this));
|
2018-08-05 00:55:21 +02:00
|
|
|
registerListener(new JoinLeaveListener(this));
|
2018-12-23 21:20:15 +01:00
|
|
|
|
|
|
|
// Register request handlers
|
|
|
|
registerRequestHandler(new LevelRequestHandler(this));
|
2019-02-27 23:14:20 +01:00
|
|
|
registerRequestHandler(new TopTenRequestHandler(this));
|
2018-12-23 21:20:15 +01:00
|
|
|
|
2020-01-28 17:32:52 +01:00
|
|
|
// Check if WildStackers is enabled on the server
|
2020-04-19 23:02:45 +02:00
|
|
|
// I only added support for counting blocks into the island level
|
|
|
|
// Someone else can PR if they want spawners added to the Leveling system :)
|
|
|
|
CalcIslandLevel.stackersEnabled = Bukkit.getPluginManager().getPlugin("WildStacker") != null;
|
2020-01-28 17:32:52 +01:00
|
|
|
|
2017-10-23 04:09:59 +02:00
|
|
|
// Done
|
2017-10-21 20:32:32 +02:00
|
|
|
}
|
2017-10-22 08:09:21 +02:00
|
|
|
|
2020-04-19 23:02:45 +02:00
|
|
|
private void registerPlaceholders(GameModeAddon gm) {
|
|
|
|
// Island Level
|
|
|
|
getPlugin().getPlaceholdersManager().registerPlaceholder(this,
|
|
|
|
gm.getDescription().getName().toLowerCase() + "_island_level",
|
|
|
|
user -> getLevelPresenter().getLevelString(getIslandLevel(gm.getOverWorld(), user.getUniqueId())));
|
|
|
|
|
|
|
|
// Visited Island Level
|
|
|
|
getPlugin().getPlaceholdersManager().registerPlaceholder(this,
|
|
|
|
gm.getDescription().getName().toLowerCase() + "_visited_island_level", user -> getVisitedIslandLevel(gm, user));
|
|
|
|
|
|
|
|
// Top Ten
|
|
|
|
for (int i = 1; i <= 10; i++) {
|
|
|
|
final int rank = i;
|
|
|
|
// Value
|
|
|
|
getPlugin().getPlaceholdersManager().registerPlaceholder(this,
|
2020-04-20 00:17:34 +02:00
|
|
|
gm.getDescription().getName().toLowerCase() + "_top_value_" + rank, u -> String.valueOf(getTopTen().getTopTenLevel(gm.getOverWorld(), rank)));
|
2020-04-19 23:02:45 +02:00
|
|
|
|
|
|
|
// Name
|
|
|
|
getPlugin().getPlaceholdersManager().registerPlaceholder(this,
|
|
|
|
gm.getDescription().getName().toLowerCase() + "_top_name_" + rank,
|
2020-04-20 00:17:34 +02:00
|
|
|
u -> getPlayers().getName(getTopTen().getTopTenUUID(gm.getOverWorld(), rank)));
|
2020-04-19 23:02:45 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
private String getVisitedIslandLevel(GameModeAddon gm, User user) {
|
|
|
|
return getIslands().getIslandAt(user.getLocation())
|
2020-04-20 00:17:34 +02:00
|
|
|
.map(island -> getLevelPresenter().getLevelString(getIslandLevel(gm.getOverWorld(), island.getOwner())))
|
2020-04-19 23:02:45 +02:00
|
|
|
.orElse("0");
|
|
|
|
}
|
|
|
|
|
|
|
|
private void registerCommands(GameModeAddon gm) {
|
|
|
|
gm.getAdminCommand().ifPresent(adminCommand -> {
|
|
|
|
new AdminLevelCommand(this, adminCommand);
|
|
|
|
new AdminTopCommand(this, adminCommand);
|
|
|
|
});
|
|
|
|
gm.getPlayerCommand().ifPresent(playerCmd -> {
|
|
|
|
new IslandLevelCommand(this, playerCmd);
|
|
|
|
new IslandTopCommand(this, playerCmd);
|
|
|
|
new IslandValueCommand(this, playerCmd);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2017-10-22 08:09:21 +02:00
|
|
|
/**
|
|
|
|
* Save the levels to the database
|
|
|
|
*/
|
2018-08-26 17:21:41 +02:00
|
|
|
private void save(){
|
2020-02-02 05:24:08 +01:00
|
|
|
// Remove any potential null values from the cache
|
|
|
|
levelsCache.values().removeIf(Objects::isNull);
|
2018-08-05 00:55:21 +02:00
|
|
|
levelsCache.values().forEach(handler::saveObject);
|
2017-10-21 20:32:32 +02:00
|
|
|
}
|
|
|
|
|
2017-10-22 04:52:11 +02:00
|
|
|
/**
|
2018-02-19 22:06:58 +01:00
|
|
|
* Sets the player's level to a value
|
2018-08-26 17:21:41 +02:00
|
|
|
* @param world - world
|
|
|
|
* @param targetPlayer - target player
|
|
|
|
* @param level - level
|
2017-10-22 04:52:11 +02:00
|
|
|
*/
|
2018-07-28 22:38:04 +02:00
|
|
|
public void setIslandLevel(World world, UUID targetPlayer, long level) {
|
2019-01-07 16:29:03 +01:00
|
|
|
if (world == null || targetPlayer == null) {
|
|
|
|
this.logError("Level: request to store a null " + world + " " + targetPlayer);
|
|
|
|
return;
|
|
|
|
}
|
2018-05-26 04:59:44 +02:00
|
|
|
LevelsData ld = getLevelsData(targetPlayer);
|
|
|
|
if (ld == null) {
|
|
|
|
ld = new LevelsData(targetPlayer, level, world);
|
|
|
|
} else {
|
|
|
|
ld.setLevel(world, level);
|
|
|
|
}
|
2017-10-25 01:24:43 +02:00
|
|
|
// Add to cache
|
2018-05-26 04:59:44 +02:00
|
|
|
levelsCache.put(targetPlayer, ld);
|
2018-07-28 22:38:04 +02:00
|
|
|
topTen.addEntry(world, targetPlayer, getIslandLevel(world, targetPlayer));
|
2019-02-03 18:36:26 +01:00
|
|
|
handler.saveObject(ld);
|
2018-07-28 22:38:04 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2019-02-22 04:56:44 +01:00
|
|
|
* Zeros the initial island level
|
2018-07-28 22:38:04 +02:00
|
|
|
* @param island - island
|
|
|
|
* @param level - initial calculated island level
|
|
|
|
*/
|
2019-12-01 03:30:08 +01:00
|
|
|
public void setInitialIslandLevel(@NonNull Island island, long level) {
|
2019-01-07 16:29:03 +01:00
|
|
|
if (island.getWorld() == null || island.getOwner() == null) {
|
|
|
|
this.logError("Level: request to store a null (initial) " + island.getWorld() + " " + island.getOwner());
|
|
|
|
return;
|
|
|
|
}
|
2019-02-22 04:56:44 +01:00
|
|
|
setIslandLevel(island.getWorld(), island.getOwner(), 0L);
|
|
|
|
levelsCache.get(island.getOwner()).setInitialLevel(island.getWorld(), level);
|
2017-10-22 04:52:11 +02:00
|
|
|
}
|
|
|
|
|
2019-02-22 04:56:44 +01:00
|
|
|
/**
|
|
|
|
* Get the initial island level
|
|
|
|
* @param island - island
|
|
|
|
* @return level or 0 by default
|
|
|
|
*/
|
2019-12-01 03:30:08 +01:00
|
|
|
public long getInitialIslandLevel(@NonNull Island island) {
|
2020-02-02 05:24:08 +01:00
|
|
|
// Remove any potential null values from the cache
|
|
|
|
levelsCache.values().removeIf(Objects::isNull);
|
2019-02-22 04:56:44 +01:00
|
|
|
return levelsCache.containsKey(island.getOwner()) ? levelsCache.get(island.getOwner()).getInitialLevel(island.getWorld()) : 0L;
|
|
|
|
}
|
2019-08-09 01:30:10 +02:00
|
|
|
|
2019-12-01 03:30:08 +01:00
|
|
|
/**
|
|
|
|
* @return database handler
|
|
|
|
*/
|
|
|
|
@Nullable
|
2018-08-06 16:43:17 +02:00
|
|
|
public Database<LevelsData> getHandler() {
|
2018-04-16 02:32:09 +02:00
|
|
|
return handler;
|
|
|
|
}
|
|
|
|
|
2020-04-19 19:46:41 +02:00
|
|
|
public static Addon getInstance() {
|
|
|
|
return addon;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return the blockConfig
|
|
|
|
*/
|
|
|
|
public BlockConfig getBlockConfig() {
|
|
|
|
return blockConfig;
|
|
|
|
}
|
|
|
|
|
2017-10-21 20:32:32 +02:00
|
|
|
}
|