diff --git a/core/src/main/java/com/sekwah/advancedportals/core/AdvancedPortalsCore.java b/core/src/main/java/com/sekwah/advancedportals/core/AdvancedPortalsCore.java index 307aa4e..e541b85 100644 --- a/core/src/main/java/com/sekwah/advancedportals/core/AdvancedPortalsCore.java +++ b/core/src/main/java/com/sekwah/advancedportals/core/AdvancedPortalsCore.java @@ -3,6 +3,7 @@ package com.sekwah.advancedportals.core; import com.google.inject.Inject; import com.google.inject.Injector; import com.sekwah.advancedportals.core.commands.CommandWithSubCommands; +import com.sekwah.advancedportals.core.commands.SubCommand; import com.sekwah.advancedportals.core.commands.subcommands.desti.*; import com.sekwah.advancedportals.core.commands.subcommands.portal.*; import com.sekwah.advancedportals.core.connector.commands.CommandRegister; @@ -149,6 +150,14 @@ public class AdvancedPortalsCore { commandRegister.registerCommand("destination", this.destiCommand); } + public boolean registerPortalCommand(String arg, SubCommand subCommand, String... aliasArgs) { + return this.portalCommand.registerSubCommand(arg, subCommand, aliasArgs); + } + + public boolean registerDestiCommand(String arg, SubCommand subCommand, String... aliasArgs) { + return this.destiCommand.registerSubCommand(arg, subCommand, aliasArgs); + } + /** * Loads the portal config into the memory and saves from the memory to check in case certain things have changed * (basically if values are missing or whatever) diff --git a/core/src/main/java/com/sekwah/advancedportals/core/serializeddata/PlayerTempData.java b/core/src/main/java/com/sekwah/advancedportals/core/serializeddata/PlayerTempData.java index 02cea8f..ef06a0e 100644 --- a/core/src/main/java/com/sekwah/advancedportals/core/serializeddata/PlayerTempData.java +++ b/core/src/main/java/com/sekwah/advancedportals/core/serializeddata/PlayerTempData.java @@ -29,6 +29,11 @@ public class PlayerTempData { */ private boolean destiVisible; + /** + * If the player is in a portal. Stops re-triggering. + */ + private boolean isInPortal = false; + /** * The next time System.currentTimeMillis() a player can use a portal. */ @@ -83,4 +88,12 @@ public class PlayerTempData { public void setDestiVisible(boolean destiVisible) { this.destiVisible = destiVisible; } + + public boolean isInPortal() { + return isInPortal; + } + + public void setInPortal(boolean inPortal) { + isInPortal = inPortal; + } } diff --git a/core/src/main/java/com/sekwah/advancedportals/core/services/DestinationServices.java b/core/src/main/java/com/sekwah/advancedportals/core/services/DestinationServices.java index f6e25ae..8aba36a 100644 --- a/core/src/main/java/com/sekwah/advancedportals/core/services/DestinationServices.java +++ b/core/src/main/java/com/sekwah/advancedportals/core/services/DestinationServices.java @@ -46,7 +46,11 @@ public class DestinationServices { } } - public Destination createDesti(PlayerContainer player, PlayerLocation playerLocation, ArrayList tags) { + public Destination createDesti(PlayerLocation playerLocation, List tags) { + return createDesti(null, playerLocation, tags); + } + + public Destination createDesti(PlayerContainer player, PlayerLocation playerLocation, List tags) { // Find the tag with the "name" NAME DataTag nameTag = tags.stream().filter(tag -> tag.NAME.equals("name")).findFirst().orElse(null); @@ -54,15 +58,15 @@ public class DestinationServices { // If the name is null, send an error saying that the name is required. if (nameTag == null) { - player.sendMessage(Lang.translate("messageprefix.negative") + Lang.translate("desti.error.noname")); + if (player != null) player.sendMessage(Lang.translate("messageprefix.negative") + Lang.translate("desti.error.noname")); return null; } if (name == null || name.equals("")) { - player.sendMessage(Lang.translate("messageprefix.negative") + Lang.translate("command.error.noname")); + if (player != null) player.sendMessage(Lang.translate("messageprefix.negative") + Lang.translate("command.error.noname")); return null; } else if (this.destinationRepository.containsKey(name)) { - player.sendMessage(Lang.translate("messageprefix.negative") + Lang.translateInsertVariables("command.error.nametaken", name)); + if (player != null) player.sendMessage(Lang.translate("messageprefix.negative") + Lang.translateInsertVariables("command.error.nametaken", name)); return null; } diff --git a/core/src/main/java/com/sekwah/advancedportals/core/services/PortalServices.java b/core/src/main/java/com/sekwah/advancedportals/core/services/PortalServices.java index 1678814..dcb327e 100644 --- a/core/src/main/java/com/sekwah/advancedportals/core/services/PortalServices.java +++ b/core/src/main/java/com/sekwah/advancedportals/core/services/PortalServices.java @@ -113,20 +113,11 @@ public class PortalServices { return false; } + public AdvancedPortal createPortal(BlockLocation pos1, BlockLocation pos2, List tags) { + return createPortal(null, pos1, pos2, tags); + } + public AdvancedPortal createPortal(PlayerContainer player, ArrayList tags) { - // Find the tag with the "name" NAME - DataTag nameTag = tags.stream().filter(tag -> tag.NAME.equals(NameTag.TAG_NAME)).findFirst().orElse(null); - - String name = nameTag == null ? null : nameTag.VALUES[0]; - if(nameTag == null || name == null || name.isEmpty()) { - player.sendMessage(Lang.translate("messageprefix.negative") + Lang.translate("command.error.noname")); - return null; - } - else if(this.portalRepository.containsKey(name)) { - player.sendMessage(Lang.translate("messageprefix.negative") + Lang.translateInsertVariables("command.error.nametaken", name)); - return null; - } - PlayerTempData tempData = portalTempDataServices.getPlayerTempData(player); if(tempData.getPos1() == null || tempData.getPos2() == null) { @@ -139,7 +130,24 @@ public class PortalServices { return null; } - AdvancedPortal portal = new AdvancedPortal(tempData.getPos1(), tempData.getPos2()); + return createPortal(player, tempData.getPos1(), tempData.getPos2(), tags); + } + + public AdvancedPortal createPortal(PlayerContainer player, BlockLocation pos1, BlockLocation pos2, List tags) { + // Find the tag with the "name" NAME + DataTag nameTag = tags.stream().filter(tag -> tag.NAME.equals(NameTag.TAG_NAME)).findFirst().orElse(null); + + String name = nameTag == null ? null : nameTag.VALUES[0]; + if(nameTag == null || name == null || name.isEmpty()) { + if(player != null) player.sendMessage(Lang.translate("messageprefix.negative") + Lang.translate("command.error.noname")); + return null; + } + else if(this.portalRepository.containsKey(name)) { + if(player != null) player.sendMessage(Lang.translate("messageprefix.negative") + Lang.translateInsertVariables("command.error.nametaken", name)); + return null; + } + + AdvancedPortal portal = new AdvancedPortal(pos1, pos2); for (DataTag portalTag : tags) { portal.setArgValues(portalTag); @@ -162,7 +170,7 @@ public class PortalServices { } } catch (Exception e) { e.printStackTrace(); - player.sendMessage(Lang.translate("messageprefix.negative") + Lang.translate("portal.error.save")); + if(player != null) player.sendMessage(Lang.translate("messageprefix.negative") + Lang.translate("portal.error.save")); } return portal; diff --git a/lang/src/main/resources/lang/en_GB.lang b/lang/src/main/resources/lang/en_GB.lang index 82421cc..e7c2280 100644 --- a/lang/src/main/resources/lang/en_GB.lang +++ b/lang/src/main/resources/lang/en_GB.lang @@ -108,6 +108,12 @@ command.selector= You have been given a portal selector. command.selector.help=Gives you a portal region selector command.selector.detailedhelp=Gives you a portal selector to select the regions for making portals. +command.portal.update= &e%1$s &aportals and &e%2$s &adestinations will be imported. Please type &e/portal update confirm &ato confirm this action. &7Config values will not be imported. +command.portal.update.confirm= &aImporting portals and destinations. +command.portal.update.complete= &aImported &e%1$s &aportals and &e%2$s &adestinations. +command.portal.update.help=Imports portals and destinations from the old format. +command.portal.update.detailedhelp=Imports portals and destinations from the old format. This not overwrite any existing portals and destinations with the same name. + command.portalblock= You have been given a &ePortal Block&a! command.endportalblock= You have been given a &8End Portal Block Placer&a! diff --git a/spigot/src/main/java/com/sekwah/advancedportals/spigot/AdvancedPortalsPlugin.java b/spigot/src/main/java/com/sekwah/advancedportals/spigot/AdvancedPortalsPlugin.java index a70187d..7336fa9 100644 --- a/spigot/src/main/java/com/sekwah/advancedportals/spigot/AdvancedPortalsPlugin.java +++ b/spigot/src/main/java/com/sekwah/advancedportals/spigot/AdvancedPortalsPlugin.java @@ -5,6 +5,7 @@ import com.sekwah.advancedportals.core.AdvancedPortalsCore; import com.sekwah.advancedportals.core.connector.commands.CommandRegister; import com.sekwah.advancedportals.core.module.AdvancedPortalsModule; import com.sekwah.advancedportals.core.util.GameScheduler; +import com.sekwah.advancedportals.spigot.commands.subcommands.portal.UpdatePortalSubCommand; import com.sekwah.advancedportals.spigot.connector.command.SpigotCommandRegister; import com.sekwah.advancedportals.spigot.connector.container.SpigotServerContainer; import com.sekwah.advancedportals.spigot.metrics.Metrics; @@ -58,6 +59,8 @@ public class AdvancedPortalsPlugin extends JavaPlugin { // Try to do this after setting up everything that would need to be injected to. this.portalsCore.onEnable(); + this.portalsCore.registerPortalCommand("update", new UpdatePortalSubCommand()); + new Metrics(this); } diff --git a/spigot/src/main/java/com/sekwah/advancedportals/spigot/commands/subcommands/portal/UpdatePortalSubCommand.java b/spigot/src/main/java/com/sekwah/advancedportals/spigot/commands/subcommands/portal/UpdatePortalSubCommand.java new file mode 100644 index 0000000..b79419d --- /dev/null +++ b/spigot/src/main/java/com/sekwah/advancedportals/spigot/commands/subcommands/portal/UpdatePortalSubCommand.java @@ -0,0 +1,165 @@ +package com.sekwah.advancedportals.spigot.commands.subcommands.portal; + +import com.google.inject.Inject; +import com.sekwah.advancedportals.core.commands.SubCommand; +import com.sekwah.advancedportals.core.connector.containers.CommandSenderContainer; +import com.sekwah.advancedportals.core.destination.Destination; +import com.sekwah.advancedportals.core.portal.AdvancedPortal; +import com.sekwah.advancedportals.core.serializeddata.BlockLocation; +import com.sekwah.advancedportals.core.serializeddata.DataTag; +import com.sekwah.advancedportals.core.serializeddata.PlayerLocation; +import com.sekwah.advancedportals.core.services.DestinationServices; +import com.sekwah.advancedportals.core.services.PortalServices; +import com.sekwah.advancedportals.core.util.Lang; +import com.sekwah.advancedportals.spigot.AdvancedPortalsPlugin; +import com.sekwah.advancedportals.spigot.commands.subcommands.portal.update.ConfigAccessor; +import org.bukkit.configuration.ConfigurationSection; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +public class UpdatePortalSubCommand implements SubCommand { + + @Inject + PortalServices portalServices; + + @Inject + DestinationServices destinationServices; + + @Inject + PortalServices portalService; + + @Override + public void onCommand(CommandSenderContainer sender, String[] args) { + if(args.length > 1 && "confirm".equals(args[1])) { + sender.sendMessage(Lang.translate("messageprefix.positive") + Lang.translateInsertVariables("command.portal.update.confirm")); + int destinations = importDestinations(); + int portals = importPortals(); + sender.sendMessage(Lang.translate("messageprefix.positive") + Lang.translateInsertVariables("command.portal.update.complete", portals, destinations)); + return; + } + sender.sendMessage(Lang.translate("messageprefix.positive") + Lang.translateInsertVariables("command.portal.update", getPortalCount(), getDestinationCount())); + } + + private int importPortals() { + ConfigAccessor portalConfig = new ConfigAccessor(AdvancedPortalsPlugin.getInstance(), "portals.yml"); + var config = portalConfig.getConfig(); + Set portalSet = config.getKeys(false); + + int count = 0; + for(String portalName : portalSet) { + BlockLocation pos1 = new BlockLocation(config.getString(portalName + ".world"), + config.getInt(portalName + ".pos1.X"), + config.getInt(portalName + ".pos1.Y"), + config.getInt(portalName + ".pos1.Z")); + BlockLocation pos2 = new BlockLocation(config.getString(portalName + ".world"), + config.getInt(portalName + ".pos2.X"), + config.getInt(portalName + ".pos2.Y"), + config.getInt(portalName + ".pos2.Z")); + List args = new ArrayList<>(); + args.add(new DataTag("name", portalName)); + args.add(new DataTag("triggerblock", config.getString(portalName + ".triggerblock"))); + // It's called bungee as that's the implementation behind it + args.add(new DataTag("bungee", config.getString(portalName + ".bungee"))); + args.add(new DataTag("destination", config.getString(portalName + ".destination"))); + + ConfigurationSection portalConfigSection = config.getConfigurationSection(portalName); + ConfigurationSection portalArgsConf = portalConfigSection.getConfigurationSection("portalArgs"); + + if (portalArgsConf != null) { + Set argsSet = portalArgsConf.getKeys(true); + for (Object argName : argsSet.toArray()) { + // skip if it argName starts with command. + if (portalArgsConf.isString(argName.toString())) { + args.add(new DataTag(argName.toString(), portalArgsConf.getString(argName.toString()))); + } + } + } + // Check if command.1 is set + List commands = new ArrayList<>(); + if(getArg(args, "command.1") != null) { + int i = 1; + while(getArg(args, "command." + i) != null) { + commands.add(getArg(args, "command." + i)); + i++; + } + } + if(!commands.isEmpty()) { + args.add(new DataTag("commands", commands.toArray(new String[0]))); + } + args.stream().filter(dataTag -> dataTag.NAME.startsWith("command.")).toList().forEach(args::remove); + + var portal = portalService.createPortal(pos1, pos2, args); + + if(portal != null) count++; + } + + return count; + } + + public String getArg(List tags, String arg) { + for (DataTag portalArg : tags) { + if (arg.equals(portalArg.NAME)) { + return portalArg.VALUES[0]; + } + } + return null; + } + + public int importDestinations() { + ConfigAccessor destiConfig = new ConfigAccessor(AdvancedPortalsPlugin.getInstance(), "destinations.yml"); + var config = destiConfig.getConfig(); + Set destiSet = config.getKeys(false); + + int count = 0; + for(String destiName : destiSet) { + var desti = destinationServices.createDesti(new PlayerLocation(config.getString(destiName + ".world"), + config.getDouble(destiName + ".x"), + config.getDouble(destiName + ".y"), + config.getDouble(destiName + ".z"), + (float) config.getDouble(destiName + ".yaw"), + (float) config.getDouble(destiName + ".pitch")), List.of(new DataTag("name", destiName))); + if(desti != null) count++; + } + return count; + } + + public int getDestinationCount() { + ConfigAccessor destiConfig = new ConfigAccessor(AdvancedPortalsPlugin.getInstance(), "destinations.yml"); + var config = destiConfig.getConfig(); + Set destiSet = config.getKeys(false); + + return destiSet.size(); + } + + public int getPortalCount() { + ConfigAccessor portalConfig = new ConfigAccessor(AdvancedPortalsPlugin.getInstance(), "portals.yml"); + var config = portalConfig.getConfig(); + Set portalSet = config.getKeys(false); + + return portalSet.size(); + } + + @Override + public boolean hasPermission(CommandSenderContainer sender) { + return true; + } + + @Override + public List onTabComplete(CommandSenderContainer sender, String[] args) { + return null; + } + + @Override + public String getBasicHelpText() { + return Lang.translate("command.portal.update.help"); + } + + @Override + public String getDetailedHelpText() { + return Lang.translate("command.portal.update.detailedhelp"); + } +} diff --git a/spigot/src/main/java/com/sekwah/advancedportals/spigot/commands/subcommands/portal/update/ConfigAccessor.java b/spigot/src/main/java/com/sekwah/advancedportals/spigot/commands/subcommands/portal/update/ConfigAccessor.java new file mode 100644 index 0000000..0379eb7 --- /dev/null +++ b/spigot/src/main/java/com/sekwah/advancedportals/spigot/commands/subcommands/portal/update/ConfigAccessor.java @@ -0,0 +1,76 @@ +package com.sekwah.advancedportals.spigot.commands.subcommands.portal.update; + +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.plugin.java.JavaPlugin; + +import java.io.File; +import java.io.IOException; +import java.util.logging.Level; + +public class ConfigAccessor { + + private final String fileName; + private final JavaPlugin plugin; + + private File configFile; + private FileConfiguration fileConfiguration; + + public ConfigAccessor(JavaPlugin plugin, String fileName) { + this.plugin = plugin; + this.fileName = fileName; + } + + // gets all of the + public void reloadConfig() { + if (configFile == null) { + File dataFolder = plugin.getDataFolder(); + if (dataFolder == null) + throw new IllegalStateException(); + configFile = new File(dataFolder, fileName); + } + fileConfiguration = YamlConfiguration.loadConfiguration(configFile); + } + + public FileConfiguration getConfig() { + if (fileConfiguration == null) { + this.reloadConfig(); + } + return fileConfiguration; + } + + // Saves all the data to the selected yml file + public void saveConfig() { + if (fileConfiguration == null || configFile == null) { + return; + } else { + try { + getConfig().save(configFile); + } catch (IOException ex) { + plugin.getLogger().log(Level.SEVERE, "Could not save config to " + configFile, ex); + } + } + } + + // Saves + + /** + * public void saveDefaultConfig() { + * if (!configFile.exists()) { + * this.plugin.saveResource(fileName, false); + * } + * } + */ + + // New save default config saving code, it checks if the needed config is in the jar file before + // overriding it. + public void saveDefaultConfig() { + if (configFile == null) { + configFile = new File(plugin.getDataFolder(), fileName); + } + if (!configFile.exists()) { + plugin.saveResource(fileName, false); + } + } + +}