diff --git a/pom.xml b/pom.xml
index 81dbe909..1ea983b2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
com.massivecraft
Factions
- 1.6.9.5-2.3.2-RC
+ 1.6.9.5-2.3.3-RC
jar
SaberFactions
diff --git a/src/main/java/com/massivecraft/factions/Conf.java b/src/main/java/com/massivecraft/factions/Conf.java
index da0bb7e5..39383305 100644
--- a/src/main/java/com/massivecraft/factions/Conf.java
+++ b/src/main/java/com/massivecraft/factions/Conf.java
@@ -22,6 +22,7 @@ public class Conf {
public static final transient String DYNMAP_STYLE_HOME_MARKER = "greenflag";
public static final transient boolean DYNMAP_STYLE_BOOST = false;
public static List baseCommandAliases = new ArrayList<>();
+ public static String serverTimeZone = "EST";
public static boolean allowNoSlashCommand = true;
// Colors
@@ -54,8 +55,8 @@ public class Conf {
public static boolean factionTagForceUpperCase = false;
public static boolean newFactionsDefaultOpen = false;
// when faction membership hits this limit, players will no longer be able to join using /f join; default is 0, no limit
- public static int factionMemberLimit = 0;
- public static int factionAltMemberLimit = 0;
+ public static int factionMemberLimit = 30;
+ public static int factionAltMemberLimit = 10;
// what faction ID to start new players in when they first join the server; default is 0, "no faction"
public static String newPlayerStartingFactionID = "0";
public static boolean showMapFactionKey = true;
@@ -86,7 +87,9 @@ public class Conf {
public static int factionBufferSize = 20;
public static boolean useCheckSystem = true;
public static boolean spawnerLock = false;
- public static boolean gracePeriod = false;
+ public static boolean useGraceSystem = true;
+ public static boolean broadcastGraceToggles = true;
+ public static int gracePeriodTimeDays = 7;
public static boolean noEnderpearlsInFly = false;
public static boolean broadcastDescriptionChanges = false;
public static boolean broadcastTagChanges = false;
diff --git a/src/main/java/com/massivecraft/factions/FactionsPlugin.java b/src/main/java/com/massivecraft/factions/FactionsPlugin.java
index ceb65004..67971470 100755
--- a/src/main/java/com/massivecraft/factions/FactionsPlugin.java
+++ b/src/main/java/com/massivecraft/factions/FactionsPlugin.java
@@ -26,6 +26,7 @@ import com.massivecraft.factions.struct.Relation;
import com.massivecraft.factions.struct.Role;
import com.massivecraft.factions.util.*;
import com.massivecraft.factions.util.adapters.*;
+import com.massivecraft.factions.util.timer.TimerManager;
import com.massivecraft.factions.util.wait.WaitExecutor;
import com.massivecraft.factions.zcore.CommandVisibility;
import com.massivecraft.factions.zcore.MPlugin;
@@ -34,7 +35,6 @@ import com.massivecraft.factions.zcore.fperms.Access;
import com.massivecraft.factions.zcore.fperms.Permissable;
import com.massivecraft.factions.zcore.fperms.PermissableAction;
import com.massivecraft.factions.zcore.frame.fupgrades.UpgradesListener;
-import com.massivecraft.factions.zcore.util.TextUtil;
import me.lucko.commodore.CommodoreProvider;
import net.milkbowl.vault.economy.Economy;
import net.milkbowl.vault.permission.Permission;
@@ -97,6 +97,7 @@ public class FactionsPlugin extends MPlugin {
private FLogManager fLogManager;
private List reserveObjects;
private FileManager fileManager;
+ private TimerManager timerManager;
public FactionsPlugin() {
instance = this;
@@ -278,6 +279,10 @@ public class FactionsPlugin extends MPlugin {
fLogManager.loadLogs(this);
+ this.timerManager = new TimerManager(this);
+ this.timerManager.reloadTimerData();
+ System.out.println("[SABER-FACTIONS] - Loaded " + timerManager.getTimers().size() + " timers into list!");
+
getServer().getPluginManager().registerEvents(factionsPlayerListener = new FactionsPlayerListener(), this);
// Register Event Handlers
@@ -290,6 +295,7 @@ public class FactionsPlugin extends MPlugin {
new MissionHandler(this),
new FChestListener(),
new MenuListener(),
+ timerManager.graceTimer,
new AntiChestListener()
};
@@ -318,6 +324,7 @@ public class FactionsPlugin extends MPlugin {
} catch (Exception e) {
e.printStackTrace();
}
+
if (getDescription().getFullName().contains("BETA")) {
divider();
System.out.println("You are using a BETA version of the plugin!");
@@ -443,6 +450,8 @@ public class FactionsPlugin extends MPlugin {
@Override
public void onDisable() {
+ super.onDisable();
+ timerManager.saveTimerData();
try {
String path = Paths.get(getDataFolder().getAbsolutePath()).toAbsolutePath().toString() + File.separator + "reserves.json";
File file = new File(path);
@@ -467,7 +476,6 @@ public class FactionsPlugin extends MPlugin {
if (Discord.jda != null) {
Discord.jda.shutdownNow();
}
- super.onDisable();
try {
fLogManager.saveLogs();
} catch (Exception e) {
@@ -527,14 +535,6 @@ public class FactionsPlugin extends MPlugin {
return sender instanceof Player && FactionsPlayerListener.preventCommand(commandString, (Player) sender) || super.handleCommand(sender, commandString, testOnly);
}
- @Override
- public boolean onCommand(CommandSender sender, Command command, String label, String[] split) {
- if (split.length == 0) return handleCommand(sender, "/f help", false);
-
- // otherwise, needs to be handled; presumably another plugin directly ran the command
- String cmd = Conf.baseCommandAliases.isEmpty() ? "/f" : "/" + Conf.baseCommandAliases.get(0);
- return handleCommand(sender, cmd + " " + TextUtil.implode(Arrays.asList(split), " "), false);
- }
// This method must stay for < 1.12 versions
@Override
@@ -721,6 +721,10 @@ public class FactionsPlugin extends MPlugin {
return perms == null || !perms.hasGroupSupport() ? " " : perms.getPrimaryGroup(Bukkit.getWorlds().get(0).toString(), player);
}
+ public TimerManager getTimerManager() {
+ return timerManager;
+ }
+
public void debug(Level level, String s) {
if (getConfig().getBoolean("debug", false)) getLogger().log(level, s);
}
diff --git a/src/main/java/com/massivecraft/factions/cmd/CmdSaveAll.java b/src/main/java/com/massivecraft/factions/cmd/CmdSaveAll.java
index 99c8ae49..22d35130 100644
--- a/src/main/java/com/massivecraft/factions/cmd/CmdSaveAll.java
+++ b/src/main/java/com/massivecraft/factions/cmd/CmdSaveAll.java
@@ -24,6 +24,7 @@ public class CmdSaveAll extends FCommand {
Factions.getInstance().forceSave(false);
Board.getInstance().forceSave(false);
Conf.save();
+ FactionsPlugin.getInstance().getTimerManager().saveTimerData();
try {
FactionsPlugin.instance.getFlogManager().saveLogs();
} catch (Exception e) {
diff --git a/src/main/java/com/massivecraft/factions/cmd/FCmdRoot.java b/src/main/java/com/massivecraft/factions/cmd/FCmdRoot.java
index a6d6b218..6b2298dd 100644
--- a/src/main/java/com/massivecraft/factions/cmd/FCmdRoot.java
+++ b/src/main/java/com/massivecraft/factions/cmd/FCmdRoot.java
@@ -8,7 +8,6 @@ import com.massivecraft.factions.cmd.check.CmdCheck;
import com.massivecraft.factions.cmd.check.CmdWeeWoo;
import com.massivecraft.factions.cmd.chest.CmdChest;
import com.massivecraft.factions.cmd.claim.*;
-import com.massivecraft.factions.cmd.configsf.CmdConvertConfig;
import com.massivecraft.factions.cmd.econ.CmdMoney;
import com.massivecraft.factions.cmd.grace.CmdGrace;
import com.massivecraft.factions.cmd.logout.CmdLogout;
@@ -156,7 +155,6 @@ public class FCmdRoot extends FCommand implements CommandExecutor {
public CmdCheck cmdCheck = new CmdCheck();
public CmdWeeWoo cmdWeeWoo = new CmdWeeWoo();
public CmdWild cmdWild = new CmdWild();
- public CmdConvertConfig cmdConvertConfig = new CmdConvertConfig();
public CmdSpawnerLock cmdSpawnerLock = new CmdSpawnerLock();
public CmdSetDiscord cmdSetDiscord = new CmdSetDiscord();
public CmdSeeDiscord cmdSeeDiscord = new CmdSeeDiscord();
@@ -302,7 +300,6 @@ public class FCmdRoot extends FCommand implements CommandExecutor {
this.addSubCommand(this.cmdCorner);
this.addSubCommand(this.cmdFGlobal);
this.addSubCommand(this.cmdViewChest);
- this.addSubCommand(this.cmdConvertConfig);
this.addSubCommand(this.cmdSpawnerLock);
this.addSubCommand(this.cmdDrain);
this.addSubCommand(this.cmdLookup);
diff --git a/src/main/java/com/massivecraft/factions/cmd/configsf/CmdConvertConfig.java b/src/main/java/com/massivecraft/factions/cmd/configsf/CmdConvertConfig.java
deleted file mode 100644
index 73ada76e..00000000
--- a/src/main/java/com/massivecraft/factions/cmd/configsf/CmdConvertConfig.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package com.massivecraft.factions.cmd.configsf;
-
-import com.massivecraft.factions.cmd.CommandContext;
-import com.massivecraft.factions.cmd.CommandRequirements;
-import com.massivecraft.factions.cmd.FCommand;
-import com.massivecraft.factions.struct.Permission;
-import com.massivecraft.factions.zcore.util.TL;
-
-public class CmdConvertConfig extends FCommand {
-
- public CmdConvertConfig() {
- super();
- this.aliases.add("convertconfig");
-
- this.requirements = new CommandRequirements.Builder(Permission.CONVERTCONFIG)
- .playerOnly()
- .build();
- }
-
- @Override
- public void perform(CommandContext context) {
- ConvertConfigHandler.convertconfig(context.player);
- }
-
- @Override
- public TL getUsageTranslation() {
- return TL.COMMAND_CONVERTCONFIG_DESCRIPTION;
- }
-}
diff --git a/src/main/java/com/massivecraft/factions/cmd/configsf/ConvertConfigHandler.java b/src/main/java/com/massivecraft/factions/cmd/configsf/ConvertConfigHandler.java
deleted file mode 100644
index f7fdc93a..00000000
--- a/src/main/java/com/massivecraft/factions/cmd/configsf/ConvertConfigHandler.java
+++ /dev/null
@@ -1,147 +0,0 @@
-package com.massivecraft.factions.cmd.configsf;
-
-import com.massivecraft.factions.FactionsPlugin;
-import com.massivecraft.factions.zcore.util.TL;
-import org.bukkit.Bukkit;
-import org.bukkit.configuration.ConfigurationSection;
-import org.bukkit.configuration.file.FileConfiguration;
-import org.bukkit.configuration.file.YamlConfiguration;
-import org.bukkit.entity.Player;
-import org.bukkit.plugin.java.JavaPlugin;
-import org.bukkit.scheduler.BukkitScheduler;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.logging.Level;
-
-public class ConvertConfigHandler {
-
- static File savageConfigFile = new File("plugins/Factions/SavageFactions/config.yml");
- static FileConfiguration sv = YamlConfiguration.loadConfiguration(savageConfigFile);
- static File configFile = new File("plugins/Factions/config.yml");
- static FileConfiguration sb = YamlConfiguration.loadConfiguration(configFile);
- static JavaPlugin plugin = JavaPlugin.getProvidingPlugin(FactionsPlugin.class);
-
- public static void setString(String s) {
- sb.set(s, sv.getString(s));
- }
-
- public static void setInt(String s) {
- sb.set(s, sv.getInt(s));
- }
-
- public static void setConfigSec(String s) {
- ConfigurationSection cs = sv.getConfigurationSection(s);
- sb.set(s, cs);
- }
-
- public static void setBoolean(String s) {
- sb.set(s, sv.getBoolean(s));
- }
-
- public static void convertconfig(Player player) {
- if (new File("plugins/Factions/SavageFactions/config.yml").exists()) {
- BukkitScheduler scheduler = plugin.getServer().getScheduler();
- scheduler.scheduleAsyncDelayedTask(plugin, () -> {
- File savageConfigFile = new File("plugins/Factions/SavageFactions/config.yml");
- FileConfiguration sv = YamlConfiguration.loadConfiguration(savageConfigFile);
- File configFile = new File("plugins/Factions/config.yml");
- FileConfiguration sb = YamlConfiguration.loadConfiguration(configFile);
- sb.set("ConfigConvertedFromSavageFactions", true);
- sb.set("debug", sv.getBoolean("debug"));
- ConfigurationSection ffe = sv.getConfigurationSection("findfactionsexploit");
- sb.set("findfactionsexploit", ffe);
- setString("default-relation");
- ConfigurationSection pC = sv.getConfigurationSection("portals");
- sb.set("portals", pC);
- sb.set("maxwarps", sv.getInt("maxwarps"));
- setConfigSec("warp-cost");
- setBoolean("enable-faction-flight");
- setBoolean("ffly.AutoEnable");
- setInt("fly-falldamage-cooldown");
- setBoolean("disable-pistons-in-territory");
- setConfigSec("tooltips");
- setConfigSec("scoreboard");
- sb.set("scoreboard.also-send-chat", true);
- setConfigSec("warmups");
- setConfigSec("max-relations");
- setInt("world-border.buffer");
- setConfigSec("hcf");
- sb.set("show", sv.getStringList("show"));
- setBoolean("show-exempt");
- sb.set("map", sv.getStringList("map"));
- setConfigSec("list");
- setBoolean("use-old-help");
- setConfigSec("help");
- setConfigSec("fperm-gui");
- sb.set("fperm-gui.action.slots.check", 50);
- setConfigSec("fwarp-gui");
- setBoolean("faction-creation-broadcast");
- setBoolean("faction-disband-broadcast");
- setBoolean("See-Invisible-Faction-Members");
- setConfigSec("frules");
- setConfigSec("ftnt");
- setBoolean("fpaypal.Enabled");
- setBoolean("checkpoints.Enabled");
- setConfigSec("fnear");
- setConfigSec("ffocus");
- setConfigSec("fvualt");
- setString("fupgrades.MainMenu.Title");
- setString("fupgrades.MainMenu.DummyItem.Name");
- setString("fupgrades.MainMenu.DummyItem.Type");
- List l = sv.getStringList("fupgrades.MainMenu.DummyItem.Lore");
- sb.set("fupgrades.MainMenu.DummyItem.Lore", l);
- setConfigSec("fupgrades.MainMenu.Crops.Crop-Boost");
- setConfigSec("fupgrades.MainMenu.Crops.Cost");
- sb.set("fupgrades.MainMenu.Crops.CropItem", sv.getConfigurationSection("fupgrades.MainMenu.Crops.DisplayItem"));
- setConfigSec("fupgrades.MainMenu.EXP.EXP-Boost");
- setConfigSec("fupgrades.MainMenu.EXP.Cost");
- sb.set("fupgrades.MainMenu.EXP.EXPItem", sv.getConfigurationSection("fupgrades.MainMenu.EXP.DisplayItem"));
- setConfigSec("fupgrades.MainMenu.Power.Power-Boost");
- setConfigSec("fupgrades.MainMenu.Power.Cost");
- sb.set("fupgrades.MainMenu.Power.PowerItem", sv.getConfigurationSection("fupgrades.MainMenu.Power.DisplayItem"));
- List p = new ArrayList();
- p.add(sv.getInt("fupgrades.MainMenu.Power.DisplayItem.Slot"));
- sb.set("fupgrades.MainMenu.Power.PowerItem.slots", p);
- sb.set("fupgrades.MainMenu.Power.PowerItem.Amount", 1);
- sb.set("fupgrades.MainMenu.Power.PowerItem.Damage", 0);
- sb.set("fupgrades.MainMenu.Power.PowerItem.Slot", null);
- sb.set("fupgrades.MainMenu.Members.Members-Limit", sv.getConfigurationSection("fupgrades.MainMenu.Members.Members-Boost"));
- setConfigSec("fupgrades.MainMenu.Spawners.Spawner-Boost");
- setConfigSec("fupgrades.MainMenu.Spawners.Cost");
- sb.set("fupgrades.MainMenu.Spawners.SpawnerItem", sv.getConfigurationSection("fupgrades.MainMenu.Spawners.DisplayItem"));
- setConfigSec("fupgrades.MainMenu.Chest.Chest-Size");
- setConfigSec("fupgrades.MainMenu.Chest.Cost");
- sb.set("fupgrades.MainMenu.Chest.ChestItem", sv.getConfigurationSection("fupgrades.MainMenu.Chest.DisplayItem"));
- setConfigSec("fupgrades.MainMenu.Members.Cost");
- sb.set("fupgrades.MainMenu.Members.MembersItem", sv.getConfigurationSection("fupgrades.MainMenu.Members.DisplayItem"));
- sb.set("fupgrades.MainMenu.Members.MembersItem.Amount", 1);
- sb.set("fupgrades.MainMenu.Members.MembersItem.Damage", 0);
- if (sv.getString("fupgrades.MainMenu.Members.DisplayItem.Type").equalsIgnoreCase("PLAYER_HEAD"))
- sb.set("fupgrades.MainMenu.Members.MembersItem.Type", "PAPER");
- List x = new ArrayList();
- x.add(sv.getInt("fupgrades.MainMenu.Members.DisplayItem.Slot"));
- sb.set("fupgrades.MainMenu.Members.MembersItem.slots", x);
- sb.set("fupgrades.MainMenu.Members.MembersItem.Slot", null);
- sb.set("fupgrades.MainMenu.Members.Members-Limit", sv.getConfigurationSection("fupgrades.MainMenu.Members.Members-Boost"));
- setConfigSec("fbanners");
- setConfigSec("see-chunk");
- setConfigSec("Tntfill");
- try {
- sb.save(configFile);
- plugin.reloadConfig();
- } catch (IOException e) {
- player.sendMessage(TL.COMMAND_CONVERTCONFIG_FAIL.toString());
- Bukkit.getLogger().log(Level.SEVERE, Arrays.toString(e.getStackTrace()));
- }
- player.sendMessage(TL.COMMAND_CONVERTCONFIG_SUCCESS.toString());
- }, 0L);
- } else {
- player.sendMessage(TL.COMMAND_CONVERTCONFIG_FAILCONFIGMISSING.toString());
- }
- }
-
-}
diff --git a/src/main/java/com/massivecraft/factions/cmd/grace/CmdGrace.java b/src/main/java/com/massivecraft/factions/cmd/grace/CmdGrace.java
index 170a057e..de6f5894 100644
--- a/src/main/java/com/massivecraft/factions/cmd/grace/CmdGrace.java
+++ b/src/main/java/com/massivecraft/factions/cmd/grace/CmdGrace.java
@@ -1,35 +1,73 @@
package com.massivecraft.factions.cmd.grace;
import com.massivecraft.factions.Conf;
+import com.massivecraft.factions.FPlayer;
+import com.massivecraft.factions.FPlayers;
import com.massivecraft.factions.FactionsPlugin;
import com.massivecraft.factions.cmd.Aliases;
import com.massivecraft.factions.cmd.CommandContext;
import com.massivecraft.factions.cmd.CommandRequirements;
import com.massivecraft.factions.cmd.FCommand;
import com.massivecraft.factions.struct.Permission;
+import com.massivecraft.factions.util.timer.TimerManager;
import com.massivecraft.factions.zcore.util.TL;
+import java.util.concurrent.TimeUnit;
+
public class CmdGrace extends FCommand {
/**
* @author Driftay
*/
- //TODO: Make Timed Format For Grace Period
public CmdGrace() {
super();
this.aliases.addAll(Aliases.grace);
+ this.optionalArgs.put("on/off", "toggle");
+
this.requirements = new CommandRequirements.Builder(Permission.GRACE)
.build();
}
@Override
public void perform(CommandContext context) {
- Conf.gracePeriod = !Conf.gracePeriod;
- context.msg(TL.COMMAND_GRACE_TOGGLE, Conf.gracePeriod ? FactionsPlugin.getInstance().color("&aEnabled") : FactionsPlugin.getInstance().color("&4Disabled"));
- }
+ if (!Conf.useGraceSystem) {
+ context.msg(TL.GENERIC_DISABLED, "factions grace");
+ return;
+ }
+ if(context.args.size() == 1) {
+ if (context.sender.hasPermission(String.valueOf(Permission.GRACETOGGLE))) {
+ if (context.argAsString(0).equalsIgnoreCase("on") || context.argAsString(0).equalsIgnoreCase("start")) {
+ FactionsPlugin.getInstance().getTimerManager().graceTimer.setPaused(false);
+ FactionsPlugin.getInstance().getTimerManager().graceTimer.setRemaining(TimeUnit.DAYS.toMillis(Conf.gracePeriodTimeDays), true);
+ if (Conf.broadcastGraceToggles) {
+ for (FPlayer follower : FPlayers.getInstance().getOnlinePlayers())
+ follower.msg(TL.COMMAND_GRACE_ENABLED_FORMAT, String.valueOf(TimerManager.getRemaining(FactionsPlugin.getInstance().getTimerManager().graceTimer.getRemaining(), true)));
+ }
+ return;
+ }
+
+ if (context.argAsString(0).equalsIgnoreCase("off") || context.argAsString(0).equalsIgnoreCase("stop")) {
+ FactionsPlugin.getInstance().getTimerManager().graceTimer.setRemaining(TimeUnit.SECONDS.toMillis(0L), true);
+ FactionsPlugin.getInstance().getTimerManager().graceTimer.setPaused(false);
+ if (Conf.broadcastGraceToggles) {
+ for (FPlayer follower : FPlayers.getInstance().getOnlinePlayers())
+ follower.msg(TL.COMMAND_GRACE_DISABLED_FORMAT);
+ }
+ return;
+ }
+ }
+ }
+
+ if(FactionsPlugin.getInstance().getTimerManager().graceTimer.getRemaining() <= 0L) {
+ context.fPlayer.msg(TL.COMMAND_GRACE_DISABLED_NO_FORMAT.toString());
+ } else {
+ context.fPlayer.msg(TL.COMMAND_GRACE_TIME_REMAINING, String.valueOf(TimerManager.getRemaining(FactionsPlugin.getInstance().getTimerManager().graceTimer.getRemaining(), true)));
+ }
+
+ }
@Override
public TL getUsageTranslation() {
diff --git a/src/main/java/com/massivecraft/factions/listeners/FactionsBlockListener.java b/src/main/java/com/massivecraft/factions/listeners/FactionsBlockListener.java
index e4a19149..fb0cc063 100644
--- a/src/main/java/com/massivecraft/factions/listeners/FactionsBlockListener.java
+++ b/src/main/java/com/massivecraft/factions/listeners/FactionsBlockListener.java
@@ -440,29 +440,6 @@ public class FactionsBlockListener implements Listener {
}
}
- //Grace
- @EventHandler
- public void onBreak(EntityExplodeEvent e) {
- if (!Conf.gracePeriod) return;
-
- e.setCancelled(true);
- }
-
-
- @EventHandler
- public void onTNTPlace(BlockPlaceEvent e1) {
- FPlayer fp = FPlayers.getInstance().getByPlayer(e1.getPlayer());
- if (!Conf.gracePeriod) return;
-
- if (!fp.isAdminBypassing()) {
- if (e1.getBlock().getType().equals(Material.TNT)) {
- e1.setCancelled(true);
-
- fp.msg(TL.COMMAND_GRACE_ENABLED, e1.getBlockPlaced().getType().toString());
- }
- }
- }
-
private boolean canPistonMoveBlock(Faction pistonFaction, Location target) {
Faction otherFaction = Board.getInstance().getFactionAt(new FLocation(target));
diff --git a/src/main/java/com/massivecraft/factions/struct/Permission.java b/src/main/java/com/massivecraft/factions/struct/Permission.java
index 0632d4f0..f5a85e61 100755
--- a/src/main/java/com/massivecraft/factions/struct/Permission.java
+++ b/src/main/java/com/massivecraft/factions/struct/Permission.java
@@ -57,6 +57,7 @@ public enum Permission {
FRIENDLYFIRE("friendlyfire"),
GLOBALCHAT("globalchat"),
GRACE("grace"),
+ GRACETOGGLE("gracetoggle"),
HELP("help"),
HOME("home"),
INVITE("invite"),
diff --git a/src/main/java/com/massivecraft/factions/util/ClipPlaceholderAPIManager.java b/src/main/java/com/massivecraft/factions/util/ClipPlaceholderAPIManager.java
index 696e685c..9b472981 100644
--- a/src/main/java/com/massivecraft/factions/util/ClipPlaceholderAPIManager.java
+++ b/src/main/java/com/massivecraft/factions/util/ClipPlaceholderAPIManager.java
@@ -5,6 +5,7 @@ import com.massivecraft.factions.integration.Econ;
import com.massivecraft.factions.struct.Relation;
import com.massivecraft.factions.tag.FactionTag;
import com.massivecraft.factions.tag.Tag;
+import com.massivecraft.factions.util.timer.TimerManager;
import com.massivecraft.factions.zcore.util.TL;
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import me.clip.placeholderapi.expansion.Relational;
@@ -209,8 +210,8 @@ public class ClipPlaceholderAPIManager extends PlaceholderExpansion implements R
return String.valueOf(faction.getMaxVaults());
case "faction_relation_color":
return fPlayer.getColorTo(faction).toString();
- case "faction_grace":
- return Conf.gracePeriod ? "Enabled" : "Disabled";
+ case "faction_grace_time":
+ return String.valueOf(TimerManager.getRemaining(FactionsPlugin.getInstance().getTimerManager().graceTimer.getRemaining(), true));
case "faction_name_at_location":
Faction factionAtLocation = Board.getInstance().getFactionAt(new FLocation(player.getLocation()));
return factionAtLocation != null ? factionAtLocation.getTag() : Factions.getInstance().getWilderness().getTag();
diff --git a/src/main/java/com/massivecraft/factions/util/Config.java b/src/main/java/com/massivecraft/factions/util/Config.java
new file mode 100644
index 00000000..50d8b851
--- /dev/null
+++ b/src/main/java/com/massivecraft/factions/util/Config.java
@@ -0,0 +1,82 @@
+package com.massivecraft.factions.util;
+
+import com.massivecraft.factions.FactionsPlugin;
+import org.bukkit.configuration.file.YamlConfiguration;
+
+import java.io.File;
+import java.util.Objects;
+
+/**
+ * Factions - Developed by Driftay.
+ * All rights reserved 2020.
+ * Creation Date: 4/7/2020
+ */
+public class Config extends YamlConfiguration {
+ private String fileName;
+ private FactionsPlugin plugin;
+
+ public Config(FactionsPlugin plugin, String fileName) {
+ this(plugin, fileName, ".yml");
+ }
+
+ public Config(FactionsPlugin plugin, String fileName, String fileExtension) {
+ this.plugin = plugin;
+ this.fileName = fileName + (fileName.endsWith(fileExtension) ? "" : fileExtension);
+ this.createFile();
+ }
+
+ public String getFileName() {
+ return this.fileName;
+ }
+
+ public FactionsPlugin getPlugin() {
+ return this.plugin;
+ }
+
+ private void createFile() {
+ File folder = this.plugin.getDataFolder();
+ try {
+ File ex = new File(folder, this.fileName);
+ if (!ex.exists()) {
+ if (this.plugin.getResource(this.fileName) != null) {
+ this.plugin.saveResource(this.fileName, false);
+ } else {
+ this.save(ex);
+ }
+ } else {
+ this.load(ex);
+ this.save(ex);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void save() {
+ File folder = this.plugin.getDataFolder();
+ try {
+ this.save(new File(folder, this.fileName));
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof Config)) {
+ return false;
+ }
+ Config config = (Config) o;
+ if (this.fileName != null) {
+ if (this.fileName.equals(config.fileName)) {
+ return Objects.equals(this.plugin, config.plugin);
+ }
+ } else if (config.fileName == null) {
+ return Objects.equals(this.plugin, config.plugin);
+ }
+ return false;
+ }
+
+}
diff --git a/src/main/java/com/massivecraft/factions/util/timer/DateTimeFormats.java b/src/main/java/com/massivecraft/factions/util/timer/DateTimeFormats.java
new file mode 100644
index 00000000..6c3879e4
--- /dev/null
+++ b/src/main/java/com/massivecraft/factions/util/timer/DateTimeFormats.java
@@ -0,0 +1,29 @@
+package com.massivecraft.factions.util.timer;
+
+import com.massivecraft.factions.Conf;
+import org.apache.commons.lang.time.FastDateFormat;
+
+import java.text.DecimalFormat;
+import java.time.ZoneId;
+import java.util.Locale;
+import java.util.TimeZone;
+
+/**
+ * Factions - Developed by Driftay.
+ * All rights reserved 2020.
+ * Creation Date: 4/7/2020
+ */
+public final class DateTimeFormats {
+ public static final TimeZone SERVER_TIME_ZONE = TimeZone.getTimeZone(Conf.serverTimeZone);
+ public static final ZoneId SERVER_ZONE_ID = SERVER_TIME_ZONE.toZoneId();
+ public static final FastDateFormat DAY_MTH_HR_MIN_SECS = FastDateFormat.getInstance("dd/MM HH:mm:ss", SERVER_TIME_ZONE, Locale.ENGLISH);
+ public static final FastDateFormat DAY_MTH_YR_HR_MIN_AMPM = FastDateFormat.getInstance("dd/MM/yy hh:mma", SERVER_TIME_ZONE, Locale.ENGLISH);
+ public static final FastDateFormat DAY_MTH_HR_MIN_AMPM = FastDateFormat.getInstance("dd/MM hh:mma", SERVER_TIME_ZONE, Locale.ENGLISH);
+ public static final FastDateFormat HR_MIN_AMPM = FastDateFormat.getInstance("hh:mma", SERVER_TIME_ZONE, Locale.ENGLISH);
+ public static final FastDateFormat HR_MIN_AMPM_TIMEZONE = FastDateFormat.getInstance("hh:mma z", SERVER_TIME_ZONE, Locale.ENGLISH);
+ public static final FastDateFormat HR_MIN = FastDateFormat.getInstance("hh:mm", SERVER_TIME_ZONE, Locale.ENGLISH);
+ public static final FastDateFormat MIN_SECS = FastDateFormat.getInstance("mm:ss", SERVER_TIME_ZONE, Locale.ENGLISH);
+ public static final ThreadLocal SECONDS = ThreadLocal.withInitial(() -> new DecimalFormat("0"));
+ public static final ThreadLocal REMAINING_SECONDS = ThreadLocal.withInitial(() -> new DecimalFormat("0.#"));
+ public static final ThreadLocal REMAINING_SECONDS_TRAILING = ThreadLocal.withInitial(() -> new DecimalFormat("0.0"));
+}
diff --git a/src/main/java/com/massivecraft/factions/util/timer/GlobalTimer.java b/src/main/java/com/massivecraft/factions/util/timer/GlobalTimer.java
new file mode 100644
index 00000000..57a41b24
--- /dev/null
+++ b/src/main/java/com/massivecraft/factions/util/timer/GlobalTimer.java
@@ -0,0 +1,66 @@
+package com.massivecraft.factions.util.timer;
+
+/**
+ * Factions - Developed by Driftay.
+ * All rights reserved 2020.
+ * Creation Date: 4/7/2020
+ */
+public abstract class GlobalTimer extends Timer {
+ private TimerRunnable runnable;
+
+ public GlobalTimer(String name, long defaultCooldown) {
+ super(name, defaultCooldown);
+ }
+
+
+ public boolean clearCooldown() {
+ if (this.runnable != null) {
+ this.runnable.cancel();
+ this.runnable = null;
+ return true;
+ }
+ return false;
+
+ }
+
+
+ public boolean isPaused() {
+ return (this.runnable != null) && (this.runnable.isPaused());
+ }
+
+
+ public void setPaused(boolean paused) {
+ if ((this.runnable != null) && (this.runnable.isPaused() != paused)) {
+ this.runnable.setPaused(paused);
+ }
+ }
+
+
+ public long getRemaining() {
+ return this.runnable == null ? 0L : this.runnable.getRemaining();
+ }
+
+ public long getRemaining(long now) {
+ return this.runnable == null ? 0L : this.runnable.getRemaining(now);
+ }
+
+
+ public boolean setRemaining() {
+ return setRemaining(this.defaultCooldown, false);
+ }
+
+
+ public boolean setRemaining(long duration, boolean overwrite) {
+ boolean hadCooldown = false;
+ if (this.runnable != null) {
+ if (!overwrite) {
+ return false;
+ }
+ hadCooldown = this.runnable.getRemaining() > 0L;
+ this.runnable.setRemaining(duration);
+ } else {
+ this.runnable = new TimerRunnable(this, duration);
+ }
+ return !hadCooldown;
+ }
+}
diff --git a/src/main/java/com/massivecraft/factions/util/timer/Timer.java b/src/main/java/com/massivecraft/factions/util/timer/Timer.java
new file mode 100644
index 00000000..d9596cc4
--- /dev/null
+++ b/src/main/java/com/massivecraft/factions/util/timer/Timer.java
@@ -0,0 +1,32 @@
+package com.massivecraft.factions.util.timer;
+
+import com.massivecraft.factions.FactionsPlugin;
+import com.massivecraft.factions.util.Config;
+import com.massivecraft.factions.util.timer.type.GraceTimer;
+
+/**
+ * Factions - Developed by Driftay.
+ * All rights reserved 2020.
+ * Creation Date: 4/7/2020
+ */
+public abstract class Timer {
+ protected final String name;
+ public final long defaultCooldown;
+
+
+ public Timer(String name, long defaultCooldown) {
+ this.name = name;
+ this.defaultCooldown = defaultCooldown;
+ }
+
+ public String getName() {
+ return this.name;
+ }
+
+ public void load(Config config) {
+ }
+
+
+ public void save(Config config) {
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/massivecraft/factions/util/timer/TimerManager.java b/src/main/java/com/massivecraft/factions/util/timer/TimerManager.java
new file mode 100644
index 00000000..f79e5fb4
--- /dev/null
+++ b/src/main/java/com/massivecraft/factions/util/timer/TimerManager.java
@@ -0,0 +1,86 @@
+package com.massivecraft.factions.util.timer;
+
+import com.massivecraft.factions.Conf;
+import com.massivecraft.factions.FactionsPlugin;
+import com.massivecraft.factions.util.Config;
+import com.massivecraft.factions.util.timer.type.GraceTimer;
+import org.apache.commons.lang.time.DurationFormatUtils;
+import org.bukkit.event.Listener;
+
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Factions - Developed by Driftay.
+ * All rights reserved 2020.
+ * Creation Date: 4/7/2020
+ */
+public class TimerManager implements Listener, Runnable {
+ private final Set timers;
+ private final FactionsPlugin plugin;
+ private final List timerRunnableList = new ArrayList<>();
+ private Config config;
+ public GraceTimer graceTimer;
+ private static final long MINUTE = TimeUnit.MINUTES.toMillis(1L);
+ private static final long HOUR = TimeUnit.HOURS.toMillis(1L);
+ private static final long MULTI_HOUR = TimeUnit.HOURS.toMillis(10);
+
+ public static String getRemaining(long millis, boolean milliseconds) {
+ return getRemaining(millis, milliseconds, true);
+ }
+
+ public static String getRemaining(long duration, boolean milliseconds, boolean trail) {
+ if ((milliseconds) && (duration < MINUTE)) {
+ return ( (trail ? DateTimeFormats.REMAINING_SECONDS_TRAILING : DateTimeFormats.REMAINING_SECONDS).get()).format(duration * 0.001D) + 's';
+ }
+ return DurationFormatUtils.formatDuration(duration, (duration >= HOUR ? (duration >= MULTI_HOUR ? "d" : "") + "d:" : "") + "HH:mm:ss");
+ }
+
+ public TimerManager(FactionsPlugin plugin) {
+ this.timers = new HashSet<>();
+ this.plugin = plugin;
+ plugin.getServer().getPluginManager().registerEvents(this, plugin);
+ if(Conf.useGraceSystem) {
+ this.registerTimer(this.graceTimer = new GraceTimer());
+ }
+ plugin.getServer().getScheduler().runTaskTimer(plugin, this, 4, 4);
+ }
+
+ public Collection getTimers() {
+ return this.timers;
+ }
+
+ public void registerTimer(Timer timer) {
+ this.timers.add(timer);
+ if (timer instanceof Listener) {
+ this.plugin.getServer().getPluginManager().registerEvents((Listener) timer, this.plugin);
+ }
+ }
+
+ public void unregisterTimer(Timer timer) {
+ this.timers.remove(timer);
+ }
+
+ public void reloadTimerData() {
+ this.config = new Config(this.plugin, "timers");
+ for (Timer timer : this.timers) {
+ timer.load(this.config);
+ }
+ }
+
+ public void saveTimerData() {
+ for (Timer timer : this.timers) {
+ timer.save(this.config);
+ }
+ this.config.save();
+ }
+
+ public void run() {
+ long now = System.currentTimeMillis();
+ timerRunnableList.removeIf(next -> next.check(now));
+ }
+
+ public List getTimerRunnableList() {
+ return timerRunnableList;
+ }
+}
diff --git a/src/main/java/com/massivecraft/factions/util/timer/TimerRunnable.java b/src/main/java/com/massivecraft/factions/util/timer/TimerRunnable.java
new file mode 100644
index 00000000..c14f0a3c
--- /dev/null
+++ b/src/main/java/com/massivecraft/factions/util/timer/TimerRunnable.java
@@ -0,0 +1,118 @@
+package com.massivecraft.factions.util.timer;
+
+import com.massivecraft.factions.FactionsPlugin;
+import com.massivecraft.factions.util.Config;
+
+import java.util.UUID;
+
+/**
+ * Factions - Developed by Driftay.
+ * All rights reserved 2020.
+ * Creation Date: 4/7/2020
+ */
+
+public class TimerRunnable {
+ private final Timer timer;
+ private long expiryMillis;
+ private long pauseMillis;
+ private boolean cancelled = false;
+
+
+ public TimerRunnable(Timer timer, long duration) {
+ this.timer = timer;
+ setRemaining(duration);
+ FactionsPlugin plugin = FactionsPlugin.getInstance();
+ plugin.getTimerManager().getTimerRunnableList().add(this);
+ }
+
+
+ public TimerRunnable(UUID playerUUID, Timer timer, long duration) {
+ this.timer = timer;
+ setRemaining(duration);
+ FactionsPlugin plugin = FactionsPlugin.getInstance();
+ plugin.getTimerManager().getTimerRunnableList().add(this);
+ }
+
+ public boolean isCancelled() {
+ return cancelled;
+ }
+
+ public Timer getTimer() {
+ return this.timer;
+ }
+
+
+ public long getRemaining() {
+ return getRemaining(false);
+ }
+
+ public long getRemaining(long now) {
+ return getRemaining(false, now);
+ }
+
+
+ public void setRemaining(long remaining) {
+ setExpiryMillis(remaining);
+ }
+
+
+ public long getRemaining(boolean ignorePaused) {
+ if ((!ignorePaused) && (this.pauseMillis != 0L)) return this.pauseMillis;
+ return this.expiryMillis - System.currentTimeMillis();
+ }
+
+ public long getRemaining(boolean ignorePaused, long now) {
+ if ((!ignorePaused) && (this.pauseMillis != 0L)) return this.pauseMillis;
+ return this.expiryMillis - now;
+ }
+
+
+ public long getExpiryMillis() {
+ return this.expiryMillis;
+ }
+
+
+ private void setExpiryMillis(long remainingMillis) {
+ long expiryMillis = System.currentTimeMillis() + remainingMillis;
+ if (expiryMillis == this.expiryMillis) return;
+ this.expiryMillis = expiryMillis;
+ }
+
+ public boolean check(long now) {
+ if (cancelled) return true;
+ return getRemaining(false, now) <= 0;
+ }
+
+
+ public long getPauseMillis() {
+ return this.pauseMillis;
+ }
+
+
+ public void setPauseMillis(long pauseMillis) {
+ this.pauseMillis = pauseMillis;
+ }
+
+
+ public boolean isPaused() {
+ return this.pauseMillis != 0L;
+ }
+
+
+ public void setPaused(boolean paused) {
+ if (paused == isPaused()) return;
+
+ if (paused) {
+ this.pauseMillis = getRemaining(true);
+ cancel();
+ } else {
+ setExpiryMillis(this.pauseMillis);
+ this.pauseMillis = 0L;
+ }
+ }
+
+
+ public void cancel() {
+ cancelled = true;
+ }
+}
diff --git a/src/main/java/com/massivecraft/factions/util/timer/type/GraceTimer.java b/src/main/java/com/massivecraft/factions/util/timer/type/GraceTimer.java
new file mode 100644
index 00000000..da98c39a
--- /dev/null
+++ b/src/main/java/com/massivecraft/factions/util/timer/type/GraceTimer.java
@@ -0,0 +1,43 @@
+package com.massivecraft.factions.util.timer.type;
+
+import com.massivecraft.factions.Conf;
+import com.massivecraft.factions.FPlayer;
+import com.massivecraft.factions.FPlayers;
+import com.massivecraft.factions.util.timer.GlobalTimer;
+import org.bukkit.Material;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.block.BlockPlaceEvent;
+import org.bukkit.event.entity.EntityExplodeEvent;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Factions - Developed by Driftay.
+ * All rights reserved 2020.
+ * Creation Date: 4/7/2020
+ */
+public class GraceTimer extends GlobalTimer implements Listener {
+
+ public GraceTimer() {
+ super("GRACE", TimeUnit.DAYS.toMillis(Conf.gracePeriodTimeDays));
+ }
+
+ @EventHandler
+ public void onBreak(EntityExplodeEvent e) {
+ if(getRemaining() > 0)
+ e.setCancelled(true);
+ }
+
+ @EventHandler
+ public void onTNTPlace(BlockPlaceEvent event) {
+ FPlayer fp = FPlayers.getInstance().getByPlayer(event.getPlayer());
+ if(getRemaining() > 0) {
+ if (!fp.isAdminBypassing()) {
+ if (event.getBlock().getType().equals(Material.TNT)) {
+ event.setCancelled(true);
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/com/massivecraft/factions/zcore/util/TL.java b/src/main/java/com/massivecraft/factions/zcore/util/TL.java
index 96f748f5..cb2f1819 100644
--- a/src/main/java/com/massivecraft/factions/zcore/util/TL.java
+++ b/src/main/java/com/massivecraft/factions/zcore/util/TL.java
@@ -434,9 +434,12 @@ public enum TL {
COMMAND_FWARP_PASSWORD_REQUIRED("&c&l[!]&c Warp Password:"),
COMMAND_FWARP_PASSWORD_TIMEOUT("&c&l[!]&7 Warp password &ccanceled"),
+ COMMAND_GRACE_TIME_REMAINING("&c&lGracePeriod &8» &cTime Remaining: &b%1$s"),
+ COMMAND_GRACE_DISABLED_NO_FORMAT("&c[!] &7Grace is disabled! Explosions are allowed!"),
+ COMMAND_GRACE_ENABLED_FORMAT("&c&lGracePeriod &8» &7Grace Period Has Now &aStarted&7! &cTime Remaining: &b%1$s"),
+ COMMAND_GRACE_DISABLED_FORMAT("&c&lGracePeriod &8» &7Grace Period Has Now &cEnded&7! &cExplosions are now enabled!"),
COMMAND_GRACE_DESCRIPTION("Toggles Grace Period on/off"),
- COMMAND_GRACE_ENABLED("&cYou cannot place &e%s &cwhile grace period is active!"),
- COMMAND_GRACE_TOGGLE("&8» &7Grace period is now &c%1$s"),
+ COMMAND_GRACE_ENABLED_PLACEMENT("&cYou cannot place &e%s &cwhile grace period is active!"),
COMMAND_HINT_PERMISSION("&aYou can manage your factions permissions using &7/f perms"),
diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml
index aeffffbc..9de61c3c 100644
--- a/src/main/resources/config.yml
+++ b/src/main/resources/config.yml
@@ -345,7 +345,7 @@ help:
# We use '1' to preserve default functionality of /f help 1
'1':
- '&7&m----------------------------------------------------'
- - '&6&lFactions Help &8- &f(1/2) '
+ - '&6&lFactions Help &8- &f(1/3) '
- '&7&m----------------------------------------------------'
- '&c/f create &f &8- &7Create your own faction.'
- '&c/f who &f &8- &7Show faction information.'
@@ -730,7 +730,7 @@ F-Shop:
# | Faction Command Cooldowns | #
# +------------------------------------------------------+ #
############################################################
-fcooldowns:
+fcooldowns: #All of These Cooldowns Are In Seconds
f-open: 5
f-disband: 10
f-create: 10