From: pk910 Date: Thu, 11 Aug 2011 20:18:07 +0000 (+0200) Subject: added get_userlist function to WHOHandler.c and wrote some test code X-Git-Tag: v5.3~613 X-Git-Url: http://git.pk910.de/?p=NeonServV5.git;a=commitdiff_plain;h=5622bbfedec4a8162cefa18b4c0a00dd1990405b added get_userlist function to WHOHandler.c and wrote some test code --- diff --git a/ClientSocket.c b/ClientSocket.c index 1d5e2f1..2f80c71 100644 --- a/ClientSocket.c +++ b/ClientSocket.c @@ -189,3 +189,12 @@ putsock(struct ClientSocket *client, const char *text, ...) write_socket(client, sendBuf, pos+1); } +struct ClientSocket* getBots(int flags, struct ClientSocket* last_bot) { + struct ClientSocket *sock = (last_bot ? last_bot->next : sockets->data); + if(sock == NULL) return NULL; + for (; sock; sock = sock->next) { + if((sock->flags & flags) == flags) + return sock; + } + return NULL; +} diff --git a/ClientSocket.h b/ClientSocket.h index 39118ec..69d3057 100644 --- a/ClientSocket.h +++ b/ClientSocket.h @@ -3,9 +3,10 @@ #include "main.h" -#define SOCKET_FLAG_DEAD 0x01 +#define SOCKET_FLAG_DEAD 0x01 #define SOCKET_FLAG_CONNECTED 0x02 -#define SOCKET_FLAG_READY 0x04 +#define SOCKET_FLAG_READY 0x04 +#define SOCKET_FLAG_NOWHO 0x08 #define BUF_SIZ 512 @@ -30,5 +31,6 @@ int close_socket(struct ClientSocket *client); int write_socket(struct ClientSocket *client, char* msg, int len); void socket_loop(int timeout_seconds); void putsock(struct ClientSocket *client, const char *text, ...) PRINTF_LIKE(2, 3); +struct ClientSocket* getBots(int flags, struct ClientSocket* last_bot); #endif \ No newline at end of file diff --git a/IRCParser.c b/IRCParser.c index 710117c..39f3150 100644 --- a/IRCParser.c +++ b/IRCParser.c @@ -84,7 +84,11 @@ static void parse_raw(struct ClientSocket *client, char *from, char *cmd, char * } static USERLIST_CALLBACK(got_channel_userlist) { - chan->flags |= CHANFLAG_RECEIVED_USERLIST; + putsock(client, "PRIVMSG %s :[BOT JOIN] Users on this Channel:", chan->name); + struct ChanUser *chanuser; + for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) { + putsock(client, "PRIVMSG %s : %s!%s@%s [%s] rights: %d", chanuser->user->nick, chanuser->user->ident, chanuser->user->host, ((chanuser->user->flags & USERFLAG_ISAUTHED) ? chanuser->user->auth : "0"), chanuser->flags); + } } static IRC_CMD(raw_001) { @@ -103,6 +107,7 @@ static IRC_CMD(raw_join) { if(chan == NULL) { chan = addChannel(argv[0]); //request member list + addChanUser(chan, user); //it must be a bot get_userlist(chan, got_channel_userlist); } else if(!isUserOnChan(user, chan) && (chan->flags & CHANFLAG_RECEIVED_USERLIST)) { struct ChanUser *chanuser = addChanUser(chan, user); diff --git a/UserNode.h b/UserNode.h index bc5780b..57e52c7 100644 --- a/UserNode.h +++ b/UserNode.h @@ -2,7 +2,9 @@ #define _UserNode_h #include "main.h" -#define USERFLAG_ISBOT 0x01 +#define USERFLAG_ISBOT 0x01 +#define USERFLAG_ISAUTHED 0x02 +#define USERFLAG_ISIRCOP 0x04 struct ChanUser; struct UserNode { @@ -10,6 +12,7 @@ struct UserNode { char ident[USERLEN+1]; char host[HOSTLEN+1]; char realname[REALLEN+1]; + char auth[AUTHLEN+1]; char flags; struct ChanUser *channel; diff --git a/WHOHandler.c b/WHOHandler.c index a5bbb80..3cb31a7 100644 --- a/WHOHandler.c +++ b/WHOHandler.c @@ -3,16 +3,21 @@ #include "ChanNode.h" #include "UserNode.h" +#define WHOQUEUETYPE_ISONQUEUE 0x01 +#define WHOQUEUETYPE_USERLIST 0x02 + struct WHOQueueEntry { char type; + struct ClientSocket *client; struct ChanNode *chan; struct UserNode *user; struct WHOQueueEntry *next; + userlist_callback_t callback; } static struct WHOQueueEntry *first_entry = NULL, *last_entry = NULL; -static struct WHOQueueEntry* addWHOQueueEntry() { +static struct WHOQueueEntry* addWHOQueueEntry(struct ClientSocket *client) { struct WHOQueueEntry *entry = malloc(sizeof(*entry)); if (!entry) { @@ -20,15 +25,21 @@ static struct WHOQueueEntry* addWHOQueueEntry() { return NULL; } entry->next = NULL; + entry->client = client; if(last_entry) last_entry->next = entry; if(!first_entry) first_entry = entry; } -static struct WHOQueueEntry* getNextWHOQueueEntry(int remove) { +static struct WHOQueueEntry* getNextWHOQueueEntry(struct ClientSocket *client, int remove) { if(!first_entry) return NULL; - struct WHOQueueEntry *entry = first_entry; + struct WHOQueueEntry *entry; + for(entry = first_entry; entry; entry = entry->next) { + if(entry->client == client) + break; + } + if(entry == NULL) return NULL; if(remove) { first_entry = first_entry->next; if(last_entry == first_entry) @@ -38,16 +49,81 @@ static struct WHOQueueEntry* getNextWHOQueueEntry(int remove) { } void get_userlist(struct ChanNode *chan, userlist_callback_t callback) { - + struct ClientSocket *bot; + for(bot = getBots(SOCKET_FLAG_READY, NULL); bot; bot = getBots(SOCKET_FLAG_READY, bot)) { + if(isUserOnChan(bot->user, chan)) + break; + } + if(bot == NULL) return; + struct WHOQueueEntry* entry = addWHOQueueEntry(bot); + entry->type = WHOQUEUETYPE_ISONQUEUE | WHOQUEUETYPE_USERLIST; + entry->chan = chan; + entry->callback = callback; + //WHO ".$channel->getName().",".$id." d%tuhnaf,".$id + putsock(bot, "WHO %s,%d %tuhnaf,%d", chan->name, entry->type, entry->type); } void recv_whohandler_354(struct ClientSocket *client, char **argv, unsigned int argc) { - struct WHOQueueEntry* entry = getNextWHOQueueEntry(0); - + int i; + if(argc < 2) return; + int type = atoi(argv[1]); + if(!(type & WHOQUEUETYPE_ISONQUEUE)) return; + struct WHOQueueEntry* entry = getNextWHOQueueEntry(client, 0); + if(entry == NULL || entry->type != type) return; + if(type & WHOQUEUETYPE_USERLIST) { + if(argc < 7) return; + //:OGN2.OnlineGamesNet.net 354 skynet 1 pk910 2001:41d0:2:1d3b::babe skynet H@ pk910 + struct ChanNode *chan = entry->chan; + //add the user toe the channel if he isn't added, yet and update its user data + struct UserNode *user = getUserByNick(argv[4]); + if(user == NULL) { + user = addUser(argv[4]); + } + //parse flags + int userflags = 0; + int chanuserflags = 0; + for(i = 0; i < strlen(argv[5]); i++) { + switch (argv[5][i]) { + case '@': + chanuserflags |= CHANUSERFLAG_OPPED; + break; + case '+': + chanuserflags |= CHANUSERFLAG_VOICED; + break; + case '*': + userflags |= USERFLAG_ISIRCOP; + break; + default: + break; + } + } + user->flags = (user->flags & ~USERFLAG_ISIRCOP) | userflags; + if(!isUserOnChan(user, chan)) { + struct ChanUser *chanuser = addChanUser(chan, user); + chanuser->flags = (chanuser->flags & ~CHANUSERFLAG_OPPED_OR_VOICED) | chanuserflags; + } + if(!*user->ident) + strcpy(user->ident, argv[2]); + if(!*user->host) + strcpy(user->host, argv[3]); + if(!(user->flags & USERFLAG_ISAUTHED) && strcmp(argv[6], "0")) { + strcpy(user->auth, argv[6]); + user->flags |= USERFLAG_ISAUTHED; + } + } } void recv_whohandler_315(struct ClientSocket *client, char **argv, unsigned int argc) { - struct WHOQueueEntry* entry = getNextWHOQueueEntry(1); - + if(argc < 2) return; + char *typestr = strstr(argv[1], ",") + 1; + int type = atoi(typestr); + if(!(type & WHOQUEUETYPE_ISONQUEUE)) return; + struct WHOQueueEntry* entry = getNextWHOQueueEntry(client, 1); + if(entry == NULL || entry->type != type) return; + if(type & WHOQUEUETYPE_USERLIST) { + //:OGN2.OnlineGamesNet.net 315 skynet #pk910,1 :End of /WHO list. + entry->chan->flags |= CHANFLAG_RECEIVED_USERLIST; + entry->callback(client, entry->chan); + } free(entry); } diff --git a/main.h b/main.h index b356c77..802c1cb 100644 --- a/main.h +++ b/main.h @@ -44,6 +44,7 @@ int stricmp (const char *s1, const char *s2) #define NICKLEN 30 #define USERLEN 10 +#define AUTHLEN 32 #define HOSTLEN 63 #define REALLEN 50 #define TOPICLEN 500