completed cmd_chanservsync
authorpk910 <philipp@zoelle1.de>
Sun, 11 Sep 2011 01:42:22 +0000 (03:42 +0200)
committerpk910 <philipp@zoelle1.de>
Sun, 11 Sep 2011 02:06:47 +0000 (04:06 +0200)
bot_NeonServ.c
cmd_neonserv_chanservsync.c

index 16422f78530d446c1becc17e342a6444a001f713..137ba28211fe072ebefbb3ba320e14908c1c1040 100644 (file)
@@ -154,6 +154,8 @@ static const struct default_language_entry msgtab[] = {
     {"NS_CHANSERVSYNC_UNSUPPORTED", "\0034WARNING\003: the user list style of %s is not known. %s can try to synchronize the userlist, but there is no guarantee that it is successful!"},
     {"NS_CHANSERVSYNC_KEY", "If you really want to synchronize the %s userlist with %s use: chanservsync %s %s"},
     {"NS_CHANSERVSYNC_INUSE", "\002chanservsync\002 is already in use by someone else. Please try again in a few seconds..."},
+    {"NS_CHANSERVSYNC_SYNCHRONIZING", "Synchronizing userlist in %s with \002%s\002..."},
+    {"NS_CHANSERVSYNC_SYNCHRONIZED", "Synchronized user \002%s\002: access \002%d\002"},
     {NULL, NULL}
 };
 
index d95f95fde909df95cc70cafbaba84720ed80e23c..67123dffbd49984731b4e5d40166aaa29f2e6a6c 100644 (file)
@@ -7,6 +7,8 @@
 
 static void neonserv_cmd_chanservsync_notice_listener(struct UserNode *user, struct UserNode *target, char *message);
 static void neonserv_cmd_chanservsync_free_cache();
+static AUTHLOOKUP_CALLBACK(neonserv_cmd_chanservsync_auth_lookup);
+static void neonserv_cmd_chanservsync_synchronize_user(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, char *username, int userid, int caccess, time_t seen, int flags, int new);
 
 struct neonserv_cmd_chanservsync_cache {
     struct ClientSocket *client, *textclient;
@@ -16,6 +18,15 @@ struct neonserv_cmd_chanservsync_cache {
     time_t last_response;
 };
 
+struct neonserv_cmd_chanservsync_auth_cache {
+    struct ClientSocket *client, *textclient;
+    struct UserNode *user;
+    struct ChanNode *chan;
+    int caccess;
+    time_t seen;
+    int flags;
+};
+
 struct neonserv_cmd_chanservsync_cache *neonserv_cmd_chanservsync_used = NULL;
 const char* neonserv_cmd_chanservsync_supported[] = {"ChanServ", NULL};
 
@@ -78,6 +89,7 @@ static CMD_BIND(neonserv_cmd_chanservsync) {
     neonserv_cmd_chanservsync_used = cache;
     putsock(client, "PRIVMSG %s :users %s", botnick, chan->name);
     bind_privnotice(neonserv_cmd_chanservsync_notice_listener);
+    reply(getTextBot(), user, "NS_CHANSERVSYNC_SYNCHRONIZING", chan->name, botnick);
 }
 
 static void neonserv_cmd_chanservsync_notice_listener(struct UserNode *user, struct UserNode *target, char *message) {
@@ -108,10 +120,24 @@ static void neonserv_cmd_chanservsync_notice_listener(struct UserNode *user, str
         if(*p) {
             tokens[tokensPos++] = p;
         }
-        if(tokensPos < 2) return;
-        int caccess = atoi(tokens[0]);
+        int caccess;
+        char *username;
+        if(tokensPos == 1) {
+            //maybe a chip-like userlist
+            if(tokens[0][0] == '@') {
+                caccess = 200;
+                username = &tokens[0][1];
+            } else if(tokens[0][0] == '+') {
+                caccess = 100;
+                username = &tokens[0][1];
+            } else
+                return;
+        } else if(tokensPos >= 2) {
+            caccess = atoi(tokens[0]);
+            username = tokens[1];
+        } else
+            return;
         if(caccess < 1 || caccess > 500) return;
-        char *username = tokens[1];
         int flags = 0;
         time_t now = time(0);
         time_t seen_time = now; //now - now = 0 (never)
@@ -147,7 +173,35 @@ static void neonserv_cmd_chanservsync_notice_listener(struct UserNode *user, str
                 seen_time = strToTime(user, seen);
         }
         seen_time = now - seen_time;
-        reply(neonserv_cmd_chanservsync_used->textclient, neonserv_cmd_chanservsync_used->user, "\002PARSED LINE!\002 Access: %d  User: %s  Seen: %lu  State: %d", caccess, username, (unsigned long) seen_time, flags);
+        //we've collected all information now. synchronize the user (use the higher access if the user is already added)
+        MYSQL_RES *res;
+        MYSQL_ROW row;
+        int userid;
+        printf_mysql_query("SELECT `user_id` FROM `users` WHERE `user_user` = '%s'", escape_string(username));
+        res = mysql_use();
+        if ((row = mysql_fetch_row(res)) != NULL) {
+            userid = atoi(row[0]);
+            neonserv_cmd_chanservsync_synchronize_user(neonserv_cmd_chanservsync_used->client, neonserv_cmd_chanservsync_used->textclient, neonserv_cmd_chanservsync_used->user, neonserv_cmd_chanservsync_used->chan, username, userid, caccess, seen_time, flags, 0);
+        } else if(!stricmp(user->nick, "chanserv")) {
+            printf_mysql_query("INSERT INTO `users` (`user_user`) VALUES ('%s')", escape_string(username));
+            userid = (int) mysql_insert_id(mysql_conn);
+            neonserv_cmd_chanservsync_synchronize_user(neonserv_cmd_chanservsync_used->client, neonserv_cmd_chanservsync_used->textclient, neonserv_cmd_chanservsync_used->user, neonserv_cmd_chanservsync_used->chan, username, userid, caccess, seen_time, flags, 1);
+        } else {
+            //lookup auth
+            struct neonserv_cmd_chanservsync_auth_cache *cache = malloc(sizeof(*cache));
+            if (!cache) {
+                perror("malloc() failed");
+                return;
+            }
+            cache->client = neonserv_cmd_chanservsync_used->client;
+            cache->textclient = neonserv_cmd_chanservsync_used->textclient;
+            cache->user = neonserv_cmd_chanservsync_used->user;
+            cache->chan = neonserv_cmd_chanservsync_used->chan;
+            cache->caccess = caccess;
+            cache->seen = seen_time;
+            cache->flags = flags;
+            lookup_authname(username, neonserv_cmd_chanservsync_auth_lookup, cache);
+        }
     }
 }
 
@@ -158,3 +212,35 @@ static void neonserv_cmd_chanservsync_free_cache() {
     neonserv_cmd_chanservsync_used = NULL;
 }
 
+static AUTHLOOKUP_CALLBACK(neonserv_cmd_chanservsync_auth_lookup) {
+    struct neonserv_cmd_chanservsync_auth_cache *cache = data;
+    if(exists) {
+        printf_mysql_query("INSERT INTO `users` (`user_user`) VALUES ('%s')", escape_string(auth));
+        int userid = (int) mysql_insert_id(mysql_conn);
+        neonserv_cmd_chanservsync_synchronize_user(cache->client, cache->textclient, cache->user, cache->chan, auth, userid, cache->caccess, cache->seen, cache->flags, 1);
+    }
+    free(cache);
+}
+
+static void neonserv_cmd_chanservsync_synchronize_user(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, char *username, int userid, int caccess, time_t seen, int flags, int new) {
+    //just sync the user with the given userid with the providet information
+    if(caccess == 500) caccess = 499;
+    if(new) {
+        //just add
+        printf_mysql_query("INSERT INTO `chanusers` (`chanuser_cid`, `chanuser_uid`, `chanuser_access`, `chanuser_seen`, `chanuser_flags`) VALUES ('%d', '%d', '%d', '%lu', '%d')", chan->channel_id, userid, caccess, (unsigned long) seen, flags);
+    } else {
+        MYSQL_RES *res;
+        MYSQL_ROW row;
+        //check if already added
+        printf_mysql_query("SELECT `chanuser_access`, `chanuser_id`, `chanuser_seen` FROM `chanusers` WHERE `chanuser_cid` = '%d' AND `chanuser_uid` = '%d'", chan->channel_id, userid);
+        res = mysql_use();
+        if ((row = mysql_fetch_row(res)) != NULL) {
+            //clvl
+            if(atoi(row[0]) >= caccess) return;
+            if(atol(row[2]) > seen) seen = atol(row[2]);
+            printf_mysql_query("UPDATE `chanusers` SET `chanuser_access` = '%d', `chanuser_seen` = '%lu' WHERE `chanuser_id` = '%s'", caccess, (unsigned long) seen, row[1]);
+        } else 
+            printf_mysql_query("INSERT INTO `chanusers` (`chanuser_cid`, `chanuser_uid`, `chanuser_access`, `chanuser_seen`, `chanuser_flags`) VALUES ('%d', '%d', '%d', '%lu', '%d')", chan->channel_id, userid, caccess, (unsigned long) seen, flags);
+    }
+    reply(textclient, user, "NS_CHANSERVSYNC_SYNCHRONIZED", username, caccess);
+}