added BlockInvite uset setting to block invites globally
[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_blockinvite(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_noinvite(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_autoinvite(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_noautoop(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *argument, MYSQL_ROW defaults);
26 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);
27
28 #define USET_FLAG_GLOBAL    0x01
29 #define USET_FLAG_CHANNEL   0x02
30 #define USET_FLAG_STAFF     0x04
31 #define USET_FLAG_INVISIBLE 0x08
32 #define USET_FLAG_DEFAULTS  0x10
33
34 #define USET_DEFAULTS_QUERY \
35     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))
36
37 static const struct {
38     const char *setting;
39     neonserv_cmd_uset_function *function;
40     int flags;
41 } uset_settings[] = {
42     {"Language",        neonserv_cmd_uset_language,    USET_FLAG_GLOBAL},
43     {"BlockInvites",    neonserv_cmd_uset_blockinvite, USET_FLAG_GLOBAL},
44     {"BlockInvite",     neonserv_cmd_uset_blockinvite, USET_FLAG_GLOBAL | USET_FLAG_INVISIBLE},
45     {"BlockAllInvites", neonserv_cmd_uset_blockinvite, USET_FLAG_GLOBAL | USET_FLAG_INVISIBLE},
46     {"NoInvite",        neonserv_cmd_uset_noinvite,    USET_FLAG_CHANNEL},
47     {"AutoInvite",      neonserv_cmd_uset_autoinvite,  USET_FLAG_CHANNEL | USET_FLAG_DEFAULTS},
48     {"NoAutoOp",        neonserv_cmd_uset_noautoop,    USET_FLAG_CHANNEL | USET_FLAG_DEFAULTS},
49     {"NoAutoVoice",     neonserv_cmd_uset_noautoop,    USET_FLAG_CHANNEL | USET_FLAG_DEFAULTS | USET_FLAG_INVISIBLE}, //alias of NoAutoOp
50     {"Info",            neonserv_cmd_uset_info,        USET_FLAG_CHANNEL | USET_FLAG_DEFAULTS},
51     {NULL, NULL, 0}
52 };
53
54 CMD_BIND(neonserv_cmd_uset) {
55     MYSQL_RES *res;
56     MYSQL_ROW row = NULL;
57     int i = 0, j = 0;
58     loadUserSettings(user);
59     if(argc > 0) {
60         char *args = (argc > 1 ? merge_argv(argv, 1, argc) : NULL);
61         while(uset_settings[i].setting) {
62             if(!stricmp(uset_settings[i].setting, argv[0])) {
63                 //setting found
64                 if(uset_settings[i].flags & USET_FLAG_CHANNEL) {
65                     if(!chan)
66                         goto neonserv_cmd_uset_err_chan_required;
67                     loadChannelSettings(chan);
68                     if(!(chan->flags & CHANFLAG_CHAN_REGISTERED)) {
69                         neonserv_cmd_uset_err_chan_required:
70                         reply(getTextBot(), user, "MODCMD_CHAN_REQUIRED");
71                         return;
72                     }
73                     if((uset_settings[i].flags & USET_FLAG_DEFAULTS) && !row) {
74                         USET_DEFAULTS_QUERY;
75                         res = mysql_use();
76                         row = mysql_fetch_row(res);
77                         if(!row) {
78                             reply(getTextBot(), user, "NS_NOT_ON_USERLIST_YOU", chan->name);
79                             return;
80                         }
81                     }
82                 }
83                 neonserv_cmd_uset_function *func = uset_settings[i].function;
84                 func(client, user, chan, event, uset_settings[i].setting, args, row);
85                 j = 1;
86                 break;
87             }
88             i++;
89         }
90         if(j == 0) {
91             //unknown setting
92             reply(getTextBot(), user, "NS_USET_UNKNOWN_SETTING", argv[0]);
93         }
94     } else {
95         //view all options
96         reply(getTextBot(), user, "NS_USET_GLOBAL");
97         while(uset_settings[i].setting) {
98             if((uset_settings[i].flags & (USET_FLAG_INVISIBLE | USET_FLAG_GLOBAL)) == USET_FLAG_GLOBAL) {
99                 neonserv_cmd_uset_function *func = uset_settings[i].function;
100                 func(client, user, chan, event, uset_settings[i].setting, NULL, row);
101             }
102             i++;
103         }
104         if(!chan) return;
105         loadChannelSettings(chan);
106         if(!(chan->flags & CHANFLAG_CHAN_REGISTERED)) return;
107         reply(getTextBot(), user, "NS_USET_CHANNEL");
108         i = 0;
109         while(uset_settings[i].setting) {
110             if((uset_settings[i].flags & (USET_FLAG_INVISIBLE | USET_FLAG_CHANNEL)) == USET_FLAG_CHANNEL) {
111                 if((uset_settings[i].flags & USET_FLAG_DEFAULTS) && !row) {
112                     USET_DEFAULTS_QUERY;
113                     res = mysql_use();
114                     row = mysql_fetch_row(res);
115                     if(!row) {
116                         i++;
117                         continue;
118                     }
119                 }
120                 neonserv_cmd_uset_function *func = uset_settings[i].function;
121                 func(client, user, chan, event, uset_settings[i].setting, NULL, row);
122             }
123             i++;
124         }
125     }
126 }
127
128 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) {
129     MYSQL_RES *res;
130     MYSQL_ROW row;
131     struct language* lang;
132     if(argument) {
133         if((lang = get_language_by_tag(argument)) == NULL && (lang = get_language_by_name(argument)) == NULL) {
134             lang = user->language;
135         } else {
136             printf_mysql_query("SELECT `user_id` FROM `users` WHERE `user_user` = '%s'", escape_string(user->auth));
137             res = mysql_use();
138             if ((row = mysql_fetch_row(res)) != NULL) {
139                 printf_mysql_query("UPDATE `users` SET `user_lang` = '%s' WHERE `user_id` = '%s'", escape_string(lang->langtag), row[0]);
140             } else {
141                 printf_mysql_query("INSERT INTO `users` (`user_user`, `user_lang`) VALUES ('%s', '%s')", escape_string(user->auth), escape_string(lang->langtag));
142             }
143             struct UserNode *cuser;
144             for(cuser = getAllUsers(NULL); cuser; cuser = getAllUsers(cuser)) {
145                 if((cuser->flags & USERFLAG_ISAUTHED) && !stricmp(user->auth, cuser->auth))
146                     cuser->language = lang;
147             }
148         }
149     } else
150         lang = user->language;
151     reply(getTextBot(), user, "\002Language    \002%s", lang->langname);
152     char tmp[MAXLEN];
153     int tmppos = 0;
154     lang = get_default_language();
155     tmppos = sprintf(tmp, "%s (%s)", lang->langname, lang->langtag);
156     printf_mysql_query("SELECT `lang`,`text` FROM `language` WHERE `ident` = 'name'");
157     res = mysql_use();
158     while((row = mysql_fetch_row(res)) != NULL) {
159         tmppos += sprintf(tmp + tmppos, ", %s (%s)", row[1], row[0]);
160     }
161     reply(getTextBot(), user, "  %s", tmp);
162 }
163
164 static void neonserv_cmd_uset_blockinvite(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *argument, MYSQL_ROW defaults) {
165     MYSQL_RES *res;
166     MYSQL_ROW row;
167     printf_mysql_query("SELECT `user_id`, `user_block_invites` FROM `users` WHERE `user_user` = '%s'", escape_string(user->auth));
168     res = mysql_use();
169     row = mysql_fetch_row(res);
170     int blockinvite = (row ? atoi(row[1]) : 0);
171     if(argument) {
172         if(!strcmp(argument, "0") || !stricmp(argument, "off") || !stricmp(argument, get_language_string(user, "NS_SET_OFF"))) {
173             blockinvite = 0;
174         } else if(!strcmp(argument, "1") || !stricmp(argument, "on") || !stricmp(argument, get_language_string(user, "NS_SET_ON"))) {
175             blockinvite = 1;
176         }
177         if(blockinvite && !row) {
178             printf_mysql_query("INSERT INTO `users` (`user_user`, `user_block_invites`) VALUES ('%s', '1')", escape_string(user->auth));
179         } else if(blockinvite != atoi(row[1])) {
180             printf_mysql_query("UPDATE `users` SET `user_block_invites` = '%d' WHERE `user_id` = '%s'", blockinvite, row[0]);
181         }
182     }
183     reply(getTextBot(), user, "\002BlockInvite \002%s", (blockinvite ? get_language_string(user, "NS_SET_ON") : get_language_string(user, "NS_SET_OFF")));
184 }
185
186 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) {
187     MYSQL_RES *res;
188     MYSQL_ROW row;
189     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));
190     res = mysql_use();
191     row = mysql_fetch_row(res);
192     int noinvite = (row ? 1 : 0);
193     if(argument) {
194         if(!strcmp(argument, "0") || !stricmp(argument, "off") || !stricmp(argument, get_language_string(user, "NS_SET_OFF"))) {
195             if(noinvite) {
196                 printf_mysql_query("DELETE FROM `noinvite` WHERE `id` = '%s'", row[0]);
197                 noinvite = 0;
198             }
199         } else if(!strcmp(argument, "1") || !stricmp(argument, "on") || !stricmp(argument, get_language_string(user, "NS_SET_ON"))) {
200             if(!noinvite) {
201                 int userid;
202                 printf_mysql_query("SELECT `user_id` FROM `users` WHERE `user_user` = '%s'", escape_string(user->auth));
203                 res = mysql_use();
204                 if ((row = mysql_fetch_row(res)) != NULL) {
205                     userid = atoi(row[0]);
206                 } else {
207                     printf_mysql_query("INSERT INTO `users` (`user_user`) VALUES ('%s')", escape_string(user->auth));
208                     userid = (int) mysql_insert_id(get_mysql_conn());
209                 }
210                 printf_mysql_query("INSERT INTO `noinvite` (`uid`, `cid`) VALUES ('%d', '%d')", userid, chan->channel_id);
211                 noinvite = 1;
212             }
213         }
214     }
215     reply(getTextBot(), user, "\002NoInvite    \002%s", (noinvite ? get_language_string(user, "NS_SET_ON") : get_language_string(user, "NS_SET_OFF")));
216 }
217
218 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) {
219     int flags = atoi(defaults[0]);
220     int getInvite = 0;
221     if(!defaults[3] && atoi(defaults[2]) >= atoi(getChanDefault("channel_getinvite")))
222         getInvite = 1;
223     else if(defaults[3] && atoi(defaults[2]) >= atoi(defaults[3]))
224         getInvite = 1;
225     if(getInvite && argument) {
226         if(!strcmp(argument, "0") || !stricmp(argument, "off") || !stricmp(argument, get_language_string(user, "NS_SET_OFF"))) {
227             if(flags & DB_CHANUSER_AUTOINVITE) {
228                 flags &= ~DB_CHANUSER_AUTOINVITE;
229                 printf_mysql_query("UPDATE `chanusers` SET `chanuser_flags` = '%d' WHERE `chanuser_id` = '%s'", flags, defaults[4]);
230             }
231         } else if(!strcmp(argument, "1") || !stricmp(argument, "on") || !stricmp(argument, get_language_string(user, "NS_SET_ON"))) {
232             if(!(flags & DB_CHANUSER_AUTOINVITE)) {
233                 flags |= DB_CHANUSER_AUTOINVITE;
234                 printf_mysql_query("UPDATE `chanusers` SET `chanuser_flags` = '%d' WHERE `chanuser_id` = '%s'", flags, defaults[4]);
235             }
236         }
237     }
238     if(getInvite)
239         reply(getTextBot(), user, "\002AutoInvite  \002%s", ((flags & DB_CHANUSER_AUTOINVITE) ? get_language_string(user, "NS_SET_ON") : get_language_string(user, "NS_SET_OFF")));
240     else
241         reply(getTextBot(), user, "\002AutoInvite  \002%s", get_language_string(user, "NS_USET_NO_ACCESS"));
242 }
243
244 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) {
245     int flags = atoi(defaults[0]);
246     if(argument) {
247         if(!strcmp(argument, "0") || !stricmp(argument, "off") || !stricmp(argument, get_language_string(user, "NS_SET_OFF"))) {
248             if(flags & DB_CHANUSER_NOAUTOOP) {
249                 flags &= ~DB_CHANUSER_NOAUTOOP;
250                 printf_mysql_query("UPDATE `chanusers` SET `chanuser_flags` = '%d' WHERE `chanuser_id` = '%s'", flags, defaults[4]);
251             }
252         } else if(!strcmp(argument, "1") || !stricmp(argument, "on") || !stricmp(argument, get_language_string(user, "NS_SET_ON"))) {
253             if(!(flags & DB_CHANUSER_NOAUTOOP)) {
254                 flags |= DB_CHANUSER_NOAUTOOP;
255                 printf_mysql_query("UPDATE `chanusers` SET `chanuser_flags` = '%d' WHERE `chanuser_id` = '%s'", flags, defaults[4]);
256             }
257         }
258     }
259     reply(getTextBot(), user, "\002NoAutoOp    \002%s", ((flags & DB_CHANUSER_NOAUTOOP) ? get_language_string(user, "NS_SET_ON") : get_language_string(user, "NS_SET_OFF")));
260 }
261
262 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) {
263     char *infoline;
264     if(argument) {
265         infoline = argument;
266         if(!strcmp(infoline, "*"))
267             infoline = "";
268         printf_mysql_query("UPDATE `chanusers` SET `chanuser_infoline` = '%s' WHERE `chanuser_id` = '%s'", escape_string(infoline), defaults[4]);
269     } else
270         infoline = defaults[1];
271     reply(getTextBot(), user, "\002Info        \002%s", infoline);
272 }