mcMMO.java 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455
  1. package com.gmail.nossr50;
  2. import java.io.File;
  3. import java.io.IOException;
  4. import java.util.ArrayList;
  5. import java.util.List;
  6. import org.bukkit.entity.Player;
  7. import org.bukkit.event.HandlerList;
  8. import org.bukkit.metadata.FixedMetadataValue;
  9. import org.bukkit.plugin.PluginManager;
  10. import org.bukkit.plugin.java.JavaPlugin;
  11. import com.gmail.nossr50.config.AdvancedConfig;
  12. import com.gmail.nossr50.config.Config;
  13. import com.gmail.nossr50.config.HiddenConfig;
  14. import com.gmail.nossr50.config.mods.CustomArmorConfig;
  15. import com.gmail.nossr50.config.mods.CustomBlockConfig;
  16. import com.gmail.nossr50.config.mods.CustomEntityConfig;
  17. import com.gmail.nossr50.config.mods.CustomToolConfig;
  18. import com.gmail.nossr50.config.repair.RepairConfigManager;
  19. import com.gmail.nossr50.config.treasure.TreasureConfig;
  20. import com.gmail.nossr50.database.DatabaseManager;
  21. import com.gmail.nossr50.database.DatabaseManagerFactory;
  22. import com.gmail.nossr50.listeners.BlockListener;
  23. import com.gmail.nossr50.listeners.EntityListener;
  24. import com.gmail.nossr50.listeners.InventoryListener;
  25. import com.gmail.nossr50.listeners.PlayerListener;
  26. import com.gmail.nossr50.listeners.ScoreboardsListener;
  27. import com.gmail.nossr50.listeners.SelfListener;
  28. import com.gmail.nossr50.listeners.WorldListener;
  29. import com.gmail.nossr50.locale.LocaleLoader;
  30. import com.gmail.nossr50.metrics.MetricsManager;
  31. import com.gmail.nossr50.party.PartyManager;
  32. import com.gmail.nossr50.runnables.SaveTimerTask;
  33. import com.gmail.nossr50.runnables.backups.CleanBackupsTask;
  34. import com.gmail.nossr50.runnables.database.UserPurgeTask;
  35. import com.gmail.nossr50.runnables.party.PartyAutoKickTask;
  36. import com.gmail.nossr50.runnables.player.PowerLevelUpdatingTask;
  37. import com.gmail.nossr50.runnables.skills.BleedTimerTask;
  38. import com.gmail.nossr50.skills.child.ChildConfig;
  39. import com.gmail.nossr50.skills.repair.repairables.Repairable;
  40. import com.gmail.nossr50.skills.repair.repairables.RepairableManager;
  41. import com.gmail.nossr50.skills.repair.repairables.SimpleRepairableManager;
  42. import com.gmail.nossr50.util.ChimaeraWing;
  43. import com.gmail.nossr50.util.LogFilter;
  44. import com.gmail.nossr50.util.Misc;
  45. import com.gmail.nossr50.util.Permissions;
  46. import com.gmail.nossr50.util.blockmeta.chunkmeta.ChunkManager;
  47. import com.gmail.nossr50.util.blockmeta.chunkmeta.ChunkManagerFactory;
  48. import com.gmail.nossr50.util.commands.CommandRegistrationManager;
  49. import com.gmail.nossr50.util.experience.FormulaManager;
  50. import com.gmail.nossr50.util.player.UserManager;
  51. import com.gmail.nossr50.util.scoreboards.ScoreboardManager;
  52. import net.gravitydevelopment.updater.mcmmo.Updater;
  53. import net.gravitydevelopment.updater.mcmmo.Updater.UpdateResult;
  54. import net.gravitydevelopment.updater.mcmmo.Updater.UpdateType;
  55. import net.shatteredlands.shatt.backup.ZipLibrary;
  56. public class mcMMO extends JavaPlugin {
  57. /* Managers */
  58. private static ChunkManager placeStore;
  59. private static RepairableManager repairableManager;
  60. private static DatabaseManager databaseManager;
  61. private static FormulaManager formulaManager;
  62. /* File Paths */
  63. private static String mainDirectory;
  64. private static String flatFileDirectory;
  65. private static String usersFile;
  66. private static String modDirectory;
  67. public static mcMMO p;
  68. // Jar Stuff
  69. public static File mcmmo;
  70. // Update Check
  71. private boolean updateAvailable;
  72. /* Plugin Checks */
  73. private static boolean combatTagEnabled;
  74. private static boolean healthBarPluginEnabled;
  75. private static boolean noCheatPlusPluginEnabled;
  76. private static boolean compatNoCheatPlusPluginEnabled;
  77. private static boolean mcpcEnabled;
  78. // Config Validation Check
  79. public boolean noErrorsInConfigFiles = true;
  80. // XP Event Check
  81. private boolean xpEventEnabled;
  82. /* Metadata Values */
  83. public final static String entityMetadataKey = "mcMMO: Spawned Entity";
  84. public final static String blockMetadataKey = "mcMMO: Piston Tracking";
  85. public final static String furnaceMetadataKey = "mcMMO: Tracked Furnace";
  86. public final static String tntMetadataKey = "mcMMO: Tracked TNT";
  87. public final static String tntsafeMetadataKey = "mcMMO: Safe TNT";
  88. public final static String customNameKey = "mcMMO: Custom Name";
  89. public final static String customVisibleKey = "mcMMO: Name Visibility";
  90. public final static String droppedItemKey = "mcMMO: Tracked Item";
  91. public final static String infiniteArrowKey = "mcMMO: Infinite Arrow";
  92. public final static String bowForceKey = "mcMMO: Bow Force";
  93. public final static String arrowDistanceKey = "mcMMO: Arrow Distance";
  94. public final static String customDamageKey = "mcMMO: Custom Damage";
  95. public final static String disarmedItemKey = "mcMMO: Disarmed Item";
  96. public static FixedMetadataValue metadataValue;
  97. /**
  98. * Things to be run when the plugin is enabled.
  99. */
  100. @Override
  101. public void onEnable() {
  102. try {
  103. p = this;
  104. getLogger().setFilter(new LogFilter(this));
  105. metadataValue = new FixedMetadataValue(this, true);
  106. mcpcEnabled = getServer().getName().equals("MCPC+");
  107. combatTagEnabled = getServer().getPluginManager().getPlugin("CombatTag") != null;
  108. healthBarPluginEnabled = getServer().getPluginManager().getPlugin("HealthBar") != null;
  109. noCheatPlusPluginEnabled = getServer().getPluginManager().getPlugin("NoCheatPlus") != null;
  110. compatNoCheatPlusPluginEnabled = getServer().getPluginManager().getPlugin("CompatNoCheatPlus") != null;
  111. setupFilePaths();
  112. loadConfigFiles();
  113. if (!noErrorsInConfigFiles) {
  114. return;
  115. }
  116. if (mcpcEnabled) {
  117. checkModConfigs();
  118. }
  119. if (healthBarPluginEnabled) {
  120. getLogger().info("HealthBar plugin found, mcMMO's healthbars are automatically disabled.");
  121. }
  122. if (noCheatPlusPluginEnabled && !compatNoCheatPlusPluginEnabled) {
  123. getLogger().warning("NoCheatPlus plugin found, but CompatNoCheatPlus was not found!");
  124. getLogger().warning("mcMMO will not work properly alongside NoCheatPlus without CompatNoCheatPlus");
  125. }
  126. databaseManager = DatabaseManagerFactory.getDatabaseManager();
  127. registerEvents();
  128. registerCustomRecipes();
  129. PartyManager.loadParties();
  130. formulaManager = new FormulaManager();
  131. for (Player player : getServer().getOnlinePlayers()) {
  132. UserManager.addUser(player); // In case of reload add all users back into UserManager
  133. ScoreboardManager.setupPlayer(player);
  134. }
  135. debug("Version " + getDescription().getVersion() + " is enabled!");
  136. scheduleTasks();
  137. CommandRegistrationManager.registerCommands();
  138. MetricsManager.setup();
  139. placeStore = ChunkManagerFactory.getChunkManager(); // Get our ChunkletManager
  140. checkForUpdates();
  141. if (Config.getInstance().getPTPCommandWorldPermissions()) {
  142. Permissions.generateWorldTeleportPermissions();
  143. }
  144. }
  145. catch (Throwable t) {
  146. getLogger().severe("There was an error while enabling mcMMO!");
  147. if (!(t instanceof ExceptionInInitializerError)) {
  148. t.printStackTrace();
  149. }
  150. else {
  151. getLogger().info("Please do not replace the mcMMO jar while the server is running.");
  152. }
  153. getServer().getPluginManager().disablePlugin(this);
  154. }
  155. }
  156. /**
  157. * Things to be run when the plugin is disabled.
  158. */
  159. @Override
  160. public void onDisable() {
  161. try {
  162. UserManager.saveAll(); // Make sure to save player information if the server shuts down
  163. PartyManager.saveParties(); // Save our parties
  164. ScoreboardManager.teardownAll();
  165. formulaManager.saveFormula();
  166. placeStore.saveAll(); // Save our metadata
  167. placeStore.cleanUp(); // Cleanup empty metadata stores
  168. }
  169. catch (NullPointerException e) {}
  170. getServer().getScheduler().cancelTasks(this); // This removes our tasks
  171. HandlerList.unregisterAll(this); // Cancel event registrations
  172. if (Config.getInstance().getBackupsEnabled()) {
  173. // Remove other tasks BEFORE starting the Backup, or we just cancel it straight away.
  174. try {
  175. ZipLibrary.mcMMOBackup();
  176. }
  177. catch (IOException e) {
  178. getLogger().severe(e.toString());
  179. }
  180. catch (Throwable e) {
  181. if (e instanceof NoClassDefFoundError) {
  182. getLogger().severe("Backup class not found!");
  183. getLogger().info("Please do not replace the mcMMO jar while the server is running.");
  184. }
  185. else {
  186. getLogger().severe(e.toString());
  187. }
  188. }
  189. }
  190. debug("Was disabled."); // How informative!
  191. }
  192. public static String getMainDirectory() {
  193. return mainDirectory;
  194. }
  195. public static String getFlatFileDirectory() {
  196. return flatFileDirectory;
  197. }
  198. public static String getUsersFilePath() {
  199. return usersFile;
  200. }
  201. public static String getModDirectory() {
  202. return modDirectory;
  203. }
  204. public boolean isUpdateAvailable() {
  205. return updateAvailable;
  206. }
  207. public boolean isXPEventEnabled() {
  208. return xpEventEnabled;
  209. }
  210. public void setXPEventEnabled(boolean enabled) {
  211. this.xpEventEnabled = enabled;
  212. }
  213. public void toggleXpEventEnabled() {
  214. xpEventEnabled = !xpEventEnabled;
  215. }
  216. public void debug(String message) {
  217. getLogger().info("[Debug] " + message);
  218. }
  219. public static FormulaManager getFormulaManager() {
  220. return formulaManager;
  221. }
  222. public static ChunkManager getPlaceStore() {
  223. return placeStore;
  224. }
  225. public static RepairableManager getRepairableManager() {
  226. return repairableManager;
  227. }
  228. public static DatabaseManager getDatabaseManager() {
  229. return databaseManager;
  230. }
  231. @Deprecated
  232. public static void setDatabaseManager(DatabaseManager databaseManager) {
  233. mcMMO.databaseManager = databaseManager;
  234. }
  235. public static boolean isCombatTagEnabled() {
  236. return combatTagEnabled;
  237. }
  238. public static boolean isHealthBarPluginEnabled() {
  239. return healthBarPluginEnabled;
  240. }
  241. public static boolean isMCPCEnabled() {
  242. return mcpcEnabled;
  243. }
  244. /**
  245. * Setup the various storage file paths
  246. */
  247. private void setupFilePaths() {
  248. mcmmo = getFile();
  249. mainDirectory = getDataFolder().getPath() + File.separator;
  250. flatFileDirectory = mainDirectory + "flatfile" + File.separator;
  251. usersFile = flatFileDirectory + "mcmmo.users";
  252. modDirectory = mainDirectory + "mods" + File.separator;
  253. fixFilePaths();
  254. }
  255. private void fixFilePaths() {
  256. File oldFlatfilePath = new File(mainDirectory + "FlatFileStuff" + File.separator);
  257. File oldModPath = new File(mainDirectory + "ModConfigs" + File.separator);
  258. if (oldFlatfilePath.exists()) {
  259. oldFlatfilePath.renameTo(new File(flatFileDirectory));
  260. }
  261. if (oldModPath.exists()) {
  262. oldModPath.renameTo(new File(modDirectory));
  263. }
  264. }
  265. private void checkForUpdates() {
  266. if (!Config.getInstance().getUpdateCheckEnabled()) {
  267. return;
  268. }
  269. Updater updater = new Updater(this, 31030, mcmmo, UpdateType.NO_DOWNLOAD, false);
  270. if (updater.getResult() != UpdateResult.UPDATE_AVAILABLE) {
  271. this.updateAvailable = false;
  272. return;
  273. }
  274. if (updater.getLatestType().equals("beta") && !Config.getInstance().getPreferBeta()) {
  275. this.updateAvailable = false;
  276. return;
  277. }
  278. this.updateAvailable = true;
  279. getLogger().info(LocaleLoader.getString("UpdateChecker.Outdated"));
  280. getLogger().info(LocaleLoader.getString("UpdateChecker.NewAvailable"));
  281. }
  282. private void loadConfigFiles() {
  283. // Force the loading of config files
  284. TreasureConfig.getInstance();
  285. HiddenConfig.getInstance();
  286. AdvancedConfig.getInstance();
  287. new ChildConfig();
  288. List<Repairable> repairables = new ArrayList<Repairable>();
  289. if (Config.getInstance().getToolModsEnabled()) {
  290. repairables.addAll(CustomToolConfig.getInstance().getLoadedRepairables());
  291. }
  292. if (Config.getInstance().getArmorModsEnabled()) {
  293. repairables.addAll(CustomArmorConfig.getInstance().getLoadedRepairables());
  294. }
  295. if (Config.getInstance().getBlockModsEnabled()) {
  296. CustomBlockConfig.getInstance();
  297. }
  298. if (Config.getInstance().getEntityModsEnabled()) {
  299. CustomEntityConfig.getInstance();
  300. }
  301. // Load repair configs, make manager, and register them at this time
  302. RepairConfigManager rManager = new RepairConfigManager(this);
  303. repairables.addAll(rManager.getLoadedRepairables());
  304. repairableManager = new SimpleRepairableManager(repairables.size());
  305. repairableManager.registerRepairables(repairables);
  306. }
  307. private void registerEvents() {
  308. PluginManager pluginManager = getServer().getPluginManager();
  309. // Register events
  310. pluginManager.registerEvents(new PlayerListener(this), this);
  311. pluginManager.registerEvents(new BlockListener(this), this);
  312. pluginManager.registerEvents(new EntityListener(this), this);
  313. pluginManager.registerEvents(new InventoryListener(this), this);
  314. pluginManager.registerEvents(new SelfListener(), this);
  315. pluginManager.registerEvents(new ScoreboardsListener(), this);
  316. pluginManager.registerEvents(new WorldListener(this), this);
  317. }
  318. private void registerCustomRecipes() {
  319. if (Config.getInstance().getChimaeraEnabled()) {
  320. getServer().addRecipe(ChimaeraWing.getChimaeraWingRecipe());
  321. }
  322. }
  323. private void scheduleTasks() {
  324. // Periodic save timer (Saves every 10 minutes by default)
  325. long saveIntervalTicks = Config.getInstance().getSaveInterval() * 1200;
  326. new SaveTimerTask().runTaskTimer(this, saveIntervalTicks, saveIntervalTicks);
  327. // Cleanup the backups folder
  328. new CleanBackupsTask().runTaskAsynchronously(mcMMO.p);
  329. // Bleed timer (Runs every two seconds)
  330. new BleedTimerTask().runTaskTimer(this, 2 * Misc.TICK_CONVERSION_FACTOR, 2 * Misc.TICK_CONVERSION_FACTOR);
  331. // Old & Powerless User remover
  332. long purgeIntervalTicks = Config.getInstance().getPurgeInterval() * 60 * 60 * Misc.TICK_CONVERSION_FACTOR;
  333. if (purgeIntervalTicks == 0) {
  334. new UserPurgeTask().runTaskLater(this, 2 * Misc.TICK_CONVERSION_FACTOR); // Start 2 seconds after startup.
  335. }
  336. else if (purgeIntervalTicks > 0) {
  337. new UserPurgeTask().runTaskTimer(this, purgeIntervalTicks, purgeIntervalTicks);
  338. }
  339. // Automatically remove old members from parties
  340. long kickIntervalTicks = Config.getInstance().getAutoPartyKickInterval() * 60 * 60 * Misc.TICK_CONVERSION_FACTOR;
  341. if (kickIntervalTicks == 0) {
  342. new PartyAutoKickTask().runTaskLater(this, 2 * Misc.TICK_CONVERSION_FACTOR); // Start 2 seconds after startup.
  343. }
  344. else if (kickIntervalTicks > 0) {
  345. new PartyAutoKickTask().runTaskTimer(this, kickIntervalTicks, kickIntervalTicks);
  346. }
  347. // Update power level tag scoreboards
  348. new PowerLevelUpdatingTask().runTaskTimer(this, 2 * Misc.TICK_CONVERSION_FACTOR, 2 * Misc.TICK_CONVERSION_FACTOR);
  349. }
  350. private void checkModConfigs() {
  351. if (!Config.getInstance().getToolModsEnabled()) {
  352. getLogger().info("MCPC+ implementation found, but the custom tool config for mcMMO is disabled!");
  353. getLogger().info("To enable, set Mods.Tool_Mods_Enabled to TRUE in config.yml.");
  354. }
  355. if (!Config.getInstance().getArmorModsEnabled()) {
  356. getLogger().info("MCPC+ implementation found, but the custom armor config for mcMMO is disabled!");
  357. getLogger().info("To enable, set Mods.Armor_Mods_Enabled to TRUE in config.yml.");
  358. }
  359. if (!Config.getInstance().getBlockModsEnabled()) {
  360. getLogger().info("MCPC+ implementation found, but the custom block config for mcMMO is disabled!");
  361. getLogger().info("To enable, set Mods.Block_Mods_Enabled to TRUE in config.yml.");
  362. }
  363. if (!Config.getInstance().getEntityModsEnabled()) {
  364. getLogger().info("MCPC+ implementation found, but the custom entity config for mcMMO is disabled!");
  365. getLogger().info("To enable, set Mods.Entity_Mods_Enabled to TRUE in config.yml.");
  366. }
  367. }
  368. }