- Wrote custom config stuff to add support for comments in the config file. They should no longer be removed by the plugin itself now.
This commit is contained in:
parent
a8821be3db
commit
404eb20c4c
src/main/java/nl/pim16aap2/armoredElytra
@ -1,6 +1,5 @@
|
||||
package nl.pim16aap2.armoredElytra;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.logging.Level;
|
||||
|
||||
@ -9,69 +8,61 @@ import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import nl.pim16aap2.armoredElytra.handlers.EventHandlers;
|
||||
import nl.pim16aap2.armoredElytra.handlers.LoginHandler;
|
||||
import nl.pim16aap2.armoredElytra.nms.NBTEditor;
|
||||
import nl.pim16aap2.armoredElytra.nms.NBTEditor_V1_11_R1;
|
||||
import nl.pim16aap2.armoredElytra.nms.NBTEditor_V1_12_R1;
|
||||
import nl.pim16aap2.armoredElytra.util.ConfigLoader;
|
||||
import nl.pim16aap2.armoredElytra.util.Metrics;
|
||||
import nl.pim16aap2.armoredElytra.util.Update;
|
||||
|
||||
public class ArmoredElytra extends JavaPlugin implements Listener
|
||||
{
|
||||
private NBTEditor nbtEditor;
|
||||
private boolean cursesAllowed;
|
||||
private int LEATHER_TO_FULL;
|
||||
private int GOLD_TO_FULL;
|
||||
private int IRON_TO_FULL;
|
||||
private int DIAMONDS_TO_FULL;
|
||||
private String[] allowedEnchants;
|
||||
|
||||
private String usageDeniedMessage;
|
||||
private String elytraReceivedMessage;
|
||||
private boolean checkForUpdates;
|
||||
private boolean allowStats;
|
||||
private boolean upToDate;
|
||||
private String elytraName;
|
||||
private String elytraLore;
|
||||
private boolean upToDate;
|
||||
|
||||
private ConfigLoader config;
|
||||
|
||||
@Override
|
||||
public void onEnable()
|
||||
{
|
||||
FileConfiguration config = this.getConfig();
|
||||
saveDefaultConfig();
|
||||
|
||||
LEATHER_TO_FULL = config.getInt("leatherRepair", 6);
|
||||
GOLD_TO_FULL = config.getInt("goldRepair", 5);
|
||||
IRON_TO_FULL = config.getInt("ironRepair", 4);
|
||||
DIAMONDS_TO_FULL = config.getInt("diamondsRepair", 3);
|
||||
cursesAllowed = config.getBoolean("allowCurses", true);
|
||||
List<String> list = config.getStringList("allowedEnchantments");
|
||||
allowedEnchants = list.toArray(new String[0]);
|
||||
config = new ConfigLoader(this);
|
||||
|
||||
// Replace color codes by the corresponding colors.
|
||||
usageDeniedMessage = config.getString("usageDeniedMessage").replaceAll("&((?i)[0-9a-fk-or])", "\u00A7$1");
|
||||
elytraReceivedMessage = config.getString("elytraReceivedMessage").replaceAll("&((?i)[0-9a-fk-or])", "\u00A7$1");
|
||||
elytraName = config.getString("elytraName").replaceAll("&((?i)[0-9a-fk-or])", "\u00A7$1");
|
||||
elytraLore = config.getString("elytraLore").replaceAll("&((?i)[0-9a-fk-or])", "\u00A7$1");
|
||||
|
||||
checkForUpdates = config.getBoolean("checkForUpdates");
|
||||
allowStats = config.getBoolean("allowStats");
|
||||
|
||||
|
||||
// Change the string to null if it says "NONE".
|
||||
usageDeniedMessage = (Objects.equals(usageDeniedMessage, new String("NONE")) ? null : usageDeniedMessage);
|
||||
elytraReceivedMessage = (Objects.equals(elytraReceivedMessage, new String("NONE")) ? null : elytraReceivedMessage);
|
||||
elytraLore = (Objects.equals(elytraLore, new String("NONE")) ? null : elytraLore);
|
||||
elytraLore = (Objects.equals(elytraLore, new String("NONE")) ? null : elytraLore);
|
||||
|
||||
|
||||
|
||||
// Check if the user allows checking for updates.
|
||||
if (checkForUpdates)
|
||||
if (config.getBool("checkForUpdates"))
|
||||
{
|
||||
// Load the loginHandler to show messages to the user when they join.
|
||||
Bukkit.getPluginManager().registerEvents(new LoginHandler(this), this);
|
||||
|
||||
Update update = new Update(278437, this);
|
||||
|
||||
String latestVersion = update.getLatestVersion();
|
||||
String thisVersion = this.getDescription().getVersion();
|
||||
// Check if this is the latest version or not.
|
||||
int updateStatus = update.versionCompare(latestVersion, thisVersion);
|
||||
|
||||
if (updateStatus > 0)
|
||||
@ -85,39 +76,46 @@ public class ArmoredElytra extends JavaPlugin implements Listener
|
||||
}
|
||||
}
|
||||
|
||||
if (allowStats)
|
||||
// Are stats allowed?
|
||||
if (config.getBool("allowStats"))
|
||||
{
|
||||
myLogger(Level.INFO, "Enabling stats!");
|
||||
@SuppressWarnings("unused")
|
||||
Metrics metrics = new Metrics(this);
|
||||
} else
|
||||
{
|
||||
// Y u do dis? :(
|
||||
myLogger(Level.INFO, "Stats disabled, not laoding stats :(");
|
||||
}
|
||||
|
||||
config.options().copyDefaults(true);
|
||||
saveConfig();
|
||||
|
||||
// Log all allowed enchantments.
|
||||
myLogger(Level.INFO, ("Allowed enchantments:"));
|
||||
for (String s : allowedEnchants)
|
||||
for (String s : config.getStringList("allowedEnchantments"))
|
||||
{
|
||||
myLogger(Level.INFO, s);
|
||||
myLogger(Level.INFO, " - " + s);
|
||||
}
|
||||
// Log whether or not curses are allowed.
|
||||
myLogger(Level.INFO, "Curses on armored elytras are " + (config.getBool("allowCurses") ? "" : "not " + "allowed!"));
|
||||
|
||||
// Load the files for the correct version of Minecraft.
|
||||
if (compatibleMCVer())
|
||||
{
|
||||
Bukkit.getPluginManager().registerEvents(new EventHandlers(this, nbtEditor, cursesAllowed, LEATHER_TO_FULL, GOLD_TO_FULL, IRON_TO_FULL, DIAMONDS_TO_FULL, allowedEnchants), this);
|
||||
Bukkit.getPluginManager().registerEvents(new EventHandlers(this, nbtEditor), this);
|
||||
} else {
|
||||
myLogger(Level.WARNING, "Trying to load the plugin on an incompatible version of Minecraft!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Returns true if this is the latest version of this plugin.
|
||||
public boolean isUpToDate()
|
||||
{
|
||||
return upToDate;
|
||||
}
|
||||
|
||||
// Returns the config handler.
|
||||
public ConfigLoader getConfigLoader()
|
||||
{
|
||||
return config;
|
||||
}
|
||||
|
||||
// Send a message to a player in a specific color.
|
||||
public void messagePlayer(Player player, ChatColor color, String s)
|
||||
{
|
||||
|
@ -1,6 +1,7 @@
|
||||
package nl.pim16aap2.armoredElytra;
|
||||
package nl.pim16aap2.armoredElytra.handlers;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
@ -21,6 +22,7 @@ import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.EnchantmentStorageMeta;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import nl.pim16aap2.armoredElytra.ArmoredElytra;
|
||||
import nl.pim16aap2.armoredElytra.nms.NBTEditor;
|
||||
|
||||
public class EventHandlers implements Listener
|
||||
@ -32,21 +34,23 @@ public class EventHandlers implements Listener
|
||||
private boolean cursesAllowed;
|
||||
private NBTEditor nbtEditor;
|
||||
private final ArmoredElytra plugin;
|
||||
private String[] allowedEnchantments;
|
||||
private List<String> allowedEnchantments;
|
||||
private String[] cursedEnchantments = {"MENDING",
|
||||
"VANISHING_CURSE",
|
||||
"BINDING_CURSE"};
|
||||
|
||||
public EventHandlers(ArmoredElytra plugin, NBTEditor nbtEditor, boolean allowCurses, int LEATHER_TO_FULL, int GOLD_TO_FULL, int IRON_TO_FULL, int DIAMONDS_TO_FULL, String[] allowedEnchantments)
|
||||
public EventHandlers(ArmoredElytra plugin, NBTEditor nbtEditor)
|
||||
{
|
||||
this.plugin = plugin;
|
||||
this.plugin = plugin;
|
||||
this.nbtEditor = nbtEditor;
|
||||
this.cursesAllowed = allowCurses;
|
||||
this.DIAMONDS_TO_FULL = DIAMONDS_TO_FULL;
|
||||
this.allowedEnchantments = allowedEnchantments;
|
||||
this.LEATHER_TO_FULL = LEATHER_TO_FULL;
|
||||
this.GOLD_TO_FULL = GOLD_TO_FULL;
|
||||
this.IRON_TO_FULL = IRON_TO_FULL;
|
||||
|
||||
// Get the values of the config options.
|
||||
this.cursesAllowed = plugin.getConfigLoader().getBool("allowCurses");
|
||||
this.allowedEnchantments = plugin.getConfigLoader().getStringList("allowedEnchantments");
|
||||
this.LEATHER_TO_FULL = plugin.getConfigLoader().getInt("leatherRepair");
|
||||
this.GOLD_TO_FULL = plugin.getConfigLoader().getInt("goldRepair");
|
||||
this.IRON_TO_FULL = plugin.getConfigLoader().getInt("ironRepair");
|
||||
this.DIAMONDS_TO_FULL = plugin.getConfigLoader().getInt("diamondsRepair");
|
||||
}
|
||||
|
||||
// Clear the anvil's inventory (destroy all the items in all 3 slots (second slot is not emptied, when repairing you can safely give multiple items)).
|
@ -1,4 +1,4 @@
|
||||
package nl.pim16aap2.armoredElytra;
|
||||
package nl.pim16aap2.armoredElytra.handlers;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.entity.Player;
|
||||
@ -7,6 +7,8 @@ import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerLoginEvent;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import nl.pim16aap2.armoredElytra.ArmoredElytra;
|
||||
|
||||
public class LoginHandler implements Listener {
|
||||
|
||||
ArmoredElytra plugin;
|
@ -117,6 +117,8 @@ public class NBTEditor_V1_11_R1 implements NBTEditor
|
||||
String nbtTags = compound.toString();
|
||||
|
||||
// Check if the item has the generic.armor attribute.
|
||||
// Format = <level>,Slot:"chest",AttributeName:"generic.armor so get pos of char before
|
||||
// The start of the string, as that's the value of the generic.armor attribute.
|
||||
int pos = nbtTags.indexOf(",Slot:\"chest\",AttributeName:\"generic.armor\"");
|
||||
if (pos > 0)
|
||||
{
|
||||
|
182
src/main/java/nl/pim16aap2/armoredElytra/util/ConfigLoader.java
Normal file
182
src/main/java/nl/pim16aap2/armoredElytra/util/ConfigLoader.java
Normal file
@ -0,0 +1,182 @@
|
||||
package nl.pim16aap2.armoredElytra.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
|
||||
import nl.pim16aap2.armoredElytra.ArmoredElytra;
|
||||
|
||||
public class ConfigLoader
|
||||
{
|
||||
private int LEATHER_TO_FULL;
|
||||
private int GOLD_TO_FULL;
|
||||
private int IRON_TO_FULL;
|
||||
private int DIAMONDS_TO_FULL;
|
||||
private boolean cursesAllowed;
|
||||
private List<String> allowedEnchantments;
|
||||
private String usageDeniedMessage;
|
||||
private String elytraReceivedMessage;
|
||||
private boolean checkForUpdates;
|
||||
private boolean allowStats;
|
||||
private String elytraName;
|
||||
private String elytraLore;
|
||||
|
||||
// All the comments for the various config options.
|
||||
private String[] repairComment =
|
||||
{"Amount of items it takes to fully repair an armored elytra",
|
||||
"Repair cost for every tier of armored elytra in number of items to repair 100%."};
|
||||
private String[] cursesComment =
|
||||
{"Will curses (vanishing, binding) be transferred when creating armored elytras?"};
|
||||
private String[] enchantmentsComment =
|
||||
{"List of enchantments that are allowed to be put on an armored elytra.",
|
||||
"If you do not want to allow any enchantments, remove them all and add \"NONE\"",
|
||||
"You can find supported enchantments here:",
|
||||
"https://hub.spigotmc.org/javadocs/spigot/org/bukkit/enchantments/Enchantment.html"};
|
||||
private String[] usageDeniedComment =
|
||||
{"Message players receive when they lack the required permissions to wear a certain armor tier. \"NONE\" = no message. ",
|
||||
"%ARMOR_TIER% is replaced by the name of the armor tier."};
|
||||
private String[] elytraReceivedComment =
|
||||
{"Message players receive when they are given an armored elytra using commands. \"NONE\" = no message. ",
|
||||
"%ARMOR_TIER% is replaced by the name of the armor tier."};
|
||||
private String[] elytraNameComment =
|
||||
{"The name of armored elytras. %ARMOR_TIER% is replaced by the name of the armor tier."};
|
||||
private String[] elytraLoreComment =
|
||||
{"The lore of armored elytras. \"NONE\" = no lore. %ARMOR_TIER% is replaced by the name of the armor tier."};
|
||||
private String[] updateComment =
|
||||
{"Allow this plugin to check for updates on startup. It will not download new versions!"};
|
||||
private String[] bStatsComment =
|
||||
{"Allow this plugin to send (anonymised) stats using bStats."};
|
||||
|
||||
private ArrayList<ConfigOption> configOptionsList;
|
||||
private ArmoredElytra plugin;
|
||||
|
||||
public ConfigLoader(ArmoredElytra plugin)
|
||||
{
|
||||
this.plugin = plugin;
|
||||
configOptionsList = new ArrayList<ConfigOption>();
|
||||
makeConfig();
|
||||
}
|
||||
|
||||
// Read the current config, the make a new one based on the old one or default values, whichever is applicable.
|
||||
public void makeConfig()
|
||||
{
|
||||
FileConfiguration config = plugin.getConfig();
|
||||
|
||||
// Read all the options from the config, then put them in a configOption with their name, value and comment.
|
||||
// THen put all configOptions into an ArrayList.
|
||||
LEATHER_TO_FULL = config.getInt("leatherRepair", 6);
|
||||
configOptionsList.add(new ConfigOption("leatherRepair", LEATHER_TO_FULL, repairComment));
|
||||
GOLD_TO_FULL = config.getInt("goldRepair", 5);
|
||||
configOptionsList.add(new ConfigOption("goldRepair", GOLD_TO_FULL));
|
||||
IRON_TO_FULL = config.getInt("ironRepair", 4);
|
||||
configOptionsList.add(new ConfigOption("ironRepair", IRON_TO_FULL));
|
||||
DIAMONDS_TO_FULL = config.getInt("diamondsRepair", 3);
|
||||
configOptionsList.add(new ConfigOption("diamondsRepair", DIAMONDS_TO_FULL));
|
||||
|
||||
cursesAllowed = config.getBoolean("allowCurses", true);
|
||||
configOptionsList.add(new ConfigOption("allowCurses", cursesAllowed, cursesComment));
|
||||
allowedEnchantments = config.getStringList("allowedEnchantments");
|
||||
|
||||
configOptionsList.add(new ConfigOption("allowedEnchantments", allowedEnchantments, enchantmentsComment));
|
||||
|
||||
usageDeniedMessage = config.getString("usageDeniedMessage");
|
||||
configOptionsList.add(new ConfigOption("usageDeniedMessage", usageDeniedMessage, usageDeniedComment));
|
||||
elytraReceivedMessage = config.getString("elytraReceivedMessage");
|
||||
configOptionsList.add(new ConfigOption("elytraReceivedMessage", elytraReceivedMessage, elytraReceivedComment));
|
||||
elytraName = config.getString("elytraName");
|
||||
configOptionsList.add(new ConfigOption("elytraName", elytraName, elytraNameComment));
|
||||
elytraLore = config.getString("elytraLore");
|
||||
configOptionsList.add(new ConfigOption("elytraLore", elytraLore, elytraLoreComment));
|
||||
|
||||
checkForUpdates = config.getBoolean("checkForUpdates");
|
||||
configOptionsList.add(new ConfigOption("checkForUpdates", checkForUpdates, updateComment));
|
||||
allowStats = config.getBoolean("allowStats");
|
||||
configOptionsList.add(new ConfigOption("allowStats", allowStats, bStatsComment));
|
||||
|
||||
writeConfig();
|
||||
}
|
||||
|
||||
// Write new config file.
|
||||
public void writeConfig()
|
||||
{
|
||||
// Write all the config options to the config.yml.
|
||||
try
|
||||
{
|
||||
File dataFolder = plugin.getDataFolder();
|
||||
if (!dataFolder.exists())
|
||||
{
|
||||
dataFolder.mkdir();
|
||||
}
|
||||
File saveTo = new File(plugin.getDataFolder(), "config.yml");
|
||||
if (!saveTo.exists())
|
||||
{
|
||||
saveTo.createNewFile();
|
||||
} else
|
||||
{
|
||||
saveTo.delete();
|
||||
saveTo.createNewFile();
|
||||
}
|
||||
FileWriter fw = new FileWriter(saveTo, true);
|
||||
PrintWriter pw = new PrintWriter(fw);
|
||||
|
||||
for (ConfigOption configOption : configOptionsList)
|
||||
pw.println(configOption.toString());
|
||||
|
||||
pw.flush();
|
||||
pw.close();
|
||||
} catch (IOException e)
|
||||
{
|
||||
Bukkit.getLogger().log(Level.SEVERE, "Could not save config.yml! Please contact the author and attach the following code:");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public Integer getInt(String path)
|
||||
{
|
||||
for (ConfigOption configOption : configOptionsList)
|
||||
{
|
||||
if (configOption.getName().equals(path))
|
||||
return configOption.getInt();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Boolean getBool(String path)
|
||||
{
|
||||
for (ConfigOption configOption : configOptionsList)
|
||||
{
|
||||
if (configOption.getName().equals(path))
|
||||
return configOption.getBool();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getString(String path)
|
||||
{
|
||||
for (ConfigOption configOption : configOptionsList)
|
||||
{
|
||||
if (configOption.getName().equals(path))
|
||||
return configOption.getString();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<String> getStringList(String path)
|
||||
{
|
||||
for (ConfigOption configOption : configOptionsList)
|
||||
{
|
||||
if (configOption.getName().equals(path))
|
||||
{
|
||||
return configOption.getStringList();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
125
src/main/java/nl/pim16aap2/armoredElytra/util/ConfigOption.java
Normal file
125
src/main/java/nl/pim16aap2/armoredElytra/util/ConfigOption.java
Normal file
@ -0,0 +1,125 @@
|
||||
package nl.pim16aap2.armoredElytra.util;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ConfigOption
|
||||
{
|
||||
private String optionName;
|
||||
List<String> listVal = null;
|
||||
private Integer intVal = null;
|
||||
private Boolean boolVal = null;
|
||||
private String stringVal = null;
|
||||
private String[] comment;
|
||||
|
||||
public ConfigOption(String optionName, int value, String[] comment)
|
||||
{
|
||||
this.optionName = optionName;
|
||||
this.intVal = value;
|
||||
this.comment = comment;
|
||||
}
|
||||
|
||||
public ConfigOption(String optionName, int value)
|
||||
{
|
||||
this.optionName = optionName;
|
||||
this.intVal = value;
|
||||
this.comment = null;
|
||||
}
|
||||
|
||||
public ConfigOption(String optionName, boolean value, String[] comment)
|
||||
{
|
||||
this.optionName = optionName;
|
||||
this.boolVal = value;
|
||||
this.comment = comment;
|
||||
}
|
||||
|
||||
public ConfigOption(String optionName, boolean value)
|
||||
{
|
||||
this.optionName = optionName;
|
||||
this.boolVal = value;
|
||||
this.comment = null;
|
||||
}
|
||||
|
||||
public ConfigOption(String optionName, String value, String[] comment)
|
||||
{
|
||||
this.optionName = optionName;
|
||||
this.stringVal = value;
|
||||
this.comment = comment;
|
||||
}
|
||||
|
||||
public ConfigOption(String optionName, String value)
|
||||
{
|
||||
this.optionName = optionName;
|
||||
this.stringVal = value;
|
||||
this.comment = null;
|
||||
}
|
||||
|
||||
public ConfigOption(String optionName, List<String> value, String[] comment)
|
||||
{
|
||||
this.optionName = optionName;
|
||||
this.listVal = value;
|
||||
this.comment = comment;
|
||||
}
|
||||
|
||||
public ConfigOption(String optionName, List<String> value)
|
||||
{
|
||||
this.optionName = optionName;
|
||||
this.listVal = value;
|
||||
this.comment = null;
|
||||
}
|
||||
|
||||
public String stringListToString()
|
||||
{
|
||||
String string = "";
|
||||
for (String s : listVal)
|
||||
string += " - " + s + "\n";
|
||||
return string;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return optionName;
|
||||
}
|
||||
|
||||
public List<String> getStringList()
|
||||
{
|
||||
return listVal;
|
||||
}
|
||||
|
||||
public int getInt()
|
||||
{
|
||||
return intVal;
|
||||
}
|
||||
|
||||
public boolean getBool()
|
||||
{
|
||||
return boolVal;
|
||||
}
|
||||
|
||||
public String getString()
|
||||
{
|
||||
return stringVal;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
String string = "";
|
||||
|
||||
// Print the comments, if there are any.
|
||||
if (comment != null)
|
||||
{
|
||||
string += "\n";
|
||||
for (String comLine : comment)
|
||||
// Prefix every line by a comment-sign (#).
|
||||
string += "# " + comLine + "\n";
|
||||
}
|
||||
|
||||
// Then add the name of the option followed by its value (if it is an int/bool/String/String[]).
|
||||
string += optionName + ": " +
|
||||
(intVal != null ? intVal :
|
||||
boolVal != null ? boolVal :
|
||||
stringVal != null ? "\'" + stringVal + "\'" :
|
||||
listVal != null ? "\n" + stringListToString() : null);
|
||||
|
||||
return string;
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package nl.pim16aap2.armoredElytra;
|
||||
package nl.pim16aap2.armoredElytra.util;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
Loading…
x
Reference in New Issue
Block a user