196 lines
7.1 KiB
Java
196 lines
7.1 KiB
Java
package net.knarcraft.permissionsigns.manager;
|
|
|
|
import net.knarcraft.permissionsigns.PermissionSigns;
|
|
import net.knarcraft.permissionsigns.container.PermissionSign;
|
|
import org.bukkit.Bukkit;
|
|
import org.bukkit.Location;
|
|
import org.bukkit.block.Block;
|
|
import org.bukkit.block.BlockState;
|
|
import org.bukkit.block.Sign;
|
|
import org.bukkit.configuration.ConfigurationSection;
|
|
import org.bukkit.configuration.InvalidConfigurationException;
|
|
import org.bukkit.configuration.file.YamlConfiguration;
|
|
|
|
import java.io.File;
|
|
import java.io.IOException;
|
|
import java.util.ArrayList;
|
|
import java.util.Arrays;
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Objects;
|
|
import java.util.UUID;
|
|
import java.util.logging.Level;
|
|
|
|
/**
|
|
* A manager for keeping track of known signs
|
|
*/
|
|
public final class SignManager {
|
|
|
|
private static Map<Location, PermissionSign> managedSigns = new HashMap<>();
|
|
private static final File signsFile = new File(PermissionSigns.getInstance().getDataFolder(), "data.yml");
|
|
|
|
private SignManager() {
|
|
|
|
}
|
|
|
|
/**
|
|
* Gets the permission sign at the given location
|
|
*
|
|
* @param signLocation <p>The location of the permission sign to get</p>
|
|
* @return <p>The permission sign at the given location, or null if no such sign exists</p>
|
|
*/
|
|
public static PermissionSign getSign(Location signLocation) {
|
|
return managedSigns.get(signLocation);
|
|
}
|
|
|
|
/**
|
|
* Adds a sign
|
|
*
|
|
* @param sign <p>The sign to add</p>
|
|
*/
|
|
public static void addSign(PermissionSign sign) {
|
|
managedSigns.put(sign.getSignLocation(), sign);
|
|
save();
|
|
}
|
|
|
|
/**
|
|
* Removes a sign
|
|
*
|
|
* @param location <p>The location of the sign to remove</p>
|
|
*/
|
|
public static void removeSign(Location location) {
|
|
managedSigns.remove(location);
|
|
save();
|
|
}
|
|
|
|
/**
|
|
* Saves all signs to the signs file
|
|
*
|
|
* @throws IOException <p>If unable to save to the signs file</p>
|
|
*/
|
|
public static void saveSigns() throws IOException {
|
|
YamlConfiguration configuration = YamlConfiguration.loadConfiguration(signsFile);
|
|
ConfigurationSection signSection = configuration.createSection("signs");
|
|
|
|
for (Location signLocation : managedSigns.keySet()) {
|
|
String locationString = Objects.requireNonNull(signLocation.getWorld()).getUID() + "," +
|
|
signLocation.getBlockX() + "," + signLocation.getBlockY() + "," + signLocation.getBlockZ();
|
|
PermissionSign sign = managedSigns.get(signLocation);
|
|
signSection.set(locationString + ".name", sign.getName());
|
|
signSection.set(locationString + ".permissions", sign.getPermissionNodes());
|
|
signSection.set(locationString + ".duration", sign.getDuration());
|
|
signSection.set(locationString + ".cost", sign.getCost());
|
|
}
|
|
configuration.save(signsFile);
|
|
}
|
|
|
|
/**
|
|
* Loads all saved signs from disk
|
|
*/
|
|
public static void loadSigns() {
|
|
YamlConfiguration configuration = YamlConfiguration.loadConfiguration(signsFile);
|
|
ConfigurationSection signSection = configuration.getConfigurationSection("signs");
|
|
managedSigns = new HashMap<>();
|
|
if (signSection == null) {
|
|
PermissionSigns.getInstance().getLogger().log(Level.WARNING, "Signs section not found in data.yml");
|
|
return;
|
|
}
|
|
for (String key : signSection.getKeys(false)) {
|
|
try {
|
|
loadSign(signSection, key);
|
|
} catch (InvalidConfigurationException e) {
|
|
PermissionSigns.getInstance().getLogger().log(Level.SEVERE, "Unable to load sign " + key + ": " +
|
|
e.getMessage());
|
|
}
|
|
}
|
|
|
|
//Re-draw all signs in a separate thread
|
|
redrawSigns();
|
|
}
|
|
|
|
/**
|
|
* Re-draws all loaded signs in case something changed
|
|
*/
|
|
private static void redrawSigns() {
|
|
Bukkit.getScheduler().scheduleSyncDelayedTask(PermissionSigns.getInstance(), () -> {
|
|
List<Location> invalidPermissionSigns = new ArrayList<>();
|
|
for (Location key : managedSigns.keySet()) {
|
|
PermissionSign permissionSign = managedSigns.get(key);
|
|
Block signBlock = key.getBlock();
|
|
BlockState state = signBlock.getState();
|
|
if (!(state instanceof Sign sign)) {
|
|
if (PermissionSigns.removePermissionSignIfMissing()) {
|
|
invalidPermissionSigns.add(permissionSign.getSignLocation());
|
|
}
|
|
continue;
|
|
}
|
|
String[] newLines = permissionSign.getSignLines();
|
|
if (Arrays.equals(sign.getLines(), newLines)) {
|
|
continue;
|
|
}
|
|
for (int i = 0; i < 4; i++) {
|
|
sign.setLine(i, newLines[i]);
|
|
}
|
|
sign.update();
|
|
}
|
|
for (Location signLocation : invalidPermissionSigns) {
|
|
SignManager.removeSign(signLocation);
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Tries to save signs and handles any errors
|
|
*/
|
|
private static void save() {
|
|
try {
|
|
saveSigns();
|
|
} catch (IOException e) {
|
|
PermissionSigns.getInstance().getLogger().log(Level.SEVERE, "Unable to save signs: " + e.getMessage());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Loads a sign from the save file
|
|
*
|
|
* @param signSection <p>The configuration section containing signs</p>
|
|
* @param key <p>The sign key which is also the sign's location</p>
|
|
* @throws InvalidConfigurationException <p>If unable to load the sign</p>
|
|
*/
|
|
private static void loadSign(ConfigurationSection signSection, String key) throws InvalidConfigurationException {
|
|
String[] locationParts = key.split(",");
|
|
Location signLocation;
|
|
try {
|
|
signLocation = new Location(Bukkit.getWorld(UUID.fromString(locationParts[0])),
|
|
Double.parseDouble(locationParts[1]), Double.parseDouble(locationParts[2]),
|
|
Double.parseDouble(locationParts[3]));
|
|
} catch (NumberFormatException exception) {
|
|
throw new InvalidConfigurationException("Invalid sign coordinates");
|
|
}
|
|
|
|
String signName = signSection.getString(key + ".name");
|
|
if (signName == null) {
|
|
throw new IllegalArgumentException("Name missing from sign data");
|
|
}
|
|
|
|
List<String> permissionStrings = new ArrayList<>();
|
|
List<?> permissions = signSection.getList(key + ".permissions");
|
|
if (permissions == null) {
|
|
throw new IllegalArgumentException("Permission list missing from sign data");
|
|
}
|
|
permissions.forEach((item) -> {
|
|
if (item instanceof String) {
|
|
permissionStrings.add((String) item);
|
|
}
|
|
});
|
|
|
|
int duration = signSection.getInt(key + ".duration");
|
|
double cost = signSection.getDouble(key + ".cost");
|
|
|
|
PermissionSign loadedSign = new PermissionSign(signLocation, signName, permissionStrings, duration, cost);
|
|
managedSigns.put(signLocation, loadedSign);
|
|
}
|
|
|
|
}
|