From 210709e5a295b28878a176dbffaf4fb370710b5f Mon Sep 17 00:00:00 2001 From: SamB440 Date: Fri, 17 Mar 2023 17:39:10 +0000 Subject: [PATCH] Add support for CustomStructures --- .../api/events/RPGRegionsReloadEvent.java | 19 ++++ build.gradle.kts | 2 +- gradle.properties | 2 +- .../integrations/lands/LandsIntegration.java | 4 +- rpgregions/build.gradle.kts | 2 + .../islandearth/rpgregions/RPGRegions.java | 5 + .../commands/RPGRegionsCommand.java | 2 + .../RPGRegionsIntegrationCommand.java | 18 +++- .../external/CustomStructuresListener.java | 95 +++++++++++++++++++ .../integrations/custom-structures.yml | 18 ++++ .../src/main/resources/integrations/lands.yml | 1 + rpgregions/src/main/resources/plugin.yml | 2 +- 12 files changed, 163 insertions(+), 7 deletions(-) create mode 100644 api/src/main/java/net/islandearth/rpgregions/api/events/RPGRegionsReloadEvent.java create mode 100644 rpgregions/src/main/java/net/islandearth/rpgregions/listener/external/CustomStructuresListener.java create mode 100644 rpgregions/src/main/resources/integrations/custom-structures.yml diff --git a/api/src/main/java/net/islandearth/rpgregions/api/events/RPGRegionsReloadEvent.java b/api/src/main/java/net/islandearth/rpgregions/api/events/RPGRegionsReloadEvent.java new file mode 100644 index 0000000..dfdfc9a --- /dev/null +++ b/api/src/main/java/net/islandearth/rpgregions/api/events/RPGRegionsReloadEvent.java @@ -0,0 +1,19 @@ +package net.islandearth.rpgregions.api.events; + +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +public class RPGRegionsReloadEvent extends Event { + + private static final HandlerList HANDLER_LIST = new HandlerList(); + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } + +} \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 804be62..dd5727f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -14,7 +14,7 @@ dependencies { allprojects { group = "net.islandearth.rpgregions" - version = "1.4.4" + version = "1.4.5" //tasks.withType(JavaCompile).configureEach { // ensure that the encoding is set to UTF-8, no matter what the system default is diff --git a/gradle.properties b/gradle.properties index dbe98a1..8db8608 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ pluginGroup=net.islandearth -pluginVersion=1.4.4 +pluginVersion=1.4.5 # Set to false if you don't have access to the UltraRegions API jar to make the plugin compilable. The purchased plugin has support for it. ultraRegionsSupport=true diff --git a/modern/src/main/java/net/islandearth/rpgregions/api/integrations/lands/LandsIntegration.java b/modern/src/main/java/net/islandearth/rpgregions/api/integrations/lands/LandsIntegration.java index b7ea4e0..3fe7b04 100644 --- a/modern/src/main/java/net/islandearth/rpgregions/api/integrations/lands/LandsIntegration.java +++ b/modern/src/main/java/net/islandearth/rpgregions/api/integrations/lands/LandsIntegration.java @@ -32,7 +32,9 @@ public class LandsIntegration implements IntegrationManager { this.plugin = plugin; this.config = YamlConfiguration.loadConfiguration(new File(plugin.getDataFolder() + File.separator + "integrations" + File.separator + "lands.yml")); this.lands = new me.angeschossen.lands.api.integration.LandsIntegration((Plugin) plugin); - Bukkit.getPluginManager().registerEvents(new LandsListener(this), (Plugin) plugin); + if (config.getBoolean("auto-generate")) { + Bukkit.getPluginManager().registerEvents(new LandsListener(this), (Plugin) plugin); + } } public IRPGRegionsAPI getPlugin() { diff --git a/rpgregions/build.gradle.kts b/rpgregions/build.gradle.kts index 474d202..88a0726 100644 --- a/rpgregions/build.gradle.kts +++ b/rpgregions/build.gradle.kts @@ -1,6 +1,7 @@ repositories { maven("https://betonquest.org/nexus/repository/betonquest/") maven("https://nexus.phoenixdvpt.fr/repository/maven-public/") + maven("https://repo.ryandw11.com/repository/maven-releases/") } dependencies { @@ -43,6 +44,7 @@ dependencies { } compileOnly(":Dynmap-3.1-spigot") // Dynmap compileOnly("com.comphenix.protocol:ProtocolLib:5.0.0-SNAPSHOT") + compileOnly("com.ryandw11:CustomStructures:1.8.2") } configurations.all { diff --git a/rpgregions/src/main/java/net/islandearth/rpgregions/RPGRegions.java b/rpgregions/src/main/java/net/islandearth/rpgregions/RPGRegions.java index afd871d..7b0f1cb 100644 --- a/rpgregions/src/main/java/net/islandearth/rpgregions/RPGRegions.java +++ b/rpgregions/src/main/java/net/islandearth/rpgregions/RPGRegions.java @@ -30,6 +30,7 @@ import net.islandearth.rpgregions.listener.ConnectionListener; import net.islandearth.rpgregions.listener.MoveListener; import net.islandearth.rpgregions.listener.RegionListener; import net.islandearth.rpgregions.listener.ServerReloadListener; +import net.islandearth.rpgregions.listener.external.CustomStructuresListener; import net.islandearth.rpgregions.managers.RPGRegionsManagers; import net.islandearth.rpgregions.managers.data.region.ConfiguredRegion; import net.islandearth.rpgregions.managers.registry.IRPGRegionsRegistry; @@ -170,6 +171,7 @@ public final class RPGRegions extends JavaPlugin implements IRPGRegionsAPI { private void createConfig() { saveDefaultConfig(); // Moved to config.yml saveResource("integrations/lands.yml", false); + saveResource("integrations/custom-structures.yml", false); } private void registerListeners() { @@ -178,6 +180,9 @@ public final class RPGRegions extends JavaPlugin implements IRPGRegionsAPI { pm.registerEvents(new ConnectionListener(this), this); pm.registerEvents(new RegionListener(this), this); pm.registerEvents(new MoveListener(this), this); + if (Bukkit.getPluginManager().getPlugin("CustomStructures") != null) { + pm.registerEvents(new CustomStructuresListener(this), this); + } } private void registerCommands() { diff --git a/rpgregions/src/main/java/net/islandearth/rpgregions/commands/RPGRegionsCommand.java b/rpgregions/src/main/java/net/islandearth/rpgregions/commands/RPGRegionsCommand.java index 079994e..27720c6 100644 --- a/rpgregions/src/main/java/net/islandearth/rpgregions/commands/RPGRegionsCommand.java +++ b/rpgregions/src/main/java/net/islandearth/rpgregions/commands/RPGRegionsCommand.java @@ -10,6 +10,7 @@ import co.aikar.commands.annotation.HelpCommand; import co.aikar.commands.annotation.Subcommand; import net.islandearth.rpgregions.RPGRegions; import net.islandearth.rpgregions.api.RPGRegionsAPI; +import net.islandearth.rpgregions.api.events.RPGRegionsReloadEvent; import net.islandearth.rpgregions.api.integrations.IntegrationType; import net.islandearth.rpgregions.gui.DiscoveryGUI; import net.islandearth.rpgregions.gui.RegionCreateGUI; @@ -201,6 +202,7 @@ public class RPGRegionsCommand extends BaseCommand { plugin.reloadConfig(); plugin.getManagers().getRegenerationManager().reload(); + Bukkit.getPluginManager().callEvent(new RPGRegionsReloadEvent()); long endTime = System.currentTimeMillis(); long totalTime = endTime - startTime; sender.sendMessage(ChatColor.GREEN + "Done! (" + totalTime + "ms)"); diff --git a/rpgregions/src/main/java/net/islandearth/rpgregions/commands/RPGRegionsIntegrationCommand.java b/rpgregions/src/main/java/net/islandearth/rpgregions/commands/RPGRegionsIntegrationCommand.java index e828f10..c4780bd 100644 --- a/rpgregions/src/main/java/net/islandearth/rpgregions/commands/RPGRegionsIntegrationCommand.java +++ b/rpgregions/src/main/java/net/islandearth/rpgregions/commands/RPGRegionsIntegrationCommand.java @@ -15,6 +15,7 @@ import net.islandearth.rpgregions.api.integrations.rpgregions.region.PolyRegion; import net.islandearth.rpgregions.api.integrations.rpgregions.region.RPGRegionsRegion; import org.bukkit.Bukkit; import org.bukkit.ChatColor; +import org.bukkit.Location; import org.bukkit.World; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; @@ -108,9 +109,20 @@ public class RPGRegionsIntegrationCommand extends BaseCommand { @Subcommand("addpos") @CommandCompletion("@regions") - public void onAddPos(final Player player, final RPGRegionsRegion region) { - region.addPoint(player.getLocation()); - player.sendMessage(ChatColor.GREEN + "Added point to " + region.getName() + "."); + public void onAddPos(final CommandSender sender, final RPGRegionsRegion region, @co.aikar.commands.annotation.Optional World world, Double x, Double y, Double z) { + if (sender instanceof Player player && world == null && x != null && y != null && z != null) { + region.addPoint(player.getLocation()); + player.sendMessage(ChatColor.GREEN + "Added point to " + region.getName() + "."); + } else { + if (world == null || x == null || y == null || z == null) { + sender.sendMessage(ChatColor.RED + "You need to specify the world, x, y, z of the point."); + return; + } + + Location location = new Location(world, x, y, z); + region.addPoint(location); + sender.sendMessage(ChatColor.GREEN + "Added point to " + region.getName() + "."); + } } @Subcommand("setpriority") diff --git a/rpgregions/src/main/java/net/islandearth/rpgregions/listener/external/CustomStructuresListener.java b/rpgregions/src/main/java/net/islandearth/rpgregions/listener/external/CustomStructuresListener.java new file mode 100644 index 0000000..9f2bc4f --- /dev/null +++ b/rpgregions/src/main/java/net/islandearth/rpgregions/listener/external/CustomStructuresListener.java @@ -0,0 +1,95 @@ +package net.islandearth.rpgregions.listener.external; + +import com.ryandw11.structure.api.StructureSpawnEvent; +import com.ryandw11.structure.structure.Structure; +import net.islandearth.rpgregions.RPGRegions; +import net.islandearth.rpgregions.api.events.RPGRegionsReloadEvent; +import net.islandearth.rpgregions.managers.data.IRPGRegionsCache; +import net.islandearth.rpgregions.managers.data.region.ConfiguredRegion; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; + +import java.io.File; +import java.io.FileReader; +import java.io.Reader; +import java.util.List; +import java.util.UUID; +import java.util.logging.Level; + +public class CustomStructuresListener implements Listener { + + private final RPGRegions plugin; + private YamlConfiguration config; + + public CustomStructuresListener(RPGRegions plugin) { + this.plugin = plugin; + this.config = YamlConfiguration.loadConfiguration(new File(plugin.getDataFolder() + File.separator + "integrations" + File.separator + "custom-structures.yml")); + } + + @EventHandler + public void onSpawn(StructureSpawnEvent event) { + final Structure structure = event.getStructure(); + final String name = structure.getName(); + final Location location = event.getLocation(); + final ConfigurationSection section = config.getConfigurationSection("templates." + name); + if (section == null) return; + + final String template = section.getString("template"); + File templateFile = new File(plugin.getDataFolder() + File.separator + "templates" + File.separator + template); + if (!templateFile.exists()) { + plugin.getLogger().log(Level.SEVERE, String.format("Unable to load template '%s' for automatic region generation.", template)); + return; + } + + final List commands = section.getStringList("commands"); + if (commands.isEmpty()) { + plugin.getLogger().log(Level.SEVERE, String.format("Unable to create region for template '%s' because there are no commands to generate a valid region.", template)); + return; + } + + try (Reader reader = new FileReader(templateFile)) { + ConfiguredRegion templateRegion = plugin.getGson().fromJson(reader, ConfiguredRegion.class); + templateRegion.setId((name + "_" + UUID.randomUUID().toString().replace("-", "")).substring(0, 36)); + templateRegion.setLocation(location); + templateRegion.setCustomName(name); + templateRegion.setWorld(location.getWorld().getUID()); + + final int preSize = plugin.getManagers().getIntegrationManager().getAllRegionNames(location.getWorld()).size(); + + final Location min = event.getMinimumPoint(); + final Location max = event.getMaximumPoint(); + for (String command : commands) { + command = command.replace("{id}", templateRegion.getId()); + command = command.replace("{world}", location.getWorld().getName()); + command = command.replace("{minX}", "" + min.getBlockX()); + command = command.replace("{minY}", "" + min.getBlockY()); + command = command.replace("{minZ}", "" + min.getBlockZ()); + command = command.replace("{maxX}", "" + max.getBlockX()); + command = command.replace("{maxY}", "" + max.getBlockY()); + command = command.replace("{maxZ}", "" + max.getBlockZ()); + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command); + } + + final int postSize = plugin.getManagers().getIntegrationManager().getAllRegionNames(location.getWorld()).size(); + if (postSize <= preSize) { + plugin.getLogger().log(Level.SEVERE, String.format("Unable to create region for template '%s' with id '%s' because no region was created from the commands.", template, templateRegion.getId())); + return; + } + + final IRPGRegionsCache regionsCache = plugin.getManagers().getRegionsCache(); + regionsCache.addConfiguredRegion(templateRegion); + plugin.debug("Automatically generated region: " + templateRegion.getId()); + } catch (Exception e) { + plugin.getLogger().log(Level.SEVERE, "Error loading template config " + templateFile.getName() + ".", e); + } + } + + @EventHandler + public void onReload(RPGRegionsReloadEvent event) { + this.config = YamlConfiguration.loadConfiguration(new File(plugin.getDataFolder() + File.separator + "integrations" + File.separator + "custom-structures.yml")); + } +} diff --git a/rpgregions/src/main/resources/integrations/custom-structures.yml b/rpgregions/src/main/resources/integrations/custom-structures.yml new file mode 100644 index 0000000..5e7abe3 --- /dev/null +++ b/rpgregions/src/main/resources/integrations/custom-structures.yml @@ -0,0 +1,18 @@ +# This is the file for additional support for the CustomStructures plugin. + +# Should we automatically generate regions based on structures created? +auto-generate: true + +# This is a group of template definitions. Templates are defined in plugins/RPGRegions/templates. +# You can use /rpgre to export a template region. +# The name of the file should be put here. The template will then be used to automatically generate a region. +templates: + demo: # For the "demo" structure... + template: "custom_structures_template_demo.json" + commands: + # You must specify a list of commands that create a valid region in your current integration + # {id} is replaced with the generated region id, e.g "demo_" and {world} with the world it was in + # {minX} {maxX}, etc. is the generated min/max positions of the structure. + - "rpgri create {id} cuboid {world}" + - "rpgri addpos {id} {world} {minX} {minY} {minZ}" + - "rpgri addpos {id} {world} {maxX} {maxY} {maxZ}" diff --git a/rpgregions/src/main/resources/integrations/lands.yml b/rpgregions/src/main/resources/integrations/lands.yml index 08cfe79..be81564 100644 --- a/rpgregions/src/main/resources/integrations/lands.yml +++ b/rpgregions/src/main/resources/integrations/lands.yml @@ -1,4 +1,5 @@ # This is the file for editing the Lands integration. + # Should we automatically generate regions based on lands created? auto-generate: true diff --git a/rpgregions/src/main/resources/plugin.yml b/rpgregions/src/main/resources/plugin.yml index 83d5e17..c8feea0 100644 --- a/rpgregions/src/main/resources/plugin.yml +++ b/rpgregions/src/main/resources/plugin.yml @@ -4,7 +4,7 @@ main: net.islandearth.rpgregions.RPGRegions api-version: '1.16' libraries: - "com.zaxxer:HikariCP:4.0.3" # database -softdepend: [Hyperverse, Multiverse, UltraRegions, WorldGuard, PlaceholderAPI, HeadDatabase, Residence, Plan, GriefPrevention, GriefDefender, Vault, MythicMobs, AlonsoLevels, Dynmap, ProtocolLib, Quests, BetonQuest, Lands, MMOCore] +softdepend: [Hyperverse, Multiverse, UltraRegions, WorldGuard, PlaceholderAPI, HeadDatabase, Residence, Plan, GriefPrevention, GriefDefender, Vault, MythicMobs, AlonsoLevels, Dynmap, ProtocolLib, Quests, BetonQuest, Lands, MMOCore, CustomStructures] authors: [SamB440] description: Discoverable regions website: https://fortitude.islandearth.net \ No newline at end of file