c9c7b5fe3f9dc0d29925a2f7da7fc211853deecc
[NeonServV5.git] / src / modules / NeonServ.mod / cmd_neonserv_uset.c
1 /* cmd_neonserv_uset.c - NeonServ v5.4
2  * Copyright (C) 2011-2012  Philipp Kreil (pk910)
3  * 
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  * 
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  * 
14  * You should have received a copy of the GNU General Public License 
15  * along with this program. If not, see <http://www.gnu.org/licenses/>. 
16  */
17
18 #include "cmd_neonserv.h"
19
20 typedef void neonserv_cmd_uset_function(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *argument, MYSQL_ROW defaults);
21 static void neonserv_cmd_uset_language(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *argument, MYSQL_ROW defaults);
22 static void neonserv_cmd_uset_noinvite(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *argument, MYSQL_ROW defaults);
23 static void neonserv_cmd_uset_autoinvite(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *argument, MYSQL_ROW defaults);
24 static void neonserv_cmd_uset_noautoop(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *argument, MYSQL_ROW defaults);
25 static void neonserv_cmd_uset_info(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *argument, MYSQL_ROW defaults);
26
27 #define USET_FLAG_GLOBAL    0x01
28 #define USET_FLAG_CHANNEL   0x02
29 #define USET_FLAG_STAFF     0x04
30 #define USET_FLAG_INVISIBLE 0x08
31 #define USET_FLAG_DEFAULTS  0x10
32
33 #define USET_DEFAULTS_QUERY \
34     printf_mysql_query("SELECT `chanuser_flags`, `chanuser_infoline`, `chanuser_access`, `channel_getinvite`, `chanuser_id` FROM `chanusers` LEFT JOIN `users` ON `chanuser_uid` = `user_id` LEFT JOIN `channels` ON `channel_id` = `chanuser_cid` WHERE `chanuser_cid` = '%d' AND `user_user` = '%s'", chan->channel_id, escape_string(user->auth))
35
36 static const struct {
37     const char *setting;
38     neonserv_cmd_uset_function *function;
39     int flags;
40 } uset_settings[] = {
41     {"Language",    neonserv_cmd_uset_language,   USET_FLAG_GLOBAL},
42     {"NoInvite",    neonserv_cmd_uset_noinvite,   USET_FLAG_CHANNEL},
43     {"AutoInvite",  neonserv_cmd_uset_autoinvite, USET_FLAG_CHANNEL | USET_FLAG_DEFAULTS},
44     {"NoAutoOp",    neonserv_cmd_uset_noautoop,   USET_FLAG_CHANNEL | USET_FLAG_DEFAULTS},
45     {"NoAutoVoice", neonserv_cmd_uset_noautoop,   USET_FLAG_CHANNEL | USET_FLAG_DEFAULTS | USET_FLAG_INVISIBLE}, //alias of NoAutoOp
46     {"Info",        neonserv_cmd_uset_info,       USET_FLAG_CHANNEL | USET_FLAG_DEFAULTS},
47     {NULL, NULL, 0}
48 };
49
50 CMD_BIND(neonserv_cmd_uset) {
51     MYSQL_RES *res;
52     MYSQL_ROW row = NULL;
53     int i = 0, j = 0;
54     loadUserSettings(user);
55     if(argc > 0) {
56         char *args = (argc > 1 ? merge_argv(argv, 1, argc) : NULL);
57         while(uset_settings[i].setting) {
58             if(!stricmp(uset_settings[i].setting, argv[0])) {
59                 //setting found
60                 if(uset_settings[i].flags & USET_FLAG_CHANNEL) {
61                     if(!chan)
62                         goto neonserv_cmd_uset_err_chan_required;
63                     loadChannelSettings(chan);
64                     if(!(chan->flags & CHANFLAG_CHAN_REGISTERED)) {
65                         neonserv_cmd_uset_err_chan_required:
66                         reply(getTextBot(), user, "MODCMD_CHAN_REQUIRED");
67                         return;
68                     }
69                     if((uset_settings[i].flags & USET_FLAG_DEFAULTS) && !row) {
70                         USET_DEFAULTS_QUERY;
71                         res = mysql_use();
72                         row = mysql_fetch_row(res);
73                         if(!row) {
74                             reply(getTextBot(), user, "NS_NOT_ON_USERLIST_YOU", chan->name);
75                             return;
76                         }
77                     }
78                 }
79                 neonserv_cmd_uset_function *func = uset_settings[i].function;
80                 func(client, user, chan, event, uset_settings[i].setting, args, row);
81                 j = 1;
82                 break;
83             }
84             i++;
85         }
86         if(j == 0) {
87             //unknown setting
88             reply(getTextBot(), user, "NS_USET_UNKNOWN_SETTING", argv[0]);
89         }
90     } else {
91         //view all options
92         reply(getTextBot(), user, "NS_USET_GLOBAL");
93         while(uset_settings[i].setting) {
94             if((uset_settings[i].flags & (USET_FLAG_INVISIBLE | USET_FLAG_GLOBAL)) == USET_FLAG_GLOBAL) {
95                 neonserv_cmd_uset_function *func = uset_settings[i].function;
96                 func(client, user, chan, event, uset_settings[i].setting, NULL, row);
97             }
98             i++;
99         }
100         if(!chan) return;
101         loadChannelSettings(chan);
102         if(!(chan->flags & CHANFLAG_CHAN_REGISTERED)) return;
103         reply(getTextBot(), user, "NS_USET_CHANNEL");
104         i = 0;
105         while(uset_settings[i].setting) {
106             if((uset_settings[i].flags & (USET_FLAG_INVISIBLE | USET_FLAG_CHANNEL)) == USET_FLAG_CHANNEL) {
107                 if((uset_settings[i].flags & USET_FLAG_DEFAULTS) && !row) {
108                     USET_DEFAULTS_QUERY;
109                     res = mysql_use();
110                     row = mysql_fetch_row(res);
111                     if(!row) {
112                         i++;
113                         continue;
114                     }
115                 }
116                 neonserv_cmd_uset_function *func = uset_settings[i].function;
117                 func(client, user, chan, event, uset_settings[i].setting, NULL, row);
118             }
119             i++;
120         }
121     }
122 }
123
124 static void neonserv_cmd_uset_language(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *argument, MYSQL_ROW defaults) {
125     MYSQL_RES *res;
126     MYSQL_ROW row;
127     struct language* lang;
128     if(argument) {
129         if((lang = get_language_by_tag(argument)) == NULL && (lang = get_language_by_name(argument)) == NULL) {
130             lang = user->language;
131         } else {
132             printf_mysql_query("SELECT `user_id` FROM `users` WHERE `user_user` = '%s'", escape_string(user->auth));
133             res = mysql_use();
134             if ((row = mysql_fetch_row(res)) != NULL) {
135                 printf_mysql_query("UPDATE `users` SET `user_lang` = '%s' WHERE `user_id` = '%s'", escape_string(lang->langtag), row[0]);
136             } else {
137                 printf_mysql_query("INSERT INTO `users` (`user_user`, `user_lang`) VALUES ('%s', '%s')", escape_string(user->auth), escape_string(lang->langtag));
138             }
139             struct UserNode *cuser;
140             for(cuser = getAllUsers(NULL); cuser; cuser = getAllUsers(cuser)) {
141                 if((cuser->flags & USERFLAG_ISAUTHED) && !stricmp(user->auth, cuser->auth))
142                     cuser->language = lang;
143             }
144         }
145     } else
146         lang = user->language;
147     reply(getTextBot(), user, "\002Language   \002%s", lang->langname);
148     char tmp[MAXLEN];
149     int tmppos = 0;
150     lang = get_default_language();
151     tmppos = sprintf(tmp, "%s (%s)", lang->langname, lang->langtag);
152     printf_mysql_query("SELECT `lang`,`text` FROM `language` WHERE `ident` = 'name'");
153     res = mysql_use();
154     while((row = mysql_fetch_row(res)) != NULL) {
155         tmppos += sprintf(tmp + tmppos, ", %s (%s)", row[1], row[0]);
156     }
157     reply(getTextBot(), user, "  %s", tmp);
158 }
159
160 static void neonserv_cmd_uset_noinvite(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *argument, MYSQL_ROW defaults) {
161     MYSQL_RES *res;
162     MYSQL_ROW row;
163     printf_mysql_query("SELECT `id` FROM `noinvite` LEFT JOIN `users` ON `uid` = `user_id` WHERE `cid` = '%d' AND `user_user` = '%s'", chan->channel_id, escape_string(user->auth));
164     res = mysql_use();
165     row = mysql_fetch_row(res);
166     int noinvite = (row ? 1 : 0);
167     if(argument) {
168         if(!strcmp(argument, "0") || !stricmp(argument, "off") || !stricmp(argument, get_language_string(user, "NS_SET_OFF"))) {
169             if(noinvite) {
170                 printf_mysql_query("DELETE FROM `noinvite` WHERE `id` = '%s'", row[0]);
171                 noinvite = 0;
172             }
173         } else if(!strcmp(argument, "1") || !stricmp(argument, "on") || !stricmp(argument, get_language_string(user, "NS_SET_ON"))) {
174             if(!noinvite) {
175                 int userid;
176                 printf_mysql_query("SELECT `user_id` FROM `users` WHERE `user_user` = '%s'", escape_string(user->auth));
177                 res = mysql_use();
178                 if ((row = mysql_fetch_row(res)) != NULL) {
179                     userid = atoi(row[0]);
180                 } else {
181                     printf_mysql_query("INSERT INTO `users` (`user_user`) VALUES ('%s')", escape_string(user->auth));
182                     userid = (int) mysql_insert_id(get_mysql_conn());
183                 }
184                 printf_mysql_query("INSERT INTO `noinvite` (`uid`, `cid`) VALUES ('%d', '%d')", userid, chan->channel_id);
185                 noinvite = 1;
186             }
187         }
188     }
189     reply(getTextBot(), user, "\002NoInvite   \002%s", (noinvite ? get_language_string(user, "NS_SET_ON") : get_language_string(user, "NS_SET_OFF")));
190 }
191
192 static void neonserv_cmd_uset_autoinvite(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *argument, MYSQL_ROW defaults) {
193     int flags = atoi(defaults[0]);
194     int getInvite = 0;
195     if(!defaults[3] && atoi(defaults[2]) >= atoi(getChanDefault("channel_getinvite")))
196         getInvite = 1;
197     else if(defaults[3] && atoi(defaults[2]) >= atoi(defaults[3]))
198         getInvite = 1;
199     if(getInvite && argument) {
200         if(!strcmp(argument, "0") || !stricmp(argument, "off") || !stricmp(argument, get_language_string(user, "NS_SET_OFF"))) {
201             if(flags & DB_CHANUSER_AUTOINVITE) {
202                 flags &= ~DB_CHANUSER_AUTOINVITE;
203                 printf_mysql_query("UPDATE `chanusers` SET `chanuser_flags` = '%d' WHERE `chanuser_id` = '%s'", flags, defaults[4]);
204             }
205         } else if(!strcmp(argument, "1") || !stricmp(argument, "on") || !stricmp(argument, get_language_string(user, "NS_SET_ON"))) {
206             if(!(flags & DB_CHANUSER_AUTOINVITE)) {
207                 flags |= DB_CHANUSER_AUTOINVITE;
208                 printf_mysql_query("UPDATE `chanusers` SET `chanuser_flags` = '%d' WHERE `chanuser_id` = '%s'", flags, defaults[4]);
209             }
210         }
211     }
212     if(getInvite)
213         reply(getTextBot(), user, "\002AutoInvite \002%s", ((flags & DB_CHANUSER_AUTOINVITE) ? get_language_string(user, "NS_SET_ON") : get_language_string(user, "NS_SET_OFF")));
214     else
215         reply(getTextBot(), user, "\002AutoInvite \002%s", get_language_string(user, "NS_USET_NO_ACCESS"));
216 }
217
218 static void neonserv_cmd_uset_noautoop(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *argument, MYSQL_ROW defaults) {
219     int flags = atoi(defaults[0]);
220     if(argument) {
221         if(!strcmp(argument, "0") || !stricmp(argument, "off") || !stricmp(argument, get_language_string(user, "NS_SET_OFF"))) {
222             if(flags & DB_CHANUSER_NOAUTOOP) {
223                 flags &= ~DB_CHANUSER_NOAUTOOP;
224                 printf_mysql_query("UPDATE `chanusers` SET `chanuser_flags` = '%d' WHERE `chanuser_id` = '%s'", flags, defaults[4]);
225             }
226         } else if(!strcmp(argument, "1") || !stricmp(argument, "on") || !stricmp(argument, get_language_string(user, "NS_SET_ON"))) {
227             if(!(flags & DB_CHANUSER_NOAUTOOP)) {
228                 flags |= DB_CHANUSER_NOAUTOOP;
229                 printf_mysql_query("UPDATE `chanusers` SET `chanuser_flags` = '%d' WHERE `chanuser_id` = '%s'", flags, defaults[4]);
230             }
231         }
232     }
233     reply(getTextBot(), user, "\002NoAutoOp   \002%s", ((flags & DB_CHANUSER_NOAUTOOP) ? get_language_string(user, "NS_SET_ON") : get_language_string(user, "NS_SET_OFF")));
234 }
235
236 static void neonserv_cmd_uset_info(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *argument, MYSQL_ROW defaults) {
237     char *infoline;
238     if(argument) {
239         infoline = argument;
240         if(!strcmp(infoline, "*"))
241             infoline = "";
242         printf_mysql_query("UPDATE `chanusers` SET `chanuser_infoline` = '%s' WHERE `chanuser_id` = '%s'", escape_string(infoline), defaults[4]);
243     } else
244         infoline = defaults[1];
245     reply(getTextBot(), user, "\002Info       \002%s", infoline);
246 }