Integrations

Everything in settings.yml that talks to something other than Ecstacy: clients, Discord, and the two systems that make the server look like it runs a different anticheat.

Client brand detection

settings.yml
client-brand:
  notify: true
  kick: true
  blacklist:
    - Impact
    - Wurst
    - LiquidBounce
    - Aristois
    - Sigma
    - Vape
  kick-message: "&cThis client is not allowed on this server."
Key Default Meaning
notify true Tell staff when a player joins with a detected client
kick true Kick players on the blacklist automatically
blacklist six entries Client brands, case-insensitive
kick-message n/a Shown to the kicked player

Note

Brand is what the client reports about itself. A cheat client that lies about its brand will not appear here. This catches the ones that do not bother, which is more of them than you would expect, but it is a filter and not a detection.

Lunar, Badlion and Feather

Ecstacy can disable specific mods for players on these clients through each client's own API.

settings.yml
lunar:
  enabled: true
  disabled-mods:
    - Freelook
    - Minimap
    - Waypoints
    - Zoom

badlion:
  enabled: true
  disabled-mods:
    - Freelook
    - Minimap
    - Waypoints
    - Zoom

feather:
  enabled: true
  disabled-mods:
    - perspective
    - autoperspective
    - waypoints
    - zoom

Lunar and Badlion take the mod names as shown in their own menus. Feather uses slug names from the Feather API documentation. Note the lowercase, and that perspective and autoperspective are Feather's names for freelook.

Discord. Use webhooks.yml

Warning

There are two Discord configurations in the plugin folder and only one of them works. The discord: section of settings.yml is inert in the current build. Nothing reads it. Put your webhook in webhooks.yml. Filling in settings.yml produces no messages and no error.

webhooks.yml gives three independent webhooks, each with its own URL, bot name, avatar and embed colour, rather than one URL with event toggles.

webhooks.yml
webhooks:
  enabled: true
  timeout_ms: 5000
  retry_attempts: 2

  violation:
    enabled: true
    url: "https://discord.com/api/webhooks/…"
    username: "Ecstacy"
    color: 16733525
    filters:
      checks: []     # empty = every check
      min_flags: 1   # post from the first flag

  punishment:
    enabled: true
    url: "https://discord.com/api/webhooks/…"

  reputation:
    enabled: true
    url: "https://discord.com/api/webhooks/…"
    bad_below: 30
Webhook Fires on Embed contains
violation Every flag Player, check, type, VL (vl/maxVl), info
punishment A punishment being applied Player, check, type, reason
reputation A player joining with reputation at or below bad_below Player and score

violation.filters narrows the noise without touching detection: checks limits which checks post (empty means all), min_flags sets how many flags a player needs before anything is posted.

Sends run on virtual threads, so a slow or dead webhook never blocks the main thread.

Create the webhook URL under Server Settings → Integrations → Webhooks in Discord.

Caution

A webhook URL is a credential. Anyone holding it can post to that channel as your bot. Do not commit webhooks.yml to a public repository with a live URL in it.

Spoofer

Registers fake anticheat commands so a cheater probing for what the server runs gets an answer that is not the truth.

settings.yml
spoofer:
  enabled: true
  type:
    - "GRIM"
    - "VULCAN"

Valid values: GRIM, VULCAN, NONE.

Mimic

A configurable version of the same idea: you define the commands, the responses, and where the version number comes from. It is independent of spoofer and both can run together.

settings.yml
mimic:
  enabled: false
  commands:
    - name: "grim"
      aliases: []
      version-source: "GITHUB"
      version-repo: "GrimAnticheat/Grim"
      version-url: ""
      static-version: "2.3.72"
      response-format: "&bGrim &8» &fThis server is running GrimAC v{version}"
      subcommands:
        - name: "alerts"
          response: "&bGrim &8» &fAlerts are now toggled"
  patterns: []
Key Meaning
version-source GITHUB, MCMARKET, SPIGOT or STATIC
version-repo For GITHUB: owner/repo
version-url For MCMARKET and SPIGOT: the full resource page URL
static-version Used when the source is STATIC, and as the fallback when a fetch fails
response-format {version} is substituted
subcommands Each with its own fixed response

patterns defines transaction patterns from config instead of implementing the TransactionPattern interface:

settings.yml
mimic:
  patterns:
    - name: "example-logger"
      type: "BOTH"          # PRE, POST or BOTH
      condition: "always"
      action: "log"         # log | broadcast | command:<cmd>

command: actions accept {player}, {uuid} and {time}.

Addons can hook the fake commands through EcstacyFakeCommandEvent and the transaction pipeline through the TransactionPattern interface. See the developer API.

Bait

settings.yml
bait:
  enabled: false

Passive NPC bait, detection-only and off by default. Experimental.

When an integration is not working

Work down this table before changing configuration. Most reports turn out to be the first row.

Symptom Check first
A client integration does nothing The client's own API plugin is installed and loaded. Ecstacy softdepends on them, so a missing one is silent
Mod control has no effect on some players Those players are not on that client. A vanilla or third-party client reports a brand and nothing else
Discord webhook posts nothing The URL, and whether the event type is enabled. A webhook Discord has revoked also fails silently
Discord posts stop after working Discord rate-limits webhooks. High-volume servers should raise fail.alert.every rather than the webhook rate
The brand blacklist catches nobody Brands are self-reported and trivially changed. It is a filter for lazy clients, not a detection
The spoofer replies to nothing It only answers the commands it implements. mimic is the configurable version
mimic shows the wrong version The remote fetch failed and it fell back to static-version. Set that to something plausible

Note

Everything under spoofer and mimic is theatre by design. It makes the server look like it runs a different anticheat. It detects nothing on its own and no flag ever comes from it. Treat it as deterrence, and do not let a convincing fake reply become the reason you skipped a real check.

What integrations are and are not for

Client integrations control what a player's client is allowed to load. That is a different job from detection and the two do not overlap:

  • Blocking a mod through Lunar, Badlion or Feather relies on the client cooperating. Those clients do cooperate. That is the point of their APIs. But a player who leaves for a client without an API simply is not covered.
  • The brand blacklist reads what the client says it is. Any cheat client that cares will report vanilla.
  • Neither of these produces a violation, a VL or a punishment. If you want a player detected rather than restricted, that is the checks, not this page.

The practical combination on a competitive server is: mod control through the client APIs to keep honest players honest, brand blacklist to catch the careless, and the detection families for everyone else.

Order of operations

When you are setting integrations up for the first time:

  1. Install the client API plugins you intend to use, and restart. Confirm they are loaded before configuring anything in Ecstacy.
  2. Enable one integration, restart, and verify with a real account on that client. Mod control fails quietly when the client-side half is missing, so testing from the server console proves nothing.
  3. Add the Discord webhook once flags are actually being produced, so you can see the volume you are signing up for.
  4. Leave spoofer and mimic until last. They change nothing about protection and are the easiest thing to misread as broken while a real problem sits elsewhere.

Last updated