mcMMO.java 20 KB

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