diff --git a/DefaultPlugin.iml b/DefaultPlugin.iml
index 8d9e804..c3507e3 100644
--- a/DefaultPlugin.iml
+++ b/DefaultPlugin.iml
@@ -11,6 +11,7 @@
+
diff --git a/src/main/java/eu/darkbot/popcorn/def/AntiPush.java b/src/main/java/eu/darkbot/popcorn/def/AntiPush.java
index f1b880d..c869588 100644
--- a/src/main/java/eu/darkbot/popcorn/def/AntiPush.java
+++ b/src/main/java/eu/darkbot/popcorn/def/AntiPush.java
@@ -8,25 +8,44 @@
import com.github.manolo8.darkbot.core.itf.Configurable;
import com.github.manolo8.darkbot.core.manager.EffectManager;
import com.github.manolo8.darkbot.core.manager.MapManager;
+import com.github.manolo8.darkbot.core.manager.RepairManager;
import com.github.manolo8.darkbot.extensions.features.Feature;
import com.github.manolo8.darkbot.modules.DisconnectModule;
import com.github.manolo8.darkbot.utils.I18n;
+import java.time.Duration;
+import java.time.Instant;
+import java.util.ArrayList;
import java.util.Arrays;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
-@Feature(name = "Anti push", description = "Turns off the bot if an enemy uses draw fire", enabledByDefault = true)
+@Feature(name = "Anti push", description = "Turns off the bot if an enemy uses draw fire or is killed over X times by the same player", enabledByDefault = true)
public class AntiPush implements Behaviour, Configurable {
private MapManager mapManager;
+ private RepairManager repairManager;
private List ships;
private Main main;
private Config config;
+ // key: user id, value: List of times of death, List::size() is death count
+ private final Map> deathStats = new HashMap<>();
+ private boolean wasDead = true;
+
public static class Config {
- @Option(value = "Pause Time (minutes)", description = "Pause time, 0 for infinite pause")
- @Num(min = 0, max = 300)
- public int PAUSE_TIME = 0;
+ @Option(value = "Pause time on draw fire (minutes)", description = "Pause time, 0 to disable feature, -1 for infinite pause")
+ @Num(min = -1, max = 300)
+ public int DRAWFIRE_PAUSE_TIME = -1;
+
+ @Option(value = "Max kills by same player", description = "The maximum times one player can kill you before bot pauses.")
+ @Num(min = 1, max = 1000, step = 1)
+ public int MAX_DEATHS = 7;
+
+ @Option(value = "Pause time after kills reached (minutes)", description = "Time to pause after kills reached, 0 to disable feature, -1 for infinite pause")
+ @Num(min = -1, max = 300)
+ public int DEATH_PAUSE_TIME = -1;
}
@Override
@@ -36,6 +55,7 @@ public void install(Main main) {
this.main = main;
this.mapManager = main.mapManager;
this.ships = main.mapManager.entities.ships;
+ this.repairManager = main.repairManager;
}
@Override
@@ -45,15 +65,63 @@ public void setConfig(Config config) {
@Override
public void tick() {
+ tickDrawFire();
+ tickDeathPause();
+ }
+
+ // updating deathStats on tickStopped() because behaviour not ticked when ship isDead()
+ @Override
+ public void tickStopped() {
+ if (config.DEATH_PAUSE_TIME == 0) return;
+
+ removeOldDeaths();
+ if (repairManager.isDead() && !wasDead) {
+ ships.stream()
+ .filter(s -> s.playerInfo.username.equals(repairManager.getKillerName()))
+ .findFirst()
+ .ifPresent(killer -> deathStats.computeIfAbsent(
+ killer.id, l -> new ArrayList<>()).add(Instant.now()));
+ wasDead = true;
+ }
+ }
+
+ private void tickDrawFire() {
+ if (config.DRAWFIRE_PAUSE_TIME == 0) return;
+
for (Ship ship : ships) {
if (!ship.playerInfo.isEnemy() || !ship.hasEffect(EffectManager.Effect.DRAW_FIRE) || !mapManager.isTarget(ship)) continue;
System.out.println("Pausing bot" +
- (config.PAUSE_TIME > 0 ? " for " + config.PAUSE_TIME + " minutes" : "") +
+ (config.DRAWFIRE_PAUSE_TIME > 0 ? " for " + config.DRAWFIRE_PAUSE_TIME + " minutes" : "") +
", enemy used draw fire");
- Long pauseMillis = config.PAUSE_TIME > 0 ? (long) config.PAUSE_TIME * 60 * 1000 : null;
+ Long pauseMillis = config.DRAWFIRE_PAUSE_TIME > 0 ? (long) config.DRAWFIRE_PAUSE_TIME * 60 * 1000 : null;
main.setModule(new DisconnectModule(pauseMillis, I18n.get("module.disconnect.reason.draw_fire")));
}
}
-}
\ No newline at end of file
+ private void tickDeathPause() {
+ if (config.DEATH_PAUSE_TIME == 0) return;
+ wasDead = false;
+
+ deathStats.entrySet().stream()
+ .filter(e -> e.getValue().size() >= config.MAX_DEATHS)
+ .findFirst()
+ .ifPresent(entry -> {
+ System.out.format("Pausing for %d minutes (Death pause feature): killed by %s %d times\n",
+ config.DEATH_PAUSE_TIME,
+ repairManager.getKillerName(),
+ entry.getValue().size());
+ main.setModule(new DisconnectModule(config.DEATH_PAUSE_TIME > 0 ? config.DEATH_PAUSE_TIME * 60 * 1000L : null,
+ I18n.get("module.disconnect.reason.death_pause",
+ repairManager.getKillerName(),
+ entry.getValue().size())));
+ deathStats.remove(entry.getKey());
+ });
+ }
+
+ private void removeOldDeaths() {
+ deathStats.values()
+ .forEach(time -> time.removeIf(t -> Duration.between(t, Instant.now()).toDays() >= 1));
+ deathStats.values().removeIf(List::isEmpty);
+ }
+}