Skip to content

Instantly share code, notes, and snippets.

@aji
Created April 24, 2012 02:20
Show Gist options
  • Save aji/2475539 to your computer and use it in GitHub Desktop.
Save aji/2475539 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <string.h>
#include <mowgli.h>
#include <unicorn.h>
struct botdata {
irc_hook_table_t *commands;
int hugs;
int prefix;
char *sender;
char *replyto;
char *rplcmd;
void (*replyf)(struct botdata*, int prefix, char*, ...);
void (*rawf)(struct botdata*, char*, ...);
void (*raw)(struct botdata*, char*);
};
void cmd_hug(int parc, char *parv[], void *priv)
{
struct botdata *bot = priv;
bot->replyf(bot, 1, "<3 %d hugs", ++bot->hugs);
}
void cmd_join(int parc, char *parv[], void *priv)
{
struct botdata *bot = priv;
if (parc == 0) {
bot->replyf(bot, 1, "Usage: join <channel>");
return;
}
bot->rawf(bot, "JOIN %s\r\n", parv[0]);
}
void cmd_part(int parc, char *parv[], void *priv)
{
struct botdata *bot = priv;
if (parc == 0) {
bot->replyf(bot, 1, "Usage: part <channel>");
return;
}
bot->rawf(bot, "PART %s\r\n", parv[0]);
}
void dispatch_command(struct botdata *bot, char *cmdspec)
{
char *args;
char *cmd;
args = strchr(cmdspec, ' ');
if (args == NULL) {
irc_hook_call(bot->commands, cmdspec, 0, NULL);
} else {
cmd = mowgli_alloc(args - cmdspec + 1);
*args++ = '\0';
strcpy(cmd, cmdspec);
irc_hook_call(bot->commands, cmd, 1, &args);
mowgli_free(cmd);
}
}
// sender target message
void privmsg_hook(int parc, char *parv[], void *priv)
{
struct botdata *bot = priv;
int offset = 1;
if (parc != 3 || bot == NULL)
return;
bot->prefix = 1;
bot->sender = parv[0];
bot->replyto = parv[1];
bot->rplcmd = "PRIVMSG";
if (parv[1][0] != '#') {
bot->prefix = 0;
bot->replyto = parv[0];
bot->rplcmd = "NOTICE";
if (parv[2][0] != '!')
offset = 0;
}
dispatch_command(bot, parv[2] + offset);
}
void bot_replyf(struct botdata *bot, int prefix, char *fmt, ...)
{
char rpl[512];
char *p, *q;
va_list va;
va_start(va, fmt);
vsprintf(rpl, fmt, va);
va_end(va);
p = q = "";
if (prefix && bot->prefix) {
p = bot->sender;
q = ": ";
}
bot->rawf(bot, "%s %s :%s%s%s\r\n", bot->rplcmd, bot->replyto, p, q, rpl);
}
void bot_rawf(struct botdata *bot, char *fmt, ...)
{
char buf[512];
va_list va;
va_start(va, fmt);
vsprintf(buf, fmt, va);
va_end(va);
bot->raw(bot, buf);
}
void bot_raw(struct botdata *bot, char *data)
{
fputs(data, stdout);
fflush(stdout);
}
struct botdata *bot_create(void)
{
struct botdata *bot;
bot = mowgli_alloc(sizeof(*bot));
bot->commands = irc_hook_table_create();
irc_hook_add(bot->commands, "hug", &cmd_hug, bot);
irc_hook_add(bot->commands, "join", &cmd_join, bot);
irc_hook_add(bot->commands, "part", &cmd_part, bot);
bot->hugs = 0;
bot->sender = NULL;
bot->replyto = NULL;
bot->rplcmd = NULL;
bot->replyf = &bot_replyf;
bot->rawf = &bot_rawf;
bot->raw = &bot_raw;
}
void bot_destroy(struct botdata *bot)
{
irc_hook_table_destroy(bot->commands);
mowgli_free(bot);
}
int main(int argc, char *argv[])
{
struct botdata *bot;
irc_message_t msg;
irc_hook_table_t *global;
mowgli_node_t *curr, *next;
bot = bot_create();
global = irc_hook_table_create();
irc_hook_add(global, "PRIVMSG", &privmsg_hook, bot);
bot->raw(bot, "NICK libunicorn\r\n");
bot->raw(bot, "USER alex 0 0 :libunicorn\r\n");
do {
memset(&msg, 0, sizeof(msg));
if (!fgets(msg.buffer, 511, stdin)) {
fprintf(stderr, "Error on read, probably EOF\n");
break;
}
if (irc_message_parse_buffer(&msg) < 0) {
fprintf(stderr, "Error occurred when parsing message :(\n");
continue;
}
irc_hook_simple_dispatch(global, &msg);
MOWGLI_LIST_FOREACH_SAFE(curr, next, msg.args.head) {
mowgli_node_delete(curr, &msg.args);
mowgli_node_free(curr);
}
} while (1);
bot_destroy(bot);
irc_hook_table_destroy(global);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment