diff options
-rw-r--r-- | src/core/chat-commands.c | 19 | ||||
-rw-r--r-- | src/fe-common/core/fe-server.c | 46 | ||||
-rw-r--r-- | src/fe-text/gui-printtext.c | 12 | ||||
-rw-r--r-- | src/fe-text/gui-printtext.h | 2 | ||||
-rw-r--r-- | src/fe-text/textbuffer-reformat.c | 6 | ||||
-rw-r--r-- | src/irc/core/irc-commands.c | 32 | ||||
-rw-r--r-- | src/irc/core/irc-servers.c | 37 | ||||
-rw-r--r-- | src/irc/core/irc-servers.h | 3 |
8 files changed, 127 insertions, 30 deletions
diff --git a/src/core/chat-commands.c b/src/core/chat-commands.c index 02ce45bf..6ddd2f1a 100644 --- a/src/core/chat-commands.c +++ b/src/core/chat-commands.c @@ -175,9 +175,20 @@ static void update_reconnection(SERVER_CONNECT_REC *conn, SERVER_REC *server) } } +static void cmd_server(const char *data, SERVER_REC *server, WI_ITEM_REC *item) +{ + command_runsub("server", data, server, item); +} + +static void sig_default_command_server(const char *data, SERVER_REC *server, + WI_ITEM_REC *item) +{ + signal_emit("command server connect", 3, data, server, item); +} + /* SYNTAX: SERVER [-4 | -6] [-ircnet <ircnet>] [-host <hostname>] [+]<address>|<chatnet> [<port> [<password> [<nick>]]] */ -static void cmd_server(const char *data, SERVER_REC *server) +static void cmd_server_connect(const char *data, SERVER_REC *server) { SERVER_CONNECT_REC *conn; int plus_addr; @@ -366,6 +377,7 @@ void chat_commands_init(void) settings_add_str("misc", "quit_message", "leaving"); command_bind("server", NULL, (SIGNAL_FUNC) cmd_server); + command_bind("server connect", NULL, (SIGNAL_FUNC) cmd_server_connect); command_bind("connect", NULL, (SIGNAL_FUNC) cmd_connect); command_bind("disconnect", NULL, (SIGNAL_FUNC) cmd_disconnect); command_bind("quit", NULL, (SIGNAL_FUNC) cmd_quit); @@ -376,6 +388,8 @@ void chat_commands_init(void) command_bind("foreach channel", NULL, (SIGNAL_FUNC) cmd_foreach_channel); command_bind("foreach query", NULL, (SIGNAL_FUNC) cmd_foreach_query); + signal_add("default command server", (SIGNAL_FUNC) sig_default_command_server); + command_set_options("connect", "4 6 +host"); command_set_options("join", "invite"); } @@ -383,6 +397,7 @@ void chat_commands_init(void) void chat_commands_deinit(void) { command_unbind("server", (SIGNAL_FUNC) cmd_server); + command_unbind("server connect", (SIGNAL_FUNC) cmd_server_connect); command_unbind("connect", (SIGNAL_FUNC) cmd_connect); command_unbind("disconnect", (SIGNAL_FUNC) cmd_disconnect); command_unbind("quit", (SIGNAL_FUNC) cmd_quit); @@ -392,4 +407,6 @@ void chat_commands_deinit(void) command_unbind("foreach server", (SIGNAL_FUNC) cmd_foreach_server); command_unbind("foreach channel", (SIGNAL_FUNC) cmd_foreach_channel); command_unbind("foreach query", (SIGNAL_FUNC) cmd_foreach_query); + + signal_remove("default command server", (SIGNAL_FUNC) sig_default_command_server); } diff --git a/src/fe-common/core/fe-server.c b/src/fe-common/core/fe-server.c index 025c77d7..b50efd0a 100644 --- a/src/fe-common/core/fe-server.c +++ b/src/fe-common/core/fe-server.c @@ -189,36 +189,30 @@ static void cmd_server_remove(const char *data) cmd_params_free(free_arg); } -static void cmd_server(const char *data, SERVER_REC *server, void *item) +static void cmd_server(const char *data) { - GHashTable *optlist; - char *addr; - void *free_arg; - - if (*data == '\0') { - if (servers == NULL && lookup_servers == NULL && - reconnects == NULL) { - printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, - TXT_NO_CONNECTED_SERVERS); - } else { - print_servers(); - print_lookup_servers(); - print_reconnects(); - } - - signal_stop(); + if (*data != '\0') return; - } - if (g_strncasecmp(data, "add ", 4) == 0 || - g_strncasecmp(data, "remove ", 7) == 0 || - g_strcasecmp(data, "list") == 0 || - g_strncasecmp(data, "list ", 5) == 0) { - command_runsub("server", data, server, item); - signal_stop(); - return; + if (servers == NULL && lookup_servers == NULL && + reconnects == NULL) { + printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, + TXT_NO_CONNECTED_SERVERS); + } else { + print_servers(); + print_lookup_servers(); + print_reconnects(); } + signal_stop(); +} + +static void cmd_server_connect(const char *data) +{ + GHashTable *optlist; + char *addr; + void *free_arg; + if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_OPTIONS, "connect", &optlist, &addr)) return; @@ -324,6 +318,7 @@ static void sig_chat_protocol_unknown(const char *protocol) void fe_server_init(void) { command_bind("server", NULL, (SIGNAL_FUNC) cmd_server); + command_bind("server connect", NULL, (SIGNAL_FUNC) cmd_server_connect); command_bind("server add", NULL, (SIGNAL_FUNC) cmd_server_add); command_bind("server remove", NULL, (SIGNAL_FUNC) cmd_server_remove); command_set_options("server add", "4 6 auto noauto -host -port"); @@ -345,6 +340,7 @@ void fe_server_init(void) void fe_server_deinit(void) { command_unbind("server", (SIGNAL_FUNC) cmd_server); + command_unbind("server connect", (SIGNAL_FUNC) cmd_server_connect); command_unbind("server add", (SIGNAL_FUNC) cmd_server_add); command_unbind("server remove", (SIGNAL_FUNC) cmd_server_remove); diff --git a/src/fe-text/gui-printtext.c b/src/fe-text/gui-printtext.c index 9444fdf3..5d94d877 100644 --- a/src/fe-text/gui-printtext.c +++ b/src/fe-text/gui-printtext.c @@ -44,6 +44,18 @@ void gui_printtext(int xpos, int ypos, const char *str) next_xpos = next_ypos = -1; } +void gui_printtext_after(TEXT_DEST_REC *dest, LINE_REC *prev, const char *str) +{ + GUI_WINDOW_REC *gui; + + gui = WINDOW_GUI(dest->window); + + gui->use_insert_after = TRUE; + gui->insert_after = prev; + format_send_to_gui(dest, str); + gui->use_insert_after = FALSE; +} + static void remove_old_lines(TEXT_BUFFER_VIEW_REC *view) { LINE_REC *line; diff --git a/src/fe-text/gui-printtext.h b/src/fe-text/gui-printtext.h index 3b2098b7..44f2b44e 100644 --- a/src/fe-text/gui-printtext.h +++ b/src/fe-text/gui-printtext.h @@ -2,6 +2,7 @@ #define __GUI_PRINTTEXT_H #include "gui-windows.h" +#include "formats.h" extern int mirc_colors[]; @@ -9,5 +10,6 @@ void gui_printtext_init(void); void gui_printtext_deinit(void); void gui_printtext(int xpos, int ypos, const char *str); +void gui_printtext_after(TEXT_DEST_REC *dest, LINE_REC *prev, const char *str); #endif diff --git a/src/fe-text/textbuffer-reformat.c b/src/fe-text/textbuffer-reformat.c index 7e0d7b4f..d719c468 100644 --- a/src/fe-text/textbuffer-reformat.c +++ b/src/fe-text/textbuffer-reformat.c @@ -25,6 +25,7 @@ #include "formats.h" #include "gui-windows.h" +#include "gui-printtext.h" #include "textbuffer.h" static GString *format; @@ -187,10 +188,7 @@ void textbuffer_reformat_line(WINDOW_REC *window, LINE_REC *line) g_free(str); g_free(prestr); - gui->use_insert_after = TRUE; - gui->insert_after = line_prev; - format_send_to_gui(&dest, tmp); - gui->use_insert_after = FALSE; + gui_printtext_after(&dest, line_prev, tmp); g_free(tmp); line = textbuffer_insert(gui->view->buffer, gui->insert_after, diff --git a/src/irc/core/irc-commands.c b/src/irc/core/irc-commands.c index bbb2ee05..d3eefbbf 100644 --- a/src/irc/core/irc-commands.c +++ b/src/irc/core/irc-commands.c @@ -43,6 +43,13 @@ is required */ #define LIST_MAX_CHANNELS_PASS 1000 +/* When /PARTing a channel, if there's more messages in output queue + than this, purge the output for channel. The idea behind this is that + if you accidentally pasted some large text and /PART the channel, the + text won't be fully pasted. Note that this counter is the whole size + of the output queue, not channel specific.. */ +#define MAX_COMMANDS_ON_PART_UNTIL_PURGE 10 + typedef struct { IRC_CHANNEL_REC *channel; char *ban; @@ -132,6 +139,10 @@ static void cmd_part(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item if (*channame == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); if (*msg == '\0') msg = (char *) settings_get_str("part_message"); + + if (server->cmdcount > MAX_COMMANDS_ON_PART_UNTIL_PURGE) + irc_server_purge_output(server, channame); + irc_send_cmdv(server, *msg == '\0' ? "PART %s" : "PART %s :%s", channame, msg); @@ -833,6 +844,24 @@ static void cmd_knockout(const char *data, IRC_SERVER_REC *server, cmd_params_free(free_arg); } +/* SYNTAX: SERVER PURGE [<target>] */ +static void cmd_server_purge(const char *data, IRC_SERVER_REC *server) +{ + char *target; + void *free_arg; + + g_return_if_fail(data != NULL); + if (!IS_IRC_SERVER(server) || !server->connected) + cmd_return_error(CMDERR_NOT_CONNECTED); + + if (!cmd_get_params(data, &free_arg, 1, &target)) + return; + + irc_server_purge_output(server, *target == '\0' ? NULL : target); + + cmd_params_free(free_arg); +} + /* destroy all knockouts in server */ static void sig_server_disconnected(IRC_SERVER_REC *server) { @@ -1060,6 +1089,7 @@ void irc_commands_init(void) command_bind("wallchops", NULL, (SIGNAL_FUNC) command_2self); command_bind("kickban", NULL, (SIGNAL_FUNC) cmd_kickban); command_bind("knockout", NULL, (SIGNAL_FUNC) cmd_knockout); + command_bind("server purge", NULL, (SIGNAL_FUNC) cmd_server_purge); signal_add("channel destroyed", (SIGNAL_FUNC) sig_channel_destroyed); signal_add("server disconnected", (SIGNAL_FUNC) sig_server_disconnected); @@ -1131,6 +1161,8 @@ void irc_commands_deinit(void) command_unbind("wallchops", (SIGNAL_FUNC) command_2self); command_unbind("kickban", (SIGNAL_FUNC) cmd_kickban); command_unbind("knockout", (SIGNAL_FUNC) cmd_knockout); + command_unbind("server purge", (SIGNAL_FUNC) cmd_server_purge); + signal_remove("channel destroyed", (SIGNAL_FUNC) sig_channel_destroyed); signal_remove("server disconnected", (SIGNAL_FUNC) sig_server_disconnected); signal_remove("nickchange over", (SIGNAL_FUNC) sig_nickchange_over); diff --git a/src/irc/core/irc-servers.c b/src/irc/core/irc-servers.c index 0d07149f..11cef94d 100644 --- a/src/irc/core/irc-servers.c +++ b/src/irc/core/irc-servers.c @@ -187,6 +187,43 @@ IRC_SERVER_REC *irc_server_connect(IRC_SERVER_CONNECT_REC *conn) return server; } +/* Returns TRUE if `command' is sent to `target' */ +static int command_has_target(const char *cmd, const char *target) +{ + const char *p; + int len; + + /* just assume the command is in form "<command> <target> <data>" */ + p = strchr(cmd, ' '); + if (p == NULL) return FALSE; + p++; + + len = strlen(target); + return strncmp(p, target, len) == 0 && p[len] == ' '; +} + +/* Purge server output, either all or for specified target */ +void irc_server_purge_output(IRC_SERVER_REC *server, const char *target) +{ + GSList *tmp, *next; + char *cmd; + + if (target != NULL && *target == '\0') + target = NULL; + + for (tmp = server->cmdqueue; tmp != NULL; tmp = next) { + next = tmp->next; + cmd = tmp->data; + + if ((target == NULL || command_has_target(cmd, target)) && + g_strncasecmp(cmd, "PONG ", 5) != 0) { + server->cmdqueue = + g_slist_remove(server->cmdqueue, cmd); + server->cmdcount--; + } + } +} + static void sig_connected(IRC_SERVER_REC *server) { if (!IS_IRC_SERVER(server)) diff --git a/src/irc/core/irc-servers.h b/src/irc/core/irc-servers.h index e9d357ba..9a4f0ea8 100644 --- a/src/irc/core/irc-servers.h +++ b/src/irc/core/irc-servers.h @@ -91,6 +91,9 @@ typedef struct { IRC_SERVER_REC *irc_server_connect(IRC_SERVER_CONNECT_REC *conn); +/* Purge server output, either all or for specified target */ +void irc_server_purge_output(IRC_SERVER_REC *server, const char *target); + /* Return a string of all channels (and keys, if any have them) in server, like "#a,#b,#c,#d x,b_chan_key,x,x" or just "#e,#f,#g" */ char *irc_server_get_channels(IRC_SERVER_REC *server); |