ASFUR PROTOCOL SPECIFICATION All packets follow this structure: [u16 size][u8 type][data...] size: total length of the packet (including header) type: packet type identifier data: payload bytes (format depends on type) ================================================================================ PACKET TYPES ================================================================================ Client -> Server: PACKET_REGISTER = 1 PACKET_AUTHENTICATE = 2 PACKET_JOIN = 3 PACKET_TEXT = 4 PACKET_LEAVE = 5 PACKET_DM_OPEN = 7 PACKET_CREATE_ROOM = 9 PACKET_DELETE_ROOM = 10 PACKET_LIST_ROOMS = 12 Server -> Client: PACKET_ERROR = 0 PACKET_OK = 6 PACKET_DM_ROOM = 8 PACKET_ROOM_CREATED = 11 PACKET_ROOM_LIST = 13 Bidirectional: PACKET_TEXT = 4 (client sends, server broadcasts) ================================================================================ PACKET DATA LAYOUTS ================================================================================ PACKET_ERROR (0) Server response indicating an error occurred. [u8 code] Error codes: 0 = ERR_UNKNOWN (unknown error) 1 = ERR_INVALID_PACKET (malformed packet) 2 = ERR_NOT_AUTHENTICATED (action requires authentication) 3 = ERR_ALREADY_REGISTERED (username already taken) 4 = ERR_INVALID_CREDENTIALS (wrong username/password) 5 = ERR_REGISTRATION_DISABLED (server disabled registration) 6 = ERR_DATABASE (internal database error) 7 = ERR_USER_NOT_FOUND (target user does not exist) 8 = ERR_ACCESS_DENIED (not allowed to access resource) 9 = ERR_ROOM_NOT_FOUND (room does not exist) 10 = ERR_ROOM_NAME_TAKEN (room name already in use) 11 = ERR_NOT_ROOM_OWNER (action requires room ownership) PACKET_REGISTER (1) Register a new user account. [char username[20]][char password[100]] Response: PACKET_OK or PACKET_ERROR PACKET_AUTHENTICATE (2) Authenticate with existing credentials. [char username[20]][char password[100]] Response: PACKET_OK or PACKET_ERROR PACKET_JOIN (3) Join a room (public or DM). [u64 room_id] Response: PACKET_OK or PACKET_ERROR Requires: authentication PACKET_TEXT (4) Send a message to a room (client -> server). [u64 room_id][char message[...]] message is variable length (packet size - header - 8 bytes) Client must have joined the room first. Requires: authentication, joined room Broadcast format (server -> client): [u64 room_id][char username[32]][char message[...]] Server broadcasts to all authenticated clients in the room. PACKET_LEAVE (5) Leave a room. [u64 room_id] Response: PACKET_OK or PACKET_ERROR Requires: authentication PACKET_OK (6) Server response indicating success. (no data) PACKET_DM_OPEN (7) Open or get existing DM room with another user. [char username[20]] Response: PACKET_DM_ROOM or PACKET_ERROR Requires: authentication PACKET_DM_ROOM (8) Server response with DM room ID. [u64 room_id] The room_id can be used with PACKET_JOIN. PACKET_CREATE_ROOM (9) Create a new public room. [char name[32]] Response: PACKET_ROOM_CREATED or PACKET_ERROR Requires: authentication PACKET_DELETE_ROOM (10) Delete a public room. [u64 room_id] Response: PACKET_OK or PACKET_ERROR Requires: authentication, room ownership PACKET_ROOM_CREATED (11) Server response after successful room creation. [u64 room_id][char name[32]] PACKET_LIST_ROOMS (12) Request list of all public rooms. (no data) Response: PACKET_ROOM_LIST or PACKET_ERROR Requires: authentication PACKET_ROOM_LIST (13) Server response with list of public rooms. [u32 count][room_entry[count]] room_entry format: [u64 room_id][char name[32]][char owner[20]] ================================================================================ TYPICAL FLOWS ================================================================================ Registration: Client: PACKET_REGISTER(username, password) Server: PACKET_OK or PACKET_ERROR(ERR_ALREADY_REGISTERED) Authentication: Client: PACKET_AUTHENTICATE(username, password) Server: PACKET_OK or PACKET_ERROR(ERR_INVALID_CREDENTIALS) Join public room: Client: PACKET_LIST_ROOMS Server: PACKET_ROOM_LIST(rooms) Client: PACKET_JOIN(room_id) Server: PACKET_OK Send message: Client: PACKET_TEXT(room_id, "hello") Server: PACKET_TEXT(room_id, sender_username, "hello") -> all clients in room Direct message: Client: PACKET_DM_OPEN(target_username) Server: PACKET_DM_ROOM(room_id) Client: PACKET_JOIN(room_id) Server: PACKET_OK Client: PACKET_TEXT(room_id, "private message") Create room: Client: PACKET_CREATE_ROOM("my-room") Server: PACKET_ROOM_CREATED(room_id, "my-room")