mcMMO.java 21 KB

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