continued cmd_neonserv_set.c
authorpk910 <philipp@zoelle1.de>
Thu, 1 Sep 2011 02:31:14 +0000 (04:31 +0200)
committerpk910 <philipp@zoelle1.de>
Thu, 1 Sep 2011 02:31:14 +0000 (04:31 +0200)
bot_NeonServ.c
cmd_neonserv_set.c

index dd8a0eb3dd4d9a7f53bfe5873d817e96e0220202..dff7184e4cc90b6cea25e4eb65c0dedbe5267e5f 100644 (file)
@@ -107,6 +107,15 @@ static const struct default_language_entry msgtab[] = {
     {"NS_SET_HEADER", "Channel Settings for %s:"},
     {"NS_SET_ON", "on"},
     {"NS_SET_OFF", "off"},
+    {"NS_SET_UNKNOWN_SETTING", "\002%s\002 is an unknown channel setting."},
+    {"NS_SET_CANNOT_SET", "That setting is above your current level, so you cannot change it."},
+    {"NS_SET_BADLEVEL", "You cannot change any setting to above your level."},
+    {"NS_SET_INVALID_OPTION", "\002%d\002 is not a valid choice.  Choose one:"},
+    {"NS_SET_INVALID_BOOLEAN", "\002%s\002 is an invalid binary value."},
+    {"NS_SET_DEFAULTS_OWNER", "You must have access 500 in %s to reset it to the default options."},
+    {"NS_SET_DEFAULTS_CODE", "To reset %s's settings to the defaults, you must use 'set defaults %s'."},
+    {"NS_SET_DEFAULTS_DONE", "All settings for %s have been reset to default values."},
+    {"NS_SET_TRIGGER_OWNER", "You must have access 500 in %s to change the channel trigger."},
     {NULL, NULL}
 };
 
index 353287a2e64b88ac57a52260c5da6099d578b2c0..2ab296fddd77d07e12ee1e36c69e720eb645f3a2 100644 (file)
@@ -1,9 +1,10 @@
 
-typedef char* neonserv_cmd_set_function(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, int set, char *argument);
-static char* neonserv_cmd_set_trigger(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, int set, char *argument);
-static char* neonserv_cmd_set_modes(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, int set, char *argument);
-static char* neonserv_cmd_set_dynlimit(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, int set, char *argument);
-static char* neonserv_cmd_set_nodelete(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, int set, char *argument);
+typedef char* neonserv_cmd_set_function(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, char *setting, char *argument);
+static char* neonserv_cmd_set_setting(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, char *setting, char *argument);
+static char* neonserv_cmd_set_trigger(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, char *setting, char *argument);
+static char* neonserv_cmd_set_modes(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, char *setting, char *argument);
+static char* neonserv_cmd_set_dynlimit(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, char *setting, char *argument);
+static char* neonserv_cmd_set_nodelete(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, char *setting, char *argument);
 
 #define NS_VALID_FUNCTION 0x01
 #define NS_VALID_STRING   0x02
@@ -60,13 +61,67 @@ static const struct {
     {NULL, NULL, 0, NULL}
 };
 
+#define MAX_QUERY_LEN 1024
 static CMD_BIND(neonserv_cmd_set) {
     int i, j;
-    if(argc && strcmp(argv[0], "help")) {
-        
+    if(argc && !strcmp(argv[0], "defaults")) {
+        //reset channel settings
+        int uaccess = getChannelAccess(user, chan, 1);
+        if(uaccess < 500) {
+            reply(getTextBot(), user, "NS_SET_DEFAULTS_OWNER", chan->name);
+            return;
+        }
+        int seed = 0;
+        static char defaultskey[16];
+        for(tmp = user->auth; *tmp; tmp++)
+            seed = (seed * 0xEECE66DL ^ ((*tmp << 24) | (*tmp << 16) | (*tmp << 8) | *tmp));
+        for(tmp = chan->name; *tmp; tmp++)
+            seed = (seed * 0xEECE66DL ^ ((*tmp << 24) | (*tmp << 16) | (*tmp << 8) | *tmp));
+        sprintf(defaultskey, "%08x", seed);
+        if(argc > 1 && !strcmp(argv[1], defaultskey)) {
+            char query[MAX_QUERY_LEN];
+            int querypos = 0;
+            check_mysql();
+            i = 0;
+            while(channel_settings[i].setting) {
+                if(channel_settings[i].chanfield)
+                    querypos += sprintf(query + querypos, "`%s` = NULL, ", channel_settings[i].chanfield);
+                i++;
+            }
+            if(querypos) {
+                query[querypos-2] = '\0';
+            }
+            printf_mysql_query("UPDATE `channels` SET %s WHERE `channel_id` = '%d'", query, chan->channel_id);
+            reply(getTextBot(), user, "NS_SET_DEFAULTS_DONE", chan->name);
+        } else {
+            reply(getTextBot(), user, "NS_SET_DEFAULTS_CODE", chan->name, defaultskey);
+        }
+    } else if(argc && strcmp(argv[0], "help")) {
+        //find the correct command
+        i = 0;
+        j = 0;
+        while(channel_settings[i].setting) {
+            if(!stricmp(channel_settings[i].setting, argv[0])) {
+                //setting found
+                char *args = (argc > 1 ? merge_argv(argv, 1, argc) : NULL);
+                if(channel_settings[i].valid & NS_VALID_FUNCTION) {
+                    neonserv_cmd_set_function *func = channel_settings[i].parameter;
+                    func(client, user, chan, channel_settings[i].setting, args);
+                } else {
+                    neonserv_cmd_set_setting(client, user, chan, channel_settings[i].setting, args);
+                }
+                j = 1;
+                break;
+            }
+            i++;
+        }
+        if(j == 0) {
+            //unknown setting
+            reply(getTextBot(), "NS_SET_UNKNOWN_SETTING", argv[0]);
+        }
     } else {
         check_mysql();
-        char query[1024], *value, *org_value, *tmp, nameBuf[64];
+        char query[MAX_QUERY_LEN], *value, *org_value, *tmp, nameBuf[64];
         int querypos = 0;
         MYSQL_RES *res, *defaults_res;
         MYSQL_ROW row, defaults;
@@ -95,7 +150,7 @@ static CMD_BIND(neonserv_cmd_set) {
                 org_value = (row[j] ? row[j] : defaults[j]);
             } else if(channel_settings[i].valid & NS_VALID_FUNCTION) {
                 neonserv_cmd_set_function *func = channel_settings[i].parameter;
-                org_value = func(client, user, chan, 0, NULL);
+                org_value = func(client, user, chan, NULL, NULL);
             } else
                 org_value = "0";
             value = org_value;
@@ -134,19 +189,214 @@ static CMD_BIND(neonserv_cmd_set) {
     }
 }
 
-static char* neonserv_cmd_set_trigger(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, int set, char *argument) {
-    return "+";
+static void neonserv_cmd_set_setting(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, int setting, char *argument) {
+    char *value;
+    char nameBuf[64];
+    //get current value
+    MYSQL_RES *res;
+    MYSQL_ROW row;
+    check_mysql();
+    printf_mysql_query("SELECT `%s` FROM `channels` WHERE `channel_id` = '%d'", channel_settings[setting].chanfield, chan->channel_id);
+    res = mysql_use();
+    row = mysql_fetch_row(res);
+    if(row[0] == NULL) {
+        printf_mysql_query("SELECT `%s` FROM `channels` WHERE `channel_name` = 'defaults'", channel_settings[setting].chanfield);
+        res = mysql_use();
+        row = mysql_fetch_row(res);
+    }
+    value = row[0];
+    if(argument) {
+        //change the channel setting
+        //check the new argument
+        int valid = channel_settings[setting].valid;
+        if(valid & NS_VALID_STRING) {
+            if(!strcmp(argument, "*")) {
+                argument = "";
+            }
+        }
+        if(valid & NS_VALID_ACCESS) {
+            int caccess = atoi(argument);
+            int max = ((valid & NS_VALID_NO501) ? 500 : 501);
+            if(caccess < 0 || caccess > max) {
+                reply(getTextBot(), user, "NS_INVALID_ACCESS", caccess);
+                return;
+            }
+            int uaccess = getChannelAccess(user, chan, 1);
+            if(uaccess == 500) uaccess++;
+            if(atoi(value) > uaccess) {
+                reply(getTextBot(), user, "NS_SET_CANNOT_SET");
+                return;
+            }
+            if(caccess > uaccess) {
+                reply(getTextBot(), user, "NS_SET_BADLEVEL");
+                return;
+            }
+        }
+        if(valid & NS_VALID_OPTIONS) {
+            int options = atoi((char *) channel_settings[setting].parameter);
+            int coption = atoi(argument);
+            if(coption < 0 || coption >= options) {
+                reply(getTextBot(), user, "NS_SET_INVALID_OPTION", argument);
+                int i;
+                int nameBufPos = 0;
+                if(valid & NS_HAS_OPT) {
+                    for(i = 0; i < options; i++) {
+                        sprintf(nameBuf, "NS_SET_OPTION_%s_%s", channel_settings[setting].setting, i);
+                        reply(getTextBot(), user, "\002%d\002 - %s", i, get_language_string(user, nameBuf));
+                    }
+                } else {
+                    for(i = 0; i < options; i++) {
+                        nameBufPos += sprintf(nameBuf + nameBufPos, "\002%d\002, ", i);
+                    }
+                    if(nameBufPos) {
+                        nameBuf[nameBufPos-2] = '\0';
+                        reply(getTextBot(), user, nameBuf);
+                    }
+                }
+                return;
+            }
+        }
+        if(valid & NS_VALID_NUMERIC) {
+            sprintf(nameBuf, "%d", atoi(argument));
+            argument = nameBuf;
+        }
+        if(valid & NS_VALID_BOOLEAN) {
+            if(!strcmp(argument, "0") || !strcmp(argument, "off") || !strcmp(argument, get_language_string(user, "NS_SET_OFF"))) {
+                argument = "0";
+            } else if(!strcmp(argument, "0") || !strcmp(argument, "off") || !strcmp(argument, get_language_string(user, "NS_SET_OFF"))) {
+                argument = "1";
+            } else {
+                reply(getTextBot(), user, "NS_SET_INVALID_BOOLEAN", argument);
+                return;
+            }
+        }
+        //valid - set it
+        value = argument;
+        printf_mysql_query("UPDATE `channels` SET `%s` = '%s' WHERE `channel_id` = '%d'", channel_settings[setting].chanfield, escape_string(value), chan->channel_id);
+    }
+    reply(getTextBot(), user, "\002%s\002 %s", channel_settings[setting].setting, value);
+    if(channel_settings[setting].valid & NS_HAS_HELP) {
+         sprintf(nameBuf, "NS_SET_HELP_%s", channel_settings[i].setting);
+         reply(getTextBot(), user, "  %s", get_language_string(user, nameBuf);
+    }
+}
+
+static char* neonserv_cmd_set_trigger(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, char *setting, char *argument) {
+    char *trigger;
+    //get current trigger
+    MYSQL_RES *res;
+    MYSQL_ROW row;
+    check_mysql();
+    printf_mysql_query("SELECT `trigger` FROM `bot_channels` WHERE `chanid` = '%d' AND `botid` = '%d'", chan->channel_id, client->clientid);
+    res = mysql_use();
+    row = mysql_fetch_row(res);
+    trigger = row[0];
+    if(argument) {
+        int uaccess = getChannelAccess(user, chan, 1);
+        if(uaccess < 500) {
+            reply(getTextBot(), user, "NS_SET_TRIGGER_OWNER", chan->name);
+            return NULL;
+        }
+        if(strlen(argument) > 15)
+            argument[15] = '\0';
+        printf_mysql_query("UPDATE `bot_channels` SET `trigger` = '%s' WHERE `chanid` = '%d' AND `botid` = '%d'", escape_string(argument), chan->channel_id, client->clientid);
+        trigger = argument;
+        changeChannelTrigger(client->botid, chan, trigger);
+    }
+    if(setting) {
+        reply(getTextBot(), user, "\002%s\002 %s", setting, trigger);
+    }
+    return trigger;
 }
 
-static char* neonserv_cmd_set_modes(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, int set, char *argument) {
-    return NULL;
+static char* neonserv_cmd_set_modes(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, char *setting, char *argument) {
+    char *value;
+    //get current value
+    MYSQL_RES *res;
+    MYSQL_ROW row;
+    check_mysql();
+    printf_mysql_query("SELECT `channel_modes` FROM `channels` WHERE `channel_id` = '%d'", chan->channel_id);
+    res = mysql_use();
+    row = mysql_fetch_row(res);
+    if(row[0] == NULL) {
+        printf_mysql_query("SELECT `channel_modes` FROM `channels` WHERE `channel_name` = 'defaults'");
+        res = mysql_use();
+        row = mysql_fetch_row(res);
+    }
+    value = row[0];
+    if(argument) {
+        //change the channel setting
+        //TODO: parse, check and set modelock
+    }
+    if(setting) {
+        reply(getTextBot(), user, "\002%s\002 %s", setting, value);
+    }
+    return value;
 }
 
-static char* neonserv_cmd_set_dynlimit(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, int set, char *argument) {
-    return NULL;
+static char* neonserv_cmd_set_dynlimit(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, char *setting, char *argument) {
+    char *value;
+    char tmp[64];
+    //get current value
+    MYSQL_RES *res;
+    MYSQL_ROW row;
+    check_mysql();
+    printf_mysql_query("SELECT `channel_dynlimit` FROM `channels` WHERE `channel_id` = '%d'", chan->channel_id);
+    res = mysql_use();
+    row = mysql_fetch_row(res);
+    if(row[0] == NULL) {
+        printf_mysql_query("SELECT `channel_dynlimit` FROM `channels` WHERE `channel_name` = 'defaults'");
+        res = mysql_use();
+        row = mysql_fetch_row(res);
+    }
+    value = row[0];
+    if(argument) {
+        //change the channel setting
+        sprintf(tmp, "%d", atoi(argument));
+        argument = tmp;
+        printf_mysql_query("UPDATE `channels` SET `channel_dynlimit` = '%s' WHERE `channel_id` = '%d'", escape_string(argument), chan->channel_id);
+        if(strcmp(argument, "0"))
+            putsock(client, "MODE %s +l %d", chan->name, (chan->usercount + atoi(argument)));
+        else if(isModeSet(chan, 'l'))
+            putsock(client, "MODE %s -l", chan->name);
+    }
+    if(setting) {
+        reply(getTextBot(), user, "\002%s\002 %s", setting, value);
+    }
+    return value;
 }
 
-static char* neonserv_cmd_set_nodelete(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, int set, char *argument) {
-    return NULL;
+static char* neonserv_cmd_set_nodelete(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, char *setting, char *argument) {
+    char *value;
+    //get current value
+    MYSQL_RES *res;
+    MYSQL_ROW row;
+    check_mysql();
+    printf_mysql_query("SELECT `channel_nodelete` FROM `channels` WHERE `channel_id` = '%d'", chan->channel_id);
+    res = mysql_use();
+    row = mysql_fetch_row(res);
+    if(row[0] == NULL) {
+        printf_mysql_query("SELECT `channel_nodelete` FROM `channels` WHERE `channel_name` = 'defaults'");
+        res = mysql_use();
+        row = mysql_fetch_row(res);
+    }
+    value = row[0];
+    if(argument && isGodMode(user)) {
+        //change the channel setting
+        if(!strcmp(argument, "0") || !strcmp(argument, "off") || !strcmp(argument, get_language_string(user, "NS_SET_OFF"))) {
+            argument = "0";
+        } else if(!strcmp(argument, "0") || !strcmp(argument, "off") || !strcmp(argument, get_language_string(user, "NS_SET_OFF"))) {
+            argument = "1";
+        } else {
+            reply(getTextBot(), user, "NS_SET_INVALID_BOOLEAN", argument);
+            return NULL;
+        }
+        printf_mysql_query("UPDATE `channels` SET `channel_nodelete` = '%s' WHERE `channel_id` = '%d'", escape_string(argument), chan->channel_id);
+    }
+    if(setting) {
+        reply(getTextBot(), user, "\002%s\002 %s", setting, value);
+    }
+    return value;
 }
 
+#undef MAX_QUERY_LEN