diff --git a/Makefile b/Makefile index c1e2b90..91b221c 100755 --- a/Makefile +++ b/Makefile @@ -20,6 +20,7 @@ main: $(CC) $(CFLAGS) $(SRC)/util.c -o $(OBJ)/util.o $(CC) $(CFLAGS) $(SRC)/events.c -o $(OBJ)/events.o $(CC) $(CFLAGS) $(SRC)/module.c -o $(OBJ)/module.o + $(CC) $(CFLAGS) $(SRC)/channel.c -o $(OBJ)/channel.o $(CC) -o $(EXEC) $(OBJECTS) $(BINFLAGS) @echo "All Done!" diff --git a/compile_commands.json b/compile_commands.json index 0d73271..43882bf 100755 --- a/compile_commands.json +++ b/compile_commands.json @@ -10,9 +10,9 @@ "./build/config.o", "./src/config.c" ], - "directory": "/home/aaron/projects/xbot", - "file": "/home/aaron/projects/xbot/src/config.c", - "output": "/home/aaron/projects/xbot/build/config.o" + "directory": "/mnt/mem/Dev/xbot", + "file": "/mnt/mem/Dev/xbot/src/config.c", + "output": "/mnt/mem/Dev/xbot/build/config.o" }, { "arguments": [ @@ -25,9 +25,9 @@ "./build/main.o", "./src/main.c" ], - "directory": "/home/aaron/projects/xbot", - "file": "/home/aaron/projects/xbot/src/main.c", - "output": "/home/aaron/projects/xbot/build/main.o" + "directory": "/mnt/mem/Dev/xbot", + "file": "/mnt/mem/Dev/xbot/src/main.c", + "output": "/mnt/mem/Dev/xbot/build/main.o" }, { "arguments": [ @@ -40,9 +40,9 @@ "./build/irc.o", "./src/irc.c" ], - "directory": "/home/aaron/projects/xbot", - "file": "/home/aaron/projects/xbot/src/irc.c", - "output": "/home/aaron/projects/xbot/build/irc.o" + "directory": "/mnt/mem/Dev/xbot", + "file": "/mnt/mem/Dev/xbot/src/irc.c", + "output": "/mnt/mem/Dev/xbot/build/irc.o" }, { "arguments": [ @@ -55,9 +55,9 @@ "./build/util.o", "./src/util.c" ], - "directory": "/home/aaron/projects/xbot", - "file": "/home/aaron/projects/xbot/src/util.c", - "output": "/home/aaron/projects/xbot/build/util.o" + "directory": "/mnt/mem/Dev/xbot", + "file": "/mnt/mem/Dev/xbot/src/util.c", + "output": "/mnt/mem/Dev/xbot/build/util.o" }, { "arguments": [ @@ -70,9 +70,9 @@ "./build/events.o", "./src/events.c" ], - "directory": "/home/aaron/projects/xbot", - "file": "/home/aaron/projects/xbot/src/events.c", - "output": "/home/aaron/projects/xbot/build/events.o" + "directory": "/mnt/mem/Dev/xbot", + "file": "/mnt/mem/Dev/xbot/src/events.c", + "output": "/mnt/mem/Dev/xbot/build/events.o" }, { "arguments": [ @@ -85,8 +85,23 @@ "./build/module.o", "./src/module.c" ], - "directory": "/home/aaron/projects/xbot", - "file": "/home/aaron/projects/xbot/src/module.c", - "output": "/home/aaron/projects/xbot/build/module.o" + "directory": "/mnt/mem/Dev/xbot", + "file": "/mnt/mem/Dev/xbot/src/module.c", + "output": "/mnt/mem/Dev/xbot/build/module.o" + }, + { + "arguments": [ + "/usr/bin/gcc", + "-g", + "-std=gnu99", + "-c", + "-I./lib", + "-o", + "./build/channel.o", + "./src/channel.c" + ], + "directory": "/mnt/mem/Dev/xbot", + "file": "/mnt/mem/Dev/xbot/src/channel.c", + "output": "/mnt/mem/Dev/xbot/build/channel.o" } ] diff --git a/lib/channel.h b/lib/channel.h new file mode 100755 index 0000000..175b2ed --- /dev/null +++ b/lib/channel.h @@ -0,0 +1,74 @@ +#ifndef CHANNEL_H +#define CHANNEL_H + +#ifdef _WIN32 +#include +#else +#include +#endif + +#include "util.h" +#include "irc.h" +#include "events.h" + +#define CHAN_PRIV_OP "@" +#define CHAN_PRIV_HALF "%" +#define CHAN_PRIV_VOICE "+" +#define CHAN_PRIV_OWNER "~" +#define CHAN_PRIV_ADMIN "&" + +struct user +{ + char nick[50]; + char host[256]; + char real_name[512]; + +#ifdef _WIN32 + BOOL is_op; + BOOL is_halfop; + BOOL is_voice; + BOOL is_owner; + BOOL is_admin; +#else + bool is_op; + bool is_halfop; + bool is_voice; + bool is_owner; + bool is_admin; +#endif +}; + +struct channel +{ + char name[32]; + int user_count; + + struct user *users; +}; + +void add_channel(char *name); +void remove_channel(char *name); +void add_user_to_channel(char *user, char *host, char *chan); +void remove_user_from_channel(char *user, char *chan); +void update_nick(char *old_nick, char *new_nick); +void update_host(char *nick, char *host); +void user_quit(char *nick); +void set_realname(char *nick, char *real_name); + +#ifdef _WIN32 +MY_API BOOL is_op(char *chan, char *nick); +MY_API BOOL is_halfop(char *chan, char *nick); +MY_API BOOL is_voice(char *chan, char *nick); +MY_API BOOL channel_exists(char *chan); +MY_API BOOL user_exists(char *chan, char *nick); +#else +MY_API bool is_op(char *chan, char *nick); +MY_API bool is_halfop(char *chan, char *nick); +MY_API bool is_voice(char *chan, char *nick); +MY_API bool is_owner(char *chan, char *nick); +MY_API bool is_admin(char *chan, char *nick); +MY_API bool channel_exists(char *chan); +MY_API bool user_exists(char *chan, char *nick); +#endif + +#endif diff --git a/lib/events.h b/lib/events.h index 39605ae..5343316 100755 --- a/lib/events.h +++ b/lib/events.h @@ -6,11 +6,18 @@ #define PRIVMSG_SELF "CMSG" #define PRIVMSG_CHAN "PMSG" #define JOIN "JOIN" +#define JOIN_MYSELF "JOIN_MYSELF" #define PART "PART" +#define PART_MYSELF "PART_MYSELF" #define QUIT "QUIT" +#define NICK "NICK" +#define NICK_MYSELF "NICK_MYSELF" +#define NICK_INUSE "433" +#define CTCP "CTCP" #define IRC_CONNECTED "001" #define IRC_MOTD "372" #define IRC_END_MOTD "376" +#define IRC_NAMREPLY "353" struct ev_handler { diff --git a/lib/irc.h b/lib/irc.h index 854fbf5..f00368b 100755 --- a/lib/irc.h +++ b/lib/irc.h @@ -23,7 +23,7 @@ struct irc_conn #endif char nick[32]; - char *admin; + char admin[64]; char host[256]; char port[5]; char real_name[512]; @@ -45,11 +45,16 @@ typedef struct handler event_handler; #define MY_API #endif -MY_API void irc_connect(struct irc_conn *bot); -MY_API void irc_auth(struct irc_conn *bot); +void irc_connect(struct irc_conn *bot); +void irc_auth(struct irc_conn *bot); + MY_API void irc_notice(struct irc_conn *bot, char *to, char *fmt, ...); MY_API void irc_privmsg(struct irc_conn *bot, char *to, char *fmt, ...); MY_API void irc_raw(struct irc_conn *bot, char *fmt, ...); -MY_API void irc_parse_raw(struct irc_conn *bot, char *raw); +MY_API void irc_join(struct irc_conn *bot, char *channel); +MY_API void irc_part(struct irc_conn *bot, char *channel, char *reason); + + +void irc_parse_raw(struct irc_conn *bot, char *raw); #endif diff --git a/lib/util.h b/lib/util.h index 2e13d48..2a8e8e0 100755 --- a/lib/util.h +++ b/lib/util.h @@ -8,7 +8,8 @@ #define UTIL_H #ifdef _WIN32 -#define USE_MY_STRLCPY 1 +#define true TRUE +#define false FALSE #endif void eprint(char *fmt, ...); diff --git a/mods/autojoin/autojoin.c b/mods/autojoin/autojoin.c index c996c8c..41b1e9a 100755 --- a/mods/autojoin/autojoin.c +++ b/mods/autojoin/autojoin.c @@ -38,7 +38,7 @@ MY_API void aj(struct irc_conn *bot, char *text) for (n = 0; n < count; n++) { chan = config_setting_get_string_elem(autojoin, n); - irc_raw(bot, "JOIN :%s", chan); + irc_join(bot, chan); } config_destroy(cf); diff --git a/mods/hello/hello.c b/mods/hello/hello.c index 2059e37..bdccf8e 100755 --- a/mods/hello/hello.c +++ b/mods/hello/hello.c @@ -9,7 +9,7 @@ int HANDLER = 0; -MY_API void hello(struct irc_conn *bot, char *user, char *chan, const char *text) +MY_API void hello(struct irc_conn *bot, char *user, char *host, char *chan, const char *text) { char *buf = (char *)malloc(sizeof(char *) * 500); sprintf(buf, "hi %s", bot->nick); diff --git a/mods/uptime/uptime.c b/mods/uptime/uptime.c index 28b34ba..2ee467b 100755 --- a/mods/uptime/uptime.c +++ b/mods/uptime/uptime.c @@ -5,12 +5,12 @@ #include #include -MY_API void up(struct irc_conn *bot, char *user, char *chan, const char *text) +MY_API void up(struct irc_conn *bot, char *user, char *host, char *chan, char *text) { char buf[100]; FILE* file; - printf("dbug up called: %s\n", text); + printf("dbug up called: %s!%s %s\n", user, host, text); if (!strcmp(text, "!uptime")) { diff --git a/src/channel.c b/src/channel.c new file mode 100755 index 0000000..a3d818f --- /dev/null +++ b/src/channel.c @@ -0,0 +1,403 @@ +#include "irc.h" +#include "util.h" +#include "events.h" +#include "module.h" +#include "channel.h" +#include +#include +#include +#include + +struct channel *channels[60]; +int chan_count = 0; + +void add_channel(char *name) +{ + if (channel_exists(name) == 1) + return; + + printf("Adding channel %s\n", name); + channels[chan_count] = calloc(1, sizeof(struct channel)); + + strlcpy(channels[chan_count]->name, name, 32); + + channels[chan_count]->user_count = 0; + channels[chan_count]->users = calloc(256, sizeof(struct user)); + + chan_count++; +} + +void remove_channel(char *name) +{ + int i, j; + + for (i = 0; i < chan_count; i++) + { + if (!strcmp(channels[i]->name, name)) + { + printf("Removing channel %s\n", name); + free(channels[i]->users); + free(channels[i]); + + for (j = i; j < chan_count; j++) + { + channels[j] = channels[j + 1]; + } + + chan_count--; + } + } +} + +void add_user_to_channel(char *user, char *host, char *chan) +{ + int i; + +#ifdef _WIN32 + BOOL is_op, is_voice, is_halfop, is_owner, is_admin; +#else + bool is_op, is_voice, is_halfop, is_owner, is_admin; +#endif + + is_op = false; + is_voice = false; + is_halfop = false; + is_owner = false; + is_admin = false; + + + if (!strcmp(chan, "")) + { + return; + } + + if (user_exists(chan, user) == 1) + return; + + // parse mode prefix symbols and remove them + if (user[0] == '@') + { + is_op = true; + user++; + } + else if (user[0] == '+') + { + is_voice = true; + user++; + } + else if (user[0] == '%') + { + is_halfop = true; + user++; + } + else if (user[0] == '~') + { + is_owner = true; + user++; + } + else if (user[0] == '&') + { + is_admin = true; + user++; + } + + printf("Adding user %s!%s to channel %s\n", user, host, chan); + + for (i = 0; i < chan_count; i++) + { + if (!strcmp(channels[i]->name, chan)) + { + strlcpy(channels[i]->users[channels[i]->user_count].nick, user, 50); + strlcpy(channels[i]->users[channels[i]->user_count].host, host, 256); + + channels[i]->users[channels[i]->user_count].is_op = is_op | is_owner | is_admin; + channels[i]->users[channels[i]->user_count].is_voice = is_voice | is_halfop | is_op | is_owner | is_admin; + channels[i]->users[channels[i]->user_count].is_halfop = is_halfop; + channels[i]->users[channels[i]->user_count].is_owner = is_owner; + channels[i]->users[channels[i]->user_count].is_admin = is_admin; + + channels[i]->user_count++; + } + } +} + +void remove_user_from_channel(char *user, char *chan) +{ + int i, j; + + for (i = 0; i < chan_count; i++) + { + if (!strcmp(channels[i]->name, chan)) + { + for (j = 0; j < channels[i]->user_count; j++) + { + if (!strcmp(channels[i]->users[j].nick, user)) + { + printf("Removing user %s from channel %s\n", user, chan); + + for (j = j; j < channels[i]->user_count; j++) + { + channels[i]->users[j] = channels[i]->users[j + 1]; + } + + + channels[i]->user_count--; + } + } + } + } +} + +void update_nick(char *old, char *new) +{ + int i, j; + + for (i = 0; i < chan_count; i++) + { + for (j = 0; j < channels[i]->user_count; j++) + { + if (!strcmp(channels[i]->users[j].nick, old)) + { + strlcpy(channels[i]->users[j].nick, new, 50); + } + } + } +} + +void update_host(char *nick, char *host) +{ + int i, j; + + for (i = 0; i < chan_count; i++) + { + for (j = 0; j < channels[i]->user_count; j++) + { + if (!strcmp(channels[i]->users[j].nick, nick)) + { + strlcpy(channels[i]->users[j].host, host, 256); + } + } + } +} + + +void user_quit(char *nick) +{ + int i, j; + + for (i = 0; i < chan_count; i++) + { + for (j = 0; j < channels[i]->user_count; j++) + { + if (!strcmp(channels[i]->users[j].nick, nick)) + { + printf("Removing user %s from channel %s\n", nick, channels[i]->name); + + for (j = j; j < channels[i]->user_count; j++) + { + channels[i]->users[j] = channels[i]->users[j + 1]; + } + + channels[i]->user_count--; + } + } + } +} + +void set_realname(char *nick, char *real_name) +{ + int i, j; + + for (i = 0; i < chan_count; i++) + { + for (j = 0; j < channels[i]->user_count; j++) + { + if (!strcmp(channels[i]->users[j].nick, nick)) + { + strlcpy(channels[i]->users[j].real_name, real_name, 256); + } + } + } +} + +#ifdef _WIN32 +MY_API BOOL is_op(char *chan, char *nick) +#else +MY_API bool is_op(char *chan, char *nick) +#endif +{ + int i; + + for (i = 0; i < chan_count; i++) + { + if (!strcmp(channels[i]->name, chan)) + { + int j; + + for (j = 0; j < channels[i]->user_count; j++) + { + if (!strcmp(channels[i]->users[j].nick, nick)) + { + return channels[i]->users[j].is_op; + } + } + } + } + + return 0; +} + +#ifdef _WIN32 +MY_API BOOL is_voice(char *chan, char *nick) +#else +MY_API bool is_voice(char *chan, char *nick) +#endif +{ + int i; + + for (i = 0; i < chan_count; i++) + { + if (!strcmp(channels[i]->name, chan)) + { + int j; + + for (j = 0; j < channels[i]->user_count; j++) + { + if (!strcmp(channels[i]->users[j].nick, nick)) + { + return channels[i]->users[j].is_voice; + } + } + } + } + + return 0; +} + +#ifdef _WIN32 +MY_API BOOL is_halfop(char *chan, char *nick) +#else +MY_API bool is_halfop(char *chan, char *nick) +#endif +{ + int i; + + for (i = 0; i < chan_count; i++) + { + if (!strcmp(channels[i]->name, chan)) + { + int j; + + for (j = 0; j < channels[i]->user_count; j++) + { + if (!strcmp(channels[i]->users[j].nick, nick)) + { + return channels[i]->users[j].is_halfop; + } + } + } + } + + return 0; +} + +#ifdef _WIN32 +MY_API BOOL is_owner(char *chan, char *nick) +#else +MY_API bool is_owner(char *chan, char *nick) +#endif +{ + int i; + + for (i = 0; i < chan_count; i++) + { + if (!strcmp(channels[i]->name, chan)) + { + int j; + + for (j = 0; j < channels[i]->user_count; j++) + { + if (!strcmp(channels[i]->users[j].nick, nick)) + { + return channels[i]->users[j].is_owner; + } + } + } + } + + return 0; +} + +#ifdef _WIN32 +MY_API BOOL is_admin(char *chan, char *nick) +#else +MY_API bool is_admin(char *chan, char *nick) +#endif +{ + int i; + + for (i = 0; i < chan_count; i++) + { + if (!strcmp(channels[i]->name, chan)) + { + int j; + + for (j = 0; j < channels[i]->user_count; j++) + { + if (!strcmp(channels[i]->users[j].nick, nick)) + { + return channels[i]->users[j].is_admin; + } + } + } + } + + return 0; +} + +#ifdef _WIN32 +MY_API BOOL channel_exists(char *chan) +#else +MY_API bool channel_exists(char *chan) +#endif +{ + int i; + + for (i = 0; i < chan_count; i++) + { + if (!strcmp(channels[i]->name, chan)) + { + return 1; + } + } + + return 0; +} + +#ifdef _WIN32 +MY_API BOOL user_exists(char *chan, char *nick) +#else +MY_API bool user_exists(char *chan, char *nick) +#endif +{ + int i; + + for (i = 0; i < chan_count; i++) + { + if (!strcmp(channels[i]->name, chan)) + { + int j; + + for (j = 0; j < channels[i]->user_count; j++) + { + if (!strcmp(channels[i]->users[j].nick, nick)) + { + return 1; + } + } + } + } + + return 0; +} + diff --git a/src/config.c b/src/config.c index 8521abb..bcd6fbf 100755 --- a/src/config.c +++ b/src/config.c @@ -39,7 +39,7 @@ struct irc_conn read_config(struct irc_conn bot, char *file) strlcpy(bot.port, base, sizeof bot.port); if (config_lookup_string(cf, "bot.admin", &base)) - bot.admin = (char *)base; + strlcpy(bot.admin, base, sizeof bot.admin); autoload = config_lookup(cf, "mods.autoload"); count = config_setting_length(autoload); diff --git a/src/events.c b/src/events.c index 1b56be0..f90c30f 100755 --- a/src/events.c +++ b/src/events.c @@ -38,7 +38,12 @@ void init_events() init_event_type(PRIVMSG_SELF); init_event_type(PRIVMSG_CHAN); init_event_type(JOIN); + init_event_type(JOIN_MYSELF); init_event_type(IRC_CONNECTED); + init_event_type(NICK_MYSELF); + init_event_type(NICK_INUSE); + init_event_type(CTCP); + init_event_type(IRC_NAMREPLY); } MY_API int add_handler(char *type, void *handler) @@ -92,6 +97,7 @@ void fire_handler(struct irc_conn *bot, char *type, ...) { va_list args; char *usr = calloc(1, 64); + char *host = calloc(1, 512); char *chan = calloc(1, 64); char *text = calloc(1, 512); int i, j; @@ -100,26 +106,19 @@ void fire_handler(struct irc_conn *bot, char *type, ...) modpath = (char *)malloc(sizeof(char)*500); - printf("Firing handler for type: %s\n", type); - if (!strcmp(type, PRIVMSG_SELF)) { - printf("Firing PRIVMSG_SELF handler\n"); va_start(args, type); usr = va_arg(args, char*); + host = va_arg(args, char*); text = va_arg(args, char*); cmd = text; arg = skip(cmd, ' '); - printf("cmd: %s\n", cmd); - printf("arg: %s\n", arg); - if (!strcmp("JOIN", cmd)) { - printf("dbug: cmp (%s : %s)\n", (char*)bot->admin, usr); - if (!strcmp(bot->admin, usr)) { irc_raw(bot, "JOIN :%s", arg); @@ -140,28 +139,24 @@ void fire_handler(struct irc_conn *bot, char *type, ...) irc_notice(bot, usr, "You are unauthorized to use this command."); } } - /* else if (!strcmp("PRINT_HANDLERS", cmd)) { if (!strcmp(bot->admin, usr)) { - for (i = 0; i < privmsg_chan->count; i++) + for (i = 0; i < handlers_count; i++) { - irc_notice(bot, usr, "handler[%i:%s]: %p", i, privmsg_chan->type, privmsg_chan->handlers[i]); - } - - for (i = 0; i < privmsg_self->count; i++) - { - irc_notice(bot, usr, "handler[%i:%s]: %p", i, privmsg_self->type, privmsg_self->handlers[i]); - } - - for (i = 0; i < irc_connected->count; i++) - { - irc_notice(bot, usr, "handler[%i:%s]: %p", i , irc_connected->type, irc_connected->handlers[i]); + irc_notice(bot, usr, "Handler type: %s\n", handlers[i]->type); + for (j = 0; j < handlers[i]->count; j++) + { + irc_notice(bot, usr, "Handler %d: %p\n", j, handlers[i]->evhands[j].handler); + } } } + else + { + irc_notice(bot, usr, "You are unauthorized to use this command."); + } } - */ else if (!strcmp("LOADMOD", cmd)) { if (!strcmp(bot->admin, usr)) @@ -197,9 +192,10 @@ void fire_handler(struct irc_conn *bot, char *type, ...) va_start(args, type); usr = va_arg(args, char*); + host = va_arg(args, char*); text = va_arg(args, char*); - (*handler)(bot, usr, text); + (*handler)(bot, usr, host, text); va_end(args); } else if (!strcmp(type, PRIVMSG_CHAN)) @@ -207,10 +203,11 @@ void fire_handler(struct irc_conn *bot, char *type, ...) va_start(args, type); usr = va_arg(args, char*); + host = va_arg(args, char*); chan = va_arg(args, char*); text = va_arg(args, char*); - (*handler)(bot, usr, chan, text); + (*handler)(bot, usr, host, chan, text); va_end(args); } else if (!strcmp(type, JOIN)) @@ -219,9 +216,9 @@ void fire_handler(struct irc_conn *bot, char *type, ...) chan = va_arg(args, char*); usr = va_arg(args, char*); + host = va_arg(args, char*); - (*handler)(bot, chan, usr); - + (*handler)(bot, chan, usr, host); va_end(args); } else if (!strcmp(type, IRC_CONNECTED)) diff --git a/src/irc.c b/src/irc.c index 5fca203..22eebcb 100755 --- a/src/irc.c +++ b/src/irc.c @@ -8,6 +8,8 @@ #include "irc.h" #include "util.h" #include "events.h" +#include "channel.h" + #include #include #include @@ -104,7 +106,7 @@ void irc_connect(struct irc_conn *bot) void irc_auth(struct irc_conn *bot) { irc_raw(bot, "NICK %s", bot->nick); - irc_raw(bot, "USER %s \" %s :xbot (v0.1) - developed by @Dark_Aaron", bot->nick, bot->host); + irc_raw(bot, "USER %s \" %s :xbot (v0.5) - developed by ab3800", bot->nick, bot->host); #ifndef _WIN32 fflush(bot->srv_fd); @@ -153,11 +155,45 @@ void irc_raw(struct irc_conn *bot, char *fmt, ...) #endif } + +void irc_join(struct irc_conn *bot, char *chan) +{ + irc_raw(bot, "JOIN %s", chan); + + add_channel(chan); +} + +void irc_part(struct irc_conn *bot, char *chan, char *reason) +{ + if (!reason) + { + reason = ""; + } + + irc_raw(bot, "PART %s :%s", chan, reason); +} + +void irc_ctcp(struct irc_conn *bot, char *to, char *fmt, ...) +{ + char msg_[4096]; + va_list ap; + + va_start(ap, fmt); + vsnprintf(msg_, sizeof msg_, fmt, ap); + va_end(ap); + + irc_privmsg(bot, to, "\001%s\001", msg_); +} + void irc_parse_raw(struct irc_conn *bot, char *raw) { - char *user, *par, *text; + char *user, *host, *par, *text, *chan, *nick, *nicks; user = bot->host; + text = calloc(1, strlen(raw) + 1); + + printf("raw: %s", raw); + if (!raw || !*raw) { return; @@ -173,14 +209,17 @@ void irc_parse_raw(struct irc_conn *bot, char *raw) return; } - skip(user, '!'); + host = skip(user, '!'); } skip(raw, '\r'); par = skip(raw, ' '); text = skip(par, ':'); + trim(par); + printf("dbug raw: %s\n", raw); + if (!strcmp("PONG", raw)) { return; @@ -188,25 +227,77 @@ void irc_parse_raw(struct irc_conn *bot, char *raw) if (!strcmp("PRIVMSG", raw)) { - if (!strcmp(par, bot->nick)) + // check for CTCP + if (text[0] == '\001') { - //handle_self_privmsg(bot, user, text); - fire_handler(bot, PRIVMSG_SELF, user, text); + char *ctcp = text + 1; + char *end = strchr(ctcp, '\001'); + + if (end) + { + *end = '\0'; + + // reply to version request + if (!strcmp("VERSION", ctcp)) + { +#ifdef _WIN32 + irc_notice(bot, user, "VERSION xbot: v0.5 (Windows) - Developed by ab3800"); +#else + irc_notice(bot, user, "VERSION xbot: v0.5 (Linux) - Developed by ab3800"); +#endif + } + else + { + fire_handler(bot, CTCP, user, host, par, ctcp); + } + } } else { - //handle_chan_privmsg(bot, user, par, text); - // - - fire_handler(bot, PRIVMSG_CHAN, user, par, text); + if (!strcmp(par, bot->nick)) + { + fire_handler(bot, PRIVMSG_SELF, user, host, text); + } + else + { + fire_handler(bot, PRIVMSG_CHAN, user, host, par, text); + } } } else if (!strcmp("JOIN", raw)) { - //handle_join(bot, user, par); - fire_handler(bot, JOIN, user, par); + if (!strcmp(user, bot->nick)) + { + add_channel(text); + add_user_to_channel(user, host, text); + fire_handler(bot, JOIN_MYSELF, user, host, text); + } + else + { + add_channel(text); + add_user_to_channel(user, host, text); + fire_handler(bot, JOIN, user, host, par); + } } + else if (!strcmp("PART", raw)) + { + if (!strcmp(user, bot->nick)) + { + remove_channel(text); + fire_handler(bot, PART_MYSELF, user, host, text); + } + else + { + remove_user_from_channel(user, text); + fire_handler(bot, PART, user, host, text); + } + } + else if (!strcmp("QUIT", raw)) + { + user_quit(user); + fire_handler(bot, QUIT, user, host, text); + } else if (!strcmp("PING", raw)) { irc_raw(bot, "PONG %s", text); @@ -215,11 +306,56 @@ void irc_parse_raw(struct irc_conn *bot, char *raw) { fire_handler(bot, IRC_CONNECTED, text); } + else if (!strcmp("433", raw)) + { + eprint("Error: Nickname '%s' is already in use\n", bot->nick); + + fire_handler(bot, NICK_INUSE, text); + +#ifdef _WIN32 + _snprintf(bot->nick, sizeof bot->nick, "%s_", bot->nick); +#else + snprintf(bot->nick, sizeof bot->nick, "%s_", bot->nick); +#endif + irc_raw(bot, "NICK %s", bot->nick); + } + else if (strstr("353", raw) != NULL) + { + printf("debug raw: %s\n", raw); + printf("debug par: %s, text: %s\n", par, text); + // par: BotName = #channel + // extract channel name + + chan = skip(par, ' '); + chan = skip(chan, '='); + chan = skip(chan, ' '); + + // text is a list of nicks separated by spaces +#ifdef _WIN32 + nicks = _strdup(text); +#else + nicks = strdup(text); +#endif + nick = strtok(nicks, " "); + + + printf("debug: chan: %s, nicks: %s\n", chan, nicks); + + while (nick) + { + add_user_to_channel(nick, "", chan); + nick = strtok(NULL, " "); + } + + fire_handler(bot, IRC_NAMREPLY, chan, text); + } else { if (!strcmp("NICK", raw) && !strcmp(user, bot->nick)) { strlcpy(bot->nick, text, sizeof bot->nick); + + fire_handler(bot, NICK_MYSELF, user, text); } } } diff --git a/src/main.c b/src/main.c index d6f522e..ebe6ed7 100755 --- a/src/main.c +++ b/src/main.c @@ -13,6 +13,8 @@ #include "irc.h" #include "util.h" #include "events.h" +#include "module.h" +#include "channel.h" #ifdef _WIN32 #include @@ -30,6 +32,8 @@ int main() struct irc_conn bot; struct timeval tv; + char *p; + int bytesRecv; init_events(); @@ -78,8 +82,6 @@ int main() return -1; } #endif - - else if (n == 0) { if (time(NULL) - trespond >= 300) @@ -111,6 +113,22 @@ int main() } bot.in[bytesRecv] = '\0'; + + printf("recv: %s\r\n", bot.in); + + // split bot.in into lines by \r\n and parse each one + + + while (1) + { + p = strchr(bot.in, '\n'); + if (p == NULL) + break; + + *p = '\0'; + irc_parse_raw(&bot, bot.in); + memmove(bot.in, p + 1, strlen(p + 1) + 1); + } #else if (FD_ISSET(fileno(bot.srv_fd), &rd)) { @@ -119,9 +137,10 @@ int main() eprint("xbot: remote host closed connection\n"); return 0; } -#endif + printf("recv: %s\r\n", bot.in); irc_parse_raw(&bot, bot.in); +#endif trespond = time(NULL); } } diff --git a/xbot.cfg b/xbot.cfg index dc74edc..90d23ff 100755 --- a/xbot.cfg +++ b/xbot.cfg @@ -3,7 +3,7 @@ bot: { verbose = 1; - nick = "Lin"; + nick = "Lini"; user = "xbot"; admin = "ab3800"; }; @@ -20,5 +20,5 @@ mods: blacklist = (); # config option for mods/autojoin.so - mod_autojoin = ("#lobby"); + mod_autojoin = ("#lobby", "#bots"); }; diff --git a/xbot.vcxproj b/xbot.vcxproj index 3618415..d909a22 100755 --- a/xbot.vcxproj +++ b/xbot.vcxproj @@ -103,6 +103,7 @@ + @@ -110,6 +111,7 @@ +