X-Git-Url: http://git.pk910.de/?a=blobdiff_plain;f=IRCParser.c;h=8662f6d8399e3907f60ef1c9713cbc5a5e438d42;hb=795115bf680185ae01043bd1222b78bfed8c1d87;hp=3c996645f4efb5a01cb0bd25504dbf889c050f1d;hpb=be360908b0934781ca58dca1a831fe96dd116ddc;p=NeonServV5.git diff --git a/IRCParser.c b/IRCParser.c index 3c99664..8662f6d 100644 --- a/IRCParser.c +++ b/IRCParser.c @@ -6,6 +6,10 @@ #include "IRCEvents.h" #include "ClientSocket.h" #include "WHOHandler.h" +#include "lang.h" +#include "DBHelper.h" +#include "BanNode.h" +#include "ModeNode.h" struct irc_cmd *irc_commands = NULL; @@ -44,6 +48,7 @@ static void parse_line(struct ClientSocket *client, char *line) { if (*line == ':') { //the rest is a single parameter argv[argc++] = line + 1; + break; } argv[argc++] = line; if (argc >= MAXNUMPARAMS) @@ -78,23 +83,21 @@ static void parse_raw(struct ClientSocket *client, char *from, char *cmd, char * break; } } - if(!ret) { - //fprintf(stderr,"PARSE ERROR: %s", cmd); commented out right now - we're still developing and this is very spammy + if(!irc_cmd) { + event_raw(client, from, cmd, argv, argc); + } else if(!ret) { + fprintf(stderr,"PARSE ERROR: %s\n", cmd); } } static USERLIST_CALLBACK(got_channel_userlist) { struct ChanUser *chanuser = data; event_join(chanuser); - putsock(client, "PRIVMSG %s :[BOT JOIN] Users on this Channel:", chan->name); - for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) { - putsock(client, "PRIVMSG %s : %s!%s@%s [%s] rights: %d", chan->name, chanuser->user->nick, chanuser->user->ident, chanuser->user->host, ((chanuser->user->flags & USERFLAG_ISAUTHED) ? chanuser->user->auth : "*"), chanuser->flags); - } } static IRC_CMD(raw_001) { client->flags |= SOCKET_FLAG_READY; - putsock(client, "JOIN #pktest"); + event_bot_ready(client); return 1; } @@ -112,6 +115,8 @@ static IRC_CMD(raw_join) { chan->chanbot = user; struct ChanUser *chanuser = addChanUser(chan, user); //it must be a bot get_userlist(chan, got_channel_userlist, chanuser); + putsock(client, "MODE %s", chan->name); + putsock(client, "MODE %s +b", chan->name); } else if(!isUserOnChan(user, chan) && (chan->flags & CHANFLAG_RECEIVED_USERLIST)) { struct ChanUser *chanuser = addChanUser(chan, user); event_join(chanuser); @@ -120,7 +125,7 @@ static IRC_CMD(raw_join) { } static IRC_CMD(raw_part) { - if(from == NULL || argc < 2) return 0; + if(from == NULL || argc < 1) return 0; struct UserNode *user = getUserByMask(from); if(user == NULL) return 0; struct ChanNode *chan = getChanByName(argv[0]); @@ -128,7 +133,7 @@ static IRC_CMD(raw_part) { if(isUserOnChan(user, chan) && (chan->flags & CHANFLAG_RECEIVED_USERLIST)) { struct ChanUser *chanuser = getChanUser(user, chan); delChanUser(chanuser, 0); //we need to free the chanuser manually! - event_part(chanuser, argv[1]); + event_part(chanuser, (argc > 1 ? argv[1] : NULL)); free(chanuser); if(chan->chanbot == user) { //check if theres another bot in the channel - otherwise free it @@ -143,11 +148,11 @@ static IRC_CMD(raw_part) { } static IRC_CMD(raw_quit) { - if(from == NULL || argc < 2) return 0; + if(from == NULL || argc < 1) return 0; struct UserNode *user = getUserByMask(from); if(user == NULL) return 0; delUser(user, 0); //a little bit crazy, but we want to delete the user on the channel's userlists - but not the users channel list - event_quit(user, argv[1]); + event_quit(user, argv[0]); if(user->flags & USERFLAG_ISBOT) { //check if there are other bots in the users channel - otherwise free them struct ChanUser *chanuser, *next; @@ -188,9 +193,6 @@ static IRC_CMD(raw_kick) { delChanUser(chanuser, 0); //we need to free the chanuser manually! event_kick(user, chanuser, argv[1]); free(chanuser); - if(user->flags & USERFLAG_ISTMPUSER) { - free(user); - } if(target->flags & USERFLAG_ISBOT) { //check if theres another bot in the channel - otherwise free it checkChannelVisibility(chan); @@ -198,7 +200,7 @@ static IRC_CMD(raw_kick) { } if(target->channel == NULL && !(target->flags & USERFLAG_ISBOT)) { //remove the user - delUser(user, 1); + delUser(target, 1); } return 1; } @@ -215,9 +217,6 @@ static IRC_CMD(raw_topic) { } event_topic(user, chan, argv[1]); strcpy(chan->topic, argv[1]); - if(user->flags & USERFLAG_ISTMPUSER) { - free(user); - } return 1; } @@ -229,20 +228,71 @@ static IRC_CMD(raw_privmsg) { user->flags |= USERFLAG_ISTMPUSER; } if(argv[0][0] == '#') { //Channel message + struct ChanNode *chan = getChanByName(argv[0]); + if(chan && chan->chanbot == client->user) { + if(argv[1][0] == '\001') { + char *cmd = &argv[1][1]; + char *text = strstr(cmd, " "); + if(text) { + *text = '\0'; + text++; + if(strlen(text) && text[strlen(text)-1] == '\001') + text[strlen(text)-1] = '\0'; + } else if(strlen(cmd) && cmd[strlen(cmd)-1] == '\001') + cmd[strlen(cmd)-1] = '\0'; + event_chanctcp(user, chan, cmd, text); + } else + event_chanmsg(user, chan, argv[1]); + } + } else { + struct UserNode *target = getUserByNick(argv[0]); + if(target) { + if(argv[1][0] == '\001') { + char *cmd = &argv[1][1]; + char *text = strstr(cmd, " "); + if(text) { + *text = '\0'; + text++; + if(strlen(text) && text[strlen(text)-1] == '\001') + text[strlen(text)-1] = '\0'; + } else if(strlen(cmd) && cmd[strlen(cmd)-1] == '\001') + cmd[strlen(cmd)-1] = '\0'; + event_privctcp(user, target, cmd, text); + } else + event_privmsg(user, target, argv[1]); + } + } + return 1; +} + +static IRC_CMD(raw_notice) { + if(from == NULL || argc < 2) return 0; + struct UserNode *user = getUserByMask(from); + if(user == NULL) { + user = createTempUser(from); + user->flags |= USERFLAG_ISTMPUSER; + } + if(argv[0][0] == '#') { //Channel notice struct ChanNode *chan = getChanByName(argv[0]); if(chan && chan->chanbot == client->user) - event_chanmsg(user, chan, argv[1]); + event_channotice(user, chan, argv[1]); } else { struct UserNode *target = getUserByNick(argv[0]); if(target) - event_privmsg(user, target, argv[1]); - } - if(user->flags & USERFLAG_ISTMPUSER) { - free(user); + event_privnotice(user, target, argv[1]); } return 1; } +static IRC_CMD(raw_nick) { + if(from == NULL || argc == 0) return 0; + struct UserNode *user = getUserByMask(from); + if(user == NULL) return 0; + event_nick(user, argv[0]); + renameUser(user, argv[0]); + return 1; +} + static IRC_CMD(raw_ping) { if(argc == 0) return 0; putsock(client, "PONG :%s", argv[0]); @@ -259,16 +309,119 @@ static IRC_CMD(raw_315) { return 1; } -void parser_init() { +static IRC_CMD(raw_324) { //MODE LIST + //Watchcat #pktest +stnzN + if(from == NULL || argc < 3) return 0; + struct ChanNode *chan = getChanByName(argv[1]); + if(chan == NULL) return 0; + parseModes(chan->modes, argv[2], argv+3, argc-3); + return 1; +} + +static IRC_CMD(raw_invite) { + if(from == NULL || argc < 2) return 0; + struct UserNode *user = getUserByMask(from); + if(user == NULL) { + user = createTempUser(from); + user->flags |= USERFLAG_ISTMPUSER; + } + event_invite(client, user, argv[1]); + return 1; +} + +static IRC_CMD(raw_mode) { + if(from == NULL || argc < 2) return 0; + struct UserNode *user = getUserByMask(from); + if(user == NULL) { + user = createTempUser(from); + user->flags |= USERFLAG_ISTMPUSER; + } + if(argv[0][0] == '#') { + //ChannelMode + struct ChanNode *chan = getChanByName(argv[0]); + if(!chan) return 0; + if(chan->chanbot != client->user) return 1; + event_mode(user, chan, argv[1], argv+2, argc-2); + parseModes(chan->modes, argv[1], argv+2, argc-2); + } else { + //UserMode + } + return 1; +} + +static IRC_CMD(raw_367) { + //Watchcat #pktest pk911!*@* TestBot!~bot@pktest.user.WebGamesNet 1315863279 + struct ChanNode *chan = getChanByName(argv[1]); + if(!chan) return 0; + struct BanNode *ban; + while((ban = getMatchingChannelBan(chan, argv[2]))) { + removeChannelBan(ban); + } + addChannelBan(chan, argv[2]); + return 1; +} + +void init_parser() { //all the raws we receive... register_irc_function("001", raw_001); + register_irc_function("324", raw_324); + register_irc_function("367", raw_367); + register_irc_function("INVITE", raw_invite); + register_irc_function("NOTICE", raw_notice); register_irc_function("TOPIC", raw_topic); register_irc_function("KICK", raw_kick); - register_irc_function("JOIN", raw_join); register_irc_function("PART", raw_part); register_irc_function("QUIT", raw_quit); + register_irc_function("JOIN", raw_join); + register_irc_function("MODE", raw_mode); + register_irc_function("NICK", raw_nick); register_irc_function("354", raw_354); register_irc_function("315", raw_315); register_irc_function("PING", raw_ping); register_irc_function("PRIVMSG", raw_privmsg); } + +void free_parser() { + struct irc_cmd *cmd, *next; + for(cmd = irc_commands; cmd; cmd = next) { + next = cmd->next; + free(cmd); + } +} + +void reply(struct ClientSocket *client, struct UserNode *user, const char *text, ...) { + const char *reply_format = get_language_string(user, text); + if(reply_format == NULL) + reply_format = text; + loadUserSettings(user); + char formatBuf[MAXLEN]; + sprintf(formatBuf, "%s %s :%s", ((user->flags & USERFLAG_REPLY_PRIVMSG) ? "PRIVMSG" : "NOTICE"), user->nick, reply_format); + va_list arg_list; + char sendBuf[MAXLEN]; + int pos; + if (!(client->flags & SOCKET_FLAG_CONNECTED)) return; + sendBuf[0] = '\0'; + va_start(arg_list, text); + pos = vsnprintf(sendBuf, MAXLEN - 2, formatBuf, arg_list); + va_end(arg_list); + if (pos < 0 || pos > (MAXLEN - 2)) pos = MAXLEN - 2; + sendBuf[pos] = '\n'; + sendBuf[pos+1] = '\0'; + write_socket(client, sendBuf, pos+1); +} + +char* merge_argv(char **argv, int start, int end) { + return merge_argv_char(argv, start, end, ' '); +} + +char* merge_argv_char(char **argv, int start, int end, char seperator) { + int i; + char *p = NULL; + for(i = start; i < end; i++) { + p = argv[i]; + while(*p) p++; + *p = seperator; + } + if(p) *p = '\0'; + return argv[start]; +}