-/* IRCParser.c - NeonServ v5.3
+/* IRCParser.c - NeonServ v5.4
* Copyright (C) 2011-2012 Philipp Kreil (pk910)
*
* This program is free software: you can redistribute it and/or modify
//request member list
chan->chanbot = user;
struct ChanUser *chanuser = addChanUser(chan, user); //it must be a bot
- get_userlist_with_invisible(chan, got_channel_userlist, chanuser);
+ get_userlist_with_invisible(chan, 0, 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) || isBot(user))) {
static IRC_CMD(raw_privmsg) {
if(from == NULL || argc < 2) return 0;
+ if(!stricmplen(from, "*status", 7) || !stricmplen(from, "-sBNC", 5)) {
+ #ifdef HAVE_THREADS
+ unsigned int tid = (unsigned int) pthread_self_tid();
+ while(!clientsocket_parseorder_top(tid)) {
+ usleep(1000); //1ms
+ }
+ #endif
+ if(!match("Disconnected from IRC.*", argv[1])) {
+ //ZNC DISCONNECT
+ bot_disconnect(client);
+ return 1;
+ }
+ if(!match("* disconnected from the server.", argv[1])) {
+ //sBNC DISCONNECT
+ bot_disconnect(client);
+ return 1;
+ }
+ }
struct UserNode *user = getUserByMask(from);
if(user == NULL) {
user = createTempUserMask(from);
if(!user) return 0;
user->flags |= USERFLAG_ISTMPUSER;
}
- if(!stricmp(user->nick, "*status") && !match("Disconnected from IRC.*", argv[1])) {
- //ZNC DISCONNECT
- bot_disconnect(client);
- return 1;
- }
- if(!stricmp(user->nick, "-sBNC") && !match("* disconnected from the server.", argv[1])) {
- //sBNC DISCONNECT
- bot_disconnect(client);
- return 1;
- }
if(argv[0][0] == '#') { //Channel message
struct ChanNode *chan = getChanByName(argv[0]);
if(chan && chan->chanbot == client->user) {
return 1;
}
+static void client_renamed(struct ClientSocket *client);
+
static IRC_CMD(raw_nick) {
if(from == NULL || argc == 0) return 0;
struct UserNode *user = getUserByMask(from);
if(user == NULL) return 0;
- if(!is_firstBotSeeUser(client, user)) return 1; //we ignore it - but it's not a parse error
+ if(isBot(user)) {
+ if(client->user != user) return 1;
+ client_renamed(client);
+ }
+ else if(!is_firstBotSeeUser(client, user)) return 1; //we ignore it - but it's not a parse error
event_nick(user, argv[0]);
renameUser(user, argv[0]);
return 1;
return 1;
}
+struct ClientRenamePartedChannel {
+ char channel[CHANNELLEN+1];
+ struct ClientRenamePartedChannel *next;
+};
+
+static IRC_CMD(raw_437) { //can NOT change nick
+ struct ClientRenamePartedChannel *partedchan = malloc(sizeof(*partedchan));
+ strcpy(partedchan->channel, argv[1]);
+ if((client->flags & SOCKET_FLAG_CHANGENICK))
+ partedchan->next = client->changenick_channels;
+ else
+ partedchan->next = NULL;
+ client->changenick_channels = partedchan;
+ client->flags |= SOCKET_FLAG_CHANGENICK;
+ putsock(client, "PART %s", argv[1]);
+ putsock(client, "NICK %s", client->nick);
+ return 1;
+}
+
+static void client_renamed(struct ClientSocket *client) {
+ if((client->flags & SOCKET_FLAG_CHANGENICK)) {
+ struct ClientRenamePartedChannel *partedchan, *nextchan;
+ for(partedchan = client->changenick_channels; partedchan; partedchan = nextchan) {
+ nextchan = partedchan->next;
+ putsock(client, "JOIN %s", partedchan->channel);
+ free(partedchan);
+ }
+ client->flags &= ~SOCKET_FLAG_CHANGENICK;
+ }
+}
+
void init_parser() {
//all the raws we receive...
+ register_irc_function("437", raw_437);
register_irc_function("002", raw_002);
register_irc_function("251", raw_251);
register_irc_function("254", raw_254);