CollabVM 1.2 Protocol Reference: Difference between revisions

From Computernewb Wiki
Jump to navigation Jump to search
(Created page with "This is the protocol reference for CollabVM 1.2, detailing how the protocol works and how to do different things. The CollabVM protocol is derived from Guacamole 0.9.5, however it now differs greatly and it is '''not''' backwards-compatible with standard guacamole = Connection = The connection starts with the client making a WebSocket connection to the CollabVM endpoint. This can be anything, for example <code>wss://computernewb.com/collab-vm/vm0</code> for VM0b0t. T...")
 
(add flag opcode)
 
(25 intermediate revisions by the same user not shown)
Line 1: Line 1:
This is the protocol reference for CollabVM 1.2, detailing how the protocol works and how to do different things.
This is the protocol reference for CollabVM 1.2, detailing how the protocol works and how to do different things.


The CollabVM protocol is derived from Guacamole 0.9.5, however it now differs greatly and it is '''not''' backwards-compatible with standard guacamole
The CollabVM protocol is the mutilated corpse of what used to be Guacamole 0.9.5. It maintains the same instruction format and opcodes for getting the VM display and controlling it, but that's about it.


= Connection =
= Wire Protocol =


The connection starts with the client making a WebSocket connection to the CollabVM endpoint. This can be anything, for example <code>wss://computernewb.com/collab-vm/vm0</code> for VM0b0t.
The connection starts with the client making a WebSocket connection to the CollabVM endpoint. This can be anything, for example <code>wss://computernewb.com/collab-vm/vm0</code> for VM0b0t.
Line 17: Line 17:
Assigned usernames are, by convention, <code>guest</code> followed by five random digits. However, the server may use whatever format it pleases.
Assigned usernames are, by convention, <code>guest</code> followed by five random digits. However, the server may use whatever format it pleases.


== Messages ==
== Message Format ==


All messages on the CollabVM protocol are UTF-8 string arrays encoded in Guacamole Format, detailed in the Design section of the [https://guacamole.apache.org/doc/0.9.5/gug/guacamole-protocol.html Guacamole 0.9.5 Manual, Chapter 9]. Servers '''SHOULD''' drop the connection if the client sends a message not conforming to this.
All messages on the CollabVM protocol are UTF-8 string arrays encoded in Guacamole Format, detailed in the Design section of the [https://guacamole.apache.org/doc/0.9.5/gug/guacamole-protocol.html Guacamole 0.9.5 Manual, Chapter 9]. Servers '''SHOULD''' drop the connection if the client sends a message not conforming to this.


Every message consists of an "opcode" at position zero, followed by zero to unlimited parameters.
All messages with a return value will be replied to with a message with a matching opcode, and additional arguments specified in this reference.


== Connection Opcodes ==
== nop ==

These are the opcodes used throughout the entire connection.

=== nop ===


This is a keepalive signal sent through the duration of the session used to verify that the client is still connected.
This is a keepalive signal sent through the duration of the session used to verify that the client is still connected.
Line 41: Line 37:
Clients '''MAY''' drop the connection if the server does not send '''any''' messages over a period of time. However this should not be limited strictly to NOPs as these may not be consistently sent if there is other activity on the connection.
Clients '''MAY''' drop the connection if the server does not send '''any''' messages over a period of time. However this should not be limited strictly to NOPs as these may not be consistently sent if there is other activity on the connection.


== Initial connection ==
== Handshake ==


Upon making a WebSocket connection, the server will immediately begin sending NOPs, which will continue for the duration of the connection.
Upon making a WebSocket connection, the server will immediately begin sending NOPs, which will continue for the duration of the connection. The client is immediately in the handshaking phase of the connection.


The handshake is as follows:
The client must first acquire a username, through the use of the <code>rename</code> opcode specified below.


=== Authentication announcement ===
The client may now get a list of all VMs on the server using the <code>list</code> opcode, or if it already knows the VM ID, it may immediately connect with the <code>connect</code> opcode.


A server that uses CollabVM Account Authentication will send a message with the <code>auth</code> opcode to announce this. This indicates a few changes in behavior:
=== Opcodes ===


* Clients may login using the <code>login</code> opcode.
==== list ====
* Clients may not change username except by logging in or having a guest username assigned.
* Depending on server configuration, clients may not be able to chat, take turns, or vote without logging in
* Staff-password authentication is disabled


==== Parameters ====
Get a list of all VMs running on the server. No parameters.


<table class="wikitable">
===== Response =====
<tr><td>Opcode</td><td><code>auth</code></td></tr>
<tr><td>Parameter 1</td><td>The base URL of the authentication server used by this instance. Ex: <code>https://auth.collabvm.org</code></td></tr>
</table>


=== Obtain a list of VMs ===
The server will respond with three arguments for each VM:


The first thing the client may want to do is obtain a list of VMs available on this server. If the client already knows exactly what node ID it wants to connect to (common for bots) this may be skipped.
'''ID''': The ID of the VM


==== Request ====
'''Name''': A display name for the VM. May contain HTML.


<table class="wikitable">
'''Thumbnail''': A Base64-encoded thumbnail for the VM. Will be either PNG or JPEG depending on the server implementation. This can be determined through magic numbers.
<tr><td>Opcode</td><td><code>list</code></td></tr>
</table>


==== connect ====
==== Response ====


Parameters 1 through 3 are repeated for every available VM.
Connect to a VM


<table class="wikitable">
===== Parameters =====
<tr><td>Opcode</td><td><code>list</code></td></tr>
<tr><td>Parameter 1</td><td>The ID of the node, that should be passed to the <code>connect</code> opcode.</td></tr>
<tr><td>Parameter 2</td><td>A display name for the VM. May contain HTML.</td></tr>
<tr><td>Parameter 3</td><td>A Base64-encoded thumbnail for the VM. Will be either PNG or JPEG depending on the server implementation. This can be determined through magic numbers.</td></tr>
</table>


=== Request a username ===
'''ID''': The ID of the VM to connect to. Can be retrieved with the list opcode.


Before connecting, the client must now obtain a username.
===== Response =====


==== Request ====
The server will respond with either 1 or 0


<table class="wikitable">
'''1''': The connection was successful and the client is now connected to the VM.
<tr><td>Opcode</td><td><code>rename</code></td></tr>
<tr><td>Parameter 1</td><td><b>(OPTIONAL)</b> The username requested by the client. May be omitted if the client has no preference. The server is under no obligation to respect this and may provide a guest username for a multitude of reasons</td></tr>
</table>


==== Response ====
'''0''': The connection failed. This is usually due to an invalid VM ID but depending on the server implementation and protocol extensions could mean something else.

The server will respond with a [[#Client Renamed|Client Renamed]] event, however with one key difference: The status will always be <code>0</code> (success), even if the requested username was not available for whatever reason. In this case, a guest username is assigned.

=== Client Capabilities ===

The client may at this point negociate capabilities with the server. This is a recent addition and so far only one exists, <code>bin</code>, enabling the [[#Binary Protocol|Binary Protocol]].

==== Request ====

<table class="wikitable">
<tr><td>Opcode</td><td><code>cap</code></td></tr>
<tr><td>Parameters</td><td>Each parameter is a client capability the client supports and wants the server to use.</td></tr>
</table>

==== Response ====

<table class="wikitable">
<tr><td>Opcode</td><td><code>cap</code></td></tr>
<tr><td>Parameters</td><td>The server lists each opcode it supports, out of the list the client sent, that will be used for this connection.</td></tr>
</table>

=== Connect to a VM ===

The client may now connect to a VM as follows:

==== Request ====

<table class="wikitable">
<tr><td>Opcode</td><td><code>connect</code></td></tr>
<tr><td>Parameter 1</td><td>The ID of the VM to connect to. Can be retrieved with the list opcode.</td></tr>
</table>

==== Response ====

<table class="wikitable">
<tr><td>Opcode</td><td><code>connect</code></td></tr>
<tr><td>Parameter 1</td><td>The status of the connection. See below</td></tr>
</table>

Possible statuses:

<table class="wikitable">
<tr><th>Value</th><th>Status</th></tr>
<tr><td>0</td><td>The connection failed. This is usually due to an invalid VM ID but depending on the server implementation and protocol extensions could mean something else.
</td></tr>
<tr><td>1</td><td>The connection was successful and the client is now connected to the VM.</td></tr>
</table>


= Post-Connection =
After successfully connecting to a VM, the client will begin to recieve messages as normal, and may send messages.
After successfully connecting to a VM, the client will begin to recieve messages as normal, and may send messages.


== Server-to-Client Opcodes ==
== Server-to-Client Opcodes ==


These messages may be sent by the server at any time after completing the handshake and must be handled by the client.
=== adduser ===


=== New User(s) ===
Sent to indicate that one or more users have joined the VM. This will always be sent on connection.


Sent to indicate that one or more users have joined the VM. This may also be sent during the handshake.
==== Parameters ====


This may be resent for an already-joined user to announce that they have changed ranks after logging in. Make sure to check for duplicates.
The server will send two parameters for each user:


Parameters 1 and 2 are repeated for each user added.
'''Username''': The username of the new user


<table class="wikitable">
'''Rank''': The rank of the user as an integer (see the Staff section).
<tr><td>Opcode</td><td><code>adduser</code></td></tr>
<tr><td>Parameter 1</td><td>The username of the added user.</td></tr>
<tr><td>Parameter 2</td><td>The [[#Rank|Rank]] of the added user as an integer.</td></tr>
</table>


=== remuser ===
=== Flag ===


Sent to provide the ISO country code for one or more users, if the server supports geolocation. The intended use is to display a country code beside each name in the list.
Sent when one or more users leaves the VM.


==== Parameters ====


Parameters 1 and 2 are repeated for each user added.
'''Number''': The number of users who have left


<table class="wikitable">
'''Username''': Username of the user who left. Repeated for each user if there are more than one
<tr><td>Opcode</td><td><code>flag</code></td></tr>
<tr><td>Parameter 1</td><td>The username whose country code is being sent</td></tr>
<tr><td>Parameter 2</td><td>The two-character, upper-cased ISO country code of the user in question.</td></tr>
</table>


=== rename ===
=== Removed User(s) ===


Sent when a user changes their username.
Sent when one or more users disconnect from the VM.


Parameter 2 is repeated for each user removed.
==== Parameters ====


<table class="wikitable">
Parameters if the client's username is being changed, either by their use of the <code>rename</code> opcode or by staff:
<tr><td>Opcode</td><td><code>remuser</code></td></tr>
<tr><td>Parameter 1</td><td>The number of users that have left</td></tr>
<tr><td>Parameter 2</td><td>The username that has left the VM.</td></tr>
</table>


=== Client Renamed ===
'''0''': This parameter will always be <code>0</code> and is used to differentiate between the client being renamed and another user

Sent when the current client (you) is renamed, either by you or the server.

<table class="wikitable">
<tr><td>Opcode</td><td><code>rename</code></td></tr>
<tr><td>Parameter 1</td><td><code>0</code></td></tr>
<tr><td>Parameter 2</td><td>The status of the rename. See below for available values.</td></tr>
<tr><td>Parameter 3</td><td>The client's new username. This may not necessarily be the username requested by the client, as the server can refuse this request for a variety of reasons and may instead assign a guest name.</td></tr>
</table>


Possible rename statuses:
'''Status''': This parameter is used for the status of the rename. It can have one of the below values:


<table class="wikitable">
<table class="wikitable">
Line 128: Line 206:
</table>
</table>


=== User Renamed ===
'''Username''': The client's new username. This will either be the requested username, or one generated by the server if a new username was not specified or was rejected for one of the reasons above.


Parameters if another user is being renamed:
Sent when another user in the list is renamed.


<table class="wikitable">
'''1''': This parameter will always be 1 and is used to differentiate between the client being renamed and another user
<tr><td>Opcode</td><td><code>rename</code></td></tr>
<tr><td>Parameter 1</td><td><code>1</code></td></tr>
<tr><td>Parameter 2</td><td>The user's old username</td></tr>
<tr><td>Parameter 3</td><td>The user's new username</td></tr>
</table>


=== Chat message ===
'''Old Name''': The user's old username


Sent when one or more chat messages are received.
'''New Name''': The user's new username


Parameters 1 and 2 may be repeated for multiple chat messages, and this should be checked for. In current server implementations, this will only happen immediately after connection to send the chat history.
=== chat ===


<table class="wikitable">
Sent when another user sends a chat message.
<tr><td>Opcode</td><td><code>chat</code></td></tr>
<tr><td>Parameter 1</td><td>The user who sent the chat message. This may be an empty string to indicate a system message sent by the server, such as the Message of the Day, or a vote notification.</td></tr>
<tr><td>Parameter 2</td><td>The chat message</td></tr>
</table>


==== Parameters ====
=== Screen Size ===


Sent to announce the screen size of the VM. This will be sent after connecting and after any resolution change on the VM.
This opcode will mostly have two parameters. However at the beginning of the connection, the server will send a chat history, containing the below parameters for each message.


<table class="wikitable">
'''Username''': The user who sent the chat message.
<tr><td>Opcode</td><td><code>size</code></td></tr>
<tr><td>Parameter 1</td><td><code>0</code></td></tr>
<tr><td>Parameter 2</td><td>Screen width</td></tr>
<tr><td>Parameter 3</td><td>Screen height</td></tr>
</table>


=== Framebuffer Update ===
'''Message''': The chat message. The server '''MUST''' HTML-sanitize the message, otherwise this poses a severe vulnerability to users.


Sent to update the VM screen. The server will send one initial message containing the entire screen on connection, and after that will send a dirty rect for each update.
=== size ===
Used to indicate the screen size of the VM. This will be sent after connecting and after any resolution change on the VM.


If the binary protocol is enabled, you will instead receive [[#Framebuffer Update (Binary)|Framebuffer Update (Binary)]] messages.
==== Parameters ====


<table class="wikitable">
'''Layer''': This will always be zero (for the screen) on current server implementations. Some servers may implement other layers such as virtual mouse. Clients are not obligated to support these.
<tr><td>Opcode</td><td><code>png</code></td></tr>
<tr><td>Parameter 1</td><td><code>0</code></td></tr>
<tr><td>Parameter 2</td><td><code>0</code></td></tr>
<tr><td>Parameter 3</td><td>X-axis position of the rectangle</td></tr>
<tr><td>Parameter 4</td><td>Y-axis position of the rectangle</td></tr>
<tr><td>Parameter 5</td><td>The base64-encoded rectangle. Despite the name of the opcode, this may be either PNG or JPEG and can be determined through magic numbers or headers.</td></tr>
</table>


=== Vote-for-reset notification ===
'''Width''': The new width


Sent when a Vote-for-reset on the VM updates
'''Height''': The new height


<table class="wikitable">
=== png ===
<tr><td>Opcode</td><td><code>vote</code></td></tr>
Used to update the VM screen. The server will send one initial PNG message containing the entire screen on connection, and after that will send a dirty rect for each update
<tr><td>Parameter 1</td><td>The status of the vote. See below for values</td></tr>
<tr><td>Parameter 2</td><td>Amount of time left on the vote in milliseconds. If the above status was 3 (cooldown), this is the amount of time before the client can start a vote.</td></tr>
<tr><td>Parameter 3</td><td>The number of users who have voted in favor of resetting the VM</td></tr>
<tr><td>Parameter 4</td><td>The number of users who have voted against resetting the VM</td></tr>
</table>


Possible vote statuses:
==== Parameters ====


<table class="wikitable">
'''mask''': This will always be zero on current server implementations.
<tr><th>Value</th><th>Status</th></tr>
<tr><td>0</td><td>The vote has started. The yes and no parameters may not be specified, and in such case should be assumed to be zero.</td></tr>
<tr><td>1</td><td>The vote count has updated.</td></tr>
<tr><td>2</td><td>The vote has ended. No other parameters will be given.</td></tr>
<tr><td>3</td><td>Sent if the client tried to start a vote, however there is an active cooldown. Only the time parameter is given.</td></tr>
</table>
=== Turn queue update ===


Indicates an update of the VM's turn queue
'''layer''': This will always be zero (for the screen) on current server implementations. Some servers may implement other layers such as virtual mouse. Clients are not obligated to support these.


<table class="wikitable">
'''x''': X-axis position of the rect
<tr><td>Opcode</td><td><code>turn</code></td></tr>
<tr><td>Parameter 1</td><td>How much time is left on the current user's turn in milliseconds.</td></tr>
<tr><td>Parameter 2</td><td>The amount of users in the queue.</td></tr>
<tr><td>Parameter 3-?</td><td>Each username in the queue given as separate parameters</td></tr>
<tr><td>End parameter</td><td>How much longer until the client will get a turn in milliseconds. Only sent if the client is waiting.</td></tr>
</table>


== Client-to-Server Opcodes ==
'''y''': Y-axis position of the rect


These opcodes may be sent by the client at any time after the handshake to perform various actions
'''data''': The base64-encoded rect. This may be either PNG or JPEG and can be determined through magic numbers or headers.


=== vote ===
=== Account Login ===


Used to log in with a CollabVM account. This should only be sent if the server announced authentication using the <code>auth</code> opcode during the handshake phase. Sending this opcode otherwise is undefined behavior.
Sent when a Vote-to-reset on the VM updates


==== Parameters ====
==== Request ====

<table class="wikitable">
<tr><td>Opcode</td><td><code>login</code></td></tr>
<tr><td>Parameter 1</td><td>A session token OR bot token obtained from the authentication server announced during handshake.</td></tr>
</table>

==== Response ====

<table class="wikitable">
<tr><td>Opcode</td><td><code>login</code></td></tr>
<tr><td>Parameter 1</td><td>Login status. <code>0</code> for error, <code>1</code> for success.</td></tr>
<tr><td>Parameter 2</td><td>Human-readable error. Only sent if status was <code>0</code></td></tr>
</table>

After a successful login, the client should expect to be renamed and have their rank updated by the server.

=== Rename ===

Used to change the client's username. This opcode is not available on servers that use account authentication, and the server will respond with an error.

==== Request ====

<table class="wikitable">
<tr><td>Opcode</td><td><code>rename</code></td></tr>
<tr><td>Parameter 1</td><td>The username requested by the client. If omitted, the server will reassign a guest username.</td></tr>
</table>

==== Response ====

The server will respond with a [[#Client Renamed|Client Renamed]] event.

=== Send Chat ===

Send a public chat message to the server.

<table class="wikitable">
<tr><td>Opcode</td><td><code>chat</code></td></tr>
<tr><td>Parameter 1</td><td>Chat message to send</td></tr>
</table>

=== Take turn ===

Request a turn on the VM.

<table class="wikitable">
<tr><td>Opcode</td><td><code>turn</code></td></tr>
<tr><td>Parameter 1</td><td><code>1</code> to take a turn, <code>0</code> to cancel your turn. If not specified, the server will infer <code>1</code>.</td></tr>
</table>

=== Mouse Instruction ===

Send a mouse update to the VM. Only effective if the client has the turn or is an Admin. This opcode has no response.

<table class="wikitable">
<tr><td>Opcode</td><td><code>mouse</code></td></tr>
<tr><td>Parameter 1</td><td>X position of the mouse pointer on the VM screen</td></tr>
<tr><td>Parameter 2</td><td>Y position of the mouse pointer on the VM screen</td></tr>
<tr><td>Parameter 3</td><td>Bitmask of mouse buttons being held. See [https://github.com/rfbproto/rfbproto/blob/master/rfbproto.rst#pointerevent Remote Framebuffer Protocol§PointerEvent]</td></tr>
</table>

=== Keyboard Instruction ===

Send a keyboard update to the VM. Only effective if the client has the turn or is an Admin. This opcode has no response.

<table class="wikitable">
<tr><td>Opcode</td><td><code>key</code></td></tr>
<tr><td>Parameter 1</td><td>Key symbol for the key being pressed as a base-10 integer. See [https://cgit.freedesktop.org/xorg/proto/x11proto/tree/keysymdef.h keysymdef.h] for a list (values are in hex and must be converted to base 10)</td></tr>
<tr><td>Parameter 2</td><td><code>1</code> to press the key, <code>0</code> to release.</td></tr>
</table>

=== Vote-for-reset ===

Vote for or against resetting the VM to snapshot.

<table class="wikitable">
<tr><td>Opcode</td><td><code>vote</code></td></tr>
<tr><td>Parameter 1</td><td><code>1</code> to vote in favor of a reset, <code>0</code> to vote against a reset. If there is no active vote, <code>1</code> is used to start one, while <code>0</code> has no effect.</td></tr>
</table>

== Admin Opcodes ==

These opcodes may be sent to perform administration actions on the VM.

=== Staff Login ===

Used to log in as an Admin or Moderator on the VM using a staff password. This opcode is disabled if the VM uses Account Authentication, in which case the [[#Account Login|Account Login]] opcode should be used instead.

==== Request ====

<table class="wikitable">
<tr><td>Opcode</td><td><code>admin</code></td></tr>
<tr><td>Parameter 1</td><td><code>2</code></td></tr>
<tr><td>Parameter 2</td><td>The staff password</td></tr>
</table>

==== Response ====

<table class="wikitable">
<tr><td>Opcode</td><td><code>admin</code></td></tr>
<tr><td>Parameter 1</td><td><code>0</code></td></tr>
<tr><td>Parameter 2</td><td>Status of the login. See below for possible values.</td></tr>
<tr><td>Parameter 3</td><td>[[#Permissions|Permissions]] integer defining available moderation actions. Only sent if status is <code>3</code></td></tr>
</table>

Status can be one of the following:


'''Status''': The status of the vote. Values:
<table class="wikitable">
<table class="wikitable">
<tr><th>Value</th><th>Status</th></tr>
<tr><th>Value</th><th>Status</th></tr>
<tr><td>0</td><td>The vote has started. The yes and no parameters may not be specified, and in such case should be assumed to be zero.</td></tr>
<tr><td>0</td><td>Invalid credentials, or access denied for another reason.</td></tr>
<tr><td>1</td><td>The vote count has updated.</td></tr>
<tr><td>1</td><td>Logged in successfully as Admin</td></tr>
<tr><td>2</td><td>The vote has ended. All below parameters will be omitted. The server may send the result in the chat.</td></tr>
<tr><td>3</td><td>Logged in successfully as Moderator</td></tr>
<tr><td>3</td><td>Sent if the client tried to start a vote, however there is an active cooldown. Only the time parameter is given.</td></tr>
</table>
</table>


After successfully logging in, the server will also send a new [[#New User(s)|New User]] event to announce your rank change.
'''Time''': Amount of time left on the vote in milliseconds. If the above status was 3 (cooldown), this is the amount of time before the client can start a vote.


=== QEMU Monitor ===
'''Yes''': The number of users who have voted in favor of resetting the VM


Used to send a [https://qemu-project.gitlab.io/qemu/system/monitor.html QEMU Monitor] command to the VM. Only Admins may use this opcode.
'''No''': The number of users who have voted against resetting the VM


=== turn ===
==== Request ====


<table class="wikitable">
Indicates an update of the VM's turn queue
<tr><td>Opcode</td><td><code>admin</code></td></tr>
<tr><td>Parameter 1</td><td><code>5</code></td></tr>
<tr><td>Parameter 2</td><td>Command to send to QEMU</td></tr>
</table>


==== Parameters ====
==== Response ====


<table class="wikitable">
'''Turn time''': How much time is left on the current user's turn in milliseconds.
<tr><td>Opcode</td><td><code>admin</code></td></tr>
<tr><td>Parameter 1</td><td><code>2</code></td></tr>
<tr><td>Parameter 2</td><td>Response from QEMU</td></tr>
</table>


=== Restore VM ===
'''Queue count''': The amount of users in the queue.


Restore the VM to snapshot without a vote.
'''Queue''': Each user in the queue given as separate parameters


<table class="wikitable">
'''Waiting timer''': How much longer until the client will get a turn in milliseconds. Only sent if the client is waiting.
<tr><td>Opcode</td><td><code>admin</code></td></tr>
<tr><td>Parameter 1</td><td><code>8</code></td></tr>
</table>


== Client-to-Server Opcodes ==
=== Reboot VM ===


Reboot the VM.


<table class="wikitable">
<tr><td>Opcode</td><td><code>admin</code></td></tr>
<tr><td>Parameter 1</td><td><code>10</code></td></tr>
</table>


== Rank ==
=== Ban User ===


Ban a user. The actual backend behavior here is dependent on server implementation. Usually this runs a command set in configuration.
CollabVM has three ranks:


<table class="wikitable">
'''0''': Unregistered. The default rank with no permissions that all users have prior to logging in.
<tr><td>Opcode</td><td><code>admin</code></td></tr>
<tr><td>Parameter 1</td><td><code>12</code></td></tr>
<tr><td>Parameter 2</td><td>Username to ban</td></tr>
</table>


=== Force vote ===
'''2''': Admin. Has all permissions on the VM.


Forcibly end a vote-for-reset with the specified outcome
'''3''': Moderator. Permissions vary depending on server configuration. Even with all permissions granted moderators can still not use the QEMU monitor.

<table class="wikitable">
<tr><td>Opcode</td><td><code>admin</code></td></tr>
<tr><td>Parameter 1</td><td><code>13</code></td></tr>
<tr><td>Parameter 2</td><td><code>1</code> to pass the vote and reset the VM, <code>0</code> to fail the vote</td></tr>
</table>.

=== Mute ===

Mute a user

<table class="wikitable">
<tr><td>Opcode</td><td><code>admin</code></td></tr>
<tr><td>Parameter 1</td><td><code>14</code></td></tr>
<tr><td>Parameter 2</td><td>Username to mute</td></tr>
<tr><td>Parameter 3</td><td><code>0</code> for temporary mute, <code>1</code> for permanent. Temporary mute duration is left up to the server and is usually configurable.</td></tr>
</table>

=== Kick ===

Disconnect a user from the VM.

<table class="wikitable">
<tr><td>Opcode</td><td><code>admin</code></td></tr>
<tr><td>Parameter 1</td><td><code>15</code></td></tr>
<tr><td>Parameter 2</td><td>Username to kick</td></tr>
</table>

=== End turn ===

End a user's turn, or forfeit their spot in the queue.

<table class="wikitable">
<tr><td>Opcode</td><td><code>admin</code></td></tr>
<tr><td>Parameter 1</td><td><code>16</code></td></tr>
<tr><td>Parameter 2</td><td>Username to end turn</td></tr>
</table>

=== Clear turn queue ===

Clear the turn queue

<table class="wikitable">
<tr><td>Opcode</td><td><code>admin</code></td></tr>
<tr><td>Parameter 1</td><td><code>17</code></td></tr>
<tr><td>Parameter 2</td><td>VM Node ID to clear the turn queue of</td></tr>
</table>

=== Rename user ===

Change another user's name.

<table class="wikitable">
<tr><td>Opcode</td><td><code>admin</code></td></tr>
<tr><td>Parameter 1</td><td><code>18</code></td></tr>
<tr><td>Parameter 2</td><td>User to rename</td></tr>
<tr><td>Parameter 3</td><td>New username</td></tr>
</table>

=== Grab IP ===

Grab a user's IP Address

==== Request ====

<table class="wikitable">
<tr><td>Opcode</td><td><code>admin</code></td></tr>
<tr><td>Parameter 1</td><td><code>19</code></td></tr>
<tr><td>Parameter 2</td><td>User to IP grab</td></tr>
</table>

==== Response ====

<table class="wikitable">
<tr><td>Opcode</td><td><code>admin</code></td></tr>
<tr><td>Parameter 1</td><td><code>19</code></td></tr>
<tr><td>Parameter 2</td><td>User whose IP was grabbed</td></tr>
<tr><td>Parameter 3</td><td>The requested IP address</td></tr>
</table>

=== Bypass turn queue ===

Jump directly in front of the queue and take the turn.

<table class="wikitable">
<tr><td>Opcode</td><td><code>admin</code></td></tr>
<tr><td>Parameter 1</td><td><code>20</code></td></tr>
</table>

=== Send raw message ===

Send a raw (XSS) message to the chat, bypassing HTML sanitization and character limits. When a moderator sends a raw message, admins will still receive a sanitized version for security reasons.

<table class="wikitable">
<tr><td>Opcode</td><td><code>admin</code></td></tr>
<tr><td>Parameter 1</td><td><code>21</code></td></tr>
<tr><td>Parameter 2</td><td>Raw message to send</td></tr>
</table>

=== Toggle turns ===

Prevent or allow non-staff to take turns on the VM

<table class="wikitable">
<tr><td>Opcode</td><td><code>admin</code></td></tr>
<tr><td>Parameter 1</td><td><code>22</code></td></tr>
<tr><td>Parameter 2</td><td><code>1</code> to enable turns, <code>0</code> to disable them.</td></tr>
</table>

=== Indefinite turn ===

Jump directly to the front of the turn queue and take a turn that does not end until you disconnect or end it manually.

<table class="wikitable">
<tr><td>Opcode</td><td><code>admin</code></td></tr>
<tr><td>Parameter 1</td><td><code>23</code></td></tr>
</table>

=== Hide screen ===

Hide or show the VM screen from non-staff.

<table class="wikitable">
<tr><td>Opcode</td><td><code>admin</code></td></tr>
<tr><td>Parameter 1</td><td><code>24</code></td></tr>
<tr><td>Parameter 2</td><td><code>1</code> to show the screen, <code>0</code> to hide it.</td></tr>
</table>

=== Send system message ===

Send a raw (XSS) message as a system message from the server.

<table class="wikitable">
<tr><td>Opcode</td><td><code>admin</code></td></tr>
<tr><td>Parameter 1</td><td><code>25</code></td></tr>
<tr><td>Parameter 2</td><td>System message to send</td></tr>
</table>

= Binary Protocol =

The binary protocol is a new addition to the CollabVM protocol, that allows certain messages to be sent as binary instead of a base64 encoded guacamole string. So far, only one such message exists.

The protocol may be enabled by [[#Client_Capabilities|Negotiating]] the <code>bin</code> protocol with the server during the [[#Handshake|Handshake]].

== Message format ==

All binary messages are encoded with [https://msgpack.org/ MsgPack] (subject to change) and follow this basic format:

{{code|lang=ts|<nowiki>
{
type: number;
// Message specific data
}
</nowiki>}}

Where <code>type</code> is one of the following:

{{code|lang=ts|<nowiki>
{
// Framebuffer Update (rectangle)
rect = 0,
}
</nowiki>}}

== Server-to-Client Messages ==

=== Framebuffer Update (Binary) ===

Sent to update the VM screen. The server will send one initial message containing the entire screen on connection, and after that will send a dirty rect for each update.

If the binary protocol is enabled, this will be sent INSTEAD of <code>png</code> opcode messages.

{{code|lang=ts|<nowiki>
{
type: 0,
rect: {
// X-coordinate of the rectangle
x: number;
// Y-coordinate of the rectangle
y: number;
// Buffer containing the JPEG data for the rectangle.
data: Uint8Array;
}
}
</nowiki>}}

= Rank =

CollabVM has four ranks:

<table class="wikitable">
<tr><th>ID</th><th>Name</th><th>Description</th></tr>
<tr><td>0</td><td>Unregistered</td><td>The default rank with no permissions that all users have prior to logging in.</td></tr>
<tr><td>1</td><td>Registered</td><td>A logged in user. This is only used by servers that use CollabVM Account Authentication.</td></tr>
<tr><td>2</td><td>Admin</td><td>Has all permissions on the VM.</td></tr>
<tr><td>3</td><td>Moderator</td><td>Permissions vary depending on server configuration. Even with all permissions granted moderators can still not use the QEMU monitor.</td></tr>
</table>

= Permissions =

When logging in as a Moderator, permissions are defined by a bitmask that can contain the following values:

<table class="wikitable">
<tr><th>Value</th><th>Description</th></tr>
<tr><td>1</td><td>Reset the VM back to it's initial state.</td></tr>
<tr><td>2</td><td>Reboot the VM</td></tr>
<tr><td>4</td><td>Ban a user from your VM</td></tr>
<tr><td>8</td><td>Forcibly pass or cancel a vote to reset</td></tr>
<tr><td>16</td><td>Mute a user, preventing them from chatting or taking turns</td></tr>
<tr><td>32</td><td>Kick a user from the VM</td></tr>
<tr><td>64</td><td>Jump to the front of the turn queue, as well as clear the turn queue and end individual turns</td></tr>
<tr><td>128</td><td>Rename another user</td></tr>
<tr><td>256</td><td>Get the IP address of another user</td></tr>
<tr><td>512</td><td>Send a raw (not HTML-sanitized) chat message, allowing the execution of arbitrary scripts on another user's browser. Admins will not be affected by XSS messages sent by mods.</td></tr>
</table>

Latest revision as of 00:35, 26 June 2024

This is the protocol reference for CollabVM 1.2, detailing how the protocol works and how to do different things.

The CollabVM protocol is the mutilated corpse of what used to be Guacamole 0.9.5. It maintains the same instruction format and opcodes for getting the VM display and controlling it, but that's about it.

Wire Protocol

The connection starts with the client making a WebSocket connection to the CollabVM endpoint. This can be anything, for example wss://computernewb.com/collab-vm/vm0 for VM0b0t.

The client MUST use guacamole as the WebSocket subprotocol and servers MUST reject any connections not using this subprotocol.

The CollabVM protocol supports multiple VMs, however current server implementations only support one per instance. This is not a requirement and new servers are welcome to support multiple VMs.

Each VM has its own ID. This ID is arbitrary however MUST be unique against all other VMs on the server, and all VMs that will be used on the same webapp.

Each client has their own username. The client must set a username or request that the server assign it one before connecting to a VM.

Assigned usernames are, by convention, guest followed by five random digits. However, the server may use whatever format it pleases.

Message Format

All messages on the CollabVM protocol are UTF-8 string arrays encoded in Guacamole Format, detailed in the Design section of the Guacamole 0.9.5 Manual, Chapter 9. Servers SHOULD drop the connection if the client sends a message not conforming to this.

Every message consists of an "opcode" at position zero, followed by zero to unlimited parameters.

nop

This is a keepalive signal sent through the duration of the session used to verify that the client is still connected.

The server MUST send a 3.nop; periodically and the client MUST respond with the same.

The server MAY omit sending NOPs if there is other activity by the client.

Servers MUST drop any client which does not respond to the NOP in a timely manner.

Clients MUST NOT send a NOP until prompted by the server.

Clients MAY drop the connection if the server does not send any messages over a period of time. However this should not be limited strictly to NOPs as these may not be consistently sent if there is other activity on the connection.

Handshake

Upon making a WebSocket connection, the server will immediately begin sending NOPs, which will continue for the duration of the connection. The client is immediately in the handshaking phase of the connection.

The handshake is as follows:

Authentication announcement

A server that uses CollabVM Account Authentication will send a message with the auth opcode to announce this. This indicates a few changes in behavior:

  • Clients may login using the login opcode.
  • Clients may not change username except by logging in or having a guest username assigned.
  • Depending on server configuration, clients may not be able to chat, take turns, or vote without logging in
  • Staff-password authentication is disabled

Parameters

Opcodeauth
Parameter 1The base URL of the authentication server used by this instance. Ex: https://auth.collabvm.org

Obtain a list of VMs

The first thing the client may want to do is obtain a list of VMs available on this server. If the client already knows exactly what node ID it wants to connect to (common for bots) this may be skipped.

Request

Opcodelist

Response

Parameters 1 through 3 are repeated for every available VM.

Opcodelist
Parameter 1The ID of the node, that should be passed to the connect opcode.
Parameter 2A display name for the VM. May contain HTML.
Parameter 3A Base64-encoded thumbnail for the VM. Will be either PNG or JPEG depending on the server implementation. This can be determined through magic numbers.

Request a username

Before connecting, the client must now obtain a username.

Request

Opcoderename
Parameter 1(OPTIONAL) The username requested by the client. May be omitted if the client has no preference. The server is under no obligation to respect this and may provide a guest username for a multitude of reasons

Response

The server will respond with a Client Renamed event, however with one key difference: The status will always be 0 (success), even if the requested username was not available for whatever reason. In this case, a guest username is assigned.

Client Capabilities

The client may at this point negociate capabilities with the server. This is a recent addition and so far only one exists, bin, enabling the Binary Protocol.

Request

Opcodecap
ParametersEach parameter is a client capability the client supports and wants the server to use.

Response

Opcodecap
ParametersThe server lists each opcode it supports, out of the list the client sent, that will be used for this connection.

Connect to a VM

The client may now connect to a VM as follows:

Request

Opcodeconnect
Parameter 1The ID of the VM to connect to. Can be retrieved with the list opcode.

Response

Opcodeconnect
Parameter 1The status of the connection. See below

Possible statuses:

ValueStatus
0The connection failed. This is usually due to an invalid VM ID but depending on the server implementation and protocol extensions could mean something else.
1The connection was successful and the client is now connected to the VM.

After successfully connecting to a VM, the client will begin to recieve messages as normal, and may send messages.

Server-to-Client Opcodes

These messages may be sent by the server at any time after completing the handshake and must be handled by the client.

New User(s)

Sent to indicate that one or more users have joined the VM. This may also be sent during the handshake.

This may be resent for an already-joined user to announce that they have changed ranks after logging in. Make sure to check for duplicates.

Parameters 1 and 2 are repeated for each user added.

Opcodeadduser
Parameter 1The username of the added user.
Parameter 2The Rank of the added user as an integer.

Flag

Sent to provide the ISO country code for one or more users, if the server supports geolocation. The intended use is to display a country code beside each name in the list.


Parameters 1 and 2 are repeated for each user added.

Opcodeflag
Parameter 1The username whose country code is being sent
Parameter 2The two-character, upper-cased ISO country code of the user in question.

Removed User(s)

Sent when one or more users disconnect from the VM.

Parameter 2 is repeated for each user removed.

Opcoderemuser
Parameter 1The number of users that have left
Parameter 2The username that has left the VM.

Client Renamed

Sent when the current client (you) is renamed, either by you or the server.

Opcoderename
Parameter 10
Parameter 2The status of the rename. See below for available values.
Parameter 3The client's new username. This may not necessarily be the username requested by the client, as the server can refuse this request for a variety of reasons and may instead assign a guest name.

Possible rename statuses:

ValueStatus
0The client got their requested username. If the renaming is sent by a staff member this must always be used even if the requested username was not available.
1The username was already taken.
2The username was invalid. See requirements above.
3The username is not allowed by the server.

User Renamed

Sent when another user in the list is renamed.

Opcoderename
Parameter 11
Parameter 2The user's old username
Parameter 3The user's new username

Chat message

Sent when one or more chat messages are received.

Parameters 1 and 2 may be repeated for multiple chat messages, and this should be checked for. In current server implementations, this will only happen immediately after connection to send the chat history.

Opcodechat
Parameter 1The user who sent the chat message. This may be an empty string to indicate a system message sent by the server, such as the Message of the Day, or a vote notification.
Parameter 2The chat message

Screen Size

Sent to announce the screen size of the VM. This will be sent after connecting and after any resolution change on the VM.

Opcodesize
Parameter 10
Parameter 2Screen width
Parameter 3Screen height

Framebuffer Update

Sent to update the VM screen. The server will send one initial message containing the entire screen on connection, and after that will send a dirty rect for each update.

If the binary protocol is enabled, you will instead receive Framebuffer Update (Binary) messages.

Opcodepng
Parameter 10
Parameter 20
Parameter 3X-axis position of the rectangle
Parameter 4Y-axis position of the rectangle
Parameter 5The base64-encoded rectangle. Despite the name of the opcode, this may be either PNG or JPEG and can be determined through magic numbers or headers.

Vote-for-reset notification

Sent when a Vote-for-reset on the VM updates

Opcodevote
Parameter 1The status of the vote. See below for values
Parameter 2Amount of time left on the vote in milliseconds. If the above status was 3 (cooldown), this is the amount of time before the client can start a vote.
Parameter 3The number of users who have voted in favor of resetting the VM
Parameter 4The number of users who have voted against resetting the VM

Possible vote statuses:

ValueStatus
0The vote has started. The yes and no parameters may not be specified, and in such case should be assumed to be zero.
1The vote count has updated.
2The vote has ended. No other parameters will be given.
3Sent if the client tried to start a vote, however there is an active cooldown. Only the time parameter is given.

Turn queue update

Indicates an update of the VM's turn queue

Opcodeturn
Parameter 1How much time is left on the current user's turn in milliseconds.
Parameter 2The amount of users in the queue.
Parameter 3-?Each username in the queue given as separate parameters
End parameterHow much longer until the client will get a turn in milliseconds. Only sent if the client is waiting.

Client-to-Server Opcodes

These opcodes may be sent by the client at any time after the handshake to perform various actions

Account Login

Used to log in with a CollabVM account. This should only be sent if the server announced authentication using the auth opcode during the handshake phase. Sending this opcode otherwise is undefined behavior.

Request

Opcodelogin
Parameter 1A session token OR bot token obtained from the authentication server announced during handshake.

Response

Opcodelogin
Parameter 1Login status. 0 for error, 1 for success.
Parameter 2Human-readable error. Only sent if status was 0

After a successful login, the client should expect to be renamed and have their rank updated by the server.

Rename

Used to change the client's username. This opcode is not available on servers that use account authentication, and the server will respond with an error.

Request

Opcoderename
Parameter 1The username requested by the client. If omitted, the server will reassign a guest username.

Response

The server will respond with a Client Renamed event.

Send Chat

Send a public chat message to the server.

Opcodechat
Parameter 1Chat message to send

Take turn

Request a turn on the VM.

Opcodeturn
Parameter 11 to take a turn, 0 to cancel your turn. If not specified, the server will infer 1.

Mouse Instruction

Send a mouse update to the VM. Only effective if the client has the turn or is an Admin. This opcode has no response.

Opcodemouse
Parameter 1X position of the mouse pointer on the VM screen
Parameter 2Y position of the mouse pointer on the VM screen
Parameter 3Bitmask of mouse buttons being held. See Remote Framebuffer Protocol§PointerEvent

Keyboard Instruction

Send a keyboard update to the VM. Only effective if the client has the turn or is an Admin. This opcode has no response.

Opcodekey
Parameter 1Key symbol for the key being pressed as a base-10 integer. See keysymdef.h for a list (values are in hex and must be converted to base 10)
Parameter 21 to press the key, 0 to release.

Vote-for-reset

Vote for or against resetting the VM to snapshot.

Opcodevote
Parameter 11 to vote in favor of a reset, 0 to vote against a reset. If there is no active vote, 1 is used to start one, while 0 has no effect.

Admin Opcodes

These opcodes may be sent to perform administration actions on the VM.

Staff Login

Used to log in as an Admin or Moderator on the VM using a staff password. This opcode is disabled if the VM uses Account Authentication, in which case the Account Login opcode should be used instead.

Request

Opcodeadmin
Parameter 12
Parameter 2The staff password

Response

Opcodeadmin
Parameter 10
Parameter 2Status of the login. See below for possible values.
Parameter 3Permissions integer defining available moderation actions. Only sent if status is 3

Status can be one of the following:

ValueStatus
0Invalid credentials, or access denied for another reason.
1Logged in successfully as Admin
3Logged in successfully as Moderator

After successfully logging in, the server will also send a new New User event to announce your rank change.

QEMU Monitor

Used to send a QEMU Monitor command to the VM. Only Admins may use this opcode.

Request

Opcodeadmin
Parameter 15
Parameter 2Command to send to QEMU

Response

Opcodeadmin
Parameter 12
Parameter 2Response from QEMU

Restore VM

Restore the VM to snapshot without a vote.

Opcodeadmin
Parameter 18

Reboot VM

Reboot the VM.

Opcodeadmin
Parameter 110

Ban User

Ban a user. The actual backend behavior here is dependent on server implementation. Usually this runs a command set in configuration.

Opcodeadmin
Parameter 112
Parameter 2Username to ban

Force vote

Forcibly end a vote-for-reset with the specified outcome

Opcodeadmin
Parameter 113
Parameter 21 to pass the vote and reset the VM, 0 to fail the vote

.

Mute

Mute a user

Opcodeadmin
Parameter 114
Parameter 2Username to mute
Parameter 30 for temporary mute, 1 for permanent. Temporary mute duration is left up to the server and is usually configurable.

Kick

Disconnect a user from the VM.

Opcodeadmin
Parameter 115
Parameter 2Username to kick

End turn

End a user's turn, or forfeit their spot in the queue.

Opcodeadmin
Parameter 116
Parameter 2Username to end turn

Clear turn queue

Clear the turn queue

Opcodeadmin
Parameter 117
Parameter 2VM Node ID to clear the turn queue of

Rename user

Change another user's name.

Opcodeadmin
Parameter 118
Parameter 2User to rename
Parameter 3New username

Grab IP

Grab a user's IP Address

Request

Opcodeadmin
Parameter 119
Parameter 2User to IP grab

Response

Opcodeadmin
Parameter 119
Parameter 2User whose IP was grabbed
Parameter 3The requested IP address

Bypass turn queue

Jump directly in front of the queue and take the turn.

Opcodeadmin
Parameter 120

Send raw message

Send a raw (XSS) message to the chat, bypassing HTML sanitization and character limits. When a moderator sends a raw message, admins will still receive a sanitized version for security reasons.

Opcodeadmin
Parameter 121
Parameter 2Raw message to send

Toggle turns

Prevent or allow non-staff to take turns on the VM

Opcodeadmin
Parameter 122
Parameter 21 to enable turns, 0 to disable them.

Indefinite turn

Jump directly to the front of the turn queue and take a turn that does not end until you disconnect or end it manually.

Opcodeadmin
Parameter 123

Hide screen

Hide or show the VM screen from non-staff.

Opcodeadmin
Parameter 124
Parameter 21 to show the screen, 0 to hide it.

Send system message

Send a raw (XSS) message as a system message from the server.

Opcodeadmin
Parameter 125
Parameter 2System message to send

Binary Protocol

The binary protocol is a new addition to the CollabVM protocol, that allows certain messages to be sent as binary instead of a base64 encoded guacamole string. So far, only one such message exists.

The protocol may be enabled by Negotiating the bin protocol with the server during the Handshake.

Message format

All binary messages are encoded with MsgPack (subject to change) and follow this basic format:

{
    type: number;
    // Message specific data
}

Where type is one of the following:

{
    // Framebuffer Update (rectangle)
    rect = 0,
}

Server-to-Client Messages

Framebuffer Update (Binary)

Sent to update the VM screen. The server will send one initial message containing the entire screen on connection, and after that will send a dirty rect for each update.

If the binary protocol is enabled, this will be sent INSTEAD of png opcode messages.

{
    type: 0,
    rect: {
        // X-coordinate of the rectangle
        x: number;
        // Y-coordinate of the rectangle
        y: number;
        // Buffer containing the JPEG data for the rectangle.
        data: Uint8Array;   
    }
}

Rank

CollabVM has four ranks:

IDNameDescription
0UnregisteredThe default rank with no permissions that all users have prior to logging in.
1RegisteredA logged in user. This is only used by servers that use CollabVM Account Authentication.
2AdminHas all permissions on the VM.
3ModeratorPermissions vary depending on server configuration. Even with all permissions granted moderators can still not use the QEMU monitor.

Permissions

When logging in as a Moderator, permissions are defined by a bitmask that can contain the following values:

ValueDescription
1Reset the VM back to it's initial state.
2Reboot the VM
4Ban a user from your VM
8Forcibly pass or cancel a vote to reset
16Mute a user, preventing them from chatting or taking turns
32Kick a user from the VM
64Jump to the front of the turn queue, as well as clear the turn queue and end individual turns
128Rename another user
256Get the IP address of another user
512Send a raw (not HTML-sanitized) chat message, allowing the execution of arbitrary scripts on another user's browser. Admins will not be affected by XSS messages sent by mods.