14 Commits

Author SHA1 Message Date
3db630f60e Updates version and changelog
Some checks failed
EpicKnarvik97/Stargate/pipeline/head There was a failure building this commit
2021-11-09 22:51:11 +01:00
7a03f49fb1 Translates the & character to make sure portal signs are colored on all servers 2021-11-09 22:47:38 +01:00
1c2cad2ec1 Updates version to 0.9.1.0, updates README and adds a permission for changing config values
Adds the stargate.admin.config permission, which is required to use /sg config
2021-11-09 21:16:53 +01:00
b4d908eaa0 Improves tab completion for Stargate commands by taking into account typed text
Sends tab completion for the config command to the config tab completer
2021-11-09 20:58:55 +01:00
8546fd4f78 Fully implements the config command 2021-11-09 20:57:06 +01:00
05328fc456 Adds a tab completer for the config sub-command 2021-11-09 20:56:43 +01:00
aba70b669e Adds a method to be able to read config options 2021-11-09 18:21:25 +01:00
d5f4b87e9b Changes how config values are loaded by using the ConfigOption class 2021-11-09 15:40:10 +01:00
85edaa4657 Adds a new class to represent a data type usable by configs 2021-11-09 15:38:42 +01:00
7c501cefe8 Gives all config options data types to make loading config values work properly 2021-11-09 15:38:10 +01:00
6466c7b0ff Adds the config command to the stargate auto completer
Some checks failed
EpicKnarvik97/Stargate/pipeline/head There was a failure building this commit
Additionally makes the reload command only auto-complete if the command sender can use it
2021-11-09 02:04:59 +01:00
37cf75ada1 Adds the config command as a child to the Stargate command 2021-11-09 02:01:58 +01:00
1ca2d36f5f Adds an unfinished implementation of the config command, which is only able to display config options for now 2021-11-09 02:01:11 +01:00
01b2907b01 Adds an enum containing information about all config options 2021-11-09 01:59:54 +01:00
13 changed files with 690 additions and 99 deletions

View File

@ -14,6 +14,7 @@ can share a network or be split into clusters; they can be hidden on a network o
- Underwater portals -- portals can be placed underwater as long as a waterproof button is used
- API available -- using the API, a lot of behavior can be changed
- Button customization -- a large amount of materials usable as buttons (buttons, wall corals, shulkers, chests)
- Config commands -- All main config values can be changed from the commandline
## Background
@ -80,11 +81,12 @@ stargate.free -- Allow free use/creation/destruction of Stargates
stargate.free.create -- Allow free creation of Stargates
stargate.free.destroy -- Allow free destruction of Stargates
stargate.admin -- Allow all admin features (Hidden/Private only so far)
stargate.admin -- Allow all admin features (Hidden/Private bypass, BungeeCord, Reload, Config)
stargate.admin.private -- Allow use of Private gates not owned by user
stargate.admin.hidden -- Allow access to Hidden gates not ownerd by user
stargate.admin.bungee -- Allow the creation of BungeeCord stargates (U option)
stargate.admin.reload -- Allow use of the reload command
stargate.admin.config -- Allows the player to change config values from the chat
```
## Default Permissions
@ -386,6 +388,16 @@ portalInfoServer=Server: %server%
# Changes
#### \[Version 0.9.1.1] EpicKnarvik97 fork
- Makes sure to translate the `&` character to fix a bug causing portal signs to not be colored on some servers
#### \[Version 0.9.1.0] EpicKnarvik97 fork
- Rewrites config loading as a part of the changes required to implement config commands
- This update adds commands to change all config values from the chat or the console, complete with tab completion
- Adds a new permission "stargate.admin.config" which is required to edit config values from the chat
#### \[Version 0.9.0.7] EpicKnarvik97 fork
- Stops registering the sign as a lookup block for stargates without a sign

View File

@ -4,7 +4,7 @@
<groupId>net.knarcraft</groupId>
<artifactId>Stargate</artifactId>
<version>0.9.0.7</version>
<version>0.9.1.1</version>
<licenses>
<license>

View File

@ -0,0 +1,144 @@
package net.knarcraft.stargate.command;
import net.knarcraft.stargate.Stargate;
import net.knarcraft.stargate.config.ConfigOption;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
/**
* This command represents the config command for changing config values
*/
public class CommandConfig implements CommandExecutor {
@Override
public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s,
@NotNull String[] args) {
if (commandSender instanceof Player player) {
if (!player.hasPermission("stargate.admin.config")) {
Stargate.getMessageSender().sendErrorMessage(commandSender, "Permission Denied");
return true;
}
}
if (args.length > 0) {
ConfigOption selectedOption = ConfigOption.getByName(args[0]);
if (selectedOption == null) {
return false;
}
if (args.length > 1) {
updateConfigValue(selectedOption, commandSender, args[1]);
} else {
//Display info and the current value of the given config value
printConfigOptionValue(commandSender, selectedOption);
}
return true;
} else {
//Display all config options
displayConfigValues(commandSender);
}
return true;
}
/**
* Updates a config value
*
* @param selectedOption <p>The option which should be updated</p>
* @param commandSender <p>The command sender that changed the value</p>
* @param value <p>The new value of the config option</p>
*/
private void updateConfigValue(ConfigOption selectedOption, CommandSender commandSender, String value) {
FileConfiguration configuration = Stargate.getInstance().getConfig();
//Validate any sign colors
if (selectedOption == ConfigOption.MAIN_SIGN_COLOR || selectedOption == ConfigOption.HIGHLIGHT_SIGN_COLOR) {
try {
ChatColor.valueOf(value.toUpperCase());
} catch (IllegalArgumentException | NullPointerException ignored) {
commandSender.sendMessage(ChatColor.RED + "Invalid color given");
return;
}
}
//Store the config values, accounting for the data type
switch (selectedOption.getDataType()) {
case BOOLEAN -> configuration.set(selectedOption.getConfigNode(), Boolean.parseBoolean(value));
case INTEGER -> {
try {
configuration.set(selectedOption.getConfigNode(), Integer.parseInt(value));
} catch (NumberFormatException exception) {
commandSender.sendMessage(ChatColor.RED + "Invalid number given");
return;
}
}
case STRING -> {
if (selectedOption == ConfigOption.GATE_FOLDER || selectedOption == ConfigOption.PORTAL_FOLDER ||
selectedOption == ConfigOption.DEFAULT_GATE_NETWORK) {
if (value.contains("../") || value.contains("..\\")) {
commandSender.sendMessage(ChatColor.RED + "Path traversal characters cannot be used");
return;
}
}
configuration.set(selectedOption.getConfigNode(), value);
}
default -> configuration.set(selectedOption.getConfigNode(), value);
}
//Save the config file and reload if necessary
Stargate.getInstance().saveConfig();
reloadIfNecessary(commandSender);
}
/**
* Reloads the config if necessary
*
* @param commandSender <p>The command sender initiating the reload</p>
*/
private void reloadIfNecessary(CommandSender commandSender) {
//TODO: Only update the config values which have changed and do the least amount of work necessary to load the
// changes. Only do a full reload if absolutely necessary, or when the partial reloading would be as
// inefficient as a full reload.
Stargate.getStargateConfig().reload(commandSender);
}
/**
* Prints information about a config option and its current value
*
* @param sender <p>The command sender that sent the command</p>
* @param option <p>The config option to print information about</p>
*/
private void printConfigOptionValue(CommandSender sender, ConfigOption option) {
Object value = Stargate.getStargateConfig().getConfigOptions().get(option);
sender.sendMessage(getOptionDescription(option));
sender.sendMessage(ChatColor.GREEN + "Current value: " + ChatColor.GOLD + value);
}
/**
* Displays the name and a small description of every config value
*
* @param sender <p>The command sender to display the config list to</p>
*/
private void displayConfigValues(CommandSender sender) {
sender.sendMessage(ChatColor.GREEN + Stargate.getBackupString("prefix") + ChatColor.GOLD +
"Config values:");
for (ConfigOption option : ConfigOption.values()) {
sender.sendMessage(getOptionDescription(option));
}
}
/**
* Gets the description of a single config option
*
* @param option <p>The option to describe</p>
* @return <p>A string describing the config option</p>
*/
private String getOptionDescription(ConfigOption option) {
return ChatColor.GOLD + option.getName() + ChatColor.WHITE + " - " + ChatColor.GREEN + option.getDescription() +
ChatColor.DARK_GRAY + " (Default: " + ChatColor.GRAY + option.getDefaultValue() + ChatColor.DARK_GRAY + ")";
}
}

View File

@ -1,6 +1,7 @@
package net.knarcraft.stargate.command;
import net.knarcraft.stargate.Stargate;
import org.apache.commons.lang.ArrayUtils;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
@ -23,6 +24,9 @@ public class CommandStarGate implements CommandExecutor {
return new CommandAbout().onCommand(commandSender, command, s, args);
} else if (args[0].equalsIgnoreCase("reload")) {
return new CommandReload().onCommand(commandSender, command, s, args);
} else if (args[0].equalsIgnoreCase("config")) {
String[] subArgs = (String[]) ArrayUtils.remove(args, 0);
return new CommandConfig().onCommand(commandSender, command, s, subArgs);
}
return false;
} else {

View File

@ -0,0 +1,182 @@
package net.knarcraft.stargate.command;
import net.knarcraft.stargate.config.ConfigOption;
import net.knarcraft.stargate.config.OptionDataType;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
/**
* This is the completer for stargates config sub-command (/sg config)
*/
public class ConfigTabCompleter implements TabCompleter {
@Nullable
@Override
public List<String> onTabComplete(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s,
@NotNull String[] args) {
if (args.length > 1) {
ConfigOption selectedOption = ConfigOption.getByName(args[0]);
if (selectedOption == null) {
return new ArrayList<>();
} else {
return getPossibleOptionValues(selectedOption, args[1]);
}
} else {
List<String> configOptionNames = new ArrayList<>();
for (ConfigOption option : ConfigOption.values()) {
configOptionNames.add(option.getName());
}
return filterMatching(configOptionNames, args[0]);
}
}
/**
* Find completable strings which match the text typed by the command's sender
*
* @param values <p>The values to filter</p>
* @param typedText <p>The text the player has started typing</p>
* @return <p>The given string values which start with the player's typed text</p>
*/
private List<String> filterMatching(List<String> values, String typedText) {
List<String> configValues = new ArrayList<>();
for (String value : values) {
if (value.toLowerCase().startsWith(typedText.toLowerCase())) {
configValues.add(value);
}
}
return configValues;
}
/**
* Get possible values for the selected option
*
* @param selectedOption <p>The selected option</p>
* @param typedText <p>The beginning of the typed text, for filtering matching results</p>
* @return <p>Some or all of the valid values for the option</p>
*/
private List<String> getPossibleOptionValues(ConfigOption selectedOption, String typedText) {
List<String> booleans = new ArrayList<>();
booleans.add("true");
booleans.add("false");
List<String> numbers = new ArrayList<>();
numbers.add("0");
numbers.add("5");
switch (selectedOption) {
case LANGUAGE:
//Return available languages
return filterMatching(getLanguages(), typedText);
case GATE_FOLDER:
case PORTAL_FOLDER:
case DEFAULT_GATE_NETWORK:
//Just return the default value as most values should be possible
if (typedText.trim().isEmpty()) {
return putStringInList((String) selectedOption.getDefaultValue());
} else {
return new ArrayList<>();
}
case MAIN_SIGN_COLOR:
case HIGHLIGHT_SIGN_COLOR:
//Return all colors
return filterMatching(getColors(), typedText);
}
//If the config value is a boolean, show the two boolean values
if (selectedOption.getDataType() == OptionDataType.BOOLEAN) {
return filterMatching(booleans, typedText);
}
//If the config value is an integer, display some valid numbers
if (selectedOption.getDataType() == OptionDataType.INTEGER) {
if (typedText.trim().isEmpty()) {
return numbers;
} else {
return new ArrayList<>();
}
}
return null;
}
/**
* Gets all available languages
*
* @return <p>The available languages</p>
*/
private List<String> getLanguages() {
List<String> languages = new ArrayList<>();
languages.add("de");
languages.add("en");
languages.add("es");
languages.add("fr");
languages.add("hu");
languages.add("it");
languages.add("nb-no");
languages.add("nl");
languages.add("nn-no");
languages.add("pt-br");
languages.add("ru");
return languages;
}
/**
* Gets all available colors
*
* @return <p>All available colors</p>
*/
private List<String> getColors() {
List<String> colors = new ArrayList<>();
for (ChatColor color : getChatColors()) {
colors.add(color.name());
}
return colors;
}
/**
* Gets a list of all available chat colors
*
* @return <p>A list of chat colors</p>
*/
private List<ChatColor> getChatColors() {
List<ChatColor> chatColors = new ArrayList<>();
chatColors.add(ChatColor.WHITE);
chatColors.add(ChatColor.BLUE);
chatColors.add(ChatColor.DARK_BLUE);
chatColors.add(ChatColor.DARK_PURPLE);
chatColors.add(ChatColor.LIGHT_PURPLE);
chatColors.add(ChatColor.GOLD);
chatColors.add(ChatColor.GREEN);
chatColors.add(ChatColor.BLACK);
chatColors.add(ChatColor.DARK_GREEN);
chatColors.add(ChatColor.DARK_RED);
chatColors.add(ChatColor.RED);
chatColors.add(ChatColor.AQUA);
chatColors.add(ChatColor.DARK_AQUA);
chatColors.add(ChatColor.DARK_GRAY);
chatColors.add(ChatColor.GRAY);
chatColors.add(ChatColor.YELLOW);
return chatColors;
}
/**
* Puts a single string value into a string list
*
* @param value <p>The string to make into a list</p>
* @return <p>A list containing the string value</p>
*/
private List<String> putStringInList(String value) {
List<String> list = new ArrayList<>();
list.add(value);
return list;
}
}

View File

@ -1,8 +1,10 @@
package net.knarcraft.stargate.command;
import org.apache.commons.lang.ArrayUtils;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -17,15 +19,39 @@ public class StarGateTabCompleter implements TabCompleter {
@Override
public @Nullable List<String> onTabComplete(@NotNull CommandSender commandSender, @NotNull Command command,
@NotNull String s, @NotNull String[] args) {
List<String> commands = new ArrayList<>();
commands.add("about");
commands.add("reload");
if (args.length == 1) {
return commands;
List<String> commands = getAvailableCommands(commandSender);
List<String> matchingCommands = new ArrayList<>();
for (String availableCommand : commands) {
if (availableCommand.startsWith(args[0])) {
matchingCommands.add(availableCommand);
}
}
return matchingCommands;
} else if (args.length > 1 && args[0].equalsIgnoreCase("config")) {
String[] subArgs = (String[]) ArrayUtils.remove(args, 0);
return new ConfigTabCompleter().onTabComplete(commandSender, command, s, subArgs);
} else {
return new ArrayList<>();
}
}
/**
* Gets the available commands
*
* @param commandSender <p>The command sender to get available commands for</p>
* @return <p>The commands available to the command sender</p>
*/
private List<String> getAvailableCommands(CommandSender commandSender) {
List<String> commands = new ArrayList<>();
commands.add("about");
if (!(commandSender instanceof Player player) || player.hasPermission("stargate.admin.reload")) {
commands.add("reload");
}
if (!(commandSender instanceof Player player) || player.hasPermission("stargate.admin.config")) {
commands.add("config");
}
return commands;
}
}

View File

@ -0,0 +1,187 @@
package net.knarcraft.stargate.config;
/**
* A ConfigOption represents one of the available config options
*/
public enum ConfigOption {
/**
* The language used for player-interface text
*/
LANGUAGE("language", "The language used for all signs and all messages to players", "en"),
/**
* The folder for portal files
*/
PORTAL_FOLDER("folders.portalFolder", "The folder containing the portal databases", "plugins/Stargate/portals/"),
/**
* The folder for gate files
*/
GATE_FOLDER("folders.gateFolder", "The folder containing all gate files", "plugins/Stargate/gates/"),
/**
* The max number of portals on a single network
*/
MAX_GATES_EACH_NETWORK("gates.maxGatesEachNetwork", "The max number of stargates in a single network", 0),
/**
* The network used if not specified
*/
DEFAULT_GATE_NETWORK("gates.defaultGateNetwork", "The network used when no network is specified", "central"),
/**
* Whether to remember the lastly used destination
*/
REMEMBER_DESTINATION("gates.cosmetic.rememberDestination", "Whether to remember the last destination used", false),
/**
* Whether to sort the network destinations
*/
SORT_NETWORK_DESTINATIONS("gates.cosmetic.sortNetworkDestinations", "Whether to sort destinations by name", false),
/**
* The main color to use for all signs
*/
MAIN_SIGN_COLOR("gates.cosmetic.mainSignColor", "The main text color of all stargate signs", "BLACK"),
/**
* The color to use for highlighting sign text
*/
HIGHLIGHT_SIGN_COLOR("gates.cosmetic.highlightSignColor", "The text color used for highlighting stargate signs", "WHITE"),
/**
* Whether to destroy portals when any blocks are broken by explosions
*/
DESTROYED_BY_EXPLOSION("gates.integrity.destroyedByExplosion", "Whether stargates should be destroyed by explosions", false),
/**
* Whether to verify each portal's gate layout after each load
*/
VERIFY_PORTALS("gates.integrity.verifyPortals", "Whether to verify that portals match their gate layout on load", false),
/**
* Whether to protect the entrance of portals
*/
PROTECT_ENTRANCE("gates.integrity.protectEntrance", "Whether to protect stargates' entrances", false),
/**
* Whether to enable BungeeCord support
*/
ENABLE_BUNGEE("gates.functionality.enableBungee", "Whether to enable BungeeCord support", false),
/**
* Whether to enable vehicle teleportation
*/
HANDLE_VEHICLES("gates.functionality.handleVehicles", "Whether to enable vehicle teleportation", true),
/**
* Whether to enable teleportation of empty vehicles
*/
HANDLE_EMPTY_VEHICLES("gates.functionality.handleEmptyVehicles", "Whether to enable teleportation of empty vehicles", true),
/**
* Whether to enable teleportation of creatures using vehicles
*/
HANDLE_CREATURE_TRANSPORTATION("gates.functionality.handleCreatureTransportation",
"Whether to enable teleportation of vehicles containing non-player creatures", true),
/**
* Whether to allow creatures to teleport alone, bypassing any access restrictions
*/
HANDLE_NON_PLAYER_VEHICLES("gates.functionality.handleNonPlayerVehicles",
"Whether to enable teleportation of non-empty vehicles without a player", true),
/**
* Whether to enable teleportations of creatures on a leash
*/
HANDLE_LEASHED_CREATURES("gates.functionality.handleLeashedCreatures",
"Whether to enable players to teleport a creature on a leash", true),
USE_ECONOMY("economy.useEconomy", "Whether to use economy to incur fees when stargates are used, created or destroyed", false),
CREATE_COST("economy.createCost", "The cost of creating a new stargate", 0),
DESTROY_COST("economy.destroyCost", "The cost of destroying a stargate. Negative to refund", 0),
USE_COST("economy.useCost", "The cost of using (teleporting through) a stargate", 0),
TO_OWNER("economy.toOwner", "Whether any teleportation fees should go to the owner of the used stargate", false),
CHARGE_FREE_DESTINATION("economy.chargeFreeDestination",
"Whether to require payment if the destination is free, but the entrance stargate is not", true),
FREE_GATES_GREEN("economy.freeGatesGreen", "Whether to use green coloring to mark all free stargates", false),
DEBUG("debugging.debug", "Whether to enable debugging output", false),
PERMISSION_DEBUG("debugging.permissionDebug", "Whether to enable permission debugging output", false);
private final String configNode;
private final String description;
private final Object defaultValue;
private final OptionDataType dataType;
/**
* Instantiates a new config option
*
* @param configNode <p>The full path of this config option's config node</p>
* @param description <p>The description of what this config option does</p>
* @param defaultValue <p>The default value of this config option</p>
*/
ConfigOption(String configNode, String description, Object defaultValue) {
this.configNode = configNode;
this.description = description;
this.defaultValue = defaultValue;
if (defaultValue instanceof String) {
this.dataType = OptionDataType.STRING;
} else if (defaultValue instanceof Boolean) {
this.dataType = OptionDataType.BOOLEAN;
} else if (defaultValue instanceof Integer) {
this.dataType = OptionDataType.INTEGER;
} else {
throw new IllegalArgumentException("Unknown config data type encountered.");
}
}
/**
* Gets a config option given its name
*
* @param name <p>The name of the config option to get</p>
* @return <p>The corresponding config option, or null if the name is invalid</p>
*/
public static ConfigOption getByName(String name) {
for (ConfigOption option : ConfigOption.values()) {
if (option.getName().equalsIgnoreCase(name)) {
return option;
}
}
return null;
}
/**
* Gets the name of this config option
*
* @return <p>The name of this config option</p>
*/
public String getName() {
if (!this.configNode.contains(".")) {
return this.configNode;
}
String[] pathParts = this.configNode.split("\\.");
return pathParts[pathParts.length - 1];
}
/**
* Gets the data type used for storing this config option
*
* @return <p>The data type used</p>
*/
public OptionDataType getDataType() {
return this.dataType;
}
/**
* Gets the config node of this config option
*
* @return <p>This config option's config node</p>
*/
public String getConfigNode() {
return this.configNode;
}
/**
* Gets the description of what this config option does
*
* @return <p>The description of this config option</p>
*/
public String getDescription() {
return this.description;
}
/**
* Gets this config option's default value
*
* @return <p>This config option's default value</p>
*/
public Object getDefaultValue() {
return this.defaultValue;
}
}

View File

@ -6,13 +6,13 @@ import net.knarcraft.stargate.portal.property.gate.Gate;
import net.knarcraft.stargate.utility.PermissionHelper;
import net.milkbowl.vault.economy.Economy;
import org.bukkit.Bukkit;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.RegisteredServiceProvider;
import org.bukkit.plugin.ServicesManager;
import java.util.Map;
import java.util.UUID;
/**
@ -33,10 +33,10 @@ public final class EconomyConfig {
/**
* Instantiates a new economy config
*
* @param newConfig <p>The file configuration to read values from</p>
* @param configOptions <p>The loaded config options to read</p>
*/
public EconomyConfig(FileConfiguration newConfig) {
loadEconomyConfig(newConfig);
public EconomyConfig(Map<ConfigOption, Object> configOptions) {
loadEconomyConfig(configOptions);
}
/**
@ -332,16 +332,16 @@ public final class EconomyConfig {
/**
* Loads all config values related to economy
*
* @param newConfig <p>The configuration containing the values to read</p>
* @param configOptions <p>The loaded config options to get values from</p>
*/
private void loadEconomyConfig(FileConfiguration newConfig) {
economyEnabled = newConfig.getBoolean("economy.useEconomy");
setDefaultCreateCost(newConfig.getInt("economy.createCost"));
setDefaultDestroyCost(newConfig.getInt("economy.destroyCost"));
setDefaultUseCost(newConfig.getInt("economy.useCost"));
toOwner = newConfig.getBoolean("economy.toOwner");
chargeFreeDestination = newConfig.getBoolean("economy.chargeFreeDestination");
freeGatesGreen = newConfig.getBoolean("economy.freeGatesGreen");
private void loadEconomyConfig(Map<ConfigOption, Object> configOptions) {
economyEnabled = (boolean) configOptions.get(ConfigOption.USE_ECONOMY);
setDefaultCreateCost((Integer) configOptions.get(ConfigOption.CREATE_COST));
setDefaultDestroyCost((Integer) configOptions.get(ConfigOption.DESTROY_COST));
setDefaultUseCost((Integer) configOptions.get(ConfigOption.USE_COST));
toOwner = (boolean) configOptions.get(ConfigOption.TO_OWNER);
chargeFreeDestination = (boolean) configOptions.get(ConfigOption.CHARGE_FREE_DESTINATION);
freeGatesGreen = (boolean) configOptions.get(ConfigOption.FREE_GATES_GREEN);
}
/**

View File

@ -0,0 +1,21 @@
package net.knarcraft.stargate.config;
/**
* An enum defining the different data types an option can have
*/
public enum OptionDataType {
/**
* The data type for the option is a String
*/
STRING,
/**
* The data type for the option is a Boolean
*/
BOOLEAN,
/**
* The data type for the option is an Integer
*/
INTEGER
}

View File

@ -18,6 +18,7 @@ import org.bukkit.plugin.messaging.Messenger;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Queue;
@ -47,6 +48,7 @@ public final class StargateConfig {
private boolean debuggingEnabled = false;
private boolean permissionDebuggingEnabled = false;
private final Map<ConfigOption, Object> configOptions;
/**
* Instantiates a new stargate config
@ -55,6 +57,7 @@ public final class StargateConfig {
*/
public StargateConfig(Logger logger) {
this.logger = logger;
configOptions = new HashMap<>();
dataFolderPath = Stargate.getInstance().getDataFolder().getPath().replaceAll("\\\\", "/");
portalFolder = dataFolderPath + "/portals/";
@ -90,6 +93,15 @@ public final class StargateConfig {
setupVaultEconomy();
}
/**
* Gets a copy of all loaded config options with its values
*
* @return <p>The loaded config options</p>
*/
public Map<ConfigOption, Object> getConfigOptions() {
return new HashMap<>(configOptions);
}
/**
* Gets the queue of open portals
*
@ -307,16 +319,34 @@ public final class StargateConfig {
//Copy missing default values if any values are missing
newConfig.options().copyDefaults(true);
//Load all options
for (ConfigOption option : ConfigOption.values()) {
Object optionValue;
String configNode = option.getConfigNode();
//Load the option using its correct data type
switch (option.getDataType()) {
case STRING -> {
String value = newConfig.getString(configNode);
optionValue = value != null ? value.trim() : "";
}
case BOOLEAN -> optionValue = newConfig.getBoolean(configNode);
case INTEGER -> optionValue = newConfig.getInt(configNode);
default -> throw new IllegalArgumentException("Invalid config data type encountered");
}
configOptions.put(option, optionValue);
}
//Get the language name from the config
languageName = newConfig.getString("language");
languageName = (String) configOptions.get(ConfigOption.LANGUAGE);
//Get important folders from the config
portalFolder = newConfig.getString("folders.portalFolder");
gateFolder = newConfig.getString("folders.gateFolder");
portalFolder = (String) configOptions.get(ConfigOption.PORTAL_FOLDER);
gateFolder = (String) configOptions.get(ConfigOption.GATE_FOLDER);
//Get enabled debug settings from the config
debuggingEnabled = newConfig.getBoolean("debugging.debug");
permissionDebuggingEnabled = newConfig.getBoolean("debugging.permissionDebug");
debuggingEnabled = (boolean) configOptions.get(ConfigOption.DEBUG);
permissionDebuggingEnabled = (boolean) configOptions.get(ConfigOption.PERMISSION_DEBUG);
//If users have an outdated config, assume they also need to update their default gates
if (isMigrating) {
@ -324,10 +354,10 @@ public final class StargateConfig {
}
//Load all gate config values
stargateGateConfig = new StargateGateConfig(newConfig);
stargateGateConfig = new StargateGateConfig(configOptions);
//Load all economy config values
economyConfig = new EconomyConfig(newConfig);
economyConfig = new EconomyConfig(configOptions);
Stargate.getInstance().saveConfig();
}

View File

@ -3,36 +3,25 @@ package net.knarcraft.stargate.config;
import net.knarcraft.stargate.Stargate;
import net.knarcraft.stargate.portal.PortalSignDrawer;
import org.bukkit.ChatColor;
import org.bukkit.configuration.file.FileConfiguration;
import java.util.Map;
/**
* The Stargate gate config keeps track of all global config values related to gates
*/
public final class StargateGateConfig {
private int maxGatesEachNetwork = 0;
private boolean rememberDestination = false;
private boolean handleVehicles = true;
private boolean handleEmptyVehicles = true;
private boolean handleCreatureTransportation = true;
private boolean handleNonPlayerVehicles = true;
private boolean handleLeashedCreatures = true;
private boolean sortNetworkDestinations = false;
private boolean protectEntrance = false;
private boolean enableBungee = true;
private boolean verifyPortals = true;
private boolean destroyExplosion = false;
private String defaultGateNetwork = "central";
private static final int activeTime = 10;
private static final int openTime = 10;
private final Map<ConfigOption, Object> configOptions;
/**
* Instantiates a new stargate config
*
* @param newConfig <p>The file configuration to read values from</p>
* @param configOptions <p>The loaded config options to use</p>
*/
public StargateGateConfig(FileConfiguration newConfig) {
loadGateConfig(newConfig);
public StargateGateConfig(Map<ConfigOption, Object> configOptions) {
this.configOptions = configOptions;
loadGateConfig();
}
/**
@ -59,7 +48,7 @@ public final class StargateGateConfig {
* @return <p>Maximum number of gates for each network</p>
*/
public int maxGatesEachNetwork() {
return maxGatesEachNetwork;
return (int) configOptions.get(ConfigOption.MAX_GATES_EACH_NETWORK);
}
/**
@ -68,7 +57,7 @@ public final class StargateGateConfig {
* @return <p>Whether a portal's lastly used destination should be remembered</p>
*/
public boolean rememberDestination() {
return rememberDestination;
return (boolean) configOptions.get(ConfigOption.REMEMBER_DESTINATION);
}
/**
@ -77,7 +66,7 @@ public final class StargateGateConfig {
* @return <p>Whether vehicle teleportation should be handled</p>
*/
public boolean handleVehicles() {
return handleVehicles;
return (boolean) configOptions.get(ConfigOption.HANDLE_VEHICLES);
}
/**
@ -89,7 +78,7 @@ public final class StargateGateConfig {
* @return <p>Whether vehicles without passengers should be handled</p>
*/
public boolean handleEmptyVehicles() {
return handleEmptyVehicles;
return (boolean) configOptions.get(ConfigOption.HANDLE_EMPTY_VEHICLES);
}
/**
@ -101,7 +90,7 @@ public final class StargateGateConfig {
* @return <p>Whether vehicles with creatures should be handled</p>
*/
public boolean handleCreatureTransportation() {
return handleCreatureTransportation;
return (boolean) configOptions.get(ConfigOption.HANDLE_CREATURE_TRANSPORTATION);
}
/**
@ -118,7 +107,7 @@ public final class StargateGateConfig {
* @return <p>Whether non-empty vehicles without a player should be handled</p>
*/
public boolean handleNonPlayerVehicles() {
return handleNonPlayerVehicles;
return (boolean) configOptions.get(ConfigOption.HANDLE_NON_PLAYER_VEHICLES);
}
/**
@ -127,7 +116,7 @@ public final class StargateGateConfig {
* @return <p>Whether leashed creatures should be handled</p>
*/
public boolean handleLeashedCreatures() {
return handleLeashedCreatures;
return (boolean) configOptions.get(ConfigOption.HANDLE_LEASHED_CREATURES);
}
/**
@ -136,7 +125,7 @@ public final class StargateGateConfig {
* @return <p>Whether network destinations should be sorted</p>
*/
public boolean sortNetworkDestinations() {
return sortNetworkDestinations;
return (boolean) configOptions.get(ConfigOption.SORT_NETWORK_DESTINATIONS);
}
/**
@ -145,7 +134,7 @@ public final class StargateGateConfig {
* @return <p>Whether portal entrances should be protected</p>
*/
public boolean protectEntrance() {
return protectEntrance;
return (boolean) configOptions.get(ConfigOption.PROTECT_ENTRANCE);
}
/**
@ -154,7 +143,7 @@ public final class StargateGateConfig {
* @return <p>Whether bungee support is enabled</p>
*/
public boolean enableBungee() {
return enableBungee;
return (boolean) configOptions.get(ConfigOption.ENABLE_BUNGEE);
}
/**
@ -163,7 +152,7 @@ public final class StargateGateConfig {
* @return <p>Whether portals need to be verified</p>
*/
public boolean verifyPortals() {
return verifyPortals;
return (boolean) configOptions.get(ConfigOption.VERIFY_PORTALS);
}
/**
@ -172,7 +161,7 @@ public final class StargateGateConfig {
* @return <p>Whether portals should be destroyed by explosions</p>
*/
public boolean destroyedByExplosion() {
return destroyExplosion;
return (boolean) configOptions.get(ConfigOption.DESTROYED_BY_EXPLOSION);
}
/**
@ -181,37 +170,16 @@ public final class StargateGateConfig {
* @return <p>The default portal network</p>
*/
public String getDefaultPortalNetwork() {
return defaultGateNetwork;
return (String) configOptions.get(ConfigOption.DEFAULT_GATE_NETWORK);
}
/**
* Loads all config values related to gates
*
* @param newConfig <p>The configuration containing the values to read</p>
*/
private void loadGateConfig(FileConfiguration newConfig) {
String defaultNetwork = newConfig.getString("gates.defaultGateNetwork");
defaultGateNetwork = defaultNetwork != null ? defaultNetwork.trim() : null;
maxGatesEachNetwork = newConfig.getInt("gates.maxGatesEachNetwork");
//Functionality
handleVehicles = newConfig.getBoolean("gates.functionality.handleVehicles");
handleEmptyVehicles = newConfig.getBoolean("gates.functionality.handleEmptyVehicles");
handleCreatureTransportation = newConfig.getBoolean("gates.functionality.handleCreatureTransportation");
handleNonPlayerVehicles = newConfig.getBoolean("gates.functionality.handleNonPlayerVehicles");
handleLeashedCreatures = newConfig.getBoolean("gates.functionality.handleLeashedCreatures");
enableBungee = newConfig.getBoolean("gates.functionality.enableBungee");
//Integrity
protectEntrance = newConfig.getBoolean("gates.integrity.protectEntrance");
verifyPortals = newConfig.getBoolean("gates.integrity.verifyPortals");
destroyExplosion = newConfig.getBoolean("gates.integrity.destroyedByExplosion");
//Cosmetic
sortNetworkDestinations = newConfig.getBoolean("gates.cosmetic.sortNetworkDestinations");
rememberDestination = newConfig.getBoolean("gates.cosmetic.rememberDestination");
loadSignColor(newConfig.getString("gates.cosmetic.mainSignColor"),
newConfig.getString("gates.cosmetic.highlightSignColor"));
private void loadGateConfig() {
//Load the sign colors
loadSignColor((String) configOptions.get(ConfigOption.MAIN_SIGN_COLOR),
(String) configOptions.get(ConfigOption.HIGHLIGHT_SIGN_COLOR));
}
/**

View File

@ -81,8 +81,7 @@ public class PortalSignDrawer {
private void drawSign(Sign sign) {
//Clear sign
clearSign(sign);
setLine(sign, 0, highlightColor + "-" + mainColor +
portal.getName() + highlightColor + "-");
setLine(sign, 0, highlightColor + "-" + mainColor + fixColor(portal.getName()) + highlightColor + "-");
if (!portal.getPortalActivator().isActive()) {
//Default sign text
@ -123,7 +122,7 @@ public class PortalSignDrawer {
return;
}
clearSign(sign);
sign.setLine(0, portal.getName());
sign.setLine(0, fixColor(portal.getName()));
sign.update();
}
@ -173,10 +172,10 @@ public class PortalSignDrawer {
boolean green = PermissionHelper.isFree(portal.getActivePlayer(), portal, destination);
ChatColor nameColor = (green ? freeColor : highlightColor);
setLine(sign, signLineIndex, nameColor + ">" + (green ? freeColor : mainColor) +
portal.getDestinationName() + nameColor + "<");
fixColor(portal.getDestinationName()) + nameColor + "<");
} else {
setLine(sign, signLineIndex, highlightColor + ">" + mainColor + portal.getDestinationName() +
highlightColor + "<");
setLine(sign, signLineIndex, highlightColor + ">" + mainColor +
fixColor(portal.getDestinationName()) + highlightColor + "<");
}
}
@ -205,9 +204,9 @@ public class PortalSignDrawer {
if (freeGatesGreen) {
Portal destination = PortalHandler.getByName(destinationName, portal.getNetwork());
boolean green = PermissionHelper.isFree(portal.getActivePlayer(), portal, destination);
setLine(sign, signLineIndex, (green ? freeColor : mainColor) + destinationName);
setLine(sign, signLineIndex, (green ? freeColor : mainColor) + fixColor(destinationName));
} else {
setLine(sign, signLineIndex, mainColor + destinationName);
setLine(sign, signLineIndex, mainColor + fixColor(destinationName));
}
}
@ -218,8 +217,10 @@ public class PortalSignDrawer {
*/
private void drawBungeeSign(Sign sign) {
setLine(sign, 1, Stargate.getString("bungeeSign"));
setLine(sign, 2, highlightColor + ">" + mainColor + portal.getDestinationName() + highlightColor + "<");
setLine(sign, 3, highlightColor + "[" + mainColor + portal.getNetwork() + highlightColor + "]");
setLine(sign, 2, highlightColor + ">" + mainColor + fixColor(portal.getDestinationName()) +
highlightColor + "<");
setLine(sign, 3, highlightColor + "[" + mainColor + fixColor(portal.getNetwork()) +
highlightColor + "]");
}
/**
@ -233,7 +234,8 @@ public class PortalSignDrawer {
setLine(sign, 1, Stargate.getString("signRightClick"));
setLine(sign, 2, Stargate.getString("signToUse"));
if (!portal.getOptions().isNoNetwork()) {
setLine(sign, 3, highlightColor + "(" + mainColor + portal.getNetwork() + highlightColor + ")");
setLine(sign, 3, highlightColor + "(" + mainColor + fixColor(portal.getNetwork()) +
highlightColor + ")");
} else {
setLine(sign, 3, "");
}
@ -247,12 +249,13 @@ public class PortalSignDrawer {
private void drawFixedSign(Sign sign) {
String destinationName = portal.getOptions().isRandom() ? Stargate.getString("signRandom") :
portal.getDestinationName();
setLine(sign, 1, highlightColor + ">" + mainColor + destinationName + highlightColor + "<");
setLine(sign, 1, highlightColor + ">" + mainColor + fixColor(destinationName) + highlightColor + "<");
if (portal.getOptions().isNoNetwork()) {
setLine(sign, 2, "");
} else {
setLine(sign, 2, highlightColor + "(" + mainColor + portal.getNetwork() + highlightColor + ")");
setLine(sign, 2, highlightColor + "(" + mainColor + fixColor(portal.getNetwork()) +
highlightColor + ")");
}
Portal destination = PortalHandler.getByName(portal.getDestinationName(), portal.getNetwork());
if (destination == null && !portal.getOptions().isRandom()) {
@ -277,4 +280,14 @@ public class PortalSignDrawer {
Stargate.logInfo(String.format("Gate layout on line %d does not exist [%s]", lineIndex, gateName));
}
/**
* Fixes coloring of signs as the & character isn't translated on all servers
*
* @param text <p>The text to fix the coloring of</p>
* @return <p>The text with the coloring fixed</p>
*/
private String fixColor(String text) {
return ChatColor.translateAlternateColorCodes('&', text);
}
}

View File

@ -1,6 +1,6 @@
name: Stargate
main: net.knarcraft.stargate.Stargate
version: 0.9.0.7
version: 0.9.1.1
description: Stargate mod for Bukkit Revived
author: EpicKnarvik97
authors: [ Drakia, PseudoKnight, EpicKnarvik97 ]
@ -138,14 +138,18 @@ permissions:
stargate.admin.bungee:
description: Allows the creation and destruction of a stargate between BungeeCord servers
default: false
stargate.admin.config:
description: Allows the player to change config values from the chat
default: false
stargate.server:
description: Allows the creation of a BungeeCord stargate going to any server
default: false
stargate.admin:
description: Allow all admin features and commands (Hidden/Private bypass, BungeeCord, Reload)
description: Allow all admin features and commands (Hidden/Private bypass, BungeeCord, Reload, Config)
default: op
children:
stargate.admin.reload: true
stargate.admin.hidden: true
stargate.admin.private: true
stargate.admin.bungee: true
stargate.admin.bungee: true
stargate.admin.config: true