10 Commits

Author SHA1 Message Date
6ddc15eeef Merge branch 'config-reloading' into dev 2021-11-24 22:39:15 +01:00
14511f558d Updates readme and version to 0.9.2.1
Some checks failed
EpicKnarvik97/Stargate/pipeline/head There was a failure building this commit
2021-11-24 22:38:44 +01:00
32975ca35d Rewrites a lot of the config command to only do the minimum necessary steps to load the changes
Adds a ConfigTag class for helping to decide the action necessary for updating a given config option
Splits the color setting in PortalSignDrawer as only one color is set at a time when the /config command is used
Updates the configOptions map when a config option is changed
2021-11-24 22:33:45 +01:00
6e7ac5dbb9 Makes the protectEntrance option protect the entrance from all block placement 2021-11-24 22:20:47 +01:00
2b4d15dab4 Adds some boldness to the description and fixes an inaccuracy
Some checks failed
EpicKnarvik97/Stargate/pipeline/head There was a failure building this commit
2021-11-24 03:06:35 +01:00
22bb75d4df Moves some methods from EconomyConfig to EconomyHelper and tries to simplify EconomyConfig
Some checks failed
EpicKnarvik97/Stargate/pipeline/head There was a failure building this commit
2021-11-23 07:20:48 +01:00
ab9a118d49 Prevents an empty deny reason from being displayed
Some checks failed
EpicKnarvik97/Stargate/pipeline/head There was a failure building this commit
2021-11-22 22:01:43 +01:00
a80a8520ce Improves the description of the /sg command 2021-11-22 17:58:56 +01:00
48bb68d665 Adds a missing 'a' in a sentence
Some checks failed
EpicKnarvik97/Stargate/pipeline/head There was a failure building this commit
2021-11-21 13:34:52 +01:00
1247c54899 Fixes some wrong migration information 2021-11-21 13:10:13 +01:00
15 changed files with 431 additions and 256 deletions

View File

@ -3,18 +3,18 @@
Create gates that allow for instant-teleportation between large distances. Gates can be always-open or triggered; they
can share a network or be split into clusters; they can be hidden on a network or accessible to everybody.
- Player permissions -- let players build their own networks.
- Vault economy support -- can add costs for create, destroy and use.
- Ability to create custom gate configurations. Three different default gate configurations are available.
- Message customization
- Multiple built-in languages (de, en, es, fr, hu, it, nb-no, nl, nn-no, pt-br, ru)
- Teleport across worlds or servers (BungeeCord supported)
- Vehicle teleportation -- teleport minecarts, boats, horses, pigs and striders
- Leashed teleportation -- teleport any creature in a leash with the player
- 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
- **Player permissions** -- let players build their own networks.
- **Vault economy support** -- can add costs for create, destroy and use.
- **Ability to create custom gate configurations**. Four different default gate configurations are available.
- **Message customization**
- **Multiple built-in languages** (de, en, es, fr, hu, it, nb-no, nl, nn-no, pt-br, ru)
- **Teleport across worlds or servers** (BungeeCord supported)
- **Vehicle teleportation** -- teleport minecarts, boats, horses, pigs and striders
- **Leashed teleportation** -- teleport any creature in a leash with the player
- **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
@ -36,10 +36,8 @@ Permissions have had a few changes, so you should check the permissions section
permissions.
Payment to owner using Economy, through Vault, is only possible if the portal owner in the portal database is defined by
a UUID, and not a username. Right now, there is no automatic upgrade from usernames to UUID. You must either make the
stargate owner re-create the stargate or edit the file in the portals folder in a text editor. There are various ways to
find the UUID of players. You may look in the usercache.json file in the server directory or search for the username on
various websites.
a UUID, and not a username. A player name will be upgraded to a UUID when the player with the given name joins the
server.
# Permissions
@ -134,7 +132,7 @@ section). See the Custom Gate Layout section to learn how to add custom gates.
player enters. (Implicitly always on)
- 'U' is for a gate connecting to another through bungee (Implicitly always on)
- 'I' is for a silent gate, which does not output anything to the chat while teleporting. Increases immersion
- 'E' is for gate without a sign. Only for fixed stargates
- 'E' is for a gate without a sign. Only for fixed stargates
The options are the single letter, not the word. So to make a private hidden gate, your 4th line would be 'PH'. The
&\[0-9a-f] color codes are not counted in the character limit, thus allowing a 13-character name with an additional 2
@ -391,6 +389,12 @@ portalInfoServer=Server: %server%
# Changes
#### \[Version 0.9.2.1] EpicKnarvik97 fork
- Makes sure to only reload whatever is necessary when config values are changed using commands, instead of reloading
the entire config file every time
- Protects portals from block placement when protectEntrance is enabled
#### \[Version 0.9.2.0] EpicKnarvik97 fork
- Increases max length of names and networks to 13 characters

View File

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

View File

@ -144,6 +144,7 @@ public class Stargate extends JavaPlugin {
*
* @return <p>The max portal name/network length</p>
*/
@SuppressWarnings("SameReturnValue")
public static int getMaxNameNetworkLength() {
return 13;
}

View File

@ -2,6 +2,10 @@ package net.knarcraft.stargate.command;
import net.knarcraft.stargate.Stargate;
import net.knarcraft.stargate.config.ConfigOption;
import net.knarcraft.stargate.config.ConfigTag;
import net.knarcraft.stargate.portal.Portal;
import net.knarcraft.stargate.portal.PortalRegistry;
import net.knarcraft.stargate.portal.PortalSignDrawer;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
@ -55,7 +59,7 @@ public class CommandConfig implements CommandExecutor {
FileConfiguration configuration = Stargate.getInstance().getConfig();
//Validate any sign colors
if (selectedOption == ConfigOption.MAIN_SIGN_COLOR || selectedOption == ConfigOption.HIGHLIGHT_SIGN_COLOR) {
if (ConfigTag.COLOR.isTagged(selectedOption)) {
try {
ChatColor.valueOf(value.toUpperCase());
} catch (IllegalArgumentException | NullPointerException ignored) {
@ -66,13 +70,21 @@ public class CommandConfig implements CommandExecutor {
//Store the config values, accounting for the data type
switch (selectedOption.getDataType()) {
case BOOLEAN -> configuration.set(selectedOption.getConfigNode(), Boolean.parseBoolean(value));
case BOOLEAN -> {
boolean newValue = Boolean.parseBoolean(value);
if (selectedOption == ConfigOption.ENABLE_BUNGEE && newValue != Stargate.getGateConfig().enableBungee()) {
Stargate.getStargateConfig().startStopBungeeListener(newValue);
}
Stargate.getStargateConfig().getConfigOptionsReference().put(selectedOption, newValue);
configuration.set(selectedOption.getConfigNode(), newValue);
}
case INTEGER -> {
try {
configuration.set(selectedOption.getConfigNode(), Integer.parseInt(value));
} catch (NumberFormatException exception) {
commandSender.sendMessage(ChatColor.RED + "Invalid number given");
Integer intValue = getInteger(commandSender, selectedOption, value);
if (intValue == null) {
return;
} else {
Stargate.getStargateConfig().getConfigOptionsReference().put(selectedOption, intValue);
configuration.set(selectedOption.getConfigNode(), intValue);
}
}
case STRING -> {
@ -83,26 +95,119 @@ public class CommandConfig implements CommandExecutor {
return;
}
}
if (ConfigTag.COLOR.isTagged(selectedOption)) {
if (!registerColor(selectedOption, value, commandSender)) {
return;
}
}
if (selectedOption == ConfigOption.LANGUAGE) {
Stargate.getStargateConfig().getLanguageLoader().setChosenLanguage(value);
}
Stargate.getStargateConfig().getConfigOptionsReference().put(selectedOption, value);
configuration.set(selectedOption.getConfigNode(), value);
}
default -> {
Stargate.getStargateConfig().getConfigOptionsReference().put(selectedOption, value);
configuration.set(selectedOption.getConfigNode(), value);
}
default -> configuration.set(selectedOption.getConfigNode(), value);
}
//Save the config file and reload if necessary
Stargate.getInstance().saveConfig();
reloadIfNecessary(commandSender);
Stargate.getMessageSender().sendSuccessMessage(commandSender, "Config updated");
//Reload whatever is necessary
reloadIfNecessary(commandSender, selectedOption);
}
/**
* Registers the chat color if
*
* @param selectedOption <p>The option to change</p>
* @param commandSender <p>The command sender to alert if the color is invalid</p>
* @param value <p>The new option value</p>
*/
private boolean registerColor(ConfigOption selectedOption, String value, CommandSender commandSender) {
ChatColor parsedColor = parseColor(value);
if (parsedColor == null) {
commandSender.sendMessage(ChatColor.RED + "Invalid color given");
return false;
}
if (selectedOption == ConfigOption.FREE_GATES_COLOR) {
PortalSignDrawer.setFreeColor(parsedColor);
} else if (selectedOption == ConfigOption.MAIN_SIGN_COLOR) {
PortalSignDrawer.setMainColor(parsedColor);
} else if (selectedOption == ConfigOption.HIGHLIGHT_SIGN_COLOR) {
PortalSignDrawer.setHighlightColor(parsedColor);
}
return true;
}
/**
* Parses a chat color
*
* @param value <p>The value to parse</p>
* @return <p>The parsed color or null</p>
*/
private ChatColor parseColor(String value) {
try {
return ChatColor.valueOf(value.toUpperCase());
} catch (IllegalArgumentException | NullPointerException ignored) {
return null;
}
}
/**
* Gets an integer from a string
*
* @param commandSender <p>The command sender that sent the config command</p>
* @param selectedOption <p>The option the command sender is trying to change</p>
* @param value <p>The value given</p>
* @return <p>An integer, or null if it was invalid</p>
*/
private Integer getInteger(CommandSender commandSender, ConfigOption selectedOption, String value) {
try {
int intValue = Integer.parseInt(value);
if ((selectedOption == ConfigOption.USE_COST || selectedOption == ConfigOption.CREATE_COST) && intValue < 0) {
commandSender.sendMessage(ChatColor.RED + "This config option cannot be negative.");
return null;
}
return intValue;
} catch (NumberFormatException exception) {
commandSender.sendMessage(ChatColor.RED + "Invalid number given");
return null;
}
}
/**
* Reloads the config if necessary
*
* @param commandSender <p>The command sender initiating the reload</p>
* @param configOption <p>The changed config option</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.
private void reloadIfNecessary(CommandSender commandSender, ConfigOption configOption) {
if (ConfigTag.requiresFullReload(configOption)) {
//Reload everything
Stargate.getStargateConfig().reload(commandSender);
} else if (ConfigTag.requiresPortalReload(configOption)) {
//Just unload and reload the portals
Stargate.getStargateConfig().unloadAllPortals();
Stargate.getStargateConfig().loadAllPortals();
} else if (ConfigTag.requiresLanguageReload(configOption)) {
//Reload the language loader
Stargate.getStargateConfig().getLanguageLoader().reload();
//Re-draw all portal signs
for (Portal portal : PortalRegistry.getAllPortals()) {
portal.drawSign();
}
} else if (ConfigTag.requiresEconomyReload(configOption)) {
//Load or unload Vault and Economy as necessary
Stargate.getStargateConfig().reloadEconomy();
}
}
/**

View File

@ -0,0 +1,74 @@
package net.knarcraft.stargate.config;
import java.util.Arrays;
/**
* A config tag groups config values by a property
*/
public enum ConfigTag {
COLOR(new ConfigOption[]{ConfigOption.FREE_GATES_COLOR, ConfigOption.MAIN_SIGN_COLOR, ConfigOption.HIGHLIGHT_SIGN_COLOR}),
FOLDER(new ConfigOption[]{ConfigOption.GATE_FOLDER, ConfigOption.PORTAL_FOLDER});
private final ConfigOption[] taggedOptions;
/**
* Instantiates a new config tag
*
* @param taggedOptions <p>The config options included in this tag</p>
*/
ConfigTag(ConfigOption[] taggedOptions) {
this.taggedOptions = taggedOptions;
}
/**
* Checks whether a config tag includes the given config option
*
* @param option <p>The config option to check</p>
* @return <p>True of the config option is tagged</p>
*/
public boolean isTagged(ConfigOption option) {
return Arrays.stream(taggedOptions).anyMatch((item) -> item == option);
}
/**
* Checks whether a given config option requires a full reload to take effect
*
* @param option <p>The config option to check</p>
* @return <p>True if changing the config option requires a full reload to take effect</p>
*/
public static boolean requiresFullReload(ConfigOption option) {
return FOLDER.isTagged(option);
}
/**
* Checks whether a given config option requires a portal reload to take effect
*
* @param option <p>The config option to check</p>
* @return <p>True if changing the config option requires a portal reload to take effect</p>
*/
public static boolean requiresPortalReload(ConfigOption option) {
return COLOR.isTagged(option) || FOLDER.isTagged(option) || option == ConfigOption.VERIFY_PORTALS;
}
/**
* Checks whether a given config option requires the language loader to be reloaded
*
* @param option <p>The config option to check</p>
* @return <p>True if the language loader requires a reload</p>
*/
public static boolean requiresLanguageReload(ConfigOption option) {
return option == ConfigOption.LANGUAGE;
}
/**
* Checks whether a given config option requires economy to be reloaded
*
* @param option <p>The config option to check</p>
* @return <p>True if economy requires a reload</p>
*/
public static boolean requiresEconomyReload(ConfigOption option) {
return option == ConfigOption.USE_ECONOMY;
}
}

View File

@ -1,12 +1,10 @@
package net.knarcraft.stargate.config;
import net.knarcraft.stargate.Stargate;
import net.knarcraft.stargate.portal.Portal;
import net.knarcraft.stargate.portal.PortalSignDrawer;
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.ChatColor;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
@ -15,22 +13,16 @@ import org.bukkit.plugin.RegisteredServiceProvider;
import org.bukkit.plugin.ServicesManager;
import java.util.Map;
import java.util.UUID;
/**
* The economy config keeps track of economy config values and performs economy actions such as payment for using a gate
*/
public final class EconomyConfig {
private boolean economyEnabled = false;
private Economy economy = null;
private Plugin vault = null;
private int useCost = 0;
private int createCost = 0;
private int destroyCost = 0;
private boolean toOwner = false;
private boolean chargeFreeDestination = true;
private boolean freeGatesColored = false;
private final Map<ConfigOption, Object> configOptions;
/**
* Instantiates a new economy config
@ -38,7 +30,13 @@ public final class EconomyConfig {
* @param configOptions <p>The loaded config options to read</p>
*/
public EconomyConfig(Map<ConfigOption, Object> configOptions) {
loadEconomyConfig(configOptions);
this.configOptions = configOptions;
try {
String freeColor = (String) configOptions.get(ConfigOption.FREE_GATES_COLOR);
PortalSignDrawer.setFreeColor(ChatColor.valueOf(freeColor.toUpperCase()));
} catch (IllegalArgumentException | NullPointerException ignored) {
PortalSignDrawer.setFreeColor(ChatColor.DARK_GREEN);
}
}
/**
@ -47,7 +45,7 @@ public final class EconomyConfig {
* @return <p>The gate use cost</p>
*/
public int getDefaultUseCost() {
return useCost;
return (Integer) configOptions.get(ConfigOption.USE_COST);
}
/**
@ -56,7 +54,7 @@ public final class EconomyConfig {
* @return <p>Whether economy is enabled</p>
*/
public boolean isEconomyEnabled() {
return economyEnabled;
return (boolean) configOptions.get(ConfigOption.USE_ECONOMY);
}
/**
@ -91,7 +89,7 @@ public final class EconomyConfig {
* @return <p>Whether free portals should be colored</p>
*/
public boolean drawFreePortalsColored() {
return freeGatesColored;
return (boolean) configOptions.get(ConfigOption.FREE_GATES_COLORED);
}
/**
@ -103,8 +101,8 @@ public final class EconomyConfig {
*
* @return <p>Whether to charge for free destinations</p>
*/
public boolean chargeFreeDestination() {
return chargeFreeDestination;
public boolean freeIfFreeDestination() {
return !((boolean) configOptions.get(ConfigOption.CHARGE_FREE_DESTINATION));
}
/**
@ -113,21 +111,7 @@ public final class EconomyConfig {
* @return <p>Whether to send payments to the portal owner</p>
*/
public boolean sendPaymentToOwner() {
return toOwner;
}
/**
* Sets the cost of using a gate without a specified cost
*
* <p>The use cost cannot be negative.</p>
*
* @param useCost <p>The gate use cost</p>
*/
public void setDefaultUseCost(int useCost) {
if (useCost < 0) {
throw new IllegalArgumentException("Using a gate cannot cost a negative amount");
}
this.useCost = useCost;
return (boolean) configOptions.get(ConfigOption.TO_OWNER);
}
/**
@ -136,18 +120,7 @@ public final class EconomyConfig {
* @return <p>The gate creation cost</p>
*/
public int getDefaultCreateCost() {
return createCost;
}
/**
* Sets the cost of creating a gate without a specified cost
*
* <p>The gate create cost cannot be negative</p>
*
* @param createCost <p>The gate creation cost</p>
*/
public void setDefaultCreateCost(int createCost) {
this.createCost = createCost;
return (Integer) configOptions.get(ConfigOption.CREATE_COST);
}
/**
@ -156,31 +129,7 @@ public final class EconomyConfig {
* @return <p>The gate destruction cost</p>
*/
public int getDefaultDestroyCost() {
return destroyCost;
}
/**
* Sets the cost of destroying a gate without a specified cost
*
* @param destroyCost <p>The gate destruction cost</p>
*/
public void setDefaultDestroyCost(int destroyCost) {
this.destroyCost = destroyCost;
}
/**
* Charges the player for an action, if required
*
* @param player <p>The player to take money from</p>
* @param cost <p>The cost of the transaction</p>
* @return <p>True if the player was charged successfully</p>
*/
public boolean chargePlayerIfNecessary(Player player, int cost) {
if (skipPayment(cost)) {
return true;
}
//Charge player
return chargePlayer(player, cost);
return (Integer) configOptions.get(ConfigOption.DESTROY_COST);
}
/**
@ -194,22 +143,6 @@ public final class EconomyConfig {
return economy.getBalance(player) > cost;
}
/**
* Charges the player for an action, if required
*
* @param player <p>The player to take money from</p>
* @param target <p>The target to pay</p>
* @param cost <p>The cost of the transaction</p>
* @return <p>True if the player was charged successfully</p>
*/
public boolean chargePlayerIfNecessary(Player player, UUID target, int cost) {
if (skipPayment(cost)) {
return true;
}
//Charge player
return chargePlayer(player, target, cost);
}
/**
* Gets a formatted string for an amount, adding the name of the currency
*
@ -217,7 +150,7 @@ public final class EconomyConfig {
* @return <p>A formatted text string describing the amount</p>
*/
public String format(int amount) {
if (economyEnabled) {
if (isEconomyEnabled()) {
return economy.format(amount);
} else {
return "";
@ -231,7 +164,7 @@ public final class EconomyConfig {
* @return <p>True if economy was enabled</p>
*/
public boolean setupEconomy(PluginManager pluginManager) {
if (!economyEnabled) {
if (!isEconomyEnabled()) {
return false;
}
//Check if vault is loaded
@ -249,7 +182,7 @@ public final class EconomyConfig {
} else {
Stargate.logInfo(Stargate.getString("vaultLoadError"));
}
economyEnabled = false;
configOptions.put(ConfigOption.USE_ECONOMY, false);
return false;
}
@ -259,46 +192,7 @@ public final class EconomyConfig {
* @return <p>True if the user has turned on economy and economy is available</p>
*/
public boolean useEconomy() {
return economyEnabled && economy != null;
}
/**
* Checks whether a payment transaction should be skipped
*
* @param cost <p>The cost of the transaction</p>
* @return <p>True if the transaction should be skipped</p>
*/
private boolean skipPayment(int cost) {
return cost == 0 || !useEconomy();
}
/**
* Determines the cost of using a gate
*
* @param player <p>The player trying to use the gate</p>
* @param source <p>The source/entry portal</p>
* @param destination <p>The destination portal</p>
* @return <p>The cost of using the portal</p>
*/
public int getUseCost(Player player, Portal source, Portal destination) {
//No payment required
if (!useEconomy() || source.getOptions().isFree()) {
return 0;
}
//Not charging for free destinations
if (destination != null && !chargeFreeDestination && destination.getOptions().isFree()) {
return 0;
}
//Cost is 0 if the player owns this gate and funds go to the owner
if (source.getGate().getToOwner() && source.isOwner(player)) {
return 0;
}
//Player gets free gate use
if (PermissionHelper.hasPermission(player, "stargate.free.use")) {
return 0;
}
return source.getGate().getUseCost();
return isEconomyEnabled() && economy != null;
}
/**
@ -331,28 +225,6 @@ public final class EconomyConfig {
}
}
/**
* Loads all config values related to economy
*
* @param configOptions <p>The loaded config options to get values from</p>
*/
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);
freeGatesColored = (boolean) configOptions.get(ConfigOption.FREE_GATES_COLORED);
try {
String freeColor = (String) configOptions.get(ConfigOption.FREE_GATES_COLOR);
PortalSignDrawer.setFreeColor(ChatColor.valueOf(freeColor.toUpperCase()));
} catch (IllegalArgumentException | NullPointerException ignored) {
PortalSignDrawer.setFreeColor(ChatColor.DARK_GREEN);
}
}
/**
* Determines if a player can do a gate action for free
*
@ -364,41 +236,4 @@ public final class EconomyConfig {
return !useEconomy() || PermissionHelper.hasPermission(player, "stargate.free." + permissionNode);
}
/**
* Charges a player
*
* @param player <p>The player to charge</p>
* @param amount <p>The amount to charge</p>
* @return <p>True if the payment succeeded, or if no payment was necessary</p>
*/
private boolean chargePlayer(Player player, double amount) {
if (economyEnabled && economy != null) {
if (!economy.has(player, amount)) {
return false;
}
economy.withdrawPlayer(player, amount);
}
return true;
}
/**
* Charges a player, giving the charge to a target
*
* @param player <p>The player to charge</p>
* @param target <p>The UUID of the player to pay</p>
* @param amount <p>The amount to charge</p>
* @return <p>True if the payment succeeded, or if no payment was necessary</p>
*/
private boolean chargePlayer(Player player, UUID target, double amount) {
if (economyEnabled && player.getUniqueId().compareTo(target) != 0 && economy != null) {
if (!economy.has(player, amount)) {
return false;
}
//Take money from the user and give to the owner
economy.withdrawPlayer(player, amount);
economy.depositPlayer(Bukkit.getOfflinePlayer(target), amount);
}
return true;
}
}

View File

@ -46,8 +46,6 @@ public final class StargateConfig {
private String portalFolder;
private String languageName = "en";
private boolean debuggingEnabled = false;
private boolean permissionDebuggingEnabled = false;
private final Map<ConfigOption, Object> configOptions;
/**
@ -65,6 +63,18 @@ public final class StargateConfig {
languageLoader = new LanguageLoader(dataFolderPath + "/lang/");
}
/**
* Gets a direct reference to the config option map
*
* <p>This reference can be used to alter the value of config options. Values should only be altered after it's
* been verified that the value is valid.</p>
*
* @return <p>A reference to the config options map</p>
*/
public Map<ConfigOption, Object> getConfigOptionsReference() {
return configOptions;
}
/**
* Finish the config setup by loading languages, gates and portals, and loading economy if vault is loaded
*/
@ -81,7 +91,7 @@ public final class StargateConfig {
languageLoader.reload();
messageSender = new MessageSender(languageLoader);
if (debuggingEnabled) {
if (isDebuggingEnabled()) {
languageLoader.debug();
}
@ -130,7 +140,7 @@ public final class StargateConfig {
* @return <p>Whether debugging is enabled</p>
*/
public boolean isDebuggingEnabled() {
return debuggingEnabled;
return (boolean) configOptions.get(ConfigOption.DEBUG);
}
/**
@ -139,7 +149,7 @@ public final class StargateConfig {
* @return <p>Whether permission debugging is enabled</p>
*/
public boolean isPermissionDebuggingEnabled() {
return permissionDebuggingEnabled;
return (boolean) configOptions.get(ConfigOption.PERMISSION_DEBUG);
}
/**
@ -186,6 +196,17 @@ public final class StargateConfig {
* Un-loads all loaded data
*/
private void unload() {
//De-activate, close and unload all loaded portals
unloadAllPortals();
//Clear all loaded gates
GateHandler.clearGates();
}
/**
* Un-loads all loaded portals
*/
public void unloadAllPortals() {
//De-activate all currently active portals
for (Portal activePortal : activePortalsQueue) {
activePortal.getPortalActivator().deactivate();
@ -201,9 +222,6 @@ public final class StargateConfig {
//Clear all loaded portals
PortalRegistry.clearPortals();
//Clear all loaded gates
GateHandler.clearGates();
}
/**
@ -256,7 +274,7 @@ public final class StargateConfig {
//Update the language loader in case the loaded language changed
languageLoader.setChosenLanguage(languageName);
languageLoader.reload();
if (debuggingEnabled) {
if (isDebuggingEnabled()) {
languageLoader.debug();
}
@ -267,7 +285,7 @@ public final class StargateConfig {
/**
* Starts the listener for listening to BungeeCord messages
*/
private void startStopBungeeListener(boolean start) {
public void startStopBungeeListener(boolean start) {
Messenger messenger = Bukkit.getMessenger();
String bungeeChannel = "BungeeCord";
@ -283,7 +301,7 @@ public final class StargateConfig {
/**
* Reloads economy by enabling or disabling it as necessary
*/
private void reloadEconomy() {
public void reloadEconomy() {
EconomyConfig economyConfig = getEconomyConfig();
if (economyConfig.isEconomyEnabled() && economyConfig.getEconomy() == null) {
setupVaultEconomy();
@ -342,10 +360,6 @@ public final class StargateConfig {
portalFolder = (String) configOptions.get(ConfigOption.PORTAL_FOLDER);
gateFolder = (String) configOptions.get(ConfigOption.GATE_FOLDER);
//Get enabled debug settings from the config
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) {
GateHandler.writeDefaultGatesToFolder(gateFolder);

View File

@ -190,13 +190,13 @@ public final class StargateGateConfig {
private void loadSignColor(String mainSignColor, String highlightSignColor) {
if (mainSignColor != null && highlightSignColor != null) {
try {
PortalSignDrawer.setColors(ChatColor.valueOf(mainSignColor.toUpperCase()),
ChatColor.valueOf(highlightSignColor.toUpperCase()));
return;
PortalSignDrawer.setMainColor(ChatColor.valueOf(highlightSignColor.toUpperCase()));
PortalSignDrawer.setHighlightColor(ChatColor.valueOf(highlightSignColor.toUpperCase()));
} catch (IllegalArgumentException | NullPointerException ignored) {
}
}
Stargate.logWarning("You have specified an invalid color in your config.yml. Defaulting to BLACK and WHITE");
PortalSignDrawer.setColors(ChatColor.BLACK, ChatColor.WHITE);
PortalSignDrawer.setMainColor(ChatColor.BLACK);
PortalSignDrawer.setHighlightColor(ChatColor.WHITE);
}
}
}
}

View File

@ -25,6 +25,7 @@ import org.bukkit.event.block.BlockPhysicsEvent;
import org.bukkit.event.block.BlockPistonEvent;
import org.bukkit.event.block.BlockPistonExtendEvent;
import org.bukkit.event.block.BlockPistonRetractEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.block.EntityBlockFormEvent;
import org.bukkit.event.block.SignChangeEvent;
@ -96,6 +97,22 @@ public class BlockEventListener implements Listener {
portal::drawSign, 1);
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onBlockPlace(BlockPlaceEvent event) {
if (event.isCancelled() || !Stargate.getGateConfig().protectEntrance()) {
return;
}
Block block = event.getBlock();
Player player = event.getPlayer();
Portal portal = PortalHandler.getByEntrance(block);
if (portal != null) {
//Prevent blocks from being placed in the entrance, if protectEntrance is enabled, as breaking the block
// would destroy the portal
event.setCancelled(true);
}
}
/**
* Detects block breaking to detect if the user is destroying a gate
*
@ -140,7 +157,9 @@ public class BlockEventListener implements Listener {
//Destroy denied
if (destroyEvent.getDeny()) {
if (!destroyEvent.getDenyReason().trim().isEmpty()) {
Stargate.getMessageSender().sendErrorMessage(player, destroyEvent.getDenyReason());
}
event.setCancelled(true);
return;
}
@ -169,7 +188,7 @@ public class BlockEventListener implements Listener {
if (cost != 0) {
String portalName = portal.getName();
//Cannot pay
if (!Stargate.getEconomyConfig().chargePlayerIfNecessary(player, cost)) {
if (!EconomyHelper.chargePlayerIfNecessary(player, cost)) {
Stargate.debug("onBlockBreak", "Insufficient Funds");
EconomyHelper.sendInsufficientFundsMessage(portalName, player, cost);
event.setCancelled(true);

View File

@ -110,7 +110,7 @@ public class VehicleEventListener implements Listener {
//To prevent the case where the first passenger pays and then the second passenger is denied, this has to be
// run after it has been confirmed that all passengers are able to pay
int cost = Stargate.getEconomyConfig().getUseCost(player, entrancePortal, destinationPortal);
int cost = EconomyHelper.getUseCost(player, entrancePortal, destinationPortal);
if (cost > 0) {
if (!takePlayerPayment(passengers, entrancePortal, cost)) {
return;
@ -164,7 +164,7 @@ public class VehicleEventListener implements Listener {
}
//Check if the player is able to afford the teleport fee
int cost = Stargate.getEconomyConfig().getUseCost(player, entrancePortal, destinationPortal);
int cost = EconomyHelper.getUseCost(player, entrancePortal, destinationPortal);
boolean canAffordFee = cost <= 0 || Stargate.getEconomyConfig().canAffordFee(player, cost);
if (!canAffordFee && !entrancePortal.getOptions().isSilent()) {
Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("ecoInFunds"));

View File

@ -192,7 +192,9 @@ public class PortalCreator {
//Tell the user why it was denied from creating the portal
if (stargateCreateEvent.getDeny()) {
if (!stargateCreateEvent.getDenyReason().trim().isEmpty()) {
Stargate.getMessageSender().sendErrorMessage(player, stargateCreateEvent.getDenyReason());
}
return null;
}
@ -264,7 +266,7 @@ public class PortalCreator {
if (cost > 0) {
//Deduct the required fee from the player
if (!Stargate.getEconomyConfig().chargePlayerIfNecessary(player, cost)) {
if (!EconomyHelper.chargePlayerIfNecessary(player, cost)) {
EconomyHelper.sendInsufficientFundsMessage(portalName, player, cost);
Stargate.debug("createPortal", "Insufficient Funds");
return false;

View File

@ -29,19 +29,27 @@ public class PortalSignDrawer {
}
/**
* Sets the main and highlighting sign colors
* Sets the highlighting sign color
*
* <p>The main sign color is used for most text on the sign, while the highlighting color is used for the markings
* around portal names and network names ('>','<','-',')','(')</p>
* <p>The highlighting color is used for the markings around portal names and network names ('>','<','-',')','(').</p>
*
* @param newMainColor <p>The new main sign color</p>
* @param newHighlightColor <p>The new highlight color</p>
*/
public static void setColors(ChatColor newMainColor, ChatColor newHighlightColor) {
mainColor = newMainColor;
public static void setHighlightColor(ChatColor newHighlightColor) {
highlightColor = newHighlightColor;
}
/**
* Sets the main sign color
*
* <p>The main sign color is used for most text on the sign.</p>
*
* @param newMainColor <p>The new main sign color</p>
*/
public static void setMainColor(ChatColor newMainColor) {
mainColor = newMainColor;
}
/**
* Sets the color to use for marking free stargates
*

View File

@ -1,8 +1,11 @@
package net.knarcraft.stargate.utility;
import net.knarcraft.stargate.Stargate;
import net.knarcraft.stargate.config.EconomyConfig;
import net.knarcraft.stargate.portal.Portal;
import net.knarcraft.stargate.portal.property.PortalOwner;
import net.milkbowl.vault.economy.Economy;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import java.util.UUID;
@ -34,9 +37,9 @@ public final class EconomyHelper {
"was therefore not possible. Make the owner re-create the portal to fix this.", entrancePortal));
}
if (entrancePortal.getGate().getToOwner() && ownerUUID != null) {
success = Stargate.getEconomyConfig().chargePlayerIfNecessary(player, ownerUUID, cost);
success = chargePlayerIfNecessary(player, ownerUUID, cost);
} else {
success = Stargate.getEconomyConfig().chargePlayerIfNecessary(player, cost);
success = chargePlayerIfNecessary(player, cost);
}
//Send the insufficient funds message
@ -118,6 +121,116 @@ public final class EconomyHelper {
Stargate.getMessageSender().sendSuccessMessage(player, refundMsg);
}
/**
* Determines the cost of using a gate
*
* @param player <p>The player trying to use the gate</p>
* @param source <p>The source/entry portal</p>
* @param destination <p>The destination portal</p>
* @return <p>The cost of using the portal</p>
*/
public static int getUseCost(Player player, Portal source, Portal destination) {
EconomyConfig config = Stargate.getEconomyConfig();
//No payment required
if (!config.useEconomy() || source.getOptions().isFree()) {
return 0;
}
//Not charging for free destinations
if (destination != null && config.freeIfFreeDestination() && destination.getOptions().isFree()) {
return 0;
}
//Cost is 0 if the player owns this gate and funds go to the owner
if (source.getGate().getToOwner() && source.isOwner(player)) {
return 0;
}
//Player gets free gate use
if (PermissionHelper.hasPermission(player, "stargate.free.use")) {
return 0;
}
return source.getGate().getUseCost();
}
/**
* Charges the player for an action, if required
*
* @param player <p>The player to take money from</p>
* @param target <p>The target to pay</p>
* @param cost <p>The cost of the transaction</p>
* @return <p>True if the player was charged successfully</p>
*/
public static boolean chargePlayerIfNecessary(Player player, UUID target, int cost) {
if (skipPayment(cost)) {
return true;
}
//Charge player
return chargePlayer(player, target, cost);
}
/**
* Charges a player
*
* @param player <p>The player to charge</p>
* @param amount <p>The amount to charge</p>
* @return <p>True if the payment succeeded, or if no payment was necessary</p>
*/
private static boolean chargePlayer(Player player, double amount) {
Economy economy = Stargate.getEconomyConfig().getEconomy();
if (Stargate.getEconomyConfig().isEconomyEnabled() && economy != null) {
if (!economy.has(player, amount)) {
return false;
}
economy.withdrawPlayer(player, amount);
}
return true;
}
/**
* Charges the player for an action, if required
*
* @param player <p>The player to take money from</p>
* @param cost <p>The cost of the transaction</p>
* @return <p>True if the player was charged successfully</p>
*/
public static boolean chargePlayerIfNecessary(Player player, int cost) {
if (skipPayment(cost)) {
return true;
}
//Charge player
return chargePlayer(player, cost);
}
/**
* Checks whether a payment transaction should be skipped
*
* @param cost <p>The cost of the transaction</p>
* @return <p>True if the transaction should be skipped</p>
*/
private static boolean skipPayment(int cost) {
return cost == 0 || !Stargate.getEconomyConfig().useEconomy();
}
/**
* Charges a player, giving the charge to a target
*
* @param player <p>The player to charge</p>
* @param target <p>The UUID of the player to pay</p>
* @param amount <p>The amount to charge</p>
* @return <p>True if the payment succeeded, or if no payment was necessary</p>
*/
private static boolean chargePlayer(Player player, UUID target, double amount) {
Economy economy = Stargate.getEconomyConfig().getEconomy();
if (Stargate.getEconomyConfig().isEconomyEnabled() && player.getUniqueId().compareTo(target) != 0 && economy != null) {
if (!economy.has(player, amount)) {
return false;
}
//Take money from the user and give to the owner
economy.withdrawPlayer(player, amount);
economy.depositPlayer(Bukkit.getOfflinePlayer(target), amount);
}
return true;
}
/**
* Replaces the cost and portal variables in a string
*

View File

@ -243,7 +243,7 @@ public final class PermissionHelper {
return true;
}
//Don't charge for free destinations unless specified in the config
return dest != null && !Stargate.getEconomyConfig().chargeFreeDestination() && dest.getOptions().isFree();
return dest != null && Stargate.getEconomyConfig().freeIfFreeDestination() && dest.getOptions().isFree();
}
/**
@ -407,7 +407,7 @@ public final class PermissionHelper {
}
//Player cannot pay for teleportation
int cost = Stargate.getEconomyConfig().getUseCost(player, entrancePortal, destination);
int cost = EconomyHelper.getUseCost(player, entrancePortal, destination);
if (cost > 0) {
return EconomyHelper.cannotPayTeleportFee(entrancePortal, player, cost);
}

View File

@ -1,6 +1,6 @@
name: Stargate
main: net.knarcraft.stargate.Stargate
version: 0.9.2.0
version: 0.9.2.1
description: Stargate mod for Bukkit Revived
author: EpicKnarvik97
authors: [ Drakia, PseudoKnight, EpicKnarvik97 ]
@ -11,8 +11,8 @@ commands:
stargate:
aliases:
- sg
description: Used to see stargate info
usage: /<command> <reload/about> - Used to see stargate info or reload the plugin
description: Used to see stargate info, reloading and editing config values
usage: /<command> <reload/about/config> - Used to see stargate info, reload the plugin or change config values
permissions:
stargate.*:
description: Wildcard permission which gives all Stargate permissions