aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Smeding <tom.smeding@gmail.com>2020-07-30 20:43:25 +0200
committerTom Smeding <tom.smeding@gmail.com>2020-07-30 20:43:42 +0200
commit79c8ffd915115728070339f30d57a3a3e31bd322 (patch)
tree4d31a49204fb5716824a8a659c2e1d67cac8eaa3
parentb12ea9fb05e636213b35d46ddaec3e255e1a6992 (diff)
weechat: WIP replies and protocol version 2, is at least compatible
-rw-r--r--weechat/tomsg.c165
1 files changed, 156 insertions, 9 deletions
diff --git a/weechat/tomsg.c b/weechat/tomsg.c
index e008104..df6e067 100644
--- a/weechat/tomsg.c
+++ b/weechat/tomsg.c
@@ -50,12 +50,20 @@ struct conndata{
i64 linebuf_sz,linebuf_len;
char *linebuf;
+
+ // struct t_hashtable *msgtable; // msgid -> msgdata
};
+// struct msgdata{
+// char *username;
+// char *message;
+// };
+
static struct t_weechat_plugin *weechat_plugin;
-static struct t_hashtable *conntable;
+static struct t_hashtable *conntable; // fd -> conndata
+static struct t_hashtable *roomtable; // roomname -> roomdata
static void display_message(
@@ -158,7 +166,7 @@ static void close_room(struct roomdata *room){
}
static void message_net_callback(int fd,struct net_response res,void *payload){
- (void)payload;
+ // struct msgdata *msgdata=(struct msgdata*)payload;
debugf("message_net_callback(fd=%d,res={.type=%d})\n",fd,res.type);
struct conndata *conn=weechat_hashtable_get(conntable,&fd);
assert(conn);
@@ -186,7 +194,12 @@ static int room_input_cb(const void *room_vp,void *_d,struct t_gui_buffer *buffe
tosend=input+skipfirst;
}
- net_sendf(conn->fd,message_net_callback,NULL,"send %s %s",room->name,tosend);
+ // struct msgdata *msgdata=malloc(sizeof(msgdata));
+ // msgdata->username=strdup(conn->username);
+ // msgdata->message=strdup(tosend);
+ void *msgdata=NULL;
+
+ net_sendf(conn->fd,message_net_callback,msgdata,"send %s -1 %s",room->name,tosend);
weechat_printf(room->buffer,"%s\t%s",conn->username,tosend);
if(free_tosend){
@@ -206,6 +219,9 @@ static void create_room_buffer(struct roomdata *room){
if(room->buffer!=NULL){
weechat_buffer_close(room->buffer);
}
+
+ weechat_hashtable_set(roomtable,room->name,room);
+
room->buffer=
weechat_buffer_new(room->name, room_input_cb,room,NULL, room_close_cb,room,NULL);
weechat_buffer_set(room->buffer,"nicklist","1");
@@ -335,6 +351,11 @@ static void push_net_callback(int fd,struct net_response res,void *payload){
} else {
display_message(room,res.timestamp,res.username,res.message,res.msgid,false);
}
+
+ // struct msgdata *msgdata=malloc(sizeof(msgdata));
+ // msgdata->username=strdup(res.username);
+ // msgdata->message=strdup(res.message);
+ // weechat_hashtable_set(conn->msgtable,(void*)res.msgid,msgdata);
} else if(res.type==NET_JOIN){
weechat_printf(room->buffer,"%sUser %s joined this room",netpfx,res.username);
if(room->buffer_nickgroup){
@@ -438,7 +459,17 @@ static void pong_net_callback(int fd,struct net_response res,void *payload){
static void conn_destroy(struct conndata *conn){
debugf("conn_destroy(conn=%p (fd=%d))\n",conn,conn->fd);
weechat_unhook(conn->fd_hook);
+
if(conntable)weechat_hashtable_remove(conntable,&conn->fd);
+ if(roomtable){
+ for(int i=0;i<conn->nrooms;i++){
+ weechat_hashtable_remove(roomtable,conn->rooms[i]->name);
+ }
+ }
+
+ // TODO: free all items in the hashtable
+ // weechat_hashtable_free(conn->msgtable);
+
for(int i=0;i<conn->nrooms;i++){
close_room(conn->rooms[i]);
}
@@ -573,8 +604,10 @@ static char* password_hide_modifier(const void *_p,void *_d,const char *modifier
static int conn_close_cb(const void *conn_vp,void *_d,struct t_gui_buffer *buffer){
(void)_d; (void)buffer;
struct conndata *conn=(struct conndata*)conn_vp;
- debugf("conn_close_cb(conn=%p,buffer=%p) fd=%d\n",conn,buffer,conn->fd);
- conn_destroy(conn);
+ if(conn){
+ debugf("conn_close_cb(conn=%p,buffer=%p) fd=%d\n",conn,buffer,conn->fd);
+ conn_destroy(conn);
+ }
return WEECHAT_RC_OK;
}
@@ -612,6 +645,9 @@ static int connect_cb(const void *_p,void *hostname,int status,int _g,int fd,con
conn->linebuf_len=0;
conn->linebuf=malloc(conn->linebuf_sz);
assert(conn->linebuf);
+ // conn->msgtable=weechat_hashtable_new(
+ // 4096, WEECHAT_HASHTABLE_INTEGER, WEECHAT_HASHTABLE_POINTER, NULL, NULL);
+ // assert(conn->msgtable);
weechat_printf(conn->buffer,"Connected!");
@@ -628,8 +664,10 @@ static int connect_cb(const void *_p,void *hostname,int status,int _g,int fd,con
}
}
-static int cmd_tomsg_cb(const void *_p,void *_d,struct t_gui_buffer *buffer,int argc,char **argv,char **_a){
- (void)_p; (void)_d; (void)_a;
+static int cmd_tomsg_cb(
+ const void *_p,void *_d,struct t_gui_buffer *buffer,
+ int argc,char **argv,char **argv_eol){
+ (void)_p; (void)_d;
if(argc<2){
weechat_printf(buffer,"%stomsg: Invalid number of arguments to /tomsg",errpfx);
return WEECHAT_RC_ERROR;
@@ -665,6 +703,50 @@ static int cmd_tomsg_cb(const void *_p,void *_d,struct t_gui_buffer *buffer,int
NULL,NULL,0,NULL,
NULL,
connect_cb,NULL,hostname_copy);
+ } else if(strcmp(argv[1],"reply")==0){
+ if(argc<4){
+ weechat_printf(buffer,"%stomsg: Invalid number of arguments to /tomsg reply",errpfx);
+ return WEECHAT_RC_ERROR;
+ }
+
+ char *endp;
+ int64_t msgid=strtol(argv[2],&endp,10);
+ if(*argv[2]=='\0'||*endp!='\0'){
+ weechat_printf(NULL,"%stomsg: Invalid msgid argument to /tomsg reply",errpfx);
+ return WEECHAT_RC_ERROR;
+ }
+
+ const char *buffername=weechat_buffer_get_string(buffer,"full_name");
+ debugf("tomsg reply: buffername=<%s>\n",buffername);
+ const char *prefix="tomsg.";
+ size_t prefixlen=strlen(prefix);
+ if(strlen(buffername)>prefixlen&&
+ memcmp(buffername,prefix,prefixlen)==0){
+ struct roomdata *room=
+ weechat_hashtable_get(roomtable,buffername+prefixlen);
+ if(!room){
+ weechat_printf(NULL,"%stomsg: Cannot locate internal room data!",errpfx);
+ return WEECHAT_RC_ERROR;
+ }
+
+ const char *message_body=argv_eol[3];
+
+ // struct msgdata *msgdata=malloc(sizeof(struct msgdata));
+ // msgdata->username=strdup(room->conn->username);
+ // msgdata->message=strdup(message_body);
+ void *msgdata=NULL;
+
+ int fd=room->conn->fd;
+ net_sendf(fd,message_net_callback,msgdata,"send %s %" PRIi64 " %s",room->name,msgid,message_body);
+
+ // TODO: fix this
+ weechat_printf(room->buffer,"%s\t%s> ...",
+ room->conn->username,weechat_color("green"));
+ weechat_printf(room->buffer,"\t%s",message_body);
+ } else {
+ weechat_printf(NULL,"%stomsg: /tomsg reply on a non-tomsg buffer",errpfx);
+ return WEECHAT_RC_ERROR;
+ }
} else {
weechat_printf(buffer,"%stomsg: Unknown command \"%s\" to /tomsg",errpfx,argv[1]);
return WEECHAT_RC_ERROR;
@@ -673,6 +755,62 @@ static int cmd_tomsg_cb(const void *_p,void *_d,struct t_gui_buffer *buffer,int
return WEECHAT_RC_OK;
}
+static void bind_key_easy(const char *context, const char *key, const char *value) {
+ struct t_hashtable *ht = weechat_hashtable_new(
+ 1, WEECHAT_HASHTABLE_STRING, WEECHAT_HASHTABLE_STRING, NULL, NULL);
+ weechat_hashtable_set(ht, key, value);
+ weechat_key_bind(context, ht);
+ weechat_hashtable_free(ht);
+}
+
+static int cursor_reply_signal_cb(
+ const void *pointer_, void *data_,
+ const char *signal, struct t_hashtable *hashtable
+) {
+ (void)pointer_; (void)data_; (void)signal;
+
+ const char *tags = weechat_hashtable_get(hashtable, "_chat_line_tags");
+ weechat_command(NULL, "/cursor stop");
+
+ int64_t msgid = -1;
+ while (*tags) {
+ const char *ptr = strchr(tags, ',');
+ if (ptr - tags > (ptrdiff_t)strlen("tomsgid_")) {
+ char *endp;
+ msgid = strtoll(tags + 8, &endp, 10);
+ if ((ptr == NULL && *endp == '\0') || endp == ptr) {
+ break;
+ }
+ msgid = -1;
+ }
+ }
+
+ if (msgid == -1) return WEECHAT_RC_OK;
+
+ const char *buffer_name = weechat_hashtable_get(hashtable, "_buffer_full_name");
+ struct t_gui_buffer *bufptr = weechat_buffer_search("==", buffer_name);
+
+ const char *current_input = weechat_buffer_get_string(bufptr, "input");
+ int input_pos = weechat_buffer_get_integer(bufptr, "input_pos");
+
+ size_t new_input_capacity = 64 + strlen(current_input) + 1;
+ char *new_input = malloc(new_input_capacity);
+ assert(new_input);
+ int total_length = snprintf(
+ new_input, new_input_capacity, "/tomsg reply %" PRIi64 " %s",
+ msgid, current_input);
+ int prefix_length = total_length - strlen(current_input);
+
+ weechat_buffer_set(bufptr, "input", new_input);
+ free(new_input);
+
+ char posbuf[64];
+ snprintf(posbuf, sizeof posbuf, "%d", prefix_length + input_pos);
+ weechat_buffer_set(bufptr, "input_pos", posbuf);
+
+ return WEECHAT_RC_OK;
+}
+
int weechat_plugin_init(struct t_weechat_plugin *plugin,int argc,char **argv){
(void)argc; (void)argv;
weechat_plugin = plugin;
@@ -685,18 +823,25 @@ int weechat_plugin_init(struct t_weechat_plugin *plugin,int argc,char **argv){
weechat_hook_command(
"tomsg",
"Execute commands related to tomsg.",
- "connect <hostname> [port]",
- " connect: Connect to a tomsg server",
+ "connect <hostname> [port] | "
+ "reply <msgid> <your reply...>",
+ " connect: Connect to a tomsg server\n"
+ " reply: Reply to a message in a tomsg buffer. Tip: use middleclick-R.",
NULL,
cmd_tomsg_cb,NULL,NULL);
weechat_hook_modifier("input_text_display_with_cursor",password_hide_modifier,NULL,NULL);
+ weechat_hook_hsignal("tomsg_cursor_reply", cursor_reply_signal_cb, NULL, NULL);
+ bind_key_easy("cursor","@chat(tomsg.*):r","hsignal:tomsg_cursor_reply");
+
net_set_push_callback(push_net_callback);
net_set_history_callback(history_push_net_callback);
conntable=weechat_hashtable_new(
16,WEECHAT_HASHTABLE_INTEGER,WEECHAT_HASHTABLE_POINTER,NULL,NULL);
+ roomtable=weechat_hashtable_new(
+ 16,WEECHAT_HASHTABLE_STRING,WEECHAT_HASHTABLE_POINTER,NULL,NULL);
return WEECHAT_RC_OK;
}
@@ -704,7 +849,9 @@ int weechat_plugin_init(struct t_weechat_plugin *plugin,int argc,char **argv){
int weechat_plugin_end(struct t_weechat_plugin *plugin){
(void)plugin;
weechat_hashtable_free(conntable);
+ weechat_hashtable_free(roomtable);
conntable=NULL;
+ roomtable=NULL;
debug_deinit();
return WEECHAT_RC_OK;
}