Protocol Messages
Data Types
The components of the messages use a little-endian byte order.
Type |
Python type |
bytes |
|---|---|---|
uint8 |
int |
1 |
uint16 |
int |
2 |
uint32 |
int |
4 |
uint64 |
int |
8 |
uchar |
int |
1 |
int32 |
int |
4 |
string |
str |
|
boolean |
bool |
1 |
String
string datatype consists of a uint32 denoting its length followed by the list of bytes. Strings will be UTF-8 encoded / decoded before sending
Array
array datatype consists of a uint32 denoting the amount of elements followed by its elements.
Bytearr
bytearr datatype consists of a uint32 denoting its length followed by the list of bytes.
Data Structures
Attribute
Attribute(key: int, value: int)
# |
Type |
Name |
Optional |
Condition |
|---|---|---|---|---|
1 |
uint32 |
key |
No |
|
2 |
uint32 |
value |
No |
SimilarUser
SimilarUser(username: str, score: int)
# |
Type |
Name |
Optional |
Condition |
|---|---|---|---|---|
1 |
string |
username |
No |
|
2 |
uint32 |
score |
No |
Recommendation
Recommendation(recommendation: str, score: int)
# |
Type |
Name |
Optional |
Condition |
|---|---|---|---|---|
1 |
string |
recommendation |
No |
|
2 |
int32 |
score |
No |
RoomTicker
RoomTicker(username: str, ticker: str)
# |
Type |
Name |
Optional |
Condition |
|---|---|---|---|---|
1 |
string |
username |
No |
|
2 |
string |
ticker |
No |
PotentialParent
PotentialParent(username: str, ip: str, port: int)
# |
Type |
Name |
Optional |
Condition |
|---|---|---|---|---|
1 |
string |
username |
No |
|
2 |
ipaddr |
ip |
No |
|
3 |
uint32 |
port |
No |
UserStats
UserStats(avg_speed: int, uploads: int, shared_file_count: int, shared_folder_count: int)
# |
Type |
Name |
Optional |
Condition |
|---|---|---|---|---|
1 |
uint32 |
avg_speed |
No |
|
2 |
uint64 |
uploads |
No |
|
3 |
uint32 |
shared_file_count |
No |
|
4 |
uint32 |
shared_folder_count |
No |
FileData
FileData(unknown: int, filename: str, filesize: int, extension: str, attributes: list[aioslsk.protocol.primitives.Attribute])
# |
Type |
Name |
Optional |
Condition |
|---|---|---|---|---|
1 |
uint8 |
unknown |
No |
|
2 |
string |
filename |
No |
|
3 |
uint64 |
filesize |
No |
|
4 |
string |
extension |
No |
|
5 |
array[Attribute] |
attributes |
No |
DirectoryData
DirectoryData(name: str, files: list[aioslsk.protocol.primitives.FileData])
# |
Type |
Name |
Optional |
Condition |
|---|---|---|---|---|
1 |
string |
name |
No |
|
2 |
array[FileData] |
files |
No |
Value Tables
Transfer Direction
This is only used in the PeerTransferRequest (Code 40) message and indicates the direction in which the file should be sent.
Value |
Meaning |
|---|---|
0 |
upload |
1 |
download |
User Status
Possible statuses:
Value |
Status |
|---|---|
0 |
offline |
1 |
away |
2 |
online |
File Attributes
Lossless: FLAC, WAV
Compressed: MP3, M4A, AAC, OGG
Index |
Meaning |
Usage |
|---|---|---|
0 |
bitrate |
compressed |
1 |
length in seconds |
compressed, lossless |
2 |
VBR |
compressed |
4 |
sample rate |
lossless |
5 |
bitness |
lossless |
Upload Permissions
Permissions indicating who is allowed to initiate an upload a file to the user. Optionally returned in the PeerUserInfoReply (Code 16) message.
Value |
Meaning |
|---|---|
0 |
No-one |
1 |
Everyone |
2 |
User list |
3 |
Permitted list |
Message Statuses
This is a description of possible statuses of each of the messages used by the protocol:
USED : Message still works and is in use
DEPRECATED : Message still works but only used by older clients
DEPRECATED, DEFUNCT : Message no longer works, has no effect or the server doesn’t send it any more
UNKNOWN
Message Structure
All messages, except the file connection messages, must be preceded with a header. This header contains
the length of the message and the message_code.
The
lengthof the header is represented as auint32and should exclude the length itself.The
message_codeis also represented as auint32for all messages except for the Peer Initialization Messages where it is represented as auint8The
bodyis optional
Header structure thus looks as follows:
Type |
Name |
Optional |
|---|---|---|
uint32 |
length |
No |
uint32 |
message_code |
No |
any |
body |
Yes |
Server Messages
Login (Code 1)
Login into the server, this should be the first message sent to the server upon connecting
The
md5hashparameter in the request is the MD5 hash of the concatenatedusernameandpasswordThe
md5hashparameter in the response is the MD5 hash of thepassword
Note
Older client versions (at least 149 or below) would not send the
md5hash and minor_version
- Code:
1 (0x1)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
string
username
No
2
string
password
No
3
uint32
client_version
No
4
string
md5hash
No
5
uint32
minor_version
No
- Receive:
#
Type
Name
Optional
Condition
1
boolean
success
No
2
string
greeting
No
if success == true
3
ipaddr
ip
No
if success == true
4
string
md5hash
No
if success == true
5
boolean
privileged
No
if success == true
6
string
reason
No
if success == false
SetListenPort (Code 2)
Advertise our listening ports to the server
Obfuscated port: this part seems to be optional, either it can be omitted
completely or both values set to 0
- Code:
2 (0x2)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
uint32
port
No
2
uint32
obfuscated_port_amount
Yes
3
uint32
obfuscated_port
Yes
GetPeerAddress (Code 3)
Retrieve the IP address/port of a peer. Obfuscated port: this part is
optional, either it can be omitted completely or both values set to 0 to
indicate there is no obfuscated port
If the peer does not exist or is not logged on the server will respond with
IP address set to 0.0.0.0, port set to 0
- Code:
3 (0x3)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
string
username
No
- Receive:
#
Type
Name
Optional
Condition
1
string
username
No
2
ipaddr
ip
No
3
uint32
port
No
4
uint32
obfuscated_port_amount
Yes
5
uint16
obfuscated_port
Yes
AddUser (Code 5)
When a user is added with this message the server will automatically send user status updates using the GetUserStatus (Code 7) message.
When a user sends a message to multiple users using the PrivateChatMessageUsers (Code 149) message then this message will only be received if the sender was added first using this message.
To remove a user use the RemoveUser (Code 6) message. Keep in mind that you will still receive status updates in case you are joined in the same room with the user.
- Code:
5 (0x5)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
string
username
No
- Receive:
#
Type
Name
Optional
Condition
1
string
username
No
2
boolean
exists
No
3
uint32
status
No
if exists == true
4
user_stats
No
if exists == true
5
string
country_code
Yes
if exists == true
RemoveUser (Code 6)
Remove the tracking of user status which was previously added with the AddUser (Code 5) message.
- Code:
6 (0x6)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
string
username
No
GetUserStatus (Code 7)
Get the user status. The server will automatically send updates for users that we have added with AddUser (Code 5) or which we share a room with.
- Code:
7 (0x7)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
string
username
No
- Receive:
#
Type
Name
Optional
Condition
1
string
username
No
2
uint32
status
No
3
boolean
privileged
No
IgnoreUser (Code 11)
Sent when we want to ignore a user. Received when another user ignores us
- Code:
11 (0xB)
- Status:
DEPRECATED, DEFUNCT
- Send:
#
Type
Name
Optional
Condition
1
string
username
No
- Receive:
#
Type
Name
Optional
Condition
1
string
username
No
UnignoreUser (Code 12)
Sent when we want to unignore a user. Received when another user unignores us
- Code:
12 (0xC)
- Status:
DEPRECATED, DEFUNCT
- Send:
#
Type
Name
Optional
Condition
1
string
username
No
- Receive:
#
Type
Name
Optional
Condition
1
string
username
No
RoomChatMessage (Code 13)
Used when sending a message to a room or receiving a message from someone (including self) who sent a message to a room
- Code:
13 (0xD)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
string
room
No
2
string
message
No
- Receive:
#
Type
Name
Optional
Condition
1
string
room
No
2
string
username
No
3
string
message
No
JoinRoom (Code 14)
Used when we want to join a chat room. If the chat room does not exist it will be created. Upon successfully joining the room the server will send the response message
- Code:
14 (0xE)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
string
room
No
2
uint32
is_private
Yes
- Receive:
#
Type
Name
Optional
Condition
1
string
room
No
2
array[string]
users
No
3
array[uint32]
users_status
No
4
array[UserStats]
users_stats
No
5
array[uint32]
users_slots_free
No
6
array[string]
users_countries
No
7
string
owner
Yes
8
array[string]
operators
Yes
LeaveRoom (Code 15)
Used when we want to leave a chat room. The receive message is confirmation that we left the room
- Code:
15 (0xF)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
string
room
No
- Receive:
#
Type
Name
Optional
Condition
1
string
room
No
UserJoinedRoom (Code 16)
Received when a user joined a room
- Code:
16 (0x10)
- Status:
USED
- Receive:
#
Type
Name
Optional
Condition
1
string
room
No
2
string
username
No
3
uint32
status
No
4
user_stats
No
5
uint32
slots_free
No
6
string
country_code
No
UserLeftRoom (Code 17)
Received when a user left a room
- Code:
17 (0x11)
- Status:
USED
- Receive:
#
Type
Name
Optional
Condition
1
string
room
No
2
string
username
No
ConnectToPeer (Code 18)
Used for making an indirect connection to another peer. If an indirect connection is needed the request should be sent to the server who will pass on the message to the other peer. The peer should try to make a connection with the information (IP, port) provided by the server.
Likewise if the response is received an attempt should be made to connect to the requesting peer
Peer A –Request(username=Peer B)–> Server –Response(username=Peer A)–> Peer B
Also see: CannotConnect (Code 1001)
- Code:
18 (0x12)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
uint32
ticket
No
2
string
username
No
3
string
typ
No
- Receive:
#
Type
Name
Optional
Condition
1
string
username
No
2
string
typ
No
3
ipaddr
ip
No
4
uint32
port
No
5
uint32
ticket
No
6
boolean
privileged
No
7
uint32
obfuscated_port_amount
Yes
8
uint32
obfuscated_port
Yes
PrivateChatMessage (Code 22)
Send or receive a private message. The chat_id should be used in the
PrivateChatMessageAck (Code 23) message to acknowledge the message has been
received. If the acknowledgement is not sent the server will repeat the
message on the next logon.
The is_direct boolean indicates whether it is the first attempt to send
the message, if the server retries then this parameter will be false
- Code:
22 (0x16)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
string
username
No
2
string
message
No
- Receive:
#
Type
Name
Optional
Condition
1
uint32
chat_id
No
2
uint32
timestamp
No
3
string
username
No
4
string
message
No
5
boolean
is_direct
Yes
PrivateChatMessageAck (Code 23)
Acknowledge we have received a private message after receiving a PrivateChatMessage (Code 22)
- Code:
23 (0x17)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
uint32
chat_id
No
FileSearchRoom (Code 25)
Deprecated message for searching a room
- Code:
25 (0x19)
- Status:
Unknown
- Send:
#
Type
Name
Optional
Condition
1
uint32
ticket
No
2
uint32
room_id
No
3
string
query
No
FileSearch (Code 26)
This message is received when another user performed a RoomSearch (Code 120) or UserSearch (Code 42) request and we are part of the room or we are the user the user would like to search in
- Code:
26 (0x1A)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
uint32
ticket
No
2
string
query
No
- Receive:
#
Type
Name
Optional
Condition
1
string
username
No
2
uint32
ticket
No
3
string
query
No
SetStatus (Code 28)
Used to update the online status. Possible values for status:
online = 2, away = 1, offline = 0
- Code:
28 (0x1C)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
uint32
status
No
Ping (Code 32)
Send a ping to the server to let it know we are still alive (every 5 minutes)
Older server versions would respond to this message with the response message
- Code:
32 (0x20)
- Status:
USED
- Send:
No parameters
- Receive:
No parameters
SendConnectTicket (Code 33)
Deprecated predecessor to ConnectToPeer (Code 18). A peer would send this message to the server when wanting to create a connection to another peer, the server would then pass to this to the targeted peer
The value of the ticket parameter would be used in the PeerInit (Code 1)
message.
- Code:
33 (0x21)
- Status:
DEPRECATED, DEFUNCT
- Send:
#
Type
Name
Optional
Condition
1
string
username
No
2
uint32
ticket
No
- Receive:
#
Type
Name
Optional
Condition
1
string
username
No
2
uint32
ticket
No
SendDownloadSpeed (Code 34)
Sent by old clients after download has completed. SendUploadSpeed (Code 121)
should be used instead. The speed value should be in bytes per second
- Code:
34 (0x22)
- Status:
DEPRECATED, DEFUNCT
- Send:
#
Type
Name
Optional
Condition
1
string
username
No
2
uint32
speed
No
GetUserStats (Code 36)
Request a user’s transfer statistics. This message will be received automatically for users with which we share a room
- Code:
36 (0x24)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
string
username
No
- Receive:
#
Type
Name
Optional
Condition
1
string
username
No
2
user_stats
No
Kicked (Code 41)
You were kicked from the server. This message is currently only known to be sent when the user was logged into at another location
- Code:
41 (0x29)
- Status:
USED
- Receive:
No parameters
UserSearch (Code 42)
Search for a file on a specific user, the user will receive this query in the form of a FileSearch (Code 26) message
- Code:
42 (0x2A)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
string
username
No
2
uint32
ticket
No
3
string
query
No
DeprecatedGetItemRecommendations (Code 50)
Similar to GetItemRecommendations (Code 111) except that no score is returned
- Code:
50 (0x32)
- Status:
DEPRECATED, DEFUNCT
- Send:
#
Type
Name
Optional
Condition
1
string
item
No
- Receive:
#
Type
Name
Optional
Condition
1
string
item
No
2
array[string]
recommendations
No
AddInterest (Code 51)
Adds an interest. This is used when requesting recommendations (eg.: GetRecommendations (Code 54), …)
- Code:
51 (0x33)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
string
interest
No
RemoveInterest (Code 52)
Removes an interest previously added with AddInterest (Code 51) message
- Code:
52 (0x34)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
string
interest
No
GetRecommendations (Code 54)
Request the server to send a list of recommendations and unrecommendations. A maximum of 100 each will be returned. The score can be negative.
- Code:
54 (0x36)
- Status:
USED
- Send:
No parameters
- Receive:
#
Type
Name
Optional
Condition
1
array[Recommendation]
recommendations
No
2
array[Recommendation]
unrecommendations
No
GetInterests (Code 55)
Request the server the list of interests it currently has stored for us. This was sent by older clients during logon, presumably to sync the interests on the client and the server. Deprecated as the client should just advertise all interests after logon using the AddInterest (Code 51) and AddHatedInterest (Code 117) messages
Not known whether the server still responds to this command
- Code:
55 (0x37)
- Status:
DEPRECATED, DEFUNCT
- Send:
No parameters
- Receive:
#
Type
Name
Optional
Condition
1
array[string]
interests
No
GetGlobalRecommendations (Code 56)
Get the global list of recommendations. This does not take into account interests or hated interests that were previously added and is just a ranking of interests that other users have set
- Code:
56 (0x38)
- Status:
USED
- Send:
No parameters
- Receive:
#
Type
Name
Optional
Condition
1
array[Recommendation]
recommendations
No
2
array[Recommendation]
unrecommendations
No
GetUserInterests (Code 57)
Get the interests and hated interests of a particular user
ExecuteCommand (Code 58)
Send a command to the server.
The command type has only ever been seen as having value admin, the arguments array
contains the subcommand and arguments. Example when banning a user:
command_type:adminarguments0 :
ban1 :
some user2 : probably some extra args, perhaps time limit in case of ban, … (optional)
- Code:
58 (0x3A)
- Status:
DEPRECATED, DEFUNCT
- Send:
#
Type
Name
Optional
Condition
1
string
command_type
No
2
array[string]
arguments
No
RoomList (Code 64)
Request or receive the list of rooms. This message will be initially sent after logging on but can also be manually requested afterwards. The initial message after logon will only return a limited number of public rooms (only the rooms with 5 or more users).
Parameter rooms_private excludes private rooms of which we are owner
Parameter rooms_private_owned_user_count / rooms_private_user_count
should be the amount of users who have joined the private room, not the
amount of members
- Code:
64 (0x40)
- Status:
USED
- Send:
No parameters
- Receive:
#
Type
Name
Optional
Condition
1
array[string]
rooms
No
2
array[uint32]
rooms_user_count
No
3
array[string]
rooms_private_owned
No
4
array[uint32]
rooms_private_owned_user_count
No
5
array[string]
rooms_private
No
6
array[uint32]
rooms_private_user_count
No
7
array[string]
rooms_private_operated
No
ExactFileSearch (Code 65)
Used by older clients but doesn’t return anything. The pathname is
optional but is still required to be sent.
For the message sending: The first 4 parameters are verified, the meaning of the final 5 bytes is unknown
For the message receiving: message is never seen and is based on other documentation (PySlsk)
- Code:
65 (0x41)
- Status:
DEPRECATED, DEFUNCT
- Send:
#
Type
Name
Optional
Condition
1
uint32
ticket
No
2
string
filename
No
3
string
pathname
No
4
uint64
filesize
No
5
uint32
checksum
No
6
uint8
unknown
No
- Receive:
#
Type
Name
Optional
Condition
1
string
username
No
2
uint32
ticket
No
3
string
filename
No
4
string
pathname
No
5
uint64
filesize
No
6
uint32
checksum
No
AdminMessage (Code 66)
Sent by the admin when the server is going down for example
- Code:
66 (0x42)
- Status:
UNKNOWN
- Receive:
#
Type
Name
Optional
Condition
1
string
message
No
GetUserList (Code 67)
Gets a list of all users on the server
TunneledMessage (Code 68)
Tunnel a message through the server to a user
- Code:
68 (0x44)
- Status:
DEPRECATED, DEFUNCT
- Send:
#
Type
Name
Optional
Condition
1
string
username
No
2
uint32
ticket
No
3
uint32
code
No
4
string
message
No
- Receive:
#
Type
Name
Optional
Condition
1
string
username
No
2
uint32
ticket
No
3
uint32
code
No
4
ipaddr
ip
No
5
uint32
port
No
6
string
message
No
PrivilegedUsers (Code 69)
List of users with privileges sent after login
- Code:
69 (0x45)
- Status:
USED
- Receive:
#
Type
Name
Optional
Condition
1
array[string]
users
No
ToggleParentSearch (Code 71)
Indicates whether we want to receive PotentialParents (Code 102) messages from the server. A message should be sent to disable if we have found a parent
- Code:
71 (0x47)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
boolean
enable
No
ParentIP (Code 73)
IP address of the parent. Not sent by newer clients
- Code:
73 (0x49)
- Status:
DEPRECATED
- Send:
#
Type
Name
Optional
Condition
1
ipaddr
ip
No
Unknown80 (Code 80)
Unknown message used by old client versions. The client would establish 2 connections to the server: to one it would send the Login (Code 1) message, to the other this message would be sent. This second connection seemed to be related to the distributed network as the client would automatically disconnect after DistributedAliveInterval (Code 90) had been reached. It would seem like the server would be the client’s parent in this case.
After an interval determined by DistributedDistributeInterval (Code 89) the client would send another message over this connection which is described in DistributedInit (Code 1). There’s many unknowns in this message and even the types are unknown as many values were just 0, only known value is the last value which is the second listening port these clients used
- Code:
80 (0x50)
- Status:
DEPRECATED, DEFUNCT
- Send:
No parameters
ParentMinSpeed (Code 83)
Used for calculating the maximum amount of children we can have in the distributed network. If our average upload speed is below this value then we should accept no children. The average upload speed should be determined by the upload speed returned by GetUserStats (Code 36) (with our own username)
- Code:
83 (0x53)
- Status:
USED
- Receive:
#
Type
Name
Optional
Condition
1
uint32
speed
No
ParentSpeedRatio (Code 84)
Used for calculating the maximum amount of children we can have in the distributed network
- Code:
84 (0x54)
- Status:
USED
- Receive:
#
Type
Name
Optional
Condition
1
uint32
ratio
No
ParentInactivityTimeout (Code 86)
Timeout for the distributed parent
- Code:
86 (0x56)
- Status:
DEPRECATED
- Receive:
#
Type
Name
Optional
Condition
1
uint32
timeout
No
SearchInactivityTimeout (Code 87)
Presumably indicates after how much time search responses should no longer be accepted
- Code:
87 (0x57)
- Status:
DEPRECATED
- Receive:
#
Type
Name
Optional
Condition
1
uint32
timeout
No
MinParentsInCache (Code 88)
Amount of parents (received through PotentialParents (Code 102)) we should keep in cache. Message has not been seen being sent by the server
- Code:
88 (0x58)
- Status:
DEPRECATED, DEFUNCT
- Receive:
#
Type
Name
Optional
Condition
1
uint32
amount
No
DistributedDistributeInterval (Code 89)
Deprecated distributed network related message
- Code:
89 (0x59)
- Status:
DEPRECATED, DEFUNCT
- Receive:
#
Type
Name
Optional
Condition
1
uint32
interval
No
DistributedAliveInterval (Code 90)
Interval at which a DistributedPing (Code 0) message should be sent to the children
- Code:
90 (0x5A)
- Status:
DEPRECATED
- Receive:
#
Type
Name
Optional
Condition
1
uint32
interval
No
AddPrivilegedUser (Code 91)
Usage unknown
- Code:
91 (0x5B)
- Status:
UNKNOWN
- Receive:
#
Type
Name
Optional
Condition
1
string
username
No
CheckPrivileges (Code 92)
Checks whether the requesting user has privileges, time_left will
be 0 in case the user has no privileges, time left in seconds otherwise
- Code:
92 (0x5C)
- Status:
USED
- Send:
No parameters
- Receive:
#
Type
Name
Optional
Condition
1
uint32
time_left
No
ServerSearchRequest (Code 93)
Search request sent by another user through the server. Upon receiving this the message should be passed on to the distributed children
- Code:
93 (0x5D)
- Status:
USED
- Receive:
#
Type
Name
Optional
Condition
1
uint8
distributed_code
No
2
uint32
unknown
No
3
string
username
No
4
uint32
ticket
No
5
string
query
No
AcceptChildren (Code 100)
Tell the server whether or not we are accepting any distributed children, the server should take this into account when sending PotentialParents (Code 102) messages to other peers
- Code:
100 (0x64)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
boolean
accept
No
PotentialParents (Code 102)
List of potential parents, used in distributed network
- Code:
102 (0x66)
- Status:
USED
- Receive:
#
Type
Name
Optional
Condition
1
array[PotentialParent]
entries
No
WishlistSearch (Code 103)
Perform a wishlist search. The interval at which a client should send this message is determined by the WishlistInterval (Code 104) message
- Code:
103 (0x67)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
uint32
ticket
No
2
string
query
No
WishlistInterval (Code 104)
The server lets us know at what interval we should perform wishlist searches (WishlistSearch (Code 103)). Sent by the server after logon
- Code:
104 (0x68)
- Status:
USED
- Receive:
#
Type
Name
Optional
Condition
1
uint32
interval
No
GetSimilarUsers (Code 110)
Get a list of similar users
- Code:
110 (0x6E)
- Status:
USED
- Send:
No parameters
- Receive:
#
Type
Name
Optional
Condition
1
array[SimilarUser]
users
No
GetItemRecommendations (Code 111)
Get a list of recommendations based on a single interest
- Code:
111 (0x6F)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
string
item
No
- Receive:
#
Type
Name
Optional
Condition
1
string
item
No
2
array[Recommendation]
recommendations
No
GetItemSimilarUsers (Code 112)
Get a list of similar users based on a single interest
- Code:
112 (0x70)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
string
item
No
- Receive:
#
Type
Name
Optional
Condition
1
string
item
No
2
array[string]
usernames
No
RoomTickers (Code 113)
List of chat room tickers (room wall)
- Code:
113 (0x71)
- Status:
USED
- Receive:
#
Type
Name
Optional
Condition
1
string
room
No
2
array[RoomTicker]
tickers
No
RoomTickerAdded (Code 114)
A ticker has been added to the room (room wall)
- Code:
114 (0x72)
- Status:
USED
- Receive:
#
Type
Name
Optional
Condition
1
string
room
No
2
string
username
No
3
string
ticker
No
RoomTickerRemoved (Code 115)
A ticker has been removed to the room (room wall)
- Code:
115 (0x73)
- Status:
USED
- Receive:
#
Type
Name
Optional
Condition
1
string
room
No
2
string
username
No
SetRoomTicker (Code 116)
Add or update a ticker for a room (room wall)
Note
An empty ticker value is not allowed in most clients. However, the server does accept
it and clears the ticker from the room
- Code:
116 (0x74)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
string
room
No
2
string
ticker
No
AddHatedInterest (Code 117)
Adds an hated interest. This is used when requesting recommendations (eg.: GetRecommendations (Code 54), …)
- Code:
117 (0x75)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
string
hated_interest
No
RemoveHatedInterest (Code 118)
Removes a hated interest previously added with AddHatedInterest (Code 117) message
- Code:
118 (0x76)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
string
hated_interest
No
RoomSearch (Code 120)
Perform a search query on all users in the given room, this can only be performed if the room was joined first. The server will send a FileSearch (Code 26) to every user in the requested room
- Code:
120 (0x78)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
string
room
No
2
uint32
ticket
No
3
string
query
No
SendUploadSpeed (Code 121)
Sent to the server right after an upload completed. speed parameter
should be in bytes per second. This should not be the global average upload
speed but rather the upload speed for that particular transfer. After this
message has been sent the server will recalculate the average speed and
increase the amount of uploads for your user.
In exception cases, for example if a transfer was failed midway then resumed, only the speed of the resumed part is taken into account. However this might be client dependent.
- Code:
121 (0x79)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
uint32
speed
No
GetUserPrivileges (Code 122)
Retrieve whether a user has privileges
- Code:
122 (0x7A)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
string
username
No
- Receive:
#
Type
Name
Optional
Condition
1
string
username
No
2
boolean
privileged
No
GiveUserPrivileges (Code 123)
Gift a user privileges. This only works if the user sending the message has privileges and needs to be less than what the gifting user has left, part of its privileges will be taken
- Code:
123 (0x7B)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
string
username
No
2
uint32
days
No
PrivilegesNotification (Code 124)
- Code:
124 (0x7C)
- Status:
Unknown
- Send:
#
Type
Name
Optional
Condition
1
uint32
notification_id
No
2
string
username
No
PrivilegesNotificationAck (Code 125)
- Code:
125 (0x7D)
- Status:
Unknown
- Send:
#
Type
Name
Optional
Condition
1
uint32
notification_id
No
BranchLevel (Code 126)
Notify the server which branch level we are at in the distributed network
- Code:
126 (0x7E)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
uint32
level
No
BranchRoot (Code 127)
Notify the server who our branch root user is in the distributed network
- Code:
127 (0x7F)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
string
username
No
ChildDepth (Code 129)
See DistributedChildDepth (Code 7)
Note
SoulSeekQt sends the depth as a uint8
- Code:
129 (0x81)
- Status:
DEPRECATED
- Send:
#
Type
Name
Optional
Condition
1
uint32
depth
No
ResetDistributed (Code 130)
Server requests to reset our parent and children
- Code:
130 (0x82)
- Status:
USED
- Receive:
No parameters
PrivateRoomMembers (Code 133)
List of all members that are part of the private room (excludes owner)
- Code:
133 (0x85)
- Status:
USED
- Receive:
#
Type
Name
Optional
Condition
1
string
room
No
2
array[string]
usernames
No
PrivateRoomGrantMembership (Code 134)
Add another user to the private room. Only operators and the owner can add members to a private room.
This message is also received by all other members in the private room
- Code:
134 (0x86)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
string
room
No
2
string
username
No
- Receive:
#
Type
Name
Optional
Condition
1
string
room
No
2
string
username
No
PrivateRoomRevokeMembership (Code 135)
Remove another user from the private room. Operators can remove regular members but not other operators or the owner. The owner can remove anyone aside from himself (see PrivateRoomDropOwnership (Code 137)).
This message is also received by all other members in the private room
- Code:
135 (0x87)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
string
room
No
2
string
username
No
- Receive:
#
Type
Name
Optional
Condition
1
string
room
No
2
string
username
No
PrivateRoomDropMembership (Code 136)
Drops membership of a private room, this will not do anything for the owner of the room. See PrivateRoomDropOwnership (Code 137) for owners
- Code:
136 (0x88)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
string
room
No
PrivateRoomDropOwnership (Code 137)
Drops ownership of a private room, this disbands the entire room.
- Code:
137 (0x89)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
string
room
No
PrivateRoomMembershipGranted (Code 139)
Received when the current user has been granted membership to a private room
- Code:
139 (0x8B)
- Status:
USED
- Receive:
#
Type
Name
Optional
Condition
1
string
room
No
PrivateRoomMembershipRevoked (Code 140)
Received when the current user had its membership revoked from a private room
- Code:
140 (0x8C)
- Status:
USED
- Receive:
#
Type
Name
Optional
Condition
1
string
room
No
TogglePrivateRoomInvites (Code 141)
Enables or disables private room invites (through PrivateRoomGrantMembership (Code 134))
- Code:
141 (0x8D)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
boolean
enable
No
- Receive:
#
Type
Name
Optional
Condition
1
boolean
enabled
No
NewPassword (Code 142)
Modifies the user’s password
- Code:
142 (0x8E)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
string
password
No
PrivateRoomGrantOperator (Code 143)
Grant operator privileges to a member in a private room. This message will also be received by all other members in the room (irrelevant of if they are online or not)
- Code:
143 (0x8F)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
string
room
No
2
string
username
No
- Receive:
#
Type
Name
Optional
Condition
1
string
room
No
2
string
username
No
PrivateRoomRevokeOperator (Code 144)
Revoke operator privileges from a member in a private room. This message will also be received by all other members in the room (irrelevant of if they are online or not).
- Code:
144 (0x90)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
string
room
No
2
string
username
No
- Receive:
#
Type
Name
Optional
Condition
1
string
room
No
2
string
username
No
PrivateRoomOperatorGranted (Code 145)
Received when granted operator privileges in a private room
- Code:
145 (0x91)
- Status:
USED
- Receive:
#
Type
Name
Optional
Condition
1
string
room
No
PrivateRoomOperatorRevoked (Code 146)
Received when operator privileges in a private room were revoked
- Code:
146 (0x92)
- Status:
USED
- Receive:
#
Type
Name
Optional
Condition
1
string
room
No
PrivateRoomOperators (Code 148)
List of operators for a private room
- Code:
148 (0x94)
- Status:
USED
- Receive:
#
Type
Name
Optional
Condition
1
string
room
No
2
array[string]
usernames
No
PrivateChatMessageUsers (Code 149)
Send a private message to a list of users. This message will only be received by users who have added you using the AddUser (Code 5) message first
- Code:
149 (0x95)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
array[string]
usernames
No
2
string
message
No
EnablePublicChat (Code 150)
Enables public chat, see PublicChatMessage (Code 152)
- Code:
150 (0x96)
- Status:
USED
- Send:
No parameters
DisablePublicChat (Code 151)
Disables public chat, see PublicChatMessage (Code 152)
- Code:
151 (0x97)
- Status:
USED
- Send:
No parameters
PublicChatMessage (Code 152)
When public chat is enabled all messages sent to public rooms will also be sent to us using this message. Use EnablePublicChat (Code 150) and DisablePublicChat (Code 151) to disable or enable receiving these messages.
- Code:
152 (0x98)
- Status:
USED
- Receive:
#
Type
Name
Optional
Condition
1
string
room
No
2
string
username
No
3
string
message
No
ExcludedSearchPhrases (Code 160)
Optionally sent by the server after logging on. Search results containing at least one of the phrases (exact match, case insensitive) should be filtered out before being sent.
It is highly recommended to take this filtering into account as not doing so could jeopardize the network
- Code:
160 (0xA0)
- Status:
USED
- Receive:
#
Type
Name
Optional
Condition
1
array[string]
phrases
No
CannotConnect (Code 1001)
Indicates an indirect connection attempt failed
The request message should be sent to the server after we received a ConnectToPeer (Code 18) message but the connection attempt failed
The response will be received from the server if we sent out a ConnectToPeer (Code 18) message but the target user failed to connect to us
- Code:
1001 (0x3E9)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
uint32
ticket
No
2
string
username
No
- Receive:
#
Type
Name
Optional
Condition
1
uint32
ticket
No
CannotCreateRoom (Code 1003)
Sent by the server when attempting to create/join a private room which already exists or the user is not part of
- Code:
1003 (0x3EB)
- Status:
USED
- Receive:
#
Type
Name
Optional
Condition
1
string
room
No
Peer Initialization Messages
PeerPierceFirewall (Code 0)
Sent after connection was successfully established in response to a
ConnectToPeer (Code 18) message. The ticket used here should be the ticket
from that ConnectToPeer (Code 18) message
- Code:
0 (0x0)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
uint32
ticket
No
PeerInit (Code 1)
Sent after direct connection was successfully established (not as a response to a ConnectToPeer (Code 18) received from the server)
The ticket is usually 0 and was filled in with ticket value from
the SendConnectTicket (Code 33) message by older versions of the client
- Code:
1 (0x1)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
string
username
No
2
string
typ
No
3
_PeerInitTicket
ticket
No
Peer Messages
PeerSearchReply (Code 9)
Response to a search request
PeerUserInfoRequest (Code 15)
Request information from the peer
- Code:
15 (0xF)
- Status:
USED
- Send:
No parameters
PeerUserInfoReply (Code 16)
Response to PeerUserInfoRequest (Code 15). Possible values for
upload_permissions can be found here
- Code:
16 (0x10)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
string
description
No
2
boolean
has_picture
No
3
bytearr
picture
No
if has_picture == true
4
uint32
upload_slots
No
5
uint32
queue_size
No
6
boolean
has_slots_free
No
7
uint32
upload_permissions
Yes
PeerDirectoryContentsRequest (Code 36)
Request the contents of a directory
- Code:
36 (0x24)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
uint32
ticket
No
2
string
directory
No
PeerDirectoryContentsReply (Code 37)
Reply to PeerDirectoryContentsRequest (Code 36).
Although the returned directories is an array it will only contain one element and will not list files from subdirectories
- Code:
37 (0x25)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
uint32
ticket
No
2
string
directory
No
3
array[DirectoryData]
directories
No
PeerTransferRequest (Code 40)
filesize can be omitted if the direction==1 however a value of 0
can be used in this case as well
- Code:
40 (0x28)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
uint32
direction
No
2
uint32
ticket
No
3
string
filename
No
4
uint64
filesize
Yes
PeerTransferReply (Code 41)
Response message to PeerTransferRequest (Code 40)
- Code:
41 (0x29)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
uint32
ticket
No
2
boolean
allowed
No
3
uint64
filesize
Yes
if allowed == true
4
string
reason
Yes
if allowed == false
PeerTransferQueue (Code 43)
Request to place the provided transfer of filename in the queue
- Code:
43 (0x2B)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
string
filename
No
PeerPlaceInQueueReply (Code 44)
Response to PeerPlaceInQueueRequest (Code 51)
- Code:
44 (0x2C)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
string
filename
No
2
uint32
place
No
PeerUploadFailed (Code 46)
Sent when uploading failed
- Code:
46 (0x2E)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
string
filename
No
PeerTransferQueueFailed (Code 50)
Sent when placing the transfer in queue failed
- Code:
50 (0x32)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
string
filename
No
2
string
reason
No
PeerPlaceInQueueRequest (Code 51)
Request the place of the transfer in the queue.
- Code:
51 (0x33)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
string
filename
No
PeerUploadQueueNotification (Code 52)
Deprecated message
- Code:
52 (0x34)
- Status:
DEPRECATED
- Send:
No parameters
Distributed Messages
DistributedPing (Code 0)
Ping request from the parent. Most clients do not send this.
- Code:
0 (0x0)
- Status:
DEPRECATED
- Send:
No parameters
DistributedInit (Code 1)
Deprecated distributed network related message
- Code:
1 (0x1)
- Status:
DEPRECATED, DEFUNCT
- Send:
#
Type
Name
Optional
Condition
1
uint32
unknown1
No
2
uint32
unknown2
No
3
uint8
unknown3
No
4
uint32
port
No
DistributedSearchRequest (Code 3)
Search request coming from the parent
- Code:
3 (0x3)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
uint32
unknown
No
2
string
username
No
3
uint32
ticket
No
4
string
query
No
DistributedBranchLevel (Code 4)
Distributed branch level
- Code:
4 (0x4)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
uint32
level
No
DistributedBranchRoot (Code 5)
Distributed branch root
- Code:
5 (0x5)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
string
username
No
DistributedChildDepth (Code 7)
Used by SoulSeek NS and still passed on by SoulSeekQt, sent to the
parent upon connecting to that parent (although unclear what happens when
a peer attaches to another parent while already having children). The parent
should increase the depth by 1 until it reaches the branch root, which
should increase by 1 and send it to the server as a ChildDepth (Code 129)
message.
- Code:
7 (0x7)
- Status:
DEPRECATED
- Send:
#
Type
Name
Optional
Condition
1
uint32
depth
No
DistributedServerSearchRequest (Code 93)
The branch root should just pass the ServerSearchRequest as-is to all its children; meaning we will get this message if we are at level 1. If we get this message we should translate it to a proper DistributedSearchRequest message.
This message might need to be revisited, as it’s only currently used for parsing
- Code:
93 (0x5D)
- Status:
USED
- Send:
#
Type
Name
Optional
Condition
1
uint8
distributed_code
No
2
uint32
unknown
No
3
string
username
No
4
uint32
ticket
No
5
string
query
No
File Messages
File connection does not have a header format but after peer initialization two values are exchanged:
uint32: ticket
uint64: offset