diff options
Diffstat (limited to 'xC-proto')
-rw-r--r-- | xC-proto | 206 |
1 files changed, 206 insertions, 0 deletions
diff --git a/xC-proto b/xC-proto new file mode 100644 index 0000000..3057404 --- /dev/null +++ b/xC-proto @@ -0,0 +1,206 @@ +// Backwards-compatible protocol version. +const VERSION = 1; + +// From the frontend to the relay. +struct CommandMessage { + // The command sequence number will be repeated in responses + // in the respective fields. + u32 command_seq; + union CommandData switch (enum Command { + HELLO, + ACTIVE, + BUFFER_ACTIVATE, + BUFFER_INPUT, + BUFFER_TOGGLE_UNIMPORTANT, + PING_RESPONSE, + PING, + BUFFER_COMPLETE, + BUFFER_LOG, + } command) { + // If the version check succeeds, the client will receive + // an initial stream of SERVER_UPDATE, BUFFER_UPDATE, BUFFER_STATS, + // BUFFER_LINE, and finally a BUFFER_ACTIVATE message. + case HELLO: + u32 version; + case ACTIVE: + void; + case BUFFER_ACTIVATE: + string buffer_name; + case BUFFER_INPUT: + string buffer_name; + string text; + // XXX: Perhaps this should rather be handled through a /buffer command. + case BUFFER_TOGGLE_UNIMPORTANT: + string buffer_name; + case PING_RESPONSE: + u32 event_seq; + + // Only these commands may produce Event.RESPONSE, as below, + // but any command may produce an error. + case PING: + void; + case BUFFER_COMPLETE: + string buffer_name; + string text; + u32 position; + case BUFFER_LOG: + string buffer_name; + } data; +}; + +// From the relay to the frontend. +struct EventMessage { + u32 event_seq; + union EventData switch (enum Event { + PING, + BUFFER_LINE, + BUFFER_UPDATE, + BUFFER_STATS, + BUFFER_RENAME, + BUFFER_REMOVE, + BUFFER_ACTIVATE, + BUFFER_CLEAR, + SERVER_UPDATE, + SERVER_RENAME, + SERVER_REMOVE, + ERROR, + RESPONSE, + } event) { + case PING: + void; + + case BUFFER_LINE: + string buffer_name; + // Whether the line should also be displayed in the active buffer. + bool leak_to_active; + bool is_unimportant; + bool is_highlight; + enum Rendition { + BARE, + INDENT, + STATUS, + ERROR, + JOIN, + PART, + ACTION, + } rendition; + // Unix timestamp in milliseconds. + u64 when; + // Broken-up text, with in-band formatting. + union ItemData switch (enum Item { + TEXT, + RESET, + FG_COLOR, + BG_COLOR, + FLIP_BOLD, + FLIP_ITALIC, + FLIP_UNDERLINE, + FLIP_INVERSE, + FLIP_CROSSED_OUT, + FLIP_MONOSPACE, + } kind) { + case TEXT: + string text; + case RESET: + void; + case FG_COLOR: + i16 color; + case BG_COLOR: + i16 color; + case FLIP_BOLD: + case FLIP_ITALIC: + case FLIP_UNDERLINE: + case FLIP_INVERSE: + case FLIP_CROSSED_OUT: + case FLIP_MONOSPACE: + void; + } items<>; + case BUFFER_UPDATE: + string buffer_name; + bool hide_unimportant; + union BufferContext switch (enum BufferKind { + GLOBAL, + SERVER, + CHANNEL, + PRIVATE_MESSAGE, + } kind) { + case GLOBAL: + void; + case SERVER: + string server_name; + case CHANNEL: + string server_name; + ItemData topic<>; + // This includes parameters, separated by spaces. + string modes; + case PRIVATE_MESSAGE: + string server_name; + } context; + case BUFFER_STATS: + string buffer_name; + // These are cumulative, even for lines flushed out from buffers. + // Updates to these values aren't broadcasted, thus handle: + // - BUFFER_LINE by bumping/setting them as appropriate, + // - BUFFER_ACTIVATE by clearing them for the previous buffer + // (this way, they can be used to mark unread messages). + u32 new_messages; + u32 new_unimportant_messages; + bool highlighted; + case BUFFER_RENAME: + string buffer_name; + string new; + case BUFFER_REMOVE: + string buffer_name; + case BUFFER_ACTIVATE: + string buffer_name; + case BUFFER_CLEAR: + string buffer_name; + + case SERVER_UPDATE: + string server_name; + union ServerData switch (enum ServerState { + DISCONNECTED, + CONNECTING, + CONNECTED, + REGISTERED, + DISCONNECTING, + } state) { + case DISCONNECTED: + case CONNECTING: + case CONNECTED: + void; + case REGISTERED: + string user; + string user_modes; + // Theoretically, we could also send user information in this state, + // but we'd have to duplicate both fields. + case DISCONNECTING: + void; + } data; + case SERVER_RENAME: + // Buffers aren't sent updates for in this circumstance, + // as that wouldn't be sufficiently atomic anyway. + string server_name; + string new; + case SERVER_REMOVE: + string server_name; + + // Restriction: command_seq strictly follows the sequence received + // by the relay, across both of these replies. + case ERROR: + u32 command_seq; + string error; + case RESPONSE: + u32 command_seq; + union ResponseData switch (Command command) { + case PING: + void; + case BUFFER_COMPLETE: + u32 start; + string completions<>; + case BUFFER_LOG: + // UTF-8, but not guaranteed. + u8 log<>; + } data; + } data; +}; |