diff --git a/pom.xml b/pom.xml index 48ac0cc..ac3fb78 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ me.plytki VirtualRealty - 1.3.0 + 1.4.0 jar VirtualRealty @@ -97,6 +97,10 @@ sonatype https://oss.sonatype.org/content/groups/public/ + + panda-repository + https://repo.panda-lang.org/ + @@ -130,5 +134,10 @@ 2.2.1 compile + + org.diorite + diorite-config-minimal + 1.2 + diff --git a/src/main/java/me/plytki/virtualrealty/VirtualRealty.java b/src/main/java/me/plytki/virtualrealty/VirtualRealty.java index dc7def5..abee090 100644 --- a/src/main/java/me/plytki/virtualrealty/VirtualRealty.java +++ b/src/main/java/me/plytki/virtualrealty/VirtualRealty.java @@ -3,31 +3,30 @@ import me.plytki.virtualrealty.commands.PlotCommand; import me.plytki.virtualrealty.commands.VirtualRealtyCommand; import me.plytki.virtualrealty.enums.PlotSize; -import me.plytki.virtualrealty.exceptions.IncompatibleVersionException; import me.plytki.virtualrealty.listeners.PlotListener; import me.plytki.virtualrealty.listeners.PlotProtectionListener; +import me.plytki.virtualrealty.listeners.WorldListener; +import me.plytki.virtualrealty.loaders.PluginConfiguration; +import me.plytki.virtualrealty.loaders.SizesConfiguration; import me.plytki.virtualrealty.managers.PlotManager; import me.plytki.virtualrealty.objects.Plot; import me.plytki.virtualrealty.sql.SQL; import me.plytki.virtualrealty.tasks.PlotExpireTask; +import me.plytki.virtualrealty.utils.ConfigUtil; import me.plytki.virtualrealty.utils.UpdateChecker; +import me.plytki.virtualrealty.utils.multiversion.VMaterial; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.LineIterator; import org.bstats.bukkit.Metrics; import org.bstats.charts.AdvancedPie; import org.bstats.charts.SimplePie; import org.bukkit.Bukkit; -import org.bukkit.ChatColor; import org.bukkit.Material; -import org.bukkit.configuration.InvalidConfigurationException; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.scheduler.BukkitTask; -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; +import java.io.*; +import java.util.*; import java.util.concurrent.Callable; public final class VirtualRealty extends JavaPlugin { @@ -36,49 +35,58 @@ public final class VirtualRealty extends JavaPlugin { public static final String PREFIX = "§a§lVR §8§l» §7"; public static ArrayList tasks = new ArrayList<>(); - private File sizesFile = new File(this.getDataFolder().getAbsolutePath() + "/sizes.yml"); - private FileConfiguration sizesConfiguration; public static File plotsFolder; public static File plotsSchemaFolder; - - private static final ArrayList compatibleVersions = new ArrayList<>(); - private boolean closedDueToIncompatibleVersion = false; + + private PluginConfiguration pluginConfiguration; + private SizesConfiguration sizesConfiguration; + private final File pluginConfigurationFile = new File(this.getDataFolder(), "config.yml"); + private final File sizesConfigurationFile = new File(this.getDataFolder(), "sizes.yml"); + + private static final ArrayList postVersions = new ArrayList<>(); + private boolean configError = false; + + public static boolean isLegacy = false; @Override public void onEnable() { // Plugin startup logic instance = this; - setCompatibleVersions(); - if (!checkCompatibleVersion(Bukkit.getBukkitVersion())) { - closedDueToIncompatibleVersion = true; - try { - throw new IncompatibleVersionException("You have installed the wrong VirtualRealty plugin for your server version - The correct plugin to use is §a§ohttps://www.spigotmc.org/resources/virtual-realty.95599/"); - } catch (IncompatibleVersionException e) { - e.printStackTrace(); - } - Bukkit.getServer().getPluginManager().disablePlugin(instance); - return; + if (!checkLegacyVersions()) { + isLegacy = true; } String[] updateCheck = UpdateChecker.getUpdate(); if (updateCheck != null) { if (!updateCheck[0].equals(this.getDescription().getVersion())) { - System.out.println(" "); this.getLogger().info("A new version is available!"); this.getLogger().info("Current version you're using: " + this.getDescription().getVersion()); this.getLogger().info("Latest version available: " + updateCheck[0]); this.getLogger().info("Download link: https://www.spigotmc.org/resources/virtual-realty.95599/"); - System.out.println(" "); } else { this.getLogger().info("Plugin is up to date!"); } } + try { + checkConfig(); + checkSizesConfig(); + } catch (IOException e) { + e.printStackTrace(); + } registerMetrics(); plotsFolder = new File(getInstance().getDataFolder().getAbsolutePath(), "plots"); plotsFolder.mkdirs(); plotsSchemaFolder = new File(plotsFolder.getAbsolutePath(), "primary-terrain"); plotsSchemaFolder.mkdirs(); - saveDefaultConfig(); - createSizesConfig(); + try { + this.pluginConfiguration = ConfigUtil.loadConfig(this.pluginConfigurationFile, PluginConfiguration.class); + this.sizesConfiguration = ConfigUtil.loadConfig(this.sizesConfigurationFile, SizesConfiguration.class); + } catch (Exception exception) { + exception.printStackTrace(); + configError = true; + this.getServer().getPluginManager().disablePlugin(this); + return; + } + //createSizesConfig(); loadSizesConfiguration(); connectToDatabase(); registerCommands(); @@ -89,7 +97,7 @@ public void onEnable() { @Override public void onDisable() { // Plugin shutdown logic - if (closedDueToIncompatibleVersion) { + if (configError) { return; } tasks.forEach(BukkitTask::cancel); @@ -104,6 +112,7 @@ private void registerCommands() { private void registerListeners() { getServer().getPluginManager().registerEvents(new PlotListener(), this); getServer().getPluginManager().registerEvents(new PlotProtectionListener(), this); + getServer().getPluginManager().registerEvents(new WorldListener(), this); } private void registerTasks() { @@ -158,53 +167,186 @@ private void connectToDatabase() { PlotManager.loadPlots(); } - private void createSizesConfig() { - sizesFile = new File(getDataFolder(), "sizes.yml"); - if (!sizesFile.exists()) { - sizesFile.getParentFile().mkdirs(); - saveResource("sizes.yml", false); - } - sizesConfiguration = new YamlConfiguration(); - try { - sizesConfiguration.load(sizesFile); - } catch (IOException | InvalidConfigurationException e) { - e.printStackTrace(); - } - } - public static void loadSizesConfiguration() { for (PlotSize plotSize : PlotSize.values()) { if (plotSize == PlotSize.CUSTOM) return; - plotSize.setLength(getInstance().sizesConfiguration.getInt("plots-sizes." + plotSize.name() + ".size.length")); - plotSize.setWidth(getInstance().sizesConfiguration.getInt("plots-sizes." + plotSize.name() + ".size.width")); - plotSize.setHeight(getInstance().sizesConfiguration.getInt("plots-sizes." + plotSize.name() + ".size.height")); - plotSize.setFloorMaterial(Material.valueOf(getInstance().sizesConfiguration.getString("plots-sizes." + plotSize.name() + ".floorMaterial"))); + SizesConfiguration.Size classSize = null; + switch (plotSize) { + case SMALL: { + classSize = getInstance().sizesConfiguration.plotSizes.SMALL; + break; + } + case MEDIUM: { + classSize = getInstance().sizesConfiguration.plotSizes.MEDIUM; + break; + } + case LARGE: { + classSize = getInstance().sizesConfiguration.plotSizes.LARGE; + break; + } + } + Material floorMaterial; + try { + floorMaterial = VMaterial.getMaterial(classSize.floorMaterial.toUpperCase()); + floorMaterial.name(); + } catch (Exception e) { + floorMaterial = VirtualRealty.isLegacy ? Material.GRASS : Material.GRASS_BLOCK; + VirtualRealty.getInstance().getLogger().warning("Couldn't parse floor-material from sizes.yml | Using default: " + (VirtualRealty.isLegacy ? Material.GRASS : Material.GRASS_BLOCK)); + } + Material borderMaterial; + try { + borderMaterial = VMaterial.getMaterial(classSize.borderMaterial.toUpperCase()); + borderMaterial.name(); + } catch (Exception e) { + borderMaterial = VirtualRealty.isLegacy ? Material.getMaterial("STEP") : Material.STONE_BRICK_SLAB; + VirtualRealty.getInstance().getLogger().warning("Couldn't parse border-material from sizes.yml | Using default: " + (VirtualRealty.isLegacy ? Material.getMaterial("STEP") : Material.STONE_BRICK_SLAB)); + } + plotSize.setFloorMaterial(floorMaterial); + plotSize.setFloorData(classSize.floorData); + plotSize.setBorderMaterial(borderMaterial); + plotSize.setBorderData(classSize.borderData); + plotSize.setLength(classSize.length); + plotSize.setWidth(classSize.width); + plotSize.setHeight(classSize.height); } } - public FileConfiguration getSizesConfiguration() { - return this.sizesConfiguration; - } - public static VirtualRealty getInstance() { return instance; } - public boolean checkCompatibleVersion(String version) { - for (String compatibleVersion : compatibleVersions) { - if (version.toLowerCase().contains(compatibleVersion.toLowerCase())) { + public static PluginConfiguration getPluginConfiguration() { + return getInstance().pluginConfiguration; + } + + public boolean checkLegacyVersions() { + setPostVersions(); + for (String postVersion : postVersions) { + if (Bukkit.getBukkitVersion().toLowerCase().contains(postVersion.toLowerCase())) { return true; } } return false; } - - public void setCompatibleVersions() { - compatibleVersions.add("1.17"); - compatibleVersions.add("1.16"); - compatibleVersions.add("1.15"); - compatibleVersions.add("1.14"); - compatibleVersions.add("1.13"); + + public void setPostVersions() { + postVersions.add("1.17"); + postVersions.add("1.16"); + postVersions.add("1.15"); + postVersions.add("1.14"); + postVersions.add("1.13"); + } + + public void checkConfig() throws IOException { + File oldConfigFile = new File(this.getDataFolder().getAbsolutePath(), "config.yml"); + if (!oldConfigFile.exists()) return; + String version = null; + boolean isOldVersion = true; + boolean updateConfigVersion = false; + BufferedReader reader = new BufferedReader(new FileReader(this.pluginConfigurationFile)); + String latestLine; + while((latestLine = reader.readLine()) != null) { + if (latestLine.contains("config-version")) { + version = latestLine.replaceAll("config-version: ", ""); + isOldVersion = false; + } + } + if (version == null) { + System.err.println(" "); + this.getLogger().warning("Config has been reset due to major config changes!"); + this.getLogger().warning("Old config has been renamed to config.yml.old"); + this.getLogger().warning("Please update your config file!"); + System.err.println(" "); + } else if (!version.equalsIgnoreCase(VirtualRealty.getInstance().getDescription().getVersion())) { + updateConfigVersion = true; + this.getLogger().info("Config has been updated!"); + } + + // save old config file + if (isOldVersion) { + File newConfigFile = new File(this.getDataFolder().getAbsolutePath(), "config.yml.old"); + if (newConfigFile.exists()) { + newConfigFile.delete(); + } + FileUtils.copyFile(oldConfigFile, newConfigFile); + oldConfigFile.delete(); + } + + // update config version + if (updateConfigVersion) { + List lines = new ArrayList<>(); + LineIterator iterator = FileUtils.lineIterator(oldConfigFile); + while (iterator.hasNext()) { + String line = iterator.next(); + lines.add(line); + } + for (String line : new ArrayList<>(lines)) { + if (line.contains("config-version")) { + int index = lines.indexOf(line); + lines.set(index, "config-version: " + VirtualRealty.getInstance().getDescription().getVersion()); + } + } + File newConfigFile = new File(this.getDataFolder().getAbsolutePath(), "config.yml"); + FileUtils.deleteQuietly(newConfigFile); + FileUtils.writeLines(newConfigFile, lines); + newConfigFile.createNewFile(); + } + } + + public void checkSizesConfig() throws IOException { + File oldConfigFile = new File(this.getDataFolder().getAbsolutePath(), "sizes.yml"); + if (!oldConfigFile.exists()) return; + String version = null; + boolean isOldVersion = true; + boolean updateConfigVersion = false; + BufferedReader reader = new BufferedReader(new FileReader(this.pluginConfigurationFile)); + String latestLine; + while((latestLine = reader.readLine()) != null) { + if (latestLine.contains("config-version")) { + version = latestLine.replaceAll("config-version: ", ""); + isOldVersion = false; + } + } + if (version == null) { + System.err.println(" "); + this.getLogger().warning("Config has been reset due to major config changes!"); + this.getLogger().warning("Old config has been renamed to sizes.yml.old"); + this.getLogger().warning("Please update your config file!"); + System.err.println(" "); + } else if (!version.equalsIgnoreCase(VirtualRealty.getInstance().getDescription().getVersion())) { + updateConfigVersion = true; + this.getLogger().info("Plot sizes config has been updated!"); + } + + // save old config file + if (isOldVersion) { + File newConfigFile = new File(this.getDataFolder().getAbsolutePath(), "sizes.yml.old"); + if (newConfigFile.exists()) { + newConfigFile.delete(); + } + FileUtils.copyFile(oldConfigFile, newConfigFile); + oldConfigFile.delete(); + } + + // update config version + if (updateConfigVersion) { + List lines = new ArrayList<>(); + LineIterator iterator = FileUtils.lineIterator(oldConfigFile); + while (iterator.hasNext()) { + String line = iterator.next(); + lines.add(line); + } + for (String line : new ArrayList<>(lines)) { + if (line.contains("config-version")) { + int index = lines.indexOf(line); + lines.set(index, "config-version: " + VirtualRealty.getInstance().getDescription().getVersion()); + } + } + File newConfigFile = new File(this.getDataFolder().getAbsolutePath(), "sizes.yml"); + FileUtils.deleteQuietly(newConfigFile); + FileUtils.writeLines(newConfigFile, lines); + newConfigFile.createNewFile(); + } } } diff --git a/src/main/java/me/plytki/virtualrealty/commands/PlotCommand.java b/src/main/java/me/plytki/virtualrealty/commands/PlotCommand.java index 34fc814..b6c724f 100644 --- a/src/main/java/me/plytki/virtualrealty/commands/PlotCommand.java +++ b/src/main/java/me/plytki/virtualrealty/commands/PlotCommand.java @@ -3,7 +3,11 @@ import me.plytki.virtualrealty.VirtualRealty; import me.plytki.virtualrealty.managers.PlotManager; import me.plytki.virtualrealty.objects.Plot; +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.api.chat.TextComponent; +import org.bukkit.Bukkit; import org.bukkit.GameMode; +import org.bukkit.Location; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; @@ -11,6 +15,7 @@ import org.jetbrains.annotations.NotNull; import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; public class PlotCommand implements CommandExecutor { @@ -24,16 +29,111 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command printHelp(sender); return false; } + if (args.length == 1) { + switch (args[0].toUpperCase()) { + case "TP": { + sender.sendMessage(" "); + sender.sendMessage(" §8§l«§8§m §8[§aVirtualRealty§8]§m §8§l»"); + sender.sendMessage(" §a/plot tp §8<§7plotID§8>"); + break; + } + case "GM": { + sender.sendMessage(" "); + sender.sendMessage(" §8§l«§8§m §8[§aVirtualRealty§8]§m §8§l»"); + sender.sendMessage(" §a/plot gm §8<§7gamemode§8>"); + break; + } + case "LIST": { + boolean hasPlot = false; + for (Plot plot : PlotManager.plots) { + if (plot.getOwnedBy() != null && plot.getOwnedBy().equals(p.getUniqueId()) && plot.getOwnedUntilDate().isAfter(LocalDateTime.now())) { + hasPlot = true; + break; + } + } + if (!hasPlot) { + sender.sendMessage(VirtualRealty.PREFIX + "§cYou don't have any plots!"); + return false; + } + sender.sendMessage(" "); + sender.sendMessage(" §8§l«§8§m §8[§aVirtualRealty§8]§m §8§l»"); + sender.sendMessage(" "); + sender.sendMessage("§7§m "); + sender.sendMessage(" §7| §a§l§oID§7 | §a§l§oOwned Until§7 | §a§l§oSize§7 | §a§l§oPlot Center§7 |"); + for (Plot plot : PlotManager.plots) { + if (plot.getOwnedBy() != null && plot.getOwnedBy().equals(p.getUniqueId()) && plot.getOwnedUntilDate().isAfter(LocalDateTime.now())) { + LocalDateTime localDateTime = plot.getOwnedUntilDate(); + DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy"); + StringBuilder ownedBy = new StringBuilder(); + ownedBy.append((plot.getOwnedBy() != null ? (Bukkit.getOfflinePlayer(plot.getOwnedBy()).isOnline() ? "§a" : "§c") + Bukkit.getOfflinePlayer(plot.getOwnedBy()).getName() : "§cAvailable")); + boolean isOwned = !ownedBy.toString().equals("§cAvailable"); + for (int i = ownedBy.length(); i < 16; i++) { + ownedBy.append(" "); + } + StringBuilder size = new StringBuilder(plot.getPlotSize().name()); + for (int i = size.length(); i < 6; i++) { + size.append(" "); + } + BaseComponent textComponent = new TextComponent(" §f" + plot.getID() + "§8 §f" + (isOwned ? " " : "") + dateTimeFormatter.format(localDateTime) + "§8 §f" + size + "§8 §f" + plot.getCenter().toSimpleString()); + sender.sendMessage(textComponent.toLegacyText()); + } + } + sender.sendMessage("§7§m "); + break; + } + default: { + printHelp(sender); + } + } + } if (args.length >= 2) { switch (args[0].toUpperCase()) { - case "GAMEMODE": { + case "TP": { + if (args.length == 2) { + int plotID; + try { + plotID = Integer.parseInt(args[1]); + } catch (IllegalArgumentException e) { + sender.sendMessage(VirtualRealty.PREFIX + "§cUse only natural numbers!"); + return false; + } + Plot plot = PlotManager.getPlot(plotID); + if (plot == null) { + sender.sendMessage(VirtualRealty.PREFIX + "§cCouldn't get plot with specified ID!"); + return false; + } + if (!(plot.getOwnedBy() != null && plot.getOwnedBy().equals(p.getUniqueId()))) { + sender.sendMessage(VirtualRealty.PREFIX + "§cIt's not your plot!"); + return false; + } + if (plot.getOwnedUntilDate().isBefore(LocalDateTime.now())) { + sender.sendMessage(VirtualRealty.PREFIX + "§cYour ownership has expired!"); + return false; + } + Location loc = new Location(plot.getCreatedLocation().getWorld(), plot.getCenter().getBlockX(), plot.getCenter().getBlockY() + 1, plot.getCenter().getBlockZ()); + loc.setY(loc.getWorld().getHighestBlockAt(loc.getBlockX(), loc.getBlockZ()).getY() + 1); + p.teleport(loc); + sender.sendMessage(VirtualRealty.PREFIX + "§aYou have been teleported to the plot!"); + } + break; + } + case "GM": { + if (!VirtualRealty.getPluginConfiguration().enablePlotGameMode || VirtualRealty.getPluginConfiguration().forcePlotGameMode) { + sender.sendMessage(VirtualRealty.PREFIX + "§cGamemode feature is disabled!"); + return false; + } GameMode gameMode; int gameModeID; try { - gameModeID = Integer.parseInt(args[1]); + gameMode = GameMode.valueOf(args[1]); + gameModeID = gameMode.getValue(); } catch (IllegalArgumentException e) { - sender.sendMessage(VirtualRealty.PREFIX + "§cUse only natural numbers!"); - return false; + try { + gameModeID = Integer.parseInt(args[1]); + } catch (IllegalArgumentException ex) { + sender.sendMessage(VirtualRealty.PREFIX + "§cIncorrect gamemode vaule!"); + return false; + } } if (!(gameModeID != 1 && gameModeID != 2)) { gameMode = GameMode.getByValue(Integer.parseInt(args[1])); @@ -85,11 +185,11 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command return false; } - private static void printHelp(CommandSender sender) { sender.sendMessage(" "); - sender.sendMessage(" §8§l«§8§m §8[§aPlots§8]§m §8§l»"); - sender.sendMessage(" §a/plot gamemode §8<§71/2§8> §8- §7Changes gamemode"); + sender.sendMessage(" §8§l«§8§m §8[§aVirtualRealty§8]§m §8§l»"); + sender.sendMessage(" §a/plot list §8- §7Shows your plots"); + sender.sendMessage(" §a/plot gm §8- §7Changes gamemode"); } -} +} \ No newline at end of file diff --git a/src/main/java/me/plytki/virtualrealty/commands/VirtualRealtyCommand.java b/src/main/java/me/plytki/virtualrealty/commands/VirtualRealtyCommand.java index 4ab8b33..5a6dd68 100644 --- a/src/main/java/me/plytki/virtualrealty/commands/VirtualRealtyCommand.java +++ b/src/main/java/me/plytki/virtualrealty/commands/VirtualRealtyCommand.java @@ -4,11 +4,11 @@ import me.plytki.virtualrealty.enums.Direction; import me.plytki.virtualrealty.enums.PlotSize; import me.plytki.virtualrealty.managers.PlotManager; -import me.plytki.virtualrealty.objects.Cuboid; import me.plytki.virtualrealty.objects.Plot; -import me.plytki.virtualrealty.objects.math.BlockVector3; import me.plytki.virtualrealty.utils.Permissions; import me.plytki.virtualrealty.utils.PlotUtil; +import me.plytki.virtualrealty.utils.multiversion.Chat; +import me.plytki.virtualrealty.utils.multiversion.VMaterial; import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.ClickEvent; import net.md_5.bungee.api.chat.HoverEvent; @@ -69,11 +69,7 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command } case "SET": { if (!Permissions.hasPermission(sender, tempPermission, "set")) return false; - sender.sendMessage(" "); - sender.sendMessage(" §8§l«§8§m §8[§aVirtualRealty§8]§m §8§l»"); - sender.sendMessage(" §a/vrplot set §8<§7plotID§8> §7ownedBy §8<§7username§8>"); - sender.sendMessage(" §a/vrplot set §8<§7plotID§8> §7floorMaterial §8<§7material§8> §8<§7initialize (optional)§8>"); - sender.sendMessage(" §a/vrplot set §8<§7plotID§8> §7ownerExpires §8<§7dd/mm/YYYY§8> §8<§7HH:mm (optional)§8>"); + printSetHelp(sender); break; } case "ASSIGN": { @@ -135,7 +131,6 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command sender.sendMessage("§7§m "); sender.sendMessage(" §7| §a§l§oID§7 | §a§l§oOwned By§7 | §a§l§oOwned Until§7 | §a§l§oSize§7 | §a§l§oPlot Center§7 |"); for (Plot plot : PlotManager.plots) { - LocalDateTime localDateTime = plot.getOwnedUntilDate(); DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy"); StringBuilder ownedBy = new StringBuilder(); @@ -151,7 +146,7 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command BaseComponent textComponent = new TextComponent(" §f" + plot.getID() + "§8 §f" + ownedBy.substring(0, 14) + "§8 §f" + (isOwned ? " " : "") + dateTimeFormatter.format(localDateTime) + "§8 §f" + size + "§8 §f" + plot.getCenter().toSimpleString()); textComponent.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponent[]{new TextComponent("§a§oClick to show detailed information about the plot! §8(§7ID: §f" + plot.getID() + "§8)")})); textComponent.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/vrplot info " + plot.getID())); - sender.spigot().sendMessage(textComponent); + new Chat(textComponent).sendTo(p); } sender.sendMessage("§7§m "); break; @@ -314,7 +309,11 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command } Material material; try { - material = Material.matchMaterial(args[3]); + material = Material.matchMaterial(args[3].split(":")[0].toUpperCase()); + if (material == null) { + sender.sendMessage(VirtualRealty.PREFIX + "§cCouldn't get material with specified name!"); + return false; + } } catch (IllegalArgumentException e) { sender.sendMessage(VirtualRealty.PREFIX + "§cCouldn't get material with specified name!"); return false; @@ -324,7 +323,11 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command sender.sendMessage(VirtualRealty.PREFIX + "§cCouldn't get plot with specified ID!"); return false; } - plot.setFloorMaterial(material); + byte data = 0; + if (args[3].split(":").length == 2) { + data = Byte.parseByte(args[3].split(":")[1]); + } + plot.setFloorMaterial(material, data); if (args.length == 5 && (args[4].toLowerCase().startsWith("t"))) { plot.initializeFloor(); sender.sendMessage(VirtualRealty.PREFIX + "§aNew floor material has been set and initialized!"); @@ -335,7 +338,46 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command plot.update(); break; } - case "OWNEREXPIRES": { + case "BORDERMATERIAL": { + if (!Permissions.hasPermission(sender, commandPermission, "set.bordermaterial")) + return false; + if (args.length < 4) { + sender.sendMessage(VirtualRealty.PREFIX + "§cSpecify material name!"); + return false; + } + int plotID; + try { + plotID = Integer.parseInt(args[1]); + } catch (IllegalArgumentException e) { + sender.sendMessage(VirtualRealty.PREFIX + "§cUse only natural numbers!"); + return false; + } + Material material; + try { + material = VMaterial.getMaterial(args[3].split(":")[0].toUpperCase()); + if (material == null) { + sender.sendMessage(VirtualRealty.PREFIX + "§cCouldn't get material with specified name!"); + return false; + } + } catch (IllegalArgumentException e) { + sender.sendMessage(VirtualRealty.PREFIX + "§cCouldn't get material with specified name!"); + return false; + } + Plot plot = PlotManager.getPlot(plotID); + if (plot == null) { + sender.sendMessage(VirtualRealty.PREFIX + "§cCouldn't get plot with specified ID!"); + return false; + } + byte data = 0; + if (args[3].split(":").length == 2) { + data = Byte.parseByte(args[3].split(":")[1]); + } + plot.setBorder(material, data); + sender.sendMessage(VirtualRealty.PREFIX + "§aNew border material has been set!"); + plot.update(); + return false; + } + case "OWNERSHIPEXPIRES": { if (!Permissions.hasPermission(sender, commandPermission, "set.ownerexpires")) return false; if (args.length < 4) { sender.sendMessage(VirtualRealty.PREFIX + "§cSpecify expiry date!"); @@ -381,20 +423,12 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command break; } default: { - sender.sendMessage(" "); - sender.sendMessage(" §8§l«§8§m §8[§aVirtualRealty§8]§m §8§l»"); - sender.sendMessage(" §a/vrplot set §8<§7plotID§8> §7ownedBy §8<§7username§8>"); - sender.sendMessage(" §a/vrplot set §8<§7plotID§8> §7floorMaterial §8<§7material§8> §8<§7initialize (optional)§8>"); - sender.sendMessage(" §a/vrplot set §8<§7plotID§8> §7ownerExpires §8<§7dd/mm/YYYY§8> §8<§7HH:mm (optional)§8>"); + printSetHelp(sender); break; } } } else { - sender.sendMessage(" "); - sender.sendMessage(" §8§l«§8§m §8[§aVirtualRealty§8]§m §8§l»"); - sender.sendMessage(" §a/vrplot set §8<§7plotID§8> §7ownedBy §8<§7username§8>"); - sender.sendMessage(" §a/vrplot set §8<§7plotID§8> §7floorMaterial §8<§7material§8> §8<§7initialize (optional)§8>"); - sender.sendMessage(" §a/vrplot set §8<§7plotID§8> §7ownerExpires §8<§7dd/mm/YYYY§8> §8<§7HH:mm (optional)§8>"); + printSetHelp(sender); } break; } @@ -568,4 +602,13 @@ private static void printHelp(CommandSender sender) { sender.sendMessage(" §a/vrplot tp §8- §7Teleports to the plot"); } + private static void printSetHelp(CommandSender sender) { + sender.sendMessage(" "); + sender.sendMessage(" §8§l«§8§m §8[§aVirtualRealty§8]§m §8§l»"); + sender.sendMessage(" §a/vrplot set §8<§7plotID§8> §7ownedBy §8<§7username§8>"); + sender.sendMessage(" §a/vrplot set §8<§7plotID§8> §7floorMaterial §8<§7material§8> §8<§7initialize{true/false} (optional)§8>"); + sender.sendMessage(" §a/vrplot set §8<§7plotID§8> §7borderMaterial §8<§7material§8>"); + sender.sendMessage(" §a/vrplot set §8<§7plotID§8> §7ownershipExpires §8<§7dd/mm/YYYY§8> §8<§7HH:mm (optional)§8>"); + } + } diff --git a/src/main/java/me/plytki/virtualrealty/enums/PlotSize.java b/src/main/java/me/plytki/virtualrealty/enums/PlotSize.java index 9d7956d..ad59d12 100644 --- a/src/main/java/me/plytki/virtualrealty/enums/PlotSize.java +++ b/src/main/java/me/plytki/virtualrealty/enums/PlotSize.java @@ -1,24 +1,31 @@ package me.plytki.virtualrealty.enums; +import me.plytki.virtualrealty.VirtualRealty; import org.bukkit.Material; public enum PlotSize { - SMALL(10, 10, 10, Material.matchMaterial("GRASS_BLOCK")), - MEDIUM(25, 25, 25, Material.matchMaterial("GRASS_BLOCK")), - LARGE(50, 50, 50, Material.matchMaterial("GRASS_BLOCK")), - CUSTOM(0, 0, 0, Material.matchMaterial("GRASS_BLOCK")); + SMALL(10, 10, 10, Material.matchMaterial(VirtualRealty.isLegacy ? "GRASS" : "GRASS_BLOCK"), (byte)0, Material.matchMaterial(VirtualRealty.isLegacy ? "STEP" : "STONE_BRICK_SLAB"), VirtualRealty.isLegacy ? (byte)5 : (byte)0), + MEDIUM(25, 25, 25, Material.matchMaterial(VirtualRealty.isLegacy ? "GRASS" : "GRASS_BLOCK"), (byte)0, Material.matchMaterial(VirtualRealty.isLegacy ? "STEP" : "STONE_BRICK_SLAB"), VirtualRealty.isLegacy ? (byte)5 : (byte)0), + LARGE(50, 50, 50, Material.matchMaterial(VirtualRealty.isLegacy ? "GRASS" : "GRASS_BLOCK"), (byte)0, Material.matchMaterial(VirtualRealty.isLegacy ? "STEP" : "STONE_BRICK_SLAB"), VirtualRealty.isLegacy ? (byte)5 : (byte)0), + CUSTOM(0, 0, 0, Material.matchMaterial(VirtualRealty.isLegacy ? "GRASS" : "GRASS_BLOCK"), (byte)0, Material.matchMaterial(VirtualRealty.isLegacy ? "STEP" : "STONE_BRICK_SLAB"), VirtualRealty.isLegacy ? (byte)5 : (byte)0); private int length; private int width; private int height; private Material floorMaterial; + private byte floorData; + private Material borderMaterial; + private byte borderData; - PlotSize(int length, int width, int height, Material floorMaterial) { + PlotSize(int length, int width, int height, Material floorMaterial, byte floorData, Material borderMaterial, byte borderData) { this.length = length; this.width = width; this.height = height; this.floorMaterial = floorMaterial; + this.floorData = floorData; + this.borderMaterial = borderMaterial; + this.borderData = borderData; } public int getLength() { @@ -52,4 +59,28 @@ public Material getFloorMaterial() { public void setFloorMaterial(Material floorMaterial) { this.floorMaterial = floorMaterial; } + + public byte getFloorData() { + return floorData; + } + + public void setFloorData(byte floorData) { + this.floorData = floorData; + } + + public Material getBorderMaterial() { + return borderMaterial; + } + + public void setBorderMaterial(Material borderMaterial) { + this.borderMaterial = borderMaterial; + } + + public byte getBorderData() { + return borderData; + } + + public void setBorderData(byte borderData) { + this.borderData = borderData; + } } diff --git a/src/main/java/me/plytki/virtualrealty/listeners/PlotListener.java b/src/main/java/me/plytki/virtualrealty/listeners/PlotListener.java index 0581d76..532ef12 100644 --- a/src/main/java/me/plytki/virtualrealty/listeners/PlotListener.java +++ b/src/main/java/me/plytki/virtualrealty/listeners/PlotListener.java @@ -1,5 +1,6 @@ package me.plytki.virtualrealty.listeners; +import me.plytki.virtualrealty.VirtualRealty; import me.plytki.virtualrealty.managers.PlotManager; import me.plytki.virtualrealty.objects.Plot; import org.bukkit.*; @@ -23,29 +24,30 @@ public void onPlotMove(PlayerMoveEvent e) { if (plot != null) { OfflinePlayer offlinePlayer; String enterPlotString = "§aYou have entered available plot!"; - //Sound enterSound = Sound.WATER; if (plot.getOwnedBy() != null) { offlinePlayer = Bukkit.getOfflinePlayer(plot.getOwnedBy()); enterPlotString = "§eYou have entered §f" + offlinePlayer.getName() + "'s §eplot!"; } if (!enteredPlot.containsKey(player)) { enteredPlot.put(player, new AbstractMap.SimpleEntry<>(plot, true)); -// PacketPlayOutChat packet = new PacketPlayOutChat(new ChatComponentText(enterPlotString), (byte)2); -// ((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet); - //player.spigot().sendMessage(ChatMessageType.ACTION_BAR, new TextComponent(enterPlotString)); - //player.playSound(to, enterSound, 1, 1); - if (plot.getOwnedBy() != null && plot.getOwnedBy().equals(player.getUniqueId())) { - player.setGameMode(plot.getSelectedGameMode()); + if (VirtualRealty.getPluginConfiguration().enablePlotGameMode) { + if (plot.getOwnedBy() != null && plot.getOwnedBy().equals(player.getUniqueId())) { + if (VirtualRealty.getPluginConfiguration().forcePlotGameMode) { + player.setGameMode(VirtualRealty.getPluginConfiguration().getGameMode()); + } else { + player.setGameMode(plot.getSelectedGameMode()); + } + } } } else { if (!enteredPlot.get(player).getValue()) { -// PacketPlayOutChat packet = new PacketPlayOutChat(new ChatComponentText(enterPlotString), (byte)2); -// ((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet); - //player.spigot().sendMessage(ChatMessageType.ACTION_BAR, new TextComponent(enterPlotString)); - //player.playSound(to, enterSound, 1, 1); enteredPlot.replace(player, new AbstractMap.SimpleEntry<>(plot, true)); - if (plot.getOwnedBy().equals(player.getUniqueId())) { - player.setGameMode(plot.getSelectedGameMode()); + if (VirtualRealty.getPluginConfiguration().enablePlotGameMode) { + if (VirtualRealty.getPluginConfiguration().forcePlotGameMode) { + player.setGameMode(VirtualRealty.getPluginConfiguration().getGameMode()); + } else { + player.setGameMode(plot.getSelectedGameMode()); + } } } } @@ -53,19 +55,16 @@ public void onPlotMove(PlayerMoveEvent e) { if (enteredPlot.containsKey(player)) { if (enteredPlot.get(player).getValue()) { OfflinePlayer offlinePlayer; - //Sound leaveSound = Sound.WATER; String leavePlotString = "§cYou have left available plot!"; if (enteredPlot.get(player).getKey().getOwnedBy() != null) { offlinePlayer = Bukkit.getOfflinePlayer(enteredPlot.get(player).getKey().getOwnedBy()); leavePlotString = "§cYou have left §f" + offlinePlayer.getName() + "'s §cplot!"; - if (enteredPlot.get(player).getKey().getOwnedBy() != null && enteredPlot.get(player).getKey().getOwnedBy().equals(player.getUniqueId())) { - player.setGameMode(Bukkit.getServer().getDefaultGameMode()); + if (VirtualRealty.getPluginConfiguration().enablePlotGameMode) { + if (enteredPlot.get(player).getKey().getOwnedBy() != null && enteredPlot.get(player).getKey().getOwnedBy().equals(player.getUniqueId())) { + player.setGameMode(Bukkit.getServer().getDefaultGameMode()); + } } } -// PacketPlayOutChat packet = new PacketPlayOutChat(new ChatComponentText(leavePlotString), (byte)2); -// ((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet); - //player.spigot().sendMessage(ChatMessageType.ACTION_BAR, new TextComponent(leavePlotString)); - //player.playSound(to, leaveSound, 1, 1); enteredPlot.remove(player); return; } diff --git a/src/main/java/me/plytki/virtualrealty/listeners/PlotProtectionListener.java b/src/main/java/me/plytki/virtualrealty/listeners/PlotProtectionListener.java index 6221786..9f82923 100644 --- a/src/main/java/me/plytki/virtualrealty/listeners/PlotProtectionListener.java +++ b/src/main/java/me/plytki/virtualrealty/listeners/PlotProtectionListener.java @@ -10,6 +10,7 @@ import org.bukkit.block.BlockState; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.block.*; import org.bukkit.event.entity.EntityExplodeEvent; @@ -85,7 +86,7 @@ public void onBlockBreakOutside(BlockBreakEvent e) { } } - @EventHandler + @EventHandler(priority = EventPriority.HIGHEST) public void onBlockPlace(BlockPlaceEvent e) { Player player = e.getPlayer(); Plot plot = PlotManager.getPlot(e.getBlockPlaced().getLocation()); @@ -104,7 +105,7 @@ public void onBlockPlace(BlockPlaceEvent e) { } } - @EventHandler + @EventHandler(priority = EventPriority.HIGHEST) public void onBlockBreak(BlockBreakEvent e) { Player player = e.getPlayer(); Plot plot = PlotManager.getPlot(e.getBlock().getLocation()); diff --git a/src/main/java/me/plytki/virtualrealty/listeners/WorldListener.java b/src/main/java/me/plytki/virtualrealty/listeners/WorldListener.java new file mode 100644 index 0000000..a22789d --- /dev/null +++ b/src/main/java/me/plytki/virtualrealty/listeners/WorldListener.java @@ -0,0 +1,64 @@ +package me.plytki.virtualrealty.listeners; + +import me.plytki.virtualrealty.VirtualRealty; +import me.plytki.virtualrealty.managers.PlotManager; +import me.plytki.virtualrealty.objects.Plot; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockPlaceEvent; + +public class WorldListener implements Listener { + + @EventHandler + public void onBlockBreak(BlockBreakEvent e) { + if (e.isCancelled()) return; + Player player = e.getPlayer(); + Plot plot = PlotManager.getPlot(e.getBlock().getLocation()); + if (!VirtualRealty.getPluginConfiguration().allowOutPlotBuild) { + if (!player.hasPermission("virtualrealty.build")) { + if (plot == null) { + e.setCancelled(!VirtualRealty.getPluginConfiguration().allowOutPlotBuild); + player.sendMessage(VirtualRealty.PREFIX + "§cYou can't build here!"); + } else { + if (plot.getOwnedBy() != null && !plot.getOwnedBy().equals(player.getUniqueId())) { + e.setCancelled(!VirtualRealty.getPluginConfiguration().allowOutPlotBuild); + player.sendMessage(VirtualRealty.PREFIX + "§cYou can't build here!"); + } else { + if (plot.getOwnedBy() == null) { + e.setCancelled(!VirtualRealty.getPluginConfiguration().allowOutPlotBuild); + player.sendMessage(VirtualRealty.PREFIX + "§cYou can't build here!"); + } + } + } + } + } + } + + @EventHandler + public void onBlockPlace(BlockPlaceEvent e) { + if (e.isCancelled()) return; + Player player = e.getPlayer(); + Plot plot = PlotManager.getPlot(e.getBlock().getLocation()); + if (!VirtualRealty.getPluginConfiguration().allowOutPlotBuild) { + if (!player.hasPermission("virtualrealty.build")) { + if (plot == null) { + e.setCancelled(!VirtualRealty.getPluginConfiguration().allowOutPlotBuild); + player.sendMessage(VirtualRealty.PREFIX + "§cYou can't build here!"); + } else { + if (plot.getOwnedBy() != null && !plot.getOwnedBy().equals(player.getUniqueId())) { + e.setCancelled(!VirtualRealty.getPluginConfiguration().allowOutPlotBuild); + player.sendMessage(VirtualRealty.PREFIX + "§cYou can't build here!"); + } else { + if (plot.getOwnedBy() == null) { + e.setCancelled(!VirtualRealty.getPluginConfiguration().allowOutPlotBuild); + player.sendMessage(VirtualRealty.PREFIX + "§cYou can't build here!"); + } + } + } + } + } + } + +} diff --git a/src/main/java/me/plytki/virtualrealty/loaders/PluginConfiguration.java b/src/main/java/me/plytki/virtualrealty/loaders/PluginConfiguration.java new file mode 100644 index 0000000..c2d33a2 --- /dev/null +++ b/src/main/java/me/plytki/virtualrealty/loaders/PluginConfiguration.java @@ -0,0 +1,105 @@ +package me.plytki.virtualrealty.loaders; + +import me.plytki.virtualrealty.VirtualRealty;; +import org.bukkit.GameMode; +import org.diorite.cfg.annotations.*; +import org.diorite.cfg.annotations.CfgStringStyle.StringStyle; +import org.diorite.cfg.annotations.defaults.CfgDelegateDefault; + +@CfgClass(name = "PluginConfiguration") +@CfgDelegateDefault("{new}") +@CfgComment("~-~-~-~-~-~-~-~-~-~-~-~~-~-~-~~ #") +@CfgComment(" #") +@CfgComment(" Virtual Realty #") +@CfgComment(" #") +@CfgComment("~-~-~-~-~-~-~-~-~-~-~-~~-~-~-~~ #") +public class PluginConfiguration { + + @CfgComment(" ") + @CfgComment("-------------------------") + @CfgComment("Don't change this value!") + @CfgName("config-version") + public final String configVersion = VirtualRealty.getInstance().getDescription().getVersion(); + + @CfgComment("-------------------------") + @CfgComment("Set player gamemode to change when they enter their plot") + @CfgName("enable-plot-gamemode") + public boolean enablePlotGameMode = false; + + @CfgComment("Set which gamemode players change to when they enter their plot") + @CfgName("default-plot-gamemode") + public String plotGameMode = "SURVIVAL"; + + @CfgComment("Set forced change to plot gamemode when players enter their plot") + @CfgName("force-plot-gamemode") + public boolean forcePlotGameMode = false; + + public GameMode getGameMode() { + try { + return GameMode.valueOf(plotGameMode); + } catch (Exception e) { + VirtualRealty.getInstance().getLogger().warning("Couldn't parse plot-gamemode from config.yml\nUsing default: SURVIVAL"); + return GameMode.SURVIVAL; + } + } + + @CfgComment("Allow players to build outside of their plots") + @CfgName("allow-outplot-build") + public boolean allowOutPlotBuild = true; + + @CfgComment("Type of data recording") + @CfgComment("H2 - Local database (Automatically started with our plugin)") + @CfgComment("MYSQL - External database") + @CfgName("data-model") + public DataModel dataModel = DataModel.H2; + + @CfgComment("Data required to connect to the database") + @CfgComment("The plotsTableName section is the name of the VR data table in the database") + @CfgComment("It is best to change these names only if you really need to (e.g. there is a conflict with another plugin)") + @CfgComment("To rename tables when you already have some VR data in the database:") + @CfgComment("1. Turn off the server") + @CfgComment("2. Change data in VR config") + @CfgComment("3. Rename database tables using phpMyAdmin for example") + @CfgName("mysql") + public MySQL mysql = new MySQL("localhost", 3306, "db", "root", "passwd", true, "vr_plots"); + + public enum DataModel { + H2, + MYSQL + } + + public static class MySQL { + @CfgStringStyle(StringStyle.ALWAYS_QUOTED) + public String hostname; + + public int port; + + @CfgStringStyle(StringStyle.ALWAYS_QUOTED) + public String database; + + @CfgStringStyle(StringStyle.ALWAYS_QUOTED) + public String user; + + @CfgStringStyle(StringStyle.ALWAYS_QUOTED) + public String password; + + public boolean useSSL; + + @CfgStringStyle(StringStyle.ALWAYS_QUOTED) + public String plotsTableName; + + public MySQL(String hostname, int port, String database, String user, String password, boolean useSSL, String plotsTableName) { + this.hostname = hostname; + this.port = port; + this.database = database; + this.user = user; + this.password = password; + this.useSSL = useSSL; + this.plotsTableName = plotsTableName; + } + + private MySQL() {} + + } + +} diff --git a/src/main/java/me/plytki/virtualrealty/loaders/SizesConfiguration.java b/src/main/java/me/plytki/virtualrealty/loaders/SizesConfiguration.java new file mode 100644 index 0000000..62d12f3 --- /dev/null +++ b/src/main/java/me/plytki/virtualrealty/loaders/SizesConfiguration.java @@ -0,0 +1,114 @@ +package me.plytki.virtualrealty.loaders; + +import me.plytki.virtualrealty.VirtualRealty; +import me.plytki.virtualrealty.enums.PlotSize; +import org.bukkit.Material; +import org.diorite.cfg.annotations.CfgClass; +import org.diorite.cfg.annotations.CfgComment; +import org.diorite.cfg.annotations.CfgName; +import org.diorite.cfg.annotations.CfgStringStyle; +import org.diorite.cfg.annotations.CfgStringStyle.StringStyle; +import org.diorite.cfg.annotations.defaults.CfgDelegateDefault; + +@CfgClass(name = "SizesConfiguration") +@CfgDelegateDefault("{new}") +@CfgComment("~-~-~-~-~-~-~-~-~-~-~-~~-~-~-~~ #") +@CfgComment(" #") +@CfgComment(" Plot Sizes #") +@CfgComment(" #") +@CfgComment("~-~-~-~-~-~-~-~-~-~-~-~~-~-~-~~ #") +public class SizesConfiguration { + + @CfgComment(" ") + @CfgComment("-------------------------") + @CfgComment("Don't change this value!") + @CfgName("config-version") + public final String configVersion = VirtualRealty.getInstance().getDescription().getVersion(); + @CfgComment("-------------------------") + + @CfgComment(" ") + @CfgComment("(<1.13) Legacy Materials: https://helpch.at/docs/1.8/org/bukkit/Material.html") + @CfgComment("(>1.12) Post-Legacy Materials: https://helpch.at/docs/1.13/org/bukkit/Material.html") + @CfgComment(" ") + @CfgComment("floor-data and border-data are only for legacy versions * <1.13 *") + @CfgName("plot-sizes") + public PlotSizes plotSizes = new PlotSizes(new Small(PlotSize.SMALL), new Medium(PlotSize.MEDIUM), new Large(PlotSize.LARGE)); + + public static class PlotSizes { + + public Small SMALL; + + public Medium MEDIUM; + + public Large LARGE; + + public PlotSizes(Small small, Medium medium, Large large) { + this.SMALL = small; + this.MEDIUM = medium; + this.LARGE = large; + } + + private PlotSizes() {} + + } + + public static class Small extends Size { + + public Small(PlotSize plotSize) { + super(plotSize.getFloorMaterial(), plotSize.getFloorData(), plotSize.getBorderMaterial(), plotSize.getBorderData(), plotSize.getLength(), plotSize.getWidth(), plotSize.getHeight()); + } + + private Small() {} + + } + + public static class Medium extends Size { + + public Medium(PlotSize plotSize) { + super(plotSize.getFloorMaterial(), plotSize.getFloorData(), plotSize.getBorderMaterial(), plotSize.getBorderData(), plotSize.getLength(), plotSize.getWidth(), plotSize.getHeight()); + + } + + private Medium() {} + + } + + public static class Large extends Size { + + public Large(PlotSize plotSize) { + super(plotSize.getFloorMaterial(), plotSize.getFloorData(), plotSize.getBorderMaterial(), plotSize.getBorderData(), plotSize.getLength(), plotSize.getWidth(), plotSize.getHeight()); + } + + private Large() {} + + } + + public abstract static class Size { + + @CfgName("floor-material") + public String floorMaterial; + @CfgName("floor-data") + public byte floorData; + @CfgName("border-material") + public String borderMaterial; + @CfgName("border-data") + public byte borderData; + public int length; + public int width; + public int height; + + public Size(Material floorMaterial, byte floorData, Material borderMaterial, byte borderData, int length, int width, int height) { + this.floorMaterial = floorMaterial.name(); + this.floorData = floorData; + this.borderMaterial = borderMaterial.name(); + this.borderData = borderData; + this.length = length; + this.width = width; + this.height = height; + } + + private Size() {} + + } + +} diff --git a/src/main/java/me/plytki/virtualrealty/managers/PlotManager.java b/src/main/java/me/plytki/virtualrealty/managers/PlotManager.java index a8697d8..4312196 100644 --- a/src/main/java/me/plytki/virtualrealty/managers/PlotManager.java +++ b/src/main/java/me/plytki/virtualrealty/managers/PlotManager.java @@ -46,7 +46,7 @@ public static Plot createPlot(Location creationLocation, PlotSize plotSize, Mate } public static Plot createPlot(Location creationLocation, int length, int width, int height) { - Plot plot = new Plot(creationLocation, Material.matchMaterial("GRASS_BLOCK"), length, width, height); + Plot plot = new Plot(creationLocation, Material.matchMaterial(VirtualRealty.isLegacy ? "GRASS" : "GRASS_BLOCK"), length, width, height); plots.add(plot); plot.insert(); return plot; diff --git a/src/main/java/me/plytki/virtualrealty/objects/Plot.java b/src/main/java/me/plytki/virtualrealty/objects/Plot.java index 4339226..66aa55c 100644 --- a/src/main/java/me/plytki/virtualrealty/objects/Plot.java +++ b/src/main/java/me/plytki/virtualrealty/objects/Plot.java @@ -7,6 +7,7 @@ import me.plytki.virtualrealty.objects.math.BlockVector3; import me.plytki.virtualrealty.sql.SQL; import me.plytki.virtualrealty.utils.SchematicUtil; +import me.plytki.virtualrealty.utils.multiversion.VMaterial; import org.bukkit.Bukkit; import org.bukkit.GameMode; import org.bukkit.Location; @@ -14,9 +15,12 @@ import org.bukkit.block.Block; import java.io.File; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Timestamp; +import java.time.LocalDate; import java.time.LocalDateTime; import java.util.*; @@ -31,6 +35,7 @@ public class Plot { private int width; private int height; private Material floorMaterial; + private byte floorData; private Location createdLocation; private Direction createdDirection; private BlockVector3 bottomLeftCorner; @@ -50,13 +55,14 @@ public Plot(Location location, Material floorMaterial, PlotSize plotSize) { this.assignedBy = null; this.ownedUntilDate = LocalDateTime.of(2999, 1, 1, 0, 0); this.floorMaterial = floorMaterial; + this.floorData = 0; this.plotSize = plotSize; this.length = plotSize.getLength(); this.width = plotSize.getWidth(); this.height = plotSize.getHeight(); this.createdLocation = location; this.createdDirection = Direction.byYaw(location.getYaw()); - this.selectedGameMode = GameMode.CREATIVE; + this.selectedGameMode = VirtualRealty.getPluginConfiguration().getGameMode(); initialize(); initializeCorners(); } @@ -67,13 +73,14 @@ public Plot(Location location, Material floorMaterial, int length, int width, in this.assignedBy = null; this.ownedUntilDate = LocalDateTime.of(2999, 12, 31, 0, 0); this.floorMaterial = floorMaterial; + this.floorData = 0; this.plotSize = PlotSize.CUSTOM; this.length = length; this.width = width; this.height = height; this.createdLocation = location; this.createdDirection = Direction.byYaw(location.getYaw()); - this.selectedGameMode = GameMode.CREATIVE; + this.selectedGameMode = VirtualRealty.getPluginConfiguration().getGameMode(); initialize(); initializeCorners(); } @@ -85,7 +92,8 @@ public Plot(ResultSet rs) { this.ownedBy = rs.getString("ownedBy").isEmpty() ? null : UUID.fromString(rs.getString("ownedBy")); this.assignedBy = rs.getString("assignedBy").equalsIgnoreCase("null") ? null : rs.getString("assignedBy"); this.ownedUntilDate = rs.getTimestamp("ownedUntilDate").toLocalDateTime(); - this.floorMaterial = Material.getMaterial(rs.getString("floorMaterial")); + this.floorMaterial = Material.getMaterial(rs.getString("floorMaterial").split(":")[0]); + this.floorData = rs.getString("floorMaterial").split(":").length == 1 ? 0 : Byte.parseByte(rs.getString("floorMaterial").split(":")[1]); this.plotSize = PlotSize.valueOf(rs.getString("plotSize")); this.length = rs.getInt("length"); this.width = rs.getInt("width"); @@ -168,8 +176,9 @@ public Material getFloorMaterial() { return floorMaterial; } - public void setFloorMaterial(Material floorMaterial) { + public void setFloorMaterial(Material floorMaterial, byte data) { this.floorMaterial = floorMaterial; + this.floorData = data; } public Location getCreatedLocation() { @@ -236,7 +245,20 @@ public void initializeFloor() { for (int x = location.getBlockX() - width + 1; x < location.getBlockX() + 1; x++) { for (int z = location.getBlockZ(); z < location.getBlockZ() + length; z++) { Block floorBlock = location.getWorld().getBlockAt(x, location.getBlockY(), z); - floorBlock.setType(floorMaterial); + if (VirtualRealty.isLegacy) { + try { + Method m = Block.class.getDeclaredMethod("setType", Material.class); + m.setAccessible(true); + m.invoke(floorBlock, this.floorMaterial); + Method m2 = Block.class.getDeclaredMethod("setData", byte.class); + m2.setAccessible(true); + m2.invoke(floorBlock, this.floorData); + } catch (Exception e) { + e.printStackTrace(); + } + } else { + floorBlock.setType(floorMaterial); + } } } break; @@ -245,7 +267,20 @@ public void initializeFloor() { for (int x = location.getBlockX() - length + 1; x < location.getBlockX() + 1; x++) { for (int z = location.getBlockZ() - width + 1; z < location.getBlockZ() + 1; z++) { Block floorBlock = location.getWorld().getBlockAt(x, location.getBlockY(), z); - floorBlock.setType(floorMaterial); + if (VirtualRealty.isLegacy) { + try { + Method m = Block.class.getDeclaredMethod("setType", Material.class); + m.setAccessible(true); + m.invoke(floorBlock, this.floorMaterial); + Method m2 = Block.class.getDeclaredMethod("setData", byte.class); + m2.setAccessible(true); + m2.invoke(floorBlock, this.floorData); + } catch (Exception e) { + e.printStackTrace(); + } + } else { + floorBlock.setType(floorMaterial); + } } } break; @@ -254,7 +289,20 @@ public void initializeFloor() { for (int x = location.getBlockX(); x < location.getBlockX() + width; x++) { for (int z = location.getBlockZ() - length + 1; z < location.getBlockZ() + 1; z++) { Block floorBlock = location.getWorld().getBlockAt(x, location.getBlockY(), z); - floorBlock.setType(floorMaterial); + if (VirtualRealty.isLegacy) { + try { + Method m = Block.class.getDeclaredMethod("setType", Material.class); + m.setAccessible(true); + m.invoke(floorBlock, this.floorMaterial); + Method m2 = Block.class.getDeclaredMethod("setData", byte.class); + m2.setAccessible(true); + m2.invoke(floorBlock, this.floorData); + } catch (Exception e) { + e.printStackTrace(); + } + } else { + floorBlock.setType(floorMaterial); + } } } break; @@ -263,7 +311,20 @@ public void initializeFloor() { for (int x = location.getBlockX(); x < location.getBlockX() + length; x++) { for (int z = location.getBlockZ(); z < location.getBlockZ() + width; z++) { Block floorBlock = location.getWorld().getBlockAt(x, location.getBlockY(), z); - floorBlock.setType(floorMaterial); + if (VirtualRealty.isLegacy) { + try { + Method m = Block.class.getDeclaredMethod("setType", Material.class); + m.setAccessible(true); + m.invoke(floorBlock, this.floorMaterial); + Method m2 = Block.class.getDeclaredMethod("setData", byte.class); + m2.setAccessible(true); + m2.invoke(floorBlock, this.floorData); + } catch (Exception e) { + e.printStackTrace(); + } + } else { + floorBlock.setType(floorMaterial); + } } } break; @@ -324,6 +385,119 @@ public void initialize() { //+ " blocks"); } + public void setBorder(Material material, byte data) { + Location location = this.getCreatedLocation(); + Direction direction = Direction.byYaw(location.getYaw()); + switch(direction) { + case SOUTH: { + int maxX = location.getBlockX() + 1 + 1; + int maxZ = location.getBlockZ() + length + 1; + int minX = location.getBlockX() - width + 1; + int minZ = location.getBlockZ() - 1; + for (int x = minX - 1; x < maxX; x++) { + for (int z = minZ; z < maxZ; z++) { + if (x == minX - 1 || z == minZ || x == maxX - 1 || z == maxZ - 1) { + Block borderBlock = location.getWorld().getBlockAt(x, location.getBlockY() + 1, z); + if (VirtualRealty.isLegacy) { + borderBlock.setType(material); + try { + Method m2 = Block.class.getDeclaredMethod("setData", byte.class); + m2.setAccessible(true); + m2.invoke(borderBlock, data); + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { + e.printStackTrace(); + } + } else { + borderBlock.setType(material); + } + } + } + } + break; + } + case WEST: { + int maxX = location.getBlockX() + 1 + 1; + int maxZ = location.getBlockZ() + 1 + 1; + int minX = location.getBlockX() - length + 1; + int minZ = location.getBlockZ() - width; + for (int x = minX - 1; x < maxX; x++) { + for (int z = minZ; z < maxZ; z++) { + if (x == minX - 1 || z == minZ || x == maxX - 1 || z == maxZ - 1) { + Block borderBlock = location.getWorld().getBlockAt(x, location.getBlockY() + 1, z); + if (VirtualRealty.isLegacy) { + borderBlock.setType(material); + try { + Method m2 = Block.class.getDeclaredMethod("setData", byte.class); + m2.setAccessible(true); + m2.invoke(borderBlock, data); + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { + e.printStackTrace(); + } + } else { + borderBlock.setType(material); + } + } + } + } + break; + } + case NORTH: { + int maxX = location.getBlockX() + width + 1; + int maxZ = location.getBlockZ() + 1 + 1; + int minX = location.getBlockX(); + int minZ = location.getBlockZ() - length; + for (int x = minX - 1; x < maxX; x++) { + for (int z = minZ; z < maxZ; z++) { + if (x == minX - 1 || z == minZ || x == maxX - 1 || z == maxZ - 1) { + Block borderBlock = location.getWorld().getBlockAt(x, location.getBlockY() + 1, z); + if (VirtualRealty.isLegacy) { + borderBlock.setType(material); + try { + Method m2 = Block.class.getDeclaredMethod("setData", byte.class); + m2.setAccessible(true); + m2.invoke(borderBlock, data); + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { + e.printStackTrace(); + } + } else { + borderBlock.setType(material); + } + } + } + } + break; + } + case EAST: { + int maxX = location.getBlockX() + length + 1; + int maxZ = location.getBlockZ() + width + 1; + int minX = location.getBlockX(); + int minZ = location.getBlockZ() - 1; + for (int x = minX - 1; x < maxX; x++) { + for (int z = minZ; z < maxZ; z++) { + if (x == minX - 1 || z == minZ || x == maxX - 1 || z == maxZ - 1) { + Block borderBlock = location.getWorld().getBlockAt(x, location.getBlockY() + 1, z); + if (VirtualRealty.isLegacy) { + borderBlock.setType(material); + try { + Method m2 = Block.class.getDeclaredMethod("setData", byte.class); + m2.setAccessible(true); + m2.invoke(borderBlock, data); + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { + e.printStackTrace(); + } + } else { + borderBlock.setType(material); + } + } + } + } + break; + } + default: + throw new IllegalStateException("Unexpected value: " + direction); + } + } + public List prepareBlocks(Location location) { List blocks = new ArrayList<>(); Direction direction = Direction.byYaw(location.getYaw()); @@ -343,10 +517,21 @@ public List prepareBlocks(Location location) { for (int z = location.getBlockZ(); z < location.getBlockZ() + length; z++) { Block floorBlock = location.getWorld().getBlockAt(x, location.getBlockY(), z); floorBlock.setType(floorMaterial); + if (VirtualRealty.isLegacy) { + try { + Method m2 = Block.class.getDeclaredMethod("setData", byte.class); + m2.setAccessible(true); + m2.invoke(floorBlock, plotSize.getFloorData()); + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { + e.printStackTrace(); + } + } for (int y = location.getBlockY(); y < location.getBlockY() + height; y++) { Block block = location.getWorld().getBlockAt(x, y, z); Block airBlock = location.getWorld().getBlockAt(x, y + 1, z); - airBlock.setType(Material.AIR); + if (airBlock == null || airBlock != null) { + airBlock.setType(Material.AIR); + } blocks.add(block); } } @@ -359,7 +544,18 @@ public List prepareBlocks(Location location) { for (int z = minZ; z < maxZ; z++) { if (x == minX - 1 || z == minZ || x == maxX - 1 || z == maxZ - 1) { Block borderBlock = location.getWorld().getBlockAt(x, location.getBlockY() + 1, z); - borderBlock.setType(Material.matchMaterial("STONE_BRICK_SLAB")); + if (VirtualRealty.isLegacy) { + borderBlock.setType(plotSize.getBorderMaterial()); + try { + Method m2 = Block.class.getDeclaredMethod("setData", byte.class); + m2.setAccessible(true); + m2.invoke(borderBlock, plotSize.getBorderData()); + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { + e.printStackTrace(); + } + } else { + borderBlock.setType(plotSize.getBorderMaterial()); + } } } } @@ -376,10 +572,23 @@ public List prepareBlocks(Location location) { for (int z = location.getBlockZ() - width + 1; z < location.getBlockZ() + 1; z++) { Block floorBlock = location.getWorld().getBlockAt(x, location.getBlockY(), z); floorBlock.setType(floorMaterial); + if (VirtualRealty.isLegacy) { + try { + Method m2 = Block.class.getDeclaredMethod("setData", byte.class); + m2.setAccessible(true); + m2.invoke(floorBlock, plotSize.getFloorData()); + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { + e.printStackTrace(); + } + } for (int y = location.getBlockY(); y < location.getBlockY() + height; y++) { Block block = location.getWorld().getBlockAt(x, y, z); - Block airBlock = location.getWorld().getBlockAt(x, y + 1, z); - airBlock.setType(Material.AIR); + Block airBlock = location. + getWorld(). + getBlockAt(x, y + 1, z); + if (airBlock == null || airBlock != null) { + airBlock.setType(Material.AIR); + } blocks.add(block); } } @@ -392,7 +601,18 @@ public List prepareBlocks(Location location) { for (int z = minZ; z < maxZ; z++) { if (x == minX - 1 || z == minZ || x == maxX - 1 || z == maxZ - 1) { Block borderBlock = location.getWorld().getBlockAt(x, location.getBlockY() + 1, z); - borderBlock.setType(Material.matchMaterial("STONE_BRICK_SLAB")); + if (VirtualRealty.isLegacy) { + borderBlock.setType(plotSize.getBorderMaterial()); + try { + Method m2 = Block.class.getDeclaredMethod("setData", byte.class); + m2.setAccessible(true); + m2.invoke(borderBlock, plotSize.getBorderData()); + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { + e.printStackTrace(); + } + } else { + borderBlock.setType(plotSize.getBorderMaterial()); + } } } } @@ -409,10 +629,21 @@ public List prepareBlocks(Location location) { for (int z = location.getBlockZ() - length + 1; z < location.getBlockZ() + 1; z++) { Block floorBlock = location.getWorld().getBlockAt(x, location.getBlockY(), z); floorBlock.setType(floorMaterial); + if (VirtualRealty.isLegacy) { + try { + Method m2 = Block.class.getDeclaredMethod("setData", byte.class); + m2.setAccessible(true); + m2.invoke(floorBlock, plotSize.getFloorData()); + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { + e.printStackTrace(); + } + } for (int y = location.getBlockY(); y < location.getBlockY() + height; y++) { Block block = location.getWorld().getBlockAt(x, y, z); Block airBlock = location.getWorld().getBlockAt(x, y + 1, z); - airBlock.setType(Material.AIR); + if (airBlock == null || airBlock != null) { + airBlock.setType(Material.AIR); + } blocks.add(block); } } @@ -425,7 +656,18 @@ public List prepareBlocks(Location location) { for (int z = minZ; z < maxZ; z++) { if (x == minX - 1 || z == minZ || x == maxX - 1 || z == maxZ - 1) { Block borderBlock = location.getWorld().getBlockAt(x, location.getBlockY() + 1, z); - borderBlock.setType(Material.matchMaterial("STONE_BRICK_SLAB")); + if (VirtualRealty.isLegacy) { + borderBlock.setType(plotSize.getBorderMaterial()); + try { + Method m2 = Block.class.getDeclaredMethod("setData", byte.class); + m2.setAccessible(true); + m2.invoke(borderBlock, plotSize.getBorderData()); + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { + e.printStackTrace(); + } + } else { + borderBlock.setType(plotSize.getBorderMaterial()); + } } } } @@ -442,10 +684,21 @@ public List prepareBlocks(Location location) { for (int z = location.getBlockZ(); z < location.getBlockZ() + width; z++) { Block floorBlock = location.getWorld().getBlockAt(x, location.getBlockY(), z); floorBlock.setType(floorMaterial); + if (VirtualRealty.isLegacy) { + try { + Method m2 = Block.class.getDeclaredMethod("setData", byte.class); + m2.setAccessible(true); + m2.invoke(floorBlock, plotSize.getFloorData()); + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { + e.printStackTrace(); + } + } for (int y = location.getBlockY(); y < location.getBlockY() + height; y++) { Block block = location.getWorld().getBlockAt(x, y, z); Block airBlock = location.getWorld().getBlockAt(x, y + 1, z); - airBlock.setType(Material.AIR); + if (airBlock == null || airBlock != null) { + airBlock.setType(Material.AIR); + } blocks.add(block); } } @@ -458,7 +711,18 @@ public List prepareBlocks(Location location) { for (int z = minZ; z < maxZ; z++) { if (x == minX - 1 || z == minZ || x == maxX - 1 || z == maxZ - 1) { Block borderBlock = location.getWorld().getBlockAt(x, location.getBlockY() + 1, z); - borderBlock.setType(Material.matchMaterial("STONE_BRICK_SLAB")); + if (VirtualRealty.isLegacy) { + borderBlock.setType(plotSize.getBorderMaterial()); + try { + Method m2 = Block.class.getDeclaredMethod("setData", byte.class); + m2.setAccessible(true); + m2.invoke(borderBlock, plotSize.getBorderData()); + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { + e.printStackTrace(); + } + } else { + borderBlock.setType(plotSize.getBorderMaterial()); + } } } } @@ -520,7 +784,7 @@ public void insert() { SQL.getStatement().execute("INSERT INTO `vr_plots` (`ID`, `ownedBy`, `assignedBy`, `ownedUntilDate`," + " `floorMaterial`, `plotSize`, `length`, `width`, `height`, `createdLocation`) " + "VALUES ('" + this.ID + "', '" + (this.ownedBy == null ? "" : this.ownedBy.toString()) + "', '" + this.assignedBy + "', " + - "'" + Timestamp.valueOf(this.ownedUntilDate) + "', '" + this.floorMaterial + "'," + + "'" + Timestamp.valueOf(this.ownedUntilDate) + "', '" + this.floorMaterial + ":" + this.floorData + "'," + " '" + this.plotSize + "', '" + this.length + "', '" + this.width + "', '" + this.height + "', '" + builder.toString() + "')"); } catch (SQLException e) { e.printStackTrace(); @@ -530,7 +794,7 @@ public void insert() { public void update() { try { SQL.getStatement().execute("UPDATE `vr_plots` SET `ownedBy`='" + (this.ownedBy == null ? "" : this.ownedBy.toString()) + "', `assignedBy`='" + this.assignedBy + "'," + - " `ownedUntilDate`='" + Timestamp.valueOf(this.ownedUntilDate) + "', `floorMaterial`='" + this.floorMaterial + "'," + + " `ownedUntilDate`='" + Timestamp.valueOf(this.ownedUntilDate) + "', `floorMaterial`='" + this.floorMaterial + ":" + this.floorData + "'," + " `plotSize`='" + this.plotSize + "', `length`='" + this.length + "', `width`='" + this.width + "', `height`='" + this.height + "'" + " WHERE `ID`='" + this.ID + "'"); } catch (SQLException e) { diff --git a/src/main/java/me/plytki/virtualrealty/sql/SQL.java b/src/main/java/me/plytki/virtualrealty/sql/SQL.java index 8d4050d..43f2655 100644 --- a/src/main/java/me/plytki/virtualrealty/sql/SQL.java +++ b/src/main/java/me/plytki/virtualrealty/sql/SQL.java @@ -1,8 +1,8 @@ package me.plytki.virtualrealty.sql; import me.plytki.virtualrealty.VirtualRealty; +import me.plytki.virtualrealty.loaders.PluginConfiguration; -import java.io.File; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; @@ -15,19 +15,9 @@ public class SQL { public static final long MYSQL_TIMEOUT_MS = 28800000; private static long lastQuery = System.currentTimeMillis(); - private static String pathname = "mysql-settings."; - - private static String host = VirtualRealty.getInstance().getConfig().getString(pathname + "host"); - private static int port = VirtualRealty.getInstance().getConfig().getInt(pathname + "port"); - private static String db_name = VirtualRealty.getInstance().getConfig().getString(pathname + "database-name"); - private static String db_username = VirtualRealty.getInstance().getConfig().getString(pathname + "database-username"); - private static String db_password = VirtualRealty.getInstance().getConfig().getString(pathname + "database-password"); - private static boolean useSSL = VirtualRealty.getInstance().getConfig().getBoolean(pathname + "useSSL"); - private static boolean autoReconnect = VirtualRealty.getInstance().getConfig().getBoolean(pathname + "autoReconnect"); - public static void connect() { try { - if (VirtualRealty.getInstance().getConfig().getString("data-storage").equalsIgnoreCase("h2")) { + if (VirtualRealty.getPluginConfiguration().dataModel == PluginConfiguration.DataModel.H2) { Class.forName("me.plytki.virtualrealty.utils.h2.Driver"); connection = DriverManager.getConnection("jdbc:h2:" + VirtualRealty.getInstance().getDataFolder().getAbsolutePath() + "\\data\\data"); // Class.forName("org.sqlite.JDBC"); @@ -38,7 +28,7 @@ public static void connect() { // connection = DriverManager.getConnection("jdbc:sqlite:" + VirtualRealty.getInstance().getDataFolder().getAbsolutePath() + "\\data\\data.db"); } else { Class.forName("com.mysql.jdbc.Driver"); - connection = DriverManager.getConnection("jdbc:mysql://" + host + ":" + port + "/" + db_name + "?useSSL=" + useSSL + "&autoReconnect=" + autoReconnect, db_username, db_password); + connection = DriverManager.getConnection("jdbc:mysql://" + VirtualRealty.getPluginConfiguration().mysql.hostname + ":" + VirtualRealty.getPluginConfiguration().mysql.port + "/" + VirtualRealty.getPluginConfiguration().mysql.database + "?useSSL=" + VirtualRealty.getPluginConfiguration().mysql.useSSL + "&autoReconnect=true", VirtualRealty.getPluginConfiguration().mysql.user, VirtualRealty.getPluginConfiguration().mysql.password); } createStatement(); } catch (SQLException | ClassNotFoundException ex) { @@ -56,6 +46,9 @@ public static void createStatement() { public static void closeConnection() { try { + if (VirtualRealty.getPluginConfiguration().dataModel.equals(PluginConfiguration.DataModel.H2)) { + statement.execute("SHUTDOWN"); + } statement.close(); connection.close(); } catch (SQLException ex) { @@ -65,7 +58,7 @@ public static void closeConnection() { public static void createTables() { try { - SQL.getStatement().execute("CREATE TABLE IF NOT EXISTS `vr_plots` (`ID` INT(12) NOT NULL, `ownedBy` VARCHAR(36) NOT NULL, `assignedBy` VARCHAR(36) NOT NULL, `ownedUntilDate` DATETIME NOT NULL, `floorMaterial` VARCHAR(32) NOT NULL, `plotSize` VARCHAR(32) NOT NULL, `length` INT(24) NOT NULL, `width` INT(24) NOT NULL, `height` INT(24) NOT NULL, `createdLocation` TEXT(500) NOT NULL, PRIMARY KEY(`ID`))"); + SQL.getStatement().execute("CREATE TABLE IF NOT EXISTS `" + VirtualRealty.getPluginConfiguration().mysql.plotsTableName + "` (`ID` INT(12) NOT NULL, `ownedBy` VARCHAR(36) NOT NULL, `assignedBy` VARCHAR(36) NOT NULL, `ownedUntilDate` DATETIME NOT NULL, `floorMaterial` VARCHAR(32) NOT NULL, `plotSize` VARCHAR(32) NOT NULL, `length` INT(24) NOT NULL, `width` INT(24) NOT NULL, `height` INT(24) NOT NULL, `createdLocation` TEXT(500) NOT NULL, PRIMARY KEY(`ID`))"); } catch (SQLException ex) { ex.printStackTrace(); diff --git a/src/main/java/me/plytki/virtualrealty/utils/ConfigUtil.java b/src/main/java/me/plytki/virtualrealty/utils/ConfigUtil.java new file mode 100644 index 0000000..c9e41bb --- /dev/null +++ b/src/main/java/me/plytki/virtualrealty/utils/ConfigUtil.java @@ -0,0 +1,51 @@ +package me.plytki.virtualrealty.utils; + +import org.apache.commons.lang.Validate; +import org.diorite.cfg.system.Template; +import org.diorite.cfg.system.TemplateCreator; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; + +public class ConfigUtil { + + public static T loadConfig(File file, Class implementationFile) { + Template template = TemplateCreator.getTemplate(implementationFile); + Constructor implementationFileConstructor = (Constructor) Reflections.getConstructor(implementationFile); + T config; + if (!file.exists()) { + try { + try { + config = template.fillDefaults(implementationFileConstructor.newInstance()); + } catch (final InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + throw new RuntimeException("Couldn't get access to " + implementationFile.getName() + " constructor", e); + } + Validate.isTrue(file.createNewFile(), "Couldn't create " + file.getAbsolutePath() + " config file"); + } catch (final IOException e) { + throw new RuntimeException("IO exception when creating config file: " + file.getAbsolutePath(), e); + } + } else { + try { + try { + config = template.load(file); + if (config == null) { + config = template.fillDefaults(implementationFileConstructor.newInstance()); + } + } catch (final IOException | IllegalArgumentException | InvocationTargetException e) { + throw new RuntimeException("IO exception when loading config file: " + file.getAbsolutePath(), e); + } + } catch (final InstantiationException | IllegalAccessException e) { + throw new RuntimeException("Couldn't get access to " + implementationFile.getName() + " constructor", e); + } + } + try { + template.dump(file, config, false); + } catch (final IOException e) { + throw new RuntimeException("Can't dump configuration file!", e); + } + return config; + } + +} diff --git a/src/main/java/me/plytki/virtualrealty/utils/Reflections.java b/src/main/java/me/plytki/virtualrealty/utils/Reflections.java new file mode 100644 index 0000000..87a8916 --- /dev/null +++ b/src/main/java/me/plytki/virtualrealty/utils/Reflections.java @@ -0,0 +1,271 @@ +package me.plytki.virtualrealty.utils; + +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.entity.Entity; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +public final class Reflections { + + public static final String SERVER_VERSION = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3]; + public static final boolean USE_PRE_13_METHODS = Integer.parseInt(SERVER_VERSION.split("_")[1]) < 13; + public static final boolean USE_PRE_12_METHODS = Integer.parseInt(SERVER_VERSION.split("_")[1]) < 12; + public static final boolean USE_PRE_9_METHODS = Integer.parseInt(SERVER_VERSION.split("_")[1]) < 9; + + private static final Map> CLASS_CACHE = new HashMap<>(); + private static final Map FIELD_CACHE = new HashMap<>(); + private static final Map> FIELD_ACCESSOR_CACHE = new HashMap<>(); + private static final Map METHOD_CACHE = new HashMap<>(); + private static final Class INVALID_CLASS = InvalidMarker.class; + private static final Method INVALID_METHOD = SafeUtil.safeInit(() -> InvalidMarker.class.getDeclaredMethod("invalidMethodMaker")); + private static final Field INVALID_FIELD = SafeUtil.safeInit(() -> InvalidMarker.class.getDeclaredField("invalidFieldMarker")); + private static final FieldAccessor INVALID_FIELD_ACCESSOR = getField(INVALID_CLASS, Void.class, 0); + + public static Class getClassOmitCache(String className) { + CLASS_CACHE.remove(className); + return getClass(className); + } + + public static Class getClass(String className) { + Class c = CLASS_CACHE.get(className); + + if (c != null) { + return c != INVALID_CLASS ? c : null; + } + + try { + c = Class.forName(className); + CLASS_CACHE.put(className, c); + } + catch (Exception ex) { + System.err.println("Could not retrieve class"); + + CLASS_CACHE.put(className, INVALID_CLASS); + } + return c; + } + + public static Class getNMSClass(String name) { + return getClass("net.minecraft.server." + SERVER_VERSION + "." + name); + } + + public static Class getCraftBukkitClass(String name) { + return getClass("org.bukkit.craftbukkit." + SERVER_VERSION + "." + name); + } + + public static Class getBukkitClass(String name) { + return getClass("org.bukkit." + name); + } + + public static Object getHandle(Entity entity) { + try { + return getMethod(entity.getClass(), "getHandle").invoke(entity); + } + catch (Exception ex) { + System.err.println("Could not get entity handle"); + return null; + } + } + + public static Object getHandle(World world) { + try { + return getMethod(world.getClass(), "getHandle").invoke(world); + } + catch (Exception ex) { + System.err.println("Could not get world handle"); + + return null; + } + } + + private static String constructFieldCacheKey(Class cl, String fieldName) { + return cl.getName() + "." + fieldName; + } + + public static Field getField(Class cl, String fieldName) { + String cacheKey = constructFieldCacheKey(cl, fieldName); + + Field field = FIELD_CACHE.get(cacheKey); + + if (field != null) { + return field != INVALID_FIELD ? field : null; + } + + try { + field = cl.getDeclaredField(fieldName); + FIELD_CACHE.put(cacheKey, field); + } + catch (Exception ex) { + System.err.println("Could not retrieve field"); + + FIELD_CACHE.put(cacheKey, INVALID_FIELD); + } + + return field; + } + + public static FieldAccessor getField(Class target, Class fieldType, int index) { + return getField(target, null, fieldType, index); + } + + @SuppressWarnings("unchecked") + private static FieldAccessor getField(Class target, String name, Class fieldType, int index) { + final String cacheKey = target.getName() + "." + (name != null ? name : "NONE") + "." + fieldType.getName() + "." + index; + + FieldAccessor output = (FieldAccessor) FIELD_ACCESSOR_CACHE.get(cacheKey); + + if (output != null) { + if (output == INVALID_FIELD_ACCESSOR) { + throw new IllegalArgumentException("Cannot find field with type " + fieldType); + } + + return output; + } + + for (final Field field : target.getDeclaredFields()) { + if ((name == null || field.getName().equals(name)) && fieldType.isAssignableFrom(field.getType()) && index-- <= 0) { + field.setAccessible(true); + + output = new FieldAccessor() { + + @Override + public T get(Object target) { + try { + return (T) field.get(target); + } catch (IllegalAccessException e) { + throw new RuntimeException("Cannot access reflection.", e); + } + } + + @Override + public void set(Object target, Object value) { + try { + field.set(target, value); + } catch (IllegalAccessException e) { + throw new RuntimeException("Cannot access reflection.", e); + } + } + + @Override + public boolean hasField(Object target) { + return field.getDeclaringClass().isAssignableFrom(target.getClass()); + } + }; + + break; + } + } + + if (output == null && target.getSuperclass() != null) { + output = getField(target.getSuperclass(), name, fieldType, index); + } + + FIELD_ACCESSOR_CACHE.put(cacheKey, output != null ? output : INVALID_FIELD_ACCESSOR); + + if (output == null) { + throw new IllegalArgumentException("Cannot find field with type " + fieldType); + } + + return output; + } + + public static Field getPrivateField(Class cl, String fieldName) { + String cacheKey = constructFieldCacheKey(cl, fieldName); + + Field c = FIELD_CACHE.get(cacheKey); + if (c != null) { + return c != INVALID_FIELD ? c : null; + } + + try { + c = cl.getDeclaredField(fieldName); + c.setAccessible(true); + FIELD_CACHE.put(cacheKey, c); + } + catch (Exception ex) { + System.err.println("Could not retrieve field"); + + FIELD_CACHE.put(cacheKey, INVALID_FIELD); + } + + return c; + } + + public static Method getMethod(Class cl, String method, Class... args) { + String cacheKey = cl.getName() + "." + method + "." + (args == null ? "NONE" : Arrays.toString(args)); + + Method output = METHOD_CACHE.get(cacheKey); + if (output != null) { + return output != INVALID_METHOD ? output : null; + } + + for (Method m : cl.getMethods()) { + if (m.getName().equals(method) && (args == null || classListEqual(args, m.getParameterTypes()))) { + output = m; + break; + } + } + + METHOD_CACHE.put(cacheKey, output == null ? INVALID_METHOD : output); + return output; + } + + public static Method getMethod(Class cl, String method) { + return getMethod(cl, method, null); + } + + public static Constructor getConstructor(Class clazz, Class... arguments) { + for (Constructor constructor : clazz.getDeclaredConstructors()) { + if (Arrays.equals(constructor.getParameterTypes(), arguments)) { + return constructor; + } + } + + return null; + } + + public static boolean classListEqual(Class[] l1, Class[] l2) { + if (l1.length != l2.length) { + return false; + } + + for (int i = 0; i < l1.length; i++) { + if (l1[i] != l2[i]) { + return false; + } + } + + return true; + } + + public interface ConstructorInvoker { + Object invoke(Object... arguments); + } + + public interface MethodInvoker { + Object invoke(Object target, Object... arguments); + } + + public interface FieldAccessor { + T get(Object target); + + void set(Object target, Object value); + + boolean hasField(Object target); + } + + private static class InvalidMarker { + public Void invalidFieldMarker; + public void invalidMethodMaker() {} + } + + private Reflections() {} + +} + diff --git a/src/main/java/me/plytki/virtualrealty/utils/SafeUtil.java b/src/main/java/me/plytki/virtualrealty/utils/SafeUtil.java new file mode 100644 index 0000000..61d809c --- /dev/null +++ b/src/main/java/me/plytki/virtualrealty/utils/SafeUtil.java @@ -0,0 +1,27 @@ +package me.plytki.virtualrealty.utils; + +public class SafeUtil { + + private static void reportUnsafe(Throwable th) { + try { + throw new Exception(th.getMessage()); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static T safeInit(SafeInitializer initializer) { + try { + return initializer.initialize(); + } catch (Exception e) { + reportUnsafe(e); + return null; + } + } + + @FunctionalInterface + public interface SafeInitializer { + T initialize() throws Exception; + } + +} diff --git a/src/main/java/me/plytki/virtualrealty/utils/SchematicUtil.java b/src/main/java/me/plytki/virtualrealty/utils/SchematicUtil.java index f349085..bb51a6b 100644 --- a/src/main/java/me/plytki/virtualrealty/utils/SchematicUtil.java +++ b/src/main/java/me/plytki/virtualrealty/utils/SchematicUtil.java @@ -3,6 +3,7 @@ import me.plytki.virtualrealty.VirtualRealty; import me.plytki.virtualrealty.managers.PlotManager; import me.plytki.virtualrealty.objects.Plot; +import me.plytki.virtualrealty.utils.multiversion.VMaterial; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; @@ -11,6 +12,8 @@ import org.bukkit.plugin.Plugin; import java.io.*; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.util.*; public class SchematicUtil { @@ -34,8 +37,11 @@ public static List getStructure(Block block, Block block2) { for (int z = minZ; z <= maxZ; ++z) { Block b = block.getWorld().getBlockAt(x, y, z); if (b.getType() != Material.AIR) - blocks.add(x - minX + ";" + (y - minY) + ";" + (z - minZ) + ";" + b.getBlockData().getAsString().substring(10)); - //System.out.println(b.getBlockData().getAsString()); + if (VirtualRealty.isLegacy) { + blocks.add(x - minX + ";" + (y - minY) + ";" + (z - minZ) + ";" + b.getType().getId() + ";" + b.getData()); + } else { + blocks.add(x - minX + ";" + (y - minY) + ";" + (z - minZ) + ";" + b.getBlockData().getAsString().substring(10)); + } } } } @@ -71,8 +77,21 @@ public void paste(int plotID, Location l) { Location displaced = l.clone(); displaced.add(x, y, z); Block b = displaced.getBlock(); - BlockData blockData = Bukkit.createBlockData("minecraft:" + cords[3]); - b.setBlockData(blockData); + if (VirtualRealty.isLegacy) { + try { + Method m = Block.class.getDeclaredMethod("setType", Material.class); + m.setAccessible(true); + m.invoke(b, VMaterial.getMaterial(Integer.parseInt(cords[3]))); + Method m2 = Block.class.getDeclaredMethod("setData", byte.class); + m2.setAccessible(true); + m2.invoke(b, (byte) Integer.parseInt(cords[4])); + } catch (Exception e) { + e.printStackTrace(); + } + } else { + BlockData blockData = Bukkit.createBlockData("minecraft:" + cords[3]); + b.setBlockData(blockData); + } b.getState().update(true); } } diff --git a/src/main/java/me/plytki/virtualrealty/utils/multiversion/Chat.java b/src/main/java/me/plytki/virtualrealty/utils/multiversion/Chat.java new file mode 100644 index 0000000..d685c98 --- /dev/null +++ b/src/main/java/me/plytki/virtualrealty/utils/multiversion/Chat.java @@ -0,0 +1,38 @@ +package me.plytki.virtualrealty.utils.multiversion; + +import me.plytki.virtualrealty.VirtualRealty; +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.api.chat.TextComponent; +import org.bukkit.entity.Player; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +public class Chat { + + private final BaseComponent text; + + public Chat(BaseComponent text) { + this.text = text; + } + + public Chat(String text) { + this.text = new TextComponent(text); + } + + public void sendTo(Player player) { + if (VirtualRealty.isLegacy) { + try { + Method m = Player.class.getDeclaredMethod("sendMessage", BaseComponent.class); + m.setAccessible(true); + m.invoke(player, text); + } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) { + e.printStackTrace(); + } + } else { + player.spigot().sendMessage(text); + } + } + + +} diff --git a/src/main/java/me/plytki/virtualrealty/utils/multiversion/VMaterial.java b/src/main/java/me/plytki/virtualrealty/utils/multiversion/VMaterial.java new file mode 100644 index 0000000..b5eace8 --- /dev/null +++ b/src/main/java/me/plytki/virtualrealty/utils/multiversion/VMaterial.java @@ -0,0 +1,43 @@ +package me.plytki.virtualrealty.utils.multiversion; + +import me.plytki.virtualrealty.VirtualRealty; +import org.bukkit.Material; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +public class VMaterial { + + public static Material getMaterial(int materialID) { + if (VirtualRealty.isLegacy) { + try { + Method m = Material.class.getDeclaredMethod("getMaterial", int.class); + m.setAccessible(true); + return (Material) m.invoke(Material.class, materialID); + } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) { + e.printStackTrace(); + } + } else { + int counter = 1; + for (Material material : Material.values()) { + if (counter == materialID) { + return material; + } + counter++; + } + } + return null; + } + + public static Material getMaterial(String material) { + try { + Method m = Material.class.getDeclaredMethod("getMaterial", String.class); + m.setAccessible(true); + return (Material) m.invoke(Material.class, material); + } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) { + e.printStackTrace(); + } + return null; + } + +} diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml deleted file mode 100644 index b150660..0000000 --- a/src/main/resources/config.yml +++ /dev/null @@ -1,10 +0,0 @@ -#Test config -data-storage: H2 -mysql-settings: - host: 127.0.0.1 - port: 3306 - database-name: virtualrealty - database-username: username - database-password: pass123 - useSSL: false - autoReconnect: true \ No newline at end of file diff --git a/src/main/resources/sizes.yml b/src/main/resources/sizes.yml deleted file mode 100644 index e74a405..0000000 --- a/src/main/resources/sizes.yml +++ /dev/null @@ -1,19 +0,0 @@ -plots-sizes: - SMALL: - floorMaterial: GRASS_BLOCK - size: - length: 10 - width: 10 - height: 10 - MEDIUM: - floorMaterial: GRASS_BLOCK - size: - length: 25 - width: 25 - height: 25 - LARGE: - floorMaterial: GRASS_BLOCK - size: - length: 50 - width: 50 - height: 50 \ No newline at end of file