added get_userlist function to WHOHandler.c and wrote some test code
authorpk910 <philipp@zoelle1.de>
Thu, 11 Aug 2011 20:18:07 +0000 (22:18 +0200)
committerpk910 <philipp@zoelle1.de>
Thu, 11 Aug 2011 20:18:07 +0000 (22:18 +0200)
ClientSocket.c
ClientSocket.h
IRCParser.c
UserNode.h
WHOHandler.c
main.h

index 1d5e2f1fb60610548deb73d0a99138f36c56346c..2f80c71bbeee31e9bff8f7dfdd7672a26cf319ae 100644 (file)
@@ -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;
+}
index 39118ec51e57e526ccb42a84a6257f94da7d59f2..69d305779f2e811184258d801a5ad7435e0a884e 100644 (file)
@@ -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
index 710117cc4f646700c2c6ba924ec69116ec884a67..39f315040a66076ed8e2caa7de79215f160548f8 100644 (file)
@@ -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);
index bc5780bb39ade865b41fc771326aace4f31352a2..57e52c74c9c63dfc69efc260f3d80b1c75dc3181 100644 (file)
@@ -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;
     
index a5bbb80fdd93d48bde9e978b45b7a31927dcaddc..3cb31a702ca84497c6b84e2466f3545bc1bdd967 100644 (file)
@@ -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 b356c77c0a457e1104a4de0f9f5c3af85a5abbe5..802c1cbaea1d256db5df2087ba4581e488fdcd2c 100644 (file)
--- 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