Added a chat history plugin.
The mod_chat_history plugin provides chat history for all public chat messages. Can be configured in the following ways: - history_max: max number of messages stored in history - history_default: the default number of messages to be returned when invoking !history - history_connect: if > 0, then this number of messages is automatically sent when connecting to the hub Removed the built-in !history command in favour of the mod_chat_history plug-in. Make sure we unescape all chat messages before forwarding any of them to plugins. Update example plugins.conf in documentation directory.
This commit is contained in:
parent
a9ed03cf38
commit
875f55a401
|
@ -1,16 +1,63 @@
|
||||||
# ATTENTION!
|
# ATTENTION!
|
||||||
# Plugins are invoked in the order of listing in the plugin config file.
|
# Plugins are invoked in the order of listing in the plugin config file.
|
||||||
|
|
||||||
# auth user
|
|
||||||
# file={path for DB file with user auth information}
|
# Sqlite based user authentication.
|
||||||
|
#
|
||||||
|
# This plugin provides a Sqlite based authentication database for
|
||||||
|
# registered users.
|
||||||
|
# Use the uhub-passwd utility to create the database and add/remove users.
|
||||||
|
#
|
||||||
|
# Parameters:
|
||||||
|
# file: path/filename for database.
|
||||||
|
#
|
||||||
plugin /var/lib/uhub/mod_auth_sqlite.so "file=/etc/uhub/users.db"
|
plugin /var/lib/uhub/mod_auth_sqlite.so "file=/etc/uhub/users.db"
|
||||||
|
|
||||||
# log subsystem.
|
|
||||||
# file={/path/to/logfile}
|
# Log file writer
|
||||||
|
#
|
||||||
|
# Parameters:
|
||||||
|
# file: path/filename for log file.
|
||||||
|
# syslog: if true then syslog is used instead of writing to a file (Unix only)
|
||||||
plugin /var/lib/uhub/mod_logging.so "file=/var/log/uhub.log"
|
plugin /var/lib/uhub/mod_logging.so "file=/var/log/uhub.log"
|
||||||
|
|
||||||
#
|
# A simple example plugin
|
||||||
# plugin /var/lib/uhub/mod_auth_simple.so
|
|
||||||
|
|
||||||
#
|
|
||||||
# plugin /var/lib/uhub/mod_example.so
|
# plugin /var/lib/uhub/mod_example.so
|
||||||
|
|
||||||
|
# Load the chat history plugin.
|
||||||
|
#
|
||||||
|
# This plugin provides chat history when users are connecting, or
|
||||||
|
# when users invoke the !history command.
|
||||||
|
# The history command can optionally take a parameter to indicate how many lines of history is requested.
|
||||||
|
#
|
||||||
|
# Parameters:
|
||||||
|
# history_max: the maximum number of messages to keep in history
|
||||||
|
# history_default: when !history is provided without arguments, then this default number of messages are returned.
|
||||||
|
# history_connect: the number of chat history messages to send when users connect (0 = do not send any history)
|
||||||
|
plugin /var/lib/uhub/mod_chat_history.so "history_max=200 history_default=10 history_connect=5"
|
||||||
|
|
||||||
|
# A plugin sending a welcome message.
|
||||||
|
#
|
||||||
|
# This plugin provides the following commands:
|
||||||
|
# !motd - Message of the day
|
||||||
|
# !rules - Show hub rules.
|
||||||
|
#
|
||||||
|
# Parameters:
|
||||||
|
# motd: path/filename for the welcome message (message of the day)
|
||||||
|
# rules: path/filenam for the rules file
|
||||||
|
#
|
||||||
|
# NOTE: The files MUST exist, however if you do not wish to provide one then these parameters can be omitted.
|
||||||
|
#
|
||||||
|
# The motd/rules files can do the following substitutions:
|
||||||
|
# %n - Nickname of the user who entered the hub or issued the command.
|
||||||
|
# %a - IP address of the user
|
||||||
|
# %% - Becomes '%'
|
||||||
|
# %H - Hour 24-hour format (00-23) (Hub local time)
|
||||||
|
# %I - Hour 12-hour format (01-12) (Hub local time)
|
||||||
|
# %P - 'AM' or 'PM'
|
||||||
|
# %p - 'am' or 'pm'
|
||||||
|
# %M - Minutes (00-59) (Hub local time)
|
||||||
|
# %S - Seconds (00-60) (Hub local time)
|
||||||
|
plugin /var/lib/uhub/mod_welcome.so "motd=/etc/uhub/motd.txt rules=/etc/uhub/rules.txt"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -685,49 +685,6 @@ static int command_broadcast(struct command_base* cbase, struct hub_user* user,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int command_history(struct command_base* cbase, struct hub_user* user, struct hub_command* cmd)
|
|
||||||
{
|
|
||||||
struct cbuffer* buf;
|
|
||||||
struct linked_list* messages = cbase->hub->chat_history;
|
|
||||||
char* message;
|
|
||||||
char* maxlines_str = list_get_first(cmd->args);
|
|
||||||
int maxlines = 0;
|
|
||||||
int skiplines = 0;
|
|
||||||
int total = list_size(messages);
|
|
||||||
|
|
||||||
if (total == 0)
|
|
||||||
return command_status(cbase, user, cmd, cbuf_create_const("No messages."));
|
|
||||||
|
|
||||||
buf = cbuf_create(MAX_HELP_MSG);
|
|
||||||
if (maxlines_str)
|
|
||||||
maxlines = uhub_atoi(maxlines_str);
|
|
||||||
|
|
||||||
if (maxlines <= 0 || maxlines > total)
|
|
||||||
maxlines = total;
|
|
||||||
|
|
||||||
if (maxlines != total)
|
|
||||||
{
|
|
||||||
skiplines = total - maxlines;
|
|
||||||
cbuf_append_format(buf, "*** %s: Displaying %d of %d message%s:", cmd->prefix, maxlines, total, ((total != 1) ? "s" : ""));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cbuf_append_format(buf, "*** %s: Displaying %d message%s:", cmd->prefix, total, ((total != 1) ? "s" : ""));
|
|
||||||
}
|
|
||||||
cbuf_append(buf, "\n");
|
|
||||||
|
|
||||||
message = (char*) list_get_first(messages);
|
|
||||||
while (message)
|
|
||||||
{
|
|
||||||
if (--skiplines < 0)
|
|
||||||
cbuf_append(buf, message);
|
|
||||||
message = (char*) list_get_next(messages);
|
|
||||||
}
|
|
||||||
cbuf_append(buf, "\n");
|
|
||||||
send_message(cbase, user, buf);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int command_log(struct command_base* cbase, struct hub_user* user, struct hub_command* cmd)
|
static int command_log(struct command_base* cbase, struct hub_user* user, struct hub_command* cmd)
|
||||||
{
|
{
|
||||||
struct cbuffer* buf;
|
struct cbuffer* buf;
|
||||||
|
@ -948,7 +905,6 @@ void commands_builtin_add(struct command_base* cbase)
|
||||||
#endif
|
#endif
|
||||||
ADD_COMMAND("getip", 5, "n", auth_cred_operator, command_getip, "Show IP address for a user" );
|
ADD_COMMAND("getip", 5, "n", auth_cred_operator, command_getip, "Show IP address for a user" );
|
||||||
ADD_COMMAND("help", 4, "?c",auth_cred_guest, command_help, "Show this help message." );
|
ADD_COMMAND("help", 4, "?c",auth_cred_guest, command_help, "Show this help message." );
|
||||||
ADD_COMMAND("history", 7, "?N",auth_cred_guest, command_history, "Show the last chat messages." );
|
|
||||||
ADD_COMMAND("kick", 4, "n", auth_cred_operator, command_kick, "Kick a user" );
|
ADD_COMMAND("kick", 4, "n", auth_cred_operator, command_kick, "Kick a user" );
|
||||||
ADD_COMMAND("log", 3, "", auth_cred_operator, command_log, "Display log" );
|
ADD_COMMAND("log", 3, "", auth_cred_operator, command_log, "Display log" );
|
||||||
ADD_COMMAND("mute", 4, "n", auth_cred_operator, command_mute, "Mute user" );
|
ADD_COMMAND("mute", 4, "n", auth_cred_operator, command_mute, "Mute user" );
|
||||||
|
|
|
@ -54,10 +54,10 @@ enum command_parse_status
|
||||||
*/
|
*/
|
||||||
struct hub_command
|
struct hub_command
|
||||||
{
|
{
|
||||||
enum command_parse_status status; /**<<< "Status of the hub_command." */
|
|
||||||
const char* message; /**<<< "The complete message." */
|
const char* message; /**<<< "The complete message." */
|
||||||
char* prefix; /**<<< "The prefix extracted from the message." */
|
char* prefix; /**<<< "The prefix extracted from the message." */
|
||||||
struct linked_list* args; /**<<< "List of all parsed arguments from the message. Type depends on expectations." */
|
struct linked_list* args; /**<<< "List of all parsed arguments from the message. Type depends on expectations." */
|
||||||
|
enum command_parse_status status; /**<<< "Status of the hub_command." */
|
||||||
command_handler handler; /**<<< "The function handler to call in order to invoke this command." */
|
command_handler handler; /**<<< "The function handler to call in order to invoke this command." */
|
||||||
const struct hub_user* user; /**<<< "The user who invoked this command." */
|
const struct hub_user* user; /**<<< "The user who invoked this command." */
|
||||||
void* ptr; /**<<< "A pointer of data which came from struct command_handler" */
|
void* ptr; /**<<< "A pointer of data which came from struct command_handler" */
|
||||||
|
|
|
@ -265,6 +265,13 @@ int hub_handle_chat_message(struct hub_info* hub, struct hub_user* u, struct adc
|
||||||
if (!message)
|
if (!message)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
message_decoded = adc_msg_unescape(message);
|
||||||
|
if (!message_decoded)
|
||||||
|
{
|
||||||
|
hub_free(message);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (!user_is_logged_in(u))
|
if (!user_is_logged_in(u))
|
||||||
{
|
{
|
||||||
hub_free(message);
|
hub_free(message);
|
||||||
|
@ -290,9 +297,7 @@ int hub_handle_chat_message(struct hub_info* hub, struct hub_user* u, struct adc
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
message_decoded = adc_msg_unescape(message);
|
|
||||||
relay = command_invoke(hub->commands, u, message_decoded);
|
relay = command_invoke(hub->commands, u, message_decoded);
|
||||||
hub_free(message_decoded);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -307,13 +312,13 @@ int hub_handle_chat_message(struct hub_info* hub, struct hub_user* u, struct adc
|
||||||
plugin_st status = st_default;
|
plugin_st status = st_default;
|
||||||
if (broadcast)
|
if (broadcast)
|
||||||
{
|
{
|
||||||
status = plugin_handle_chat_message(hub, u, message, 0);
|
status = plugin_handle_chat_message(hub, u, message_decoded, 0);
|
||||||
}
|
}
|
||||||
else if (private_msg)
|
else if (private_msg)
|
||||||
{
|
{
|
||||||
struct hub_user* target = uman_get_user_by_sid(hub, cmd->target);
|
struct hub_user* target = uman_get_user_by_sid(hub, cmd->target);
|
||||||
if (target)
|
if (target)
|
||||||
status = plugin_handle_private_message(hub, u, target, message, 0);
|
status = plugin_handle_private_message(hub, u, target, message_decoded, 0);
|
||||||
else
|
else
|
||||||
relay = 0;
|
relay = 0;
|
||||||
}
|
}
|
||||||
|
@ -327,39 +332,15 @@ int hub_handle_chat_message(struct hub_info* hub, struct hub_user* u, struct adc
|
||||||
/* adc_msg_remove_named_argument(cmd, "PM"); */
|
/* adc_msg_remove_named_argument(cmd, "PM"); */
|
||||||
if (broadcast)
|
if (broadcast)
|
||||||
{
|
{
|
||||||
hub_chat_history_add(hub, u, cmd);
|
plugin_log_chat_message(hub, u, message_decoded, 0);
|
||||||
plugin_log_chat_message(hub, u, message, 0);
|
|
||||||
}
|
}
|
||||||
ret = route_message(hub, u, cmd);
|
ret = route_message(hub, u, cmd);
|
||||||
}
|
}
|
||||||
hub_free(message);
|
hub_free(message);
|
||||||
|
hub_free(message_decoded);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void hub_chat_history_add(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd)
|
|
||||||
{
|
|
||||||
char* msg_esc = adc_msg_get_argument(cmd, 0);
|
|
||||||
char* message = adc_msg_unescape(msg_esc);
|
|
||||||
size_t loglen = strlen(message) + strlen(user->id.nick) + 13;
|
|
||||||
char* log = hub_malloc(loglen + 1);
|
|
||||||
snprintf(log, loglen, "%s <%s> %s\n", get_timestamp(time(NULL)), user->id.nick, message);
|
|
||||||
log[loglen] = '\0';
|
|
||||||
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);
|
|
||||||
hub_free(msg_esc);
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
void hub_send_support(struct hub_info* hub, struct hub_user* u)
|
||||||
{
|
{
|
||||||
if (user_is_connecting(u) || user_is_logged_in(u))
|
if (user_is_connecting(u) || user_is_logged_in(u))
|
||||||
|
@ -803,20 +784,7 @@ struct hub_info* hub_start_service(struct hub_config* config)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
hub->chat_history = (struct linked_list*) list_create();
|
|
||||||
hub->logout_info = (struct linked_list*) list_create();
|
hub->logout_info = (struct linked_list*) list_create();
|
||||||
if (!hub->chat_history)
|
|
||||||
{
|
|
||||||
net_con_close(hub->server);
|
|
||||||
list_destroy(hub->chat_history);
|
|
||||||
list_destroy(hub->logout_info);
|
|
||||||
hub_free(hub->recvbuf);
|
|
||||||
hub_free(hub->sendbuf);
|
|
||||||
uman_shutdown(hub);
|
|
||||||
hub_free(hub);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
server_alt_port_start(hub, config);
|
server_alt_port_start(hub, config);
|
||||||
|
|
||||||
hub->status = hub_status_running;
|
hub->status = hub_status_running;
|
||||||
|
@ -844,8 +812,6 @@ void hub_shutdown_service(struct hub_info* hub)
|
||||||
hub->status = hub_status_stopped;
|
hub->status = hub_status_stopped;
|
||||||
hub_free(hub->sendbuf);
|
hub_free(hub->sendbuf);
|
||||||
hub_free(hub->recvbuf);
|
hub_free(hub->recvbuf);
|
||||||
hub_chat_history_clear(hub);
|
|
||||||
list_destroy(hub->chat_history);
|
|
||||||
list_clear(hub->logout_info, &hub_free);
|
list_clear(hub->logout_info, &hub_free);
|
||||||
list_destroy(hub->logout_info);
|
list_destroy(hub->logout_info);
|
||||||
command_shutdown(hub->commands);
|
command_shutdown(hub->commands);
|
||||||
|
|
|
@ -109,7 +109,6 @@ struct hub_info
|
||||||
char* recvbuf; /* Global receive buffer */
|
char* recvbuf; /* Global receive buffer */
|
||||||
char* sendbuf; /* Global send buffer */
|
char* sendbuf; /* Global send buffer */
|
||||||
|
|
||||||
struct linked_list* chat_history; /* Chat history */
|
|
||||||
struct linked_list* logout_info; /* Log of people logging out. */
|
struct linked_list* logout_info; /* Log of people logging out. */
|
||||||
|
|
||||||
struct command_base* commands; /* Hub command handler */
|
struct command_base* commands; /* Hub command handler */
|
||||||
|
@ -151,16 +150,6 @@ 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);
|
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
|
* Used internally by hub_handle_info
|
||||||
* @return 1 if nickname is OK, or 0 if nickname is not accepted.
|
* @return 1 if nickname is OK, or 0 if nickname is not accepted.
|
||||||
|
|
|
@ -0,0 +1,245 @@
|
||||||
|
/*
|
||||||
|
* uhub - A tiny ADC p2p connection hub
|
||||||
|
* Copyright (C) 2007-2012, Jan Vidar Krey
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "plugin_api/handle.h"
|
||||||
|
#include "plugin_api/command_api.h"
|
||||||
|
#include "util/config_token.h"
|
||||||
|
#include "util/memory.h"
|
||||||
|
#include "util/misc.h"
|
||||||
|
#include "util/list.h"
|
||||||
|
#include "util/cbuffer.h"
|
||||||
|
|
||||||
|
#define MAX_HISTORY_SIZE 16384
|
||||||
|
|
||||||
|
struct chat_history_data
|
||||||
|
{
|
||||||
|
size_t history_max; ///<<< "the maximum number of chat messages kept in history."
|
||||||
|
size_t history_default; ///<<< "the default number of chat messages returned if no limit was provided"
|
||||||
|
size_t history_connect; ///<<< "the number of chat messages provided when users connect to the hub."
|
||||||
|
struct linked_list* chat_history; ///<<< "The chat history storage."
|
||||||
|
struct plugin_command_handle* command_history_handle; ///<<< "A handle to the !history command."
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a chat message to history.
|
||||||
|
*/
|
||||||
|
static void history_add(struct plugin_handle* plugin, struct plugin_user* from, const char* message, int flags)
|
||||||
|
{
|
||||||
|
size_t loglen = strlen(message) + strlen(from->nick) + 13;
|
||||||
|
struct chat_history_data* data = (struct chat_history_data*) plugin->ptr;
|
||||||
|
char* log = hub_malloc(loglen + 1);
|
||||||
|
|
||||||
|
snprintf(log, loglen, "%s <%s> %s\n", get_timestamp(time(NULL)), from->nick, message);
|
||||||
|
log[loglen] = '\0';
|
||||||
|
list_append(data->chat_history, log);
|
||||||
|
while (list_size(data->chat_history) > data->history_max)
|
||||||
|
{
|
||||||
|
char* msg = list_get_first(data->chat_history);
|
||||||
|
list_remove(data->chat_history, msg);
|
||||||
|
hub_free(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain 'num' messages from the chat history and append them to outbuf.
|
||||||
|
*
|
||||||
|
* @return the number of messages added to the buffer.
|
||||||
|
*/
|
||||||
|
static size_t get_messages(struct chat_history_data* data, size_t num, struct cbuffer* outbuf)
|
||||||
|
{
|
||||||
|
struct linked_list* messages = data->chat_history;
|
||||||
|
char* message;
|
||||||
|
int skiplines = 0;
|
||||||
|
size_t lines = 0;
|
||||||
|
int total = list_size(messages);
|
||||||
|
|
||||||
|
if (total == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (num <= 0 || num > total)
|
||||||
|
num = total;
|
||||||
|
|
||||||
|
if (num != total)
|
||||||
|
skiplines = total - num;
|
||||||
|
|
||||||
|
cbuf_append(outbuf, "\n");
|
||||||
|
message = (char*) list_get_first(messages);
|
||||||
|
while (message)
|
||||||
|
{
|
||||||
|
if (--skiplines < 0)
|
||||||
|
{
|
||||||
|
cbuf_append(outbuf, message);
|
||||||
|
lines++;
|
||||||
|
}
|
||||||
|
message = (char*) list_get_next(messages);
|
||||||
|
}
|
||||||
|
cbuf_append(outbuf, "\n");
|
||||||
|
return lines;
|
||||||
|
}
|
||||||
|
|
||||||
|
void user_login(struct plugin_handle* plugin, struct plugin_user* user)
|
||||||
|
{
|
||||||
|
struct chat_history_data* data = (struct chat_history_data*) plugin->ptr;
|
||||||
|
struct cbuffer* buf = NULL;
|
||||||
|
// size_t messages = 0;
|
||||||
|
|
||||||
|
if (data->history_connect > 0 && list_size(data->chat_history) > 0)
|
||||||
|
{
|
||||||
|
buf = cbuf_create(MAX_HISTORY_SIZE);
|
||||||
|
cbuf_append(buf, "Chat history:\n");
|
||||||
|
get_messages(data, data->history_connect, buf);
|
||||||
|
plugin->hub.send_message(plugin, user, cbuf_get(buf));
|
||||||
|
cbuf_destroy(buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a status message back to the user who issued the !history command.
|
||||||
|
*/
|
||||||
|
static int command_status(struct plugin_handle* plugin, struct plugin_user* user, struct plugin_command* cmd, struct cbuffer* buf)
|
||||||
|
{
|
||||||
|
struct cbuffer* msg = cbuf_create(cbuf_size(buf) + strlen(cmd->prefix) + 8);
|
||||||
|
cbuf_append_format(msg, "*** %s: %s", cmd->prefix, cbuf_get(buf));
|
||||||
|
plugin->hub.send_message(plugin, user, cbuf_get(msg));
|
||||||
|
cbuf_destroy(msg);
|
||||||
|
cbuf_destroy(buf);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The callback function for handling the !history command.
|
||||||
|
*/
|
||||||
|
static int command_history(struct plugin_handle* plugin, struct plugin_user* user, struct plugin_command* cmd)
|
||||||
|
{
|
||||||
|
struct cbuffer* buf;
|
||||||
|
struct chat_history_data* data = (struct chat_history_data*) plugin->ptr;
|
||||||
|
int maxlines = 0;
|
||||||
|
|
||||||
|
if (!list_size(data->chat_history))
|
||||||
|
return command_status(plugin, user, cmd, cbuf_create_const("No messages."));
|
||||||
|
|
||||||
|
if (list_size(cmd->args) > 0)
|
||||||
|
maxlines = (int) (intptr_t) ((intptr_t*) (void*) list_get_first(cmd->args));
|
||||||
|
else
|
||||||
|
maxlines = data->history_default;
|
||||||
|
|
||||||
|
buf = cbuf_create(MAX_HISTORY_SIZE);
|
||||||
|
cbuf_append_format(buf, "*** %s: Chat History:\n", cmd->prefix);
|
||||||
|
get_messages(data, maxlines, buf);
|
||||||
|
|
||||||
|
plugin->hub.send_message(plugin, user, cbuf_get(buf));
|
||||||
|
cbuf_destroy(buf);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_error_message(struct plugin_handle* plugin, const char* msg)
|
||||||
|
{
|
||||||
|
plugin->error_msg = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct chat_history_data* parse_config(const char* line, struct plugin_handle* plugin)
|
||||||
|
{
|
||||||
|
struct chat_history_data* data = (struct chat_history_data*) hub_malloc_zero(sizeof(struct chat_history_data));
|
||||||
|
struct cfg_tokens* tokens = cfg_tokenize(line);
|
||||||
|
char* token = cfg_token_get_first(tokens);
|
||||||
|
|
||||||
|
assert(data != NULL);
|
||||||
|
|
||||||
|
data->history_max = 200;
|
||||||
|
data->history_default = 25;
|
||||||
|
data->history_connect = 5;
|
||||||
|
data->chat_history = list_create();
|
||||||
|
|
||||||
|
while (token)
|
||||||
|
{
|
||||||
|
struct cfg_settings* setting = cfg_settings_split(token);
|
||||||
|
|
||||||
|
if (!setting)
|
||||||
|
{
|
||||||
|
set_error_message(plugin, "Unable to parse startup parameters");
|
||||||
|
cfg_tokens_free(tokens);
|
||||||
|
hub_free(data);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(cfg_settings_get_key(setting), "history_max") == 0)
|
||||||
|
{
|
||||||
|
data->history_max = (size_t) uhub_atoi(cfg_settings_get_value(setting));
|
||||||
|
}
|
||||||
|
else if (strcmp(cfg_settings_get_key(setting), "history_default") == 0)
|
||||||
|
{
|
||||||
|
data->history_default = (size_t) uhub_atoi(cfg_settings_get_value(setting));
|
||||||
|
}
|
||||||
|
else if (strcmp(cfg_settings_get_key(setting), "history_connect") == 0)
|
||||||
|
{
|
||||||
|
data->history_connect = (size_t) uhub_atoi(cfg_settings_get_value(setting));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
set_error_message(plugin, "Unknown startup parameters given");
|
||||||
|
cfg_tokens_free(tokens);
|
||||||
|
cfg_settings_free(setting);
|
||||||
|
hub_free(data);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg_settings_free(setting);
|
||||||
|
token = cfg_token_get_next(tokens);
|
||||||
|
}
|
||||||
|
cfg_tokens_free(tokens);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
int plugin_register(struct plugin_handle* plugin, const char* config)
|
||||||
|
{
|
||||||
|
struct chat_history_data* data;
|
||||||
|
PLUGIN_INITIALIZE(plugin, "Chat history plugin", "1.0", "Provide a global chat history log.");
|
||||||
|
|
||||||
|
plugin->funcs.on_user_chat_message = history_add;
|
||||||
|
plugin->funcs.on_user_login = user_login;
|
||||||
|
data = parse_config(config, plugin);
|
||||||
|
if (!data)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
plugin->ptr = data;
|
||||||
|
|
||||||
|
data->command_history_handle = (struct plugin_command_handle*) hub_malloc(sizeof(struct plugin_command_handle));
|
||||||
|
PLUGIN_COMMAND_INITIALIZE(data->command_history_handle, plugin, "history", "?N", auth_cred_guest, &command_history, "Show chat message history.");
|
||||||
|
plugin->hub.command_add(plugin, data->command_history_handle);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int plugin_unregister(struct plugin_handle* plugin)
|
||||||
|
{
|
||||||
|
struct chat_history_data* data = (struct chat_history_data*) plugin->ptr;
|
||||||
|
|
||||||
|
if (data)
|
||||||
|
{
|
||||||
|
list_clear(data->chat_history, &hub_free);
|
||||||
|
list_destroy(data->chat_history);
|
||||||
|
|
||||||
|
plugin->hub.command_del(plugin, data->command_history_handle);
|
||||||
|
hub_free(data->command_history_handle);
|
||||||
|
hub_free(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue