package me.desht.scrollingmenusign.commandlets;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import me.desht.dhutils.Debugger;
import me.desht.dhutils.Duration;
import me.desht.dhutils.LogUtils;
import me.desht.scrollingmenusign.DirectoryStructure;
import me.desht.scrollingmenusign.SMSException;
import me.desht.scrollingmenusign.SMSValidate;
import me.desht.scrollingmenusign.ScrollingMenuSign;
import me.desht.scrollingmenusign.enums.ReturnStatus;
import me.desht.scrollingmenusign.parser.CommandUtils;
import me.desht.scrollingmenusign.views.CommandTrigger;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.server.PluginDisableEvent;
import org.bukkit.scheduler.BukkitTask;
import com.google.common.base.Joiner;
public class CooldownCommandlet extends BaseCommandlet implements Listener {
private static final String COOLDOWNS_YML = "cooldowns.yml";
private final Map<String, Long> cooldowns = new HashMap<String, Long>();
private BukkitTask saveTask;
private long lastCooldownTime = 0L;
public CooldownCommandlet() {
super("COOLDOWN");
load();
Bukkit.getPluginManager().registerEvents(this, ScrollingMenuSign.getInstance());
}
@EventHandler
public void onDisable(PluginDisableEvent event) {
if (event.getPlugin() == ScrollingMenuSign.getInstance()) {
save();
}
}
@Override
public boolean execute(ScrollingMenuSign plugin, CommandSender sender, CommandTrigger trigger, String cmd, String[] args) {
SMSValidate.isTrue(args.length >= 4, "Usage: " + cmd + " <cooldown-name> <delay> <command string>");
String cooldownName = args[1];
Duration delay;
try {
delay = new Duration(args[2]);
} catch (IllegalArgumentException e) {
throw new SMSException("Invalid duration: " + args[2]);
}
final String command = Joiner.on(" ").join(Arrays.copyOfRange(args, 3, args.length));
lastCooldownTime = getCooldownRemaining(sender, cooldownName, delay.getTotalDuration());
if (lastCooldownTime > 0) {
return false;
} else {
CommandUtils.executeCommand(sender, command, trigger);
updateCooldown(sender, cooldownName);
ReturnStatus rs = CommandUtils.getLastReturnStatus();
return rs == ReturnStatus.CMD_OK || rs == ReturnStatus.UNKNOWN;
}
}
private long getCooldownRemaining(CommandSender sender, String name, long delay) {
String key = makeKey(name, sender.getName());
if (!cooldowns.containsKey(key)) {
cooldowns.put(key, 0L);
}
long last = cooldowns.get(key);
Debugger.getInstance().debug("cooldown: " + key + "=" + last + ", delay = " + delay);
return delay - (System.currentTimeMillis() - last);
}
public long getLastCooldownTimeRemaining() {
return lastCooldownTime;
}
private void updateCooldown(CommandSender sender, String name) {
String key = makeKey(name, sender.getName());
cooldowns.put(key, System.currentTimeMillis());
if (saveTask == null) {
saveTask = Bukkit.getScheduler().runTaskLater(ScrollingMenuSign.getInstance(), new Runnable() {
@Override
public void run() {
save();
}
}, 600L);
}
}
private boolean isOnCooldown(CommandSender sender, String name, long delay) {
String key = makeKey(name, sender.getName());
if (!cooldowns.containsKey(key)) {
cooldowns.put(key, 0L);
}
long last = cooldowns.get(key);
Debugger.getInstance().debug("cooldown: " + key + "=" + last + ", delay = " + delay);
return System.currentTimeMillis() - last < delay;
}
private String makeKey(String cooldownName, String player) {
return cooldownName.toLowerCase().startsWith("global:") ? cooldownName : player + "," + cooldownName;
}
public void save() {
File saveFile = new File(DirectoryStructure.getDataFolder(), COOLDOWNS_YML);
YamlConfiguration conf = new YamlConfiguration();
for (Entry<String, Long> e : cooldowns.entrySet()) {
conf.set(e.getKey(), e.getValue());
}
try {
Debugger.getInstance().debug("saving cooldown data");
conf.save(saveFile);
saveTask = null;
} catch (IOException e) {
LogUtils.warning("can't save " + saveFile + ": " + e.getMessage());
}
}
public void load() {
File saveFile = new File(DirectoryStructure.getDataFolder(), COOLDOWNS_YML);
cooldowns.clear();
YamlConfiguration conf = new YamlConfiguration();
try {
if (saveFile.exists()) {
Debugger.getInstance().debug("loading cooldown data");
conf.load(saveFile);
for (String k : conf.getKeys(false)) {
cooldowns.put(k, conf.getLong(k));
}
}
} catch (Exception e) {
LogUtils.warning("can't load " + saveFile + ": " + e.getMessage());
}
}
}