mirror of
https://github.com/amalthea-mc/ShopChest.git
synced 2024-11-22 02:12:25 +00:00
Load/unload shops on chunk load/unload
This breaks shop limits, only loaded shops are counted at the moment
This commit is contained in:
parent
f15fdc781f
commit
c595b574ec
@ -43,6 +43,8 @@ import me.wiefferink.areashop.AreaShop;
|
||||
import net.milkbowl.vault.economy.Economy;
|
||||
import org.bstats.bukkit.Metrics;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||
@ -65,6 +67,7 @@ import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class ShopChest extends JavaPlugin {
|
||||
|
||||
@ -437,13 +440,26 @@ public class ShopChest extends JavaPlugin {
|
||||
* Initializes the shops
|
||||
*/
|
||||
private void initializeShops() {
|
||||
debug("Initializing Shops...");
|
||||
shopUtils.reloadShops(false, true, new Callback<Integer>(this) {
|
||||
getShopDatabase().connect(new Callback<Integer>(this) {
|
||||
@Override
|
||||
public void onResult(Integer result) {
|
||||
Bukkit.getServer().getPluginManager().callEvent(new ShopInitializedEvent(result));
|
||||
getLogger().info("Initialized " + result + " Shops");
|
||||
debug("Initialized " + result + " Shops");
|
||||
Chunk[] loadedChunks = getServer().getWorlds().stream().map(World::getLoadedChunks)
|
||||
.flatMap(Stream::of).toArray(Chunk[]::new);
|
||||
|
||||
shopUtils.loadShops(loadedChunks, new Callback<Integer>(ShopChest.this) {
|
||||
@Override
|
||||
public void onResult(Integer result) {
|
||||
getServer().getPluginManager().callEvent(new ShopInitializedEvent(result));
|
||||
getLogger().info("Loaded " + result + " shops in already loaded chunks");
|
||||
debug("Loaded " + result + " shops in already loaded chunks");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Throwable throwable) {
|
||||
getLogger().severe("Failed to load shops in already loaded chunks");
|
||||
if (throwable != null) getLogger().severe(throwable.getMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -26,8 +26,10 @@ import de.epiceric.shopchest.utils.ClickType.CreateClickType;
|
||||
import de.epiceric.shopchest.utils.ClickType.SelectClickType;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
@ -36,7 +38,9 @@ import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
class ShopCommandExecutor implements CommandExecutor {
|
||||
|
||||
@ -191,12 +195,40 @@ class ShopCommandExecutor implements CommandExecutor {
|
||||
return;
|
||||
}
|
||||
|
||||
shopUtils.reloadShops(true, true, new Callback<Integer>(plugin) {
|
||||
// Reload configurations
|
||||
plugin.getShopChestConfig().reload(false, true, true);
|
||||
plugin.getHologramFormat().reload();
|
||||
plugin.getUpdater().restart();
|
||||
|
||||
// Remove all shops
|
||||
Iterator<Shop> iter = shopUtils.getShops().iterator();
|
||||
while (iter.hasNext()) {
|
||||
shopUtils.removeShop(iter.next(), false);
|
||||
}
|
||||
|
||||
Chunk[] loadedChunks = Bukkit.getWorlds().stream().map(World::getLoadedChunks)
|
||||
.flatMap(Stream::of).toArray(Chunk[]::new);
|
||||
|
||||
// Reconnect to the database and re-load shops in loaded chunks
|
||||
plugin.getShopDatabase().connect(new Callback<Integer>(plugin) {
|
||||
@Override
|
||||
public void onResult(Integer result) {
|
||||
sender.sendMessage(LanguageUtils.getMessage(Message.RELOADED_SHOPS,
|
||||
new Replacement(Placeholder.AMOUNT, String.valueOf(result))));
|
||||
plugin.debug(sender.getName() + " has reloaded " + result + " shops");
|
||||
shopUtils.loadShops(loadedChunks, new Callback<Integer>(plugin) {
|
||||
@Override
|
||||
public void onResult(Integer result) {
|
||||
sender.sendMessage(LanguageUtils.getMessage(Message.RELOADED_SHOPS,
|
||||
new Replacement(Placeholder.AMOUNT, String.valueOf(result))));
|
||||
plugin.debug(sender.getName() + " has reloaded " + result + " shops");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Throwable throwable) {
|
||||
sender.sendMessage(LanguageUtils.getMessage(Message.ERROR_OCCURRED,
|
||||
new Replacement(Placeholder.ERROR, "Failed to load shops from database")));
|
||||
plugin.getLogger().severe("Failed to load shops");
|
||||
if (throwable != null) plugin.getLogger().severe(throwable.getMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -3,6 +3,11 @@ package de.epiceric.shopchest.event;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link ShopsLoadedEvent} instead since shops are loaded
|
||||
* dynamically based on chunk loading
|
||||
*/
|
||||
@Deprecated
|
||||
public class ShopInitializedEvent extends Event {
|
||||
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
|
@ -0,0 +1,33 @@
|
||||
package de.epiceric.shopchest.event;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
import de.epiceric.shopchest.shop.Shop;
|
||||
|
||||
/**
|
||||
* Called when shops have been loaded and added to the server
|
||||
*/
|
||||
public class ShopsLoadedEvent extends Event {
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private Collection<Shop> shops;
|
||||
|
||||
public ShopsLoadedEvent(Collection<Shop> shops) {
|
||||
this.shops = shops;
|
||||
}
|
||||
|
||||
public Collection<Shop> getShops() {
|
||||
return shops;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package de.epiceric.shopchest.event;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
import de.epiceric.shopchest.shop.Shop;
|
||||
|
||||
/**
|
||||
* Called when shops have been unloaded and removed from the server
|
||||
*/
|
||||
public class ShopsUnloadedEvent extends Event {
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private Collection<Shop> shops;
|
||||
|
||||
public ShopsUnloadedEvent(Collection<Shop> shops) {
|
||||
this.shops = shops;
|
||||
}
|
||||
|
||||
public Collection<Shop> getShops() {
|
||||
return shops;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
}
|
@ -4,6 +4,10 @@ import de.epiceric.shopchest.ShopChest;
|
||||
import de.epiceric.shopchest.shop.Shop;
|
||||
import de.epiceric.shopchest.utils.Callback;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
@ -12,12 +16,14 @@ import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerMoveEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
import org.bukkit.event.world.WorldLoadEvent;
|
||||
import org.bukkit.event.world.ChunkLoadEvent;
|
||||
import org.bukkit.event.world.ChunkUnloadEvent;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
public class ShopUpdateListener implements Listener {
|
||||
|
||||
private ShopChest plugin;
|
||||
private final ShopChest plugin;
|
||||
private final Set<Chunk> newLoadedChunks = new HashSet<>();
|
||||
|
||||
public ShopUpdateListener(ShopChest plugin) {
|
||||
this.plugin = plugin;
|
||||
@ -83,23 +89,55 @@ public class ShopUpdateListener implements Listener {
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onWorldLoad(WorldLoadEvent e) {
|
||||
final String worldName = e.getWorld().getName();
|
||||
public void onChunkLoad(ChunkLoadEvent e) {
|
||||
if (!plugin.getShopDatabase().isInitialized()) {
|
||||
return;
|
||||
}
|
||||
|
||||
plugin.getShopUtils().reloadShops(false, false, new Callback<Integer>(plugin) {
|
||||
@Override
|
||||
public void onResult(Integer result) {
|
||||
plugin.getLogger().info(String.format("Reloaded %d shops because a new world '%s' was loaded", result, worldName));
|
||||
plugin.debug(String.format("Reloaded %d shops because a new world '%s' was loaded", result, worldName));
|
||||
}
|
||||
// Wait 10 ticks after first event is triggered, so that multiple
|
||||
// chunk loads can be handled at the same time without having to
|
||||
// send a database request for each chunk.
|
||||
if (newLoadedChunks.isEmpty()) {
|
||||
new BukkitRunnable(){
|
||||
@Override
|
||||
public void run() {
|
||||
int chunkCount = newLoadedChunks.size();
|
||||
plugin.getShopUtils().loadShops(newLoadedChunks.toArray(new Chunk[chunkCount]), new Callback<Integer>(plugin) {
|
||||
@Override
|
||||
public void onResult(Integer result) {
|
||||
if (result == 0) {
|
||||
return;
|
||||
}
|
||||
plugin.debug("Loaded " + result + " shops in " + chunkCount + " chunks");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Throwable throwable) {
|
||||
// Database connection probably failed => disable plugin to prevent more errors
|
||||
plugin.getLogger().severe("Failed to load shops in newly loaded chunks");
|
||||
plugin.debug("Failed to load shops in newly loaded chunks");
|
||||
if (throwable != null) plugin.debug(throwable);
|
||||
}
|
||||
});
|
||||
newLoadedChunks.clear();
|
||||
}
|
||||
}.runTaskLater(plugin, 10L);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Throwable throwable) {
|
||||
// Database connection probably failed => disable plugin to prevent more errors
|
||||
plugin.getLogger().severe("No database access. Disabling ShopChest");
|
||||
if (throwable != null) plugin.getLogger().severe(throwable.getMessage());
|
||||
plugin.getServer().getPluginManager().disablePlugin(plugin);
|
||||
}
|
||||
});
|
||||
newLoadedChunks.add(e.getChunk());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onChunkUnload(ChunkUnloadEvent e) {
|
||||
if (!plugin.getShopDatabase().isInitialized()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int num = plugin.getShopUtils().unloadShops(e.getChunk());
|
||||
|
||||
if (num > 0) {
|
||||
String chunkStr = "[" + e.getChunk().getX() + "; " + e.getChunk().getZ() + "]";
|
||||
plugin.debug("Unloaded " + num + " shops in chunk " + chunkStr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,13 +4,13 @@ import de.epiceric.shopchest.ShopChest;
|
||||
import de.epiceric.shopchest.config.Config;
|
||||
import de.epiceric.shopchest.event.ShopBuySellEvent;
|
||||
import de.epiceric.shopchest.event.ShopBuySellEvent.Type;
|
||||
import de.epiceric.shopchest.exceptions.WorldNotFoundException;
|
||||
import de.epiceric.shopchest.shop.Shop;
|
||||
import de.epiceric.shopchest.shop.ShopProduct;
|
||||
import de.epiceric.shopchest.shop.Shop.ShopType;
|
||||
import de.epiceric.shopchest.utils.Callback;
|
||||
import de.epiceric.shopchest.utils.Utils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.World;
|
||||
@ -28,16 +28,20 @@ import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
|
||||
public abstract class Database {
|
||||
private final Set<String> notFoundWorlds = new HashSet<>();
|
||||
private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
private boolean initialized;
|
||||
|
||||
String tableShops;
|
||||
String tableLogs;
|
||||
String tableLogouts;
|
||||
@ -305,6 +309,7 @@ public abstract class Database {
|
||||
ResultSet rs = s.executeQuery("SELECT COUNT(id) FROM " + tableShops);
|
||||
if (rs.next()) {
|
||||
int count = rs.getInt(1);
|
||||
initialized = true;
|
||||
|
||||
plugin.debug("Initialized database with " + count + " entries");
|
||||
|
||||
@ -362,74 +367,108 @@ public abstract class Database {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all shops from the database
|
||||
* Get all shops from the database that are located in the given chunks
|
||||
*
|
||||
* @param showConsoleMessages Whether console messages (errors or warnings)
|
||||
* should be shown
|
||||
* @param callback Callback that - if succeeded - returns a read-only
|
||||
* collection of all shops (as
|
||||
* {@code Collection<Shop>})
|
||||
* @param chunks Shops in these chunks are retrieved
|
||||
* @param callback Callback that returns an immutable collection of shops if succeeded
|
||||
*/
|
||||
public void getShops(final boolean showConsoleMessages, final Callback<Collection<Shop>> callback) {
|
||||
new BukkitRunnable() {
|
||||
public void getShopsInChunks(final Chunk[] chunks, final Callback<Collection<Shop>> callback) {
|
||||
// Split chunks into packages containing each {splitSize} chunks at max
|
||||
int splitSize = 80;
|
||||
int parts = (int) Math.ceil(chunks.length / (double) splitSize);
|
||||
Chunk[][] splitChunks = new Chunk[parts][];
|
||||
for (int i = 0; i < parts; i++) {
|
||||
int size = i < parts - 1 ? splitSize : chunks.length % splitSize;
|
||||
Chunk[] tmp = new Chunk[size];
|
||||
System.arraycopy(chunks, i * splitSize, tmp, 0, size);
|
||||
splitChunks[i] = tmp;
|
||||
}
|
||||
|
||||
new BukkitRunnable(){
|
||||
@Override
|
||||
public void run() {
|
||||
ArrayList<Shop> shops = new ArrayList<>();
|
||||
List<Shop> shops = new ArrayList<>();
|
||||
|
||||
try (Connection con = dataSource.getConnection();
|
||||
PreparedStatement ps = con.prepareStatement("SELECT * FROM " + tableShops + "")) {
|
||||
ResultSet rs = ps.executeQuery();
|
||||
// Send a request for each chunk package
|
||||
for (Chunk[] newChunks : splitChunks) {
|
||||
|
||||
while (rs.next()) {
|
||||
int id = rs.getInt("id");
|
||||
|
||||
plugin.debug("Getting Shop... (#" + id + ")");
|
||||
|
||||
String worldName = rs.getString("world");
|
||||
World world = Bukkit.getWorld(worldName);
|
||||
|
||||
if (world == null) {
|
||||
WorldNotFoundException ex = new WorldNotFoundException(worldName);
|
||||
if (showConsoleMessages && !notFoundWorlds.contains(worldName)) {
|
||||
plugin.getLogger().warning(ex.getMessage());
|
||||
notFoundWorlds.add(worldName);
|
||||
}
|
||||
plugin.debug("Failed to get shop (#" + id + ")");
|
||||
plugin.debug(ex);
|
||||
continue;
|
||||
// Map chunks by world
|
||||
Map<String, Set<Chunk>> chunksByWorld = new HashMap<>();
|
||||
for (Chunk chunk : newChunks) {
|
||||
String world = chunk.getWorld().getName();
|
||||
Set<Chunk> chunksForWorld = chunksByWorld.getOrDefault(world, new HashSet<>());
|
||||
chunksForWorld.add(chunk);
|
||||
chunksByWorld.put(world, chunksForWorld);
|
||||
}
|
||||
|
||||
// Create query dynamically
|
||||
String query = "SELECT * FROM " + tableShops + " WHERE ";
|
||||
for (String world : chunksByWorld.keySet()) {
|
||||
query += "(world = ? AND (";
|
||||
int chunkNum = chunksByWorld.get(world).size();
|
||||
for (int i = 0; i < chunkNum; i++) {
|
||||
query += "((x BETWEEN ? AND ?) AND (z BETWEEN ? AND ?)) OR ";
|
||||
}
|
||||
|
||||
int x = rs.getInt("x");
|
||||
int y = rs.getInt("y");
|
||||
int z = rs.getInt("z");
|
||||
Location location = new Location(world, x, y, z);
|
||||
OfflinePlayer vendor = Bukkit.getOfflinePlayer(UUID.fromString(rs.getString("vendor")));
|
||||
ItemStack itemStack = Utils.decode(rs.getString("product"));
|
||||
int amount = rs.getInt("amount");
|
||||
ShopProduct product = new ShopProduct(itemStack, amount);
|
||||
double buyPrice = rs.getDouble("buyprice");
|
||||
double sellPrice = rs.getDouble("sellprice");
|
||||
ShopType shopType = ShopType.valueOf(rs.getString("shoptype"));
|
||||
|
||||
plugin.debug("Initializing new shop... (#" + id + ")");
|
||||
|
||||
shops.add(new Shop(id, plugin, vendor, product, location, buyPrice, sellPrice, shopType));
|
||||
query += "1=0)) OR ";
|
||||
}
|
||||
query += "1=0";
|
||||
|
||||
try (Connection con = dataSource.getConnection();
|
||||
PreparedStatement ps = con.prepareStatement(query)) {
|
||||
int index = 0;
|
||||
for (String world : chunksByWorld.keySet()) {
|
||||
ps.setString(++index, world);
|
||||
for (Chunk chunk : chunksByWorld.get(world)) {
|
||||
int minX = chunk.getX() * 16;
|
||||
int minZ = chunk.getZ() * 16;
|
||||
ps.setInt(++index, minX);
|
||||
ps.setInt(++index, minX + 15);
|
||||
ps.setInt(++index, minZ);
|
||||
ps.setInt(++index, minZ + 15);
|
||||
}
|
||||
}
|
||||
|
||||
ResultSet rs = ps.executeQuery();
|
||||
while (rs.next()) {
|
||||
int id = rs.getInt("id");
|
||||
|
||||
plugin.debug("Getting Shop... (#" + id + ")");
|
||||
|
||||
int x = rs.getInt("x");
|
||||
int y = rs.getInt("y");
|
||||
int z = rs.getInt("z");
|
||||
|
||||
World world = plugin.getServer().getWorld(rs.getString("world"));
|
||||
Location location = new Location(world, x, y, z);
|
||||
OfflinePlayer vendor = Bukkit.getOfflinePlayer(UUID.fromString(rs.getString("vendor")));
|
||||
ItemStack itemStack = Utils.decode(rs.getString("product"));
|
||||
int amount = rs.getInt("amount");
|
||||
ShopProduct product = new ShopProduct(itemStack, amount);
|
||||
double buyPrice = rs.getDouble("buyprice");
|
||||
double sellPrice = rs.getDouble("sellprice");
|
||||
ShopType shopType = ShopType.valueOf(rs.getString("shoptype"));
|
||||
|
||||
plugin.debug("Initializing new shop... (#" + id + ")");
|
||||
|
||||
shops.add(new Shop(id, plugin, vendor, product, location, buyPrice, sellPrice, shopType));
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
if (callback != null) {
|
||||
callback.callSyncError(ex);
|
||||
}
|
||||
|
||||
plugin.getLogger().severe("Failed to get shops from database");
|
||||
plugin.debug("Failed to get shops");
|
||||
plugin.debug(ex);
|
||||
|
||||
if (callback != null) {
|
||||
callback.callSyncResult(Collections.unmodifiableCollection(shops));
|
||||
return;
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
if (callback != null) {
|
||||
callback.callSyncError(ex);
|
||||
}
|
||||
|
||||
plugin.getLogger().severe("Failed to get shops from database");
|
||||
plugin.debug("Failed to get shops");
|
||||
plugin.debug(ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (callback != null) {
|
||||
callback.callSyncResult(Collections.unmodifiableCollection(shops));
|
||||
}
|
||||
};
|
||||
}.runTaskAsynchronously(plugin);
|
||||
}
|
||||
|
||||
@ -730,6 +769,13 @@ public abstract class Database {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether a connection to the database has been established
|
||||
*/
|
||||
public boolean isInitialized() {
|
||||
return initialized;
|
||||
}
|
||||
|
||||
public enum DatabaseType {
|
||||
SQLite, MySQL
|
||||
}
|
||||
|
@ -2,8 +2,12 @@ package de.epiceric.shopchest.utils;
|
||||
|
||||
import de.epiceric.shopchest.ShopChest;
|
||||
import de.epiceric.shopchest.config.Config;
|
||||
import de.epiceric.shopchest.event.ShopsLoadedEvent;
|
||||
import de.epiceric.shopchest.event.ShopsUnloadedEvent;
|
||||
import de.epiceric.shopchest.shop.Shop;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.block.Chest;
|
||||
@ -246,6 +250,7 @@ public class ShopUtils {
|
||||
* @return The amount of a shops a player has (if {@link Config#excludeAdminShops} is true, admin shops won't be counted)
|
||||
*/
|
||||
public int getShopAmount(OfflinePlayer p) {
|
||||
// FIXME: currently only showing loaded shops
|
||||
float shopCount = 0;
|
||||
|
||||
for (Shop shop : getShops()) {
|
||||
@ -265,54 +270,65 @@ public class ShopUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* Reload the shops
|
||||
* @param reloadConfig Whether the configuration should also be reloaded
|
||||
* @param showConsoleMessages Whether messages about the language file should be shown in the console
|
||||
* @param callback Callback that - if succeeded - returns the amount of shops that were reloaded (as {@code int})
|
||||
* Gets all shops in the given chunk from the database and adds them to the server
|
||||
* @param chunk The chunk to load shops from
|
||||
* @param callback Callback that returns the amount of shops added if succeeded
|
||||
* @see ShopUtils#loadShops(Chunk[], Callback)
|
||||
*/
|
||||
public void reloadShops(boolean reloadConfig, final boolean showConsoleMessages, final Callback<Integer> callback) {
|
||||
plugin.debug("Reloading shops...");
|
||||
public void loadShops(final Chunk chunk, final Callback<Integer> callback) {
|
||||
loadShops(new Chunk[] {chunk}, callback);
|
||||
}
|
||||
|
||||
if (reloadConfig) {
|
||||
plugin.getShopChestConfig().reload(false, true, showConsoleMessages);
|
||||
plugin.getHologramFormat().reload();
|
||||
plugin.getUpdater().restart();
|
||||
}
|
||||
|
||||
plugin.getShopDatabase().connect(new Callback<Integer>(plugin) {
|
||||
/**
|
||||
* Gets all shops in the given chunks from the database and adds them to the server
|
||||
* @param chunk The chunks to load shops from
|
||||
* @param callback Callback that returns the amount of shops added if succeeded
|
||||
* @see ShopUtils#loadShops(Chunk Callback)
|
||||
*/
|
||||
public void loadShops(final Chunk[] chunks, final Callback<Integer> callback) {
|
||||
plugin.getShopDatabase().getShopsInChunks(chunks, new Callback<Collection<Shop>>(plugin) {
|
||||
@Override
|
||||
public void onResult(Integer result) {
|
||||
for (Shop shop : getShopsCopy()) {
|
||||
removeShop(shop, false);
|
||||
plugin.debug("Removed shop (#" + shop.getID() + ")");
|
||||
public void onResult(Collection<Shop> result) {
|
||||
for (Shop shop : result) {
|
||||
if (shop.create(true)) {
|
||||
addShop(shop, false);
|
||||
}
|
||||
}
|
||||
|
||||
plugin.getShopDatabase().getShops(showConsoleMessages, new Callback<Collection<Shop>>(plugin) {
|
||||
@Override
|
||||
public void onResult(Collection<Shop> result) {
|
||||
for (Shop shop : result) {
|
||||
if (shop.create(showConsoleMessages)) {
|
||||
addShop(shop, false);
|
||||
}
|
||||
}
|
||||
if (callback != null) callback.onResult(result.size());
|
||||
|
||||
if (callback != null) callback.callSyncResult(result.size());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Throwable throwable) {
|
||||
if (callback != null) callback.callSyncError(throwable);
|
||||
}
|
||||
});
|
||||
Bukkit.getPluginManager().callEvent(new ShopsLoadedEvent(result));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Throwable throwable) {
|
||||
if (callback != null) callback.callSyncError(throwable);
|
||||
if (callback != null) callback.onError(throwable);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all shops from the given chunk from the server
|
||||
* @param chunk The chunk containing the shops to unload
|
||||
* @return The amount of shops that were unloaded
|
||||
*/
|
||||
public int unloadShops(final Chunk chunk) {
|
||||
Set<Shop> unloadedShops = new HashSet<>();
|
||||
|
||||
Iterator<Shop> iter = getShops().iterator();
|
||||
while(iter.hasNext()) {
|
||||
Shop shop = iter.next();
|
||||
if (shop.getLocation().getChunk().equals(chunk)) {
|
||||
removeShop(shop, false);
|
||||
unloadedShops.add(shop);
|
||||
plugin.debug("Unloaded shop (#" + shop.getID() + ")");
|
||||
}
|
||||
}
|
||||
|
||||
Bukkit.getPluginManager().callEvent(new ShopsUnloadedEvent(Collections.unmodifiableCollection(unloadedShops)));
|
||||
return unloadedShops.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update hologram and item of all shops for a player
|
||||
* @param player Player to show the updates
|
||||
|
Loading…
Reference in New Issue
Block a user