added channel.c

This commit is contained in:
Aaron Blakely 2024-02-16 15:28:11 -06:00
parent 7635b513d7
commit c0de3e4bbc
16 changed files with 731 additions and 71 deletions

View File

@ -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!"

View File

@ -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"
}
]

74
lib/channel.h Executable file
View File

@ -0,0 +1,74 @@
#ifndef CHANNEL_H
#define CHANNEL_H
#ifdef _WIN32
#include <windef.h>
#else
#include <stdbool.h>
#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

View File

@ -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
{

View File

@ -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

View File

@ -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, ...);

View File

@ -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);

View File

@ -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);

View File

@ -5,12 +5,12 @@
#include <stdlib.h>
#include <string.h>
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"))
{

403
src/channel.c Executable file
View File

@ -0,0 +1,403 @@
#include "irc.h"
#include "util.h"
#include "events.h"
#include "module.h"
#include "channel.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
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;
}

View File

@ -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);

View File

@ -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))

160
src/irc.c
View File

@ -8,6 +8,8 @@
#include "irc.h"
#include "util.h"
#include "events.h"
#include "channel.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
@ -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);
}
}
}

View File

@ -13,6 +13,8 @@
#include "irc.h"
#include "util.h"
#include "events.h"
#include "module.h"
#include "channel.h"
#ifdef _WIN32
#include <winsock2.h>
@ -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);
}
}

View File

@ -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");
};

View File

@ -103,6 +103,7 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="lib\channel.h" />
<ClInclude Include="lib\config.h" />
<ClInclude Include="lib\events.h" />
<ClInclude Include="lib\irc.h" />
@ -110,6 +111,7 @@
<ClInclude Include="lib\util.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\channel.c" />
<ClCompile Include="src\config.c" />
<ClCompile Include="src\events.c" />
<ClCompile Include="src\irc.c" />