CloudLink

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Welcome!

Welcome to the official documentation for the CloudLink Suite!

Please keep the comments clean. Information pretaining to the extension and the server can be found here.

Note that these docs contain stability levels. You can view the information about stability levels here:

 

Stable
3 (Stable)
2.5 (Stable/Subject to Change)
2 (Subject to Change)

Experimental
1 (Experimental)

Draft/Not Usable
0 (Draft)

Deprecated
-1 (Not Recommended)
-2 (Deprecated)

Extension

Loading the extension

Stability: 3 (Stable)

To use CloudLink, you will need to load it in a Scratch Mod. You can use one of the following to load CloudLink:

Automatically loaded

• TurboWarp
• SheepTester's E羊icques

Manual loading required

• Ogadaki's Adacraft
Open the Editor, Click on the "Extensions" button (it looks like this):

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
and click on "CloudLink".

Extension Basics

Stability: 0 (Draft)

Getting started

Learn more on how to correctly start a CloudLink connection.

Blocks index

Stability: 3 (Stable)

Connect to (ws://localhost:3000/)

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

This block allows you to connect to any server IP. By default, it will allow you to connect to CloudLink running on your computer's localhost on port 3000 (see the server section for more details).

You can put in any server address that starts with wss://.

(For security purposes, web browsers don't allow you to use server URLs that start withws://, as these connections aren't secure. The only exception to this rule is the localhost/127.0.0.1.)

Connect to (Server)

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

This block allows you to connect to a publically accessible server. The list is only updated when the extension is loaded. When the extension is loaded, a fetch request is sent and will download a string of JSON from GitHub, containing an array of all the available servers to use. From there, you can simply select a server through the menu button on the block, and run the block to connect.

To implement a user-friendly server selector, use the Server List reporter, the JSON parser block, and the Connect to IP block.

This block is intended for testing/development purposes only and shouldn't be used in production. Server list subject to change.

Disconnect

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

This block terminates the connection to the server. Should be self-explanitory.

Set (A name) as username

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

This block sets your username on the link. This will only work when you are connected to a server.

The block only allows the username to be set when the input meets the following criteria:

  1. The input is no longer than 20 characters.
  2. The input cannot be blank.
  3. The input cannot contain a username that already exists on the link (username conflicts)
  4. The input cannot be a reserved ID:
    • %CA% - CloudAccount services
    • %CC% - CloudCoin services
    • %CD% - CloudDisk services
  5. The connection must be established and working.
  6. The username has not been set previously.

The username block can only be used once per connection. To change your username, you must disconnect from the link and reconnect.

Send (Apple)

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

This block sends general-purpose packets to everyone (including you) connected on the link.

The block supports the following datatypes:

  • String (ASCII, UTF, etc.)
  • Int/Float (Numbers)
  • JSON ({"foo": "bar"})

The packet will be sent under the following criteria:

  1. The data input cannot be larger than 1 KB in size (1000 characters/bytes)

Send (Apple) to (A name)

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Like the "Send (A name)" block, this block allows you to send general-purpose packets to specific usernames.

The packet supports all the same datatypes as it's counterpart, and only allows the packet to be send under the following criteria:

  1. The username input cannot be blank.
  2. The username input contains a username present on the link.
  3. The data input cannot be larger than 1 KB in size (1000 characters/bytes)

Send Var (Apple) with Data (Banana)

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Like the "Send (Apple)" block, it allows you to send general-purpose packets to everyone (including you) on the link, however, this data is sent as a custom variable.

By specifying a name and setting a value, you can send an infinite amount of custom variables.

Like the "Send (Apple)" block, it supports all the same datatypes.

The packet will be sent, under the following criteria:

  1. The variable name input cannot be blank.
  2. The variable data input cannot be larger than 1 KB in size (1000 characters/bytes)

On the receiving end, if the variable doesn't exist, it will be created and it's value will be written. Variables will survive as long as the connection is established and running. All variable data will be destroyed when the connection is lost or the "Disconnect" block is used.

Send Var (Apple) to (A name) with Data (Banana)

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Like the "Send (Apple) to (A name)" block, it allows you to send general-purpose packets to specific usernames, however, this data is sent as a custom variable.

By specifying a name and setting a value, you can send an infinite amount of custom variables.

Like the "Send Var (Apple) with Data (Banana)" block, it supports all the same datatypes.

The packet will be sent, under the following criteria:

  1. The variable name input cannot be blank.
  2. The username input must cannot be blank.
  3. The username input contains a username present on the link.
  4. The variable data input cannot be larger than 1 KB in size (1000 characters/bytes)

Reset Got New [Global/Private/Direct/Status Code] data

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

This block resets the "Got New [Global/Private/Direct/Status Code] Data?" reporter's value to False.

You can use this block to signify that a new Global/Private stream packet has been handled and that the code should wait for a new packet.

Reset Got New [Global/Private] var (Apple) data

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

This block resets the "Got New [Global/Private] var (Apple) Data?" reporter's value to False.

You can use this block to signify that a new Global/Private variable packet has been handled and that the code should wait for a new packet.

Send command (cmd) (id) (val)

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

This block is a custom command block, which allows you to interact with CloudLink to a greater degree than before. You can write your own commands for CloudLink Server and use this block to interface with those commands. See more information on how to use this block.

Reporters index

Stability: 3 (Stable)

Global data

gdatavar
This reporter returns the output of the global data stream. It is automatically updated whenever someone on the link uses the "Send (Apple)" block.

Private data

pdatavar
This reporter returns the output of your private data stream. It is automatically updated whenever someone on the link uses the "Send (Apple) to (A name)" block, and that the username has been set to yours.

Direct data

ddatavar
This reporter returns the output of the direct data stream between the client and CloudLink server. It is automatically updated whenever the server sends information directly to the client.

linkstate
This reporter returns the state of the extension as well as the state of the connection. It returns a int. value in this list:

Value Description
0 Extension started
1 Connecting to server
2 Connected
3 Disconnected

Status Code

statuscodevar
This reporter returns the output of the current status code of the server. The output is updated when CloudLink server handles a request. You can view an entire list of possible codes here.

Usernames

usernames
This reporter returns the current list of all connected users (Any username that has % at the beginning/end will be filtered out). The output is a string array, separated by a semicolon (;).

Example:
A name; Another name; apple; banana; MikeDEV; TheLongestUsername;

My username

myusername
This reporter returns the currently set username for your client. It's value is set when the "Set (A name) as username" is used.

Extension version

extvers
This reporter returns the current version number of the extension.

Server version

servers
This reporter returns the current version number of the server.

Server List

srvrlist
This block returns a string of JSON containing the available public servers to use. This block is recommended for implementing a server selector. Block will be set immediately when the extension is loaded and the latest server list data has been fetched.

[Global/Private] var (Apple) data

g/pvardata
This block returns the output of the variable within the specified data stream. It is automatically updated whenever someone on the link uses the "Send Var (Apple) with Data (Banana)" (Global) or the "Send Var (Apple) to (A name) with Data (Banana)" (Private) block.

JSON Parser

jsonparser
This block returns the output of parsed JSON.

Boolean index

Stability: 3 (Stable)

Connected?

connected
This boolean returns true if the link state is connected (2), and returns false otherwise.

You can use this block to syncronize connections.

Username synced?

usernamesynced
This boolean returns true if the username has been set on the server and has been relayed to all clients.

You can use this block to syncronize connections.

Got new [Global/Private/Direct/Status Code] Data?

gotnewg/pdata
This boolean returns true if there is new data present on the Global/Private/Direct/Status Code data streams. It's value(s) are reset when the "Reset Got New [Global/Private/Direct/Status Code] data" block is used.

You can use this block to wait for new packets and perform functions when a new Global/Private stream packet is received.

Got new [Global/Private] Var (Apple) Data?

gotnewg/pvardata
This boolean returns true if there is new data present on the global/private variables. It's value(s) are reset when the "Reset Got New [Global/Private] var (Apple) data" block is used.

You can use this block to wait for new packets and perform functions when a new Global/Private variable packet is received.

ID (Another name) Connected?

idconnected
This boolean returns true if the specified username exists on the link.

You can use this block to check if a server is online or that a certain user is connected.

Python Server/Client Quickstart Guide

Stability: 2.5 (Stable/Subject to change)

CloudLink can be downloaded and imported as a python module. To install CloudLink, you can:

  • ​​​​​​py -m pip install cloudlink (on Windows)
    
  • ​​​​​​python3.9 -m pip install cloudlink (on Linux/Unix)
    

2. Directly downloading the latest build from GitHub

Simply download cloudlink.py and place it into your development environment's directory or into the directory where you'll be using it.

Dependencies

CloudLink has 2 dependencies, which are websocket-server and websocket-client. Install these libraries to get CloudLink to work.

To instanciate CloudLink in your project, simply add the following lines of code:

from cloudlink import CloudLink
cl = CloudLink()

From here, CloudLink will be accessable as part of the "cl" object. From there, you can do whatever you need CloudLink to do.

Basic usage

Protect yourself from security exploits!

If you are exposing CloudLink to the internet, a good suggestion is to use a reputable tunneling or reverse proxy service. Also be sure to install CloudLink into a virtual environment or on a up-to-date machine!

For details on supported services, please see this GitHub Issue.

Starting a server

At the very end of your code, add cl.server(). This will start running CloudLink in server mode, which creates a new websocket server on ws://127.0.0.1:3000/.

from cloudlink import CloudLink
cl = CloudLink()
cl.server()

DO NOT INCLUDE ANY CODE AFTER STARTING THE CLOUDLINK SERVER, AS IT WILL NOT RUN. CLOUDLINK SERVER WILL BLOCK ANY OTHER CODE FROM RUNNING.

or, you can just run CloudLink in another thread. But that's some otherworldly stuff there.

Custom Ports

You can specify the port number CloudLink will host on by specifying the optional "port" parameter.

cl.server(port = 42069)

  • In this example, we are specifying CloudLink to run on port 42069.

Custom IPs

Like the "port" parameter, you can also specify the IP address CloudLink will run on using the optional "ip" parameter.

cl.server(ip = "0.0.0.0")

  • In this example, we are specifying CloudLink to run on the local machine on IP 0.0.0.0, which will allow CloudLink to be accessable over the local network.
  • This is required if you want to run CloudLink on Repl.

Running as a Client

Like with CloudLink server, you can run the module as a client, which will emulate the likes of the Scratch extension. As you can probably tell, simply add cl.client() to run as a client.

from cloudlink import CloudLink
cl = CloudLink()
cl.client()

By default, leaving this function with no extra parameters will connect to CloudLink on the Localhost on port 3000, or ws://127.0.0.1:3000/.

Connecting to an external server or custom IP

You can specify the server IP to connect to by adding the "ip" parameter.

cl.client(wss://cloudlink-sample-server.mikedev101.repl.co/)

  • This example will tell CloudLink to connect to the CloudLink sample server, hosted on Repl.

URL formatting

The server IP must be formatted using the following:

(ws or wss)://(subdomain).(hostname).(top level domain):(port number (if needed))/

It is not recommended to connect to an insecure websocket server (ws://). Ideally, you should connect to a secure websocket server (wss://).

Callbacks

Both CloudLink Client and CloudLink server can have callback bindings.

The on_packet binding will function differently in CloudLink Server than CloudLink Client.

If running as a server, CloudLink will only run your function if the server gets a direct command.

See CloudLink Protocol Reference for more details about commands.

Notice that while running the above scripts, nothing really happens in the console. That's because nothing else is happening! If you want to get CloudLink to do things, you'll need to bind some callbacks.

Binding callbacks is simple, as all you need to do is run:

cl.callback("(CALLBACK ID)", (A FUNCTION IN YOUR CODE))

from cloudlink import CloudLink
cl = CloudLink()
def got_a_message_for_you(message):
print(message)
cl.callback("on_packet", got_a_message_for_you)
cl.client()

  • In this example, we are telling CloudLink to bind the function "got_a_message_for_you" to CloudLink's built-in callback function "on_packet." Every time CloudLink gets a new message, it will run the function "got_a_message_for_you", with a "message".

As mentioned above, do NOT run any other code after starting the server or client, as it will not run.

Add your cl.callback() function(s) BEFORE calling cl.server() or cl.client().

Debugging mode

CloudLink is designed to be as resilient and stable as possible, so even tiny exceptions will get caught, which might be problematic when you are debugging your code.

If you are running into code troubles and can't figure out why, you can pass along the "debug" parameter while instanciating CloudLink.

from cloudlink import CloudLink
cl = CloudLink(debug = true)

From here, CloudLink will start spitting out everything that occurs when you run a server or start a client.

It is recommended to enable the debug parameter in a production server environment for info if you encounter server problems.

Python Client/Server API Reference

Stability: 2.5 (Stable/Subject to change)

API Methods

Method Description Takes Returns Supported modes
server() Runs CloudLink in server mode. (Optional) ip: Str. Type, Specifies the IP to bind to run CloudLink server on. (Optional) port: Int. Type, Specifies the port # to listen to. None None
client() Runs CloudLink in client mode. (Optional) ip: Str. Type, specifies the Server IP to connect to, not specifying this parameter will default to ws://127.0.0.1:3000/ None None
stop() Shuts down the server or disconnects the client. (Optional) abrupt: Bool. Type, if true the server will forcefully terminate, leaving false or not specifying this parameter will default to graceful shutdown, this parameter only works if running in Server mode. None Client and Server
callback() Binds a function for callbacks. callback_id: Str. Type, the ID of the callback to bind to. function: Function Type, the function to run code when this callback is used Depends on function. See Callback IDs for more info. Client and Server
sendPacket() Sends JSON packets. msg: Dict type, see CLPv3 table for more info. None Client and Server
setMOTD() Sends JSON packets. enable: Bool type, can be set to true to enable Message-Of-The-Day, false to disable. motd: Str. type, the message to broadcast as the Message-Of-The-Day None Server only
getUsernames() Returns the current username list. None List Client and Server
getIPofUsername() Returns the IP address of a username. user: Str. Type, the username of the client to get the IP address from. Str Server only
getIPofObject() Returns the IP address of a client using it's memory object instead of a username. obj: Dict. Type, the memory address reference to a websocket client. Str Server only
trustedAccess() Enables or disables Trusted Access on the server. enable: Bool. Type, turns on/off the feature. keys: List Type, the list of valid keys, only supports strings. None Server only
untrust() Manually untrusts a client. obj: Dict. Type, the memory address reference to a websocket client. None Server only
loadIPBlocklist() Loads a list of blocked IPs. blist: List Type, a list containing strings of IP addresses to block. None Server only
blockIP() Blocks an IP address. ip: Str. Type, the IP address to block. None Server only
unblockIP() Unblocks an IP address. ip: Str. Type, the IP address to unblock. None Server only
getIPBlocklist() Gets the current IP blocklist. None List Server only

Callback IDs

Callback ID Returns Description
on_packet Message (JSON, String, Number) Returns data when a new message is received. If the packet is JSON, thecmd parameter is the direct command, and the client does not have a username set up, it will return with the client's dict. memory object instead for the origin.
on_error Error (String, Client Only), None (Server) Returns error info if an error occurs.
on_connect Client (Object, Server only), None (Client) Runs code when the server gets a new user connected, or the client has connected to the server.
on_close Client (Dict, Server only), None (Client) Runs code when the server detects a disconnect or when the client closes the connection.

CloudLink Protocol Reference

Stability: 2.5 (Stable/Subject to change)

Example Connection Setup

This is an example of a proper CloudLink connection setup.

For servers WITHOUT Trusted Access enabled

  1. A client connects to a server.
  2. The server sends the client the MOTD (if enabled), and it's CloudLink version number.
  3. The server sends over the username list.

{
"cmd": "ulist",
"val": "something; another boring name; foobar;"
}

  1. The server sends over the current "Global Data" value.

{
"cmd": "gmsg",
"val": "Hello, world!"
}

  1. The client reports it's client type.

{
"cmd": "direct",
"val": {"cmd": "type", "val": "(scratch/py/js)"}
}

  1. The client specifies a username using the "setid" command.

{
"cmd": "setid",
"val": "(Username)"
}

  1. The server and client, as well as all the other clients, can now begin communication.
  2. The client can close it's websocket connection to disconnect.

For servers WITH Trusted Access enabled

  1. A client connects to a server and sends over it's IP address and client type.

{
"cmd": "direct",
"val": {"cmd": "ip", "val": "(IP ADDRESS)"}
}

{
"cmd": "direct",
"val": {"cmd": "type", "val": "(scratch/py/js)"}
}

  1. The server will send over the MOTD (if enabled), CloudLink version number, and status code I:112 | Trusted Access enabled. The server will be listening for only direct packets or gmsg packets. Any other packet will return with E:115 | Refused.

{
"cmd": "statuscode",
"val": "I:112 | Trusted Access enabled"
}

  1. The client can either:
    A. Send a TA Key over the Direct link:
    {
    "cmd": "direct",
    "val": "(KEY)"
    }
    B. Send a TA Key over the Global data stream link (The "Send (Apple)" block):
    {
    "cmd": "gmsg",
    "val": "(KEY)"
    }
  2. If the key is valid, the server will return with status code I:100 | OK and send over the username list and current "Global Data" value.

{
"cmd": "ulist",
"val": "something; another boring name; foobar;"
}

{
"cmd": "gmsg",
"val": "Hello, world!"
}

  1. The client specifies a username using the "setid" command.

{
"cmd": "setid",
"val": "(Username)"
}

  1. The server and client, as well as all the other clients, can now begin communication.
  2. The client can close it's websocket connection to disconnect.

Uniform Packet Layout (UPL)

Ever since CloudLink 0.1.6, a feature called UPL (Uniform Packet Layout) was introduced to make life easier for developers.

Before UPL, you had to stringify JSON if you had nested JSON because of the limitations of Scratch. However, starting with 0.1.7, UPL has been improved so that anyone with basic knowledge of JSON and websockets can interface with a CloudLink server.

The basic specifications of CloudLink UPL are as follows:

  1. There must be a command parameter.
  2. There must be a value input/output parameter.
  3. If needed, there must be an ID to get an Origin from.
  4. If other parameters are specified, they must be compatible with it's respective command.
  5. Other parameters that are not needed will be ignored.

Packet limitations and restrictions

Some things to note:

  1. val cannot be larger than 1000 Characters (1KB) in size. Packets with val larger than 1KB will be rejected by the server. If a packet specifies name, it must not be larger than 100 characters.
  2. Attempting to spoof the packet id or origin will likely end in being overridden by the server.
  3. The server has been designed to catch all possible errors/exceptions and will return a code under typical networking conditions.

Sending and Getting packets

As part of CloudLink's UPL (Uniform Packet Layout), sending packets is as simple as formatting some JSON to the following:

{
"cmd": "(Command)",
"val": (Payload),
"id": "(Username)"
}

This command will return as the following on the other end (if it's a private data command):

{
"cmd": "(Command)",
"val": (Payload),
"origin": "(Packet origin, username)"
}

If the packet is not a private data command, it will not include the "origin" parameter.

{
"cmd": "(Command)",
"val": (Payload),
}

Global stream variable packets can be sent/will return with the following:
{
"cmd": "gvar",
"val": (Payload),
"name": "(Variable name)"
}

Private stream variable packets can be sent with the following:
{
"cmd": "pvar",
"val": (Payload),
"name": "(Variable name)"
}

and will return with:
{
"cmd": "pvar",
"val": (Payload),
"name": "(Variable name)",
"origin": "(Packet origin, username)"
}

Because of a security explot found in past versions of CloudLink, specifying the origin parameter manually will be overriden by the server.

Packet Parameters

Parameter Description Datatypes
cmd Packet's command/function. See Commands Reference (CloudLink Only) for more info. String
val Packet/variable data. String, Int, Float, Dict/JSON
id Packet recipient's username, dependent on Packet command, see Commands Reference (CloudLink Only) for more info. String
origin Packet origin's username, automatically added by server and cannot be specified manually, depends upon the existence/requirement of the "id" parameter. String
name Variable name (Only used for gvar and pvar) String
Command (cmd) Description Takes (sending val) Gives (receiving val) Requires id parameter? (Yes -> Returns with origin parameter) Sends from
gmsg Global data stream Dict/JSON, String, Float, Int. Dict/JSON, String, Float, Int. No Client or Server
pmsg Private data stream Dict/JSON, String, Float, Int. Dict/JSON, String, Float, Int. Yes Client or Server
gvar Global data stream variable Dict/JSON, String, Float, Int. Dict/JSON, String, Float, Int. No Client or Server
pvar Private data stream variable Dict/JSON, String, Float, Int. Dict/JSON, String, Float, Int. Yes Client or Server
ulist Username list Not applicable String (Turbowarp, split with semicolons (;) to convert to list) or List (Python) No Server only
direct Direct server-to-client and client-to-server communications, see Direct COMMs Reference Dict/JSON, String, Float, Int. Dict/JSON, String, Float, Int. Yes Client or Server
setid Sets username for client and enables private/direct COMMs String Not Applicable Not Applicable Client only
statuscode Returns server state info when any packet is handled (Kinda like HTTP status codes). See Status Codes for more info. Not Applicable String Not Applicable Server only

Direct COMMs Reference

If you have set a callback for on_packet in CloudLink Server, it will only listen for packets that uses the direct command. This reference below will provide more details on how to use this feature.

Client-side

On connection

When the client connects to the server, it will send (at most 2) packets with the direct command. Both will look something like this:

{
"cmd": "direct",
"val": {"cmd": "vers", "val": "(Version string, ex. '0.1.7')"}
}

The first packet is the version number reporter. This tells the client what version of CloudLink Server it has. This can be used to check if a client or server is out of date.

{
"cmd": "direct",
"val": {"cmd": "motd", "val": "(Message-Of-The-Day, ex. 'Hello, world!')"}
}

The second packet will return the Message-Of-The-Day (if the server admin chooses to enable it). This is just for fun, and does nothing important.

Custom commands

This feature allows you to use custom command handlers in CloudLink server. This assumes you know what you're doing.

{
"cmd": "direct",
"val": {"cmd": "(CUSTOM COMMAND)", "val": (PAYLOAD)}
}

The second packet will return the Message-Of-The-Day (if the server admin chooses to enable it). This is just for fun, and does nothing important.

Specifying Client Type

Clients need to specify it's type. This helps with managing packets to help prevent hiccups. When the CloudLink Scratch Client connects, it will send over this JSON to the server:

{
"cmd": "direct",
"val": {"cmd": "type", "val": "scratch"}
}

which tells the server that it will need to stringfify any nested JSON it finds. As for the Python client, it will send over:

{
"cmd": "direct",
"val": {"cmd": "type", "val": "py"}
}

which tells the server that it doesn't need to stringfify any nested JSON it finds.

If you use CloudLink In a Browser, it must send over the following:

{
"cmd": "direct",
"val": {"cmd": "type", "val": "js"}
}

which also tells the server that it doesn't need to stringfify any nested JSON it finds.

You can specify a custom client type by simply changing the nested val's value. But if you use a custom client type, be warned that it will assume that your client can interpret nested JSON without stringification. Scratch cannot process nested JSON well, so this feature is to prevent hiccupps.

You can send custom data directly to the server using the following JSON:

{
"cmd": "direct",
"val": (Payload)
}

and you can write custom commands with this feature.

Server-side

When a client sends a packet with the direct command, it will return the following output to the on_packet callback function:

{
"val": (Payload),
"origin": (Packet origin's username or dict. memory object)
}

You can use this feature to write custom command handlers to further expand CloudLink's functionality.

For example, you can write a custom command for ducks.
{
"val": {"cmd": "ducks", "val": "quack"},
"origin": (Packet origin's username or dict. memory object)
}

from there, you can simply read back the values of on_packet and it will return with:

{
"cmd": "ducks",
"val": "quack",
"origin": (Packet origin's username or dict. memory object)
}

Status Codes

This reference will only be for the statuscode command. This table will provide more details on the state of the CloudLink Server.

Status Code Formatting

(Type):(Code) | (Description)

Formatting info

Type Code Description
Letter (E for Error, I for Info) 3-Digit Int. (ex. 123), describes the info/error in machine-readable format String, describes the info/error in a human-readable format

Codes

Code Type Description
I:000 Test A test info code for debugging functions.
I:100 OK The server handed the request correctly.
E:101 Syntax The packet was not formatted correctly (Bad JSON?) or has missing parameters.
E:102 Datatype The packet contained a parameter that was not the correct datatype.
E:103 IDNotFound The client attempted to send/route a packet to an ID that currently doesn't exist.
E:104 InternalServerError The server suffered an internal error.
E:105 Loop While handing the request, the server predicted a loop would occur and has stopped the request.
E:106 RateLimit The server is ratelimiting the request because the request has been used too many times too quicky.
E:107 TooLarge The packet val or name is too large to safely use.
E:108 BrokenPipe The server suffered a broken pipe error internally.
E:109 EmptyPacket The server got an empty packet, which is basically useless.
E:110 IDConflict The server refused to set the client's ID as it would conflict with an existing ID.
E:111 IDSet The server refused to set the client's ID as it has already been set.
I:112 TAEnabled The server has TA enabled, and is requesting the client to send a key.
E:113 TAInvalid The server refused the key as it was invalid.
E:114 TAExpired The server refused the key as it has expired.
E:115 Refused The server refused to handle the packet. This can happen if the server has blocked your IP address or you attempted to send a packet while not authorized on a Trusted Access server.
E:116 IDRequired The server cannot process the command without a username set for the client.
E:117 TATrustLost The server has lost trust in the user.
E:118 Invalid The command was invalid for the custom commands feature.
E:119 Blocked The server has blocked the user's IP address and will refuse any packets it receives.
E:120 IPRequired The server requires the client's IP address to gain trust.