Skip to content

Webhook Fixer & more

Choose a tag to compare

@SrCodexStudio SrCodexStudio released this 26 Apr 01:36
99a0864

Discord Webhook System

  • Added Discord webhook notifications for alt account detection with rich embeds showing full player profile, IP history with connection counts, detailed
    alt list with spoilered IPs, country, and last seen timestamps
  • Added Discord webhook notifications for banned IP connection attempts showing player name, ban type (OP1/OP2/CIDR), pattern, reason, banned by, duration
    remaining, and known alt accounts
  • Webhook configuration lives in its own discordwebhook.yml file with per-event toggles, separate embed colors, and full reload support via /ipdy reload
  • Implemented global rate-limited queue system (configurable max-per-minute and queue size) that respects Discord's rate limits and automatically backs
    off on 429 responses
  • Thread-safe cooldown using AtomicLong.compareAndSet to prevent duplicate webhook sends under concurrent events
  • Webhook async tasks are tied to the plugin lifecycle via Bukkit scheduler, preventing orphan coroutines on reload

Emergency Performance Patch (16 fixes)

  • Fixed AlertService calling Bukkit API (getOnlinePlayers, sendMessage, playSound) from async threads. All broadcasts now scheduled to the main thread via
    runTask
  • Fixed BanService cache reload allowing banned IPs to connect during the reload window. Cache now uses atomic swap strategy with Volatile references so
    readers never see a partially loaded state
  • Fixed the entire ConnectionListener join pipeline running on the main thread between suspend points. The full 8-step pipeline now executes on
    Dispatchers.IO, freeing the main thread completely
  • Increased SQLite HikariCP connection pool from 3 to 10 and reduced connection timeout from 10s to 5s to prevent pool exhaustion under burst joins (50+
    simultaneous connections)
  • Fixed GeoIP service caching failed lookups with full TTL duration, poisoning country restrictions and VPN detection. Failed results now cache for only
    60 seconds
  • Simplified ExpiringCache by removing the ConcurrentLinkedDeque LRU tracker which had a race condition causing unbounded memory growth from duplicate
    keys. Now uses TTL-only eviction which is simpler and thread-safe
  • Fixed WhitelistService cache reload with the same atomic swap strategy as BanService to prevent whitelisted players from being subject to ban checks
    during reload
  • Fixed WhitelistService calling Bukkit.getOfflinePlayer() without IO dispatcher, potentially blocking the coroutine thread
  • Fixed DiscordWebhookService cooldown check having a time-of-check-time-of-use race condition on the volatile field
  • Replaced CopyOnWriteArrayList in RateMonitorTask with ConcurrentLinkedQueue to eliminate full array copies on every bot connection during attack waves
  • Added player.isOnline guards before alt detection and VPN enforcement steps in the join pipeline to prevent processing stale Player references after
    disconnect
  • Fixed DataRetentionTask silently swallowing all exceptions, which could cause the connections table to grow unboundedly without any log indication
  • Fixed operator precedence bug in BanService.getEstimatedIPCount for CIDR bans where coerceAtMost was applied to the shift amount instead of the result
  • Replaced non-atomic getOrPut with computeIfAbsent on ConcurrentHashMap in RateMonitorTask for safe concurrent insertion
  • Eliminated SELECT queries inside the PlayerRepository write transaction by using INSERT OR IGNORE pattern, reducing SQLite write lock duration
  • Fixed loadCaches running on main thread between IO dispatches during plugin startup

Bedrock/Floodgate Support

  • Full support for Bedrock player names with prefix characters like .Steve or *Steve
  • Smart UUID resolution for whitelist: checks online player first, then own database, then Mojang API (skipped for Bedrock names), then Bukkit fallback
  • Enhanced tab completion across all player commands so typing Ste suggests both Steve and .Steve
  • Added PlayerUtils utility with isBedrockName, stripBedrockPrefix, and matchPlayerName helpers

Database Hardening

  • Added missing index on connections.username (COLLATE NOCASE) fixing full table scans on the largest table for every history query
  • Replaced all LOWER(username) = LOWER(?) queries with username = ? COLLATE NOCASE across PlayerRepository and ConnectionRepository to enable proper index
    usage
  • Added per-connection SQLite PRAGMAs via HikariCP connectionInitSql so WAL mode, foreign keys, and busy timeout apply to all pool connections, not just
    the first one
  • Fixed race condition in PlayerRepository.recordConnection where two simultaneous first-joins for the same UUID could cause a primary key violation. Now
    uses idempotent INSERT OR IGNORE plus UPDATE
  • Added audit log retention with configurable audit-max-days (default 90) to prevent unbounded growth of the audit_log table
  • Country rules added via commands now persist to the database and survive reloads and server restarts

bStats Integration

  • Added bStats metrics with 6 custom charts: active bans, whitelisted players, GeoIP cache size, VPN detection status, country restriction status, and
    country restriction mode

First-Join Console Notification

  • Professional formatted console notification when a brand-new player joins for the first time showing username, IP, country, and detected alt accounts
  • Disabled by default, enable with first-join-console in config.yml
  • Fully customizable message template in messages.yml