332 lines
13 KiB
Java
332 lines
13 KiB
Java
package org.maxgamer.QuickShop;
|
|
|
|
import java.io.File;
|
|
import java.sql.Connection;
|
|
import java.sql.PreparedStatement;
|
|
import java.sql.ResultSet;
|
|
import java.sql.SQLException;
|
|
import java.sql.Timestamp;
|
|
import java.util.Calendar;
|
|
import java.util.Date;
|
|
import java.util.Map.Entry;
|
|
|
|
import org.bukkit.Bukkit;
|
|
import org.bukkit.ChatColor;
|
|
import org.bukkit.Location;
|
|
import org.bukkit.Material;
|
|
import org.bukkit.World;
|
|
import org.bukkit.configuration.ConfigurationSection;
|
|
import org.bukkit.configuration.file.FileConfiguration;
|
|
import org.bukkit.entity.Player;
|
|
import org.bukkit.inventory.InventoryHolder;
|
|
import org.bukkit.inventory.ItemStack;
|
|
import org.bukkit.plugin.Plugin;
|
|
import org.bukkit.plugin.PluginManager;
|
|
import org.bukkit.plugin.java.JavaPlugin;
|
|
import org.bukkit.scheduler.BukkitTask;
|
|
import org.maxgamer.QuickShop.Command.QuickShopCommands;
|
|
import org.maxgamer.QuickShop.Config.ConfigManager;
|
|
import org.maxgamer.QuickShop.Database.Database;
|
|
import org.maxgamer.QuickShop.Database.DatabaseCore;
|
|
import org.maxgamer.QuickShop.Database.DatabaseHelper;
|
|
import org.maxgamer.QuickShop.Database.MySQLCore;
|
|
import org.maxgamer.QuickShop.Database.SQLiteCore;
|
|
import org.maxgamer.QuickShop.Economy.Economy;
|
|
import org.maxgamer.QuickShop.Economy.EconomyCore;
|
|
import org.maxgamer.QuickShop.Economy.Economy_Vault;
|
|
import org.maxgamer.QuickShop.Listeners.BlockListener;
|
|
import org.maxgamer.QuickShop.Listeners.ChatListener;
|
|
import org.maxgamer.QuickShop.Listeners.LockListener;
|
|
import org.maxgamer.QuickShop.Listeners.PlayerListener;
|
|
import org.maxgamer.QuickShop.Listeners.ProtectListener;
|
|
import org.maxgamer.QuickShop.Listeners.WorldListener;
|
|
import org.maxgamer.QuickShop.Shop.ContainerShop;
|
|
import org.maxgamer.QuickShop.Shop.Shop;
|
|
import org.maxgamer.QuickShop.Shop.ShopManager;
|
|
import org.maxgamer.QuickShop.Shop.ShopType;
|
|
import org.maxgamer.QuickShop.Util.MsgUtil;
|
|
import org.maxgamer.QuickShop.Util.Util;
|
|
import org.maxgamer.QuickShop.Watcher.LogWatcher;
|
|
|
|
import pw.yumc.YumCore.config.FileConfig;
|
|
import pw.yumc.YumCore.global.L10N;
|
|
import pw.yumc.YumCore.statistic.Statistics;
|
|
import pw.yumc.YumCore.update.SubscribeTask;
|
|
|
|
public class QuickShop extends JavaPlugin {
|
|
/** 初始化 QuickShop 的接口 */
|
|
public static QuickShop instance;
|
|
/** 插件的配置文件 */
|
|
public FileConfig config;
|
|
// private HeroChatListener heroChatListener;
|
|
// Listeners (These don't)
|
|
/** The Config Manager used to read config */
|
|
private ConfigManager configManager;
|
|
/** The database for storing all our data for persistence */
|
|
private Database database;
|
|
/** The economy we hook into for transactions */
|
|
private Economy economy;
|
|
public BukkitTask itemWatcherTask;
|
|
private LogWatcher logWatcher;
|
|
/** The Shop Manager used to store shops */
|
|
private ShopManager shopManager;
|
|
|
|
/**
|
|
* Prints debug information if QuickShop is configured to do so.
|
|
*
|
|
* @param s
|
|
* The string to print.
|
|
*/
|
|
public void debug(final String s) {
|
|
if (!configManager.isDebug()) { return; }
|
|
this.getLogger().info(ChatColor.YELLOW + "[Debug] " + s);
|
|
}
|
|
|
|
@Override
|
|
public FileConfiguration getConfig() {
|
|
return config;
|
|
}
|
|
|
|
public ConfigManager getConfigManager() {
|
|
return configManager;
|
|
}
|
|
|
|
/**
|
|
* @return Returns the database handler for queries etc.
|
|
*/
|
|
public Database getDB() {
|
|
return this.database;
|
|
}
|
|
|
|
/**
|
|
* Returns the economy for moving currency around
|
|
*
|
|
* @return The economy for moving currency around
|
|
*/
|
|
public EconomyCore getEcon() {
|
|
return economy;
|
|
}
|
|
|
|
public int getShopLimit(final Player p) {
|
|
int max = configManager.getLimitdefault();
|
|
for (final Entry<String, Integer> entry : configManager.getLimits().entrySet()) {
|
|
if (entry.getValue() > max && p.hasPermission(entry.getKey())) {
|
|
max = entry.getValue();
|
|
}
|
|
}
|
|
return max;
|
|
}
|
|
|
|
/**
|
|
* Returns the ShopManager. This is used for fetching, adding and removing
|
|
* shops.
|
|
*
|
|
* @return The ShopManager.
|
|
*/
|
|
public ShopManager getShopManager() {
|
|
return this.shopManager;
|
|
}
|
|
|
|
/**
|
|
* Tries to load the economy and its core. If this fails, it will try to use
|
|
* vault. If that fails, it will return false.
|
|
*
|
|
* @return true if successful, false if the core is invalid or is not found,
|
|
* and vault cannot be used.
|
|
*/
|
|
public boolean loadEcon() {
|
|
final EconomyCore core = new Economy_Vault();
|
|
if (!core.isValid()) {
|
|
getLogger().warning("无法找到经济管理类插件...");
|
|
getLogger().warning("卸载插件!!!");
|
|
this.getPluginLoader().disablePlugin(this);
|
|
return false;
|
|
}
|
|
this.economy = new Economy(core);
|
|
return true;
|
|
}
|
|
|
|
public void loadShop() {
|
|
/* 从数据库载入商店信息到内存 */
|
|
int count = 0; // 商店个数
|
|
int unload = 0;
|
|
Connection con;
|
|
try {
|
|
getLogger().info("开始从数据库载入商店数据...");
|
|
con = database.getConnection();
|
|
final PreparedStatement ps = con.prepareStatement("SELECT * FROM shops");
|
|
final ResultSet rs = ps.executeQuery();
|
|
int errors = 0;
|
|
while (rs.next()) {
|
|
int x = 0;
|
|
int y = 0;
|
|
int z = 0;
|
|
String worldName = null;
|
|
try {
|
|
x = rs.getInt("x");
|
|
y = rs.getInt("y");
|
|
z = rs.getInt("z");
|
|
worldName = rs.getString("world");
|
|
final World world = Bukkit.getWorld(worldName);
|
|
final ItemStack item = Util.deserialize(rs.getString("itemConfig"));
|
|
final String owner = rs.getString("owner");
|
|
final double price = rs.getDouble("price");
|
|
final Location loc = new Location(world, x, y, z);
|
|
/* Skip invalid shops, if we know of any */
|
|
if (world != null && loc.getChunk().isLoaded() && !(loc.getBlock().getState() instanceof InventoryHolder)) {
|
|
getLogger().info("商店不是一个可存储的方块 坐标 " + rs.getString("world") + ", " + x + ", " + y + ", " + z + ". 删除...");
|
|
database.execute("DELETE FROM shops WHERE x = ? AND y = ? and z = ? and world = ?", x, y, z, worldName);
|
|
continue;
|
|
}
|
|
final int type = rs.getInt("type");
|
|
final Shop shop = new ContainerShop(loc, price, item, owner);
|
|
shop.setUnlimited(rs.getBoolean("unlimited"));
|
|
shop.setShopType(ShopType.fromID(type));
|
|
shopManager.loadShop(rs.getString("world"), shop);
|
|
if (loc.getWorld() != null && loc.getChunk().isLoaded()) {
|
|
shop.onLoad();
|
|
}
|
|
count++;
|
|
} catch (final IllegalStateException e) {
|
|
unload++;
|
|
} catch (final Exception e) {
|
|
errors++;
|
|
e.printStackTrace();
|
|
getLogger().warning("载入商店数据时发生错误! 商店位置: " + worldName + " (" + x + ", " + y + ", " + z + ")...");
|
|
if (errors < 3) {
|
|
getLogger().warning("删除错误的商店数据...");
|
|
database.execute("DELETE FROM shops WHERE x = ? AND y = ? and z = ? and world = ?", x, y, z, worldName);
|
|
} else {
|
|
getLogger().warning("过多的错误数据 可能您的数据库文件已损坏! 请检查数据库文件!");
|
|
e.printStackTrace();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
} catch (final SQLException e) {
|
|
getLogger().warning("无法载入商店数据...");
|
|
getLogger().warning("错误信息: " + e.getMessage());
|
|
e.printStackTrace();
|
|
}
|
|
getLogger().info("已载入 " + count + " 个商店 剩余 " + unload + " 个商店将在区块载入后加载...");
|
|
}
|
|
|
|
/**
|
|
* Logs the given string to qs.log, if QuickShop is configured to do so.
|
|
*
|
|
* @param s
|
|
* The string to log. It will be prefixed with the date and time.
|
|
*/
|
|
public void log(final String s) {
|
|
if (this.logWatcher == null) { return; }
|
|
final Date date = Calendar.getInstance().getTime();
|
|
final Timestamp time = new Timestamp(date.getTime());
|
|
this.logWatcher.add("[" + time.toString() + "] " + s);
|
|
}
|
|
|
|
@Override
|
|
public void onDisable() {
|
|
if (itemWatcherTask != null) {
|
|
itemWatcherTask.cancel();
|
|
}
|
|
if (logWatcher != null) {
|
|
logWatcher.task.cancel();
|
|
logWatcher.close(); // Closes the file
|
|
}
|
|
/* Remove all display items, and any dupes we can find */
|
|
if (shopManager != null) {
|
|
shopManager.clear();
|
|
}
|
|
/* Empty the buffer */
|
|
if (database != null) {
|
|
database.close();
|
|
try {
|
|
database.getConnection().close();
|
|
} catch (final SQLException ignored) {
|
|
}
|
|
}
|
|
if (configManager != null) {
|
|
configManager.getWarnings().clear();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onEnable() {
|
|
if (!loadEcon()) { return; }
|
|
Util.initialize();
|
|
// Create the shop manager.
|
|
shopManager = new ShopManager(this);
|
|
configManager = new ConfigManager(this);
|
|
// Initialize Util
|
|
if (configManager.isLogAction()) {
|
|
// Logger Handler
|
|
this.logWatcher = new LogWatcher(this, new File(this.getDataFolder(), "qs.log"));
|
|
logWatcher.task = Bukkit.getScheduler().runTaskTimerAsynchronously(this, this.logWatcher, 150, 150);
|
|
}
|
|
if (configManager.isShopLock()) {
|
|
final LockListener ll = new LockListener(this);
|
|
getServer().getPluginManager().registerEvents(ll, this);
|
|
}
|
|
try {
|
|
final ConfigurationSection dbCfg = getConfig().getConfigurationSection("database");
|
|
DatabaseCore dbCore;
|
|
if (dbCfg != null && dbCfg.getBoolean("mysql")) {
|
|
getLogger().info("启用MySQL 开始连接数据库...");
|
|
// MySQL database - Required database be created first.
|
|
final String user = dbCfg.getString("user");
|
|
final String pass = dbCfg.getString("password");
|
|
final String host = dbCfg.getString("host");
|
|
final String port = dbCfg.getString("port");
|
|
final String database = dbCfg.getString("database");
|
|
dbCore = new MySQLCore(host, user, pass, database, port);
|
|
} else {
|
|
// SQLite database - Doing this handles file creation
|
|
dbCore = new SQLiteCore(new File(this.getDataFolder(), "shops.db"));
|
|
}
|
|
this.database = new Database(dbCore);
|
|
// Make the database up to date
|
|
DatabaseHelper.setup(getDB());
|
|
} catch (final Exception e) {
|
|
getLogger().warning("数据库连接错误或配置错误...");
|
|
getLogger().warning("错误信息: " + e.getMessage());
|
|
e.printStackTrace();
|
|
getLogger().warning("关闭插件!!!");
|
|
getServer().getPluginManager().disablePlugin(this);
|
|
return;
|
|
}
|
|
loadShop();
|
|
MsgUtil.loadTransactionMessages();
|
|
MsgUtil.clean();
|
|
// Register events
|
|
final PluginManager pm = this.getServer().getPluginManager();
|
|
pm.registerEvents(new BlockListener(this), this);
|
|
pm.registerEvents(new PlayerListener(this), this);
|
|
pm.registerEvents(new WorldListener(this), this);
|
|
pm.registerEvents(new ProtectListener(this), this);
|
|
pm.registerEvents(new ChatListener(this), this);
|
|
// Command handlers
|
|
new QuickShopCommands();
|
|
|
|
if (configManager.getFindDistance() > 100) {
|
|
getLogger().warning("商店查找半径过大 可能导致服务器Lag! 推荐使用低于 100 的配置!");
|
|
}
|
|
this.getLogger().info("载入完成! 版本: " + this.getDescription().getVersion() + " 重制 by 喵♂呜");
|
|
new Statistics();
|
|
new SubscribeTask();
|
|
}
|
|
|
|
@Override
|
|
public void onLoad() {
|
|
instance = this;
|
|
config = new FileConfig();
|
|
MsgUtil.init(this);
|
|
L10N.getItemName(new ItemStack(Material.AIR));
|
|
}
|
|
|
|
/** Reloads QuickShops config */
|
|
@Override
|
|
public void reloadConfig() {
|
|
config.reload();
|
|
L10N.reload();
|
|
}
|
|
} |