added antiGrief inhabited chunk time calculation
This commit is contained in:
@@ -8,4 +8,10 @@ public class NumberUtil {
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
public static <T extends Comparable<T>> T clamp(T value, T min, T max) {
|
||||
if (value.compareTo(min) < 0) return min;
|
||||
if (value.compareTo(max) > 0) return max;
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
@@ -2,6 +2,7 @@ package eu.mhsl.craftattack.spawn.craftattack.appliances.security.antiGrief;
|
||||
|
||||
import eu.mhsl.craftattack.spawn.core.Main;
|
||||
import eu.mhsl.craftattack.spawn.core.appliance.Appliance;
|
||||
import eu.mhsl.craftattack.spawn.core.util.NumberUtil;
|
||||
import eu.mhsl.craftattack.spawn.craftattack.appliances.security.antiGrief.listener.*;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.event.ClickEvent;
|
||||
@@ -139,6 +140,11 @@ public class AntiGrief extends Appliance {
|
||||
/** Smoothing factor for EMA baseline. Lower = smoother, higher = more reactive. 0.0 < EMA_ALPHA <= 1.0 */
|
||||
private static final double EMA_ALPHA = 0.2;
|
||||
|
||||
/** Minimal chunk inhabited time to start registering scores linearly to INHABITED_FULL_MS */
|
||||
private static final int INHABITED_MIN_MS = 60 * 60 * 1000;
|
||||
/** Max time to reach 100% effect on the score */
|
||||
private static final int INHABITED_FULL_MS = 24 * 60 * 60 * 1000;
|
||||
|
||||
/** Stores direct incidents mapped by player UUID. */
|
||||
private final Map<UUID, Set<GriefIncident>> directGriefRegistry = new ConcurrentHashMap<>();
|
||||
/** Stores passive incidents mapped by chunk key. */
|
||||
@@ -176,15 +182,18 @@ public class AntiGrief extends Appliance {
|
||||
final double currentScore = state.currentScore(bucketIdx);
|
||||
if (currentScore <= 0.0) return;
|
||||
|
||||
final double base = (state.ema == 0.0) ? currentScore : state.ema;
|
||||
final double newBase = EMA_ALPHA * currentScore + (1 - EMA_ALPHA) * base;
|
||||
final double adjustedScore = adjustScoreToInhabitantTime(state, currentScore);
|
||||
if (adjustedScore <= 0.0) return;
|
||||
|
||||
final double base = (state.ema == 0.0) ? adjustedScore : state.ema;
|
||||
final double newBase = EMA_ALPHA * adjustedScore + (1 - EMA_ALPHA) * base;
|
||||
state.ema = Math.max(3, newBase);
|
||||
|
||||
boolean spike = currentScore >= HARD_THRESHOLD || currentScore >= base * FACTOR_SPIKE;
|
||||
final boolean spike = adjustedScore >= HARD_THRESHOLD || adjustedScore >= base * FACTOR_SPIKE;
|
||||
if (spike && (now - state.lastAlertAt) >= ALERT_COOLDOWN_MS) {
|
||||
state.lastAlertAt = now;
|
||||
Bukkit.getScheduler().runTask(Main.instance(), () ->
|
||||
this.alertAdmins(areaKey, bucketIdx, currentScore, newBase)
|
||||
this.alertAdmins(areaKey, bucketIdx, adjustedScore, newBase)
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -212,6 +221,14 @@ public class AntiGrief extends Appliance {
|
||||
}, Ticks.TICKS_PER_SECOND * 30, Ticks.TICKS_PER_SECOND * 30);
|
||||
}
|
||||
|
||||
private static double adjustScoreToInhabitantTime(AreaState state, double currentScore) {
|
||||
final long inhabitedMs = state.getInhabitedTime() * Ticks.SINGLE_TICK_DURATION_MS / Ticks.TICKS_PER_SECOND;
|
||||
|
||||
double factor = (double) (inhabitedMs - INHABITED_MIN_MS) / (double) (INHABITED_FULL_MS - INHABITED_MIN_MS);
|
||||
factor = NumberUtil.clamp(factor, 0.0, 1.0);
|
||||
return currentScore * factor;
|
||||
}
|
||||
|
||||
private void alertAdmins(long areaKey, long bucketIdx, double curr, double baseline) {
|
||||
AreaState meta = this.areas.get(areaKey);
|
||||
if (meta == null) return;
|
||||
|
Reference in New Issue
Block a user