API overview
Venus exposes one entry point, ten services and a small event system. This page covers how to reach them and what to expect from each.
Adding the dependency
The API artifact is compile-only. It contains stub implementations of the provider so that a plugin can reference the types at compile time; the working objects are supplied by Venus at runtime. Shading it would bundle the stubs and break access, so leave it out of any shaded jar.
repositories {
maven("https://repo.venus.ac/snapshots")
}
dependencies {
compileOnly("ac.venus.venusac:VenusAPI:VERSION")
}<repository>
<id>venusac-snapshots</id>
<url>https://repo.venus.ac/snapshots</url>
</repository>
<dependency>
<groupId>ac.venus.venusac</groupId>
<artifactId>VenusAPI</artifactId>
<version>VERSION</version>
<scope>provided</scope>
</dependency>Getting the API object
The API is a singleton published once Venus has loaded. VenusAPIProvider.get() returns it and throws if it is called too early; getOrNull() returns null instead, and getAsync() completes later. Because Venus loads asynchronously relative to the Bukkit plugin sequence, callers that cannot tolerate an exception should use the async form — see VenusAPIProvider and the loader hook.
VenusAPIProvider.getAsync().thenAccept(api -> {
api.events().repository().register(ViolationEvent.class, event -> {
getLogger().info(event.user().username() + " failed " + event.check().name());
});
});What the API exposes
- Server — identity, TPS, player count, cloud state, the profiler and a config reload.
- UserRepository — look up tracked players.
- CheckRegistry — the full check catalog, also when nobody is online.
- Events — register listeners and dispatch your own events.
- Subcommands — add commands under
/venus. - PunishmentService — kick, ban, ban wave.
- HistoryService — sessions and violations.
- AlertService — per-player alert channels.
- ExemptionService — exemptions and tolerance.
- CloudService — cloud connection and profiles.
Events
Venus has its own event system, independent of Bukkit's. The hierarchy is small:
VenusApiEvent (timestamp)
├── CancellableVenusEvent (cancelled)
│ └── UserCancellableEvent (user)
│ ├── ViolationEvent check, vl, verbose, experimental
│ ├── DetectionAlertEvent check, vl, message, action
│ ├── VerboseEvent check, vl, message, output
│ ├── MitigationEvent check, vl, mitigation
│ ├── PunishmentEvent check, type, reason
│ ├── QueuePunishmentEvent check, delayMs, reason
│ ├── OrdinaryKickEvent reason, apiInitiated
│ └── CloudDetectionEvent type, tags, confidence, message
└── UserEvent (user)
├── UserJoinEvent
└── UserQuitEventCancelling an event suppresses the action it describes: a cancelled ViolationEvent drops the flag before it is counted, a cancelled PunishmentEvent means the punishment does not run, and a cancelled OrdinaryKickEvent keeps the player connected. Full details are on event classes.
Threading
- User events are dispatched on the thread that observed the user — usually that user's Netty thread. Keep listeners short and thread-safe.
- Cloud events arrive on the cloud thread.
- Reads on the API are safe from any thread. If you need to touch the server or a
Bukkitobject, hop to the main thread yourself.
Class loading
Venus is loaded by its own loader, so it may not be present at the moment your plugin is enabled even though both are installed. Two rules avoid the whole class of problem:
- Declare
depend: [VenusLoader]inplugin.yml. - Keep API access out of your main class; call into a separate class from an async callback so the API classes are resolved on demand.