Created
April 24, 2012 02:20
-
-
Save aji/2475539 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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