From 9c7ddb4ac71e7b4bd298e20500ef66f58db6d329 Mon Sep 17 00:00:00 2001 From: Tom Smeding Date: Tue, 28 Jul 2020 20:06:57 +0200 Subject: clientlib: Update to protocol version 2 with replies --- ssh/client.c | 21 +++++++++++++++++---- ssh/tomsg_clientlib.c | 10 +++++++--- ssh/tomsg_clientlib.h | 5 +++++ 3 files changed, 29 insertions(+), 7 deletions(-) (limited to 'ssh') diff --git a/ssh/client.c b/ssh/client.c index 52f26c6..ad0f107 100644 --- a/ssh/client.c +++ b/ssh/client.c @@ -199,7 +199,7 @@ static bool handle_line( if (state->focus_room != NULL) { char *message = NULL; sv_copy(line, &message); - enum tomsg_retval ret = tomsg_send(client, state->focus_room, message, NULL); + enum tomsg_retval ret = tomsg_send(client, state->focus_room, message, -1, NULL); free(message); if (ret != TOMSG_OK) return true; return false; @@ -253,7 +253,15 @@ static bool handle_line( } else if (sv_equals(command, "s") || sv_equals(command, "send")) { if (parse_args(line, args, num_args = 2, true)) { autocomplete_roomname(state, &args[0]); - ret = tomsg_send(client, args[0], args[1], NULL); + ret = tomsg_send(client, args[0], args[1], -1, NULL); + } + + } else if (sv_equals(command, "r") || sv_equals(command, "reply")) { + int64_t replyid; + if (parse_args(line, args, num_args = 3, true) && + parse_i64(args[1], &replyid)) { + autocomplete_roomname(state, &args[0]); + ret = tomsg_send(client, args[0], args[2], replyid, NULL); } } else if (sv_equals(command, "ping")) { @@ -314,6 +322,7 @@ static bool handle_line( " create_room\n" " invite \n" " s/send \n" + " r/reply \n" " ping\n" " hist/history \n" " histb/history_before \n" @@ -365,8 +374,12 @@ static const char* event_type_descr(enum tomsg_event_type type) { } static void print_history_message(const struct history_message msg) { - printf("%" PRIi64 " \x1B[90m%" PRIi64 "\x1B[0m <%s> %s\n", - msg.msgid, msg.timestamp, msg.username, msg.message); + printf("%" PRIi64 " \x1B[90m%" PRIi64 "\x1B[0m <%s> ", + msg.msgid, msg.timestamp, msg.username); + if (msg.replyid != -1) { + printf("\x1B[32m[%" PRIi64 "<-]\x1B[0m ", msg.replyid); + } + printf("%s\n", msg.message); } static void handle_event(struct state *state, const struct tomsg_event event) { diff --git a/ssh/tomsg_clientlib.c b/ssh/tomsg_clientlib.c index c14d5c5..05ee09d 100644 --- a/ssh/tomsg_clientlib.c +++ b/ssh/tomsg_clientlib.c @@ -178,7 +178,7 @@ const char* tomsg_strerror(enum tomsg_retval code) { static enum tomsg_retval version_negotiation(struct tomsg_client *client) { if (!client->conn) return TOMSG_ERR_CLOSED; - const enum sshnc_retval retssh = sshnc_send(client->conn, "ver version 1\n", 14); + const enum sshnc_retval retssh = sshnc_send(client->conn, "ver version 2\n", 14); if (retssh == SSHNC_EOF) return TOMSG_ERR_CLOSED; if (retssh != SSHNC_OK) return TOMSG_ERR_TRANSPORT; @@ -691,6 +691,7 @@ static enum tomsg_retval handle_line( PARSE_WORD(push_message.message.username); PARSE_I64(push_message.message.timestamp); PARSE_I64(push_message.message.msgid); + PARSE_I64(push_message.message.replyid); PARSE_RESTSTRING(push_message.message.message); return TOMSG_OK; } else if (sv_equals(command, "online")) { @@ -822,11 +823,12 @@ static enum tomsg_retval handle_line( // (and everywhere): the messages buffer has been allocated with // calloc(), so tomsg_event_nullify() will cleanup up precisely // everything that we haven't filled in yet. - struct history_message *msg = &inflight.event.history.messages[index];; + struct history_message *msg = &inflight.event.history.messages[index]; if (!sv_equals(sv_tokenise_word(&line), inflight.event.history.room_name)) CLEANUP_RETURN(TOMSG_ERR_PARSE); if (!sv_copy(sv_tokenise_word(&line), &msg->username)) CLEANUP_RETURN(TOMSG_ERR_PARSE); if (!sv_parse_i64(sv_tokenise_word(&line), &msg->timestamp)) CLEANUP_RETURN(TOMSG_ERR_PARSE); if (!sv_parse_i64(sv_tokenise_word(&line), &msg->msgid)) CLEANUP_RETURN(TOMSG_ERR_PARSE); + if (!sv_parse_i64(sv_tokenise_word(&line), &msg->replyid)) CLEANUP_RETURN(TOMSG_ERR_PARSE); if (!sv_copy(line, &msg->message)) CLEANUP_RETURN(TOMSG_ERR_PARSE); // If there are more history_message events coming, re-add the tag for them @@ -1018,13 +1020,15 @@ enum tomsg_retval tomsg_invite( enum tomsg_retval tomsg_send( struct tomsg_client *client, const char *room_name, const char *message, + int64_t replyid, int64_t *tagp //output ) { if (!client->conn) return TOMSG_ERR_CLOSED; if (hasspacelf(room_name)) return TOMSG_ERR_SPACE; if (haslf(message)) return TOMSG_ERR_SPACE; const int64_t tag = client->next_tag++; - SEND_FMT(client, tag, "send %s %s", room_name, message); + if (replyid < 0) replyid = -1; + SEND_FMT(client, tag, "send %s %" PRIi64 " %s", room_name, replyid, message); const struct tomsg_event event = (struct tomsg_event){ .type = TOMSG_EV_SEND, .send.tag = tag, diff --git a/ssh/tomsg_clientlib.h b/ssh/tomsg_clientlib.h index ab1bde5..b164eb3 100644 --- a/ssh/tomsg_clientlib.h +++ b/ssh/tomsg_clientlib.h @@ -139,6 +139,7 @@ struct history_message { char *username; int64_t timestamp; int64_t msgid; + int64_t replyid; // -1 if normal message, the replied-to message id otherwise char *message; }; @@ -245,8 +246,12 @@ enum tomsg_retval tomsg_invite( // If 'tag' is not NULL, will write the message request tag to the referenced // location. This tag will also be given in the TOMSG_EV_SEND response, so that // the response can be linked to the original message. +// If 'replyid' is -1, will send a normal message. If not, it must be the id of +// an earlier message in the same room, and this will send a reply to the +// indicated message. enum tomsg_retval tomsg_send( struct tomsg_client *client, const char *room_name, const char *message, + int64_t replyid, int64_t *tag // output ); -- cgit v1.2.3-70-g09d2 From 2ec25e126f54ba1e12c5b98a7d345f18fc52e898 Mon Sep 17 00:00:00 2001 From: Tom Smeding Date: Wed, 29 Jul 2020 10:33:53 +0200 Subject: clientlib: Support get_message --- ssh/client.c | 16 ++++++++++++++++ ssh/tomsg_clientlib.c | 26 ++++++++++++++++++++++++++ ssh/tomsg_clientlib.h | 8 ++++++++ 3 files changed, 50 insertions(+) (limited to 'ssh') diff --git a/ssh/client.c b/ssh/client.c index ad0f107..a262d6f 100644 --- a/ssh/client.c +++ b/ssh/client.c @@ -285,6 +285,14 @@ static bool handle_line( ret = tomsg_history(client, args[0], count, msgid); } + } else if (sv_equals(command, "get") || + sv_equals(command, "get_message")) { + int64_t msgid; + if (parse_args(line, args, num_args = 1, false) && + parse_i64(args[0], &msgid)) { + ret = tomsg_get_message(client, msgid); + } + } else if (sv_equals(command, "on") || sv_equals(command, "is_online")) { if (parse_args(line, args, num_args = 1, false)) { @@ -326,6 +334,7 @@ static bool handle_line( " ping\n" " hist/history \n" " histb/history_before \n" + " get/get_message \n" " on/is_online \n" " act/user_active \n" " help\n" @@ -361,6 +370,7 @@ static const char* event_type_descr(enum tomsg_event_type type) { case TOMSG_EV_INVITE: return "invite"; case TOMSG_EV_SEND: return "send"; case TOMSG_EV_HISTORY: return "history"; + case TOMSG_EV_GET_MESSAGE: return "get_message"; case TOMSG_EV_PING: return "ping"; case TOMSG_EV_IS_ONLINE: return "is_online"; case TOMSG_EV_USER_ACTIVE: return "user_active"; @@ -451,6 +461,12 @@ static void handle_event(struct state *state, const struct tomsg_event event) { } break; + case TOMSG_EV_GET_MESSAGE: + printf(" %" PRIi64 " is in room %s:\n ", + event.get_message.message.msgid, event.get_message.room_name); + print_history_message(event.get_message.message); + break; + case TOMSG_EV_PING: printf(" Pong\n"); break; diff --git a/ssh/tomsg_clientlib.c b/ssh/tomsg_clientlib.c index 05ee09d..adcb4ee 100644 --- a/ssh/tomsg_clientlib.c +++ b/ssh/tomsg_clientlib.c @@ -635,6 +635,11 @@ void tomsg_event_nullify(struct tomsg_event event) { free(event.history.messages); break; + case TOMSG_EV_GET_MESSAGE: + free(event.get_message.room_name); + history_message_nullify(event.get_message.message); + break; + case TOMSG_EV_PUSH_MESSAGE: free(event.push_message.room_name); history_message_nullify(event.push_message.message); @@ -843,6 +848,16 @@ static enum tomsg_retval handle_line( CLEANUP_RETURN(TOMSG_ERR_PARSE); } + case TOMSG_EV_GET_MESSAGE: + if (!sv_equals(command, "message")) CLEANUP_RETURN(TOMSG_ERR_PARSE); + if (!sv_copy(sv_tokenise_word(&line), &inflight.event.get_message.room_name)) CLEANUP_RETURN(TOMSG_ERR_PARSE); + if (!sv_copy(sv_tokenise_word(&line), &inflight.event.get_message.message.username)) CLEANUP_RETURN(TOMSG_ERR_PARSE); + if (!sv_parse_i64(sv_tokenise_word(&line), &inflight.event.get_message.message.timestamp)) CLEANUP_RETURN(TOMSG_ERR_PARSE); + if (!sv_parse_i64(sv_tokenise_word(&line), &inflight.event.get_message.message.msgid)) CLEANUP_RETURN(TOMSG_ERR_PARSE); + if (!sv_parse_i64(sv_tokenise_word(&line), &inflight.event.get_message.message.replyid)) CLEANUP_RETURN(TOMSG_ERR_PARSE); + if (!sv_copy(line, &inflight.event.get_message.message.message)) CLEANUP_RETURN(TOMSG_ERR_PARSE); + SUCCESS_RETURN(); + case TOMSG_EV_PING: if (!sv_equals(command, "pong")) CLEANUP_RETURN(TOMSG_ERR_PARSE); if (!sv_is_empty(line)) CLEANUP_RETURN(TOMSG_ERR_PARSE); @@ -1059,6 +1074,17 @@ enum tomsg_retval tomsg_history( return add_inflight(client, tag, event); } +enum tomsg_retval tomsg_get_message(struct tomsg_client *client, int64_t msgid) { + if (!client->conn) return TOMSG_ERR_CLOSED; + if (msgid < -1) msgid = -1; + const int64_t tag = client->next_tag++; + const struct tomsg_event event = (struct tomsg_event){ + .type = TOMSG_EV_GET_MESSAGE, + }; + SEND_FMT(client, tag, "get_message %" PRIi64, msgid); + return add_inflight(client, tag, event); +} + enum tomsg_retval tomsg_ping(struct tomsg_client *client) { if (!client->conn) return TOMSG_ERR_CLOSED; const int64_t tag = client->next_tag++; diff --git a/ssh/tomsg_clientlib.h b/ssh/tomsg_clientlib.h index b164eb3..8a4aae4 100644 --- a/ssh/tomsg_clientlib.h +++ b/ssh/tomsg_clientlib.h @@ -126,6 +126,7 @@ enum tomsg_event_type { TOMSG_EV_INVITE, // join TOMSG_EV_SEND, // send TOMSG_EV_HISTORY, // history + TOMSG_EV_GET_MESSAGE, // get_message TOMSG_EV_PING, // - TOMSG_EV_IS_ONLINE, // is_online TOMSG_EV_USER_ACTIVE, // user_active @@ -180,6 +181,10 @@ struct tomsg_event { int64_t count; struct history_message *messages; } history; + struct { + char *room_name; + struct history_message message; + } get_message; struct { char *username; int64_t online_count; @@ -262,6 +267,9 @@ enum tomsg_retval tomsg_history( struct tomsg_client *client, const char *room_name, int64_t count, int64_t before_msgid); +// Send a get_message command to the server. +enum tomsg_retval tomsg_get_message(struct tomsg_client *client, int64_t msgid); + // Send a ping command to the server. enum tomsg_retval tomsg_ping(struct tomsg_client *client); -- cgit v1.2.3-70-g09d2 From 0d07fa5da9f4c287410ce68d9d89da5c436fcc68 Mon Sep 17 00:00:00 2001 From: Tom Smeding Date: Wed, 29 Jul 2020 17:09:53 +0200 Subject: clientlib: Fix behaviour for zero history --- ssh/tomsg_clientlib.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'ssh') diff --git a/ssh/tomsg_clientlib.c b/ssh/tomsg_clientlib.c index adcb4ee..e6d3684 100644 --- a/ssh/tomsg_clientlib.c +++ b/ssh/tomsg_clientlib.c @@ -815,6 +815,11 @@ static enum tomsg_retval handle_line( inflight.event.history.messages = calloc(count, sizeof(struct history_message)); if (!inflight.event.history.messages) CLEANUP_RETURN(TOMSG_ERR_MEMORY); + // If there are no history_message's coming, complete early + if (count == 0) { + SUCCESS_RETURN(); + } + // Re-add the tag for the history_message events enum tomsg_retval ret = add_inflight(client, tag, inflight.event); if (ret != TOMSG_OK) return ret; -- cgit v1.2.3-70-g09d2