/* * To change this template, choose Tools | Templates and open the template in * the editor. */ package com.bekvon.bukkit.residence; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.logging.Logger; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Server; import org.bukkit.World; import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.java.JavaPlugin; import com.bekvon.bukkit.residence.chat.ChatManager; import com.bekvon.bukkit.residence.config.FileConfig; import com.bekvon.bukkit.residence.economy.EconomyInterface; import com.bekvon.bukkit.residence.economy.EssentialsEcoAdapter; import com.bekvon.bukkit.residence.economy.TransactionManager; import com.bekvon.bukkit.residence.economy.rent.RentManager; import com.bekvon.bukkit.residence.itemlist.WorldItemManager; import com.bekvon.bukkit.residence.listeners.ResidenceBlockListener; import com.bekvon.bukkit.residence.listeners.ResidenceEntityListener; import com.bekvon.bukkit.residence.listeners.ResidencePlayerListener; import com.bekvon.bukkit.residence.permissions.PermissionManager; import com.bekvon.bukkit.residence.persistance.YMLSaveHelper; import com.bekvon.bukkit.residence.protection.ClaimedResidence; import com.bekvon.bukkit.residence.protection.FlagPermissions; import com.bekvon.bukkit.residence.protection.LeaseManager; import com.bekvon.bukkit.residence.protection.PermissionListManager; import com.bekvon.bukkit.residence.protection.ResidenceManager; import com.bekvon.bukkit.residence.protection.WorldFlagManager; import com.bekvon.bukkit.residence.selection.SelectionManager; import com.bekvon.bukkit.residence.selection.WorldEditSelectionManager; import com.bekvon.bukkit.residence.text.Language; import com.bekvon.bukkit.residence.text.help.HelpEntry; import com.bekvon.bukkit.residence.text.help.InformationPager; import com.bekvon.bukkit.residence.utils.DataBackup; import com.bekvon.bukkit.residence.utils.VersionChecker; import com.bekvon.bukkit.residence.vaultinterface.ResidenceVaultAdapter; import com.earth2me.essentials.Essentials; /** * * @author Gary Smoak - bekvon * */ public class Residence extends JavaPlugin { public static String bukkitver; protected static ResidenceManager rmanager; protected static SelectionManager smanager; protected static PermissionManager gmanager; protected static ConfigManager cmanager; protected static ResidenceBlockListener blistener; protected static ResidencePlayerListener plistener; protected static ResidenceEntityListener elistener; protected static TransactionManager tmanager; protected static PermissionListManager pmanager; protected static LeaseManager leasemanager; protected static WorldItemManager imanager; protected static WorldFlagManager wmanager; protected static RentManager rentmanager; protected static ChatManager chatmanager; protected static Server server; protected static HelpEntry helppages; protected static Language language; protected static Logger log; protected static boolean useWorldEdit; protected static EconomyInterface economy; public final static int saveVersion = 1; protected static File dataFolder; protected static int leaseBukkitId = -1; protected static int rentBukkitId = -1; protected static int healBukkitId = -1; protected static int autosaveBukkitId = -1; protected static boolean initsuccess = false; protected static List resadminToggle; protected static FileConfig config; private final static String[] validLanguages = { "English", "Chinese" }; public static ResidenceBlockListener getBlockListener() { return blistener; } public static ChatManager getChatManager() { return chatmanager; } public static ConfigManager getConfigManager() { return cmanager; } public static File getDataLocation() { return dataFolder; } public static EconomyInterface getEconomyManager() { return economy; } public static ResidenceEntityListener getEntityListener() { return elistener; } public static WorldItemManager getItemManager() { return imanager; } public static Language getLanguage() { if (language == null) { language = new Language(); } return language; } public static LeaseManager getLeaseManager() { return leasemanager; } public static Logger getLog() { return log; } public static PermissionManager getPermissionManager() { return gmanager; } public static FlagPermissions getPermsByLoc(Location loc) { ClaimedResidence res = rmanager.getByLoc(loc); if (res != null) return res.getPermissions(); else return wmanager.getPerms(loc.getWorld().getName()); } public static FlagPermissions getPermsByLocForPlayer(Location loc, Player player) { ClaimedResidence res = rmanager.getByLoc(loc); if (res != null) return res.getPermissions(); else { if (player != null) return wmanager.getPerms(player); else return wmanager.getPerms(loc.getWorld().getName()); } } public static ResidencePlayerListener getPlayerListener() { return plistener; } public static RentManager getRentManager() { return rentmanager; } public static ResidenceManager getResidenceManager() { return rmanager; } public static SelectionManager getSelectionManager() { return smanager; } public static Server getServ() { return server; } public static TransactionManager getTransactionManager() { return tmanager; } public static WorldFlagManager getWorldFlags() { return wmanager; } public static boolean isResAdminOn(Player player) { if (resadminToggle.contains(player.getName())) return true; return false; } public static boolean isResAdminOn(String player) { if (resadminToggle.contains(player.toLowerCase())) return true; return false; } public static boolean isUseWorldEdit() { return useWorldEdit; } public static void turnResAdminOn(Player player) { resadminToggle.add(player.getName()); } public static boolean validName(String name) { if (name.contains(":") || name.contains(".")) return false; if (cmanager.getResidenceNameRegex() == null) return true; else { String namecheck = name.replaceAll(cmanager.getResidenceNameRegex(), ""); if (!name.equals(namecheck)) return false; return true; } } protected boolean firstenable = true; protected Map deleteConfirm; private Runnable doHeals = new Runnable() { @Override public void run() { plistener.doHeals(); } }; private Runnable rentExpire = new Runnable() { @Override public void run() { rentmanager.checkCurrentRents(); if (cmanager.showIntervalMessages()) { getLog().info(" - Rent Expirations checked!"); } } }; private Runnable leaseExpire = new Runnable() { @Override public void run() { leasemanager.doExpirations(); if (cmanager.showIntervalMessages()) { getLog().info(" - Lease Expirations checked!"); } } }; private Runnable autoSave = new Runnable() { @Override public void run() { try { if (initsuccess) { saveYml(); } } catch (Exception ex) { getLog().warning("领地数据保存错误,可能造成部分领地丢失,请尝试恢复备份文件!"); } } }; public Residence() { } private boolean checkNewLanguageVersion(String lang) throws IOException, FileNotFoundException, InvalidConfigurationException { File outFile = new File(new File(this.getDataFolder(), "Language"), lang + ".yml"); File checkFile = new File(new File(this.getDataFolder(), "Language"), "temp-" + lang + ".yml"); if (outFile.isFile()) { FileConfig testconfig = new FileConfig(this, outFile); int oldversion = testconfig.getInt("FieldsVersion", 0); if (!this.writeDefaultFileFromJar(checkFile, "languagefiles/" + lang + ".yml", false)) return false; FileConfig testconfig2 = new FileConfig(this, checkFile); testconfig2.load(checkFile); int newversion = testconfig2.getInt("FieldsVersion", oldversion); if (checkFile.isFile()) { checkFile.delete(); } if (newversion > oldversion) return true; return false; } return true; } public void consoleMessage(String message) { this.getLogger().info(message); } public void consoleMessage(String[] msg) { for (String s : msg) { consoleMessage(s); } } @Override public FileConfiguration getConfig() { return config; } private void loadEssentialsEconomy() { Plugin p = getServer().getPluginManager().getPlugin("Essentials"); if (p != null) { economy = new EssentialsEcoAdapter((Essentials) p); this.getLogger().info("成功关联Essentials Economy!"); } else { this.getLogger().info("Essentials Economy 未找到!"); } } public void loadLang(File langFile) throws FileNotFoundException, IOException, InvalidConfigurationException { FileConfig langconfig = new FileConfig(this, langFile); helppages = HelpEntry.parseHelp(langconfig, "CommandHelp"); HelpEntry.setLinesPerPage(langconfig.getInt("HelpLinesPerPage", 7)); InformationPager.setLinesPerPage(langconfig.getInt("HelpLinesPerPage", 7)); language = Language.parseText(langconfig, "Language"); } private void loadVaultEconomy() { Plugin p = getServer().getPluginManager().getPlugin("Vault"); if (p != null) { ResidenceVaultAdapter vault = new ResidenceVaultAdapter(getServer()); if (vault.economyOK()) { this.getLogger().info("发现 Vault 使用经济系统: " + vault.getEconomyName()); economy = vault; } else { this.getLogger().info("发现 Vault, 但是 Vault 未找到经济系统..."); } } else { this.getLogger().info("Vault 未找到!"); } } @SuppressWarnings("unchecked") protected boolean loadYml() throws Exception { File saveFolder = new File(dataFolder, "Save"); try { File worldFolder = new File(saveFolder, "Worlds"); if (!saveFolder.isDirectory()) { this.getLogger().warning("领地数据保存目录不存在..."); this.getLogger().warning("请重新启动服务器生成新的文件..."); return true; } YMLSaveHelper yml; File loadFile; long time = System.currentTimeMillis(); HashMap worlds = new HashMap(); for (World world : server.getWorlds()) { loadFile = new File(worldFolder, "res_" + world.getName() + ".yml"); if (loadFile.isFile()) { yml = new YMLSaveHelper(loadFile); yml.load(); worlds.put(world.getName(), yml.getRoot().get("Residences")); } } rmanager = ResidenceManager.load(worlds); loadFile = new File(saveFolder, "forsale.yml"); if (loadFile.isFile()) { yml = new YMLSaveHelper(loadFile); yml.load(); tmanager = TransactionManager.load((Map) yml.getRoot().get("Economy"), gmanager, rmanager); } loadFile = new File(saveFolder, "leases.yml"); if (loadFile.isFile()) { yml = new YMLSaveHelper(loadFile); yml.load(); leasemanager = LeaseManager.load((Map) yml.getRoot().get("Leases"), rmanager); } loadFile = new File(saveFolder, "permlists.yml"); if (loadFile.isFile()) { yml = new YMLSaveHelper(loadFile); yml.load(); pmanager = PermissionListManager.load((Map) yml.getRoot().get("PermissionLists")); } loadFile = new File(saveFolder, "rent.yml"); if (loadFile.isFile()) { yml = new YMLSaveHelper(loadFile); yml.load(); rentmanager = RentManager.load((Map) yml.getRoot().get("RentSystem")); } this.getLogger().info("从配置文件中读取领地数据,耗时" + ((float) (System.currentTimeMillis() - time) / 1000) + " 秒)"); // System.out.print("[Residence] Loaded..."); return true; } catch (Exception ex) { this.getLogger().warning("领地数据载入时发生错误,请报告以下内容给作者: "); this.getLogger().warning("错误: " + ex); throw ex; } } @Override public void onDisable() { server.getScheduler().cancelTask(autosaveBukkitId); server.getScheduler().cancelTask(healBukkitId); if (cmanager.useLeases()) { server.getScheduler().cancelTask(leaseBukkitId); } if (cmanager.enabledRentSystem()) { server.getScheduler().cancelTask(rentBukkitId); } if (initsuccess) { try { saveYml(); DataBackup.run(); } catch (Exception ex) { this.getLogger().warning("领地数据保存错误,可能造成部分领地丢失,请尝试恢复备份文件!"); this.getLogger().warning("错误: " + ex); } } } @Override public void onEnable() { try { log = this.getLogger(); bukkitver = this.getServer().getBukkitVersion().substring(0, 5); initsuccess = false; deleteConfirm = new HashMap(); resadminToggle = new ArrayList(); server = this.getServer(); dataFolder = this.getDataFolder(); if (!dataFolder.isDirectory()) { dataFolder.mkdirs(); } if (!new File(dataFolder, "config.yml").isFile()) { this.writeDefaultConfigFromJar(); } if (this.getConfig().getInt("ResidenceVersion", 0) == 0) { this.writeDefaultConfigFromJar(); this.getConfig().load("config.yml"); this.getLogger().warning("配置文件不存在,写入默认配置文件."); } cmanager = new ConfigManager(this.getConfig()); String multiworld = cmanager.getMultiworldPlugin(); if (multiworld != null) { Plugin plugin = server.getPluginManager().getPlugin(multiworld); if (plugin != null) { if (!plugin.isEnabled()) { this.getLogger().info(" - 加载多世界插件: " + multiworld); server.getPluginManager().enablePlugin(plugin); } } } gmanager = new PermissionManager(this.getConfig()); imanager = new WorldItemManager(this.getConfig()); wmanager = new WorldFlagManager(this.getConfig()); chatmanager = new ChatManager(); rentmanager = new RentManager(); for (String lang : validLanguages) { try { if (this.checkNewLanguageVersion(lang)) { this.writeDefaultLanguageFile(lang); } } catch (Exception ex) { this.getLogger().warning("语言文件升级失败: " + lang + ".yml"); helppages = new HelpEntry(""); language = new Language(); } } File langFile = new File(new File(dataFolder, "Language"), cmanager.getLanguage() + ".yml"); try { if (langFile.isFile()) { loadLang(langFile); } else { this.getLogger().warning("语言文件不存在..."); } } catch (Exception ex) { this.getLogger().warning("语言文件载入失败: " + cmanager.getLanguage() + ".yml 写入默认语言文件"); this.writeDefaultLanguageFile(cmanager.getLanguage()); loadLang(langFile); } economy = null; if (this.getConfig().getBoolean("Global.EnableEconomy", false)) { this.getLogger().info("扫描经济系统..."); if (gmanager.getPermissionsPlugin() instanceof ResidenceVaultAdapter) { ResidenceVaultAdapter vault = (ResidenceVaultAdapter) gmanager.getPermissionsPlugin(); if (vault.economyOK()) { economy = vault; this.getLogger().info("发现 Vault 使用经济系统: " + vault.getEconomyName()); } } if (economy == null) { this.loadVaultEconomy(); } if (economy == null) { this.loadEssentialsEconomy(); } if (economy == null) { this.getLogger().warning("未找到经济系统..."); } } try { this.loadYml(); } catch (Exception e) { this.getLogger().warning("领地数据载入错误,可能造成插件无法启动,请尝试恢复备份文件!"); this.getLogger().warning("错误: " + e); } if (rmanager == null) { rmanager = new ResidenceManager(); } if (leasemanager == null) { leasemanager = new LeaseManager(rmanager); } if (tmanager == null) { tmanager = new TransactionManager(rmanager, gmanager); } if (pmanager == null) { pmanager = new PermissionListManager(); } if (firstenable) { if (!this.isEnabled()) return; FlagPermissions.initValidFlags(); Plugin p = server.getPluginManager().getPlugin("WorldEdit"); if (p != null) { smanager = new WorldEditSelectionManager(server); useWorldEdit = true; this.getLogger().info("发现 WorldEdit"); } else { smanager = new SelectionManager(server); useWorldEdit = false; this.getLogger().warning("WorldEdit 未找到!"); } blistener = new ResidenceBlockListener(); plistener = new ResidencePlayerListener(); elistener = new ResidenceEntityListener(); PluginManager pm = getServer().getPluginManager(); pm.registerEvents(blistener, this); pm.registerEvents(plistener, this); pm.registerEvents(elistener, this); firstenable = false; } else { plistener.reload(); } int autosaveInt = cmanager.getAutoSaveInterval(); if (autosaveInt < 1) { autosaveInt = 1; } autosaveInt = autosaveInt * 60 * 20; autosaveBukkitId = server.getScheduler().scheduleSyncRepeatingTask(this, autoSave, autosaveInt, autosaveInt); healBukkitId = server.getScheduler().scheduleSyncRepeatingTask(this, doHeals, 20, 20); if (cmanager.useLeases()) { int leaseInterval = cmanager.getLeaseCheckInterval(); if (leaseInterval < 1) { leaseInterval = 1; } leaseInterval = leaseInterval * 60 * 20; leaseBukkitId = server.getScheduler().scheduleSyncRepeatingTask(this, leaseExpire, leaseInterval, leaseInterval); } if (cmanager.enabledRentSystem()) { int rentint = cmanager.getRentCheckInterval(); if (rentint < 1) { rentint = 1; } rentint = rentint * 60 * 20; rentBukkitId = server.getScheduler().scheduleSyncRepeatingTask(this, rentExpire, rentint, rentint); } for (Player player : Bukkit.getServer().getOnlinePlayers()) { if (Residence.getPermissionManager().isResidenceAdmin(player)) { turnResAdminOn(player); } } this.getLogger().info("载入完成! 版本: " + this.getDescription().getVersion() + " 重制 by 喵♂呜"); initsuccess = true; } catch (Exception ex) { initsuccess = false; getServer().getPluginManager().disablePlugin(this); this.getLogger().warning(" - 初始化失败! 卸载插件! 请报告以下错误给作者,谢谢!"); this.getLogger().warning("错误: " + ex); } new VersionChecker(this); } @Override public void onLoad() { config = new FileConfig(this, "config.yml"); }; @Override public void reloadConfig() { config.reload(); } public void reloadPlugin() { this.onDisable(); this.reloadConfig(); this.onEnable(); } @Override public void saveConfig() { config.save(); } private void saveYml() throws IOException { File saveFolder = new File(dataFolder, "Save"); File worldFolder = new File(saveFolder, "Worlds"); worldFolder.mkdirs(); YMLSaveHelper yml; long time = System.currentTimeMillis(); Map save = rmanager.save(); for (Entry entry : save.entrySet()) { File ymlSaveLoc = new File(worldFolder, "res_" + entry.getKey() + ".yml"); File tmpFile = new File(worldFolder, "tmp_res_" + entry.getKey() + ".yml"); yml = new YMLSaveHelper(tmpFile); yml.getRoot().put("Version", saveVersion); World world = server.getWorld(entry.getKey()); if (world != null) { yml.getRoot().put("Seed", world.getSeed()); } yml.getRoot().put("Residences", entry.getValue()); yml.save(); if (ymlSaveLoc.isFile()) { File backupFolder = new File(worldFolder, "Backup"); backupFolder.mkdirs(); File backupFile = new File(backupFolder, "res_" + entry.getKey() + ".yml"); if (backupFile.isFile()) { backupFile.delete(); } ymlSaveLoc.renameTo(backupFile); } tmpFile.renameTo(ymlSaveLoc); } // For Sale save File ymlSaveLoc = new File(saveFolder, "forsale.yml"); File tmpFile = new File(saveFolder, "tmp_forsale.yml"); yml = new YMLSaveHelper(tmpFile); yml.save(); yml.getRoot().put("Version", saveVersion); yml.getRoot().put("Economy", tmanager.save()); yml.save(); if (ymlSaveLoc.isFile()) { File backupFolder = new File(saveFolder, "Backup"); backupFolder.mkdirs(); File backupFile = new File(backupFolder, "forsale.yml"); if (backupFile.isFile()) { backupFile.delete(); } ymlSaveLoc.renameTo(backupFile); } tmpFile.renameTo(ymlSaveLoc); // Leases save ymlSaveLoc = new File(saveFolder, "leases.yml"); tmpFile = new File(saveFolder, "tmp_leases.yml"); yml = new YMLSaveHelper(tmpFile); yml.getRoot().put("Version", saveVersion); yml.getRoot().put("Leases", leasemanager.save()); yml.save(); if (ymlSaveLoc.isFile()) { File backupFolder = new File(saveFolder, "Backup"); backupFolder.mkdirs(); File backupFile = new File(backupFolder, "leases.yml"); if (backupFile.isFile()) { backupFile.delete(); } ymlSaveLoc.renameTo(backupFile); } tmpFile.renameTo(ymlSaveLoc); // permlist save ymlSaveLoc = new File(saveFolder, "permlists.yml"); tmpFile = new File(saveFolder, "tmp_permlists.yml"); yml = new YMLSaveHelper(tmpFile); yml.getRoot().put("Version", saveVersion); yml.getRoot().put("PermissionLists", pmanager.save()); yml.save(); if (ymlSaveLoc.isFile()) { File backupFolder = new File(saveFolder, "Backup"); backupFolder.mkdirs(); File backupFile = new File(backupFolder, "permlists.yml"); if (backupFile.isFile()) { backupFile.delete(); } ymlSaveLoc.renameTo(backupFile); } tmpFile.renameTo(ymlSaveLoc); // rent save ymlSaveLoc = new File(saveFolder, "rent.yml"); tmpFile = new File(saveFolder, "tmp_rent.yml"); yml = new YMLSaveHelper(tmpFile); yml.getRoot().put("Version", saveVersion); yml.getRoot().put("RentSystem", rentmanager.save()); yml.save(); if (ymlSaveLoc.isFile()) { File backupFolder = new File(saveFolder, "Backup"); backupFolder.mkdirs(); File backupFile = new File(backupFolder, "rent.yml"); if (backupFile.isFile()) { backupFile.delete(); } ymlSaveLoc.renameTo(backupFile); } tmpFile.renameTo(ymlSaveLoc); this.getLogger().info("保存领地数据到文件中,耗时" + ((float) (System.currentTimeMillis() - time) / 1000) + " 秒)"); if (cmanager.showIntervalMessages()) { this.getLogger().info(" - 保存插件数据..."); } } private void writeDefaultConfigFromJar() { if (this.writeDefaultFileFromJar(new File(this.getDataFolder(), "config.yml"), "config.yml", true)) { this.getLogger().info("保存默认配置文件..."); } } @SuppressWarnings("resource") private boolean writeDefaultFileFromJar(File writeName, String jarPath, boolean backupOld) { try { File fileBackup = new File(this.getDataFolder(), "backup-" + writeName); File jarloc = new File(getClass().getProtectionDomain().getCodeSource().getLocation().toURI()).getCanonicalFile(); if (jarloc.isFile()) { JarFile jar = new JarFile(jarloc); JarEntry entry = jar.getJarEntry(jarPath); if (entry != null && !entry.isDirectory()) { InputStream in = jar.getInputStream(entry); InputStreamReader isr = new InputStreamReader(in, "UTF8"); if (writeName.isFile()) { if (backupOld) { if (fileBackup.isFile()) { fileBackup.delete(); } writeName.renameTo(fileBackup); } else { writeName.delete(); } } FileOutputStream out = new FileOutputStream(writeName); OutputStreamWriter osw = new OutputStreamWriter(out, "UTF8"); char[] tempbytes = new char[512]; int readbytes = isr.read(tempbytes, 0, 512); while (readbytes > -1) { osw.write(tempbytes, 0, readbytes); readbytes = isr.read(tempbytes, 0, 512); } osw.close(); isr.close(); return true; } } return false; } catch (Exception ex) { this.getLogger().warning("文件写入失败: " + writeName); return false; } } private void writeDefaultLanguageFile(String lang) { File outFile = new File(new File(this.getDataFolder(), "Language"), lang + ".yml"); outFile.getParentFile().mkdirs(); if (this.writeDefaultFileFromJar(outFile, "languagefiles/" + lang + ".yml", true)) { this.getLogger().info("保存默认 " + lang + " 语言文件..."); } } }