mcMMO.java 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537
  1. package com.gmail.nossr50;
  2. import com.gmail.nossr50.config.AdvancedConfig;
  3. import com.gmail.nossr50.config.Config;
  4. import com.gmail.nossr50.config.CoreSkillsConfig;
  5. import com.gmail.nossr50.config.HiddenConfig;
  6. import com.gmail.nossr50.config.experience.ExperienceConfig;
  7. import com.gmail.nossr50.config.mods.ArmorConfigManager;
  8. import com.gmail.nossr50.config.mods.BlockConfigManager;
  9. import com.gmail.nossr50.config.mods.EntityConfigManager;
  10. import com.gmail.nossr50.config.mods.ToolConfigManager;
  11. import com.gmail.nossr50.config.skills.alchemy.PotionConfig;
  12. import com.gmail.nossr50.config.skills.repair.RepairConfigManager;
  13. import com.gmail.nossr50.config.skills.salvage.SalvageConfigManager;
  14. import com.gmail.nossr50.config.treasure.TreasureConfig;
  15. import com.gmail.nossr50.database.DatabaseManager;
  16. import com.gmail.nossr50.database.DatabaseManagerFactory;
  17. import com.gmail.nossr50.datatypes.skills.PrimarySkill;
  18. import com.gmail.nossr50.datatypes.skills.subskills.acrobatics.Roll;
  19. import com.gmail.nossr50.listeners.*;
  20. import com.gmail.nossr50.party.PartyManager;
  21. import com.gmail.nossr50.runnables.CheckDateTask;
  22. import com.gmail.nossr50.runnables.SaveTimerTask;
  23. import com.gmail.nossr50.runnables.backups.CleanBackupsTask;
  24. import com.gmail.nossr50.runnables.database.UserPurgeTask;
  25. import com.gmail.nossr50.runnables.party.PartyAutoKickTask;
  26. import com.gmail.nossr50.runnables.player.ClearRegisteredXPGainTask;
  27. import com.gmail.nossr50.runnables.player.PlayerProfileLoadingTask;
  28. import com.gmail.nossr50.runnables.player.PowerLevelUpdatingTask;
  29. import com.gmail.nossr50.runnables.skills.BleedTimerTask;
  30. import com.gmail.nossr50.skills.alchemy.Alchemy;
  31. import com.gmail.nossr50.skills.child.ChildConfig;
  32. import com.gmail.nossr50.skills.repair.repairables.Repairable;
  33. import com.gmail.nossr50.skills.repair.repairables.RepairableManager;
  34. import com.gmail.nossr50.skills.repair.repairables.SimpleRepairableManager;
  35. import com.gmail.nossr50.skills.salvage.salvageables.Salvageable;
  36. import com.gmail.nossr50.skills.salvage.salvageables.SalvageableManager;
  37. import com.gmail.nossr50.skills.salvage.salvageables.SimpleSalvageableManager;
  38. import com.gmail.nossr50.skills.smelting.SmeltingManager;
  39. import com.gmail.nossr50.util.*;
  40. import com.gmail.nossr50.util.blockmeta.chunkmeta.ChunkManager;
  41. import com.gmail.nossr50.util.blockmeta.chunkmeta.ChunkManagerFactory;
  42. import com.gmail.nossr50.util.commands.CommandRegistrationManager;
  43. import com.gmail.nossr50.util.experience.FormulaManager;
  44. import com.gmail.nossr50.util.player.UserManager;
  45. import com.gmail.nossr50.util.scoreboards.ScoreboardManager;
  46. import com.gmail.nossr50.util.upgrade.UpgradeManager;
  47. import com.google.common.base.Charsets;
  48. import net.shatteredlands.shatt.backup.ZipLibrary;
  49. import org.bukkit.Material;
  50. import org.bukkit.entity.Player;
  51. import org.bukkit.event.HandlerList;
  52. import org.bukkit.metadata.FixedMetadataValue;
  53. import org.bukkit.plugin.PluginManager;
  54. import org.bukkit.plugin.java.JavaPlugin;
  55. import java.io.File;
  56. import java.io.IOException;
  57. import java.io.InputStream;
  58. import java.io.InputStreamReader;
  59. import java.util.ArrayList;
  60. import java.util.List;
  61. public class mcMMO extends JavaPlugin {
  62. /* Managers */
  63. private static ChunkManager placeStore;
  64. private static RepairableManager repairableManager;
  65. private static SalvageableManager salvageableManager;
  66. private static ModManager modManager;
  67. private static DatabaseManager databaseManager;
  68. private static FormulaManager formulaManager;
  69. private static HolidayManager holidayManager;
  70. private static UpgradeManager upgradeManager;
  71. /* File Paths */
  72. private static String mainDirectory;
  73. private static String flatFileDirectory;
  74. private static String usersFile;
  75. private static String modDirectory;
  76. public static mcMMO p;
  77. // Jar Stuff
  78. public static File mcmmo;
  79. /* Plugin Checks */
  80. private static boolean healthBarPluginEnabled;
  81. // Config Validation Check
  82. public boolean noErrorsInConfigFiles = true;
  83. // XP Event Check
  84. private boolean xpEventEnabled;
  85. private boolean UseOldLevelScalingEnabled;
  86. /* Metadata Values */
  87. public final static String entityMetadataKey = "mcMMO: Spawned Entity";
  88. public final static String blockMetadataKey = "mcMMO: Piston Tracking";
  89. public final static String furnaceMetadataKey = "mcMMO: Tracked Furnace";
  90. public final static String tntMetadataKey = "mcMMO: Tracked TNT";
  91. public final static String funfettiMetadataKey = "mcMMO: Funfetti";
  92. public final static String tntsafeMetadataKey = "mcMMO: Safe TNT";
  93. public final static String customNameKey = "mcMMO: Custom Name";
  94. public final static String customVisibleKey = "mcMMO: Name Visibility";
  95. public final static String droppedItemKey = "mcMMO: Tracked Item";
  96. public final static String infiniteArrowKey = "mcMMO: Infinite Arrow";
  97. public final static String bowForceKey = "mcMMO: Bow Force";
  98. public final static String arrowDistanceKey = "mcMMO: Arrow Distance";
  99. //public final static String customDamageKey = "mcMMO: Custom Damage";
  100. public final static String disarmedItemKey = "mcMMO: Disarmed Item";
  101. public final static String playerDataKey = "mcMMO: Player Data";
  102. public final static String greenThumbDataKey = "mcMMO: Green Thumb";
  103. public final static String databaseCommandKey = "mcMMO: Processing Database Command";
  104. public final static String bredMetadataKey = "mcMMO: Bred Animal";
  105. public static FixedMetadataValue metadataValue;
  106. /**
  107. * Things to be run when the plugin is enabled.
  108. */
  109. @Override
  110. public void onEnable() {
  111. try {
  112. p = this;
  113. getLogger().setFilter(new LogFilter(this));
  114. metadataValue = new FixedMetadataValue(this, true);
  115. PluginManager pluginManager = getServer().getPluginManager();
  116. healthBarPluginEnabled = pluginManager.getPlugin("HealthBar") != null;
  117. upgradeManager = new UpgradeManager();
  118. setupFilePaths();
  119. modManager = new ModManager();
  120. loadConfigFiles();
  121. if (!noErrorsInConfigFiles) {
  122. return;
  123. }
  124. if (getServer().getName().equals("Cauldron") || getServer().getName().equals("MCPC+")) {
  125. checkModConfigs();
  126. }
  127. if (healthBarPluginEnabled) {
  128. getLogger().info("HealthBar plugin found, mcMMO's healthbars are automatically disabled.");
  129. }
  130. if (pluginManager.getPlugin("NoCheatPlus") != null && pluginManager.getPlugin("CompatNoCheatPlus") == null) {
  131. getLogger().warning("NoCheatPlus plugin found, but CompatNoCheatPlus was not found!");
  132. getLogger().warning("mcMMO will not work properly alongside NoCheatPlus without CompatNoCheatPlus");
  133. }
  134. databaseManager = DatabaseManagerFactory.getDatabaseManager();
  135. registerEvents();
  136. registerCoreSkills();
  137. registerCustomRecipes();
  138. PartyManager.loadParties();
  139. formulaManager = new FormulaManager();
  140. holidayManager = new HolidayManager();
  141. for (Player player : getServer().getOnlinePlayers()) {
  142. new PlayerProfileLoadingTask(player).runTaskLaterAsynchronously(mcMMO.p, 1); // 1 Tick delay to ensure the player is marked as online before we begin loading
  143. }
  144. debug("Version " + getDescription().getVersion() + " is enabled!");
  145. scheduleTasks();
  146. CommandRegistrationManager.registerCommands();
  147. placeStore = ChunkManagerFactory.getChunkManager(); // Get our ChunkletManager
  148. if (Config.getInstance().getPTPCommandWorldPermissions()) {
  149. Permissions.generateWorldTeleportPermissions();
  150. }
  151. }
  152. catch (Throwable t) {
  153. getLogger().severe("There was an error while enabling mcMMO!");
  154. if (!(t instanceof ExceptionInInitializerError)) {
  155. t.printStackTrace();
  156. }
  157. else {
  158. getLogger().info("Please do not replace the mcMMO jar while the server is running.");
  159. }
  160. getServer().getPluginManager().disablePlugin(this);
  161. }
  162. }
  163. /**
  164. * Things to be run when the plugin is disabled.
  165. */
  166. @Override
  167. public void onDisable() {
  168. try {
  169. Alchemy.finishAllBrews(); // Finish all partially complete AlchemyBrewTasks to prevent vanilla brewing continuation on restart
  170. UserManager.saveAll(); // Make sure to save player information if the server shuts down
  171. UserManager.clearAll();
  172. PartyManager.saveParties(); // Save our parties
  173. ScoreboardManager.teardownAll();
  174. formulaManager.saveFormula();
  175. holidayManager.saveAnniversaryFiles();
  176. placeStore.saveAll(); // Save our metadata
  177. placeStore.cleanUp(); // Cleanup empty metadata stores
  178. }
  179. catch (NullPointerException e) {}
  180. debug("Canceling all tasks...");
  181. getServer().getScheduler().cancelTasks(this); // This removes our tasks
  182. debug("Unregister all events...");
  183. HandlerList.unregisterAll(this); // Cancel event registrations
  184. if (Config.getInstance().getBackupsEnabled()) {
  185. // Remove other tasks BEFORE starting the Backup, or we just cancel it straight away.
  186. try {
  187. ZipLibrary.mcMMOBackup();
  188. }
  189. catch (IOException e) {
  190. getLogger().severe(e.toString());
  191. }
  192. catch (Throwable e) {
  193. if (e instanceof NoClassDefFoundError) {
  194. getLogger().severe("Backup class not found!");
  195. getLogger().info("Please do not replace the mcMMO jar while the server is running.");
  196. }
  197. else {
  198. getLogger().severe(e.toString());
  199. }
  200. }
  201. }
  202. databaseManager.onDisable();
  203. debug("Was disabled."); // How informative!
  204. }
  205. public static String getMainDirectory() {
  206. return mainDirectory;
  207. }
  208. public static String getFlatFileDirectory() {
  209. return flatFileDirectory;
  210. }
  211. public static String getUsersFilePath() {
  212. return usersFile;
  213. }
  214. public static String getModDirectory() {
  215. return modDirectory;
  216. }
  217. public boolean isXPEventEnabled() {
  218. return xpEventEnabled;
  219. }
  220. public void setXPEventEnabled(boolean enabled) {
  221. this.xpEventEnabled = enabled;
  222. }
  223. public void toggleXpEventEnabled() {
  224. xpEventEnabled = !xpEventEnabled;
  225. }
  226. public void debug(String message) {
  227. getLogger().info("[Debug] " + message);
  228. }
  229. public static FormulaManager getFormulaManager() {
  230. return formulaManager;
  231. }
  232. public static HolidayManager getHolidayManager() {
  233. return holidayManager;
  234. }
  235. public static ChunkManager getPlaceStore() {
  236. return placeStore;
  237. }
  238. public static RepairableManager getRepairableManager() {
  239. return repairableManager;
  240. }
  241. public static SalvageableManager getSalvageableManager() {
  242. return salvageableManager;
  243. }
  244. public static DatabaseManager getDatabaseManager() {
  245. return databaseManager;
  246. }
  247. public static ModManager getModManager() {
  248. return modManager;
  249. }
  250. public static UpgradeManager getUpgradeManager() {
  251. return upgradeManager;
  252. }
  253. @Deprecated
  254. public static void setDatabaseManager(DatabaseManager databaseManager) {
  255. mcMMO.databaseManager = databaseManager;
  256. }
  257. public static boolean isHealthBarPluginEnabled() {
  258. return healthBarPluginEnabled;
  259. }
  260. /**
  261. * Setup the various storage file paths
  262. */
  263. private void setupFilePaths() {
  264. mcmmo = getFile();
  265. mainDirectory = getDataFolder().getPath() + File.separator;
  266. flatFileDirectory = mainDirectory + "flatfile" + File.separator;
  267. usersFile = flatFileDirectory + "mcmmo.users";
  268. modDirectory = mainDirectory + "mods" + File.separator;
  269. fixFilePaths();
  270. }
  271. private void fixFilePaths() {
  272. File oldFlatfilePath = new File(mainDirectory + "FlatFileStuff" + File.separator);
  273. File oldModPath = new File(mainDirectory + "ModConfigs" + File.separator);
  274. if (oldFlatfilePath.exists()) {
  275. if (!oldFlatfilePath.renameTo(new File(flatFileDirectory))) {
  276. getLogger().warning("Failed to rename FlatFileStuff to flatfile!");
  277. }
  278. }
  279. if (oldModPath.exists()) {
  280. if (!oldModPath.renameTo(new File(modDirectory))) {
  281. getLogger().warning("Failed to rename ModConfigs to mods!");
  282. }
  283. }
  284. File oldArmorFile = new File(modDirectory + "armor.yml");
  285. File oldBlocksFile = new File(modDirectory + "blocks.yml");
  286. File oldEntitiesFile = new File(modDirectory + "entities.yml");
  287. File oldToolsFile = new File(modDirectory + "tools.yml");
  288. if (oldArmorFile.exists()) {
  289. if (!oldArmorFile.renameTo(new File(modDirectory + "armor.default.yml"))) {
  290. getLogger().warning("Failed to rename armor.yml to armor.default.yml!");
  291. }
  292. }
  293. if (oldBlocksFile.exists()) {
  294. if (!oldBlocksFile.renameTo(new File(modDirectory + "blocks.default.yml"))) {
  295. getLogger().warning("Failed to rename blocks.yml to blocks.default.yml!");
  296. }
  297. }
  298. if (oldEntitiesFile.exists()) {
  299. if (!oldEntitiesFile.renameTo(new File(modDirectory + "entities.default.yml"))) {
  300. getLogger().warning("Failed to rename entities.yml to entities.default.yml!");
  301. }
  302. }
  303. if (oldToolsFile.exists()) {
  304. if (!oldToolsFile.renameTo(new File(modDirectory + "tools.default.yml"))) {
  305. getLogger().warning("Failed to rename tools.yml to tools.default.yml!");
  306. }
  307. }
  308. File currentFlatfilePath = new File(flatFileDirectory);
  309. currentFlatfilePath.mkdirs();
  310. }
  311. private void loadConfigFiles() {
  312. // Force the loading of config files
  313. TreasureConfig.getInstance();
  314. HiddenConfig.getInstance();
  315. AdvancedConfig.getInstance();
  316. PotionConfig.getInstance();
  317. CoreSkillsConfig.getInstance();
  318. new ChildConfig();
  319. List<Repairable> repairables = new ArrayList<Repairable>();
  320. List<Salvageable> salvageables = new ArrayList<Salvageable>();
  321. if (Config.getInstance().getToolModsEnabled()) {
  322. new ToolConfigManager(this);
  323. }
  324. if (Config.getInstance().getArmorModsEnabled()) {
  325. new ArmorConfigManager(this);
  326. }
  327. if (Config.getInstance().getBlockModsEnabled()) {
  328. new BlockConfigManager(this);
  329. }
  330. if (Config.getInstance().getEntityModsEnabled()) {
  331. new EntityConfigManager(this);
  332. }
  333. // Load repair configs, make manager, and register them at this time
  334. repairables.addAll(new RepairConfigManager(this).getLoadedRepairables());
  335. repairables.addAll(modManager.getLoadedRepairables());
  336. repairableManager = new SimpleRepairableManager(repairables.size());
  337. repairableManager.registerRepairables(repairables);
  338. // Load salvage configs, make manager and register them at this time
  339. SalvageConfigManager sManager = new SalvageConfigManager(this);
  340. salvageables.addAll(sManager.getLoadedSalvageables());
  341. salvageableManager = new SimpleSalvageableManager(salvageables.size());
  342. salvageableManager.registerSalvageables(salvageables);
  343. }
  344. private void registerEvents() {
  345. PluginManager pluginManager = getServer().getPluginManager();
  346. // Register events
  347. pluginManager.registerEvents(new PlayerListener(this), this);
  348. pluginManager.registerEvents(new BlockListener(this), this);
  349. pluginManager.registerEvents(new EntityListener(this), this);
  350. pluginManager.registerEvents(new InventoryListener(this), this);
  351. pluginManager.registerEvents(new SelfListener(), this);
  352. pluginManager.registerEvents(new WorldListener(this), this);
  353. }
  354. /**
  355. * Registers core skills
  356. * This enables the skills in the new skill system
  357. */
  358. private void registerCoreSkills() {
  359. /*
  360. * Acrobatics skills
  361. */
  362. if(CoreSkillsConfig.getInstance().isPrimarySkillEnabled(PrimarySkill.ACROBATICS))
  363. {
  364. System.out.println("[mcMMO]" + " enabling Acrobatics Skills");
  365. //TODO: Should do this differently
  366. Roll roll = new Roll();
  367. CoreSkillsConfig.getInstance().isSkillEnabled(roll);
  368. InteractionManager.registerSubSkill(new Roll());
  369. }
  370. }
  371. private void registerCustomRecipes() {
  372. getServer().getScheduler().scheduleSyncDelayedTask(this, () -> {
  373. if (Config.getInstance().getChimaeraEnabled()) {
  374. getServer().addRecipe(ChimaeraWing.getChimaeraWingRecipe());
  375. }
  376. if (Config.getInstance().getFluxPickaxeEnabled()) {
  377. getServer().addRecipe(SmeltingManager.getFluxPickaxeRecipe(Material.DIAMOND_PICKAXE));
  378. getServer().addRecipe(SmeltingManager.getFluxPickaxeRecipe(Material.GOLDEN_PICKAXE));
  379. getServer().addRecipe(SmeltingManager.getFluxPickaxeRecipe(Material.IRON_PICKAXE));
  380. getServer().addRecipe(SmeltingManager.getFluxPickaxeRecipe(Material.STONE_PICKAXE));
  381. getServer().addRecipe(SmeltingManager.getFluxPickaxeRecipe(Material.WOODEN_PICKAXE));
  382. }
  383. }, 40);
  384. }
  385. private void scheduleTasks() {
  386. // Periodic save timer (Saves every 10 minutes by default)
  387. long saveIntervalTicks = Config.getInstance().getSaveInterval() * 1200;
  388. new SaveTimerTask().runTaskTimer(this, saveIntervalTicks, saveIntervalTicks);
  389. // Cleanup the backups folder
  390. new CleanBackupsTask().runTaskAsynchronously(mcMMO.p);
  391. // Bleed timer (Runs every two seconds)
  392. new BleedTimerTask().runTaskTimer(this, 2 * Misc.TICK_CONVERSION_FACTOR, 2 * Misc.TICK_CONVERSION_FACTOR);
  393. // Old & Powerless User remover
  394. long purgeIntervalTicks = Config.getInstance().getPurgeInterval() * 60L * 60L * Misc.TICK_CONVERSION_FACTOR;
  395. if (purgeIntervalTicks == 0) {
  396. new UserPurgeTask().runTaskLaterAsynchronously(this, 2 * Misc.TICK_CONVERSION_FACTOR); // Start 2 seconds after startup.
  397. }
  398. else if (purgeIntervalTicks > 0) {
  399. new UserPurgeTask().runTaskTimerAsynchronously(this, purgeIntervalTicks, purgeIntervalTicks);
  400. }
  401. // Automatically remove old members from parties
  402. long kickIntervalTicks = Config.getInstance().getAutoPartyKickInterval() * 60L * 60L * Misc.TICK_CONVERSION_FACTOR;
  403. if (kickIntervalTicks == 0) {
  404. new PartyAutoKickTask().runTaskLater(this, 2 * Misc.TICK_CONVERSION_FACTOR); // Start 2 seconds after startup.
  405. }
  406. else if (kickIntervalTicks > 0) {
  407. new PartyAutoKickTask().runTaskTimer(this, kickIntervalTicks, kickIntervalTicks);
  408. }
  409. // Update power level tag scoreboards
  410. new PowerLevelUpdatingTask().runTaskTimer(this, 2 * Misc.TICK_CONVERSION_FACTOR, 2 * Misc.TICK_CONVERSION_FACTOR);
  411. if (getHolidayManager().nearingAprilFirst()) {
  412. new CheckDateTask().runTaskTimer(this, 10L * Misc.TICK_CONVERSION_FACTOR, 1L * 60L * 60L * Misc.TICK_CONVERSION_FACTOR);
  413. }
  414. // Clear the registered XP data so players can earn XP again
  415. if (ExperienceConfig.getInstance().getDiminishedReturnsEnabled()) {
  416. new ClearRegisteredXPGainTask().runTaskTimer(this, 60, 60);
  417. }
  418. }
  419. private void checkModConfigs() {
  420. if (!Config.getInstance().getToolModsEnabled()) {
  421. getLogger().warning("Cauldron implementation found, but the custom tool config for mcMMO is disabled!");
  422. getLogger().info("To enable, set Mods.Tool_Mods_Enabled to TRUE in config.yml.");
  423. }
  424. if (!Config.getInstance().getArmorModsEnabled()) {
  425. getLogger().warning("Cauldron implementation found, but the custom armor config for mcMMO is disabled!");
  426. getLogger().info("To enable, set Mods.Armor_Mods_Enabled to TRUE in config.yml.");
  427. }
  428. if (!Config.getInstance().getBlockModsEnabled()) {
  429. getLogger().warning("Cauldron implementation found, but the custom block config for mcMMO is disabled!");
  430. getLogger().info("To enable, set Mods.Block_Mods_Enabled to TRUE in config.yml.");
  431. }
  432. if (!Config.getInstance().getEntityModsEnabled()) {
  433. getLogger().warning("Cauldron implementation found, but the custom entity config for mcMMO is disabled!");
  434. getLogger().info("To enable, set Mods.Entity_Mods_Enabled to TRUE in config.yml.");
  435. }
  436. }
  437. public InputStreamReader getResourceAsReader(String fileName) {
  438. InputStream in = getResource(fileName);
  439. return in == null ? null : new InputStreamReader(in, Charsets.UTF_8);
  440. }
  441. }