Build AsminVoicechat / prepare-release (push) Successful in 14s
Build AsminVoicechat / build-and-test (17) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (18) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (19) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (20) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (21) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (22) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (23) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (24) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (25) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (26) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (27-ea) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (16) (push) Canceled after 38s
67 lines
2.1 KiB
Java
67 lines
2.1 KiB
Java
/*
|
|
* Decompiled with CFR 0.152.
|
|
*
|
|
* Could not load the following classes:
|
|
* org.bukkit.entity.Player
|
|
*/
|
|
package de.maxhenkel.voicechat.net;
|
|
|
|
import java.util.UUID;
|
|
import java.util.concurrent.ConcurrentHashMap;
|
|
import org.bukkit.entity.Player;
|
|
|
|
public class PacketRateLimiter {
|
|
private final ConcurrentHashMap<UUID, RateLimiter> rateLimiters = new ConcurrentHashMap();
|
|
private final int maxPacketsPerSecond;
|
|
private final int timeWindowSeconds = 5;
|
|
|
|
public PacketRateLimiter(int maxPacketsPerSecond) {
|
|
this.maxPacketsPerSecond = maxPacketsPerSecond;
|
|
}
|
|
|
|
public boolean allow(UUID player) {
|
|
if (this.maxPacketsPerSecond <= 0) {
|
|
return true;
|
|
}
|
|
RateLimiter limiter = this.rateLimiters.computeIfAbsent(player, id -> new RateLimiter(this.maxPacketsPerSecond * 5, 5000L));
|
|
return limiter.tryAcquire();
|
|
}
|
|
|
|
public void onPlayerLoggedOut(Player player) {
|
|
this.rateLimiters.remove(player.getUniqueId());
|
|
}
|
|
|
|
private static class RateLimiter {
|
|
private final int threshold;
|
|
private final long timePerTokenNanos;
|
|
private long lastLeakNanos;
|
|
private long amount;
|
|
|
|
public RateLimiter(int threshold, long windowMillis) {
|
|
this.threshold = threshold;
|
|
this.timePerTokenNanos = windowMillis * 1000000L / (long)threshold;
|
|
this.lastLeakNanos = System.nanoTime();
|
|
this.amount = 0L;
|
|
}
|
|
|
|
public boolean tryAcquire() {
|
|
long currentTime = System.nanoTime();
|
|
long elapsed = currentTime - this.lastLeakNanos;
|
|
long leakedTokens = elapsed / this.timePerTokenNanos;
|
|
if (leakedTokens > 0L) {
|
|
this.amount -= leakedTokens;
|
|
if (this.amount < 0L) {
|
|
this.amount = 0L;
|
|
}
|
|
this.lastLeakNanos += leakedTokens * this.timePerTokenNanos;
|
|
}
|
|
if (this.amount >= (long)this.threshold) {
|
|
return false;
|
|
}
|
|
++this.amount;
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|