From c119e8216a89e21bd00e8efeafe5d987f0ebcd4d Mon Sep 17 00:00:00 2001 From: Govindas Date: Sun, 16 Feb 2020 17:13:31 +0200 Subject: [PATCH] Starting work on event cooldowns... --- src/lt/govindas/skooldown/Skooldown.java | 11 +++- .../conditions/CondCooldownOver.java | 46 --------------- .../conditions/CondIsCooldownOver.java | 59 +++++++++++++++++++ .../skooldown/effects/EffStartCooldown.java | 40 ++++++++++++- .../skooldown/events/CooldownEndEvent.java | 30 ++++++++++ .../skooldown/expressions/ExprCooldown.java | 14 ++--- .../skooldown/utilities/CleanupTimer.java | 39 ++++++++++++ 7 files changed, 181 insertions(+), 58 deletions(-) delete mode 100644 src/lt/govindas/skooldown/conditions/CondCooldownOver.java create mode 100644 src/lt/govindas/skooldown/conditions/CondIsCooldownOver.java create mode 100644 src/lt/govindas/skooldown/events/CooldownEndEvent.java create mode 100644 src/lt/govindas/skooldown/utilities/CleanupTimer.java diff --git a/src/lt/govindas/skooldown/Skooldown.java b/src/lt/govindas/skooldown/Skooldown.java index 0a5a410..396d406 100644 --- a/src/lt/govindas/skooldown/Skooldown.java +++ b/src/lt/govindas/skooldown/Skooldown.java @@ -3,24 +3,29 @@ package lt.govindas.skooldown; import ch.njol.skript.Skript; import ch.njol.skript.lang.ExpressionType; import ch.njol.skript.util.Timespan; -import lt.govindas.skooldown.conditions.CondCooldownOver; +import lt.govindas.skooldown.conditions.CondIsCooldownOver; import lt.govindas.skooldown.effects.EffStartCooldown; +import lt.govindas.skooldown.effects.EffStartEventCooldown; import lt.govindas.skooldown.expressions.ExprCooldown; +import lt.govindas.skooldown.utilities.CleanupTimer; import org.bukkit.plugin.java.JavaPlugin; +import javax.swing.*; import java.util.HashMap; public final class Skooldown extends JavaPlugin { public static HashMap cooldowns = new HashMap(); + public static HashMap eventCooldowns = new HashMap(); @Override public void onEnable() { - Skript.registerEffect(EffStartCooldown.class, "(create|start) [a] cooldown %string% for %timespan%"); - Skript.registerCondition(CondCooldownOver.class, "[the] cooldown %string% (is|has) (finished|over|done)", "[the] cooldown %string% is(n't| not) unfinished)", "[the] cooldown %string% is(n't| not) (finished|over|done)", "[the] cooldown %string% is unfinished"); + Skript.registerEffect(EffStartCooldown.class, "(create|start) [a] [(1¦event] cooldown %string% [with data %-string%] for %timespan%"); + Skript.registerCondition(CondIsCooldownOver.class, "[the] [(1¦event] cooldown %string% [with data %-string%] (is|has) (finished|over|done)", "[the] [(1¦event] cooldown %string% [with data %-string%] is(n't| not) unfinished)", "[the] [(1¦event] cooldown %string% [with data %-string%] is(n't| not) (finished|over|done)", "[the] [(1¦event] cooldown %string% [with data %-string%] is unfinished"); Skript.registerExpression(ExprCooldown.class, Timespan.class, ExpressionType.PROPERTY, "cooldown %string%"); getLogger().info("[Skooldown] Plugin enabled!"); + new CleanupTimer(); } @Override diff --git a/src/lt/govindas/skooldown/conditions/CondCooldownOver.java b/src/lt/govindas/skooldown/conditions/CondCooldownOver.java deleted file mode 100644 index 3090bda..0000000 --- a/src/lt/govindas/skooldown/conditions/CondCooldownOver.java +++ /dev/null @@ -1,46 +0,0 @@ -package lt.govindas.skooldown.conditions; - -import ch.njol.skript.lang.Condition; -import ch.njol.skript.lang.Expression; -import ch.njol.skript.lang.SkriptParser.ParseResult; -import ch.njol.util.Kleenean; -import lt.govindas.skooldown.Skooldown; -import org.bukkit.event.Event; -import org.jetbrains.annotations.Nullable; - -public class CondCooldownOver extends Condition { - - private Expression name; - - @SuppressWarnings("unchecked") - @Override - - public boolean init(Expression[] expr, int matchedPattern, Kleenean paramKleenean, ParseResult paramParseResult) { - name = (Expression) expr[0]; - System.out.println(matchedPattern); - setNegated(matchedPattern == 2 || matchedPattern == 3); - return true; - } - - @Override - public String toString(@Nullable Event e, boolean debug) { - return "is cooldown over" + name; - } - - @Override - public boolean check(Event e) { - Long cooldown = Skooldown.cooldowns.get(name.getSingle(e)); - - //if cooldown isn't created, will return that it is over - if (cooldown == null) return !isNegated(); - - if (cooldown < System.currentTimeMillis()) { - Skooldown.cooldowns.remove(name.getSingle(e)); - //will return that cooldown is over - return !isNegated(); - } - //will return that cooldown is not over - - return isNegated(); - } -} \ No newline at end of file diff --git a/src/lt/govindas/skooldown/conditions/CondIsCooldownOver.java b/src/lt/govindas/skooldown/conditions/CondIsCooldownOver.java new file mode 100644 index 0000000..45a1efd --- /dev/null +++ b/src/lt/govindas/skooldown/conditions/CondIsCooldownOver.java @@ -0,0 +1,59 @@ +package lt.govindas.skooldown.conditions; + +import ch.njol.skript.lang.Condition; +import ch.njol.skript.lang.Expression; +import ch.njol.skript.lang.SkriptParser.ParseResult; +import ch.njol.util.Kleenean; +import lt.govindas.skooldown.Skooldown; +import org.bukkit.event.Event; +import org.jetbrains.annotations.Nullable; + +public class CondIsCooldownOver extends Condition { + + private Expression name; + private Expression data; + private boolean eventCooldown = false; + + @SuppressWarnings("unchecked") + @Override + + public boolean init(Expression[] expr, int matchedPattern, Kleenean paramKleenean, ParseResult paramParseResult) { + name = (Expression) expr[0]; + int mark = paramParseResult.mark; + if (mark == 1) eventCooldown = true; + if (expr.length > 1) data = (Expression) expr[1]; + setNegated(matchedPattern == 2 || matchedPattern == 3); + return true; + } + + @Override + public String toString(@Nullable Event e, boolean debug) { + return "is cooldown over " + name; + } + + @Override + public boolean check(Event e) { + if (!eventCooldown) { + Long cooldown = Skooldown.cooldowns.get(name.getSingle(e)); + + //if cooldown isn't created, will return that it is over + if (cooldown == null) return !isNegated(); + + if (cooldown < System.currentTimeMillis()) { + Skooldown.cooldowns.remove(name.getSingle(e)); + //will return that cooldown is over + return !isNegated(); + } + //will return that cooldown is not over + + return isNegated(); + } else { + String dataInput; + if (data == null) dataInput = ""; + else dataInput = data.getSingle(e); + + if (Skooldown.eventCooldowns.containsKey(name.getSingle(e) + dataInput)) return isNegated(); + else return !isNegated(); + } + } +} \ No newline at end of file diff --git a/src/lt/govindas/skooldown/effects/EffStartCooldown.java b/src/lt/govindas/skooldown/effects/EffStartCooldown.java index 0169fab..67d4456 100644 --- a/src/lt/govindas/skooldown/effects/EffStartCooldown.java +++ b/src/lt/govindas/skooldown/effects/EffStartCooldown.java @@ -6,20 +6,38 @@ import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.skript.util.Timespan; import ch.njol.util.Kleenean; import lt.govindas.skooldown.Skooldown; +import lt.govindas.skooldown.events.CooldownEndEvent; +import org.bukkit.Bukkit; import org.bukkit.event.Event; import org.jetbrains.annotations.Nullable; +import javax.swing.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + public class EffStartCooldown extends Effect { private Expression name; private Expression time; + private Expression data; + private boolean eventCooldown = false; @SuppressWarnings("unchecked") @Override public boolean init(Expression[] expr, int matchedPattern, Kleenean paramKleenean, ParseResult paramParseResult) { name = (Expression) expr[0]; - time = (Expression) expr[1]; + int mark = paramParseResult.mark; + if (mark == 1) { + eventCooldown = true; + } + //TODO test if this is right, maybe expression IDs are solid + if (expr.length > 2) { + data = (Expression) expr[1]; + time = (Expression) expr[2]; + } else { + time = (Expression) expr[1]; + } return true; } @@ -30,7 +48,25 @@ public class EffStartCooldown extends Effect { @Override protected void execute(Event e) { - Skooldown.cooldowns.put(name.getSingle(e), System.currentTimeMillis() + time.getSingle(e).getMilliSeconds()); + String dataInput; + + if (data == null) dataInput = ""; + else dataInput = data.getSingle(e); + + if (!eventCooldown) { + Skooldown.cooldowns.put(name.getSingle(e), System.currentTimeMillis() + time.getSingle(e).getMilliSeconds()); + } else { + Timer timer = new Timer((int) time.getSingle(e).getMilliSeconds(), new ActionListener() { + @Override + public void actionPerformed(ActionEvent arg0) { + Skooldown.eventCooldowns.remove(name.getSingle(e) + dataInput); + Bukkit.getServer().getPluginManager().callEvent(new CooldownEndEvent(name.getSingle(e), dataInput, time.getSingle(e).getMilliSeconds())); + } + }); + timer.setRepeats(false); + timer.start(); + Skooldown.eventCooldowns.put(name.getSingle(e) + dataInput, timer); + } } } diff --git a/src/lt/govindas/skooldown/events/CooldownEndEvent.java b/src/lt/govindas/skooldown/events/CooldownEndEvent.java new file mode 100644 index 0000000..545d41f --- /dev/null +++ b/src/lt/govindas/skooldown/events/CooldownEndEvent.java @@ -0,0 +1,30 @@ +package lt.govindas.skooldown.events; + +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +public final class CooldownEndEvent extends Event { + private static final HandlerList handlers = new HandlerList(); + private String data; + private String name; + private long delay; + + public CooldownEndEvent(String name, String data, long delay) { + this.data = data; + this.name = name; + this.delay = delay; + } + + public String getData() { return data; } + public String getName() { return name;} + public long getDelay() { return delay;} + + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} + diff --git a/src/lt/govindas/skooldown/expressions/ExprCooldown.java b/src/lt/govindas/skooldown/expressions/ExprCooldown.java index 612a0f6..94df1e9 100644 --- a/src/lt/govindas/skooldown/expressions/ExprCooldown.java +++ b/src/lt/govindas/skooldown/expressions/ExprCooldown.java @@ -13,7 +13,7 @@ import lt.govindas.skooldown.Skooldown; import org.bukkit.event.Event; import org.jetbrains.annotations.Nullable; -//TODO rename "delta" into something else, since I don't know what delta is +//TODO add event cooldown support public class ExprCooldown extends SimpleExpression { private Expression name; @@ -55,10 +55,10 @@ public class ExprCooldown extends SimpleExpression { } @Override - public void change(Event e, Object[] delta, ChangeMode mode) { + public void change(Event e, Object[] changer, ChangeMode mode) { switch (mode) { case SET: - Skooldown.cooldowns.put(name.getSingle(e), System.currentTimeMillis() + ((Timespan) delta[0]).getMilliSeconds()); + Skooldown.cooldowns.put(name.getSingle(e), System.currentTimeMillis() + ((Timespan) changer[0]).getMilliSeconds()); break; case REMOVE_ALL: case DELETE: @@ -68,10 +68,10 @@ public class ExprCooldown extends SimpleExpression { case ADD: Long cooldown = Skooldown.cooldowns.get(name.getSingle(e)); if (cooldown == null) { - Skooldown.cooldowns.put(name.getSingle(e), System.currentTimeMillis() + ((Timespan) delta[0]).getMilliSeconds()); + Skooldown.cooldowns.put(name.getSingle(e), System.currentTimeMillis() + ((Timespan) changer[0]).getMilliSeconds()); break; } - Skooldown.cooldowns.put(name.getSingle(e), cooldown + ((Timespan) delta[0]).getMilliSeconds()); + Skooldown.cooldowns.put(name.getSingle(e), cooldown + ((Timespan) changer[0]).getMilliSeconds()); break; case REMOVE: cooldown = Skooldown.cooldowns.get(name.getSingle(e)); @@ -80,10 +80,10 @@ public class ExprCooldown extends SimpleExpression { //remove cooldown from hashMap if it would expire with new value - if ((cooldown - ((Timespan) delta[0]).getMilliSeconds()) < System.currentTimeMillis()) { + if ((cooldown - ((Timespan) changer[0]).getMilliSeconds()) < System.currentTimeMillis()) { Skooldown.cooldowns.remove(name.getSingle(e)); } else { - Skooldown.cooldowns.put(name.getSingle(e), cooldown - ((Timespan) delta[0]).getMilliSeconds()); + Skooldown.cooldowns.put(name.getSingle(e), cooldown - ((Timespan) changer[0]).getMilliSeconds()); } break; default: diff --git a/src/lt/govindas/skooldown/utilities/CleanupTimer.java b/src/lt/govindas/skooldown/utilities/CleanupTimer.java new file mode 100644 index 0000000..51f363b --- /dev/null +++ b/src/lt/govindas/skooldown/utilities/CleanupTimer.java @@ -0,0 +1,39 @@ +package lt.govindas.skooldown.utilities; + +import lt.govindas.skooldown.Skooldown; + +import java.util.Iterator; +import java.util.Map; +import java.util.Timer; +import java.util.TimerTask; + +public class CleanupTimer { + //Hourly Timer to prevent memory leaks + public CleanupTimer() { + Timer timer = new Timer(); + TimerTask hourlyTask = new TimerTask() { + int i = 0; + + @Override + public void run() { + Iterator it = Skooldown.cooldowns.entrySet().iterator(); + while (it.hasNext()) { + Map.Entry pair = (Map.Entry) it.next(); + + long value = (long) pair.getValue(); + if (value < System.currentTimeMillis()) { + i++; + + it.remove(); + } + } + if (i > 0) { + System.out.println("[Skooldown Hourly Memory Cleanup] " + i + " finished cooldowns cleared from memory."); + } + } + + }; + //hourly schedule + timer.schedule(hourlyTask, 100, 1000 * 60 * 60); + } +}