Skip to content
Fllip edited this page Oct 21, 2024 · 23 revisions

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>

CloudAPI

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.

Events

SimpleCloud provides its own event system.

Register a listener

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

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.

Groups

To get all groups use:

CloudAPI.getInstance().getCloudServiceGroupManager().getAllCachedObjects();

To get a specific group use:

CloudAPI.getInstance().getCloudServiceGroupManager().getServiceGroupByName("Lobby");

Start a service

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.

CloudPlayer

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.

Properties

The cloud provided the possibility to add properties to services or players. The properties are then accessible over the whole network.

Set propeties

    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.

Read properties

    IProperty<Integer> property = service.getProperty("countdown");
    Integer countdown = property.getValue();

CloudPlayer properties

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.

MessageChannel

SimpleCloud MessageChannels are an easy way to communicate between services. You can send and receive objects.

Register a MessageChannel

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()

Send a message

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.

Receive a message

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.

CommunicationPromise

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.