
AtomGuard
🛡️ Advanced Minecraft Server Security & Exploit Protection — No scam unlike other plugins this one works fr.
Список изменений
🔧 Improvements
-
Velocity —
PlayerBehaviorProfile:usedUsernamesset is now thread-safe: The field was backed by a plainHashSet.recordSession()can be called from multiple Netty I/O threads simultaneously (each pre-login event arrives on a different thread), creating a risk ofConcurrentModificationExceptionor silent data corruption. Replaced withConcurrentHashMap.newKeySet(), which provides the sameSetcontract with full thread safety at zero contention cost. -
Velocity —
PlayerBehaviorProfile.calculateTrustScore(): new-player first-login bonus: Brand-new players (no sessions, no logins, no violations) start with score 50. Iftrust-score-thresholdis ever misconfigured above 50, every new player is denied before they can build any history. Added a +5 bonus applied only to completely fresh profiles, raising the guaranteed floor to 55 and providing a safe buffer against accidental misconfiguration. -
Velocity —
BehaviorManager.getProfile():offlineModeLenientset at profile creation time: Previously the flag was set only insiderecordLogin(), which is called afterTrustScoreCheckalready ran. A fresh profile therefore always hadofflineModeLenient = false, making the multi-account username penalty fire on offline-mode servers even when it should have been suppressed. Now the config is read once at profile instantiation so the flag is correct before any pipeline check consults the score. -
Velocity —
ThreatScoresetters are nowsynchronized:resetForNewAnalysis()andcalculate()were alreadysynchronized, but individual setters (e.g.setConnectionRateScore()) were not. Under concurrent analysis of the same IP: Thread A sets a score → Thread B resets → Thread A callscalculate()— resulting in a corrupted total that could trigger a false-positive block or silently suppress a real threat. All seven setters are nowsynchronizedon the same monitor ascalculate(). -
Velocity —
AttackLevelManager.shouldAllowConnection(): LOCKDOWN no longer blocks verified players: TheLOCKDOWNcase previously returnedfalseunconditionally, with a comment claimingVerifiedPlayerShieldhandles verified players separately. In practice the call order inDDoSProtectionModule.checkConnection()is Shield first, thenshouldAllowConnection(). The level manager's blanketfalseoverrode the Shield's approval, meaning verified players were rejected during LOCKDOWN regardless of slot availability. Changed toisVerified— matching theCRITICALcase. -
Velocity —
SmartThrottleEngine: LOCKDOWN verified-player limit has a hard minimum of 5:getLimitForLevel()returnedlockdownLimitfor verified players under LOCKDOWN. IflockdownLimitwas set to 0 or 1 in config, verified players could still be throttled out. The value is nowMath.max(5, lockdownLimit), guaranteeing that at least 5 reconnect attempts per 60-second window are allowed even during the strictest attack mode. -
Velocity —
VerifiedPlayerShield.isVerified(): consultsVerificationModulefirst: Previously only checkedVelocityAntiBotModule.isVerified(). Players verified via the Limbo system (VerificationModule) were not recognized by the Shield during CRITICAL/LOCKDOWN, causing them to be denied slots despite having completed the physics challenge. Now checks VerificationModule when enabled, with AntiBot as fallback. -
Velocity —
DDoSProtectionModule.checkConnection(): CPS counter excludes verified connections:synFloodDetector.recordConnection(ip)was called for every incoming connection, including verified players. Fifty verified players reconnecting simultaneously after a server restart could push the CPS counter above the attack threshold, escalating the attack level artificially and triggering unnecessary lockdown for unrelated new players. Verified connections are now excluded from the CPS count. -
Velocity —
DDoSProtectionModule: verified players do not receive attack-mode reputation penalties:reputationTracker.recordAttackConnection(ip)was called for all connections during attack mode. Verified players reconnecting during an attack were penalized, eventually getting close to the auto-ban threshold despite being legitimate users. Penalty is now skipped whenisVerifiedis true. -
Velocity —
ConnectionListener.onDisconnect():VerifiedPlayerShieldslot released on player quit:VerifiedPlayerShield.onConnectionClosed()decrementsslotsInUsebut was never called from the disconnect listener. Slots only grew, never shrank. After enough players logged out and back in during a CRITICAL/LOCKDOWN event,slotsInUsewould reachguaranteedSlotsand all subsequent verified connections would be denied with "slot full".plugin.getDdosModule().onConnectionClosed(ip, "player-disconnect")is now called on everyDisconnectEvent. -
Velocity — Five modules default to
enabled: falseinconfig.yml:ReconnectControlModule,LatencyCheckModule,FastChatModule,PasswordCheckModule, andCountryFilterModulehad nomodules.<name>.enabledkey inconfig.yml.VelocityModule.isConfigActive()defaults totruewhen the key is absent, so all five were silently active on every fresh install — imposing reconnect cooldowns, latency-based kicks, and chat rate limits without the admin's knowledge. Explicitenabled: falsesections have been added for each. -
Velocity —
ReconnectControlModule: verified players bypass cooldown and crash-loop detection: Pre-login listener had no verified-player check. Verified players reconnecting after a server restart hit the 10-second reconnect cooldown or were flagged as crash-loop clients. Added verified bypass via VerificationModule and AntiBot before any cooldown/crash-loop logic runs. Crash-loop threshold raised from 3 to 5 reconnects, window extended from 30 s to 60 s, and default action changed fromkicktoflagto prevent mass false kicks after restarts. -
Velocity —
LatencyCheckModule: verified players bypass latency checks: The module registered its ownLoginEventlistener, independent of the pipeline'sskipForVerified()mechanism. A player allowed by the pipeline could still be kicked by this module for a sub-5 ms login time (common on local datacenter proxies). Verified players now return early. Defaultminimum-mslowered from 5 to 0 and default actions changed fromkicktoflag. -
Velocity —
ChatListener: defers toFastChatModulewhen active: BothChatListener(backed byProxyExploitModule.checkChat()) andFastChatModulesubscribed toPlayerChatEventindependently with separate rate-limit counters. A single message could be evaluated by both systems, producing inconsistent deny decisions and sending two different error messages to the player.ChatListenernow returns early whenFastChatModule.isEnabled()is true. -
Velocity —
NicknameBlocker+HandshakeValidator: Bedrock/Floodgate prefix exemption: Floodgate prefixes usernames with.(e.g..BedrockPlayer123).ozel-karakter-engel: truein NicknameBlocker and the[a-zA-Z0-9_]+regex in HandshakeValidator both rejected these names as containing illegal characters. A configurablebedrock-prefixkey (default.) is now checked first in NicknameBlocker; HandshakeValidator strips a leading.or*before applying the character regex. -
Velocity —
JoinPatternDetector.getJoinScore(): maximum capped at 60: The raw score could reach 50 (rapid + quitter combined). WithjoinPatternScore * 0.25weighting andflagCount = 1, the 60 % single-flag reduction yields50 * 0.25 * 0.60 = 7.5— harmless alone. But combined with any second flag, the reduction disappears and the score contribution can push a borderline connection to medium-risk. The cap prevents this single detector from dominating the total score. -
Velocity —
AntiBotCheck: redundantantiBot.isVerified()call removed:skipForVerified() = truealready prevents the check from running for verified players at the pipeline level. The additionalif (antiBot.isVerified(ctx.ip()))guard insidecheck()was dead code that added unnecessary log noise and a redundant ConcurrentHashMap lookup on every pre-login. -
Velocity —
DDoSCheck: verified status sourced fromctx.verified()instead ofAntiBot: Was callingantiBot.isVerified(ctx.ip())directly insidecheck(), ignoring thatctx.verified()already encodes the correct value (from both VerificationModule and AntiBot) as set byConnectionListener.onPreLogin(). Unified to usectx.verified()and removed the now-unusedVelocityAntiBotModuleimport. -
Velocity —
ProtocolCheck: protocol number included in kick message: The kick message calledbuildKickMessage("kick.protocol", Map.of("min", "1.21.4", "max", "1.21.4"))with hardcoded version strings unrelated to the actual validation result. Replaced withMap.of("sebep", result.reason(), "protokol", String.valueOf(ctx.protocol()))so the message conveys the actual rejected protocol ID — useful for diagnosing ViaVersion setups. -
Velocity —
ConnectionPipeline.addCheck()is nowsynchronized: The method calledchecks.clear()thenchecks.addAll(sorted)on aCopyOnWriteArrayList. Aprocess()call arriving between those two operations would see an empty list and skip all security checks silently. The method is now synchronized to make the snapshot-replace operation atomic. -
Velocity —
VPNCheck.check(): timeout reduced to 2 s withexceptionallyfail-open: The synchronouscheck()calledcheckAsync(ctx).join(), blocking the Velocity event thread for up to 3 seconds on VPN lookup timeout. Timeout reduced to 2 seconds;exceptionally(e -> CheckResult.allowed())ensures any completion exception (timeout, network error) is treated as a pass rather than crashing the pipeline. -
Limbo —
GravityCheck: tolerance widened and warmup period added:TOLERANCEraised from0.04to0.08blocks. High-latency clients (300 ms+) may have multiple tick position updates batched into a single packet, causing the reported Y to deviate from the expected value by more than the old tolerance. A 2-tick warmup period is now applied — ticks 1 and 2 are never counted as incorrect — to absorb the initial positional offset that occurs when gravity integration begins from a rest state.
🐛 Bug Fixes
-
Core —
DuplicationFixModule.onInventoryClick():ArrayIndexOutOfBoundsExceptionon slot -1:event.getRawSlot()andevent.getSlot()return-1for clicks outside the inventory window (e.g. dropping items, clicking the area around the inventory). The handler attempted array-index operations with this value. Added an early return when either slot is negative, guarding all subsequent slot-access code. -
Core — Duplicate
HandlerList.unregisterAll(this)removed from six modules:AbstractModule.onDisable()already callsHandlerList.unregisterAll(this). Six subclasses (SmartLagModule,ShulkerByteModule,BundleLockModule,StorageEntityLockModule,ItemSanitizerModule,RedstoneLimiterModule,DuplicationFixModule) repeated this call aftersuper.onDisable(), resulting in a no-op double-unregister on every plugin reload. Redundant calls removed.
