-
Notifications
You must be signed in to change notification settings - Fork 48
2. API
SimpleCloud provides an API that can be used everywhere. To use the API add the following to your pom.xml file.
<repository>
<id>gradle-release-local</id>
<url>https://repo.thesimplecloud.eu/artifactory/list/gradle-release-local/</url>
</repository>
<!--For plugins and modules-->
<dependency>
<groupId>eu.thesimplecloud.simplecloud</groupId>
<artifactId>simplecloud-api</artifactId>
<version>2.8.1</version>
<scope>provided</scope>
</dependency>
<!--For plugins only-->
<dependency>
<groupId>eu.thesimplecloud.simplecloud</groupId>
<artifactId>simplecloud-plugin</artifactId>
<version>2.8.1</version>
<scope>provided</scope>
</dependency>
<!--For modules only-->
<dependency>
<groupId>eu.thesimplecloud.simplecloud</groupId>
<artifactId>simplecloud-base</artifactId>
<version>2.8.1</version>
<scope>provided</scope>
</dependency>
<!--For modules only-->
<dependency>
<groupId>eu.thesimplecloud.simplecloud</groupId>
<artifactId>simplecloud-launcher</artifactId>
<version>2.8.1</version>
<scope>provided</scope>
</dependency>
The CloudAPI class is everywhere in the network accessible. It is used to get information about Services, Groups, Wrappers, Players, Templates,call events and send messages.
SimpleCloud provides its own event system.
First, you need to create a class that implements the listener. You will see that there is almost no difference to Bukkit and BungeeCord.
public class CloudListener implements IListener {
@CloudEventHandler
public void handle(CloudServiceStartedEvent event) {
ICloudService cloudService = event.getCloudService();
}
}
Now you have to register the listener.
CloudAPI.getInstance().getEventManager().registerListener(yourCloudModule, new CloudListener());
If you are not programming a CloudModule replace yourCloudModule
with CloudAPI.getInstance().getThisSidesCloudModule()
Services in SimpleCloud are all proxies and servers. To get all services use:
CloudAPI.getInstance().getCloudServiceManager().getAllCachedObjects();
To get a specific service use:
CloudAPI.getInstance().getCloudServiceManager().getCloudServiceByName("Lobby-1");
To get the service you're plugin is running on use:
ICloudService cloudService = CloudPlugin.getInstance().thisService();
Now you can, for example, update the state.
cloudService.setState(ServiceState.INVISIBLE);
cloudService.update();
Don't forget to call the update
method the service after you made changes. Otherwise, your changes will be lost.
To get all groups use:
CloudAPI.getInstance().getCloudServiceGroupManager().getAllCachedObjects();
To get a specific group use:
CloudAPI.getInstance().getCloudServiceGroupManager().getServiceGroupByName("Lobby");
To start a service you need the group of the service you want to start first.
ICloudServiceGroup serviceGroup = CloudAPI.getInstance().getCloudServiceGroupManager().getServiceGroupByName("Lobby");
serviceGroup.startNewService();
You can specify custom parameters for the new service:
ITemplate template = CloudAPI.getInstance().getTemplateManager().getTemplateByName("Lobby");
ICloudServiceGroup serviceGroup = CloudAPI.getInstance().getCloudServiceGroupManager().getServiceGroupByName("Lobby");
serviceGroup.createStartConfiguration() //Creates a new start configuration to apply custom settings
.setMaxMemory(1024) //Sets the amount of memory in MB
.setMaxPlayers(10) //Sets the maximum amount of players
.setTemplate(template) //Sets the template to use
.setServiceNumber(1) //Sets the service number e.g. Lobby-1 1 would be the service number
.startService(); //Starts the service
You don't need to call any of these methods. The settings of the group will be set as default.
ICloudServiceGroup serviceGroup = CloudAPI.getInstance().getCloudServiceGroupManager().getServiceGroupByName("Lobby");
serviceGroup.createStartConfiguration() //Creates a new start configuration to apply custom settings
.setMaxMemory(1024) //Sets the amount of memory in MB
.startService(); //Starts the service
This is ok too. The cloud will use the template and max-players of the group. The service number will be generated automatically. Only the memory will be overridden.
There are two ways to get a CloudPlayer
.
The first one is used if you're writing a module ore the player is currently connected to the server the plugin is running on.
ICloudPlayer player = CloudAPI.getInstance().getCloudPlayerManager().getCachedCloudPlayer("Fllip");
This method returns the CloudPlayer from the cache. The second one is used if the player is not connected to the server your plugin is running on.
ICommunicationPromise<ICloudPlayer> promise = CloudAPI.getInstance().getCloudPlayerManager().getCloudPlayer("Fllip");
This method sends a request to the manager and returns the CloudPlayer
if he is online.
The cloud provided the possibility to add properties to services or players. The properties are then accessible over the whole network.
ICloudService service = CloudAPI.getInstance().getCloudServiceManager().getCloudServiceByName("Lobby-1");
service.setProperty("countdown", 60);
service.update();
This work the same way for players. Don't forget to update the service or the player after you set a property.
IProperty<Integer> property = service.getProperty("countdown");
Integer countdown = property.getValue();
Setting and getting properties works the same way as for services. You can find it above. Note that properties for players will also be saved in the database after the player disconnects.
SimpleCloud MessageChannels are an easy way to communicate between services. You can send and receive objects.
Fist, you need to create a class which you want to send. Of course, you can also send a string or an integer.
This is just an example class
public class ClassToSend {
private final String name;
private final UUID uniqueId;
private final String message;
public ClassToSend(String name, UUID uniqueId, String message) {
this.name = name;
this.uniqueId = uniqueId;
this.message = message;
}
public String getName() {
return name;
}
public UUID getUniqueId() {
return uniqueId;
}
public String getMessage() {
return message;
}
}
Note, that you cannot send an interface or objects with recursive fields. For example, the Bukkit Player or CraftPlayer will not work.
Now you can register your message channel.
IMessageChannel<ClassToSend> messageChannel = CloudAPI.getInstance().getMessageChannelManager().registerMessageChannel(yourCloudModule, "your-message-channel", ClassToSend.class);
If you are not programming a CloudModule replace yourCloudModule
with CloudAPI.getInstance().getThisSidesCloudModule()
With the IMessageChannel
it is now easy to send a message
ICloudService receiver = CloudAPI.getInstance().getCloudServiceManager().getCloudServiceByName("Lobby-1");
ICloudService receiver2 = CloudAPI.getInstance().getCloudServiceManager().getCloudServiceByName("Lobby-2");
ClassToSend classToSend = new ClassToSend("Fllip", UUID.randomUUID(), "He likes fish");
messageChannel.sendMessage(classToSend, Arrays.asList(receiver, receiver2));
This example will send the classToSend
to Lobby-1 and Lobby-2.
To receive the message you have to register the MessageChannel
the same way as on the sender side.
It is important that you specify the same class. (ClassToSend)
Now you can add a listener to the MessageChannel
messageChannel.registerListener(new IMessageListener<ClassToSend>() {
@Override
public void messageReceived(ClassToSend message, @NotNull INetworkComponent sender) {
}
});
The messageReceived
method is called when the MessageChannel receives a message.
The provided sender
is the sender of the message. If you are sending the message from a service you can cast it to ICloudService
.
Often when you call an API method you get an ICommunicationPromise
back. This happens when the cloud cannot deliver the result immediately. Here are ways to deal with the promise.
ICloudService service = CloudAPI.getInstance().getCloudServiceManager().getCloudServiceByName("BW-1");
ICommunicationPromise<ICloudPlayer> promise = CloudAPI.getInstance().getCloudPlayerManager().getCloudPlayer("Fllip");
promise.then(player -> player.connect(service));
The then
method is called with the result and only if the request was successful. So if the player is not online then
is never called. To catch the failure or print it use:
promise.then(player -> player.connect(service)).throwFailure();
This method will just throw the failure. It is sometimes useful if you just want to see if an error occurs but it doesn't catch the error.
promise.addListener(resultPromise -> {
if (resultPromise.isSuccess()) {
ICloudPlayer cloudPlayer = promise.get();
cloudPlayer.connect(service);
} else {
//handle failure
Throwable cause = resultPromise.cause(); //the cause of the failure.
}
});
Please note that then
and all listeners added to the promise are called in a different thread.
There are also blocking methods to get the result:
ICloudPlayer player = promise.getBlocking();
This method waits for the promise to complete and returns the result if the request was successful. If it wasn't the cause will be thrown.
ICloudPlayer player = promise.getBlockingOrNull();
This method waits for the promise to complete and returns the result if the request was successful. If it wasn't this methods returns null
.