Plugins
Build your own plugins against the bridge API.
Every server and every proxy receives the bridge from the cloud. It ships a small API that your own plugins compile against. The bridge itself does not belong inside your plugin; it is present on the server at runtime anyway.
Adding it
Install the bridge locally once, after that it is available to every project as a dependency:
For Velocity the artifact is called mutecloud-bridge-velocity. In Gradle it is the same with
compileOnly. To make sure the bridge loads before your plugin, add it to the dependencies:
for Paper depend: [MuteCloudBridge] in plugin.yml, for Velocity
dependencies = {@Dependency(id = "mutecloudbridge")} in the @Plugin annotation.
Everything goes through the static class MuteCloud, on Paper from
de.mutebefehl.cloud.bridge.paper, on Velocity from de.mutebefehl.cloud.bridge.velocity.
Servers in the network
A ServiceInfo contains name, group, node, address, phase, player count, version and the
properties the server has set itself.
Properties
A server can publish information about itself, such as the state of a round or the map that
is running. The values appear on every other server, in service info and in the API.
A server may have up to 64 properties, a name at most 64 characters, a value at most 1024. If the bridge briefly loses its connection, it sends everything again on reconnect.
Channels
Channels let plugins on different servers talk to each other without Redis or a database.
A message is text; an object is turned into JSON with Gson and comes back out on the other
side with as.
On Paper, receivers run on the main thread, so they may touch players and worlds. On Velocity they run on a background thread. The sender does not hear its own messages. A message may be up to 64 KB.
A channel name consists of letters, digits, -, _ and .. Subscribing to * receives
every channel.
Events
If you prefer listeners, the same happenings are available as platform events. On Paper they
are Bukkit events from de.mutebefehl.cloud.bridge.paper.event, fired on the main thread; on
Velocity they are events from de.mutebefehl.cloud.bridge.velocity.event for @Subscribe.
| Event | When |
|---|---|
CloudServiceUpdateEvent | a server changed its state, player count or properties. previous() returns the state before, becameReady() and propertiesChanged() save the comparison |
CloudServiceGoneEvent | a server is gone, last() is its last known state |
CloudMessageEvent | a message on a channel the plugin registered with MuteCloud.listen(channel) |
CloudConnectionEvent | the connection to the node is up (connected()) or has dropped |
Shared storage
The storage lives on the node, in a cluster on the leader. It is meant for small values every server should see, not as a replacement for a database.
From outside
Channels are also reachable through the API, so a website or a Discord bot can address plugins directly:
The token needs the right channels.publish. In the console the same works with
publish shop @Lobby {"player":"Steve","coins":100}, which is handy for trying things out.
Over the WebSocket a program listens by registering channels after its hello:
Messages then arrive as message with channel, message, from and target.
Servers up to 1.20.4
Servers running on Java 8 or 17 receive the legacy bridge, whose API is smaller. It lives at
de.mutebefehl.cloud.bridge.legacy.MuteCloud in the artifact mutecloud-bridge-legacy and
offers serviceName, group, connected, services, own, best, networkPlayers,
players, node, send, requestStart, stop, drain and data. There, own and best
return null instead of an Optional. Properties, channels and events are not yet available
on these servers.