172 lines
7.0 KiB
Java
172 lines
7.0 KiB
Java
package net.knarcraft.paidsigns.manager;
|
|
|
|
import net.knarcraft.paidsigns.PaidSigns;
|
|
import net.knarcraft.paidsigns.container.TrackedSign;
|
|
import net.knarcraft.paidsigns.formatting.PaidSignsTranslatableMessage;
|
|
import net.knarcraft.paidsigns.utility.SignHelper;
|
|
import org.bukkit.Bukkit;
|
|
import org.bukkit.Location;
|
|
import org.bukkit.OfflinePlayer;
|
|
import org.bukkit.configuration.ConfigurationSection;
|
|
import org.bukkit.configuration.file.YamlConfiguration;
|
|
import org.bukkit.entity.Player;
|
|
|
|
import java.io.File;
|
|
import java.io.IOException;
|
|
import java.util.HashMap;
|
|
import java.util.Map;
|
|
import java.util.Objects;
|
|
import java.util.UUID;
|
|
import java.util.logging.Level;
|
|
|
|
/**
|
|
* A manager for keeping track of plugin-signs created by players
|
|
*/
|
|
public final class TrackedSignManager {
|
|
|
|
private static Map<Location, TrackedSign> trackedSigns = new HashMap<>();
|
|
private static final File signsFile = new File(PaidSigns.getInstance().getDataFolder(), "data.yml");
|
|
|
|
private TrackedSignManager() {
|
|
|
|
}
|
|
|
|
/**
|
|
* Adds a tracked sign to the manager
|
|
*
|
|
* @param signLocation <p>The location the sign was created at</p>
|
|
* @param playerId <p>The unique id of the player that created the sign</p>
|
|
* @throws IOException <p>If unable to save the tracked signs</p>
|
|
*/
|
|
public static void addTrackedSign(Location signLocation, UUID playerId, double cost) throws IOException {
|
|
trackedSigns.put(signLocation, new TrackedSign(playerId, cost));
|
|
saveTrackedSigns();
|
|
}
|
|
|
|
/**
|
|
* Removes a tracked sign from the manager
|
|
*
|
|
* @param signLocation <p>The location the sign was removed from</p>
|
|
* @param refund <p>Whether to perform a refund after un-tracking the sign</p>
|
|
* @param forceRefund <p>Whether to force a refund, even if refunding is disabled</p>
|
|
* @throws IOException <p>If unable to save the tracked signs</p>
|
|
*/
|
|
public static void removeTrackedSign(Location signLocation, boolean refund, boolean forceRefund) throws IOException {
|
|
if (!trackedSigns.containsKey(signLocation)) {
|
|
return;
|
|
}
|
|
TrackedSign trackedSign = trackedSigns.get(signLocation);
|
|
trackedSigns.remove(signLocation);
|
|
saveTrackedSigns();
|
|
refund(trackedSign, refund, forceRefund);
|
|
}
|
|
|
|
/**
|
|
* Loads all tracked signs from the data file
|
|
*/
|
|
public static void loadTrackedSigns() {
|
|
YamlConfiguration configuration = YamlConfiguration.loadConfiguration(signsFile);
|
|
ConfigurationSection signSection = configuration.getConfigurationSection("trackedSigns");
|
|
trackedSigns = new HashMap<>();
|
|
|
|
if (signSection == null) {
|
|
PaidSigns.getInstance().getLogger().log(Level.INFO, "Tracked signs section not found in data.yml");
|
|
return;
|
|
}
|
|
|
|
for (String key : signSection.getKeys(false)) {
|
|
loadSign(signSection, key);
|
|
}
|
|
|
|
//Save tracked signs in case some were invalidated after loading
|
|
try {
|
|
TrackedSignManager.saveTrackedSigns();
|
|
} catch (IOException e) {
|
|
PaidSigns.getInstance().getLogger().log(Level.WARNING, "Unable to save tracked signs");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 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>
|
|
*/
|
|
private static void loadSign(ConfigurationSection signSection, String key) {
|
|
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) {
|
|
PaidSigns.getInstance().getLogger().log(Level.SEVERE, "Unable to load tracked sign " + key + ": " +
|
|
exception.getMessage());
|
|
return;
|
|
}
|
|
|
|
double cost = signSection.getDouble(key + ".cost");
|
|
UUID playerId = UUID.fromString(Objects.requireNonNull(signSection.getString(key + ".playerId")));
|
|
TrackedSign trackedSign = new TrackedSign(playerId, cost);
|
|
|
|
//Prevent destroyed signs from being tracked indefinitely
|
|
if (!SignHelper.isSign(signLocation.getBlock())) {
|
|
Bukkit.getScheduler().scheduleSyncDelayedTask(PaidSigns.getInstance(), () -> {
|
|
PaidSigns.getInstance().getLogger().log(Level.WARNING, "The sign at " + signLocation +
|
|
" no longer exists. Removing from sign tracker. Refunding the player.");
|
|
refund(trackedSign, true, false);
|
|
}, 100);
|
|
return;
|
|
}
|
|
|
|
trackedSigns.put(signLocation, trackedSign);
|
|
}
|
|
|
|
/**
|
|
* Saves the managed tracked signs to the data file
|
|
*
|
|
* @throws IOException <p>If unable to write to the data file</p>
|
|
*/
|
|
public static void saveTrackedSigns() throws IOException {
|
|
YamlConfiguration configuration = YamlConfiguration.loadConfiguration(signsFile);
|
|
ConfigurationSection signSection = configuration.createSection("trackedSigns");
|
|
|
|
for (Location signLocation : trackedSigns.keySet()) {
|
|
TrackedSign sign = trackedSigns.get(signLocation);
|
|
String locationString = Objects.requireNonNull(signLocation.getWorld()).getUID() + "," +
|
|
signLocation.getBlockX() + "," + signLocation.getBlockY() + "," + signLocation.getBlockZ();
|
|
signSection.set(locationString + ".cost", sign.cost());
|
|
signSection.set(locationString + ".playerId", sign.playerId().toString());
|
|
}
|
|
configuration.save(signsFile);
|
|
}
|
|
|
|
/**
|
|
* Refunds the player for the sign if refunds are enabled and refund is set to true
|
|
*
|
|
* @param trackedSign <p>The tracked sign to refund for</p>
|
|
* @param refund <p>Whether to actually refund</p>
|
|
* @param forceRefund <p>Whether to force a refund, even if refunding is disabled</p>
|
|
*/
|
|
private static void refund(TrackedSign trackedSign, boolean refund, boolean forceRefund) {
|
|
if ((!PaidSigns.getInstance().areRefundsEnabled() || !refund) && !forceRefund) {
|
|
return;
|
|
}
|
|
OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(trackedSign.playerId());
|
|
double refundSum;
|
|
if (forceRefund) {
|
|
//In the case where a refund is forced, the normal refund rate should not apply
|
|
refundSum = trackedSign.cost();
|
|
} else {
|
|
refundSum = trackedSign.cost() / 100 * PaidSigns.getInstance().getRefundPercentage();
|
|
}
|
|
EconomyManager.deposit(offlinePlayer, refundSum);
|
|
if (offlinePlayer instanceof Player player) {
|
|
PaidSigns.getStringFormatter().displaySuccessMessage(player,
|
|
PaidSigns.getStringFormatter().replacePlaceholder(PaidSignsTranslatableMessage.SUCCESS_REFUNDED,
|
|
"{cost}", EconomyManager.format(refundSum)));
|
|
}
|
|
}
|
|
|
|
}
|