added cmd_register
authorpk910 <philipp@zoelle1.de>
Mon, 12 Sep 2011 02:05:12 +0000 (04:05 +0200)
committerpk910 <philipp@zoelle1.de>
Mon, 12 Sep 2011 02:09:38 +0000 (04:09 +0200)
DATABASE.txt
bot_NeonServ.c
cmd_neonserv_register.c [new file with mode: 0644]
modcmd.c
modcmd.h

index 053096a56c8063cc0305bc842cf8728bd6c492f9..77ba154a86d94d22c8b4b0481b164dd9cb0588e2 100644 (file)
@@ -35,3 +35,5 @@ ALTER TABLE `bans` CHANGE `ban_owner` `ban_owner` INT( 11 ) NOT NULL;
 
 ALTER TABLE `channels` ADD `channel_exttopic` TINYINT( 1 ) NOT NULL AFTER `channel_topicmask` ,
 ADD `channel_exttopic_topic` VARCHAR( 512 ) NOT NULL AFTER `channel_exttopic`;
+
+ALTER TABLE `bots` ADD `max_channels` INT( 5 ) NOT NULL ;
\ No newline at end of file
index 137ba28211fe072ebefbb3ba320e14908c1c1040..91c699fc6d5634cedddf84034fadd96e8044494d 100644 (file)
@@ -156,6 +156,11 @@ static const struct default_language_entry msgtab[] = {
     {"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"},
+    {"NS_REGISTER_ALREADY", "%s is already registered with %s."},
+    {"NS_INVALID_CHANNEL_NAME", "%s is not a valid channel name."},
+    {"NS_REGISTER_FULL", "the bot can not join more channels."},
+    {"NS_REGISTER_DISCONNECTED", "%s has been registered with a Bot, that is currently NOT connected. The Bot should join the channel, when it reconnects to the IRC-Network."},
+    {"NS_REGISTER_DONE", "\002%s\002 is now registered to \002%s\002."},
     {NULL, NULL}
 };
 
@@ -217,7 +222,7 @@ INCLUDE ALL CMD's HERE
 //#include "cmd_neonserv_bind.c"
 //#include "cmd_neonserv_unbind.c"
 //#include "cmd_neonserv_modcmd.c"
-//#include "cmd_neonserv_register.c"
+#include "cmd_neonserv_register.c"
 //#include "cmd_neonserv_unregister.c"
 //#include "cmd_neonserv_allowregister.c"
 //#include "cmd_neonserv_noregister.c"
@@ -343,7 +348,7 @@ void init_NeonServ() {
     register_command(BOTID, "chanservsync", neonserv_cmd_chanservsync, 0, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH,  "500",               0);
     
     register_command(BOTID, "trace",        neonserv_cmd_trace,     1, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH,                                                   NULL,                   400);
-    
+    register_command(BOTID, "register",     neonserv_cmd_register,  2, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_CHAN_PARAM,                              NULL,                   100);
     
     start_bots();
     bind_bot_ready(neonserv_bot_ready);
diff --git a/cmd_neonserv_register.c b/cmd_neonserv_register.c
new file mode 100644 (file)
index 0000000..0a287f1
--- /dev/null
@@ -0,0 +1,163 @@
+
+/*
+* argv[0] - channel
+* argv[0/1] - nick / *auth
+*/
+static AUTHLOOKUP_CALLBACK(neonserv_cmd_register_auth_lookup);
+static USERAUTH_CALLBACK(neonserv_cmd_register_nick_lookup);
+static void neonserv_cmd_register_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, char *channel, char *auth);
+
+struct neonserv_cmd_register_cache {
+    struct ClientSocket *client, *textclient;
+    struct UserNode *user;
+    struct ChanNode *chan;
+    char *nick;
+    char *channel;
+};
+
+static CMD_BIND(neonserv_cmd_register) {
+    MYSQL_RES *res;
+    MYSQL_ROW row;
+    char *channel = argv[0];
+    if(!is_valid_chan(channel)) {
+        reply(getTextBot(), user, "NS_INVALID_CHANNEL_NAME", argv[0]);
+        return;
+    }
+    printf_mysql_query("SELECT `botid` FROM `bot_channels` LEFT JOIN `bots` ON `bot_channels`.`botid` = `bots`.`id` WHERE `chanid` = '%d' AND `botclass` = '%d'", chan->channel_id, client->botid);
+    res = mysql_use();
+    if ((row = mysql_fetch_row(res)) != NULL) {
+        reply(getTextBot(), user, "NS_REGISTER_ALREADY", argv[0], client->user->nick);
+        return;
+    }
+    //check own access
+    if(argv[0][0] == '*') {
+        //we've got an auth
+        argv[0]++;
+        printf_mysql_query("SELECT `user_user` FROM `users` WHERE `user_user` = '%s'", escape_string(argv[0]));
+        res = mysql_use();
+        if ((row = mysql_fetch_row(res)) != NULL) {
+            neonserv_cmd_register_async1(client, getTextBot(), user, chan, channel, row[0]);
+        } else {
+            //we need to create a new user...
+            //but first lookup the auth to check if it really exists
+            struct neonserv_cmd_register_cache *cache = malloc(sizeof(*cache));
+            if (!cache) {
+                perror("malloc() failed");
+                return;
+            }
+            cache->client = client;
+            cache->textclient = getTextBot();
+            cache->user = user;
+            cache->chan = chan;
+            cache->nick = strdup(argv[0]);
+            cache->channel = strdup(channel);
+            lookup_authname(argv[0], neonserv_cmd_register_auth_lookup, cache);
+        }
+    } else {
+        struct UserNode *cuser = getUserByNick(argv[0]);
+        if(!cuser) {
+            cuser = createTempUser(argv[0]);
+            cuser->flags |= USERFLAG_ISTMPUSER;
+        }
+        if(cuser->flags & USERFLAG_ISAUTHED) {
+            neonserv_cmd_register_async1(client, getTextBot(), user, chan, channel, cuser->auth);
+        } else {
+            struct neonserv_cmd_register_cache *cache = malloc(sizeof(*cache));
+            if (!cache) {
+                perror("malloc() failed");
+                return;
+            }
+            cache->client = client;
+            cache->textclient = getTextBot();
+            cache->user = user;
+            cache->chan = chan;
+            cache->nick = strdup(argv[0]);
+            cache->channel = strdup(channel);
+            get_userauth(cuser, neonserv_cmd_register_nick_lookup, cache);
+        }
+    }
+}
+
+static AUTHLOOKUP_CALLBACK(neonserv_cmd_register_auth_lookup) {
+    struct neonserv_cmd_register_cache *cache = data;
+    if(!exists) {
+        //AUTH_DOES_NOT_EXIST
+        reply(cache->textclient, cache->user, "NS_AUTH_UNKNOWN", cache->nick);
+    } else
+        neonserv_cmd_register_async1(cache->client, cache->textclient, cache->user, cache->chan, cache->channel, auth);
+    free(cache->channel);
+    free(cache->nick);
+    free(cache);
+}
+
+static USERAUTH_CALLBACK(neonserv_cmd_register_nick_lookup) {
+    struct neonserv_cmd_register_cache *cache = data;
+    if(!user) {
+        //USER_DOES_NOT_EXIST
+        reply(cache->textclient, cache->user, "NS_USER_UNKNOWN", cache->nick);
+    }
+    else if(!(user->flags & USERFLAG_ISAUTHED)) {
+        //USER_NOT_AUTHED
+        reply(cache->textclient, cache->user, "NS_USER_NEED_AUTH", cache->nick);
+    }
+    else
+        neonserv_cmd_register_async1(cache->client, cache->textclient, cache->user, cache->chan, cache->channel, user->auth);
+    free(cache->channel);
+    free(cache->nick);
+    free(cache);
+}
+
+static void neonserv_cmd_register_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, char *channel, char *auth) {
+    //we've got a valid auth now...
+    MYSQL_RES *res;
+    MYSQL_ROW row, row2;
+    int userid;
+    printf_mysql_query("SELECT `user_id` FROM `users` WHERE `user_user` = '%s'", escape_string(auth));
+    res = mysql_use();
+    if ((row = mysql_fetch_row(res)) != NULL) {
+        userid = atoi(row[0]);
+    } else {
+        printf_mysql_query("INSERT INTO `users` (`user_user`) VALUES ('%s')", escape_string(auth));
+        userid = (int) mysql_insert_id(mysql_conn);
+    }
+    printf_mysql_query("SELECT `botid`, `max_channels`, `defaulttrigger` FROM `bots` WHERE `botclass` = '%d' ORDER BY `register_priority` DESC", client->botid);
+    res = mysql_use();
+    int botid = 0;
+    char *bottrigger;
+    while ((row = mysql_fetch_row(res)) != NULL) {
+        //check channel count
+        printf_mysql_query("SELECT COUNT(*) FROM `bot_channels` WHERE `botid` = '%s'", row[0]);
+        row2 = mysql_fetch_row(mysql_use());
+        if(atoi(row2[0]) < atoi(row[1])) {
+            botid = atoi(row[0]);
+            bottrigger = row[2];
+            break;
+        }
+    }
+    if(!botid) {
+        reply(textclient, user, "NS_REGISTER_FULL");
+        return;
+    }
+    int chanid;
+    printf_mysql_query("SELECT `channel_id` FROM `channels` WHERE `channel_name` = '%s'", escape_string(channel));
+    res = mysql_use();
+    if ((row = mysql_fetch_row(res)) != NULL) {
+        chanid = atoi(row[0]);
+    } else {
+        printf_mysql_query("INSERT INTO `channels` (`channel_name`) VALUES ('%s')", escape_string(channel));
+        chanid = (int) mysql_insert_id(mysql_conn);
+    }
+    struct ClientSocket *bot;
+    for(bot = getBots(SOCKET_FLAG_READY, NULL); bot; bot = getBots(SOCKET_FLAG_READY, bot)) {
+        if(bot->clientid == botid)
+            break;
+    }
+    if(bot) {
+        putsock(bot, "JOIN %s", channel);
+    } else
+        reply(textclient, user, "NS_REGISTER_DISCONNECTED");
+    printf_mysql_query("INSERT INTO `bot_channels` (`botid`, `chanid`, `trigger`) VALUES ('%d', '%d', '%s')", botid, chanid, bottrigger);
+    printf_mysql_query("DELETE FROM `chanusers` WHERE `chanuser_cid` = '%d'", chanid);
+    printf_mysql_query("INSERT INTO `chanusers` (`chanuser_cid`, `chanuser_uid`, `chanuser_access`) VALUES ('%d', '%d', '%d')", chanid, userid, 500);
+    reply(textclient, user, "NS_REGISTER_DONE", channel, auth);
+}
index c480529e9389d0dcf9f5e272b3e96ba5734be21e..32011f2a6c82eb58d4001720499828b7465ce28d 100644 (file)
--- a/modcmd.c
+++ b/modcmd.c
@@ -138,7 +138,7 @@ static void handle_command(struct ClientSocket *client, struct UserNode *user, s
                 }
             }
             argv = arga;
-            if(argc != 0 && argv[0][0] == '#') {
+            if(argc != 0 && argv[0][0] == '#' && !(cbind->func->flags & CMDFLAG_CHAN_PARAM)) {
                 struct ChanNode *chan2 = getChanByName(argv[0]);
                 if(chan2) {
                     argv += 1;
index 2afdfe43f20d3f26f33fb6f906a733e7a80d7186..fd313b00005e4b99fdf7a63f78a9525914841933 100644 (file)
--- a/modcmd.h
+++ b/modcmd.h
@@ -2,13 +2,14 @@
 #define _modcmd_h
 #include "main.h"
 
-#define CMDFLAG_REQUIRE_CHAN 0x01
-#define CMDFLAG_REQUIRE_AUTH 0x02
-#define CMDFLAG_REQUIRE_GOD  0x04
-#define CMDFLAG_CHECK_AUTH   0x08
-#define CMDFLAG_REGISTERED_CHAN 0x10
-#define CMDFLAG_OVERRIDE_GLOBAL_ACCESS 0x20
+#define CMDFLAG_REQUIRE_CHAN            0x01
+#define CMDFLAG_REQUIRE_AUTH            0x02
+#define CMDFLAG_REQUIRE_GOD             0x04
+#define CMDFLAG_CHECK_AUTH              0x08
+#define CMDFLAG_REGISTERED_CHAN         0x10
+#define CMDFLAG_OVERRIDE_GLOBAL_ACCESS  0x20
 #define CMDFLAG_OVERRIDE_CHANNEL_ACCESS 0x40
+#define CMDFLAG_CHAN_PARAM              0x80
 
 struct ClientSocket;
 struct UserNode;