From 59e5e8eeea577d9fc066ee11e50db4938a927b85 Mon Sep 17 00:00:00 2001 From: V V Date: Mon, 30 Nov 2015 12:24:59 +0300 Subject: [PATCH] added 'msg @username' command, fixed small bugs --- interface.c | 129 ++++++++++++++++++++++++++++++++++++++++++++++++++-- lua-tg.c | 6 +-- tgl | 2 +- 3 files changed, 128 insertions(+), 9 deletions(-) diff --git a/interface.c b/interface.c index 9a66de2..7ad3967 100644 --- a/interface.c +++ b/interface.c @@ -95,6 +95,19 @@ #include +#include "tgl/tree.h" + +struct username_peer_pair { + const char *username; + tgl_peer_t *peer; +}; + +#define username_peer_pair_cmp(a,b) strcmp (a->username, b->username) +DEFINE_TREE (username_peer_pair, struct username_peer_pair *, username_peer_pair_cmp, NULL) +struct tree_username_peer_pair *username_peer_pair; + +struct username_peer_pair *current_map; + #define ALLOW_MULT 1 char *default_prompt = "> "; @@ -478,6 +491,19 @@ tgl_peer_id_t parse_input_peer_id (const char *s, int l, int mask) { return res; } + if (*s == '@') { + s ++; + l --; + char *tmp = strndup (s, l); + struct username_peer_pair *p = tree_lookup_username_peer_pair (username_peer_pair, (void *)&tmp); + free (tmp); + if (p && (!mask || tgl_get_peer_type (p->peer->id) == mask)) { + return p->peer->id; + } else { + return TGL_PEER_NOT_FOUND; + } + } + const char *ss[] = {"user#id", "user#", "chat#id", "chat#", "secret_chat#id", "secret_chat#", "channel#id", "channel#"}; int tt[] = {TGL_PEER_USER, TGL_PEER_USER, TGL_PEER_CHAT, TGL_PEER_CHAT, TGL_PEER_ENCR_CHAT, TGL_PEER_ENCR_CHAT, TGL_PEER_CHANNEL, TGL_PEER_CHANNEL}; @@ -2050,6 +2076,44 @@ int complete_chat_command (tgl_peer_t *P, int index, const char *text, int len, } } +int complete_username (int mode, int index, const char *text, int len, char **R) { + *R = NULL; + if (len > 0 && *text == '@') { + text ++; + len --; + } + index ++; + while (index < TLS->peer_num) { + tgl_peer_t *P = TLS->Peers[index]; + if (mode && tgl_get_peer_type (P->id) != mode) { + index ++; + continue; + } + char *u = NULL; + if (tgl_get_peer_type (P->id) == TGL_PEER_USER) { + u = P->user.username; + } else if (tgl_get_peer_type (P->id) == TGL_PEER_CHANNEL) { + u = P->channel.username; + } + if (!u) { + index ++; + continue; + } + if ((int)strlen (u) < len || memcmp (u, text, len)) { + index ++; + continue; + } + *R = malloc (strlen (u) + 2); + *R[0] = '@'; + memcpy (*R + 1, u, strlen (u) + 1); + break; + } + if (index == TLS->peer_num) { + return -1; + } + return index; +} + char *command_generator (const char *text, int state) { #ifndef DISABLE_EXTF static int len; @@ -2094,11 +2158,19 @@ char *command_generator (const char *text, int state) { if (c) { rl_line_buffer[rl_point] = c; } return R; case ca_user: - index = tgl_complete_user_list (TLS, index, command_pos, command_len, &R); + if (command_len && command_pos[0] == '@') { + index = complete_username (TGL_PEER_USER, index, command_pos, command_len, &R); + } else { + index = tgl_complete_user_list (TLS, index, command_pos, command_len, &R); + } if (c) { rl_line_buffer[rl_point] = c; } return R; case ca_peer: - index = tgl_complete_peer_list (TLS, index, command_pos, command_len, &R); + if (command_len && command_pos[0] == '@') { + index = complete_username (0, index, command_pos, command_len, &R); + } else { + index = tgl_complete_peer_list (TLS, index, command_pos, command_len, &R); + } if (c) { rl_line_buffer[rl_point] = c; } return R; case ca_file_name: @@ -2115,7 +2187,11 @@ char *command_generator (const char *text, int state) { if (c) { rl_line_buffer[rl_point] = c; } return R; case ca_channel: - index = tgl_complete_channel_list (TLS, index, command_pos, command_len, &R); + if (command_len && command_pos[0] == '@') { + index = complete_username (TGL_PEER_CHANNEL, index, command_pos, command_len, &R); + } else { + index = tgl_complete_channel_list (TLS, index, command_pos, command_len, &R); + } if (c) { rl_line_buffer[rl_point] = c; } return R; case ca_modifier: @@ -3073,6 +3149,39 @@ void json_peer_update (struct in_ev *ev, tgl_peer_t *P, unsigned flags) { #endif } +void peer_update_username (tgl_peer_t *P, const char *username) { + if (!username) { + if (P->extra) { + struct username_peer_pair *p = tree_lookup_username_peer_pair (username_peer_pair, (void *)&P->extra); + assert (p); + username_peer_pair = tree_delete_username_peer_pair (username_peer_pair, p); + tfree_str (P->extra); + tfree (p, sizeof (*p)); + P->extra = NULL; + } + return; + } + assert (username); + if (P->extra && !strcmp (P->extra, username)) { + return; + } + if (P->extra) { + struct username_peer_pair *p = tree_lookup_username_peer_pair (username_peer_pair, (void *)&P->extra); + assert (p); + username_peer_pair = tree_delete_username_peer_pair (username_peer_pair, p); + tfree_str (P->extra); + tfree (p, sizeof (*p)); + P->extra = NULL; + } + + P->extra = tstrdup (username); + struct username_peer_pair *p = talloc (sizeof (*p)); + p->peer = P; + p->username = P->extra; + + username_peer_pair = tree_insert_username_peer_pair (username_peer_pair, p, rand ()); +} + void user_update_gw (struct tgl_state *TLSR, struct tgl_user *U, unsigned flags) { assert (TLSR == TLS); #ifdef USE_LUA @@ -3081,6 +3190,8 @@ void user_update_gw (struct tgl_state *TLSR, struct tgl_user *U, unsigned flags) #ifdef USE_PYTHON py_user_update (U, flags); #endif + + peer_update_username ((void *)U, U->username); if (disable_output && !notify_ev) { return; } if (!binlog_read) { return; } @@ -3149,8 +3260,6 @@ void secret_chat_update_gw (struct tgl_state *TLSR, struct tgl_secret_chat *U, u #ifdef USE_PYTHON py_secret_chat_update (U, flags); #endif - - if ((flags & TGL_UPDATE_WORKING) || (flags & TGL_UPDATE_DELETED)) { write_secret_chat_file (); @@ -3188,6 +3297,15 @@ void secret_chat_update_gw (struct tgl_state *TLSR, struct tgl_secret_chat *U, u } } +void channel_update_gw (struct tgl_state *TLSR, struct tgl_channel *U, unsigned flags) { + assert (TLSR == TLS); + + peer_update_username ((void *)U, U->username); + + if (disable_output && !notify_ev) { return; } + if (!binlog_read) { return; } +} + void print_card_gw (struct tgl_state *TLSR, void *extra, int success, int size, int *card) { assert (TLSR == TLS); struct in_ev *ev = extra; @@ -3295,6 +3413,7 @@ struct tgl_update_callback upd_cb = { .user_update = user_update_gw, .chat_update = chat_update_gw, .secret_chat_update = secret_chat_update_gw, + .channel_update = channel_update_gw, .msg_receive = print_message_gw, .our_id = our_id_gw, .user_status_update = user_status_upd, diff --git a/lua-tg.c b/lua-tg.c index 4746db0..3a54503 100644 --- a/lua-tg.c +++ b/lua-tg.c @@ -226,11 +226,11 @@ void push_update_types (unsigned flags) { void push_peer (tgl_peer_id_t id, tgl_peer_t *P) { lua_newtable (luaState); - lua_add_string_field ("id", print_permanent_peer_id (P->id)); + lua_add_string_field ("id", print_permanent_peer_id (P ? P->id : id)); lua_pushstring (luaState, "peer_type"); - push_tgl_peer_type (tgl_get_peer_type (P->id)); + push_tgl_peer_type (tgl_get_peer_type (id)); lua_settable (luaState, -3); - lua_add_num_field ("peer_id", tgl_get_peer_id (P->id)); + lua_add_num_field ("peer_id", tgl_get_peer_id (id)); if (!P || !(P->flags & TGLPF_CREATED)) { lua_pushstring (luaState, "print_name"); diff --git a/tgl b/tgl index bc86138..056613b 160000 --- a/tgl +++ b/tgl @@ -1 +1 @@ -Subproject commit bc8613899875589d7dd31e7f6de74cb5d4d4a8ae +Subproject commit 056613be03b8faf8be8248c2e0fc04050bf9d3ae