diff --git a/src/core/commands.c b/src/core/commands.c index 88dcc31..0830cb2 100644 --- a/src/core/commands.c +++ b/src/core/commands.c @@ -360,6 +360,47 @@ static int command_broadcast(struct hub_info* hub, struct hub_user* user, struct return 0; } +static int command_history(struct hub_info* hub, struct hub_user* user, struct hub_command* cmd) +{ + char* buffer; + struct linked_list* messages = hub->chat_history; + char* message = 0; + int ret = (int) list_size(messages); + size_t bufsize; + + if (!ret) + { + return command_status(hub, user, cmd, "No messages."); + } + + char tmp[128]; + snprintf(tmp, 128, "Found %d message%s:", (int) ret, ((ret != 1) ? "s" : "")); + bufsize = strlen(tmp); + message = (char*) list_get_first(messages); + while (message) + { + bufsize += strlen(message); + message = (char*) list_get_next(messages); + } + + buffer = hub_malloc(bufsize+4); + buffer[0] = 0; + strcat(buffer, tmp); + strcat(buffer, "\n"); + + message = (char*) list_get_first(messages); + while (message) + { + strcat(buffer, message); + message = (char*) list_get_next(messages); + } + strcat(buffer, "\n"); + + ret = command_status(hub, user, cmd, buffer); + hub_free(buffer); + return ret; +} + #ifdef CRASH_DEBUG static int command_crash(struct hub_info* hub, struct hub_user* user, struct hub_command* cmd) { @@ -417,6 +458,7 @@ static struct commands_handler command_handlers[] = { { "help", 4, 0, cred_guest, command_help, "Show this help message." }, { "stats", 5, 0, cred_super, command_stats, "Show hub statistics." }, { "version", 7, 0, cred_guest, command_version, "Show hub version info." }, + { "history", 7, 0, cred_guest, command_history, "Show hub version info." }, { "uptime", 6, 0, cred_guest, command_uptime, "Display hub uptime info." }, { "kick", 4, "n", cred_operator, command_kick, "Kick a user" }, { "ban", 3, "n", cred_operator, command_ban, "Ban a user" }, diff --git a/src/core/commands.h b/src/core/commands.h index 116f436..aa0809d 100644 --- a/src/core/commands.h +++ b/src/core/commands.h @@ -19,17 +19,4 @@ #include "uhub.h" -#define CHAT_MSG_HANDLED 1 -#define CHAT_MSG_IGNORED 0 -#define CHAT_MSG_INVALID -1 - -typedef int (*plugin_event_chat_message)(struct hub_info*, struct hub_user*, struct adc_message*); - -struct command_info -{ - const char* prefix; - enum user_credentials cred; - plugin_event_chat_message function; -}; - -int command_dipatcher(struct hub_info* hub, struct hub_user* user, const char* message); +extern int command_dipatcher(struct hub_info* hub, struct hub_user* user, const char* message); diff --git a/src/core/config.c b/src/core/config.c index 126f479..f720246 100644 --- a/src/core/config.c +++ b/src/core/config.c @@ -116,6 +116,7 @@ #define DEF_FILE_ACL "" #define DEF_FILE_MOTD "" #define DEF_MAX_USERS 500 +#define DEF_MAX_CHAT_HISTORY 20 #define DEF_MAX_RECV_BUFFER 4096 #define DEF_MAX_SEND_BUFFER 131072 #define DEF_MAX_SEND_BUFFER_SOFT 98304 @@ -175,6 +176,7 @@ void config_defaults(struct hub_config* config) DEFAULT_STRING (file_motd, DEF_FILE_MOTD); DEFAULT_INTEGER(server_port, DEF_SERVER_PORT); DEFAULT_INTEGER(max_users, DEF_MAX_USERS); + DEFAULT_INTEGER(max_chat_history, DEF_MAX_CHAT_HISTORY); DEFAULT_INTEGER(max_recv_buffer, DEF_MAX_RECV_BUFFER); DEFAULT_INTEGER(max_send_buffer, DEF_MAX_SEND_BUFFER); DEFAULT_INTEGER(max_send_buffer_soft, DEF_MAX_SEND_BUFFER_SOFT); @@ -245,6 +247,7 @@ static int apply_config(struct hub_config* config, char* key, char* data, int li GET_STR (hub_description); GET_BOOL(hub_enabled); GET_INT (max_users); + GET_INT (max_chat_history); GET_INT (max_recv_buffer); GET_INT (max_send_buffer); GET_INT (max_send_buffer_soft); @@ -391,6 +394,7 @@ void dump_config(struct hub_config* config, int ignore_defaults) DUMP_STR (hub_description, DEF_HUB_DESCRIPTION); DUMP_BOOL(hub_enabled, DEF_HUB_ENABLED); DUMP_INT (max_users, DEF_MAX_USERS); + DUMP_INT (max_chat_history, DEF_MAX_CHAT_HISTORY); DUMP_INT (max_recv_buffer, DEF_MAX_RECV_BUFFER); DUMP_INT (max_send_buffer, DEF_MAX_SEND_BUFFER); DUMP_INT (max_send_buffer_soft, DEF_MAX_SEND_BUFFER_SOFT); diff --git a/src/core/config.h b/src/core/config.h index d9a9659..f909bc0 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -38,7 +38,9 @@ struct hub_config int max_send_buffer; /**<<< "Max send buffer before disconnect, per user (default: 128K)" */ int max_send_buffer_soft; /**<<< "Max send buffer before message drops, per user (default: 96K)" */ int low_bandwidth_mode; /**<<< "If this is enabled, the hub will strip off elements from each user's info message to reduce bandwidth usage" */ - + + int max_chat_history; /**<<< "Number of chat messages kept in history (default: 20)" */ + /* Limits enforced on users */ int limit_max_hubs_user; /**<<< "Max concurrent hubs as a user. (0=off, default: 10)" */ int limit_max_hubs_reg; /**<<< "Max concurrent hubs as registered user. (0=off, default: 10)" */ @@ -51,7 +53,7 @@ struct hub_config int limit_max_share; /**<<< "Limit maximum share size in megabytes (MiB) (0=off, default: 0)" */ int limit_min_slots; /**<<< "Limit minimum number of slots open per user (0=off, default: 0)" */ int limit_max_slots; /**<<< "Limit maximum number of slots open per user (0=off, default: 0)" */ - + /* Messages that can be sent to a user */ char* msg_hub_full; /**<<< "hub is full" */ char* msg_hub_disabled; /**<<< "hub is disabled" */ diff --git a/src/core/hub.c b/src/core/hub.c index f013b0d..fe685ad 100644 --- a/src/core/hub.c +++ b/src/core/hub.c @@ -197,13 +197,36 @@ int hub_handle_chat_message(struct hub_info* hub, struct hub_user* u, struct adc if (relay && user_is_logged_in(u)) { /* adc_msg_remove_named_argument(cmd, "PM"); */ + hub_chat_history_add(hub, u, cmd); ret = route_message(hub, u, cmd); } - - free(message); + + hub_free(message); return ret; } +void hub_chat_history_add(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd) +{ + char* message = adc_msg_get_argument(cmd, 0); + char* log = hub_malloc(strlen(message) + strlen(user->id.nick) + 14); + time_t now = time(NULL); + struct tm* t = localtime(&now); + sprintf(log, "[%02d:%02d] <%s> %s\n", t->tm_hour, t->tm_min, user->id.nick, message); + list_append(hub->chat_history, log); + while (list_size(hub->chat_history) > (size_t) hub->config->max_chat_history) + { + char* msg = list_get_first(hub->chat_history); + list_remove(hub->chat_history, msg); + hub_free(msg); + } + hub_free(message); +} + +void hub_chat_history_clear(struct hub_info* hub) +{ + list_clear(hub->chat_history, &hub_free); +} + void hub_send_support(struct hub_info* hub, struct hub_user* u) { if (user_is_connecting(u) || user_is_logged_in(u)) @@ -526,6 +549,17 @@ struct hub_info* hub_start_service(struct hub_config* config) return 0; } + hub->chat_history = (struct linked_list*) list_create(); + if (!hub->chat_history) + { + hub_free(hub->recvbuf); + hub_free(hub->sendbuf); + uman_shutdown(hub); + hub_free(hub); + net_close(server_tcp); + return 0; + } + hub->status = hub_status_running; g_hub = hub; @@ -545,6 +579,8 @@ void hub_shutdown_service(struct hub_info* hub) event_base_free(hub->evbase); hub_free(hub->sendbuf); hub_free(hub->recvbuf); + hub_chat_history_clear(hub); + list_destroy(hub->chat_history); hub_free(hub); hub = 0; g_hub = 0; diff --git a/src/core/hub.h b/src/core/hub.h index 846e84d..51fd74d 100644 --- a/src/core/hub.h +++ b/src/core/hub.h @@ -98,7 +98,9 @@ struct hub_info int status; char* recvbuf; /* Global receive buffer */ char* sendbuf; /* Global send buffer */ - + + struct linked_list* chat_history; /* Chat history */ + #ifdef SSL_SUPPORT SSL_METHOD* ssl_method; SSL_CTX* ssl_ctx; @@ -135,6 +137,16 @@ extern int hub_handle_password(struct hub_info* hub, struct hub_user* u, struct */ extern int hub_handle_chat_message(struct hub_info* hub, struct hub_user* u, struct adc_message* cmd); +/** + * Add a chat message to the chat history + */ +extern void hub_chat_history_add(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd); + +/** + * Clear the chat history. + */ +extern void hub_chat_history_clear(struct hub_info* hub); + /** * Used internally by hub_handle_info * @return 1 if nickname is OK, or 0 if nickname is not accepted.