package plus.crates; import com.google.common.io.ByteStreams; import org.apache.commons.io.FileUtils; import org.apache.commons.io.LineIterator; import org.bukkit.*; import org.bukkit.block.Block; import org.bukkit.command.ConsoleCommandSender; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; import org.bukkit.event.Listener; import org.bukkit.metadata.MetadataValue; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.java.JavaPlugin; import plus.crates.Commands.CrateCommand; import plus.crates.Crates.Crate; import plus.crates.Crates.KeyCrate; import plus.crates.Handlers.*; import plus.crates.Listeners.BlockListeners; import plus.crates.Listeners.GUIListeners; import plus.crates.Listeners.PlayerInteract; import plus.crates.Listeners.PlayerJoin; import plus.crates.Utils.*; import java.io.*; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.UUID; import java.util.regex.Matcher; import java.util.regex.Pattern; public class CratesPlus extends JavaPlugin implements Listener { private String pluginPrefix = ""; private String updateMessage = ""; private String configBackup = null; private boolean updateAvailable = false; private ConfigHandler configHandler; private CrateHandler crateHandler; private SettingsHandler settingsHandler; private HologramHandler hologramHandler; private StorageHandler storageHandler; private String bukkitVersion = "0.0"; private Version_Util version_util; private static OpenHandler openHandler; private ArrayList<UUID> creatingCrate = new ArrayList<>(); public void onEnable() { Server server = getServer(); Pattern pattern = Pattern.compile("(^[^\\-]*)"); Matcher matcher = pattern.matcher(server.getBukkitVersion()); if (!matcher.find()) { getLogger().severe("Could not find Bukkit version... Disabling plugin"); setEnabled(false); return; } bukkitVersion = matcher.group(1); if (getConfig().isSet("Bukkit Version")) bukkitVersion = getConfig().getString("Bukkit Version"); if (LinfootUtil.versionCompare(bukkitVersion, "1.14.2") > 0) { // This means the plugin is using something newer than the latest tested build... we'll show a warning but carry on as usual getLogger().warning("CratesPlus has not yet been officially tested with Bukkit " + bukkitVersion + " but should still work"); } if (LinfootUtil.versionCompare(bukkitVersion, "1.9") > -1) { // Use 1.9+ Util version_util = new Version_1_9(this); } else if (LinfootUtil.versionCompare(bukkitVersion, "1.8") > -1) { // Use 1.8 Util version_util = new Version_1_8(this); } else if (LinfootUtil.versionCompare(bukkitVersion, "1.7") > -1) { // Use Default Util getLogger().warning("CratesPlus does NOT fully support Bukkit 1.7, if you have issues please report them but they may not be fixed"); version_util = new Version_Util(this); } else { getLogger().severe("CratesPlus does NOT support Bukkit " + bukkitVersion + ", if you believe this is an error please let me know"); if (!getConfig().isSet("Ignore Version") || !getConfig().getBoolean("Ignore Version")) { // People should only ignore this in the case of an error, doing an ignore on a unsupported version could break something setEnabled(false); return; } version_util = new Version_Util(this); // Use the 1.7 util? Probably has a lower chance of breaking } final ConsoleCommandSender console = server.getConsoleSender(); getConfig().options().copyDefaults(true); saveConfig(); hologramHandler = new HologramHandler(); StorageHandler.StorageType storageType = StorageHandler.StorageType.FLAT; try { storageType = StorageHandler.StorageType.valueOf(getConfig().getString("Storage Type", "FLAT").toUpperCase()); } catch (Exception e) { getLogger().warning(getConfig().getString("Storage Type", "FLAT") + " is not a valid storage type! Falling back to flat!"); } storageHandler = new StorageHandler(this, storageType); // Load new messages.yml File messagesFile = new File(getDataFolder(), "messages.yml"); if (!messagesFile.exists()) { try { messagesFile.createNewFile(); InputStream inputStream = getResource("messages.yml"); OutputStream outputStream = new FileOutputStream(messagesFile); ByteStreams.copy(inputStream, outputStream); } catch (IOException e) { e.printStackTrace(); } } YamlConfiguration messagesConfig = YamlConfiguration.loadConfiguration(messagesFile); MessageHandler.loadMessageConfiguration(this, messagesConfig, messagesFile); configHandler = new ConfigHandler(getConfig(), this); if (getConfig().getBoolean("Metrics")) { try { Metrics metrics = new Metrics(this); metrics.start(); MetricsCustom metricsCustom = new MetricsCustom(this); metricsCustom.start(); } catch (IOException e) { // Failed to submit the stats :-( } } // Load the crate handler crateHandler = new CrateHandler(this); // Do Prefix pluginPrefix = ChatColor.translateAlternateColorCodes('&', messagesConfig.getString("Prefix", "&7[&bCratesPlus&7]")) + " " + ChatColor.RESET; // Register /crate command Bukkit.getPluginCommand("crate").setExecutor(new CrateCommand(this)); // Register Events Bukkit.getPluginManager().registerEvents(new BlockListeners(this), this); Bukkit.getPluginManager().registerEvents(new PlayerJoin(this), this); Bukkit.getPluginManager().registerEvents(new GUIListeners(), this); Bukkit.getPluginManager().registerEvents(new PlayerInteract(this), this); openHandler = new OpenHandler(this); settingsHandler = new SettingsHandler(this); loadMetaData(); console.sendMessage(ChatColor.AQUA + getDescription().getName() + " Version " + getDescription().getVersion()); if (getDescription().getVersion().contains("SNAPSHOT")) { // Added this because some people didn't really understand what a "snapshot" is... console.sendMessage(ChatColor.RED + "Warning: You are running a snapshot build of CratesPlus"); console.sendMessage(ChatColor.RED + "It is advised that you do NOT run this on a production server!"); } switch (getHologramHandler().getHologramPlugin()) { default: case NONE: console.sendMessage(ChatColor.RED + "Unable to find compatible Hologram plugin, holograms will not work!"); break; case HOLOGRAPHIC_DISPLAYS: console.sendMessage(ChatColor.GREEN + "HolographicDisplays was found, hooking in!"); break; case INDIVIDUAL_HOLOGRAMS: console.sendMessage(ChatColor.GREEN + "IndividualHolograms was found, hooking in!"); break; } if (configBackup != null && Bukkit.getOnlinePlayers().size() > 0) { for (Player player : Bukkit.getOnlinePlayers()) { if (player.hasPermission("cratesplus.admin")) { player.sendMessage(pluginPrefix + ChatColor.GREEN + "Your config has been updated. Your old config was backed up to " + configBackup); configBackup = null; } } } if (getConfig().getBoolean("Update Checks", true)) { getServer().getScheduler().runTaskLaterAsynchronously(this, () -> checkUpdate(console), 10L); } } public void onDisable() { getConfigHandler().getCrates().forEach((key, crate) -> crate.onDisable()); } public String uploadConfig() { return uploadFile("config.yml"); } public String uploadData() { return uploadFile("data.yml"); } public String uploadMessages() { return uploadFile("messages.yml"); } public String uploadFile(String fileName) { File file = new File(getDataFolder(), fileName); if (!file.exists()) return null; LineIterator it; String lines = ""; try { it = FileUtils.lineIterator(file, "UTF-8"); try { while (it.hasNext()) { String line = it.nextLine(); lines += line + "\n"; } } finally { it.close(); } } catch (IOException e) { e.printStackTrace(); } return MCDebug.paste(fileName, lines); } private void checkUpdate(final ConsoleCommandSender console) { String updateBranch = getConfig().getString("Update Branch"); if (getDescription().getVersion().contains("SNAPSHOT")) updateBranch = "snapshot";//Force snapshot branch on snapshot builds String branch = updateBranch.toLowerCase(); if (branch.equalsIgnoreCase("snapshot")) { console.sendMessage(ChatColor.RED + "WARNING: Snapshot updates are not recommended on production servers"); } console.sendMessage(ChatColor.GREEN + "Checking for updates via " + branch + " branch..."); final LinfootUpdater updater = new LinfootUpdater(this, branch); final LinfootUpdater.UpdateResult snapShotResult = updater.getResult(); switch (snapShotResult) { default: case FAILED: updateAvailable = false; updateMessage = pluginPrefix + "Failed to check for updates. Will try again later."; getServer().getScheduler().runTaskLaterAsynchronously(this, () -> checkUpdate(console), 60 * (60 * 20L)); // Checks again an hour later break; case NO_UPDATE: updateAvailable = false; updateMessage = pluginPrefix + "No update was found, you are running the latest version. Will check again later."; getServer().getScheduler().runTaskLaterAsynchronously(this, () -> checkUpdate(console), 60 * (60 * 20L)); // Checks again an hour later break; case SNAPSHOT_UPDATE_AVAILABLE: updateAvailable = true; updateMessage = pluginPrefix + "A snapshot update for CratesPlus is available, new version is " + updater.getVersion() + ". Your installed version is " + getDescription().getVersion() + ".\nPlease update to the latest version :)"; break; case UPDATE_AVAILABLE: updateAvailable = true; updateMessage = pluginPrefix + "An update for CratesPlus is available, new version is " + updater.getVersion() + ". Your installed version is " + getDescription().getVersion() + ".\nPlease update to the latest version :)"; break; } if (updateMessage != null) console.sendMessage(updateMessage); } public void reloadPlugin() { reloadConfig(); // Do Prefix pluginPrefix = ChatColor.translateAlternateColorCodes('&', getConfig().getString("Prefix", "&7[&bCratesPlus&7]")) + " " + ChatColor.RESET; // Reload Configuration configHandler = new ConfigHandler(getConfig(), this); // Settings Handler settingsHandler = new SettingsHandler(this); } private void loadMetaData() { if (!getStorageHandler().getFlatConfig().isSet("Crate Locations")) return; for (String name : getStorageHandler().getFlatConfig().getConfigurationSection("Crate Locations").getKeys(false)) { final Crate crate = configHandler.getCrate(name.toLowerCase()); if (crate == null) continue; if (!(crate instanceof KeyCrate)) continue; KeyCrate keyCrate = (KeyCrate) crate; String path = "Crate Locations." + name; List<String> locations = getStorageHandler().getFlatConfig().getStringList(path); for (String location : locations) { List<String> strings = Arrays.asList(location.split("\\|")); if (strings.size() < 4) continue; // Somethings broke? if (strings.size() > 4) { // Somethings broke? But we'll try and fix it! for (int i = 0; i < strings.size(); i++) { if (strings.get(i).isEmpty() || strings.get(i).equals("")) { strings.remove(i); } } } Location locationObj; try { locationObj = new Location(Bukkit.getWorld(strings.get(0)), Double.parseDouble(strings.get(1)), Double.parseDouble(strings.get(2)), Double.parseDouble(strings.get(3))); Block block = locationObj.getBlock(); if (block == null || block.getType().equals(Material.AIR)) { getLogger().warning("No block found at " + location + " removing from data.yml"); keyCrate.removeFromConfig(locationObj); continue; } Location location1 = locationObj.getBlock().getLocation().add(0.5, 0.5, 0.5); keyCrate.loadHolograms(location1); final CratesPlus cratesPlus = this; block.setMetadata("CrateType", new MetadataValue() { @Override public Object value() { return crate.getName(false); } @Override public int asInt() { return 0; } @Override public float asFloat() { return 0; } @Override public double asDouble() { return 0; } @Override public long asLong() { return 0; } @Override public short asShort() { return 0; } @Override public byte asByte() { return 0; } @Override public boolean asBoolean() { return false; } @Override public String asString() { return value().toString(); } @Override public Plugin getOwningPlugin() { return cratesPlus; } @Override public void invalidate() { } }); } catch (Exception ignored) { } } } } public SettingsHandler getSettingsHandler() { return settingsHandler; } public String getPluginPrefix() { return pluginPrefix; } public ConfigHandler getConfigHandler() { return configHandler; } public HologramHandler getHologramHandler() { return hologramHandler; } public StorageHandler getStorageHandler() { return storageHandler; } public String getUpdateMessage() { return updateMessage; } public String getConfigBackup() { return configBackup; } public void setConfigBackup(String configBackup) { this.configBackup = configBackup; } public Version_Util getVersion_util() { return version_util; } public boolean isUpdateAvailable() { return updateAvailable; } public CrateHandler getCrateHandler() { return crateHandler; } public static OpenHandler getOpenHandler() { return openHandler; } public String getBukkitVersion() { return bukkitVersion; } public boolean isCreating(UUID uuid) { return creatingCrate.contains(uuid); } public void addCreating(UUID uuid) { creatingCrate.add(uuid); } public void removeCreating(UUID uuid) { creatingCrate.remove(uuid); } }