struct BanNode *next;
};
+#ifndef DND_FUNCTIONS
struct BanNode* addChannelBan(struct ChanNode *chan, char *mask);
-struct BanNode* getMatchingChannelBan(struct ChanNode *chan, char *mask);
+/* MODULAR ACCESSIBLE */ struct BanNode* getMatchingChannelBan(struct ChanNode *chan, char *mask);
void removeChannelBanMask(struct ChanNode *chan, char *mask);
void removeChannelBan(struct BanNode *ban);
void removeChannelBans(struct ChanNode *chan);
+#endif
#endif
\ No newline at end of file
struct ChanNode *next;
};
+#ifndef DND_FUNCTIONS
void init_ChanNode();
void free_ChanNode();
-int is_valid_chan(const char *name);
-struct ChanNode* getAllChans(struct ChanNode *last);
-struct ChanNode* getChanByName(const char *name);
+/* MODULAR ACCESSIBLE */ int is_valid_chan(const char *name);
+/* MODULAR ACCESSIBLE */ struct ChanNode* getAllChans(struct ChanNode *last);
+/* MODULAR ACCESSIBLE */ struct ChanNode* getChanByName(const char *name);
struct ChanNode* addChannel(const char *chan);
-int getChannelCount();
-int getChanUserCount();
-int getChanBanCount();
+/* MODULAR ACCESSIBLE */ int getChannelCount();
+/* MODULAR ACCESSIBLE */ int getChanUserCount();
+/* MODULAR ACCESSIBLE */ int getChanBanCount();
void delChannel(struct ChanNode* chan, int freeChan);
void freeChanNode(struct ChanNode* chan);
int checkChannelVisibility(struct ChanNode* chan);
-
+#endif
#endif
\ No newline at end of file
struct ChanUser *next_chan;
};
+#ifndef DND_FUNCTIONS
struct ChanUser* addChanUser(struct ChanNode *chan, struct UserNode *user);
struct ChanUser* addInvisibleChanUser(struct ChanNode *chan, struct UserNode *user);
-int isUserOnChan(struct UserNode *user, struct ChanNode *chan);
-struct ChanUser* getChanUser(struct UserNode *user, struct ChanNode *chan);
-struct ChanUser* getChannelUsers(struct ChanNode *chan, struct ChanUser *last);
-struct ChanUser* getUserChannels(struct UserNode *user, struct ChanUser *last);
+/* MODULAR ACCESSIBLE */ int isUserOnChan(struct UserNode *user, struct ChanNode *chan);
+/* MODULAR ACCESSIBLE */ struct ChanUser* getChanUser(struct UserNode *user, struct ChanNode *chan);
+/* MODULAR ACCESSIBLE */ struct ChanUser* getChannelUsers(struct ChanNode *chan, struct ChanUser *last);
+/* MODULAR ACCESSIBLE */ struct ChanUser* getUserChannels(struct UserNode *user, struct ChanUser *last);
void delChanUser(struct ChanUser *chanuser, int freeChanUser);
void removeChanUserFromLists(struct ChanUser *chanuser, int remove_from_userlist, int remove_from_channellist, int freeChanUser);
void freeChanUser(struct ChanUser *chanuser);
-
-#endif
\ No newline at end of file
+#endif
+#endif
struct ClientSocket *next;
};
-struct ClientSocket* create_socket(char *host, int port, char *bindto, char *pass, char *nick, char *ident, char *realname);
-int connect_socket(struct ClientSocket *client);
-int close_socket(struct ClientSocket *client);
-int disconnect_socket(struct ClientSocket *client);
+#ifndef DND_FUNCTIONS
+/* MODULAR ACCESSIBLE */ struct ClientSocket* create_socket(char *host, int port, char *bindto, char *pass, char *nick, char *ident, char *realname);
+/* MODULAR ACCESSIBLE */ int connect_socket(struct ClientSocket *client);
+/* MODULAR ACCESSIBLE */ int close_socket(struct ClientSocket *client);
+/* MODULAR ACCESSIBLE */ int disconnect_socket(struct ClientSocket *client);
int write_socket_force(struct ClientSocket *client, char* msg, int len);
-int write_socket(struct ClientSocket *client, char* msg, int len);
+/* MODULAR ACCESSIBLE */ int write_socket(struct ClientSocket *client, char* msg, int len);
#ifdef HAVE_THREADS
int clientsocket_parseorder_top(unsigned int tid);
#endif
int socket_loop(int timeout_seconds);
-void putsock(struct ClientSocket *client, const char *text, ...) PRINTF_LIKE(2, 3);
-struct ClientSocket* getBots(int flags, struct ClientSocket* last_bot);
+/* MODULAR ACCESSIBLE */ void putsock(struct ClientSocket *client, const char *text, ...) PRINTF_LIKE(2, 3);
+/* MODULAR ACCESSIBLE */ struct ClientSocket* getBots(int flags, struct ClientSocket* last_bot);
void init_sockets();
void free_sockets();
-
-#endif
\ No newline at end of file
+#endif
+#endif
#define _ConfigParser_h
#include "main.h"
+#ifndef DND_FUNCTIONS
int loadConfig(const char *filename);
-int get_int_field(char *field_path);
-char *get_string_field(char *field_path);
+/* MODULAR ACCESSIBLE */ int get_int_field(char *field_path);
+/* MODULAR ACCESSIBLE */ char *get_string_field(char *field_path);
void free_loaded_config();
-
-#endif
\ No newline at end of file
+#endif
+#endif
#define DB_CHANUSER_AUTOINVITE 0x02
#define DB_CHANUSER_NOAUTOOP 0x04
-void _loadUserSettings(struct UserNode* user);
#define loadUserSettings(USER) if((USER->flags & USERFLAG_ISAUTHED) && !(USER->flags & USERFLAG_LOADED_SETTINGS)) _loadUserSettings(USER)
-int isGodMode(struct UserNode *user);
-char *getChanDefault(char *channel_setting);
-int getChannelAccess(struct UserNode *user, struct ChanNode *chan);
-int checkChannelAccess(struct UserNode *user, struct ChanNode *chan, char *channel_setting, int allow_501);
-void _loadChannelSettings(struct ChanNode *chan);
#define loadChannelSettings(CHAN) if(!(CHAN->flags & CHANFLAG_REQUESTED_CHANINFO)) _loadChannelSettings(CHAN)
-int isUserProtected(struct ChanNode *chan, struct UserNode *victim, struct UserNode *issuer);
-char *getBanAffectingMask(struct ChanNode *chan, char *mask); //returns bans that match a given mask eg. *!*@ab* if you pass *!*@abcdefg.*
+#ifndef DND_FUNCTIONS
+/* MODULAR ACCESSIBLE */ void _loadUserSettings(struct UserNode* user);
+/* MODULAR ACCESSIBLE */ int isGodMode(struct UserNode *user);
+/* MODULAR ACCESSIBLE */ char *getChanDefault(char *channel_setting);
+/* MODULAR ACCESSIBLE */ int getChannelAccess(struct UserNode *user, struct ChanNode *chan);
+/* MODULAR ACCESSIBLE */ int checkChannelAccess(struct UserNode *user, struct ChanNode *chan, char *channel_setting, int allow_501);
+/* MODULAR ACCESSIBLE */ void _loadChannelSettings(struct ChanNode *chan);
-int renameAccount(char *oldauth, char *newauth);
+/* MODULAR ACCESSIBLE */ int isUserProtected(struct ChanNode *chan, struct UserNode *victim, struct UserNode *issuer);
-void deleteUser(int userid);
+/* MODULAR ACCESSIBLE */ char *getBanAffectingMask(struct ChanNode *chan, char *mask); //returns bans that match a given mask eg. *!*@ab* if you pass *!*@abcdefg.*
+
+/* MODULAR ACCESSIBLE */ int renameAccount(char *oldauth, char *newauth);
+
+/* MODULAR ACCESSIBLE */ void deleteUser(int userid);
void init_DBHelper();
-#endif
\ No newline at end of file
+#endif
+#endif
struct Event *next;
};
+#ifndef DND_FUNCTIONS
struct Event *createEvent(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct cmd_binding *command, char **args, int argc, int flags);
-void logEvent(struct Event *event);
+/* MODULAR ACCESSIBLE */ void logEvent(struct Event *event);
void destroyEvents();
-
-#endif
\ No newline at end of file
+#endif
+#endif
#define AUTHLOOKUP_CALLBACK(NAME) void NAME(UNUSED_ARG(char *auth), UNUSED_ARG(int exists), UNUSED_ARG(time_t registered), UNUSED_ARG(void *data))
typedef AUTHLOOKUP_CALLBACK(authlookup_callback_t);
+#ifndef DND_FUNCTIONS
void clear_handleinfoqueue(struct ClientSocket *client);
-void lookup_authname(char *auth, authlookup_callback_t callback, void *data);
+/* MODULAR ACCESSIBLE */ void lookup_authname(char *auth, authlookup_callback_t callback, void *data);
void init_handleinfohandler();
void free_handleinfohandler();
-
-#endif
\ No newline at end of file
+#endif
+#endif
struct binding {
void *func;
+ int module_id;
struct binding *next;
};
free(binds);
}
+void unregister_module_events(int module_id) {
+ struct binding *cbind, *next, *prev;
+ int i;
+ for(i = 0; i < TOTAL_BIND_TYPES; i++) {
+ prev = NULL;
+ for(cbind = binds[i]; cbind; cbind = next) {
+ next = cbind->next;
+ if(cbind->module_id == module_id) {
+ if(prev)
+ prev->next = next;
+ else
+ binds[i] = next;
+ free(cbind);
+ } else
+ prev = cbind;
+ }
+ }
+}
+
static int is_bound(unsigned char type, void *func) {
struct binding *cbind;
for(cbind = binds[type]; cbind; cbind = cbind->next) {
}
#define FUNC_BIND(NAME,FUNCTYPE,TYPE) \
-int bind_##NAME(FUNCTYPE *func) { \
+int bind_##NAME(FUNCTYPE *func, int module_id) { \
if(!is_bound(TYPE, func)) { \
struct binding *cbind = malloc(sizeof(*cbind)); \
if (!cbind) { \
return 0; \
} \
cbind->func = func; \
+ cbind->module_id = module_id \
cbind->next = binds[TYPE]; \
binds[TYPE] = cbind; \
return 1; \
struct ChanUser;
struct ClientSocket;
+#ifndef DND_FUNCTIONS
void init_bind();
void free_bind();
+void unregister_module_events(int module_id);
+#endif
typedef void join_func_t(struct ChanUser *chanuser);
-int bind_join(join_func_t *func);
-void unbind_join(join_func_t *func);
+#ifndef DND_FUNCTIONS
+/* MODULAR ACCESSIBLE */ int bind_join(join_func_t *func, int module_id);
+/* MODULAR ACCESSIBLE */ void unbind_join(join_func_t *func);
int event_join(struct ChanUser *chanuser);
+#endif
typedef void nick_func_t(struct UserNode *user, char *new_nick);
-int bind_nick(nick_func_t *func);
-void unbind_nick(nick_func_t *func);
+#ifndef DND_FUNCTIONS
+/* MODULAR ACCESSIBLE */ int bind_nick(nick_func_t *func, int module_id);
+/* MODULAR ACCESSIBLE */ void unbind_nick(nick_func_t *func);
int event_nick(struct UserNode *user, char *new_nick);
+#endif
typedef void part_func_t(struct ChanUser *chanuser, char *reason);
-int bind_part(part_func_t *func);
-void unbind_part(part_func_t *func);
+#ifndef DND_FUNCTIONS
+/* MODULAR ACCESSIBLE */ int bind_part(part_func_t *func, int module_id);
+/* MODULAR ACCESSIBLE */ void unbind_part(part_func_t *func);
int event_part(struct ChanUser *chanuser, char *reason);
+#endif
typedef void quit_func_t(struct UserNode *user, char *reason);
-int bind_quit(quit_func_t *func);
-void unbind_quit(quit_func_t *func);
+#ifndef DND_FUNCTIONS
+/* MODULAR ACCESSIBLE */ int bind_quit(quit_func_t *func, int module_id);
+/* MODULAR ACCESSIBLE */ void unbind_quit(quit_func_t *func);
int event_quit(struct UserNode *user, char *reason);
+#endif
typedef void kick_func_t(struct UserNode *user, struct ChanUser *target, char *reason);
-int bind_kick(kick_func_t *func);
-void unbind_kick(kick_func_t *func);
+#ifndef DND_FUNCTIONS
+/* MODULAR ACCESSIBLE */ int bind_kick(kick_func_t *func, int module_id);
+/* MODULAR ACCESSIBLE */ void unbind_kick(kick_func_t *func);
int event_kick(struct UserNode *user, struct ChanUser *target, char *reason);
+#endif
typedef void topic_func_t(struct UserNode *user, struct ChanNode *chan, const char *new_topic);
-int bind_topic(topic_func_t *func);
-void unbind_topic(topic_func_t *func);
+#ifndef DND_FUNCTIONS
+/* MODULAR ACCESSIBLE */ int bind_topic(topic_func_t *func, int module_id);
+/* MODULAR ACCESSIBLE */ void unbind_topic(topic_func_t *func);
int event_topic(struct UserNode *user, struct ChanNode *chan, const char *new_topic);
+#endif
typedef void mode_func_t(struct UserNode *user, struct ChanNode *chan, char *modes, char **argv, int argc);
-int bind_mode(mode_func_t *func);
-void unbind_mode(mode_func_t *func);
+#ifndef DND_FUNCTIONS
+/* MODULAR ACCESSIBLE */ int bind_mode(mode_func_t *func, int module_id);
+/* MODULAR ACCESSIBLE */ void unbind_mode(mode_func_t *func);
int event_mode(struct UserNode *user, struct ChanNode *chan, char *modes, char **argv, int argc);
+#endif
typedef void chanmsg_func_t(struct UserNode *user, struct ChanNode *chan, char *message);
-int bind_chanmsg(chanmsg_func_t *func);
-void unbind_chanmsg(chanmsg_func_t *func);
+#ifndef DND_FUNCTIONS
+/* MODULAR ACCESSIBLE */ int bind_chanmsg(chanmsg_func_t *func, int module_id);
+/* MODULAR ACCESSIBLE */ void unbind_chanmsg(chanmsg_func_t *func);
int event_chanmsg(struct UserNode *user, struct ChanNode *chan, char *message);
+#endif
typedef void privmsg_func_t(struct UserNode *user, struct UserNode *target, char *message);
-int bind_privmsg(privmsg_func_t *func);
-void unbind_privmsg(privmsg_func_t *func);
+#ifndef DND_FUNCTIONS
+/* MODULAR ACCESSIBLE */ int bind_privmsg(privmsg_func_t *func, int module_id);
+/* MODULAR ACCESSIBLE */ void unbind_privmsg(privmsg_func_t *func);
int event_privmsg(struct UserNode *user, struct UserNode *target, char *message);
+#endif
typedef void channotice_func_t(struct UserNode *user, struct ChanNode *chan, char *message);
-int bind_channotice(channotice_func_t *func);
-void unbind_channotice(channotice_func_t *func);
+#ifndef DND_FUNCTIONS
+/* MODULAR ACCESSIBLE */ int bind_channotice(channotice_func_t *func, int module_id);
+/* MODULAR ACCESSIBLE */ void unbind_channotice(channotice_func_t *func);
int event_channotice(struct UserNode *user, struct ChanNode *chan, char *message);
+#endif
typedef void privnotice_func_t(struct UserNode *user, struct UserNode *target, char *message);
-int bind_privnotice(privnotice_func_t *func);
-void unbind_privnotice(privnotice_func_t *func);
+#ifndef DND_FUNCTIONS
+/* MODULAR ACCESSIBLE */ int bind_privnotice(privnotice_func_t *func, int module_id);
+/* MODULAR ACCESSIBLE */ void unbind_privnotice(privnotice_func_t *func);
int event_privnotice(struct UserNode *user, struct UserNode *target, char *message);
+#endif
typedef void chanctcp_func_t(struct UserNode *user, struct ChanNode *chan, char *command, char *text);
-int bind_chanctcp(chanctcp_func_t *func);
-void unbind_chanctcp(chanctcp_func_t *func);
+#ifndef DND_FUNCTIONS
+/* MODULAR ACCESSIBLE */ int bind_chanctcp(chanctcp_func_t *func, int module_id);
+/* MODULAR ACCESSIBLE */ void unbind_chanctcp(chanctcp_func_t *func);
int event_chanctcp(struct UserNode *user, struct ChanNode *chan, char *command, char *text);
+#endif
typedef void privctcp_func_t(struct UserNode *user, struct UserNode *target, char *command, char *text);
-int bind_privctcp(privctcp_func_t *func);
-void unbind_privctcp(privctcp_func_t *func);
+#ifndef DND_FUNCTIONS
+/* MODULAR ACCESSIBLE */ int bind_privctcp(privctcp_func_t *func, int module_id);
+/* MODULAR ACCESSIBLE */ void unbind_privctcp(privctcp_func_t *func);
int event_privctcp(struct UserNode *user, struct UserNode *target, char *command, char *text);
+#endif
typedef void invite_func_t(struct ClientSocket *client, struct UserNode *user, char *channel);
-int bind_invite(invite_func_t *func);
-void unbind_invite(invite_func_t *func);
+#ifndef DND_FUNCTIONS
+/* MODULAR ACCESSIBLE */ int bind_invite(invite_func_t *func, int module_id);
+/* MODULAR ACCESSIBLE */ void unbind_invite(invite_func_t *func);
int event_invite(struct ClientSocket *client, struct UserNode *user, char *channel);
+#endif
typedef void raw_func_t(struct ClientSocket *client, char *from, char *cmd, char **argv, int argc);
-int bind_raw(raw_func_t *func);
-void unbind_raw(raw_func_t *func);
+#ifndef DND_FUNCTIONS
+/* MODULAR ACCESSIBLE */ int bind_raw(raw_func_t *func, int module_id);
+/* MODULAR ACCESSIBLE */ void unbind_raw(raw_func_t *func);
int event_raw(struct ClientSocket *client, char *from, char *cmd, char **argv, int argc);
+#endif
typedef void bot_ready_func_t(struct ClientSocket *client);
-int bind_bot_ready(bot_ready_func_t *func);
-void unbind_bot_ready(bot_ready_func_t *func);
+#ifndef DND_FUNCTIONS
+/* MODULAR ACCESSIBLE */ int bind_bot_ready(bot_ready_func_t *func, int module_id);
+/* MODULAR ACCESSIBLE */ void unbind_bot_ready(bot_ready_func_t *func);
int event_bot_ready(struct ClientSocket *client);
+#endif
typedef int registered_func_t(struct UserNode *old_user, struct UserNode *new_user);
-int bind_registered(registered_func_t *func);
-void unbind_registered(registered_func_t *func);
+#ifndef DND_FUNCTIONS
+/* MODULAR ACCESSIBLE */ int bind_registered(registered_func_t *func, int module_id);
+/* MODULAR ACCESSIBLE */ void unbind_registered(registered_func_t *func);
int event_registered(struct UserNode *old_user, struct UserNode *new_user);
+#endif
typedef int freeuser_func_t(struct UserNode *user);
-int bind_freeuser(freeuser_func_t *func);
-void unbind_freeuser(freeuser_func_t *func);
+#ifndef DND_FUNCTIONS
+/* MODULAR ACCESSIBLE */ int bind_freeuser(freeuser_func_t *func, int module_id);
+/* MODULAR ACCESSIBLE */ void unbind_freeuser(freeuser_func_t *func);
int event_freeuser(struct UserNode *user);
+#endif
typedef int freechan_func_t(struct ChanNode *chan);
-int bind_freechan(freechan_func_t *func);
-void unbind_freechan(freechan_func_t *func);
+#ifndef DND_FUNCTIONS
+/* MODULAR ACCESSIBLE */ int bind_freechan(freechan_func_t *func, int module_id);
+/* MODULAR ACCESSIBLE */ void unbind_freechan(freechan_func_t *func);
int event_freechan(struct ChanNode *chan);
+#endif
-#endif
\ No newline at end of file
+#endif
struct irc_cmd *next;
};
+#ifndef DND_FUNCTIONS
extern int statistics_privmsg;
extern int statistics_network_users;
extern int statistics_network_channels;
void bot_disconnect(struct ClientSocket *client);
void init_parser();
void free_parser();
-void reply(struct ClientSocket *client, struct UserNode *user, const char *text, ...);
-char* merge_argv(char **argv, int start, int end);
-char* merge_argv_char(char **argv, int start, int end, char seperator);
-
-#endif
\ No newline at end of file
+/* MODULAR ACCESSIBLE */ void reply(struct ClientSocket *client, struct UserNode *user, const char *text, ...);
+/* MODULAR ACCESSIBLE */ char* merge_argv(char **argv, int start, int end);
+/* MODULAR ACCESSIBLE */ char* merge_argv_char(char **argv, int start, int end, char seperator);
+#endif
+#endif
int *mode_int_args;
};
-extern unsigned int valid_modes[];
-
+#ifndef DND_FUNCTIONS
void init_ModeNode();
-struct ModeNode *createModeNode(struct ChanNode *chan);
-void freeModeNode(struct ModeNode *modes);
-int isModeSet(struct ModeNode* modes, char modeChar);
-int isModeAffected(struct ModeNode* modes, char modeChar);
-void* getModeValue(struct ModeNode* modes, char modeChar);
-unsigned int getModeType(struct ModeNode* modes, char modeChar);
-void parseModes(struct ModeNode* modes, char *modeStr, char **argv, int argc);
-void parseModeString(struct ModeNode* modes, char *modeStr);
-int parseMode(struct ModeNode* modes, int add, char mode, char *param);
-void getModeString(struct ModeNode* modes, char *modesStr);
-void getFullModeString(struct ModeNode* modes, char *modesStr);
-
-#endif
\ No newline at end of file
+/* MODULAR ACCESSIBLE */ struct ModeNode *createModeNode(struct ChanNode *chan);
+/* MODULAR ACCESSIBLE */ void freeModeNode(struct ModeNode *modes);
+/* MODULAR ACCESSIBLE */ int isModeSet(struct ModeNode* modes, char modeChar);
+/* MODULAR ACCESSIBLE */ int isModeAffected(struct ModeNode* modes, char modeChar);
+/* MODULAR ACCESSIBLE */ void* getModeValue(struct ModeNode* modes, char modeChar);
+/* MODULAR ACCESSIBLE */ unsigned int getModeType(struct ModeNode* modes, char modeChar);
+/* MODULAR ACCESSIBLE */ void parseModes(struct ModeNode* modes, char *modeStr, char **argv, int argc);
+/* MODULAR ACCESSIBLE */ void parseModeString(struct ModeNode* modes, char *modeStr);
+/* MODULAR ACCESSIBLE */ int parseMode(struct ModeNode* modes, int add, char mode, char *param);
+/* MODULAR ACCESSIBLE */ void getModeString(struct ModeNode* modes, char *modesStr);
+/* MODULAR ACCESSIBLE */ void getFullModeString(struct ModeNode* modes, char *modesStr);
+#endif
+#endif
#define isNetworkService(USER) (USER->flags & (USERFLAG_ISBOT | USERFLAG_ISIRCOP | USERFLAG_ISSERVER))
#define isBot(USER) (USER->flags & (USERFLAG_ISBOT))
+#ifndef DND_FUNCTIONS
void init_UserNode();
void free_UserNode();
-int is_valid_nick(const char *nick);
-struct UserNode* getUserByNick(const char *nick);
-struct UserNode* getUserByMask(const char *mask);
-int countUsersWithHost(char *host);
-char *getAuthFakehost(char *auth);
-struct UserNode* searchUserByNick(const char *nick);
-struct UserNode* getAllUsers(struct UserNode *last);
-struct UserNode* getUsersWithAuth(const char *auth, struct UserNode *last);
-int getUserCount();
+/* MODULAR ACCESSIBLE */ int is_valid_nick(const char *nick);
+/* MODULAR ACCESSIBLE */ struct UserNode* getUserByNick(const char *nick);
+/* MODULAR ACCESSIBLE */ struct UserNode* getUserByMask(const char *mask);
+/* MODULAR ACCESSIBLE */ int countUsersWithHost(char *host);
+/* MODULAR ACCESSIBLE */ char *getAuthFakehost(char *auth);
+/* MODULAR ACCESSIBLE */ struct UserNode* searchUserByNick(const char *nick);
+/* MODULAR ACCESSIBLE */ struct UserNode* getAllUsers(struct UserNode *last);
+/* MODULAR ACCESSIBLE */ struct UserNode* getUsersWithAuth(const char *auth, struct UserNode *last);
+/* MODULAR ACCESSIBLE */ int getUserCount();
struct UserNode* addUser(const char *nick);
struct UserNode* addUserMask(const char *mask);
struct UserNode* createTempUser(const char *nick);
int renameUser(struct UserNode* user, const char *new_nick);
void delUser(struct UserNode* user, int freeUser);
void clearTempUsers();
-
+#endif
#endif
#include "ModeNode.h"
#include "ClientSocket.h"
#include "IPNode.h"
+#include "modules.h"
#define WHOQUEUETYPE_ISONQUEUE 0x01
#define WHOQUEUETYPE_USERLIST 0x02
struct UserNode *user;
struct WHOQueueEntry *next;
void *callback[MAXCALLBACKS];
+ int module_id[MAXCALLBACKS];
void *data[MAXCALLBACKS];
};
DESYNCHRONIZE(whohandler_sync);
}
-void get_userlist(struct ChanNode *chan, userlist_callback_t callback, void *data) {
+void get_userlist(struct ChanNode *chan, int module_id, userlist_callback_t callback, void *data) {
struct ClientSocket *bot;
for(bot = getBots(SOCKET_FLAG_READY, NULL); bot; bot = getBots(SOCKET_FLAG_READY, bot)) {
if(isUserOnChan(bot->user, chan))
entry->type = WHOQUEUETYPE_ISONQUEUE | WHOQUEUETYPE_USERLIST;
entry->chan = chan;
entry->callback[0] = callback;
+ entry->module_id[0] = module_id;
int i;
for(i = 1; i < MAXCALLBACKS; i++)
entry->callback[i] = NULL;
callback(bot, chan, data);
}
-void _get_userlist_with_invisible(struct ChanNode *chan, userlist_callback_t callback, void *data, int force) {
+void _get_userlist_with_invisible(struct ChanNode *chan, int module_id, userlist_callback_t callback, void *data, int force) {
struct ClientSocket *bot;
for(bot = getBots(SOCKET_FLAG_READY, NULL); bot; bot = getBots(SOCKET_FLAG_READY, bot)) {
if(isUserOnChan(bot->user, chan))
entry->type = WHOQUEUETYPE_ISONQUEUE | WHOQUEUETYPE_USERLIST;
entry->chan = chan;
entry->callback[0] = callback;
+ entry->module_id[0] = module_id;
int i;
for(i = 1; i < MAXCALLBACKS; i++)
entry->callback[i] = NULL;
callback(bot, chan, data);
}
-void get_userauth(struct UserNode *user, userauth_callback_t callback, void *data) {
+void get_userauth(struct UserNode *user, int module_id, userauth_callback_t callback, void *data) {
//check if we have already an active WHO for this user
struct ClientSocket *bot, *whobot = NULL;
struct WHOQueueEntry *entry;
for(i = 1; i < MAXCALLBACKS; i++) {
if(!entry->callback[i]) {
entry->callback[i] = callback;
+ entry->module_id[i] = module_id;
entry->data[i] = data;
return;
}
entry->user = user;
user->flags |= USERFLAG_IS_ON_WHO_QUEUE;
entry->callback[0] = callback;
+ entry->module_id[0] = module_id;
int i;
for(i = 1; i < MAXCALLBACKS; i++)
entry->callback[i] = NULL;
for(i = 0; i < MAXCALLBACKS; i++) {
userauth_callback_t *callback = entry->callback[i];
if(!callback) break;
- callback(client, entry->user->nick, entry->user, entry->data[i]);
+ if(!entry->module_id[i] || module_loaded(entry->module_id[i]))
+ callback(client, entry->user->nick, entry->user, entry->data[i]);
}
}
}
for(i = 0; i < MAXCALLBACKS; i++) {
callback = entry->callback[i];
if(!callback) break;
- callback(client, entry->chan, entry->data[i]);
+ if(!entry->module_id[i] || module_loaded(entry->module_id[i]))
+ callback(client, entry->chan, entry->data[i]);
}
if(entry->chan->flags & CHANFLAG_HAVE_INVISIBLES) {
//remove all invisible users again
for(i = 0; i < MAXCALLBACKS; i++) {
callback = entry->callback[i];
if(!callback) break;
- callback(client, entry->user->nick, NULL, entry->data[i]);
+ if(!entry->module_id[i] || module_loaded(entry->module_id[i]))
+ callback(client, entry->user->nick, NULL, entry->data[i]);
}
}
entry->user->flags &= ~USERFLAG_IS_ON_WHO_QUEUE;
#define USERAUTH_CALLBACK(NAME) void NAME(UNUSED_ARG(struct ClientSocket *client), UNUSED_ARG(char *user_nick), UNUSED_ARG(struct UserNode *user), UNUSED_ARG(void *data))
typedef USERAUTH_CALLBACK(userauth_callback_t);
+#define get_userlist_if_invisible(CHAN, MODID, CALLBACK, DATA) _get_userlist_with_invisible(CHAN, MODID, CALLBACK, DATA, 0)
+#define get_userlist_with_invisible(CHAN, MODID, CALLBACK, DATA) _get_userlist_with_invisible(CHAN, MODID, CALLBACK, DATA, 1)
+
+#ifndef DND_FUNCTIONS
void clear_whoqueue(struct ClientSocket *client);
void recv_whohandler_354(struct ClientSocket *client, char **argv, unsigned int argc);
void recv_whohandler_315(struct ClientSocket *client, char **argv, unsigned int argc);
-void get_userlist(struct ChanNode *chan, userlist_callback_t callback, void *data);
-#define get_userlist_if_invisible(CHAN, CALLBACK, DATA) _get_userlist_with_invisible(CHAN, CALLBACK, DATA, 0)
-#define get_userlist_with_invisible(CHAN, CALLBACK, DATA) _get_userlist_with_invisible(CHAN, CALLBACK, DATA, 1)
-void _get_userlist_with_invisible(struct ChanNode *chan, userlist_callback_t callback, void *data, int force);
-void get_userauth(struct UserNode *user, userauth_callback_t callback, void *data);
+/* MODULAR ACCESSIBLE */ void get_userlist(struct ChanNode *chan, int module_id, userlist_callback_t callback, void *data);
+/* MODULAR ACCESSIBLE */ void _get_userlist_with_invisible(struct ChanNode *chan, int module_id, userlist_callback_t callback, void *data, int force);
+/* MODULAR ACCESSIBLE */ void get_userauth(struct UserNode *user, int module_id, userauth_callback_t callback, void *data);
void free_whoqueue();
-
-#endif
\ No newline at end of file
+#endif
+#endif
+++ /dev/null
-/* bot_DummyServ.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "bot_DummyServ.h"
-#include "modcmd.h"
-#include "IRCParser.h"
-#include "IRCEvents.h"
-#include "UserNode.h"
-#include "ChanNode.h"
-#include "ChanUser.h"
-#include "ModeNode.h"
-#include "BanNode.h"
-#include "ClientSocket.h"
-#include "mysqlConn.h"
-#include "lang.h"
-#include "HandleInfoHandler.h"
-#include "WHOHandler.h"
-#include "DBHelper.h"
-#include "tools.h"
-#include "timeq.h"
-#include "version.h"
-#include "EventLogger.h"
-#include "bots.h"
-#include "cmd_neonserv.h"
-#include "cmd_neonspam.h"
-
-#define BOTID 3
-#define BOTALIAS "DummyServ"
-
-static void dummyserv_bot_ready(struct ClientSocket *client) {
- MYSQL_RES *res;
- MYSQL_ROW row;
-
- printf_mysql_query("SELECT `automodes` FROM `bots` WHERE `id` = '%d'", client->clientid);
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) != NULL) {
- putsock(client, "MODE %s +%s", client->user->nick, row[0]);
- }
-
- printf_mysql_query("SELECT `channel_name`, `channel_key` FROM `bot_channels` LEFT JOIN `channels` ON `chanid` = `channel_id` WHERE `botid` = '%d' AND `suspended` = '0'", client->clientid);
- res = mysql_use();
-
- while ((row = mysql_fetch_row(res)) != NULL) {
- putsock(client, "JOIN %s %s", row[0], row[1]);
- }
-}
-
-static void dummyserv_trigger_callback(int clientid, struct ChanNode *chan, char *trigger) {
- //this bot doesn't have a trigger
- strcpy(trigger, "");
-}
-
-static void start_bots() {
- struct ClientSocket *client;
- MYSQL_RES *res, *res2;
- MYSQL_ROW row;
-
- printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `textbot`, `id`, `queue`, `ssl`, `bind` FROM `bots` WHERE `botclass` = '%d' AND `active` = '1'", BOTID);
- res = mysql_use();
-
- while ((row = mysql_fetch_row(res)) != NULL) {
- client = create_socket(row[3], atoi(row[4]), row[10], row[5], row[0], row[1], row[2]);
- client->flags |= (strcmp(row[6], "0") ? SOCKET_FLAG_PREFERRED : 0);
- client->flags |= (strcmp(row[8], "0") ? SOCKET_FLAG_USE_QUEUE : 0);
- client->flags |= (strcmp(row[9], "0") ? SOCKET_FLAG_SSL : 0);
- client->flags |= SOCKET_FLAG_SILENT;
- client->botid = BOTID;
- client->clientid = atoi(row[7]);
- connect_socket(client);
- }
-
- printf_mysql_query("SELECT `command`, `function`, `parameters`, `global_access`, `chan_access`, `flags` FROM `bot_binds` WHERE `botclass` = '%d'", BOTID);
- res2 = mysql_use();
- while ((row = mysql_fetch_row(res2)) != NULL) {
- if(bind_cmd_to_command(BOTID, row[0], row[1])) {
- if(row[2] && strcmp(row[2], "")) {
- bind_set_parameters(BOTID, row[0], row[2]);
- }
- if(row[3]) {
- bind_set_global_access(BOTID, row[0], atoi(row[3]));
- }
- if(row[4]) {
- bind_set_channel_access(BOTID, row[0], row[4]);
- }
- if(strcmp(row[5], "0"))
- bind_set_bind_flags(BOTID, row[0], atoi(row[5]));
- }
- }
- bind_unbound_required_functions(BOTID);
-}
-
-void init_DummyServ() {
-
- set_bot_alias(BOTID, BOTALIAS);
- start_bots();
-
- //register events
- bind_bot_ready(dummyserv_bot_ready);
-
- set_trigger_callback(BOTID, dummyserv_trigger_callback);
-}
-
-void loop_DummyServ() {
-
-}
-
-void free_DummyServ() {
-
-}
-
-#undef BOTID
-#undef BOTALIAS
+++ /dev/null
-/* bot_DummyServ.h - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-#ifndef _bot_DummyServ_h
-#define _bot_DummyServ_h
-
-#include "main.h"
-
-void init_DummyServ();
-void loop_DummyServ();
-void free_DummyServ();
-
-#endif
\ No newline at end of file
+++ /dev/null
-/* bot_NeonHelp.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "bot_NeonHelp.h"
-#include "modcmd.h"
-#include "cmd_neonhelp.h"
-#include "lang.h"
-#include "mysqlConn.h"
-#include "ClientSocket.h"
-#include "UserNode.h"
-#include "ChanNode.h"
-#include "ChanUser.h"
-#include "IRCEvents.h"
-#include "IRCParser.h"
-#include "bots.h"
-#include "DBHelper.h"
-#include "WHOHandler.h"
-
-#define BOTID 4
-#define BOTALIAS "NeonHelp"
-
-static const struct default_language_entry msgtab[] = {
- {"NH_NOT_ON_CHAN_1", "You cannot open this request as you are not in %s."}, /* {ARGS: "#test"} */
- {"NH_NOT_ON_CHAN_2", "You cannot open this request as you are not in %s or %s."}, /* {ARGS: "test", "#test-support"} */
- {"NH_REQUEST_RECORDED", "Your message has been recorded and assigned request ID#%d A helper should contact you shortly."}, /* {ARGS: 5} */
- {"NH_REQUEST_OTHERS_0", "There are no other unhandled requests."},
- {"NH_REQUEST_OTHERS_1", "There is 1 other unhandled request."},
- {"NH_REQUEST_OTHERS_2", "There are %d other unhandled requests."}, /* {ARGS: 1337} */
- {"NH_REQUEST_FOOTER_1", "Everything you tell me until you are helped (or you leave %1$s) will be recorded. If you part %1$s, your request will be lost."}, /* {ARGS: "#test"} */
- {"NH_REQUEST_FOOTER_2", "Everything you tell me until you are helped (or you leave %1$s or %2$s) will be recorded. If you part %1$s or %2$s, your request will be lost."}, /* {ARGS: "#test", "#test-support"} */
- {"NH_NEW_REQUEST", "New request #%d by %s: %s"}, /* {ARGS: 5, "pk910", "Help, I've fallen and I can't get up!"} */
- {"NH_NEXT_NONE", "No more requests."},
- {"NH_NEXT_NOT_FOUND", "No request found."},
- {"NH_NEXT_HEADER", "$bNext request: #%d %s$b"}, /* {ARGS: 5, "pk910"} */
- {"NH_NEXT_HELPER", "Your helper for request ID#%d is %s (Current nick: %s)."}, /* {ARGS: 5, "pk910", "Skynet"} */
- {"NH_NEXT_JOIN", "Please /join %s now."}, /* {ARGS: "#test-support"} */
- {"NH_DELETED", "Your request ID#%d has been deleted."}, /* {ARGS: 5} */
- {"NH_DELETED_STAFF", "Request deleted: #%d (%s)"}, /* {ARGS: 5, "pk910"} */
- {"NH_REMIND_OPEN_REQUESTS_1", "There is %d unhandled request!"}, /* {ARGS: 1} */
- {"NH_REMIND_OPEN_REQUESTS_2", "There are %d unhandled requests!"}, /* {ARGS: 4} */
- {"NH_REQUESTS_HEADER_ID", "ID"},
- {"NH_REQUESTS_HEADER_STATUS", "State"},
- {"NH_REQUESTS_HEADER_NICK", "Nick"},
- {"NH_REQUESTS_HEADER_TIME", "Time"},
- {"NH_REQUESTS_HEADER_REQUEST", "Question"},
- {"NH_REQUESTS_STATE_ACTIVE", "active"},
- {"NH_REQUESTS_STATE_PENDING", "pending"},
- {"NH_REQUESTS_STATE_ERROR", "ERROR"},
- {"NH_STATS_HEADER_USER", "User"},
- {"NH_STATS_HEADER_LAST_24H", "last 24h"},
- {"NH_STATS_HEADER_LAST_7DAY", "last 7d"},
- {"NH_STATS_HEADER_LAST_30DAY", "last 30d"},
- {NULL, NULL}
-};
-
-static void neonhelp_bot_ready(struct ClientSocket *client) {
- MYSQL_RES *res;
- MYSQL_ROW row;
-
- printf_mysql_query("SELECT `automodes` FROM `bots` WHERE `id` = '%d'", client->clientid);
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) != NULL) {
- putsock(client, "MODE %s +%s", client->user->nick, row[0]);
- }
-
- printf_mysql_query("SELECT `channel_name`, `channel_key` FROM `bot_channels` LEFT JOIN `channels` ON `chanid` = `channel_id` WHERE `botid` = '%d' AND `suspended` = '0'", client->clientid);
- res = mysql_use();
-
- while ((row = mysql_fetch_row(res)) != NULL) {
- putsock(client, "JOIN %s %s", row[0], row[1]);
- }
-}
-
-static void neonhelp_trigger_callback(int clientid, struct ChanNode *chan, char *trigger) {
- MYSQL_RES *res;
- MYSQL_ROW row;
- loadChannelSettings(chan);
- if(!(chan->flags & CHANFLAG_CHAN_REGISTERED)) {
- strcpy(trigger, "!");
- return;
- }
- printf_mysql_query("SELECT `trigger`, `defaulttrigger` FROM `bot_channels` LEFT JOIN `bots` ON `botid` = `bots`.`id` WHERE `chanid` = '%d' AND `botclass` = '%d'", chan->channel_id, BOTID);
- res = mysql_use();
- if(!(row = mysql_fetch_row(res))) {
- strcpy(trigger, "!");
- return;
- }
- if(row[0] && *row[0])
- strcpy(trigger, row[0]);
- else
- strcpy(trigger, ((row[1] && *row[1]) ? row[1] : "!"));
-}
-
-static void start_bots() {
- struct ClientSocket *client;
- MYSQL_RES *res, *res2;
- MYSQL_ROW row;
-
- printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `textbot`, `id`, `queue`, `ssl`, `bind` FROM `bots` WHERE `botclass` = '%d' AND `active` = '1'", BOTID);
- res = mysql_use();
-
- while ((row = mysql_fetch_row(res)) != NULL) {
- client = create_socket(row[3], atoi(row[4]), row[10], row[5], row[0], row[1], row[2]);
- client->flags |= (strcmp(row[6], "0") ? SOCKET_FLAG_PREFERRED : 0);
- client->flags |= (strcmp(row[8], "0") ? SOCKET_FLAG_USE_QUEUE : 0);
- client->flags |= (strcmp(row[9], "0") ? SOCKET_FLAG_SSL : 0);
- client->flags |= SOCKET_FLAG_SILENT;
- client->botid = BOTID;
- client->clientid = atoi(row[7]);
- connect_socket(client);
- //close old, still opened requests
- printf_mysql_query("UPDATE `helpserv_requests` SET `status` = '2' WHERE `botid` = '%d'", client->clientid);
- }
-
- printf_mysql_query("SELECT `command`, `function`, `parameters`, `global_access`, `chan_access`, `flags` FROM `bot_binds` WHERE `botclass` = '%d'", BOTID);
- res2 = mysql_use();
- while ((row = mysql_fetch_row(res2)) != NULL) {
- if(bind_cmd_to_command(BOTID, row[0], row[1])) {
- if(row[2] && strcmp(row[2], "")) {
- bind_set_parameters(BOTID, row[0], row[2]);
- }
- if(row[3]) {
- bind_set_global_access(BOTID, row[0], atoi(row[3]));
- }
- if(row[4]) {
- bind_set_channel_access(BOTID, row[0], row[4]);
- }
- if(strcmp(row[5], "0"))
- bind_set_bind_flags(BOTID, row[0], atoi(row[5]));
- }
- }
- bind_unbound_required_functions(BOTID);
-}
-
-static void neonhelp_event_privmsg_async(struct ClientSocket *client, struct UserNode *user, struct UserNode *target, char *message);
-static USERAUTH_CALLBACK(neonhelp_event_privmsg_nick_lookup);
-struct neonhelp_event_privmsg_cache {
- struct ClientSocket *client;
- struct UserNode *user, *target;
- char *message;
-};
-
-static void neonhelp_event_privmsg(struct UserNode *user, struct UserNode *target, char *message) {
- struct ClientSocket *client;
- for(client = getBots(SOCKET_FLAG_READY, NULL); client; client = getBots(SOCKET_FLAG_READY, client)) {
- if(client->user == target) {
- if(client->botid != BOTID) return;
- break;
- }
- }
- if(!client) return; //we got the message but we have no client that could receive it???
- if(user->flags & USERFLAG_ISAUTHED) {
- neonhelp_event_privmsg_async(client, user, target, message);
- } else {
- struct neonhelp_event_privmsg_cache *cache = malloc(sizeof(*cache));
- if(!cache) return;
- cache->client = client;
- cache->user = user;
- cache->target = target;
- cache->message = strdup(message);
- get_userauth(user, neonhelp_event_privmsg_nick_lookup, cache);
- }
-}
-
-static USERAUTH_CALLBACK(neonhelp_event_privmsg_nick_lookup) {
- struct neonhelp_event_privmsg_cache *cache = data;
- neonhelp_event_privmsg_async(cache->client, cache->user, cache->target, cache->message);
- free(cache->message);
- free(cache);
-}
-
-static TIMEQ_CALLBACK(neonhelp_remind_open_requests);
-
-static void neonhelp_event_privmsg_async(struct ClientSocket *client, struct UserNode *user, struct UserNode *target, char *message) {
- MYSQL_RES *res;
- MYSQL_ROW row, row2;
- printf_mysql_query("SELECT `helpserv_support`, `helpserv_public`, `helpserv_intern`, `helpserv_intern_announce` FROM `helpserv_settings` WHERE `helpserv_botid` = '%d'", client->clientid);
- res = mysql_use();
- if (!(row = mysql_fetch_row(res))) return;
- //check if the user is a supporter (access in the support channel)
- if((user->flags & USERFLAG_ISAUTHED)) {
- int caccess = 0;
- int userid;
- if(user->flags & USERFLAG_HAS_USERID)
- userid = user->user_id;
- else {
- printf_mysql_query("SELECT `user_id` FROM `users` WHERE `user_user` = '%s'", escape_string(user->auth));
- res = mysql_use();
- if ((row2 = mysql_fetch_row(res)) != NULL) {
- userid = atoi(row2[0]);
- user->user_id = userid;
- user->flags |= USERFLAG_HAS_USERID;
- } else
- userid = 0;
- }
- printf_mysql_query("SELECT `chanuser_access`, `chanuser_flags` FROM `chanusers` LEFT JOIN `channels` ON `chanuser_cid` = `channel_id` WHERE `chanuser_uid` = '%d' AND `channel_name` = '%s'", userid, escape_string(row[0]));
- res = mysql_use();
- if ((row2 = mysql_fetch_row(res)) != NULL) {
- int cflags = atoi(row2[1]);
- if(!(cflags & DB_CHANUSER_SUSPENDED))
- caccess = atoi(row2[0]);
- }
- if(caccess) return; //ignore messages from supporters
- }
- //check if the user is in one of the bot's channels
- struct ChanUser *chanuser;
- struct ChanNode *chan;
- for(chanuser = getUserChannels(target, NULL); chanuser; chanuser = getUserChannels(target, chanuser)) {
- chan = chanuser->chan;
- if((!stricmp(chan->name, row[0]) || (row[1] && !stricmp(chan->name, row[1]))) && isUserOnChan(user, chan))
- break;
- }
- if(!chanuser) {
- if(row[1])
- reply(client, user, "NH_NOT_ON_CHAN_2", row[0], row[1]);
- else
- reply(client, user, "NH_NOT_ON_CHAN_1", row[0]);
- return;
- }
- //check if there is already a support request
- int others = 0;
- if(client->flags & SOCKET_HAVE_HELPNODE) {
- struct NeonHelpNode *helpnode;
- for(helpnode = client->botclass_helpnode; helpnode; helpnode = helpnode->next) {
- if(helpnode->user == user) {
- //simply append the message to the database
- printf_mysql_query("SELECT `text` FROM `helpserv_requests` WHERE `id` = %d", helpnode->suppid);
- res = mysql_use();
- if ((row2 = mysql_fetch_row(res)) != NULL) {
- char *old_msg = escape_string(row2[0]);
- char *new_msg = escape_string(message);
- printf_long_mysql_query(1024 + strlen(old_msg) + strlen(new_msg), "UPDATE `helpserv_requests` SET `text` = '%s\n%s' WHERE `id` = %d", old_msg, new_msg, helpnode->suppid);
- }
- return;
- }
- others++;
- }
- }
- //add new request
- struct NeonHelpNode *helpnode = malloc(sizeof(*helpnode));
- if(!helpnode) return;
- helpnode->user = user;
- helpnode->logchan = getChanByName(row[0]);
- helpnode->status = 0;
- helpnode->announce = (row[2] && strcmp(row[3], "0") ? 1 : 0);
- if(helpnode->announce) {
- char nameBuf[30];
- sprintf(nameBuf, "neonhelp_%d", client->clientid);
- if(!timeq_name_exists(nameBuf)) {
- int *cidptr = malloc(sizeof(int));
- *cidptr = client->clientid;
- timeq_add_name(nameBuf, 300, neonhelp_remind_open_requests, cidptr);
- }
- }
- printf_mysql_query("INSERT INTO `helpserv_requests` (`botid`, `host`, `hand`, `nick`, `status`, `supporter`, `time`, `text`) VALUES ('%d', '%s@%s', '%s', '%s', '0', '-1', UNIX_TIMESTAMP(), '%s')", client->clientid, escape_string(user->ident), escape_string(user->host), ((user->flags & USERFLAG_ISAUTHED) ? escape_string(user->auth) : "*"), escape_string(user->nick), escape_string(message));
- helpnode->suppid = (int) mysql_insert_id(get_mysql_conn());
- helpnode->log = NULL;
- helpnode->next = ((client->flags & SOCKET_HAVE_HELPNODE) ? client->botclass_helpnode : NULL);
- client->botclass_helpnode = helpnode;
- client->flags |= SOCKET_HAVE_HELPNODE;
- //build the user reply...
- char user_reply[MAXLEN];
- int user_reply_pos = 0;
- char reply_buff[MAXLEN];
- //1st part: NH_REQUEST_RECORDED
- strcpy(user_reply + user_reply_pos, build_language_string(user, reply_buff, "NH_REQUEST_RECORDED", helpnode->suppid));
- user_reply_pos += strlen(reply_buff);
- //2nd part: NH_REQUEST_OTHERS_0 / NH_REQUEST_OTHERS_1 / NH_REQUEST_OTHERS_2
- user_reply[user_reply_pos++] = ' ';
- if(others <= 1)
- strcpy(user_reply + user_reply_pos, build_language_string(user, reply_buff, (others ? "NH_REQUEST_OTHERS_1" : "NH_REQUEST_OTHERS_0")));
- else
- strcpy(user_reply + user_reply_pos, build_language_string(user, reply_buff, "NH_REQUEST_OTHERS_2", others));
- user_reply_pos += strlen(reply_buff);
- //3th part: NH_REQUEST_FOOTER_1 / NH_REQUEST_FOOTER_2
- user_reply[user_reply_pos++] = ' ';
- if(row[1])
- strcpy(user_reply + user_reply_pos, build_language_string(user, reply_buff, "NH_REQUEST_FOOTER_2", row[0], row[1]));
- else
- strcpy(user_reply + user_reply_pos, build_language_string(user, reply_buff, "NH_REQUEST_FOOTER_1", row[0]));
- user_reply_pos += strlen(reply_buff);
- reply(client, user, "%s", user_reply);
- //sent a message to the internal channel / onotice to supp channel
- build_language_string(user, reply_buff, "NH_NEW_REQUEST", helpnode->suppid, user->nick, message);
- if(row[2]) {
- putsock(client, "PRIVMSG %s :%s", row[2], reply_buff);
- } else {
- putsock(client, "NOTICE @%s :%s", row[0], reply_buff);
- }
-}
-
-static TIMEQ_CALLBACK(neonhelp_remind_open_requests) {
- int clientid = *((int*)data);
- MYSQL_RES *res;
- MYSQL_ROW row;
- printf_mysql_query("SELECT `helpserv_support`, `helpserv_public`, `helpserv_intern`, `helpserv_intern_announce` FROM `helpserv_settings` WHERE `helpserv_botid` = '%d'", clientid);
- res = mysql_use();
- if (!(row = mysql_fetch_row(res)) || !row[2]) {
- free(data);
- return;
- }
- struct ClientSocket *client;
- for(client = getBots(SOCKET_FLAG_READY, NULL); client; client = getBots(SOCKET_FLAG_READY, client)) {
- if(client->clientid == clientid)
- break;
- }
- if(!client) {
- free(data);
- return;
- }
- //count open requests
- int requests = 0;
- struct NeonHelpNode *helpnode;
- if(client->flags & SOCKET_HAVE_HELPNODE) {
- for(helpnode = client->botclass_helpnode; helpnode; helpnode = helpnode->next) {
- if(helpnode->status == 0) {
- requests++;
- }
- }
- }
- if(requests) {
- char nameBuf[30];
- sprintf(nameBuf, "neonhelp_%d", client->clientid);
- if(!timeq_name_exists(nameBuf)) {
- timeq_add_name(nameBuf, 300, neonhelp_remind_open_requests, data);
- }
- char replybuf[MAXLEN];
- build_language_string(NULL, replybuf, (requests == 1 ? "NH_REMIND_OPEN_REQUESTS_1" : "NH_REMIND_OPEN_REQUESTS_2"), requests);
- putsock(client, "PRIVMSG %s :%s", row[2], replybuf);
- } else
- free(data);
-}
-
-static void neonhelp_event_chanmsg(struct UserNode *user, struct ChanNode *chan, char *message) {
- char logline[MAXLEN];
- sprintf(logline, "<%s> %s", user->nick, message);
- struct ClientSocket *client;
- for(client = getBots(SOCKET_FLAG_READY, NULL); client; client = getBots(SOCKET_FLAG_READY, client)) {
- if(client->botid == BOTID) {
- struct NeonHelpNode *helpnode;
- if(client->flags & SOCKET_HAVE_HELPNODE) {
- for(helpnode = client->botclass_helpnode; helpnode; helpnode = helpnode->next) {
- if(helpnode->logchan == chan && helpnode->status == 1) {
- if(!helpnode->log) {
- helpnode->log = calloc(LOGBUFFERLINES, sizeof(char*));
- if(!helpnode->log) return;
- }
- int i;
- for(i = 0; i < LOGBUFFERLINES; i++) {
- if(!helpnode->log[i]) {
- helpnode->log[i] = strdup(logline);
- break;
- }
- }
- if(i == LOGBUFFERLINES) {
- //write buffer to database
- char logbuff[MAXLEN * LOGBUFFERLINES];
- int len = 0;
- for(i = 0; i < LOGBUFFERLINES; i++) {
- len += sprintf(logbuff + len, "%s\n", helpnode->log[i]);
- free(helpnode->log[i]);
- helpnode->log[i] = NULL;
- }
- printf_long_mysql_query(1024 + len, "UPDATE `helpserv_requests` SET `log` = CONCAT(`log`, '%s') WHERE `id` = %d", escape_string(logbuff), helpnode->suppid);
- }
- break;
- }
- }
- }
- }
- }
-}
-
-static void destroy_support_request(struct ClientSocket *client, struct NeonHelpNode *helpnode, int do_reply) {
- //write buffer to database
- char logbuff[MAXLEN * LOGBUFFERLINES];
- int len = 0;
- int i;
- if(helpnode->log) {
- for(i = 0; i < LOGBUFFERLINES; i++) {
- if(!helpnode->log[i]) break;
- len += sprintf(logbuff + len, "%s\n", helpnode->log[i]);
- free(helpnode->log[i]);
- helpnode->log[i] = NULL;
- }
- free(helpnode->log);
- } else
- logbuff[0] = '\0';
- printf_long_mysql_query(1024 + len, "UPDATE `helpserv_requests` SET `status`='2', `log` = CONCAT(`log`, '%s') WHERE `id` = %d", escape_string(logbuff), helpnode->suppid);
- if(do_reply) {
- reply(client, helpnode->user, "NH_DELETED", helpnode->suppid);
- }
- free(helpnode);
-}
-
-static void neonhelp_event_kick(struct UserNode *user, struct ChanUser *target, char *reason) {
- struct ClientSocket *client;
- MYSQL_RES *res;
- MYSQL_ROW row;
- struct ChanNode *support, *public;
- int userHasRequest;
- for(client = getBots(SOCKET_FLAG_READY, NULL); client; client = getBots(SOCKET_FLAG_READY, client)) {
- if(client->botid == BOTID && isUserOnChan(client->user, target->chan)) {
- userHasRequest = 0;
- struct NeonHelpNode *helpnode, *prev_helpnode = NULL;
- if(client->flags & SOCKET_HAVE_HELPNODE) {
- for(helpnode = client->botclass_helpnode; helpnode; helpnode = helpnode->next) {
- if(helpnode->user == target->user) {
- userHasRequest = 1;
- break;
- } else
- prev_helpnode = helpnode;
- }
- }
- if(!userHasRequest) continue;
- printf_mysql_query("SELECT `helpserv_support`, `helpserv_public`, `helpserv_intern` FROM `helpserv_settings` WHERE `helpserv_botid` = '%d'", client->clientid);
- res = mysql_use();
- if (!(row = mysql_fetch_row(res))) continue;
- support = getChanByName(row[0]);
- public = (row[1] ? getChanByName(row[1]) : NULL);
- if(target->chan == support || !((support && isUserOnChan(target->user, support)) || (public && isUserOnChan(target->user, public)))) {
- //free the user's support request
- if(prev_helpnode)
- prev_helpnode->next = helpnode->next;
- else
- client->botclass_helpnode = helpnode->next;
- destroy_support_request(client, helpnode, 1);
- }
- }
- }
-}
-
-static void neonhelp_event_part(struct ChanUser *target, char *reason) {
- struct ClientSocket *client;
- MYSQL_RES *res;
- MYSQL_ROW row;
- struct ChanNode *support, *public;
- int userHasRequest;
- for(client = getBots(SOCKET_FLAG_READY, NULL); client; client = getBots(SOCKET_FLAG_READY, client)) {
- if(client->botid == BOTID && isUserOnChan(client->user, target->chan)) {
- userHasRequest = 0;
- struct NeonHelpNode *helpnode, *prev_helpnode = NULL;
- if(client->flags & SOCKET_HAVE_HELPNODE) {
- for(helpnode = client->botclass_helpnode; helpnode; helpnode = helpnode->next) {
- if(helpnode->user == target->user) {
- userHasRequest = 1;
- break;
- } else
- prev_helpnode = helpnode;
- }
- }
- if(!userHasRequest) continue;
- printf_mysql_query("SELECT `helpserv_support`, `helpserv_public`, `helpserv_intern` FROM `helpserv_settings` WHERE `helpserv_botid` = '%d'", client->clientid);
- res = mysql_use();
- if (!(row = mysql_fetch_row(res))) continue;
- support = getChanByName(row[0]);
- public = (row[1] ? getChanByName(row[1]) : NULL);
- if(target->chan == support || !((support && isUserOnChan(target->user, support)) || (public && isUserOnChan(target->user, public)))) {
- //free the user's support request
- if(prev_helpnode)
- prev_helpnode->next = helpnode->next;
- else
- client->botclass_helpnode = helpnode->next;
- destroy_support_request(client, helpnode, 1);
- }
- }
- }
-}
-
-static void neonhelp_event_quit(struct UserNode *target, char *reason) {
- struct ClientSocket *client;
- int userHasRequest;
- for(client = getBots(SOCKET_FLAG_READY, NULL); client; client = getBots(SOCKET_FLAG_READY, client)) {
- if(client->botid == BOTID) {
- userHasRequest = 0;
- struct NeonHelpNode *helpnode, *prev_helpnode = NULL;
- if(client->flags & SOCKET_HAVE_HELPNODE) {
- for(helpnode = client->botclass_helpnode; helpnode; helpnode = helpnode->next) {
- if(helpnode->user == target) {
- userHasRequest = 1;
- break;
- } else
- prev_helpnode = helpnode;
- }
- }
- if(!userHasRequest) continue;
- //free the user's support request
- if(prev_helpnode)
- prev_helpnode->next = helpnode->next;
- else
- client->botclass_helpnode = helpnode->next;
- destroy_support_request(client, helpnode, 0);
- }
- }
-}
-
-void init_NeonHelp() {
-
- set_bot_alias(BOTID, BOTALIAS);
- start_bots();
-
- //register events
- bind_bot_ready(neonhelp_bot_ready);
- bind_privmsg(neonhelp_event_privmsg);
- bind_chanmsg(neonhelp_event_chanmsg);
- bind_part(neonhelp_event_part);
- bind_kick(neonhelp_event_kick);
- bind_quit(neonhelp_event_quit);
-
- set_trigger_callback(BOTID, neonhelp_trigger_callback);
-
- register_default_language_table(msgtab);
-}
-
-void loop_NeonHelp() {
-
-}
-
-void free_NeonHelp() {
-
-}
-
-#undef BOTID
-#undef BOTALIAS
+++ /dev/null
-/* bot_NeonHelp.h - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-#ifndef _bot_NeonHelp_h
-#define _bot_NeonHelp_h
-
-#include "main.h"
-
-/* definition for ClientSocket struct */
-#define botclass_helpnode botclassvalue1
-#define SOCKET_HAVE_HELPNODE SOCKET_HAVE_BOTCLASSVALUE1
-
-#define LOGBUFFERLINES 20
-
-struct UserNode;
-struct ChanNode;
-
-struct NeonHelpNode {
- struct UserNode *user;
- int suppid;
- char status:6;
- char announce:2;
- struct NeonHelpNode *next;
- struct ChanNode *logchan;
- char **log;
-};
-
-void init_NeonHelp();
-void loop_NeonHelp();
-void free_NeonHelp();
-
-#endif
\ No newline at end of file
+++ /dev/null
-/* bot_NeonServ.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "bot_NeonServ.h"
-#include "modcmd.h"
-#include "IRCEvents.h"
-#include "IRCParser.h"
-#include "UserNode.h"
-#include "ChanNode.h"
-#include "ChanUser.h"
-#include "BanNode.h"
-#include "ModeNode.h"
-#include "ClientSocket.h"
-#include "mysqlConn.h"
-#include "lang.h"
-#include "HandleInfoHandler.h"
-#include "WHOHandler.h"
-#include "DBHelper.h"
-#include "tools.h"
-#include "timeq.h"
-#include "EventLogger.h"
-#include "cmd_neonserv.h"
-#include "ConfigParser.h"
-
-#define BOTID 1
-#define BOTALIAS "NeonServ"
-
-static const struct default_language_entry msgtab[] = {
- {"NS_USER_UNKNOWN", "User with nick $b%s$b does not exist."}, /* {ARGS: "TestUser"} */
- {"NS_AUTH_UNKNOWN", "Account $b%s$b has not been registered."}, /* {ARGS: "TestAuth"} */
- {"NS_USER_NEED_AUTH", "%s must first authenticate with $bAuthServ$b."}, /* {ARGS: "TestUser"} */
- {"NS_YOU_NEED_AUTH", "You must first authenticate with $bAuthServ$b."},
- {"NS_INVALID_ACCESS", "$b%d$b is an invalid access level."}, /* {ARGS: 1337} */
- {"NS_ADDUSER_ALREADY_ADDED", "%s is already on the $b%s$b user list (with access %d)."}, /* {ARGS: "TestUser", "#TestChan", 123} */
- {"NS_ADDUSER_DONE", "Added %s to the %s user list with access %d."}, /* {ARGS: "TestUser", "#TestChan", 123} */
- {"NS_NOT_ON_USERLIST", "%s lacks access to $b%s$b."}, /* {ARGS: "TestUser", "#TestChan"} */
- {"NS_NOT_ON_USERLIST_YOU", "You lack access to $b%s$b."}, /* {ARGS: "#TestChan"} */
- {"NS_NOT_ON_CHANNEL", "%s isn't currently in $b%s$b."}, /* {ARGS: "TestUser", "#TestChan"} */
- {"NS_NOT_ON_CHANNEL_YOU", "You aren't currently in $b%s$b."}, /* {ARGS: "#TestChan"} */
- {"NS_DELUSER_DONE", "Deleted %s (with access %d) from the %s user list."}, /* {ARGS: "TestUser", 123, "#TestChan"} */
- {"NS_ACCESS_OUTRANKED", "You cannot give users access greater than or equal to your own."},
- {"NS_USER_OUTRANKED", "$b%s$b outranks you (command has no effect)."}, /* {ARGS: "TestUser"} */
- {"NS_ACCESS_DENIED", "Access denied."},
- {"NS_NO_ACCESS", "You lack sufficient access to use this command."},
- {"NS_USER_PROTECTED", "Sorry, $b%s$b is protected."}, /* {ARGS: "TestUser"} */
- {"NS_SERVICE_IMMUNE", "$b%s$b may not be kicked, killed, banned, or deopped."}, /* {ARGS: "TestUser"} */
- {"NS_YOU_PROTECTED", "You may not kick or ban yourself."},
- {"NS_TABLE_NONE", " None"},
- {"NS_TABLE_COUNT", "Found $b%d$b matches."}, /* {ARGS: 5} */
- {"NS_BAN_ALREADY_ADDED", "$b%s$b is already banned in %s."}, /* {ARGS: "*!*@moeeep.*", "#TestChan"} */
- {"NS_INVALID_ACCESS_RANGE", "Invalid access range; minimum (%d) must be lower than maximum (%d)."}, /* {ARGS: 450, 400} */
- {"NS_CLVL_DONE", "%s now has access $b%d$b in %s."}, /* {ARGS: "TestUser", 123, "#TestChan"} */
- {"NS_A_LACKS_ACCESS_BUT_GOD_NICK", "%s lacks access to %s but has $bsecurity override$b enabled."}, /* {ARGS: "TestAuth", "#TestChan"} */
- {"NS_A_LACKS_ACCESS_BUT_GOD_AUTH", "%s (%s) lacks access to %s but has $bsecurity override$b enabled."}, /* {ARGS: "TestAuth", "TestUser", "#TestChan"} */
- {"NS_A_ACCESS_NICK", "%s has access $b%d$b in %s."}, /* {ARGS: "TestAuth", 123, "#TestChan"} */
- {"NS_A_ACCESS_AUTH", "%s (%s) has access $b%d$b in %s."}, /* {ARGS: "TestAuth", "TestUser", 123, "#TestChan"} */
- {"NS_A_ACCESS_NICK_GOD", "%s has access $b%d$b in %s and has $bsecurity override$b enabled."}, /* {ARGS: "TestAuth", 123, "#TestChan"} */
- {"NS_A_ACCESS_AUTH_GOD", "%s (%s) has access $b%d$b in %s and has $bsecurity override$b enabled."}, /* {ARGS: "TestAuth", "TestUser", 123, "#TestChan"} */
- {"NS_A_SUSPENDED", "$b%s$b's access to %s has been suspended."}, /* {ARGS: "TestAuth", "#TestChan"} */
- {"NS_A_IS_IRCOP", "%s is an $bIRC operator$b."}, /* {ARGS: "TestUser", "#TestChan"} */
- {"NS_USERS_HEADER", "%s users from level %d to %d:"}, /* {ARGS: "#TestChan", 1, 500} */
- {"NS_USERS_HEADER_MATCH", "%s users from level %d to %d matching %s:"}, /* {ARGS: "#TestChan", 1, 500, "Test*"} */
- {"NS_USERS_HEADER_ACCESS", "Access"},
- {"NS_USERS_HEADER_ACCOUNT", "Accout"},
- {"NS_USERS_HEADER_SEEN", "Last Seen"},
- {"NS_USERS_HEADER_STATE", "Status"},
- {"NS_USERS_COUNT", "There are $b%d$b users in %s."}, /* {ARGS: 20, "#TestChan"} */
- {"NS_USERS_COUNT_1", "There is $b%d$b user in %s."}, /* {ARGS: 1, "#TestChan"} */
- {"NS_USERS_COUNT_MATCH", "There are $b%d$b users in %s. ($b%d$b matching your request)"}, /* {ARGS: 20, "#TestChan", 5} */
- {"NS_USERS_COUNT_MATCH_1", "There is $b%d$b user in %s. ($b%d$b matching your request)"}, /* {ARGS: 1, "#TestChan", 1} */
- {"NS_USERS_SEEN_HERE", "Here"},
- {"NS_USERS_SEEN_INVISIBLE", "Here (invisible)"},
- {"NS_USERS_SEEN_NEVER", "Never"},
- {"NS_USERS_STATE_SUSPENDED", "Suspended"},
- {"NS_USERS_STATE_NORMAL", "Normal"},
- {"NS_SUSPEND_ALREADY", "$b%s$b is already suspended." }, /* {ARGS: "TestUser"} */
- {"NS_SUSPEND_NOT", "$b%s$b is not suspended." }, /* {ARGS: "TestUser"} */
- {"NS_SUSPEND_DONE", "$b%s$b's access to $b%s$b has been suspended." }, /* {ARGS: "TestUser", "#TestChan"} */
- {"NS_SUSPEND_RESTORED", "$b%s$b's access to $b%s$b has been restored." }, /* {ARGS: "TestUser", "#TestChan"} */
- {"NS_DELME_OWNER", "You cannot delete your owner access in $b%s$b."}, /* {ARGS: "#TestChan"} */
- {"NS_DELME_KEY", "To really remove yourself, you must use 'deleteme %s'."}, /* {ARGS: "abc123"} */
- {"NS_DELME_DONE", "Your $b%d$b access has been deleted from $b%s$b."}, /* {ARGS: 123, "#TestChan"} */
- {"NS_MYACCESS_SELF_ONLY", "You may only see the list of infolines for yourself (by using $bmyaccess$b with no arguments)."},
- {"NS_MYACCESS_HEADER", "Showing all channel entries for account $b%s$b:"}, /* {ARGS: "TestAuth"} */
- {"NS_MYACCESS_HEADER_MATCH", "Showing all channel entries for account $b%s$b matching %s:"}, /* {ARGS: "TestAuth", "#Test*"} */
- {"NS_MYACCESS_HEADER_NAME", "Name"},
- {"NS_MYACCESS_HEADER_ACCESS", "Access"},
- {"NS_MYACCESS_HEADER_FLAGS", "Flags"},
- {"NS_MYACCESS_HEADER_INFO", "Info"},
- {"NS_MYACCESS_COUNT", "%s has access in $b%d$b channel(s) and is owner of $b%d$b channel(s)."}, /* {ARGS: "TestUser", 15, 5} */
- {"NS_MYACCESS_COUNT_MATCH", "%s has access in $b%d$b channel(s) and is owner of $b%d$b channel(s) ($b%d$b channels matching your request)."}, /* {ARGS: "TestUser", 15, 5, 7} */
- {"NS_UP_ALREADY_OP", "You are already opped in $b%s$b."}, /* {ARGS: "#TestChan"} */
- {"NS_UP_ALREADY_VOICE", "You are already voiced in $b%s$b."}, /* {ARGS: "#TestChan"} */
- {"NS_DOWN_ALREADY", "You are not opped or voiced in $b%s$b."}, /* {ARGS: "#TestChan"} */
- {"NS_MDELUSER_DONE", "Deleted $b%d$b account(s) matching $b%s$b with access from $b%d$b to $b%d$b from the %s user list."}, /* {ARGS: 10, "Test*", 1, 200, "#TestChan"} */
- {"NS_TRIM_DURATION_TOO_SHORT", "You must include a minimum inactivity duration of at least %d seconds to trim."},
- {"NS_TRIM_DONE", "Trimmed $b%d users$b with access from %d to %d from the %s user list who were inactive for at least %s."}, /* {ARGS: 10, 1, 100, "#TestChan", "10 days"} */
- {"NS_TRIM_BAN_DONE", "Trimmed $b%d bans$b from the %s ban list who were banned for at least %s."}, /* {ARGS: 5, "#TestChan", "1 day"} */
- {"NS_GIVEOWNER_SELF", "You cannot give ownership to your own account."},
- {"NS_GIVEOWNER_TIMEOUT", "You must wait %s before you can give ownership of $b%s$b to someone else."}, /* {ARGS: "5 hours", "#TestChan"} */
- {"NS_GIVEOWNER_CONFIRM", "To really give ownership to $b%1$s$b, you must use 'giveownership *%1$s %2$s'."}, /* {ARGS: "TestUser", "abc123"} */
- {"NS_GIVEOWNER_DONE", "Ownership of $b%s$b has been transferred to account $b%s$b."}, /* {ARGS: "#TestChan", "TestUser"} */
- {"NS_OP_FAIL", "$b%s$b could not op some of the nicks you provided."}, /* {ARGS: "NeonServ"} */
- {"NS_OP_DONE", "Opped users in $b%s$b."}, /* {ARGS: "#TestChan"} */
- {"NS_HALFOP_FAIL", "$b%s$b could not halfop some of the nicks you provided."}, /* {ARGS: "NeonServ"} */
- {"NS_HALFOP_DONE", "Half-Opped users in $b%s$b."}, /* {ARGS: "#TestChan"} */
- {"NS_VOICE_FAIL", "$b%s$b could not voice some of the nicks you provided."}, /* {ARGS: "NeonServ"} */
- {"NS_VOICE_DONE", "Voiced users in $b%s$b."}, /* {ARGS: "#TestChan"} */
- {"NS_DEOP_FAIL", "$b%s$b could not deop some of the nicks you provided."}, /* {ARGS: "NeonServ"} */
- {"NS_DEOP_DONE", "Deopped users in $b%s$b."}, /* {ARGS: "#TestChan"} */
- {"NS_DEHALFOP_FAIL", "$b%s$b could not dehalfop some of the nicks you provided."}, /* {ARGS: "NeonServ"} */
- {"NS_DEHALFOP_DONE", "Dehalfopped users in $b%s$b."}, /* {ARGS: "#TestChan"} */
- {"NS_DEVOICE_FAIL", "$b%s$b could not devoice some of the nicks you provided."}, /* {ARGS: "NeonServ"} */
- {"NS_DEVOICE_DONE", "Devoiced users in $b%s$b."}, /* {ARGS: "#TestChan"} */
- {"NS_OPALL_SECURITY", "$bWARNING$b: Opping all users on a channel is very insecure! If you still want do op all users on %s use: '$bopall FORCE$b [nick mask]'"},
- {"NS_OPALL_DONE", "Opped $b%d$b users in %s."}, /* {ARGS: 20, "#TestChan"} */
- {"NS_HALFOPALL_DONE", "Half-Opped $b%d$b users in %s."}, /* {ARGS: 20, "#TestChan"} */
- {"NS_VOICEALL_DONE", "Voiced $b%d$b users in %s."}, /* {ARGS: 20, "#TestChan"} */
- {"NS_DEOPALL_DONE", "Deopped $b%d$b users in %s."}, /* {ARGS: 20, "#TestChan"} */
- {"NS_DEHALFOPALL_DONE", "Dehalfopped $b%d$b users in %s."}, /* {ARGS: 20, "#TestChan"} */
- {"NS_DEVOICEALL_DONE", "Devoiced $b%d$b users in %s."}, /* {ARGS: 20, "#TestChan"} */
- {"NS_KICK_DONE", "Kicked $b%d$b users from %s"}, /* {ARGS: 20, "#TestChan"} */
- {"NS_KICK_FAIL", "$b%s$b could not kick some of the nicks you provided."}, /* {ARGS: "NeonServ"} */
- {"NS_KICKBAN_DONE", "KickBanned $b%d$b users from %s"}, /* {ARGS: 10, "#TestChan"} */
- {"NS_KICKBAN_FAIL", "$b%s$b could not kickban some of the nicks you provided."}, /* {ARGS: "NeonServ"} */
- {"NS_BAN_DONE", "$b%d$b masks added to the %s ban list. (matching %d users)"}, /* {ARGS: 5, "#TestChan", 15} */
- {"NS_BAN_FAIL", "$b%s$b could not ban some of the nicks you provided."}, /* {ARGS: "NeonServ"} */
- {"NS_LAME_MASK", "$b%s$b is a little too general. Try making it more specific."}, /* {ARGS: "*!*@*"} */
- {"NS_LAME_MASK_WARNING", "$k4WARNING$k: $b%s$b is very general. (matches %d users)"},
- {"NS_SET_HEADER", "Channel Settings for %s:"}, /* {ARGS: "#TestChan"} */
- {"NS_SET_ON", "on"},
- {"NS_SET_OFF", "off"},
- {"NS_SET_UNKNOWN_SETTING", "$b%s$b is an unknown channel setting."}, /* {ARGS: "TestSetting"} */
- {"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", "$b%d$b is not a valid choice. Choose one:"}, /* {ARGS: 5} */
- {"NS_SET_INVALID_BOOLEAN", "$b%s$b is an invalid binary value."}, /* {ARGS: 2} */
- {"NS_SET_DEFAULTS_OWNER", "You must have access 500 in %s to reset it to the default options."}, /* {ARGS: "#TestChan"} */
- {"NS_SET_DEFAULTS_CODE", "To reset %s's settings to the defaults, you must use 'set defaults %s'."}, /* {ARGS: "#TestChan", "abc123"} */
- {"NS_SET_DEFAULTS_DONE", "All settings for %s have been reset to default values."}, /* {ARGS: "#TestChan"} */
- {"NS_SET_TRIGGER_OWNER", "You must have access 500 in %s to change the channel trigger."}, /* {ARGS: "#TestChan"} */
- {"NS_SET_HELP_USERINFO","(access to set the userinfo)"},
- {"NS_SET_HELP_WIPEINFO","(access to clear the userinfo of other users)"},
- {"NS_SET_HELP_INVITEME","(access to get invited by the bot)"},
- {"NS_SET_HELP_ENFVOICE","(access to give voice to other users)"},
- {"NS_SET_HELP_ENFOPS","(access to give op to their users)"},
- {"NS_SET_HELP_GIVEOPS","(access to get op by the bot)"},
- {"NS_SET_HELP_GIVEVOICE","(access to get voice by the bot)"},
- {"NS_SET_HELP_KICK","(access to kick other users from the channel)"},
- {"NS_SET_HELP_BAN","(access to ban other users from the channel)"},
- {"NS_SET_HELP_STATICBAN","(access to add static bans to the channel banlist e.g. +addban)"},
- {"NS_SET_HELP_PUBCMD","(access to do public commands in the channel e.g. +users)"},
- {"NS_SET_HELP_ENFMODES","(access to override the modelock)"},
- {"NS_SET_HELP_ENFTOPIC","(access to override the topicmask)"},
- {"NS_SET_HELP_TOPICSNARF","(access to set the default topic by changing the topic with /TOPIC)"},
- {"NS_SET_HELP_CHANGETOPIC","(access to change the topic)"},
- {"NS_SET_HELP_SETTERS","(access to change this settings)"},
- {"NS_SET_HELP_ADDUSER","(access to add an user to the userlist)"},
- {"NS_SET_HELP_DELUSER","(access to delete an user from the userlist)"},
- {"NS_SET_HELP_CLVL","(access to change the access of an user in the userlist)"},
- {"NS_SET_HELP_RESYNC","(access to synchronize the channelrights (@,+) with the userlist)"},
- {"NS_SET_HELP_SUSPEND","(access to suspend an user on the userlist)"},
- {"NS_SET_OPTION_CTCPREACTION_0","Kick on disallowed CTCPs"},
- {"NS_SET_OPTION_CTCPREACTION_1","Kickban on disallowed CTCPs"},
- {"NS_SET_OPTION_CTCPREACTION_2","Short timed ban on disallowed CTCPs"},
- {"NS_SET_OPTION_CTCPREACTION_3","Long timed ban on disallowed CTCPs"},
- {"NS_SET_OPTION_NOTICEREACTION_0","Kick on disallowed NOTICEs"},
- {"NS_SET_OPTION_NOTICEREACTION_1","Kickban on disallowed NOTICEs"},
- {"NS_SET_OPTION_NOTICEREACTION_2","Short timed ban on disallowed NOTICEs"},
- {"NS_SET_OPTION_NOTICEREACTION_3","Long timed ban on disallowed NOTICEs"},
- {"NS_SET_OPTION_PROTECT_0","All users will be protected from users with equal or lower access."},
- {"NS_SET_OPTION_PROTECT_1","All users with access will be protected from users with equal or lower access."},
- {"NS_SET_OPTION_PROTECT_2","All users with access will be protected from user with lower access."},
- {"NS_SET_OPTION_PROTECT_3","Nobody will be protected."},
- {"NS_SET_OPTION_TOYS_0","Funcommands can't be used."},
- {"NS_SET_OPTION_TOYS_1","Funcommands are possible but the reply will be sent as a notice."},
- {"NS_SET_OPTION_TOYS_2","Funcommands are possible and the reply will be sent to the channel."},
- {"NS_SET_OPTION_DYNLIMIT_0","off"},
- {"NS_SET_OPTION_NODELETE_0","off (only bot masters)"},
- {"NS_SET_OPTION_NODELETE_1","on (only bot masters)"},
- {"NS_WIPEINFO_DONE", "Removed $b%s$b's infoline in $b%s$b."}, /* {ARGS: "TestUser", "#TestChan"} */
- {"NS_TRACE_HEADER", "The following users were found:"},
- {"NS_ADDBAN_DONE", "$b%s$b permantly added to the %s ban list. (matching %d users)"}, /* {ARGS: "*!*@Test.*", "#TestChan", 4} */
- {"NS_BANS_HEADER_MASK", "Mask"},
- {"NS_BANS_HEADER_SETBY", "Set By"},
- {"NS_BANS_HEADER_TRIGGERED", "Triggered"},
- {"NS_BANS_HEADER_EXPIRES", "Expires"},
- {"NS_BANS_HEADER_REASON", "Reason"},
- {"NS_DELBAN_BANNED_BY", "%s is banned by %s."}, /* {ARGS: "*!*@bla*", "*!*@b*"} */
- {"NS_DELBAN_FAIL", "Sorry, no ban found for $b%s$b."}, /* {ARGS: "*!*@bla*"} */
- {"NS_DELBAN_DONE", "Removed $b%s$b from the %s ban list."}, /* {ARGS: "*!*@bla.*", "#TestChan"} */
- {"NS_NETINFO_HEADER", "$bNetwork information$b"},
- {"NS_NETINFO_BOTS", "Bots:"},
- {"NS_NETINFO_UPTIME", "Uptime:"},
- {"NS_NETINFO_TRAFFIC", "Traffic:"},
- {"NS_NETINFO_CACHE", "Cache:"},
- {"NS_NETINFO_DATABASE", "Database:"},
- {"NS_NETINFO_CHANNEL", " Channel:"},
- {"NS_NETINFO_CHANNEL_BAN", " Bans:"},
- {"NS_NETINFO_USER", " User:"},
- {"NS_NETINFO_CHANUSER", " Channel-User:"},
- {"NS_NETINFO_OTHER", " Other:"},
- {"NS_NETINFO_THREADS", "Threads:"},
- {"NS_NETINFO_VERSION", "Version:"},
- {"NS_NETINFO_CODE", "Code:"},
- {"NS_NETINFO_CODE_VALUE", "%s lines c code (view it at http://dev.pk910.de/NeonServ)"}, /* {ARGS: 20} */
- {"NS_NETINFO_COMPILER", "Compiler:"},
- {"NS_NETINFO_COMPILER_VALUE", "%s (%s)"}, /* {ARGS: "GCC 4.4.5", "Sun Sep 18 2011 at 05:21:33 CEST"} */
- {"NS_EXTTOPIC_INVALID_ID", "ADVANCEDTOPIC is enabled and $b%s$b is an invalid TOPIC ID. Valid topic id's are: 1-9"}, /* {ARGS: 10} */
- {"NS_EXTTOPIC_TOPICID", "Topic %d: %s"}, /* {ARGS: 5, "topic"} */
- {"NS_TOPIC_DONE", "Topic is now '%s'."}, /* {ARGS: "i like you :D"} */
- {"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!"}, /* {ARGS: "CowBot"} */
- {"NS_CHANSERVSYNC_KEY", "If you really want to synchronize the %s userlist with %s use: chanservsync %s %s"}, /* {ARGS: "#TestChan", "CowBot", "CowBot", "abc123"} */
- {"NS_CHANSERVSYNC_INUSE", "$bchanservsync$b is already in use by someone else. Please try again in a few seconds..."},
- {"NS_CHANSERVSYNC_SYNCHRONIZING", "Synchronizing userlist in %s with $b%s$b..."}, /* {ARGS: "#TestChan", "CowBot"} */
- {"NS_CHANSERVSYNC_SYNCHRONIZED", "Synchronized user $b%s$b: access $b%d$b"}, /* {ARGS: "TestUser", 123} */
- {"NS_REGISTER_ALREADY", "%s is already registered with %s."}, /* {ARGS: "#TestChan", "NeonServ"} */
- {"NS_INVALID_CHANNEL_NAME", "%s is not a valid channel name."}, /* {ARGS: "#invalid"} */
- {"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."}, /* {ARGS: "#TestChan"} */
- {"NS_REGISTER_DONE", "$b%s$b is now registered to $b%s$b."}, /* {ARGS: "#TestChan", "TestUser"} */
- {"NS_REGISTER_DONE_NOAUTH", "$b%s$b is now registered."}, /* {ARGS: "#TestChan"} */
- {"NS_UNREGISTER_NOT_REGISTERED", "$b%s$b is not registered with %s."}, /* {ARGS: "#TestChan", "NeonServ"} */
- {"NS_UNREGISTER_DONE", "$b%s$b unregistered."}, /* {ARGS: "#TestChan"} */
- {"NS_RECOVER_DONE", "$b%s$b has been recovered."}, /* {ARGS: "#TestChan"} */
- {"NS_RESYNC_DONE", "Synchronized users in $b%s$b with the userlist."}, /* {ARGS: "#TestChan"} */
- {"NS_TIMEBAN_DURATION_TOO_SHORT", "You must specify a ban duration of at least %d seconds."}, /* {ARGS: 30} */
- {"NS_TIMEBAN_DONE", "Banned $b%s$b from %s for %s. (matching %d users)"}, /* {ARGS: "*!*@bla*", "#TestChan", "2 hours", 5} */
- {"NS_MODE_INVALID", "$b%c$b is an invalid set of channel modes."}, /* {ARGS: "+xyz"} */
- {"NS_MODE_LOCKED", "Modes conflicting with $b%s$b are not allowed in %s."}, /* {ARGS: "+xyz", "#TestChan"} */
- {"NS_MODE_DONE", "Channel modes are now $b%s$b."}, /* {ARGS: "+xyz"} */
- {"NS_MODE_ENFOPS", "You may not op or deop users on $b%s$b."}, /* {ARGS: "#TestChan"} */
- {"NS_MODE_ENFVOICE", "You may not voice or devoice users on $b%s$b."}, /* {ARGS: "#TestChan"} */
- {"NS_MODE_CANBAN", "You may not ban or unban users on $b%s$b."}, /* {ARGS: "#TestChan"} */
- {"NS_GOD_ON", "Security override has been enabled."},
- {"NS_GOD_OFF", "Security override has been disabled."},
- {"NS_PEEK_HEADER", "$b%s$b Status:"}, /* {ARGS: "#TestChan"} */
- {"NS_PEEK_TOPIC", "Topic: %s"}, /* {ARGS: "TOPIC"} */
- {"NS_PEEK_MODES", "Modes: %s"}, /* {ARGS: "+xyz"} */
- {"NS_PEEK_USERS", "Total Users: %d (%d ops, %d voices, %d regulars, %d invisible)"}, /* {ARGS: 20, 4, 6, 8, 2} */
- {"NS_PEEK_USERS_HALFOP", "Total Users: %d (%d ops, %d halfops, %d voices, %d regulars, %d invisible)"}, /* {ARGS: 25, 5, 4, 6, 8, 2} */
- {"NS_PEEK_OPS", "Ops:"},
- {"NS_USET_GLOBAL", "$b--- Global ---$b"},
- {"NS_USET_CHANNEL", "$b--- User options (channel) ---$b"},
- {"NS_USET_NO_ACCESS", "no access"},
- {"NS_USET_UNKNOWN_SETTING", "$b%s$b is an unknown uset setting."}, /* {ARGS: "TestSetting"} */
- {"NS_RELOADLANG_UNKNOWN", "$b%s$b is an unknown language tag."}, /* {ARGS: "de"} */
- {"NS_RELOADLANG_DONE", "$b%s$b (%s) reloaded."}, /* {ARGS: "Deutsch", "de"} */
- {"NS_UNBAN_DONE", "$b%d$b masks removed from the %s ban list."}, /* {ARGS: 5, "#TestChan"} */
- {"NS_UNBAN_FAIL", "$b%s$b could not unban some of the masks you provided."}, /* {ARGS: "NeonServ"} */
- {"NS_UNBANALL_DONE", "all $b%d$b masks removed from the %s ban list."}, /* {ARGS: 5, "#TestChan"} */
- {"NS_UNBANALL_FAIL", "$b%s$b could not find any bans in %s."}, /* {ARGS: "NeonServ", "#TestChan"} */
- {"NS_UNBANME_DONE", "removed $b%d$b masks from the %s ban list."}, /* {ARGS: 5, "#TestChan"} */
- {"NS_UNBANME_FAIL", "$b%s$b could not find any bans matching %s."}, /* {ARGS: "NeonServ", "TestUser!TestIdent@TestUser.user.WebGamesNet"} */
- {"NS_INVITE_RESTRICTION", "%s doesn't want to be invited to %s."}, /* {ARGS: "TestUser", "#TestChan"} */
- {"NS_INVITE_TIMEOUT", "%s has already been invited to $b%s$b."}, /* {ARGS: "TestUser", "#TestChan"} */
- {"NS_INVITE_ON_CHAN", "%s is already in $b%s$b."}, /* {ARGS: "TestUser", "#TestChan"} */
- {"NS_INVITE_DONE_USER", "You have been invited to join $b%s$b by %s. (Do $b/msg %s %1$s uset noinvite 1$b if you don't want to be invited to %1$s anymore.)"}, /* {ARGS: "#TestChan", "TestUser", "NeonServ"} */
- {"NS_INVITE_DONE", "Invited $b%s$b to join %s."}, /* {ARGS: "TestUser", "#TestChan"} */
- {"NS_INVITEME_ON_CHAN", "You are already in $b%s$b."}, /* {ARGS: "#TestChan"} */
- {"NS_INVITEME_DONE", "You have been invited to join %s."}, /* {ARGS: "#TestChan"} */
- {"NS_HELP_TOPIC", "No help on that topic."},
- {"NS_CSUSPEND_ALREADY", "$b%s$b is already suspended."}, /* {ARGS: "#TestChan"} */
- {"NS_CSUSPEND_DONE", "Channel $b%s$b has been temporarily suspended."}, /* {ARGS: "#TestChan"} */
- {"NS_CUNSUSPEND_NOT", "$b%s$b is not suspended."}, /* {ARGS: "#TestChan"} */
- {"NS_CUNSUSPEND_DONE", "Channel $b%s$b has been restored."}, /* {ARGS: "#TestChan"} */
- {"NS_MOVE_SUSPENDED", "Moving cannot be performed if the source channel is suspended."},
- {"NS_MOVE_SELF", "Moving cannot be performed if the source and target channels are the same."},
- {"NS_MOVE_DONE", "Channel $b%s$b has been moved to $b%s$b."}, /* {ARGS: "#TestChan", "#NewTestChan"} */
- {"NS_BIND_ALREADY", "$b%s$b is already bound to %s."}, /* {ARGS: "TestCommand", "TestFunction"} */
- {"NS_BIND_UNKNOWN", "$b%s$b is an undefined function."}, /* {ARGS: "TestFunction"} */
- {"NS_BIND_DONE", "New command $b%s$b bound to %s."}, /* {ARGS: "TestCommand", "TestFunction"} */
- {"NS_UNBIND_NOT_FOUND", "There is no command called $b%s$b bound."}, /* {ARGS: "TestCommand"} */
- {"NS_UNBIND_DONE", "Unbound command $b%s$b."}, /* {ARGS: "TestCommand"} */
- {"NS_EVENTS_HEADER", "The following channel events were found:"},
- {"NS_OPLOG_HEADER", "The following oper events were found:"},
- {"NS_SEARCH_HEADER", "The following channels were found:"},
- {"NS_COMMAND_BINDING", "$b%s$b is a binding of %s %s"}, /* {ARGS: "TestCommand", "TestFunction", "TestParameters"} */
- {"NS_COMMAND_ACCESS", "You need at least %d channel access and %d oper access to execute this command."}, /* {ARGS: 500, 100} */
- {"NS_TOPIC_ACCESS", "You lack sufficient access in %s to change the topic."}, /* {ARGS: "#TestChan"} */
- {"NS_BOTWAR_DETECTED", "$b$k4BOTWAR DETECTED!$k Please check the channel configuration!$b"},
- {"NS_BOTWAR_REPORTED", "A supporter has been informed to help you preventing botwars in the future."},
- {"NS_BOTWAR_ALERT", "$b$k4BOTWAR ALERT:$k$b Botwar in $b%s$b detected. (opponent: $b%s$b) Please join and help them preventing Botwars."}, /* {ARGS: "#TestChan", "OtherBot"} */
- {"NS_INVITE_FAIL", "$b%s$b is not registered with %s or suspended."}, /* {ARGS: "#TestChan", "NeonServ"} */
- {"NS_SETACCESS_DONE", "$b%s$b has now %d global access."}, /* {ARGS: "TestUser", 1000} */
- {"NS_ADDRANK_EXISTS", "Another support ranking called '$b%s$b' already exists."}, /* {ARGS: "Supporter"} */
- {"NS_ADDRANK_DONE", "Support ranking '$b%s$b' created."}, /* {ARGS: "Supporter"} */
- {"NS_DELRANK_NOT_FOUND", "There is no support ranking called '$b%s$b'."}, /* {ARGS: "Supporter"} */
- {"NS_DELRANK_DELETED", "Support ranking called '$b%s$b' removed."}, /* {ARGS: "Supporter"} */
- {"NS_LISTRANK_ID", "Id"},
- {"NS_LISTRANK_NAME", "Name"},
- {"NS_LISTRANK_ASSIGNED", "Assigned to"},
- {"NS_LISTRANK_UNRANKED", "There are also %d unranked users with global access."}, /* {ARGS: 10} */
- {"NS_SETRANK_NOT_FOUND", "There is no support ranking with ID '$b%s$b'."}, /* {ARGS: 42} */
- {"NS_SETRANK_HEAD", "Support ranking settings for Id %s:"}, /* {ARGS: 42} */
- {"NS_SETRANK_UNKNOWN_SETTING", "$b%s$b is an unknown support rank setting."}, /* {ARGS: "moep"} */
- {"NS_SETRANK_ORDER_INVALID", "%d is an invalid numeric value. (valid: 1-99)"}, /* {ARGS: 100} */
- {"NS_ASSIGNRANK_DONE", "$b%s$b is now ranked as '$b%s$b'."}, /* {ARGS: "TestUser", "Supporter"} */
- {"NS_INFO_HEADER", "$b%s$b Information:"}, /* {ARGS: "#TestChan"} */
- {"NS_INFO_DEFAULTTOPIC", "Default Topic:"},
- {"NS_INFO_MODELOCK", "Mode Lock:"},
- {"NS_INFO_RECORD", "Record Visitors:"},
- {"NS_INFO_OWNER", "Owner:"},
- {"NS_INFO_USERS", "Total User Count:"},
- {"NS_INFO_BANS", "Ban Count:"},
- {"NS_INFO_VISITED", "Visited:"},
- {"NS_INFO_REGISTERED", "Registered:"},
- {"NS_INFO_REGISTRAR", "Registered by:"},
- {"NS_INFO_OWNERLOG", "Ownership transfer history for $b%s$b:"}, /* {ARGS: "#TestChan"} */
- {"NS_INFO_OWNERCHANGE", " from %s to %s on %s"},
- {"NS_RENAME_DONE", "Renamed $b%s$b to $b%s$b."}, /* {ARGS: "TestUser", "TestUser2"} */
- {"NS_RENAME_FAIL", "Failed renaming $b%s$b."}, /* {ARGS: "TestUser"} */
- {"NS_FUN_DISABLED", "Fun commands are disabled in %s."}, /* {ARGS: "#TestChan"} */
- {"NS_UNBIND_REQUIRED", "%1$s is a required function and there is no other command bound to %1$s. Bind another command to %1$s first."}, /* {ARGS: "bind"} */
- {"NS_COMMANDS_NAME", "Name"},
- {"NS_COMMANDS_ACCESS", "Access"},
- {"NS_COMMANDS_GACCESS", "GodAccess"},
- {"NS_COMMANDS_TRIGGERED", "Triggered"},
- {"NS_COMMANDS_FUNCTION", "Function"},
- {"NS_DNR_SET", "$b%s$b is do-not-register (by $b%s$b): %s" }, /* {ARGS: "#TestChan", "TestUser", "because of it is like it is"} */
- {"NS_DNR_SET_EXPIRES", "$b%s$b is do-not-register (by $b%s$b; expires %s): %s" }, /* {ARGS: "#TestChan", "TestUser", "1 day", "because of it is like it is"} */
- {"NS_DNR_SET_ANONYM", "$b%s$b is do-not-register. Please contact the support to get more information."}, /* {ARGS: "TestUser"} */
- {"NS_NOREGISTER_INVALID_DURATION", "$b%s$b is not a valid duration."}, /* {ARGS: "möp"} */
- {"NS_NOREGISTER_REGISTERED", "$b%s$b is currently registered and can't be added to the do-not-register list."}, /* {ARGS: "#TestChan"} */
- {"NS_NOREGISTER_DONE", "added $b%s$b to the do-not-register list."}, /* {ARGS: "#TestChan"} */
- {"NS_NOREGISTER_HEAD", "The following do-not-registers were found:"},
- {"NS_DNR_TARGET", "Target"},
- {"NS_DNR_USER", "Issuer"},
- {"NS_DNR_EXPIRES", "Expires"},
- {"NS_DNR_REASON", "Reason"},
- {"NS_STAFF_LOGGEDIN", "Logged in as"},
- {"NS_BOTS_ID", "Id"},
- {"NS_BOTS_NICK", "Nick"},
- {"NS_BOTS_SERVER", "Server:Port(:Pass)"},
- {"NS_BOTS_CLASS", "Bot Class"},
- {"NS_BOTS_FLAGS", "Flags"},
- {"NS_BOTS_CHANNELS", "Channels"},
- {"NS_BOTS_TRIGGER", "Trigger"},
- {"NS_NICKLIST_NICK", "Nick"},
- {"NS_NICKLIST_STATE", "State"},
- {"NS_NICKLIST_ACCESS", "Access"},
- {"NS_NICKLIST_SYNC", "use `nicklist sync` to fix all red and orange entrys in the list above (add opped users with %d and voiced with %d access)"},
- {"NS_SETBOT_UNKNOWN", "`%d` is an unknown botid."}, /* {ARGS: 50} */
- {"NS_SETBOT_HEADER", "$bSettings for botid `%d`:$b"}, /* {ARGS: 50} */
- {"NS_SETBOT_SETTING", "$b%s$b is an unknown bot setting."}, /* {ARGS: "strangeSetting"} */
- {"NS_SETBOT_NICK_INVALID", "`%s` is an invalid botnick."}, /* {ARGS: "-SuperMagicBananaBotWithManyFunctions"} */
- {"NS_SETBOT_NEED_RESTART", "You need to reconnect the bot to apply this setting."},
- {"NS_SETBOT_PORT_INVALID", "`%s` is an invalid port number."}, /* {ARGS: "-1"} */
- {"NS_SETBOT_INVALID_CLASS", "`%s` is an invalid botclass."}, /* {ARGS: "MistColaLeer"} */
- {"NS_SETBOT_MAXCHAN_INVALID", "`%s` is an invalid maxchan value."}, /* {ARGS: "-1"} */
- {"NS_SETBOT_PRIORITY_INVALID", "`%s` is an invalid priority value."}, /* {ARGS: "-1"} */
- {"NS_SETBOT_TRIGGER_INVALID", "`%s` is an invalid bot trigger."}, /* {ARGS: "tooLongTrigger"} */
- {"NS_SETBOT_TRIGGER_NOTE", "Please note: This Setting will only affect new channels."},
- {"NS_ADDBOT_EXISTING", "A bot with nick %s does already exist."}, /* {ARGS: "NeonServ"} */
- {"NS_ADDBOT_DONE", "Added %s with BotID $b%d$b."}, /* {ARGS: "NeonServ", 2} */
- {"NS_DELBOT_NOT_FOUND", "Bot with BotID / nick $b%s$b not found."}, /* {ARGS: "NeonServ"} */
- {"NS_DELBOT_DONE", "Bot deleted."},
- {"NS_RECONNECT_DONE", "Reconnected bot."},
- {"NS_MODCMD_SETTING", "$b%s$b is an unknown modcmd setting."}, /* {ARGS: "strangeSetting"} */
- {"NS_MODCMD_HEADER", "$bSettings for command %s:$b"}, /* {ARGS: "access"} */
- {"NS_MODCMD_OUTRANKED", "$b%s$b outranks you. (required access: %d)"}, /* {ARGS: "die", 1000} */
- {"NS_MODCMD_STATIC_FLAG", "This Flag is added statically. It can't be modified manually."},
- {"NS_MEMINFO_DISABLED", "Memory Debugger is disabled!"},
- {"NS_MEMINFO_NAME", "Name"},
- {"NS_MEMINFO_COUNT", "Count"},
- {"NS_MEMINFO_SIZE", "Size"},
- {"NS_MEMINFO_LINE", "Line"},
- {"NS_MEMINFO_TOTAL", "Total"},
- {NULL, NULL}
-};
-
-/* TODO:
-cmd_neonserv_open.c
-set modelock
-cmd_neonserv_modcmd.c
-cmd_neonserv_allowregister.c
-cmd_neonserv_noregister.c
-cmd_neonserv_expire.c
-cmd_neonserv_unvisited.c
-cmd_neonserv_merge.c
-cmd_neonserv_dnrsearch.c
-cmd_neonserv_iplocate.c
-cmd_neonserv_calc.c
-*/
-//EVENTS
-#include "event_neonserv_join.c"
-#include "event_neonserv_part.c"
-#include "event_neonserv_quit.c"
-#include "event_neonserv_kick.c"
-#include "event_neonserv_mode.c"
-#include "event_neonserv_ctcp.c"
-#include "event_neonserv_notice.c"
-#include "event_neonserv_invite.c"
-#include "event_neonserv_topic.c"
-
-
-struct ClientSocket *getBotForChannel(struct ChanNode *chan) {
- return getChannelBot(chan, BOTID);
-}
-
-static void neonserv_bot_ready(struct ClientSocket *client) {
- MYSQL_RES *res;
- MYSQL_ROW row;
-
- printf_mysql_query("SELECT `automodes` FROM `bots` WHERE `id` = '%d'", client->clientid);
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) != NULL) {
- putsock(client, "MODE %s +%s", client->user->nick, row[0]);
- }
-
- printf_mysql_query("SELECT `channel_name`, `channel_key` FROM `bot_channels` LEFT JOIN `channels` ON `chanid` = `channel_id` WHERE `botid` = '%d' AND `suspended` = '0'", client->clientid);
- res = mysql_use();
-
- while ((row = mysql_fetch_row(res)) != NULL) {
- putsock(client, "JOIN %s %s", row[0], row[1]);
- }
-}
-
-static void neonserv_trigger_callback(int clientid, struct ChanNode *chan, char *trigger) {
- MYSQL_RES *res;
- MYSQL_ROW row;
- loadChannelSettings(chan);
- if(!(chan->flags & CHANFLAG_CHAN_REGISTERED)) {
- strcpy(trigger, "+");
- return;
- }
- printf_mysql_query("SELECT `trigger`, `defaulttrigger` FROM `bot_channels` LEFT JOIN `bots` ON `botid` = `bots`.`id` WHERE `chanid` = '%d' AND `botclass` = '%d'", chan->channel_id, BOTID);
- res = mysql_use();
- if(!(row = mysql_fetch_row(res))) {
- strcpy(trigger, "+");
- return;
- }
- if(row[0] && *row[0])
- strcpy(trigger, row[0]);
- else
- strcpy(trigger, ((row[1] && *row[1]) ? row[1] : "~"));
-}
-
-static void start_bots() {
- struct ClientSocket *client;
- MYSQL_RES *res, *res2;
- MYSQL_ROW row;
-
- printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `textbot`, `id`, `queue`, `ssl`, `bind` FROM `bots` WHERE `botclass` = '%d' AND `active` = '1'", BOTID);
- res = mysql_use();
-
- while ((row = mysql_fetch_row(res)) != NULL) {
- client = create_socket(row[3], atoi(row[4]), row[10], row[5], row[0], row[1], row[2]);
- client->flags |= (strcmp(row[6], "0") ? SOCKET_FLAG_PREFERRED : 0);
- client->flags |= (strcmp(row[8], "0") ? SOCKET_FLAG_USE_QUEUE : 0);
- client->flags |= (strcmp(row[9], "0") ? SOCKET_FLAG_SSL : 0);
- client->botid = BOTID;
- client->clientid = atoi(row[7]);
- connect_socket(client);
- }
-
- printf_mysql_query("SELECT `command`, `function`, `parameters`, `global_access`, `chan_access`, `flags` FROM `bot_binds` WHERE `botclass` = '%d'", BOTID);
- res2 = mysql_use();
- while ((row = mysql_fetch_row(res2)) != NULL) {
- if(bind_cmd_to_command(BOTID, row[0], row[1])) {
- if(row[2] && strcmp(row[2], "")) {
- bind_set_parameters(BOTID, row[0], row[2]);
- }
- if(row[3]) {
- bind_set_global_access(BOTID, row[0], atoi(row[3]));
- }
- if(row[4]) {
- bind_set_channel_access(BOTID, row[0], row[4]);
- }
- if(strcmp(row[5], "0"))
- bind_set_bind_flags(BOTID, row[0], atoi(row[5]));
- }
- }
- bind_unbound_required_functions(BOTID);
-}
-
-void init_NeonServ() {
-
- set_bot_alias(BOTID, BOTALIAS);
- start_bots();
-
- //register events
- bind_bot_ready(neonserv_bot_ready);
- bind_join(neonserv_event_join);
- bind_part(neonserv_event_part);
- bind_quit(neonserv_event_quit);
- bind_chanctcp(neonserv_event_chanctcp);
- bind_privctcp(general_event_privctcp);
- bind_channotice(neonserv_event_channotice);
- bind_topic(neonserv_event_topic);
- bind_invite(neonserv_event_invite);
- bind_mode(neonserv_event_mode);
- bind_kick(neonserv_event_kick);
-
- set_trigger_callback(BOTID, neonserv_trigger_callback);
-
- register_default_language_table(msgtab);
-}
-
-void loop_NeonServ() {
-
-}
-
-void free_NeonServ() {
-
-}
-
-#undef BOTID
-#undef BOTALIAS
+++ /dev/null
-/* bot_NeonServ.h - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-#ifndef _bot_NeonServ_h
-#define _bot_NeonServ_h
-
-#include "main.h"
-
-struct ChanNode;
-
-void init_NeonServ();
-void loop_NeonServ();
-void free_NeonServ();
-
-struct ClientSocket *getBotForChannel(struct ChanNode *chan);
-
-#endif
\ No newline at end of file
+++ /dev/null
-/* bot_NeonSpam.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "bot_NeonSpam.h"
-#include "modcmd.h"
-#include "IRCParser.h"
-#include "IRCEvents.h"
-#include "UserNode.h"
-#include "ChanNode.h"
-#include "ChanUser.h"
-#include "ModeNode.h"
-#include "BanNode.h"
-#include "ClientSocket.h"
-#include "mysqlConn.h"
-#include "lang.h"
-#include "HandleInfoHandler.h"
-#include "WHOHandler.h"
-#include "DBHelper.h"
-#include "tools.h"
-#include "timeq.h"
-#include "version.h"
-#include "EventLogger.h"
-#include "bots.h"
-#include "cmd_neonserv.h"
-#include "cmd_neonspam.h"
-
-#define BOTID 2
-#define BOTALIAS "NeonSpam"
-
-static const struct default_language_entry msgtab[] = {
- {"SS_SET_PERCENT", "%u is an invalid percent value (valid: 0-100)"}, /* {ARGS: 120} */
- {"SS_SET_SENSIBILITY", "%s is an invalid sensibility format. (valid: amount:time e.g. 5:10)"}, /* {ARGS: "möp"} */
- {"SS_SET_SENSIBILITY_AMOUNT", "%d is an invalid amount value. (valid: %d-%d)"}, /* {ARGS: 120, 1, 5} */
- {"SS_SET_SENSIBILITY_TIME", "%d is an invalid time value. (valid: %d-%d)"}, /* {ARGS: 300, 15, 180} */
- {"SS_SET_SPAMLIMIT", "%d is an invalid spamlimit value. (valid: %d-%d)"}, /* {ARGS: 120, 2, 8} */
- {"SS_SET_OPTION_SpamReaction_0", "Kick"},
- {"SS_SET_OPTION_SpamReaction_1", "KickBan"},
- {"SS_SET_OPTION_SpamReaction_2", "Timed Ban"},
- {"SS_SET_OPTION_FloodReaction_0", "Kick"},
- {"SS_SET_OPTION_FloodReaction_1", "KickBan"},
- {"SS_SET_OPTION_FloodReaction_2", "Timed Ban"},
- {"SS_SET_OPTION_JoinReaction_0", "Kick"},
- {"SS_SET_OPTION_JoinReaction_1", "KickBan"},
- {"SS_SET_OPTION_JoinReaction_2", "Timed Ban"},
- {"SS_SET_OPTION_CapsReaction_0", "Kick"},
- {"SS_SET_OPTION_CapsReaction_1", "KickBan"},
- {"SS_SET_OPTION_CapsReaction_2", "Timed Ban"},
- {"SS_SET_OPTION_DigitReaction_0", "Kick"},
- {"SS_SET_OPTION_DigitReaction_1", "KickBan"},
- {"SS_SET_OPTION_DigitReaction_2", "Timed Ban"},
- {NULL, NULL}
-};
-
-static unsigned int convertNeonSpamSettingsToFlags(char *str);
-static void createSpamNode(struct ChanUser *chanuser);
-static void freeJoinNode(struct NeonSpamJoinNode *joinnode);
-static struct NeonSpamJoinNode *getNeonSpamJoinNode(struct ChanUser *chanuser);
-
-#define SPAMSERV_CHECK_IGNORE 0
-#define SPAMSERV_CHECK_WARN 1
-#define SPAMSERV_CHECK_PUNISH 2
-#define SPAMSERV_CHECK_DEAD 3 /* scanner has already killed the user */
-
-#define SPAMSERV_MSG_SPAM "Spamming"
-#define SPAMSERV_MSG_FLOOD "Flooding the channel/network"
-#define SPAMSERV_MSG_ADV "Advertising"
-#define SPAMSERV_MSG_JOINFLOOD "Join flooding the channel"
-#define SPAMSERV_MSG_WARNING "%s is against the channel rules"
-#define SPAMSERV_MSG_BOTNET "BotNet detected."
-#define SPAMSERV_MSG_CAPS "Using too many chars in UPPER CASE"
-#define SPAMSERV_MSG_DIGIT "Using too many numeric chars"
-
-//EVENTS
-#include "event_neonspam_join.c"
-#include "event_neonspam_chanmsg.c"
-
-static void neonspam_event_kick(struct UserNode *user, struct ChanUser *target, char *reason) {
- struct ChanNode *chan = target->chan;
- if(isBot(target->user)) {
- struct ClientSocket *client = getChannelBot(chan, 0);
- struct ClientSocket *bot = client;
- for(client = getBots(SOCKET_FLAG_READY, NULL); client; client = getBots(SOCKET_FLAG_READY, client)) {
- if(client->user == target->user) {
- break;
- }
- }
- if(!client) return;
- if(bot && bot != client && (isModeSet(chan->modes, 'i') || isModeSet(chan->modes, 'a') || isModeSet(chan->modes, 'l'))) {
- struct ChanUser *chanuser = getChanUser(bot->user, chan);
- if(chanuser && chanuser->flags & CHANUSERFLAG_OPPED)
- putsock(bot, "INVITE %s %s", target->user->nick, chan->name);
- }
- char *key = "";
- if(isModeSet(chan->modes, 'k')) {
- key = getModeValue(chan->modes, 'k');
- }
- putsock(client, "JOIN %s %s", chan->name, key);
- return;
- }
-}
-
-static void neonspam_bot_ready(struct ClientSocket *client) {
- MYSQL_RES *res;
- MYSQL_ROW row;
-
- printf_mysql_query("SELECT `automodes` FROM `bots` WHERE `id` = '%d'", client->clientid);
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) != NULL) {
- putsock(client, "MODE %s +%s", client->user->nick, row[0]);
- }
-
- printf_mysql_query("SELECT `channel_name`, `channel_key` FROM `bot_channels` LEFT JOIN `channels` ON `chanid` = `channel_id` WHERE `botid` = '%d' AND `suspended` = '0'", client->clientid);
- res = mysql_use();
-
- while ((row = mysql_fetch_row(res)) != NULL) {
- putsock(client, "JOIN %s %s", row[0], row[1]);
- }
-}
-
-static void neonspam_trigger_callback(int clientid, struct ChanNode *chan, char *trigger) {
- MYSQL_RES *res;
- MYSQL_ROW row;
- loadChannelSettings(chan);
- if(!(chan->flags & CHANFLAG_CHAN_REGISTERED)) {
- strcpy(trigger, "~");
- return;
- }
- printf_mysql_query("SELECT `trigger`, `defaulttrigger` FROM `bot_channels` LEFT JOIN `bots` ON `botid` = `bots`.`id` WHERE `chanid` = '%d' AND `botclass` = '%d'", chan->channel_id, BOTID);
- res = mysql_use();
- if(!(row = mysql_fetch_row(res))) {
- strcpy(trigger, "~");
- return;
- }
- if(row[0] && *row[0])
- strcpy(trigger, row[0]);
- else
- strcpy(trigger, ((row[1] && *row[1]) ? row[1] : "~"));
-}
-
-static void start_bots() {
- struct ClientSocket *client;
- MYSQL_RES *res, *res2;
- MYSQL_ROW row;
-
- printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `textbot`, `id`, `queue`, `ssl`, `bind` FROM `bots` WHERE `botclass` = '%d' AND `active` = '1'", BOTID);
- res = mysql_use();
-
- while ((row = mysql_fetch_row(res)) != NULL) {
- client = create_socket(row[3], atoi(row[4]), row[10], row[5], row[0], row[1], row[2]);
- client->flags |= (strcmp(row[6], "0") ? SOCKET_FLAG_PREFERRED : 0);
- client->flags |= (strcmp(row[8], "0") ? SOCKET_FLAG_USE_QUEUE : 0);
- client->flags |= (strcmp(row[9], "0") ? SOCKET_FLAG_SSL : 0);
- client->botid = BOTID;
- client->clientid = atoi(row[7]);
- connect_socket(client);
- }
-
- printf_mysql_query("SELECT `command`, `function`, `parameters`, `global_access`, `chan_access`, `flags` FROM `bot_binds` WHERE `botclass` = '%d'", BOTID);
- res2 = mysql_use();
- while ((row = mysql_fetch_row(res2)) != NULL) {
- if(bind_cmd_to_command(BOTID, row[0], row[1])) {
- if(row[2] && strcmp(row[2], "")) {
- bind_set_parameters(BOTID, row[0], row[2]);
- }
- if(row[3]) {
- bind_set_global_access(BOTID, row[0], atoi(row[3]));
- }
- if(row[4]) {
- bind_set_channel_access(BOTID, row[0], row[4]);
- }
- if(strcmp(row[5], "0"))
- bind_set_bind_flags(BOTID, row[0], atoi(row[5]));
- }
- }
- bind_unbound_required_functions(BOTID);
-}
-
-char* convertNeonSpamSettingsToString(unsigned int flags, char *buffer) {
- int pos = 0;
- unsigned int i;
- int j = 0;
- char *chars = SPAMSETTINGS_CHARS;
- for(i = 1; i <= SPAMSETTINGS_FLAGS; i = i << 1) {
- if(flags & i)
- buffer[pos++] = chars[j];
- j++;
- }
- buffer[pos] = '\0';
- return buffer;
-}
-
-static unsigned int convertNeonSpamSettingsToFlags(char *str) {
- unsigned int i = 1, flags = 0;
- int j = 0;
- char *chars = SPAMSETTINGS_CHARS;
- while(*str) {
- for(; i <= SPAMSETTINGS_FLAGS; i = i << 1) {
- if(*str == chars[j]) {
- flags |= i;
- j++;
- i = i << 1;
- break;
- }
- j++;
- }
- str++;
- }
- return flags;
-}
-
-int loadNeonSpamSettings(struct ChanNode *chan) {
- if(chan->spam_settings) return 0;
- struct NeonSpamSettings *settings = malloc(sizeof(*settings));
- if(!settings) {
- perror("malloc() failed");
- return 0;
- }
- MYSQL_RES *res;
- MYSQL_ROW row, defaults = NULL;
- loadChannelSettings(chan);
- printf_mysql_query("SELECT `channel_scanner`, `channel_spam_limit`, `channel_spam_except`, `channel_flood_limit`, `channel_flood_time`, `channel_flood_except`, `channel_join_limit`, `channel_join_time`, `channel_join_except`, `channel_caps_percent`, `channel_caps_except`, `channel_digit_percent`, `channel_digit_except` FROM `channels` WHERE `channel_id` = '%d'", chan->channel_id);
- res = mysql_use();
- row = mysql_fetch_row(res);
- if(!row[0] || !row[1] || !row[2] || !row[3] || !row[4] || !row[5] || !row[6] || !row[7] || !row[8] || !row[9] || !row[10] || !row[11] || !row[12]) {
- printf_mysql_query("SELECT `channel_scanner`, `channel_spam_limit`, `channel_spam_except`, `channel_flood_limit`, `channel_flood_time`, `channel_flood_except`, `channel_join_limit`, `channel_join_time`, `channel_join_except`, `channel_caps_percent`, `channel_caps_except`, `channel_digit_percent`, `channel_digit_except` FROM `channels` WHERE `channel_name` = 'defaults'");
- res = mysql_use();
- defaults = mysql_fetch_row(res);
- }
- settings->flags = convertNeonSpamSettingsToFlags(row[0] ? row[0] : defaults[0]);
- settings->spam_amount = atoi(row[1] ? row[1] : defaults[1]);
- settings->exceptlevel[SPAMSETTINGS_SPAMEXCINDEX] = atoi(row[2] ? row[2] : defaults[2]);
- settings->sensibility_amount[SPAMSETTINGS_FLOODSENINDEX] = atoi(row[3] ? row[3] : defaults[3]);
- settings->sensibility_time[SPAMSETTINGS_FLOODSENINDEX] = atoi(row[4] ? row[4] : defaults[4]);
- settings->exceptlevel[SPAMSETTINGS_FLOODEXCINDEX] = atoi(row[5] ? row[5] : defaults[5]);
- settings->sensibility_amount[SPAMSETTINGS_JOINSENINDEX] = atoi(row[6] ? row[6] : defaults[6]);
- settings->sensibility_time[SPAMSETTINGS_JOINSENINDEX] = atoi(row[7] ? row[7] : defaults[7]);
- settings->exceptlevel[SPAMSETTINGS_JOINEXCINDEX] = atoi(row[8] ? row[8] : defaults[8]);
- settings->percent[SPAMSETTINGS_CAPSPERCENTINDEX] = atoi(row[9] ? row[9] : defaults[9]);
- settings->exceptlevel[SPAMSETTINGS_CAPSEXCINDEX] = atoi(row[10] ? row[10] : defaults[10]);
- settings->percent[SPAMSETTINGS_DIGITPERCENTINDEX] = atoi(row[11] ? row[11] : defaults[11]);
- settings->exceptlevel[SPAMSETTINGS_DIGITEXCINDEX] = atoi(row[12] ? row[12] : defaults[12]);
- settings->join_nodes = NULL;
- settings->lastmsg_time = 0;
- int i;
- for(i = 0; i < BOTNETSCAN_USERS; i++)
- settings->botnicks[i] = NULL;
- chan->spam_settings = settings;
- return 1;
-}
-
-void freeNeonSpamSettings(struct NeonSpamSettings *settings) {
- struct NeonSpamJoinNode *joinnode, *nextjoinnode;
- for(joinnode = settings->join_nodes; joinnode; joinnode = nextjoinnode) {
- nextjoinnode = joinnode->next;
- freeJoinNode(joinnode);
- }
- free(settings);
-}
-
-static void freeJoinNode(struct NeonSpamJoinNode *joinnode) {
- free(joinnode->ident);
- free(joinnode->host);
- free(joinnode);
-}
-
-static struct NeonSpamJoinNode *getNeonSpamJoinNode(struct ChanUser *chanuser) {
- struct NeonSpamJoinNode *joinnode, *prevjoinnode = NULL, *nextjoinnode, *result = NULL;
- for(joinnode = chanuser->chan->spam_settings->join_nodes; joinnode; joinnode = nextjoinnode) {
- nextjoinnode = joinnode->next;
- if(!stricmp(joinnode->ident, chanuser->user->ident) && !stricmp(joinnode->host, chanuser->user->host)) {
- prevjoinnode = joinnode;
- result = joinnode;
- } else if(time(0) - joinnode->last_penalty_update > MAX_JOIN_TIME) {
- freeJoinNode(joinnode);
- if(prevjoinnode)
- prevjoinnode->next = nextjoinnode;
- else
- chanuser->chan->spam_settings->join_nodes = nextjoinnode;
- } else
- prevjoinnode = joinnode;
- }
- if(result)
- return result;
- joinnode = malloc(sizeof(*joinnode));
- if(!joinnode) {
- perror("malloc() failed");
- return NULL;
- }
- joinnode->ident = strdup(chanuser->user->ident);
- joinnode->host = strdup(chanuser->user->host);
- joinnode->last_penalty_update = time(0);
- joinnode->joinpenalty = 0;
- joinnode->next = chanuser->chan->spam_settings->join_nodes;
- chanuser->chan->spam_settings->join_nodes = joinnode;
- return joinnode;
-}
-
-static void createSpamNode(struct ChanUser *chanuser) {
- struct NeonSpamNode *spamnode = malloc(sizeof(*spamnode));
- if(!spamnode) {
- perror("malloc() failed");
- return;
- }
- spamnode->lastmsg = 0;
- spamnode->spamcount = 0;
- spamnode->floodpenalty = 0;
- spamnode->last_penalty_update = time(0);
- chanuser->spamnode = spamnode;
-}
-
-void init_NeonSpam() {
-
- set_bot_alias(BOTID, BOTALIAS);
- start_bots();
-
- //register events
- bind_bot_ready(neonspam_bot_ready);
- bind_join(neonspam_event_join);
- bind_chanmsg(neonspam_event_chanmsg);
- bind_privctcp(general_event_privctcp);
- bind_kick(neonspam_event_kick);
-
- set_trigger_callback(BOTID, neonspam_trigger_callback);
-
- register_default_language_table(msgtab);
-}
-
-void loop_NeonSpam() {
-
-}
-
-void free_NeonSpam() {
-
-}
-
-#undef BOTID
-#undef BOTALIAS
+++ /dev/null
-/* bot_NeonSpam.h - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef _bot_NeonSpam_h
-#define _bot_NeonSpam_h
-
-#include "main.h"
-
-struct ChanNode;
-
-//SPAMSCAN
-#define SPAMSETTINGS_SPAMSCAN 0x000001
-#define SPAMSETTINGS_SPAMSCAN_OPS 0x000002
-#define SPAMSETTINGS_SPAMSCAN_VOICE 0x000004
-#define SPAMSETTINGS_SPAMCHARS "abc"
-#define SPAMSETTINGS_SPAMEXCINDEX 0
-
-//FLOODSCAN
-#define SPAMSETTINGS_FLOODSCAN 0x000008
-#define SPAMSETTINGS_FLOODSCAN_OPS 0x000010
-#define SPAMSETTINGS_FLOODSCAN_VOICE 0x000020
-#define SPAMSETTINGS_FLOODCHARS "def"
-#define SPAMSETTINGS_FLOODEXCINDEX 1
-#define SPAMSETTINGS_FLOODSENINDEX 0
-
-//JOINSCAN
-#define SPAMSETTINGS_JOINSCAN 0x000040
-#define SPAMSETTINGS_JOINSCAN_OPS 0x000080
-#define SPAMSETTINGS_JOINSCAN_VOICE 0x000100
-#define SPAMSETTINGS_JOINCHARS "ghi"
-#define SPAMSETTINGS_JOINEXCINDEX 2
-#define SPAMSETTINGS_JOINSENINDEX 1
-
-//BOTNET SCAN
-#define SPAMSETTINGS_BOTNETSCAN 0x000200
-#define SPAMSETTINGS_BOTNETSCAN_OPS 0x000400
-#define SPAMSETTINGS_BOTNETSCAN_VOICE 0x000800
-#define SPAMSETTINGS_BOTNETSCAN_STRIPCC 0x001000
-#define SPAMSETTINGS_BOTNETCHARS "jklm"
-#define SPAMSETTINGS_BOTNETEXCINDEX 3
-
-//CAPSSCAN
-#define SPAMSETTINGS_CAPSSCAN 0x002000
-#define SPAMSETTINGS_CAPSSCAN_OPS 0x004000
-#define SPAMSETTINGS_CAPSSCAN_VOICE 0x008000
-#define SPAMSETTINGS_CAPSCHARS "nop"
-#define SPAMSETTINGS_CAPSEXCINDEX 4
-#define SPAMSETTINGS_CAPSPERCENTINDEX 0
-
-//DIGITSCAN
-#define SPAMSETTINGS_DIGITSCAN 0x010000
-#define SPAMSETTINGS_DIGITSCAN_OPS 0x020000
-#define SPAMSETTINGS_DIGITSCAN_VOICE 0x040000
-#define SPAMSETTINGS_DIGITCHARS "qrs"
-#define SPAMSETTINGS_DIGITEXCINDEX 5
-#define SPAMSETTINGS_DIGITPERCENTINDEX 1
-
-
-#define SPAMSETTINGS_CHARS SPAMSETTINGS_SPAMCHARS SPAMSETTINGS_FLOODCHARS SPAMSETTINGS_JOINCHARS SPAMSETTINGS_BOTNETCHARS SPAMSETTINGS_CAPSCHARS SPAMSETTINGS_DIGITCHARS
-#define SPAMSETTINGS_FLAGS 0x07ffff /* all flags that can be stored in the database */
-#define SPAMSETTINGS_EXCEPTINDEXES 6
-#define SPAMSETTINGS_SENSIBILITYINDEXES 2
-#define SPAMSETTINGS_PERCENTINDEXES 2
-
-//SCRIPT FLAGS
-#define SPAMSETTINGS_KICKEDBOTQUEUE 0x080000
-#define SPAMSETTINGS_ISTIMEBAN 0x100000
-#define SPAMSETTINGS_SETTIMEBAN 0x200000
-
-#define MAX_FLOOD_AMOUNT 300
-#define MIN_FLOOD_AMOUNT 2
-#define MAX_FLOOD_TIME 200
-
-#define MAX_JOIN_AMOUNT 300
-#define MIN_JOIN_AMOUNT 2
-#define MAX_JOIN_TIME 200
-
-#define BOTNETSCAN_USERS 4
-#define BOTNETSCAN_TIME 2
-
-struct NeonSpamSettings {
- unsigned int flags;
- unsigned char spam_amount;
- unsigned char sensibility_amount[SPAMSETTINGS_SENSIBILITYINDEXES];
- unsigned char sensibility_time[SPAMSETTINGS_SENSIBILITYINDEXES];
- unsigned int exceptlevel[SPAMSETTINGS_EXCEPTINDEXES];
- unsigned char percent[SPAMSETTINGS_PERCENTINDEXES];
-
- //joinflood
- struct NeonSpamJoinNode *join_nodes;
-
- //botnet
- unsigned long lastmsg; //crc32 hash
- time_t lastmsg_time;
- char *botnicks[BOTNETSCAN_USERS];
-
-
-};
-/* PENALTY SYSTEM
-* user gets MAX_FLOOD_TIME points per message
-* points get removed each loop
-* pounts to be removed each second:
-* MAX_FLOOD_TIME/flood_time
-*
-* the floodlimit is reached, if the penalty points
-* are bigger than MAX_FLOOD_TIME * flood_amount
-*/
-
-#define NEONSPAMNODE_FLAG_CAPSSCAN_WARNED 0x01
-#define NEONSPAMNODE_FLAG_DIGITSCAN_WARNED 0x02
-
-struct NeonSpamNode {
- unsigned long lastmsg; //crc32 hash
- unsigned char spamcount;
- int floodpenalty;
- time_t last_penalty_update;
- unsigned char flags;
-};
-
-struct NeonSpamJoinNode {
- char *ident;
- char *host;
- int joinpenalty;
- time_t last_penalty_update;
- struct NeonSpamJoinNode *next;
-};
-
-void init_NeonSpam();
-void loop_NeonSpam();
-void free_NeonSpam();
-
-void freeNeonSpamSettings(struct NeonSpamSettings *settings);
-char* convertNeonSpamSettingsToString(unsigned int flags, char *buffer);
-int loadNeonSpamSettings(struct ChanNode *chan);
-
-#endif
\ No newline at end of file
}
void init_bots() {
- init_NeonServ();
- init_NeonSpam();
- init_DummyServ();
- init_NeonHelp();
-
set_bot_alias(0, "0");
start_zero_bots();
set_trigger_callback(0, zero_bots_trigger_callback);
}
}
-void loop_bots() {
- loop_NeonServ();
- loop_NeonSpam();
- loop_DummyServ();
- loop_NeonHelp();
-}
-
-void free_bots() {
- free_NeonServ();
- free_NeonSpam();
- free_DummyServ();
- free_NeonHelp();
-}
-
struct ClientSocket *getChannelBot(struct ChanNode *chan, int botid) {
struct ClientSocket *bot, *use_bot = NULL, *second_bot = NULL, *third_bot = NULL;
struct ChanUser *chanuser;
struct ChanNode;
struct ClientSocket;
+#ifndef DND_FUNCTIONS
void init_bots();
-void loop_bots();
-void free_bots();
-
-struct ClientSocket *getChannelBot(struct ChanNode *chan, int botid);
-void requestOp(struct UserNode *user, struct ChanNode *chan);
-TIMEQ_CALLBACK(channel_ban_timeout);
-void general_event_privctcp(struct UserNode *user, struct UserNode *target, char *command, char *text);
-void set_bot_alias(int botid, char *alias);
-const char *resolve_botid(int botid);
-int resolve_botalias(const char *alias);
+/* MODULAR ACCESSIBLE */ struct ClientSocket *getChannelBot(struct ChanNode *chan, int botid);
+/* MODULAR ACCESSIBLE */ void requestOp(struct UserNode *user, struct ChanNode *chan);
+/* MODULAR ACCESSIBLE */ TIMEQ_CALLBACK(channel_ban_timeout);
+/* MODULAR ACCESSIBLE */ void general_event_privctcp(struct UserNode *user, struct UserNode *target, char *command, char *text);
+/* MODULAR ACCESSIBLE */ void set_bot_alias(int botid, char *alias);
+/* MODULAR ACCESSIBLE */ const char *resolve_botid(int botid);
+/* MODULAR ACCESSIBLE */ int resolve_botalias(const char *alias);
+#endif
#endif
\ No newline at end of file
+++ /dev/null
-/* cmd_funcmds.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_funcmds.h"
-#include "modcmd.h"
-#include "mysqlConn.h"
-#include "IRCParser.h"
-#include "ClientSocket.h"
-#include "UserNode.h"
-#include "ChanNode.h"
-#include "lang.h"
-#include "tools.h"
-#include "DBHelper.h"
-
-static const struct default_language_entry msgtab[] = {
- {"FUN_DICE", "$b%s$b: A $b%d$b shows on the %d-sided die."}, /* {ARGS: "TestUser", 5, 6} */
- {"FUN_DICE_NUM", "I do not understand $b%s$b. Please use a single number above 1."}, /* {ARGS: "bla"} */
- {"FUN_8BALL", "$b%s$b: %s"}, /* {ARGS: "TestUser", "Not a chance."} */
- {"FUN_8BALL_REPLIES", "Not a chance.|In your dreams.|Absolutely!|Could be, could be.|No!"},
- {"FUN_COOKIE", "gives %1$s a very big chocolate cookie. %1$s has got %2$d cookies until now (%3$d in this channel)."}, /* {ARGS: "TestUser", 20, 50} */
- {NULL, NULL}
-};
-
-void init_funcmds() {
- register_default_language_table(msgtab);
- srand(time(NULL));
-}
-
-struct current_funcmd_header {
- struct ClientSocket *client;
- struct UserNode *user;
- struct ChanNode *chan;
- char send_notice;
-};
-
-static struct current_funcmd_header current_funcmd;
-
-#define FUNCMD_HEADER \
-current_funcmd.client = getTextBot(); \
-current_funcmd.user = user; \
-current_funcmd.chan = chan; \
-{\
- MYSQL_RES *res; \
- MYSQL_ROW row; \
- printf_mysql_query("SELECT `channel_toys` FROM `channels` WHERE `channel_name` = '%s'", escape_string(chan->name)); \
- res = mysql_use(); \
- row = mysql_fetch_row(res); \
- if(!row || !strcmp(row[0], "0")) { \
- reply(getTextBot(), user, "NS_FUN_DISABLED", chan->name); \
- return; \
- } else if(!strcmp(row[0], "1")) \
- current_funcmd.send_notice = 1; \
- else \
- current_funcmd.send_notice = 0; \
-}
-
-#define REPLYTYPE_NORMAL 0
-#define REPLYTYPE_ACTION 1
-static void funcmd_reply(const char *text, int type, ...) {
- if (!(current_funcmd.client->flags & SOCKET_FLAG_CONNECTED)) return;
- const char *reply_format = get_language_string(current_funcmd.user, text);
- if(reply_format)
- text = reply_format;
- char formatBuf[MAXLEN];
- if(current_funcmd.send_notice) {
- if(type == REPLYTYPE_ACTION)
- sprintf(formatBuf, "NOTICE %s :%s %s", current_funcmd.user->nick, current_funcmd.client->user->nick, text);
- else
- sprintf(formatBuf, "NOTICE %s :%s", current_funcmd.user->nick, text);
- } else {
- if(type == REPLYTYPE_ACTION)
- sprintf(formatBuf, "PRIVMSG %s :\001ACTION %s\001", current_funcmd.chan->name, text);
- else
- sprintf(formatBuf, "PRIVMSG %s :%s", current_funcmd.chan->name, text);
- }
- va_list arg_list;
- char sendBuf[MAXLEN];
- int pos;
- sendBuf[0] = '\0';
- va_start(arg_list, type);
- pos = vsnprintf(sendBuf, MAXLEN - 2, formatBuf, arg_list);
- va_end(arg_list);
- if (pos < 0 || pos > (MAXLEN - 2)) pos = MAXLEN - 2;
- sendBuf[pos] = '\n';
- sendBuf[pos+1] = '\0';
- write_socket(current_funcmd.client, sendBuf, pos+1);
-}
-
-static char* getSetting(struct UserNode *user, struct ChanNode *chan, const char *setting) {
- char *uname = "";
- int cid = 0;
- MYSQL_RES *res;
- MYSQL_ROW row;
- if(user) {
- uname = ((user->flags & USERFLAG_ISAUTHED) ? user->auth : "*");
- }
- if(chan) {
- loadChannelSettings(chan);
- if(chan->flags & CHANFLAG_CHAN_REGISTERED)
- cid = chan->channel_id;
- }
- printf_mysql_query("SELECT `value` FROM `fundata` WHERE `user` = '%s' AND `cid` = '%d' AND `name` = '%s'", escape_string(uname), cid, escape_string(setting));
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) != NULL) {
- return row[0];
- } else
- return NULL;
-}
-
-static void setSetting(struct UserNode *user, struct ChanNode *chan, const char *setting, const char *value) {
- char *uname = "";
- int cid = 0;
- MYSQL_RES *res;
- MYSQL_ROW row;
- if(user) {
- uname = ((user->flags & USERFLAG_ISAUTHED) ? user->auth : "*");
- }
- if(chan) {
- loadChannelSettings(chan);
- if(chan->flags & CHANFLAG_CHAN_REGISTERED)
- cid = chan->channel_id;
- }
- printf_mysql_query("SELECT `id`, `value` FROM `fundata` WHERE `user` = '%s' AND `cid` = '%d' AND `name` = '%s'", escape_string(uname), cid, escape_string(setting));
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) != NULL) {
- if(strcmp(row[1], value))
- printf_mysql_query("UPDATE `fundata` SET `value` = '%s' WHERE `id` = '%s'", escape_string(value), row[0]);
- } else
- printf_mysql_query("INSERT INTO `fundata` (`user`, `cid`, `name`, `value`) VALUES ('%s', '%d', '%s', '%s')", escape_string(uname), cid, escape_string(setting), escape_string(value));
-}
-
-CMD_BIND(funcmd_ping) {
- FUNCMD_HEADER;
- funcmd_reply("\002%s\002: Pong!", REPLYTYPE_NORMAL, user->nick);
-}
-
-CMD_BIND(funcmd_pong) {
- FUNCMD_HEADER;
- funcmd_reply("\002%s\002: Ping!", REPLYTYPE_NORMAL, user->nick);
-}
-
-CMD_BIND(funcmd_dice) {
- FUNCMD_HEADER;
- int max = atoi(argv[0]);
- if(max > 1) {
- int val = (rand() % max) + 1;
- funcmd_reply("FUN_DICE", REPLYTYPE_NORMAL, user->nick, val, max);
- } else
- funcmd_reply("FUN_DICE_NUM", REPLYTYPE_NORMAL, argv[0]);
-}
-
-CMD_BIND(funcmd_8ball) {
- FUNCMD_HEADER;
- char *message = merge_argv(argv, 0, argc);
- const char *const_replies = get_language_string(current_funcmd.user, "FUN_8BALL_REPLIES");
- char replies[MAXLEN];
- int i, reply_count = 1;
- for(i = 0; const_replies[i]; i++) {
- if(const_replies[i] == '|')
- reply_count++;
- replies[i] = const_replies[i];
- }
- replies[i] = '\0';
- unsigned int crc32_val = (crc32(message)) % reply_count;
- char *creply = (crc32_val == 0 ? replies : NULL);
- reply_count = 0;
- for(i = 0; replies[i]; i++) {
- if(replies[i] == '|') {
- if(creply) {
- replies[i] = '\0';
- break;
- } else {
- reply_count++;
- if(reply_count == crc32_val) {
- creply = &replies[i+1];
- }
- }
- }
- }
- if(creply) {
- funcmd_reply("FUN_8BALL", REPLYTYPE_NORMAL, user->nick, creply);
- }
-}
-
-CMD_BIND(funcmd_cookie) {
- FUNCMD_HEADER;
- if(argc) {
- if(!(user = getUserByNick(argv[0]))) {
- reply(current_funcmd.client, current_funcmd.user, "NS_USER_UNKNOWN", argv[0]);
- return;
- }
- }
- char *tmp;
- int user_count = ((tmp = getSetting(user, chan, "cookies")) ? atoi(tmp) : 0);
- int total_count = ((tmp = getSetting(user, NULL, "cookies")) ? atoi(tmp) : 0);
- user_count++;
- total_count++;
- char buf[10];
- sprintf(buf, "%d", user_count);
- setSetting(user, chan, "cookies", buf);
- sprintf(buf, "%d", total_count);
- setSetting(user, NULL, "cookies", buf);
- funcmd_reply("FUN_COOKIE", REPLYTYPE_ACTION, user->nick, total_count, user_count);
-}
+++ /dev/null
-/* cmd_funcmds.h - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-#ifndef _cmd_funcmds_h
-#define _cmd_funcmds_h
-#include "main.h"
-#include "modcmd.h"
-
-void init_funcmds();
-
-CMD_BIND(funcmd_ping);
-CMD_BIND(funcmd_pong);
-CMD_BIND(funcmd_dice);
-CMD_BIND(funcmd_8ball);
-CMD_BIND(funcmd_cookie);
-
-#endif
\ No newline at end of file
+++ /dev/null
-/* cmd_global.h - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-#ifndef _cmd_global_h
-#define _cmd_global_h
-#include "main.h"
-#include "modcmd.h"
-#include "IRCParser.h"
-#include "IRCEvents.h"
-#include "UserNode.h"
-#include "ChanNode.h"
-#include "ChanUser.h"
-#include "ModeNode.h"
-#include "BanNode.h"
-#include "ClientSocket.h"
-#include "mysqlConn.h"
-#include "lang.h"
-#include "HandleInfoHandler.h"
-#include "WHOHandler.h"
-#include "DBHelper.h"
-#include "tools.h"
-#include "timeq.h"
-#include "version.h"
-#include "EventLogger.h"
-#include "bots.h"
-
-CMD_BIND(global_cmd_addbot);
-CMD_BIND(global_cmd_bind);
-CMD_BIND(global_cmd_bots);
-CMD_BIND(global_cmd_command);
-CMD_BIND(global_cmd_commands);
-CMD_BIND(global_cmd_delbot);
-CMD_BIND(global_cmd_die);
-CMD_BIND(global_cmd_emote);
-CMD_BIND(global_cmd_god);
-CMD_BIND(global_cmd_meminfo);
-CMD_BIND(global_cmd_modcmd);
-CMD_BIND(global_cmd_motd);
-CMD_BIND(global_cmd_netinfo);
-CMD_BIND(global_cmd_notice);
-CMD_BIND(global_cmd_raw);
-CMD_BIND(global_cmd_reconnect);
-CMD_BIND(global_cmd_register);
-CMD_BIND(global_cmd_reload);
-CMD_BIND(global_cmd_restart);
-CMD_BIND(global_cmd_reloadlang);
-CMD_BIND(global_cmd_say);
-CMD_BIND(global_cmd_setaccess);
-CMD_BIND(global_cmd_setbot);
-CMD_BIND(global_cmd_staff);
-CMD_BIND(global_cmd_unbind);
-CMD_BIND(global_cmd_unregister);
-CMD_BIND(global_cmd_version);
-
-#endif
\ No newline at end of file
+++ /dev/null
-/* cmd_global_addbot.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_global.h"
-
-/*
-* argv[0] nick
-* argv[1] class
-*/
-
-CMD_BIND(global_cmd_addbot) {
- MYSQL_RES *res;
- int botid;
- if((botid = resolve_botalias(argv[1])) == -1) {
- reply(getTextBot(), user, "NS_SETBOT_INVALID_CLASS", argv[1]);
- return;
- }
- printf_mysql_query("SELECT `id` FROM `bots` WHERE `nick` = '%s'", escape_string(argv[0]));
- res = mysql_use();
- if(mysql_fetch_row(res)) {
- reply(getTextBot(), user, "NS_ADDBOT_EXISTING", argv[0]);
- return;
- }
- printf_mysql_query("INSERT INTO `bots` (`nick`, `botclass`) VALUES ('%s', '%d')", escape_string(argv[0]), botid);
- botid = (int) mysql_insert_id(get_mysql_conn());
- reply(getTextBot(), user, "NS_ADDBOT_DONE", argv[0], botid);
- logEvent(event);
-}
-
+++ /dev/null
-/* cmd_global_bind.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_global.h"
-
-/*
-* argv[0] command name
-* argv[1] command function
-* argv[2-*] parameters (optional)
-*/
-
-CMD_BIND(global_cmd_bind) {
- MYSQL_RES *res;
- MYSQL_ROW row;
- if(client->botid == 0)
- printf_mysql_query("SELECT `function` FROM `bot_binds` WHERE `botclass` = '%d' AND `botid` = '%d' AND `command` = '%s'", client->botid, client->clientid, escape_string(argv[0]));
- else
- printf_mysql_query("SELECT `function` FROM `bot_binds` WHERE `botclass` = '%d' AND `command` = '%s'", client->botid, escape_string(argv[0]));
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) != NULL) {
- reply(getTextBot(), user, "NS_BIND_ALREADY", argv[0], row[0]);
- return;
- }
- char *params;
- if(argc > 2)
- params = merge_argv(argv, 2, argc);
- else
- params = "";
- struct cmd_function *function = find_cmd_function(client->botid, argv[1]);
- if(!function) {
- reply(getTextBot(), user, "NS_BIND_UNKNOWN", argv[1]);
- return;
- }
- bind_botwise_cmd_to_function(client->botid, client->clientid, argv[0], function);
- printf_mysql_query("INSERT INTO `bot_binds` (`botclass`, `botid`, `command`, `function`, `parameters`) VALUES ('%d', '%d', '%s', '%s', '%s')", client->botid, (client->botid == 0 ? client->clientid : 0), escape_string(argv[0]), escape_string(argv[1]), params);
- if(*params)
- bind_botwise_set_parameters(client->botid, client->clientid, argv[0], params);
- reply(getTextBot(), user, "NS_BIND_DONE", argv[0], function->name);
- logEvent(event);
-}
+++ /dev/null
-/* cmd_global_bots.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_global.h"
-
-/*
-* argv[0] (optional) class name
-*/
-
-CMD_BIND(global_cmd_bots) {
- struct Table *table;
- MYSQL_RES *res, *res2;
- MYSQL_ROW row, row2;
- printf_mysql_query("SELECT `active`, `nick`, `server`, `port`, `pass`, `botclass`, `textbot`, `queue`, `defaulttrigger`, `max_channels`, `register_priority`, `id` FROM `bots`");
- res = mysql_use();
- table = table_init(7, mysql_num_rows(res) + 1, 0);
- char *content[7];
- content[0] = get_language_string(user, "NS_BOTS_ID");
- content[1] = get_language_string(user, "NS_BOTS_NICK");
- content[2] = get_language_string(user, "NS_BOTS_SERVER");
- content[3] = get_language_string(user, "NS_BOTS_CLASS");
- content[4] = get_language_string(user, "NS_BOTS_FLAGS");
- content[5] = get_language_string(user, "NS_BOTS_CHANNELS");
- content[6] = get_language_string(user, "NS_BOTS_TRIGGER");
- table_add(table, content);
- char botnick[NICKLEN + 3];
- char botserver[MAXLEN];
- char botflags[10];
- int flagspos;
- char botchans[20];
- while ((row = mysql_fetch_row(res)) != NULL) {
- content[0] = row[11];
- sprintf(botnick, (strcmp(row[0], "0") ? "%s" : "!%s"), row[1]);
- content[1] = botnick;
- sprintf(botserver, (strcmp(row[4], "") ? "%s:%s:*" : "%s:%s"), row[2], row[3]);
- content[2] = botserver;
- content[3] = (char *) resolve_botid(atoi(row[5]));
- flagspos = 0;
- if(!strcmp(row[6], "1"))
- botflags[flagspos++] = 't';
- if(!strcmp(row[7], "1"))
- botflags[flagspos++] = 'q';
- botflags[flagspos] = '\0';
- content[4] = botflags;
- printf_mysql_query("SELECT COUNT(*) FROM `bot_channels` WHERE `botid` = '%s'", row[11]);
- res2 = mysql_use();
- row2 = mysql_fetch_row(res2);
- sprintf(botchans, "%s/%s", row2[0], row[9]);
- content[5] = botchans;
- content[6] = row[8];
- table_add(table, content);
- }
- char **table_lines = table_end(table);
- int i;
- for(i = 0; i < table->entrys; i++) {
- reply(getTextBot(), user, table_lines[i]);
- }
- table_free(table);
-}
\ No newline at end of file
+++ /dev/null
-/* cmd_global_command.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_global.h"
-
-/*
-* argv[0-1] command
-*/
-static int global_cmd_command_chanaccess(struct cmd_binding *cbind, struct ChanNode *chan);
-static int global_cmd_command_operaccess(struct cmd_binding *cbind);
-
-CMD_BIND(global_cmd_command) {
- char *ident;
- MYSQL_RES *res;
- MYSQL_ROW row;
- struct cmd_binding *cbind = find_botwise_cmd_binding(client->botid, client->clientid, argv[0]);
- if (!cbind) {
- reply(getTextBot(), user, "NS_UNBIND_NOT_FOUND", argv[0]);
- return;
- }
- ident = argv[0];
- char parameters[MAXLEN];
- if(cbind->paramcount) {
- int i, parampos = 0;
- for(i = 0; i < cbind->paramcount; i++) {
- parampos += sprintf(parameters + parampos, (i ? " %s" : "%s"), cbind->parameters[i]);
- }
- } else
- parameters[0] = '\0';
- reply(getTextBot(), user, "NS_COMMAND_BINDING", cbind->cmd, cbind->func->name, parameters);
- if(chan)
- reply(getTextBot(), user, "NS_COMMAND_ACCESS", global_cmd_command_chanaccess(cbind, chan), global_cmd_command_operaccess(cbind));
- printf_mysql_query("SELECT `user_lang` FROM `users` WHERE `user_user` = '%s'", escape_string(user->auth));
- res = mysql_use();
- char *lang;
- if ((row = mysql_fetch_row(res)) != NULL)
- lang = row[0];
- else
- lang = "en";
- printf_mysql_query("SELECT `text` FROM `help` WHERE `lang` = '%s' AND `ident` = '%s'", escape_string(lang), escape_string(ident));
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) == NULL) {
- if(stricmp(lang, "en")) {
- printf_mysql_query("SELECT `text` FROM `help` WHERE `lang` = 'en' AND `ident` = '%s'", escape_string(ident));
- res = mysql_use();
- }
- if ((row = mysql_fetch_row(res)) == NULL) {
- printf_mysql_query("SELECT `text` FROM `help` WHERE `lang` = '%s' AND `ident` = '%s'", escape_string(lang), escape_string(cbind->func->name));
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) == NULL) {
- if(stricmp(lang, "en")) {
- printf_mysql_query("SELECT `text` FROM `help` WHERE `lang` = 'en' AND `ident` = '%s'", escape_string(cbind->func->name));
- res = mysql_use();
- }
- if ((row = mysql_fetch_row(res)) == NULL) {
- return;
- }
- }
- }
- }
- char sendBuf[MAXLEN];
- int sendBufPos = 0;
- int i;
- for(i = 0; i < strlen(row[0]); i++) {
- switch(row[0][i]) {
- case '\n':
- if(sendBufPos) {
- sendBuf[sendBufPos] = '\0';
- reply(getTextBot(), user, "%s", sendBuf);
- sendBufPos = 0;
- }
- break;
- case '$':
- switch(row[0][i+1]) {
- case 'b':
- sendBuf[sendBufPos++] = '\002';
- i++;
- break;
- case 'k':
- sendBuf[sendBufPos++] = '\003';
- i++;
- break;
- case 'u':
- sendBuf[sendBufPos++] = '\031';
- i++;
- break;
- case 'C':
- case 'S':
- sendBufPos += sprintf(sendBuf + sendBufPos, "%s", client->user->nick);
- i++;
- break;
- default:
- sendBuf[sendBufPos++] = '$';
- break;
- }
- break;
- default:
- sendBuf[sendBufPos++] = row[0][i];
- break;
- }
- }
- if(sendBufPos) {
- sendBuf[sendBufPos] = '\0';
- reply(getTextBot(), user, "%s", sendBuf);
- sendBufPos = 0;
- }
-}
-
-static int global_cmd_command_chanaccess(struct cmd_binding *cbind, struct ChanNode *chan) {
- char access_list[256];
- int access_pos = 0;
- int access_count = 0;
- int minaccess = 0;
- char *str_a, *str_b = cbind->func->channel_access, *str_c;
- if(cbind->flags & CMDFLAG_OVERRIDE_CHANNEL_ACCESS)
- str_b = cbind->channel_access;
- access_list[0] = '\0';
- if(str_b) {
- str_c = strdup(str_b);
- str_b = str_c;
- while((str_a = str_b)) {
- str_b = strstr(str_a, ",");
- if(str_b) {
- *str_b = '\0';
- str_b++;
- }
- if(*str_a == '@' || *str_a == '+') {
- //privs can override this access requirement
- str_a++;
- }
- if(*str_a == '#') {
- str_a++;
- access_pos += sprintf(access_list+access_pos, (access_pos ? ", `%s`" : "`%s`"), str_a);
- access_count++;
- } else {
- if(atoi(str_a) > minaccess)
- minaccess = atoi(str_a);
- }
- }
- free(str_c);
- }
- if(access_count) {
- MYSQL_RES *res;
- MYSQL_ROW row, defaults = NULL;
- printf_mysql_query("SELECT %s FROM `channels` WHERE `channel_name` = '%s'", access_list, escape_string(chan->name));
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) != NULL) {
- int i, caccess;
- for(i = 0; i < access_count; i++) {
- if(!row[i] && !defaults) {
- printf_mysql_query("SELECT %s FROM `channels` WHERE `channel_name` = 'defaults'", access_list);
- defaults = mysql_fetch_row(mysql_use());
- }
- caccess = (row[i] ? atoi(row[i]) : atoi(defaults[i]));
- if(caccess > minaccess)
- minaccess = caccess;
- }
- }
- }
- return minaccess;
-}
-
-static int global_cmd_command_operaccess(struct cmd_binding *cbind) {
- return ((cbind->flags & CMDFLAG_OVERRIDE_GLOBAL_ACCESS) ? cbind->global_access : cbind->func->global_access);
-}
+++ /dev/null
-/* cmd_global_commands.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_global.h"
-
-/*
-* argv[0] mask
-*/
-
-static int global_cmd_commands_sort(const void *a, const void *b);
-static int global_cmd_commands_chanaccess(struct cmd_binding *cbind, struct ChanNode *chan);
-static int global_cmd_commands_operaccess(struct cmd_binding *cbind);
-
-CMD_BIND(global_cmd_commands) {
- struct cmd_binding *cbind;
- int bindcount = 0;
- for(cbind = getAllBinds(NULL); cbind; cbind = getAllBinds(cbind)) {
- if(cbind->botid == client->botid && (cbind->botid || cbind->clientid == client->clientid) && !(cbind->func->flags & CMDFLAG_FUNCMD))
- bindcount++;
- }
- struct cmd_binding *binds[bindcount];
- bindcount = 0;
- for(cbind = getAllBinds(NULL); cbind; cbind = getAllBinds(cbind)) {
- if(cbind->botid == client->botid && (cbind->botid || cbind->clientid == client->clientid) && !(cbind->func->flags & CMDFLAG_FUNCMD))
- binds[bindcount++] = cbind;
- }
- qsort(binds, bindcount, sizeof(struct cmd_binding *), global_cmd_commands_sort);
- int i;
- struct Table *table;
- table = table_init(5, bindcount + 1, 0);
- char *content[5];
- content[0] = get_language_string(user, "NS_COMMANDS_NAME");
- content[1] = get_language_string(user, "NS_COMMANDS_ACCESS");
- content[2] = get_language_string(user, "NS_COMMANDS_GACCESS");
- content[3] = get_language_string(user, "NS_COMMANDS_TRIGGERED");
- content[4] = get_language_string(user, "NS_COMMANDS_FUNCTION");
- table_add(table, content);
- char caccess[5];
- char gaccess[5];
- char triggered[10];
- char funcname[MAXLEN];
- int funcpos;
- for(i = 0; i < bindcount; i++) {
- cbind = binds[i];
- content[0] = cbind->cmd;
- sprintf(caccess, "%d", global_cmd_commands_chanaccess(cbind, chan));
- content[1] = caccess;
- sprintf(gaccess, "%d", global_cmd_commands_operaccess(cbind));
- content[2] = gaccess;
- sprintf(triggered, "%d", cbind->triggered);
- content[3] = triggered;
- funcpos = sprintf(funcname, "%s", cbind->func->name);
- if(cbind->paramcount) {
- int j;
- for(j = 0; j < cbind->paramcount; j++) {
- funcpos += sprintf(funcname + funcpos, " %s", cbind->parameters[j]);
- }
- }
- content[4] = funcname;
- table_add(table, content);
- }
- //send the table
- char **table_lines = table_end(table);
- for(i = 0; i < table->entrys; i++) {
- reply(getTextBot(), user, table_lines[i]);
- }
- table_free(table);
-}
-
-static int global_cmd_commands_sort(const void *a, const void *b) {
- const struct cmd_binding *bind_a = *((struct cmd_binding * const *) a);
- const struct cmd_binding *bind_b = *((struct cmd_binding * const *) b);
- int i = stricmp(bind_a->func->name, bind_b->func->name);
- if(i == 0) {
- return stricmp(bind_a->cmd, bind_b->cmd);
- } else
- return i;
-}
-
-static int global_cmd_commands_chanaccess(struct cmd_binding *cbind, struct ChanNode *chan) {
- char access_list[256];
- int access_pos = 0;
- int access_count = 0;
- int minaccess = 0;
- char *str_a, *str_b = cbind->func->channel_access, *str_c;
- if(cbind->flags & CMDFLAG_OVERRIDE_CHANNEL_ACCESS)
- str_b = cbind->channel_access;
- access_list[0] = '\0';
- if(str_b) {
- str_c = strdup(str_b);
- str_b = str_c;
- while((str_a = str_b)) {
- str_b = strstr(str_a, ",");
- if(str_b) {
- *str_b = '\0';
- str_b++;
- }
- if(*str_a == '@' || *str_a == '+') {
- //privs can override this access requirement
- str_a++;
- }
- if(*str_a == '#') {
- str_a++;
- access_pos += sprintf(access_list+access_pos, (access_pos ? ", `%s`" : "`%s`"), str_a);
- access_count++;
- } else {
- if(atoi(str_a) > minaccess)
- minaccess = atoi(str_a);
- }
- }
- free(str_c);
- }
- if(access_count) {
- if(!chan) {
- return -1;
- }
- MYSQL_RES *res;
- MYSQL_ROW row, defaults = NULL;
- printf_mysql_query("SELECT %s FROM `channels` WHERE `channel_name` = '%s'", access_list, escape_string(chan->name));
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) != NULL) {
- int i, caccess;
- for(i = 0; i < access_count; i++) {
- if(!row[i] && !defaults) {
- printf_mysql_query("SELECT %s FROM `channels` WHERE `channel_name` = 'defaults'", access_list);
- defaults = mysql_fetch_row(mysql_use());
- }
- caccess = (row[i] ? atoi(row[i]) : atoi(defaults[i]));
- if(caccess > minaccess)
- minaccess = caccess;
- }
- }
- }
- return minaccess;
-}
-
-static int global_cmd_commands_operaccess(struct cmd_binding *cbind) {
- return ((cbind->flags & CMDFLAG_OVERRIDE_GLOBAL_ACCESS) ? cbind->global_access : cbind->func->global_access);
-}
+++ /dev/null
-/* cmd_global_delbot.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_global.h"
-
-/*
-* argv[0] nick/botid
-*/
-
-CMD_BIND(global_cmd_delbot) {
- MYSQL_RES *res;
- MYSQL_ROW row;
- printf_mysql_query("SELECT `id` FROM `bots` WHERE `nick` = '%s' OR `id` = '%s'", escape_string(argv[0]), escape_string(argv[0]));
- res = mysql_use();
- if((row = mysql_fetch_row(res)) == NULL) {
- reply(getTextBot(), user, "NS_DELBOT_NOT_FOUND", argv[0]);
- return;
- }
- int botid = atoi(row[0]);
- printf_mysql_query("DELETE FROM `bots` WHERE `id` = '%s'", row[0]);
- printf_mysql_query("DELETE FROM `bot_binds` WHERE `botid` = '%s'", row[0]);
- printf_mysql_query("DELETE FROM `bot_channels` WHERE `botid` = '%s'", row[0]);
- for(client = getBots(0, NULL); client; client = getBots(0, client)) {
- if(client->clientid == botid) {
- close_socket(client);
- break;
- }
- }
- reply(getTextBot(), user, "NS_DELBOT_DONE");
- logEvent(event);
-}
+++ /dev/null
-/* cmd_global_die.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_global.h"
-
-/*
-* no args
-*/
-
-CMD_BIND(global_cmd_die) {
- //hard work! :D
- stop_bot();
-}
+++ /dev/null
-/* cmd_global_emote.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_global.h"
-
-/*
-* argv[0] target
-* argv[1-*] message
-*/
-
-CMD_BIND(global_cmd_emote) {
- char *message = merge_argv(argv, 1, argc);
- putsock(client, "PRIVMSG %s :\001ACTION %s\001", argv[0], message);
-}
\ No newline at end of file
+++ /dev/null
-/* cmd_global_god.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_global.h"
-
-/*
-* argv[0] (optional) on/off
-*/
-
-CMD_BIND(global_cmd_god) {
- if(argc > 0) {
- if(!strcmp(argv[0], "0") || !stricmp(argv[0], "off") || !stricmp(argv[0], get_language_string(user, "NS_SET_OFF"))) {
- if(isGodMode(user)) {
- printf_mysql_query("UPDATE `users` SET `user_god` = '0' WHERE `user_user` = '%s'", escape_string(user->auth));
- user->flags &= ~USERFLAG_GOD_MODE;
- }
- reply(getTextBot(), user, "NS_GOD_OFF");
- } else if(!strcmp(argv[0], "1") || !stricmp(argv[0], "on") || !stricmp(argv[0], get_language_string(user, "NS_SET_ON"))) {
- if(!isGodMode(user)) {
- printf_mysql_query("UPDATE `users` SET `user_god` = '1' WHERE `user_user` = '%s'", escape_string(user->auth));
- user->flags |= USERFLAG_GOD_MODE;
- }
- reply(getTextBot(), user, "NS_GOD_ON");
- } else {
- reply(getTextBot(), user, "NS_SET_INVALID_BOOLEAN", argv[0]);
- return;
- }
- } else {
- if(isGodMode(user)) {
- printf_mysql_query("UPDATE `users` SET `user_god` = '0' WHERE `user_user` = '%s'", escape_string(user->auth));
- user->flags &= ~USERFLAG_GOD_MODE;
- reply(getTextBot(), user, "NS_GOD_OFF");
- } else {
- printf_mysql_query("UPDATE `users` SET `user_god` = '1' WHERE `user_user` = '%s'", escape_string(user->auth));
- user->flags |= USERFLAG_GOD_MODE;
- reply(getTextBot(), user, "NS_GOD_ON");
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-/* cmd_global_meminfo.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_global.h"
-#include "memoryInfo.h"
-
-/*
-* no arguments
-*/
-
-CMD_BIND(global_cmd_meminfo) {
- #ifndef ENABLE_MEMORY_DEBUG
- reply(getTextBot(), user, "NS_MEMINFO_DISABLED");
- #else
- if(argc > 0) {
- struct Table *table;
- int elementcount = 0;
- struct memoryInfoLines *element, *elements;
- elements = getMemoryInfoLines(argv[0]);
- for(element = elements; element; element = element->next) {
- elementcount++;
- }
- table = table_init(4, elementcount+2, 0);
- char *content[4];
- content[0] = get_language_string(user, "NS_MEMINFO_LINE");
- content[1] = get_language_string(user, "NS_MEMINFO_COUNT");
- content[2] = get_language_string(user, "NS_MEMINFO_SIZE");
- content[3] = get_language_string(user, "NS_MEMINFO_TOTAL");
- table_add(table, content);
- char lineBuf[20];
- char countBuf[20];
- char sizeBuf[20];
- char totalBuf[50];
- unsigned int total_allocations = 0;
- unsigned int total_allocated = 0;
- for(element = elements; element; element = element->next) {
- sprintf(lineBuf, "%u", element->line);
- content[0] = lineBuf;
- sprintf(countBuf, "%u", element->allocations);
- total_allocations += element->allocations;
- content[1] = countBuf;
- sprintf(sizeBuf, "%uB", element->allocate);
- content[2] = sizeBuf;
- sprintf(totalBuf, "%u (%.2f kB)", (element->allocate * element->allocations), ((float)(element->allocate * element->allocations) / 1024));
- total_allocated += (element->allocate * element->allocations);
- content[3] = totalBuf;
- table_add(table, content);
- }
- content[0] = "Total";
- sprintf(countBuf, "%u", total_allocations);
- content[1] = countBuf;
- content[2] = "*";
- sprintf(sizeBuf, "%u (%.2f kB)", total_allocated, ((float)total_allocated / 1024));
- content[3] = sizeBuf;
- table_add(table, content);
- char **table_lines = table_end(table);
- int i;
- for(i = 0; i < table->entrys; i++) {
- reply(getTextBot(), user, table_lines[i]);
- }
- table_free(table);
- } else {
- struct Table *table;
- int elementcount = 0;
- struct memoryInfoFiles *element, *elements;
- elements = getMemoryInfoFiles();
- for(element = elements; element; element = element->next) {
- elementcount++;
- }
- table = table_init(3, elementcount+2, 0);
- char *content[3];
- content[0] = get_language_string(user, "NS_MEMINFO_NAME");
- content[1] = get_language_string(user, "NS_MEMINFO_COUNT");
- content[2] = get_language_string(user, "NS_MEMINFO_SIZE");
- table_add(table, content);
- char countBuf[20];
- char sizeBuf[50];
- unsigned int total_allocations = 0;
- unsigned int total_allocated = 0;
- for(element = elements; element; element = element->next) {
- content[0] = element->filename;
- sprintf(countBuf, "%u", element->allocations);
- total_allocations += element->allocations;
- content[1] = countBuf;
- sprintf(sizeBuf, "%u (%.2f kB)", element->allocated, ((float)element->allocated / 1024));
- total_allocated += element->allocated;
- content[2] = sizeBuf;
- table_add(table, content);
- }
- content[0] = "Total";
- sprintf(countBuf, "%u", total_allocations);
- content[1] = countBuf;
- sprintf(sizeBuf, "%u (%.2f kB)", total_allocated, ((float)total_allocated / 1024));
- content[2] = sizeBuf;
- table_add(table, content);
- char **table_lines = table_end(table);
- int i;
- for(i = 0; i < table->entrys; i++) {
- reply(getTextBot(), user, table_lines[i]);
- }
- table_free(table);
- }
- #endif
-}
\ No newline at end of file
+++ /dev/null
-/* cmd_global_modcmd.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_global.h"
-
-/*
-* argv[0] command
-* argv[1] setting
-* argv[2] value
-*/
-
-static int global_cmd_modcmd_params(struct UserNode *user, struct cmd_binding *cbind, char *value);
-static int global_cmd_modcmd_flags(struct UserNode *user, struct cmd_binding *cbind, char *value);
-static int global_cmd_modcmd_caccess(struct UserNode *user, struct cmd_binding *cbind, char *value);
-static int global_cmd_modcmd_oaccess(struct UserNode *user, struct cmd_binding *cbind, char *value);
-
-CMD_BIND(global_cmd_modcmd) {
- MYSQL_RES *res;
- MYSQL_ROW row;
- struct cmd_binding *cbind = find_botwise_cmd_binding(client->botid, client->clientid, argv[0]);
- if (!cbind) {
- reply(getTextBot(), user, "NS_UNBIND_NOT_FOUND", argv[0]);
- return;
- }
- int uaccess = 0;
- printf_mysql_query("SELECT `user_access` FROM `users` WHERE `user_user` = '%s'", escape_string(user->auth));
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) != NULL) {
- uaccess = atoi(row[0]);
- }
- int gaccess = ((cbind->flags & CMDFLAG_OVERRIDE_GLOBAL_ACCESS) ? cbind->global_access : cbind->func->global_access);
- if(gaccess > uaccess) {
- reply(getTextBot(), user, "NS_MODCMD_OUTRANKED", cbind->cmd, gaccess);
- return;
- }
- if(argc > 1) {
- char *value;
- if(argc > 2) {
- value = merge_argv(argv, 2, argc);
- } else
- value = NULL;
- int log_event = 0;
- if(!stricmp(argv[1], "caccess")) log_event = global_cmd_modcmd_caccess(user, cbind, value);
- else if(!stricmp(argv[1], "oaccess")) log_event = global_cmd_modcmd_oaccess(user, cbind, value);
- else if(!stricmp(argv[1], "parameters")) log_event = global_cmd_modcmd_params(user, cbind, value);
- else if(!stricmp(argv[1], "flags")) log_event = global_cmd_modcmd_flags(user, cbind, value);
- else {
- reply(getTextBot(), user, "NS_MODCMD_SETTING", argv[1]);
- }
- if(log_event) {
- logEvent(event);
- }
- } else {
- reply(getTextBot(), user, "NS_MODCMD_HEADER", cbind->cmd);
- global_cmd_modcmd_params(user, cbind, NULL);
- global_cmd_modcmd_caccess(user, cbind, NULL);
- global_cmd_modcmd_oaccess(user, cbind, NULL);
- global_cmd_modcmd_flags(user, cbind, NULL);
- }
-}
-
-static int global_cmd_modcmd_params(struct UserNode *user, struct cmd_binding *cbind, char *value) {
- char parameters[MAXLEN];
- int ret = 0;
- if(cbind->paramcount) {
- int i, parampos = 0;
- for(i = 0; i < cbind->paramcount; i++) {
- parampos += sprintf(parameters + parampos, (i ? " %s" : "%s"), cbind->parameters[i]);
- }
- } else
- parameters[0] = '\0';
- if(value) {
- if(!strcmp(value, "*"))
- value = NULL;
- bind_botwise_set_parameters(cbind->botid, cbind->clientid, cbind->cmd, value);
- if(cbind->botid == 0)
- printf_mysql_query("UPDATE `bot_binds` SET `parameters` = '%s' WHERE `botclass` = '0' AND `botid` = '%d' AND `command` = '%s'", (value ? escape_string(value) : ""), cbind->clientid, escape_string(cbind->cmd));
- else
- printf_mysql_query("UPDATE `bot_binds` SET `parameters` = '%s' WHERE `botclass` = '%d' AND `command` = '%s'", (value ? escape_string(value) : ""), cbind->botid, escape_string(cbind->cmd));
- strcpy(parameters, (value ? value : ""));
- ret = 1;
- }
- reply(getTextBot(), user, "\002PARAMETERS \002 %s", parameters);
- return ret;
-}
-
-static const struct {
- const char *name;
- unsigned int flag;
-} global_cmd_modcmd_show_flags[] = {
- {"REQUIRE_CHAN", CMDFLAG_REQUIRE_CHAN}, //The command requires a valid channel (at least one bot in it)
- {"REQUIRE_AUTH", CMDFLAG_REQUIRE_AUTH}, //The command requires the user to be authenticated
- {"REQUIRE_GOD", CMDFLAG_REQUIRE_GOD}, //The command requires the user to have security override enabled
- {"REQUIRE_REGISTERED", CMDFLAG_REGISTERED_CHAN}, //The command requires the channel to be registered (database entry)
- {"CHECK_AUTH", CMDFLAG_CHECK_AUTH}, //WHO the user if no auth is known, yet
- {"CHANNEL_ARGS", CMDFLAG_CHAN_PARAM}, //don't interpret channel arguments as channel - just pass them as a string
- {"LOG", CMDFLAG_LOG},
- {"OPLOG", CMDFLAG_OPLOG},
- {"FUNCMD", CMDFLAG_FUNCMD},
- {"ESCAPED_ARGS", CMDFLAG_ESCAPE_ARGS}, //allows arguments to be escaped ("a\ b" = "a b" as one argument)
- {"NO_CROSSCHAN", CMDFLAG_NO_CROSSCHAN},
- {NULL, 0}
-};
-
-static int global_cmd_modcmd_flags(struct UserNode *user, struct cmd_binding *cbind, char *value) {
- char flags[MAXLEN];
- int flagpos = 0;
- int ret = 0;
- unsigned int visible_flags = 0;
- int i = 0;
- while(global_cmd_modcmd_show_flags[i].name) {
- if(cbind->func->flags & global_cmd_modcmd_show_flags[i].flag) {
- flagpos += sprintf(flags + flagpos, (flagpos ? " %s" : "\00314%s"), global_cmd_modcmd_show_flags[i].name);
- }
- visible_flags |= global_cmd_modcmd_show_flags[i].flag;
- i++;
- }
- if(flagpos)
- flags[flagpos++] = '\003';
- if(value) {
- int add = 1;
- unsigned int current_flag = 0;
- if(value[0] == '+') {
- value++;
- } else if(value[0] == '-') {
- add = 0;
- value++;
- }
- if(*value) {
- i = 0;
- while(global_cmd_modcmd_show_flags[i].name) {
- if(!stricmp(global_cmd_modcmd_show_flags[i].name, value)) {
- current_flag = global_cmd_modcmd_show_flags[i].flag;
- break;
- }
- i++;
- }
- }
- if(cbind->func->flags & current_flag) {
- reply(getTextBot(), user, "NS_MODCMD_STATIC_FLAG");
- return 0;
- }
- if(add)
- cbind->flags |= current_flag;
- else
- cbind->flags &= ~current_flag;
- if(cbind->botid == 0)
- printf_mysql_query("UPDATE `bot_binds` SET `flags` = '%u' WHERE `botclass` = '0' AND `botid` = '%d' AND `command` = '%s'", (cbind->flags & visible_flags), cbind->clientid, escape_string(cbind->cmd));
- else
- printf_mysql_query("UPDATE `bot_binds` SET `flags` = '%u' WHERE `botclass` = '%d' AND `command` = '%s'", (cbind->flags & visible_flags), cbind->botid, escape_string(cbind->cmd));
- ret = 1;
- }
- i = 0;
- while(global_cmd_modcmd_show_flags[i].name) {
- if(cbind->flags & global_cmd_modcmd_show_flags[i].flag) {
- flagpos += sprintf(flags + flagpos, (flagpos ? " %s" : "%s"), global_cmd_modcmd_show_flags[i].name);
- }
- i++;
- }
- flags[flagpos] = '\0';
- reply(getTextBot(), user, "\002FLAGS \002 %s", flags);
- return ret;
-}
-
-static int global_cmd_modcmd_caccess(struct UserNode *user, struct cmd_binding *cbind, char *value) {
- char caccess[MAXLEN];
- int ret = 0;
- if(value) {
- if(!strcmp(value, "*"))
- value = NULL;
- bind_botwise_set_channel_access(cbind->botid, cbind->clientid, cbind->cmd, value);
- if(cbind->botid == 0)
- printf_mysql_query("UPDATE `bot_binds` SET `chan_access` = %s%s%s WHERE `botclass` = '0' AND `botid` = '%d' AND `command` = '%s'", (value ? "'" : ""), (value ? escape_string(value) : "NULL"), (value ? "'" : ""), cbind->clientid, escape_string(cbind->cmd));
- else
- printf_mysql_query("UPDATE `bot_binds` SET `chan_access` = %s%s%s WHERE `botclass` = '%d' AND `command` = '%s'", (value ? "'" : ""), (value ? escape_string(value) : "NULL"), (value ? "'" : ""), cbind->botid, escape_string(cbind->cmd));
-
- ret = 1;
- }
- if(cbind->flags & CMDFLAG_OVERRIDE_CHANNEL_ACCESS)
- sprintf(caccess, "%s", cbind->channel_access);
- else
- sprintf(caccess, "\00314%s\003", (cbind->func->channel_access ? cbind->func->channel_access : "0"));
- reply(getTextBot(), user, "\002CACCESS \002 %s", caccess);
- return ret;
-}
-
-static int global_cmd_modcmd_oaccess(struct UserNode *user, struct cmd_binding *cbind, char *value) {
- char oaccess[MAXLEN];
- int ret = 0;
- if(value) {
- if(!strcmp(value, "*"))
- value = NULL;
- bind_botwise_set_global_access(cbind->botid, cbind->clientid, cbind->cmd, atoi(value));
- if(cbind->botid == 0)
- printf_mysql_query("UPDATE `bot_binds` SET `global_access` = %s%s%s WHERE `botclass` = '0' AND `botid` = '%d' AND `command` = '%s'", (value ? "'" : ""), (value ? escape_string(value) : "NULL"), (value ? "'" : ""), cbind->clientid, escape_string(cbind->cmd));
- else
- printf_mysql_query("UPDATE `bot_binds` SET `global_access` = %s%s%s WHERE `botclass` = '%d' AND `command` = '%s'", (value ? "'" : ""), (value ? escape_string(value) : "NULL"), (value ? "'" : ""), cbind->botid, escape_string(cbind->cmd));
-
- ret = 1;
- }
- if(cbind->flags & CMDFLAG_OVERRIDE_GLOBAL_ACCESS)
- sprintf(oaccess, "%d", cbind->global_access);
- else
- sprintf(oaccess, "\00314%d\003", (cbind->func->global_access ? cbind->func->global_access : 0));
- reply(getTextBot(), user, "\002OACCESS \002 %s", oaccess);
- return ret;
-}
-
+++ /dev/null
-/* cmd_global_motd.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_global.h"
-
-/*
-* no args
-*/
-
-CMD_BIND(global_cmd_motd) {
- FILE *f;
- f = fopen("motd.txt", "rb");
- if(!f) return;
- char line[MAXLEN];
- char *a;
- while (fgets(line, MAXLEN, f) != NULL) {
- if((a = strchr(line, '\n')))
- *a = '\0';
- reply(getTextBot(), user, "%s", line);
- }
- fclose(f);
-}
\ No newline at end of file
+++ /dev/null
-/* cmd_global_netinfo.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_global.h"
-
-/*
-* no args
-*/
-
-CMD_BIND(global_cmd_netinfo) {
- reply(getTextBot(), user, "NS_NETINFO_HEADER");
- char tmp[MAXLEN];
- struct Table *table;
- table = table_init(2, 19, 0);
- char *content[2];
-
- content[0] = get_language_string(user, "NS_NETINFO_UPTIME");
- content[1] = timeToStr(user, (time(0) - start_time), 3, tmp);
- table_add(table, content);
-
- content[0] = get_language_string(user, "NS_NETINFO_BOTS");
- struct ClientSocket *cclient;
- int bot_count = 0, connected_bot_count = 0;
- float traffic_in = 0, traffic_out = 0;
- for(cclient = getBots(0, NULL); cclient; cclient = getBots(0, cclient)) {
- bot_count++;
- if(cclient->flags & SOCKET_FLAG_READY)
- connected_bot_count++;
- traffic_in += cclient->traffic_in;
- traffic_out += cclient->traffic_out;
- }
- sprintf(tmp, "%d (%d connected)", bot_count, connected_bot_count);
- content[1] = tmp;
- table_add(table, content);
-
- content[0] = get_language_string(user, "NS_NETINFO_TRAFFIC");
- sprintf(tmp, "in: %.2f kb out: %.2f kb", traffic_in / 1024, traffic_out / 1024);
- content[1] = tmp;
- table_add(table, content);
-
- int channel_count = getChannelCount();
- float channel_memory = channel_count * sizeof(struct ChanNode);
- int channel_ban_count = getChanBanCount();
- float channel_ban_memory = channel_ban_count * sizeof(struct BanNode);
- int user_count = getUserCount();
- float user_memory = user_count * sizeof(struct UserNode);
- int chanuser_count = getChanUserCount();
- float chanuser_memory = chanuser_count * sizeof(struct ChanUser);
- float total_memory = channel_memory + channel_ban_memory + user_memory + chanuser_memory;
- content[0] = get_language_string(user, "NS_NETINFO_CACHE");
- sprintf(tmp, "%.2f kB (%.2f MB)", total_memory / 1024, total_memory / 1024 / 1024);
- content[1] = tmp;
- table_add(table, content);
- content[0] = get_language_string(user, "NS_NETINFO_CHANNEL");
- sprintf(tmp, "%d %.2f kB (%d * %u B = %.2f kB)", channel_count, channel_memory / 1024, channel_count, (unsigned int) sizeof(struct ChanNode), channel_memory / 1024);
- content[1] = tmp;
- table_add(table, content);
- content[0] = get_language_string(user, "NS_NETINFO_CHANNEL_BAN");
- sprintf(tmp, "%d %.2f kB (%d * %u B = %.2f kB)", channel_ban_count, channel_ban_memory / 1024, channel_ban_count, (unsigned int) sizeof(struct BanNode), channel_ban_memory / 1024);
- content[1] = tmp;
- table_add(table, content);
- content[0] = get_language_string(user, "NS_NETINFO_USER");
- sprintf(tmp, "%d %.2f kB (%d * %u B = %.2f kB)", user_count, user_memory / 1024, user_count, (unsigned int) sizeof(struct UserNode), user_memory / 1024);
- content[1] = tmp;
- table_add(table, content);
- content[0] = get_language_string(user, "NS_NETINFO_CHANUSER");
- sprintf(tmp, "%d %.2f kB (%d * %u B = %.2f kB)", chanuser_count, chanuser_memory / 1024, chanuser_count, (unsigned int) sizeof(struct ChanUser), chanuser_memory / 1024);
- content[1] = tmp;
- table_add(table, content);
-
- MYSQL_RES *res;
- MYSQL_ROW row;
- printf_mysql_query("SHOW TABLE STATUS");
- res = mysql_use();
- int mysql_entrys[4];
- float mysql_length[5];
- total_memory = 0;
- mysql_entrys[0] = 0; mysql_entrys[1] = 0; mysql_entrys[2] = 0; mysql_entrys[3] = 0;
- mysql_length[0] = 0; mysql_length[1] = 0; mysql_length[2] = 0; mysql_length[3] = 0; mysql_length[4] = 0;
- while ((row = mysql_fetch_row(res)) != NULL) {
- if(!stricmp(row[0], "channels")) {
- mysql_entrys[0] = atoi(row[4]);
- mysql_length[0] = atof(row[6]);
- total_memory += atof(row[6]);
- } else if(!stricmp(row[0], "bans")) {
- mysql_entrys[1] = atoi(row[4]);
- mysql_length[1] = atof(row[6]);
- total_memory += atof(row[6]);
- } else if(!stricmp(row[0], "users")) {
- mysql_entrys[2] = atoi(row[4]);
- mysql_length[2] = atof(row[6]);
- total_memory += atof(row[6]);
- } else if(!stricmp(row[0], "chanusers")) {
- mysql_entrys[3] = atoi(row[4]);
- mysql_length[3] = atof(row[6]);
- total_memory += atof(row[6]);
- } else {
- mysql_length[4] += atof(row[6]);
- total_memory += atof(row[6]);
- }
- }
-
- content[0] = get_language_string(user, "NS_NETINFO_DATABASE");
- sprintf(tmp, "%.2f kB (%.2f MB)", total_memory / 1024, total_memory / 1024 / 1024);
- content[1] = tmp;
- table_add(table, content);
-
- content[0] = get_language_string(user, "NS_NETINFO_CHANNEL");
- sprintf(tmp, "%d %.2f kB", mysql_entrys[0], mysql_length[0] / 1024);
- content[1] = tmp;
- table_add(table, content);
-
- content[0] = get_language_string(user, "NS_NETINFO_CHANNEL_BAN");
- sprintf(tmp, "%d %.2f kB", mysql_entrys[1], mysql_length[1] / 1024);
- content[1] = tmp;
- table_add(table, content);
-
- content[0] = get_language_string(user, "NS_NETINFO_USER");
- sprintf(tmp, "%d %.2f kB", mysql_entrys[2], mysql_length[2] / 1024);
- content[1] = tmp;
- table_add(table, content);
-
- content[0] = get_language_string(user, "NS_NETINFO_CHANUSER");
- sprintf(tmp, "%d %.2f kB", mysql_entrys[3], mysql_length[3] / 1024);
- content[1] = tmp;
- table_add(table, content);
-
- content[0] = get_language_string(user, "NS_NETINFO_OTHER");
- sprintf(tmp, "* %.2f kB", mysql_length[4] / 1024);
- content[1] = tmp;
- table_add(table, content);
-
- #ifdef HAVE_THREADS
- content[0] = get_language_string(user, "NS_NETINFO_THREADS");
- sprintf(tmp, "%d (current thread: %i)", running_threads, getCurrentThreadID());
- content[1] = tmp;
- table_add(table, content);
- #endif
-
- if(strcmp(revision, ""))
- sprintf(tmp, "%s.%d (%s)", NEONSERV_VERSION, patchlevel, revision);
- else
- sprintf(tmp, "%s.%d", NEONSERV_VERSION, patchlevel);
- content[0] = get_language_string(user, "NS_NETINFO_VERSION");
- content[1] = tmp;
- table_add(table, content);
-
- content[0] = get_language_string(user, "NS_NETINFO_COMPILER");
- content[1] = build_language_string(user, tmp, "NS_NETINFO_COMPILER_VALUE", COMPILER, creation);
- table_add(table, content);
-
- content[0] = get_language_string(user, "NS_NETINFO_CODE");
- content[1] = build_language_string(user, tmp, "NS_NETINFO_CODE_VALUE", codelines);
- table_add(table, content);
-
- char **table_lines = table_end(table);
- int i;
- for(i = 0; i < table->entrys; i++) {
- reply(getTextBot(), user, table_lines[i]);
- }
- table_free(table);
-}
-
+++ /dev/null
-/* cmd_global_notice.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_global.h"
-
-/*
-* argv[0] target
-* argv[1-*] message
-*/
-
-CMD_BIND(global_cmd_notice) {
- char *message = merge_argv(argv, 1, argc);
- putsock(client, "NOTICE %s :%s", argv[0], message);
-}
\ No newline at end of file
+++ /dev/null
-/* cmd_global_raw.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_global.h"
-
-/*
-* argv[0-*] raw
-*/
-
-CMD_BIND(global_cmd_raw) {
- char *raw = merge_argv(argv, 0, argc);
- putsock(client, "%s", raw);
-}
\ No newline at end of file
+++ /dev/null
-/* cmd_global_reconnect.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_global.h"
-
-/*
-* argv[0] nick/botid
-*/
-
-CMD_BIND(global_cmd_reconnect) {
- int botid;
- if(argc) {
- MYSQL_RES *res;
- MYSQL_ROW row;
- printf_mysql_query("SELECT `id` FROM `bots` WHERE `nick` = '%s' OR `id` = '%s'", escape_string(argv[0]), escape_string(argv[0]));
- res = mysql_use();
- if((row = mysql_fetch_row(res)) == NULL) {
- reply(getTextBot(), user, "NS_DELBOT_NOT_FOUND", argv[0]);
- return;
- }
- botid = atoi(row[0]);
- for(client = getBots(0, NULL); client; client = getBots(0, client)) {
- if(client->clientid == botid) {
- disconnect_socket(client);
- client->flags |= SOCKET_FLAG_FAST_JUMP;
- break;
- }
- }
- } else {
- disconnect_socket(client);
- connect_socket(client);
- }
- reply(getTextBot(), user, "NS_RECONNECT_DONE");
- logEvent(event);
-}
+++ /dev/null
-/* cmd_global_register.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_global.h"
-
-/*
-* argv[0] - channel
-* argv[1] - nick / *auth
-* argv[2] - (optional) bot nick
-*/
-static AUTHLOOKUP_CALLBACK(global_cmd_register_auth_lookup);
-static USERAUTH_CALLBACK(global_cmd_register_nick_lookup);
-static void global_cmd_register_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *channel, char *auth, int multibot, char *botname);
-
-struct global_cmd_register_cache {
- struct ClientSocket *client, *textclient;
- struct UserNode *user;
- struct ChanNode *chan;
- struct Event *event;
- char *nick;
- char *channel;
- char *botname;
- int multibot;
-};
-
-CMD_BIND(global_cmd_register) {
- MYSQL_RES *res;
- MYSQL_ROW row;
- char *channel = argv[0];
- char *botname = (argc > 2 ? argv[2] : NULL);
- int multibot = 0;
- if(!is_valid_chan(channel)) {
- reply(getTextBot(), user, "NS_INVALID_CHANNEL_NAME", argv[0]);
- return;
- }
- printf_mysql_query("SELECT `botid`, `botclass` FROM `bot_channels` LEFT JOIN `bots` ON `bot_channels`.`botid` = `bots`.`id` LEFT JOIN `channels` ON `bot_channels`.`chanid` = `channels`.`channel_id` WHERE `channel_name` = '%s'", escape_string(channel));
- res = mysql_use();
- while ((row = mysql_fetch_row(res)) != NULL) {
- if(atoi(row[1]) == client->botid && (client->botid || client->clientid == atoi(row[0]))) {
- reply(getTextBot(), user, "NS_REGISTER_ALREADY", argv[0], client->user->nick);
- return;
- } else
- multibot = 1;
- }
- printf_mysql_query("SELECT `user_user`, `dnr_timeout`, `dnr_reason`, `dnr_id` FROM `donotregister` LEFT JOIN `users` ON `dnr_user` = `user_id` WHERE `dnr_target` = '%s'", escape_string(channel));
- res = mysql_use();
- if((row = mysql_fetch_row(res)) != NULL) {
- int expire_time = atoi(row[1]);
- if(expire_time) {
- if(expire_time - time(0) <= 0) {
- printf_mysql_query("DELETE FROM `donotregister` WHERE `dnr_id` = '%s'", row[3]);
- } else {
- char expireBuf[MAXLEN];
- reply(getTextBot(), user, "NS_DNR_SET_EXPIRES", channel, row[0], timeToStr(user, (expire_time - time(0)), 2, expireBuf), row[2]);
- return;
- }
- } else {
- reply(getTextBot(), user, "NS_DNR_SET", channel, row[0], row[2]);
- return;
- }
- }
- //if theres already another bot in the channel we don't need a owner parameter...
- if(multibot && argc < 2) {
- //skip all these owner check lines
- multibot = 2;
- global_cmd_register_async1(client, getTextBot(), user, chan, event, channel, NULL, multibot, botname);
- return;
- } else if(argc < 2) {
- global_cmd_register_async1(client, getTextBot(), user, chan, event, channel, user->auth, multibot, botname);
- return;
- }
- //check own access
- if(argv[1][0] == '*') {
- //we've got an auth
- argv[1]++;
- printf_mysql_query("SELECT `user_user` FROM `users` WHERE `user_user` = '%s'", escape_string(argv[1]));
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) != NULL) {
- global_cmd_register_async1(client, getTextBot(), user, chan, event, channel, row[0], multibot, botname);
- } else {
- //we need to create a new user...
- //but first lookup the auth to check if it really exists
- struct global_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->event = event;
- cache->nick = strdup(argv[1]);
- cache->channel = strdup(channel);
- cache->multibot = multibot;
- cache->botname = (botname ? strdup(botname) : NULL);
- lookup_authname(argv[1], global_cmd_register_auth_lookup, cache);
- }
- } else {
- struct UserNode *cuser = getUserByNick(argv[1]);
- if(!cuser) {
- cuser = createTempUser(argv[1]);
- if(!cuser) {
- reply(getTextBot(), user, "NS_USER_UNKNOWN", argv[1]);
- return;
- }
- cuser->flags |= USERFLAG_ISTMPUSER;
- }
- if(cuser->flags & USERFLAG_ISAUTHED) {
- global_cmd_register_async1(client, getTextBot(), user, chan, event, channel, cuser->auth, multibot, botname);
- } else {
- struct global_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->event = event;
- cache->nick = strdup(argv[1]);
- cache->channel = strdup(channel);
- cache->multibot = multibot;
- cache->botname = (botname ? strdup(botname) : NULL);
- get_userauth(cuser, global_cmd_register_nick_lookup, cache);
- }
- }
-}
-
-static AUTHLOOKUP_CALLBACK(global_cmd_register_auth_lookup) {
- struct global_cmd_register_cache *cache = data;
- if(!exists) {
- //AUTH_DOES_NOT_EXIST
- reply(cache->textclient, cache->user, "NS_AUTH_UNKNOWN", cache->nick);
- } else
- global_cmd_register_async1(cache->client, cache->textclient, cache->user, cache->chan, cache->event, cache->channel, auth, cache->multibot, cache->botname);
- if(cache->botname)
- free(cache->botname);
- free(cache->channel);
- free(cache->nick);
- free(cache);
-}
-
-static USERAUTH_CALLBACK(global_cmd_register_nick_lookup) {
- struct global_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
- global_cmd_register_async1(cache->client, cache->textclient, cache->user, cache->chan, cache->event, cache->channel, user->auth, cache->multibot, cache->botname);
- if(cache->botname)
- free(cache->botname);
- free(cache->channel);
- free(cache->nick);
- free(cache);
-}
-
-static void global_cmd_register_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *channel, char *auth, int multibot, char *botname) {
- //we've got a valid auth now...
- MYSQL_RES *res;
- MYSQL_ROW row, row2;
- int userid = 0, adminid;
- printf_mysql_query("SELECT `user_id` FROM `users` WHERE `user_user` = '%s'", escape_string(user->auth));
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) != NULL)
- adminid = atoi(row[0]);
- else
- adminid = 0;
- if(multibot != 2) {
- printf_mysql_query("SELECT `user_user`, `dnr_timeout`, `dnr_reason`, `dnr_id` FROM `donotregister` LEFT JOIN `users` ON `dnr_user` = `user_id` WHERE `dnr_target` = '%s'", escape_string(auth));
- res = mysql_use();
- if((row = mysql_fetch_row(res)) != NULL) {
- int expire_time = atoi(row[1]);
- if(expire_time) {
- if(expire_time - time(0) <= 0) {
- printf_mysql_query("DELETE FROM `donotregister` WHERE `dnr_id` = '%s'", row[3]);
- } else {
- char expireBuf[MAXLEN];
- reply(getTextBot(), user, "NS_DNR_SET_EXPIRES", auth, row[0], timeToStr(user, (expire_time - time(0)), 2, expireBuf), row[2]);
- return;
- }
- } else {
- reply(getTextBot(), user, "NS_DNR_SET", auth, row[0], row[2]);
- return;
- }
- }
- 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(get_mysql_conn());
- }
- }
- if(client->botid)
- printf_mysql_query("SELECT `id`, `max_channels`, `defaulttrigger`, `nick` FROM `bots` WHERE `botclass` = '%d' AND `active` = '1' ORDER BY `register_priority` DESC", client->botid);
- else
- printf_mysql_query("SELECT `id`, `max_channels`, `defaulttrigger`, `nick` FROM `bots` WHERE `id` = '%d' AND `active` = '1'", client->clientid);
- res = mysql_use();
- int botid = 0;
- 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]) && (!botname || !stricmp(botname, row[3]))) {
- botid = atoi(row[0]);
- 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]);
- printf_mysql_query("UPDATE `channels` SET `channel_registered` = UNIX_TIMESTAMP(), `channel_registrator` = '%d' WHERE `channel_id` = '%d'", adminid, chanid);
- } else {
- printf_mysql_query("INSERT INTO `channels` (`channel_name`, `channel_registered`, `channel_registrator`) VALUES ('%s', UNIX_TIMESTAMP(), '%d')", escape_string(channel), adminid);
- chanid = (int) mysql_insert_id(get_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", channel);
- printf_mysql_query("INSERT INTO `bot_channels` (`botid`, `chanid`, `trigger`) VALUES ('%d', '%d', NULL)", botid, chanid);
- if(multibot != 2) {
- if(multibot) {
- printf_mysql_query("UPDATE `chanusers` SET `chanuser_access` = 499 WHERE `chanuser_cid` = '%d' AND `chanuser_access` = '500'", chanid);
- printf_mysql_query("DELETE FROM `chanusers` WHERE `chanuser_cid` = '%d' AND `chanuser_uid` = '%d'", chanid, userid);
- } else
- 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);
- } else
- reply(textclient, user, "NS_REGISTER_DONE_NOAUTH", channel);
- logEvent(event);
-}
+++ /dev/null
-/* cmd_global_reload.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_global.h"
-
-/*
-* argv[0] soft (optional)
-*/
-
-CMD_BIND(global_cmd_reload) {
- reload_config();
- reply(client, user, "reloaded.");
-}
+++ /dev/null
-/* cmd_global_reloadlang.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_global.h"
-
-/*
-* argv[0] language tag
-*/
-
-CMD_BIND(global_cmd_reloadlang) {
- MYSQL_RES *res;
- MYSQL_ROW row;
- printf_mysql_query("SELECT `text`, `lang` FROM `language` WHERE `ident` = 'name' AND `lang` = '%s'", escape_string(argv[0]));
- res = mysql_use();
- if((row = mysql_fetch_row(res)) != NULL) {
- load_language(row[1], row[0]);
- reply(getTextBot(), user, "NS_RELOADLANG_DONE", row[0], row[1]);
- } else {
- reply(getTextBot(), user, "NS_RELOADLANG_UNKNOWN", argv[0]);
- }
-}
\ No newline at end of file
+++ /dev/null
-/* cmd_global_restart.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_global.h"
-
-/*
-* argv[0] soft (optional)
-*/
-
-CMD_BIND(global_cmd_restart) {
- int hard_restart = 1;
- if(argc > 0 && !stricmp(argv[0], "soft")) hard_restart = 0;
- restart_bot(hard_restart);
-}
+++ /dev/null
-/* cmd_global_say.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_global.h"
-
-/*
-* argv[0] target
-* argv[1-*] message
-*/
-
-CMD_BIND(global_cmd_say) {
- char *message = merge_argv(argv, 1, argc);
- putsock(client, "PRIVMSG %s :%s", argv[0], message);
-}
\ No newline at end of file
+++ /dev/null
-/* cmd_global_setaccess.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_global.h"
-
-/*
-* argv[0] - nick / *auth
-* argv[1] - global access
-*/
-static AUTHLOOKUP_CALLBACK(global_cmd_setaccess_auth_lookup);
-static USERAUTH_CALLBACK(global_cmd_setaccess_nick_lookup);
-static void global_cmd_setaccess_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct Event *event, char *nick, char *auth, int access);
-
-struct global_cmd_setaccess_cache {
- struct ClientSocket *client, *textclient;
- struct UserNode *user;
- struct Event *event;
- int access;
- char *nick;
-};
-
-CMD_BIND(global_cmd_setaccess) {
- int caccess;
- MYSQL_RES *res;
- MYSQL_ROW row;
- caccess = atoi(argv[1]);
- if(caccess < 0 || caccess > 1000) {
- reply(getTextBot(), user, "NS_INVALID_ACCESS", caccess);
- return;
- }
- printf_mysql_query("SELECT `user_access` FROM `users` WHERE `user_user` = '%s'", escape_string(user->auth));
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) == NULL || atoi(row[0]) < caccess) {
- reply(getTextBot(), user, "NS_ACCESS_OUTRANKED");
- return;
- }
- 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) {
- global_cmd_setaccess_async1(client, getTextBot(), user, event, argv[0], row[0], caccess);
- } else {
- //we need to create a new user...
- //but first lookup the auth to check if it really exists
- struct global_cmd_setaccess_cache *cache = malloc(sizeof(*cache));
- if (!cache) {
- perror("malloc() failed");
- return;
- }
- cache->client = client;
- cache->textclient = getTextBot();
- cache->user = user;
- cache->event = event;
- cache->access = caccess;
- cache->nick = strdup(argv[0]);
- lookup_authname(argv[0], global_cmd_setaccess_auth_lookup, cache);
- }
- } else {
- struct UserNode *cuser = getUserByNick(argv[0]);
- if(!cuser) {
- cuser = createTempUser(argv[0]);
- if(!cuser) {
- reply(getTextBot(), user, "NS_USER_UNKNOWN", argv[0]);
- return;
- }
- cuser->flags |= USERFLAG_ISTMPUSER;
- }
- if(cuser->flags & USERFLAG_ISAUTHED) {
- global_cmd_setaccess_async1(client, getTextBot(), user, event, argv[0], cuser->auth, caccess);
- } else {
- struct global_cmd_setaccess_cache *cache = malloc(sizeof(*cache));
- if (!cache) {
- perror("malloc() failed");
- return;
- }
- cache->client = client;
- cache->textclient = getTextBot();
- cache->user = user;
- cache->event = event;
- cache->access = caccess;
- cache->nick = strdup(argv[0]);
- get_userauth(cuser, global_cmd_setaccess_nick_lookup, cache);
- }
- }
-}
-
-static AUTHLOOKUP_CALLBACK(global_cmd_setaccess_auth_lookup) {
- struct global_cmd_setaccess_cache *cache = data;
- if(!exists) {
- //AUTH_DOES_NOT_EXIST
- reply(cache->textclient, cache->user, "NS_AUTH_UNKNOWN", cache->nick);
- } else
- global_cmd_setaccess_async1(cache->client, cache->textclient, cache->user, cache->event, cache->nick, auth, cache->access);
- free(cache->nick);
- free(cache);
-}
-
-static USERAUTH_CALLBACK(global_cmd_setaccess_nick_lookup) {
- struct global_cmd_setaccess_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
- global_cmd_setaccess_async1(cache->client, cache->textclient, cache->user, cache->event, user->nick, user->auth, cache->access);
- free(cache->nick);
- free(cache);
-}
-
-static void global_cmd_setaccess_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct Event *event, char *nick, char *auth, int caccess) {
- //we've got a valid auth now...
- MYSQL_RES *res;
- MYSQL_ROW row;
- printf_mysql_query("SELECT `user_id`, `user_access` FROM `users` WHERE `user_user` = '%s'", escape_string(auth));
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) != NULL) {
- if(atoi(row[1]) != caccess)
- printf_mysql_query("UPDATE `users` SET `user_access` = '%d' WHERE `user_id` = '%s'", caccess, row[0]);
- } else {
- printf_mysql_query("INSERT INTO `users` (`user_user`, `user_access`) VALUES ('%s', '%d')", escape_string(auth), caccess);
- }
- reply(textclient, user, "NS_SETACCESS_DONE", auth, caccess);
- logEvent(event);
-}
+++ /dev/null
-/* cmd_global_setbot.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_global.h"
-
-/*
-* argv[0] botid
-* argv[1] setting
-* argv[2] value
-*/
-
-static int global_cmd_setbot_active(struct UserNode *user, MYSQL_ROW bot, char *value);
-static int global_cmd_setbot_nick(struct UserNode *user, MYSQL_ROW bot, char *value);
-static int global_cmd_setbot_ident(struct UserNode *user, MYSQL_ROW bot, char *value);
-static int global_cmd_setbot_realname(struct UserNode *user, MYSQL_ROW bot, char *value);
-static int global_cmd_setbot_server(struct UserNode *user, MYSQL_ROW bot, char *value);
-static int global_cmd_setbot_port(struct UserNode *user, MYSQL_ROW bot, char *value);
-static int global_cmd_setbot_bind(struct UserNode *user, MYSQL_ROW bot, char *value);
-static int global_cmd_setbot_ssl(struct UserNode *user, MYSQL_ROW bot, char *value);
-static int global_cmd_setbot_serverpass(struct UserNode *user, MYSQL_ROW bot, char *value);
-static int global_cmd_setbot_class(struct UserNode *user, MYSQL_ROW bot, char *value);
-static int global_cmd_setbot_queue(struct UserNode *user, MYSQL_ROW bot, char *value);
-static int global_cmd_setbot_prefered(struct UserNode *user, MYSQL_ROW bot, char *value);
-static int global_cmd_setbot_maxchan(struct UserNode *user, MYSQL_ROW bot, char *value);
-static int global_cmd_setbot_priority(struct UserNode *user, MYSQL_ROW bot, char *value);
-static int global_cmd_setbot_trigger(struct UserNode *user, MYSQL_ROW bot, char *value);
-
-CMD_BIND(global_cmd_setbot) {
- MYSQL_RES *res;
- MYSQL_ROW row;
- int botid = atoi(argv[0]);
- printf_mysql_query("SELECT `active`, `nick`, `server`, `port`, `pass`, `botclass`, `textbot`, `queue`, `defaulttrigger`, `max_channels`, `register_priority`, `bind`, `ident`, `realname`, `ssl`, `id` FROM `bots` WHERE `id` = '%d'", botid);
- res = mysql_use();
- if(!(row = mysql_fetch_row(res))) {
- reply(getTextBot(), user, "NS_SETBOT_UNKNOWN", botid);
- return;
- }
- if(argc > 1) {
- char *value;
- if(argc > 2) {
- value = merge_argv(argv, 2, argc);
- } else
- value = NULL;
- int log_event = 0;
- if(!stricmp(argv[1], "active")) log_event = global_cmd_setbot_active(user, row, value);
- else if(!stricmp(argv[1], "nick")) log_event = global_cmd_setbot_nick(user, row, value);
- else if(!stricmp(argv[1], "ident")) log_event = global_cmd_setbot_ident(user, row, value);
- else if(!stricmp(argv[1], "realname")) log_event = global_cmd_setbot_realname(user, row, value);
- else if(!stricmp(argv[1], "server")) log_event = global_cmd_setbot_server(user, row, value);
- else if(!stricmp(argv[1], "port")) log_event = global_cmd_setbot_port(user, row, value);
- else if(!stricmp(argv[1], "bind")) log_event = global_cmd_setbot_bind(user, row, value);
- else if(!stricmp(argv[1], "ssl")) log_event = global_cmd_setbot_ssl(user, row, value);
- else if(!stricmp(argv[1], "serverpass")) log_event = global_cmd_setbot_serverpass(user, row, value);
- else if(!stricmp(argv[1], "botclass")) log_event = global_cmd_setbot_class(user, row, value);
- else if(!stricmp(argv[1], "queue")) log_event = global_cmd_setbot_queue(user, row, value);
- else if(!stricmp(argv[1], "prefered")) log_event = global_cmd_setbot_prefered(user, row, value);
- else if(!stricmp(argv[1], "maxchan")) log_event = global_cmd_setbot_maxchan(user, row, value);
- else if(!stricmp(argv[1], "priority")) log_event = global_cmd_setbot_priority(user, row, value);
- else if(!stricmp(argv[1], "trigger")) log_event = global_cmd_setbot_trigger(user, row, value);
- else {
- reply(getTextBot(), user, "NS_SETBOT_SETTING", argv[1]);
- }
- if(log_event) {
- if(!stricmp(argv[1], "serverpass") && value) { //censor server password
- char cmd_args[MAXLEN];
- sprintf(cmd_args, "%d SERVERPASS ***", botid);
- free(event->arguments);
- event->arguments = strdup(cmd_args);
- }
- logEvent(event);
- }
- } else {
- reply(getTextBot(), user, "NS_SETBOT_HEADER", botid);
- global_cmd_setbot_active(user, row, NULL);
- global_cmd_setbot_nick(user, row, NULL);
- global_cmd_setbot_ident(user, row, NULL);
- global_cmd_setbot_realname(user, row, NULL);
- global_cmd_setbot_server(user, row, NULL);
- global_cmd_setbot_port(user, row, NULL);
- global_cmd_setbot_bind(user, row, NULL);
- global_cmd_setbot_ssl(user, row, NULL);
- global_cmd_setbot_serverpass(user, row, NULL);
- global_cmd_setbot_class(user, row, NULL);
- global_cmd_setbot_queue(user, row, NULL);
- global_cmd_setbot_prefered(user, row, NULL);
- global_cmd_setbot_maxchan(user, row, NULL);
- global_cmd_setbot_priority(user, row, NULL);
- global_cmd_setbot_trigger(user, row, NULL);
- }
-}
-
-static int global_cmd_setbot_active(struct UserNode *user, MYSQL_ROW bot, char *value) {
- int val = ((bot[0] && !strcmp(bot[0], "1")) ? 1 : 0);
- int ret = 0;
- if(value) {
- if(!strcmp(value, "0") || !stricmp(value, "off") || !stricmp(value, get_language_string(user, "NS_SET_OFF"))) {
- val = 0;
- } else if(!strcmp(value, "1") || !stricmp(value, "on") || !stricmp(value, get_language_string(user, "NS_SET_ON"))) {
- val = 1;
- } else {
- reply(getTextBot(), user, "NS_SET_INVALID_BOOLEAN", value);
- return 0;
- }
- if(val != ((bot[0] && !strcmp(bot[0], "1")) ? 1 : 0)) {
- if(val) {
- //add the bot
- struct ClientSocket *client;
- client = create_socket(bot[2], atoi(bot[3]), bot[11], bot[4], bot[1], bot[12], bot[13]);
- client->flags |= (strcmp(bot[6], "0") ? SOCKET_FLAG_PREFERRED : 0);
- client->flags |= (strcmp(bot[7], "0") ? SOCKET_FLAG_USE_QUEUE : 0);
- client->flags |= (strcmp(bot[14], "0") ? SOCKET_FLAG_SSL : 0);
- client->botid = atoi(bot[5]);
- client->clientid = atoi(bot[15]);
- connect_socket(client);
- if(client->botid == 0) {
- MYSQL_RES *res;
- MYSQL_ROW row;
- printf_mysql_query("SELECT `command`, `function`, `parameters`, `global_access`, `chan_access` FROM `bot_binds` WHERE `botclass` = '0' AND `botid` = '%d'", client->clientid);
- res = mysql_use();
- while ((row = mysql_fetch_row(res)) != NULL) {
- if(bind_botwise_cmd_to_command(0, client->clientid, row[0], row[1])) {
- if(row[2] && strcmp(row[2], "")) {
- bind_botwise_set_parameters(0, client->clientid, row[0], row[2]);
- }
- if(row[3]) {
- bind_botwise_set_global_access(0, client->clientid, row[0], atoi(row[3]));
- }
- if(row[4]) {
- bind_botwise_set_channel_access(0, client->clientid, row[0], row[4]);
- }
- }
- }
- bind_botwise_unbound_required_functions(0, client->clientid);
- }
- } else {
- //remove the bot
- struct ClientSocket *client;
- for(client = getBots(0, NULL); client; client = getBots(0, client)) {
- if(client->clientid == atoi(bot[15])) {
- unbind_botwise_allcmd(client->clientid);
- close_socket(client);
- break;
- }
- }
- }
- printf_mysql_query("UPDATE `bots` SET `active` = '%d' WHERE `id` = '%s'", val, bot[15]);
- ret = 1;
- }
- }
- reply(getTextBot(), user, "\002ACTIVE \002 %s", get_language_string(user, (val ? "NS_SET_ON" : "NS_SET_OFF")));
- return ret;
-}
-
-static int global_cmd_setbot_nick(struct UserNode *user, MYSQL_ROW bot, char *value) {
- char *val = bot[1];
- int ret = 0;
- if(value) {
- if(!is_valid_nick(value)) {
- reply(getTextBot(), user, "NS_SETBOT_NICK_INVALID", value);
- return 0;
- }
- //rename the bot
- struct ClientSocket *client;
- for(client = getBots(0, NULL); client; client = getBots(0, client)) {
- if(client->clientid == atoi(bot[15])) {
- if(client->nick)
- free(client->nick);
- client->nick = strdup(value);
- if(client->flags & SOCKET_FLAG_READY)
- putsock(client, "NICK %s", value);
- break;
- }
- }
- printf_mysql_query("UPDATE `bots` SET `nick` = '%s' WHERE `id` = '%s'", escape_string(value), bot[15]);
- val = value;
- ret = 1;
- }
- reply(getTextBot(), user, "\002NICK \002 %s", val);
- return ret;
-}
-
-static int global_cmd_setbot_ident(struct UserNode *user, MYSQL_ROW bot, char *value) {
- char *val = bot[12];
- int ret = 0;
- if(value) {
- if(strlen(value) > 12)
- value[12] = '\0';
- //rename the bot
- struct ClientSocket *client;
- for(client = getBots(0, NULL); client; client = getBots(0, client)) {
- if(client->clientid == atoi(bot[15])) {
- if(client->ident)
- free(client->ident);
- client->ident = strdup(value);
- break;
- }
- }
- printf_mysql_query("UPDATE `bots` SET `ident` = '%s' WHERE `id` = '%s'", escape_string(value), bot[15]);
- val = value;
- ret = 1;
- }
- reply(getTextBot(), user, "\002IDENT \002 %s", val);
- return ret;
-}
-
-static int global_cmd_setbot_realname(struct UserNode *user, MYSQL_ROW bot, char *value) {
- char *val = bot[13];
- int ret = 0;
- if(value) {
- if(strlen(value) > 255)
- value[255] = '\0';
- //rename the bot
- struct ClientSocket *client;
- for(client = getBots(0, NULL); client; client = getBots(0, client)) {
- if(client->clientid == atoi(bot[15])) {
- if(client->ident)
- free(client->ident);
- client->ident = strdup(value);
- break;
- }
- }
- printf_mysql_query("UPDATE `bots` SET `realname` = '%s' WHERE `id` = '%s'", escape_string(value), bot[15]);
- val = value;
- ret = 1;
- }
- reply(getTextBot(), user, "\002REALNAME \002 %s", val);
- return ret;
-}
-
-static int global_cmd_setbot_server(struct UserNode *user, MYSQL_ROW bot, char *value) {
- char *val = bot[2];
- int ret = 0;
- if(value) {
- struct ClientSocket *client;
- for(client = getBots(0, NULL); client; client = getBots(0, client)) {
- if(client->clientid == atoi(bot[15])) {
- if(client->host)
- free(client->host);
- client->host = strdup(value);
- if(client->flags & SOCKET_FLAG_READY)
- reply(getTextBot(), user, "NS_SETBOT_NEED_RESTART");
- break;
- }
- }
- printf_mysql_query("UPDATE `bots` SET `server` = '%s' WHERE `id` = '%s'", escape_string(value), bot[15]);
- val = value;
- ret = 1;
- }
- reply(getTextBot(), user, "\002SERVER \002 %s", val);
- return ret;
-}
-
-static int global_cmd_setbot_port(struct UserNode *user, MYSQL_ROW bot, char *value) {
- int val = atoi(bot[3]);
- int ret = 0;
- if(value) {
- val = atoi(value);
- if(val <= 0 || val > 65534) {
- reply(getTextBot(), user, "NS_SETBOT_PORT_INVALID", value);
- return 0;
- }
- struct ClientSocket *client;
- for(client = getBots(0, NULL); client; client = getBots(0, client)) {
- if(client->clientid == atoi(bot[15])) {
- client->port = val;
- if(client->flags & SOCKET_FLAG_READY)
- reply(getTextBot(), user, "NS_SETBOT_NEED_RESTART");
- break;
- }
- }
- printf_mysql_query("UPDATE `bots` SET `port` = '%d' WHERE `id` = '%s'", val, bot[15]);
- ret = 1;
- }
- reply(getTextBot(), user, "\002PORT \002 %d", val);
- return ret;
-}
-
-static int global_cmd_setbot_bind(struct UserNode *user, MYSQL_ROW bot, char *value) {
- char *val = bot[11];
- int ret = 0;
- if(value) {
- if(!strcmp(value, "*"))
- value = NULL;
- struct ClientSocket *client;
- for(client = getBots(0, NULL); client; client = getBots(0, client)) {
- if(client->clientid == atoi(bot[15])) {
- if(client->bind)
- free(client->bind);
- client->bind = (value ? strdup(value) : NULL);
- if(client->flags & SOCKET_FLAG_READY)
- reply(getTextBot(), user, "NS_SETBOT_NEED_RESTART");
- break;
- }
- }
- if(value)
- printf_mysql_query("UPDATE `bots` SET `bind` = '%s' WHERE `id` = '%s'", escape_string(value), bot[15]);
- else
- printf_mysql_query("UPDATE `bots` SET `bind` = NULL WHERE `id` = '%s'", bot[15]);
- val = value;
- ret = 1;
- }
- reply(getTextBot(), user, "\002BIND \002 %s", val);
- return ret;
-}
-
-static int global_cmd_setbot_ssl(struct UserNode *user, MYSQL_ROW bot, char *value) {
- int val = (strcmp(bot[14], "0") ? 1 : 0);
- int ret = 0;
- if(value) {
- if(!strcmp(value, "0") || !stricmp(value, "off") || !stricmp(value, get_language_string(user, "NS_SET_OFF"))) {
- val = 0;
- } else if(!strcmp(value, "1") || !stricmp(value, "on") || !stricmp(value, get_language_string(user, "NS_SET_ON"))) {
- val = 1;
- } else {
- reply(getTextBot(), user, "NS_SET_INVALID_BOOLEAN", value);
- return 0;
- }
- struct ClientSocket *client;
- for(client = getBots(0, NULL); client; client = getBots(0, client)) {
- if(client->clientid == atoi(bot[15])) {
- if(val)
- client->flags |= SOCKET_FLAG_SSL;
- else
- client->flags &= ~SOCKET_FLAG_SSL;
- if(client->flags & SOCKET_FLAG_READY)
- reply(getTextBot(), user, "NS_SETBOT_NEED_RESTART");
- break;
- }
- }
- printf_mysql_query("UPDATE `bots` SET `ssl` = '%d' WHERE `id` = '%s'", val, bot[15]);
- ret = 1;
- }
- reply(getTextBot(), user, "\002SSL \002 %s", get_language_string(user, (val ? "NS_SET_ON" : "NS_SET_OFF")));
- return ret;
-}
-
-static int global_cmd_setbot_serverpass(struct UserNode *user, MYSQL_ROW bot, char *value) {
- char *val = bot[4];
- int ret = 0;
- if(value) {
- if(!strcmp(value, "*"))
- value = "";
- struct ClientSocket *client;
- for(client = getBots(0, NULL); client; client = getBots(0, client)) {
- if(client->clientid == atoi(bot[15])) {
- if(client->pass)
- free(client->pass);
- client->pass = (value ? strdup(value) : NULL);
- if(client->flags & SOCKET_FLAG_READY)
- reply(getTextBot(), user, "NS_SETBOT_NEED_RESTART");
- break;
- }
- }
- printf_mysql_query("UPDATE `bots` SET `pass` = '%s' WHERE `id` = '%s'", escape_string(value), bot[15]);
- val = value;
- ret = 1;
- }
- reply(getTextBot(), user, "\002SERVERPASS \002 %s", val);
- return ret;
-}
-
-static int global_cmd_setbot_class(struct UserNode *user, MYSQL_ROW bot, char *value) {
- int val = atoi(bot[5]);
- int ret = 0;
- if(value) {
- if((val = resolve_botalias(value)) == -1) {
- reply(getTextBot(), user, "NS_SETBOT_INVALID_CLASS", value);
- return 0;
- }
- if(val != atoi(bot[5])) {
- struct ClientSocket *client;
- for(client = getBots(0, NULL); client; client = getBots(0, client)) {
- if(client->clientid == atoi(bot[15])) {
- unbind_botwise_allcmd(client->clientid);
- client->botid = val;
- if(client->botid == 0) {
- MYSQL_RES *res;
- MYSQL_ROW row;
- printf_mysql_query("SELECT `command`, `function`, `parameters`, `global_access`, `chan_access` FROM `bot_binds` WHERE `botclass` = '0' AND `botid` = '%d'", client->clientid);
- res = mysql_use();
- while ((row = mysql_fetch_row(res)) != NULL) {
- if(bind_botwise_cmd_to_command(client->botid, client->clientid, row[0], row[1])) {
- if(row[2] && strcmp(row[2], "")) {
- bind_botwise_set_parameters(client->botid, client->clientid, row[0], row[2]);
- }
- if(row[3]) {
- bind_botwise_set_global_access(client->botid, client->clientid, row[0], atoi(row[3]));
- }
- if(row[4]) {
- bind_botwise_set_channel_access(client->botid, client->clientid, row[0], row[4]);
- }
- }
- }
- bind_botwise_unbound_required_functions(client->botid, client->clientid);
- }
- break;
- }
- }
- printf_mysql_query("UPDATE `bots` SET `botclass` = '%d' WHERE `id` = '%s'", val, bot[15]);
- ret = 1;
- }
- }
- reply(getTextBot(), user, "\002BOTCLASS \002 %s", resolve_botid(val));
- return ret;
-}
-
-static int global_cmd_setbot_queue(struct UserNode *user, MYSQL_ROW bot, char *value) {
- int val = (strcmp(bot[7], "0") ? 1 : 0);
- int ret = 0;
- if(value) {
- if(!strcmp(value, "0") || !stricmp(value, "off") || !stricmp(value, get_language_string(user, "NS_SET_OFF"))) {
- val = 0;
- } else if(!strcmp(value, "1") || !stricmp(value, "on") || !stricmp(value, get_language_string(user, "NS_SET_ON"))) {
- val = 1;
- } else {
- reply(getTextBot(), user, "NS_SET_INVALID_BOOLEAN", value);
- return 0;
- }
- struct ClientSocket *client;
- for(client = getBots(0, NULL); client; client = getBots(0, client)) {
- if(client->clientid == atoi(bot[15])) {
- if(val)
- client->flags |= SOCKET_FLAG_USE_QUEUE;
- else
- client->flags &= ~SOCKET_FLAG_USE_QUEUE;
- break;
- }
- }
- printf_mysql_query("UPDATE `bots` SET `queue` = '%d' WHERE `id` = '%s'", val, bot[15]);
- ret = 1;
- }
- reply(getTextBot(), user, "\002QUEUE \002 %s", get_language_string(user, (val ? "NS_SET_ON" : "NS_SET_OFF")));
- return ret;
-}
-
-static int global_cmd_setbot_prefered(struct UserNode *user, MYSQL_ROW bot, char *value) {
- int val = (strcmp(bot[6], "0") ? 1 : 0);
- int ret = 0;
- if(value) {
- if(!strcmp(value, "0") || !stricmp(value, "off") || !stricmp(value, get_language_string(user, "NS_SET_OFF"))) {
- val = 0;
- } else if(!strcmp(value, "1") || !stricmp(value, "on") || !stricmp(value, get_language_string(user, "NS_SET_ON"))) {
- val = 1;
- } else {
- reply(getTextBot(), user, "NS_SET_INVALID_BOOLEAN", value);
- return 0;
- }
- struct ClientSocket *client;
- for(client = getBots(0, NULL); client; client = getBots(0, client)) {
- if(client->clientid == atoi(bot[15])) {
- if(val)
- client->flags |= SOCKET_FLAG_PREFERRED;
- else
- client->flags &= ~SOCKET_FLAG_PREFERRED;
- break;
- }
- }
- printf_mysql_query("UPDATE `bots` SET `prefered` = '%d' WHERE `id` = '%s'", val, bot[15]);
- ret = 1;
- }
- reply(getTextBot(), user, "\002PREFERED \002 %s", get_language_string(user, (val ? "NS_SET_ON" : "NS_SET_OFF")));
- return ret;
-}
-
-static int global_cmd_setbot_maxchan(struct UserNode *user, MYSQL_ROW bot, char *value) {
- int val = atoi(bot[9]);
- int ret = 0;
- if(value) {
- val = atoi(value);
- if(val < 0 || val > 99999) {
- reply(getTextBot(), user, "NS_SETBOT_MAXCHAN_INVALID", value);
- return 0;
- }
- printf_mysql_query("UPDATE `bots` SET `max_channels` = '%d' WHERE `id` = '%s'", val, bot[15]);
- ret = 1;
- }
- reply(getTextBot(), user, "\002MAXCHAN \002 %d", val);
- return ret;
-}
-
-static int global_cmd_setbot_priority(struct UserNode *user, MYSQL_ROW bot, char *value) {
- int val = atoi(bot[10]);
- int ret = 0;
- if(value) {
- val = atoi(value);
- if(val < 0 || val > 99) {
- reply(getTextBot(), user, "NS_SETBOT_PRIORITY_INVALID", value);
- return 0;
- }
- printf_mysql_query("UPDATE `bots` SET `register_priority` = '%d' WHERE `id` = '%s'", val, bot[15]);
- ret = 1;
- }
- reply(getTextBot(), user, "\002PRIORITY \002 %d", val);
- return ret;
-}
-
-static int global_cmd_setbot_trigger(struct UserNode *user, MYSQL_ROW bot, char *value) {
- char *val = bot[8];
- int ret = 0;
- if(value) {
- if(!*value || strlen(value) > 10) {
- reply(getTextBot(), user, "NS_SETBOT_TRIGGER_INVALID", value);
- return 0;
- }
- printf_mysql_query("UPDATE `bots` SET `defaulttrigger` = '%s' WHERE `id` = '%s'", escape_string(value), bot[15]);
- flush_trigger_cache(atoi(bot[5]), atoi(bot[15]));
- reply(getTextBot(), user, "NS_SETBOT_TRIGGER_NOTE");
- val = value;
- ret = 1;
- }
- reply(getTextBot(), user, "\002TRIGGER \002 %s", val);
- return ret;
-}
+++ /dev/null
-/* cmd_global_staff.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_global.h"
-
-/*
-* no arguments
-*/
-
-CMD_BIND(global_cmd_staff) {
- MYSQL_RES *res, *res2;
- MYSQL_ROW row, row2;
- printf_mysql_query("SELECT `rank_id`, `rank_name` FROM `support_ranks` ORDER BY `rank_order` ASC");
- res = mysql_use();
- while ((row = mysql_fetch_row(res)) != NULL) {
- printf_mysql_query("SELECT `user_user`, `user_god` FROM `users` WHERE `user_rank` = '%s'", row[0]);
- res2 = mysql_use();
- if(mysql_num_rows(res2)) {
- reply(getTextBot(), user, "\002%s\002", row[1]);
- while ((row2 = mysql_fetch_row(res2)) != NULL) {
- if(strcmp(row2[1], "0")) {
- //god enabled - show nicks
- char loggedinBuf[MAXLEN];
- int loggedinPos = 0;
- struct UserNode *cuser;
- for(cuser = getUsersWithAuth(row2[0], NULL); cuser; cuser = getUsersWithAuth(row2[0], cuser)) {
- loggedinPos += sprintf(loggedinBuf+loggedinPos, (loggedinPos ? ", %s" : "%s"), cuser->nick);
- }
- if(loggedinPos)
- reply(getTextBot(), user, " %s (%s: %s)", row2[0], get_language_string(user, "NS_STAFF_LOGGEDIN"), loggedinBuf);
- else
- reply(getTextBot(), user, " %s", row2[0]);
- } else
- reply(getTextBot(), user, " %s", row2[0]);
- }
- }
- }
-}
+++ /dev/null
-/* cmd_global_unbind.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_global.h"
-
-/*
-* argv[0] command name
-*/
-
-CMD_BIND(global_cmd_unbind) {
- MYSQL_RES *res;
- MYSQL_ROW row;
- struct cmd_binding *cbind = find_botwise_cmd_binding(client->botid, client->clientid, argv[0]);
- if(client->botid == 0)
- printf_mysql_query("SELECT `id`, `function` FROM `bot_binds` WHERE `botclass` = '0' AND `botid` = '%d' AND `command` = '%s'", client->clientid, escape_string(argv[0]));
- else
- printf_mysql_query("SELECT `id`, `function` FROM `bot_binds` WHERE `botclass` = '%d' AND `command` = '%s'", client->botid, escape_string(argv[0]));
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) == NULL && (!cbind || !(cbind->flags & CMDFLAG_TEMPONARY_BIND))) {
- reply(getTextBot(), user, "NS_UNBIND_NOT_FOUND", argv[0]);
- return;
- }
- struct cmd_function *function = find_cmd_function(client->botid, cbind->func->name);
- if(function && (function->flags & CMDFLAG_REQUIRED)) {
- if(client->botid == 0)
- printf_mysql_query("SELECT `id` FROM `bot_binds` WHERE `botclass` = '0' AND `botid` = '%d' AND `function` = '%s'", client->clientid, escape_string(function->name));
- else
- printf_mysql_query("SELECT `id` FROM `bot_binds` WHERE `botclass` = '%d' AND `function` = '%s'", client->botid, escape_string(function->name));
- res = mysql_use();
- if (mysql_num_rows(res) <= 1) {
- reply(getTextBot(), user, "NS_UNBIND_REQUIRED", function->name);
- return;
- }
- }
- unbind_botwise_cmd(client->botid, client->clientid, argv[0]);
- if(!cbind || !(cbind->flags & CMDFLAG_TEMPONARY_BIND))
- printf_mysql_query("DELETE FROM `bot_binds` WHERE `id` = '%s'", row[0]);
- reply(getTextBot(), user, "NS_UNBIND_DONE", argv[0]);
- logEvent(event);
-}
+++ /dev/null
-/* cmd_global_unregister.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_global.h"
-
-/*
-* argv[0] - channel
-*/
-CMD_BIND(global_cmd_unregister) {
- MYSQL_RES *res;
- MYSQL_ROW row;
- char *channel;
- if(argc)
- channel = argv[0];
- else
- channel = (chan ? chan->name : "");
- if(!is_valid_chan(channel)) {
- reply(getTextBot(), user, "NS_INVALID_CHANNEL_NAME", argv[0]);
- 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 {
- reply(getTextBot(), user, "NS_UNREGISTER_NOT_REGISTERED", argv[0], client->user->nick);
- return;
- }
- if(client->botid == 0)
- printf_mysql_query("SELECT `botid`, `bot_channels`.`id`, `suspended` FROM `bot_channels` LEFT JOIN `bots` ON `bot_channels`.`botid` = `bots`.`id` WHERE `chanid` = '%d' AND `botclass` = '0' AND `botid` = '%d'", chanid, client->clientid);
- else
- printf_mysql_query("SELECT `botid`, `bot_channels`.`id`, `suspended` FROM `bot_channels` LEFT JOIN `bots` ON `bot_channels`.`botid` = `bots`.`id` WHERE `chanid` = '%d' AND `botclass` = '%d'", chanid, client->botid);
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) == NULL) {
- reply(getTextBot(), user, "NS_UNREGISTER_NOT_REGISTERED", argv[0], client->user->nick);
- return;
- }
- int botid = atoi(row[0]);
- struct ClientSocket *bot;
- for(bot = getBots(SOCKET_FLAG_READY, NULL); bot; bot = getBots(SOCKET_FLAG_READY, bot)) {
- if(bot->clientid == botid)
- break;
- }
- printf_mysql_query("DELETE FROM `bot_channels` WHERE `id` = '%s'", row[1]);
- reply(getTextBot(), user, "NS_UNREGISTER_DONE", channel);
- if(bot && strcmp(row[2], "1")) {
- putsock(bot, "PART %s :Channel unregistered.", channel);
- }
- logEvent(event);
-}
+++ /dev/null
-/* cmd_global_version.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_global.h"
-
-/*
-* no args
-*/
-
-CMD_BIND(global_cmd_version) {
- reply(getTextBot(), user, "\002NeonServ %s.%d\002 (%s), written by pk910", NEONSERV_VERSION, patchlevel, (strcmp(revision, "") ? revision : "-"));
- reply(getTextBot(), user, "Build (#%s) %s (%s lines, " COMPILER ")", compilation, creation, codelines);
- reply(getTextBot(), user, "NeonServ can be found on: http://dev.pk910.de/NeonServ");
- //helpers :D
- reply(getTextBot(), user, "special thanks to:");
- reply(getTextBot(), user, " Zer0n, TeaTow, Phil (testing and ideas current version)");
- reply(getTextBot(), user, " Buschman, Zer0n, Neon (translating current version)");
- reply(getTextBot(), user, " Patschi95, DerGrinch, Darkfly, Zer0n, Buschman (testing and ideas older versions)");
- reply(getTextBot(), user, " Buschman, Georg, richard (translating older versions)");
- reply(getTextBot(), user, "and all the other users that reported all these nasty bugs :D");
- reply(getTextBot(), user, "\002If you found a bug or if you have a good idea report it on http://dev.pk910.de/BugTrack\002");
-
-}
\ No newline at end of file
+++ /dev/null
-/* cmd_neonhelp.h - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-#ifndef _cmd_neonhelp_h
-#define _cmd_neonhelp_h
-#include "main.h"
-#include "modcmd.h"
-#include "mysqlConn.h"
-#include "ClientSocket.h"
-#include "UserNode.h"
-#include "ChanNode.h"
-#include "ChanUser.h"
-#include "DBHelper.h"
-#include "IRCParser.h"
-#include "bot_NeonHelp.h"
-#include "lang.h"
-#include "tools.h"
-
-CMD_BIND(neonhelp_cmd_delete);
-CMD_BIND(neonhelp_cmd_next);
-CMD_BIND(neonhelp_cmd_requests);
-CMD_BIND(neonhelp_cmd_stats);
-
-#endif
\ No newline at end of file
+++ /dev/null
-/* cmd_neonhelp_delete.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonhelp.h"
-
-/*
-* argv[0] suppid
-*/
-
-CMD_BIND(neonhelp_cmd_delete) {
- //check permissions
- MYSQL_RES *res;
- MYSQL_ROW row, row2;
- int caccess = 0;
- printf_mysql_query("SELECT `helpserv_support`, `helpserv_public`, `helpserv_intern` FROM `helpserv_settings` WHERE `helpserv_botid` = '%d'", client->clientid);
- res = mysql_use();
- if (!(row = mysql_fetch_row(res))) return;
- //check if the user is a supporter (access in the support channel)
- if((user->flags & USERFLAG_ISAUTHED)) {
- int userid;
- if(user->flags & USERFLAG_HAS_USERID)
- userid = user->user_id;
- else {
- printf_mysql_query("SELECT `user_id` FROM `users` WHERE `user_user` = '%s'", escape_string(user->auth));
- res = mysql_use();
- if ((row2 = mysql_fetch_row(res)) != NULL) {
- userid = atoi(row2[0]);
- user->user_id = userid;
- user->flags |= USERFLAG_HAS_USERID;
- } else
- userid = 0;
- }
- printf_mysql_query("SELECT `chanuser_access`, `chanuser_flags` FROM `chanusers` LEFT JOIN `channels` ON `chanuser_cid` = `channel_id` WHERE `chanuser_uid` = '%d' AND `channel_name` = '%s'", userid, escape_string(row[0]));
- res = mysql_use();
- if ((row2 = mysql_fetch_row(res)) != NULL) {
- int cflags = atoi(row2[1]);
- if(!(cflags & DB_CHANUSER_SUSPENDED))
- caccess = atoi(row2[0]);
- }
- }
- if(!caccess) {
- reply(getTextBot(), user, "MODCMD_ACCESS_DENIED");
- return;
- }
- if(!(client->flags & SOCKET_HAVE_HELPNODE) || client->botclass_helpnode == NULL) {
- reply(getTextBot(), user, "NH_NEXT_NONE");
- return;
- }
- struct NeonHelpNode *helpnode, *next_helpnode = NULL, *prev_helpnode = NULL;
- for(helpnode = client->botclass_helpnode; helpnode; helpnode = helpnode->next) {
- if(atoi(argv[0]) == helpnode->suppid) {
- next_helpnode = helpnode;
- break;
- } else
- prev_helpnode = helpnode;
- }
- if(!next_helpnode) {
- reply(getTextBot(), user, "NH_NEXT_NOT_FOUND");
- return;
- }
- reply(client, next_helpnode->user, "NH_DELETED", next_helpnode->suppid);
- printf_mysql_query("UPDATE `helpserv_requests` SET `status` = '2' WHERE `id` = '%d'", next_helpnode->suppid);
- if(prev_helpnode)
- prev_helpnode->next = next_helpnode->next;
- else
- client->botclass_helpnode = next_helpnode->next;
- reply(getTextBot(), user, "NH_DELETED_STAFF", next_helpnode->suppid, next_helpnode->user->nick);
- free(next_helpnode);
-}
+++ /dev/null
-/* cmd_neonhelp_next.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonhelp.h"
-
-/*
-* argv[0] (optional) suppid
-*/
-
-CMD_BIND(neonhelp_cmd_next) {
- //check permissions
- MYSQL_RES *res;
- MYSQL_ROW row, row2;
- int caccess = 0;
- int userid;
- printf_mysql_query("SELECT `helpserv_support`, `helpserv_public`, `helpserv_intern` FROM `helpserv_settings` WHERE `helpserv_botid` = '%d'", client->clientid);
- res = mysql_use();
- if (!(row = mysql_fetch_row(res))) return;
- //check if the user is a supporter (access in the support channel)
- if((user->flags & USERFLAG_ISAUTHED)) {
- if(user->flags & USERFLAG_HAS_USERID)
- userid = user->user_id;
- else {
- printf_mysql_query("SELECT `user_id` FROM `users` WHERE `user_user` = '%s'", escape_string(user->auth));
- res = mysql_use();
- if ((row2 = mysql_fetch_row(res)) != NULL) {
- userid = atoi(row2[0]);
- user->user_id = userid;
- user->flags |= USERFLAG_HAS_USERID;
- } else
- userid = 0;
- }
- printf_mysql_query("SELECT `chanuser_access`, `chanuser_flags` FROM `chanusers` LEFT JOIN `channels` ON `chanuser_cid` = `channel_id` WHERE `chanuser_uid` = '%d' AND `channel_name` = '%s'", userid, escape_string(row[0]));
- res = mysql_use();
- if ((row2 = mysql_fetch_row(res)) != NULL) {
- int cflags = atoi(row2[1]);
- if(!(cflags & DB_CHANUSER_SUSPENDED))
- caccess = atoi(row2[0]);
- }
- }
- if(!caccess) {
- reply(getTextBot(), user, "MODCMD_ACCESS_DENIED");
- return;
- }
- if(!(client->flags & SOCKET_HAVE_HELPNODE) || client->botclass_helpnode == NULL) {
- reply(getTextBot(), user, "NH_NEXT_NONE");
- return;
- }
- struct NeonHelpNode *helpnode, *next_helpnode = NULL;
- int lowest_id = -1;
- for(helpnode = client->botclass_helpnode; helpnode; helpnode = helpnode->next) {
- if(helpnode->status == 0) {
- if(argc) {
- if(atoi(argv[0]) == helpnode->suppid) {
- next_helpnode = helpnode;
- break;
- }
- } else {
- if(helpnode->suppid < lowest_id || lowest_id == -1) {
- lowest_id = helpnode->suppid;
- next_helpnode = helpnode;
- }
- }
- }
- }
- if(!next_helpnode) {
- reply(getTextBot(), user, "NH_NEXT_NOT_FOUND");
- return;
- }
- printf_mysql_query("SELECT `text` FROM `helpserv_requests` WHERE `id` = '%d'", next_helpnode->suppid);
- res = mysql_use();
- if (!(row2 = mysql_fetch_row(res))) return;
- reply(getTextBot(), user, "NH_NEXT_HEADER", next_helpnode->suppid, next_helpnode->user->nick);
- char *a, *b = row2[0];
- do {
- a = strstr(b, "\n");
- if(a) *a = '\0';
- reply(getTextBot(), user, " %s", b);
- if(a) {
- *a = '\n';
- b = a+1;
- }
- } while(a);
- if(row[1])
- putsock(client, "INVITE %s %s", next_helpnode->user->nick, row[0]);
- else
- putsock(client, "MODE %s +v %s", row[0], next_helpnode->user->nick);
- char sendbuf1[MAXLEN];
- char sendbuf2[MAXLEN];
- char *join_now = (row[1] ? build_language_string(user, sendbuf2, "NH_NEXT_JOIN", row[0]) : "");
- putsock(client, "PRIVMSG %s :%s %s", next_helpnode->user->nick, build_language_string(user, sendbuf1, "NH_NEXT_HELPER", next_helpnode->suppid, user->auth, user->nick), join_now);
- next_helpnode->status = 1;
- printf_mysql_query("UPDATE `helpserv_requests` SET `status` = '1', `supporter` = '%d' WHERE `id` = '%d'", userid, next_helpnode->suppid);
-}
+++ /dev/null
-/* cmd_neonhelp_requests.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonhelp.h"
-
-/*
-* no args
-*/
-
-CMD_BIND(neonhelp_cmd_requests) {
- //check permissions
- MYSQL_RES *res;
- MYSQL_ROW row, row2;
- int caccess = 0;
- int userid;
- printf_mysql_query("SELECT `helpserv_support`, `helpserv_public`, `helpserv_intern` FROM `helpserv_settings` WHERE `helpserv_botid` = '%d'", client->clientid);
- res = mysql_use();
- if (!(row = mysql_fetch_row(res))) return;
- //check if the user is a supporter (access in the support channel)
- if((user->flags & USERFLAG_ISAUTHED)) {
- if(user->flags & USERFLAG_HAS_USERID)
- userid = user->user_id;
- else {
- printf_mysql_query("SELECT `user_id` FROM `users` WHERE `user_user` = '%s'", escape_string(user->auth));
- res = mysql_use();
- if ((row2 = mysql_fetch_row(res)) != NULL) {
- userid = atoi(row2[0]);
- user->user_id = userid;
- user->flags |= USERFLAG_HAS_USERID;
- } else
- userid = 0;
- }
- printf_mysql_query("SELECT `chanuser_access`, `chanuser_flags` FROM `chanusers` LEFT JOIN `channels` ON `chanuser_cid` = `channel_id` WHERE `chanuser_uid` = '%d' AND `channel_name` = '%s'", userid, escape_string(row[0]));
- res = mysql_use();
- if ((row2 = mysql_fetch_row(res)) != NULL) {
- int cflags = atoi(row2[1]);
- if(!(cflags & DB_CHANUSER_SUSPENDED))
- caccess = atoi(row2[0]);
- }
- }
- if(!caccess) {
- reply(getTextBot(), user, "MODCMD_ACCESS_DENIED");
- return;
- }
- struct Table *table;
- printf_mysql_query("SELECT `id`, `time`, `text` FROM `helpserv_requests` WHERE `botid` = '%d' AND `status` != 2 ORDER BY `time` DESC", client->clientid);
- res = mysql_use();
- table = table_init(5, mysql_num_rows(res) + 1, 0);
- char *content[5];
- content[0] = get_language_string(user, "NH_REQUESTS_HEADER_ID");
- content[1] = get_language_string(user, "NH_REQUESTS_HEADER_STATUS");
- content[2] = get_language_string(user, "NH_REQUESTS_HEADER_NICK");
- content[3] = get_language_string(user, "NH_REQUESTS_HEADER_TIME");
- content[4] = get_language_string(user, "NH_REQUESTS_HEADER_REQUEST");
- table_add(table, content);
- char timestr[MAXLEN];
- struct NeonHelpNode *helpnode;
- int suppid;
- while ((row = mysql_fetch_row(res)) != NULL) {
- content[0] = row[0];
- suppid = atoi(row[0]);
- if(client->flags & SOCKET_HAVE_HELPNODE) {
- for(helpnode = client->botclass_helpnode; helpnode; helpnode = helpnode->next) {
- if(helpnode->suppid == suppid) {
- if(helpnode->status)
- content[1] = get_language_string(user, "NH_REQUESTS_STATE_ACTIVE");
- else
- content[1] = get_language_string(user, "NH_REQUESTS_STATE_PENDING");
- content[2] = helpnode->user->nick;
- break;
- }
- }
- } else {
- content[1] = get_language_string(user, "NH_REQUESTS_STATE_ERROR");
- content[2] = NULL;
- }
- timeToStr(user, (time(0) - atoi(row[1])), 2, timestr);
- content[3] = timestr;
- char *p;
- if((p = strstr(row[2], "\n")))
- *p = '\0';
- content[4] = row[2];
- table_add(table, content);
- }
- //send the table
- char **table_lines = table_end(table);
- int i;
- for(i = 0; i < table->entrys; i++) {
- reply(getTextBot(), user, table_lines[i]);
- }
- if(table->entrys == 1)
- reply(getTextBot(), user, "NS_TABLE_NONE");
- table_free(table);
-}
+++ /dev/null
-/* cmd_neonhelp_stats.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonhelp.h"
-
-/*
-* argv[0] user
-*/
-
-CMD_BIND(neonhelp_cmd_stats) {
- //check permissions
- MYSQL_RES *res;
- MYSQL_ROW row, row2;
- int caccess = 0;
- printf_mysql_query("SELECT `helpserv_support`, `helpserv_public`, `helpserv_intern` FROM `helpserv_settings` WHERE `helpserv_botid` = '%d'", client->clientid);
- res = mysql_use();
- if (!(row = mysql_fetch_row(res))) return;
- //check if the user is a supporter (access in the support channel)
- if((user->flags & USERFLAG_ISAUTHED)) {
- int userid;
- if(user->flags & USERFLAG_HAS_USERID)
- userid = user->user_id;
- else {
- printf_mysql_query("SELECT `user_id` FROM `users` WHERE `user_user` = '%s'", escape_string(user->auth));
- res = mysql_use();
- if ((row2 = mysql_fetch_row(res)) != NULL) {
- userid = atoi(row2[0]);
- user->user_id = userid;
- user->flags |= USERFLAG_HAS_USERID;
- } else
- userid = 0;
- }
- printf_mysql_query("SELECT `chanuser_access`, `chanuser_flags` FROM `chanusers` LEFT JOIN `channels` ON `chanuser_cid` = `channel_id` WHERE `chanuser_uid` = '%d' AND `channel_name` = '%s'", userid, escape_string(row[0]));
- res = mysql_use();
- if ((row2 = mysql_fetch_row(res)) != NULL) {
- int cflags = atoi(row2[1]);
- if(!(cflags & DB_CHANUSER_SUSPENDED))
- caccess = atoi(row2[0]);
- }
- }
- if(!caccess) {
- reply(getTextBot(), user, "MODCMD_ACCESS_DENIED");
- return;
- }
- if(argc > 0) {
- //following
- } else {
- struct Table *table;
- printf_mysql_query("SELECT DISTINCT a.`supporter`, `user_user`, (SELECT COUNT(*) FROM `helpserv_requests` AS b WHERE b.`supporter` = a.`supporter` AND b.`time` > (UNIX_TIMESTAMP()-(3600*24))), (SELECT COUNT(*) FROM `helpserv_requests` AS b WHERE b.`supporter` = a.`supporter` AND b.`time` > (UNIX_TIMESTAMP()-(3600*24*7))), (SELECT COUNT(*) FROM `helpserv_requests` AS b WHERE b.`supporter` = a.`supporter` AND b.`time` > (UNIX_TIMESTAMP()-(3600*24*7*4))) FROM `helpserv_requests` AS a LEFT JOIN `users` ON a.`supporter` = `user_id` WHERE a.`time` > (UNIX_TIMESTAMP()-(3600*24*7*4)) AND `botid` = '%d' ORDER BY `user_user` ASC", client->clientid);
- res = mysql_use();
- table = table_init(4, mysql_num_rows(res) + 1, 0);
- char *content[4];
- content[0] = get_language_string(user, "NH_STATS_HEADER_USER");
- content[1] = get_language_string(user, "NH_STATS_HEADER_LAST_24H");
- content[2] = get_language_string(user, "NH_STATS_HEADER_LAST_7DAY");
- content[3] = get_language_string(user, "NH_STATS_HEADER_LAST_30DAY");
- table_add(table, content);
- while ((row = mysql_fetch_row(res)) != NULL) {
- content[0] = (strcmp(row[0], "-1") ? row[1] : "-");
- content[1] = row[2];
- content[2] = row[3];
- content[3] = row[4];
- table_add(table, content);
- }
- char **table_lines = table_end(table);
- int i;
- for(i = 0; i < table->entrys; i++) {
- reply(getTextBot(), user, table_lines[i]);
- }
- if(table->entrys == 1)
- reply(getTextBot(), user, "NS_TABLE_NONE");
- table_free(table);
- }
-}
+++ /dev/null
-/* cmd_neonserv.h - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-#ifndef _cmd_neonserv_h
-#define _cmd_neonserv_h
-#include "main.h"
-#include "modcmd.h"
-#include "IRCParser.h"
-#include "IRCEvents.h"
-#include "UserNode.h"
-#include "ChanNode.h"
-#include "ChanUser.h"
-#include "ModeNode.h"
-#include "BanNode.h"
-#include "ClientSocket.h"
-#include "mysqlConn.h"
-#include "lang.h"
-#include "HandleInfoHandler.h"
-#include "WHOHandler.h"
-#include "DBHelper.h"
-#include "tools.h"
-#include "timeq.h"
-#include "version.h"
-#include "EventLogger.h"
-#include "bots.h"
-#include "bot_NeonServ.h"
-#include "ConfigParser.h"
-
-CMD_BIND(neonserv_cmd_access);
-CMD_BIND(neonserv_cmd_addban);
-CMD_BIND(neonserv_cmd_addrank);
-CMD_BIND(neonserv_cmd_addtimeban);
-CMD_BIND(neonserv_cmd_adduser);
-CMD_BIND(neonserv_cmd_assignrank);
-CMD_BIND(neonserv_cmd_ban);
-CMD_BIND(neonserv_cmd_bans);
-CMD_BIND(neonserv_cmd_chanservsync);
-CMD_BIND(neonserv_cmd_clvl);
-CMD_BIND(neonserv_cmd_csuspend);
-CMD_BIND(neonserv_cmd_cunsuspend);
-CMD_BIND(neonserv_cmd_dehalfop);
-CMD_BIND(neonserv_cmd_dehalfopall);
-CMD_BIND(neonserv_cmd_delban);
-CMD_BIND(neonserv_cmd_delme);
-CMD_BIND(neonserv_cmd_delrank);
-CMD_BIND(neonserv_cmd_deluser);
-CMD_BIND(neonserv_cmd_deop);
-CMD_BIND(neonserv_cmd_deopall);
-CMD_BIND(neonserv_cmd_devoice);
-CMD_BIND(neonserv_cmd_devoiceall);
-CMD_BIND(neonserv_cmd_down);
-CMD_BIND(neonserv_cmd_downall);
-CMD_BIND(neonserv_cmd_events);
-CMD_BIND(neonserv_cmd_extscript);
-CMD_BIND(neonserv_cmd_giveowner);
-CMD_BIND(neonserv_cmd_halfop);
-CMD_BIND(neonserv_cmd_halfopall);
-CMD_BIND(neonserv_cmd_help);
-CMD_BIND(neonserv_cmd_info);
-CMD_BIND(neonserv_cmd_invite);
-CMD_BIND(neonserv_cmd_inviteme);
-CMD_BIND(neonserv_cmd_kick);
-CMD_BIND(neonserv_cmd_kickban);
-CMD_BIND(neonserv_cmd_listrank);
-CMD_BIND(neonserv_cmd_mdeluser);
-CMD_BIND(neonserv_cmd_mode);
-CMD_BIND(neonserv_cmd_move);
-CMD_BIND(neonserv_cmd_myaccess);
-CMD_BIND(neonserv_cmd_nicklist);
-CMD_BIND(neonserv_cmd_noregister);
-CMD_BIND(neonserv_cmd_op);
-CMD_BIND(neonserv_cmd_opall);
-CMD_BIND(neonserv_cmd_oplog);
-CMD_BIND(neonserv_cmd_peek);
-CMD_BIND(neonserv_cmd_recover);
-CMD_BIND(neonserv_cmd_rename);
-CMD_BIND(neonserv_cmd_resync);
-CMD_BIND(neonserv_cmd_search);
-CMD_BIND(neonserv_cmd_set);
-CMD_BIND(neonserv_cmd_setrank);
-CMD_BIND(neonserv_cmd_suspend);
-CMD_BIND(neonserv_cmd_topic);
-CMD_BIND(neonserv_cmd_trace);
-CMD_BIND(neonserv_cmd_trim);
-CMD_BIND(neonserv_cmd_unban);
-CMD_BIND(neonserv_cmd_unbanall);
-CMD_BIND(neonserv_cmd_unbanme);
-CMD_BIND(neonserv_cmd_unsuspend);
-CMD_BIND(neonserv_cmd_unvisited);
-CMD_BIND(neonserv_cmd_up);
-CMD_BIND(neonserv_cmd_upall);
-CMD_BIND(neonserv_cmd_users);
-CMD_BIND(neonserv_cmd_uset);
-CMD_BIND(neonserv_cmd_voice);
-CMD_BIND(neonserv_cmd_voiceall);
-CMD_BIND(neonserv_cmd_wipeinfo);
-
-#endif
\ No newline at end of file
+++ /dev/null
-/* cmd_neonserv_access.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* argv[0] - nick / *auth
-*/
-static USERAUTH_CALLBACK(neonserv_cmd_access_nick_lookup);
-static void neonserv_cmd_access_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, char *nick, char *auth, struct UserNode *target);
-static void neonserv_cmd_access_filter_ranking_info(char *info, char *buffer, char *nick, char *auth, char *rank_name);
-
-struct neonserv_cmd_access_cache {
- struct ClientSocket *client, *textclient;
- struct UserNode *user;
- struct ChanNode *chan;
- char *nick;
-};
-
-CMD_BIND(neonserv_cmd_access) {
- if(argc == 0) {
- if(!(user->flags & USERFLAG_ISAUTHED)) {
- struct neonserv_cmd_access_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(user->nick);
- get_userauth(user, neonserv_cmd_access_nick_lookup, cache);
- } else
- neonserv_cmd_access_async1(client, getTextBot(), user, chan, user->nick, user->auth, user);
- }
- else if(argv[0][0] == '*') {
- //we've got an auth
- argv[0]++;
- neonserv_cmd_access_async1(client, getTextBot(), user, chan, NULL, argv[0], NULL);
- } else {
- struct UserNode *cuser = getUserByNick(argv[0]);
- if(!cuser) {
- cuser = createTempUser(argv[0]);
- if(!cuser) {
- reply(getTextBot(), user, "NS_USER_UNKNOWN", argv[0]);
- return;
- }
- cuser->flags |= USERFLAG_ISTMPUSER;
- }
- if(cuser->flags & USERFLAG_ISAUTHED) {
- neonserv_cmd_access_async1(client, getTextBot(), user, chan, argv[0], cuser->auth, cuser);
- } else {
- struct neonserv_cmd_access_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]);
- get_userauth(cuser, neonserv_cmd_access_nick_lookup, cache);
- }
- }
-}
-
-static USERAUTH_CALLBACK(neonserv_cmd_access_nick_lookup) {
- struct neonserv_cmd_access_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
- if(!strcmp(cache->nick, cache->user->nick))
- reply(cache->textclient, cache->user, "NS_YOU_NEED_AUTH");
- else
- reply(cache->textclient, cache->user, "NS_USER_NEED_AUTH", cache->nick);
- }
- else
- neonserv_cmd_access_async1(cache->client, cache->textclient, cache->user, cache->chan, user->nick, user->auth, user);
- free(cache->nick);
- free(cache);
-}
-
-static void neonserv_cmd_access_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, char *nick, char *auth, struct UserNode *target) {
- //we've got a valid auth now...
- MYSQL_RES *res;
- MYSQL_ROW user_row, chanuser_row;
- int userid;
- printf_mysql_query("SELECT `user_id`, `user_access`, `user_god`, `user_rank`, `rank_info`, `rank_name` FROM `users` LEFT JOIN `support_ranks` ON `rank_id` = `user_rank` WHERE `user_user` = '%s'", escape_string(auth));
- res = mysql_use();
- if ((user_row = mysql_fetch_row(res)) != NULL) {
- userid = atoi(user_row[0]);
- //check if the user is already added
- printf_mysql_query("SELECT `chanuser_access`, `chanuser_flags`, `chanuser_infoline` FROM `chanusers` WHERE `chanuser_cid` = '%d' AND `chanuser_uid` = '%d'", chan->channel_id, userid);
- res = mysql_use();
- if(strcmp(user_row[3], "0") && strcmp(user_row[4], "")) {
- char rank_info[MAXLEN];
- neonserv_cmd_access_filter_ranking_info(user_row[4], rank_info, nick, auth, user_row[5]);
- reply(textclient, user, "%s", rank_info);
- }
- if ((chanuser_row = mysql_fetch_row(res)) != NULL) {
- //access output
- if(nick)
- reply(textclient, user, (strcmp(user_row[2], "1") ? "NS_A_ACCESS_AUTH" : "NS_A_ACCESS_AUTH_GOD"), nick, auth, atoi(chanuser_row[0]), chan->name);
- else
- reply(textclient, user, (strcmp(user_row[2], "1") ? "NS_A_ACCESS_NICK" : "NS_A_ACCESS_NICK_GOD"), auth, atoi(chanuser_row[0]), chan->name);
- int cflags = atoi(chanuser_row[1]);
- if(cflags & DB_CHANUSER_SUSPENDED)
- reply(textclient, user, "NS_A_SUSPENDED", (nick ? nick : auth), chan->name);
- if(chanuser_row[2] && strcmp(chanuser_row[2], ""))
- reply(textclient, user, "[%s] %s", (nick ? nick : auth), chanuser_row[2]);
- } else if(!strcmp(user_row[2], "1")) {
- if(nick)
- reply(textclient, user, "NS_A_LACKS_ACCESS_BUT_GOD_AUTH", nick, auth, chan->name);
- else
- reply(textclient, user, "NS_A_LACKS_ACCESS_BUT_GOD_NICK", auth, chan->name);
- } else
- reply(textclient, user, "NS_NOT_ON_USERLIST", (nick ? nick : auth), chan->name);
- } else
- reply(textclient, user, "NS_NOT_ON_USERLIST", (nick ? nick : auth), chan->name);
- if(target && (target->flags & USERFLAG_ISIRCOP))
- reply(textclient, user, "NS_A_IS_IRCOP", nick);
-}
-
-static void neonserv_cmd_access_filter_ranking_info(char *info, char *buffer, char *nick, char *auth, char *rank_name) {
- int bufferPos = 0;
- char *a, *b = info;
- do {
- if(!b) break;
- a = strstr(b, "$");
- if(a) *a = '\0';
- bufferPos += sprintf(buffer + bufferPos, "%s", b);
- if(!a) break;
- switch(a[1]) {
- case '\0':
- a = NULL;
- break;
- case 'U':
- bufferPos += sprintf(buffer + bufferPos, "%s", auth);
- break;
- case 'N':
- bufferPos += sprintf(buffer + bufferPos, "%s", (nick ? nick : auth));
- break;
- case 'R':
- bufferPos += sprintf(buffer + bufferPos, "%s", rank_name);
- break;
- default:
- buffer[bufferPos++] = '$';
- buffer[bufferPos++] = a[1];
- break;
- }
- if(a)
- b = a+2;
- } while(a);
-}
+++ /dev/null
-/* cmd_neonserv_addban.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* argv[0] nick|*auth|*!*@mask
-* argv[1-*] reason
-*/
-static USERLIST_CALLBACK(neonserv_cmd_addban_userlist_lookup);
-static void neonserv_cmd_addban_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *mas, char *reason);
-
-struct neonserv_cmd_addban_cache {
- struct ClientSocket *client, *textclient;
- struct UserNode *user;
- struct Event *event;
- char *mask;
- char *reason;
-};
-
-CMD_BIND(neonserv_cmd_addban) {
- struct neonserv_cmd_addban_cache *cache = malloc(sizeof(*cache));
- if (!cache) {
- perror("malloc() failed");
- return;
- }
- cache->client = client;
- cache->textclient = getTextBot();
- cache->user = user;
- cache->event = event;
- cache->mask = strdup(argv[0]);
- if(argc > 1) {
- cache->reason = strdup(merge_argv(argv, 1, argc));
- } else
- cache->reason = NULL;
- get_userlist(chan, neonserv_cmd_addban_userlist_lookup, cache);
-}
-
-static USERLIST_CALLBACK(neonserv_cmd_addban_userlist_lookup) {
- struct neonserv_cmd_addban_cache *cache = data;
- neonserv_cmd_addban_async1(cache->client, cache->textclient, cache->user, chan, cache->event, cache->mask, (cache->reason ? cache->reason : "Bye."));
- free(cache->mask);
- if(cache->reason)
- free(cache->reason);
- free(cache);
-}
-
-static void neonserv_cmd_addban_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *mask, char *reason) {
- int match_count = 0;
- char hostmask_buffer[NICKLEN+USERLEN+HOSTLEN+3];
- char usermask[NICKLEN+USERLEN+HOSTLEN+3];
- struct UserNode *cuser;
- struct ChanUser *chanuser;
- mask = make_banmask(mask, hostmask_buffer);
- for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
- cuser = chanuser->user;
- sprintf(usermask, "%s!%s@%s", cuser->nick, cuser->ident, cuser->host);
- if(!match(mask, usermask)) {
- if(isNetworkService(chanuser->user)) {
- reply(textclient, user, "NS_SERVICE_IMMUNE", chanuser->user->nick);
- return;
- }
- if(cuser == user || ((cuser->flags & USERFLAG_ISAUTHED) && !stricmp(user->auth, cuser->auth))) {
- reply(textclient, user, "NS_YOU_PROTECTED");
- return;
- }
- if(isUserProtected(chan, cuser, user)) {
- reply(textclient, user, "NS_USER_PROTECTED", cuser->nick);
- return;
- }
- match_count++;
- if(match_count > 4 && (match_count * 3) > chan->usercount && !isGodMode(user)) {
- reply(textclient, user, "NS_LAME_MASK", mask);
- return;
- }
- }
- }
- MYSQL_RES *res;
- MYSQL_ROW row;
- //check if the provided mask is already banned by another ban
- char *ban = getBanAffectingMask(chan, mask);
- if(ban != NULL) {
- reply(textclient, user, "NS_BAN_ALREADY_ADDED", mask, chan->name);
- return;
- }
- //check if the provided mask affects any existing bans
- printf_mysql_query("SELECT `ban_mask`, `ban_id` FROM `bans` WHERE `ban_channel` = '%d'", chan->channel_id);
- res = mysql_use();
- while ((row = mysql_fetch_row(res)) != NULL) {
- if(!match(mask, row[0])) {
- //remove the ban
- printf_mysql_query("DELETE FROM `bans` WHERE `ban_id` = '%s'", row[1]);
- }
- }
- printf_mysql_query("SELECT `user_id` FROM `users` WHERE `user_user` = '%s'", escape_string(user->auth));
- int userid;
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) != NULL)
- userid = atoi(row[0]);
- else
- return;
- //add the ban
- printf_mysql_query("INSERT INTO `bans` (`ban_channel`, `ban_mask`, `ban_triggered`, `ban_owner`, `ban_reason`) VALUES ('%d', '%s', UNIX_TIMESTAMP(), '%d', '%s')", chan->channel_id, escape_string(mask), userid, escape_string(reason));
- putsock(client, "MODE %s +b %s", chan->name, mask);
- for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
- cuser = chanuser->user;
- sprintf(usermask, "%s!%s@%s", cuser->nick, cuser->ident, cuser->host);
- if(!match(mask, usermask)) {
- putsock(client, "KICK %s %s :(%s) %s", chan->name, cuser->nick, user->nick, reason);
- }
- }
- reply(textclient, user, "NS_ADDBAN_DONE", mask, chan->name, match_count);
- logEvent(event);
-}
+++ /dev/null
-/* cmd_neonserv_addrank.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* argv[0-*] rank name
-*/
-
-CMD_BIND(neonserv_cmd_addrank) {
- char *name = merge_argv(argv, 0, argc);
- MYSQL_RES *res;
- MYSQL_ROW row;
- printf_mysql_query("SELECT `rank_name` FROM `support_ranks` WHERE `rank_name` = '%s'", escape_string(name));
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) != NULL) {
- reply(getTextBot(), user, "NS_ADDRANK_EXISTS", row[0]);
- return;
- }
- printf_mysql_query("INSERT INTO `support_ranks` (`rank_name`) VALUES ('%s')", escape_string(name));
- reply(getTextBot(), user, "NS_ADDRANK_DONE", name);
-}
+++ /dev/null
-/* cmd_neonserv_addtimeban.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* argv[0] nick|*auth|*!*@mask
-* argv[1] time
-* argv[2-*] reason
-*/
-static USERLIST_CALLBACK(neonserv_cmd_addtimeban_userlist_lookup);
-static void neonserv_cmd_addtimeban_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *mask, int duration, char *reason);
-
-struct neonserv_cmd_addtimeban_cache {
- struct ClientSocket *client, *textclient;
- struct UserNode *user;
- struct Event *event;
- char *mask;
- int duration;
- char *reason;
-};
-
-CMD_BIND(neonserv_cmd_addtimeban) {
- int duration = strToTime(user, argv[1]);
- if(duration < 5) {
- reply(getTextBot(), user, "NS_TIMEBAN_DURATION_TOO_SHORT", 5);
- return;
- }
- struct neonserv_cmd_addtimeban_cache *cache = malloc(sizeof(*cache));
- if (!cache) {
- perror("malloc() failed");
- return;
- }
- cache->client = client;
- cache->textclient = getTextBot();
- cache->user = user;
- cache->event = event;
- cache->mask = strdup(argv[0]);
- cache->duration = duration;
- if(argc > 2) {
- cache->reason = strdup(merge_argv(argv, 2, argc));
- } else
- cache->reason = NULL;
- get_userlist(chan, neonserv_cmd_addtimeban_userlist_lookup, cache);
-}
-
-static USERLIST_CALLBACK(neonserv_cmd_addtimeban_userlist_lookup) {
- struct neonserv_cmd_addtimeban_cache *cache = data;
- neonserv_cmd_addtimeban_async1(cache->client, cache->textclient, cache->user, chan, cache->event, cache->mask, cache->duration, (cache->reason ? cache->reason : "Bye."));
- free(cache->mask);
- if(cache->reason)
- free(cache->reason);
- free(cache);
-}
-
-static void neonserv_cmd_addtimeban_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *mask, int duration, char *reason) {
- int match_count = 0;
- char hostmask_buffer[NICKLEN+USERLEN+HOSTLEN+3];
- char usermask[NICKLEN+USERLEN+HOSTLEN+3];
- struct UserNode *cuser;
- struct ChanUser *chanuser;
- mask = make_banmask(mask, hostmask_buffer);
- for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
- cuser = chanuser->user;
- sprintf(usermask, "%s!%s@%s", cuser->nick, cuser->ident, cuser->host);
- if(!match(mask, usermask)) {
- if(isNetworkService(chanuser->user)) {
- reply(textclient, user, "NS_SERVICE_IMMUNE", chanuser->user->nick);
- return;
- }
- if(isUserProtected(chan, cuser, user)) {
- reply(textclient, user, "NS_USER_PROTECTED", cuser->nick);
- return;
- }
- match_count++;
- if(match_count > 4 && (match_count * 3) > chan->usercount && !isGodMode(user)) {
- reply(textclient, user, "NS_LAME_MASK", mask);
- return;
- }
- }
- }
- MYSQL_RES *res;
- MYSQL_ROW row;
- //check if the provided mask is already banned by another ban
- char *ban = getBanAffectingMask(chan, mask);
- if(ban != NULL) {
- reply(textclient, user, "NS_BAN_ALREADY_ADDED", mask, chan->name);
- return;
- }
- //check if the provided mask affects any existing bans
- printf_mysql_query("SELECT `ban_mask`, `ban_id` FROM `bans` WHERE `ban_channel` = '%d'", chan->channel_id);
- res = mysql_use();
- while ((row = mysql_fetch_row(res)) != NULL) {
- if(!match(mask, row[0])) {
- //remove the ban
- printf_mysql_query("DELETE FROM `bans` WHERE `ban_id` = '%s'", row[1]);
- }
- }
- printf_mysql_query("SELECT `user_id` FROM `users` WHERE `user_user` = '%s'", escape_string(user->auth));
- int userid;
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) != NULL)
- userid = atoi(row[0]);
- else
- return;
- //add the ban
- printf_mysql_query("INSERT INTO `bans` (`ban_channel`, `ban_mask`, `ban_triggered`, `ban_timeout`, `ban_owner`, `ban_reason`) VALUES ('%d', '%s', UNIX_TIMESTAMP(), '%lu', '%d', '%s')", chan->channel_id, escape_string(mask), (unsigned long) (time(0) + duration), userid, escape_string(reason));
- int banid = (int) mysql_insert_id(get_mysql_conn());
- putsock(client, "MODE %s +b %s", chan->name, mask);
- for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
- cuser = chanuser->user;
- sprintf(usermask, "%s!%s@%s", cuser->nick, cuser->ident, cuser->host);
- if(!match(mask, usermask)) {
- putsock(client, "KICK %s %s :(%s) %s", chan->name, cuser->nick, user->nick, reason);
- }
- }
- char nameBuf[MAXLEN];
- char banidBuf[20];
- sprintf(nameBuf, "ban_%d", banid);
- sprintf(banidBuf, "%d", banid);
- timeq_add_name(nameBuf, duration, channel_ban_timeout, strdup(banidBuf));
- reply(textclient, user, "NS_TIMEBAN_DONE", mask, chan->name, timeToStr(user, duration, 2, nameBuf), match_count);
- logEvent(event);
-}
+++ /dev/null
-/* cmd_neonserv_adduser.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* argv[0] - nick / *auth
-* argv[1] - chan access
-*/
-static AUTHLOOKUP_CALLBACK(neonserv_cmd_adduser_auth_lookup);
-static USERAUTH_CALLBACK(neonserv_cmd_adduser_nick_lookup);
-static void neonserv_cmd_adduser_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nick, char *auth, int access);
-
-struct neonserv_cmd_adduser_cache {
- struct ClientSocket *client, *textclient;
- struct UserNode *user;
- struct ChanNode *chan;
- struct Event *event;
- int access;
- char *nick;
-};
-
-CMD_BIND(neonserv_cmd_adduser) {
- int caccess;
- MYSQL_RES *res;
- MYSQL_ROW row;
- caccess = atoi(argv[1]);
- if(caccess <= 0 || caccess > 500) {
- reply(getTextBot(), user, "NS_INVALID_ACCESS", caccess);
- return;
- }
- if(caccess >= getChannelAccess(user, chan)) {
- if(isGodMode(user)) {
- event->flags |= CMDFLAG_OPLOG;
- } else {
- reply(getTextBot(), user, "NS_ACCESS_OUTRANKED");
- 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_adduser_async1(client, getTextBot(), user, chan, event, argv[0], row[0], caccess);
- } else {
- //we need to create a new user...
- //but first lookup the auth to check if it really exists
- struct neonserv_cmd_adduser_cache *cache = malloc(sizeof(*cache));
- if (!cache) {
- perror("malloc() failed");
- return;
- }
- cache->client = client;
- cache->textclient = getTextBot();
- cache->user = user;
- cache->chan = chan;
- cache->event = event;
- cache->access = caccess;
- cache->nick = strdup(argv[0]);
- lookup_authname(argv[0], neonserv_cmd_adduser_auth_lookup, cache);
- }
- } else {
- struct UserNode *cuser = getUserByNick(argv[0]);
- if(!cuser) {
- cuser = createTempUser(argv[0]);
- if(!cuser) {
- reply(getTextBot(), user, "NS_USER_UNKNOWN", argv[0]);
- return;
- }
- cuser->flags |= USERFLAG_ISTMPUSER;
- }
- if(cuser->flags & USERFLAG_ISAUTHED) {
- neonserv_cmd_adduser_async1(client, getTextBot(), user, chan, event, argv[0], cuser->auth, caccess);
- } else {
- struct neonserv_cmd_adduser_cache *cache = malloc(sizeof(*cache));
- if (!cache) {
- perror("malloc() failed");
- return;
- }
- cache->client = client;
- cache->textclient = getTextBot();
- cache->user = user;
- cache->chan = chan;
- cache->event = event;
- cache->access = caccess;
- cache->nick = strdup(argv[0]);
- get_userauth(cuser, neonserv_cmd_adduser_nick_lookup, cache);
- }
- }
-}
-
-static AUTHLOOKUP_CALLBACK(neonserv_cmd_adduser_auth_lookup) {
- struct neonserv_cmd_adduser_cache *cache = data;
- if(!exists) {
- //AUTH_DOES_NOT_EXIST
- reply(cache->textclient, cache->user, "NS_AUTH_UNKNOWN", cache->nick);
- } else
- neonserv_cmd_adduser_async1(cache->client, cache->textclient, cache->user, cache->chan, cache->event, cache->nick, auth, cache->access);
- free(cache->nick);
- free(cache);
-}
-
-static USERAUTH_CALLBACK(neonserv_cmd_adduser_nick_lookup) {
- struct neonserv_cmd_adduser_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_adduser_async1(cache->client, cache->textclient, cache->user, cache->chan, cache->event, user->nick, user->auth, cache->access);
- free(cache->nick);
- free(cache);
-}
-
-static void neonserv_cmd_adduser_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nick, char *auth, int caccess) {
- //we've got a valid auth now...
- MYSQL_RES *res;
- MYSQL_ROW row;
- 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]);
- //check if the user is already added
- printf_mysql_query("SELECT `chanuser_access` FROM `chanusers` WHERE `chanuser_cid` = '%d' AND `chanuser_uid` = '%d'", chan->channel_id, userid);
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) != NULL) {
- reply(textclient, user, "NS_ADDUSER_ALREADY_ADDED", nick, chan->name, atoi(row[0]));
- return;
- }
- } else {
- printf_mysql_query("INSERT INTO `users` (`user_user`) VALUES ('%s')", escape_string(auth));
- userid = (int) mysql_insert_id(get_mysql_conn());
- }
- printf_mysql_query("INSERT INTO `chanusers` (`chanuser_cid`, `chanuser_uid`, `chanuser_access`) VALUES ('%d', '%d', '%d')", chan->channel_id, userid, caccess);
- reply(textclient, user, "NS_ADDUSER_DONE", nick, chan->name, caccess);
- logEvent(event);
-}
+++ /dev/null
-/* cmd_neonserv_assignrank.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* argv[0] - nick / *auth
-* argv[1-*] - rank name
-*/
-static AUTHLOOKUP_CALLBACK(neonserv_cmd_assignrank_auth_lookup);
-static USERAUTH_CALLBACK(neonserv_cmd_assignrank_nick_lookup);
-static void neonserv_cmd_assignrank_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct Event *event, char *nick, char *auth, int rank_id);
-
-struct neonserv_cmd_assignrank_cache {
- struct ClientSocket *client, *textclient;
- struct UserNode *user;
- struct Event *event;
- int rank_id;
- char *nick;
-};
-
-CMD_BIND(neonserv_cmd_assignrank) {
- MYSQL_RES *res;
- MYSQL_ROW row;
- char *name = merge_argv(argv, 1, argc);
- int rank_id = 0;
- if(stricmp(name, "*") && stricmp(name, "user") && stricmp(name, "none")) {
- printf_mysql_query("SELECT `rank_id`, `rank_name` FROM `support_ranks` WHERE `rank_name` = '%s'", escape_string(name));
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) == NULL) {
- reply(getTextBot(), user, "NS_DELRANK_NOT_FOUND", name);
- return;
- }
- rank_id = atoi(row[0]);
- }
- 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_assignrank_async1(client, getTextBot(), user, event, argv[0], row[0], rank_id);
- } else {
- //we need to create a new user...
- //but first lookup the auth to check if it really exists
- struct neonserv_cmd_assignrank_cache *cache = malloc(sizeof(*cache));
- if (!cache) {
- perror("malloc() failed");
- return;
- }
- cache->client = client;
- cache->textclient = getTextBot();
- cache->user = user;
- cache->event = event;
- cache->rank_id = rank_id;
- cache->nick = strdup(argv[0]);
- lookup_authname(argv[0], neonserv_cmd_assignrank_auth_lookup, cache);
- }
- } else {
- struct UserNode *cuser = getUserByNick(argv[0]);
- if(!cuser) {
- cuser = createTempUser(argv[0]);
- if(!cuser) {
- reply(getTextBot(), user, "NS_USER_UNKNOWN", argv[0]);
- return;
- }
- cuser->flags |= USERFLAG_ISTMPUSER;
- }
- if(cuser->flags & USERFLAG_ISAUTHED) {
- neonserv_cmd_assignrank_async1(client, getTextBot(), user, event, argv[0], cuser->auth, rank_id);
- } else {
- struct neonserv_cmd_assignrank_cache *cache = malloc(sizeof(*cache));
- if (!cache) {
- perror("malloc() failed");
- return;
- }
- cache->client = client;
- cache->textclient = getTextBot();
- cache->user = user;
- cache->event = event;
- cache->rank_id = rank_id;
- cache->nick = strdup(argv[0]);
- get_userauth(cuser, neonserv_cmd_assignrank_nick_lookup, cache);
- }
- }
-}
-
-static AUTHLOOKUP_CALLBACK(neonserv_cmd_assignrank_auth_lookup) {
- struct neonserv_cmd_assignrank_cache *cache = data;
- if(!exists) {
- //AUTH_DOES_NOT_EXIST
- reply(cache->textclient, cache->user, "NS_AUTH_UNKNOWN", cache->nick);
- } else
- neonserv_cmd_assignrank_async1(cache->client, cache->textclient, cache->user, cache->event, cache->nick, auth, cache->rank_id);
- free(cache->nick);
- free(cache);
-}
-
-static USERAUTH_CALLBACK(neonserv_cmd_assignrank_nick_lookup) {
- struct neonserv_cmd_assignrank_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_assignrank_async1(cache->client, cache->textclient, cache->user, cache->event, user->nick, user->auth, cache->rank_id);
- free(cache->nick);
- free(cache);
-}
-
-static void neonserv_cmd_assignrank_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct Event *event, char *nick, char *auth, int rank_id) {
- //we've got a valid auth now...
- MYSQL_RES *res;
- MYSQL_ROW row, rank = NULL;
- int caccess = 0;
- if(rank_id) {
- printf_mysql_query("SELECT `rank_access`, `rank_name` FROM `support_ranks` WHERE `rank_id` = '%d'", rank_id);
- res = mysql_use();
- rank = mysql_fetch_row(res);
- caccess = atoi(rank[0]);
- }
- printf_mysql_query("SELECT `user_id`, `user_rank` FROM `users` WHERE `user_user` = '%s'", escape_string(auth));
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) != NULL) {
- if(atoi(row[1]) != rank_id) {
- printf_mysql_query("UPDATE `users` SET `user_access` = '%d', `user_rank` = '%d' WHERE `user_id` = '%s'", caccess, rank_id, row[0]);
- }
- } else if(rank_id) {
- printf_mysql_query("INSERT INTO `users` (`user_user`, `user_access`, `user_rank`) VALUES ('%s', '%d', '%d')", escape_string(auth), caccess, rank_id);
- }
- reply(textclient, user, "NS_ASSIGNRANK_DONE", auth, (rank_id ? rank[1] : "*"));
- logEvent(event);
-}
+++ /dev/null
-/* cmd_neonserv_ban.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* argv[0-*] nick[,*auth[,*!*@mask[...]]]
-*/
-static USERLIST_CALLBACK(neonserv_cmd_ban_userlist_lookup);
-static void neonserv_cmd_ban_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *masks);
-
-struct neonserv_cmd_ban_cache {
- struct ClientSocket *client, *textclient;
- struct UserNode *user;
- struct Event *event;
- char *masks;
-};
-
-CMD_BIND(neonserv_cmd_ban) {
- struct neonserv_cmd_ban_cache *cache = malloc(sizeof(*cache));
- if (!cache) {
- perror("malloc() failed");
- return;
- }
- cache->client = client;
- cache->textclient = getTextBot();
- cache->user = user;
- cache->event = event;
- cache->masks = strdup(merge_argv_char(argv, 0, argc, ','));
- get_userlist_with_invisible(chan, neonserv_cmd_ban_userlist_lookup, cache);
-}
-
-static USERLIST_CALLBACK(neonserv_cmd_ban_userlist_lookup) {
- struct neonserv_cmd_ban_cache *cache = data;
- neonserv_cmd_ban_async1(cache->client, cache->textclient, cache->user, chan, cache->event, cache->masks);
- free(cache->masks);
- free(cache);
-}
-
-static void neonserv_cmd_ban_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *masks) {
- int done_masks = 0, provided_masks = 0, skip, match_count, total_match;
- char *mask, *nextmask;
- char hostmask_buffer[NICKLEN+USERLEN+HOSTLEN+3];
- char usermask[NICKLEN+USERLEN+HOSTLEN+3];
- struct UserNode *cuser;
- struct ChanUser *chanuser;
- struct ModeBuffer *modeBuf;
- modeBuf = initModeBuffer(client, chan);
- nextmask = masks;
- while((mask = nextmask)) {
- nextmask = strstr(mask, ",");
- if(nextmask) {
- *nextmask = '\0';
- nextmask++;
- }
- provided_masks++;
- skip = 0;
- match_count = 0;
- mask = make_banmask(mask, hostmask_buffer);
- for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
- cuser = chanuser->user;
- sprintf(usermask, "%s!%s@%s", cuser->nick, cuser->ident, cuser->host);
- if(!match(mask, usermask)) {
- cuser->flags |= USERFLAG_SCRIPTFLAG1; //we mark the user as 'matching'
- if(isNetworkService(chanuser->user)) {
- reply(textclient, user, "NS_SERVICE_IMMUNE", chanuser->user->nick);
- skip = 1;
- break;
- }
- if(cuser == user || ((cuser->flags & USERFLAG_ISAUTHED) && !stricmp(user->auth, cuser->auth))) {
- reply(textclient, user, "NS_YOU_PROTECTED");
- skip = 1;
- break;
- }
- if(isUserProtected(chan, cuser, user)) {
- reply(textclient, user, "NS_USER_PROTECTED", cuser->nick);
- skip = 1;
- break;
- }
- match_count++;
- if(match_count > 4 && (match_count * 3) > chan->usercount && !isGodMode(user)) {
- skip = 1;
- reply(textclient, user, "NS_LAME_MASK", mask);
- break;
- }
- }
- }
- if(!skip) {
- done_masks++;
- modeBufferBan(modeBuf, mask);
- }
- }
- total_match = 0; // count all users marked as 'matching'
- for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
- cuser = chanuser->user;
- if(cuser->flags & USERFLAG_SCRIPTFLAG1) {
- cuser->flags &= ~USERFLAG_SCRIPTFLAG1;
- total_match++;
- }
- }
- freeModeBuffer(modeBuf);
- if(done_masks == provided_masks)
- reply(getTextBot(), user, "NS_BAN_DONE", done_masks, chan->name, total_match);
- else
- reply(getTextBot(), user, "NS_BAN_FAIL", client->user->nick);
- if(done_masks)
- logEvent(event);
-}
+++ /dev/null
-/* cmd_neonserv_bans.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* argv[0] (optional) mask
-*/
-CMD_BIND(neonserv_cmd_bans) {
- MYSQL_RES *res;
- MYSQL_ROW row;
- //ban list
- int i, with_expire = 0, cindex = 0;
- char triggered_str[MAXLEN], expires_str[MAXLEN];
- struct Table *table;
- printf_mysql_query("SELECT `ban_mask`, `user_user`, `ban_triggered`, `ban_timeout`, `ban_reason` FROM `bans` LEFT JOIN `users` ON `ban_owner` = `user_id` WHERE `ban_channel` = '%d'", chan->channel_id);
- res = mysql_use();
- table = table_init(5, mysql_num_rows(res) + 1, 0);
- char *content[5];
- //add a NULL row (we add values later)
- content[0] = NULL;
- content[1] = NULL;
- content[2] = NULL;
- content[3] = NULL;
- content[4] = NULL;
- table_add(table, content);
- while ((row = mysql_fetch_row(res)) != NULL) {
- if(argc > 0 && match(argv[0], row[0])) continue;
- content[0] = row[0];
- content[1] = row[1];
- content[2] = (strcmp(row[2], "0") ? timeToStr(user, (time(0) - atoi(row[2])), 2, triggered_str) : get_language_string(user, "NS_USERS_SEEN_NEVER"));
- if(strcmp(row[3], "0")) {
- if(!with_expire) {
- //we're using expire times now...
- for(i = 0; i < cindex; i++)
- table_change_field(table, i+1, 3, get_language_string(user, "NS_USERS_SEEN_NEVER"));
- with_expire = 1;
- }
- content[3] = timeToStr(user, (atoi(row[3]) - time(0)), 2, expires_str);
- } else
- content[3] = (with_expire ? get_language_string(user, "NS_USERS_SEEN_NEVER") : NULL);
- content[4] = row[4];
- cindex++;
- table_add(table, content);
- }
- //now we add the table header
- content[0] = get_language_string(user, "NS_BANS_HEADER_MASK");
- content[1] = get_language_string(user, "NS_BANS_HEADER_SETBY");
- content[2] = get_language_string(user, "NS_BANS_HEADER_TRIGGERED");
- content[3] = (with_expire ? get_language_string(user, "NS_BANS_HEADER_EXPIRES") : NULL);
- content[4] = get_language_string(user, "NS_BANS_HEADER_REASON");
- table_change(table, 0, content);
- char **table_lines = table_end(table);
- for(i = 0; i < table->entrys; i++) {
- reply(getTextBot(), user, table_lines[i]);
- }
- if(!cindex)
- reply(getTextBot(), user, "NS_TABLE_NONE");
- reply(getTextBot(), user, "NS_TABLE_COUNT", cindex);
- table_free(table);
-}
+++ /dev/null
-/* cmd_neonserv_chanservsync.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* argv[0] - botnick
-* argv[1] - key
-*/
-#define CHANSERVSYNC_END_TIMEOUT 5
-
-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;
- struct UserNode *user;
- struct ChanNode *chan;
- char *botnick;
- 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};
-
-CMD_BIND(neonserv_cmd_chanservsync) {
- if(neonserv_cmd_chanservsync_used && time(0) - neonserv_cmd_chanservsync_used->last_response < CHANSERVSYNC_END_TIMEOUT) {
- reply(getTextBot(), user, "NS_CHANSERVSYNC_INUSE");
- return;
- }
- if(neonserv_cmd_chanservsync_used) {
- neonserv_cmd_chanservsync_free_cache();
- }
- char *botnick = "ChanServ";
- char *key = "";
- if(argc) {
- if(argv[0][0] == '!') {
- key = argv[0];
- } else {
- botnick = argv[0];
- if(argc > 1)
- key = argv[1];
- }
- }
- int seed = 0;
- char *tmp;
- char synckey[18];
- 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));
- for(tmp = botnick; *tmp; tmp++)
- seed = (seed * 0xEECE66DL ^ ((*tmp << 24) | (*tmp << 16) | (*tmp << 8) | *tmp));
- sprintf(synckey, "!%08x!", seed);
- if(strcmp(synckey, key)) {
- int f = 0;
- const char **supp = neonserv_cmd_chanservsync_supported;
- while(*supp) {
- if(!stricmp(*supp, botnick)) {
- f = 1;
- break;
- }
- supp++;
- }
- if(!f) {
- reply(getTextBot(), user, "NS_CHANSERVSYNC_UNSUPPORTED", botnick, client->user->nick);
- }
- reply(getTextBot(), user, "NS_CHANSERVSYNC_KEY", client->user->nick, botnick, botnick, synckey);
- return;
- }
- struct neonserv_cmd_chanservsync_cache *cache = malloc(sizeof(*cache));
- if (!cache) {
- perror("malloc() failed");
- return;
- }
- cache->client = client;
- cache->textclient = getTextBot();
- cache->user = user;
- cache->chan = chan;
- cache->botnick = strdup(botnick);
- cache->last_response = time(0);
- 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);
- logEvent(event);
-}
-
-static void neonserv_cmd_chanservsync_notice_listener(struct UserNode *user, struct UserNode *target, char *message) {
- if(neonserv_cmd_chanservsync_used && neonserv_cmd_chanservsync_used->client->user == target && !stricmp(user->nick, neonserv_cmd_chanservsync_used->botnick)) {
- //we've got a notice from our bot...
- //let's try parsing it....
- char *p = message;
- char *tokens[MAXLEN];
- int tokensPos = 0;
- while(*p == ' ') //skip leading spaces (airb0t)
- p++;
- message = p;
- char *q = p;
- while(*q) {
- if(*q < 32) *q = ' ';
- q++;
- }
- while((q = strstr(p, " "))) {
- *q = '\0';
- do {
- q++;
- } while(*q == ' ' || *q == '-');
- if(*p) {
- tokens[tokensPos++] = p;
- }
- p = q;
- }
- if(*p) {
- tokens[tokensPos++] = p;
- }
- 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) {
- if(atoi(tokens[0]) > 0) {
- caccess = atoi(tokens[0]);
- username = tokens[1];
- } else {
- caccess = atoi(tokens[1]);
- username = tokens[0];
- }
- } else
- return;
- if(caccess < 1 || caccess > 500) return;
- int flags = 0;
- time_t now = time(0);
- time_t seen_time = now; //now - now = 0 (never)
- neonserv_cmd_chanservsync_used->last_response = now;
- if(strlen(username) < 3) return;
- //ok we have access and username... maybe there is something else we can parse???
- char *seen = NULL;
- char *status = NULL;
- if(tokensPos > 2) {
- if(!stricmp("normal", tokens[2]) || !stricmp("suspended", tokens[2]) || !stricmp("bot", tokens[2])) {
- status = tokens[2];
- if (tokensPos > 3) {
- seen = merge_argv(tokens, 3, tokensPos);
- }
- } else if (tokensPos > 3) {
- if(!stricmp("normal", tokens[tokensPos-1]) || !stricmp("suspended", tokens[tokensPos-1]) || !stricmp("bot", tokens[tokensPos-1])) {
- status = tokens[tokensPos-1];
- seen = merge_argv(tokens, 2, tokensPos-1);
- } else {
- seen = merge_argv(tokens, 2, tokensPos);
- }
- } else {
- seen = merge_argv(tokens, 2, tokensPos);
- }
- }
- if(status && !stricmp(status, "suspended")) {
- flags |= DB_CHANUSER_SUSPENDED;
- }
- if(seen) {
- if(!stricmp(seen, "here"))
- seen_time = 0;
- else if(stricmp(seen, "never"))
- seen_time = strToTime(user, seen);
- }
- seen_time = now - seen_time;
- //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(get_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);
- }
- }
-}
-
-static void neonserv_cmd_chanservsync_free_cache() {
- free(neonserv_cmd_chanservsync_used->botnick);
- free(neonserv_cmd_chanservsync_used);
- unbind_privnotice(neonserv_cmd_chanservsync_notice_listener);
- 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(get_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);
-}
+++ /dev/null
-/* cmd_neonserv_clvl.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* argv[0] - nick / *auth
-* argv[1] - access
-*/
-static USERAUTH_CALLBACK(neonserv_cmd_clvl_nick_lookup);
-static void neonserv_cmd_clvl_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nick, char *auth, int caccess);
-
-struct neonserv_cmd_clvl_cache {
- struct ClientSocket *client, *textclient;
- struct UserNode *user;
- struct ChanNode *chan;
- struct Event *event;
- char *nick;
- int access;
-};
-
-CMD_BIND(neonserv_cmd_clvl) {
- int caccess;
- caccess = atoi(argv[1]);
- if(caccess <= 0 || caccess > 500) {
- reply(getTextBot(), user, "NS_INVALID_ACCESS", caccess);
- return;
- }
- if(caccess >= getChannelAccess(user, chan)) {
- if(isGodMode(user)) {
- event->flags |= CMDFLAG_OPLOG;
- } else {
- reply(getTextBot(), user, "NS_ACCESS_OUTRANKED");
- return;
- }
- }
- if(argv[0][0] == '*') {
- //we've got an auth
- argv[0]++;
- neonserv_cmd_clvl_async1(client, getTextBot(), user, chan, event, argv[0], argv[0], caccess);
- } else {
- struct UserNode *cuser = getUserByNick(argv[0]);
- if(!cuser) {
- cuser = createTempUser(argv[0]);
- if(!cuser) {
- reply(getTextBot(), user, "NS_USER_UNKNOWN", argv[0]);
- return;
- }
- cuser->flags |= USERFLAG_ISTMPUSER;
- }
- if(cuser->flags & USERFLAG_ISAUTHED) {
- neonserv_cmd_clvl_async1(client, getTextBot(), user, chan, event, argv[0], cuser->auth, caccess);
- } else {
- struct neonserv_cmd_clvl_cache *cache = malloc(sizeof(*cache));
- if (!cache) {
- perror("malloc() failed");
- return;
- }
- cache->client = client;
- cache->textclient = getTextBot();
- cache->user = user;
- cache->chan = chan;
- cache->event = event;
- cache->nick = strdup(argv[0]);
- cache->access = caccess;
- get_userauth(cuser, neonserv_cmd_clvl_nick_lookup, cache);
- }
- }
-}
-
-static USERAUTH_CALLBACK(neonserv_cmd_clvl_nick_lookup) {
- struct neonserv_cmd_clvl_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_clvl_async1(cache->client, cache->textclient, cache->user, cache->chan, cache->event, user->nick, user->auth, cache->access);
- free(cache->nick);
- free(cache);
-}
-
-static void neonserv_cmd_clvl_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nick, char *auth, int caccess) {
- //we've got a valid auth now...
- MYSQL_RES *res;
- MYSQL_ROW row;
- 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]);
- //check if the user is already added
- printf_mysql_query("SELECT `chanuser_access`, `chanuser_id` 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]) >= getChannelAccess(user, chan)) {
- if(isGodMode(user)) {
- event->flags |= CMDFLAG_OPLOG;
- } else {
- reply(textclient, user, "NS_USER_OUTRANKED", nick);
- return;
- }
- }
- printf_mysql_query("UPDATE `chanusers` SET `chanuser_access` = '%d' WHERE `chanuser_id` = '%s'", caccess, row[1]);
- reply(textclient, user, "NS_CLVL_DONE", nick, caccess, chan->name);
- logEvent(event);
- return;
- }
- }
- reply(textclient, user, "NS_NOT_ON_USERLIST", nick, chan->name);
-}
+++ /dev/null
-/* cmd_neonserv_csuspend.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* argv[0] - channel
-*/
-CMD_BIND(neonserv_cmd_csuspend) {
- 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;
- }
- 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 {
- reply(getTextBot(), user, "NS_UNREGISTER_NOT_REGISTERED", argv[0], client->user->nick);
- return;
- }
- printf_mysql_query("SELECT `botid`, `bot_channels`.`id`, `suspended` FROM `bot_channels` LEFT JOIN `bots` ON `bot_channels`.`botid` = `bots`.`id` WHERE `chanid` = '%d' AND `botclass` = '%d'", chanid, client->botid);
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) == NULL) {
- reply(getTextBot(), user, "NS_UNREGISTER_NOT_REGISTERED", argv[0], client->user->nick);
- return;
- }
- if(!strcmp(row[2], "1")) {
- reply(getTextBot(), user, "NS_CSUSPEND_ALREADY", channel);
- return;
- }
- int botid = atoi(row[0]);
- 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, "PART %s :Channel suspended.", channel);
- }
- printf_mysql_query("UPDATE `bot_channels` SET `suspended` = '1' WHERE `id` = '%s'", row[1]);
- reply(getTextBot(), user, "NS_CSUSPEND_DONE", channel);
- logEvent(event);
-}
+++ /dev/null
-/* cmd_neonserv_cunsuspend.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* argv[0] - channel
-*/
-CMD_BIND(neonserv_cmd_cunsuspend) {
- 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;
- }
- 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 {
- reply(getTextBot(), user, "NS_UNREGISTER_NOT_REGISTERED", argv[0], client->user->nick);
- return;
- }
- printf_mysql_query("SELECT `botid`, `bot_channels`.`id`, `suspended` FROM `bot_channels` LEFT JOIN `bots` ON `bot_channels`.`botid` = `bots`.`id` WHERE `chanid` = '%d' AND `botclass` = '%d'", chanid, client->botid);
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) == NULL) {
- reply(getTextBot(), user, "NS_UNREGISTER_NOT_REGISTERED", argv[0], client->user->nick);
- return;
- }
- if(!strcmp(row[2], "0")) {
- reply(getTextBot(), user, "NS_CUNSUSPEND_NOT", channel);
- return;
- }
- int botid = atoi(row[0]);
- 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);
- }
- printf_mysql_query("UPDATE `bot_channels` SET `suspended` = '0' WHERE `id` = '%s'", row[1]);
- reply(getTextBot(), user, "NS_CUNSUSPEND_DONE", channel);
- logEvent(event);
-}
+++ /dev/null
-/* cmd_neonserv_dehalfop.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* argv[0-*] nicks
-*/
-static USERLIST_CALLBACK(neonserv_cmd_dehalfop_userlist_lookup);
-static void neonserv_cmd_dehalfop_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char **argv, int argc);
-
-struct neonserv_cmd_dehalfop_cache {
- struct ClientSocket *client, *textclient;
- struct UserNode *user;
- struct Event *event;
- char **argv;
- int argc;
-};
-
-CMD_BIND(neonserv_cmd_dehalfop) {
- struct neonserv_cmd_dehalfop_cache *cache = malloc(sizeof(*cache));
- if (!cache) {
- perror("malloc() failed");
- return;
- }
- cache->client = client;
- cache->textclient = getTextBot();
- cache->user = user;
- cache->event = event;
- cache->argv = calloc(argc, sizeof(char*));
- int i;
- for(i = 0; i < argc; i++) {
- cache->argv[i] = strdup(argv[i]);
- }
- cache->argc = argc;
- get_userlist(chan, neonserv_cmd_dehalfop_userlist_lookup, cache);
-}
-
-static USERLIST_CALLBACK(neonserv_cmd_dehalfop_userlist_lookup) {
- struct neonserv_cmd_dehalfop_cache *cache = data;
- neonserv_cmd_dehalfop_async1(cache->client, cache->textclient, cache->user, chan, cache->event, cache->argv, cache->argc);
- int i;
- for(i = 0; i < cache->argc; i++) {
- free(cache->argv[i]);
- }
- free(cache->argv);
- free(cache);
-}
-
-static void neonserv_cmd_dehalfop_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char **argv, int argc) {
- int i, done_users = 0;
- struct UserNode *cuser;
- struct ChanUser *chanuser;
- struct ModeBuffer *modeBuf;
- modeBuf = initModeBuffer(client, chan);
- for(i = 0; i < argc; i++) {
- cuser = searchUserByNick(argv[i]);
- if(!cuser) continue;
- chanuser = getChanUser(cuser, chan);
- if(!chanuser) continue;
- if(isNetworkService(cuser)) {
- reply(textclient, user, "NS_SERVICE_IMMUNE", cuser->nick);
- continue;
- }
- if(isUserProtected(chan, cuser, user)) {
- reply(textclient, user, "NS_USER_PROTECTED", cuser->nick);
- continue;
- }
- done_users++;
- if(!(chanuser->flags & CHANUSERFLAG_OPPED)) continue;
- modeBufferDehalfop(modeBuf, argv[i]);
- }
- freeModeBuffer(modeBuf);
- if(done_users == argc)
- reply(textclient, user, "NS_DEHALFOP_DONE", chan->name);
- else
- reply(textclient, user, "NS_DEHALFOP_FAIL", client->user->nick);
- if(done_users)
- logEvent(event);
-}
+++ /dev/null
-/* cmd_neonserv_dehalfopall.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* argv[0] (optional) nick mask
-*/
-static USERLIST_CALLBACK(neonserv_cmd_dehalfopall_userlist_lookup);
-static void neonserv_cmd_dehalfopall_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char **argv, int argc);
-
-struct neonserv_cmd_dehalfopall_cache {
- struct ClientSocket *client, *textclient;
- struct UserNode *user;
- struct Event *event;
- char **argv;
- int argc;
-};
-
-CMD_BIND(neonserv_cmd_dehalfopall) {
- struct neonserv_cmd_dehalfopall_cache *cache = malloc(sizeof(*cache));
- if (!cache) {
- perror("malloc() failed");
- return;
- }
- cache->client = client;
- cache->textclient = getTextBot();
- cache->user = user;
- cache->event = event;
- cache->argv = calloc(argc, sizeof(char*));
- int i;
- for(i = 0; i < argc; i++) {
- cache->argv[i] = strdup(argv[i]);
- }
- cache->argc = argc;
- get_userlist(chan, neonserv_cmd_dehalfopall_userlist_lookup, cache);
-}
-
-static USERLIST_CALLBACK(neonserv_cmd_dehalfopall_userlist_lookup) {
- struct neonserv_cmd_dehalfopall_cache *cache = data;
- neonserv_cmd_dehalfopall_async1(cache->client, cache->textclient, cache->user, chan, cache->event, cache->argv, cache->argc);
- int i;
- for(i = 0; i < cache->argc; i++) {
- free(cache->argv[i]);
- }
- free(cache->argv);
- free(cache);
-}
-
-static void neonserv_cmd_dehalfopall_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char **argv, int argc) {
- int issuer_access, victim_access, done_users = 0;
- char *nickmask = NULL;
- struct ChanUser *chanuser;
- struct ModeBuffer *modeBuf;
- if(argc > 0)
- nickmask = argv[0];
- modeBuf = initModeBuffer(client, chan);
- issuer_access = getChannelAccess(user, chan);
- for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
- if(nickmask && match(nickmask, chanuser->user->nick)) continue;
- victim_access = getChannelAccess(chanuser->user, chan);
- if(victim_access >= issuer_access || isNetworkService(chanuser->user)) continue;
- if(!(chanuser->flags & CHANUSERFLAG_OPPED)) continue;
- modeBufferDehalfop(modeBuf, chanuser->user->nick);
- done_users++;
- }
- freeModeBuffer(modeBuf);
- reply(getTextBot(), user, "NS_DEHALFOPALL_DONE", done_users, chan->name);
- if(done_users)
- logEvent(event);
-}
+++ /dev/null
-/* cmd_neonserv_delban.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* argv[0] nick|*auth|*!*@mask
-*/
-
-CMD_BIND(neonserv_cmd_delban) {
- char hostmask_buffer[NICKLEN+USERLEN+HOSTLEN+3];
- char *mask = make_banmask(argv[0], hostmask_buffer);
- int matching_bans = 0;
- MYSQL_RES *res;
- MYSQL_ROW row;
- //check if the provided mask affects any existing bans
- char nameBuf[20];
- printf_mysql_query("SELECT `ban_mask`, `ban_id`, `ban_timeout` FROM `bans` WHERE `ban_channel` = '%d'", chan->channel_id);
- res = mysql_use();
- while ((row = mysql_fetch_row(res)) != NULL) {
- if(!match(mask, row[0])) {
- //remove the ban
- if(strcmp(row[2], "0")) {
- sprintf(nameBuf, "ban_%s", row[1]);
- timeq_del_name(nameBuf);
- }
- printf_mysql_query("DELETE FROM `bans` WHERE `ban_id` = '%s'", row[1]);
- matching_bans++;
- }
- }
- if(matching_bans) {
- putsock(client, "MODE %s -b %s", chan->name, mask);
- reply(getTextBot(), user, "NS_DELBAN_DONE", mask, chan->name);
- logEvent(event);
- } else
- reply(getTextBot(), user, "NS_DELBAN_FAIL", mask);
-}
+++ /dev/null
-/* cmd_neonserv_delme.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* argv[0] - key
-*/
-
-CMD_BIND(neonserv_cmd_delme) {
- MYSQL_RES *res;
- MYSQL_ROW row;
- int userid;
- printf_mysql_query("SELECT `user_id` FROM `users` WHERE `user_user` = '%s'", escape_string(user->auth));
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) != NULL) {
- userid = atoi(row[0]);
- //check if the user is added
- printf_mysql_query("SELECT `chanuser_access`, `chanuser_id` FROM `chanusers` WHERE `chanuser_cid` = '%d' AND `chanuser_uid` = '%d'", chan->channel_id, userid);
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) != NULL) {
- if(atoi(row[0]) == 500) {
- reply(getTextBot(), user, "NS_DELME_OWNER", chan->name);
- return;
- }
- //check key
- int seed = 0;
- char *tmp;
- static char unregkey[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(unregkey, "%08x", seed);
- if(argc < 1 || strcmp(argv[0], unregkey)) {
- reply(getTextBot(), user, "NS_DELME_KEY", unregkey);
- return;
- } else {
- //delete
- printf_mysql_query("DELETE FROM `chanusers` WHERE `chanuser_id` = '%s'", row[1]);
- reply(getTextBot(), user, "NS_DELME_DONE", atoi(row[0]), chan->name);
- logEvent(event);
- return;
- }
- }
- }
- reply(getTextBot(), user, "NS_NOT_ON_USERLIST_YOU", chan->name);
-}
+++ /dev/null
-/* cmd_neonserv_delrank.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* argv[0-*] rank name
-*/
-
-CMD_BIND(neonserv_cmd_delrank) {
- char *name = merge_argv(argv, 0, argc);
- MYSQL_RES *res;
- MYSQL_ROW row;
- printf_mysql_query("SELECT `rank_id`, `rank_name` FROM `support_ranks` WHERE `rank_name` = '%s'", escape_string(name));
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) == NULL) {
- reply(getTextBot(), user, "NS_DELRANK_NOT_FOUND", name);
- return;
- }
- printf_mysql_query("UPDATE `users` SET `user_rank` = '0', `user_access` = '0' WHERE `user_rank` = '%s'", row[0]);
- printf_mysql_query("DELETE FROM `support_ranks` WHERE `rank_id` = '%s'", row[0]);
- reply(getTextBot(), user, "NS_DELRANK_DELETED", row[1]);
-}
+++ /dev/null
-/* cmd_neonserv_deluser.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* argv[0] - nick / *auth
-*/
-static USERAUTH_CALLBACK(neonserv_cmd_deluser_nick_lookup);
-static void neonserv_cmd_deluser_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nick, char *auth);
-
-struct neonserv_cmd_deluser_cache {
- struct ClientSocket *client, *textclient;
- struct UserNode *user;
- struct ChanNode *chan;
- struct Event *event;
- char *nick;
-};
-
-CMD_BIND(neonserv_cmd_deluser) {
- if(argv[0][0] == '*') {
- //we've got an auth
- argv[0]++;
- neonserv_cmd_deluser_async1(client, getTextBot(), user, chan, event, argv[0], argv[0]);
- } else {
- struct UserNode *cuser = getUserByNick(argv[0]);
- if(!cuser) {
- cuser = createTempUser(argv[0]);
- if(!cuser) {
- reply(getTextBot(), user, "NS_USER_UNKNOWN", argv[0]);
- return;
- }
- cuser->flags |= USERFLAG_ISTMPUSER;
- }
- if(cuser->flags & USERFLAG_ISAUTHED) {
- neonserv_cmd_deluser_async1(client, getTextBot(), user, chan, event, argv[0], cuser->auth);
- } else {
- struct neonserv_cmd_deluser_cache *cache = malloc(sizeof(*cache));
- if (!cache) {
- perror("malloc() failed");
- return;
- }
- cache->client = client;
- cache->textclient = getTextBot();
- cache->user = user;
- cache->chan = chan;
- cache->event = event;
- cache->nick = strdup(argv[0]);
- get_userauth(cuser, neonserv_cmd_deluser_nick_lookup, cache);
- }
- }
-}
-
-static USERAUTH_CALLBACK(neonserv_cmd_deluser_nick_lookup) {
- struct neonserv_cmd_deluser_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_deluser_async1(cache->client, cache->textclient, cache->user, cache->chan, cache->event, user->nick, user->auth);
- free(cache->nick);
- free(cache);
-}
-
-static void neonserv_cmd_deluser_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nick, char *auth) {
- //we've got a valid auth now...
- MYSQL_RES *res;
- MYSQL_ROW row;
- 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]);
- //check if the user is already added
- printf_mysql_query("SELECT `chanuser_access`, `chanuser_id` FROM `chanusers` WHERE `chanuser_cid` = '%d' AND `chanuser_uid` = '%d'", chan->channel_id, userid);
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) != NULL) {
- if(atoi(row[0]) >= getChannelAccess(user, chan)) {
- if(isGodMode(user)) {
- event->flags |= CMDFLAG_OPLOG;
- } else {
- reply(textclient, user, "NS_USER_OUTRANKED", nick);
- return;
- }
- }
- //delete
- printf_mysql_query("DELETE FROM `chanusers` WHERE `chanuser_id` = '%s'", row[1]);
- reply(textclient, user, "NS_DELUSER_DONE", nick, atoi(row[0]), chan->name);
- logEvent(event);
- return;
- }
- }
- reply(textclient, user, "NS_NOT_ON_USERLIST", nick, chan->name);
-}
+++ /dev/null
-/* cmd_neonserv_deop.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* argv[0-*] nicks
-*/
-static USERLIST_CALLBACK(neonserv_cmd_deop_userlist_lookup);
-static void neonserv_cmd_deop_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char **argv, int argc);
-
-struct neonserv_cmd_deop_cache {
- struct ClientSocket *client, *textclient;
- struct UserNode *user;
- struct Event *event;
- char **argv;
- int argc;
-};
-
-CMD_BIND(neonserv_cmd_deop) {
- struct neonserv_cmd_deop_cache *cache = malloc(sizeof(*cache));
- if (!cache) {
- perror("malloc() failed");
- return;
- }
- cache->client = client;
- cache->textclient = getTextBot();
- cache->user = user;
- cache->event = event;
- cache->argv = calloc(argc, sizeof(char*));
- int i;
- for(i = 0; i < argc; i++) {
- cache->argv[i] = strdup(argv[i]);
- }
- cache->argc = argc;
- get_userlist(chan, neonserv_cmd_deop_userlist_lookup, cache);
-}
-
-static USERLIST_CALLBACK(neonserv_cmd_deop_userlist_lookup) {
- struct neonserv_cmd_deop_cache *cache = data;
- neonserv_cmd_deop_async1(cache->client, cache->textclient, cache->user, chan, cache->event, cache->argv, cache->argc);
- int i;
- for(i = 0; i < cache->argc; i++) {
- free(cache->argv[i]);
- }
- free(cache->argv);
- free(cache);
-}
-
-static void neonserv_cmd_deop_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char **argv, int argc) {
- int i, done_users = 0;
- struct UserNode *cuser;
- struct ChanUser *chanuser;
- struct ModeBuffer *modeBuf;
- modeBuf = initModeBuffer(client, chan);
- for(i = 0; i < argc; i++) {
- cuser = searchUserByNick(argv[i]);
- if(!cuser) continue;
- chanuser = getChanUser(cuser, chan);
- if(!chanuser) continue;
- if(isNetworkService(cuser)) {
- reply(textclient, user, "NS_SERVICE_IMMUNE", cuser->nick);
- continue;
- }
- if(isUserProtected(chan, cuser, user)) {
- reply(textclient, user, "NS_USER_PROTECTED", cuser->nick);
- continue;
- }
- done_users++;
- if(!(chanuser->flags & CHANUSERFLAG_OPPED)) continue;
- modeBufferDeop(modeBuf, argv[i]);
- }
- freeModeBuffer(modeBuf);
- if(done_users == argc)
- reply(textclient, user, "NS_DEOP_DONE", chan->name);
- else
- reply(textclient, user, "NS_DEOP_FAIL", client->user->nick);
- if(done_users)
- logEvent(event);
-}
+++ /dev/null
-/* cmd_neonserv_deopall.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* argv[0] (optional) nick mask
-*/
-static USERLIST_CALLBACK(neonserv_cmd_deopall_userlist_lookup);
-static void neonserv_cmd_deopall_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char **argv, int argc);
-
-struct neonserv_cmd_deopall_cache {
- struct ClientSocket *client, *textclient;
- struct UserNode *user;
- struct Event *event;
- char **argv;
- int argc;
-};
-
-CMD_BIND(neonserv_cmd_deopall) {
- struct neonserv_cmd_deopall_cache *cache = malloc(sizeof(*cache));
- if (!cache) {
- perror("malloc() failed");
- return;
- }
- cache->client = client;
- cache->textclient = getTextBot();
- cache->user = user;
- cache->event = event;
- cache->argv = calloc(argc, sizeof(char*));
- int i;
- for(i = 0; i < argc; i++) {
- cache->argv[i] = strdup(argv[i]);
- }
- cache->argc = argc;
- get_userlist(chan, neonserv_cmd_deopall_userlist_lookup, cache);
-}
-
-static USERLIST_CALLBACK(neonserv_cmd_deopall_userlist_lookup) {
- struct neonserv_cmd_deopall_cache *cache = data;
- neonserv_cmd_deopall_async1(cache->client, cache->textclient, cache->user, chan, cache->event, cache->argv, cache->argc);
- int i;
- for(i = 0; i < cache->argc; i++) {
- free(cache->argv[i]);
- }
- free(cache->argv);
- free(cache);
-}
-
-static void neonserv_cmd_deopall_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char **argv, int argc) {
- int issuer_access, victim_access, done_users = 0;
- char *nickmask = NULL;
- struct ChanUser *chanuser;
- struct ModeBuffer *modeBuf;
- if(argc > 0)
- nickmask = argv[0];
- modeBuf = initModeBuffer(client, chan);
- issuer_access = getChannelAccess(user, chan);
- for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
- if(nickmask && match(nickmask, chanuser->user->nick)) continue;
- victim_access = getChannelAccess(chanuser->user, chan);
- if(victim_access >= issuer_access || isNetworkService(chanuser->user)) continue;
- if(!(chanuser->flags & CHANUSERFLAG_OPPED)) continue;
- modeBufferDeop(modeBuf, chanuser->user->nick);
- done_users++;
- }
- freeModeBuffer(modeBuf);
- reply(getTextBot(), user, "NS_DEOPALL_DONE", done_users, chan->name);
- if(done_users)
- logEvent(event);
-}
+++ /dev/null
-/* cmd_neonserv_devoice.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* argv[0-*] nicks
-*/
-
-CMD_BIND(neonserv_cmd_devoice) {
- int i, done_users = 0;
- struct UserNode *cuser;
- struct ChanUser *chanuser;
- struct ModeBuffer *modeBuf;
- modeBuf = initModeBuffer(client, chan);
- for(i = 0; i < argc; i++) {
- cuser = searchUserByNick(argv[i]);
- if(!cuser) continue;
- chanuser = getChanUser(cuser, chan);
- if(!chanuser) continue;
- if(isUserProtected(chan, cuser, user)) {
- reply(getTextBot(), user, "NS_USER_PROTECTED", cuser->nick);
- continue;
- }
- done_users++;
- if(!(chanuser->flags & CHANUSERFLAG_VOICED)) continue;
- modeBufferDevoice(modeBuf, argv[i]);
- }
- freeModeBuffer(modeBuf);
- if(done_users == argc)
- reply(getTextBot(), user, "NS_DEVOICE_DONE", chan->name);
- else
- reply(getTextBot(), user, "NS_DEVOICE_FAIL", client->user->nick);
- if(done_users)
- logEvent(event);
-}
+++ /dev/null
-/* cmd_neonserv_devoiceall.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* argv[0] (optional) nick mask
-*/
-
-CMD_BIND(neonserv_cmd_devoiceall) {
- int issuer_access, victim_access, done_users = 0;
- char *nickmask = NULL;
- struct ChanUser *chanuser;
- struct ModeBuffer *modeBuf;
- check_mysql();
- if(argc > 0)
- nickmask = argv[0];
- modeBuf = initModeBuffer(client, chan);
- issuer_access = getChannelAccess(user, chan);
- for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
- if(nickmask && match(nickmask, chanuser->user->nick)) continue;
- victim_access = getChannelAccess(chanuser->user, chan);
- if(victim_access >= issuer_access) continue;
- if(!(chanuser->flags & CHANUSERFLAG_VOICED)) continue;
- modeBufferDevoice(modeBuf, chanuser->user->nick);
- done_users++;
- }
- freeModeBuffer(modeBuf);
- reply(getTextBot(), user, "NS_DEVOICEALL_DONE", done_users, chan->name);
- if(done_users)
- logEvent(event);
-}
+++ /dev/null
-/* cmd_neonserv_down.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* no arguments
-*/
-
-CMD_BIND(neonserv_cmd_down) {
- struct ChanUser *chanuser = getChanUser(user, chan);
- if(!chanuser) {
- reply(getTextBot(), user, "NS_NOT_ON_CHANNEL_YOU", chan->name);
- return;
- }
- if((chanuser->flags & CHANUSERFLAG_OPPED)) {
- putsock(client, "MODE %s -ov %s %s", chan->name, user->nick, user->nick);
- logEvent(event);
- } else if((chanuser->flags & CHANUSERFLAG_VOICED)) {
- putsock(client, "MODE %s -v %s", chan->name, user->nick);
- logEvent(event);
- } else
- reply(getTextBot(), user, "NS_DOWN_ALREADY", chan->name);
-}
+++ /dev/null
-/* cmd_neonserv_downall.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* no arguments
-*/
-
-CMD_BIND(neonserv_cmd_downall) {
- struct ChanUser *chanuser;
- int botid = client->botid;
- for(chanuser = getUserChannels(user, NULL); chanuser; chanuser = getUserChannels(user, chanuser)) {
- chan = chanuser->chan;
- loadChannelSettings(chan);
- if(!(chan->flags & CHANFLAG_CHAN_REGISTERED)) continue;
- 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);
- if (mysql_fetch_row(mysql_use()) == NULL) continue;
- int done = 0;
- client = getChannelBot(chan, botid);
- if(!client) continue;
- if((chanuser->flags & CHANUSERFLAG_OPPED)) {
- putsock(client, "MODE %s -o %s", chan->name, user->nick);
- done = 1;
- }
- if((chanuser->flags & CHANUSERFLAG_VOICED)) {
- putsock(client, "MODE %s -v %s", chan->name, user->nick);
- done = 1;
- }
- if(done) {
- //event hack
- event->chan = chan;
- logEvent(event);
- }
- }
-}
+++ /dev/null
-/* cmd_neonserv_events.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* argv[0] time
-* argv[1-*] match
-*/
-
-CMD_BIND(neonserv_cmd_events) {
- char *str_match;
- int duration = (argc ? strToTime(user, argv[0]) : 0);
- if(argc > (duration ? 1 : 0))
- str_match = merge_argv(argv, (duration ? 1 : 0), argc);
- else
- str_match = "";
- if(!duration) duration = (60*60*24);
- MYSQL_RES *res;
- MYSQL_ROW row;
- printf_mysql_query("SELECT `time`, `auth`, `nick`, `command` FROM `events` WHERE `cid` = '%d' AND `time` > '%lu' ORDER BY `time` ASC", chan->channel_id, ((unsigned long) time(0) - duration));
- res = mysql_use();
- int skip = mysql_num_rows(res) - 100;
- int count = 0;
- char timeBuf[50];
- struct tm *timeinfo;
- time_t event_time;
- if(skip < 0) skip = 0;
- reply(getTextBot(), user, "NS_EVENTS_HEADER");
- while ((row = mysql_fetch_row(res)) != NULL) {
- if(skip) {
- skip--;
- continue;
- }
- if(*str_match && match(str_match, row[3])) continue;
- count++;
- event_time = (time_t) atol(row[0]);
- timeinfo = localtime(&event_time);
- strftime(timeBuf, 80, "%X %x", timeinfo);
- reply(getTextBot(), user, "[%s] [%s:%s]: %s", timeBuf, row[2], row[1], row[3]);
- }
- reply(getTextBot(), user, "NS_TABLE_COUNT", count);
-}
+++ /dev/null
-/* cmd_neonserv_extscript.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-#include <fcntl.h>
-
-/*
-* argv[0] 'toys' if it's a toy command (check if toys are enabled)
-* argv[0-*] script name & parameter patterns
-* argv[argc-1] all arguments passed to the command
-*/
-
-static TIMEQ_CALLBACK(neonserv_cmd_extscript_callback);
-
-struct neonserv_cmd_extscript_cache {
- struct ClientSocket *client, *textclient;
- struct Event *event;
- struct UserNode *user;
- struct ChanNode *chan;
- int answere_channel;
- FILE *pipe;
-};
-
-CMD_BIND(neonserv_cmd_extscript) {
- int i, j;
- char *args[MAXNUMPARAMS];
- int argpos = 0;
- char *next, *curr;
- char command[1024];
- int commandpos = 0;
- char part[MAXLEN];
- int partpos;
- int escape_param;
- int answere_channel = 0;
- //check first arg
- if(argc && !stricmp(argv[0], "toys")) {
- if(!chan) return; //toys are not allowed via query
- MYSQL_RES *res;
- MYSQL_ROW row;
- printf_mysql_query("SELECT `channel_toys` FROM `channels` WHERE `channel_name` = '%s'", escape_string(chan->name));
- res = mysql_use();
- row = mysql_fetch_row(res);
- if(!row || !strcmp(row[0], "0")) {
- //disabled
- reply(getTextBot(), user, "NS_FUN_DISABLED", chan->name);
- return;
- } else if(!strcmp(row[0], "2"))
- answere_channel = 1;
- argc--;
- argv++;
- }
- //parse arguments
- if(argc < 2) return;
- curr = argv[argc-1];
- while(curr) {
- next = strstr(curr, " ");
- args[argpos++] = curr;
- if(next) {
- *next = '\0';
- curr = next+1;
- } else
- curr = NULL;
- }
- //parse command pattern and build command
- commandpos = sprintf(command, "%s", argv[0]);
- for(i = 1; i < argc-1; i++) {
- partpos = 0;
- escape_param = 1;
- if(argv[i][0] == '$') {
- argv[i]++;
- if(argv[i][strlen(argv[i])-1] == '-') {
- argv[i][strlen(argv[i])-1] = '\0';
- j = atoi(argv[i]);
- if(j <= argpos)
- partpos = sprintf(part, "%s", merge_argv(args, j-1, argpos));
- } else if((j = atoi(argv[i])) > 0) {
- if(j <= argpos)
- partpos = sprintf(part, "%s", args[j-1]);
- } else if(!strcmp(argv[i], "c")) {
- partpos = sprintf(part, "%s", (chan ? chan->name : ""));
- } else if(!strcmp(argv[i], "n")) {
- partpos = sprintf(part, "%s", user->nick);
- } else if(!strcmp(argv[i], "a")) {
- partpos = sprintf(part, "%s", ((user->flags & USERFLAG_ISAUTHED) ? user->auth : ""));
- } else if(!strcmp(argv[i], "access")) {
- if(chan)
- partpos = sprintf(part, "%d", getChannelAccess(user, chan));
- }
- } else {
- partpos = sprintf(part, "%s", argv[i]);
- escape_param = 0;
- }
- //escape shell argument
- command[commandpos++] = ' ';
- if(escape_param) {
- command[commandpos++] = '\'';
- for(j = 0; j < partpos; j++) {
- if(part[j] == '\'') {
- command[commandpos++] = '\'';
- command[commandpos++] = '\\';
- command[commandpos++] = '\'';
- command[commandpos++] = '\'';
- } else
- command[commandpos++] = part[j];
- }
- command[commandpos++] = '\'';
- } else
- commandpos += sprintf(command + commandpos, " %s", part);
- }
- command[commandpos] = '\0';
- //we should now have a valid command
-
- struct neonserv_cmd_extscript_cache *cache = malloc(sizeof(*cache));
- if (!cache) {
- perror("malloc() failed");
- return;
- }
- cache->client = client;
- cache->textclient = getTextBot();
- cache->event = event;
- cache->user = user;
- cache->chan = chan;
- cache->answere_channel = answere_channel;
- cache->pipe = popen(command, "r");
- #ifndef WIN32
- fcntl(fileno(cache->pipe), F_SETFL, O_NONBLOCK);
- #endif
- timeq_uadd(200, neonserv_cmd_extscript_callback, cache);
-}
-
-static TIMEQ_CALLBACK(neonserv_cmd_extscript_callback) {
- struct neonserv_cmd_extscript_cache *cache = data;
- char command[512];
- char *a;
- if(feof(cache->pipe)) {
- pclose(cache->pipe);
- free(cache);
- return;
- }
- while (fgets(command, 512, cache->pipe) != NULL) {
- if((a = strchr(command, '\n')))
- *a = '\0';
- if(!stricmp(command, "/log")) {
- logEvent(cache->event);
- continue;
- }
- if(cache->answere_channel)
- putsock(cache->client, "PRIVMSG %s :%s", cache->chan->name, command);
- else
- reply(cache->textclient, cache->user, "%s", command);
- }
- timeq_uadd(200, neonserv_cmd_extscript_callback, cache);
-}
-
-
-
+++ /dev/null
-/* cmd_neonserv_giveowner.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* argv[0] - nick / *auth
-* argv[1] - key
-*/
-
-#define GIVEOWNER_TIMEOUT 86400 /* 60*60*24 = 86400 */
-
-static USERAUTH_CALLBACK(neonserv_cmd_giveowner_nick_lookup);
-static void neonserv_cmd_giveowner_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nick, char *auth, char *key);
-
-struct neonserv_cmd_giveowner_cache {
- struct ClientSocket *client, *textclient;
- struct UserNode *user;
- struct ChanNode *chan;
- struct Event *event;
- char *nick;
- char *key;
-};
-
-CMD_BIND(neonserv_cmd_giveowner) {
- MYSQL_RES *res;
- MYSQL_ROW row;
- printf_mysql_query("SELECT `channel_lastgiveowner` FROM `channels` WHERE `channel_id` = '%d'", chan->channel_id);
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) == NULL) return;
- if(strcmp(row[0], "0") && (atoi(row[0]) + GIVEOWNER_TIMEOUT) > time(0)) {
- char timeBuf[MAXLEN];
- reply(getTextBot(), user, "NS_GIVEOWNER_TIMEOUT", timeToStr(user, (GIVEOWNER_TIMEOUT - (time(0) - atoi(row[0]))), 2, timeBuf), chan->name);
- return;
- }
- if(argv[0][0] == '*') {
- //we've got an auth
- argv[0]++;
- neonserv_cmd_giveowner_async1(client, getTextBot(), user, chan, event, argv[0], argv[0], (argc != 1 ? argv[1] : NULL));
- } else {
- struct UserNode *cuser = getUserByNick(argv[0]);
- if(!cuser) {
- cuser = createTempUser(argv[0]);
- if(!cuser) {
- reply(getTextBot(), user, "NS_USER_UNKNOWN", argv[0]);
- return;
- }
- cuser->flags |= USERFLAG_ISTMPUSER;
- }
- if(cuser->flags & USERFLAG_ISAUTHED) {
- neonserv_cmd_giveowner_async1(client, getTextBot(), user, chan, event, argv[0], cuser->auth, (argc != 1 ? argv[1] : NULL));
- } else {
- struct neonserv_cmd_giveowner_cache *cache = malloc(sizeof(*cache));
- if (!cache) {
- perror("malloc() failed");
- return;
- }
- cache->client = client;
- cache->textclient = getTextBot();
- cache->user = user;
- cache->chan = chan;
- cache->event = event;
- cache->nick = strdup(argv[0]);
- cache->key = (argc != 1 ? strdup(argv[1]) : NULL);
- get_userauth(cuser, neonserv_cmd_giveowner_nick_lookup, cache);
- }
- }
-}
-
-static USERAUTH_CALLBACK(neonserv_cmd_giveowner_nick_lookup) {
- struct neonserv_cmd_giveowner_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_giveowner_async1(cache->client, cache->textclient, cache->user, cache->chan, cache->event, user->nick, user->auth, cache->key);
- free(cache->nick);
- if(cache->key)
- free(cache->key);
- free(cache);
-}
-
-static void neonserv_cmd_giveowner_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nick, char *auth, char *key) {
- //we've got a valid auth now...
- if(!stricmp(user->auth, auth)) {
- reply(textclient, user, "NS_GIVEOWNER_SELF");
- return;
- }
- MYSQL_RES *res;
- MYSQL_ROW row;
- printf_mysql_query("SELECT `user_user`, `dnr_timeout`, `dnr_reason`, `dnr_id` FROM `donotregister` LEFT JOIN `users` ON `dnr_user` = `user_id` WHERE `dnr_target` = '%s'", escape_string(auth));
- res = mysql_use();
- if((row = mysql_fetch_row(res)) != NULL) {
- int expire_time = atoi(row[1]);
- if(expire_time) {
- if(expire_time - time(0) <= 0) {
- printf_mysql_query("DELETE FROM `donotregister` WHERE `dnr_id` = '%s'", row[3]);
- } else {
- reply(getTextBot(), user, "NS_DNR_SET_ANONYM", auth);
- return;
- }
- } else {
- reply(getTextBot(), user, "NS_DNR_SET_ANONYM", auth);
- return;
- }
- }
- 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]);
- //check if the user is already added
- printf_mysql_query("SELECT `chanuser_access`, `chanuser_id` FROM `chanusers` WHERE `chanuser_cid` = '%d' AND `chanuser_uid` = '%d'", chan->channel_id, userid);
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) != NULL) {
- int seed = 0;
- char *tmp;
- char giveownerkey[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(giveownerkey, "%08x", seed);
- if(key && !stricmp(giveownerkey, key)) {
- //give ownership
- printf_mysql_query("UPDATE `chanusers` SET `chanuser_access` = '500' WHERE `chanuser_id` = '%s'", row[1]);
- printf_mysql_query("UPDATE `chanusers` SET `chanuser_access` = '499' WHERE `chanuser_cid` = '%d' AND `chanuser_uid` = (SELECT `user_id` FROM `users` WHERE `user_user` = '%s')", chan->channel_id, escape_string(user->auth));
- printf_mysql_query("INSERT INTO `owner_history` (`owner_history_cid`, `owner_history_from_uid`, `owner_history_to_uid`, `owner_history_time`) VALUE ('%d', (SELECT `user_id` FROM `users` WHERE `user_user` = '%s'), '%d', UNIX_TIMESTAMP())", chan->channel_id, escape_string(user->auth), userid);
- reply(textclient, user, "NS_GIVEOWNER_DONE", chan->name, auth);
- logEvent(event);
- } else {
- reply(textclient, user, "NS_GIVEOWNER_CONFIRM", auth, giveownerkey);
- }
- return;
- }
- }
- reply(textclient, user, "NS_NOT_ON_USERLIST", nick, chan->name);
-}
+++ /dev/null
-/* cmd_neonserv_halfop.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* argv[0-*] nicks
-*/
-static USERLIST_CALLBACK(neonserv_cmd_halfop_userlist_lookup);
-static void neonserv_cmd_halfop_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nicks);
-
-struct neonserv_cmd_halfop_cache {
- struct ClientSocket *client, *textclient;
- struct UserNode *user;
- struct Event *event;
- char *nicks;
-};
-
-CMD_BIND(neonserv_cmd_halfop) {
- struct neonserv_cmd_halfop_cache *cache = malloc(sizeof(*cache));
- if (!cache) {
- perror("malloc() failed");
- return;
- }
- cache->client = client;
- cache->textclient = getTextBot();
- cache->user = user;
- cache->event = event;
- cache->nicks = strdup(merge_argv(argv, 0, argc));
- get_userlist_if_invisible(chan, neonserv_cmd_halfop_userlist_lookup, cache);
-}
-
-static USERLIST_CALLBACK(neonserv_cmd_halfop_userlist_lookup) {
- struct neonserv_cmd_halfop_cache *cache = data;
- neonserv_cmd_halfop_async1(cache->client, cache->textclient, cache->user, chan, cache->event, cache->nicks);
- free(cache->nicks);
- free(cache);
-}
-
-static void neonserv_cmd_halfop_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nicks) {
- int total_users = 0, done_users = 0;
- struct UserNode *cuser;
- struct ChanUser *chanuser;
- struct ModeBuffer *modeBuf;
- modeBuf = initModeBuffer(client, chan);
- char *a, *b = nicks;
- do {
- a = strstr(b, " ");
- if(a) *a = '\0';
- total_users++;
- cuser = searchUserByNick(b);
- if(!cuser) {
- //check for an invisible user
- for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
- if(!stricmp(chanuser->user->nick, b)) {
- cuser = chanuser->user;
- break;
- }
- }
- if(!cuser) continue;
- } else {
- chanuser = getChanUser(cuser, chan);
- if(!chanuser) continue;
- }
- done_users++;
- if(chanuser->flags & CHANUSERFLAG_OPPED) continue;
- modeBufferHalfop(modeBuf, b);
- if(a) {
- b = a+1;
- }
- } while(a);
- freeModeBuffer(modeBuf);
- if(done_users == total_users)
- reply(textclient, user, "NS_HALFOP_DONE", chan->name);
- else
- reply(textclient, user, "NS_HALFOP_FAIL", client->user->nick);
- if(done_users)
- logEvent(event);
-}
+++ /dev/null
-/* cmd_neonserv_halfopall.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* argv[0] "force"
-* argv[1] (optional) nick mask
-*/
-static USERLIST_CALLBACK(neonserv_cmd_halfopall_userlist_lookup);
-static void neonserv_cmd_halfopall_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nickmask);
-
-struct neonserv_cmd_halfopall_cache {
- struct ClientSocket *client, *textclient;
- struct UserNode *user;
- struct Event *event;
- char *nickmask;
-};
-
-CMD_BIND(neonserv_cmd_halfopall) {
- struct neonserv_cmd_halfopall_cache *cache = malloc(sizeof(*cache));
- if (!cache) {
- perror("malloc() failed");
- return;
- }
- cache->client = client;
- cache->textclient = getTextBot();
- cache->user = user;
- cache->event = event;
- if(argc) {
- cache->nickmask = strdup(argv[0]);
- } else
- cache->nickmask = NULL;
- get_userlist_if_invisible(chan, neonserv_cmd_halfopall_userlist_lookup, cache);
-}
-
-static USERLIST_CALLBACK(neonserv_cmd_halfopall_userlist_lookup) {
- struct neonserv_cmd_halfopall_cache *cache = data;
- neonserv_cmd_halfopall_async1(cache->client, cache->textclient, cache->user, chan, cache->event, cache->nickmask);
- if(cache->nickmask)
- free(cache->nickmask);
- free(cache);
-}
-
-static void neonserv_cmd_halfopall_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nickmask) {
- int done_users = 0;
- struct ChanUser *chanuser;
- struct ModeBuffer *modeBuf;
- modeBuf = initModeBuffer(client, chan);
- for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
- if(nickmask && match(nickmask, chanuser->user->nick)) continue;
- if(chanuser->flags & CHANUSERFLAG_OPPED) continue;
- modeBufferHalfop(modeBuf, chanuser->user->nick);
- done_users++;
- }
- freeModeBuffer(modeBuf);
- reply(textclient, user, "NS_HALFOPALL_DONE", done_users, chan->name);
- if(done_users)
- logEvent(event);
-}
+++ /dev/null
-/* cmd_neonserv_help.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* argv[0-*] index
-*/
-
-CMD_BIND(neonserv_cmd_help) {
- char *ident;
- if(argc)
- ident = merge_argv(argv, 0, argc);
- else
- ident = "0";
- MYSQL_RES *res;
- MYSQL_ROW row;
- printf_mysql_query("SELECT `user_lang` FROM `users` WHERE `user_user` = '%s'", escape_string(user->auth));
- res = mysql_use();
- char *lang;
- if ((row = mysql_fetch_row(res)) != NULL)
- lang = row[0];
- else
- lang = "en";
- printf_mysql_query("SELECT `text` FROM `help` WHERE `lang` = '%s' AND `ident` = '%s'", escape_string(lang), escape_string(ident));
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) == NULL) {
- if(stricmp(lang, "en")) {
- printf_mysql_query("SELECT `text` FROM `help` WHERE `lang` = 'en' AND `ident` = '%s'", escape_string(ident));
- res = mysql_use();
- }
- if ((row = mysql_fetch_row(res)) == NULL) {
- reply(getTextBot(), user, "NS_HELP_TOPIC");
- return;
- }
- }
- char sendBuf[MAXLEN];
- int sendBufPos = 0;
- int i;
- for(i = 0; i < strlen(row[0]); i++) {
- switch(row[0][i]) {
- case '\n':
- if(sendBufPos) {
- sendBuf[sendBufPos] = '\0';
- reply(getTextBot(), user, "%s", sendBuf);
- sendBufPos = 0;
- }
- break;
- case '$':
- switch(row[0][i+1]) {
- case 'b':
- sendBuf[sendBufPos++] = 2;
- i++;
- break;
- case 'k':
- sendBuf[sendBufPos++] = 3;
- i++;
- break;
- case 'u':
- sendBuf[sendBufPos++] = 31;
- i++;
- break;
- case 'C':
- case 'S':
- sendBufPos += sprintf(sendBuf + sendBufPos, "%s", client->user->nick);
- i++;
- break;
- default:
- sendBuf[sendBufPos++] = '$';
- break;
- }
- break;
- default:
- sendBuf[sendBufPos++] = row[0][i];
- break;
- }
- }
- if(sendBufPos) {
- sendBuf[sendBufPos] = '\0';
- reply(getTextBot(), user, "%s", sendBuf);
- sendBufPos = 0;
- }
-}
+++ /dev/null
-/* cmd_neonserv_info.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* no parameters
-*/
-
-CMD_BIND(neonserv_cmd_info) {
- MYSQL_RES *res;
- MYSQL_ROW row, row2;
- struct Table *table;
- printf_mysql_query("SELECT `channel_defaulttopic`, `channel_modes`, `channel_maxusers`, `channel_lastvisit`, `channel_registered`, `user_user` FROM `channels` LEFT JOIN `users` ON `channel_registrator` = `user_id` WHERE `channel_id` = '%d'", chan->channel_id);
- res = mysql_use();
- row = mysql_fetch_row(res);
- table = table_init(2, 9, 0);
- table_set_bold(table, 0, 1);
- char *content[2];
- reply(getTextBot(), user, "NS_INFO_HEADER", chan->name);
- content[0] = get_language_string(user, "NS_INFO_DEFAULTTOPIC");
- content[1] = row[0];
- table_add(table, content);
- content[0] = get_language_string(user, "NS_INFO_MODELOCK");
- content[1] = row[1];
- table_add(table, content);
- content[0] = get_language_string(user, "NS_INFO_RECORD");
- content[1] = row[2];
- table_add(table, content);
- printf_mysql_query("SELECT `user_user`, `chanuser_access` FROM `chanusers` LEFT JOIN `users` ON `user_id` = `chanuser_uid` WHERE `chanuser_cid` = '%d'", chan->channel_id);
- res = mysql_use();
- char ownerstr[MAXLEN];
- int ownerpos = 0, usercount = 0;
- int userisowner = 0;
- while((row2 = mysql_fetch_row(res))) {
- if(!strcmp(row2[1], "500")) {
- ownerpos += sprintf(ownerstr + ownerpos, (ownerpos ? ", %s" : "%s"), row2[0]);
- if((user->flags & USERFLAG_ISAUTHED) && !stricmp(row2[0], user->auth))
- userisowner = 1;
- }
- usercount++;
- }
- content[0] = get_language_string(user, "NS_INFO_OWNER");
- content[1] = ownerstr;
- table_add(table, content);
- sprintf(ownerstr, "%d", usercount);
- content[0] = get_language_string(user, "NS_INFO_USERS");
- content[1] = ownerstr;
- table_add(table, content);
- printf_mysql_query("SELECT COUNT(*) FROM `bans` WHERE `ban_channel` = '%d'", chan->channel_id);
- res = mysql_use();
- row2 = mysql_fetch_row(res);
- content[0] = get_language_string(user, "NS_INFO_BANS");
- content[1] = row2[0];
- table_add(table, content);
- content[0] = get_language_string(user, "NS_INFO_VISITED");
- content[1] = timeToStr(user, time(0) - atoi(row[3]), 2, ownerstr);
- table_add(table, content);
- if(strcmp(row[4], "0")) {
- content[0] = get_language_string(user, "NS_INFO_REGISTERED");
- content[1] = timeToStr(user, time(0) - atoi(row[4]), 2, ownerstr);
- table_add(table, content);
- }
- if(row[5] && isGodMode(user)) {
- content[0] = get_language_string(user, "NS_INFO_REGISTRAR");
- content[1] = row[5];
- table_add(table, content);
- }
- char **table_lines = table_end(table);
- int i;
- for(i = 0; i < table->entrys; i++) {
- reply(getTextBot(), user, table_lines[i]);
- }
- table_free(table);
- if(userisowner || isGodMode(user)) {
- printf_mysql_query("SELECT `owner_history_time`, a.`user_user`, b.`user_user` FROM `owner_history` LEFT JOIN `users` a ON `owner_history_from_uid` = a.`user_id` LEFT JOIN `users` b ON `owner_history_to_uid` = b.`user_id` WHERE `owner_history_cid` = '%d'", chan->channel_id);
- res = mysql_use();
- if(mysql_num_rows(res)) {
- reply(getTextBot(), user, "NS_INFO_OWNERLOG", chan->name);
- time_t rawtime;
- struct tm *timeinfo;
- char timeBuf[80];
- while((row = mysql_fetch_row(res))) {
- rawtime = (time_t) atol(row[0]);
- timeinfo = localtime(&rawtime);
- strftime(timeBuf, 80, "%c", timeinfo);
- reply(getTextBot(), user, "NS_INFO_OWNERCHANGE", row[1], row[2], timeBuf);
- }
- }
- }
-}
+++ /dev/null
-/* cmd_neonserv_invite.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* argv[0] - nick / *auth
-*/
-static USERAUTH_CALLBACK(neonserv_cmd_invite_nick_lookup);
-static void neonserv_cmd_invite_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nick, char *auth);
-static TIMEQ_CALLBACK(neonserv_cmd_invite_timeout_timeout);
-static struct neonserv_cmd_invite_timeout* neonserv_cmd_invite_add_timeout(char *nick, char *chan);
-static int neonserv_cmd_invite_is_timeout(char *nick, char *chan);
-static void neonserv_cmd_invite_del_timeout(struct neonserv_cmd_invite_timeout *timeout);
-
-
-struct neonserv_cmd_invite_cache {
- struct ClientSocket *client, *textclient;
- struct UserNode *user;
- struct ChanNode *chan;
- struct Event *event;
- char *nick;
-};
-
-struct neonserv_cmd_invite_timeout {
- char *nick;
- char *chan;
-
- struct neonserv_cmd_invite_timeout *next;
-};
-
-static struct neonserv_cmd_invite_timeout *first_timeout = NULL, *last_timeout = NULL;
-
-CMD_BIND(neonserv_cmd_invite) {
- if(neonserv_cmd_invite_is_timeout(argv[0], chan->name)) {
- reply(getTextBot(), user, "NS_INVITE_TIMEOUT", argv[0], chan->name);
- return;
- }
- struct UserNode *cuser = getUserByNick(argv[0]);
- if(!cuser) {
- cuser = createTempUser(argv[0]);
- if(!cuser) {
- reply(getTextBot(), user, "NS_USER_UNKNOWN", argv[0]);
- return;
- }
- cuser->flags |= USERFLAG_ISTMPUSER;
- } else if(getChanUser(cuser, chan)) {
- reply(getTextBot(), user, "NS_INVITE_ON_CHAN", cuser->nick, chan->name);
- /* BUG
- This check does not work if the user is invisible (CHMODE +D/+d)
- to fix this we'd need to request the full userlist...
- this is really senseless to invite a simple user so we simply mark this bug as unsolvable.
- */
- return;
- }
- if(cuser->flags & USERFLAG_ISAUTHED) {
- neonserv_cmd_invite_async1(client, getTextBot(), user, chan, event, argv[0], cuser->auth);
- } else {
- struct neonserv_cmd_invite_cache *cache = malloc(sizeof(*cache));
- if (!cache) {
- perror("malloc() failed");
- return;
- }
- cache->client = client;
- cache->textclient = getTextBot();
- cache->user = user;
- cache->chan = chan;
- cache->event = event;
- cache->nick = strdup(argv[0]);
- get_userauth(cuser, neonserv_cmd_invite_nick_lookup, cache);
- }
-}
-
-static USERAUTH_CALLBACK(neonserv_cmd_invite_nick_lookup) {
- struct neonserv_cmd_invite_cache *cache = data;
- if(!user) {
- //USER_DOES_NOT_EXIST
- reply(cache->textclient, cache->user, "NS_USER_UNKNOWN", cache->nick);
- } else
- neonserv_cmd_invite_async1(cache->client, cache->textclient, cache->user, cache->chan, cache->event, user->nick, ((user->flags & USERFLAG_ISAUTHED) ? user->auth : NULL));
- free(cache->nick);
- free(cache);
-}
-
-static void neonserv_cmd_invite_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nick, char *auth) {
- if(auth) {
- MYSQL_RES *res;
- MYSQL_ROW row;
- 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) {
- //check if the user has set noinvite
- printf_mysql_query("SELECT `id` FROM `noinvite` WHERE `uid` = '%s' AND `cid` = '%d'", row[0], chan->channel_id);
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) != NULL) {
- reply(textclient, user, "NS_INVITE_RESTRICTION", nick, chan->name);
- return;
- }
- }
- }
- struct neonserv_cmd_invite_timeout *timeout = neonserv_cmd_invite_add_timeout(nick, chan->name);
- timeq_add(INVITE_TIMEOUT, neonserv_cmd_invite_timeout_timeout, timeout);
- putsock(client, "INVITE %s %s", nick, chan->name);
- struct UserNode *tmpu = getUserByNick(nick);
- if(!tmpu) {
- tmpu = createTempUser(nick);
- tmpu->flags |= USERFLAG_ISTMPUSER | (auth ? USERFLAG_ISAUTHED : 0);
- if(auth)
- strcpy(tmpu->auth, auth);
- }
- reply(textclient, tmpu, "NS_INVITE_DONE_USER", chan->name, user->nick, client->user->nick);
- reply(textclient, user, "NS_INVITE_DONE", nick, chan->name);
-}
-
-static TIMEQ_CALLBACK(neonserv_cmd_invite_timeout_timeout) {
- struct neonserv_cmd_invite_timeout *entry = data;
- neonserv_cmd_invite_del_timeout(entry);
-}
-
-static struct neonserv_cmd_invite_timeout* neonserv_cmd_invite_add_timeout(char *nick, char *chan) {
- struct neonserv_cmd_invite_timeout *entry = malloc(sizeof(*entry));
- if (!entry) {
- perror("malloc() failed");
- return NULL;
- }
- entry->next = NULL;
- entry->nick = strdup(nick);
- entry->chan = strdup(chan);
- if(last_timeout) {
- last_timeout->next = entry;
- last_timeout = entry;
- } else {
- last_timeout = entry;
- first_timeout = entry;
- }
- return entry;
-}
-
-static int neonserv_cmd_invite_is_timeout(char *nick, char *chan) {
- if(!first_timeout) return 0;
- struct neonserv_cmd_invite_timeout *entry;
- for(entry = first_timeout; entry; entry = entry->next) {
- if(!stricmp(entry->nick, nick) && !stricmp(entry->chan, chan))
- return 1;
- }
- return 0;
-}
-
-static void neonserv_cmd_invite_del_timeout(struct neonserv_cmd_invite_timeout *timeout) {
- struct neonserv_cmd_invite_timeout *entry, *prev = NULL;
- for(entry = first_timeout; entry; entry = entry->next) {
- if(entry == timeout) {
- if(prev)
- prev->next = entry->next;
- else
- first_timeout = entry->next;
- break;
- } else
- prev = entry;
- }
- if(last_timeout == timeout)
- last_timeout = prev;
- free(timeout->nick);
- free(timeout->chan);
- free(timeout);
-}
+++ /dev/null
-/* cmd_neonserv_inviteme.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* no arguments
-*/
-
-CMD_BIND(neonserv_cmd_inviteme) {
- if(getChanUser(user, chan)) {
- reply(getTextBot(), user, "NS_INVITEME_ON_CHAN", chan->name);
- /* BUG
- This check does not work if the user is invisible (CHMODE +D/+d)
- to fix this we'd need to request the full userlist...
- this is really senseless to invite a simple user so we simply mark this bug as unsolvable.
- */
- return;
- }
- putsock(client, "INVITE %s %s", user->nick, chan->name);
- reply(getTextBot(), user, "NS_INVITEME_DONE", chan->name);
-}
+++ /dev/null
-/* cmd_neonserv_kick.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* argv[0] nick[,*auth[,*!*@mask[...]]]
-* argv[1-*] reason
-*/
-static USERLIST_CALLBACK(neonserv_cmd_kick_userlist_lookup);
-static void neonserv_cmd_kick_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nicks, char *reason);
-
-struct neonserv_cmd_kick_cache {
- struct ClientSocket *client, *textclient;
- struct UserNode *user;
- struct Event *event;
- char *nicks;
- char *reason;
-};
-
-CMD_BIND(neonserv_cmd_kick) {
- struct neonserv_cmd_kick_cache *cache = malloc(sizeof(*cache));
- if (!cache) {
- perror("malloc() failed");
- return;
- }
- cache->client = client;
- cache->textclient = getTextBot();
- cache->user = user;
- cache->event = event;
- cache->nicks = strdup(argv[0]);
- if(argc > 1) {
- cache->reason = strdup(merge_argv(argv, 1, argc));
- } else
- cache->reason = NULL;
- get_userlist_with_invisible(chan, neonserv_cmd_kick_userlist_lookup, cache);
-}
-
-static USERLIST_CALLBACK(neonserv_cmd_kick_userlist_lookup) {
- struct neonserv_cmd_kick_cache *cache = data;
- neonserv_cmd_kick_async1(cache->client, cache->textclient, cache->user, chan, cache->event, cache->nicks, (cache->reason ? cache->reason : "Bye."));
- free(cache->nicks);
- if(cache->reason)
- free(cache->reason);
- free(cache);
-}
-
-static void neonserv_cmd_kick_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nicks, char *reason) {
- int i, kicked_users = 0, provided_nicks = 0;
- char *nick, *nextnick;
- struct UserNode *cuser;
- struct ChanUser *chanuser;
- nextnick = nicks;
- while((nick = nextnick)) {
- nextnick = strstr(nick, ",");
- if(nextnick) {
- *nextnick = '\0';
- nextnick++;
- }
- if(!*nick) continue;
- if(is_ircmask(nick)) {
- //KICK HOSTMASK
- char usermask[NICKLEN+USERLEN+HOSTLEN+3];
- struct ChanUser *kick_chanuser[chan->usercount];
- int kick_chanuser_pos = 0;
- for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
- cuser = chanuser->user;
- sprintf(usermask, "%s!%s@%s", cuser->nick, cuser->ident, cuser->host);
- if(!match(nick, usermask)) {
- provided_nicks++;
- if(isNetworkService(chanuser->user)) {
- reply(textclient, user, "NS_SERVICE_IMMUNE", chanuser->user->nick);
- continue;
- }
- if(cuser == user || ((cuser->flags & USERFLAG_ISAUTHED) && !stricmp(user->auth, cuser->auth))) {
- reply(textclient, user, "NS_YOU_PROTECTED");
- continue;
- }
- if(isUserProtected(chan, cuser, user)) {
- reply(textclient, user, "NS_USER_PROTECTED", cuser->nick);
- continue;
- }
- kick_chanuser[kick_chanuser_pos++] = chanuser;
- if(kick_chanuser_pos > 4 && (kick_chanuser_pos * 3) > chan->usercount && !isGodMode(user)) {
- kick_chanuser_pos = 0;
- reply(textclient, user, "NS_LAME_MASK", nick);
- break;
- }
- }
- }
- for(i = 0; i < kick_chanuser_pos; i++) {
- kicked_users++;
- putsock(client, "KICK %s %s :(%s) %s", chan->name, kick_chanuser[i]->user->nick, user->nick, reason);
- }
- } else if(*nick == '*') {
- //KICK AUTH
- nick++;
- cuser = NULL;
- if(!stricmp(user->auth, nick)) {
- reply(textclient, user, "NS_YOU_PROTECTED");
- continue;
- }
- for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
- if((chanuser->user->flags & USERFLAG_ISAUTHED) && !stricmp(chanuser->user->auth, nick)) {
- provided_nicks++;
- if(isNetworkService(chanuser->user)) {
- reply(textclient, user, "NS_SERVICE_IMMUNE", chanuser->user->nick);
- continue;
- }
- if(!cuser) {
- //check if the user is protected
- if(isUserProtected(chan, chanuser->user, user)) {
- reply(textclient, user, "NS_USER_PROTECTED", chanuser->user->nick);
- break; //all other users are also protected...
- }
- cuser = chanuser->user;
- }
- kicked_users++;
- putsock(client, "KICK %s %s :(%s) %s", chan->name, cuser->nick, user->nick, reason);
- }
- }
- } else {
- provided_nicks++;
- cuser = NULL;
- for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
- if(!stricmp(chanuser->user->nick, nick)) {
- cuser = chanuser->user;
- }
- }
- if(!cuser) continue;
- if(isNetworkService(cuser)) {
- reply(textclient, user, "NS_SERVICE_IMMUNE", cuser->nick);
- continue;
- }
- if(cuser == user || ((cuser->flags & USERFLAG_ISAUTHED) && !stricmp(user->auth, cuser->auth))) {
- reply(textclient, user, "NS_YOU_PROTECTED");
- continue;
- }
- if(isUserProtected(chan, cuser, user)) {
- reply(textclient, user, "NS_USER_PROTECTED", cuser->nick);
- continue;
- }
- kicked_users++;
- putsock(client, "KICK %s %s :(%s) %s", chan->name, cuser->nick, user->nick, reason);
- }
- }
- if(kicked_users == provided_nicks)
- reply(getTextBot(), user, "NS_KICK_DONE", kicked_users, chan->name);
- else
- reply(getTextBot(), user, "NS_KICK_FAIL", client->user->nick);
- if(kicked_users)
- logEvent(event);
-}
+++ /dev/null
-/* cmd_neonserv_kickban.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* argv[0] nick[,*auth[,*!*@mask[...]]]
-* argv[1-*] reason
-*/
-static USERLIST_CALLBACK(neonserv_cmd_kickban_userlist_lookup);
-static void neonserv_cmd_kickban_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nicks, char *reason);
-
-struct neonserv_cmd_kickban_cache {
- struct ClientSocket *client, *textclient;
- struct UserNode *user;
- struct Event *event;
- char *nicks;
- char *reason;
-};
-
-CMD_BIND(neonserv_cmd_kickban) {
- struct neonserv_cmd_kickban_cache *cache = malloc(sizeof(*cache));
- if (!cache) {
- perror("malloc() failed");
- return;
- }
- cache->client = client;
- cache->textclient = getTextBot();
- cache->user = user;
- cache->event = event;
- cache->nicks = strdup(argv[0]);
- if(argc > 1) {
- cache->reason = strdup(merge_argv(argv, 1, argc));
- } else
- cache->reason = NULL;
- get_userlist_with_invisible(chan, neonserv_cmd_kickban_userlist_lookup, cache);
-}
-
-static USERLIST_CALLBACK(neonserv_cmd_kickban_userlist_lookup) {
- struct neonserv_cmd_kickban_cache *cache = data;
- neonserv_cmd_kickban_async1(cache->client, cache->textclient, cache->user, chan, cache->event, cache->nicks, (cache->reason ? cache->reason : "Bye."));
- free(cache->nicks);
- if(cache->reason)
- free(cache->reason);
- free(cache);
-}
-
-static void neonserv_cmd_kickban_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nicks, char *reason) {
- int i, kicked_users = 0, provided_nicks = 0;
- char *nick, *nextnick;
- struct UserNode *cuser;
- struct ChanUser *chanuser;
- char usermask[NICKLEN+USERLEN+HOSTLEN+3];
- nextnick = nicks;
- while((nick = nextnick)) {
- nextnick = strstr(nick, ",");
- if(nextnick) {
- *nextnick = '\0';
- nextnick++;
- }
- if(!*nick) continue;
- if(is_ircmask(nick)) {
- //KICK HOSTMASK
- struct ChanUser *kickban_chanuser[chan->usercount];
- int kick_chanuser_pos = 0;
- for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
- cuser = chanuser->user;
- sprintf(usermask, "%s!%s@%s", cuser->nick, cuser->ident, cuser->host);
- if(!match(nick, usermask)) {
- provided_nicks++;
- if(isNetworkService(chanuser->user)) {
- reply(textclient, user, "NS_SERVICE_IMMUNE", chanuser->user->nick);
- continue;
- }
- if(cuser == user || ((cuser->flags & USERFLAG_ISAUTHED) && !stricmp(user->auth, cuser->auth))) {
- reply(textclient, user, "NS_YOU_PROTECTED");
- continue;
- }
- if(isUserProtected(chan, cuser, user)) {
- reply(textclient, user, "NS_USER_PROTECTED", cuser->nick);
- continue;
- }
- kickban_chanuser[kick_chanuser_pos++] = chanuser;
- if(kick_chanuser_pos > 4 && (kick_chanuser_pos * 3) > chan->usercount && !isGodMode(user)) {
- kick_chanuser_pos = 0;
- reply(textclient, user, "NS_LAME_MASK", nick);
- break;
- }
- }
- }
- for(i = 0; i < kick_chanuser_pos; i++) {
- if(i == 0) {
- putsock(client, "MODE %s +b %s", chan->name, nick);
- }
- kicked_users++;
- putsock(client, "KICK %s %s :(%s) %s", chan->name, kickban_chanuser[i]->user->nick, user->nick, reason);
- }
- } else if(*nick == '*') {
- //KICK AUTH
- nick++;
- cuser = NULL;
- if(!stricmp(user->auth, nick)) {
- reply(textclient, user, "NS_YOU_PROTECTED");
- continue;
- }
- for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
- if((chanuser->user->flags & USERFLAG_ISAUTHED) && !stricmp(chanuser->user->auth, nick)) {
- provided_nicks++;
- if(isNetworkService(chanuser->user)) {
- reply(textclient, user, "NS_SERVICE_IMMUNE", chanuser->user->nick);
- continue;
- }
- if(!cuser) {
- //check if the user is protected
- if(isUserProtected(chan, chanuser->user, user)) {
- reply(textclient, user, "NS_USER_PROTECTED", chanuser->user->nick);
- break; //all other users are also protected...
- }
- cuser = chanuser->user;
- }
- kicked_users++;
- putsock(client, "MODE %s +b %s", chan->name, generate_banmask(cuser, usermask));
- putsock(client, "KICK %s %s :(%s) %s", chan->name, cuser->nick, user->nick, reason);
- }
- }
- } else {
- provided_nicks++;
- cuser = searchUserByNick(nick);
- if(!cuser) continue;
- chanuser = getChanUser(cuser, chan);
- if(!chanuser) continue;
- if(isNetworkService(cuser)) {
- reply(textclient, user, "NS_SERVICE_IMMUNE", cuser->nick);
- continue;
- }
- if(cuser == user || ((cuser->flags & USERFLAG_ISAUTHED) && !stricmp(user->auth, cuser->auth))) {
- reply(textclient, user, "NS_YOU_PROTECTED");
- continue;
- }
- if(isUserProtected(chan, cuser, user)) {
- reply(textclient, user, "NS_USER_PROTECTED", cuser->nick);
- continue;
- }
- kicked_users++;
- putsock(client, "MODE %s +b %s", chan->name, generate_banmask(cuser, usermask));
- putsock(client, "KICK %s %s :(%s) %s", chan->name, cuser->nick, user->nick, reason);
- }
- }
- if(kicked_users == provided_nicks)
- reply(getTextBot(), user, "NS_KICKBAN_DONE", kicked_users, chan->name);
- else
- reply(getTextBot(), user, "NS_KICKBAN_FAIL", client->user->nick);
- if(kicked_users)
- logEvent(event);
-}
+++ /dev/null
-/* cmd_neonserv_listrank.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* no arguments
-*/
-
-CMD_BIND(neonserv_cmd_listrank) {
- MYSQL_RES *res, *res2;
- MYSQL_ROW row, row2;
- struct Table *table;
- int ranks = 0;
- printf_mysql_query("SELECT `rank_id`, `rank_name` FROM `support_ranks` ORDER BY `rank_order` ASC");
- res = mysql_use();
- table = table_init(3, mysql_num_rows(res) + 1, 0);
- char *content[3];
- content[0] = get_language_string(user, "NS_LISTRANK_ID");
- content[1] = get_language_string(user, "NS_LISTRANK_NAME");
- content[2] = get_language_string(user, "NS_LISTRANK_ASSIGNED");
- table_add(table, content);
- char usersBuf[MAXLEN];
- int usersPos, userCount;
- char assignedBuf[MAXLEN];
- while ((row = mysql_fetch_row(res)) != NULL) {
- ranks++;
- content[0] = row[0];
- content[1] = row[1];
- printf_mysql_query("SELECT `user_user`, `user_god` FROM `users` WHERE `user_rank` = '%s'", row[0]);
- res2 = mysql_use();
- usersPos = 0;
- userCount = 0;
- while((row2 = mysql_fetch_row(res2)) != NULL) {
- usersPos += sprintf(usersBuf+usersPos, (usersPos ? ", %s%s" : "%s%s"), (strcmp(row2[1], "0") ? "@" : ""), row2[0]);
- userCount++;
- }
- sprintf(assignedBuf, (userCount ? "%d (%s)" : "%d"), userCount, usersBuf);
- content[2] = assignedBuf;
- table_add(table, content);
- }
- //send the table
- char **table_lines = table_end(table);
- int i;
- for(i = 0; i < table->entrys; i++) {
- reply(getTextBot(), user, table_lines[i]);
- }
- if(!ranks)
- reply(getTextBot(), user, "NS_TABLE_NONE");
- table_free(table);
- printf_mysql_query("SELECT `user_user` FROM `users` WHERE `user_rank` = '0' AND `user_access` > 0");
- res2 = mysql_use();
- usersPos = 0;
- userCount = 0;
- while((row2 = mysql_fetch_row(res2)) != NULL) {
- usersPos += sprintf(usersBuf+usersPos, (usersPos ? ", %s%s" : "%s%s"), (strcmp(row2[1], "0") ? "@" : ""), row2[0]);
- userCount++;
- }
- reply(getTextBot(), user, "NS_LISTRANK_UNRANKED", userCount);
- if(userCount) {
- reply(getTextBot(), user, " %s", usersBuf);
- }
-}
+++ /dev/null
-/* cmd_neonserv_mdeluser.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* argv[0] access (format: minaccess-maxaccess)
-* argv[1] pattern
-*/
-
-CMD_BIND(neonserv_cmd_mdeluser) {
- int min_access, max_access;
- char *seperator = strstr(argv[0], "-");
- if(seperator) {
- *seperator = '\0';
- seperator++;
- min_access = atoi(argv[0]);
- max_access = atoi(seperator);
- if(max_access < min_access) {
- reply(getTextBot(), user, "NS_INVALID_ACCESS_RANGE", min_access, max_access);
- return;
- }
- } else {
- min_access = atoi(argv[0]);
- max_access = min_access;
- }
- if(max_access >= getChannelAccess(user, chan)) {
- if(isGodMode(user)) {
- event->flags |= CMDFLAG_OPLOG;
- } else {
- reply(getTextBot(), user, "NS_NO_ACCESS");
- return;
- }
- }
- MYSQL_RES *res;
- MYSQL_ROW row;
- int del_count = 0;
- printf_mysql_query("SELECT `user_user`, `chanuser_id` FROM `chanusers` LEFT JOIN `users` ON `chanuser_uid` = `user_id` WHERE `chanuser_cid` = '%d' AND `chanuser_access` >= '%d' AND `chanuser_access` <= '%d'", chan->channel_id, min_access, max_access);
- res = mysql_use();
- while((row = mysql_fetch_row(res)) != NULL) {
- if(!match(argv[1], row[0])) {
- del_count++;
- printf_mysql_query("DELETE FROM `chanusers` WHERE `chanuser_id` = '%s'", row[1]);
- }
- }
- reply(getTextBot(), user, "NS_MDELUSER_DONE", del_count, argv[1], min_access, max_access, chan->name);
- if(del_count)
- logEvent(event);
-}
-
+++ /dev/null
-/* cmd_neonserv_mode.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* argv[0] - modes
-* argv[1-*] - parameters
-*/
-static USERLIST_CALLBACK(neonserv_cmd_mode_userlist_lookup);
-static void neonserv_cmd_mode_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *mode);
-
-struct neonserv_cmd_mode_cache {
- struct ClientSocket *client, *textclient;
- struct UserNode *user;
- struct Event *event;
- char *mode;
-};
-
-CMD_BIND(neonserv_cmd_mode) {
- struct neonserv_cmd_mode_cache *cache = malloc(sizeof(*cache));
- if (!cache) {
- perror("malloc() failed");
- return;
- }
- cache->client = client;
- cache->textclient = getTextBot();
- cache->user = user;
- cache->event = event;
- cache->mode = strdup(merge_argv(argv, 0, argc));
- get_userlist_with_invisible(chan, neonserv_cmd_mode_userlist_lookup, cache);
-}
-
-static USERLIST_CALLBACK(neonserv_cmd_mode_userlist_lookup) {
- struct neonserv_cmd_mode_cache *cache = data;
- neonserv_cmd_mode_async1(cache->client, cache->textclient, cache->user, chan, cache->event, cache->mode);
- free(cache->mode);
- free(cache);
-}
-
-static void neonserv_cmd_mode_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *mode) {
- MYSQL_ROW row, defaults = NULL;
- int i, arg, add = 1, skip = 0;
- unsigned int modetype;
- int db_canop, db_canvoice, db_canban, db_enfmodes;
- struct ModeNode *modelock = createModeNode(NULL), *changemodes = createModeNode(NULL);
- struct ModeBuffer *modeBuf;
- struct UserNode *cuser;
- struct ChanUser *chanuser;
- modeBuf = initModeBuffer(client, chan);
- printf_mysql_query("SELECT `channel_canop`, `channel_canvoice`, `channel_canban`, `channel_enfmodes`, `channel_modes` FROM `channels` WHERE `channel_id` = '%d'", chan->channel_id);
- row = mysql_fetch_row(mysql_use());
- if(row[0] == NULL || row[1] == NULL || row[2] == NULL || row[3] == NULL) {
- printf_mysql_query("SELECT `channel_canop`, `channel_canvoice`, `channel_canban`, `channel_enfmodes`, `channel_modes` FROM `channels` WHERE `channel_name` = 'defaults'");
- defaults = mysql_fetch_row(mysql_use());
- }
- db_canop = atoi((row[0] ? row[0] : defaults[0]));
- db_canvoice = atoi((row[1] ? row[1] : defaults[1]));
- db_canban = atoi((row[2] ? row[2] : defaults[2]));
- db_enfmodes = atoi((row[3] ? row[3] : defaults[3]));
- if(row[4])
- parseModeString(modelock, row[4]);
- else if(defaults[4])
- parseModeString(modelock, defaults[4]);
- int uaccess = getChannelAccess(user, chan);
- char *a, *b = mode;
- char *argv[MAXNUMPARAMS];
- char *carg;
- char tmp[MAXLEN];
- int argc = 0;
- do {
- a = strstr(b, " ");
- if(a) *a = '\0';
- argv[argc++] = b;
- if(argc == MAXNUMPARAMS) break;
- if(a) b = a+1;
- } while(a);
- arg = 0;
- while(arg < argc) {
- char *modeStr = argv[arg++];
- for(i = 0; i < strlen(modeStr); i++) {
- switch(modeStr[i]) {
- case '+':
- add = 1;
- break;
- case '-':
- add = 0;
- break;
- case 'o':
- case 'v':
- if(arg == argc) {
- reply(textclient, user, "NS_MODE_INVALID", modeStr[i]);
- return;
- }
- carg = argv[arg++];
- if(modeStr[i] == 'o') {
- if(uaccess < db_canop) {
- reply(textclient, user, "NS_MODE_ENFOPS", chan->name);
- db_canop = -1;
- break;
- }
- if(db_canop == -1) break;
- } else {
- if(uaccess < db_canvoice) {
- reply(textclient, user, "NS_MODE_ENFVOICE", chan->name);
- db_canvoice = -1;
- break;
- }
- if(db_canvoice == -1) break;
- }
- cuser = searchUserByNick(carg);
- if(!cuser) {
- //check for an invisible user
- for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
- if(!stricmp(chanuser->user->nick, carg)) {
- cuser = chanuser->user;
- break;
- }
- }
- if(!cuser) break;
- } else {
- chanuser = getChanUser(cuser, chan);
- if(!chanuser) break;
- }
- if(!(add ^ (chanuser->flags & (modeStr[i] == 'o' ? CHANUSERFLAG_OPPED : CHANUSERFLAG_VOICED)))) break;
- if(!add) {
- //check protection
- if(modeStr[i] == 'o' && isNetworkService(cuser)) {
- reply(textclient, user, "NS_SERVICE_IMMUNE", cuser->nick);
- break;
- }
- if(isUserProtected(chan, cuser, user)) {
- reply(textclient, user, "NS_USER_PROTECTED", cuser->nick);
- break;
- }
- }
- modeBufferSet(modeBuf, add, modeStr[i], carg);
- break;
- case 'b':
- if(arg == argc) {
- reply(textclient, user, "NS_MODE_INVALID", modeStr[i]);
- return;
- }
- carg = argv[arg++];
- if(uaccess < db_canban) {
- reply(textclient, user, "NS_MODE_CANBAN", chan->name);
- db_canban = -1;
- break;
- }
- if(db_canban == -1) break;
- char hostmask_buffer[NICKLEN+USERLEN+HOSTLEN+3];
- char usermask[NICKLEN+USERLEN+HOSTLEN+3];
- struct BanNode *ban;
- int match_count = 0;
- carg = make_banmask(carg, hostmask_buffer);
- if(add) {
- for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
- cuser = chanuser->user;
- sprintf(usermask, "%s!%s@%s", cuser->nick, cuser->ident, cuser->host);
- if(!match(carg, usermask)) {
- if(isNetworkService(chanuser->user)) {
- reply(textclient, user, "NS_SERVICE_IMMUNE", chanuser->user->nick);
- skip = 1;
- break;
- }
- if(isUserProtected(chan, cuser, user)) {
- reply(textclient, user, "NS_USER_PROTECTED", cuser->nick);
- skip = 1;
- break;
- }
- match_count++;
- if(match_count > 4 && (match_count * 3) > chan->usercount && !isGodMode(user)) {
- skip = 1;
- reply(textclient, user, "NS_LAME_MASK", carg);
- break;
- }
- }
- }
- } else {
- skip = 1;
- for(ban = chan->bans; ban; ban = ban->next) {
- if(!match(carg, ban->mask)) {
- skip = 0;
- break;
- }
- }
- }
- if(!skip) {
- modeBufferSet(modeBuf, add, 'b', carg);
- }
- break;
- default:
- modetype = getModeType(modelock, modeStr[i]);
- if(modetype == 0) {
- reply(textclient, user, "NS_MODE_INVALID", modeStr[i]);
- return;
- }
- if(isModeAffected(modelock, modeStr[i]) && add == !isModeSet(modelock, modeStr[i]) && uaccess < db_enfmodes) {
- if(isGodMode(user))
- event->flags |= CMDFLAG_OPLOG;
- else {
- getFullModeString(modelock, tmp);
- reply(textclient, user, "NS_MODE_LOCKED", tmp, chan->name);
- return;
- }
- }
- if(add && (modetype & CHANNEL_MODE_TYPE) != CHANNEL_MODE_TYPE_D) {
- if(arg == argc) {
- reply(textclient, user, "NS_MODE_INVALID", modeStr[i]);
- return;
- }
- carg = argv[arg++];
- if((modetype & CHANNEL_MODE_VALUE) == CHANNEL_MODE_VALUE_STRING && isModeSet(modelock, modeStr[i])) {
- char *modelock_val = getModeValue(modelock, modeStr[i]);
- if(stricmp(carg, modelock_val)) {
- if(isGodMode(user))
- event->flags |= CMDFLAG_OPLOG;
- else {
- getFullModeString(modelock, tmp);
- reply(textclient, user, "NS_MODE_LOCKED", tmp, chan->name);
- return;
- }
- }
- }
- if((modetype & CHANNEL_MODE_VALUE) == CHANNEL_MODE_VALUE_STRING && isModeSet(modelock, modeStr[i])) {
- int *modelock_val = getModeValue(modelock, modeStr[i]);
- if(atoi(carg) != *modelock_val) {
- if(isGodMode(user))
- event->flags |= CMDFLAG_OPLOG;
- else {
- getFullModeString(modelock, tmp);
- reply(textclient, user, "NS_MODE_LOCKED", tmp, chan->name);
- return;
- }
- }
- }
- } else if(!add && (modetype & CHANNEL_MODE_TYPE) == CHANNEL_MODE_TYPE_B) {
- if(arg == argc && !(modetype & CHANNEL_MODE_KEY)) {
- reply(textclient, user, "NS_MODE_INVALID", modeStr[i]);
- return;
- }
- carg = (arg == argc ? NULL : argv[arg++]);
- } else
- carg = NULL;
- if((modetype & CHANNEL_MODE_TYPE) == CHANNEL_MODE_TYPE_D && isModeSet(chan->modes, modeStr[i]) == add)
- break;
- if(!isModeAffected(changemodes, modeStr[i])) {
- if(!add && (modetype & CHANNEL_MODE_KEY)) {
- if(isModeSet(chan->modes, modeStr[i])) {
- char *current_val = getModeValue(chan->modes, modeStr[i]);
- carg = current_val;
- }
- }
- if(parseMode(changemodes, add, modeStr[i], carg)) {
- if(carg) {
- if(add && (modetype & CHANNEL_MODE_KEY) && isModeSet(chan->modes, modeStr[i])) {
- char *current_val = getModeValue(chan->modes, modeStr[i]);
- modeBufferSet(modeBuf, 0, modeStr[i], current_val);
- flushModeBuffer(modeBuf);
- }
- if(!add && !isModeSet(chan->modes, modeStr[i])) break;
- modeBufferSet(modeBuf, add, modeStr[i], carg);
- } else {
- modeBufferSimpleMode(modeBuf, add, modeStr[i]);
- }
- } else {
- reply(textclient, user, "NS_MODE_INVALID", modeStr[i]);
- return;
- }
- }
- break;
- }
- }
- }
- getFullModeString(changemodes, tmp);
- freeModeBuffer(modeBuf);
- if(strcmp(tmp, "+"))
- reply(textclient, user, "NS_MODE_DONE", tmp);
-
- logEvent(event);
- freeModeNode(modelock);
- freeModeNode(changemodes);
-}
+++ /dev/null
-/* cmd_neonserv_move.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* argv[0] - channel
-* argv[1] - new channel
-*/
-CMD_BIND(neonserv_cmd_move) {
- MYSQL_RES *res;
- MYSQL_ROW row;
- char *channel = argv[0];
- char *new_channel = argv[1];
- if(!is_valid_chan(new_channel)) {
- reply(getTextBot(), user, "NS_INVALID_CHANNEL_NAME", new_channel);
- return;
- }
- if(!stricmp(channel, new_channel)) {
- reply(getTextBot(), user, "NS_MOVE_SELF");
- return;
- }
- printf_mysql_query("SELECT `channel_id` FROM `bot_channels` LEFT JOIN `channels` ON `channel_id` = `chanid` WHERE `channel_name` = '%s'", escape_string(new_channel));
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) != NULL) {
- reply(getTextBot(), user, "NS_REGISTER_ALREADY", new_channel, client->user->nick);
- 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 {
- reply(getTextBot(), user, "NS_UNREGISTER_NOT_REGISTERED", argv[0], client->user->nick);
- return;
- }
- printf_mysql_query("SELECT `botid`, `bot_channels`.`id`, `suspended` FROM `bot_channels` LEFT JOIN `bots` ON `bot_channels`.`botid` = `bots`.`id` WHERE `chanid` = '%d' AND `botclass` = '%d'", chanid, client->botid);
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) == NULL) {
- reply(getTextBot(), user, "NS_UNREGISTER_NOT_REGISTERED", argv[0], client->user->nick);
- return;
- }
- if(!strcmp(row[2], "1")) {
- reply(getTextBot(), user, "NS_MOVE_SUSPENDED");
- return;
- }
- int botid = atoi(row[0]);
- 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, "PART %s :Channel moved to %s.", channel, new_channel);
- putsock(bot, "JOIN %s", new_channel);
- }
- printf_mysql_query("SELECT `channel_id` FROM `channels` WHERE `channel_name` = '%s'", escape_string(new_channel));
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) != NULL) {
- chanid = atoi(row[0]);
- printf_mysql_query("DELETE FROM `chanusers` WHERE `chanuser_cid` = '%d'", chanid);
- printf_mysql_query("DELETE FROM `bans` WHERE `ban_channel` = '%d'", chanid);
- printf_mysql_query("DELETE FROM `events` WHERE `cid` = '%d'", chanid);
- printf_mysql_query("DELETE FROM `noinvite` WHERE `cid` = '%d'", chanid);
- printf_mysql_query("DELETE FROM `owner_history` WHERE `owner_history_cid` = '%d'", chanid);
- printf_mysql_query("DELETE FROM `channels` WHERE `channel_id` = '%d'", chanid);
- }
- printf_mysql_query("UPDATE `channels` SET `channel_name` = '%s' WHERE `channel_name` = '%s'", escape_string(new_channel), escape_string(channel));
- struct ChanNode *channode = getChanByName(channel);
- if(channode && channode->flags & CHANFLAG_REQUESTED_CHANINFO) {
- channode->flags &= ~CHANFLAG_CHAN_REGISTERED;
- channode->channel_id = 0;
- }
- reply(getTextBot(), user, "NS_MOVE_DONE", channel, new_channel);
- logEvent(event);
-}
+++ /dev/null
-/* cmd_neonserv_myaccess.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* argv[0] - nick / *auth
-*/
-static USERAUTH_CALLBACK(neonserv_cmd_myaccess_nick_lookup);
-static void neonserv_cmd_myaccess_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, char *nick, char *auth, char *chanmatch);
-
-struct neonserv_cmd_myaccess_cache {
- struct ClientSocket *client, *textclient;
- struct UserNode *user;
- struct ChanNode *chan;
- char *nick;
- char *chanmatch;
-};
-
-CMD_BIND(neonserv_cmd_myaccess) {
- char *chanmatch = NULL;
- if(argc == 0 || argv[0][0] == '#') {
- if(argc != 0) {
- chanmatch = argv[0];
- }
- if(!(user->flags & USERFLAG_ISAUTHED)) {
- struct neonserv_cmd_myaccess_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->chanmatch = (chanmatch ? strdup(chanmatch) : NULL);
- get_userauth(user, neonserv_cmd_myaccess_nick_lookup, cache);
- } else
- neonserv_cmd_myaccess_async1(client, getTextBot(), user, chan, user->nick, user->auth, chanmatch);
- }
- else if(argv[0][0] == '*') {
- //we've got an auth
- if(argc > 1 && argv[1][0] == '#') {
- chanmatch = argv[1];
- }
- argv[0]++;
- neonserv_cmd_myaccess_async1(client, getTextBot(), user, chan, NULL, argv[0], chanmatch);
- } else {
- if(argc > 1 && argv[1][0] == '#') {
- chanmatch = argv[1];
- }
- struct UserNode *cuser = getUserByNick(argv[0]);
- if(!cuser) {
- cuser = createTempUser(argv[0]);
- if(!cuser) {
- reply(getTextBot(), user, "NS_USER_UNKNOWN", argv[0]);
- return;
- }
- cuser->flags |= USERFLAG_ISTMPUSER;
- }
- if(cuser->flags & USERFLAG_ISAUTHED) {
- neonserv_cmd_myaccess_async1(client, getTextBot(), user, chan, argv[0], cuser->auth, chanmatch);
- } else {
- struct neonserv_cmd_myaccess_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->chanmatch = (chanmatch ? strdup(chanmatch) : NULL);
- get_userauth(cuser, neonserv_cmd_myaccess_nick_lookup, cache);
- }
- }
-}
-
-static USERAUTH_CALLBACK(neonserv_cmd_myaccess_nick_lookup) {
- struct neonserv_cmd_myaccess_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
- if(!strcmp(cache->nick, cache->user->nick))
- reply(cache->textclient, cache->user, "NS_YOU_NEED_AUTH");
- else
- reply(cache->textclient, cache->user, "NS_USER_NEED_AUTH", cache->nick);
- }
- else
- neonserv_cmd_myaccess_async1(cache->client, cache->textclient, cache->user, cache->chan, user->nick, user->auth, cache->chanmatch);
- if(cache->chanmatch)
- free(cache->chanmatch);
- free(cache->nick);
- free(cache);
-}
-
-static void neonserv_cmd_myaccess_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, char *nick, char *auth, char *chanmatch) {
- //we've got a valid auth now...
- if(stricmp(user->auth, auth) && !isGodMode(user)) {
- reply(textclient, user, "NS_MYACCESS_SELF_ONLY");
- return;
- }
- MYSQL_RES *res, *default_res;
- MYSQL_ROW user_row, chanuser_row, default_chan = NULL;
- char flagBuf[5];
- int userid, cflags, caccess, flagPos;
- int i, total_count = 0, match_count = 0, owner_count = 0;
- struct Table *table = NULL;
- printf_mysql_query("SELECT `user_id`, `user_access`, `user_god` FROM `users` WHERE `user_user` = '%s'", escape_string(auth));
- res = mysql_use();
- char *content[4];
- content[0] = get_language_string(user, "NS_MYACCESS_HEADER_NAME");
- content[1] = get_language_string(user, "NS_MYACCESS_HEADER_ACCESS");
- content[2] = get_language_string(user, "NS_MYACCESS_HEADER_FLAGS");
- content[3] = get_language_string(user, "NS_MYACCESS_HEADER_INFO");
- if(chanmatch)
- reply(textclient, user, "NS_MYACCESS_HEADER_MATCH", auth, chanmatch);
- else
- reply(textclient, user, "NS_MYACCESS_HEADER", auth);
- if ((user_row = mysql_fetch_row(res)) != NULL) {
- userid = atoi(user_row[0]);
- //check if the user is already added
- printf_mysql_query("SELECT `chanuser_access`, `chanuser_flags`, `chanuser_infoline`, `channel_name`, `channel_getop`, `channel_getvoice`, `botid` FROM `chanusers` LEFT JOIN `channels` ON `chanuser_cid` = `channel_id` LEFT JOIN `bot_channels` ON `chanuser_cid` = `chanid` LEFT JOIN `bots` ON `bots`.`id` = `botid` WHERE `chanuser_uid` = '%d' AND `botclass` = '%d' AND `active` = '1' ORDER BY `chanuser_access` DESC, `channel_name` ASC", userid, client->botid);
- res = mysql_use();
- total_count = mysql_num_rows(res);
- table = table_init(4, total_count + 1, 0);
- table_add(table, content);
- while ((chanuser_row = mysql_fetch_row(res)) != NULL) {
- if(!strcmp(chanuser_row[0], "500")) owner_count++;
- if(chanmatch && match(chanmatch, chanuser_row[0])) continue;
- match_count++;
- if((!chanuser_row[4] || !chanuser_row[5]) && !default_chan) {
- printf_mysql_query("SELECT `channel_getop`, `channel_getvoice` FROM `channels` WHERE `channel_name` = 'defaults'");
- default_res = mysql_use();
- default_chan = mysql_fetch_row(default_res);
- }
- flagPos = 0;
- content[0] = chanuser_row[3];
- content[1] = chanuser_row[0];
- cflags = atoi(chanuser_row[1]);
- caccess = atoi(chanuser_row[0]);
- if((cflags & DB_CHANUSER_SUSPENDED))
- flagPos += sprintf(flagBuf + flagPos, "s");
- if(caccess >= (chanuser_row[4] ? atoi(chanuser_row[4]) : atoi(default_chan[0])))
- flagPos += sprintf(flagBuf + flagPos, "o");
- if(caccess >= (chanuser_row[5] ? atoi(chanuser_row[5]) : atoi(default_chan[1])))
- flagPos += sprintf(flagBuf + flagPos, "v");
- if((cflags & DB_CHANUSER_AUTOINVITE))
- flagPos += sprintf(flagBuf + flagPos, "i");
- content[2] = (flagPos ? flagBuf : "");
- content[3] = chanuser_row[2];
- table_add(table, content);
- }
- } else {
- table = table_init(4, 1, 0);
- table_add(table, content);
- }
- //send the table
- char **table_lines = table_end(table);
- for(i = 0; i < table->entrys; i++) {
- reply(textclient, user, table_lines[i]);
- }
- if(!match_count)
- reply(textclient, user, "NS_TABLE_NONE");
- if(chanmatch) {
- reply(textclient, user, "NS_MYACCESS_COUNT_MATCH", auth, total_count, owner_count, match_count, chanmatch);
- } else {
- reply(textclient, user, "NS_MYACCESS_COUNT", auth, total_count, owner_count);
- }
- table_free(table);
-}
+++ /dev/null
-/* cmd_neonserv_nicklist.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* argv[0] "force"
-* argv[1] (optional) nick mask
-*/
-static USERLIST_CALLBACK(neonserv_cmd_nicklist_userlist_lookup);
-static void neonserv_cmd_nicklist_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nickmask, int syncusers);
-static void neonserv_cmd_nicklist_synchronize_user(struct ChanNode *chan, struct UserNode *user, int access);
-
-struct neonserv_cmd_nicklist_cache {
- struct ClientSocket *client, *textclient;
- struct UserNode *user;
- struct Event *event;
- char *nickmask;
- int syncusers;
-};
-
-CMD_BIND(neonserv_cmd_nicklist) {
- int syncusers = 0;
- if(argc && !stricmp(argv[0], "sync")) {
- if(!checkChannelAccess(user, chan, "channel_canadd", 0)) {
- if(isGodMode(user)) {
- event->flags |= CMDFLAG_OPLOG;
- } else {
- reply(getTextBot(), user, "NS_ACCESS_DENIED");
- return;
- }
- }
- argv++;
- argc--;
- syncusers = 1;
- event->flags |= CMDFLAG_LOG;
- }
- if(argc && !stricmp(argv[0], "nowho") && isGodMode(user)) {
- argv++;
- argc--;
- neonserv_cmd_nicklist_async1(client, getTextBot(), user, chan, event, (argc ? argv[0] : NULL), syncusers);
- return;
- }
- struct neonserv_cmd_nicklist_cache *cache = malloc(sizeof(*cache));
- if (!cache) {
- perror("malloc() failed");
- return;
- }
- cache->client = client;
- cache->textclient = getTextBot();
- cache->user = user;
- cache->event = event;
- if(argc) {
- cache->nickmask = strdup(argv[0]);
- } else
- cache->nickmask = NULL;
- cache->syncusers = syncusers;
- get_userlist_with_invisible(chan, neonserv_cmd_nicklist_userlist_lookup, cache);
-}
-
-static USERLIST_CALLBACK(neonserv_cmd_nicklist_userlist_lookup) {
- struct neonserv_cmd_nicklist_cache *cache = data;
- neonserv_cmd_nicklist_async1(cache->client, cache->textclient, cache->user, chan, cache->event, cache->nickmask, cache->syncusers);
- if(cache->nickmask)
- free(cache->nickmask);
- free(cache);
-}
-
-static void neonserv_cmd_nicklist_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nickmask, int syncusers) {
- MYSQL_RES *res;
- MYSQL_ROW row, defaults = NULL;
- struct Table *table;
- table = table_init(3, chan->usercount + 1, 0);
- char *content[3];
- content[0] = get_language_string(user, "NS_NICKLIST_NICK");
- content[1] = get_language_string(user, "NS_NICKLIST_STATE");
- content[2] = get_language_string(user, "NS_NICKLIST_ACCESS");
- table_add(table, content);
- printf_mysql_query("SELECT `chanuser_access`, `user_user`, `chanuser_flags` FROM `chanusers` LEFT JOIN `users` ON `chanuser_uid` = `user_id` WHERE `chanuser_cid` = '%d'", chan->channel_id);
- res = mysql_use();
- int userlistlen = mysql_num_rows(res);
- int i = 0;
- MYSQL_ROW userlist[userlistlen];
- while ((row = mysql_fetch_row(res)) != NULL) {
- userlist[i++] = row;
- }
- int db_enfops, db_enfvoice;
- printf_mysql_query("SELECT `channel_getop`, `channel_getvoice` FROM `channels` WHERE `channel_id` = '%d'", chan->channel_id);
- row = mysql_fetch_row(mysql_use());
- if(row[0] == NULL || row[1] == NULL) {
- printf_mysql_query("SELECT `channel_getop`, `channel_getvoice` FROM `channels` WHERE `channel_name` = 'defaults'");
- defaults = mysql_fetch_row(mysql_use());
- }
- db_enfops = atoi((row[0] ? row[0] : defaults[0]));
- db_enfvoice = atoi((row[1] ? row[1] : defaults[1]));
- int caccess = getChannelAccess(user, chan);
- int synced_user = 0;
- struct ChanUser *chanuser;
- int sort_nicklist[] = {
- CHANUSERFLAG_OPPED | CHANUSERFLAG_HALFOPPED | CHANUSERFLAG_VOICED,
- CHANUSERFLAG_OPPED | CHANUSERFLAG_HALFOPPED,
- CHANUSERFLAG_OPPED | CHANUSERFLAG_VOICED,
- CHANUSERFLAG_OPPED,
- CHANUSERFLAG_HALFOPPED | CHANUSERFLAG_VOICED,
- CHANUSERFLAG_HALFOPPED,
- CHANUSERFLAG_VOICED,
- CHANUSERFLAG_INVISIBLE,
- 0
- };
- int *sort_pos = sort_nicklist;
- int sort_flags;
- do {
- sort_flags = *(sort_pos++);
- char statebuf[5];
- char accessbuf[9];
- int uaccess;
- int stateset = 0;
- for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
- if((chanuser->flags & (CHANUSERFLAG_OPPED | CHANUSERFLAG_VOICED | CHANUSERFLAG_INVISIBLE)) != sort_flags) continue;
- if(nickmask && match(nickmask, chanuser->user->nick)) continue;
- if(!stateset) {
- if((chanuser->flags & CHANUSERFLAG_INVISIBLE)) statebuf[stateset++] = '<';
- if((chanuser->flags & CHANUSERFLAG_OPPED)) statebuf[stateset++] = '@';
- if((chanuser->flags & CHANUSERFLAG_HALFOPPED)) statebuf[stateset++] = '%';
- if((chanuser->flags & CHANUSERFLAG_VOICED)) statebuf[stateset++] = '+';
- statebuf[stateset++] = '\0';
- }
- content[0] = chanuser->user->nick;
- content[1] = statebuf;
- uaccess = 0;
- if(chanuser->user->flags & USERFLAG_ISAUTHED) {
- for(i = 0; i < userlistlen; i++) {
- if(!stricmp(chanuser->user->auth, userlist[i][1])) {
- uaccess = atoi(userlist[i][0]);
- if((((chanuser->flags & CHANUSERFLAG_OPPED) && uaccess < db_enfops) || ((chanuser->flags & CHANUSERFLAG_VOICED) && uaccess < db_enfvoice)) && !isNetworkService(chanuser->user)) {
- if(syncusers) {
- if((chanuser->flags & CHANUSERFLAG_OPPED) && (db_enfops < caccess || isGodMode(user))) {
- if(db_enfops >= caccess)
- event->flags |= CMDFLAG_OPLOG;
- uaccess = db_enfops;
- } else if((chanuser->flags & CHANUSERFLAG_VOICED) && (caccess < db_enfvoice || isGodMode(user))) {
- if(db_enfvoice >= caccess)
- event->flags |= CMDFLAG_OPLOG;
- uaccess = db_enfvoice;
- } else {
- //fail...
- sprintf(accessbuf, "\00307%d\003", uaccess);
- break;
- }
- neonserv_cmd_nicklist_synchronize_user(chan, chanuser->user, uaccess);
- sprintf(accessbuf, "\00309%d\003", uaccess);
- synced_user = 1;
- } else {
- synced_user = 1;
- sprintf(accessbuf, "\00307%d\003", uaccess);
- }
- } else if((uaccess >= db_enfops && !(chanuser->flags & CHANUSERFLAG_OPPED)) || (uaccess >= db_enfvoice && !(chanuser->flags & CHANUSERFLAG_OPPED_OR_VOICED)))
- sprintf(accessbuf, "\00303%d\003", uaccess);
- else
- sprintf(accessbuf, "%d", uaccess);
- break;
- }
- }
- }
- if(!uaccess && (chanuser->flags & CHANUSERFLAG_OPPED_OR_VOICED) && !isNetworkService(chanuser->user)) {
- if(syncusers) {
- if((chanuser->flags & CHANUSERFLAG_OPPED) && (db_enfops < caccess || isGodMode(user))) {
- if(db_enfops >= caccess)
- event->flags |= CMDFLAG_OPLOG;
- uaccess = db_enfops;
- } else if((chanuser->flags & CHANUSERFLAG_VOICED) && (db_enfvoice < caccess || isGodMode(user))) {
- if(db_enfvoice >= caccess)
- event->flags |= CMDFLAG_OPLOG;
- uaccess = db_enfvoice;
- } else {
- uaccess = 0;
- sprintf(accessbuf, "\003040\003");
- }
- if(uaccess && (chanuser->user->flags & USERFLAG_ISAUTHED)) {
- neonserv_cmd_nicklist_synchronize_user(chan, chanuser->user, uaccess);
- sprintf(accessbuf, "\00309%d\003", uaccess);
- synced_user = 1;
- } else if(uaccess) {
- sprintf(accessbuf, "\003040\003");
- }
- } else {
- synced_user = 1;
- sprintf(accessbuf, "\003040\003");
- }
- } else if(!uaccess)
- sprintf(accessbuf, "0");
- content[2] = accessbuf;
- table_add(table, content);
- }
- } while(sort_flags != 0);
- //send the table
- char **table_lines = table_end(table);
- for(i = 0; i < table->entrys; i++) {
- reply(textclient, user, table_lines[i]);
- }
- if(table->length == 1)
- reply(textclient, user, "NS_TABLE_NONE");
- reply(textclient, user, "NS_TABLE_COUNT", table->length - 1);
- table_free(table);
- if(synced_user) {
- if(!syncusers)
- reply(textclient, user, "NS_NICKLIST_SYNC", db_enfops, db_enfvoice);
- else
- logEvent(event);
- }
-}
-
-static void neonserv_cmd_nicklist_synchronize_user(struct ChanNode *chan, struct UserNode *user, int caccess) {
- if(!(user->flags & USERFLAG_ISAUTHED)) return;
- MYSQL_RES *res;
- MYSQL_ROW row;
- int userid;
- printf_mysql_query("SELECT `user_id` FROM `users` WHERE `user_user` = '%s'", escape_string(user->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(user->auth));
- userid = (int) mysql_insert_id(get_mysql_conn());
- }
- //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;
- printf_mysql_query("UPDATE `chanusers` SET `chanuser_access` = '%d' WHERE `chanuser_id` = '%s'", caccess, row[1]);
- } else
- printf_mysql_query("INSERT INTO `chanusers` (`chanuser_cid`, `chanuser_uid`, `chanuser_access`) VALUES ('%d', '%d', '%d')", chan->channel_id, userid, caccess);
-}
+++ /dev/null
-/* cmd_neonserv_noregister.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* argv[0] *auth/#channel
-* argv[1] duration
-* argv[2-*] reason
-*/
-
-static AUTHLOOKUP_CALLBACK(neonserv_cmd_noregister_auth_lookup);
-static USERAUTH_CALLBACK(neonserv_cmd_noregister_nick_lookup);
-static void neonserv_cmd_noregister_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event,char *auth, int duration, char *reason);
-static void neonserv_cmd_noregister_list(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, char **argv, int argc);
-
-struct neonserv_cmd_noregister_cache {
- struct ClientSocket *client, *textclient;
- struct UserNode *user;
- struct ChanNode *chan;
- struct Event *event;
- int duration;
- char *reason, *nick;
-};
-
-CMD_BIND(neonserv_cmd_noregister) {
- if(argc < 3) {
- neonserv_cmd_noregister_list(client, user, chan, event, argv, argc);
- return;
- }
- int duration = strToTime(user, argv[1]);
- if(duration == 0 && strcmp(argv[1], "0")) {
- reply(getTextBot(), user, "NS_NOREGISTER_INVALID_DURATION", argv[1]);
- return;
- }
- char *reason = merge_argv(argv, 2, argc);
- MYSQL_RES *res;
- MYSQL_ROW row;
- if(argv[0][0] == '#') {
- printf_mysql_query("SELECT `botid` FROM `bot_channels` LEFT JOIN `channels` ON `bot_channels`.`chanid` = `channels`.`channel_id` WHERE `channel_name` = '%s'", escape_string(argv[0]));
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) != NULL) {
- reply(getTextBot(), user, "NS_NOREGISTER_REGISTERED", argv[0]);
- return;
- }
- neonserv_cmd_noregister_async1(client, getTextBot(), user, chan, event, argv[0], duration, reason);
- } else 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_noregister_async1(client, getTextBot(), user, chan, event, row[0], duration, reason);
- } else {
- //we need to create a new user...
- //but first lookup the auth to check if it really exists
- struct neonserv_cmd_noregister_cache *cache = malloc(sizeof(*cache));
- if (!cache) {
- perror("malloc() failed");
- return;
- }
- cache->client = client;
- cache->textclient = getTextBot();
- cache->user = user;
- cache->chan = chan;
- cache->event = event;
- cache->nick = strdup(argv[0]);
- cache->duration = duration;
- cache->reason = strdup(reason);
- lookup_authname(argv[0], neonserv_cmd_noregister_auth_lookup, cache);
- }
- } else {
- struct UserNode *cuser = getUserByNick(argv[0]);
- if(!cuser) {
- cuser = createTempUser(argv[0]);
- if(!cuser) {
- reply(getTextBot(), user, "NS_USER_UNKNOWN", argv[0]);
- return;
- }
- cuser->flags |= USERFLAG_ISTMPUSER;
- }
- if(cuser->flags & USERFLAG_ISAUTHED) {
- neonserv_cmd_noregister_async1(client, getTextBot(), user, chan, event, cuser->auth, duration, reason);
- } else {
- struct neonserv_cmd_noregister_cache *cache = malloc(sizeof(*cache));
- if (!cache) {
- perror("malloc() failed");
- return;
- }
- cache->client = client;
- cache->textclient = getTextBot();
- cache->user = user;
- cache->chan = chan;
- cache->event = event;
- cache->nick = strdup(user->nick);
- cache->duration = duration;
- cache->reason = strdup(reason);
- get_userauth(cuser, neonserv_cmd_noregister_nick_lookup, cache);
- }
- }
-}
-
-static AUTHLOOKUP_CALLBACK(neonserv_cmd_noregister_auth_lookup) {
- struct neonserv_cmd_noregister_cache *cache = data;
- if(!exists) {
- //AUTH_DOES_NOT_EXIST
- reply(cache->textclient, cache->user, "NS_AUTH_UNKNOWN", cache->nick);
- } else
- neonserv_cmd_noregister_async1(cache->client, cache->textclient, cache->user, cache->chan, cache->event, auth, cache->duration, cache->reason);
- free(cache->reason);
- free(cache->nick);
- free(cache);
-}
-
-static USERAUTH_CALLBACK(neonserv_cmd_noregister_nick_lookup) {
- struct neonserv_cmd_noregister_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_noregister_async1(cache->client, cache->textclient, cache->user, cache->chan, cache->event, user->auth, cache->duration, cache->reason);
- free(cache->reason);
- free(cache->nick);
- free(cache);
-}
-
-static void neonserv_cmd_noregister_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event,char *auth, int duration, char *reason) {
- MYSQL_RES *res;
- MYSQL_ROW row;
- printf_mysql_query("SELECT `dnr_id` FROM `donotregister` WHERE `dnr_target` = '%s'", escape_string(auth));
- res = mysql_use();
- if((row = mysql_fetch_row(res)) != NULL) {
- printf_mysql_query("DELETE FROM `donotregister` WHERE `dnr_id` = '%s'", row[0]);
- }
- int userid;
- printf_mysql_query("SELECT `user_id` FROM `users` WHERE `user_user` = '%s'", escape_string(user->auth));
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) != NULL)
- userid = atoi(row[0]);
- else
- userid = 0;
- printf_mysql_query("INSERT INTO `donotregister` (`dnr_target`, `dnr_timeout`, `dnr_user`, `dnr_reason`) VALUES ('%s', '%lu', '%d', '%s')", escape_string(auth), (duration ? (time(0)+duration) : 0), userid, escape_string(reason));
- reply(getTextBot(), user, "NS_NOREGISTER_DONE", auth);
-}
-
-static void neonserv_cmd_noregister_list(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, char **argv, int argc) {
- struct Table *table;
- int entrys = 0;
- MYSQL_RES *res;
- MYSQL_ROW row;
- printf_mysql_query("SELECT `dnr_target`, `dnr_timeout`, `user_user`, `dnr_reason` FROM `donotregister` LEFT JOIN `users` ON `dnr_user` = `user_id` ORDER BY `dnr_target` ASC");
- res = mysql_use();
- table = table_init(4, mysql_num_rows(res) + 1, 0);
- char *content[4];
- content[0] = get_language_string(user, "NS_DNR_TARGET");
- content[1] = get_language_string(user, "NS_DNR_USER");
- content[2] = get_language_string(user, "NS_DNR_EXPIRES");
- content[3] = get_language_string(user, "NS_DNR_REASON");
- table_add(table, content);
- int duration;
- char expires_str[MAXLEN];
- while ((row = mysql_fetch_row(res)) != NULL) {
- entrys++;
- content[0] = row[0];
- content[1] = row[2];
- duration = atoi(row[1]);
- content[2] = (duration ? timeToStr(user, (duration - time(0)), 2, expires_str) : get_language_string(user, "NS_USERS_SEEN_NEVER"));
- content[3] = row[3];
- table_add(table, content);
- }
- //send the table
- char **table_lines = table_end(table);
- int i;
- for(i = 0; i < table->entrys; i++) {
- reply(getTextBot(), user, table_lines[i]);
- }
- if(!entrys)
- reply(getTextBot(), user, "NS_TABLE_NONE");
- table_free(table);
-}
+++ /dev/null
-/* cmd_neonserv_op.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* argv[0-*] nicks
-*/
-static USERLIST_CALLBACK(neonserv_cmd_op_userlist_lookup);
-static void neonserv_cmd_op_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nicks);
-
-struct neonserv_cmd_op_cache {
- struct ClientSocket *client, *textclient;
- struct UserNode *user;
- struct Event *event;
- char *nicks;
-};
-
-CMD_BIND(neonserv_cmd_op) {
- struct neonserv_cmd_op_cache *cache = malloc(sizeof(*cache));
- if (!cache) {
- perror("malloc() failed");
- return;
- }
- cache->client = client;
- cache->textclient = getTextBot();
- cache->user = user;
- cache->event = event;
- cache->nicks = strdup(merge_argv(argv, 0, argc));
- get_userlist_if_invisible(chan, neonserv_cmd_op_userlist_lookup, cache);
-}
-
-static USERLIST_CALLBACK(neonserv_cmd_op_userlist_lookup) {
- struct neonserv_cmd_op_cache *cache = data;
- neonserv_cmd_op_async1(cache->client, cache->textclient, cache->user, chan, cache->event, cache->nicks);
- free(cache->nicks);
- free(cache);
-}
-
-static void neonserv_cmd_op_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nicks) {
- int total_users = 0, done_users = 0;
- struct UserNode *cuser;
- struct ChanUser *chanuser;
- struct ModeBuffer *modeBuf;
- modeBuf = initModeBuffer(client, chan);
- char *a, *b = nicks;
- do {
- a = strstr(b, " ");
- if(a) *a = '\0';
- total_users++;
- cuser = searchUserByNick(b);
- if(!cuser) {
- //check for an invisible user
- for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
- if(!stricmp(chanuser->user->nick, b)) {
- cuser = chanuser->user;
- break;
- }
- }
- if(!cuser) continue;
- } else {
- chanuser = getChanUser(cuser, chan);
- if(!chanuser) continue;
- }
- done_users++;
- if(chanuser->flags & CHANUSERFLAG_OPPED) continue;
- modeBufferOp(modeBuf, b);
- if(a) {
- b = a+1;
- }
- } while(a);
- freeModeBuffer(modeBuf);
- if(done_users == total_users)
- reply(textclient, user, "NS_OP_DONE", chan->name);
- else
- reply(textclient, user, "NS_OP_FAIL", client->user->nick);
- if(done_users)
- logEvent(event);
-}
+++ /dev/null
-/* cmd_neonserv_opall.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* argv[0] "force"
-* argv[1] (optional) nick mask
-*/
-static USERLIST_CALLBACK(neonserv_cmd_opall_userlist_lookup);
-static void neonserv_cmd_opall_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nickmask);
-
-struct neonserv_cmd_opall_cache {
- struct ClientSocket *client, *textclient;
- struct UserNode *user;
- struct Event *event;
- char *nickmask;
-};
-
-CMD_BIND(neonserv_cmd_opall) {
- if(!argc || strcmp(argv[0], "FORCE")) {
- reply(getTextBot(), user, "NS_OPALL_SECURITY", chan->name);
- return;
- }
- struct neonserv_cmd_opall_cache *cache = malloc(sizeof(*cache));
- if (!cache) {
- perror("malloc() failed");
- return;
- }
- cache->client = client;
- cache->textclient = getTextBot();
- cache->user = user;
- cache->event = event;
- if(argc > 1) {
- cache->nickmask = strdup(argv[1]);
- } else
- cache->nickmask = NULL;
- get_userlist_if_invisible(chan, neonserv_cmd_opall_userlist_lookup, cache);
-}
-
-static USERLIST_CALLBACK(neonserv_cmd_opall_userlist_lookup) {
- struct neonserv_cmd_opall_cache *cache = data;
- neonserv_cmd_opall_async1(cache->client, cache->textclient, cache->user, chan, cache->event, cache->nickmask);
- if(cache->nickmask)
- free(cache->nickmask);
- free(cache);
-}
-
-static void neonserv_cmd_opall_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nickmask) {
- int done_users = 0;
- struct ChanUser *chanuser;
- struct ModeBuffer *modeBuf;
- modeBuf = initModeBuffer(client, chan);
- for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
- if(nickmask && match(nickmask, chanuser->user->nick)) continue;
- if(chanuser->flags & CHANUSERFLAG_OPPED) continue;
- modeBufferOp(modeBuf, chanuser->user->nick);
- done_users++;
- }
- freeModeBuffer(modeBuf);
- reply(textclient, user, "NS_OPALL_DONE", done_users, chan->name);
- if(done_users)
- logEvent(event);
-}
+++ /dev/null
-/* cmd_neonserv_oplog.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* argv[0] time
-* argv[1-*] match
-*/
-
-CMD_BIND(neonserv_cmd_oplog) {
- char *str_match;
- int duration = (argc ? strToTime(user, argv[0]) : 0);
- if(argc > (duration ? 1 : 0))
- str_match = merge_argv(argv, (duration ? 1 : 0), argc);
- else
- str_match = "";
- if(!duration) duration = (60*60*24);
- MYSQL_RES *res;
- MYSQL_ROW row;
- printf_mysql_query("SELECT `godlog_time`, `user_user`, `channel_name`, `godlog_cmd` FROM `godlog` LEFT JOIN `channels` ON `godlog_cid` = `channel_id` LEFT JOIN `users` ON `godlog_uid` = `user_id` WHERE `godlog_time` > '%lu' ORDER BY `godlog_time` ASC", ((unsigned long) time(0) - duration));
- res = mysql_use();
- int skip = mysql_num_rows(res) - 100;
- int count = 0;
- char timeBuf[50];
- struct tm *timeinfo;
- time_t event_time;
- if(skip < 0) skip = 0;
- reply(getTextBot(), user, "NS_EVENTS_HEADER");
- while ((row = mysql_fetch_row(res)) != NULL) {
- if(skip) {
- skip--;
- continue;
- }
- if(*str_match && match(str_match, row[3])) continue;
- count++;
- event_time = (time_t) atol(row[0]);
- timeinfo = localtime(&event_time);
- strftime(timeBuf, 80, "%X %x", timeinfo);
- reply(getTextBot(), user, "[%s] [%s%s%s]: %s", timeBuf, row[1], (row[2] ? ":" : ""), (row[2] ? row[2] : ""), row[3]);
- }
- reply(getTextBot(), user, "NS_TABLE_COUNT", count);
-}
+++ /dev/null
-/* cmd_neonserv_peek.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* no parameters
-*/
-static USERLIST_CALLBACK(neonserv_cmd_peek_userlist_lookup);
-static void neonserv_cmd_peek_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan);
-
-struct neonserv_cmd_peek_cache {
- struct ClientSocket *client, *textclient;
- struct UserNode *user;
-};
-
-CMD_BIND(neonserv_cmd_peek) {
- struct neonserv_cmd_peek_cache *cache = malloc(sizeof(*cache));
- if (!cache) {
- perror("malloc() failed");
- return;
- }
- cache->client = client;
- cache->textclient = getTextBot();
- cache->user = user;
- get_userlist_if_invisible(chan, neonserv_cmd_peek_userlist_lookup, cache);
-}
-
-static USERLIST_CALLBACK(neonserv_cmd_peek_userlist_lookup) {
- struct neonserv_cmd_peek_cache *cache = data;
- neonserv_cmd_peek_async1(cache->client, cache->textclient, cache->user, chan);
- free(cache);
-}
-
-static void neonserv_cmd_peek_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan) {
- reply(textclient, user, "NS_PEEK_HEADER", chan->name);
- reply(textclient, user, "NS_PEEK_TOPIC", chan->topic);
- char tmpStr[MAXLEN];
- getModeString(chan->modes, tmpStr);
- reply(textclient, user, "NS_PEEK_MODES", tmpStr);
- struct ChanUser *chanuser;
- int with_halfops = get_int_field("General.have_halfop");
- int op_count = 0, halfop_count = 0, voice_count = 0, normal_count = 0, invi_count = 0;
- for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
- if(chanuser->flags & CHANUSERFLAG_OPPED)
- op_count++;
- else if(with_halfops && (chanuser->flags & CHANUSERFLAG_HALFOPPED))
- halfop_count++;
- else if(chanuser->flags & CHANUSERFLAG_VOICED)
- voice_count++;
- else if(chanuser->flags & CHANUSERFLAG_INVISIBLE)
- invi_count++;
- else
- normal_count++;
- }
- if(with_halfops)
- reply(textclient, user, "NS_PEEK_USERS_HALFOP", op_count+halfop_count+voice_count+invi_count+normal_count, op_count, halfop_count, voice_count, normal_count, invi_count);
- else
- reply(textclient, user, "NS_PEEK_USERS", op_count+voice_count+invi_count+normal_count, op_count, voice_count, normal_count, invi_count);
- int tmpStrPos = 0;
- int headerlen = 10 + strlen(user->nick);
- for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
- if(chanuser->flags & CHANUSERFLAG_OPPED) {
- if(tmpStrPos + headerlen + strlen(chanuser->user->nick) + 2 >= 512) {
- //clear buffer
- reply(textclient, user, "%s", tmpStr);
- tmpStrPos = 0;
- }
- tmpStrPos += sprintf(tmpStr + tmpStrPos, (tmpStrPos ? ", %s" : "%s"), chanuser->user->nick);
- }
- }
- if(tmpStrPos) {
- reply(textclient, user, "%s", tmpStr);
- }
-}
+++ /dev/null
-/* cmd_neonserv_recover.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* argv[0] - channel
-*/
-CMD_BIND(neonserv_cmd_recover) {
- MYSQL_RES *res;
- MYSQL_ROW row, row2;
- char *channel = argv[0];
- if(!is_valid_chan(channel)) {
- reply(getTextBot(), user, "NS_INVALID_CHANNEL_NAME", argv[0]);
- return;
- }
- printf_mysql_query("SELECT `botid`, `bot_channels`.`id` 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;
- }
- 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 {
- reply(getTextBot(), user, "NS_UNREGISTER_NOT_REGISTERED", argv[0], client->user->nick);
- return;
- }
- printf_mysql_query("SELECT `id`, `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(getTextBot(), user, "NS_REGISTER_FULL");
- return;
- }
- 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(getTextBot(), user, "NS_REGISTER_DISCONNECTED");
- printf_mysql_query("INSERT INTO `bot_channels` (`botid`, `chanid`, `trigger`) VALUES ('%d', '%d', '%s')", botid, chanid, bottrigger);
- reply(getTextBot(), user, "NS_RECOVER_DONE", channel);
- logEvent(event);
-}
+++ /dev/null
-/* cmd_neonserv_rename.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* argv[0] old auth
-* argv[1] new auth
-*/
-
-struct neonserv_cmd_rename_cache {
- struct ClientSocket *client, *textclient;
- struct UserNode *user;
- struct Event *event;
- char *oldauth, *newauth;
-};
-
-static AUTHLOOKUP_CALLBACK(neonserv_cmd_rename_auth_lookup);
-static void neonserv_cmd_rename_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct Event *event, char *oldauth, char *newauth);
-
-CMD_BIND(neonserv_cmd_rename) {
- struct neonserv_cmd_rename_cache *cache = malloc(sizeof(*cache));
- if (!cache) {
- perror("malloc() failed");
- return;
- }
- cache->client = client;
- cache->textclient = getTextBot();
- cache->user = user;
- cache->event = event;
- cache->oldauth = strdup(argv[0]);
- cache->newauth = strdup(argv[1]);
- lookup_authname(argv[1], neonserv_cmd_rename_auth_lookup, cache);
-}
-
-static AUTHLOOKUP_CALLBACK(neonserv_cmd_rename_auth_lookup) {
- struct neonserv_cmd_rename_cache *cache = data;
- if(!exists) {
- //AUTH_DOES_NOT_EXIST
- reply(cache->textclient, cache->user, "NS_AUTH_UNKNOWN", cache->newauth);
- } else
- neonserv_cmd_rename_async1(cache->client, cache->textclient, cache->user, cache->event, cache->oldauth, auth);
- free(cache->oldauth);
- free(cache->newauth);
- free(cache);
-}
-
-static void neonserv_cmd_rename_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct Event *event, char *oldauth, char *newauth) {
- if(renameAccount(oldauth, newauth)) {
- reply(textclient, user, "NS_RENAME_DONE", oldauth, newauth);
- } else {
- reply(textclient, user, "NS_RENAME_FAIL", oldauth);
- }
-}
+++ /dev/null
-/* cmd_neonserv_resync.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* argv[0] - (optional) usermask
-* argv[1] - (optional) min access
-* argv[2] - (optional) max access
-* argv[1/3] - (optional) FORCE (override NoAutoOp)
-*/
-static USERLIST_CALLBACK(neonserv_cmd_resync_userlist_lookup);
-static void neonserv_cmd_resync_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, char *usermask, int min_access, int max_access, char override_noautoop);
-
-struct neonserv_cmd_resync_cache {
- struct ClientSocket *client, *textclient;
- struct UserNode *user;
- char *usermask;
- int min_access;
- int max_access;
- char override_noautoop;
-};
-
-CMD_BIND(neonserv_cmd_resync) {
- int min_access = 0, max_access = 500;
- char *usermask = NULL;
- char override_noautoop = 0;
- if(argc > 0) {
- usermask = argv[0];
- if(argc > 2) {
- min_access = atoi(argv[1]);
- max_access = atoi(argv[2]);
- if(argc > 3)
- override_noautoop = (!stricmp(argv[3], "FORCE") ? 1 : 0);
- } else if(argc > 1)
- override_noautoop = (!stricmp(argv[1], "FORCE") ? 1 : 0);
- }
- struct neonserv_cmd_resync_cache *cache = malloc(sizeof(*cache));
- if (!cache) {
- perror("malloc() failed");
- return;
- }
- cache->client = client;
- cache->textclient = getTextBot();
- cache->user = user;
- cache->usermask = (usermask ? strdup(usermask) : NULL);
- cache->min_access = min_access;
- cache->max_access = max_access;
- cache->override_noautoop = override_noautoop;
- get_userlist_with_invisible(chan, neonserv_cmd_resync_userlist_lookup, cache);
-}
-
-static USERLIST_CALLBACK(neonserv_cmd_resync_userlist_lookup) {
- struct neonserv_cmd_resync_cache *cache = data;
- neonserv_cmd_resync_async1(cache->client, cache->textclient, cache->user, chan, cache->usermask, cache->min_access, cache->max_access, cache->override_noautoop);
- if(cache->usermask)
- free(cache->usermask);
- free(cache);
-}
-
-static void neonserv_cmd_resync_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, char *usermask, int min_access, int max_access, char override_noautoop) {
- MYSQL_RES *res;
- MYSQL_ROW row, defaults = NULL;
- int i;
- int resync_op = 1;
- int with_halfop = get_int_field("General.have_halfop");
- int resync_halfop = with_halfop;
- int resync_voice = 1;
- if(usermask && usermask[0] == '@') {
- resync_voice = 0;
- resync_halfop = 0;
- usermask++;
- if(!*usermask) usermask = NULL;
- } else if(usermask && with_halfop && usermask[0] == 'h') {
- resync_op = 0;
- resync_voice = 0;
- usermask++;
- if(!*usermask) usermask = NULL;
- } else if(usermask && usermask[0] == '+') {
- resync_op = 0;
- resync_halfop = 0;
- usermask++;
- if(!*usermask) usermask = NULL;
- }
- struct ChanUser *chanuser;
- int db_enfops, db_enfhalfop, db_enfvoice;
- printf_mysql_query("SELECT `channel_getop`, `channel_getvoice`, `channel_gethalfop` FROM `channels` WHERE `channel_id` = '%d'", chan->channel_id);
- row = mysql_fetch_row(mysql_use());
- if(row[0] == NULL || row[1] == NULL) {
- printf_mysql_query("SELECT `channel_getop`, `channel_getvoice`, `channel_gethalfop` FROM `channels` WHERE `channel_name` = 'defaults'");
- defaults = mysql_fetch_row(mysql_use());
- }
- db_enfops = atoi((row[0] ? row[0] : defaults[0]));
- db_enfvoice = atoi((row[1] ? row[1] : defaults[1]));
- db_enfhalfop = (with_halfop ? atoi((row[2] ? row[2] : defaults[2])) : 0);
- printf_mysql_query("SELECT `chanuser_access`, `user_user`, `chanuser_flags` FROM `chanusers` LEFT JOIN `users` ON `chanuser_uid` = `user_id` WHERE `chanuser_cid` = '%d' ORDER BY `chanuser_access` DESC, `user_user` ASC", chan->channel_id);
- res = mysql_use();
- char *db_users[mysql_num_rows(res)];
- int db_access[mysql_num_rows(res)];
- int db_flags[mysql_num_rows(res)];
- int db_count = 0;
- while ((row = mysql_fetch_row(res)) != NULL) {
- db_users[db_count] = row[1];
- db_access[db_count] = atoi(row[0]);
- db_flags[db_count] = atoi(row[2]);
- db_count++;
- }
- int caccess, cflags;
- struct ModeBuffer *modeBuf;
- modeBuf = initModeBuffer(client, chan);
- for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
- caccess = 0;
- cflags = 0;
- if((chanuser->user->flags & USERFLAG_ISAUTHED)) {
- for(i = 0; i < db_count; i++) {
- if(!stricmp(db_users[i], chanuser->user->auth)) {
- caccess = db_access[i];
- cflags = db_flags[i];
- if(cflags & DB_CHANUSER_SUSPENDED)
- caccess = 0;
- break;
- }
- }
- }
- if((usermask && *usermask && match(usermask, chanuser->user->nick)) || caccess < min_access || caccess > max_access) continue;
- if(caccess >= db_enfops) {
- if(!(chanuser->flags & CHANUSERFLAG_OPPED) && resync_op && (override_noautoop || !(cflags & DB_CHANUSER_NOAUTOOP)))
- modeBufferOp(modeBuf, chanuser->user->nick);
- } else if(with_halfop && caccess >= db_enfhalfop) {
- if((chanuser->flags & CHANUSERFLAG_OPPED) && resync_op && !(chanuser->user->flags & (USERFLAG_ISBOT | USERFLAG_ISIRCOP)))
- modeBufferDeop(modeBuf, chanuser->user->nick);
- if(!(chanuser->flags & CHANUSERFLAG_HALFOPPED) && resync_halfop && (override_noautoop || !(cflags & DB_CHANUSER_NOAUTOOP)))
- modeBufferHalfop(modeBuf, chanuser->user->nick);
- } else if(caccess >= db_enfvoice) {
- if((chanuser->flags & CHANUSERFLAG_OPPED) && resync_op && !(chanuser->user->flags & (USERFLAG_ISBOT | USERFLAG_ISIRCOP)))
- modeBufferDeop(modeBuf, chanuser->user->nick);
- if((chanuser->flags & CHANUSERFLAG_HALFOPPED) && resync_halfop && !(chanuser->user->flags & (USERFLAG_ISBOT | USERFLAG_ISIRCOP)))
- modeBufferDehalfop(modeBuf, chanuser->user->nick);
- if(!(chanuser->flags & CHANUSERFLAG_VOICED) && resync_voice && (override_noautoop || !(cflags & DB_CHANUSER_NOAUTOOP)))
- modeBufferVoice(modeBuf, chanuser->user->nick);
- } else {
- if((chanuser->flags & CHANUSERFLAG_OPPED) && resync_op && !(chanuser->user->flags & (USERFLAG_ISBOT | USERFLAG_ISIRCOP)))
- modeBufferDeop(modeBuf, chanuser->user->nick);
- if((chanuser->flags & CHANUSERFLAG_HALFOPPED) && resync_halfop && !(chanuser->user->flags & (USERFLAG_ISBOT | USERFLAG_ISIRCOP)))
- modeBufferDehalfop(modeBuf, chanuser->user->nick);
- if((chanuser->flags & CHANUSERFLAG_VOICED) && resync_voice && !(chanuser->user->flags & (USERFLAG_ISBOT | USERFLAG_ISIRCOP)))
- modeBufferDevoice(modeBuf, chanuser->user->nick);
- }
-
- }
- freeModeBuffer(modeBuf);
- reply(textclient, user, "NS_RESYNC_DONE", chan->name);
-}
+++ /dev/null
-/* cmd_neonserv_search.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-#define CMD_SEARCH_FLAG_HAS_NODELETE 0x001
-#define CMD_SEARCH_FLAG_NOT_NODELETE 0x002
-#define CMD_SEARCH_FLAG_HAS_SUSPENDED 0x004
-#define CMD_SEARCH_FLAG_NOT_SUSPENDED 0x008
-#define CMD_SEARCH_FLAG_IS_JOINED 0x010
-#define CMD_SEARCH_FLAG_NOT_JOINED 0x020
-#define CMD_SEARCH_FLAG_IS_OPPED 0x040
-#define CMD_SEARCH_FLAG_NOT_OPPED 0x080
-#define CMD_SEARCH_FLAG_IS_VOICED 0x100
-#define CMD_SEARCH_FLAG_NOT_VOICED 0x200
-#define CMD_SEARCH_FLAG_STATES 0x3f0
-
-struct neonserv_cmd_search_criteria {
- char *name;
- char *registrar;
- char *onchan;
- unsigned int flags : 16;
- unsigned int unvisited;
- unsigned int registered;
- unsigned int limit : 16;
-};
-
-CMD_BIND(neonserv_cmd_search) {
- //ok parse the criterias
- struct neonserv_cmd_search_criteria criteria;
- memset(&criteria, 0, sizeof(criteria));
- criteria.limit = 50;
- int i, show_chans = 0, positive;
- if(!stricmp(argv[0], "print")) {
- show_chans = 1;
- }
- for(i = 1; i < argc; i += 2) {
- if(argc <= i+1) {
- reply(getTextBot(), user, "MODCMD_LESS_PARAM_COUNT");
- return;
- }
- if(!stricmp(argv[i], "name")) criteria.name = argv[i+1];
- else if(!stricmp(argv[i], "registrar")) criteria.registrar = argv[i+1];
- else if(!stricmp(argv[i], "onchan")) criteria.onchan = argv[i+1];
- else if(!stricmp(argv[i], "unvisited")) criteria.unvisited = strToTime(user, argv[i+1]);
- else if(!stricmp(argv[i], "registered")) criteria.registered = strToTime(user, argv[i+1]);
- else if(!stricmp(argv[i], "flags")) {
- if(argv[i+1][0] == '+') {
- positive = 1;
- argv[i+1]++;
- } else if(argv[i+1][0] == '-') {
- positive = 0;
- argv[i+1]++;
- } else
- positive = 1;
- if(!stricmp(argv[i+1], "nodelete")) {
- if(positive)
- criteria.flags |= CMD_SEARCH_FLAG_HAS_NODELETE;
- else
- criteria.flags |= CMD_SEARCH_FLAG_NOT_NODELETE;
- } else if(!stricmp(argv[i+1], "suspended")) {
- if(positive)
- criteria.flags |= CMD_SEARCH_FLAG_HAS_SUSPENDED;
- else
- criteria.flags |= CMD_SEARCH_FLAG_NOT_SUSPENDED;
- }
- }
- else if(!stricmp(argv[i], "state")) {
- if(argv[i+1][0] == '+') {
- positive = 1;
- argv[i+1]++;
- } else if(argv[i+1][0] == '-') {
- positive = 0;
- argv[i+1]++;
- } else
- positive = 1;
- if(!stricmp(argv[i+1], "joined")) {
- if(positive)
- criteria.flags |= CMD_SEARCH_FLAG_IS_JOINED;
- else
- criteria.flags |= CMD_SEARCH_FLAG_NOT_JOINED;
- } else if(!stricmp(argv[i+1], "opped")) {
- if(positive)
- criteria.flags |= CMD_SEARCH_FLAG_IS_OPPED;
- else
- criteria.flags |= CMD_SEARCH_FLAG_NOT_OPPED;
- } else if(!stricmp(argv[i+1], "voiced")) {
- if(positive)
- criteria.flags |= CMD_SEARCH_FLAG_IS_VOICED;
- else
- criteria.flags |= CMD_SEARCH_FLAG_NOT_VOICED;
- }
- }
- else if(!stricmp(argv[i], "limit")) {
- criteria.limit = atoi(argv[i+1]);
- }
- }
- int matches = 0;
- reply(getTextBot(), user, "NS_SEARCH_HEADER");
- MYSQL_RES *res, *res2;
- MYSQL_ROW row, row2;
- printf_mysql_query("SELECT `channel_name`, `user_user`, `channel_registered`, `channel_nodelete`, `suspended`, `channel_id` FROM `bot_channels` LEFT JOIN `bots` ON `bots`.`id` = `botid` LEFT JOIN `channels` ON `chanid` = `channel_id` LEFT JOIN `users` ON `channel_registrator` = `user_id` WHERE `botclass` = '%d' AND `active` = '1'", client->botid);
- res = mysql_use();
- while ((row = mysql_fetch_row(res)) != NULL) {
- if(show_chans && matches == criteria.limit) {
- //too many
- break;
- }
- if(criteria.name && match(criteria.name, row[0])) continue;
- if(criteria.registrar && row[1] && match(criteria.registrar, row[1])) continue;
- if(criteria.unvisited) {
- printf_mysql_query("SELECT `chanuser_seen` FROM `chanusers` WHERE `chanuser_cid` = '%s' ORDER BY `chanuser_seen` DESC LIMIT 1", row[5]);
- res2 = mysql_use();
- row2 = mysql_fetch_row(res2);
- if(!row2) continue;
- if((time(0) - atoi(row2[0])) < criteria.unvisited) continue;
- }
- if(criteria.registered && (time(0) - atoi(row[2])) < criteria.registered) continue;
-
- if((criteria.flags & CMD_SEARCH_FLAG_HAS_NODELETE) && strcmp(row[3], "1")) continue;
- if((criteria.flags & CMD_SEARCH_FLAG_NOT_NODELETE) && strcmp(row[3], "0")) continue;
- if((criteria.flags & CMD_SEARCH_FLAG_HAS_SUSPENDED) && strcmp(row[4], "1")) continue;
- if((criteria.flags & CMD_SEARCH_FLAG_NOT_SUSPENDED) && strcmp(row[4], "0")) continue;
- if((criteria.flags & CMD_SEARCH_FLAG_STATES) || criteria.onchan) {
- struct ChanNode *channel = getChanByName(row[0]);
- if(criteria.onchan) {
- if(!channel) continue;
- struct ChanUser *chanuser = NULL;
- for(chanuser = getChannelUsers(channel, NULL); chanuser; chanuser = getChannelUsers(channel, chanuser)) {
- if(!match(criteria.onchan, chanuser->user->nick)) break;
- }
- if(!chanuser) continue;
- }
- if((criteria.flags & CMD_SEARCH_FLAG_IS_JOINED) && !channel) continue;
- if((criteria.flags & CMD_SEARCH_FLAG_NOT_JOINED) && channel) continue;
- if(channel && (criteria.flags & (CMD_SEARCH_FLAG_IS_OPPED | CMD_SEARCH_FLAG_NOT_OPPED | CMD_SEARCH_FLAG_IS_VOICED | CMD_SEARCH_FLAG_NOT_VOICED))) {
- int flags = 0;
- struct ClientSocket *bot;
- for(bot = getBots(SOCKET_FLAG_READY, NULL); bot; bot = getBots(SOCKET_FLAG_READY, bot)) {
- if(bot->botid == client->botid) {
- struct ChanUser *chanuser = getChanUser(bot->user, channel);
- if(chanuser) {
- flags = chanuser->flags;
- break;
- }
- }
- }
- if((criteria.flags & CMD_SEARCH_FLAG_IS_OPPED) && !(flags & CHANUSERFLAG_OPPED)) continue;
- if((criteria.flags & CMD_SEARCH_FLAG_NOT_OPPED) && (flags & CHANUSERFLAG_OPPED)) continue;
- if((criteria.flags & CMD_SEARCH_FLAG_IS_VOICED) && !(flags & CHANUSERFLAG_VOICED)) continue;
- if((criteria.flags & CMD_SEARCH_FLAG_NOT_VOICED) && (flags & CHANUSERFLAG_VOICED)) continue;
- }
- }
- matches++;
- //output
- if(show_chans) {
- reply(getTextBot(), user, "%s", row[0]);
- }
- }
- reply(getTextBot(), user, "NS_TABLE_COUNT", matches);
-}
+++ /dev/null
-/* cmd_neonserv_set.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-typedef char* neonserv_cmd_set_function(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *argument);
-static void neonserv_cmd_set_setting(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int setting, char *argument);
-static char* neonserv_cmd_set_trigger(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *argument);
-static char* neonserv_cmd_set_modes(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *argument);
-static char* neonserv_cmd_set_dynlimit(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *argument);
-static char* neonserv_cmd_set_nodelete(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *argument);
-
-#define NS_VALID_FUNCTION 0x01
-#define NS_VALID_STRING 0x02
-#define NS_VALID_ACCESS 0x04
-#define NS_VALID_NO501 0x08
-#define NS_VALID_OPTIONS 0x10
-#define NS_VALID_NUMERIC 0x20
-#define NS_VALID_BOOLEAN 0x40
-#define NS_VALID_IF_HALFOP 0x80
-
-#define NS_HAS_OPT 0x100 /* options (SET_OPTION_{NAME}_{VALUE}) */
-#define NS_HAS_HELP 0x200 /* help (SET_HELP_{NAME}) - only shown if help is requested */
-
-static const struct {
- const char *setting;
- const char *chanfield;
- unsigned int valid;
- void *parameter;
-} channel_settings[] = {
- {"TRIGGER", NULL, NS_VALID_FUNCTION, neonserv_cmd_set_trigger},
- {"DEFAULTTOPIC", "channel_defaulttopic", NS_VALID_STRING, NULL},
- {"TOPICMASK", "channel_topicmask", NS_VALID_STRING, NULL},
- {"ADVANCEDTOPIC", "channel_exttopic", NS_VALID_BOOLEAN | NS_HAS_OPT, NULL},
- {"GREETING", "channel_greeting", NS_VALID_STRING, NULL},
- {"USERGREETING", "channel_usergreeting", NS_VALID_STRING, NULL},
- {"USERINFO", "channel_userinfo", NS_VALID_ACCESS | NS_HAS_HELP, NULL},
- {"WIPEINFO", "channel_wipeinfo", NS_VALID_ACCESS | NS_HAS_HELP, NULL},
- {"MODES", "channel_modes", NS_VALID_FUNCTION, neonserv_cmd_set_modes},
- {"INVITEME", "channel_getinvite", NS_VALID_ACCESS, NULL},
- {"GIVEOPS", "channel_getop", NS_VALID_ACCESS | NS_HAS_HELP, NULL},
- {"GIVEHALFOPS", "channel_gethalfop", NS_VALID_ACCESS | NS_HAS_HELP | NS_VALID_IF_HALFOP, NULL},
- {"GIVEVOICE", "channel_getvoice", NS_VALID_ACCESS | NS_HAS_HELP, NULL},
- {"ENFOPS", "channel_canop", NS_VALID_ACCESS | NS_HAS_HELP, NULL},
- {"ENFHALFOPS", "channel_canhalfop", NS_VALID_ACCESS | NS_HAS_HELP | NS_VALID_IF_HALFOP, NULL},
- {"ENFVOICE", "channel_canvoice", NS_VALID_ACCESS | NS_HAS_HELP, NULL},
- {"KICK", "channel_cankick", NS_VALID_ACCESS | NS_HAS_HELP, NULL},
- {"BAN", "channel_canban", NS_VALID_ACCESS | NS_HAS_HELP, NULL},
- {"STATICBAN", "channel_staticban", NS_VALID_ACCESS | NS_HAS_HELP, NULL},
- {"PUBCMD", "channel_pubcmd", NS_VALID_ACCESS, NULL},
- {"ENFMODES", "channel_enfmodes", NS_VALID_ACCESS, NULL},
- {"ENFTOPIC", "channel_enftopic", NS_VALID_ACCESS, NULL},
- {"TOPICSNARF", "channel_topicsnarf", NS_VALID_ACCESS | NS_HAS_HELP, NULL},
- {"CHANGETOPIC", "channel_changetopic", NS_VALID_ACCESS | NS_HAS_HELP, NULL},
- {"SETTERS", "channel_setters", NS_VALID_ACCESS | NS_VALID_NO501 | NS_HAS_HELP, NULL},
- {"ADDUSER", "channel_canadd", NS_VALID_ACCESS | NS_HAS_HELP, NULL},
- {"DELUSER", "channel_candel", NS_VALID_ACCESS | NS_HAS_HELP, NULL},
- {"CLVL", "channel_canclvl", NS_VALID_ACCESS | NS_HAS_HELP, NULL},
- {"RESYNC", "channel_canresync", NS_VALID_ACCESS | NS_HAS_HELP, NULL},
- {"SUSPEND", "channel_cansuspend", NS_VALID_ACCESS | NS_HAS_HELP, NULL},
- {"NOTICEUSERS", "channel_notice", NS_VALID_ACCESS, NULL},
- {"NOTICEREACTION", "channel_noticereaction", NS_VALID_OPTIONS | NS_HAS_OPT, "4"},
- {"CTCPUSERS", "channel_ctcp", NS_VALID_ACCESS, NULL},
- {"CTCPREACTION", "channel_ctcpreaction", NS_VALID_OPTIONS | NS_HAS_OPT, "4"},
- {"PROTECT", "channel_protect", NS_VALID_OPTIONS | NS_HAS_OPT, "4"},
- {"TOYS", "channel_toys", NS_VALID_OPTIONS | NS_HAS_OPT, "3"},
- {"DYNLIMIT", "channel_dynlimit", NS_VALID_NUMERIC | NS_VALID_FUNCTION | NS_HAS_OPT, neonserv_cmd_set_dynlimit},
- {"NODELETE", "channel_nodelete", NS_VALID_BOOLEAN | NS_VALID_FUNCTION, neonserv_cmd_set_nodelete},
- {NULL, NULL, 0, NULL}
-};
-
-#define MAX_QUERY_LEN 1024
-CMD_BIND(neonserv_cmd_set) {
- int i, j;
- if(argc && !strcmp(argv[0], "defaults")) {
- //reset channel settings
- int uaccess = getChannelAccess(user, chan);
- if(uaccess < 500) {
- if(isGodMode(user)) {
- event->flags |= CMDFLAG_OPLOG;
- } else {
- reply(getTextBot(), user, "NS_SET_DEFAULTS_OWNER", chan->name);
- return;
- }
- }
- int seed = 0;
- char *tmp;
- 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;
- 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);
- logEvent(event);
- } 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;
- char *args = (argc > 1 ? merge_argv(argv, 1, argc) : NULL);
- int with_halfops = get_int_field("General.have_halfop");
- while(channel_settings[i].setting) {
- if(!stricmp(channel_settings[i].setting, argv[0]) && (!(channel_settings[i].valid & NS_VALID_IF_HALFOP) || with_halfops)) {
- //setting found
- if(channel_settings[i].valid & NS_VALID_FUNCTION) {
- neonserv_cmd_set_function *func = channel_settings[i].parameter;
- func(client, user, chan, event, channel_settings[i].setting, args);
- } else {
- neonserv_cmd_set_setting(client, user, chan, event, i, args);
- }
- j = 1;
- break;
- }
- i++;
- }
- if(j == 0) {
- //unknown setting
- reply(getTextBot(), user, "NS_SET_UNKNOWN_SETTING", argv[0]);
- }
- } else {
- char query[MAX_QUERY_LEN], *value, *org_value, *tmp, nameBuf[64];
- int querypos = 0;
- MYSQL_RES *res, *defaults_res;
- MYSQL_ROW row, defaults;
- struct Table *table;
- char *content[2];
- int with_halfops = get_int_field("General.have_halfop");
- i = 0;
- j = 0;
- while(channel_settings[i].setting) {
- if((channel_settings[i].valid & NS_VALID_IF_HALFOP) && !with_halfops) {
- j++;
- i++;
- continue;
- }
- if(channel_settings[i].chanfield)
- querypos += sprintf(query + querypos, ", `%s`", channel_settings[i].chanfield);
- i++;
- }
- table = table_init(2, i-j, 0);
- table_set_bold(table, 0, 1);
- printf_mysql_query("SELECT `channel_id` %s FROM `channels` WHERE `channel_name` = 'defaults'", query);
- defaults_res = mysql_use();
- defaults = mysql_fetch_row(defaults_res);
- printf_mysql_query("SELECT `channel_name` %s FROM `channels` WHERE `channel_id` = '%d'", query, chan->channel_id);
- res = mysql_use();
- row = mysql_fetch_row(res);
- i = 0;
- j = 0;
- reply(getTextBot(), user, "NS_SET_HEADER", chan->name);
- while(channel_settings[i].setting) {
- if((channel_settings[i].valid & NS_VALID_IF_HALFOP) && !with_halfops) {
- i++;
- continue;
- }
- if(channel_settings[i].chanfield) {
- j++;
- 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, event, NULL, NULL);
- } else
- org_value = "0";
- value = org_value;
- if(channel_settings[i].valid & NS_VALID_BOOLEAN) {
- if(!strcmp(value, "0"))
- value = get_language_string(user, "NS_SET_OFF");
- else
- value = get_language_string(user, "NS_SET_ON");
- }
- strcpy(query, value);
- querypos = strlen(query);
- if(channel_settings[i].valid & NS_HAS_OPT) {
- sprintf(nameBuf, "NS_SET_OPTION_%s_%s", channel_settings[i].setting, org_value);
- tmp = get_language_string(user, nameBuf);
- if(tmp) {
- querypos += sprintf(query+querypos, " - %s", tmp);
- }
- }
- if(argc && channel_settings[i].valid & NS_HAS_HELP) {
- sprintf(nameBuf, "NS_SET_HELP_%s", channel_settings[i].setting);
- tmp = get_language_string(user, nameBuf);
- if(tmp) {
- querypos += sprintf(query+querypos, " - %s", tmp);
- }
- }
- content[0] = (char*)channel_settings[i].setting;
- content[1] = query;
- table_add(table, content);
- i++;
- }
- char **table_lines = table_end(table);
- for(i = 0; i < table->entrys; i++) {
- reply(getTextBot(), user, table_lines[i]);
- }
- table_free(table);
- }
-}
-
-static void neonserv_cmd_set_setting(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int setting, char *args) {
- char *value;
- char nameBuf[64];
- //get current value
- MYSQL_RES *res;
- MYSQL_ROW row;
- 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(args) {
- //change the channel setting
- //check the new argument
- int valid = channel_settings[setting].valid;
- if(valid & NS_VALID_STRING) {
- if(!strcmp(args, "*")) {
- args = "";
- }
- }
- if(valid & NS_VALID_ACCESS) {
- int caccess = atoi(args);
- 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);
- if(uaccess == 500) uaccess++;
- if(atoi(value) > uaccess) {
- if(isGodMode(user)) {
- event->flags |= CMDFLAG_OPLOG;
- } else {
- reply(getTextBot(), user, "NS_SET_CANNOT_SET");
- return;
- }
- }
- if(caccess > uaccess) {
- if(isGodMode(user)) {
- event->flags |= CMDFLAG_OPLOG;
- } else {
- reply(getTextBot(), user, "NS_SET_BADLEVEL");
- return;
- }
- }
- sprintf(nameBuf, "%d", caccess);
- args = nameBuf;
- }
- if(valid & NS_VALID_OPTIONS) {
- int options = atoi((char *) channel_settings[setting].parameter);
- int coption = atoi(args);
- if(coption < 0 || coption >= options) {
- reply(getTextBot(), user, "NS_SET_INVALID_OPTION", coption);
- int i;
- int nameBufPos = 0;
- if(valid & NS_HAS_OPT) {
- for(i = 0; i < options; i++) {
- sprintf(nameBuf, "NS_SET_OPTION_%s_%d", 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(args));
- args = nameBuf;
- }
- if(valid & NS_VALID_BOOLEAN) {
- if(!strcmp(args, "0") || !stricmp(args, "off") || !stricmp(args, get_language_string(user, "NS_SET_OFF"))) {
- args = "0";
- } else if(!strcmp(args, "1") || !stricmp(args, "on") || !stricmp(args, get_language_string(user, "NS_SET_ON"))) {
- args = "1";
- } else {
- reply(getTextBot(), user, "NS_SET_INVALID_BOOLEAN", args);
- return;
- }
- }
- //valid - set it
- value = args;
- printf_mysql_query("UPDATE `channels` SET `%s` = '%s' WHERE `channel_id` = '%d'", channel_settings[setting].chanfield, escape_string(value), chan->channel_id);
- logEvent(event);
- }
- if(channel_settings[setting].valid & NS_HAS_OPT) {
- sprintf(nameBuf, "NS_SET_OPTION_%s_%s", channel_settings[setting].setting, value);
- char *tmp = get_language_string(user, nameBuf);
- if(tmp)
- reply(getTextBot(), user, "\002%s\002 %s - %s", channel_settings[setting].setting, value, tmp);
- else
- reply(getTextBot(), user, "\002%s\002 %s", channel_settings[setting].setting, value);
- } else
- 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[setting].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, struct Event *event, const char *setting, char *argument) {
- char *trigger;
- //get current trigger
- MYSQL_RES *res;
- MYSQL_ROW row;
- printf_mysql_query("SELECT `trigger`, `defaulttrigger` FROM `bot_channels` LEFT JOIN `bots` ON `botid` = `bots`.`id` WHERE `chanid` = '%d' AND `botid` = '%d'", chan->channel_id, client->clientid);
- res = mysql_use();
- row = mysql_fetch_row(res);
- trigger = (row[0] ? row[0] : row[1]);
- if(argument) {
- int uaccess = getChannelAccess(user, chan);
- if(uaccess < 500) {
- if(isGodMode(user)) {
- event->flags |= CMDFLAG_OPLOG;
- } else {
- 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);
- logEvent(event);
- }
- 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, struct Event *event, const char *setting, char *argument) {
- char *value;
- char valueBuf[MAXLEN];
- //get current value
- MYSQL_RES *res;
- MYSQL_ROW row;
- 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
- struct ModeNode *modenode = createModeNode(NULL);
- parseModeString(modenode, argument);
- getFullModeString(modenode, valueBuf);
- value = valueBuf;
- printf_mysql_query("UPDATE `channels` SET `channel_modes` = '%s' WHERE `channel_id` = '%d'", escape_string(value), chan->channel_id);
- //TODO: set modelock
- freeModeNode(modenode);
- }
- 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, struct Event *event, const char *setting, char *argument) {
- char *value;
- char tmp[64];
- //get current value
- MYSQL_RES *res;
- MYSQL_ROW row;
- 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->modes, 'l'))
- putsock(client, "MODE %s -l", chan->name);
- value = argument;
- logEvent(event);
- }
- 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, struct Event *event, const char *setting, char *argument) {
- char *value;
- //get current value
- MYSQL_RES *res;
- MYSQL_ROW row;
- 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);
- event->flags |= CMDFLAG_OPLOG;
- value = argument;
- logEvent(event);
- }
- if(setting) {
- reply(getTextBot(), user, "\002%s\002 %s", setting, value);
- }
- return value;
-}
-
-#undef MAX_QUERY_LEN
+++ /dev/null
-/* cmd_neonserv_setrank.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* argv[0] rank id
-* argv[1] setting
-* argv[2-*] value
-*/
-
-static void neonserv_cmd_setrank_name(struct UserNode *user, int rank_id, char *current, char *value);
-static void neonserv_cmd_setrank_info(struct UserNode *user, int rank_id, char *current, char *value);
-static void neonserv_cmd_setrank_access(struct UserNode *user, int rank_id, char *current, char *value);
-static void neonserv_cmd_setrank_order(struct UserNode *user, int rank_id, char *current, char *value);
-
-CMD_BIND(neonserv_cmd_setrank) {
- MYSQL_RES *res;
- MYSQL_ROW row;
- printf_mysql_query("SELECT `rank_id`, `rank_name`, `rank_info`, `rank_access`, `rank_order` FROM `support_ranks` WHERE `rank_id` = '%s'", escape_string(argv[0]));
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) == NULL) {
- reply(getTextBot(), user, "NS_SETRANK_NOT_FOUND", argv[0]);
- return;
- }
- if(argc < 2) {
- reply(getTextBot(), user, "NS_SETRANK_HEAD", row[0]);
- reply(getTextBot(), user, "\002NAME \002 %s", row[1]);
- reply(getTextBot(), user, "\002INFO \002 %s", row[2]);
- reply(getTextBot(), user, "\002ACCESS \002 %s", row[3]);
- reply(getTextBot(), user, "\002ORDER \002 %s", row[4]);
- } else {
- char *value = NULL;
- if(argc > 2) {
- value = merge_argv(argv, 2, argc);
- }
- if(!stricmp(argv[1], "name"))
- neonserv_cmd_setrank_name(user, atoi(row[0]), row[1], value);
- else if(!stricmp(argv[1], "info"))
- neonserv_cmd_setrank_info(user, atoi(row[0]), row[2], value);
- else if(!stricmp(argv[1], "access"))
- neonserv_cmd_setrank_access(user, atoi(row[0]), row[3], value);
- else if(!stricmp(argv[1], "order"))
- neonserv_cmd_setrank_order(user, atoi(row[0]), row[4], value);
- else
- reply(getTextBot(), user, "NS_SETRANK_UNKNOWN_SETTING", row[1]);
- }
-}
-
-static void neonserv_cmd_setrank_name(struct UserNode *user, int rank_id, char *current, char *value) {
- if(value && stricmp(value, current)) {
- MYSQL_RES *res;
- MYSQL_ROW row;
- printf_mysql_query("SELECT `rank_id` FROM `support_ranks` WHERE `rank_name` = '%s'", escape_string(value));
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) != NULL) {
- reply(getTextBot(), user, "NS_ADDRANK_EXISTS", value);
- return;
- }
- printf_mysql_query("UPDATE `support_ranks` SET `rank_name` = '%s' WHERE `rank_id` = '%d'", escape_string(value), rank_id);
- current = value;
- }
- reply(getTextBot(), user, "\002NAME\002 %s", current);
-}
-
-static void neonserv_cmd_setrank_info(struct UserNode *user, int rank_id, char *current, char *value) {
- if(value && stricmp(value, current)) {
- printf_mysql_query("UPDATE `support_ranks` SET `rank_info` = '%s' WHERE `rank_id` = '%d'", escape_string(value), rank_id);
- current = value;
- }
- reply(getTextBot(), user, "\002INFO\002 %s", current);
-}
-
-static void neonserv_cmd_setrank_access(struct UserNode *user, int rank_id, char *current, char *value) {
- if(value && stricmp(value, current)) {
- int new_access = atoi(value);
- if(new_access <= 0 || new_access > 1000) {
- reply(getTextBot(), user, "NS_INVALID_ACCESS", new_access);
- return;
- }
- printf_mysql_query("UPDATE `users` SET `user_access` = '%d' WHERE `user_rank` = '%d'", new_access, rank_id);
- printf_mysql_query("UPDATE `support_ranks` SET `rank_access` = '%d' WHERE `rank_id` = '%d'", new_access, rank_id);
- current = value;
- }
- reply(getTextBot(), user, "\002ACCESS\002 %s", current);
-}
-
-static void neonserv_cmd_setrank_order(struct UserNode *user, int rank_id, char *current, char *value) {
- if(value && stricmp(value, current)) {
- int new_order = atoi(value);
- if(new_order <= 0 || new_order > 99) {
- reply(getTextBot(), user, "NS_SETRANK_ORDER_INVALID", new_order);
- return;
- }
- printf_mysql_query("UPDATE `support_ranks` SET `rank_order` = '%d' WHERE `rank_id` = '%d'", new_order, rank_id);
- current = value;
- }
- reply(getTextBot(), user, "\002ORDER\002 %s", current);
-}
+++ /dev/null
-/* cmd_neonserv_suspend.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* argv[0] - nick / *auth
-*/
-static USERAUTH_CALLBACK(neonserv_cmd_suspend_nick_lookup);
-static void neonserv_cmd_suspend_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nick, char *auth);
-
-struct neonserv_cmd_suspend_cache {
- struct ClientSocket *client, *textclient;
- struct UserNode *user;
- struct ChanNode *chan;
- struct Event *event;
- char *nick;
-};
-
-CMD_BIND(neonserv_cmd_suspend) {
- if(argv[0][0] == '*') {
- //we've got an auth
- argv[0]++;
- neonserv_cmd_suspend_async1(client, getTextBot(), user, chan, event, argv[0], argv[0]);
- } else {
- struct UserNode *cuser = getUserByNick(argv[0]);
- if(!cuser) {
- cuser = createTempUser(argv[0]);
- if(!cuser) {
- reply(getTextBot(), user, "NS_USER_UNKNOWN", argv[0]);
- return;
- }
- cuser->flags |= USERFLAG_ISTMPUSER;
- }
- if(cuser->flags & USERFLAG_ISAUTHED) {
- neonserv_cmd_suspend_async1(client, getTextBot(), user, chan, event, argv[0], cuser->auth);
- } else {
- struct neonserv_cmd_suspend_cache *cache = malloc(sizeof(*cache));
- if (!cache) {
- perror("malloc() failed");
- return;
- }
- cache->client = client;
- cache->textclient = getTextBot();
- cache->user = user;
- cache->chan = chan;
- cache->event = event;
- cache->nick = strdup(argv[0]);
- get_userauth(cuser, neonserv_cmd_suspend_nick_lookup, cache);
- }
- }
-}
-
-static USERAUTH_CALLBACK(neonserv_cmd_suspend_nick_lookup) {
- struct neonserv_cmd_suspend_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_suspend_async1(cache->client, cache->textclient, cache->user, cache->chan, cache->event, user->nick, user->auth);
- free(cache->nick);
- free(cache);
-}
-
-static void neonserv_cmd_suspend_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nick, char *auth) {
- //we've got a valid auth now...
- MYSQL_RES *res;
- MYSQL_ROW row;
- int userid, cflags;
- 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]);
- //check if the user is added
- printf_mysql_query("SELECT `chanuser_access`, `chanuser_id`, `chanuser_flags` FROM `chanusers` WHERE `chanuser_cid` = '%d' AND `chanuser_uid` = '%d'", chan->channel_id, userid);
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) != NULL) {
- if(atoi(row[0]) >= getChannelAccess(user, chan)) {
- if(isGodMode(user)) {
- event->flags |= CMDFLAG_OPLOG;
- } else {
- reply(textclient, user, "NS_USER_OUTRANKED", nick);
- return;
- }
- }
- //suspend
- cflags = atoi(row[2]);
- if(cflags & DB_CHANUSER_SUSPENDED) {
- reply(textclient, user, "NS_SUSPEND_ALREADY", nick);
- return;
- }
- cflags |= DB_CHANUSER_SUSPENDED;
- printf_mysql_query("UPDATE `chanusers` SET `chanuser_flags` = '%d' WHERE `chanuser_id` = '%s'", cflags, row[1]);
- reply(textclient, user, "NS_SUSPEND_DONE", nick, chan->name);
- logEvent(event);
- return;
- }
- }
- reply(textclient, user, "NS_NOT_ON_USERLIST", nick, chan->name);
-}
+++ /dev/null
-/* cmd_neonserv_topic.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* ADVANCEDTOPIC enabled
-* argv[0] topic id
-* argv[1-*] topic
-*
-* ADVANCEDTOPIC disabled
-* argv[0-*] topic
-*/
-
-#define ADVANCEDTOPIC_MAXID 9
-
-CMD_BIND(neonserv_cmd_topic) {
- MYSQL_RES *res;
- MYSQL_ROW row, default_row = NULL;
- int advanced_topic, i;
- char *newtopic;
- char *a,*b;
-
- printf_mysql_query("SELECT `channel_exttopic`, `channel_exttopic_topic`, `channel_topicmask`, `channel_enftopic`, `channel_topicsnarf`, `channel_defaulttopic` FROM `channels` WHERE `channel_id` = '%d'", chan->channel_id);
- res = mysql_use();
- row = mysql_fetch_row(res);
- if(!row[0] || !row[3] || !row[4]) {
- printf_mysql_query("SELECT `channel_exttopic`, `channel_enftopic`, `channel_topicsnarf` FROM `channels` WHERE `channel_name` = 'defaults'");
- default_row = mysql_fetch_row(mysql_use());
- }
-
- if(row[0] == NULL) {
- advanced_topic = atoi(default_row[0]);
- } else
- advanced_topic = atoi(row[0]);
- if(argc == 0) {
- //default topic!
- putsock(client, "TOPIC %s :%s", chan->name, row[5]);
- reply(getTextBot(), user, "NS_TOPIC_DONE", row[5]);
- logEvent(event);
- return;
- }
- int uaccess = getChannelAccess(user, chan);
- if(uaccess >= atoi((row[3] ? row[3] : default_row[1]))) {
- //just set the topic
- newtopic = merge_argv(argv, 0, argc);
- if(uaccess >= atoi((row[4] ? row[4] : default_row[2]))) {
- //set the default topic
- printf_mysql_query("UPDATE `channels` SET `channel_defaulttopic` = '%s' WHERE `channel_id` = '%d'", escape_string(newtopic), chan->channel_id);
- }
- putsock(client, "TOPIC %s :%s", chan->name, newtopic);
- reply(getTextBot(), user, "NS_TOPIC_DONE", newtopic);
- logEvent(event);
- return;
- }
- if(advanced_topic) {
- char *advtopics[ADVANCEDTOPIC_MAXID];
- int topic_id = 0;
- topic_id = atoi(argv[0]);
- if(!topic_id || topic_id > ADVANCEDTOPIC_MAXID) {
- reply(getTextBot(), user, "NS_EXTTOPIC_INVALID_ID", argv[0]);
- return;
- }
- //parse topics
- i = 0;
- b = row[1];
- while((a = strstr(b, "\n")) != NULL) {
- *a = '\0';
- if(i == ADVANCEDTOPIC_MAXID-1) break;
- advtopics[i++] = b;
- b = a+1;
- }
- advtopics[i++] = b;
- for(;i < ADVANCEDTOPIC_MAXID;i++)
- advtopics[i] = "";
- if(argc < 2) {
- //just show the topic with this id
- reply(getTextBot(), user, "NS_EXTTOPIC_TOPICID", topic_id, advtopics[topic_id-1]);
- return;
- }
- newtopic = merge_argv(argv, 1, argc);
- if(!strcmp(newtopic, "*"))
- newtopic = "";
- advtopics[topic_id-1] = newtopic;
- char topiclist[MAXLEN*2];
- topiclist[0] = '\0';
- int topiclistpos = 0;
- for(i = 0; i < ADVANCEDTOPIC_MAXID; i++) {
- if(topiclistpos + strlen(advtopics[i]) + 2 >= MAXLEN) break;
- topiclistpos += sprintf(topiclist+topiclistpos, (i ? "\n%s" : "%s"), advtopics[i]);
- }
- printf_mysql_query("UPDATE `channels` SET `channel_exttopic_topic` = '%s' WHERE `channel_id` = '%d'", escape_string(topiclist), chan->channel_id);
- //now build the new topic and set it...
- topiclistpos = 0;
- b = row[2];
- char *topicpart, *debugbb;
- while((a = strstr(b, "%")) != NULL) {
- *a = '\0';
- if(isdigit(a[1]) && a[1] - 48 > 0) {
- topicpart = advtopics[a[1] - 49];
- if(isdigit(topicpart[0]) && isdigit(b[strlen(b)-1]))
- debugbb = "\002\002"; //double bold to prevent following digits used as color code
- else
- debugbb = "";
- topiclistpos += sprintf(topiclist + topiclistpos, "%s%s%s", b, debugbb, topicpart);
- b = a+2;
- } else {
- topiclistpos += sprintf(topiclist + topiclistpos, "%s%%", b);
- b = a+1;
- }
- }
- topiclistpos += sprintf(topiclist + topiclistpos, "%s", b);
- if(topiclistpos > MAXLEN)
- topiclist[MAXLEN] = '\0';
- putsock(client, "TOPIC %s :%s", chan->name, topiclist);
- reply(getTextBot(), user, "NS_TOPIC_DONE", topiclist);
- logEvent(event);
- } else {
- newtopic = merge_argv(argv, 0, argc);
- char topiclist[MAXLEN*2];
- topiclist[0] = '\0';
- int topiclistpos = 0;
- b = row[2];
- char *debugbb;
- while((a = strstr(b, "*")) != NULL) {
- *a = '\0';
- if(isdigit(newtopic[0]) && isdigit(b[strlen(b)-1]))
- debugbb = "\002\002"; //double bold to prevent following digits used as color code
- else
- debugbb = "";
- topiclistpos += sprintf(topiclist + topiclistpos, "%s%s%s", b, debugbb, newtopic);
- b = a+1;
- }
- topiclistpos += sprintf(topiclist + topiclistpos, "%s", b);
- if(topiclistpos > MAXLEN)
- topiclist[MAXLEN] = '\0';
- putsock(client, "TOPIC %s :%s", chan->name, topiclist);
- reply(getTextBot(), user, "NS_TOPIC_DONE", topiclist);
- logEvent(event);
- }
-}
-
-#undef ADVANCEDTOPIC_MAXID
\ No newline at end of file
+++ /dev/null
-/* cmd_neonserv_trace.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-#define NS_TRACE_CRITERIA_AUTHED 0x01
-#define NS_TRACE_CRITERIA_NUMCHAN 0x02
-
-struct neonserv_cmd_trace_criteria {
- char *mask;
- char *nick;
- char *ident;
- char *host;
- char *account;
- unsigned int flags : 4;
- unsigned int authed : 1;
- unsigned int used_channel : 5; //32 max
- char *channel[10];
- unsigned int numchannels;
- unsigned int limit : 16;
-};
-
-CMD_BIND(neonserv_cmd_trace) {
- //ok parse the criterias
- struct neonserv_cmd_trace_criteria *criteria = malloc(sizeof(*criteria));
- if (!criteria) {
- perror("malloc() failed");
- return;
- }
- memset(criteria, 0, sizeof(*criteria));
- criteria->limit = 50;
- int i, show_user = 0;
- if(!stricmp(argv[0], "print")) {
- show_user = 1;
- }
- for(i = 1; i < argc; i += 2) {
- if(argc <= i+1) {
- reply(getTextBot(), user, "MODCMD_LESS_PARAM_COUNT");
- return;
- }
- if(!stricmp(argv[i], "mask")) criteria->mask = argv[i+1];
- else if(!stricmp(argv[i], "nick")) criteria->nick = argv[i+1];
- else if(!stricmp(argv[i], "ident")) criteria->ident = argv[i+1];
- else if(!stricmp(argv[i], "host")) criteria->host = argv[i+1];
- else if(!stricmp(argv[i], "account")) criteria->account = argv[i+1];
- else if(!stricmp(argv[i], "authed")) {
- if(!strcmp(argv[i+1], "0") || !strcmp(argv[i+1], "off") || !strcmp(argv[i+1], get_language_string(user, "NS_SET_OFF"))) {
- criteria->authed = 1;
- } else if(!strcmp(argv[i+1], "0") || !strcmp(argv[i+1], "off") || !strcmp(argv[i+1], get_language_string(user, "NS_SET_OFF"))) {
- criteria->authed = 0;
- } else {
- reply(getTextBot(), user, "NS_SET_INVALID_BOOLEAN", argv[i+1]);
- return;
- }
- criteria->flags |= NS_TRACE_CRITERIA_AUTHED;
- }
- else if(!stricmp(argv[i], "channel")) criteria->channel[criteria->used_channel++] = argv[i+1];
- else if(!stricmp(argv[i], "numchannels")) {
- criteria->numchannels = atoi(argv[i+1]);
- criteria->flags |= NS_TRACE_CRITERIA_NUMCHAN;
- }
- else if(!stricmp(argv[i], "limit")) {
- criteria->limit = atoi(argv[i+1]);
- }
- }
- char tmp[MAXLEN];
- int matches = 0;
- struct UserNode *cuser;
- reply(getTextBot(), user, "NS_TRACE_HEADER");
- for(cuser = getAllUsers(NULL); cuser; cuser = getAllUsers(cuser)) {
- if(show_user && matches == criteria->limit) {
- //too many
- break;
- }
- if(criteria->mask) {
- sprintf(tmp, "%s!%s@%s", cuser->nick, cuser->ident, cuser->host);
- if(match(criteria->mask, tmp)) continue;
- }
- if(criteria->nick && match(criteria->nick, cuser->nick)) continue;
- if(criteria->ident && match(criteria->ident, cuser->ident)) continue;
- if(criteria->host && match(criteria->host, cuser->host)) continue;
- if(criteria->account && (!(cuser->flags & USERFLAG_ISAUTHED) || match(criteria->account, cuser->auth))) continue;
- if((criteria->flags & NS_TRACE_CRITERIA_AUTHED) && (criteria->authed ^ (cuser->flags & USERFLAG_ISAUTHED))) continue;
- if((criteria->flags & NS_TRACE_CRITERIA_NUMCHAN)) {
- int ccount = 0;
- struct ChanUser *chanuser;
- for(chanuser = getUserChannels(cuser, NULL); chanuser; chanuser = getUserChannels(cuser, chanuser))
- ccount++;
- if(ccount < criteria->numchannels)
- continue;
- }
- matches++;
- //output
- if(show_user) {
- reply(getTextBot(), user, "%s!%s@%s %s", cuser->nick, cuser->ident, cuser->host, ((cuser->flags & USERFLAG_ISAUTHED) ? cuser->auth : "*"));
- }
- }
- reply(getTextBot(), user, "NS_TABLE_COUNT", matches);
-}
+++ /dev/null
-/* cmd_neonserv_trim.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* argv[0] target (format: minaccess-maxaccess/users/bans)
-* argv[1] duration
-*/
-static USERLIST_CALLBACK(neonserv_cmd_trim_userlist_lookup);
-static void neonserv_cmd_trim_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, int min_access, int max_access, int duration);
-
-struct neonserv_cmd_trim_cache {
- struct ClientSocket *client, *textclient;
- struct UserNode *user;
- struct Event *event;
- int min_access;
- int max_access;
- int duration;
-};
-
-CMD_BIND(neonserv_cmd_trim) {
- if(stricmp(argv[0], "bans") && !checkChannelAccess(user, chan, "channel_candel", 0)) {
- if(isGodMode(user)) {
- event->flags |= CMDFLAG_OPLOG;
- } else {
- reply(getTextBot(), user, "NS_ACCESS_DENIED");
- return;
- }
- }
- int min_access, max_access;
- int duration = strToTime(user, argv[1]);
- if(duration < 30) {
- reply(getTextBot(), user, "NS_TRIM_DURATION_TOO_SHORT", 30);
- return;
- }
- if(!stricmp(argv[0], "users")) {
- min_access = 1;
- max_access = getChannelAccess(user, chan) - 1;
- } else if(!stricmp(argv[0], "bans")) {
- if(!checkChannelAccess(user, chan, "channel_staticban", 0)) {
- if(isGodMode(user)) {
- event->flags |= CMDFLAG_OPLOG;
- } else {
- reply(getTextBot(), user, "NS_ACCESS_DENIED");
- return;
- }
- }
- MYSQL_RES *res;
- MYSQL_ROW row;
- char nameBuf[20];
- printf_mysql_query("SELECT `ban_mask`, `ban_id`, `ban_timeout` FROM `bans` WHERE `ban_channel` = '%d' AND `ban_triggered` < %d", chan->channel_id, (int) (time(0) - duration));
- res = mysql_use();
- int bancount = mysql_num_rows(res);
- struct ModeBuffer *modenode = initModeBuffer(client, chan);
- while ((row = mysql_fetch_row(res)) != NULL) {
- if(strcmp(row[2], "0")) {
- sprintf(nameBuf, "ban_%s", row[1]);
- timeq_del_name(nameBuf);
- }
- printf_mysql_query("DELETE FROM `bans` WHERE `ban_id` = '%s'", row[1]);
- modeBufferUnban(modenode, row[0]);
- }
- freeModeBuffer(modenode);
- char timeBuf[MAXLEN];
- reply(getTextBot(), user, "NS_TRIM_BAN_DONE", bancount, chan->name, timeToStr(user, duration, 3, timeBuf));
- if(bancount)
- logEvent(event);
- return;
- } else {
- char *seperator = strstr(argv[0], "-");
- if(seperator) {
- *seperator = '\0';
- seperator++;
- min_access = atoi(argv[0]);
- max_access = atoi(seperator);
- if(max_access < min_access) {
- reply(getTextBot(), user, "NS_INVALID_ACCESS_RANGE", min_access, max_access);
- return;
- }
- } else {
- min_access = atoi(argv[0]);
- max_access = min_access;
- }
- if(max_access >= getChannelAccess(user, chan)) {
- if(isGodMode(user)) {
- event->flags |= CMDFLAG_OPLOG;
- } else {
- reply(getTextBot(), user, "NS_NO_ACCESS");
- return;
- }
- }
- }
- struct neonserv_cmd_trim_cache *cache = malloc(sizeof(*cache));
- if (!cache) {
- perror("malloc() failed");
- return;
- }
- cache->client = client;
- cache->textclient = getTextBot();
- cache->user = user;
- cache->event = event;
- cache->min_access = min_access;
- cache->max_access = max_access;
- cache->duration = duration;
- get_userlist_with_invisible(chan, neonserv_cmd_trim_userlist_lookup, cache);
-}
-
-static USERLIST_CALLBACK(neonserv_cmd_trim_userlist_lookup) {
- struct neonserv_cmd_trim_cache *cache = data;
- //got userlist
- neonserv_cmd_trim_async1(cache->client, cache->textclient, cache->user, chan, cache->event, cache->min_access, cache->max_access, cache->duration);
- free(cache);
-}
-
-static void neonserv_cmd_trim_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, int min_access, int max_access, int duration) {
- MYSQL_RES *res;
- MYSQL_ROW row;
- int trim_count = 0, is_here;
- struct ChanUser *chanuser;
- printf_mysql_query("SELECT `chanuser_seen`, `user_user`, `chanuser_id` FROM `chanusers` LEFT JOIN `users` ON `chanuser_uid` = `user_id` WHERE `chanuser_cid` = '%d' AND `chanuser_access` >= '%d' AND `chanuser_access` <= '%d'", chan->channel_id, min_access, max_access);
- res = mysql_use();
- while ((row = mysql_fetch_row(res)) != NULL) {
- if(!strcmp(row[0], "0") || time(0) - atoi(row[0]) >= duration) {
- //check if the user is currently in the channel
- is_here = 0;
- for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
- if((chanuser->user->flags & USERFLAG_ISAUTHED) && !strcmp(chanuser->user->auth, row[1])) {
- is_here = 1;
- break;
- }
- }
- if(!is_here) {
- //delete the user
- trim_count++;
- printf_mysql_query("DELETE FROM `chanusers` WHERE `chanuser_id` = '%s'", row[2]);
- }
- }
- }
- char timeBuf[MAXLEN];
- reply(getTextBot(), user, "NS_TRIM_DONE", trim_count, min_access, max_access, chan->name, timeToStr(user, duration, 3, timeBuf));
- if(trim_count)
- logEvent(event);
-}
+++ /dev/null
-/* cmd_neonserv_unban.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* argv[0-*] nick[,*auth[,*!*@mask[...]]]
-*/
-struct neonserv_cmd_unban_cache {
- struct ClientSocket *client, *textclient;
- struct UserNode *user;
- struct ChanNode *chan;
- struct Event *event;
- struct ModeBuffer *modeBuf;
- int provided_masks, done_masks, pending_whos, unbanned_masks;
-};
-
-static USERAUTH_CALLBACK(neonserv_cmd_unban_userauth_lookup);
-static void neonserv_cmd_unban_nick(struct neonserv_cmd_unban_cache *cache, struct UserNode *user);
-static void neonserv_cmd_unban_mask(struct neonserv_cmd_unban_cache *cache, char *mask);
-static void neonserv_cmd_unban_finish(struct neonserv_cmd_unban_cache *cache);
-
-CMD_BIND(neonserv_cmd_unban) {
- char *mask, *nextmask;
- struct ModeBuffer *modeBuf;
- modeBuf = initModeBuffer(client, chan);
- nextmask = merge_argv_char(argv, 0, argc, ',');
- struct neonserv_cmd_unban_cache *cache = malloc(sizeof(*cache));
- if (!cache) {
- perror("malloc() failed");
- return;
- }
- cache->client = client;
- cache->textclient = getTextBot();
- cache->user = user;
- cache->chan = chan;
- cache->event = event;
- cache->modeBuf = modeBuf;
- cache->done_masks = 0;
- cache->provided_masks = 0;
- cache->unbanned_masks = 0;
- while((mask = nextmask)) {
- nextmask = strstr(mask, ",");
- if(nextmask) {
- *nextmask = '\0';
- nextmask++;
- }
- cache->provided_masks++;
- if(is_valid_nick(mask)) {
- struct UserNode *cuser = getUserByNick(mask);
- if(!cuser) {
- cuser = createTempUserMask(mask);
- if(!cuser) {
- break; //internal bot error
- }
- cuser->flags |= USERFLAG_ISTMPUSER;
- get_userauth(cuser, neonserv_cmd_unban_userauth_lookup, cache);
- cache->pending_whos++;
- } else {
- neonserv_cmd_unban_nick(cache, cuser);
- }
- } else {
- neonserv_cmd_unban_mask(cache, mask);
- }
- }
- if(!cache->pending_whos)
- neonserv_cmd_unban_finish(cache);
-}
-
-static USERAUTH_CALLBACK(neonserv_cmd_unban_userauth_lookup) {
- struct neonserv_cmd_unban_cache *cache = data;
- cache->pending_whos--;
- if(user)
- neonserv_cmd_unban_nick(cache, user);
- else
- neonserv_cmd_unban_mask(cache, user_nick);
- if(!cache->pending_whos)
- neonserv_cmd_unban_finish(cache);
-}
-
-static void neonserv_cmd_unban_nick(struct neonserv_cmd_unban_cache *cache, struct UserNode *user) {
- int matches = 0;
- struct BanNode *ban;
- char usermask[NICKLEN+USERLEN+HOSTLEN+3];
- sprintf(usermask, "%s!%s@%s", user->nick, user->ident, user->host);
- for(ban = cache->chan->bans; ban; ban = ban->next) {
- if(!match(ban->mask, usermask)) {
- modeBufferUnban(cache->modeBuf, ban->mask);
- cache->unbanned_masks++;
- matches++;
- }
- }
- if(matches)
- cache->done_masks++;
-}
-
-static void neonserv_cmd_unban_mask(struct neonserv_cmd_unban_cache *cache, char *mask) {
- char banmask[NICKLEN+USERLEN+HOSTLEN+3];
- int matches = 0;
- struct BanNode *ban;
- mask = make_banmask(mask, banmask);
- for(ban = cache->chan->bans; ban; ban = ban->next) {
- if(!match(mask, ban->mask)) {
- modeBufferUnban(cache->modeBuf, ban->mask);
- cache->unbanned_masks++;
- matches++;
- }
- }
- if(matches)
- cache->done_masks++;
- else {
- for(ban = cache->chan->bans; ban; ban = ban->next) {
- if(!match(ban->mask, mask)) {
- reply(cache->textclient, cache->user, "NS_DELBAN_BANNED_BY", mask, ban->mask);
- break;
- }
- }
- }
-}
-
-static void neonserv_cmd_unban_finish(struct neonserv_cmd_unban_cache *cache) {
- freeModeBuffer(cache->modeBuf);
- if(cache->done_masks == cache->provided_masks)
- reply(cache->textclient, cache->user, "NS_UNBAN_DONE", cache->unbanned_masks, cache->chan->name);
- else
- reply(cache->textclient, cache->user, "NS_UNBAN_FAIL", cache->client->user->nick);
- if(cache->done_masks)
- logEvent(cache->event);
- free(cache);
-}
-
+++ /dev/null
-/* cmd_neonserv_unbanall.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* argv[0-*] nothing
-*/
-
-CMD_BIND(neonserv_cmd_unbanall) {
- struct ModeBuffer *modeBuf;
- int bans = 0;
- struct BanNode *ban;
- modeBuf = initModeBuffer(client, chan);
- for(ban = chan->bans; ban; ban = ban->next) {
- modeBufferUnban(modeBuf, ban->mask);
- bans++;
- }
- freeModeBuffer(modeBuf);
- if(bans) {
- reply(getTextBot(), user, "NS_UNBANALL_DONE", bans, chan->name);
- logEvent(event);
- } else
- reply(getTextBot(), user, "NS_UNBANALL_FAIL", client->user->nick, chan->name);
-}
+++ /dev/null
-/* cmd_neonserv_unbanme.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* argv[0-*] nothing
-*/
-
-CMD_BIND(neonserv_cmd_unbanme) {
- struct ModeBuffer *modeBuf;
- int bans = 0;
- struct BanNode *ban;
- modeBuf = initModeBuffer(client, chan);
- char usermask[NICKLEN+USERLEN+HOSTLEN+3];
- sprintf(usermask, "%s!%s@%s", user->nick, user->ident, user->host);
- for(ban = chan->bans; ban; ban = ban->next) {
- if(!match(ban->mask, usermask)) {
- modeBufferUnban(modeBuf, ban->mask);
- bans++;
- }
- }
- freeModeBuffer(modeBuf);
- if(bans) {
- reply(getTextBot(), user, "NS_UNBANME_DONE", bans, chan->name);
- logEvent(event);
- } else
- reply(getTextBot(), user, "NS_UNBANME_FAIL", client->user->nick, usermask);
-}
+++ /dev/null
-/* cmd_neonserv_unsuspend.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* argv[0] - nick / *auth
-*/
-static USERAUTH_CALLBACK(neonserv_cmd_unsuspend_nick_lookup);
-static void neonserv_cmd_unsuspend_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nick, char *auth);
-
-struct neonserv_cmd_unsuspend_cache {
- struct ClientSocket *client, *textclient;
- struct UserNode *user;
- struct ChanNode *chan;
- struct Event *event;
- char *nick;
-};
-
-CMD_BIND(neonserv_cmd_unsuspend) {
- if(argv[0][0] == '*') {
- //we've got an auth
- argv[0]++;
- neonserv_cmd_unsuspend_async1(client, getTextBot(), user, chan, event, argv[0], argv[0]);
- } else {
- struct UserNode *cuser = getUserByNick(argv[0]);
- if(!cuser) {
- cuser = createTempUser(argv[0]);
- if(!cuser) {
- reply(getTextBot(), user, "NS_USER_UNKNOWN", argv[0]);
- return;
- }
- cuser->flags |= USERFLAG_ISTMPUSER;
- }
- if(cuser->flags & USERFLAG_ISAUTHED) {
- neonserv_cmd_unsuspend_async1(client, getTextBot(), user, chan, event, argv[0], cuser->auth);
- } else {
- struct neonserv_cmd_unsuspend_cache *cache = malloc(sizeof(*cache));
- if (!cache) {
- perror("malloc() failed");
- return;
- }
- cache->client = client;
- cache->textclient = getTextBot();
- cache->user = user;
- cache->chan = chan;
- cache->event = event;
- cache->nick = strdup(argv[0]);
- get_userauth(cuser, neonserv_cmd_unsuspend_nick_lookup, cache);
- }
- }
-}
-
-static USERAUTH_CALLBACK(neonserv_cmd_unsuspend_nick_lookup) {
- struct neonserv_cmd_unsuspend_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_unsuspend_async1(cache->client, cache->textclient, cache->user, cache->chan, cache->event, user->nick, user->auth);
- free(cache->nick);
- free(cache);
-}
-
-static void neonserv_cmd_unsuspend_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nick, char *auth) {
- //we've got a valid auth now...
- MYSQL_RES *res;
- MYSQL_ROW row;
- int userid, cflags;
- 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]);
- //check if the user is added
- printf_mysql_query("SELECT `chanuser_access`, `chanuser_id`, `chanuser_flags` FROM `chanusers` WHERE `chanuser_cid` = '%d' AND `chanuser_uid` = '%d'", chan->channel_id, userid);
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) != NULL) {
- if(atoi(row[0]) >= getChannelAccess(user, chan)) {
- if(isGodMode(user)) {
- event->flags |= CMDFLAG_OPLOG;
- } else {
- reply(textclient, user, "NS_USER_OUTRANKED", nick);
- return;
- }
- }
- //unsuspend
- cflags = atoi(row[2]);
- if(!(cflags & DB_CHANUSER_SUSPENDED)) {
- reply(textclient, user, "NS_SUSPEND_NOT", nick);
- return;
- }
- cflags &= ~DB_CHANUSER_SUSPENDED;
- printf_mysql_query("UPDATE `chanusers` SET `chanuser_flags` = '%d' WHERE `chanuser_id` = '%s'", cflags, row[1]);
- reply(textclient, user, "NS_SUSPEND_RESTORED", nick, chan->name);
- logEvent(event);
- return;
- }
- }
- reply(textclient, user, "NS_NOT_ON_USERLIST", nick, chan->name);
-}
+++ /dev/null
-/* cmd_neonserv_unvisited.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-struct neonserv_cmd_unvisited_cache {
- struct ClientSocket *client, *textclient;
- struct UserNode *user;
- int duration;
- int who_count, matches;
-};
-
-static USERLIST_CALLBACK(neonserv_cmd_unvisited_userlist_lookup);
-static int neonserv_cmd_unvisited_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, int duration);
-static void neonserv_cmd_unvisited_async2(struct neonserv_cmd_unvisited_cache *cache);
-
-CMD_BIND(neonserv_cmd_unvisited) {
- int duration = (argc ? strToTime(user, argv[0]) : 60*60*24*7*3);
- reply(getTextBot(), user, "NS_SEARCH_HEADER");
- MYSQL_RES *res, *res2;
- MYSQL_ROW row, row2;
- struct ChanNode *channel;
- struct neonserv_cmd_unvisited_cache *cache = malloc(sizeof(*cache));
- if (!cache) {
- perror("malloc() failed");
- return;
- }
- cache->client = client;
- cache->textclient = getTextBot();
- cache->user = user;
- cache->duration = duration;
- cache->who_count = 1; /* small fake to prevent the cache to be freed too early */
- cache->matches = 0;
- printf_mysql_query("SELECT `channel_id`, `channel_name`, `channel_nodelete` FROM `bot_channels` LEFT JOIN `channels` ON `chanid` = `channel_id` LEFT JOIN `users` ON `channel_registrator` = `user_id` WHERE `botid` = '%d'", client->botid);
- res = mysql_use();
- while ((row = mysql_fetch_row(res)) != NULL) {
- if(!strcmp(row[2], "1")) continue;
- printf_mysql_query("SELECT `chanuser_seen` FROM `chanusers` WHERE `chanuser_cid` = '%s' AND `chanuser_access` >= 300 ORDER BY `chanuser_seen` DESC LIMIT 1", row[0]);
- res2 = mysql_use();
- row2 = mysql_fetch_row(res2);
- if(row2 && atol(row2[0]) > (time(0) - duration)) continue;
- channel = getChanByName(row[1]);
- if(channel) {
- cache->who_count++;
- channel->channel_id = atoi(row[0]);
- get_userlist_with_invisible(channel, neonserv_cmd_unvisited_userlist_lookup, cache);
- } else {
- reply(getTextBot(), user, "%s", row[1]);
- cache->matches++;
- }
- }
- cache->who_count--; //see fix on line 46
- if(cache->who_count == 0) {
- neonserv_cmd_unvisited_async2(cache);
- }
-}
-
-static USERLIST_CALLBACK(neonserv_cmd_unvisited_userlist_lookup) {
- struct neonserv_cmd_unvisited_cache *cache = data;
- if(neonserv_cmd_unvisited_async1(cache->client, cache->textclient, cache->user, chan, cache->duration))
- cache->matches++;
- cache->who_count--;
- if(cache->who_count == 0) {
- neonserv_cmd_unvisited_async2(cache);
- }
-}
-
-static int neonserv_cmd_unvisited_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, int duration) {
- struct ChanUser *chanuser;
- MYSQL_RES *res2;
- MYSQL_ROW row2;
- int active = 0;
- for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
- if(isBot(chanuser->user)) continue;
- if((chanuser->user->flags & USERFLAG_ISAUTHED)) {
- printf_mysql_query("SELECT `chanuser_id`, `chanuser_access` FROM `chanusers` LEFT JOIN `users` ON `user_id` = `chanuser_uid` WHERE `chanuser_cid` = '%d' AND `user_user` = '%s'", chan->channel_id, escape_string(chanuser->user->auth));
- res2 = mysql_use();
- row2 = mysql_fetch_row(res2);
- if(row2 && atoi(row2[1]) >= 300) {
- printf_mysql_query("UPDATE `chanusers` SET `chanuser_seen` = UNIX_TIMESTAMP() WHERE `chanuser_id` = '%s'", row2[0]);
- active = 1;
- }
- }
- }
- if(!active) {
- reply(textclient, user, "%s", chan->name);
- }
- return !active;
-}
-
-static void neonserv_cmd_unvisited_async2(struct neonserv_cmd_unvisited_cache *cache) {
- reply(cache->textclient, cache->user, "NS_TABLE_COUNT", cache->matches);
- free(cache);
-}
+++ /dev/null
-/* cmd_neonserv_up.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* no arguments
-*/
-
-struct neonserv_cmd_up_cache {
- struct ClientSocket *client;
- struct ClientSocket *textclient;
- struct UserNode *user;
- struct Event *event;
-};
-
-static void neonserv_cmd_up_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event);
-static USERLIST_CALLBACK(neonserv_cmd_up_userlist_lookup);
-
-CMD_BIND(neonserv_cmd_up) {
- if(isModeSet(chan->modes, 'd') || isModeSet(chan->modes, 'D')) {
- struct neonserv_cmd_up_cache *cache = malloc(sizeof(*cache));
- if (!cache) {
- perror("malloc() failed");
- return;
- }
- cache->client = client;
- cache->textclient = getTextBot();
- cache->user = user;
- cache->event = event;
- get_userlist_if_invisible(chan, neonserv_cmd_up_userlist_lookup, cache);
- } else {
- neonserv_cmd_up_async1(client, getTextBot(), user, chan, event);
- }
-}
-
-static USERLIST_CALLBACK(neonserv_cmd_up_userlist_lookup) {
- struct neonserv_cmd_up_cache *cache = data;
- neonserv_cmd_up_async1(cache->client, cache->textclient, cache->user, chan, cache->event);
- free(cache);
-}
-
-static void neonserv_cmd_up_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event) {
- struct ChanUser *chanuser = getChanUser(user, chan);
- if(!chanuser) {
- reply(getTextBot(), user, "NS_NOT_ON_CHANNEL_YOU", chan->name);
- return;
- }
- check_mysql();
- loadChannelSettings(chan);
- MYSQL_RES *res, *default_res;
- MYSQL_ROW row, default_row;
- int chan_getop, chan_getvoice, caccess;
- printf_mysql_query("SELECT `channel_getop`, `channel_getvoice` FROM `channels` WHERE `channel_id` = '%d'", chan->channel_id);
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) == NULL) return;
- if(!row[0] || !row[1]) {
- printf_mysql_query("SELECT `channel_getop`, `channel_getvoice` FROM `channels` WHERE `channel_name` = 'defaults'");
- default_res = mysql_use();
- if ((default_row = mysql_fetch_row(default_res)) == NULL) return;
- chan_getop = (row[0] ? atoi(row[0]) : atoi(default_row[0]));
- chan_getvoice = (row[1] ? atoi(row[1]) : atoi(default_row[1]));
- } else {
- chan_getop = atoi(row[0]);
- chan_getvoice = atoi(row[1]);
- }
- caccess = getChannelAccess(user, chan);
- if(caccess >= chan_getop) {
- if(!(chanuser->flags & CHANUSERFLAG_OPPED)) {
- putsock(client, "MODE %s +o %s", chan->name, user->nick);
- logEvent(event);
- } else
- reply(getTextBot(), user, "NS_UP_ALREADY_OP", chan->name);
- } else if(caccess >= chan_getvoice) {
- if(!(chanuser->flags & CHANUSERFLAG_VOICED)) {
- putsock(client, "MODE %s +v %s", chan->name, user->nick);
- logEvent(event);
- } else
- reply(getTextBot(), user, "NS_UP_ALREADY_VOICE", chan->name);
- } else
- reply(getTextBot(), user, "NS_NOT_ON_USERLIST_YOU", chan->name);
-}
+++ /dev/null
-/* cmd_neonserv_upall.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* no arguments
-*/
-
-CMD_BIND(neonserv_cmd_upall) {
- MYSQL_RES *res, *default_res;
- MYSQL_ROW row, default_row;
- struct ChanUser *chanuser;
- int userid, chan_getop, chan_getvoice, caccess;
- int botid = client->botid;
- printf_mysql_query("SELECT `user_id` FROM `users` WHERE `user_user` = '%s'", user->auth);
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) == NULL)
- return;
- userid = atoi(row[0]);
- printf_mysql_query("SELECT `chanuser_access`, `channel_getop`, `channel_getvoice`, `channel_name`, `channel_id` FROM `chanusers` LEFT JOIN `channels` ON `chanuser_cid` = `channel_id` WHERE `chanuser_uid` = '%d'", userid);
- res = mysql_use();
- while ((row = mysql_fetch_row(res)) != NULL) {
- chan = getChanByName(row[3]);
- if(!chan) continue;
- printf_mysql_query("SELECT `botid` FROM `bot_channels` LEFT JOIN `bots` ON `bot_channels`.`botid` = `bots`.`id` WHERE `chanid` = '%s' AND `botclass` = '%d'", row[4], client->botid);
- if (mysql_fetch_row(mysql_use()) == NULL) continue;
- if(!(chanuser = getChanUser(user, chan))) continue;
- if(!row[1] || !row[2]) {
- printf_mysql_query("SELECT `channel_getop`, `channel_getvoice` FROM `channels` WHERE `channel_name` = 'defaults'");
- default_res = mysql_use();
- if ((default_row = mysql_fetch_row(default_res)) == NULL) return;
- chan_getop = (row[1] ? atoi(row[1]) : atoi(default_row[0]));
- chan_getvoice = (row[2] ? atoi(row[2]) : atoi(default_row[1]));
- } else {
- chan_getop = atoi(row[1]);
- chan_getvoice = atoi(row[2]);
- }
- caccess = atoi(row[0]);
- int done = 0;
- client = getChannelBot(chan, botid);
- if(!client) continue;
- if(caccess >= chan_getop) {
- if(!(chanuser->flags & CHANUSERFLAG_OPPED)) {
- putsock(client, "MODE %s +o %s", chan->name, user->nick);
- done = 1;
- }
- } else if(caccess >= chan_getvoice) {
- if(!(chanuser->flags & CHANUSERFLAG_VOICED)) {
- putsock(client, "MODE %s +v %s", chan->name, user->nick);
- done = 1;
- }
- }
- if(done) {
- event->chan = chan;
- logEvent(event);
- }
- }
-}
+++ /dev/null
-/* cmd_neonserv_users.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* argv[0] - usermask
-* argv[1] - min access
-* argv[2] - max access
-*/
-static USERLIST_CALLBACK(neonserv_cmd_users_userlist_lookup);
-static void neonserv_cmd_users_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, char *usermask, int min_access, int max_access);
-
-struct neonserv_cmd_users_cache {
- struct ClientSocket *client, *textclient;
- struct UserNode *user;
- char *usermask;
- int min_access;
- int max_access;
-};
-
-CMD_BIND(neonserv_cmd_users) {
- int min_access = 1, max_access = 500;
- char *usermask = NULL;
- if(argc > 0)
- usermask = argv[0];
- if(argc > 2) {
- min_access = atoi(argv[1]);
- max_access = atoi(argv[2]);
- }
- struct neonserv_cmd_users_cache *cache = malloc(sizeof(*cache));
- if (!cache) {
- perror("malloc() failed");
- return;
- }
- cache->client = client;
- cache->textclient = getTextBot();
- cache->user = user;
- cache->usermask = (usermask ? strdup(usermask) : NULL);
- cache->min_access = min_access;
- cache->max_access = max_access;
- get_userlist_with_invisible(chan, neonserv_cmd_users_userlist_lookup, cache);
-}
-
-static USERLIST_CALLBACK(neonserv_cmd_users_userlist_lookup) {
- struct neonserv_cmd_users_cache *cache = data;
- neonserv_cmd_users_async1(cache->client, cache->textclient, cache->user, chan, cache->usermask, cache->min_access, cache->max_access);
- if(cache->usermask)
- free(cache->usermask);
- free(cache);
-}
-
-static void neonserv_cmd_users_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, char *usermask, int min_access, int max_access) {
- MYSQL_RES *res;
- MYSQL_ROW row;
- int content_count = 0, cflags, is_here, caccess, i;
- char seenstr[MAXLEN];
- struct Table *table;
- struct ChanUser *chanuser;
- printf_mysql_query("SELECT `chanuser_access`, `user_user`, `chanuser_seen`, `chanuser_flags` FROM `chanusers` LEFT JOIN `users` ON `chanuser_uid` = `user_id` WHERE `chanuser_cid` = '%d' ORDER BY `chanuser_access` DESC, `user_user` ASC", chan->channel_id);
- res = mysql_use();
- table = table_init(4, mysql_num_rows(res) + 1, 0);
- if(usermask)
- reply(textclient, user, "NS_USERS_HEADER_MATCH", chan->name, min_access, max_access, usermask);
- else
- reply(textclient, user, "NS_USERS_HEADER", chan->name, min_access, max_access);
- char *content[4];
- content[0] = get_language_string(user, "NS_USERS_HEADER_ACCESS");
- content[1] = get_language_string(user, "NS_USERS_HEADER_ACCOUNT");
- content[2] = get_language_string(user, "NS_USERS_HEADER_SEEN");
- content[3] = get_language_string(user, "NS_USERS_HEADER_STATE");
- table_add(table, content);
- while ((row = mysql_fetch_row(res)) != NULL) {
- caccess = atoi(row[0]);
- if((!usermask || !match(usermask, row[1])) && caccess >= min_access && caccess <= max_access) {
- content[0] = row[0];
- content[1] = row[1];
- is_here = 0;
- for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
- if((chanuser->user->flags & USERFLAG_ISAUTHED) && !stricmp(chanuser->user->auth, row[1])) {
- if((chanuser->flags & CHANUSERFLAG_INVISIBLE))
- is_here = 2;
- else {
- is_here = 1;
- break;
- }
- }
- }
- if(is_here) {
- content[2] = get_language_string(user, (is_here == 2 ? "NS_USERS_SEEN_INVISIBLE" : "NS_USERS_SEEN_HERE"));
- } else if(!strcmp(row[2], "0")) {
- content[2] = get_language_string(user, "NS_USERS_SEEN_NEVER");
- } else {
- timeToStr(user, (time(0) - atoi(row[2])), 2, seenstr);
- content[2] = seenstr; //generate time
- }
- cflags = atoi(row[3]);
- if(cflags & DB_CHANUSER_SUSPENDED)
- content[3] = get_language_string(user, "NS_USERS_STATE_SUSPENDED");
- else
- content[3] = get_language_string(user, "NS_USERS_STATE_NORMAL");
- content_count++;
- table_add(table, content);
- }
- }
- //send the table
- char **table_lines = table_end(table);
- for(i = 0; i < table->entrys; i++) {
- reply(textclient, user, table_lines[i]);
- }
- if(!content_count)
- reply(textclient, user, "NS_TABLE_NONE");
- if(usermask || min_access != 1 || max_access != 500)
- reply(textclient, user, (table->length == 2 ? "NS_USERS_COUNT_MATCH_1" : "NS_USERS_COUNT_MATCH"), table->length - 1, chan->name, content_count);
- else
- reply(textclient, user, (table->length == 2 ? "NS_USERS_COUNT_1" : "NS_USERS_COUNT"), table->length - 1, chan->name);
- table_free(table);
-}
+++ /dev/null
-/* cmd_neonserv_uset.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-CMD_BIND(neonserv_cmd_uset) {
- MYSQL_RES *res;
- MYSQL_ROW row;
- loadUserSettings(user);
- if(argc > 0) {
- if(!stricmp(argv[0], "language")) {
- struct language* lang;
- if(argc > 1) {
- if((lang = get_language_by_tag(argv[1])) == NULL && (lang = get_language_by_name(argv[1])) == NULL) {
- lang = user->language;
- } else {
- printf_mysql_query("SELECT `user_id` FROM `users` WHERE `user_user` = '%s'", escape_string(user->auth));
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) != NULL) {
- printf_mysql_query("UPDATE `users` SET `user_lang` = '%s' WHERE `user_id` = '%s'", escape_string(lang->langtag), row[0]);
- } else {
- printf_mysql_query("INSERT INTO `users` (`user_user`, `user_lang`) VALUES ('%s', '%s')", escape_string(user->auth), escape_string(lang->langtag));
- }
- struct UserNode *cuser;
- for(cuser = getAllUsers(NULL); cuser; cuser = getAllUsers(cuser)) {
- if((cuser->flags & USERFLAG_ISAUTHED) && !stricmp(user->auth, cuser->auth))
- cuser->language = lang;
- }
- }
- } else
- lang = user->language;
- reply(getTextBot(), user, "\002Language \002%s", lang->langname);
- char tmp[MAXLEN];
- int tmppos = 0;
- lang = get_default_language();
- tmppos = sprintf(tmp, "%s (%s)", lang->langname, lang->langtag);
- printf_mysql_query("SELECT `lang`,`text` FROM `language` WHERE `ident` = 'name'");
- res = mysql_use();
- while((row = mysql_fetch_row(res)) != NULL) {
- tmppos += sprintf(tmp + tmppos, ", %s (%s)", row[1], row[0]);
- }
- reply(getTextBot(), user, " %s", tmp);
- } else if(!stricmp(argv[0], "noinvite") && chan) {
- loadChannelSettings(chan);
- if(!(chan->flags & CHANFLAG_CHAN_REGISTERED)) {
- reply(getTextBot(), user, "MODCMD_CHAN_REQUIRED");
- return;
- }
- 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));
- res = mysql_use();
- row = mysql_fetch_row(res);
- int noinvite = (row ? 1 : 0);
- if(argc > 1) {
- if(!strcmp(argv[1], "0") || !stricmp(argv[1], "off") || !stricmp(argv[1], get_language_string(user, "NS_SET_OFF"))) {
- if(noinvite) {
- printf_mysql_query("DELETE FROM `noinvite` WHERE `id` = '%s'", row[0]);
- noinvite = 0;
- }
- } else if(!strcmp(argv[1], "1") || !stricmp(argv[1], "on") || !stricmp(argv[1], get_language_string(user, "NS_SET_ON"))) {
- if(!noinvite) {
- int userid;
- printf_mysql_query("SELECT `user_id` FROM `users` WHERE `user_user` = '%s'", escape_string(user->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(user->auth));
- userid = (int) mysql_insert_id(get_mysql_conn());
- }
- printf_mysql_query("INSERT INTO `noinvite` (`uid`, `cid`) VALUES ('%d', '%d')", userid, chan->channel_id);
- noinvite = 1;
- }
- }
- }
- reply(getTextBot(), user, "\002NoInvite \002%s", (noinvite ? get_language_string(user, "NS_SET_ON") : get_language_string(user, "NS_SET_OFF")));
- } else if((!stricmp(argv[0], "autoinvite") || !stricmp(argv[0], "noautoop") || !stricmp(argv[0], "info")) && chan) {
- loadChannelSettings(chan);
- if(!(chan->flags & CHANFLAG_CHAN_REGISTERED)) {
- reply(getTextBot(), user, "MODCMD_CHAN_REQUIRED");
- return;
- }
- 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));
- res = mysql_use();
- row = mysql_fetch_row(res);
- if(row) {
- int flags = atoi(row[0]);
- if(!stricmp(argv[0], "autoinvite")) {
- int getInvite = 0;
- if(!row[3] && atoi(row[2]) >= atoi(getChanDefault("channel_getinvite")))
- getInvite = 1;
- else if(row[3] && atoi(row[2]) >= atoi(row[3]))
- getInvite = 1;
- if(getInvite && argc > 1) {
- if(!strcmp(argv[1], "0") || !stricmp(argv[1], "off") || !stricmp(argv[1], get_language_string(user, "NS_SET_OFF"))) {
- if(flags & DB_CHANUSER_AUTOINVITE) {
- flags &= ~DB_CHANUSER_AUTOINVITE;
- printf_mysql_query("UPDATE `chanusers` SET `chanuser_flags` = '%d' WHERE `chanuser_id` = '%s'", flags, row[4]);
- }
- } else if(!strcmp(argv[1], "1") || !stricmp(argv[1], "on") || !stricmp(argv[1], get_language_string(user, "NS_SET_ON"))) {
- if(!(flags & DB_CHANUSER_AUTOINVITE)) {
- flags |= DB_CHANUSER_AUTOINVITE;
- printf_mysql_query("UPDATE `chanusers` SET `chanuser_flags` = '%d' WHERE `chanuser_id` = '%s'", flags, row[4]);
- }
- }
- }
- if(getInvite)
- reply(getTextBot(), user, "\002AutoInvite \002%s", ((flags & DB_CHANUSER_AUTOINVITE) ? get_language_string(user, "NS_SET_ON") : get_language_string(user, "NS_SET_OFF")));
- else
- reply(getTextBot(), user, "\002AutoInvite \002%s", get_language_string(user, "NS_USET_NO_ACCESS"));
- } else if(!stricmp(argv[0], "noautoop")) {
- if(argc > 1) {
- if(!strcmp(argv[1], "0") || !stricmp(argv[1], "off") || !stricmp(argv[1], get_language_string(user, "NS_SET_OFF"))) {
- if(flags & DB_CHANUSER_NOAUTOOP) {
- flags &= ~DB_CHANUSER_NOAUTOOP;
- printf_mysql_query("UPDATE `chanusers` SET `chanuser_flags` = '%d' WHERE `chanuser_id` = '%s'", flags, row[4]);
- }
- } else if(!strcmp(argv[1], "1") || !stricmp(argv[1], "on") || !stricmp(argv[1], get_language_string(user, "NS_SET_ON"))) {
- if(!(flags & DB_CHANUSER_NOAUTOOP)) {
- flags |= DB_CHANUSER_NOAUTOOP;
- printf_mysql_query("UPDATE `chanusers` SET `chanuser_flags` = '%d' WHERE `chanuser_id` = '%s'", flags, row[4]);
- }
- }
- }
- reply(getTextBot(), user, "\002NoAutoOp \002%s", ((flags & DB_CHANUSER_NOAUTOOP) ? get_language_string(user, "NS_SET_ON") : get_language_string(user, "NS_SET_OFF")));
- } else if(!stricmp(argv[0], "info")) {
- char *infoline;
- if(argc > 1) {
- infoline = merge_argv(argv, 1, argc);
- if(!strcmp(infoline, "*"))
- infoline = "";
- printf_mysql_query("UPDATE `chanusers` SET `chanuser_infoline` = '%s' WHERE `chanuser_id` = '%s'", escape_string(infoline), row[4]);
- } else
- infoline = row[1];
- reply(getTextBot(), user, "\002Info \002%s", infoline);
- }
- } else
- reply(getTextBot(), user, "NS_NOT_ON_USERLIST_YOU", chan);
- } else
- reply(getTextBot(), user, "NS_USET_UNKNOWN_SETTING", argv[0]);
- } else {
- //view all options
- reply(getTextBot(), user, "NS_USET_GLOBAL");
- reply(getTextBot(), user, "\002Language \002%s", user->language->langname);
- if(!chan) return;
- loadChannelSettings(chan);
- if(!(chan->flags & CHANFLAG_CHAN_REGISTERED)) return;
- reply(getTextBot(), user, "NS_USET_CHANNEL");
- 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));
- res = mysql_use();
- row = mysql_fetch_row(res);
- reply(getTextBot(), user, "\002NoInvite \002%s", (row ? get_language_string(user, "NS_SET_ON") : get_language_string(user, "NS_SET_OFF")));
- printf_mysql_query("SELECT `chanuser_flags`, `chanuser_infoline`, `chanuser_access`, `channel_getinvite` 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));
- res = mysql_use();
- row = mysql_fetch_row(res);
- if(row) {
- int flags = atoi(row[0]);
- int getInvite = 0;
- if(!row[3] && atoi(row[2]) >= atoi(getChanDefault("channel_getinvite")))
- getInvite = 1;
- else if(row[3] && atoi(row[2]) >= atoi(row[3]))
- getInvite = 1;
- if(getInvite)
- reply(getTextBot(), user, "\002AutoInvite \002%s", ((flags & DB_CHANUSER_AUTOINVITE) ? get_language_string(user, "NS_SET_ON") : get_language_string(user, "NS_SET_OFF")));
- else
- reply(getTextBot(), user, "\002AutoInvite \002%s", get_language_string(user, "NS_USET_NO_ACCESS"));
- reply(getTextBot(), user, "\002NoAutoOp \002%s", ((flags & DB_CHANUSER_NOAUTOOP) ? get_language_string(user, "NS_SET_ON") : get_language_string(user, "NS_SET_OFF")));
- reply(getTextBot(), user, "\002Info \002%s", row[1]);
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-/* cmd_neonserv_voice.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* argv[0-*] nicks
-*/
-static USERLIST_CALLBACK(neonserv_cmd_voice_userlist_lookup);
-static void neonserv_cmd_voice_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nicks);
-
-struct neonserv_cmd_voice_cache {
- struct ClientSocket *client, *textclient;
- struct UserNode *user;
- struct Event *event;
- char *nicks;
-};
-
-CMD_BIND(neonserv_cmd_voice) {
- struct neonserv_cmd_voice_cache *cache = malloc(sizeof(*cache));
- if (!cache) {
- perror("malloc() failed");
- return;
- }
- cache->client = client;
- cache->textclient = getTextBot();
- cache->user = user;
- cache->event = event;
- cache->nicks = strdup(merge_argv(argv, 0, argc));
- get_userlist_if_invisible(chan, neonserv_cmd_voice_userlist_lookup, cache);
-}
-
-static USERLIST_CALLBACK(neonserv_cmd_voice_userlist_lookup) {
- struct neonserv_cmd_voice_cache *cache = data;
- neonserv_cmd_voice_async1(cache->client, cache->textclient, cache->user, chan, cache->event, cache->nicks);
- free(cache->nicks);
- free(cache);
-}
-
-static void neonserv_cmd_voice_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nicks) {
- int total_users = 0, done_users = 0;
- struct UserNode *cuser;
- struct ChanUser *chanuser;
- struct ModeBuffer *modeBuf;
- modeBuf = initModeBuffer(client, chan);
- char *a, *b = nicks;
- do {
- a = strstr(b, " ");
- if(a) *a = '\0';
- total_users++;
- cuser = searchUserByNick(b);
- if(!cuser) {
- //check for an invisible user
- for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
- if(!stricmp(chanuser->user->nick, b)) {
- cuser = chanuser->user;
- break;
- }
- }
- if(!cuser) continue;
- } else {
- chanuser = getChanUser(cuser, chan);
- if(!chanuser) continue;
- }
- done_users++;
- if(chanuser->flags & CHANUSERFLAG_VOICED) continue;
- modeBufferVoice(modeBuf, b);
- if(a) {
- b = a+1;
- }
- } while(a);
- freeModeBuffer(modeBuf);
- if(done_users == total_users)
- reply(textclient, user, "NS_VOICE_DONE", chan->name);
- else
- reply(textclient, user, "NS_VOICE_FAIL", client->user->nick);
- if(done_users)
- logEvent(event);
-}
+++ /dev/null
-/* cmd_neonserv_voiceall.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* argv[0] (optional) nick mask
-*/
-static USERLIST_CALLBACK(neonserv_cmd_voiceall_userlist_lookup);
-static void neonserv_cmd_voiceall_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nickmask);
-
-struct neonserv_cmd_voiceall_cache {
- struct ClientSocket *client, *textclient;
- struct UserNode *user;
- struct Event *event;
- char *nickmask;
-};
-
-CMD_BIND(neonserv_cmd_voiceall) {
- struct neonserv_cmd_voiceall_cache *cache = malloc(sizeof(*cache));
- if (!cache) {
- perror("malloc() failed");
- return;
- }
- cache->client = client;
- cache->textclient = getTextBot();
- cache->user = user;
- cache->event = event;
- if(argc > 0) {
- cache->nickmask = strdup(argv[0]);
- } else
- cache->nickmask = NULL;
- get_userlist_if_invisible(chan, neonserv_cmd_voiceall_userlist_lookup, cache);
-}
-
-static USERLIST_CALLBACK(neonserv_cmd_voiceall_userlist_lookup) {
- struct neonserv_cmd_voiceall_cache *cache = data;
- neonserv_cmd_voiceall_async1(cache->client, cache->textclient, cache->user, chan, cache->event, cache->nickmask);
- if(cache->nickmask)
- free(cache->nickmask);
- free(cache);
-}
-
-static void neonserv_cmd_voiceall_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nickmask) {
- int done_users = 0;
- struct ChanUser *chanuser;
- struct ModeBuffer *modeBuf;
- modeBuf = initModeBuffer(client, chan);
- for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
- if(nickmask && match(nickmask, chanuser->user->nick)) continue;
- if(chanuser->flags & CHANUSERFLAG_VOICED) continue;
- modeBufferVoice(modeBuf, chanuser->user->nick);
- done_users++;
- }
- freeModeBuffer(modeBuf);
- reply(textclient, user, "NS_VOICEALL_DONE", done_users, chan->name);
- if(done_users)
- logEvent(event);
-}
+++ /dev/null
-/* cmd_neonserv_wipeinfo.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonserv.h"
-
-/*
-* argv[0] - nick / *auth
-*/
-static USERAUTH_CALLBACK(neonserv_cmd_wipeinfo_nick_lookup);
-static void neonserv_cmd_wipeinfo_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nick, char *auth);
-
-struct neonserv_cmd_wipeinfo_cache {
- struct ClientSocket *client, *textclient;
- struct UserNode *user;
- struct ChanNode *chan;
- struct Event *event;
- char *nick;
-};
-
-CMD_BIND(neonserv_cmd_wipeinfo) {
- if(argv[0][0] == '*') {
- //we've got an auth
- argv[0]++;
- neonserv_cmd_wipeinfo_async1(client, getTextBot(), user, chan, event, argv[0], argv[0]);
- } else {
- struct UserNode *cuser = getUserByNick(argv[0]);
- if(!cuser) {
- cuser = createTempUser(argv[0]);
- if(!cuser) {
- reply(getTextBot(), user, "NS_USER_UNKNOWN", argv[0]);
- return;
- }
- cuser->flags |= USERFLAG_ISTMPUSER;
- }
- if(cuser->flags & USERFLAG_ISAUTHED) {
- neonserv_cmd_wipeinfo_async1(client, getTextBot(), user, chan, event, argv[0], cuser->auth);
- } else {
- struct neonserv_cmd_wipeinfo_cache *cache = malloc(sizeof(*cache));
- if (!cache) {
- perror("malloc() failed");
- return;
- }
- cache->client = client;
- cache->textclient = getTextBot();
- cache->user = user;
- cache->chan = chan;
- cache->event = event;
- cache->nick = strdup(argv[0]);
- get_userauth(cuser, neonserv_cmd_wipeinfo_nick_lookup, cache);
- }
- }
-}
-
-static USERAUTH_CALLBACK(neonserv_cmd_wipeinfo_nick_lookup) {
- struct neonserv_cmd_wipeinfo_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_wipeinfo_async1(cache->client, cache->textclient, cache->user, cache->chan, cache->event, user->nick, user->auth);
- free(cache->nick);
- free(cache);
-}
-
-static void neonserv_cmd_wipeinfo_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nick, char *auth) {
- //we've got a valid auth now...
- MYSQL_RES *res;
- MYSQL_ROW row;
- 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]);
- //check if the user is already added
- printf_mysql_query("SELECT `chanuser_access`, `chanuser_id` FROM `chanusers` WHERE `chanuser_cid` = '%d' AND `chanuser_uid` = '%d'", chan->channel_id, userid);
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) != NULL) {
- if(atoi(row[0]) >= getChannelAccess(user, chan)) {
- if(isGodMode(user)) {
- event->flags |= CMDFLAG_OPLOG;
- } else {
- reply(textclient, user, "NS_USER_OUTRANKED", nick);
- return;
- }
- }
- //delete
- printf_mysql_query("UPDATE `chanusers` SET `chanuser_infoline` = '' WHERE `chanuser_id` = '%s'", row[1]);
- reply(textclient, user, "NS_WIPEINFO_DONE", nick, chan->name);
- logEvent(event);
- return;
- }
- }
- reply(textclient, user, "NS_NOT_ON_USERLIST", nick, chan->name);
-}
+++ /dev/null
-/* cmd_neonspam.h - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-#ifndef _cmd_neonspam_h
-#define _cmd_neonspam_h
-#include "main.h"
-#include "modcmd.h"
-#include "IRCParser.h"
-#include "IRCEvents.h"
-#include "UserNode.h"
-#include "ChanNode.h"
-#include "ChanUser.h"
-#include "ModeNode.h"
-#include "BanNode.h"
-#include "ClientSocket.h"
-#include "mysqlConn.h"
-#include "lang.h"
-#include "HandleInfoHandler.h"
-#include "WHOHandler.h"
-#include "DBHelper.h"
-#include "tools.h"
-#include "timeq.h"
-#include "version.h"
-#include "EventLogger.h"
-#include "bots.h"
-#include "bot_NeonSpam.h"
-
-CMD_BIND(neonspam_cmd_set);
-
-#endif
\ No newline at end of file
+++ /dev/null
-/* cmd_neonspam_set.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_neonspam.h"
-
-typedef char* neonspam_cmd_set_function(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int intparam, char *charparam, char *argument, char *retBuf);
-static char* neonspam_cmd_set_trigger(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int intparam, char *charparam, char *argument, char *retBuf);
-static char* neonspam_cmd_setflags(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int intparam, char *charparam, char *argument, char *retBuf);
-static char* neonspam_cmd_setexcept(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int intparam, char *charparam, char *argument, char *retBuf);
-static char* neonspam_cmd_set_reaction(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int intparam, char *charparam, char *argument, char *retBuf);
-static char* neonspam_cmd_set_reaction_time(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int intparam, char *charparam, char *argument, char *retBuf);
-static char* neonspam_cmd_setpercent(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int intparam, char *charparam, char *argument, char *retBuf);
-static char* neonspam_cmd_setsensibility(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int intparam, char *charparam, char *argument, char *retBuf);
-static char* neonspam_cmd_set_spamlimit(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int intparam, char *charparam, char *argument, char *retBuf);
-static char* neonspam_cmd_setscanops(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int intparam, char *charparam, char *argument, char *retBuf);
-static char* neonspam_cmd_setscanvoice(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int intparam, char *charparam, char *argument, char *retBuf);
-static char* neonspam_cmd_setscanexcept(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int intparam, char *charparam, char *argument, char *retBuf);
-
-static MYSQL_ROW neonspam_settings_row, neonspam_settings_defaults;
-#define SPAMSERV_SETTINGS_QUERY "`channel_spam_reaction`, `channel_spam_reaction_duration`, `channel_flood_reaction`, `channel_flood_reaction_duration`, `channel_join_reaction`, `channel_join_reaction_duration`, `channel_botnet_bantime`, `channel_caps_reaction`, `channel_caps_reaction_duration`, `channel_digit_reaction`, `channel_digit_reaction_duration`"
-#define SPAMSERV_SETTINGS_RESET "\
-`channel_scanner` = NULL, \
-`channel_spam_limit` = NULL, \
-`channel_spam_reaction` = NULL, \
-`channel_spam_reaction_duration` = NULL, \
-`channel_spam_except` = NULL, \
-`channel_flood_limit` = NULL, \
-`channel_flood_time` = NULL, \
-`channel_flood_reaction` = NULL, \
-`channel_flood_reaction_duration` = NULL, \
-`channel_flood_except` = NULL, \
-`channel_join_limit` = NULL, \
-`channel_join_time` = NULL, \
-`channel_join_reaction` = NULL, \
-`channel_join_reaction_duration` = NULL, \
-`channel_join_except` = NULL, \
-`channel_botnet_bantime` = NULL, \
-`channel_botnet_except` = NULL, \
-`channel_caps_percent` = NULL, \
-`channel_caps_reaction` = NULL, \
-`channel_caps_reaction_duration` = NULL, \
-`channel_caps_except` = NULL,\
-`channel_digit_percent` = NULL, \
-`channel_digit_reaction` = NULL, \
-`channel_digit_reaction_duration` = NULL, \
-`channel_digit_except` = NULL "
-
-#define SET_HELP 0x0001
-#define SET_BOOL 0x0002
-#define SET_OPT 0x0004
-
-#define SET_SCANOPS 0x0010
-#define SET_SCANVOICE 0x0020
-#define SET_SCANEXCEPT 0x0040
-
-#define SET_OPT_MAX 0xff00
-#define SET_OPT_SHIFT 8
-
-static const struct {
- unsigned int if_flag;
- unsigned int indent;
- const char *setting;
- void *function;
- int intparam;
- char *charparam;
- int flags;
-} neonspam_settings[] = {
- {0, 0, "Trigger", neonspam_cmd_set_trigger, 0, NULL, SET_HELP},
-
- {0, 0, "SpamScan", neonspam_cmd_setflags, SPAMSETTINGS_SPAMSCAN, NULL, SET_BOOL},
- {SPAMSETTINGS_SPAMSCAN, 2, "SpamLimit", neonspam_cmd_set_spamlimit, 0, NULL, SET_HELP},
- {SPAMSETTINGS_SPAMSCAN | SPAMSETTINGS_SETTIMEBAN, 2, "SpamReaction", neonspam_cmd_set_reaction, 0, "channel_spam_reaction", SET_OPT | (3 << SET_OPT_SHIFT)},
- {SPAMSETTINGS_SPAMSCAN | SPAMSETTINGS_ISTIMEBAN, 4, "SpamBanDuration", neonspam_cmd_set_reaction_time, 1, "channel_spam_reaction_duration", 0},
- {SPAMSETTINGS_SPAMSCAN, 2, "SpamScanChanOps", neonspam_cmd_setflags, SPAMSETTINGS_SPAMSCAN_OPS, NULL, SET_BOOL | SET_SCANOPS},
- {SPAMSETTINGS_SPAMSCAN, 2, "SpamScanVoiced", neonspam_cmd_setflags, SPAMSETTINGS_SPAMSCAN_VOICE, NULL, SET_BOOL | SET_SCANVOICE},
- {SPAMSETTINGS_SPAMSCAN, 2, "SpamScanExcept", neonspam_cmd_setexcept, SPAMSETTINGS_SPAMEXCINDEX, "channel_spam_except", SET_HELP | SET_SCANEXCEPT},
-
- {0, 0, "FloodScan", neonspam_cmd_setflags, SPAMSETTINGS_FLOODSCAN, NULL, SET_BOOL},
- {SPAMSETTINGS_FLOODSCAN, 2, "FloodSensibility", neonspam_cmd_setsensibility, SPAMSETTINGS_FLOODSENINDEX, "channel_flood_", SET_HELP},
- {SPAMSETTINGS_FLOODSCAN | SPAMSETTINGS_SETTIMEBAN, 2, "FloodReaction", neonspam_cmd_set_reaction, 2, "channel_flood_reaction", SET_OPT | (3 << SET_OPT_SHIFT)},
- {SPAMSETTINGS_FLOODSCAN | SPAMSETTINGS_ISTIMEBAN, 4, "FloodBanDuration", neonspam_cmd_set_reaction_time, 3, "channel_flood_reaction_duration",0},
- {SPAMSETTINGS_FLOODSCAN, 2, "FloodScanChanOps", neonspam_cmd_setflags, SPAMSETTINGS_FLOODSCAN_OPS, NULL, SET_BOOL | SET_SCANOPS},
- {SPAMSETTINGS_FLOODSCAN, 2, "FloodScanVoiced", neonspam_cmd_setflags, SPAMSETTINGS_FLOODSCAN_VOICE, NULL, SET_BOOL | SET_SCANVOICE},
- {SPAMSETTINGS_FLOODSCAN, 2, "FloodScanExcept", neonspam_cmd_setexcept, SPAMSETTINGS_FLOODEXCINDEX, "channel_flood_except", SET_HELP | SET_SCANEXCEPT},
-
- {0, 0, "JoinScan", neonspam_cmd_setflags, SPAMSETTINGS_JOINSCAN, NULL, SET_BOOL},
- {SPAMSETTINGS_JOINSCAN, 2, "JoinSensibility", neonspam_cmd_setsensibility, SPAMSETTINGS_JOINSENINDEX, "channel_join_", SET_HELP},
- {SPAMSETTINGS_JOINSCAN | SPAMSETTINGS_SETTIMEBAN, 2, "JoinReaction", neonspam_cmd_set_reaction, 4, "channel_join_reaction", SET_OPT | (3 << SET_OPT_SHIFT)},
- {SPAMSETTINGS_JOINSCAN | SPAMSETTINGS_ISTIMEBAN, 4, "JoinBanDuration", neonspam_cmd_set_reaction_time, 5, "channel_join_reaction_duration", 0},
- {SPAMSETTINGS_JOINSCAN, 2, "JoinScanChanOps", neonspam_cmd_setflags, SPAMSETTINGS_JOINSCAN_OPS, NULL, SET_BOOL | SET_SCANOPS},
- {SPAMSETTINGS_JOINSCAN, 2, "JoinScanVoiced", neonspam_cmd_setflags, SPAMSETTINGS_JOINSCAN_VOICE, NULL, SET_BOOL | SET_SCANVOICE},
- {SPAMSETTINGS_JOINSCAN, 2, "JoinScanExcept", neonspam_cmd_setexcept, SPAMSETTINGS_JOINEXCINDEX, "channel_join_except", SET_HELP | SET_SCANEXCEPT},
-
- {0, 0, "BotNetScan", neonspam_cmd_setflags, SPAMSETTINGS_BOTNETSCAN, NULL, SET_BOOL},
- {SPAMSETTINGS_BOTNETSCAN, 4, "BotNetBanDuration", neonspam_cmd_set_reaction_time, 6, "channel_botnet_bantime", 0},
- {SPAMSETTINGS_BOTNETSCAN, 2, "BotNetScanChanOps", neonspam_cmd_setflags, SPAMSETTINGS_BOTNETSCAN_OPS, NULL, SET_BOOL | SET_SCANOPS},
- {SPAMSETTINGS_BOTNETSCAN, 2, "BotNetScanVoiced", neonspam_cmd_setflags, SPAMSETTINGS_BOTNETSCAN_VOICE, NULL, SET_BOOL | SET_SCANVOICE},
- //{SPAMSETTINGS_BOTNETSCAN, 2, "BotNetScanExcept", neonspam_cmd_setexcept, SPAMSETTINGS_BOTNETEXCINDEX, "channel_botnet_except", SET_HELP},
-
- {0, 0, "CapsScan", neonspam_cmd_setflags, SPAMSETTINGS_CAPSSCAN, NULL, SET_BOOL},
- {SPAMSETTINGS_CAPSSCAN, 2, "CapsPercent", neonspam_cmd_setpercent, SPAMSETTINGS_CAPSPERCENTINDEX, "channel_caps_percent", SET_HELP},
- {SPAMSETTINGS_CAPSSCAN | SPAMSETTINGS_SETTIMEBAN, 2, "CapsReaction", neonspam_cmd_set_reaction, 7, "channel_caps_reaction", SET_OPT | (3 << SET_OPT_SHIFT)},
- {SPAMSETTINGS_CAPSSCAN | SPAMSETTINGS_ISTIMEBAN, 4, "CapsBanDuration", neonspam_cmd_set_reaction_time, 8, "channel_caps_reaction_duration", 0},
- {SPAMSETTINGS_CAPSSCAN, 2, "CapsScanChanOps", neonspam_cmd_setflags, SPAMSETTINGS_CAPSSCAN_OPS, NULL, SET_BOOL | SET_SCANOPS},
- {SPAMSETTINGS_CAPSSCAN, 2, "CapsScanVoiced", neonspam_cmd_setflags, SPAMSETTINGS_CAPSSCAN_VOICE, NULL, SET_BOOL | SET_SCANVOICE},
- {SPAMSETTINGS_CAPSSCAN, 2, "CapsScanExcept", neonspam_cmd_setexcept, SPAMSETTINGS_CAPSEXCINDEX, "channel_caps_except", SET_HELP | SET_SCANEXCEPT},
-
- {0, 0, "DigitScan", neonspam_cmd_setflags, SPAMSETTINGS_DIGITSCAN, NULL, SET_BOOL},
- {SPAMSETTINGS_DIGITSCAN, 2, "DigitPercent", neonspam_cmd_setpercent, SPAMSETTINGS_DIGITPERCENTINDEX, "channel_digit_percent", SET_HELP},
- {SPAMSETTINGS_DIGITSCAN | SPAMSETTINGS_SETTIMEBAN, 2, "DigitReaction", neonspam_cmd_set_reaction, 9, "channel_digit_reaction", SET_OPT | (3 << SET_OPT_SHIFT)},
- {SPAMSETTINGS_DIGITSCAN | SPAMSETTINGS_ISTIMEBAN, 4, "DigitBanDuration", neonspam_cmd_set_reaction_time, 10, "channel_digit_reaction_duration", 0},
- {SPAMSETTINGS_DIGITSCAN, 2, "DigitScanChanOps", neonspam_cmd_setflags, SPAMSETTINGS_DIGITSCAN_OPS, NULL, SET_BOOL | SET_SCANOPS},
- {SPAMSETTINGS_DIGITSCAN, 2, "DigitScanVoiced", neonspam_cmd_setflags, SPAMSETTINGS_DIGITSCAN_VOICE, NULL, SET_BOOL | SET_SCANVOICE},
- {SPAMSETTINGS_DIGITSCAN, 2, "DigitScanExcept", neonspam_cmd_setexcept, SPAMSETTINGS_DIGITEXCINDEX, "channel_digit_except", SET_HELP | SET_SCANEXCEPT},
-
- {0, 0, "GlobalScanChanOps", neonspam_cmd_setscanops, 0, NULL, SET_BOOL},
- {0, 0, "GlobalScanVoice", neonspam_cmd_setscanvoice, 0, NULL, SET_BOOL},
- {0, 0, "GlobalScanExcept", neonspam_cmd_setscanexcept, 0, NULL, SET_HELP},
-
- {0, 0, NULL, NULL, 0, NULL, 0}
-};
-
-#define MAX_QUERY_LEN 1024
-CMD_BIND(neonspam_cmd_set) {
- int i, j;
- loadNeonSpamSettings(chan);
- if(argc && !strcmp(argv[0], "defaults")) {
- //reset channel settings
- int uaccess = getChannelAccess(user, chan);
- if(uaccess < 500) {
- if(isGodMode(user)) {
- event->flags |= CMDFLAG_OPLOG;
- } else {
- reply(getTextBot(), user, "NS_SET_DEFAULTS_OWNER", chan->name);
- return;
- }
- }
- int seed = 0;
- char *tmp;
- 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)) {
- printf_mysql_query("UPDATE `channels` SET " SPAMSERV_SETTINGS_RESET " WHERE `channel_id` = '%d'", chan->channel_id);
- reply(getTextBot(), user, "NS_SET_DEFAULTS_DONE", chan->name);
- logEvent(event);
- } 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;
- char *args = (argc > 1 ? merge_argv(argv, 1, argc) : NULL);
- neonspam_settings_row = NULL;
- neonspam_settings_defaults = NULL;
- while(neonspam_settings[i].setting) {
- if(!stricmp(neonspam_settings[i].setting, argv[0])) {
- //setting found
- char valueBuf[MAXLEN], nameBuf[MAXLEN];
- char *value, *optimized_value, *option_help;
- neonspam_cmd_set_function *func = neonspam_settings[i].function;
- value = func(client, user, chan, event, neonspam_settings[i].intparam, neonspam_settings[i].charparam, args, valueBuf);
- if(value) {
- optimized_value = value;
- if(neonspam_settings[i].flags & SET_BOOL) {
- if(!strcmp(value, "0"))
- optimized_value = get_language_string(user, "NS_SET_OFF");
- else if(!strcmp(value, "1"))
- optimized_value = get_language_string(user, "NS_SET_ON");
- }
- if(neonspam_settings[i].flags & SET_OPT) {
- sprintf(nameBuf, "SS_SET_OPTION_%s_%s", neonspam_settings[i].setting, value);
- option_help = get_language_string(user, nameBuf);
- } else
- option_help = NULL;
- reply(getTextBot(), user, "\002%s\002 %s%s%s", neonspam_settings[i].setting, optimized_value, (option_help ? " - " : ""), (option_help ? option_help : ""));
- if(neonspam_settings[i].flags & SET_OPT) {
- int maxoption = (neonspam_settings[i].flags & SET_OPT_MAX) >> SET_OPT_SHIFT;
- for(j = 0; j < maxoption; j++) {
- sprintf(nameBuf, "SS_SET_OPTION_%s_%d", neonspam_settings[i].setting, j);
-
- reply(getTextBot(), user, " \002%d\002 - %s", j, option_help);
- }
- }
- if((neonspam_settings[i].flags & SET_HELP) && argc && !strcmp(argv[0], "help")) {
- char *tmp;
- sprintf(nameBuf, "SS_SET_HELP_%s", neonspam_settings[i].setting);
- tmp = get_language_string(user, nameBuf);
- if(tmp) {
- reply(getTextBot(), user, " %s", tmp);
- }
- }
- }
- j = 1;
- break;
- }
- i++;
- }
- if(j == 0) {
- //unknown setting
- reply(getTextBot(), user, "NS_SET_UNKNOWN_SETTING", argv[0]);
- }
- } else {
- char valueBuf[MAXLEN], nameBuf[MAXLEN];
- char *value;
- int namePos, boolflag = 0;
- MYSQL_RES *res, *defaults_res;
- struct Table *table;
- char *content[2];
- i = 0;
- while(neonspam_settings[i].setting)
- i++;
- table = table_init(2, i, 0);
- table_set_bold(table, 0, 1);
- printf_mysql_query("SELECT " SPAMSERV_SETTINGS_QUERY " FROM `channels` WHERE `channel_name` = 'defaults'");
- defaults_res = mysql_use();
- neonspam_settings_defaults = mysql_fetch_row(defaults_res);
- printf_mysql_query("SELECT " SPAMSERV_SETTINGS_QUERY " FROM `channels` WHERE `channel_id` = '%d'", chan->channel_id);
- res = mysql_use();
- neonspam_settings_row = mysql_fetch_row(res);
- i = -1;
- reply(getTextBot(), user, "NS_SET_HEADER", chan->name);
- while(neonspam_settings[++i].setting) {
- if((chan->spam_settings->flags & (neonspam_settings[i].if_flag & SPAMSETTINGS_FLAGS)) != (neonspam_settings[i].if_flag & SPAMSETTINGS_FLAGS))
- continue;
- if((neonspam_settings[i].if_flag & SPAMSETTINGS_ISTIMEBAN) && !boolflag)
- continue;
- neonspam_cmd_set_function *func = neonspam_settings[i].function;
- value = func(client, user, chan, event, neonspam_settings[i].intparam, neonspam_settings[i].charparam, NULL, valueBuf);
- if(neonspam_settings[i].if_flag & SPAMSETTINGS_SETTIMEBAN)
- boolflag = !strcmp(value, "2");
- //TODO: append option or help info
- strcpy(valueBuf, value);
- if(neonspam_settings[i].flags & SET_BOOL) {
- if(!strcmp(value, "0"))
- strcpy(valueBuf, get_language_string(user, "NS_SET_OFF"));
- else if(!strcmp(value, "1"))
- strcpy(valueBuf, get_language_string(user, "NS_SET_ON"));
- }
- if(neonspam_settings[i].flags & SET_OPT) {
- char *tmp;
- sprintf(nameBuf, "SS_SET_OPTION_%s_%s", neonspam_settings[i].setting, value);
- tmp = get_language_string(user, nameBuf);
- if(tmp) {
- sprintf(valueBuf + strlen(valueBuf), " - %s", tmp);
- }
- }
- if((neonspam_settings[i].flags & SET_HELP) && argc && !strcmp(argv[0], "help")) {
- char *tmp;
- sprintf(nameBuf, "SS_SET_HELP_%s", neonspam_settings[i].setting);
- tmp = get_language_string(user, nameBuf);
- if(tmp) {
- sprintf(valueBuf + strlen(valueBuf), " - %s", tmp);
- }
- }
- namePos = 0;
- for(j = 0; j < neonspam_settings[i].indent; j++) {
- nameBuf[namePos++] = ' ';
- }
- sprintf(nameBuf + namePos, "%s", neonspam_settings[i].setting);
- content[0] = nameBuf;
- content[1] = valueBuf;
- table_add(table, content);
- }
- char **table_lines = table_end(table);
- for(i = 0; i < table->entrys; i++) {
- reply(getTextBot(), user, table_lines[i]);
- }
- table_free(table);
- }
-}
-
-static char* neonspam_cmd_set_trigger(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int intparam, char *charparam, char *argument, char *retBuf) {
- char *trigger;
- //get current trigger
- MYSQL_RES *res;
- MYSQL_ROW row;
- printf_mysql_query("SELECT `trigger`, `defaulttrigger` FROM `bot_channels` LEFT JOIN `bots` ON `botid` = `bots`.`id` WHERE `chanid` = '%d' AND `botid` = '%d'", chan->channel_id, client->clientid);
- res = mysql_use();
- row = mysql_fetch_row(res);
- trigger = (row[0] ? row[0] : row[1]);
- if(argument) {
- int uaccess = getChannelAccess(user, chan);
- if(uaccess < 500) {
- if(isGodMode(user)) {
- event->flags |= CMDFLAG_OPLOG;
- } else {
- 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);
- logEvent(event);
- }
- return trigger;
-}
-
-static char* neonspam_cmd_setflags(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int flag, char *charparam, char *argument, char *retBuf) {
- char *value = ((chan->spam_settings->flags & flag) ? "1" : "0");
- if(argument) {
- //binary argument...
- if(!strcmp(argument, "0") || !stricmp(argument, "off") || !stricmp(argument, get_language_string(user, "NS_SET_OFF"))) {
- chan->spam_settings->flags &= ~flag;
- } else if(!strcmp(argument, "1") || !stricmp(argument, "on") || !stricmp(argument, get_language_string(user, "NS_SET_ON"))) {
- chan->spam_settings->flags |= flag;
- } else {
- reply(getTextBot(), user, "NS_SET_INVALID_BOOLEAN", argument);
- return NULL;
- }
- char str_flags[50];
- convertNeonSpamSettingsToString(chan->spam_settings->flags, str_flags);
- printf_mysql_query("UPDATE `channels` SET `channel_scanner` = '%s' WHERE `channel_id` = '%d' ", str_flags, chan->channel_id);
- value = argument;
- }
- return value;
-}
-
-static char* neonspam_cmd_setexcept(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int exceptlvl_index, char *field, char *argument, char *retBuf) {
- unsigned int value = chan->spam_settings->exceptlevel[exceptlvl_index];
- if(argument) {
- //numeric argument... (access)
- int caccess = atoi(argument);
- if(caccess < 0 || caccess > 501) {
- reply(getTextBot(), user, "NS_INVALID_ACCESS", caccess);
- return NULL;
- }
- int uaccess = getChannelAccess(user, chan);
- if(uaccess == 500) uaccess++;
- if(value > uaccess) {
- if(isGodMode(user)) {
- event->flags |= CMDFLAG_OPLOG;
- } else {
- reply(getTextBot(), user, "NS_SET_CANNOT_SET");
- return NULL;
- }
- }
- if(caccess > uaccess) {
- if(isGodMode(user)) {
- event->flags |= CMDFLAG_OPLOG;
- } else {
- reply(getTextBot(), user, "NS_SET_BADLEVEL");
- return NULL;
- }
- }
- value = caccess;
- chan->spam_settings->exceptlevel[exceptlvl_index] = value;
- printf_mysql_query("UPDATE `channels` SET `%s` = '%u' WHERE `channel_id` = '%d' ", field, value, chan->channel_id);
- }
- sprintf(retBuf, "%u", value);
- return retBuf;
-}
-
-static char* neonspam_cmd_set_reaction(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int mysqlindex, char *mysqlfield, char *argument, char *retBuf) {
- if(argument) {
- /* valid options:
- * 0/kick - kick
- * 1/kickban - kickban
- * 2/ban - timed ban
- */
- if(!strcmp(argument, "0") || !stricmp(argument, "kick")) {
- argument = "0";
- } else if(!strcmp(argument, "1") || !stricmp(argument, "kickban")) {
- argument = "1";
- } else if(!strcmp(argument, "2") || !stricmp(argument, "ban")) {
- argument = "2";
- } else {
- reply(getTextBot(), user, "NS_SET_INVALID_OPTION_STR", argument);
- return NULL;
- }
- printf_mysql_query("UPDATE `channels` SET `%s` = '%s' WHERE `channel_id` = '%d' ", mysqlfield, argument, chan->channel_id);
- return argument;
- } else {
- if(neonspam_settings_row) {
- return (neonspam_settings_row[mysqlindex] ? neonspam_settings_row[mysqlindex] : neonspam_settings_defaults[mysqlindex]);
- } else {
- MYSQL_RES *res;
- MYSQL_ROW row;
- printf_mysql_query("SELECT `%s` FROM `channels` WHERE `channel_id` = '%d'", mysqlfield, chan->channel_id);
- res = mysql_use();
- row = mysql_fetch_row(res);
- return row[0];
- }
- }
-}
-
-static char* neonspam_cmd_set_reaction_time(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int mysqlindex, char *mysqlfield, char *argument, char *retBuf) {
- int duration;
- if(argument) {
- duration = strToTime(user, argument);
- if(duration < 30) {
- reply(getTextBot(), user, "NS_TIMEBAN_DURATION_TOO_SHORT", 30);
- return NULL;
- }
- printf_mysql_query("UPDATE `channels` SET `%s` = '%s' WHERE `channel_id` = '%d' ", mysqlfield, argument, chan->channel_id);
- } else {
- if(neonspam_settings_row) {
- duration = atoi(neonspam_settings_row[mysqlindex] ? neonspam_settings_row[mysqlindex] : neonspam_settings_defaults[mysqlindex]);
- } else {
- MYSQL_RES *res;
- MYSQL_ROW row;
- printf_mysql_query("SELECT `%s` FROM `channels` WHERE `channel_id` = '%d'", mysqlfield, chan->channel_id);
- res = mysql_use();
- row = mysql_fetch_row(res);
- duration = atoi(row[0]);
- }
- }
- timeToStr(user, duration, 3, retBuf);
- return retBuf;
-}
-
-static char* neonspam_cmd_setpercent(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int percent_index, char *mysqlfield, char *argument, char *retBuf) {
- unsigned int value = chan->spam_settings->percent[percent_index];
- if(argument) {
- //numeric argument... (access)
- value = atoi(argument);
- if(value < 0 || value > 100) {
- //invalid percent value
- reply(getTextBot(), user, "SS_SET_PERCENT", value);
- return NULL;
- }
- chan->spam_settings->percent[percent_index] = value;
- printf_mysql_query("UPDATE `channels` SET `%s` = '%u' WHERE `channel_id` = '%d' ", mysqlfield, value, chan->channel_id);
- }
- sprintf(retBuf, "%u", value);
- return retBuf;
-}
-
-static char* neonspam_cmd_setsensibility(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int sensibility_index, char *mysqlfield, char *argument, char *retBuf) {
- if(argument) {
- //change value
- char *delimiter = strstr(argument, ":");
- if(!delimiter) {
- //invalid format
- reply(getTextBot(), user, "SS_SET_SENSIBILITY", argument);
- return NULL;
- }
- *delimiter = '\0';
- delimiter++;
- int amount = atoi(argument);
- int timep = atoi(delimiter);
- if(amount > MAX_FLOOD_AMOUNT || amount < MIN_FLOOD_AMOUNT) {
- //invalid amount
- reply(getTextBot(), user, "SS_SET_SENSIBILITY_AMOUNT", amount, MIN_FLOOD_AMOUNT, MAX_FLOOD_AMOUNT);
- return NULL;
- }
- if(timep > MAX_FLOOD_TIME || timep < 0) {
- //invalid time period
- reply(getTextBot(), user, "SS_SET_SENSIBILITY_TIME", timep, 0, MAX_FLOOD_TIME);
- return NULL;
- }
- char amountfield[50], timefield[50];
- sprintf(amountfield, "%s%s", mysqlfield, "limit");
- sprintf(timefield, "%s%s", mysqlfield, "time");
- printf_mysql_query("UPDATE `channels` SET `%s` = '%d', `%s` = '%d' WHERE `channel_id` = '%d' ", amountfield, amount, timefield, timep, chan->channel_id);
- sprintf(retBuf, "%d:%d", amount, timep);
- chan->spam_settings->sensibility_amount[sensibility_index] = amount;
- chan->spam_settings->sensibility_time[sensibility_index] = timep;
- } else {
- sprintf(retBuf, "%d:%d", chan->spam_settings->sensibility_amount[sensibility_index], chan->spam_settings->sensibility_time[sensibility_index]);
- }
- return retBuf;
-}
-
-static char* neonspam_cmd_set_spamlimit(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int intparam, char *charparam, char *argument, char *retBuf) {
- if(argument) {
- //change value
- int amount = atoi(argument);
- if(amount > 10 || amount < 2) {
- //invalid amount
- reply(getTextBot(), user, "SS_SET_SPAMLIMIT", amount, 2, 10);
- return NULL;
- }
- printf_mysql_query("UPDATE `channels` SET `channel_maxrepeat` = '%d' WHERE `channel_id` = '%d' ", amount, chan->channel_id);
- sprintf(retBuf, "%d", amount);
- chan->spam_settings->spam_amount = amount;
- } else
- sprintf(retBuf, "%d", chan->spam_settings->spam_amount);
- return retBuf;
-}
-
-static char* neonspam_cmd_setscanops(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int flag, char *charparam, char *argument, char *retBuf) {
- int i = 0;
- int value = -1;
- int identical = 1;
- while(neonspam_settings[i].setting) {
- if(neonspam_settings[i].flags & SET_SCANOPS) {
- if(value == -1)
- value = ((chan->spam_settings->flags & neonspam_settings[i].intparam) ? 1 : 0);
- else {
- if(((chan->spam_settings->flags & neonspam_settings[i].intparam) ? 1 : 0) != value) {
- identical = 0;
- break;
- }
- }
- }
- i++;
- }
- if(argument) {
- //binary argument...
- if(!strcmp(argument, "0") || !stricmp(argument, "off") || !stricmp(argument, get_language_string(user, "NS_SET_OFF"))) {
- value = 0;
- } else if(!strcmp(argument, "1") || !stricmp(argument, "on") || !stricmp(argument, get_language_string(user, "NS_SET_ON"))) {
- value = 1;
- } else {
- reply(getTextBot(), user, "NS_SET_INVALID_BOOLEAN", argument);
- return NULL;
- }
- i = 0;
- char valueBuf[MAXLEN];
- while(neonspam_settings[i].setting) {
- if(neonspam_settings[i].flags & SET_SCANOPS) {
- neonspam_cmd_set_function *func = neonspam_settings[i].function;
- func(client, user, chan, event, neonspam_settings[i].intparam, neonspam_settings[i].charparam, (value ? "1" : "0"), valueBuf);
- }
- i++;
- }
- identical = 1;
- }
- if(identical && value)
- return "1";
- if(identical && !value)
- return "0";
- return "?";
-}
-
-static char* neonspam_cmd_setscanvoice(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int flag, char *charparam, char *argument, char *retBuf) {
- int i = 0;
- int value = -1;
- int identical = 1;
- while(neonspam_settings[i].setting) {
- if(neonspam_settings[i].flags & SET_SCANVOICE) {
- if(value == -1)
- value = ((chan->spam_settings->flags & neonspam_settings[i].intparam) ? 1 : 0);
- else {
- if(((chan->spam_settings->flags & neonspam_settings[i].intparam) ? 1 : 0) != value) {
- identical = 0;
- break;
- }
- }
- }
- i++;
- }
- if(argument) {
- //binary argument...
- if(!strcmp(argument, "0") || !stricmp(argument, "off") || !stricmp(argument, get_language_string(user, "NS_SET_OFF"))) {
- value = 0;
- } else if(!strcmp(argument, "1") || !stricmp(argument, "on") || !stricmp(argument, get_language_string(user, "NS_SET_ON"))) {
- value = 1;
- } else {
- reply(getTextBot(), user, "NS_SET_INVALID_BOOLEAN", argument);
- return NULL;
- }
- i = 0;
- char valueBuf[MAXLEN];
- while(neonspam_settings[i].setting) {
- if(neonspam_settings[i].flags & SET_SCANVOICE) {
- neonspam_cmd_set_function *func = neonspam_settings[i].function;
- func(client, user, chan, event, neonspam_settings[i].intparam, neonspam_settings[i].charparam, (value ? "1" : "0"), valueBuf);
- }
- i++;
- }
- identical = 1;
- }
- if(identical && value)
- return "1";
- if(identical && !value)
- return "0";
- return "?";
-}
-
-static char* neonspam_cmd_setscanexcept(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int flag, char *charparam, char *argument, char *retBuf) {
- int i = 0;
- int value = -1;
- int identical = 1;
- while(neonspam_settings[i].setting) {
- if(neonspam_settings[i].flags & SET_SCANEXCEPT) {
- if(value == -1)
- value = chan->spam_settings->exceptlevel[neonspam_settings[i].intparam];
- else {
- if(chan->spam_settings->exceptlevel[neonspam_settings[i].intparam] != value) {
- identical = 0;
- break;
- }
- }
- }
- i++;
- }
- if(argument) {
- //numeric argument... (access)
- int caccess = atoi(argument);
- if(caccess < 0 || caccess > 501) {
- reply(getTextBot(), user, "NS_INVALID_ACCESS", caccess);
- return NULL;
- }
- int uaccess = getChannelAccess(user, chan);
- if(uaccess == 500) uaccess++;
- if(identical && value > uaccess) {
- if(isGodMode(user)) {
- event->flags |= CMDFLAG_OPLOG;
- } else {
- reply(getTextBot(), user, "NS_SET_CANNOT_SET");
- return NULL;
- }
- }
- if(caccess > uaccess) {
- if(isGodMode(user)) {
- event->flags |= CMDFLAG_OPLOG;
- } else {
- reply(getTextBot(), user, "NS_SET_BADLEVEL");
- return NULL;
- }
- }
- i = 0;
- char valueBuf[MAXLEN];
- sprintf(retBuf, "%d", caccess);
- while(neonspam_settings[i].setting) {
- if(neonspam_settings[i].flags & SET_SCANEXCEPT) {
- neonspam_cmd_set_function *func = neonspam_settings[i].function;
- func(client, user, chan, event, neonspam_settings[i].intparam, neonspam_settings[i].charparam, retBuf, valueBuf);
- }
- i++;
- }
- identical = 1;
- value = caccess;
- }
- if(identical) {
- sprintf(retBuf, "%d", value);
- return retBuf;
- }
- return "?";
-}
-
-#undef MAX_QUERY_LEN
+++ /dev/null
-/* commands.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cmd_global.h"
-#include "cmd_neonserv.h"
-#include "cmd_neonspam.h"
-#include "cmd_funcmds.h"
-#include "cmd_neonhelp.h"
-#include "modcmd.h"
-#include "ConfigParser.h"
-
-void register_commands() {
-
- //Global Commands
- #define USER_COMMAND(NAME,FUNCTION,PARAMCOUNT,PRIVS,FLAGS) register_command(0, NAME, FUNCTION, PARAMCOUNT, PRIVS, 0, FLAGS)
- // NAME FUNCTION PARAMS PRIVS FLAGS
- USER_COMMAND("version", global_cmd_version, 0, NULL, 0);
- USER_COMMAND("netinfo", global_cmd_netinfo, 0, NULL, 0);
- USER_COMMAND("commands", global_cmd_commands, 0, NULL, 0);
- USER_COMMAND("command", global_cmd_command, 1, NULL, CMDFLAG_ESCAPE_ARGS);
- USER_COMMAND("staff", global_cmd_staff, 0, NULL, 0);
- USER_COMMAND("motd", global_cmd_motd, 0, NULL, 0);
- #undef USER_COMMAND
-
- #define OPER_COMMAND(NAME,FUNCTION,PARAMCOUNT,GACCESS,FLAGS) register_command(0, NAME, FUNCTION, PARAMCOUNT, NULL, GACCESS, FLAGS)
- // NAME FUNCTION PARAMS ACCS FLAGS
- OPER_COMMAND("register", global_cmd_register, 1, 200, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_CHAN_PARAM | CMDFLAG_OPLOG);
- OPER_COMMAND("unregister", global_cmd_unregister,0, 200, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_CHAN_PARAM | CMDFLAG_OPLOG);
- OPER_COMMAND("say", global_cmd_say, 2, 600, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_CHAN_PARAM | CMDFLAG_OPLOG);
- OPER_COMMAND("emote", global_cmd_emote, 2, 600, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_CHAN_PARAM | CMDFLAG_OPLOG);
- OPER_COMMAND("notice", global_cmd_notice, 2, 600, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_CHAN_PARAM | CMDFLAG_OPLOG);
- OPER_COMMAND("raw", global_cmd_raw, 1, 800, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG);
- OPER_COMMAND("god", global_cmd_god, 0, 1, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG);
- OPER_COMMAND("reloadlang", global_cmd_reloadlang,1, 500, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG);
- OPER_COMMAND("bind", global_cmd_bind, 2, 900, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG | CMDFLAG_REQUIRED | CMDFLAG_ESCAPE_ARGS);
- OPER_COMMAND("unbind", global_cmd_unbind, 1, 900, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG | CMDFLAG_REQUIRED | CMDFLAG_ESCAPE_ARGS);
- OPER_COMMAND("setaccess", global_cmd_setaccess, 2, 1000, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG);
- OPER_COMMAND("bots", global_cmd_bots, 0, 1000, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH);
- OPER_COMMAND("reload", global_cmd_reload, 0, 1000, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG);
- OPER_COMMAND("restart", global_cmd_restart, 0, 1000, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG);
- OPER_COMMAND("die", global_cmd_die, 0, 1000, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG);
- OPER_COMMAND("setbot", global_cmd_setbot, 1, 1000, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG);
- OPER_COMMAND("addbot", global_cmd_addbot, 2, 1000, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG);
- OPER_COMMAND("delbot", global_cmd_delbot, 1, 1000, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG);
- OPER_COMMAND("reconnect", global_cmd_reconnect, 0, 1000, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG);
- OPER_COMMAND("modcmd", global_cmd_modcmd, 1, 900, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG | CMDFLAG_REQUIRED | CMDFLAG_ESCAPE_ARGS);
- OPER_COMMAND("meminfo", global_cmd_meminfo, 0, 1000, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH);
- #undef OPER_COMMAND
-
- //NeonServ Commands
- register_command_alias(1, "NeonServ");
-
- #define USER_COMMAND(NAME,FUNCTION,PARAMCOUNT,PRIVS,FLAGS) register_command(1, NAME, FUNCTION, PARAMCOUNT, PRIVS, 0, FLAGS)
- // NAME FUNCTION PARAMS PRIVS FLAGS
- USER_COMMAND("adduser", neonserv_cmd_adduser, 2, "#channel_canadd", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
- USER_COMMAND("deluser", neonserv_cmd_deluser, 1, "#channel_candel", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
- USER_COMMAND("clvl", neonserv_cmd_clvl, 2, "#channel_canclvl", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
- USER_COMMAND("access", neonserv_cmd_access, 0, NULL, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_LOG);
- USER_COMMAND("users", neonserv_cmd_users, 0, NULL, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_NO_CROSSCHAN);
- USER_COMMAND("suspend", neonserv_cmd_suspend, 1, "#channel_cansuspend", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
- USER_COMMAND("unsuspend", neonserv_cmd_unsuspend, 1, "#channel_cansuspend", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
- USER_COMMAND("delme", neonserv_cmd_delme, 0, "1", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
- USER_COMMAND("myaccess", neonserv_cmd_myaccess, 0, NULL, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH);
- USER_COMMAND("up", neonserv_cmd_up, 0, NULL, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
- USER_COMMAND("down", neonserv_cmd_down, 0, NULL, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_LOG);
- USER_COMMAND("upall", neonserv_cmd_upall, 0, NULL, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
- USER_COMMAND("downall", neonserv_cmd_downall, 0, NULL, CMDFLAG_LOG);
- USER_COMMAND("mdeluser", neonserv_cmd_mdeluser, 2, "#channel_candel", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
- USER_COMMAND("trim", neonserv_cmd_trim, 2, NULL, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
- USER_COMMAND("giveowner", neonserv_cmd_giveowner, 1, "500", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
- USER_COMMAND("op", neonserv_cmd_op, 1, "@#channel_getop,#channel_canop", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
- USER_COMMAND("deop", neonserv_cmd_deop, 1, "@#channel_getop,#channel_canop", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
- USER_COMMAND("voice", neonserv_cmd_voice, 1, "+#channel_getvoice,#channel_canvoice", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
- USER_COMMAND("devoice", neonserv_cmd_devoice, 1, "+#channel_getvoice,#channel_canvoice", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
- USER_COMMAND("opall", neonserv_cmd_opall, 0, "@#channel_getop,#channel_canop", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
- USER_COMMAND("deopall", neonserv_cmd_deopall, 0, "@#channel_getop,#channel_canop", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
- USER_COMMAND("voiceall", neonserv_cmd_voiceall, 0, "+#channel_getvoice,#channel_canvoice", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
- USER_COMMAND("devoiceall", neonserv_cmd_devoiceall,0, "+#channel_getvoice,#channel_canvoice", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
- if(get_int_field("General.have_halfop")) {
- USER_COMMAND("halfop", neonserv_cmd_halfop, 1, "%#channel_gethalfop,#channel_canhalfop", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
- USER_COMMAND("dehalfop", neonserv_cmd_dehalfop, 1, "%#channel_gethalfop,#channel_canhalfop", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
- USER_COMMAND("halfopall", neonserv_cmd_halfopall, 0, "%#channel_gethalfop,#channel_canhalfop", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
- USER_COMMAND("dehalfopall", neonserv_cmd_dehalfopall,0,"%#channel_gethalfop,#channel_canhalfop", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
- }
- USER_COMMAND("set", neonserv_cmd_set, 0, "#channel_setters", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
- USER_COMMAND("kick", neonserv_cmd_kick, 1, "#channel_cankick", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
- USER_COMMAND("kickban", neonserv_cmd_kickban, 1, "#channel_cankick,#channel_canban", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
- USER_COMMAND("ban", neonserv_cmd_ban, 1, "#channel_canban", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
- USER_COMMAND("wipeinfo", neonserv_cmd_wipeinfo, 1, "#channel_wipeinfo", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
- USER_COMMAND("addban", neonserv_cmd_addban, 1, "#channel_staticban", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
- USER_COMMAND("bans", neonserv_cmd_bans, 0, "1", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH);
- USER_COMMAND("delban", neonserv_cmd_delban, 1, "#channel_staticban", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
- USER_COMMAND("topic", neonserv_cmd_topic, 0, "#channel_changetopic", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
- USER_COMMAND("chanservsync", neonserv_cmd_chanservsync, 0,"500", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
- USER_COMMAND("resync", neonserv_cmd_resync, 0, "#channel_canresync", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
- USER_COMMAND("addtimeban", neonserv_cmd_addtimeban,2, "#channel_staticban", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
- USER_COMMAND("mode", neonserv_cmd_mode, 1, "#channel_getop", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
- USER_COMMAND("peek", neonserv_cmd_peek, 0, NULL, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_NO_CROSSCHAN);
- USER_COMMAND("uset", neonserv_cmd_uset, 0, NULL, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_NO_CROSSCHAN);
- USER_COMMAND("unban", neonserv_cmd_unban, 1, "#channel_canban", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
- USER_COMMAND("unbanall", neonserv_cmd_unbanall, 0, "#channel_canban", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
- USER_COMMAND("unbanme", neonserv_cmd_unbanme, 0, "#channel_canban", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
- USER_COMMAND("invite", neonserv_cmd_invite, 1, "#channel_canop", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
- USER_COMMAND("inviteme", neonserv_cmd_inviteme, 0, "#channel_getinvite", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
- USER_COMMAND("help", neonserv_cmd_help, 0, NULL, 0);
- USER_COMMAND("events", neonserv_cmd_events, 0, "1", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH);
- USER_COMMAND("info", neonserv_cmd_info, 0, NULL, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_NO_CROSSCHAN);
- USER_COMMAND("extscript", neonserv_cmd_extscript, 0, NULL, CMDFLAG_EMPTY_ARGS | CMDFLAG_CHAN_PARAM);
- USER_COMMAND("nicklist", neonserv_cmd_nicklist, 0, "1", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH);
- #undef USER_COMMAND
-
- #define OPER_COMMAND(NAME,FUNCTION,PARAMCOUNT,GACCESS,FLAGS) register_command(1, NAME, FUNCTION, PARAMCOUNT, NULL, GACCESS, FLAGS)
- // NAME FUNCTION PARAMS ACCS FLAGS
- OPER_COMMAND("trace", neonserv_cmd_trace, 1, 400, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH);
- OPER_COMMAND("recover", neonserv_cmd_recover, 1, 200, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_CHAN_PARAM | CMDFLAG_OPLOG);
- OPER_COMMAND("csuspend", neonserv_cmd_csuspend, 1, 100, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_CHAN_PARAM | CMDFLAG_OPLOG);
- OPER_COMMAND("cunsuspend", neonserv_cmd_cunsuspend,1, 100, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_CHAN_PARAM | CMDFLAG_OPLOG);
- OPER_COMMAND("move", neonserv_cmd_move, 2, 300, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_CHAN_PARAM | CMDFLAG_OPLOG);
- OPER_COMMAND("oplog", neonserv_cmd_oplog, 0, 1, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG);
- OPER_COMMAND("search", neonserv_cmd_search, 1, 400, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH);
- OPER_COMMAND("addrank", neonserv_cmd_addrank, 1, 1000, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG);
- OPER_COMMAND("delrank", neonserv_cmd_delrank, 1, 1000, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG);
- OPER_COMMAND("setrank", neonserv_cmd_setrank, 1, 1000, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG);
- OPER_COMMAND("assignrank", neonserv_cmd_assignrank,2, 1000, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG);
- OPER_COMMAND("listrank", neonserv_cmd_listrank, 0, 1, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG);
- OPER_COMMAND("rename", neonserv_cmd_rename, 2, 300, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG);
- OPER_COMMAND("unvisited", neonserv_cmd_unvisited, 0, 400, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG);
- OPER_COMMAND("noregister", neonserv_cmd_noregister,0, 300, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_CHAN_PARAM | CMDFLAG_OPLOG);
- #undef OPER_COMMAND
-
- //NeonSpam Commands
- register_command_alias(2, "NeonSpam");
-
- #define USER_COMMAND(NAME,FUNCTION,PARAMCOUNT,PRIVS,FLAGS) register_command(2, NAME, FUNCTION, PARAMCOUNT, PRIVS, 0, FLAGS)
- // NAME FUNCTION PARAMS PRIVS FLAGS
- USER_COMMAND("set", neonspam_cmd_set, 0, "#channel_setters", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
- #undef USER_COMMAND
-
- //Fun Commands
- init_funcmds();
- register_command_alias(3, "FunCMD");
- #define USER_COMMAND(NAME,FUNCTION,PARAMCOUNT,FLAGS) register_command(3, NAME, FUNCTION, PARAMCOUNT, NULL, 0, FLAGS)
- // NAME FUNCTION PARAMS FLAGS
- USER_COMMAND("extscript", neonserv_cmd_extscript, 0, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_EMPTY_ARGS | CMDFLAG_CHAN_PARAM | CMDFLAG_FUNCMD);
- USER_COMMAND("ping", funcmd_ping, 0, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_FUNCMD);
- USER_COMMAND("pong", funcmd_pong, 0, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_FUNCMD);
- USER_COMMAND("dice", funcmd_dice, 1, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_FUNCMD);
- USER_COMMAND("8ball", funcmd_8ball, 1, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_FUNCMD);
- USER_COMMAND("cookie", funcmd_cookie, 0, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_FUNCMD);
- #undef USER_COMMAND
-
- //NeonHelp Commands
- register_command_alias(4, "NeonHelp");
-
- #define USER_COMMAND(NAME,FUNCTION,PARAMCOUNT,PRIVS,FLAGS) register_command(4, NAME, FUNCTION, PARAMCOUNT, PRIVS, 0, FLAGS)
- // NAME FUNCTION PARAMS PRIVS FLAGS
- USER_COMMAND("next", neonhelp_cmd_next, 0, NULL, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH);
- USER_COMMAND("delete", neonhelp_cmd_delete, 1, NULL, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH);
- USER_COMMAND("requests", neonhelp_cmd_requests, 0, NULL, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH);
- USER_COMMAND("stats", neonhelp_cmd_stats, 0, NULL, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH);
- #undef USER_COMMAND
-
-}
\ No newline at end of file
+++ /dev/null
-/* commands.h - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-#ifndef _commands_h
-#define _commands_h
-#include "main.h"
-
-void register_commands();
-
-#endif
\ No newline at end of file
+++ /dev/null
-/* event_neonserv_ctcp.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-struct neonserv_event_ctcp_cache {
- struct ClientSocket *client;
- struct UserNode *user;
- struct ChanNode *chan;
- char *command;
- char *text;
-};
-
-static USERAUTH_CALLBACK(neonserv_event_ctcp_nick_lookup);
-static void neonserv_event_ctcp_async1(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, char *command, char *text);
-
-static void neonserv_event_chanctcp(struct UserNode *user, struct ChanNode *chan, char *command, char *text) {
- if(!stricmp(command, "ACTION")) return; //always allow CTCP ACTION (/me)
- struct ClientSocket *client = getBotForChannel(chan);
- if(!client) return; //we can't "see" this event
- if(isNetworkService(user)) return;
- loadChannelSettings(chan);
- if(!(chan->flags & CHANFLAG_CHAN_REGISTERED)) return;
- if(!(user->flags & USERFLAG_ISAUTHED)) {
- struct neonserv_event_ctcp_cache *cache = malloc(sizeof(*cache));
- if (!cache) {
- perror("malloc() failed");
- return;
- }
- cache->client = client;
- cache->user = user;
- cache->chan = chan;
- cache->command = strdup(command);
- cache->text = (text ? strdup(text) : NULL);
- get_userauth(user, neonserv_event_ctcp_nick_lookup, cache);
- } else
- neonserv_event_ctcp_async1(client, user, chan, command, text);
-}
-
-static USERAUTH_CALLBACK(neonserv_event_ctcp_nick_lookup) {
- struct neonserv_event_ctcp_cache *cache = data;
- if(user) {
- neonserv_event_ctcp_async1(cache->client, cache->user, cache->chan, cache->command, cache->text);
- }
- free(cache->command);
- if(cache->text)
- free(cache->text);
- free(cache);
-}
-
-static void neonserv_event_ctcp_async1(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, char *command, char *text) {
- MYSQL_RES *res;
- MYSQL_ROW row, defaultrow = NULL, chanuser;
- int uaccess = 0;
- printf_mysql_query("SELECT `channel_ctcp`, `channel_ctcpreaction` FROM `channels` WHERE `channel_id` = '%d'", chan->channel_id);
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) == NULL) return;
- if(!row[0] || !row[1]) {
- printf_mysql_query("SELECT `channel_ctcp`, `channel_ctcpreaction` FROM `channels` WHERE `channel_name` = 'defaults'");
- res = mysql_use();
- defaultrow = mysql_fetch_row(res);
- }
- int ctcpaccess = atoi((row[0] ? row[0] : defaultrow[0]));
- if((user->flags & USERFLAG_ISAUTHED)) {
- printf_mysql_query("SELECT `chanuser_access`, `chanuser_flags` FROM `chanusers` LEFT JOIN `users` ON `chanuser_uid` = `user_id` WHERE `chanuser_cid` = '%d' AND `user_user` = '%s'", chan->channel_id, escape_string(user->auth));
- res = mysql_use();
- chanuser = mysql_fetch_row(res);
- if(chanuser)
- uaccess = ((atoi(chanuser[1]) & DB_CHANUSER_SUSPENDED) ? 0 : atoi(chanuser[0]));
- }
- int duration = 0;
- char banmaskBuf[NICKLEN+USERLEN+HOSTLEN+3];
- char *banmask = NULL;
- char *reason = "disallowed channel CTCP";
- if(uaccess < ctcpaccess) {
- switch(atoi((row[1] ? row[1] : defaultrow[1]))) {
- case 2: //TIMEBAN: 3min
- duration = 180;
- case 3: //TIMEBAN: 1h
- if(!duration)
- duration = 3600;
- banmask = generate_banmask(user, banmaskBuf);
- printf_mysql_query("INSERT INTO `bans` (`ban_channel`, `ban_mask`, `ban_triggered`, `ban_timeout`, `ban_owner`, `ban_reason`) VALUES ('%d', '%s', UNIX_TIMESTAMP(), '%lu', '%d', '%s')", chan->channel_id, escape_string(banmask), (unsigned long) (time(0) + duration), 0, escape_string(reason));
- int banid = (int) mysql_insert_id(get_mysql_conn());
- char nameBuf[MAXLEN];
- char banidBuf[20];
- sprintf(nameBuf, "ban_%d", banid);
- sprintf(banidBuf, "%d", banid);
- timeq_add_name(nameBuf, duration, channel_ban_timeout, strdup(banidBuf));
- case 1: //KICKBAN
- if(!banmask)
- banmask = generate_banmask(user, banmaskBuf);
- putsock(client, "MODE %s +b %s", chan->name, banmask);
- case 0: //KICK
- putsock(client, "KICK %s %s :%s", chan->name, user->nick, reason);
- break;
- }
- }
-}
-
+++ /dev/null
-/* event_neonserv_invite.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-static void neonserv_event_invite(struct ClientSocket *client, struct UserNode *user, char *channel) {
- MYSQL_RES *res;
- MYSQL_ROW row;
- printf_mysql_query("SELECT `botid`, `bot_channels`.`id`, `suspended` FROM `bot_channels` LEFT JOIN `bots` ON `bot_channels`.`botid` = `bots`.`id` LEFT JOIN `channels` ON `chanid` = `channel_id` WHERE `channel_name` = '%s' AND `botclass` = '%d'", escape_string(channel), client->botid);
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) == NULL) {
- reply(client, user, "NS_INVITE_FAIL", channel, client->user->nick);
- return;
- }
- if(!strcmp(row[2], "1")) {
- reply(client, user, "MODCMD_CHAN_SUSPENDED");
- return;
- }
- int botid = atoi(row[0]);
- struct ClientSocket *bot;
- for(bot = getBots(SOCKET_FLAG_READY, NULL); bot; bot = getBots(SOCKET_FLAG_READY, bot)) {
- if(bot->clientid == botid)
- break;
- }
- if(bot) {
- struct ChanNode *chan = getChanByName(channel);
- if(chan && isUserOnChan(bot->user, chan)) {
- reply(client, user, "NS_INVITE_ON_CHAN", bot->user->nick, chan->name);
- } else
- putsock(bot, "JOIN %s", channel);
- }
-}
-
+++ /dev/null
-/* event_neonserv_join.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-struct neonserv_event_join_cache {
- struct ClientSocket *client;
- struct ChanUser *chanuser;
- int was_registering;
-};
-
-static USERAUTH_CALLBACK(neonserv_event_join_nick_lookup);
-static void neonserv_event_join_async1(struct ClientSocket *client, struct ChanUser *chanuser, int was_registering);
-static TIMEQ_CALLBACK(neonserv_event_join_dynlimit);
-
-static void neonserv_event_join(struct ChanUser *chanuser) {
- struct UserNode *user = chanuser->user;
- struct ClientSocket *client = getBotForChannel(chanuser->chan);
- if(!client) return; //we can't "see" this event
- if(chanuser->user == client->user) {
- requestOp(client->user, chanuser->chan);
- return;
- }
- if(chanuser->user->flags & USERFLAG_ISBOT) return;
- loadChannelSettings(chanuser->chan);
- if(!(chanuser->chan->flags & CHANFLAG_CHAN_REGISTERED)) return;
- char *ban;
- char usermask[NICKLEN+USERLEN+HOSTLEN+3];
- sprintf(usermask, "%s!%s@%s", user->nick, user->ident, user->host);
- if((ban = getBanAffectingMask(chanuser->chan, usermask)) != NULL && !(user->flags & (USERFLAG_ISBOT | USERFLAG_ISIRCOP))) {
- MYSQL_RES *res;
- MYSQL_ROW row;
- printf_mysql_query("SELECT `ban_reason`, `user_user` FROM `bans` LEFT JOIN `users` ON `ban_owner` = `user_id` WHERE `ban_channel` = '%d' AND `ban_mask` = '%s'", chanuser->chan->channel_id, escape_string(ban));
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) != NULL) {
- putsock(client, "MODE %s +b %s", chanuser->chan->name, ban);
- putsock(client, "KICK %s %s :(%s) %s", chanuser->chan->name, chanuser->user->nick, (row[1] ? row[1] : client->user->nick), row[0]);
- return;
- }
- }
- if(!(user->flags & USERFLAG_ISAUTHED)) {
- struct neonserv_event_join_cache *cache = malloc(sizeof(*cache));
- if (!cache) {
- perror("malloc() failed");
- return;
- }
- cache->client = client;
- cache->chanuser = chanuser;
- cache->was_registering = (user->flags & USERFLAG_WAS_REGISTRING);
- get_userauth(user, neonserv_event_join_nick_lookup, cache);
- } else
- neonserv_event_join_async1(client, chanuser, (user->flags & USERFLAG_WAS_REGISTRING));
-}
-
-static USERAUTH_CALLBACK(neonserv_event_join_nick_lookup) {
- struct neonserv_event_join_cache *cache = data;
- if(user) {
- neonserv_event_join_async1(cache->client, cache->chanuser, cache->was_registering);
- }
- free(cache);
-}
-
-static void neonserv_event_join_async1(struct ClientSocket *client, struct ChanUser *chanuser, int was_registering) {
- struct ClientSocket *textclient = ((client->flags & SOCKET_FLAG_PREFERRED) ? client : get_prefered_bot(client->botid));
- struct ChanNode *chan = chanuser->chan;
- struct UserNode *user = chanuser->user;
- struct ModeBuffer *modeBuf;
- int with_halfops = get_int_field("General.have_halfop");
- MYSQL_RES *res;
- MYSQL_ROW row, chanuserrow, defaultrow = NULL;
- printf_mysql_query("SELECT `channel_maxusers`, `channel_greeting`, `channel_usergreeting`, `channel_getop`, `channel_getvoice`, `channel_userinfo`, `channel_dynlimit`, `channel_gethalfop` FROM `channels` WHERE `channel_id` = '%d'", chan->channel_id);
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) == NULL) return;
- if(!row[3] || !row[4] || !row[5] || (!row[7] && with_halfops)) {
- printf_mysql_query("SELECT `channel_getop`, `channel_getvoice`, `channel_userinfo`, `channel_gethalfop` FROM `channels` WHERE `channel_name` = 'defaults'");
- res = mysql_use();
- defaultrow = mysql_fetch_row(res);
- }
- if(chan->usercount > atoi(row[0])) {
- //update maxusers
- printf_mysql_query("UPDATE `channels` SET `channel_maxusers` = '%d' WHERE `channel_id` = '%d'", chan->usercount, chan->channel_id);
- }
- if((user->flags & USERFLAG_ISAUTHED)) {
- printf_mysql_query("SELECT `chanuser_access`, `chanuser_flags`, `chanuser_infoline`, `chanuser_seen`, `chanuser_id` FROM `chanusers` LEFT JOIN `users` ON `chanuser_uid` = `user_id` WHERE `chanuser_cid` = '%d' AND `user_user` = '%s'", chan->channel_id, escape_string(user->auth));
- res = mysql_use();
- chanuserrow = mysql_fetch_row(res);
- } else
- chanuserrow = NULL;
- if(!chanuserrow)
- printf_mysql_query("UPDATE `channels` SET `channel_lastvisit` = UNIX_TIMESTAMP() WHERE `channel_id` = '%d'", chan->channel_id);
- int userflags = (chanuserrow ? atoi(chanuserrow[1]) : 0);
- int uaccess = ((chanuserrow && !(userflags & DB_CHANUSER_SUSPENDED)) ? atoi(chanuserrow[0]) : 0);
- //GREETING
- char greeting[MAXLEN];
- int greetingPos = 0;
- char *a, *b = (chanuserrow && *row[2] ? row[2] : row[1]);
- do {
- if(!b) break;
- a = strstr(b, "$");
- if(a) *a = '\0';
- greetingPos += sprintf(greeting + greetingPos, "%s", b);
- if(!a) break;
- switch(a[1]) {
- case '\0':
- a = NULL;
- break;
- case 'A':
- greetingPos += sprintf(greeting + greetingPos, "%d", uaccess);
- break;
- case 'B':
- greetingPos += sprintf(greeting + greetingPos, "%s", client->user->nick);
- break;
- case 'N':
- greetingPos += sprintf(greeting + greetingPos, "%s", user->nick);
- break;
- case 'H':
- greetingPos += sprintf(greeting + greetingPos, "%s@%s", user->ident, user->host);
- break;
- case 'U':
- greetingPos += sprintf(greeting + greetingPos, "%s", ((user->flags & USERFLAG_ISAUTHED) ? user->auth : "*"));
- break;
- default:
- greeting[greetingPos++] = '$';
- greeting[greetingPos++] = a[1];
- break;
- }
- if(a)
- b = a+2;
- } while(a);
- if(greetingPos && (!was_registering || *row[2]))
- reply(textclient, user, "[%s] %s", chan->name, greeting);
- //USER RIGHTS
- if(!(userflags & DB_CHANUSER_NOAUTOOP)) {
- int getop = atoi((row[3] ? row[3] : defaultrow[0]));
- int gethalfop = (with_halfops ? atoi((row[7] ? row[7] : defaultrow[3])) : 0);
- int getvoice = atoi((row[4] ? row[4] : defaultrow[1]));
- modeBuf = initModeBuffer(client, chan);
- if(uaccess >= getop && uaccess != 0) { //we disallow auto op for all users
- modeBufferOp(modeBuf, user->nick);
- } else if(with_halfops && uaccess >= gethalfop) {
- modeBufferHalfop(modeBuf, user->nick);
- } else if(uaccess >= getvoice) {
- modeBufferVoice(modeBuf, user->nick);
- }
- freeModeBuffer(modeBuf);
- }
- //INFOLINE
- int userinfoaccess = atoi((row[5] ? row[5] : defaultrow[2]));
- if(chanuserrow && strcmp(chanuserrow[2], "") && uaccess > userinfoaccess) {
- if(!strcmp(chanuserrow[3], "0") || time(0) - atol(chanuserrow[3]) >= 30) {
- putsock(client, "PRIVMSG %s :[%s] %s", chan->name, user->nick, chanuserrow[2]);
- }
- }
- //SEEN
- if(chanuserrow) {
- printf_mysql_query("UPDATE `chanusers` SET `chanuser_seen` = UNIX_TIMESTAMP() WHERE `chanuser_id` = '%s'", chanuserrow[4]);
- }
- //DYNLIMIT
- if(row[6] && strcmp(row[6], "0")) {
- char nameBuf[CHANNELLEN + 10];
- sprintf(nameBuf, "dynlimit_%s", chan->name);
- if(!timeq_name_exists(nameBuf)) {
- //neonserv_event_join_dynlimit
- timeq_add_name(nameBuf, 30, neonserv_event_join_dynlimit, strdup(chan->name));
- }
- }
- //AUTOINVITE
- if((user->flags & USERFLAG_ISAUTHED) && (!chanuserrow || !strcmp(chanuserrow[3], "0") || time(0) - atol(chanuserrow[3]) >= 30)) {
- //check if it's the first channel, the user is seen by the bot (IMPORTANT: ignore other bot's channel!)
- char first_chan = 1;
- char bot_in_chan;
- struct ChanUser *cchanuser, *bchanuser;
- struct ClientSocket *bot;
- for(cchanuser = getUserChannels(user, NULL); cchanuser; cchanuser = getUserChannels(user, cchanuser)) {
- if(chanuser == cchanuser) continue; //ignore this one ;)
- //check if this bot is in the specific channel
- bot_in_chan = 0;
- for(bchanuser = getChannelUsers(cchanuser->chan, NULL); bchanuser; bchanuser = getChannelUsers(cchanuser->chan, bchanuser)) {
- if(bchanuser->user->flags & USERFLAG_ISBOT) {
- //get the botid
- for(bot = getBots(SOCKET_FLAG_READY, NULL); bot; bot = getBots(SOCKET_FLAG_READY, bot)) {
- if(bot->user == bchanuser->user) {
- if(bot->botid == client->botid)
- bot_in_chan = 1;
- break;
- }
- }
- if(bot_in_chan) break;
- }
- }
- if(!bot_in_chan) continue;
- first_chan = 0;
- break;
- }
- if(first_chan) {
- //autoinvite :)
- defaultrow = NULL;
- printf_mysql_query("SELECT `chanuser_access`, `chanuser_flags`, `channel_name`, `channel_getinvite` FROM `chanusers` LEFT JOIN `channels` ON `chanuser_cid` = `channel_id` LEFT JOIN `users` ON `chanuser_uid` = `user_id` WHERE `user_user` = '%s' AND `chanuser_flags` >= '%d'", escape_string(user->auth), DB_CHANUSER_AUTOINVITE);
- res = mysql_use();
- int getinvite;
- while((chanuserrow = mysql_fetch_row(res)) != NULL) {
- userflags = atoi(chanuserrow[1]);
- if(!(userflags & DB_CHANUSER_AUTOINVITE)) continue;
- if(!(chan = getChanByName(chanuserrow[2]))) continue; //no bot is in the channel
- if((bchanuser = getChanUser(client->user, chan)) && (bchanuser->flags & CHANUSERFLAG_OPPED))
- bot = client;
- else {
- bot = getBotForChannel(chan);
- }
- if(chanuserrow[3] == NULL && defaultrow == NULL) {
- printf_mysql_query("SELECT `channel_getinvite` FROM `channels` WHERE `channel_name` = 'defaults'");
- res = mysql_use();
- defaultrow = mysql_fetch_row(res);
- }
- getinvite = atoi((chanuserrow[3] ? chanuserrow[3] : defaultrow[0]));
- if(atoi(chanuserrow[0]) >= getinvite) {
- putsock(bot, "INVITE %s %s", user->nick, chan->name);
- }
- }
- }
- }
-}
-
-static TIMEQ_CALLBACK(neonserv_event_join_dynlimit) {
- char *chanName = data;
- struct ChanNode *chan = getChanByName(chanName);
- free(chanName);
- struct ClientSocket *client = getBotForChannel(chan);
- if(!client) return;
- loadChannelSettings(chan);
- if(!(chan->flags & CHANFLAG_CHAN_REGISTERED)) return;
- MYSQL_RES *res;
- MYSQL_ROW row;
- printf_mysql_query("SELECT `channel_dynlimit` FROM `channels` WHERE `channel_id` = '%d'", chan->channel_id);
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) == NULL) return;
- if(row[0] && strcmp(row[0], "0")) {
- putsock(client, "MODE %s +l %d", chan->name, chan->usercount + atoi(row[0]));
- }
-}
+++ /dev/null
-/* event_neonserv_kick.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-struct neonserv_event_kick_cache {
- struct ClientSocket *client;
- struct UserNode *user;
- struct UserNode *target;
- struct ChanNode *chan;
- int userauth_pending;
-};
-
-static USERAUTH_CALLBACK(neonserv_event_kick_nick_lookup);
-static void neonserv_event_kick_async1(struct neonserv_event_kick_cache *cache);
-static void neonserv_event_kick_async2(struct ClientSocket *client, struct UserNode *user, struct UserNode *target, struct ChanNode *chan);
-
-static void neonserv_event_kick(struct UserNode *user, struct ChanUser *target, char *reason) {
- struct ChanNode *chan = target->chan;
- struct ClientSocket *client;
- if(isBot(target->user)) {
- client = getChannelBot(chan, 0);
- struct ClientSocket *bot = client;
- for(client = getBots(SOCKET_FLAG_READY, NULL); client; client = getBots(SOCKET_FLAG_READY, client)) {
- if(client->user == target->user) {
- break;
- }
- }
- if(!client) return;
- if(bot && bot != client && (isModeSet(chan->modes, 'i') || isModeSet(chan->modes, 'a') || isModeSet(chan->modes, 'l'))) {
- struct ChanUser *chanuser = getChanUser(bot->user, chan);
- if(chanuser && chanuser->flags & CHANUSERFLAG_OPPED)
- putsock(bot, "INVITE %s %s", target->user->nick, chan->name);
- }
- char *key = "";
- if(isModeSet(chan->modes, 'k')) {
- key = getModeValue(chan->modes, 'k');
- }
- putsock(client, "JOIN %s %s", chan->name, key);
- return;
- }
- client = getBotForChannel(chan);
- if(!client) return; //we can't "see" this event
- if(isNetworkService(user)) return;
- loadChannelSettings(chan);
- if(!(chan->flags & CHANFLAG_CHAN_REGISTERED)) return;
- struct neonserv_event_kick_cache *cache = malloc(sizeof(*cache));
- if (!cache) {
- perror("malloc() failed");
- return;
- }
- cache->client = client;
- cache->user = user;
- cache->target = target->user;
- cache->chan = target->chan;
- cache->userauth_pending = 0;
- if(!(user->flags & USERFLAG_ISAUTHED)) {
- get_userauth(user, neonserv_event_kick_nick_lookup, cache);
- cache->userauth_pending++;
- }
- if(!(target->user->flags & USERFLAG_ISAUTHED)) {
- get_userauth(target->user, neonserv_event_kick_nick_lookup, cache);
- cache->userauth_pending++;
- }
- neonserv_event_kick_async1(cache);
-}
-
-static USERAUTH_CALLBACK(neonserv_event_kick_nick_lookup) {
- struct neonserv_event_kick_cache *cache = data;
- cache->userauth_pending--;
- neonserv_event_kick_async1(cache);
-}
-
-static void neonserv_event_kick_async1(struct neonserv_event_kick_cache *cache) {
- if(cache->userauth_pending == 0) {
- neonserv_event_kick_async2(cache->client, cache->user, cache->target, cache->chan);
- free(cache);
- }
-}
-
-static void neonserv_event_kick_async2(struct ClientSocket *client, struct UserNode *user, struct UserNode *target, struct ChanNode *chan) {
- if(isUserProtected(chan, target, user)) {
- char buf[MAXLEN];
- putsock(client, "KICK %s %s :%s", chan->name, user->nick, build_language_string(user, buf, "NS_USER_PROTECTED", target->nick));
- putsock(client, "INVITE %s %s", target->nick, chan->name);
- }
-}
+++ /dev/null
-/* event_neonserv_mode.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-static USERLIST_CALLBACK(neonserv_event_mode_userlist_lookup);
-static void neonserv_event_mode_async1(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, char *modes, char **argv, int argc);
-static int neonserv_cmd_mode_botwar_detect(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, int *botwar_detect_executed);
-
-struct neonserv_event_mode_cache {
- struct ClientSocket *client;
- struct UserNode *user;
- char *modes;
- char **argv;
- int argc;
-};
-
-static void neonserv_event_mode(struct UserNode *user, struct ChanNode *chan, char *modes, char **argv, int argc) {
- struct ClientSocket *client = getBotForChannel(chan);
- if(!client) return; //we can't "see" this event
- if(isNetworkService(user)) return;
- loadChannelSettings(chan);
- if(!(chan->flags & CHANFLAG_CHAN_REGISTERED)) return;
- struct neonserv_event_mode_cache *cache = malloc(sizeof(*cache));
- char **temp_argv = NULL;
- if(argc)
- temp_argv = malloc(argc*sizeof(*temp_argv));
- if (!cache || (argc && !temp_argv)) {
- perror("malloc() failed");
- return;
- }
- if(argc) {
- int i;
- for(i = 0; i < argc; i++) {
- temp_argv[i] = strdup(argv[i]);
- }
- }
- cache->client = client;
- cache->user = user;
- cache->modes = strdup(modes);
- cache->argv = temp_argv;
- cache->argc = argc;
- get_userlist_with_invisible(chan, neonserv_event_mode_userlist_lookup, cache);
-}
-
-static USERLIST_CALLBACK(neonserv_event_mode_userlist_lookup) {
- struct neonserv_event_mode_cache *cache = data;
- neonserv_event_mode_async1(cache->client, cache->user, chan, cache->modes, cache->argv, cache->argc);
- if(cache->argc) {
- int i;
- for(i = 0; i < cache->argc; i++) {
- free(cache->argv[i]);
- }
- free(cache->argv);
- }
- free(cache->modes);
- free(cache);
-}
-
-static void neonserv_event_mode_async1(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, char *modes, char **argv, int argc) {
- struct ClientSocket *textclient = ((client->flags & SOCKET_FLAG_PREFERRED) ? client : get_prefered_bot(client->botid));
- int botwar_detect_executed = 0;
- MYSQL_ROW row, defaults = NULL;
- int i, arg, add = 1, skip = 0;
- unsigned int modetype;
- int db_canop, db_canhalfop, db_canvoice, db_canban, db_enfmodes, db_getop, db_gethalfop, db_getvoice;
- struct ModeNode *modelock = createModeNode(NULL);
- struct ModeBuffer *modeBuf;
- struct UserNode *cuser;
- struct ChanUser *chanuser;
- int with_halfops = get_int_field("General.have_halfop");
- modeBuf = initModeBuffer(client, chan);
- printf_mysql_query("SELECT `channel_canop`, `channel_canvoice`, `channel_canban`, `channel_enfmodes`, `channel_modes`, `channel_getop`, `channel_getvoice`, `channel_gethalfop`, `channel_canhalfop` FROM `channels` WHERE `channel_id` = '%d'", chan->channel_id);
- row = mysql_fetch_row(mysql_use());
- if(row[0] == NULL || row[1] == NULL || row[2] == NULL || row[3] == NULL || row[4] == NULL || row[5] == NULL || row[6] == NULL || (row[7] == NULL && with_halfops) || (row[8] == NULL && with_halfops)) {
- printf_mysql_query("SELECT `channel_canop`, `channel_canvoice`, `channel_canban`, `channel_enfmodes`, `channel_modes`, `channel_getop`, `channel_getvoice`, `channel_gethalfop`, `channel_canhalfop` FROM `channels` WHERE `channel_name` = 'defaults'");
- defaults = mysql_fetch_row(mysql_use());
- }
- db_canop = atoi((row[0] ? row[0] : defaults[0]));
- db_canvoice = atoi((row[1] ? row[1] : defaults[1]));
- db_canban = atoi((row[2] ? row[2] : defaults[2]));
- db_enfmodes = atoi((row[3] ? row[3] : defaults[3]));
- db_getop = atoi((row[5] ? row[5] : defaults[5]));
- db_getvoice = atoi((row[6] ? row[6] : defaults[6]));
- db_gethalfop = (with_halfops ? atoi((row[7] ? row[7] : defaults[7])) : 0);
- db_canhalfop = (with_halfops ? atoi((row[8] ? row[8] : defaults[8])) : 0);
- if(row[4])
- parseModeString(modelock, row[4]);
- else if(defaults[4])
- parseModeString(modelock, defaults[4]);
- int uaccess = getChannelAccess(user, chan);
- int caccess;
- char *carg;
- int sent_modes_locked = 0;
- char deop_user = 0;
- char tmp[MAXLEN];
- arg = 0;
- for(i = 0; i < strlen(modes); i++) {
- switch(modes[i]) {
- case '+':
- add = 1;
- break;
- case '-':
- add = 0;
- break;
- case 'o':
- case 'h':
- case 'v':
- if(arg == argc) {
- break;
- }
- carg = argv[arg++];
- cuser = searchUserByNick(carg);
- if(!cuser) {
- break; //internal Bot error - this should never happen
- }
- caccess = getChannelAccess(cuser, chan);
- if(modes[i] == 'o' && !add && cuser == client->user) {
- //someone deopped the bot???
- if(!neonserv_cmd_mode_botwar_detect(client, user, chan, &botwar_detect_executed))
- requestOp(client->user, chan);
- }
- if((modes[i] == 'o' || (modes[i] == 'h' && !with_halfops)) && !(add && isBot(cuser))) {
- if(uaccess < db_canop) {
- reply(textclient, user, "NS_MODE_ENFOPS", chan->name);
- db_canop = -1;
- if(uaccess < db_getop)
- deop_user = 1;
- }
- if(db_canop == -1 && caccess < db_getop) {
- if(!neonserv_cmd_mode_botwar_detect(client, user, chan, &botwar_detect_executed))
- modeBufferSet(modeBuf, !add, modes[i], carg);
- break;
- }
- } else if(modes[i] == 'h' && with_halfops && !(add && isBot(cuser))) {
- if(uaccess < db_canhalfop) {
- reply(textclient, user, "NS_MODE_ENFOPS", chan->name);
- db_canhalfop = -1;
- if(uaccess < db_gethalfop)
- deop_user = 1;
- }
- if(db_canhalfop == -1 && caccess < db_gethalfop) {
- if(!neonserv_cmd_mode_botwar_detect(client, user, chan, &botwar_detect_executed))
- modeBufferSet(modeBuf, !add, modes[i], carg);
- break;
- }
- } else if(modes[i] == 'v' && !(add && isBot(cuser))) {
- if(uaccess < db_canvoice) {
- reply(textclient, user, "NS_MODE_ENFVOICE", chan->name);
- db_canvoice = -1;
- if(uaccess < db_getop)
- deop_user = 1;
- }
- if(db_canvoice == -1 && caccess < db_getvoice) {
- if(!neonserv_cmd_mode_botwar_detect(client, user, chan, &botwar_detect_executed))
- modeBufferSet(modeBuf, !add, modes[i], carg);
- break;
- }
- }
- if(!add) {
- //check protection
- if(isBot(cuser)) {
- //don't send this - just try to reop
- //reply(textclient, user, "NS_SERVICE_IMMUNE", cuser->nick);
- if(!neonserv_cmd_mode_botwar_detect(client, user, chan, &botwar_detect_executed))
- modeBufferSet(modeBuf, !add, modes[i], carg);
- break;
- }
- if(isUserProtected(chan, cuser, user)) {
- reply(textclient, user, "NS_USER_PROTECTED", cuser->nick);
- if(!neonserv_cmd_mode_botwar_detect(client, user, chan, &botwar_detect_executed))
- modeBufferSet(modeBuf, !add, modes[i], carg);
- if(uaccess < db_getop)
- deop_user = 1;
- break;
- }
- }
- break;
- case 'b':
- if(arg == argc) {
- break;
- }
- carg = argv[arg++];
- if(uaccess < db_canban) {
- reply(textclient, user, "NS_MODE_CANBAN", chan->name);
- db_canban = -1;
- }
- if(db_canban == -1) {
- if(!neonserv_cmd_mode_botwar_detect(client, user, chan, &botwar_detect_executed))
- modeBufferSet(modeBuf, !add, modes[i], carg);
- if(uaccess < db_getop)
- deop_user = 1;
- break;
- }
- char hostmask_buffer[NICKLEN+USERLEN+HOSTLEN+3];
- char usermask[NICKLEN+USERLEN+HOSTLEN+3];
- int match_count = 0;
- carg = make_banmask(carg, hostmask_buffer);
- if(add) {
- for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
- cuser = chanuser->user;
- sprintf(usermask, "%s!%s@%s", cuser->nick, cuser->ident, cuser->host);
- if(!match(carg, usermask)) {
- if(isUserProtected(chan, cuser, user)) {
- reply(textclient, user, "NS_USER_PROTECTED", cuser->nick);
- skip = 1;
- break;
- }
- match_count++;
- }
- }
- if(match_count > 4 && (match_count * 3) > chan->usercount) {
- reply(textclient, user, "NS_LAME_MASK_WARNING", carg, match_count);
- }
- }
- if(skip) {
- if(!neonserv_cmd_mode_botwar_detect(client, user, chan, &botwar_detect_executed))
- modeBufferSet(modeBuf, !add, modes[i], carg);
- if(uaccess < db_getop)
- deop_user = 1;
- }
- break;
- default:
- modetype = getModeType(modelock, modes[i]);
- if(modetype == 0) {
- break; //unknown mode
- }
-
- if(add && (modetype & CHANNEL_MODE_TYPE) != CHANNEL_MODE_TYPE_D) {
- if(arg == argc) {
- break;
- }
- carg = argv[arg++];
- if((modetype & CHANNEL_MODE_VALUE) == CHANNEL_MODE_VALUE_STRING && isModeSet(modelock, modes[i])) {
- char *modelock_val = getModeValue(modelock, modes[i]);
- if(stricmp(carg, modelock_val) && uaccess < db_enfmodes && !isGodMode(user)) {
- if(!sent_modes_locked) {
- getFullModeString(modelock, tmp);
- reply(textclient, user, "NS_MODE_LOCKED", tmp, chan->name);
- sent_modes_locked = 1;
- if(uaccess < db_getop)
- deop_user = 1;
- }
- if(!neonserv_cmd_mode_botwar_detect(client, user, chan, &botwar_detect_executed))
- modeBufferSet(modeBuf, add, modes[i], modelock_val);
- break;
- }
- }
- if((modetype & CHANNEL_MODE_VALUE) == CHANNEL_MODE_VALUE_STRING && isModeSet(modelock, modes[i])) {
- int *modelock_val = getModeValue(modelock, modes[i]);
- if(atoi(carg) != *modelock_val && uaccess < db_enfmodes && !isGodMode(user)) {
- if(!sent_modes_locked) {
- getFullModeString(modelock, tmp);
- reply(textclient, user, "NS_MODE_LOCKED", tmp, chan->name);
- sent_modes_locked = 1;
- if(uaccess < db_getop)
- deop_user = 1;
- }
- sprintf(tmp, "%d", *modelock_val);
- if(!neonserv_cmd_mode_botwar_detect(client, user, chan, &botwar_detect_executed))
- modeBufferSet(modeBuf, add, modes[i], tmp);
- break;
- }
- }
- } else if(!add && (modetype & CHANNEL_MODE_TYPE) == CHANNEL_MODE_TYPE_B) {
- if(arg == argc) {
- break;
- }
- carg = argv[arg++];
- } else
- carg = NULL;
- if(isModeAffected(modelock, modes[i]) && add == !isModeSet(modelock, modes[i]) && uaccess < db_enfmodes && !isGodMode(user)) {
- if(!sent_modes_locked) {
- getFullModeString(modelock, tmp);
- reply(textclient, user, "NS_MODE_LOCKED", tmp, chan->name);
- sent_modes_locked = 1;
- if(uaccess < db_getop)
- deop_user = 1;
- }
- if(!neonserv_cmd_mode_botwar_detect(client, user, chan, &botwar_detect_executed))
- modeBufferSet(modeBuf, !add, modes[i], carg);
- break;
- }
- break;
- }
- }
- if(deop_user && !neonserv_cmd_mode_botwar_detect(client, user, chan, &botwar_detect_executed)) {
- modeBufferDeop(modeBuf, user->nick);
- }
- freeModeBuffer(modeBuf);
- freeModeNode(modelock);
-}
-
-static int neonserv_cmd_mode_botwar_detect(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, int *botwar_detect_executed) {
- struct ChanUser *chanuser = getChanUser(user, chan);
- if(!chanuser) return 0; //flying super cow?
- if(time(0) - chanuser->changeTime > BOTWAR_DETECTION_TIME) {
- chanuser->changeTime = time(0);
- chanuser->chageEvents = 1;
- } else {
- if(!*botwar_detect_executed)
- chanuser->chageEvents++;
- *botwar_detect_executed = 1;
- if(chanuser->chageEvents >= BOTWAR_DETECTION_EVENTS || chanuser->chageEvents < 0) {
- //BOTWAR!
- chanuser->changeTime = time(0);
- if(chanuser->chageEvents > 0) {
- char *alertchan = get_string_field("General.alertchan");
- putsock(client, "NOTICE @%s :%s %s", chan->name, get_language_string(user, "NS_BOTWAR_DETECTED"), (alertchan ? get_language_string(user, "NS_BOTWAR_REPORTED") : ""));
- if(alertchan) {
- struct ChanNode *alertchan_chan = getChanByName(alertchan);
- struct ClientSocket *alertclient;
- if(alertchan_chan && (alertclient = getBotForChannel(chan)) != NULL) {
- char msgBuf[MAXLEN];
- putsock(alertclient, "PRIVMSG %s :%s", alertchan_chan->name, build_language_string(NULL, msgBuf, "NS_BOTWAR_ALERT", chan->name, user->nick));
- }
- }
- }
- chanuser->chageEvents = -2;
- return 1;
- }
- }
- return 0;
-}
-
+++ /dev/null
-/* event_neonserv_notice.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-struct neonserv_event_notice_cache {
- struct ClientSocket *client;
- struct UserNode *user;
- struct ChanNode *chan;
- char *message;
-};
-
-static USERAUTH_CALLBACK(neonserv_event_notice_nick_lookup);
-static void neonserv_event_notice_async1(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, char *message);
-
-static void neonserv_event_channotice(struct UserNode *user, struct ChanNode *chan, char *message) {
- struct ClientSocket *client = getBotForChannel(chan);
- if(!client) return; //we can't "see" this event
- if(isNetworkService(user)) return;
- loadChannelSettings(chan);
- if(!(chan->flags & CHANFLAG_CHAN_REGISTERED)) return;
- if(!(user->flags & USERFLAG_ISAUTHED)) {
- struct neonserv_event_notice_cache *cache = malloc(sizeof(*cache));
- if (!cache) {
- perror("malloc() failed");
- return;
- }
- cache->client = client;
- cache->user = user;
- cache->chan = chan;
- cache->message = strdup(message);
- get_userauth(user, neonserv_event_notice_nick_lookup, cache);
- } else
- neonserv_event_notice_async1(client, user, chan, message);
-}
-
-static USERAUTH_CALLBACK(neonserv_event_notice_nick_lookup) {
- struct neonserv_event_notice_cache *cache = data;
- if(user) {
- neonserv_event_notice_async1(cache->client, cache->user, cache->chan, cache->message);
- }
- free(cache->message);
- free(cache);
-}
-
-static void neonserv_event_notice_async1(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, char *message) {
- MYSQL_RES *res;
- MYSQL_ROW row, defaultrow = NULL, chanuser;
- int uaccess = 0;
- printf_mysql_query("SELECT `channel_ctcp`, `channel_ctcpreaction` FROM `channels` WHERE `channel_id` = '%d'", chan->channel_id);
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) == NULL) return;
- if(!row[0] || !row[1]) {
- printf_mysql_query("SELECT `channel_ctcp`, `channel_ctcpreaction` FROM `channels` WHERE `channel_name` = 'defaults'");
- res = mysql_use();
- defaultrow = mysql_fetch_row(res);
- }
- int noticeaccess = atoi((row[0] ? row[0] : defaultrow[0]));
- if((user->flags & USERFLAG_ISAUTHED)) {
- printf_mysql_query("SELECT `chanuser_access`, `chanuser_flags` FROM `chanusers` LEFT JOIN `users` ON `chanuser_uid` = `user_id` WHERE `chanuser_cid` = '%d' AND `user_user` = '%s'", chan->channel_id, escape_string(user->auth));
- res = mysql_use();
- chanuser = mysql_fetch_row(res);
- if(chanuser)
- uaccess = ((atoi(chanuser[1]) & DB_CHANUSER_SUSPENDED) ? 0 : atoi(chanuser[0]));
- }
- int duration = 0;
- char banmaskBuf[NICKLEN+USERLEN+HOSTLEN+3];
- char *banmask = NULL;
- char *reason = "disallowed channel NOTICE";
- if(uaccess < noticeaccess) {
- switch(atoi((row[1] ? row[1] : defaultrow[1]))) {
- case 2: //TIMEBAN: 3min
- duration = 180;
- case 3: //TIMEBAN: 1h
- if(!duration)
- duration = 3600;
- banmask = generate_banmask(user, banmaskBuf);
- printf_mysql_query("INSERT INTO `bans` (`ban_channel`, `ban_mask`, `ban_triggered`, `ban_timeout`, `ban_owner`, `ban_reason`) VALUES ('%d', '%s', UNIX_TIMESTAMP(), '%lu', '%d', '%s')", chan->channel_id, escape_string(banmask), (unsigned long) (time(0) + duration), 0, escape_string(reason));
- int banid = (int) mysql_insert_id(get_mysql_conn());
- char nameBuf[MAXLEN];
- char banidBuf[20];
- sprintf(nameBuf, "ban_%d", banid);
- sprintf(banidBuf, "%d", banid);
- timeq_add_name(nameBuf, duration, channel_ban_timeout, strdup(banidBuf));
- case 1: //KICKBAN
- if(!banmask)
- banmask = generate_banmask(user, banmaskBuf);
- putsock(client, "MODE %s +b %s", chan->name, banmask);
- case 0: //KICK
- putsock(client, "KICK %s %s :%s", chan->name, user->nick, reason);
- break;
- }
- }
-}
-
+++ /dev/null
-/* event_neonserv_part.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-static void neonserv_event_part(struct ChanUser *chanuser, char *reason) {
- struct ChanNode *chan = chanuser->chan;
- struct UserNode *user = chanuser->user;
- MYSQL_RES *res;
- MYSQL_ROW chanuserrow;
- loadChannelSettings(chan);
- if(!(chan->flags & CHANFLAG_CHAN_REGISTERED)) return;
- if((user->flags & USERFLAG_ISAUTHED)) {
- printf_mysql_query("SELECT `chanuser_id` FROM `chanusers` LEFT JOIN `users` ON `chanuser_uid` = `user_id` WHERE `chanuser_cid` = '%d' AND `user_user` = '%s'", chan->channel_id, escape_string(user->auth));
- res = mysql_use();
- if((chanuserrow = mysql_fetch_row(res)) != NULL)
- printf_mysql_query("UPDATE `chanusers` SET `chanuser_seen` = UNIX_TIMESTAMP() WHERE `chanuser_id` = '%s'", chanuserrow[0]);
- }
-}
+++ /dev/null
-/* event_neonserv_quit.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-static void neonserv_event_quit(struct UserNode *user, char *reason) {
- MYSQL_RES *res;
- MYSQL_ROW chanuserrow;
- struct ChanUser *chanuser;
- if((user->flags & USERFLAG_ISAUTHED)) {
- for(chanuser = getUserChannels(user, NULL); chanuser; chanuser = getUserChannels(user, chanuser)) {
- printf_mysql_query("SELECT `chanuser_id` FROM `chanusers` LEFT JOIN `users` ON `chanuser_uid` = `user_id` LEFT JOIN `channels` ON `chanuser_cid` = `channel_id` WHERE `channel_name` = '%s' AND `user_user` = '%s'", escape_string(chanuser->chan->name), escape_string(user->auth));
- res = mysql_use();
- if((chanuserrow = mysql_fetch_row(res)) != NULL)
- printf_mysql_query("UPDATE `chanusers` SET `chanuser_seen` = UNIX_TIMESTAMP() WHERE `chanuser_id` = '%s'", chanuserrow[0]);
- }
- }
-}
+++ /dev/null
-/* event_neonserv_topic.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-struct neonserv_event_topic_cache {
- struct ClientSocket *client;
- struct UserNode *user;
- struct ChanNode *chan;
- char *new_topic;
-};
-
-static USERAUTH_CALLBACK(neonserv_event_topic_nick_lookup);
-static void neonserv_event_topic_async1(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, const char *new_topic);
-
-static void neonserv_event_topic(struct UserNode *user, struct ChanNode *chan, const char *new_topic) {
- struct ClientSocket *client = getBotForChannel(chan);
- if(!client) return; //we can't "see" this event
- if(isNetworkService(user)) return;
- loadChannelSettings(chan);
- if(!(chan->flags & CHANFLAG_CHAN_REGISTERED)) return;
- if(!(user->flags & USERFLAG_ISAUTHED)) {
- struct neonserv_event_topic_cache *cache = malloc(sizeof(*cache));
- if (!cache) {
- perror("malloc() failed");
- return;
- }
- cache->client = client;
- cache->user = user;
- cache->chan = chan;
- cache->new_topic = strdup(new_topic);
- get_userauth(user, neonserv_event_topic_nick_lookup, cache);
- } else
- neonserv_event_topic_async1(client, user, chan, new_topic);
-}
-
-static USERAUTH_CALLBACK(neonserv_event_topic_nick_lookup) {
- struct neonserv_event_topic_cache *cache = data;
- if(user) {
- neonserv_event_topic_async1(cache->client, cache->user, cache->chan, cache->new_topic);
- }
- free(cache->new_topic);
- free(cache);
-}
-
-static void neonserv_event_topic_async1(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, const char *new_topic) {
- MYSQL_RES *res;
- MYSQL_ROW row, defaultrow = NULL, chanuserrow;
- int uaccess = 0;
- printf_mysql_query("SELECT `channel_changetopic`, `channel_topicsnarf` FROM `channels` WHERE `channel_id` = '%d'", chan->channel_id);
- res = mysql_use();
- if ((row = mysql_fetch_row(res)) == NULL) return;
- if(!row[0] || !row[1]) {
- printf_mysql_query("SELECT `channel_changetopic`, `channel_topicsnarf` FROM `channels` WHERE `channel_name` = 'defaults'");
- res = mysql_use();
- defaultrow = mysql_fetch_row(res);
- }
- int changetopic = atoi((row[0] ? row[0] : defaultrow[0]));
- int topicsnarf = atoi((row[1] ? row[1] : defaultrow[1]));
- if((user->flags & USERFLAG_ISAUTHED)) {
- printf_mysql_query("SELECT `chanuser_access`, `chanuser_flags` FROM `chanusers` LEFT JOIN `users` ON `chanuser_uid` = `user_id` WHERE `chanuser_cid` = '%d' AND `user_user` = '%s'", chan->channel_id, escape_string(user->auth));
- res = mysql_use();
- chanuserrow = mysql_fetch_row(res);
- if(chanuserrow)
- uaccess = ((atoi(chanuserrow[1]) & DB_CHANUSER_SUSPENDED) ? 0 : atoi(chanuserrow[0]));
- }
- if(uaccess < changetopic) {
- //undo topic change
- struct ClientSocket *textclient = ((client->flags & SOCKET_FLAG_PREFERRED) ? client : get_prefered_bot(client->botid));
- struct ChanUser *chanuser = getChanUser(user, chan);
- if(!chanuser) return; //flying super cow?
- if(time(0) - chanuser->changeTime > BOTWAR_DETECTION_TIME) {
- chanuser->changeTime = time(0);
- chanuser->chageEvents = 1;
- } else {
- chanuser->chageEvents++;
- if(chanuser->chageEvents >= BOTWAR_DETECTION_EVENTS || chanuser->chageEvents < 0) {
- //BOTWAR!
- chanuser->changeTime = time(0);
- if(chanuser->chageEvents > 0) {
- char *alertchan = get_string_field("General.alertchan");
- putsock(client, "NOTICE @%s :%s %s", chan->name, get_language_string(user, "NS_BOTWAR_DETECTED"), (alertchan ? get_language_string(user, "NS_BOTWAR_REPORTED") : ""));
- if(alertchan) {
- struct ChanNode *alertchan_chan = getChanByName(alertchan);
- struct ClientSocket *alertclient;
- if(alertchan_chan && (alertclient = getBotForChannel(chan)) != NULL) {
- char msgBuf[MAXLEN];
- putsock(alertclient, "PRIVMSG %s :%s", alertchan_chan->name, build_language_string(NULL, msgBuf, "NS_BOTWAR_ALERT", chan->name, user->nick));
- }
- }
- }
- chanuser->chageEvents = -2;
- return;
- }
- }
- reply(textclient, user, "NS_TOPIC_ACCESS", chan->name);
- putsock(client, "TOPIC %s :%s", chan->name, chan->topic);
- } else if(uaccess >= topicsnarf) {
- printf_mysql_query("UPDATE `channels` SET `channel_defaulttopic` = '%s' WHERE `channel_id` = '%d'", escape_string(new_topic), chan->channel_id);
- }
-}
-
+++ /dev/null
-/* event_neonspam_chanmsg.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-static int neonspam_spamscan(struct NeonSpamSettings *settings, struct ChanUser *chanuser, char *message);
-static int neonspam_floodscan(struct NeonSpamSettings *settings, struct ChanUser *chanuser);
-static int neonspam_botnetscan(struct ClientSocket *client, struct NeonSpamSettings *settings, struct ChanUser *chanuser, char *message);
-static int neonspam_capsscan(struct NeonSpamSettings *settings, struct ChanUser *chanuser, char *message);
-static int neonspam_digitscan(struct NeonSpamSettings *settings, struct ChanUser *chanuser, char *message);
-
-static USERAUTH_CALLBACK(neonspam_event_chanmsg_nick_lookup);
-static void neonspam_event_chanmsg_punish(struct ClientSocket *client, struct ChanUser *chanuser, struct NeonSpamSettings *settings, unsigned int warn, unsigned int punish);
-
-struct neonspam_event_chanmsg_cache {
- struct ClientSocket *client;
- struct ChanUser *chanuser;
- struct NeonSpamSettings *settings;
- unsigned int warn;
- unsigned int punish;
-};
-
-
-
-static void neonspam_event_chanmsg(struct UserNode *user, struct ChanNode *chan, char *message) {
- struct ClientSocket *client = getChannelBot(chan, BOTID);
- if(!client || (user->flags & USERFLAG_ISBOT)) return; //we can't "see" this event
- loadNeonSpamSettings(chan);
- struct NeonSpamSettings *settings = chan->spam_settings;
- struct ChanUser *chanuser = getChanUser(user, chan);
- if(!settings || !chanuser) return;
- #define NEONSPAM_CHANMSG_DO_SCANOPS(FLAG) ((settings->flags & FLAG) || !(chanuser->flags & CHANUSERFLAG_OPPED))
- #define NEONSPAM_CHANMSG_DO_SCANVOICE(FLAG) ((settings->flags & FLAG) || !(chanuser->flags & CHANUSERFLAG_VOICED))
- #define NEONSPAM_CHANMSG_DO_EXCEPT(INDEX) (settings->exceptlevel[INDEX] != 0)
- #define NEONSPAM_CHANMSG_NEED_WHO(INDEX) (settings->exceptlevel[INDEX] != 501)
- //scan the message
- int result = 0;
- unsigned int warn = 0;
- unsigned int punish = 0;
- int needwho = 0;
- if((settings->flags & SPAMSETTINGS_SPAMSCAN) && NEONSPAM_CHANMSG_DO_SCANOPS(SPAMSETTINGS_SPAMSCAN_OPS) && NEONSPAM_CHANMSG_DO_SCANVOICE(SPAMSETTINGS_SPAMSCAN_VOICE) && NEONSPAM_CHANMSG_DO_EXCEPT(SPAMSETTINGS_SPAMEXCINDEX)) {
- result = neonspam_spamscan(settings, chanuser, message);
- switch(result) {
- case SPAMSERV_CHECK_IGNORE:
- break;
- case SPAMSERV_CHECK_WARN:
- warn |= SPAMSETTINGS_SPAMSCAN;
- if(NEONSPAM_CHANMSG_NEED_WHO(SPAMSETTINGS_SPAMEXCINDEX))
- needwho = 1;
- break;
- case SPAMSERV_CHECK_PUNISH:
- punish |= SPAMSETTINGS_SPAMSCAN;
- if(NEONSPAM_CHANMSG_NEED_WHO(SPAMSETTINGS_SPAMEXCINDEX))
- needwho = 1;
- break;
- }
- }
- if((settings->flags & SPAMSETTINGS_FLOODSCAN) && NEONSPAM_CHANMSG_DO_SCANOPS(SPAMSETTINGS_FLOODSCAN_OPS) && NEONSPAM_CHANMSG_DO_SCANVOICE(SPAMSETTINGS_FLOODSCAN_VOICE) && NEONSPAM_CHANMSG_DO_EXCEPT(SPAMSETTINGS_FLOODEXCINDEX)) {
- result = neonspam_floodscan(settings, chanuser);
- switch(result) {
- case SPAMSERV_CHECK_IGNORE:
- break;
- case SPAMSERV_CHECK_WARN:
- warn |= SPAMSETTINGS_FLOODSCAN;
- if(NEONSPAM_CHANMSG_NEED_WHO(SPAMSETTINGS_FLOODEXCINDEX))
- needwho = 1;
- break;
- case SPAMSERV_CHECK_PUNISH:
- punish |= SPAMSETTINGS_FLOODSCAN;
- if(NEONSPAM_CHANMSG_NEED_WHO(SPAMSETTINGS_FLOODEXCINDEX))
- needwho = 1;
- break;
- }
- }
- if((settings->flags & SPAMSETTINGS_BOTNETSCAN) && NEONSPAM_CHANMSG_DO_SCANOPS(SPAMSETTINGS_BOTNETSCAN_OPS) && NEONSPAM_CHANMSG_DO_SCANVOICE(SPAMSETTINGS_BOTNETSCAN_VOICE)) {
- result = neonspam_botnetscan(client, settings, chanuser, message);
- switch(result) {
- case SPAMSERV_CHECK_DEAD:
- return;
- case SPAMSERV_CHECK_IGNORE:
- break;
- }
- }
- if((settings->flags & SPAMSETTINGS_CAPSSCAN) && NEONSPAM_CHANMSG_DO_SCANOPS(SPAMSETTINGS_CAPSSCAN_OPS) && NEONSPAM_CHANMSG_DO_SCANVOICE(SPAMSETTINGS_CAPSSCAN_VOICE) && NEONSPAM_CHANMSG_DO_EXCEPT(SPAMSETTINGS_CAPSEXCINDEX)) {
- result = neonspam_capsscan(settings, chanuser, message);
- switch(result) {
- case SPAMSERV_CHECK_IGNORE:
- break;
- case SPAMSERV_CHECK_WARN:
- warn |= SPAMSETTINGS_CAPSSCAN;
- if(NEONSPAM_CHANMSG_NEED_WHO(SPAMSETTINGS_CAPSEXCINDEX))
- needwho = 1;
- break;
- case SPAMSERV_CHECK_PUNISH:
- punish |= SPAMSETTINGS_CAPSSCAN;
- if(NEONSPAM_CHANMSG_NEED_WHO(SPAMSETTINGS_CAPSEXCINDEX))
- needwho = 1;
- break;
- }
- }
- if((settings->flags & SPAMSETTINGS_DIGITSCAN) && NEONSPAM_CHANMSG_DO_SCANOPS(SPAMSETTINGS_DIGITSCAN_OPS) && NEONSPAM_CHANMSG_DO_SCANVOICE(SPAMSETTINGS_DIGITSCAN_VOICE) && NEONSPAM_CHANMSG_DO_EXCEPT(SPAMSETTINGS_DIGITEXCINDEX)) {
- result = neonspam_digitscan(settings, chanuser, message);
- switch(result) {
- case SPAMSERV_CHECK_IGNORE:
- break;
- case SPAMSERV_CHECK_WARN:
- warn |= SPAMSETTINGS_DIGITSCAN;
- if(NEONSPAM_CHANMSG_NEED_WHO(SPAMSETTINGS_DIGITEXCINDEX))
- needwho = 1;
- break;
- case SPAMSERV_CHECK_PUNISH:
- punish |= SPAMSETTINGS_DIGITSCAN;
- if(NEONSPAM_CHANMSG_NEED_WHO(SPAMSETTINGS_DIGITEXCINDEX))
- needwho = 1;
- break;
- }
- }
- //some other checks?
-
- if(warn || punish) {
- //whois the user to check against exceptlevel
- if(!needwho || (user->flags & USERFLAG_ISAUTHED)) {
- neonspam_event_chanmsg_punish(client, chanuser, settings, warn, punish);
- } else {
- struct neonspam_event_chanmsg_cache *cache = malloc(sizeof(*cache));
- if (!cache) {
- perror("malloc() failed");
- return;
- }
- cache->client = client;
- cache->chanuser = chanuser;
- cache->settings = settings;
- cache->warn = warn;
- cache->punish = punish;
- get_userauth(user, neonspam_event_chanmsg_nick_lookup, cache);
- }
-
- }
- #undef NEONSPAM_CHANMSG_DO_SCANOPS
- #undef NEONSPAM_CHANMSG_DO_SCANVOICE
- #undef NEONSPAM_CHANMSG_DO_EXCEPT
- #undef NEONSPAM_CHANMSG_NEED_WHO
-}
-
-static USERAUTH_CALLBACK(neonspam_event_chanmsg_nick_lookup) {
- struct neonspam_event_chanmsg_cache *cache = data;
- neonspam_event_chanmsg_punish(cache->client, cache->chanuser, cache->settings, cache->warn, cache->punish);
- free(cache);
-}
-
-static void neonspam_event_chanmsg_punish(struct ClientSocket *client, struct ChanUser *chanuser, struct NeonSpamSettings *settings, unsigned int warn, unsigned int punish) {
- MYSQL_RES *res;
- MYSQL_ROW row, defaults;
- loadChannelSettings(chanuser->chan);
- int uaccess = 0;
- if(chanuser->user->flags & USERFLAG_ISAUTHED)
- uaccess = getChannelAccess(chanuser->user, chanuser->chan);
- char reason[MAXLEN];
- reason[0] = '\0';
- int punishment = 0;
- int punish_time = 0;
- if(!punishment && (punish & SPAMSETTINGS_SPAMSCAN) && settings->exceptlevel[SPAMSETTINGS_SPAMEXCINDEX] > uaccess) {
- printf_mysql_query("SELECT `channel_spam_reaction`, `channel_spam_reaction_duration` FROM `channels` WHERE `channel_id` = '%d'", chanuser->chan->channel_id);
- res = mysql_use();
- row = mysql_fetch_row(res);
- if(!row[0] || !row[1]) {
- printf_mysql_query("SELECT `channel_spam_reaction`, `channel_spam_reaction_duration` FROM `channels` WHERE `channel_name` = 'defaults'");
- res = mysql_use();
- defaults = mysql_fetch_row(res);
- }
- sprintf(reason, SPAMSERV_MSG_WARNING, SPAMSERV_MSG_SPAM);
- punishment = atoi((row[0] ? row[0] : defaults[0])) + 1;
- punish_time = atoi((row[1] ? row[1] : defaults[1]));
- }
- if(!punishment && (punish & SPAMSETTINGS_FLOODSCAN) && settings->exceptlevel[SPAMSETTINGS_FLOODEXCINDEX] > uaccess) {
- printf_mysql_query("SELECT `channel_flood_reaction`, `channel_flood_reaction_duration` FROM `channels` WHERE `channel_id` = '%d'", chanuser->chan->channel_id);
- res = mysql_use();
- row = mysql_fetch_row(res);
- if(!row[0] || !row[1]) {
- printf_mysql_query("SELECT `channel_flood_reaction`, `channel_flood_reaction_duration` FROM `channels` WHERE `channel_name` = 'defaults'");
- res = mysql_use();
- defaults = mysql_fetch_row(res);
- }
- sprintf(reason, SPAMSERV_MSG_WARNING, SPAMSERV_MSG_FLOOD);
- punishment = atoi((row[0] ? row[0] : defaults[0])) + 1;
- punish_time = atoi((row[1] ? row[1] : defaults[1]));
- }
- if(!punishment && (punish & SPAMSETTINGS_CAPSSCAN) && settings->exceptlevel[SPAMSETTINGS_CAPSEXCINDEX] > uaccess) {
- printf_mysql_query("SELECT `channel_caps_reaction`, `channel_caps_reaction_duration` FROM `channels` WHERE `channel_id` = '%d'", chanuser->chan->channel_id);
- res = mysql_use();
- row = mysql_fetch_row(res);
- if(!row[0] || !row[1]) {
- printf_mysql_query("SELECT `channel_caps_reaction`, `channel_caps_reaction_duration` FROM `channels` WHERE `channel_name` = 'defaults'");
- res = mysql_use();
- defaults = mysql_fetch_row(res);
- }
- sprintf(reason, SPAMSERV_MSG_WARNING, SPAMSERV_MSG_CAPS);
- punishment = atoi((row[0] ? row[0] : defaults[0])) + 1;
- punish_time = atoi((row[1] ? row[1] : defaults[1]));
- }
- if(!punishment && (punish & SPAMSETTINGS_DIGITSCAN) && settings->exceptlevel[SPAMSETTINGS_DIGITEXCINDEX] > uaccess) {
- printf_mysql_query("SELECT `channel_digit_reaction`, `channel_digit_reaction_duration` FROM `channels` WHERE `channel_id` = '%d'", chanuser->chan->channel_id);
- res = mysql_use();
- row = mysql_fetch_row(res);
- if(!row[0] || !row[1]) {
- printf_mysql_query("SELECT `channel_digit_reaction`, `channel_digit_reaction_duration` FROM `channels` WHERE `channel_name` = 'defaults'");
- res = mysql_use();
- defaults = mysql_fetch_row(res);
- }
- sprintf(reason, SPAMSERV_MSG_WARNING, SPAMSERV_MSG_DIGIT);
- punishment = atoi((row[0] ? row[0] : defaults[0])) + 1;
- punish_time = atoi((row[1] ? row[1] : defaults[1]));
- }
- if(!punishment && (warn & SPAMSETTINGS_SPAMSCAN) && settings->exceptlevel[SPAMSETTINGS_SPAMEXCINDEX] > uaccess) {
- sprintf(reason, SPAMSERV_MSG_WARNING, SPAMSERV_MSG_SPAM);
- }
- if(!punishment && (warn & SPAMSETTINGS_FLOODSCAN) && settings->exceptlevel[SPAMSETTINGS_FLOODEXCINDEX] > uaccess) {
- sprintf(reason, SPAMSERV_MSG_WARNING, SPAMSERV_MSG_FLOOD);
- }
- if(!punishment && (warn & SPAMSETTINGS_CAPSSCAN) && settings->exceptlevel[SPAMSETTINGS_CAPSEXCINDEX] > uaccess) {
- sprintf(reason, SPAMSERV_MSG_WARNING, SPAMSERV_MSG_CAPS);
- }
- if(!punishment && (warn & SPAMSETTINGS_DIGITSCAN) && settings->exceptlevel[SPAMSETTINGS_DIGITEXCINDEX] > uaccess) {
- sprintf(reason, SPAMSERV_MSG_WARNING, SPAMSERV_MSG_DIGIT);
- }
- if(punishment) {
- char banmaskBuf[NICKLEN+USERLEN+HOSTLEN+3];
- char *banmask = NULL;
- switch (punishment) {
- case 3: //TIMEBAN
- banmask = generate_banmask(chanuser->user, banmaskBuf);
- printf_mysql_query("INSERT INTO `bans` (`ban_channel`, `ban_mask`, `ban_triggered`, `ban_timeout`, `ban_owner`, `ban_reason`) VALUES ('%d', '%s', UNIX_TIMESTAMP(), '%lu', '%d', '%s')", chanuser->chan->channel_id, escape_string(banmask), (unsigned long) (punish_time ? (time(0) + punish_time) : 0), 0, escape_string(reason));
- if(punish_time) {
- int banid = (int) mysql_insert_id(get_mysql_conn());
- char nameBuf[MAXLEN];
- char banidBuf[20];
- sprintf(nameBuf, "ban_%d", banid);
- sprintf(banidBuf, "%d", banid);
- timeq_add_name(nameBuf, punish_time, channel_ban_timeout, strdup(banidBuf));
- }
- case 2: //KICKBAN
- if(!banmask)
- banmask = generate_banmask(chanuser->user, banmaskBuf);
- putsock(client, "MODE %s +b %s", chanuser->chan->name, banmask);
- case 1: //KICK
- putsock(client, "KICK %s %s :%s", chanuser->chan->name, chanuser->user->nick, reason);
- break;
- }
- } else if(*reason)
- reply(client, chanuser->user, "%s", reason);
-}
-
-static int neonspam_spamscan(struct NeonSpamSettings *settings, struct ChanUser *chanuser, char *message) {
- //crc32 hash of the message
- unsigned long msghash = crc32(message);
- if(chanuser->spamnode) {
- if(chanuser->spamnode->lastmsg == msghash) {
- chanuser->spamnode->spamcount++;
- if(chanuser->spamnode->spamcount == settings->spam_amount)
- return SPAMSERV_CHECK_WARN;
- else if(chanuser->spamnode->spamcount > settings->spam_amount)
- return SPAMSERV_CHECK_PUNISH;
- else
- return SPAMSERV_CHECK_IGNORE;
- }
- } else
- createSpamNode(chanuser);
- chanuser->spamnode->lastmsg = msghash;
- chanuser->spamnode->spamcount = 1;
- return SPAMSERV_CHECK_IGNORE;
-}
-
-static int neonspam_update_penalty(struct NeonSpamSettings *settings, struct ChanUser *chanuser, int addmsg) {
- int last_update = time(0) - chanuser->spamnode->last_penalty_update;
- if(last_update) {
- if(last_update < MAX_FLOOD_TIME && chanuser->spamnode->floodpenalty) {
- chanuser->spamnode->floodpenalty -= last_update * (MAX_FLOOD_TIME / settings->sensibility_time[SPAMSETTINGS_FLOODSENINDEX]);
- if(chanuser->spamnode->floodpenalty < 0)
- chanuser->spamnode->floodpenalty = 0;
- } else
- chanuser->spamnode->floodpenalty = 0;
- chanuser->spamnode->last_penalty_update = time(0);
- }
- chanuser->spamnode->floodpenalty += MAX_FLOOD_TIME * addmsg;
- return chanuser->spamnode->floodpenalty / MAX_FLOOD_TIME + ((chanuser->spamnode->floodpenalty % MAX_FLOOD_TIME) ? 1 : 0);
-}
-
-static int neonspam_floodscan(struct NeonSpamSettings *settings, struct ChanUser *chanuser) {
- if(!chanuser->spamnode)
- createSpamNode(chanuser);
- int messages_pending = neonspam_update_penalty(settings, chanuser, 1);
- if(messages_pending == settings->sensibility_amount[SPAMSETTINGS_FLOODSENINDEX])
- return SPAMSERV_CHECK_WARN;
- else if(messages_pending > settings->sensibility_amount[SPAMSETTINGS_FLOODSENINDEX])
- return SPAMSERV_CHECK_PUNISH;
- else
- return SPAMSERV_CHECK_IGNORE;
-}
-
-static int neonspam_botnetscan(struct ClientSocket *client, struct NeonSpamSettings *settings, struct ChanUser *chanuser, char *message) {
- //crc32 hash of the message
- unsigned long msghash = crc32(message);
- if((time(0) - settings->lastmsg_time) > BOTNETSCAN_TIME || settings->lastmsg != msghash) {
- int i;
- for(i = 0; i < BOTNETSCAN_USERS; i++) {
- if(settings->botnicks[i]) {
- free(settings->botnicks[i]);
- settings->botnicks[i] = NULL;
- }
- }
- settings->flags &= ~SPAMSETTINGS_KICKEDBOTQUEUE;
- settings->lastmsg = msghash;
- } else if(settings->lastmsg == msghash) {
- int i;
- for(i = 0; i < BOTNETSCAN_USERS; i++) {
- if(!settings->botnicks[i]) {
- settings->botnicks[i] = strdup(chanuser->user->nick);
- break;
- } else if(!stricmp(chanuser->user->nick, settings->botnicks[i])) {
- return SPAMSERV_CHECK_IGNORE;
- }
- }
- if(i == BOTNETSCAN_USERS) {
- //BOTNETSCAN_USERS exceeded
- if(!(settings->flags & SPAMSETTINGS_KICKEDBOTQUEUE)) {
- for(i = 0; i < BOTNETSCAN_USERS; i++) {
- putsock(client, "KICK %s %s :%s", chanuser->chan->name, settings->botnicks[i], SPAMSERV_MSG_BOTNET);
- }
- settings->flags |= SPAMSETTINGS_KICKEDBOTQUEUE;
- }
- putsock(client, "KICK %s %s :%s", chanuser->chan->name, chanuser->user->nick, SPAMSERV_MSG_BOTNET);
- return SPAMSERV_CHECK_DEAD;
- }
- }
- settings->lastmsg_time = time(0);
- return SPAMSERV_CHECK_IGNORE;
-}
-
-static int neonspam_capsscan(struct NeonSpamSettings *settings, struct ChanUser *chanuser, char *message) {
- int caps = 0, msglen = strlen(message);
- int i;
- if(msglen <= 4) return SPAMSERV_CHECK_IGNORE;
- for(i = 0; i < msglen; i++) {
- if(isupper(message[i])) caps++;
- }
- caps = 100*caps/msglen;
- if(caps >= settings->percent[SPAMSETTINGS_CAPSPERCENTINDEX]) {
- if(!chanuser->spamnode)
- createSpamNode(chanuser);
- if(chanuser->spamnode->flags & NEONSPAMNODE_FLAG_CAPSSCAN_WARNED)
- return SPAMSERV_CHECK_PUNISH;
- else {
- chanuser->spamnode->flags |= NEONSPAMNODE_FLAG_CAPSSCAN_WARNED;
- return SPAMSERV_CHECK_WARN;
- }
- }
- return SPAMSERV_CHECK_IGNORE;
-}
-
-static int neonspam_digitscan(struct NeonSpamSettings *settings, struct ChanUser *chanuser, char *message) {
- int digit = 0, msglen = strlen(message);
- int i;
- if(msglen <= 4) return SPAMSERV_CHECK_IGNORE;
- for(i = 0; i < msglen; i++) {
- if(isdigit(message[i])) digit++;
- }
- digit = 100*digit/msglen;
- if(digit >= settings->percent[SPAMSETTINGS_DIGITPERCENTINDEX]) {
- if(!chanuser->spamnode)
- createSpamNode(chanuser);
- if(chanuser->spamnode->flags & NEONSPAMNODE_FLAG_DIGITSCAN_WARNED)
- return SPAMSERV_CHECK_PUNISH;
- else {
- chanuser->spamnode->flags |= NEONSPAMNODE_FLAG_DIGITSCAN_WARNED;
- return SPAMSERV_CHECK_WARN;
- }
- }
- return SPAMSERV_CHECK_IGNORE;
-}
-
+++ /dev/null
-/* event_neonspam_join.c - NeonServ v5.3
- * Copyright (C) 2011-2012 Philipp Kreil (pk910)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-static USERAUTH_CALLBACK(neonspam_event_join_nick_lookup);
-static void neonspam_event_join_punish(struct ClientSocket *client, struct ChanUser *chanuser, struct NeonSpamSettings *settings, int action);
-static int neonspam_joinfloodscan(struct NeonSpamSettings *settings, struct ChanUser *chanuser);
-
-struct neonspam_event_join_cache {
- struct ClientSocket *client;
- struct ChanUser *chanuser;
- struct NeonSpamSettings *settings;
- int action;
-};
-
-static void neonspam_event_join(struct ChanUser *chanuser) {
- if(chanuser->user->flags & USERFLAG_WAS_REGISTRING) return;
- struct ClientSocket *client = getChannelBot(chanuser->chan, BOTID);
- if(!client) return; //we can't "see" this event
- if(chanuser->user == client->user) {
- requestOp(client->user, chanuser->chan);
- return;
- }
- if(chanuser->user->flags & USERFLAG_ISBOT) return;
- loadNeonSpamSettings(chanuser->chan);
- struct NeonSpamSettings *settings = chanuser->chan->spam_settings;
- if(!settings || !(settings->flags & SPAMSETTINGS_JOINSCAN)) return;
- if(settings->exceptlevel[SPAMSETTINGS_JOINEXCINDEX] == 0) return;
- int result = neonspam_joinfloodscan(settings, chanuser);
- if(result != SPAMSERV_CHECK_IGNORE) {
- //whois the user to check against exceptlevel
- if((chanuser->user->flags & USERFLAG_ISAUTHED) || settings->exceptlevel[SPAMSETTINGS_JOINEXCINDEX] == 501) {
- neonspam_event_join_punish(client, chanuser, settings, result);
- } else {
- struct neonspam_event_join_cache *cache = malloc(sizeof(*cache));
- if (!cache) {
- perror("malloc() failed");
- return;
- }
- cache->client = client;
- cache->chanuser = chanuser;
- cache->settings = settings;
- cache->action = result;
- get_userauth(chanuser->user, neonspam_event_join_nick_lookup, cache);
- }
- }
-}
-
-static USERAUTH_CALLBACK(neonspam_event_join_nick_lookup) {
- struct neonspam_event_join_cache *cache = data;
- neonspam_event_join_punish(cache->client, cache->chanuser, cache->settings, cache->action);
- free(cache);
-}
-
-static void neonspam_event_join_punish(struct ClientSocket *client, struct ChanUser *chanuser, struct NeonSpamSettings *settings, int action) {
- int uaccess = 0;
- if(chanuser->user->flags & USERFLAG_ISAUTHED)
- uaccess = getChannelAccess(chanuser->user, chanuser->chan);
- if(uaccess >= settings->exceptlevel[SPAMSETTINGS_JOINEXCINDEX]) return;
- //scanops / scanvoiced
- MYSQL_RES *res;
- MYSQL_ROW row, defaults = NULL;
- loadChannelSettings(chanuser->chan);
- printf_mysql_query("SELECT `channel_flood_reaction`, `channel_flood_reaction_duration`, `channel_getop`, `channel_getvoice` FROM `channels` WHERE `channel_id` = '%d'", chanuser->chan->channel_id);
- res = mysql_use();
- row = mysql_fetch_row(res);
- if(!row[0] || !row[1] || !row[2] || !row[3]) {
- printf_mysql_query("SELECT `channel_flood_reaction`, `channel_flood_reaction_duration`, `channel_getop`, `channel_getvoice` FROM `channels` WHERE `channel_name` = 'defaults'");
- res = mysql_use();
- defaults = mysql_fetch_row(res);
- }
- if(!(settings->flags & SPAMSETTINGS_JOINSCAN_OPS) && uaccess >= atoi((row[2] ? row[2] : defaults[2]))) return;
- if(!(settings->flags & SPAMSETTINGS_JOINSCAN_VOICE) && uaccess >= atoi((row[3] ? row[3] : defaults[3]))) return;
- char reason[MAXLEN];
- sprintf(reason, SPAMSERV_MSG_WARNING, SPAMSERV_MSG_JOINFLOOD);
- if(action == SPAMSERV_CHECK_WARN) {
- reply(client, chanuser->user, "%s", reason);
- } else if(action == SPAMSERV_CHECK_PUNISH) {
- int duration = atoi((row[1] ? row[1] : defaults[1]));
- char banmaskBuf[NICKLEN+USERLEN+HOSTLEN+3];
- char *banmask = NULL;
- switch (atoi((row[0] ? row[0] : defaults[0]))) {
- case 2: //TIMEBAN
- banmask = generate_banmask(chanuser->user, banmaskBuf);
- printf_mysql_query("INSERT INTO `bans` (`ban_channel`, `ban_mask`, `ban_triggered`, `ban_timeout`, `ban_owner`, `ban_reason`) VALUES ('%d', '%s', UNIX_TIMESTAMP(), '%lu', '%d', '%s')", chanuser->chan->channel_id, escape_string(banmask), (unsigned long) (duration ? (time(0) + duration) : 0), 0, escape_string(reason));
- if(duration) {
- int banid = (int) mysql_insert_id(get_mysql_conn());
- char nameBuf[MAXLEN];
- char banidBuf[20];
- sprintf(nameBuf, "ban_%d", banid);
- sprintf(banidBuf, "%d", banid);
- timeq_add_name(nameBuf, duration, channel_ban_timeout, strdup(banidBuf));
- }
- case 1: //KICKBAN
- if(!banmask)
- banmask = generate_banmask(chanuser->user, banmaskBuf);
- putsock(client, "MODE %s +b %s", chanuser->chan->name, banmask);
- case 0: //KICK
- putsock(client, "KICK %s %s :%s", chanuser->chan->name, chanuser->user->nick, reason);
- break;
- }
- }
-}
-
-static int neonspam_update_join_penalty(struct NeonSpamSettings *settings, struct NeonSpamJoinNode *joinnode, int addjoin) {
- int last_update = time(0) - joinnode->last_penalty_update;
- if(last_update) {
- if(last_update < MAX_JOIN_TIME && joinnode->joinpenalty) {
- joinnode->joinpenalty -= last_update * (MAX_JOIN_TIME / settings->sensibility_time[SPAMSETTINGS_JOINSENINDEX]);
- if(joinnode->joinpenalty < 0)
- joinnode->joinpenalty = 0;
- } else
- joinnode->joinpenalty = 0;
- joinnode->last_penalty_update = time(0);
- }
- joinnode->joinpenalty += MAX_JOIN_TIME * addjoin;
- return joinnode->joinpenalty / MAX_JOIN_TIME + ((joinnode->joinpenalty % MAX_JOIN_TIME) ? 1 : 0);
-}
-
-static int neonspam_joinfloodscan(struct NeonSpamSettings *settings, struct ChanUser *chanuser) {
- if(!chanuser->spamnode)
- createSpamNode(chanuser);
- int joins_pending = neonspam_update_join_penalty(settings, getNeonSpamJoinNode(chanuser), 1);
- if(joins_pending == settings->sensibility_amount[SPAMSETTINGS_JOINSENINDEX])
- return SPAMSERV_CHECK_WARN;
- else if(joins_pending > settings->sensibility_amount[SPAMSETTINGS_JOINSENINDEX])
- return SPAMSERV_CHECK_PUNISH;
- else
- return SPAMSERV_CHECK_IGNORE;
-}
-
-
void register_language_string(struct language *lang, char *ident, char *text) {
int cindex = get_entry_index(ident);
- struct language_table *lang_entry = malloc(sizeof(*lang_entry));
- if (!lang_entry) {
- perror("malloc() failed");
- return;
+ struct language_table *lang_entry;
+ for(lang_entry = lang->entrys[cindex]; lang_entry; lang_entry = lang_entry->next) {
+ if(!strcmp(lang_entry->ident, ident)) break;
+ }
+ if(!lang_entry) {
+ lang_entry = malloc(sizeof(*lang_entry));
+ if (!lang_entry) {
+ perror("malloc() failed");
+ return;
+ }
+ lang_entry->ident = strdup(ident);
}
-
- lang_entry->ident = strdup(ident);
//replace all:
//$b to \002
//$k to \003
struct language_table **entrys;
};
+#ifndef DND_FUNCTIONS
void init_lang();
void free_lang();
-struct language* get_language_by_tag(char *tag);
-struct language* get_language_by_name(char *name);
-struct language* get_default_language();
+/* MODULAR ACCESSIBLE */ struct language* get_language_by_tag(char *tag);
+/* MODULAR ACCESSIBLE */ struct language* get_language_by_name(char *name);
+/* MODULAR ACCESSIBLE */ struct language* get_default_language();
void load_languages();
-void load_language(char *tag, char *name);
+/* MODULAR ACCESSIBLE */ void load_language(char *tag, char *name);
void register_language_string(struct language *lang, char *ident, char *text);
-void register_default_language_table(const struct default_language_entry *msgtab);
-char *get_language_string(struct UserNode *user, const char* msg_ident);
-char *build_language_string(struct UserNode *user, char *buffer, const char *msg_ident, ...);
-
-#endif
\ No newline at end of file
+/* MODULAR ACCESSIBLE */ void register_default_language_table(const struct default_language_entry *msgtab);
+/* MODULAR ACCESSIBLE */ char *get_language_string(struct UserNode *user, const char* msg_ident);
+/* MODULAR ACCESSIBLE */ char *build_language_string(struct UserNode *user, char *buffer, const char *msg_ident, ...);
+#endif
+#endif
static void check_firstrun();
void cleanup() {
+ stop_modules();
free_sockets();
qserver_free();
free_parser();
free_bind();
free_modcmd();
free_whoqueue();
- free_bots();
free_mysql();
free_handleinfohandler();
free_lang();
init_modcmd();
init_handleinfohandler();
init_tools();
- register_commands();
+
init_bots();
init_DBHelper();
qserver_init();
load_languages();
int update_minutes = get_int_field("statistics.frequency");
if(!update_minutes) update_minutes = 2;
- timeq_add(update_minutes * 60 + 10, main_statistics, NULL);
+ timeq_add(update_minutes * 60 + 10, 0, main_statistics, NULL);
- timeq_add(90, main_checkauths, NULL);
+ timeq_add(90, 0, main_checkauths, NULL);
int worker_threads = get_int_field("General.worker_threads");
if(!worker_threads) worker_threads = 1;
int usleep_delay = 1000000 / TICKS_PER_SECOND;
while(running) {
timeq_tick();
- loop_bots();
+ loop_modules();
qserver_loop();
queue_loop();
mysql_free();
}
} while(time(0) < socket_wait);
timeq_tick();
- loop_bots();
+ loop_modules();
clearTempUsers();
destroyEvents();
qserver_loop();
}
}
- timeq_add(next_call, main_checkauths, NULL);
+ timeq_add(next_call, 0, main_checkauths, NULL);
}
TIMEQ_CALLBACK(main_statistics) {
int update_minutes = get_int_field("statistics.frequency");
if(!update_minutes) update_minutes = 2;
- timeq_add(update_minutes * 60, main_statistics, NULL);
+ timeq_add(update_minutes * 60, 0, main_statistics, NULL);
if(get_int_field("statistics.enable")) {
statistics_enabled = 1;
statistics_requested_lusers = 1;
}
}
+time_t getStartTime() {
+ return start_time;
+}
+
+int getRunningThreads() {
+ return running_threads;
+}
+
void write_log(int loglevel, const char *line, int len) {
SYNCHRONIZE(log_sync);
if(!daemonized && (print_loglevel & loglevel)) {
*/
#ifndef _main_h
#define _main_h
-#include "../config.h"
-
-#define NEONSERV_VERSION "5.3"
-#define VERSION_PATCHLEVEL 543
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#ifdef WIN32
-#include <windows.h>
-#include <winsock2.h>
-#include <malloc.h>
-#else
-#include <features.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <sys/wait.h>
-#endif
-#include <unistd.h>
-#include <getopt.h>
-#include <stdarg.h>
-#include <sys/time.h>
-#include <time.h>
-#ifdef HAVE_THREADS
-#include <pthread.h>
-#ifdef WIN32
-#define pthread_self_tid() pthread_self().p
-#else
-#define pthread_self_tid() pthread_self()
-#endif
-#define THREAD_MUTEX_INIT(var) { \
- pthread_mutexattr_t mutex_attr; \
- pthread_mutexattr_init(&mutex_attr);\
- pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_RECURSIVE_NP);\
- pthread_mutex_init(&var, &mutex_attr); \
-}
-#define THREAD_MUTEX_INIT_TYPE(var, type) { \
- pthread_mutexattr_t mutex_attr; \
- pthread_mutexattr_init(&mutex_attr);\
- pthread_mutexattr_settype(&mutex_attr, type);\
- pthread_mutex_init(&var, &mutex_attr); \
-}
-#define SYNCHRONIZE(var) pthread_mutex_lock(&var)
-#define SET_SYNCHRONIZE(var) pthread_mutex_trylock(&var)
-#define DESYNCHRONIZE(var) pthread_mutex_unlock(&var)
-#else
-#define THREAD_MUTEX_INIT(var)
-#define SYNCHRONIZE(var)
-#define DESYNCHRONIZE(var)
-#endif
-
-#if __GNUC__
-#define PRINTF_LIKE(M,N) __attribute__((format (printf, M, N)))
-#else
-#define PRINTF_LIKE(M,N)
-#endif
-
-#if __GNUC__ >= 2
-#define UNUSED_ARG(ARG) ARG __attribute__((unused))
-#elif defined(S_SPLINT_S)
-#define UNUSED_ARG(ARG) /*@unused@*/ ARG
-#define const /*@observer@*/ /*@temp@*/
-#else
-#define UNUSED_ARG(ARG) ARG
-#endif
-
-#define STRINGIFY_(x) #x
-#define STRINGIFY(x) STRINGIFY_(x)
-
-#if defined(__GNUC__)
-#if defined(__GNUC_PATCHLEVEL__)
-#define COMPILER "GCC" " " STRINGIFY(__GNUC__) "." STRINGIFY(__GNUC_MINOR__) "." STRINGIFY(__GNUC_PATCHLEVEL__)
-#else
-#define COMPILER "GCC" " " STRINGIFY(__GNUC__) "." STRINGIFY(__GNUC_MINOR__)
-#endif
-#elif defined (__IMAGECRAFT__)
-#define COMPILER "ICCAVR"
-#else
-#define COMPILER "Unknown"
-#endif
-
-#ifdef ENABLE_MEMORY_DEBUG
-#include "memoryDebug.h"
-#endif
-
-#define PID_FILE "neonserv.pid"
-#define CONF_FILE "neonserv.conf"
-#define LOG_FILE "neonserv.log"
-
-#define SOCKET_SELECT_TIME 1
-#define SOCKET_RECONNECT_TIME 20
-
-#define NICKLEN 30
-#define USERLEN 10
-#define AUTHLEN 32
-#define HOSTLEN 63
-#define REALLEN 50
-#define TOPICLEN 500
-#define CHANNELLEN 200
-#define MAXLEN 512
-#define MAXLOGLEN 1024
-#define TRIGGERLEN 50
-#define MAXNUMPARAMS 200 /* maximum number of parameters in one line */
-#define MAXLANGUAGES 5
-#define MAXMODES 6
-#define INVITE_TIMEOUT 30
-#define BOTWAR_DETECTION_TIME 7
-#define BOTWAR_DETECTION_EVENTS 6
-#define REWHO_TIMEOUT 10 /* wait 10 seconds before WHO an unauthed user again */
-#define TICKS_PER_SECOND 10
-
-//valid nick chars
-#define VALID_NICK_CHARS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890{|}~[\\]^-_`"
-//the first char is a little bit different
-// 0 1 2 3 4 5 6
-// 1234567890123456789012345678901234567890123456789012345678 9012 62
-#define VALID_NICK_CHARS_FIRST "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~[\\]^_`"
-#define VALID_NICK_CHARS_FIRST_LEN 62
-
-#define TEMPUSER_LIST_INDEX VALID_NICK_CHARS_FIRST_LEN
-
-#define LOGLEVEL_INFO 0x01
-#define LOGLEVEL_ERROR 0x02
-#define LOGLEVEL_RAW 0x04
-#define LOGLEVEL_MYSQL 0x08
-
-#define timeval_is_bigger(x,y) ((x.tv_sec > y.tv_sec) || (x.tv_sec == y.tv_sec && x.tv_usec > y.tv_usec))
+#include "overall.h"
+#ifndef DND_FUNCTIONS
extern time_t start_time;
extern int statistics_enabled;
#ifdef HAVE_THREADS
extern pthread_mutex_t cache_sync;
extern pthread_mutex_t whohandler_sync, whohandler_mass_sync;
-int getCurrentThreadID();
+/* MODULAR ACCESSIBLE */ int getCurrentThreadID();
#endif
+/* MODULAR ACCESSIBLE */ time_t getStartTime();
+/* MODULAR ACCESSIBLE */ int getRunningThreads();
+
void exit_daemon();
-int stricmp (const char *s1, const char *s2);
-int stricmplen (const char *s1, const char *s2, int len);
+/* MODULAR ACCESSIBLE */ int stricmp (const char *s1, const char *s2);
+/* MODULAR ACCESSIBLE */ int stricmplen (const char *s1, const char *s2, int len);
-void restart_process();
-void cleanup();
-void restart_bot(int do_hard_restart);
-void stop_bot();
-void reload_config();
+/* MODULAR ACCESSIBLE */ void restart_process();
+/* MODULAR ACCESSIBLE */ void cleanup();
+/* MODULAR ACCESSIBLE */ void restart_bot(int do_hard_restart);
+/* MODULAR ACCESSIBLE */ void stop_bot();
+/* MODULAR ACCESSIBLE */ void reload_config();
void statistics_update();
-void putlog(int loglevel, const char *text, ...) PRINTF_LIKE(2, 3);
-
-#define perror(errmsg) (putlog(LOGLEVEL_ERROR, "ERROR (%s:%d) %s", __FILE__, __LINE__, errmsg))
-
+/* MODULAR ACCESSIBLE */ void putlog(int loglevel, const char *text, ...) PRINTF_LIKE(2, 3);
+#endif
#endif
\ No newline at end of file
DESYNCHRONIZE(synchronized);
}
-void report_mem_leak() {
- SYNCHRONIZE(synchronized);
- struct MemoryLeak *leak_info;
- FILE *fp_write = fopen(OUTPUT_FILE, "wt");
- char info[1024];
-
- if(fp_write != NULL) {
- sprintf(info, "%s\n", "Memory Leak Summary");
- fwrite(info, (strlen(info)) , 1, fp_write);
- sprintf(info, "%s\n", "-----------------------------------");
- fwrite(info, (strlen(info)) , 1, fp_write);
-
- for(leak_info = ptr_start; leak_info != NULL; leak_info = leak_info->next) {
- sprintf(info, "address : %p\n", leak_info->mem_info.address);
- fwrite(info, (strlen(info)) , 1, fp_write);
- sprintf(info, "size : %d bytes\n", leak_info->mem_info.size);
- fwrite(info, (strlen(info)) , 1, fp_write);
- sprintf(info, "file : %s\n", leak_info->mem_info.file_name);
- fwrite(info, (strlen(info)) , 1, fp_write);
- sprintf(info, "line : %d\n", leak_info->mem_info.line);
- fwrite(info, (strlen(info)) , 1, fp_write);
- sprintf(info, "%s\n", "-----------------------------------");
- fwrite(info, (strlen(info)) , 1, fp_write);
- }
- }
- fclose(fp_write);
- DESYNCHRONIZE(synchronized);
-}
-
void initMemoryDebug() {
THREAD_MUTEX_INIT(synchronized);
}
#define strdup(data) xstrdup (data, __FILE__, __LINE__)
#define free(mem_ref) xfree(mem_ref)
-void *xmalloc(unsigned int size, const char *file, unsigned int line);
-void *xcalloc(unsigned int elements, unsigned int size, const char *file, unsigned int line);
-char *xstrdup(const char *data, const char *file, unsigned int line);
-void xfree(void *mem_ref);
+#ifndef DND_FUNCTIONS
+/* MODULAR ACCESSIBLE */ void *xmalloc(unsigned int size, const char *file, unsigned int line);
+/* MODULAR ACCESSIBLE */ void *xcalloc(unsigned int elements, unsigned int size, const char *file, unsigned int line);
+/* MODULAR ACCESSIBLE */ char *xstrdup(const char *data, const char *file, unsigned int line);
+/* MODULAR ACCESSIBLE */ void xfree(void *mem_ref);
-void report_mem_leak();
void initMemoryDebug();
-
+#endif
#endif
struct memoryInfoFiles *next;
};
-struct memoryInfoFiles *getMemoryInfoFiles();
-void freeMemoryInfoFiles(struct memoryInfoFiles *files);
-
+#ifndef DND_FUNCTIONS
+/* MODULAR ACCESSIBLE */ struct memoryInfoFiles *getMemoryInfoFiles();
+/* MODULAR ACCESSIBLE */ void freeMemoryInfoFiles(struct memoryInfoFiles *files);
+#endif
struct memoryInfoLines {
unsigned int line;
struct memoryInfoLines *next;
};
-struct memoryInfoLines *getMemoryInfoLines(const char *filename);
-void freeMemoryInfoLines(struct memoryInfoLines *lines);
-
+#ifndef DND_FUNCTIONS
+/* MODULAR ACCESSIBLE */ struct memoryInfoLines *getMemoryInfoLines(const char *filename);
+/* MODULAR ACCESSIBLE */ void freeMemoryInfoLines(struct memoryInfoLines *lines);
+#endif
#endif
struct trigger_callback {
int botid;
+ int module_id;
trigger_callback_t *func;
struct trigger_callback *next;
}
}
-int register_command(int botid, char *name, cmd_bind_t *func, int paramcount, char *channel_access, int global_access, unsigned int flags) {
+int register_command(int botid, char *name, int module_id, cmd_bind_t *func, int paramcount, char *channel_access, int global_access, unsigned int flags) {
struct cmd_function *cmdfunc;
for(cmdfunc = cmd_functions; cmdfunc; cmdfunc = cmdfunc->next) {
if((cmdfunc->botid == botid || cmdfunc->botid == 0) && strcmp(cmdfunc->name, name) == 0)
}
cmdfunc->botid = botid;
cmdfunc->name = strdup(name);
+ cmdfunc->module_id = module_id;
cmdfunc->func = func;
cmdfunc->flags = flags;
cmdfunc->paramcount = paramcount;
return 1;
}
-int set_trigger_callback(int botid, trigger_callback_t *func) {
+int set_trigger_callback(int botid, int module_id, trigger_callback_t *func) {
static struct trigger_callback *cb = NULL;
for(cb = trigger_callbacks; cb; cb = cb->next) {
if(cb->botid == botid)
cb->next = trigger_callbacks;
trigger_callbacks = cb;
}
+ cb->module_id = module_id;
cb->func = func;
return 1;
}
return 0;
}
-int unbind_botwise_allcmd(int clientid) {
+int unbind_botwise_allcmd(int botid, int clientid) {
int i;
for(i = 0; i < 27; i++) {
struct cmd_binding *cbind, *next, *last = NULL;
for(cbind = cmd_binds[i]; cbind; cbind = next) {
next = cbind->next;
- if(clientid == cbind->clientid) {
+ if((botid == 0 && clientid == cbind->clientid) || (botid && botid == cbind->botid)) {
if(last)
last->next = cbind->next;
else
} while(bind_index < 27);
return NULL;
}
+
+void unregister_module_commands(int module_id) {
+ struct cmd_function *cmdfunct, *nextfunct, *prevfunct = NULL;
+ int i;
+ for(cmdfunct = cmd_functions; cmdfunct; cmdfunct = nextfunct) {
+ nextfunct = cmdfunct->next;
+ if(cmdfunct->module_id == module_id) {
+ for(i = 0; i < 27; i++) {
+ struct cmd_binding *cbind, *next, *last = NULL;
+ for(cbind = cmd_binds[i]; cbind; cbind = next) {
+ next = cbind->next;
+ if(cmdfunct == cbind->func) {
+ if(last)
+ last->next = cbind->next;
+ else
+ cmd_binds[i] = cbind->next;
+ free(cbind->cmd);
+ if(cbind->paramcount) {
+ int j;
+ for(j = 0; j < cbind->paramcount; j++)
+ free(cbind->parameters[j]);
+ }
+ if(cbind->channel_access)
+ free(cbind->channel_access);
+ free(cbind);
+ } else
+ last = cbind;
+ }
+ }
+ if(prevfunct)
+ prevfunct->next = nextfunct;
+ else
+ cmd_functions = nextfunct;
+ free(cmdfunct->name);
+ free(cmdfunct);
+ } else
+ prevfunct = cmdfunct;
+ }
+ static struct trigger_callback *cb, *prevcb = NULL, *nextcb;
+ for(cb = trigger_callbacks; cb; cb = nextcb) {
+ nextcb = cb->next;
+ if(cb->module_id == module_id) {
+ if(prevcb)
+ prevcb->next = nextcb;
+ else
+ trigger_callbacks = nextcb;
+ free(cb);
+ } else
+ prevcb = cb;
+ }
+}
struct cmd_function {
char *name;
int botid;
+ int module_id;
cmd_bind_t *func;
unsigned int flags;
int paramcount;
struct trigger_cache *next;
};
-extern int statistics_commands;
-
-void init_modcmd();
-void free_modcmd();
-
#define get_prefered_bot(BOTID) get_botwise_prefered_bot(BOTID, 0)
-struct ClientSocket* get_botwise_prefered_bot(int botid, int clientid);
-
-int register_command(int botid, char *name, cmd_bind_t *func, int paramcount, char *channel_access, int global_access, unsigned int flags);
-int set_trigger_callback(int botid, trigger_callback_t *func);
-
-int flush_trigger_cache(int botid, int clientid);
-
#define changeChannelTrigger(BOTID,CHAN,NEW) changeBotwiseChannelTrigger(BOTID, 0, CHAN, NEW)
-int changeBotwiseChannelTrigger(int botid, int clientid, struct ChanNode *chan, char *new_trigger);
-
#define bind_cmd_to_function(BOTID,CMD,FUNC) bind_botwise_cmd_to_function(BOTID, 0, CMD, FUNC)
-int bind_botwise_cmd_to_function(int botid, int clientid, char *cmd, struct cmd_function *func);
-
#define bind_cmd_to_command(BOTID,CMD,FUNC) bind_botwise_cmd_to_command(BOTID, 0, CMD, FUNC)
-int bind_botwise_cmd_to_command(int botid, int clientid, char *cmd, char *func);
-
#define unbind_cmd(BOTID,CMD) unbind_botwise_cmd(BOTID, 0, CMD)
-int unbind_botwise_cmd(int botid, int clientid, char *cmd);
-
-int unbind_botwise_allcmd(int clientid);
-
+#define unbind_allcmd(BOTID) unbind_botwise_allcmd(BOTID, 0)
#define bind_set_parameters(BOTID,CMD,PARAMETERS) bind_botwise_set_parameters(BOTID, 0, CMD, PARAMETERS)
-void bind_botwise_set_parameters(int botid, int clientid, char *cmd, char *parameters);
-
#define bind_set_global_access(BOTID,CMD,GACCESS) bind_botwise_set_global_access(BOTID, 0, CMD, GACCESS)
-void bind_botwise_set_global_access(int botid, int clientid, char *cmd, int gaccess);
-
#define bind_set_channel_access(BOTID,CMD,CACCESS) bind_botwise_set_channel_access(BOTID, 0, CMD, CACCESS)
-void bind_botwise_set_channel_access(int botid, int clientid, char *cmd, char *chanaccess);
-
#define bind_set_bind_flags(BOTID,CMD,FLAGS) bind_botwise_set_bind_flags(BOTID, 0, CMD, FLAGS)
-void bind_botwise_set_bind_flags(int botid, int clientid, char *cmd, unsigned int flags);
-
#define find_cmd_binding(BOTID,CMD) find_botwise_cmd_binding(BOTID, 0, CMD)
-struct cmd_binding *find_botwise_cmd_binding(int botid, int clientid, char *cmd);
-
#define bind_unbound_required_functions(BOTID) bind_botwise_unbound_required_functions(BOTID, 0)
-void bind_botwise_unbound_required_functions(int botid, int clientid);
-struct cmd_function *find_cmd_function(int botid, char *name);
-struct ClientSocket *getTextBot();
-void register_command_alias(int botid, char *alias);
-struct cmd_binding *getAllBinds(struct cmd_binding *last);
-#endif
\ No newline at end of file
+#ifndef DND_FUNCTIONS
+extern int statistics_commands;
+
+void init_modcmd();
+void free_modcmd();
+
+/* MODULAR ACCESSIBLE */ struct ClientSocket* get_botwise_prefered_bot(int botid, int clientid);
+
+/* MODULAR ACCESSIBLE */ int register_command(int botid, char *name, int module_id, cmd_bind_t *func, int paramcount, char *channel_access, int global_access, unsigned int flags);
+/* MODULAR ACCESSIBLE */ int set_trigger_callback(int botid, int module_id, trigger_callback_t *func);
+
+/* MODULAR ACCESSIBLE */ int flush_trigger_cache(int botid, int clientid);
+/* MODULAR ACCESSIBLE */ int changeBotwiseChannelTrigger(int botid, int clientid, struct ChanNode *chan, char *new_trigger);
+/* MODULAR ACCESSIBLE */ int bind_botwise_cmd_to_function(int botid, int clientid, char *cmd, struct cmd_function *func);
+/* MODULAR ACCESSIBLE */ int bind_botwise_cmd_to_command(int botid, int clientid, char *cmd, char *func);
+/* MODULAR ACCESSIBLE */ int unbind_botwise_cmd(int botid, int clientid, char *cmd);
+/* MODULAR ACCESSIBLE */ int unbind_botwise_allcmd(int botid, int clientid);
+/* MODULAR ACCESSIBLE */ void bind_botwise_set_parameters(int botid, int clientid, char *cmd, char *parameters);
+/* MODULAR ACCESSIBLE */ void bind_botwise_set_global_access(int botid, int clientid, char *cmd, int gaccess);
+/* MODULAR ACCESSIBLE */ void bind_botwise_set_channel_access(int botid, int clientid, char *cmd, char *chanaccess);
+/* MODULAR ACCESSIBLE */ void bind_botwise_set_bind_flags(int botid, int clientid, char *cmd, unsigned int flags);
+/* MODULAR ACCESSIBLE */ struct cmd_binding *find_botwise_cmd_binding(int botid, int clientid, char *cmd);
+/* MODULAR ACCESSIBLE */ void bind_botwise_unbound_required_functions(int botid, int clientid);
+/* MODULAR ACCESSIBLE */ struct cmd_function *find_cmd_function(int botid, char *name);
+/* MODULAR ACCESSIBLE */ struct ClientSocket *getTextBot();
+/* MODULAR ACCESSIBLE */ void register_command_alias(int botid, char *alias);
+/* MODULAR ACCESSIBLE */ struct cmd_binding *getAllBinds(struct cmd_binding *last);
+
+void unregister_module_commands(int module_id);
+
+#endif
+#endif
--- /dev/null
+/* modules.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "modules.h"
+
+/* 000-011 */ #include "main.h"
+/* 012 */ #include "BanNode.h"
+/* 013-019 */ #include "bots.h"
+/* 020-025 */ #include "ChanNode.h"
+/* 026-029 */ #include "ChanUser.h"
+/* 030-036 */ #include "ClientSocket.h"
+/* 037-038 */ #include "ConfigParser.h"
+/* 039-048 */ #include "DBHelper.h"
+/* 049 */ #include "EventLogger.h"
+/* 050 */ #include "HandleInfoHandler.h"
+/* 051-088 */ #include "IRCEvents.h"
+/* 089-091 */ #include "IRCParser.h"
+/* 092-098 */ #include "lang.h"
+#ifdef ENABLE_MEMORY_DEBUG
+/* 099-102 */ #include "memoryDebug.h"
+#endif
+/* 103-106 */ #include "memoryInfo.h"
+/* 107-125 */ #include "modcmd.h"
+/* 126-136 */ #include "ModeNode.h"
+/* 137-142 */ #include "mysqlConn.h"
+/* 143-149 */ #include "timeq.h"
+/* 150-169 */ #include "tools.h"
+/* 170-178 */ #include "UserNode.h"
+/* 179 */ #include "version.h"
+/* 180-182 */ #include "WHOHandler.h"
+
+void **global_functions = {
+/* 000 */ getStartTime,
+/* 001 */ getRunningThreads,
+/* 002 */ exit_daemon,
+/* 003 */ stricmp,
+/* 004 */ stricmplen,
+/* 005 */ restart_process,
+/* 006 */ cleanup,
+/* 007 */ restart_bot,
+/* 008 */ stop_bot,
+/* 009 */ reload_config,
+/* 010 */ putlog,
+#ifdef HAVE_THREADS
+/* 011 */ getCurrentThreadID,
+#else
+/* 011 */ NULL,
+#endif
+/* 012 */ getMatchingChannelBan,
+/* 013 */ getChannelBot,
+/* 014 */ requestOp,
+/* 015 */ channel_ban_timeout,
+/* 016 */ general_event_privctcp,
+/* 017 */ set_bot_alias,
+/* 018 */ resolve_botid,
+/* 019 */ resolve_botalias,
+/* 020 */ is_valid_chan,
+/* 021 */ getAllChans,
+/* 022 */ getChanByName,
+/* 023 */ getChannelCount,
+/* 024 */ getChanUserCount,
+/* 025 */ getChanBanCount,
+/* 026 */ isUserOnChan,
+/* 027 */ getChanUser,
+/* 028 */ getChannelUsers,
+/* 029 */ getUserChannels,
+/* 030 */ create_socket,
+/* 031 */ connect_socket,
+/* 032 */ close_socket,
+/* 033 */ disconnect_socket,
+/* 034 */ write_socket,
+/* 035 */ putsock,
+/* 036 */ getBots,
+/* 037 */ get_int_field,
+/* 038 */ get_string_field,
+/* 039 */ _loadUserSettings,
+/* 040 */ isGodMode,
+/* 041 */ getChanDefault,
+/* 042 */ getChannelAccess,
+/* 043 */ checkChannelAccess,
+/* 044 */ _loadChannelSettings,
+/* 045 */ isUserProtected,
+/* 046 */ getBanAffectingMask,
+/* 047 */ renameAccount,
+/* 048 */ deleteUser,
+/* 049 */ logEvent,
+/* 050 */ lookup_authname,
+/* 051 */ bind_join,
+/* 052 */ unbind_join,
+/* 053 */ bind_nick,
+/* 054 */ unbind_nick,
+/* 055 */ bind_part,
+/* 056 */ unbind_part,
+/* 057 */ bind_quit,
+/* 058 */ unbind_quit,
+/* 059 */ bind_kick,
+/* 060 */ unbind_kick,
+/* 061 */ bind_topic,
+/* 062 */ unbind_topic,
+/* 063 */ bind_mode,
+/* 064 */ unbind_mode,
+/* 065 */ bind_chanmsg,
+/* 066 */ unbind_chanmsg,
+/* 067 */ bind_privmsg,
+/* 068 */ unbind_privmsg,
+/* 069 */ bind_channotice,
+/* 070 */ unbind_channotice,
+/* 071 */ bind_privnotice,
+/* 072 */ unbind_privnotice,
+/* 073 */ bind_chanctcp,
+/* 074 */ unbind_chanctcp,
+/* 075 */ bind_privctcp,
+/* 076 */ unbind_privctcp,
+/* 077 */ bind_invite,
+/* 078 */ unbind_invite,
+/* 079 */ bind_raw,
+/* 080 */ unbind_raw,
+/* 081 */ bind_bot_ready,
+/* 082 */ unbind_bot_ready,
+/* 083 */ bind_registered,
+/* 084 */ unbind_registered,
+/* 085 */ bind_freeuser,
+/* 086 */ unbind_freeuser,
+/* 087 */ bind_freechan,
+/* 088 */ unbind_freechan,
+/* 089 */ reply,
+/* 090 */ merge_argv,
+/* 091 */ merge_argv_char,
+/* 092 */ get_language_by_tag,
+/* 093 */ get_language_by_name,
+/* 094 */ get_default_language,
+/* 095 */ load_language,
+/* 096 */ register_default_language_table,
+/* 097 */ get_language_string,
+/* 098 */ build_language_string,
+#ifdef ENABLE_MEMORY_DEBUG
+/* 099 */ xmalloc,
+/* 100 */ xcalloc,
+/* 101 */ xstrdup,
+/* 102 */ xfree,
+#else
+/* 099 */ NULL,
+/* 100 */ NULL,
+/* 101 */ NULL,
+/* 102 */ NULL,
+#endif
+/* 103 */ getMemoryInfoFiles,
+/* 104 */ freeMemoryInfoFiles,
+/* 105 */ getMemoryInfoLines,
+/* 106 */ freeMemoryInfoLines,
+/* 107 */ get_botwise_prefered_bot,
+/* 108 */ register_command,
+/* 109 */ set_trigger_callback,
+/* 110 */ flush_trigger_cache,
+/* 111 */ changeBotwiseChannelTrigger,
+/* 112 */ bind_botwise_cmd_to_function,
+/* 113 */ bind_botwise_cmd_to_command,
+/* 114 */ unbind_botwise_cmd,
+/* 115 */ unbind_botwise_allcmd,
+/* 116 */ bind_botwise_set_parameters,
+/* 117 */ bind_botwise_set_global_access,
+/* 118 */ bind_botwise_set_channel_access,
+/* 119 */ bind_botwise_set_bind_flags,
+/* 120 */ find_botwise_cmd_binding,
+/* 121 */ bind_botwise_unbound_required_functions,
+/* 122 */ find_cmd_function,
+/* 123 */ getTextBot,
+/* 124 */ register_command_alias,
+/* 125 */ getAllBinds,
+/* 126 */ createModeNode,
+/* 127 */ freeModeNode,
+/* 128 */ isModeSet,
+/* 129 */ isModeAffected,
+/* 130 */ getModeValue,
+/* 131 */ getModeType,
+/* 132 */ parseModes,
+/* 133 */ parseModeString,
+/* 134 */ parseMode,
+/* 135 */ getModeString,
+/* 136 */ getFullModeString,
+/* 137 */ mysql_use,
+/* 138 */ mysql_free,
+/* 139 */ printf_mysql_query,
+/* 140 */ printf_long_mysql_query,
+/* 141 */ escape_string,
+/* 142 */ get_mysql_conn,
+/* 143 */ timeq_add,
+/* 144 */ timeq_uadd,
+/* 145 */ timeq_add_name,
+/* 146 */ timeq_uadd_name,
+/* 147 */ timeq_del,
+/* 148 */ timeq_del_name,
+/* 149 */ timeq_name_exists,
+/* 150 */ match,
+/* 151 */ table_init,
+/* 152 */ table_add,
+/* 153 */ table_change,
+/* 154 */ table_change_field,
+/* 155 */ table_set_bold,
+/* 156 */ table_end,
+/* 157 */ table_free,
+/* 158 */ timeToStr,
+/* 159 */ strToTime,
+/* 160 */ initModeBuffer,
+/* 161 */ modeBufferSet,
+/* 162 */ flushModeBuffer,
+/* 163 */ freeModeBuffer,
+/* 164 */ is_ircmask,
+/* 165 */ generate_banmask,
+/* 166 */ make_banmask,
+/* 167 */ isFakeHost,
+/* 168 */ mask_match,
+/* 169 */ crc32,
+/* 170 */ is_valid_nick,
+/* 171 */ getUserByNick,
+/* 172 */ getUserByMask,
+/* 173 */ countUsersWithHost,
+/* 174 */ getAuthFakehost,
+/* 175 */ searchUserByNick,
+/* 176 */ getAllUsers,
+/* 177 */ getUsersWithAuth,
+/* 178 */ getUserCount,
+/* 179 */ get_userlist,
+/* 180 */ _get_userlist_with_invisible,
+/* 181 */ get_userauth,
+/* 182 */ &compilation,
+/* 183 */ &creation,
+/* 184 */ &revision,
+/* 185 */ &codelines,
+/* 186 */ &patchlevel
+};
+
+#define MODINFO_STATE_STARTED 0x01
+
+struct ModuleInfo {
+ char *name;
+ int module_id;
+ #ifndef WIN32
+ void *module;
+ #else
+ HMODULE module;
+ #endif
+ int state;
+ void *startfunc;
+ void *loopfunc;
+ void *stopfunc;
+ struct ModuleInfo *next;
+}
+
+static int module_id_counter = 1;
+static struct ModuleInfo *modules = NULL;
+
+static void unregister_module_hooks(int module_id);
+
+int loadModule(char *name) {
+ char fname[256];
+ #ifndef WIN32
+ sprintf(fname, "%s.so", name);
+ void* module = dlopen(fname, RTLD_LAZY);
+ if(!module) {
+ putlog(LOGLEVEL_ERROR, "Error loading module '%s': %s not found.", name, fname);
+ return 0;
+ }
+ void* initfunc = dlsym(module, "init_module");
+ void* startfunc = dlsym(module, "start_module");
+ void* loopfunc = dlsym(module, "loop_module");
+ void* stopfunc = dlsym(module, "stop_module");
+ void* modversion = dlsym(module, "modversion");
+ #else
+ sprintf(fname, "%s.dll", name);
+ HMODULE module = LoadLibrary(fname);
+ if(!module) {
+ putlog(LOGLEVEL_ERROR, "Error loading module '%s': %s not found.", name, fname);
+ return 0;
+ }
+ FARPROC initfunc = GetProcAddress(module, "init_module");
+ FARPROC startfunc = GetProcAddress(module, "start_module");
+ FARPROC loopfunc = GetProcAddress(module, "loop_module");
+ FARPROC stopfunc = GetProcAddress(module, "stop_module");
+ FARPROC modversion = GetProcAddress(module, "modversion");
+ #endif
+ if(!startfunc || !loopfunc || !stopfunc || !modversion) {
+ putlog(LOGLEVEL_ERROR, "Error loading module '%s': required symbols not found.", name);
+ return 0;
+ }
+ int version = ((int (*)(void)) modversion)();
+ if(version != MODULE_VERSION) {
+ putlog(LOGLEVEL_ERROR, "Error loading module '%s': version mismatch ('%d' main code, '%d' module)", name, MODULE_VERSION, version);
+ return 0;
+ }
+ //start module
+ int errid;
+ int module_id = module_id_counter++;
+ if((errid = ((int (*)(void **, int)) initfunc)(global_functions, module_id))) {
+ putlog(LOGLEVEL_ERROR, "Error loading module '%s': module reported error (errid: %d)", name, errid);
+ return 0;
+ }
+ struct ModuleInfo *modinfo = malloc(sizeof(*modinfo));
+ if(!modinfo) {
+ unregister_module_hooks(module_id);
+ return 0;
+ }
+ modinfo->name = strdup(name);
+ modinfo->module_id = module_id;
+ modinfo->module = module;
+ modinfo->startfunc = startfunc;
+ modinfo->loopfunc = loopfunc;
+ modinfo->stopfunc = stopfunc;
+ modinfo->next = modules;
+ modules = modinfo;
+ return 1;
+}
+
+#ifndef WIN32
+static void closemodule(void *module) {
+ dlclose(module);
+}
+#else
+static void closemodule(HMODULE module) {
+ FreeLibrary(module);
+}
+#endif
+
+int reload_module(char *name) {
+ struct ModuleInfo *old_modinfo, *old_prev = NULL;
+ for(old_modinfo = modules; old_modinfo; old_modinfo = old_modinfo->next) {
+ if(old_prev)
+ old_prev->next = old_modinfo->next;
+ else
+ modules = old_modinfo->next;
+ unregister_module_hooks(old_modinfo->module_id);
+ ((void (*)(void)) old_modinfo->stopfunc)(MODSTATE_RELOAD);
+ closemodule(old_modinfo->module);
+ free(old_modinfo->name);
+ free(old_modinfo);
+ break;
+ } else
+ old_prev = old_modinfo;
+ if(!loadModule(name)) return 0;
+ struct ModuleInfo *modinfo;
+ for(modinfo = modules; modinfo; modinfo = modinfo->next) {
+ if(!(modinfo->state & MODINFO_STATE_STARTED)) {
+ modinfo->state |= MODINFO_STATE_STARTED;
+ ((void (*)(void)) modinfo->startfunc)(MODSTATE_STARTSTOP);
+ } else
+ ((void (*)(void)) modinfo->startfunc)(MODSTATE_REBIND);
+ }
+}
+
+void start_modules() {
+ struct ModuleInfo *modinfo;
+ for(modinfo = modules; modinfo; modinfo = modinfo->next) {
+ if(!(modinfo->state & MODINFO_STATE_STARTED)) {
+ modinfo->state |= MODINFO_STATE_STARTED;
+ ((void (*)(void)) modinfo->startfunc)(MODSTATE_STARTSTOP);
+ }
+ }
+}
+
+void loop_modules() {
+ struct ModuleInfo *modinfo;
+ for(modinfo = modules; modinfo; modinfo = modinfo->next) {
+ ((void (*)(void)) modinfo->loopfunc)();
+ }
+}
+
+void stop_modules() {
+ struct ModuleInfo *modinfo, *next;
+ for(modinfo = modules; modinfo; modinfo = next) {
+ next = modinfo->next;
+ unregister_module_hooks(modinfo->module_id);
+ ((void (*)(int)) modinfo->stopfunc)(MODSTATE_STARTSTOP);
+ closemodule(modinfo->module);
+ free(modinfo->name);
+ free(modinfo);
+ }
+ modules = NULL;
+}
+
+static void unregister_module_hooks(int module_id) {
+ unregister_module_commands(module_id);
+ unregister_module_events(module_id);
+ unregister_module_timers(module_id);
+}
+
+int module_loaded(int module_id) {
+ if(!module_id) return 1;
+ struct ModuleInfo *modinfo;
+ for(modinfo = modules; modinfo; modinfo = modinfo->next) {
+ if(modinfo->module_id == module_id)
+ return 1;
+ }
+ return 0;
+}
--- /dev/null
+/* modules.h - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef _modules_h
+#define _modules_h
+
+void load_module(char *name);
+void start_modules();
+void loop_modules();
+void stop_modules();
+int module_loaded(int module_id);
+
+#endif
\ No newline at end of file
--- /dev/null
+/* bot_DummyServ.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "../module.h"
+
+#include "bot_DummyServ.h"
+#include "modcmd.h"
+#include "IRCParser.h"
+#include "IRCEvents.h"
+#include "UserNode.h"
+#include "ChanNode.h"
+#include "ChanUser.h"
+#include "ModeNode.h"
+#include "BanNode.h"
+#include "ClientSocket.h"
+#include "mysqlConn.h"
+#include "lang.h"
+#include "HandleInfoHandler.h"
+#include "WHOHandler.h"
+#include "DBHelper.h"
+#include "tools.h"
+#include "timeq.h"
+#include "version.h"
+#include "EventLogger.h"
+#include "bots.h"
+#include "cmd_neonserv.h"
+#include "cmd_neonspam.h"
+
+#define BOTID 3
+#define BOTALIAS "DummyServ"
+
+static void dummyserv_bot_ready(struct ClientSocket *client) {
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+
+ printf_mysql_query("SELECT `automodes` FROM `bots` WHERE `id` = '%d'", client->clientid);
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) != NULL) {
+ putsock(client, "MODE %s +%s", client->user->nick, row[0]);
+ }
+
+ printf_mysql_query("SELECT `channel_name`, `channel_key` FROM `bot_channels` LEFT JOIN `channels` ON `chanid` = `channel_id` WHERE `botid` = '%d' AND `suspended` = '0'", client->clientid);
+ res = mysql_use();
+
+ while ((row = mysql_fetch_row(res)) != NULL) {
+ putsock(client, "JOIN %s %s", row[0], row[1]);
+ }
+}
+
+static void dummyserv_trigger_callback(int clientid, struct ChanNode *chan, char *trigger) {
+ //this bot doesn't have a trigger
+ strcpy(trigger, "");
+}
+
+static void start_bots(int type) {
+ struct ClientSocket *client;
+ MYSQL_RES *res, *res2;
+ MYSQL_ROW row;
+
+ if(type == MODSTATE_STARTSTOP) {
+ printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `textbot`, `id`, `queue`, `ssl`, `bind` FROM `bots` WHERE `botclass` = '%d' AND `active` = '1'", BOTID);
+ res = mysql_use();
+
+ while ((row = mysql_fetch_row(res)) != NULL) {
+ client = create_socket(row[3], atoi(row[4]), row[10], row[5], row[0], row[1], row[2]);
+ client->flags |= (strcmp(row[6], "0") ? SOCKET_FLAG_PREFERRED : 0);
+ client->flags |= (strcmp(row[8], "0") ? SOCKET_FLAG_USE_QUEUE : 0);
+ client->flags |= (strcmp(row[9], "0") ? SOCKET_FLAG_SSL : 0);
+ client->flags |= SOCKET_FLAG_SILENT;
+ client->botid = BOTID;
+ client->clientid = atoi(row[7]);
+ connect_socket(client);
+ }
+ }
+
+ printf_mysql_query("SELECT `command`, `function`, `parameters`, `global_access`, `chan_access`, `flags` FROM `bot_binds` WHERE `botclass` = '%d'", BOTID);
+ res2 = mysql_use();
+ while ((row = mysql_fetch_row(res2)) != NULL) {
+ if(bind_cmd_to_command(BOTID, row[0], row[1])) {
+ if(row[2] && strcmp(row[2], "")) {
+ bind_set_parameters(BOTID, row[0], row[2]);
+ }
+ if(row[3]) {
+ bind_set_global_access(BOTID, row[0], atoi(row[3]));
+ }
+ if(row[4]) {
+ bind_set_channel_access(BOTID, row[0], row[4]);
+ }
+ if(strcmp(row[5], "0"))
+ bind_set_bind_flags(BOTID, row[0], atoi(row[5]));
+ }
+ }
+ bind_unbound_required_functions(BOTID);
+}
+
+void init_DummyServ(int type) {
+ set_bot_alias(BOTID, BOTALIAS);
+ start_bots(type);
+
+ if(type == MODSTATE_REBIND) return;
+
+ //register events
+ bind_bot_ready(dummyserv_bot_ready);
+
+ set_trigger_callback(BOTID, dummyserv_trigger_callback);
+}
+
+void loop_DummyServ() {
+
+}
+
+void free_DummyServ(int type) {
+ unbind_allcmd(BOTID);
+ if(type == MODSTATE_STARTSTOP) {
+ //disconnect all our bots
+ struct ClientSocket *client;
+ for(client = getBots(0, NULL); client; client = getBots(0, client)) {
+ if(client->botid == BOTID) {
+ unbind_botwise_allcmd(0, client->clientid);
+ close_socket(client);
+ break;
+ }
+ }
+ }
+}
+
+#undef BOTID
+#undef BOTALIAS
--- /dev/null
+/* bot_DummyServ.h - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef _bot_DummyServ_h
+#define _bot_DummyServ_h
+
+#include "main.h"
+
+void init_DummyServ(int type);
+void loop_DummyServ();
+void free_DummyServ(int type);
+
+#endif
\ No newline at end of file
--- /dev/null
+/* module.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "../module.h"
+#include "bot_DummyServ.h"
+
+static int module_initialize() {
+ return 0;
+}
+
+static void module_start(int type) {
+ init_DummyServ(type);
+}
+
+static void module_loop() {
+ loop_DummyServ();
+}
+
+static void module_stop(int type) {
+ free_DummyServ(type);
+}
+
+MODULE_HEADER(module_initialize, module_start, module_loop, module_stop);
--- /dev/null
+/* bot_NeonHelp.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "bot_NeonHelp.h"
+#include "modcmd.h"
+#include "cmd_neonhelp.h"
+#include "lang.h"
+#include "mysqlConn.h"
+#include "ClientSocket.h"
+#include "UserNode.h"
+#include "ChanNode.h"
+#include "ChanUser.h"
+#include "IRCEvents.h"
+#include "IRCParser.h"
+#include "bots.h"
+#include "DBHelper.h"
+#include "WHOHandler.h"
+
+#define BOTID 4
+#define BOTALIAS "NeonHelp"
+
+static const struct default_language_entry msgtab[] = {
+ {"NH_NOT_ON_CHAN_1", "You cannot open this request as you are not in %s."}, /* {ARGS: "#test"} */
+ {"NH_NOT_ON_CHAN_2", "You cannot open this request as you are not in %s or %s."}, /* {ARGS: "test", "#test-support"} */
+ {"NH_REQUEST_RECORDED", "Your message has been recorded and assigned request ID#%d A helper should contact you shortly."}, /* {ARGS: 5} */
+ {"NH_REQUEST_OTHERS_0", "There are no other unhandled requests."},
+ {"NH_REQUEST_OTHERS_1", "There is 1 other unhandled request."},
+ {"NH_REQUEST_OTHERS_2", "There are %d other unhandled requests."}, /* {ARGS: 1337} */
+ {"NH_REQUEST_FOOTER_1", "Everything you tell me until you are helped (or you leave %1$s) will be recorded. If you part %1$s, your request will be lost."}, /* {ARGS: "#test"} */
+ {"NH_REQUEST_FOOTER_2", "Everything you tell me until you are helped (or you leave %1$s or %2$s) will be recorded. If you part %1$s or %2$s, your request will be lost."}, /* {ARGS: "#test", "#test-support"} */
+ {"NH_NEW_REQUEST", "New request #%d by %s: %s"}, /* {ARGS: 5, "pk910", "Help, I've fallen and I can't get up!"} */
+ {"NH_NEXT_NONE", "No more requests."},
+ {"NH_NEXT_NOT_FOUND", "No request found."},
+ {"NH_NEXT_HEADER", "$bNext request: #%d %s$b"}, /* {ARGS: 5, "pk910"} */
+ {"NH_NEXT_HELPER", "Your helper for request ID#%d is %s (Current nick: %s)."}, /* {ARGS: 5, "pk910", "Skynet"} */
+ {"NH_NEXT_JOIN", "Please /join %s now."}, /* {ARGS: "#test-support"} */
+ {"NH_DELETED", "Your request ID#%d has been deleted."}, /* {ARGS: 5} */
+ {"NH_DELETED_STAFF", "Request deleted: #%d (%s)"}, /* {ARGS: 5, "pk910"} */
+ {"NH_REMIND_OPEN_REQUESTS_1", "There is %d unhandled request!"}, /* {ARGS: 1} */
+ {"NH_REMIND_OPEN_REQUESTS_2", "There are %d unhandled requests!"}, /* {ARGS: 4} */
+ {"NH_REQUESTS_HEADER_ID", "ID"},
+ {"NH_REQUESTS_HEADER_STATUS", "State"},
+ {"NH_REQUESTS_HEADER_NICK", "Nick"},
+ {"NH_REQUESTS_HEADER_TIME", "Time"},
+ {"NH_REQUESTS_HEADER_REQUEST", "Question"},
+ {"NH_REQUESTS_STATE_ACTIVE", "active"},
+ {"NH_REQUESTS_STATE_PENDING", "pending"},
+ {"NH_REQUESTS_STATE_ERROR", "ERROR"},
+ {"NH_STATS_HEADER_USER", "User"},
+ {"NH_STATS_HEADER_LAST_24H", "last 24h"},
+ {"NH_STATS_HEADER_LAST_7DAY", "last 7d"},
+ {"NH_STATS_HEADER_LAST_30DAY", "last 30d"},
+ {NULL, NULL}
+};
+
+static void neonhelp_bot_ready(struct ClientSocket *client) {
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+
+ printf_mysql_query("SELECT `automodes` FROM `bots` WHERE `id` = '%d'", client->clientid);
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) != NULL) {
+ putsock(client, "MODE %s +%s", client->user->nick, row[0]);
+ }
+
+ printf_mysql_query("SELECT `channel_name`, `channel_key` FROM `bot_channels` LEFT JOIN `channels` ON `chanid` = `channel_id` WHERE `botid` = '%d' AND `suspended` = '0'", client->clientid);
+ res = mysql_use();
+
+ while ((row = mysql_fetch_row(res)) != NULL) {
+ putsock(client, "JOIN %s %s", row[0], row[1]);
+ }
+}
+
+static void neonhelp_trigger_callback(int clientid, struct ChanNode *chan, char *trigger) {
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ loadChannelSettings(chan);
+ if(!(chan->flags & CHANFLAG_CHAN_REGISTERED)) {
+ strcpy(trigger, "!");
+ return;
+ }
+ printf_mysql_query("SELECT `trigger`, `defaulttrigger` FROM `bot_channels` LEFT JOIN `bots` ON `botid` = `bots`.`id` WHERE `chanid` = '%d' AND `botclass` = '%d'", chan->channel_id, BOTID);
+ res = mysql_use();
+ if(!(row = mysql_fetch_row(res))) {
+ strcpy(trigger, "!");
+ return;
+ }
+ if(row[0] && *row[0])
+ strcpy(trigger, row[0]);
+ else
+ strcpy(trigger, ((row[1] && *row[1]) ? row[1] : "!"));
+}
+
+static void start_bots(int type) {
+ struct ClientSocket *client;
+ MYSQL_RES *res, *res2;
+ MYSQL_ROW row;
+
+ if(type == MODSTATE_STARTSTOP) {
+ printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `textbot`, `id`, `queue`, `ssl`, `bind` FROM `bots` WHERE `botclass` = '%d' AND `active` = '1'", BOTID);
+ res = mysql_use();
+
+ while ((row = mysql_fetch_row(res)) != NULL) {
+ client = create_socket(row[3], atoi(row[4]), row[10], row[5], row[0], row[1], row[2]);
+ client->flags |= (strcmp(row[6], "0") ? SOCKET_FLAG_PREFERRED : 0);
+ client->flags |= (strcmp(row[8], "0") ? SOCKET_FLAG_USE_QUEUE : 0);
+ client->flags |= (strcmp(row[9], "0") ? SOCKET_FLAG_SSL : 0);
+ client->flags |= SOCKET_FLAG_SILENT;
+ client->botid = BOTID;
+ client->clientid = atoi(row[7]);
+ connect_socket(client);
+ //close old, still opened requests
+ printf_mysql_query("UPDATE `helpserv_requests` SET `status` = '2' WHERE `botid` = '%d'", client->clientid);
+ }
+ }
+
+ printf_mysql_query("SELECT `command`, `function`, `parameters`, `global_access`, `chan_access`, `flags` FROM `bot_binds` WHERE `botclass` = '%d'", BOTID);
+ res2 = mysql_use();
+ while ((row = mysql_fetch_row(res2)) != NULL) {
+ if(bind_cmd_to_command(BOTID, row[0], row[1])) {
+ if(row[2] && strcmp(row[2], "")) {
+ bind_set_parameters(BOTID, row[0], row[2]);
+ }
+ if(row[3]) {
+ bind_set_global_access(BOTID, row[0], atoi(row[3]));
+ }
+ if(row[4]) {
+ bind_set_channel_access(BOTID, row[0], row[4]);
+ }
+ if(strcmp(row[5], "0"))
+ bind_set_bind_flags(BOTID, row[0], atoi(row[5]));
+ }
+ }
+ bind_unbound_required_functions(BOTID);
+}
+
+static void neonhelp_event_privmsg_async(struct ClientSocket *client, struct UserNode *user, struct UserNode *target, char *message);
+static USERAUTH_CALLBACK(neonhelp_event_privmsg_nick_lookup);
+struct neonhelp_event_privmsg_cache {
+ struct ClientSocket *client;
+ struct UserNode *user, *target;
+ char *message;
+};
+
+static void neonhelp_event_privmsg(struct UserNode *user, struct UserNode *target, char *message) {
+ struct ClientSocket *client;
+ for(client = getBots(SOCKET_FLAG_READY, NULL); client; client = getBots(SOCKET_FLAG_READY, client)) {
+ if(client->user == target) {
+ if(client->botid != BOTID) return;
+ break;
+ }
+ }
+ if(!client) return; //we got the message but we have no client that could receive it???
+ if(user->flags & USERFLAG_ISAUTHED) {
+ neonhelp_event_privmsg_async(client, user, target, message);
+ } else {
+ struct neonhelp_event_privmsg_cache *cache = malloc(sizeof(*cache));
+ if(!cache) return;
+ cache->client = client;
+ cache->user = user;
+ cache->target = target;
+ cache->message = strdup(message);
+ get_userauth(user, neonhelp_event_privmsg_nick_lookup, cache);
+ }
+}
+
+static USERAUTH_CALLBACK(neonhelp_event_privmsg_nick_lookup) {
+ struct neonhelp_event_privmsg_cache *cache = data;
+ neonhelp_event_privmsg_async(cache->client, cache->user, cache->target, cache->message);
+ free(cache->message);
+ free(cache);
+}
+
+static TIMEQ_CALLBACK(neonhelp_remind_open_requests);
+
+static void neonhelp_event_privmsg_async(struct ClientSocket *client, struct UserNode *user, struct UserNode *target, char *message) {
+ MYSQL_RES *res;
+ MYSQL_ROW row, row2;
+ printf_mysql_query("SELECT `helpserv_support`, `helpserv_public`, `helpserv_intern`, `helpserv_intern_announce` FROM `helpserv_settings` WHERE `helpserv_botid` = '%d'", client->clientid);
+ res = mysql_use();
+ if (!(row = mysql_fetch_row(res))) return;
+ //check if the user is a supporter (access in the support channel)
+ if((user->flags & USERFLAG_ISAUTHED)) {
+ int caccess = 0;
+ int userid;
+ if(user->flags & USERFLAG_HAS_USERID)
+ userid = user->user_id;
+ else {
+ printf_mysql_query("SELECT `user_id` FROM `users` WHERE `user_user` = '%s'", escape_string(user->auth));
+ res = mysql_use();
+ if ((row2 = mysql_fetch_row(res)) != NULL) {
+ userid = atoi(row2[0]);
+ user->user_id = userid;
+ user->flags |= USERFLAG_HAS_USERID;
+ } else
+ userid = 0;
+ }
+ printf_mysql_query("SELECT `chanuser_access`, `chanuser_flags` FROM `chanusers` LEFT JOIN `channels` ON `chanuser_cid` = `channel_id` WHERE `chanuser_uid` = '%d' AND `channel_name` = '%s'", userid, escape_string(row[0]));
+ res = mysql_use();
+ if ((row2 = mysql_fetch_row(res)) != NULL) {
+ int cflags = atoi(row2[1]);
+ if(!(cflags & DB_CHANUSER_SUSPENDED))
+ caccess = atoi(row2[0]);
+ }
+ if(caccess) return; //ignore messages from supporters
+ }
+ //check if the user is in one of the bot's channels
+ struct ChanUser *chanuser;
+ struct ChanNode *chan;
+ for(chanuser = getUserChannels(target, NULL); chanuser; chanuser = getUserChannels(target, chanuser)) {
+ chan = chanuser->chan;
+ if((!stricmp(chan->name, row[0]) || (row[1] && !stricmp(chan->name, row[1]))) && isUserOnChan(user, chan))
+ break;
+ }
+ if(!chanuser) {
+ if(row[1])
+ reply(client, user, "NH_NOT_ON_CHAN_2", row[0], row[1]);
+ else
+ reply(client, user, "NH_NOT_ON_CHAN_1", row[0]);
+ return;
+ }
+ //check if there is already a support request
+ int others = 0;
+ if(client->flags & SOCKET_HAVE_HELPNODE) {
+ struct NeonHelpNode *helpnode;
+ for(helpnode = client->botclass_helpnode; helpnode; helpnode = helpnode->next) {
+ if(helpnode->user == user) {
+ //simply append the message to the database
+ printf_mysql_query("SELECT `text` FROM `helpserv_requests` WHERE `id` = %d", helpnode->suppid);
+ res = mysql_use();
+ if ((row2 = mysql_fetch_row(res)) != NULL) {
+ char *old_msg = escape_string(row2[0]);
+ char *new_msg = escape_string(message);
+ printf_long_mysql_query(1024 + strlen(old_msg) + strlen(new_msg), "UPDATE `helpserv_requests` SET `text` = '%s\n%s' WHERE `id` = %d", old_msg, new_msg, helpnode->suppid);
+ }
+ return;
+ }
+ others++;
+ }
+ }
+ //add new request
+ struct NeonHelpNode *helpnode = malloc(sizeof(*helpnode));
+ if(!helpnode) return;
+ helpnode->user = user;
+ helpnode->logchan = getChanByName(row[0]);
+ helpnode->status = 0;
+ helpnode->announce = (row[2] && strcmp(row[3], "0") ? 1 : 0);
+ if(helpnode->announce) {
+ char nameBuf[30];
+ sprintf(nameBuf, "neonhelp_%d", client->clientid);
+ if(!timeq_name_exists(nameBuf)) {
+ int *cidptr = malloc(sizeof(int));
+ *cidptr = client->clientid;
+ timeq_add_name(nameBuf, 300, neonhelp_remind_open_requests, cidptr);
+ }
+ }
+ printf_mysql_query("INSERT INTO `helpserv_requests` (`botid`, `host`, `hand`, `nick`, `status`, `supporter`, `time`, `text`) VALUES ('%d', '%s@%s', '%s', '%s', '0', '-1', UNIX_TIMESTAMP(), '%s')", client->clientid, escape_string(user->ident), escape_string(user->host), ((user->flags & USERFLAG_ISAUTHED) ? escape_string(user->auth) : "*"), escape_string(user->nick), escape_string(message));
+ helpnode->suppid = (int) mysql_insert_id(get_mysql_conn());
+ helpnode->log = NULL;
+ helpnode->next = ((client->flags & SOCKET_HAVE_HELPNODE) ? client->botclass_helpnode : NULL);
+ client->botclass_helpnode = helpnode;
+ client->flags |= SOCKET_HAVE_HELPNODE;
+ //build the user reply...
+ char user_reply[MAXLEN];
+ int user_reply_pos = 0;
+ char reply_buff[MAXLEN];
+ //1st part: NH_REQUEST_RECORDED
+ strcpy(user_reply + user_reply_pos, build_language_string(user, reply_buff, "NH_REQUEST_RECORDED", helpnode->suppid));
+ user_reply_pos += strlen(reply_buff);
+ //2nd part: NH_REQUEST_OTHERS_0 / NH_REQUEST_OTHERS_1 / NH_REQUEST_OTHERS_2
+ user_reply[user_reply_pos++] = ' ';
+ if(others <= 1)
+ strcpy(user_reply + user_reply_pos, build_language_string(user, reply_buff, (others ? "NH_REQUEST_OTHERS_1" : "NH_REQUEST_OTHERS_0")));
+ else
+ strcpy(user_reply + user_reply_pos, build_language_string(user, reply_buff, "NH_REQUEST_OTHERS_2", others));
+ user_reply_pos += strlen(reply_buff);
+ //3th part: NH_REQUEST_FOOTER_1 / NH_REQUEST_FOOTER_2
+ user_reply[user_reply_pos++] = ' ';
+ if(row[1])
+ strcpy(user_reply + user_reply_pos, build_language_string(user, reply_buff, "NH_REQUEST_FOOTER_2", row[0], row[1]));
+ else
+ strcpy(user_reply + user_reply_pos, build_language_string(user, reply_buff, "NH_REQUEST_FOOTER_1", row[0]));
+ user_reply_pos += strlen(reply_buff);
+ reply(client, user, "%s", user_reply);
+ //sent a message to the internal channel / onotice to supp channel
+ build_language_string(user, reply_buff, "NH_NEW_REQUEST", helpnode->suppid, user->nick, message);
+ if(row[2]) {
+ putsock(client, "PRIVMSG %s :%s", row[2], reply_buff);
+ } else {
+ putsock(client, "NOTICE @%s :%s", row[0], reply_buff);
+ }
+}
+
+static TIMEQ_CALLBACK(neonhelp_remind_open_requests) {
+ int clientid = *((int*)data);
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ printf_mysql_query("SELECT `helpserv_support`, `helpserv_public`, `helpserv_intern`, `helpserv_intern_announce` FROM `helpserv_settings` WHERE `helpserv_botid` = '%d'", clientid);
+ res = mysql_use();
+ if (!(row = mysql_fetch_row(res)) || !row[2]) {
+ free(data);
+ return;
+ }
+ struct ClientSocket *client;
+ for(client = getBots(SOCKET_FLAG_READY, NULL); client; client = getBots(SOCKET_FLAG_READY, client)) {
+ if(client->clientid == clientid)
+ break;
+ }
+ if(!client) {
+ free(data);
+ return;
+ }
+ //count open requests
+ int requests = 0;
+ struct NeonHelpNode *helpnode;
+ if(client->flags & SOCKET_HAVE_HELPNODE) {
+ for(helpnode = client->botclass_helpnode; helpnode; helpnode = helpnode->next) {
+ if(helpnode->status == 0) {
+ requests++;
+ }
+ }
+ }
+ if(requests) {
+ char nameBuf[30];
+ sprintf(nameBuf, "neonhelp_%d", client->clientid);
+ if(!timeq_name_exists(nameBuf)) {
+ timeq_add_name(nameBuf, 300, neonhelp_remind_open_requests, data);
+ }
+ char replybuf[MAXLEN];
+ build_language_string(NULL, replybuf, (requests == 1 ? "NH_REMIND_OPEN_REQUESTS_1" : "NH_REMIND_OPEN_REQUESTS_2"), requests);
+ putsock(client, "PRIVMSG %s :%s", row[2], replybuf);
+ } else
+ free(data);
+}
+
+static void neonhelp_event_chanmsg(struct UserNode *user, struct ChanNode *chan, char *message) {
+ char logline[MAXLEN];
+ sprintf(logline, "<%s> %s", user->nick, message);
+ struct ClientSocket *client;
+ for(client = getBots(SOCKET_FLAG_READY, NULL); client; client = getBots(SOCKET_FLAG_READY, client)) {
+ if(client->botid == BOTID) {
+ struct NeonHelpNode *helpnode;
+ if(client->flags & SOCKET_HAVE_HELPNODE) {
+ for(helpnode = client->botclass_helpnode; helpnode; helpnode = helpnode->next) {
+ if(helpnode->logchan == chan && helpnode->status == 1) {
+ if(!helpnode->log) {
+ helpnode->log = calloc(LOGBUFFERLINES, sizeof(char*));
+ if(!helpnode->log) return;
+ }
+ int i;
+ for(i = 0; i < LOGBUFFERLINES; i++) {
+ if(!helpnode->log[i]) {
+ helpnode->log[i] = strdup(logline);
+ break;
+ }
+ }
+ if(i == LOGBUFFERLINES) {
+ //write buffer to database
+ char logbuff[MAXLEN * LOGBUFFERLINES];
+ int len = 0;
+ for(i = 0; i < LOGBUFFERLINES; i++) {
+ len += sprintf(logbuff + len, "%s\n", helpnode->log[i]);
+ free(helpnode->log[i]);
+ helpnode->log[i] = NULL;
+ }
+ printf_long_mysql_query(1024 + len, "UPDATE `helpserv_requests` SET `log` = CONCAT(`log`, '%s') WHERE `id` = %d", escape_string(logbuff), helpnode->suppid);
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+}
+
+static void destroy_support_request(struct ClientSocket *client, struct NeonHelpNode *helpnode, int do_reply) {
+ //write buffer to database
+ char logbuff[MAXLEN * LOGBUFFERLINES];
+ int len = 0;
+ int i;
+ if(helpnode->log) {
+ for(i = 0; i < LOGBUFFERLINES; i++) {
+ if(!helpnode->log[i]) break;
+ len += sprintf(logbuff + len, "%s\n", helpnode->log[i]);
+ free(helpnode->log[i]);
+ helpnode->log[i] = NULL;
+ }
+ free(helpnode->log);
+ } else
+ logbuff[0] = '\0';
+ printf_long_mysql_query(1024 + len, "UPDATE `helpserv_requests` SET `status`='2', `log` = CONCAT(`log`, '%s') WHERE `id` = %d", escape_string(logbuff), helpnode->suppid);
+ if(do_reply) {
+ reply(client, helpnode->user, "NH_DELETED", helpnode->suppid);
+ }
+ free(helpnode);
+}
+
+static void neonhelp_event_kick(struct UserNode *user, struct ChanUser *target, char *reason) {
+ struct ClientSocket *client;
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ struct ChanNode *support, *public;
+ int userHasRequest;
+ for(client = getBots(SOCKET_FLAG_READY, NULL); client; client = getBots(SOCKET_FLAG_READY, client)) {
+ if(client->botid == BOTID && isUserOnChan(client->user, target->chan)) {
+ userHasRequest = 0;
+ struct NeonHelpNode *helpnode, *prev_helpnode = NULL;
+ if(client->flags & SOCKET_HAVE_HELPNODE) {
+ for(helpnode = client->botclass_helpnode; helpnode; helpnode = helpnode->next) {
+ if(helpnode->user == target->user) {
+ userHasRequest = 1;
+ break;
+ } else
+ prev_helpnode = helpnode;
+ }
+ }
+ if(!userHasRequest) continue;
+ printf_mysql_query("SELECT `helpserv_support`, `helpserv_public`, `helpserv_intern` FROM `helpserv_settings` WHERE `helpserv_botid` = '%d'", client->clientid);
+ res = mysql_use();
+ if (!(row = mysql_fetch_row(res))) continue;
+ support = getChanByName(row[0]);
+ public = (row[1] ? getChanByName(row[1]) : NULL);
+ if(target->chan == support || !((support && isUserOnChan(target->user, support)) || (public && isUserOnChan(target->user, public)))) {
+ //free the user's support request
+ if(prev_helpnode)
+ prev_helpnode->next = helpnode->next;
+ else
+ client->botclass_helpnode = helpnode->next;
+ destroy_support_request(client, helpnode, 1);
+ }
+ }
+ }
+}
+
+static void neonhelp_event_part(struct ChanUser *target, char *reason) {
+ struct ClientSocket *client;
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ struct ChanNode *support, *public;
+ int userHasRequest;
+ for(client = getBots(SOCKET_FLAG_READY, NULL); client; client = getBots(SOCKET_FLAG_READY, client)) {
+ if(client->botid == BOTID && isUserOnChan(client->user, target->chan)) {
+ userHasRequest = 0;
+ struct NeonHelpNode *helpnode, *prev_helpnode = NULL;
+ if(client->flags & SOCKET_HAVE_HELPNODE) {
+ for(helpnode = client->botclass_helpnode; helpnode; helpnode = helpnode->next) {
+ if(helpnode->user == target->user) {
+ userHasRequest = 1;
+ break;
+ } else
+ prev_helpnode = helpnode;
+ }
+ }
+ if(!userHasRequest) continue;
+ printf_mysql_query("SELECT `helpserv_support`, `helpserv_public`, `helpserv_intern` FROM `helpserv_settings` WHERE `helpserv_botid` = '%d'", client->clientid);
+ res = mysql_use();
+ if (!(row = mysql_fetch_row(res))) continue;
+ support = getChanByName(row[0]);
+ public = (row[1] ? getChanByName(row[1]) : NULL);
+ if(target->chan == support || !((support && isUserOnChan(target->user, support)) || (public && isUserOnChan(target->user, public)))) {
+ //free the user's support request
+ if(prev_helpnode)
+ prev_helpnode->next = helpnode->next;
+ else
+ client->botclass_helpnode = helpnode->next;
+ destroy_support_request(client, helpnode, 1);
+ }
+ }
+ }
+}
+
+static void neonhelp_event_quit(struct UserNode *target, char *reason) {
+ struct ClientSocket *client;
+ int userHasRequest;
+ for(client = getBots(SOCKET_FLAG_READY, NULL); client; client = getBots(SOCKET_FLAG_READY, client)) {
+ if(client->botid == BOTID) {
+ userHasRequest = 0;
+ struct NeonHelpNode *helpnode, *prev_helpnode = NULL;
+ if(client->flags & SOCKET_HAVE_HELPNODE) {
+ for(helpnode = client->botclass_helpnode; helpnode; helpnode = helpnode->next) {
+ if(helpnode->user == target) {
+ userHasRequest = 1;
+ break;
+ } else
+ prev_helpnode = helpnode;
+ }
+ }
+ if(!userHasRequest) continue;
+ //free the user's support request
+ if(prev_helpnode)
+ prev_helpnode->next = helpnode->next;
+ else
+ client->botclass_helpnode = helpnode->next;
+ destroy_support_request(client, helpnode, 0);
+ }
+ }
+}
+
+void init_NeonHelp(int type) {
+ set_bot_alias(BOTID, BOTALIAS);
+ start_bots();
+
+ if(type == MODSTATE_REBIND) return;
+
+ //register events
+ bind_bot_ready(neonhelp_bot_ready);
+ bind_privmsg(neonhelp_event_privmsg);
+ bind_chanmsg(neonhelp_event_chanmsg);
+ bind_part(neonhelp_event_part);
+ bind_kick(neonhelp_event_kick);
+ bind_quit(neonhelp_event_quit);
+
+ set_trigger_callback(BOTID, neonhelp_trigger_callback);
+
+ register_default_language_table(msgtab);
+}
+
+void loop_NeonHelp() {
+
+}
+
+void free_NeonHelp(int type) {
+ unbind_allcmd(BOTID);
+ if(type == MODSTATE_STARTSTOP) {
+ //disconnect all our bots
+ struct ClientSocket *client;
+ for(client = getBots(0, NULL); client; client = getBots(0, client)) {
+ if(client->botid == BOTID) {
+ unbind_botwise_allcmd(0, client->clientid);
+ close_socket(client);
+ break;
+ }
+ }
+ }
+}
+
+#undef BOTID
+#undef BOTALIAS
--- /dev/null
+/* bot_NeonHelp.h - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef _bot_NeonHelp_h
+#define _bot_NeonHelp_h
+
+#include "main.h"
+
+/* definition for ClientSocket struct */
+#define botclass_helpnode botclassvalue1
+#define SOCKET_HAVE_HELPNODE SOCKET_HAVE_BOTCLASSVALUE1
+
+#define LOGBUFFERLINES 20
+
+struct UserNode;
+struct ChanNode;
+
+struct NeonHelpNode {
+ struct UserNode *user;
+ int suppid;
+ char status:6;
+ char announce:2;
+ struct NeonHelpNode *next;
+ struct ChanNode *logchan;
+ char **log;
+};
+
+void init_NeonHelp(int type);
+void loop_NeonHelp();
+void free_NeonHelp(int type);
+
+#endif
\ No newline at end of file
--- /dev/null
+/* cmd_neonhelp.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "../module.h"
+#include "cmd_neonhelp.h"
+#include "modcmd.h"
+#include "ConfigParser.h"
+
+void register_commands() {
+ //NeonHelp Commands
+ register_command_alias(4, "NeonHelp");
+
+ #define USER_COMMAND(NAME,FUNCTION,PARAMCOUNT,PRIVS,FLAGS) register_command(4, NAME, FUNCTION, PARAMCOUNT, PRIVS, 0, FLAGS)
+ // NAME FUNCTION PARAMS PRIVS FLAGS
+ USER_COMMAND("next", neonhelp_cmd_next, 0, NULL, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH);
+ USER_COMMAND("delete", neonhelp_cmd_delete, 1, NULL, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH);
+ USER_COMMAND("requests", neonhelp_cmd_requests, 0, NULL, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH);
+ USER_COMMAND("stats", neonhelp_cmd_stats, 0, NULL, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH);
+ #undef USER_COMMAND
+
+}
\ No newline at end of file
--- /dev/null
+/* cmd_neonhelp.h - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef _cmd_neonhelp_h
+#define _cmd_neonhelp_h
+#include "../module.h"
+#include "main.h"
+#include "modcmd.h"
+#include "mysqlConn.h"
+#include "ClientSocket.h"
+#include "UserNode.h"
+#include "ChanNode.h"
+#include "ChanUser.h"
+#include "DBHelper.h"
+#include "IRCParser.h"
+#include "bot_NeonHelp.h"
+#include "lang.h"
+#include "tools.h"
+
+void register_commands();
+
+CMD_BIND(neonhelp_cmd_delete);
+CMD_BIND(neonhelp_cmd_next);
+CMD_BIND(neonhelp_cmd_requests);
+CMD_BIND(neonhelp_cmd_stats);
+
+#endif
\ No newline at end of file
--- /dev/null
+/* cmd_neonhelp_delete.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonhelp.h"
+
+/*
+* argv[0] suppid
+*/
+
+CMD_BIND(neonhelp_cmd_delete) {
+ //check permissions
+ MYSQL_RES *res;
+ MYSQL_ROW row, row2;
+ int caccess = 0;
+ printf_mysql_query("SELECT `helpserv_support`, `helpserv_public`, `helpserv_intern` FROM `helpserv_settings` WHERE `helpserv_botid` = '%d'", client->clientid);
+ res = mysql_use();
+ if (!(row = mysql_fetch_row(res))) return;
+ //check if the user is a supporter (access in the support channel)
+ if((user->flags & USERFLAG_ISAUTHED)) {
+ int userid;
+ if(user->flags & USERFLAG_HAS_USERID)
+ userid = user->user_id;
+ else {
+ printf_mysql_query("SELECT `user_id` FROM `users` WHERE `user_user` = '%s'", escape_string(user->auth));
+ res = mysql_use();
+ if ((row2 = mysql_fetch_row(res)) != NULL) {
+ userid = atoi(row2[0]);
+ user->user_id = userid;
+ user->flags |= USERFLAG_HAS_USERID;
+ } else
+ userid = 0;
+ }
+ printf_mysql_query("SELECT `chanuser_access`, `chanuser_flags` FROM `chanusers` LEFT JOIN `channels` ON `chanuser_cid` = `channel_id` WHERE `chanuser_uid` = '%d' AND `channel_name` = '%s'", userid, escape_string(row[0]));
+ res = mysql_use();
+ if ((row2 = mysql_fetch_row(res)) != NULL) {
+ int cflags = atoi(row2[1]);
+ if(!(cflags & DB_CHANUSER_SUSPENDED))
+ caccess = atoi(row2[0]);
+ }
+ }
+ if(!caccess) {
+ reply(getTextBot(), user, "MODCMD_ACCESS_DENIED");
+ return;
+ }
+ if(!(client->flags & SOCKET_HAVE_HELPNODE) || client->botclass_helpnode == NULL) {
+ reply(getTextBot(), user, "NH_NEXT_NONE");
+ return;
+ }
+ struct NeonHelpNode *helpnode, *next_helpnode = NULL, *prev_helpnode = NULL;
+ for(helpnode = client->botclass_helpnode; helpnode; helpnode = helpnode->next) {
+ if(atoi(argv[0]) == helpnode->suppid) {
+ next_helpnode = helpnode;
+ break;
+ } else
+ prev_helpnode = helpnode;
+ }
+ if(!next_helpnode) {
+ reply(getTextBot(), user, "NH_NEXT_NOT_FOUND");
+ return;
+ }
+ reply(client, next_helpnode->user, "NH_DELETED", next_helpnode->suppid);
+ printf_mysql_query("UPDATE `helpserv_requests` SET `status` = '2' WHERE `id` = '%d'", next_helpnode->suppid);
+ if(prev_helpnode)
+ prev_helpnode->next = next_helpnode->next;
+ else
+ client->botclass_helpnode = next_helpnode->next;
+ reply(getTextBot(), user, "NH_DELETED_STAFF", next_helpnode->suppid, next_helpnode->user->nick);
+ free(next_helpnode);
+}
--- /dev/null
+/* cmd_neonhelp_next.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonhelp.h"
+
+/*
+* argv[0] (optional) suppid
+*/
+
+CMD_BIND(neonhelp_cmd_next) {
+ //check permissions
+ MYSQL_RES *res;
+ MYSQL_ROW row, row2;
+ int caccess = 0;
+ int userid;
+ printf_mysql_query("SELECT `helpserv_support`, `helpserv_public`, `helpserv_intern` FROM `helpserv_settings` WHERE `helpserv_botid` = '%d'", client->clientid);
+ res = mysql_use();
+ if (!(row = mysql_fetch_row(res))) return;
+ //check if the user is a supporter (access in the support channel)
+ if((user->flags & USERFLAG_ISAUTHED)) {
+ if(user->flags & USERFLAG_HAS_USERID)
+ userid = user->user_id;
+ else {
+ printf_mysql_query("SELECT `user_id` FROM `users` WHERE `user_user` = '%s'", escape_string(user->auth));
+ res = mysql_use();
+ if ((row2 = mysql_fetch_row(res)) != NULL) {
+ userid = atoi(row2[0]);
+ user->user_id = userid;
+ user->flags |= USERFLAG_HAS_USERID;
+ } else
+ userid = 0;
+ }
+ printf_mysql_query("SELECT `chanuser_access`, `chanuser_flags` FROM `chanusers` LEFT JOIN `channels` ON `chanuser_cid` = `channel_id` WHERE `chanuser_uid` = '%d' AND `channel_name` = '%s'", userid, escape_string(row[0]));
+ res = mysql_use();
+ if ((row2 = mysql_fetch_row(res)) != NULL) {
+ int cflags = atoi(row2[1]);
+ if(!(cflags & DB_CHANUSER_SUSPENDED))
+ caccess = atoi(row2[0]);
+ }
+ }
+ if(!caccess) {
+ reply(getTextBot(), user, "MODCMD_ACCESS_DENIED");
+ return;
+ }
+ if(!(client->flags & SOCKET_HAVE_HELPNODE) || client->botclass_helpnode == NULL) {
+ reply(getTextBot(), user, "NH_NEXT_NONE");
+ return;
+ }
+ struct NeonHelpNode *helpnode, *next_helpnode = NULL;
+ int lowest_id = -1;
+ for(helpnode = client->botclass_helpnode; helpnode; helpnode = helpnode->next) {
+ if(helpnode->status == 0) {
+ if(argc) {
+ if(atoi(argv[0]) == helpnode->suppid) {
+ next_helpnode = helpnode;
+ break;
+ }
+ } else {
+ if(helpnode->suppid < lowest_id || lowest_id == -1) {
+ lowest_id = helpnode->suppid;
+ next_helpnode = helpnode;
+ }
+ }
+ }
+ }
+ if(!next_helpnode) {
+ reply(getTextBot(), user, "NH_NEXT_NOT_FOUND");
+ return;
+ }
+ printf_mysql_query("SELECT `text` FROM `helpserv_requests` WHERE `id` = '%d'", next_helpnode->suppid);
+ res = mysql_use();
+ if (!(row2 = mysql_fetch_row(res))) return;
+ reply(getTextBot(), user, "NH_NEXT_HEADER", next_helpnode->suppid, next_helpnode->user->nick);
+ char *a, *b = row2[0];
+ do {
+ a = strstr(b, "\n");
+ if(a) *a = '\0';
+ reply(getTextBot(), user, " %s", b);
+ if(a) {
+ *a = '\n';
+ b = a+1;
+ }
+ } while(a);
+ if(row[1])
+ putsock(client, "INVITE %s %s", next_helpnode->user->nick, row[0]);
+ else
+ putsock(client, "MODE %s +v %s", row[0], next_helpnode->user->nick);
+ char sendbuf1[MAXLEN];
+ char sendbuf2[MAXLEN];
+ char *join_now = (row[1] ? build_language_string(user, sendbuf2, "NH_NEXT_JOIN", row[0]) : "");
+ putsock(client, "PRIVMSG %s :%s %s", next_helpnode->user->nick, build_language_string(user, sendbuf1, "NH_NEXT_HELPER", next_helpnode->suppid, user->auth, user->nick), join_now);
+ next_helpnode->status = 1;
+ printf_mysql_query("UPDATE `helpserv_requests` SET `status` = '1', `supporter` = '%d' WHERE `id` = '%d'", userid, next_helpnode->suppid);
+}
--- /dev/null
+/* cmd_neonhelp_requests.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonhelp.h"
+
+/*
+* no args
+*/
+
+CMD_BIND(neonhelp_cmd_requests) {
+ //check permissions
+ MYSQL_RES *res;
+ MYSQL_ROW row, row2;
+ int caccess = 0;
+ int userid;
+ printf_mysql_query("SELECT `helpserv_support`, `helpserv_public`, `helpserv_intern` FROM `helpserv_settings` WHERE `helpserv_botid` = '%d'", client->clientid);
+ res = mysql_use();
+ if (!(row = mysql_fetch_row(res))) return;
+ //check if the user is a supporter (access in the support channel)
+ if((user->flags & USERFLAG_ISAUTHED)) {
+ if(user->flags & USERFLAG_HAS_USERID)
+ userid = user->user_id;
+ else {
+ printf_mysql_query("SELECT `user_id` FROM `users` WHERE `user_user` = '%s'", escape_string(user->auth));
+ res = mysql_use();
+ if ((row2 = mysql_fetch_row(res)) != NULL) {
+ userid = atoi(row2[0]);
+ user->user_id = userid;
+ user->flags |= USERFLAG_HAS_USERID;
+ } else
+ userid = 0;
+ }
+ printf_mysql_query("SELECT `chanuser_access`, `chanuser_flags` FROM `chanusers` LEFT JOIN `channels` ON `chanuser_cid` = `channel_id` WHERE `chanuser_uid` = '%d' AND `channel_name` = '%s'", userid, escape_string(row[0]));
+ res = mysql_use();
+ if ((row2 = mysql_fetch_row(res)) != NULL) {
+ int cflags = atoi(row2[1]);
+ if(!(cflags & DB_CHANUSER_SUSPENDED))
+ caccess = atoi(row2[0]);
+ }
+ }
+ if(!caccess) {
+ reply(getTextBot(), user, "MODCMD_ACCESS_DENIED");
+ return;
+ }
+ struct Table *table;
+ printf_mysql_query("SELECT `id`, `time`, `text` FROM `helpserv_requests` WHERE `botid` = '%d' AND `status` != 2 ORDER BY `time` DESC", client->clientid);
+ res = mysql_use();
+ table = table_init(5, mysql_num_rows(res) + 1, 0);
+ char *content[5];
+ content[0] = get_language_string(user, "NH_REQUESTS_HEADER_ID");
+ content[1] = get_language_string(user, "NH_REQUESTS_HEADER_STATUS");
+ content[2] = get_language_string(user, "NH_REQUESTS_HEADER_NICK");
+ content[3] = get_language_string(user, "NH_REQUESTS_HEADER_TIME");
+ content[4] = get_language_string(user, "NH_REQUESTS_HEADER_REQUEST");
+ table_add(table, content);
+ char timestr[MAXLEN];
+ struct NeonHelpNode *helpnode;
+ int suppid;
+ while ((row = mysql_fetch_row(res)) != NULL) {
+ content[0] = row[0];
+ suppid = atoi(row[0]);
+ if(client->flags & SOCKET_HAVE_HELPNODE) {
+ for(helpnode = client->botclass_helpnode; helpnode; helpnode = helpnode->next) {
+ if(helpnode->suppid == suppid) {
+ if(helpnode->status)
+ content[1] = get_language_string(user, "NH_REQUESTS_STATE_ACTIVE");
+ else
+ content[1] = get_language_string(user, "NH_REQUESTS_STATE_PENDING");
+ content[2] = helpnode->user->nick;
+ break;
+ }
+ }
+ } else {
+ content[1] = get_language_string(user, "NH_REQUESTS_STATE_ERROR");
+ content[2] = NULL;
+ }
+ timeToStr(user, (time(0) - atoi(row[1])), 2, timestr);
+ content[3] = timestr;
+ char *p;
+ if((p = strstr(row[2], "\n")))
+ *p = '\0';
+ content[4] = row[2];
+ table_add(table, content);
+ }
+ //send the table
+ char **table_lines = table_end(table);
+ int i;
+ for(i = 0; i < table->entrys; i++) {
+ reply(getTextBot(), user, table_lines[i]);
+ }
+ if(table->entrys == 1)
+ reply(getTextBot(), user, "NS_TABLE_NONE");
+ table_free(table);
+}
--- /dev/null
+/* cmd_neonhelp_stats.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonhelp.h"
+
+/*
+* argv[0] user
+*/
+
+CMD_BIND(neonhelp_cmd_stats) {
+ //check permissions
+ MYSQL_RES *res;
+ MYSQL_ROW row, row2;
+ int caccess = 0;
+ printf_mysql_query("SELECT `helpserv_support`, `helpserv_public`, `helpserv_intern` FROM `helpserv_settings` WHERE `helpserv_botid` = '%d'", client->clientid);
+ res = mysql_use();
+ if (!(row = mysql_fetch_row(res))) return;
+ //check if the user is a supporter (access in the support channel)
+ if((user->flags & USERFLAG_ISAUTHED)) {
+ int userid;
+ if(user->flags & USERFLAG_HAS_USERID)
+ userid = user->user_id;
+ else {
+ printf_mysql_query("SELECT `user_id` FROM `users` WHERE `user_user` = '%s'", escape_string(user->auth));
+ res = mysql_use();
+ if ((row2 = mysql_fetch_row(res)) != NULL) {
+ userid = atoi(row2[0]);
+ user->user_id = userid;
+ user->flags |= USERFLAG_HAS_USERID;
+ } else
+ userid = 0;
+ }
+ printf_mysql_query("SELECT `chanuser_access`, `chanuser_flags` FROM `chanusers` LEFT JOIN `channels` ON `chanuser_cid` = `channel_id` WHERE `chanuser_uid` = '%d' AND `channel_name` = '%s'", userid, escape_string(row[0]));
+ res = mysql_use();
+ if ((row2 = mysql_fetch_row(res)) != NULL) {
+ int cflags = atoi(row2[1]);
+ if(!(cflags & DB_CHANUSER_SUSPENDED))
+ caccess = atoi(row2[0]);
+ }
+ }
+ if(!caccess) {
+ reply(getTextBot(), user, "MODCMD_ACCESS_DENIED");
+ return;
+ }
+ if(argc > 0) {
+ //following
+ } else {
+ struct Table *table;
+ printf_mysql_query("SELECT DISTINCT a.`supporter`, `user_user`, (SELECT COUNT(*) FROM `helpserv_requests` AS b WHERE b.`supporter` = a.`supporter` AND b.`time` > (UNIX_TIMESTAMP()-(3600*24))), (SELECT COUNT(*) FROM `helpserv_requests` AS b WHERE b.`supporter` = a.`supporter` AND b.`time` > (UNIX_TIMESTAMP()-(3600*24*7))), (SELECT COUNT(*) FROM `helpserv_requests` AS b WHERE b.`supporter` = a.`supporter` AND b.`time` > (UNIX_TIMESTAMP()-(3600*24*7*4))) FROM `helpserv_requests` AS a LEFT JOIN `users` ON a.`supporter` = `user_id` WHERE a.`time` > (UNIX_TIMESTAMP()-(3600*24*7*4)) AND `botid` = '%d' ORDER BY `user_user` ASC", client->clientid);
+ res = mysql_use();
+ table = table_init(4, mysql_num_rows(res) + 1, 0);
+ char *content[4];
+ content[0] = get_language_string(user, "NH_STATS_HEADER_USER");
+ content[1] = get_language_string(user, "NH_STATS_HEADER_LAST_24H");
+ content[2] = get_language_string(user, "NH_STATS_HEADER_LAST_7DAY");
+ content[3] = get_language_string(user, "NH_STATS_HEADER_LAST_30DAY");
+ table_add(table, content);
+ while ((row = mysql_fetch_row(res)) != NULL) {
+ content[0] = (strcmp(row[0], "-1") ? row[1] : "-");
+ content[1] = row[2];
+ content[2] = row[3];
+ content[3] = row[4];
+ table_add(table, content);
+ }
+ char **table_lines = table_end(table);
+ int i;
+ for(i = 0; i < table->entrys; i++) {
+ reply(getTextBot(), user, table_lines[i]);
+ }
+ if(table->entrys == 1)
+ reply(getTextBot(), user, "NS_TABLE_NONE");
+ table_free(table);
+ }
+}
--- /dev/null
+/* module.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "../module.h"
+#include "bot_NeonHelp.h"
+#include "cmd_neonhelp.h"
+
+static int module_initialize() {
+ register_commands();
+ return 0;
+}
+
+static void module_start(int type) {
+ init_NeonHelp(type);
+}
+
+static void module_loop() {
+ loop_NeonHelp();
+}
+
+static void module_stop(int type) {
+ free_NeonHelp(type);
+}
+
+MODULE_HEADER(module_initialize, module_start, module_loop, module_stop);
--- /dev/null
+/* bot_NeonServ.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "../module.h"
+
+#include "bot_NeonServ.h"
+#include "modcmd.h"
+#include "IRCEvents.h"
+#include "IRCParser.h"
+#include "UserNode.h"
+#include "ChanNode.h"
+#include "ChanUser.h"
+#include "BanNode.h"
+#include "ModeNode.h"
+#include "ClientSocket.h"
+#include "mysqlConn.h"
+#include "lang.h"
+#include "HandleInfoHandler.h"
+#include "WHOHandler.h"
+#include "DBHelper.h"
+#include "tools.h"
+#include "timeq.h"
+#include "EventLogger.h"
+#include "cmd_neonserv.h"
+#include "ConfigParser.h"
+
+#define BOTID 1
+#define BOTALIAS "NeonServ"
+
+static const struct default_language_entry msgtab[] = {
+ {"NS_USER_UNKNOWN", "User with nick $b%s$b does not exist."}, /* {ARGS: "TestUser"} */
+ {"NS_AUTH_UNKNOWN", "Account $b%s$b has not been registered."}, /* {ARGS: "TestAuth"} */
+ {"NS_USER_NEED_AUTH", "%s must first authenticate with $bAuthServ$b."}, /* {ARGS: "TestUser"} */
+ {"NS_YOU_NEED_AUTH", "You must first authenticate with $bAuthServ$b."},
+ {"NS_INVALID_ACCESS", "$b%d$b is an invalid access level."}, /* {ARGS: 1337} */
+ {"NS_ADDUSER_ALREADY_ADDED", "%s is already on the $b%s$b user list (with access %d)."}, /* {ARGS: "TestUser", "#TestChan", 123} */
+ {"NS_ADDUSER_DONE", "Added %s to the %s user list with access %d."}, /* {ARGS: "TestUser", "#TestChan", 123} */
+ {"NS_NOT_ON_USERLIST", "%s lacks access to $b%s$b."}, /* {ARGS: "TestUser", "#TestChan"} */
+ {"NS_NOT_ON_USERLIST_YOU", "You lack access to $b%s$b."}, /* {ARGS: "#TestChan"} */
+ {"NS_NOT_ON_CHANNEL", "%s isn't currently in $b%s$b."}, /* {ARGS: "TestUser", "#TestChan"} */
+ {"NS_NOT_ON_CHANNEL_YOU", "You aren't currently in $b%s$b."}, /* {ARGS: "#TestChan"} */
+ {"NS_DELUSER_DONE", "Deleted %s (with access %d) from the %s user list."}, /* {ARGS: "TestUser", 123, "#TestChan"} */
+ {"NS_ACCESS_OUTRANKED", "You cannot give users access greater than or equal to your own."},
+ {"NS_USER_OUTRANKED", "$b%s$b outranks you (command has no effect)."}, /* {ARGS: "TestUser"} */
+ {"NS_ACCESS_DENIED", "Access denied."},
+ {"NS_NO_ACCESS", "You lack sufficient access to use this command."},
+ {"NS_USER_PROTECTED", "Sorry, $b%s$b is protected."}, /* {ARGS: "TestUser"} */
+ {"NS_SERVICE_IMMUNE", "$b%s$b may not be kicked, killed, banned, or deopped."}, /* {ARGS: "TestUser"} */
+ {"NS_YOU_PROTECTED", "You may not kick or ban yourself."},
+ {"NS_TABLE_NONE", " None"},
+ {"NS_TABLE_COUNT", "Found $b%d$b matches."}, /* {ARGS: 5} */
+ {"NS_BAN_ALREADY_ADDED", "$b%s$b is already banned in %s."}, /* {ARGS: "*!*@moeeep.*", "#TestChan"} */
+ {"NS_INVALID_ACCESS_RANGE", "Invalid access range; minimum (%d) must be lower than maximum (%d)."}, /* {ARGS: 450, 400} */
+ {"NS_CLVL_DONE", "%s now has access $b%d$b in %s."}, /* {ARGS: "TestUser", 123, "#TestChan"} */
+ {"NS_A_LACKS_ACCESS_BUT_GOD_NICK", "%s lacks access to %s but has $bsecurity override$b enabled."}, /* {ARGS: "TestAuth", "#TestChan"} */
+ {"NS_A_LACKS_ACCESS_BUT_GOD_AUTH", "%s (%s) lacks access to %s but has $bsecurity override$b enabled."}, /* {ARGS: "TestAuth", "TestUser", "#TestChan"} */
+ {"NS_A_ACCESS_NICK", "%s has access $b%d$b in %s."}, /* {ARGS: "TestAuth", 123, "#TestChan"} */
+ {"NS_A_ACCESS_AUTH", "%s (%s) has access $b%d$b in %s."}, /* {ARGS: "TestAuth", "TestUser", 123, "#TestChan"} */
+ {"NS_A_ACCESS_NICK_GOD", "%s has access $b%d$b in %s and has $bsecurity override$b enabled."}, /* {ARGS: "TestAuth", 123, "#TestChan"} */
+ {"NS_A_ACCESS_AUTH_GOD", "%s (%s) has access $b%d$b in %s and has $bsecurity override$b enabled."}, /* {ARGS: "TestAuth", "TestUser", 123, "#TestChan"} */
+ {"NS_A_SUSPENDED", "$b%s$b's access to %s has been suspended."}, /* {ARGS: "TestAuth", "#TestChan"} */
+ {"NS_A_IS_IRCOP", "%s is an $bIRC operator$b."}, /* {ARGS: "TestUser", "#TestChan"} */
+ {"NS_USERS_HEADER", "%s users from level %d to %d:"}, /* {ARGS: "#TestChan", 1, 500} */
+ {"NS_USERS_HEADER_MATCH", "%s users from level %d to %d matching %s:"}, /* {ARGS: "#TestChan", 1, 500, "Test*"} */
+ {"NS_USERS_HEADER_ACCESS", "Access"},
+ {"NS_USERS_HEADER_ACCOUNT", "Accout"},
+ {"NS_USERS_HEADER_SEEN", "Last Seen"},
+ {"NS_USERS_HEADER_STATE", "Status"},
+ {"NS_USERS_COUNT", "There are $b%d$b users in %s."}, /* {ARGS: 20, "#TestChan"} */
+ {"NS_USERS_COUNT_1", "There is $b%d$b user in %s."}, /* {ARGS: 1, "#TestChan"} */
+ {"NS_USERS_COUNT_MATCH", "There are $b%d$b users in %s. ($b%d$b matching your request)"}, /* {ARGS: 20, "#TestChan", 5} */
+ {"NS_USERS_COUNT_MATCH_1", "There is $b%d$b user in %s. ($b%d$b matching your request)"}, /* {ARGS: 1, "#TestChan", 1} */
+ {"NS_USERS_SEEN_HERE", "Here"},
+ {"NS_USERS_SEEN_INVISIBLE", "Here (invisible)"},
+ {"NS_USERS_SEEN_NEVER", "Never"},
+ {"NS_USERS_STATE_SUSPENDED", "Suspended"},
+ {"NS_USERS_STATE_NORMAL", "Normal"},
+ {"NS_SUSPEND_ALREADY", "$b%s$b is already suspended." }, /* {ARGS: "TestUser"} */
+ {"NS_SUSPEND_NOT", "$b%s$b is not suspended." }, /* {ARGS: "TestUser"} */
+ {"NS_SUSPEND_DONE", "$b%s$b's access to $b%s$b has been suspended." }, /* {ARGS: "TestUser", "#TestChan"} */
+ {"NS_SUSPEND_RESTORED", "$b%s$b's access to $b%s$b has been restored." }, /* {ARGS: "TestUser", "#TestChan"} */
+ {"NS_DELME_OWNER", "You cannot delete your owner access in $b%s$b."}, /* {ARGS: "#TestChan"} */
+ {"NS_DELME_KEY", "To really remove yourself, you must use 'deleteme %s'."}, /* {ARGS: "abc123"} */
+ {"NS_DELME_DONE", "Your $b%d$b access has been deleted from $b%s$b."}, /* {ARGS: 123, "#TestChan"} */
+ {"NS_MYACCESS_SELF_ONLY", "You may only see the list of infolines for yourself (by using $bmyaccess$b with no arguments)."},
+ {"NS_MYACCESS_HEADER", "Showing all channel entries for account $b%s$b:"}, /* {ARGS: "TestAuth"} */
+ {"NS_MYACCESS_HEADER_MATCH", "Showing all channel entries for account $b%s$b matching %s:"}, /* {ARGS: "TestAuth", "#Test*"} */
+ {"NS_MYACCESS_HEADER_NAME", "Name"},
+ {"NS_MYACCESS_HEADER_ACCESS", "Access"},
+ {"NS_MYACCESS_HEADER_FLAGS", "Flags"},
+ {"NS_MYACCESS_HEADER_INFO", "Info"},
+ {"NS_MYACCESS_COUNT", "%s has access in $b%d$b channel(s) and is owner of $b%d$b channel(s)."}, /* {ARGS: "TestUser", 15, 5} */
+ {"NS_MYACCESS_COUNT_MATCH", "%s has access in $b%d$b channel(s) and is owner of $b%d$b channel(s) ($b%d$b channels matching your request)."}, /* {ARGS: "TestUser", 15, 5, 7} */
+ {"NS_UP_ALREADY_OP", "You are already opped in $b%s$b."}, /* {ARGS: "#TestChan"} */
+ {"NS_UP_ALREADY_VOICE", "You are already voiced in $b%s$b."}, /* {ARGS: "#TestChan"} */
+ {"NS_DOWN_ALREADY", "You are not opped or voiced in $b%s$b."}, /* {ARGS: "#TestChan"} */
+ {"NS_MDELUSER_DONE", "Deleted $b%d$b account(s) matching $b%s$b with access from $b%d$b to $b%d$b from the %s user list."}, /* {ARGS: 10, "Test*", 1, 200, "#TestChan"} */
+ {"NS_TRIM_DURATION_TOO_SHORT", "You must include a minimum inactivity duration of at least %d seconds to trim."},
+ {"NS_TRIM_DONE", "Trimmed $b%d users$b with access from %d to %d from the %s user list who were inactive for at least %s."}, /* {ARGS: 10, 1, 100, "#TestChan", "10 days"} */
+ {"NS_TRIM_BAN_DONE", "Trimmed $b%d bans$b from the %s ban list who were banned for at least %s."}, /* {ARGS: 5, "#TestChan", "1 day"} */
+ {"NS_GIVEOWNER_SELF", "You cannot give ownership to your own account."},
+ {"NS_GIVEOWNER_TIMEOUT", "You must wait %s before you can give ownership of $b%s$b to someone else."}, /* {ARGS: "5 hours", "#TestChan"} */
+ {"NS_GIVEOWNER_CONFIRM", "To really give ownership to $b%1$s$b, you must use 'giveownership *%1$s %2$s'."}, /* {ARGS: "TestUser", "abc123"} */
+ {"NS_GIVEOWNER_DONE", "Ownership of $b%s$b has been transferred to account $b%s$b."}, /* {ARGS: "#TestChan", "TestUser"} */
+ {"NS_OP_FAIL", "$b%s$b could not op some of the nicks you provided."}, /* {ARGS: "NeonServ"} */
+ {"NS_OP_DONE", "Opped users in $b%s$b."}, /* {ARGS: "#TestChan"} */
+ {"NS_HALFOP_FAIL", "$b%s$b could not halfop some of the nicks you provided."}, /* {ARGS: "NeonServ"} */
+ {"NS_HALFOP_DONE", "Half-Opped users in $b%s$b."}, /* {ARGS: "#TestChan"} */
+ {"NS_VOICE_FAIL", "$b%s$b could not voice some of the nicks you provided."}, /* {ARGS: "NeonServ"} */
+ {"NS_VOICE_DONE", "Voiced users in $b%s$b."}, /* {ARGS: "#TestChan"} */
+ {"NS_DEOP_FAIL", "$b%s$b could not deop some of the nicks you provided."}, /* {ARGS: "NeonServ"} */
+ {"NS_DEOP_DONE", "Deopped users in $b%s$b."}, /* {ARGS: "#TestChan"} */
+ {"NS_DEHALFOP_FAIL", "$b%s$b could not dehalfop some of the nicks you provided."}, /* {ARGS: "NeonServ"} */
+ {"NS_DEHALFOP_DONE", "Dehalfopped users in $b%s$b."}, /* {ARGS: "#TestChan"} */
+ {"NS_DEVOICE_FAIL", "$b%s$b could not devoice some of the nicks you provided."}, /* {ARGS: "NeonServ"} */
+ {"NS_DEVOICE_DONE", "Devoiced users in $b%s$b."}, /* {ARGS: "#TestChan"} */
+ {"NS_OPALL_SECURITY", "$bWARNING$b: Opping all users on a channel is very insecure! If you still want do op all users on %s use: '$bopall FORCE$b [nick mask]'"},
+ {"NS_OPALL_DONE", "Opped $b%d$b users in %s."}, /* {ARGS: 20, "#TestChan"} */
+ {"NS_HALFOPALL_DONE", "Half-Opped $b%d$b users in %s."}, /* {ARGS: 20, "#TestChan"} */
+ {"NS_VOICEALL_DONE", "Voiced $b%d$b users in %s."}, /* {ARGS: 20, "#TestChan"} */
+ {"NS_DEOPALL_DONE", "Deopped $b%d$b users in %s."}, /* {ARGS: 20, "#TestChan"} */
+ {"NS_DEHALFOPALL_DONE", "Dehalfopped $b%d$b users in %s."}, /* {ARGS: 20, "#TestChan"} */
+ {"NS_DEVOICEALL_DONE", "Devoiced $b%d$b users in %s."}, /* {ARGS: 20, "#TestChan"} */
+ {"NS_KICK_DONE", "Kicked $b%d$b users from %s"}, /* {ARGS: 20, "#TestChan"} */
+ {"NS_KICK_FAIL", "$b%s$b could not kick some of the nicks you provided."}, /* {ARGS: "NeonServ"} */
+ {"NS_KICKBAN_DONE", "KickBanned $b%d$b users from %s"}, /* {ARGS: 10, "#TestChan"} */
+ {"NS_KICKBAN_FAIL", "$b%s$b could not kickban some of the nicks you provided."}, /* {ARGS: "NeonServ"} */
+ {"NS_BAN_DONE", "$b%d$b masks added to the %s ban list. (matching %d users)"}, /* {ARGS: 5, "#TestChan", 15} */
+ {"NS_BAN_FAIL", "$b%s$b could not ban some of the nicks you provided."}, /* {ARGS: "NeonServ"} */
+ {"NS_LAME_MASK", "$b%s$b is a little too general. Try making it more specific."}, /* {ARGS: "*!*@*"} */
+ {"NS_LAME_MASK_WARNING", "$k4WARNING$k: $b%s$b is very general. (matches %d users)"},
+ {"NS_SET_HEADER", "Channel Settings for %s:"}, /* {ARGS: "#TestChan"} */
+ {"NS_SET_ON", "on"},
+ {"NS_SET_OFF", "off"},
+ {"NS_SET_UNKNOWN_SETTING", "$b%s$b is an unknown channel setting."}, /* {ARGS: "TestSetting"} */
+ {"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", "$b%d$b is not a valid choice. Choose one:"}, /* {ARGS: 5} */
+ {"NS_SET_INVALID_BOOLEAN", "$b%s$b is an invalid binary value."}, /* {ARGS: 2} */
+ {"NS_SET_DEFAULTS_OWNER", "You must have access 500 in %s to reset it to the default options."}, /* {ARGS: "#TestChan"} */
+ {"NS_SET_DEFAULTS_CODE", "To reset %s's settings to the defaults, you must use 'set defaults %s'."}, /* {ARGS: "#TestChan", "abc123"} */
+ {"NS_SET_DEFAULTS_DONE", "All settings for %s have been reset to default values."}, /* {ARGS: "#TestChan"} */
+ {"NS_SET_TRIGGER_OWNER", "You must have access 500 in %s to change the channel trigger."}, /* {ARGS: "#TestChan"} */
+ {"NS_SET_HELP_USERINFO","(access to set the userinfo)"},
+ {"NS_SET_HELP_WIPEINFO","(access to clear the userinfo of other users)"},
+ {"NS_SET_HELP_INVITEME","(access to get invited by the bot)"},
+ {"NS_SET_HELP_ENFVOICE","(access to give voice to other users)"},
+ {"NS_SET_HELP_ENFOPS","(access to give op to their users)"},
+ {"NS_SET_HELP_GIVEOPS","(access to get op by the bot)"},
+ {"NS_SET_HELP_GIVEVOICE","(access to get voice by the bot)"},
+ {"NS_SET_HELP_KICK","(access to kick other users from the channel)"},
+ {"NS_SET_HELP_BAN","(access to ban other users from the channel)"},
+ {"NS_SET_HELP_STATICBAN","(access to add static bans to the channel banlist e.g. +addban)"},
+ {"NS_SET_HELP_PUBCMD","(access to do public commands in the channel e.g. +users)"},
+ {"NS_SET_HELP_ENFMODES","(access to override the modelock)"},
+ {"NS_SET_HELP_ENFTOPIC","(access to override the topicmask)"},
+ {"NS_SET_HELP_TOPICSNARF","(access to set the default topic by changing the topic with /TOPIC)"},
+ {"NS_SET_HELP_CHANGETOPIC","(access to change the topic)"},
+ {"NS_SET_HELP_SETTERS","(access to change this settings)"},
+ {"NS_SET_HELP_ADDUSER","(access to add an user to the userlist)"},
+ {"NS_SET_HELP_DELUSER","(access to delete an user from the userlist)"},
+ {"NS_SET_HELP_CLVL","(access to change the access of an user in the userlist)"},
+ {"NS_SET_HELP_RESYNC","(access to synchronize the channelrights (@,+) with the userlist)"},
+ {"NS_SET_HELP_SUSPEND","(access to suspend an user on the userlist)"},
+ {"NS_SET_OPTION_CTCPREACTION_0","Kick on disallowed CTCPs"},
+ {"NS_SET_OPTION_CTCPREACTION_1","Kickban on disallowed CTCPs"},
+ {"NS_SET_OPTION_CTCPREACTION_2","Short timed ban on disallowed CTCPs"},
+ {"NS_SET_OPTION_CTCPREACTION_3","Long timed ban on disallowed CTCPs"},
+ {"NS_SET_OPTION_NOTICEREACTION_0","Kick on disallowed NOTICEs"},
+ {"NS_SET_OPTION_NOTICEREACTION_1","Kickban on disallowed NOTICEs"},
+ {"NS_SET_OPTION_NOTICEREACTION_2","Short timed ban on disallowed NOTICEs"},
+ {"NS_SET_OPTION_NOTICEREACTION_3","Long timed ban on disallowed NOTICEs"},
+ {"NS_SET_OPTION_PROTECT_0","All users will be protected from users with equal or lower access."},
+ {"NS_SET_OPTION_PROTECT_1","All users with access will be protected from users with equal or lower access."},
+ {"NS_SET_OPTION_PROTECT_2","All users with access will be protected from user with lower access."},
+ {"NS_SET_OPTION_PROTECT_3","Nobody will be protected."},
+ {"NS_SET_OPTION_TOYS_0","Funcommands can't be used."},
+ {"NS_SET_OPTION_TOYS_1","Funcommands are possible but the reply will be sent as a notice."},
+ {"NS_SET_OPTION_TOYS_2","Funcommands are possible and the reply will be sent to the channel."},
+ {"NS_SET_OPTION_DYNLIMIT_0","off"},
+ {"NS_SET_OPTION_NODELETE_0","off (only bot masters)"},
+ {"NS_SET_OPTION_NODELETE_1","on (only bot masters)"},
+ {"NS_WIPEINFO_DONE", "Removed $b%s$b's infoline in $b%s$b."}, /* {ARGS: "TestUser", "#TestChan"} */
+ {"NS_TRACE_HEADER", "The following users were found:"},
+ {"NS_ADDBAN_DONE", "$b%s$b permantly added to the %s ban list. (matching %d users)"}, /* {ARGS: "*!*@Test.*", "#TestChan", 4} */
+ {"NS_BANS_HEADER_MASK", "Mask"},
+ {"NS_BANS_HEADER_SETBY", "Set By"},
+ {"NS_BANS_HEADER_TRIGGERED", "Triggered"},
+ {"NS_BANS_HEADER_EXPIRES", "Expires"},
+ {"NS_BANS_HEADER_REASON", "Reason"},
+ {"NS_DELBAN_BANNED_BY", "%s is banned by %s."}, /* {ARGS: "*!*@bla*", "*!*@b*"} */
+ {"NS_DELBAN_FAIL", "Sorry, no ban found for $b%s$b."}, /* {ARGS: "*!*@bla*"} */
+ {"NS_DELBAN_DONE", "Removed $b%s$b from the %s ban list."}, /* {ARGS: "*!*@bla.*", "#TestChan"} */
+ {"NS_NETINFO_HEADER", "$bNetwork information$b"},
+ {"NS_NETINFO_BOTS", "Bots:"},
+ {"NS_NETINFO_UPTIME", "Uptime:"},
+ {"NS_NETINFO_TRAFFIC", "Traffic:"},
+ {"NS_NETINFO_CACHE", "Cache:"},
+ {"NS_NETINFO_DATABASE", "Database:"},
+ {"NS_NETINFO_CHANNEL", " Channel:"},
+ {"NS_NETINFO_CHANNEL_BAN", " Bans:"},
+ {"NS_NETINFO_USER", " User:"},
+ {"NS_NETINFO_CHANUSER", " Channel-User:"},
+ {"NS_NETINFO_OTHER", " Other:"},
+ {"NS_NETINFO_THREADS", "Threads:"},
+ {"NS_NETINFO_VERSION", "Version:"},
+ {"NS_NETINFO_CODE", "Code:"},
+ {"NS_NETINFO_CODE_VALUE", "%s lines c code (view it at http://dev.pk910.de/NeonServ)"}, /* {ARGS: 20} */
+ {"NS_NETINFO_COMPILER", "Compiler:"},
+ {"NS_NETINFO_COMPILER_VALUE", "%s (%s)"}, /* {ARGS: "GCC 4.4.5", "Sun Sep 18 2011 at 05:21:33 CEST"} */
+ {"NS_EXTTOPIC_INVALID_ID", "ADVANCEDTOPIC is enabled and $b%s$b is an invalid TOPIC ID. Valid topic id's are: 1-9"}, /* {ARGS: 10} */
+ {"NS_EXTTOPIC_TOPICID", "Topic %d: %s"}, /* {ARGS: 5, "topic"} */
+ {"NS_TOPIC_DONE", "Topic is now '%s'."}, /* {ARGS: "i like you :D"} */
+ {"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!"}, /* {ARGS: "CowBot"} */
+ {"NS_CHANSERVSYNC_KEY", "If you really want to synchronize the %s userlist with %s use: chanservsync %s %s"}, /* {ARGS: "#TestChan", "CowBot", "CowBot", "abc123"} */
+ {"NS_CHANSERVSYNC_INUSE", "$bchanservsync$b is already in use by someone else. Please try again in a few seconds..."},
+ {"NS_CHANSERVSYNC_SYNCHRONIZING", "Synchronizing userlist in %s with $b%s$b..."}, /* {ARGS: "#TestChan", "CowBot"} */
+ {"NS_CHANSERVSYNC_SYNCHRONIZED", "Synchronized user $b%s$b: access $b%d$b"}, /* {ARGS: "TestUser", 123} */
+ {"NS_REGISTER_ALREADY", "%s is already registered with %s."}, /* {ARGS: "#TestChan", "NeonServ"} */
+ {"NS_INVALID_CHANNEL_NAME", "%s is not a valid channel name."}, /* {ARGS: "#invalid"} */
+ {"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."}, /* {ARGS: "#TestChan"} */
+ {"NS_REGISTER_DONE", "$b%s$b is now registered to $b%s$b."}, /* {ARGS: "#TestChan", "TestUser"} */
+ {"NS_REGISTER_DONE_NOAUTH", "$b%s$b is now registered."}, /* {ARGS: "#TestChan"} */
+ {"NS_UNREGISTER_NOT_REGISTERED", "$b%s$b is not registered with %s."}, /* {ARGS: "#TestChan", "NeonServ"} */
+ {"NS_UNREGISTER_DONE", "$b%s$b unregistered."}, /* {ARGS: "#TestChan"} */
+ {"NS_RECOVER_DONE", "$b%s$b has been recovered."}, /* {ARGS: "#TestChan"} */
+ {"NS_RESYNC_DONE", "Synchronized users in $b%s$b with the userlist."}, /* {ARGS: "#TestChan"} */
+ {"NS_TIMEBAN_DURATION_TOO_SHORT", "You must specify a ban duration of at least %d seconds."}, /* {ARGS: 30} */
+ {"NS_TIMEBAN_DONE", "Banned $b%s$b from %s for %s. (matching %d users)"}, /* {ARGS: "*!*@bla*", "#TestChan", "2 hours", 5} */
+ {"NS_MODE_INVALID", "$b%c$b is an invalid set of channel modes."}, /* {ARGS: "+xyz"} */
+ {"NS_MODE_LOCKED", "Modes conflicting with $b%s$b are not allowed in %s."}, /* {ARGS: "+xyz", "#TestChan"} */
+ {"NS_MODE_DONE", "Channel modes are now $b%s$b."}, /* {ARGS: "+xyz"} */
+ {"NS_MODE_ENFOPS", "You may not op or deop users on $b%s$b."}, /* {ARGS: "#TestChan"} */
+ {"NS_MODE_ENFVOICE", "You may not voice or devoice users on $b%s$b."}, /* {ARGS: "#TestChan"} */
+ {"NS_MODE_CANBAN", "You may not ban or unban users on $b%s$b."}, /* {ARGS: "#TestChan"} */
+ {"NS_GOD_ON", "Security override has been enabled."},
+ {"NS_GOD_OFF", "Security override has been disabled."},
+ {"NS_PEEK_HEADER", "$b%s$b Status:"}, /* {ARGS: "#TestChan"} */
+ {"NS_PEEK_TOPIC", "Topic: %s"}, /* {ARGS: "TOPIC"} */
+ {"NS_PEEK_MODES", "Modes: %s"}, /* {ARGS: "+xyz"} */
+ {"NS_PEEK_USERS", "Total Users: %d (%d ops, %d voices, %d regulars, %d invisible)"}, /* {ARGS: 20, 4, 6, 8, 2} */
+ {"NS_PEEK_USERS_HALFOP", "Total Users: %d (%d ops, %d halfops, %d voices, %d regulars, %d invisible)"}, /* {ARGS: 25, 5, 4, 6, 8, 2} */
+ {"NS_PEEK_OPS", "Ops:"},
+ {"NS_USET_GLOBAL", "$b--- Global ---$b"},
+ {"NS_USET_CHANNEL", "$b--- User options (channel) ---$b"},
+ {"NS_USET_NO_ACCESS", "no access"},
+ {"NS_USET_UNKNOWN_SETTING", "$b%s$b is an unknown uset setting."}, /* {ARGS: "TestSetting"} */
+ {"NS_RELOADLANG_UNKNOWN", "$b%s$b is an unknown language tag."}, /* {ARGS: "de"} */
+ {"NS_RELOADLANG_DONE", "$b%s$b (%s) reloaded."}, /* {ARGS: "Deutsch", "de"} */
+ {"NS_UNBAN_DONE", "$b%d$b masks removed from the %s ban list."}, /* {ARGS: 5, "#TestChan"} */
+ {"NS_UNBAN_FAIL", "$b%s$b could not unban some of the masks you provided."}, /* {ARGS: "NeonServ"} */
+ {"NS_UNBANALL_DONE", "all $b%d$b masks removed from the %s ban list."}, /* {ARGS: 5, "#TestChan"} */
+ {"NS_UNBANALL_FAIL", "$b%s$b could not find any bans in %s."}, /* {ARGS: "NeonServ", "#TestChan"} */
+ {"NS_UNBANME_DONE", "removed $b%d$b masks from the %s ban list."}, /* {ARGS: 5, "#TestChan"} */
+ {"NS_UNBANME_FAIL", "$b%s$b could not find any bans matching %s."}, /* {ARGS: "NeonServ", "TestUser!TestIdent@TestUser.user.WebGamesNet"} */
+ {"NS_INVITE_RESTRICTION", "%s doesn't want to be invited to %s."}, /* {ARGS: "TestUser", "#TestChan"} */
+ {"NS_INVITE_TIMEOUT", "%s has already been invited to $b%s$b."}, /* {ARGS: "TestUser", "#TestChan"} */
+ {"NS_INVITE_ON_CHAN", "%s is already in $b%s$b."}, /* {ARGS: "TestUser", "#TestChan"} */
+ {"NS_INVITE_DONE_USER", "You have been invited to join $b%s$b by %s. (Do $b/msg %s %1$s uset noinvite 1$b if you don't want to be invited to %1$s anymore.)"}, /* {ARGS: "#TestChan", "TestUser", "NeonServ"} */
+ {"NS_INVITE_DONE", "Invited $b%s$b to join %s."}, /* {ARGS: "TestUser", "#TestChan"} */
+ {"NS_INVITEME_ON_CHAN", "You are already in $b%s$b."}, /* {ARGS: "#TestChan"} */
+ {"NS_INVITEME_DONE", "You have been invited to join %s."}, /* {ARGS: "#TestChan"} */
+ {"NS_HELP_TOPIC", "No help on that topic."},
+ {"NS_CSUSPEND_ALREADY", "$b%s$b is already suspended."}, /* {ARGS: "#TestChan"} */
+ {"NS_CSUSPEND_DONE", "Channel $b%s$b has been temporarily suspended."}, /* {ARGS: "#TestChan"} */
+ {"NS_CUNSUSPEND_NOT", "$b%s$b is not suspended."}, /* {ARGS: "#TestChan"} */
+ {"NS_CUNSUSPEND_DONE", "Channel $b%s$b has been restored."}, /* {ARGS: "#TestChan"} */
+ {"NS_MOVE_SUSPENDED", "Moving cannot be performed if the source channel is suspended."},
+ {"NS_MOVE_SELF", "Moving cannot be performed if the source and target channels are the same."},
+ {"NS_MOVE_DONE", "Channel $b%s$b has been moved to $b%s$b."}, /* {ARGS: "#TestChan", "#NewTestChan"} */
+ {"NS_BIND_ALREADY", "$b%s$b is already bound to %s."}, /* {ARGS: "TestCommand", "TestFunction"} */
+ {"NS_BIND_UNKNOWN", "$b%s$b is an undefined function."}, /* {ARGS: "TestFunction"} */
+ {"NS_BIND_DONE", "New command $b%s$b bound to %s."}, /* {ARGS: "TestCommand", "TestFunction"} */
+ {"NS_UNBIND_NOT_FOUND", "There is no command called $b%s$b bound."}, /* {ARGS: "TestCommand"} */
+ {"NS_UNBIND_DONE", "Unbound command $b%s$b."}, /* {ARGS: "TestCommand"} */
+ {"NS_EVENTS_HEADER", "The following channel events were found:"},
+ {"NS_OPLOG_HEADER", "The following oper events were found:"},
+ {"NS_SEARCH_HEADER", "The following channels were found:"},
+ {"NS_COMMAND_BINDING", "$b%s$b is a binding of %s %s"}, /* {ARGS: "TestCommand", "TestFunction", "TestParameters"} */
+ {"NS_COMMAND_ACCESS", "You need at least %d channel access and %d oper access to execute this command."}, /* {ARGS: 500, 100} */
+ {"NS_TOPIC_ACCESS", "You lack sufficient access in %s to change the topic."}, /* {ARGS: "#TestChan"} */
+ {"NS_BOTWAR_DETECTED", "$b$k4BOTWAR DETECTED!$k Please check the channel configuration!$b"},
+ {"NS_BOTWAR_REPORTED", "A supporter has been informed to help you preventing botwars in the future."},
+ {"NS_BOTWAR_ALERT", "$b$k4BOTWAR ALERT:$k$b Botwar in $b%s$b detected. (opponent: $b%s$b) Please join and help them preventing Botwars."}, /* {ARGS: "#TestChan", "OtherBot"} */
+ {"NS_INVITE_FAIL", "$b%s$b is not registered with %s or suspended."}, /* {ARGS: "#TestChan", "NeonServ"} */
+ {"NS_SETACCESS_DONE", "$b%s$b has now %d global access."}, /* {ARGS: "TestUser", 1000} */
+ {"NS_ADDRANK_EXISTS", "Another support ranking called '$b%s$b' already exists."}, /* {ARGS: "Supporter"} */
+ {"NS_ADDRANK_DONE", "Support ranking '$b%s$b' created."}, /* {ARGS: "Supporter"} */
+ {"NS_DELRANK_NOT_FOUND", "There is no support ranking called '$b%s$b'."}, /* {ARGS: "Supporter"} */
+ {"NS_DELRANK_DELETED", "Support ranking called '$b%s$b' removed."}, /* {ARGS: "Supporter"} */
+ {"NS_LISTRANK_ID", "Id"},
+ {"NS_LISTRANK_NAME", "Name"},
+ {"NS_LISTRANK_ASSIGNED", "Assigned to"},
+ {"NS_LISTRANK_UNRANKED", "There are also %d unranked users with global access."}, /* {ARGS: 10} */
+ {"NS_SETRANK_NOT_FOUND", "There is no support ranking with ID '$b%s$b'."}, /* {ARGS: 42} */
+ {"NS_SETRANK_HEAD", "Support ranking settings for Id %s:"}, /* {ARGS: 42} */
+ {"NS_SETRANK_UNKNOWN_SETTING", "$b%s$b is an unknown support rank setting."}, /* {ARGS: "moep"} */
+ {"NS_SETRANK_ORDER_INVALID", "%d is an invalid numeric value. (valid: 1-99)"}, /* {ARGS: 100} */
+ {"NS_ASSIGNRANK_DONE", "$b%s$b is now ranked as '$b%s$b'."}, /* {ARGS: "TestUser", "Supporter"} */
+ {"NS_INFO_HEADER", "$b%s$b Information:"}, /* {ARGS: "#TestChan"} */
+ {"NS_INFO_DEFAULTTOPIC", "Default Topic:"},
+ {"NS_INFO_MODELOCK", "Mode Lock:"},
+ {"NS_INFO_RECORD", "Record Visitors:"},
+ {"NS_INFO_OWNER", "Owner:"},
+ {"NS_INFO_USERS", "Total User Count:"},
+ {"NS_INFO_BANS", "Ban Count:"},
+ {"NS_INFO_VISITED", "Visited:"},
+ {"NS_INFO_REGISTERED", "Registered:"},
+ {"NS_INFO_REGISTRAR", "Registered by:"},
+ {"NS_INFO_OWNERLOG", "Ownership transfer history for $b%s$b:"}, /* {ARGS: "#TestChan"} */
+ {"NS_INFO_OWNERCHANGE", " from %s to %s on %s"},
+ {"NS_RENAME_DONE", "Renamed $b%s$b to $b%s$b."}, /* {ARGS: "TestUser", "TestUser2"} */
+ {"NS_RENAME_FAIL", "Failed renaming $b%s$b."}, /* {ARGS: "TestUser"} */
+ {"NS_FUN_DISABLED", "Fun commands are disabled in %s."}, /* {ARGS: "#TestChan"} */
+ {"NS_UNBIND_REQUIRED", "%1$s is a required function and there is no other command bound to %1$s. Bind another command to %1$s first."}, /* {ARGS: "bind"} */
+ {"NS_COMMANDS_NAME", "Name"},
+ {"NS_COMMANDS_ACCESS", "Access"},
+ {"NS_COMMANDS_GACCESS", "GodAccess"},
+ {"NS_COMMANDS_TRIGGERED", "Triggered"},
+ {"NS_COMMANDS_FUNCTION", "Function"},
+ {"NS_DNR_SET", "$b%s$b is do-not-register (by $b%s$b): %s" }, /* {ARGS: "#TestChan", "TestUser", "because of it is like it is"} */
+ {"NS_DNR_SET_EXPIRES", "$b%s$b is do-not-register (by $b%s$b; expires %s): %s" }, /* {ARGS: "#TestChan", "TestUser", "1 day", "because of it is like it is"} */
+ {"NS_DNR_SET_ANONYM", "$b%s$b is do-not-register. Please contact the support to get more information."}, /* {ARGS: "TestUser"} */
+ {"NS_NOREGISTER_INVALID_DURATION", "$b%s$b is not a valid duration."}, /* {ARGS: "möp"} */
+ {"NS_NOREGISTER_REGISTERED", "$b%s$b is currently registered and can't be added to the do-not-register list."}, /* {ARGS: "#TestChan"} */
+ {"NS_NOREGISTER_DONE", "added $b%s$b to the do-not-register list."}, /* {ARGS: "#TestChan"} */
+ {"NS_NOREGISTER_HEAD", "The following do-not-registers were found:"},
+ {"NS_DNR_TARGET", "Target"},
+ {"NS_DNR_USER", "Issuer"},
+ {"NS_DNR_EXPIRES", "Expires"},
+ {"NS_DNR_REASON", "Reason"},
+ {"NS_STAFF_LOGGEDIN", "Logged in as"},
+ {"NS_BOTS_ID", "Id"},
+ {"NS_BOTS_NICK", "Nick"},
+ {"NS_BOTS_SERVER", "Server:Port(:Pass)"},
+ {"NS_BOTS_CLASS", "Bot Class"},
+ {"NS_BOTS_FLAGS", "Flags"},
+ {"NS_BOTS_CHANNELS", "Channels"},
+ {"NS_BOTS_TRIGGER", "Trigger"},
+ {"NS_NICKLIST_NICK", "Nick"},
+ {"NS_NICKLIST_STATE", "State"},
+ {"NS_NICKLIST_ACCESS", "Access"},
+ {"NS_NICKLIST_SYNC", "use `nicklist sync` to fix all red and orange entrys in the list above (add opped users with %d and voiced with %d access)"},
+ {"NS_SETBOT_UNKNOWN", "`%d` is an unknown botid."}, /* {ARGS: 50} */
+ {"NS_SETBOT_HEADER", "$bSettings for botid `%d`:$b"}, /* {ARGS: 50} */
+ {"NS_SETBOT_SETTING", "$b%s$b is an unknown bot setting."}, /* {ARGS: "strangeSetting"} */
+ {"NS_SETBOT_NICK_INVALID", "`%s` is an invalid botnick."}, /* {ARGS: "-SuperMagicBananaBotWithManyFunctions"} */
+ {"NS_SETBOT_NEED_RESTART", "You need to reconnect the bot to apply this setting."},
+ {"NS_SETBOT_PORT_INVALID", "`%s` is an invalid port number."}, /* {ARGS: "-1"} */
+ {"NS_SETBOT_INVALID_CLASS", "`%s` is an invalid botclass."}, /* {ARGS: "MistColaLeer"} */
+ {"NS_SETBOT_MAXCHAN_INVALID", "`%s` is an invalid maxchan value."}, /* {ARGS: "-1"} */
+ {"NS_SETBOT_PRIORITY_INVALID", "`%s` is an invalid priority value."}, /* {ARGS: "-1"} */
+ {"NS_SETBOT_TRIGGER_INVALID", "`%s` is an invalid bot trigger."}, /* {ARGS: "tooLongTrigger"} */
+ {"NS_SETBOT_TRIGGER_NOTE", "Please note: This Setting will only affect new channels."},
+ {"NS_ADDBOT_EXISTING", "A bot with nick %s does already exist."}, /* {ARGS: "NeonServ"} */
+ {"NS_ADDBOT_DONE", "Added %s with BotID $b%d$b."}, /* {ARGS: "NeonServ", 2} */
+ {"NS_DELBOT_NOT_FOUND", "Bot with BotID / nick $b%s$b not found."}, /* {ARGS: "NeonServ"} */
+ {"NS_DELBOT_DONE", "Bot deleted."},
+ {"NS_RECONNECT_DONE", "Reconnected bot."},
+ {"NS_MODCMD_SETTING", "$b%s$b is an unknown modcmd setting."}, /* {ARGS: "strangeSetting"} */
+ {"NS_MODCMD_HEADER", "$bSettings for command %s:$b"}, /* {ARGS: "access"} */
+ {"NS_MODCMD_OUTRANKED", "$b%s$b outranks you. (required access: %d)"}, /* {ARGS: "die", 1000} */
+ {"NS_MODCMD_STATIC_FLAG", "This Flag is added statically. It can't be modified manually."},
+ {"NS_MEMINFO_DISABLED", "Memory Debugger is disabled!"},
+ {"NS_MEMINFO_NAME", "Name"},
+ {"NS_MEMINFO_COUNT", "Count"},
+ {"NS_MEMINFO_SIZE", "Size"},
+ {"NS_MEMINFO_LINE", "Line"},
+ {"NS_MEMINFO_TOTAL", "Total"},
+ {NULL, NULL}
+};
+
+/* TODO:
+cmd_neonserv_open.c
+set modelock
+cmd_neonserv_modcmd.c
+cmd_neonserv_allowregister.c
+cmd_neonserv_noregister.c
+cmd_neonserv_expire.c
+cmd_neonserv_unvisited.c
+cmd_neonserv_merge.c
+cmd_neonserv_dnrsearch.c
+cmd_neonserv_iplocate.c
+cmd_neonserv_calc.c
+*/
+//EVENTS
+#include "event_neonserv_join.c"
+#include "event_neonserv_part.c"
+#include "event_neonserv_quit.c"
+#include "event_neonserv_kick.c"
+#include "event_neonserv_mode.c"
+#include "event_neonserv_ctcp.c"
+#include "event_neonserv_notice.c"
+#include "event_neonserv_invite.c"
+#include "event_neonserv_topic.c"
+
+
+struct ClientSocket *getBotForChannel(struct ChanNode *chan) {
+ return getChannelBot(chan, BOTID);
+}
+
+static void neonserv_bot_ready(struct ClientSocket *client) {
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+
+ printf_mysql_query("SELECT `automodes` FROM `bots` WHERE `id` = '%d'", client->clientid);
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) != NULL) {
+ putsock(client, "MODE %s +%s", client->user->nick, row[0]);
+ }
+
+ printf_mysql_query("SELECT `channel_name`, `channel_key` FROM `bot_channels` LEFT JOIN `channels` ON `chanid` = `channel_id` WHERE `botid` = '%d' AND `suspended` = '0'", client->clientid);
+ res = mysql_use();
+
+ while ((row = mysql_fetch_row(res)) != NULL) {
+ putsock(client, "JOIN %s %s", row[0], row[1]);
+ }
+}
+
+static void neonserv_trigger_callback(int clientid, struct ChanNode *chan, char *trigger) {
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ loadChannelSettings(chan);
+ if(!(chan->flags & CHANFLAG_CHAN_REGISTERED)) {
+ strcpy(trigger, "+");
+ return;
+ }
+ printf_mysql_query("SELECT `trigger`, `defaulttrigger` FROM `bot_channels` LEFT JOIN `bots` ON `botid` = `bots`.`id` WHERE `chanid` = '%d' AND `botclass` = '%d'", chan->channel_id, BOTID);
+ res = mysql_use();
+ if(!(row = mysql_fetch_row(res))) {
+ strcpy(trigger, "+");
+ return;
+ }
+ if(row[0] && *row[0])
+ strcpy(trigger, row[0]);
+ else
+ strcpy(trigger, ((row[1] && *row[1]) ? row[1] : "~"));
+}
+
+static void start_bots(int type) {
+ struct ClientSocket *client;
+ MYSQL_RES *res, *res2;
+ MYSQL_ROW row;
+
+ if(type == MODSTATE_STARTSTOP) {
+ printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `textbot`, `id`, `queue`, `ssl`, `bind` FROM `bots` WHERE `botclass` = '%d' AND `active` = '1'", BOTID);
+ res = mysql_use();
+ while ((row = mysql_fetch_row(res)) != NULL) {
+ client = create_socket(row[3], atoi(row[4]), row[10], row[5], row[0], row[1], row[2]);
+ client->flags |= (strcmp(row[6], "0") ? SOCKET_FLAG_PREFERRED : 0);
+ client->flags |= (strcmp(row[8], "0") ? SOCKET_FLAG_USE_QUEUE : 0);
+ client->flags |= (strcmp(row[9], "0") ? SOCKET_FLAG_SSL : 0);
+ client->botid = BOTID;
+ client->clientid = atoi(row[7]);
+ connect_socket(client);
+ }
+ }
+
+ printf_mysql_query("SELECT `command`, `function`, `parameters`, `global_access`, `chan_access`, `flags` FROM `bot_binds` WHERE `botclass` = '%d'", BOTID);
+ res2 = mysql_use();
+ while ((row = mysql_fetch_row(res2)) != NULL) {
+ if(bind_cmd_to_command(BOTID, row[0], row[1])) {
+ if(row[2] && strcmp(row[2], "")) {
+ bind_set_parameters(BOTID, row[0], row[2]);
+ }
+ if(row[3]) {
+ bind_set_global_access(BOTID, row[0], atoi(row[3]));
+ }
+ if(row[4]) {
+ bind_set_channel_access(BOTID, row[0], row[4]);
+ }
+ if(strcmp(row[5], "0"))
+ bind_set_bind_flags(BOTID, row[0], atoi(row[5]));
+ }
+ }
+ bind_unbound_required_functions(BOTID);
+}
+
+void init_NeonServ(int type) {
+ set_bot_alias(BOTID, BOTALIAS);
+ start_bots(type);
+
+ if(type == MODSTATE_REBIND) return;
+
+ //register events
+ bind_bot_ready(neonserv_bot_ready, module_id);
+ bind_join(neonserv_event_join, module_id);
+ bind_part(neonserv_event_part, module_id);
+ bind_quit(neonserv_event_quit, module_id);
+ bind_chanctcp(neonserv_event_chanctcp, module_id);
+ bind_privctcp(general_event_privctcp, module_id);
+ bind_channotice(neonserv_event_channotice, module_id);
+ bind_topic(neonserv_event_topic, module_id);
+ bind_invite(neonserv_event_invite, module_id);
+ bind_mode(neonserv_event_mode, module_id);
+ bind_kick(neonserv_event_kick, module_id);
+
+ set_trigger_callback(BOTID, module_id, neonserv_trigger_callback);
+
+ register_default_language_table(msgtab);
+}
+
+void loop_NeonServ() {
+
+}
+
+void free_NeonServ(int type) {
+ unbind_allcmd(BOTID);
+ if(type == MODSTATE_STARTSTOP) {
+ //disconnect all our bots
+ struct ClientSocket *client;
+ for(client = getBots(0, NULL); client; client = getBots(0, client)) {
+ if(client->botid == BOTID) {
+ unbind_botwise_allcmd(0, client->clientid);
+ close_socket(client);
+ break;
+ }
+ }
+ }
+}
+
+#undef BOTID
+#undef BOTALIAS
--- /dev/null
+/* bot_NeonServ.h - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef _bot_NeonServ_h
+#define _bot_NeonServ_h
+
+#include "main.h"
+
+struct ChanNode;
+
+void init_NeonServ(int type);
+void loop_NeonServ();
+void free_NeonServ(int type);
+
+struct ClientSocket *getBotForChannel(struct ChanNode *chan);
+
+#endif
\ No newline at end of file
--- /dev/null
+/* cmd_neonserv.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "../module.h"
+#include "cmd_neonserv.h"
+#include "modcmd.h"
+#include "ConfigParser.h"
+
+void register_commands() {
+ //NeonServ Commands
+ register_command_alias(1, "NeonServ");
+
+ #define USER_COMMAND(NAME,FUNCTION,PARAMCOUNT,PRIVS,FLAGS) register_command(1, NAME, module_id, FUNCTION, PARAMCOUNT, PRIVS, 0, FLAGS)
+ // NAME FUNCTION PARAMS PRIVS FLAGS
+ USER_COMMAND("adduser", neonserv_cmd_adduser, 2, "#channel_canadd", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
+ USER_COMMAND("deluser", neonserv_cmd_deluser, 1, "#channel_candel", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
+ USER_COMMAND("clvl", neonserv_cmd_clvl, 2, "#channel_canclvl", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
+ USER_COMMAND("access", neonserv_cmd_access, 0, NULL, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_LOG);
+ USER_COMMAND("users", neonserv_cmd_users, 0, NULL, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_NO_CROSSCHAN);
+ USER_COMMAND("suspend", neonserv_cmd_suspend, 1, "#channel_cansuspend", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
+ USER_COMMAND("unsuspend", neonserv_cmd_unsuspend, 1, "#channel_cansuspend", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
+ USER_COMMAND("delme", neonserv_cmd_delme, 0, "1", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
+ USER_COMMAND("myaccess", neonserv_cmd_myaccess, 0, NULL, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH);
+ USER_COMMAND("up", neonserv_cmd_up, 0, NULL, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
+ USER_COMMAND("down", neonserv_cmd_down, 0, NULL, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_LOG);
+ USER_COMMAND("upall", neonserv_cmd_upall, 0, NULL, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
+ USER_COMMAND("downall", neonserv_cmd_downall, 0, NULL, CMDFLAG_LOG);
+ USER_COMMAND("mdeluser", neonserv_cmd_mdeluser, 2, "#channel_candel", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
+ USER_COMMAND("trim", neonserv_cmd_trim, 2, NULL, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
+ USER_COMMAND("giveowner", neonserv_cmd_giveowner, 1, "500", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
+ USER_COMMAND("op", neonserv_cmd_op, 1, "@#channel_getop,#channel_canop", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
+ USER_COMMAND("deop", neonserv_cmd_deop, 1, "@#channel_getop,#channel_canop", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
+ USER_COMMAND("voice", neonserv_cmd_voice, 1, "+#channel_getvoice,#channel_canvoice", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
+ USER_COMMAND("devoice", neonserv_cmd_devoice, 1, "+#channel_getvoice,#channel_canvoice", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
+ USER_COMMAND("opall", neonserv_cmd_opall, 0, "@#channel_getop,#channel_canop", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
+ USER_COMMAND("deopall", neonserv_cmd_deopall, 0, "@#channel_getop,#channel_canop", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
+ USER_COMMAND("voiceall", neonserv_cmd_voiceall, 0, "+#channel_getvoice,#channel_canvoice", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
+ USER_COMMAND("devoiceall", neonserv_cmd_devoiceall,0, "+#channel_getvoice,#channel_canvoice", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
+ if(get_int_field("General.have_halfop")) {
+ USER_COMMAND("halfop", neonserv_cmd_halfop, 1, "%#channel_gethalfop,#channel_canhalfop", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
+ USER_COMMAND("dehalfop", neonserv_cmd_dehalfop, 1, "%#channel_gethalfop,#channel_canhalfop", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
+ USER_COMMAND("halfopall", neonserv_cmd_halfopall, 0, "%#channel_gethalfop,#channel_canhalfop", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
+ USER_COMMAND("dehalfopall", neonserv_cmd_dehalfopall,0,"%#channel_gethalfop,#channel_canhalfop", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
+ }
+ USER_COMMAND("set", neonserv_cmd_set, 0, "#channel_setters", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
+ USER_COMMAND("kick", neonserv_cmd_kick, 1, "#channel_cankick", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
+ USER_COMMAND("kickban", neonserv_cmd_kickban, 1, "#channel_cankick,#channel_canban", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
+ USER_COMMAND("ban", neonserv_cmd_ban, 1, "#channel_canban", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
+ USER_COMMAND("wipeinfo", neonserv_cmd_wipeinfo, 1, "#channel_wipeinfo", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
+ USER_COMMAND("addban", neonserv_cmd_addban, 1, "#channel_staticban", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
+ USER_COMMAND("bans", neonserv_cmd_bans, 0, "1", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH);
+ USER_COMMAND("delban", neonserv_cmd_delban, 1, "#channel_staticban", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
+ USER_COMMAND("topic", neonserv_cmd_topic, 0, "#channel_changetopic", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
+ USER_COMMAND("chanservsync", neonserv_cmd_chanservsync, 0,"500", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
+ USER_COMMAND("resync", neonserv_cmd_resync, 0, "#channel_canresync", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
+ USER_COMMAND("addtimeban", neonserv_cmd_addtimeban,2, "#channel_staticban", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
+ USER_COMMAND("mode", neonserv_cmd_mode, 1, "#channel_getop", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
+ USER_COMMAND("peek", neonserv_cmd_peek, 0, NULL, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_NO_CROSSCHAN);
+ USER_COMMAND("uset", neonserv_cmd_uset, 0, NULL, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_NO_CROSSCHAN);
+ USER_COMMAND("unban", neonserv_cmd_unban, 1, "#channel_canban", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
+ USER_COMMAND("unbanall", neonserv_cmd_unbanall, 0, "#channel_canban", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
+ USER_COMMAND("unbanme", neonserv_cmd_unbanme, 0, "#channel_canban", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
+ USER_COMMAND("invite", neonserv_cmd_invite, 1, "#channel_canop", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
+ USER_COMMAND("inviteme", neonserv_cmd_inviteme, 0, "#channel_getinvite", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
+ USER_COMMAND("help", neonserv_cmd_help, 0, NULL, 0);
+ USER_COMMAND("events", neonserv_cmd_events, 0, "1", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH);
+ USER_COMMAND("info", neonserv_cmd_info, 0, NULL, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_NO_CROSSCHAN);
+ USER_COMMAND("extscript", neonserv_cmd_extscript, 0, NULL, CMDFLAG_EMPTY_ARGS | CMDFLAG_CHAN_PARAM);
+ USER_COMMAND("nicklist", neonserv_cmd_nicklist, 0, "1", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH);
+ #undef USER_COMMAND
+
+ #define OPER_COMMAND(NAME,FUNCTION,PARAMCOUNT,GACCESS,FLAGS) register_command(1, NAME, module_id, FUNCTION, PARAMCOUNT, NULL, GACCESS, FLAGS)
+ // NAME FUNCTION PARAMS ACCS FLAGS
+ OPER_COMMAND("trace", neonserv_cmd_trace, 1, 400, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH);
+ OPER_COMMAND("recover", neonserv_cmd_recover, 1, 200, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_CHAN_PARAM | CMDFLAG_OPLOG);
+ OPER_COMMAND("csuspend", neonserv_cmd_csuspend, 1, 100, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_CHAN_PARAM | CMDFLAG_OPLOG);
+ OPER_COMMAND("cunsuspend", neonserv_cmd_cunsuspend,1, 100, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_CHAN_PARAM | CMDFLAG_OPLOG);
+ OPER_COMMAND("move", neonserv_cmd_move, 2, 300, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_CHAN_PARAM | CMDFLAG_OPLOG);
+ OPER_COMMAND("oplog", neonserv_cmd_oplog, 0, 1, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG);
+ OPER_COMMAND("search", neonserv_cmd_search, 1, 400, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH);
+ OPER_COMMAND("addrank", neonserv_cmd_addrank, 1, 1000, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG);
+ OPER_COMMAND("delrank", neonserv_cmd_delrank, 1, 1000, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG);
+ OPER_COMMAND("setrank", neonserv_cmd_setrank, 1, 1000, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG);
+ OPER_COMMAND("assignrank", neonserv_cmd_assignrank,2, 1000, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG);
+ OPER_COMMAND("listrank", neonserv_cmd_listrank, 0, 1, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG);
+ OPER_COMMAND("rename", neonserv_cmd_rename, 2, 300, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG);
+ OPER_COMMAND("unvisited", neonserv_cmd_unvisited, 0, 400, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG);
+ OPER_COMMAND("noregister", neonserv_cmd_noregister,0, 300, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_CHAN_PARAM | CMDFLAG_OPLOG);
+ #undef OPER_COMMAND
+}
--- /dev/null
+/* cmd_neonserv.h - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef _cmd_neonserv_h
+#define _cmd_neonserv_h
+#include "../module.h"
+#include "main.h"
+#include "modcmd.h"
+#include "IRCParser.h"
+#include "IRCEvents.h"
+#include "UserNode.h"
+#include "ChanNode.h"
+#include "ChanUser.h"
+#include "ModeNode.h"
+#include "BanNode.h"
+#include "ClientSocket.h"
+#include "mysqlConn.h"
+#include "lang.h"
+#include "HandleInfoHandler.h"
+#include "WHOHandler.h"
+#include "DBHelper.h"
+#include "tools.h"
+#include "timeq.h"
+#include "version.h"
+#include "EventLogger.h"
+#include "bots.h"
+#include "bot_NeonServ.h"
+#include "ConfigParser.h"
+
+void register_commands();
+
+CMD_BIND(neonserv_cmd_access);
+CMD_BIND(neonserv_cmd_addban);
+CMD_BIND(neonserv_cmd_addrank);
+CMD_BIND(neonserv_cmd_addtimeban);
+CMD_BIND(neonserv_cmd_adduser);
+CMD_BIND(neonserv_cmd_assignrank);
+CMD_BIND(neonserv_cmd_ban);
+CMD_BIND(neonserv_cmd_bans);
+CMD_BIND(neonserv_cmd_chanservsync);
+CMD_BIND(neonserv_cmd_clvl);
+CMD_BIND(neonserv_cmd_csuspend);
+CMD_BIND(neonserv_cmd_cunsuspend);
+CMD_BIND(neonserv_cmd_dehalfop);
+CMD_BIND(neonserv_cmd_dehalfopall);
+CMD_BIND(neonserv_cmd_delban);
+CMD_BIND(neonserv_cmd_delme);
+CMD_BIND(neonserv_cmd_delrank);
+CMD_BIND(neonserv_cmd_deluser);
+CMD_BIND(neonserv_cmd_deop);
+CMD_BIND(neonserv_cmd_deopall);
+CMD_BIND(neonserv_cmd_devoice);
+CMD_BIND(neonserv_cmd_devoiceall);
+CMD_BIND(neonserv_cmd_down);
+CMD_BIND(neonserv_cmd_downall);
+CMD_BIND(neonserv_cmd_events);
+CMD_BIND(neonserv_cmd_extscript);
+CMD_BIND(neonserv_cmd_giveowner);
+CMD_BIND(neonserv_cmd_halfop);
+CMD_BIND(neonserv_cmd_halfopall);
+CMD_BIND(neonserv_cmd_help);
+CMD_BIND(neonserv_cmd_info);
+CMD_BIND(neonserv_cmd_invite);
+CMD_BIND(neonserv_cmd_inviteme);
+CMD_BIND(neonserv_cmd_kick);
+CMD_BIND(neonserv_cmd_kickban);
+CMD_BIND(neonserv_cmd_listrank);
+CMD_BIND(neonserv_cmd_mdeluser);
+CMD_BIND(neonserv_cmd_mode);
+CMD_BIND(neonserv_cmd_move);
+CMD_BIND(neonserv_cmd_myaccess);
+CMD_BIND(neonserv_cmd_nicklist);
+CMD_BIND(neonserv_cmd_noregister);
+CMD_BIND(neonserv_cmd_op);
+CMD_BIND(neonserv_cmd_opall);
+CMD_BIND(neonserv_cmd_oplog);
+CMD_BIND(neonserv_cmd_peek);
+CMD_BIND(neonserv_cmd_recover);
+CMD_BIND(neonserv_cmd_rename);
+CMD_BIND(neonserv_cmd_resync);
+CMD_BIND(neonserv_cmd_search);
+CMD_BIND(neonserv_cmd_set);
+CMD_BIND(neonserv_cmd_setrank);
+CMD_BIND(neonserv_cmd_suspend);
+CMD_BIND(neonserv_cmd_topic);
+CMD_BIND(neonserv_cmd_trace);
+CMD_BIND(neonserv_cmd_trim);
+CMD_BIND(neonserv_cmd_unban);
+CMD_BIND(neonserv_cmd_unbanall);
+CMD_BIND(neonserv_cmd_unbanme);
+CMD_BIND(neonserv_cmd_unsuspend);
+CMD_BIND(neonserv_cmd_unvisited);
+CMD_BIND(neonserv_cmd_up);
+CMD_BIND(neonserv_cmd_upall);
+CMD_BIND(neonserv_cmd_users);
+CMD_BIND(neonserv_cmd_uset);
+CMD_BIND(neonserv_cmd_voice);
+CMD_BIND(neonserv_cmd_voiceall);
+CMD_BIND(neonserv_cmd_wipeinfo);
+
+#endif
\ No newline at end of file
--- /dev/null
+/* cmd_neonserv_access.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* argv[0] - nick / *auth
+*/
+static USERAUTH_CALLBACK(neonserv_cmd_access_nick_lookup);
+static void neonserv_cmd_access_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, char *nick, char *auth, struct UserNode *target);
+static void neonserv_cmd_access_filter_ranking_info(char *info, char *buffer, char *nick, char *auth, char *rank_name);
+
+struct neonserv_cmd_access_cache {
+ struct ClientSocket *client, *textclient;
+ struct UserNode *user;
+ struct ChanNode *chan;
+ char *nick;
+};
+
+CMD_BIND(neonserv_cmd_access) {
+ if(argc == 0) {
+ if(!(user->flags & USERFLAG_ISAUTHED)) {
+ struct neonserv_cmd_access_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(user->nick);
+ get_userauth(user, neonserv_cmd_access_nick_lookup, cache);
+ } else
+ neonserv_cmd_access_async1(client, getTextBot(), user, chan, user->nick, user->auth, user);
+ }
+ else if(argv[0][0] == '*') {
+ //we've got an auth
+ argv[0]++;
+ neonserv_cmd_access_async1(client, getTextBot(), user, chan, NULL, argv[0], NULL);
+ } else {
+ struct UserNode *cuser = getUserByNick(argv[0]);
+ if(!cuser) {
+ cuser = createTempUser(argv[0]);
+ if(!cuser) {
+ reply(getTextBot(), user, "NS_USER_UNKNOWN", argv[0]);
+ return;
+ }
+ cuser->flags |= USERFLAG_ISTMPUSER;
+ }
+ if(cuser->flags & USERFLAG_ISAUTHED) {
+ neonserv_cmd_access_async1(client, getTextBot(), user, chan, argv[0], cuser->auth, cuser);
+ } else {
+ struct neonserv_cmd_access_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]);
+ get_userauth(cuser, neonserv_cmd_access_nick_lookup, cache);
+ }
+ }
+}
+
+static USERAUTH_CALLBACK(neonserv_cmd_access_nick_lookup) {
+ struct neonserv_cmd_access_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
+ if(!strcmp(cache->nick, cache->user->nick))
+ reply(cache->textclient, cache->user, "NS_YOU_NEED_AUTH");
+ else
+ reply(cache->textclient, cache->user, "NS_USER_NEED_AUTH", cache->nick);
+ }
+ else
+ neonserv_cmd_access_async1(cache->client, cache->textclient, cache->user, cache->chan, user->nick, user->auth, user);
+ free(cache->nick);
+ free(cache);
+}
+
+static void neonserv_cmd_access_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, char *nick, char *auth, struct UserNode *target) {
+ //we've got a valid auth now...
+ MYSQL_RES *res;
+ MYSQL_ROW user_row, chanuser_row;
+ int userid;
+ printf_mysql_query("SELECT `user_id`, `user_access`, `user_god`, `user_rank`, `rank_info`, `rank_name` FROM `users` LEFT JOIN `support_ranks` ON `rank_id` = `user_rank` WHERE `user_user` = '%s'", escape_string(auth));
+ res = mysql_use();
+ if ((user_row = mysql_fetch_row(res)) != NULL) {
+ userid = atoi(user_row[0]);
+ //check if the user is already added
+ printf_mysql_query("SELECT `chanuser_access`, `chanuser_flags`, `chanuser_infoline` FROM `chanusers` WHERE `chanuser_cid` = '%d' AND `chanuser_uid` = '%d'", chan->channel_id, userid);
+ res = mysql_use();
+ if(strcmp(user_row[3], "0") && strcmp(user_row[4], "")) {
+ char rank_info[MAXLEN];
+ neonserv_cmd_access_filter_ranking_info(user_row[4], rank_info, nick, auth, user_row[5]);
+ reply(textclient, user, "%s", rank_info);
+ }
+ if ((chanuser_row = mysql_fetch_row(res)) != NULL) {
+ //access output
+ if(nick)
+ reply(textclient, user, (strcmp(user_row[2], "1") ? "NS_A_ACCESS_AUTH" : "NS_A_ACCESS_AUTH_GOD"), nick, auth, atoi(chanuser_row[0]), chan->name);
+ else
+ reply(textclient, user, (strcmp(user_row[2], "1") ? "NS_A_ACCESS_NICK" : "NS_A_ACCESS_NICK_GOD"), auth, atoi(chanuser_row[0]), chan->name);
+ int cflags = atoi(chanuser_row[1]);
+ if(cflags & DB_CHANUSER_SUSPENDED)
+ reply(textclient, user, "NS_A_SUSPENDED", (nick ? nick : auth), chan->name);
+ if(chanuser_row[2] && strcmp(chanuser_row[2], ""))
+ reply(textclient, user, "[%s] %s", (nick ? nick : auth), chanuser_row[2]);
+ } else if(!strcmp(user_row[2], "1")) {
+ if(nick)
+ reply(textclient, user, "NS_A_LACKS_ACCESS_BUT_GOD_AUTH", nick, auth, chan->name);
+ else
+ reply(textclient, user, "NS_A_LACKS_ACCESS_BUT_GOD_NICK", auth, chan->name);
+ } else
+ reply(textclient, user, "NS_NOT_ON_USERLIST", (nick ? nick : auth), chan->name);
+ } else
+ reply(textclient, user, "NS_NOT_ON_USERLIST", (nick ? nick : auth), chan->name);
+ if(target && (target->flags & USERFLAG_ISIRCOP))
+ reply(textclient, user, "NS_A_IS_IRCOP", nick);
+}
+
+static void neonserv_cmd_access_filter_ranking_info(char *info, char *buffer, char *nick, char *auth, char *rank_name) {
+ int bufferPos = 0;
+ char *a, *b = info;
+ do {
+ if(!b) break;
+ a = strstr(b, "$");
+ if(a) *a = '\0';
+ bufferPos += sprintf(buffer + bufferPos, "%s", b);
+ if(!a) break;
+ switch(a[1]) {
+ case '\0':
+ a = NULL;
+ break;
+ case 'U':
+ bufferPos += sprintf(buffer + bufferPos, "%s", auth);
+ break;
+ case 'N':
+ bufferPos += sprintf(buffer + bufferPos, "%s", (nick ? nick : auth));
+ break;
+ case 'R':
+ bufferPos += sprintf(buffer + bufferPos, "%s", rank_name);
+ break;
+ default:
+ buffer[bufferPos++] = '$';
+ buffer[bufferPos++] = a[1];
+ break;
+ }
+ if(a)
+ b = a+2;
+ } while(a);
+}
--- /dev/null
+/* cmd_neonserv_addban.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* argv[0] nick|*auth|*!*@mask
+* argv[1-*] reason
+*/
+static USERLIST_CALLBACK(neonserv_cmd_addban_userlist_lookup);
+static void neonserv_cmd_addban_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *mas, char *reason);
+
+struct neonserv_cmd_addban_cache {
+ struct ClientSocket *client, *textclient;
+ struct UserNode *user;
+ struct Event *event;
+ char *mask;
+ char *reason;
+};
+
+CMD_BIND(neonserv_cmd_addban) {
+ struct neonserv_cmd_addban_cache *cache = malloc(sizeof(*cache));
+ if (!cache) {
+ perror("malloc() failed");
+ return;
+ }
+ cache->client = client;
+ cache->textclient = getTextBot();
+ cache->user = user;
+ cache->event = event;
+ cache->mask = strdup(argv[0]);
+ if(argc > 1) {
+ cache->reason = strdup(merge_argv(argv, 1, argc));
+ } else
+ cache->reason = NULL;
+ get_userlist(chan, neonserv_cmd_addban_userlist_lookup, cache);
+}
+
+static USERLIST_CALLBACK(neonserv_cmd_addban_userlist_lookup) {
+ struct neonserv_cmd_addban_cache *cache = data;
+ neonserv_cmd_addban_async1(cache->client, cache->textclient, cache->user, chan, cache->event, cache->mask, (cache->reason ? cache->reason : "Bye."));
+ free(cache->mask);
+ if(cache->reason)
+ free(cache->reason);
+ free(cache);
+}
+
+static void neonserv_cmd_addban_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *mask, char *reason) {
+ int match_count = 0;
+ char hostmask_buffer[NICKLEN+USERLEN+HOSTLEN+3];
+ char usermask[NICKLEN+USERLEN+HOSTLEN+3];
+ struct UserNode *cuser;
+ struct ChanUser *chanuser;
+ mask = make_banmask(mask, hostmask_buffer);
+ for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
+ cuser = chanuser->user;
+ sprintf(usermask, "%s!%s@%s", cuser->nick, cuser->ident, cuser->host);
+ if(!match(mask, usermask)) {
+ if(isNetworkService(chanuser->user)) {
+ reply(textclient, user, "NS_SERVICE_IMMUNE", chanuser->user->nick);
+ return;
+ }
+ if(cuser == user || ((cuser->flags & USERFLAG_ISAUTHED) && !stricmp(user->auth, cuser->auth))) {
+ reply(textclient, user, "NS_YOU_PROTECTED");
+ return;
+ }
+ if(isUserProtected(chan, cuser, user)) {
+ reply(textclient, user, "NS_USER_PROTECTED", cuser->nick);
+ return;
+ }
+ match_count++;
+ if(match_count > 4 && (match_count * 3) > chan->usercount && !isGodMode(user)) {
+ reply(textclient, user, "NS_LAME_MASK", mask);
+ return;
+ }
+ }
+ }
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ //check if the provided mask is already banned by another ban
+ char *ban = getBanAffectingMask(chan, mask);
+ if(ban != NULL) {
+ reply(textclient, user, "NS_BAN_ALREADY_ADDED", mask, chan->name);
+ return;
+ }
+ //check if the provided mask affects any existing bans
+ printf_mysql_query("SELECT `ban_mask`, `ban_id` FROM `bans` WHERE `ban_channel` = '%d'", chan->channel_id);
+ res = mysql_use();
+ while ((row = mysql_fetch_row(res)) != NULL) {
+ if(!match(mask, row[0])) {
+ //remove the ban
+ printf_mysql_query("DELETE FROM `bans` WHERE `ban_id` = '%s'", row[1]);
+ }
+ }
+ printf_mysql_query("SELECT `user_id` FROM `users` WHERE `user_user` = '%s'", escape_string(user->auth));
+ int userid;
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) != NULL)
+ userid = atoi(row[0]);
+ else
+ return;
+ //add the ban
+ printf_mysql_query("INSERT INTO `bans` (`ban_channel`, `ban_mask`, `ban_triggered`, `ban_owner`, `ban_reason`) VALUES ('%d', '%s', UNIX_TIMESTAMP(), '%d', '%s')", chan->channel_id, escape_string(mask), userid, escape_string(reason));
+ putsock(client, "MODE %s +b %s", chan->name, mask);
+ for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
+ cuser = chanuser->user;
+ sprintf(usermask, "%s!%s@%s", cuser->nick, cuser->ident, cuser->host);
+ if(!match(mask, usermask)) {
+ putsock(client, "KICK %s %s :(%s) %s", chan->name, cuser->nick, user->nick, reason);
+ }
+ }
+ reply(textclient, user, "NS_ADDBAN_DONE", mask, chan->name, match_count);
+ logEvent(event);
+}
--- /dev/null
+/* cmd_neonserv_addrank.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* argv[0-*] rank name
+*/
+
+CMD_BIND(neonserv_cmd_addrank) {
+ char *name = merge_argv(argv, 0, argc);
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ printf_mysql_query("SELECT `rank_name` FROM `support_ranks` WHERE `rank_name` = '%s'", escape_string(name));
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) != NULL) {
+ reply(getTextBot(), user, "NS_ADDRANK_EXISTS", row[0]);
+ return;
+ }
+ printf_mysql_query("INSERT INTO `support_ranks` (`rank_name`) VALUES ('%s')", escape_string(name));
+ reply(getTextBot(), user, "NS_ADDRANK_DONE", name);
+}
--- /dev/null
+/* cmd_neonserv_addtimeban.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* argv[0] nick|*auth|*!*@mask
+* argv[1] time
+* argv[2-*] reason
+*/
+static USERLIST_CALLBACK(neonserv_cmd_addtimeban_userlist_lookup);
+static void neonserv_cmd_addtimeban_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *mask, int duration, char *reason);
+
+struct neonserv_cmd_addtimeban_cache {
+ struct ClientSocket *client, *textclient;
+ struct UserNode *user;
+ struct Event *event;
+ char *mask;
+ int duration;
+ char *reason;
+};
+
+CMD_BIND(neonserv_cmd_addtimeban) {
+ int duration = strToTime(user, argv[1]);
+ if(duration < 5) {
+ reply(getTextBot(), user, "NS_TIMEBAN_DURATION_TOO_SHORT", 5);
+ return;
+ }
+ struct neonserv_cmd_addtimeban_cache *cache = malloc(sizeof(*cache));
+ if (!cache) {
+ perror("malloc() failed");
+ return;
+ }
+ cache->client = client;
+ cache->textclient = getTextBot();
+ cache->user = user;
+ cache->event = event;
+ cache->mask = strdup(argv[0]);
+ cache->duration = duration;
+ if(argc > 2) {
+ cache->reason = strdup(merge_argv(argv, 2, argc));
+ } else
+ cache->reason = NULL;
+ get_userlist(chan, neonserv_cmd_addtimeban_userlist_lookup, cache);
+}
+
+static USERLIST_CALLBACK(neonserv_cmd_addtimeban_userlist_lookup) {
+ struct neonserv_cmd_addtimeban_cache *cache = data;
+ neonserv_cmd_addtimeban_async1(cache->client, cache->textclient, cache->user, chan, cache->event, cache->mask, cache->duration, (cache->reason ? cache->reason : "Bye."));
+ free(cache->mask);
+ if(cache->reason)
+ free(cache->reason);
+ free(cache);
+}
+
+static void neonserv_cmd_addtimeban_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *mask, int duration, char *reason) {
+ int match_count = 0;
+ char hostmask_buffer[NICKLEN+USERLEN+HOSTLEN+3];
+ char usermask[NICKLEN+USERLEN+HOSTLEN+3];
+ struct UserNode *cuser;
+ struct ChanUser *chanuser;
+ mask = make_banmask(mask, hostmask_buffer);
+ for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
+ cuser = chanuser->user;
+ sprintf(usermask, "%s!%s@%s", cuser->nick, cuser->ident, cuser->host);
+ if(!match(mask, usermask)) {
+ if(isNetworkService(chanuser->user)) {
+ reply(textclient, user, "NS_SERVICE_IMMUNE", chanuser->user->nick);
+ return;
+ }
+ if(isUserProtected(chan, cuser, user)) {
+ reply(textclient, user, "NS_USER_PROTECTED", cuser->nick);
+ return;
+ }
+ match_count++;
+ if(match_count > 4 && (match_count * 3) > chan->usercount && !isGodMode(user)) {
+ reply(textclient, user, "NS_LAME_MASK", mask);
+ return;
+ }
+ }
+ }
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ //check if the provided mask is already banned by another ban
+ char *ban = getBanAffectingMask(chan, mask);
+ if(ban != NULL) {
+ reply(textclient, user, "NS_BAN_ALREADY_ADDED", mask, chan->name);
+ return;
+ }
+ //check if the provided mask affects any existing bans
+ printf_mysql_query("SELECT `ban_mask`, `ban_id` FROM `bans` WHERE `ban_channel` = '%d'", chan->channel_id);
+ res = mysql_use();
+ while ((row = mysql_fetch_row(res)) != NULL) {
+ if(!match(mask, row[0])) {
+ //remove the ban
+ printf_mysql_query("DELETE FROM `bans` WHERE `ban_id` = '%s'", row[1]);
+ }
+ }
+ printf_mysql_query("SELECT `user_id` FROM `users` WHERE `user_user` = '%s'", escape_string(user->auth));
+ int userid;
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) != NULL)
+ userid = atoi(row[0]);
+ else
+ return;
+ //add the ban
+ printf_mysql_query("INSERT INTO `bans` (`ban_channel`, `ban_mask`, `ban_triggered`, `ban_timeout`, `ban_owner`, `ban_reason`) VALUES ('%d', '%s', UNIX_TIMESTAMP(), '%lu', '%d', '%s')", chan->channel_id, escape_string(mask), (unsigned long) (time(0) + duration), userid, escape_string(reason));
+ int banid = (int) mysql_insert_id(get_mysql_conn());
+ putsock(client, "MODE %s +b %s", chan->name, mask);
+ for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
+ cuser = chanuser->user;
+ sprintf(usermask, "%s!%s@%s", cuser->nick, cuser->ident, cuser->host);
+ if(!match(mask, usermask)) {
+ putsock(client, "KICK %s %s :(%s) %s", chan->name, cuser->nick, user->nick, reason);
+ }
+ }
+ char nameBuf[MAXLEN];
+ char banidBuf[20];
+ sprintf(nameBuf, "ban_%d", banid);
+ sprintf(banidBuf, "%d", banid);
+ timeq_add_name(nameBuf, duration, channel_ban_timeout, strdup(banidBuf));
+ reply(textclient, user, "NS_TIMEBAN_DONE", mask, chan->name, timeToStr(user, duration, 2, nameBuf), match_count);
+ logEvent(event);
+}
--- /dev/null
+/* cmd_neonserv_adduser.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* argv[0] - nick / *auth
+* argv[1] - chan access
+*/
+static AUTHLOOKUP_CALLBACK(neonserv_cmd_adduser_auth_lookup);
+static USERAUTH_CALLBACK(neonserv_cmd_adduser_nick_lookup);
+static void neonserv_cmd_adduser_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nick, char *auth, int access);
+
+struct neonserv_cmd_adduser_cache {
+ struct ClientSocket *client, *textclient;
+ struct UserNode *user;
+ struct ChanNode *chan;
+ struct Event *event;
+ int access;
+ char *nick;
+};
+
+CMD_BIND(neonserv_cmd_adduser) {
+ int caccess;
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ caccess = atoi(argv[1]);
+ if(caccess <= 0 || caccess > 500) {
+ reply(getTextBot(), user, "NS_INVALID_ACCESS", caccess);
+ return;
+ }
+ if(caccess >= getChannelAccess(user, chan)) {
+ if(isGodMode(user)) {
+ event->flags |= CMDFLAG_OPLOG;
+ } else {
+ reply(getTextBot(), user, "NS_ACCESS_OUTRANKED");
+ 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_adduser_async1(client, getTextBot(), user, chan, event, argv[0], row[0], caccess);
+ } else {
+ //we need to create a new user...
+ //but first lookup the auth to check if it really exists
+ struct neonserv_cmd_adduser_cache *cache = malloc(sizeof(*cache));
+ if (!cache) {
+ perror("malloc() failed");
+ return;
+ }
+ cache->client = client;
+ cache->textclient = getTextBot();
+ cache->user = user;
+ cache->chan = chan;
+ cache->event = event;
+ cache->access = caccess;
+ cache->nick = strdup(argv[0]);
+ lookup_authname(argv[0], neonserv_cmd_adduser_auth_lookup, cache);
+ }
+ } else {
+ struct UserNode *cuser = getUserByNick(argv[0]);
+ if(!cuser) {
+ cuser = createTempUser(argv[0]);
+ if(!cuser) {
+ reply(getTextBot(), user, "NS_USER_UNKNOWN", argv[0]);
+ return;
+ }
+ cuser->flags |= USERFLAG_ISTMPUSER;
+ }
+ if(cuser->flags & USERFLAG_ISAUTHED) {
+ neonserv_cmd_adduser_async1(client, getTextBot(), user, chan, event, argv[0], cuser->auth, caccess);
+ } else {
+ struct neonserv_cmd_adduser_cache *cache = malloc(sizeof(*cache));
+ if (!cache) {
+ perror("malloc() failed");
+ return;
+ }
+ cache->client = client;
+ cache->textclient = getTextBot();
+ cache->user = user;
+ cache->chan = chan;
+ cache->event = event;
+ cache->access = caccess;
+ cache->nick = strdup(argv[0]);
+ get_userauth(cuser, neonserv_cmd_adduser_nick_lookup, cache);
+ }
+ }
+}
+
+static AUTHLOOKUP_CALLBACK(neonserv_cmd_adduser_auth_lookup) {
+ struct neonserv_cmd_adduser_cache *cache = data;
+ if(!exists) {
+ //AUTH_DOES_NOT_EXIST
+ reply(cache->textclient, cache->user, "NS_AUTH_UNKNOWN", cache->nick);
+ } else
+ neonserv_cmd_adduser_async1(cache->client, cache->textclient, cache->user, cache->chan, cache->event, cache->nick, auth, cache->access);
+ free(cache->nick);
+ free(cache);
+}
+
+static USERAUTH_CALLBACK(neonserv_cmd_adduser_nick_lookup) {
+ struct neonserv_cmd_adduser_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_adduser_async1(cache->client, cache->textclient, cache->user, cache->chan, cache->event, user->nick, user->auth, cache->access);
+ free(cache->nick);
+ free(cache);
+}
+
+static void neonserv_cmd_adduser_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nick, char *auth, int caccess) {
+ //we've got a valid auth now...
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ 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]);
+ //check if the user is already added
+ printf_mysql_query("SELECT `chanuser_access` FROM `chanusers` WHERE `chanuser_cid` = '%d' AND `chanuser_uid` = '%d'", chan->channel_id, userid);
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) != NULL) {
+ reply(textclient, user, "NS_ADDUSER_ALREADY_ADDED", nick, chan->name, atoi(row[0]));
+ return;
+ }
+ } else {
+ printf_mysql_query("INSERT INTO `users` (`user_user`) VALUES ('%s')", escape_string(auth));
+ userid = (int) mysql_insert_id(get_mysql_conn());
+ }
+ printf_mysql_query("INSERT INTO `chanusers` (`chanuser_cid`, `chanuser_uid`, `chanuser_access`) VALUES ('%d', '%d', '%d')", chan->channel_id, userid, caccess);
+ reply(textclient, user, "NS_ADDUSER_DONE", nick, chan->name, caccess);
+ logEvent(event);
+}
--- /dev/null
+/* cmd_neonserv_assignrank.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* argv[0] - nick / *auth
+* argv[1-*] - rank name
+*/
+static AUTHLOOKUP_CALLBACK(neonserv_cmd_assignrank_auth_lookup);
+static USERAUTH_CALLBACK(neonserv_cmd_assignrank_nick_lookup);
+static void neonserv_cmd_assignrank_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct Event *event, char *nick, char *auth, int rank_id);
+
+struct neonserv_cmd_assignrank_cache {
+ struct ClientSocket *client, *textclient;
+ struct UserNode *user;
+ struct Event *event;
+ int rank_id;
+ char *nick;
+};
+
+CMD_BIND(neonserv_cmd_assignrank) {
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ char *name = merge_argv(argv, 1, argc);
+ int rank_id = 0;
+ if(stricmp(name, "*") && stricmp(name, "user") && stricmp(name, "none")) {
+ printf_mysql_query("SELECT `rank_id`, `rank_name` FROM `support_ranks` WHERE `rank_name` = '%s'", escape_string(name));
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) == NULL) {
+ reply(getTextBot(), user, "NS_DELRANK_NOT_FOUND", name);
+ return;
+ }
+ rank_id = atoi(row[0]);
+ }
+ 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_assignrank_async1(client, getTextBot(), user, event, argv[0], row[0], rank_id);
+ } else {
+ //we need to create a new user...
+ //but first lookup the auth to check if it really exists
+ struct neonserv_cmd_assignrank_cache *cache = malloc(sizeof(*cache));
+ if (!cache) {
+ perror("malloc() failed");
+ return;
+ }
+ cache->client = client;
+ cache->textclient = getTextBot();
+ cache->user = user;
+ cache->event = event;
+ cache->rank_id = rank_id;
+ cache->nick = strdup(argv[0]);
+ lookup_authname(argv[0], neonserv_cmd_assignrank_auth_lookup, cache);
+ }
+ } else {
+ struct UserNode *cuser = getUserByNick(argv[0]);
+ if(!cuser) {
+ cuser = createTempUser(argv[0]);
+ if(!cuser) {
+ reply(getTextBot(), user, "NS_USER_UNKNOWN", argv[0]);
+ return;
+ }
+ cuser->flags |= USERFLAG_ISTMPUSER;
+ }
+ if(cuser->flags & USERFLAG_ISAUTHED) {
+ neonserv_cmd_assignrank_async1(client, getTextBot(), user, event, argv[0], cuser->auth, rank_id);
+ } else {
+ struct neonserv_cmd_assignrank_cache *cache = malloc(sizeof(*cache));
+ if (!cache) {
+ perror("malloc() failed");
+ return;
+ }
+ cache->client = client;
+ cache->textclient = getTextBot();
+ cache->user = user;
+ cache->event = event;
+ cache->rank_id = rank_id;
+ cache->nick = strdup(argv[0]);
+ get_userauth(cuser, neonserv_cmd_assignrank_nick_lookup, cache);
+ }
+ }
+}
+
+static AUTHLOOKUP_CALLBACK(neonserv_cmd_assignrank_auth_lookup) {
+ struct neonserv_cmd_assignrank_cache *cache = data;
+ if(!exists) {
+ //AUTH_DOES_NOT_EXIST
+ reply(cache->textclient, cache->user, "NS_AUTH_UNKNOWN", cache->nick);
+ } else
+ neonserv_cmd_assignrank_async1(cache->client, cache->textclient, cache->user, cache->event, cache->nick, auth, cache->rank_id);
+ free(cache->nick);
+ free(cache);
+}
+
+static USERAUTH_CALLBACK(neonserv_cmd_assignrank_nick_lookup) {
+ struct neonserv_cmd_assignrank_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_assignrank_async1(cache->client, cache->textclient, cache->user, cache->event, user->nick, user->auth, cache->rank_id);
+ free(cache->nick);
+ free(cache);
+}
+
+static void neonserv_cmd_assignrank_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct Event *event, char *nick, char *auth, int rank_id) {
+ //we've got a valid auth now...
+ MYSQL_RES *res;
+ MYSQL_ROW row, rank = NULL;
+ int caccess = 0;
+ if(rank_id) {
+ printf_mysql_query("SELECT `rank_access`, `rank_name` FROM `support_ranks` WHERE `rank_id` = '%d'", rank_id);
+ res = mysql_use();
+ rank = mysql_fetch_row(res);
+ caccess = atoi(rank[0]);
+ }
+ printf_mysql_query("SELECT `user_id`, `user_rank` FROM `users` WHERE `user_user` = '%s'", escape_string(auth));
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) != NULL) {
+ if(atoi(row[1]) != rank_id) {
+ printf_mysql_query("UPDATE `users` SET `user_access` = '%d', `user_rank` = '%d' WHERE `user_id` = '%s'", caccess, rank_id, row[0]);
+ }
+ } else if(rank_id) {
+ printf_mysql_query("INSERT INTO `users` (`user_user`, `user_access`, `user_rank`) VALUES ('%s', '%d', '%d')", escape_string(auth), caccess, rank_id);
+ }
+ reply(textclient, user, "NS_ASSIGNRANK_DONE", auth, (rank_id ? rank[1] : "*"));
+ logEvent(event);
+}
--- /dev/null
+/* cmd_neonserv_ban.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* argv[0-*] nick[,*auth[,*!*@mask[...]]]
+*/
+static USERLIST_CALLBACK(neonserv_cmd_ban_userlist_lookup);
+static void neonserv_cmd_ban_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *masks);
+
+struct neonserv_cmd_ban_cache {
+ struct ClientSocket *client, *textclient;
+ struct UserNode *user;
+ struct Event *event;
+ char *masks;
+};
+
+CMD_BIND(neonserv_cmd_ban) {
+ struct neonserv_cmd_ban_cache *cache = malloc(sizeof(*cache));
+ if (!cache) {
+ perror("malloc() failed");
+ return;
+ }
+ cache->client = client;
+ cache->textclient = getTextBot();
+ cache->user = user;
+ cache->event = event;
+ cache->masks = strdup(merge_argv_char(argv, 0, argc, ','));
+ get_userlist_with_invisible(chan, neonserv_cmd_ban_userlist_lookup, cache);
+}
+
+static USERLIST_CALLBACK(neonserv_cmd_ban_userlist_lookup) {
+ struct neonserv_cmd_ban_cache *cache = data;
+ neonserv_cmd_ban_async1(cache->client, cache->textclient, cache->user, chan, cache->event, cache->masks);
+ free(cache->masks);
+ free(cache);
+}
+
+static void neonserv_cmd_ban_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *masks) {
+ int done_masks = 0, provided_masks = 0, skip, match_count, total_match;
+ char *mask, *nextmask;
+ char hostmask_buffer[NICKLEN+USERLEN+HOSTLEN+3];
+ char usermask[NICKLEN+USERLEN+HOSTLEN+3];
+ struct UserNode *cuser;
+ struct ChanUser *chanuser;
+ struct ModeBuffer *modeBuf;
+ modeBuf = initModeBuffer(client, chan);
+ nextmask = masks;
+ while((mask = nextmask)) {
+ nextmask = strstr(mask, ",");
+ if(nextmask) {
+ *nextmask = '\0';
+ nextmask++;
+ }
+ provided_masks++;
+ skip = 0;
+ match_count = 0;
+ mask = make_banmask(mask, hostmask_buffer);
+ for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
+ cuser = chanuser->user;
+ sprintf(usermask, "%s!%s@%s", cuser->nick, cuser->ident, cuser->host);
+ if(!match(mask, usermask)) {
+ cuser->flags |= USERFLAG_SCRIPTFLAG1; //we mark the user as 'matching'
+ if(isNetworkService(chanuser->user)) {
+ reply(textclient, user, "NS_SERVICE_IMMUNE", chanuser->user->nick);
+ skip = 1;
+ break;
+ }
+ if(cuser == user || ((cuser->flags & USERFLAG_ISAUTHED) && !stricmp(user->auth, cuser->auth))) {
+ reply(textclient, user, "NS_YOU_PROTECTED");
+ skip = 1;
+ break;
+ }
+ if(isUserProtected(chan, cuser, user)) {
+ reply(textclient, user, "NS_USER_PROTECTED", cuser->nick);
+ skip = 1;
+ break;
+ }
+ match_count++;
+ if(match_count > 4 && (match_count * 3) > chan->usercount && !isGodMode(user)) {
+ skip = 1;
+ reply(textclient, user, "NS_LAME_MASK", mask);
+ break;
+ }
+ }
+ }
+ if(!skip) {
+ done_masks++;
+ modeBufferBan(modeBuf, mask);
+ }
+ }
+ total_match = 0; // count all users marked as 'matching'
+ for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
+ cuser = chanuser->user;
+ if(cuser->flags & USERFLAG_SCRIPTFLAG1) {
+ cuser->flags &= ~USERFLAG_SCRIPTFLAG1;
+ total_match++;
+ }
+ }
+ freeModeBuffer(modeBuf);
+ if(done_masks == provided_masks)
+ reply(getTextBot(), user, "NS_BAN_DONE", done_masks, chan->name, total_match);
+ else
+ reply(getTextBot(), user, "NS_BAN_FAIL", client->user->nick);
+ if(done_masks)
+ logEvent(event);
+}
--- /dev/null
+/* cmd_neonserv_bans.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* argv[0] (optional) mask
+*/
+CMD_BIND(neonserv_cmd_bans) {
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ //ban list
+ int i, with_expire = 0, cindex = 0;
+ char triggered_str[MAXLEN], expires_str[MAXLEN];
+ struct Table *table;
+ printf_mysql_query("SELECT `ban_mask`, `user_user`, `ban_triggered`, `ban_timeout`, `ban_reason` FROM `bans` LEFT JOIN `users` ON `ban_owner` = `user_id` WHERE `ban_channel` = '%d'", chan->channel_id);
+ res = mysql_use();
+ table = table_init(5, mysql_num_rows(res) + 1, 0);
+ char *content[5];
+ //add a NULL row (we add values later)
+ content[0] = NULL;
+ content[1] = NULL;
+ content[2] = NULL;
+ content[3] = NULL;
+ content[4] = NULL;
+ table_add(table, content);
+ while ((row = mysql_fetch_row(res)) != NULL) {
+ if(argc > 0 && match(argv[0], row[0])) continue;
+ content[0] = row[0];
+ content[1] = row[1];
+ content[2] = (strcmp(row[2], "0") ? timeToStr(user, (time(0) - atoi(row[2])), 2, triggered_str) : get_language_string(user, "NS_USERS_SEEN_NEVER"));
+ if(strcmp(row[3], "0")) {
+ if(!with_expire) {
+ //we're using expire times now...
+ for(i = 0; i < cindex; i++)
+ table_change_field(table, i+1, 3, get_language_string(user, "NS_USERS_SEEN_NEVER"));
+ with_expire = 1;
+ }
+ content[3] = timeToStr(user, (atoi(row[3]) - time(0)), 2, expires_str);
+ } else
+ content[3] = (with_expire ? get_language_string(user, "NS_USERS_SEEN_NEVER") : NULL);
+ content[4] = row[4];
+ cindex++;
+ table_add(table, content);
+ }
+ //now we add the table header
+ content[0] = get_language_string(user, "NS_BANS_HEADER_MASK");
+ content[1] = get_language_string(user, "NS_BANS_HEADER_SETBY");
+ content[2] = get_language_string(user, "NS_BANS_HEADER_TRIGGERED");
+ content[3] = (with_expire ? get_language_string(user, "NS_BANS_HEADER_EXPIRES") : NULL);
+ content[4] = get_language_string(user, "NS_BANS_HEADER_REASON");
+ table_change(table, 0, content);
+ char **table_lines = table_end(table);
+ for(i = 0; i < table->entrys; i++) {
+ reply(getTextBot(), user, table_lines[i]);
+ }
+ if(!cindex)
+ reply(getTextBot(), user, "NS_TABLE_NONE");
+ reply(getTextBot(), user, "NS_TABLE_COUNT", cindex);
+ table_free(table);
+}
--- /dev/null
+/* cmd_neonserv_chanservsync.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* argv[0] - botnick
+* argv[1] - key
+*/
+#define CHANSERVSYNC_END_TIMEOUT 5
+
+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;
+ struct UserNode *user;
+ struct ChanNode *chan;
+ char *botnick;
+ 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};
+
+CMD_BIND(neonserv_cmd_chanservsync) {
+ if(neonserv_cmd_chanservsync_used && time(0) - neonserv_cmd_chanservsync_used->last_response < CHANSERVSYNC_END_TIMEOUT) {
+ reply(getTextBot(), user, "NS_CHANSERVSYNC_INUSE");
+ return;
+ }
+ if(neonserv_cmd_chanservsync_used) {
+ neonserv_cmd_chanservsync_free_cache();
+ }
+ char *botnick = "ChanServ";
+ char *key = "";
+ if(argc) {
+ if(argv[0][0] == '!') {
+ key = argv[0];
+ } else {
+ botnick = argv[0];
+ if(argc > 1)
+ key = argv[1];
+ }
+ }
+ int seed = 0;
+ char *tmp;
+ char synckey[18];
+ 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));
+ for(tmp = botnick; *tmp; tmp++)
+ seed = (seed * 0xEECE66DL ^ ((*tmp << 24) | (*tmp << 16) | (*tmp << 8) | *tmp));
+ sprintf(synckey, "!%08x!", seed);
+ if(strcmp(synckey, key)) {
+ int f = 0;
+ const char **supp = neonserv_cmd_chanservsync_supported;
+ while(*supp) {
+ if(!stricmp(*supp, botnick)) {
+ f = 1;
+ break;
+ }
+ supp++;
+ }
+ if(!f) {
+ reply(getTextBot(), user, "NS_CHANSERVSYNC_UNSUPPORTED", botnick, client->user->nick);
+ }
+ reply(getTextBot(), user, "NS_CHANSERVSYNC_KEY", client->user->nick, botnick, botnick, synckey);
+ return;
+ }
+ struct neonserv_cmd_chanservsync_cache *cache = malloc(sizeof(*cache));
+ if (!cache) {
+ perror("malloc() failed");
+ return;
+ }
+ cache->client = client;
+ cache->textclient = getTextBot();
+ cache->user = user;
+ cache->chan = chan;
+ cache->botnick = strdup(botnick);
+ cache->last_response = time(0);
+ 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);
+ logEvent(event);
+}
+
+static void neonserv_cmd_chanservsync_notice_listener(struct UserNode *user, struct UserNode *target, char *message) {
+ if(neonserv_cmd_chanservsync_used && neonserv_cmd_chanservsync_used->client->user == target && !stricmp(user->nick, neonserv_cmd_chanservsync_used->botnick)) {
+ //we've got a notice from our bot...
+ //let's try parsing it....
+ char *p = message;
+ char *tokens[MAXLEN];
+ int tokensPos = 0;
+ while(*p == ' ') //skip leading spaces (airb0t)
+ p++;
+ message = p;
+ char *q = p;
+ while(*q) {
+ if(*q < 32) *q = ' ';
+ q++;
+ }
+ while((q = strstr(p, " "))) {
+ *q = '\0';
+ do {
+ q++;
+ } while(*q == ' ' || *q == '-');
+ if(*p) {
+ tokens[tokensPos++] = p;
+ }
+ p = q;
+ }
+ if(*p) {
+ tokens[tokensPos++] = p;
+ }
+ 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) {
+ if(atoi(tokens[0]) > 0) {
+ caccess = atoi(tokens[0]);
+ username = tokens[1];
+ } else {
+ caccess = atoi(tokens[1]);
+ username = tokens[0];
+ }
+ } else
+ return;
+ if(caccess < 1 || caccess > 500) return;
+ int flags = 0;
+ time_t now = time(0);
+ time_t seen_time = now; //now - now = 0 (never)
+ neonserv_cmd_chanservsync_used->last_response = now;
+ if(strlen(username) < 3) return;
+ //ok we have access and username... maybe there is something else we can parse???
+ char *seen = NULL;
+ char *status = NULL;
+ if(tokensPos > 2) {
+ if(!stricmp("normal", tokens[2]) || !stricmp("suspended", tokens[2]) || !stricmp("bot", tokens[2])) {
+ status = tokens[2];
+ if (tokensPos > 3) {
+ seen = merge_argv(tokens, 3, tokensPos);
+ }
+ } else if (tokensPos > 3) {
+ if(!stricmp("normal", tokens[tokensPos-1]) || !stricmp("suspended", tokens[tokensPos-1]) || !stricmp("bot", tokens[tokensPos-1])) {
+ status = tokens[tokensPos-1];
+ seen = merge_argv(tokens, 2, tokensPos-1);
+ } else {
+ seen = merge_argv(tokens, 2, tokensPos);
+ }
+ } else {
+ seen = merge_argv(tokens, 2, tokensPos);
+ }
+ }
+ if(status && !stricmp(status, "suspended")) {
+ flags |= DB_CHANUSER_SUSPENDED;
+ }
+ if(seen) {
+ if(!stricmp(seen, "here"))
+ seen_time = 0;
+ else if(stricmp(seen, "never"))
+ seen_time = strToTime(user, seen);
+ }
+ seen_time = now - seen_time;
+ //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(get_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);
+ }
+ }
+}
+
+static void neonserv_cmd_chanservsync_free_cache() {
+ free(neonserv_cmd_chanservsync_used->botnick);
+ free(neonserv_cmd_chanservsync_used);
+ unbind_privnotice(neonserv_cmd_chanservsync_notice_listener);
+ 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(get_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);
+}
--- /dev/null
+/* cmd_neonserv_clvl.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* argv[0] - nick / *auth
+* argv[1] - access
+*/
+static USERAUTH_CALLBACK(neonserv_cmd_clvl_nick_lookup);
+static void neonserv_cmd_clvl_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nick, char *auth, int caccess);
+
+struct neonserv_cmd_clvl_cache {
+ struct ClientSocket *client, *textclient;
+ struct UserNode *user;
+ struct ChanNode *chan;
+ struct Event *event;
+ char *nick;
+ int access;
+};
+
+CMD_BIND(neonserv_cmd_clvl) {
+ int caccess;
+ caccess = atoi(argv[1]);
+ if(caccess <= 0 || caccess > 500) {
+ reply(getTextBot(), user, "NS_INVALID_ACCESS", caccess);
+ return;
+ }
+ if(caccess >= getChannelAccess(user, chan)) {
+ if(isGodMode(user)) {
+ event->flags |= CMDFLAG_OPLOG;
+ } else {
+ reply(getTextBot(), user, "NS_ACCESS_OUTRANKED");
+ return;
+ }
+ }
+ if(argv[0][0] == '*') {
+ //we've got an auth
+ argv[0]++;
+ neonserv_cmd_clvl_async1(client, getTextBot(), user, chan, event, argv[0], argv[0], caccess);
+ } else {
+ struct UserNode *cuser = getUserByNick(argv[0]);
+ if(!cuser) {
+ cuser = createTempUser(argv[0]);
+ if(!cuser) {
+ reply(getTextBot(), user, "NS_USER_UNKNOWN", argv[0]);
+ return;
+ }
+ cuser->flags |= USERFLAG_ISTMPUSER;
+ }
+ if(cuser->flags & USERFLAG_ISAUTHED) {
+ neonserv_cmd_clvl_async1(client, getTextBot(), user, chan, event, argv[0], cuser->auth, caccess);
+ } else {
+ struct neonserv_cmd_clvl_cache *cache = malloc(sizeof(*cache));
+ if (!cache) {
+ perror("malloc() failed");
+ return;
+ }
+ cache->client = client;
+ cache->textclient = getTextBot();
+ cache->user = user;
+ cache->chan = chan;
+ cache->event = event;
+ cache->nick = strdup(argv[0]);
+ cache->access = caccess;
+ get_userauth(cuser, neonserv_cmd_clvl_nick_lookup, cache);
+ }
+ }
+}
+
+static USERAUTH_CALLBACK(neonserv_cmd_clvl_nick_lookup) {
+ struct neonserv_cmd_clvl_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_clvl_async1(cache->client, cache->textclient, cache->user, cache->chan, cache->event, user->nick, user->auth, cache->access);
+ free(cache->nick);
+ free(cache);
+}
+
+static void neonserv_cmd_clvl_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nick, char *auth, int caccess) {
+ //we've got a valid auth now...
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ 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]);
+ //check if the user is already added
+ printf_mysql_query("SELECT `chanuser_access`, `chanuser_id` 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]) >= getChannelAccess(user, chan)) {
+ if(isGodMode(user)) {
+ event->flags |= CMDFLAG_OPLOG;
+ } else {
+ reply(textclient, user, "NS_USER_OUTRANKED", nick);
+ return;
+ }
+ }
+ printf_mysql_query("UPDATE `chanusers` SET `chanuser_access` = '%d' WHERE `chanuser_id` = '%s'", caccess, row[1]);
+ reply(textclient, user, "NS_CLVL_DONE", nick, caccess, chan->name);
+ logEvent(event);
+ return;
+ }
+ }
+ reply(textclient, user, "NS_NOT_ON_USERLIST", nick, chan->name);
+}
--- /dev/null
+/* cmd_neonserv_csuspend.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* argv[0] - channel
+*/
+CMD_BIND(neonserv_cmd_csuspend) {
+ 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;
+ }
+ 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 {
+ reply(getTextBot(), user, "NS_UNREGISTER_NOT_REGISTERED", argv[0], client->user->nick);
+ return;
+ }
+ printf_mysql_query("SELECT `botid`, `bot_channels`.`id`, `suspended` FROM `bot_channels` LEFT JOIN `bots` ON `bot_channels`.`botid` = `bots`.`id` WHERE `chanid` = '%d' AND `botclass` = '%d'", chanid, client->botid);
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) == NULL) {
+ reply(getTextBot(), user, "NS_UNREGISTER_NOT_REGISTERED", argv[0], client->user->nick);
+ return;
+ }
+ if(!strcmp(row[2], "1")) {
+ reply(getTextBot(), user, "NS_CSUSPEND_ALREADY", channel);
+ return;
+ }
+ int botid = atoi(row[0]);
+ 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, "PART %s :Channel suspended.", channel);
+ }
+ printf_mysql_query("UPDATE `bot_channels` SET `suspended` = '1' WHERE `id` = '%s'", row[1]);
+ reply(getTextBot(), user, "NS_CSUSPEND_DONE", channel);
+ logEvent(event);
+}
--- /dev/null
+/* cmd_neonserv_cunsuspend.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* argv[0] - channel
+*/
+CMD_BIND(neonserv_cmd_cunsuspend) {
+ 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;
+ }
+ 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 {
+ reply(getTextBot(), user, "NS_UNREGISTER_NOT_REGISTERED", argv[0], client->user->nick);
+ return;
+ }
+ printf_mysql_query("SELECT `botid`, `bot_channels`.`id`, `suspended` FROM `bot_channels` LEFT JOIN `bots` ON `bot_channels`.`botid` = `bots`.`id` WHERE `chanid` = '%d' AND `botclass` = '%d'", chanid, client->botid);
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) == NULL) {
+ reply(getTextBot(), user, "NS_UNREGISTER_NOT_REGISTERED", argv[0], client->user->nick);
+ return;
+ }
+ if(!strcmp(row[2], "0")) {
+ reply(getTextBot(), user, "NS_CUNSUSPEND_NOT", channel);
+ return;
+ }
+ int botid = atoi(row[0]);
+ 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);
+ }
+ printf_mysql_query("UPDATE `bot_channels` SET `suspended` = '0' WHERE `id` = '%s'", row[1]);
+ reply(getTextBot(), user, "NS_CUNSUSPEND_DONE", channel);
+ logEvent(event);
+}
--- /dev/null
+/* cmd_neonserv_dehalfop.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* argv[0-*] nicks
+*/
+static USERLIST_CALLBACK(neonserv_cmd_dehalfop_userlist_lookup);
+static void neonserv_cmd_dehalfop_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char **argv, int argc);
+
+struct neonserv_cmd_dehalfop_cache {
+ struct ClientSocket *client, *textclient;
+ struct UserNode *user;
+ struct Event *event;
+ char **argv;
+ int argc;
+};
+
+CMD_BIND(neonserv_cmd_dehalfop) {
+ struct neonserv_cmd_dehalfop_cache *cache = malloc(sizeof(*cache));
+ if (!cache) {
+ perror("malloc() failed");
+ return;
+ }
+ cache->client = client;
+ cache->textclient = getTextBot();
+ cache->user = user;
+ cache->event = event;
+ cache->argv = calloc(argc, sizeof(char*));
+ int i;
+ for(i = 0; i < argc; i++) {
+ cache->argv[i] = strdup(argv[i]);
+ }
+ cache->argc = argc;
+ get_userlist(chan, neonserv_cmd_dehalfop_userlist_lookup, cache);
+}
+
+static USERLIST_CALLBACK(neonserv_cmd_dehalfop_userlist_lookup) {
+ struct neonserv_cmd_dehalfop_cache *cache = data;
+ neonserv_cmd_dehalfop_async1(cache->client, cache->textclient, cache->user, chan, cache->event, cache->argv, cache->argc);
+ int i;
+ for(i = 0; i < cache->argc; i++) {
+ free(cache->argv[i]);
+ }
+ free(cache->argv);
+ free(cache);
+}
+
+static void neonserv_cmd_dehalfop_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char **argv, int argc) {
+ int i, done_users = 0;
+ struct UserNode *cuser;
+ struct ChanUser *chanuser;
+ struct ModeBuffer *modeBuf;
+ modeBuf = initModeBuffer(client, chan);
+ for(i = 0; i < argc; i++) {
+ cuser = searchUserByNick(argv[i]);
+ if(!cuser) continue;
+ chanuser = getChanUser(cuser, chan);
+ if(!chanuser) continue;
+ if(isNetworkService(cuser)) {
+ reply(textclient, user, "NS_SERVICE_IMMUNE", cuser->nick);
+ continue;
+ }
+ if(isUserProtected(chan, cuser, user)) {
+ reply(textclient, user, "NS_USER_PROTECTED", cuser->nick);
+ continue;
+ }
+ done_users++;
+ if(!(chanuser->flags & CHANUSERFLAG_OPPED)) continue;
+ modeBufferDehalfop(modeBuf, argv[i]);
+ }
+ freeModeBuffer(modeBuf);
+ if(done_users == argc)
+ reply(textclient, user, "NS_DEHALFOP_DONE", chan->name);
+ else
+ reply(textclient, user, "NS_DEHALFOP_FAIL", client->user->nick);
+ if(done_users)
+ logEvent(event);
+}
--- /dev/null
+/* cmd_neonserv_dehalfopall.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* argv[0] (optional) nick mask
+*/
+static USERLIST_CALLBACK(neonserv_cmd_dehalfopall_userlist_lookup);
+static void neonserv_cmd_dehalfopall_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char **argv, int argc);
+
+struct neonserv_cmd_dehalfopall_cache {
+ struct ClientSocket *client, *textclient;
+ struct UserNode *user;
+ struct Event *event;
+ char **argv;
+ int argc;
+};
+
+CMD_BIND(neonserv_cmd_dehalfopall) {
+ struct neonserv_cmd_dehalfopall_cache *cache = malloc(sizeof(*cache));
+ if (!cache) {
+ perror("malloc() failed");
+ return;
+ }
+ cache->client = client;
+ cache->textclient = getTextBot();
+ cache->user = user;
+ cache->event = event;
+ cache->argv = calloc(argc, sizeof(char*));
+ int i;
+ for(i = 0; i < argc; i++) {
+ cache->argv[i] = strdup(argv[i]);
+ }
+ cache->argc = argc;
+ get_userlist(chan, neonserv_cmd_dehalfopall_userlist_lookup, cache);
+}
+
+static USERLIST_CALLBACK(neonserv_cmd_dehalfopall_userlist_lookup) {
+ struct neonserv_cmd_dehalfopall_cache *cache = data;
+ neonserv_cmd_dehalfopall_async1(cache->client, cache->textclient, cache->user, chan, cache->event, cache->argv, cache->argc);
+ int i;
+ for(i = 0; i < cache->argc; i++) {
+ free(cache->argv[i]);
+ }
+ free(cache->argv);
+ free(cache);
+}
+
+static void neonserv_cmd_dehalfopall_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char **argv, int argc) {
+ int issuer_access, victim_access, done_users = 0;
+ char *nickmask = NULL;
+ struct ChanUser *chanuser;
+ struct ModeBuffer *modeBuf;
+ if(argc > 0)
+ nickmask = argv[0];
+ modeBuf = initModeBuffer(client, chan);
+ issuer_access = getChannelAccess(user, chan);
+ for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
+ if(nickmask && match(nickmask, chanuser->user->nick)) continue;
+ victim_access = getChannelAccess(chanuser->user, chan);
+ if(victim_access >= issuer_access || isNetworkService(chanuser->user)) continue;
+ if(!(chanuser->flags & CHANUSERFLAG_OPPED)) continue;
+ modeBufferDehalfop(modeBuf, chanuser->user->nick);
+ done_users++;
+ }
+ freeModeBuffer(modeBuf);
+ reply(getTextBot(), user, "NS_DEHALFOPALL_DONE", done_users, chan->name);
+ if(done_users)
+ logEvent(event);
+}
--- /dev/null
+/* cmd_neonserv_delban.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* argv[0] nick|*auth|*!*@mask
+*/
+
+CMD_BIND(neonserv_cmd_delban) {
+ char hostmask_buffer[NICKLEN+USERLEN+HOSTLEN+3];
+ char *mask = make_banmask(argv[0], hostmask_buffer);
+ int matching_bans = 0;
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ //check if the provided mask affects any existing bans
+ char nameBuf[20];
+ printf_mysql_query("SELECT `ban_mask`, `ban_id`, `ban_timeout` FROM `bans` WHERE `ban_channel` = '%d'", chan->channel_id);
+ res = mysql_use();
+ while ((row = mysql_fetch_row(res)) != NULL) {
+ if(!match(mask, row[0])) {
+ //remove the ban
+ if(strcmp(row[2], "0")) {
+ sprintf(nameBuf, "ban_%s", row[1]);
+ timeq_del_name(nameBuf);
+ }
+ printf_mysql_query("DELETE FROM `bans` WHERE `ban_id` = '%s'", row[1]);
+ matching_bans++;
+ }
+ }
+ if(matching_bans) {
+ putsock(client, "MODE %s -b %s", chan->name, mask);
+ reply(getTextBot(), user, "NS_DELBAN_DONE", mask, chan->name);
+ logEvent(event);
+ } else
+ reply(getTextBot(), user, "NS_DELBAN_FAIL", mask);
+}
--- /dev/null
+/* cmd_neonserv_delme.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* argv[0] - key
+*/
+
+CMD_BIND(neonserv_cmd_delme) {
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ int userid;
+ printf_mysql_query("SELECT `user_id` FROM `users` WHERE `user_user` = '%s'", escape_string(user->auth));
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) != NULL) {
+ userid = atoi(row[0]);
+ //check if the user is added
+ printf_mysql_query("SELECT `chanuser_access`, `chanuser_id` FROM `chanusers` WHERE `chanuser_cid` = '%d' AND `chanuser_uid` = '%d'", chan->channel_id, userid);
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) != NULL) {
+ if(atoi(row[0]) == 500) {
+ reply(getTextBot(), user, "NS_DELME_OWNER", chan->name);
+ return;
+ }
+ //check key
+ int seed = 0;
+ char *tmp;
+ static char unregkey[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(unregkey, "%08x", seed);
+ if(argc < 1 || strcmp(argv[0], unregkey)) {
+ reply(getTextBot(), user, "NS_DELME_KEY", unregkey);
+ return;
+ } else {
+ //delete
+ printf_mysql_query("DELETE FROM `chanusers` WHERE `chanuser_id` = '%s'", row[1]);
+ reply(getTextBot(), user, "NS_DELME_DONE", atoi(row[0]), chan->name);
+ logEvent(event);
+ return;
+ }
+ }
+ }
+ reply(getTextBot(), user, "NS_NOT_ON_USERLIST_YOU", chan->name);
+}
--- /dev/null
+/* cmd_neonserv_delrank.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* argv[0-*] rank name
+*/
+
+CMD_BIND(neonserv_cmd_delrank) {
+ char *name = merge_argv(argv, 0, argc);
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ printf_mysql_query("SELECT `rank_id`, `rank_name` FROM `support_ranks` WHERE `rank_name` = '%s'", escape_string(name));
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) == NULL) {
+ reply(getTextBot(), user, "NS_DELRANK_NOT_FOUND", name);
+ return;
+ }
+ printf_mysql_query("UPDATE `users` SET `user_rank` = '0', `user_access` = '0' WHERE `user_rank` = '%s'", row[0]);
+ printf_mysql_query("DELETE FROM `support_ranks` WHERE `rank_id` = '%s'", row[0]);
+ reply(getTextBot(), user, "NS_DELRANK_DELETED", row[1]);
+}
--- /dev/null
+/* cmd_neonserv_deluser.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* argv[0] - nick / *auth
+*/
+static USERAUTH_CALLBACK(neonserv_cmd_deluser_nick_lookup);
+static void neonserv_cmd_deluser_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nick, char *auth);
+
+struct neonserv_cmd_deluser_cache {
+ struct ClientSocket *client, *textclient;
+ struct UserNode *user;
+ struct ChanNode *chan;
+ struct Event *event;
+ char *nick;
+};
+
+CMD_BIND(neonserv_cmd_deluser) {
+ if(argv[0][0] == '*') {
+ //we've got an auth
+ argv[0]++;
+ neonserv_cmd_deluser_async1(client, getTextBot(), user, chan, event, argv[0], argv[0]);
+ } else {
+ struct UserNode *cuser = getUserByNick(argv[0]);
+ if(!cuser) {
+ cuser = createTempUser(argv[0]);
+ if(!cuser) {
+ reply(getTextBot(), user, "NS_USER_UNKNOWN", argv[0]);
+ return;
+ }
+ cuser->flags |= USERFLAG_ISTMPUSER;
+ }
+ if(cuser->flags & USERFLAG_ISAUTHED) {
+ neonserv_cmd_deluser_async1(client, getTextBot(), user, chan, event, argv[0], cuser->auth);
+ } else {
+ struct neonserv_cmd_deluser_cache *cache = malloc(sizeof(*cache));
+ if (!cache) {
+ perror("malloc() failed");
+ return;
+ }
+ cache->client = client;
+ cache->textclient = getTextBot();
+ cache->user = user;
+ cache->chan = chan;
+ cache->event = event;
+ cache->nick = strdup(argv[0]);
+ get_userauth(cuser, neonserv_cmd_deluser_nick_lookup, cache);
+ }
+ }
+}
+
+static USERAUTH_CALLBACK(neonserv_cmd_deluser_nick_lookup) {
+ struct neonserv_cmd_deluser_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_deluser_async1(cache->client, cache->textclient, cache->user, cache->chan, cache->event, user->nick, user->auth);
+ free(cache->nick);
+ free(cache);
+}
+
+static void neonserv_cmd_deluser_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nick, char *auth) {
+ //we've got a valid auth now...
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ 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]);
+ //check if the user is already added
+ printf_mysql_query("SELECT `chanuser_access`, `chanuser_id` FROM `chanusers` WHERE `chanuser_cid` = '%d' AND `chanuser_uid` = '%d'", chan->channel_id, userid);
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) != NULL) {
+ if(atoi(row[0]) >= getChannelAccess(user, chan)) {
+ if(isGodMode(user)) {
+ event->flags |= CMDFLAG_OPLOG;
+ } else {
+ reply(textclient, user, "NS_USER_OUTRANKED", nick);
+ return;
+ }
+ }
+ //delete
+ printf_mysql_query("DELETE FROM `chanusers` WHERE `chanuser_id` = '%s'", row[1]);
+ reply(textclient, user, "NS_DELUSER_DONE", nick, atoi(row[0]), chan->name);
+ logEvent(event);
+ return;
+ }
+ }
+ reply(textclient, user, "NS_NOT_ON_USERLIST", nick, chan->name);
+}
--- /dev/null
+/* cmd_neonserv_deop.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* argv[0-*] nicks
+*/
+static USERLIST_CALLBACK(neonserv_cmd_deop_userlist_lookup);
+static void neonserv_cmd_deop_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char **argv, int argc);
+
+struct neonserv_cmd_deop_cache {
+ struct ClientSocket *client, *textclient;
+ struct UserNode *user;
+ struct Event *event;
+ char **argv;
+ int argc;
+};
+
+CMD_BIND(neonserv_cmd_deop) {
+ struct neonserv_cmd_deop_cache *cache = malloc(sizeof(*cache));
+ if (!cache) {
+ perror("malloc() failed");
+ return;
+ }
+ cache->client = client;
+ cache->textclient = getTextBot();
+ cache->user = user;
+ cache->event = event;
+ cache->argv = calloc(argc, sizeof(char*));
+ int i;
+ for(i = 0; i < argc; i++) {
+ cache->argv[i] = strdup(argv[i]);
+ }
+ cache->argc = argc;
+ get_userlist(chan, neonserv_cmd_deop_userlist_lookup, cache);
+}
+
+static USERLIST_CALLBACK(neonserv_cmd_deop_userlist_lookup) {
+ struct neonserv_cmd_deop_cache *cache = data;
+ neonserv_cmd_deop_async1(cache->client, cache->textclient, cache->user, chan, cache->event, cache->argv, cache->argc);
+ int i;
+ for(i = 0; i < cache->argc; i++) {
+ free(cache->argv[i]);
+ }
+ free(cache->argv);
+ free(cache);
+}
+
+static void neonserv_cmd_deop_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char **argv, int argc) {
+ int i, done_users = 0;
+ struct UserNode *cuser;
+ struct ChanUser *chanuser;
+ struct ModeBuffer *modeBuf;
+ modeBuf = initModeBuffer(client, chan);
+ for(i = 0; i < argc; i++) {
+ cuser = searchUserByNick(argv[i]);
+ if(!cuser) continue;
+ chanuser = getChanUser(cuser, chan);
+ if(!chanuser) continue;
+ if(isNetworkService(cuser)) {
+ reply(textclient, user, "NS_SERVICE_IMMUNE", cuser->nick);
+ continue;
+ }
+ if(isUserProtected(chan, cuser, user)) {
+ reply(textclient, user, "NS_USER_PROTECTED", cuser->nick);
+ continue;
+ }
+ done_users++;
+ if(!(chanuser->flags & CHANUSERFLAG_OPPED)) continue;
+ modeBufferDeop(modeBuf, argv[i]);
+ }
+ freeModeBuffer(modeBuf);
+ if(done_users == argc)
+ reply(textclient, user, "NS_DEOP_DONE", chan->name);
+ else
+ reply(textclient, user, "NS_DEOP_FAIL", client->user->nick);
+ if(done_users)
+ logEvent(event);
+}
--- /dev/null
+/* cmd_neonserv_deopall.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* argv[0] (optional) nick mask
+*/
+static USERLIST_CALLBACK(neonserv_cmd_deopall_userlist_lookup);
+static void neonserv_cmd_deopall_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char **argv, int argc);
+
+struct neonserv_cmd_deopall_cache {
+ struct ClientSocket *client, *textclient;
+ struct UserNode *user;
+ struct Event *event;
+ char **argv;
+ int argc;
+};
+
+CMD_BIND(neonserv_cmd_deopall) {
+ struct neonserv_cmd_deopall_cache *cache = malloc(sizeof(*cache));
+ if (!cache) {
+ perror("malloc() failed");
+ return;
+ }
+ cache->client = client;
+ cache->textclient = getTextBot();
+ cache->user = user;
+ cache->event = event;
+ cache->argv = calloc(argc, sizeof(char*));
+ int i;
+ for(i = 0; i < argc; i++) {
+ cache->argv[i] = strdup(argv[i]);
+ }
+ cache->argc = argc;
+ get_userlist(chan, neonserv_cmd_deopall_userlist_lookup, cache);
+}
+
+static USERLIST_CALLBACK(neonserv_cmd_deopall_userlist_lookup) {
+ struct neonserv_cmd_deopall_cache *cache = data;
+ neonserv_cmd_deopall_async1(cache->client, cache->textclient, cache->user, chan, cache->event, cache->argv, cache->argc);
+ int i;
+ for(i = 0; i < cache->argc; i++) {
+ free(cache->argv[i]);
+ }
+ free(cache->argv);
+ free(cache);
+}
+
+static void neonserv_cmd_deopall_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char **argv, int argc) {
+ int issuer_access, victim_access, done_users = 0;
+ char *nickmask = NULL;
+ struct ChanUser *chanuser;
+ struct ModeBuffer *modeBuf;
+ if(argc > 0)
+ nickmask = argv[0];
+ modeBuf = initModeBuffer(client, chan);
+ issuer_access = getChannelAccess(user, chan);
+ for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
+ if(nickmask && match(nickmask, chanuser->user->nick)) continue;
+ victim_access = getChannelAccess(chanuser->user, chan);
+ if(victim_access >= issuer_access || isNetworkService(chanuser->user)) continue;
+ if(!(chanuser->flags & CHANUSERFLAG_OPPED)) continue;
+ modeBufferDeop(modeBuf, chanuser->user->nick);
+ done_users++;
+ }
+ freeModeBuffer(modeBuf);
+ reply(getTextBot(), user, "NS_DEOPALL_DONE", done_users, chan->name);
+ if(done_users)
+ logEvent(event);
+}
--- /dev/null
+/* cmd_neonserv_devoice.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* argv[0-*] nicks
+*/
+
+CMD_BIND(neonserv_cmd_devoice) {
+ int i, done_users = 0;
+ struct UserNode *cuser;
+ struct ChanUser *chanuser;
+ struct ModeBuffer *modeBuf;
+ modeBuf = initModeBuffer(client, chan);
+ for(i = 0; i < argc; i++) {
+ cuser = searchUserByNick(argv[i]);
+ if(!cuser) continue;
+ chanuser = getChanUser(cuser, chan);
+ if(!chanuser) continue;
+ if(isUserProtected(chan, cuser, user)) {
+ reply(getTextBot(), user, "NS_USER_PROTECTED", cuser->nick);
+ continue;
+ }
+ done_users++;
+ if(!(chanuser->flags & CHANUSERFLAG_VOICED)) continue;
+ modeBufferDevoice(modeBuf, argv[i]);
+ }
+ freeModeBuffer(modeBuf);
+ if(done_users == argc)
+ reply(getTextBot(), user, "NS_DEVOICE_DONE", chan->name);
+ else
+ reply(getTextBot(), user, "NS_DEVOICE_FAIL", client->user->nick);
+ if(done_users)
+ logEvent(event);
+}
--- /dev/null
+/* cmd_neonserv_devoiceall.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* argv[0] (optional) nick mask
+*/
+
+CMD_BIND(neonserv_cmd_devoiceall) {
+ int issuer_access, victim_access, done_users = 0;
+ char *nickmask = NULL;
+ struct ChanUser *chanuser;
+ struct ModeBuffer *modeBuf;
+ check_mysql();
+ if(argc > 0)
+ nickmask = argv[0];
+ modeBuf = initModeBuffer(client, chan);
+ issuer_access = getChannelAccess(user, chan);
+ for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
+ if(nickmask && match(nickmask, chanuser->user->nick)) continue;
+ victim_access = getChannelAccess(chanuser->user, chan);
+ if(victim_access >= issuer_access) continue;
+ if(!(chanuser->flags & CHANUSERFLAG_VOICED)) continue;
+ modeBufferDevoice(modeBuf, chanuser->user->nick);
+ done_users++;
+ }
+ freeModeBuffer(modeBuf);
+ reply(getTextBot(), user, "NS_DEVOICEALL_DONE", done_users, chan->name);
+ if(done_users)
+ logEvent(event);
+}
--- /dev/null
+/* cmd_neonserv_down.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* no arguments
+*/
+
+CMD_BIND(neonserv_cmd_down) {
+ struct ChanUser *chanuser = getChanUser(user, chan);
+ if(!chanuser) {
+ reply(getTextBot(), user, "NS_NOT_ON_CHANNEL_YOU", chan->name);
+ return;
+ }
+ if((chanuser->flags & CHANUSERFLAG_OPPED)) {
+ putsock(client, "MODE %s -ov %s %s", chan->name, user->nick, user->nick);
+ logEvent(event);
+ } else if((chanuser->flags & CHANUSERFLAG_VOICED)) {
+ putsock(client, "MODE %s -v %s", chan->name, user->nick);
+ logEvent(event);
+ } else
+ reply(getTextBot(), user, "NS_DOWN_ALREADY", chan->name);
+}
--- /dev/null
+/* cmd_neonserv_downall.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* no arguments
+*/
+
+CMD_BIND(neonserv_cmd_downall) {
+ struct ChanUser *chanuser;
+ int botid = client->botid;
+ for(chanuser = getUserChannels(user, NULL); chanuser; chanuser = getUserChannels(user, chanuser)) {
+ chan = chanuser->chan;
+ loadChannelSettings(chan);
+ if(!(chan->flags & CHANFLAG_CHAN_REGISTERED)) continue;
+ 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);
+ if (mysql_fetch_row(mysql_use()) == NULL) continue;
+ int done = 0;
+ client = getChannelBot(chan, botid);
+ if(!client) continue;
+ if((chanuser->flags & CHANUSERFLAG_OPPED)) {
+ putsock(client, "MODE %s -o %s", chan->name, user->nick);
+ done = 1;
+ }
+ if((chanuser->flags & CHANUSERFLAG_VOICED)) {
+ putsock(client, "MODE %s -v %s", chan->name, user->nick);
+ done = 1;
+ }
+ if(done) {
+ //event hack
+ event->chan = chan;
+ logEvent(event);
+ }
+ }
+}
--- /dev/null
+/* cmd_neonserv_events.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* argv[0] time
+* argv[1-*] match
+*/
+
+CMD_BIND(neonserv_cmd_events) {
+ char *str_match;
+ int duration = (argc ? strToTime(user, argv[0]) : 0);
+ if(argc > (duration ? 1 : 0))
+ str_match = merge_argv(argv, (duration ? 1 : 0), argc);
+ else
+ str_match = "";
+ if(!duration) duration = (60*60*24);
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ printf_mysql_query("SELECT `time`, `auth`, `nick`, `command` FROM `events` WHERE `cid` = '%d' AND `time` > '%lu' ORDER BY `time` ASC", chan->channel_id, ((unsigned long) time(0) - duration));
+ res = mysql_use();
+ int skip = mysql_num_rows(res) - 100;
+ int count = 0;
+ char timeBuf[50];
+ struct tm *timeinfo;
+ time_t event_time;
+ if(skip < 0) skip = 0;
+ reply(getTextBot(), user, "NS_EVENTS_HEADER");
+ while ((row = mysql_fetch_row(res)) != NULL) {
+ if(skip) {
+ skip--;
+ continue;
+ }
+ if(*str_match && match(str_match, row[3])) continue;
+ count++;
+ event_time = (time_t) atol(row[0]);
+ timeinfo = localtime(&event_time);
+ strftime(timeBuf, 80, "%X %x", timeinfo);
+ reply(getTextBot(), user, "[%s] [%s:%s]: %s", timeBuf, row[2], row[1], row[3]);
+ }
+ reply(getTextBot(), user, "NS_TABLE_COUNT", count);
+}
--- /dev/null
+/* cmd_neonserv_extscript.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+#include <fcntl.h>
+
+/*
+* argv[0] 'toys' if it's a toy command (check if toys are enabled)
+* argv[0-*] script name & parameter patterns
+* argv[argc-1] all arguments passed to the command
+*/
+
+static TIMEQ_CALLBACK(neonserv_cmd_extscript_callback);
+
+struct neonserv_cmd_extscript_cache {
+ struct ClientSocket *client, *textclient;
+ struct Event *event;
+ struct UserNode *user;
+ struct ChanNode *chan;
+ int answere_channel;
+ FILE *pipe;
+};
+
+CMD_BIND(neonserv_cmd_extscript) {
+ int i, j;
+ char *args[MAXNUMPARAMS];
+ int argpos = 0;
+ char *next, *curr;
+ char command[1024];
+ int commandpos = 0;
+ char part[MAXLEN];
+ int partpos;
+ int escape_param;
+ int answere_channel = 0;
+ //check first arg
+ if(argc && !stricmp(argv[0], "toys")) {
+ if(!chan) return; //toys are not allowed via query
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ printf_mysql_query("SELECT `channel_toys` FROM `channels` WHERE `channel_name` = '%s'", escape_string(chan->name));
+ res = mysql_use();
+ row = mysql_fetch_row(res);
+ if(!row || !strcmp(row[0], "0")) {
+ //disabled
+ reply(getTextBot(), user, "NS_FUN_DISABLED", chan->name);
+ return;
+ } else if(!strcmp(row[0], "2"))
+ answere_channel = 1;
+ argc--;
+ argv++;
+ }
+ //parse arguments
+ if(argc < 2) return;
+ curr = argv[argc-1];
+ while(curr) {
+ next = strstr(curr, " ");
+ args[argpos++] = curr;
+ if(next) {
+ *next = '\0';
+ curr = next+1;
+ } else
+ curr = NULL;
+ }
+ //parse command pattern and build command
+ commandpos = sprintf(command, "%s", argv[0]);
+ for(i = 1; i < argc-1; i++) {
+ partpos = 0;
+ escape_param = 1;
+ if(argv[i][0] == '$') {
+ argv[i]++;
+ if(argv[i][strlen(argv[i])-1] == '-') {
+ argv[i][strlen(argv[i])-1] = '\0';
+ j = atoi(argv[i]);
+ if(j <= argpos)
+ partpos = sprintf(part, "%s", merge_argv(args, j-1, argpos));
+ } else if((j = atoi(argv[i])) > 0) {
+ if(j <= argpos)
+ partpos = sprintf(part, "%s", args[j-1]);
+ } else if(!strcmp(argv[i], "c")) {
+ partpos = sprintf(part, "%s", (chan ? chan->name : ""));
+ } else if(!strcmp(argv[i], "n")) {
+ partpos = sprintf(part, "%s", user->nick);
+ } else if(!strcmp(argv[i], "a")) {
+ partpos = sprintf(part, "%s", ((user->flags & USERFLAG_ISAUTHED) ? user->auth : ""));
+ } else if(!strcmp(argv[i], "access")) {
+ if(chan)
+ partpos = sprintf(part, "%d", getChannelAccess(user, chan));
+ }
+ } else {
+ partpos = sprintf(part, "%s", argv[i]);
+ escape_param = 0;
+ }
+ //escape shell argument
+ command[commandpos++] = ' ';
+ if(escape_param) {
+ command[commandpos++] = '\'';
+ for(j = 0; j < partpos; j++) {
+ if(part[j] == '\'') {
+ command[commandpos++] = '\'';
+ command[commandpos++] = '\\';
+ command[commandpos++] = '\'';
+ command[commandpos++] = '\'';
+ } else
+ command[commandpos++] = part[j];
+ }
+ command[commandpos++] = '\'';
+ } else
+ commandpos += sprintf(command + commandpos, " %s", part);
+ }
+ command[commandpos] = '\0';
+ //we should now have a valid command
+
+ struct neonserv_cmd_extscript_cache *cache = malloc(sizeof(*cache));
+ if (!cache) {
+ perror("malloc() failed");
+ return;
+ }
+ cache->client = client;
+ cache->textclient = getTextBot();
+ cache->event = event;
+ cache->user = user;
+ cache->chan = chan;
+ cache->answere_channel = answere_channel;
+ cache->pipe = popen(command, "r");
+ #ifndef WIN32
+ fcntl(fileno(cache->pipe), F_SETFL, O_NONBLOCK);
+ #endif
+ timeq_uadd(200, neonserv_cmd_extscript_callback, cache);
+}
+
+static TIMEQ_CALLBACK(neonserv_cmd_extscript_callback) {
+ struct neonserv_cmd_extscript_cache *cache = data;
+ char command[512];
+ char *a;
+ if(feof(cache->pipe)) {
+ pclose(cache->pipe);
+ free(cache);
+ return;
+ }
+ while (fgets(command, 512, cache->pipe) != NULL) {
+ if((a = strchr(command, '\n')))
+ *a = '\0';
+ if(!stricmp(command, "/log")) {
+ logEvent(cache->event);
+ continue;
+ }
+ if(cache->answere_channel)
+ putsock(cache->client, "PRIVMSG %s :%s", cache->chan->name, command);
+ else
+ reply(cache->textclient, cache->user, "%s", command);
+ }
+ timeq_uadd(200, neonserv_cmd_extscript_callback, cache);
+}
+
+
+
--- /dev/null
+/* cmd_neonserv_giveowner.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* argv[0] - nick / *auth
+* argv[1] - key
+*/
+
+#define GIVEOWNER_TIMEOUT 86400 /* 60*60*24 = 86400 */
+
+static USERAUTH_CALLBACK(neonserv_cmd_giveowner_nick_lookup);
+static void neonserv_cmd_giveowner_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nick, char *auth, char *key);
+
+struct neonserv_cmd_giveowner_cache {
+ struct ClientSocket *client, *textclient;
+ struct UserNode *user;
+ struct ChanNode *chan;
+ struct Event *event;
+ char *nick;
+ char *key;
+};
+
+CMD_BIND(neonserv_cmd_giveowner) {
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ printf_mysql_query("SELECT `channel_lastgiveowner` FROM `channels` WHERE `channel_id` = '%d'", chan->channel_id);
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) == NULL) return;
+ if(strcmp(row[0], "0") && (atoi(row[0]) + GIVEOWNER_TIMEOUT) > time(0)) {
+ char timeBuf[MAXLEN];
+ reply(getTextBot(), user, "NS_GIVEOWNER_TIMEOUT", timeToStr(user, (GIVEOWNER_TIMEOUT - (time(0) - atoi(row[0]))), 2, timeBuf), chan->name);
+ return;
+ }
+ if(argv[0][0] == '*') {
+ //we've got an auth
+ argv[0]++;
+ neonserv_cmd_giveowner_async1(client, getTextBot(), user, chan, event, argv[0], argv[0], (argc != 1 ? argv[1] : NULL));
+ } else {
+ struct UserNode *cuser = getUserByNick(argv[0]);
+ if(!cuser) {
+ cuser = createTempUser(argv[0]);
+ if(!cuser) {
+ reply(getTextBot(), user, "NS_USER_UNKNOWN", argv[0]);
+ return;
+ }
+ cuser->flags |= USERFLAG_ISTMPUSER;
+ }
+ if(cuser->flags & USERFLAG_ISAUTHED) {
+ neonserv_cmd_giveowner_async1(client, getTextBot(), user, chan, event, argv[0], cuser->auth, (argc != 1 ? argv[1] : NULL));
+ } else {
+ struct neonserv_cmd_giveowner_cache *cache = malloc(sizeof(*cache));
+ if (!cache) {
+ perror("malloc() failed");
+ return;
+ }
+ cache->client = client;
+ cache->textclient = getTextBot();
+ cache->user = user;
+ cache->chan = chan;
+ cache->event = event;
+ cache->nick = strdup(argv[0]);
+ cache->key = (argc != 1 ? strdup(argv[1]) : NULL);
+ get_userauth(cuser, neonserv_cmd_giveowner_nick_lookup, cache);
+ }
+ }
+}
+
+static USERAUTH_CALLBACK(neonserv_cmd_giveowner_nick_lookup) {
+ struct neonserv_cmd_giveowner_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_giveowner_async1(cache->client, cache->textclient, cache->user, cache->chan, cache->event, user->nick, user->auth, cache->key);
+ free(cache->nick);
+ if(cache->key)
+ free(cache->key);
+ free(cache);
+}
+
+static void neonserv_cmd_giveowner_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nick, char *auth, char *key) {
+ //we've got a valid auth now...
+ if(!stricmp(user->auth, auth)) {
+ reply(textclient, user, "NS_GIVEOWNER_SELF");
+ return;
+ }
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ printf_mysql_query("SELECT `user_user`, `dnr_timeout`, `dnr_reason`, `dnr_id` FROM `donotregister` LEFT JOIN `users` ON `dnr_user` = `user_id` WHERE `dnr_target` = '%s'", escape_string(auth));
+ res = mysql_use();
+ if((row = mysql_fetch_row(res)) != NULL) {
+ int expire_time = atoi(row[1]);
+ if(expire_time) {
+ if(expire_time - time(0) <= 0) {
+ printf_mysql_query("DELETE FROM `donotregister` WHERE `dnr_id` = '%s'", row[3]);
+ } else {
+ reply(getTextBot(), user, "NS_DNR_SET_ANONYM", auth);
+ return;
+ }
+ } else {
+ reply(getTextBot(), user, "NS_DNR_SET_ANONYM", auth);
+ return;
+ }
+ }
+ 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]);
+ //check if the user is already added
+ printf_mysql_query("SELECT `chanuser_access`, `chanuser_id` FROM `chanusers` WHERE `chanuser_cid` = '%d' AND `chanuser_uid` = '%d'", chan->channel_id, userid);
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) != NULL) {
+ int seed = 0;
+ char *tmp;
+ char giveownerkey[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(giveownerkey, "%08x", seed);
+ if(key && !stricmp(giveownerkey, key)) {
+ //give ownership
+ printf_mysql_query("UPDATE `chanusers` SET `chanuser_access` = '500' WHERE `chanuser_id` = '%s'", row[1]);
+ printf_mysql_query("UPDATE `chanusers` SET `chanuser_access` = '499' WHERE `chanuser_cid` = '%d' AND `chanuser_uid` = (SELECT `user_id` FROM `users` WHERE `user_user` = '%s')", chan->channel_id, escape_string(user->auth));
+ printf_mysql_query("INSERT INTO `owner_history` (`owner_history_cid`, `owner_history_from_uid`, `owner_history_to_uid`, `owner_history_time`) VALUE ('%d', (SELECT `user_id` FROM `users` WHERE `user_user` = '%s'), '%d', UNIX_TIMESTAMP())", chan->channel_id, escape_string(user->auth), userid);
+ reply(textclient, user, "NS_GIVEOWNER_DONE", chan->name, auth);
+ logEvent(event);
+ } else {
+ reply(textclient, user, "NS_GIVEOWNER_CONFIRM", auth, giveownerkey);
+ }
+ return;
+ }
+ }
+ reply(textclient, user, "NS_NOT_ON_USERLIST", nick, chan->name);
+}
--- /dev/null
+/* cmd_neonserv_halfop.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* argv[0-*] nicks
+*/
+static USERLIST_CALLBACK(neonserv_cmd_halfop_userlist_lookup);
+static void neonserv_cmd_halfop_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nicks);
+
+struct neonserv_cmd_halfop_cache {
+ struct ClientSocket *client, *textclient;
+ struct UserNode *user;
+ struct Event *event;
+ char *nicks;
+};
+
+CMD_BIND(neonserv_cmd_halfop) {
+ struct neonserv_cmd_halfop_cache *cache = malloc(sizeof(*cache));
+ if (!cache) {
+ perror("malloc() failed");
+ return;
+ }
+ cache->client = client;
+ cache->textclient = getTextBot();
+ cache->user = user;
+ cache->event = event;
+ cache->nicks = strdup(merge_argv(argv, 0, argc));
+ get_userlist_if_invisible(chan, neonserv_cmd_halfop_userlist_lookup, cache);
+}
+
+static USERLIST_CALLBACK(neonserv_cmd_halfop_userlist_lookup) {
+ struct neonserv_cmd_halfop_cache *cache = data;
+ neonserv_cmd_halfop_async1(cache->client, cache->textclient, cache->user, chan, cache->event, cache->nicks);
+ free(cache->nicks);
+ free(cache);
+}
+
+static void neonserv_cmd_halfop_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nicks) {
+ int total_users = 0, done_users = 0;
+ struct UserNode *cuser;
+ struct ChanUser *chanuser;
+ struct ModeBuffer *modeBuf;
+ modeBuf = initModeBuffer(client, chan);
+ char *a, *b = nicks;
+ do {
+ a = strstr(b, " ");
+ if(a) *a = '\0';
+ total_users++;
+ cuser = searchUserByNick(b);
+ if(!cuser) {
+ //check for an invisible user
+ for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
+ if(!stricmp(chanuser->user->nick, b)) {
+ cuser = chanuser->user;
+ break;
+ }
+ }
+ if(!cuser) continue;
+ } else {
+ chanuser = getChanUser(cuser, chan);
+ if(!chanuser) continue;
+ }
+ done_users++;
+ if(chanuser->flags & CHANUSERFLAG_OPPED) continue;
+ modeBufferHalfop(modeBuf, b);
+ if(a) {
+ b = a+1;
+ }
+ } while(a);
+ freeModeBuffer(modeBuf);
+ if(done_users == total_users)
+ reply(textclient, user, "NS_HALFOP_DONE", chan->name);
+ else
+ reply(textclient, user, "NS_HALFOP_FAIL", client->user->nick);
+ if(done_users)
+ logEvent(event);
+}
--- /dev/null
+/* cmd_neonserv_halfopall.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* argv[0] "force"
+* argv[1] (optional) nick mask
+*/
+static USERLIST_CALLBACK(neonserv_cmd_halfopall_userlist_lookup);
+static void neonserv_cmd_halfopall_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nickmask);
+
+struct neonserv_cmd_halfopall_cache {
+ struct ClientSocket *client, *textclient;
+ struct UserNode *user;
+ struct Event *event;
+ char *nickmask;
+};
+
+CMD_BIND(neonserv_cmd_halfopall) {
+ struct neonserv_cmd_halfopall_cache *cache = malloc(sizeof(*cache));
+ if (!cache) {
+ perror("malloc() failed");
+ return;
+ }
+ cache->client = client;
+ cache->textclient = getTextBot();
+ cache->user = user;
+ cache->event = event;
+ if(argc) {
+ cache->nickmask = strdup(argv[0]);
+ } else
+ cache->nickmask = NULL;
+ get_userlist_if_invisible(chan, neonserv_cmd_halfopall_userlist_lookup, cache);
+}
+
+static USERLIST_CALLBACK(neonserv_cmd_halfopall_userlist_lookup) {
+ struct neonserv_cmd_halfopall_cache *cache = data;
+ neonserv_cmd_halfopall_async1(cache->client, cache->textclient, cache->user, chan, cache->event, cache->nickmask);
+ if(cache->nickmask)
+ free(cache->nickmask);
+ free(cache);
+}
+
+static void neonserv_cmd_halfopall_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nickmask) {
+ int done_users = 0;
+ struct ChanUser *chanuser;
+ struct ModeBuffer *modeBuf;
+ modeBuf = initModeBuffer(client, chan);
+ for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
+ if(nickmask && match(nickmask, chanuser->user->nick)) continue;
+ if(chanuser->flags & CHANUSERFLAG_OPPED) continue;
+ modeBufferHalfop(modeBuf, chanuser->user->nick);
+ done_users++;
+ }
+ freeModeBuffer(modeBuf);
+ reply(textclient, user, "NS_HALFOPALL_DONE", done_users, chan->name);
+ if(done_users)
+ logEvent(event);
+}
--- /dev/null
+/* cmd_neonserv_help.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* argv[0-*] index
+*/
+
+CMD_BIND(neonserv_cmd_help) {
+ char *ident;
+ if(argc)
+ ident = merge_argv(argv, 0, argc);
+ else
+ ident = "0";
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ printf_mysql_query("SELECT `user_lang` FROM `users` WHERE `user_user` = '%s'", escape_string(user->auth));
+ res = mysql_use();
+ char *lang;
+ if ((row = mysql_fetch_row(res)) != NULL)
+ lang = row[0];
+ else
+ lang = "en";
+ printf_mysql_query("SELECT `text` FROM `help` WHERE `lang` = '%s' AND `ident` = '%s'", escape_string(lang), escape_string(ident));
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) == NULL) {
+ if(stricmp(lang, "en")) {
+ printf_mysql_query("SELECT `text` FROM `help` WHERE `lang` = 'en' AND `ident` = '%s'", escape_string(ident));
+ res = mysql_use();
+ }
+ if ((row = mysql_fetch_row(res)) == NULL) {
+ reply(getTextBot(), user, "NS_HELP_TOPIC");
+ return;
+ }
+ }
+ char sendBuf[MAXLEN];
+ int sendBufPos = 0;
+ int i;
+ for(i = 0; i < strlen(row[0]); i++) {
+ switch(row[0][i]) {
+ case '\n':
+ if(sendBufPos) {
+ sendBuf[sendBufPos] = '\0';
+ reply(getTextBot(), user, "%s", sendBuf);
+ sendBufPos = 0;
+ }
+ break;
+ case '$':
+ switch(row[0][i+1]) {
+ case 'b':
+ sendBuf[sendBufPos++] = 2;
+ i++;
+ break;
+ case 'k':
+ sendBuf[sendBufPos++] = 3;
+ i++;
+ break;
+ case 'u':
+ sendBuf[sendBufPos++] = 31;
+ i++;
+ break;
+ case 'C':
+ case 'S':
+ sendBufPos += sprintf(sendBuf + sendBufPos, "%s", client->user->nick);
+ i++;
+ break;
+ default:
+ sendBuf[sendBufPos++] = '$';
+ break;
+ }
+ break;
+ default:
+ sendBuf[sendBufPos++] = row[0][i];
+ break;
+ }
+ }
+ if(sendBufPos) {
+ sendBuf[sendBufPos] = '\0';
+ reply(getTextBot(), user, "%s", sendBuf);
+ sendBufPos = 0;
+ }
+}
--- /dev/null
+/* cmd_neonserv_info.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* no parameters
+*/
+
+CMD_BIND(neonserv_cmd_info) {
+ MYSQL_RES *res;
+ MYSQL_ROW row, row2;
+ struct Table *table;
+ printf_mysql_query("SELECT `channel_defaulttopic`, `channel_modes`, `channel_maxusers`, `channel_lastvisit`, `channel_registered`, `user_user` FROM `channels` LEFT JOIN `users` ON `channel_registrator` = `user_id` WHERE `channel_id` = '%d'", chan->channel_id);
+ res = mysql_use();
+ row = mysql_fetch_row(res);
+ table = table_init(2, 9, 0);
+ table_set_bold(table, 0, 1);
+ char *content[2];
+ reply(getTextBot(), user, "NS_INFO_HEADER", chan->name);
+ content[0] = get_language_string(user, "NS_INFO_DEFAULTTOPIC");
+ content[1] = row[0];
+ table_add(table, content);
+ content[0] = get_language_string(user, "NS_INFO_MODELOCK");
+ content[1] = row[1];
+ table_add(table, content);
+ content[0] = get_language_string(user, "NS_INFO_RECORD");
+ content[1] = row[2];
+ table_add(table, content);
+ printf_mysql_query("SELECT `user_user`, `chanuser_access` FROM `chanusers` LEFT JOIN `users` ON `user_id` = `chanuser_uid` WHERE `chanuser_cid` = '%d'", chan->channel_id);
+ res = mysql_use();
+ char ownerstr[MAXLEN];
+ int ownerpos = 0, usercount = 0;
+ int userisowner = 0;
+ while((row2 = mysql_fetch_row(res))) {
+ if(!strcmp(row2[1], "500")) {
+ ownerpos += sprintf(ownerstr + ownerpos, (ownerpos ? ", %s" : "%s"), row2[0]);
+ if((user->flags & USERFLAG_ISAUTHED) && !stricmp(row2[0], user->auth))
+ userisowner = 1;
+ }
+ usercount++;
+ }
+ content[0] = get_language_string(user, "NS_INFO_OWNER");
+ content[1] = ownerstr;
+ table_add(table, content);
+ sprintf(ownerstr, "%d", usercount);
+ content[0] = get_language_string(user, "NS_INFO_USERS");
+ content[1] = ownerstr;
+ table_add(table, content);
+ printf_mysql_query("SELECT COUNT(*) FROM `bans` WHERE `ban_channel` = '%d'", chan->channel_id);
+ res = mysql_use();
+ row2 = mysql_fetch_row(res);
+ content[0] = get_language_string(user, "NS_INFO_BANS");
+ content[1] = row2[0];
+ table_add(table, content);
+ content[0] = get_language_string(user, "NS_INFO_VISITED");
+ content[1] = timeToStr(user, time(0) - atoi(row[3]), 2, ownerstr);
+ table_add(table, content);
+ if(strcmp(row[4], "0")) {
+ content[0] = get_language_string(user, "NS_INFO_REGISTERED");
+ content[1] = timeToStr(user, time(0) - atoi(row[4]), 2, ownerstr);
+ table_add(table, content);
+ }
+ if(row[5] && isGodMode(user)) {
+ content[0] = get_language_string(user, "NS_INFO_REGISTRAR");
+ content[1] = row[5];
+ table_add(table, content);
+ }
+ char **table_lines = table_end(table);
+ int i;
+ for(i = 0; i < table->entrys; i++) {
+ reply(getTextBot(), user, table_lines[i]);
+ }
+ table_free(table);
+ if(userisowner || isGodMode(user)) {
+ printf_mysql_query("SELECT `owner_history_time`, a.`user_user`, b.`user_user` FROM `owner_history` LEFT JOIN `users` a ON `owner_history_from_uid` = a.`user_id` LEFT JOIN `users` b ON `owner_history_to_uid` = b.`user_id` WHERE `owner_history_cid` = '%d'", chan->channel_id);
+ res = mysql_use();
+ if(mysql_num_rows(res)) {
+ reply(getTextBot(), user, "NS_INFO_OWNERLOG", chan->name);
+ time_t rawtime;
+ struct tm *timeinfo;
+ char timeBuf[80];
+ while((row = mysql_fetch_row(res))) {
+ rawtime = (time_t) atol(row[0]);
+ timeinfo = localtime(&rawtime);
+ strftime(timeBuf, 80, "%c", timeinfo);
+ reply(getTextBot(), user, "NS_INFO_OWNERCHANGE", row[1], row[2], timeBuf);
+ }
+ }
+ }
+}
--- /dev/null
+/* cmd_neonserv_invite.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* argv[0] - nick / *auth
+*/
+static USERAUTH_CALLBACK(neonserv_cmd_invite_nick_lookup);
+static void neonserv_cmd_invite_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nick, char *auth);
+static TIMEQ_CALLBACK(neonserv_cmd_invite_timeout_timeout);
+static struct neonserv_cmd_invite_timeout* neonserv_cmd_invite_add_timeout(char *nick, char *chan);
+static int neonserv_cmd_invite_is_timeout(char *nick, char *chan);
+static void neonserv_cmd_invite_del_timeout(struct neonserv_cmd_invite_timeout *timeout);
+
+
+struct neonserv_cmd_invite_cache {
+ struct ClientSocket *client, *textclient;
+ struct UserNode *user;
+ struct ChanNode *chan;
+ struct Event *event;
+ char *nick;
+};
+
+struct neonserv_cmd_invite_timeout {
+ char *nick;
+ char *chan;
+
+ struct neonserv_cmd_invite_timeout *next;
+};
+
+static struct neonserv_cmd_invite_timeout *first_timeout = NULL, *last_timeout = NULL;
+
+CMD_BIND(neonserv_cmd_invite) {
+ if(neonserv_cmd_invite_is_timeout(argv[0], chan->name)) {
+ reply(getTextBot(), user, "NS_INVITE_TIMEOUT", argv[0], chan->name);
+ return;
+ }
+ struct UserNode *cuser = getUserByNick(argv[0]);
+ if(!cuser) {
+ cuser = createTempUser(argv[0]);
+ if(!cuser) {
+ reply(getTextBot(), user, "NS_USER_UNKNOWN", argv[0]);
+ return;
+ }
+ cuser->flags |= USERFLAG_ISTMPUSER;
+ } else if(getChanUser(cuser, chan)) {
+ reply(getTextBot(), user, "NS_INVITE_ON_CHAN", cuser->nick, chan->name);
+ /* BUG
+ This check does not work if the user is invisible (CHMODE +D/+d)
+ to fix this we'd need to request the full userlist...
+ this is really senseless to invite a simple user so we simply mark this bug as unsolvable.
+ */
+ return;
+ }
+ if(cuser->flags & USERFLAG_ISAUTHED) {
+ neonserv_cmd_invite_async1(client, getTextBot(), user, chan, event, argv[0], cuser->auth);
+ } else {
+ struct neonserv_cmd_invite_cache *cache = malloc(sizeof(*cache));
+ if (!cache) {
+ perror("malloc() failed");
+ return;
+ }
+ cache->client = client;
+ cache->textclient = getTextBot();
+ cache->user = user;
+ cache->chan = chan;
+ cache->event = event;
+ cache->nick = strdup(argv[0]);
+ get_userauth(cuser, neonserv_cmd_invite_nick_lookup, cache);
+ }
+}
+
+static USERAUTH_CALLBACK(neonserv_cmd_invite_nick_lookup) {
+ struct neonserv_cmd_invite_cache *cache = data;
+ if(!user) {
+ //USER_DOES_NOT_EXIST
+ reply(cache->textclient, cache->user, "NS_USER_UNKNOWN", cache->nick);
+ } else
+ neonserv_cmd_invite_async1(cache->client, cache->textclient, cache->user, cache->chan, cache->event, user->nick, ((user->flags & USERFLAG_ISAUTHED) ? user->auth : NULL));
+ free(cache->nick);
+ free(cache);
+}
+
+static void neonserv_cmd_invite_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nick, char *auth) {
+ if(auth) {
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ 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) {
+ //check if the user has set noinvite
+ printf_mysql_query("SELECT `id` FROM `noinvite` WHERE `uid` = '%s' AND `cid` = '%d'", row[0], chan->channel_id);
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) != NULL) {
+ reply(textclient, user, "NS_INVITE_RESTRICTION", nick, chan->name);
+ return;
+ }
+ }
+ }
+ struct neonserv_cmd_invite_timeout *timeout = neonserv_cmd_invite_add_timeout(nick, chan->name);
+ timeq_add(INVITE_TIMEOUT, neonserv_cmd_invite_timeout_timeout, timeout);
+ putsock(client, "INVITE %s %s", nick, chan->name);
+ struct UserNode *tmpu = getUserByNick(nick);
+ if(!tmpu) {
+ tmpu = createTempUser(nick);
+ tmpu->flags |= USERFLAG_ISTMPUSER | (auth ? USERFLAG_ISAUTHED : 0);
+ if(auth)
+ strcpy(tmpu->auth, auth);
+ }
+ reply(textclient, tmpu, "NS_INVITE_DONE_USER", chan->name, user->nick, client->user->nick);
+ reply(textclient, user, "NS_INVITE_DONE", nick, chan->name);
+}
+
+static TIMEQ_CALLBACK(neonserv_cmd_invite_timeout_timeout) {
+ struct neonserv_cmd_invite_timeout *entry = data;
+ neonserv_cmd_invite_del_timeout(entry);
+}
+
+static struct neonserv_cmd_invite_timeout* neonserv_cmd_invite_add_timeout(char *nick, char *chan) {
+ struct neonserv_cmd_invite_timeout *entry = malloc(sizeof(*entry));
+ if (!entry) {
+ perror("malloc() failed");
+ return NULL;
+ }
+ entry->next = NULL;
+ entry->nick = strdup(nick);
+ entry->chan = strdup(chan);
+ if(last_timeout) {
+ last_timeout->next = entry;
+ last_timeout = entry;
+ } else {
+ last_timeout = entry;
+ first_timeout = entry;
+ }
+ return entry;
+}
+
+static int neonserv_cmd_invite_is_timeout(char *nick, char *chan) {
+ if(!first_timeout) return 0;
+ struct neonserv_cmd_invite_timeout *entry;
+ for(entry = first_timeout; entry; entry = entry->next) {
+ if(!stricmp(entry->nick, nick) && !stricmp(entry->chan, chan))
+ return 1;
+ }
+ return 0;
+}
+
+static void neonserv_cmd_invite_del_timeout(struct neonserv_cmd_invite_timeout *timeout) {
+ struct neonserv_cmd_invite_timeout *entry, *prev = NULL;
+ for(entry = first_timeout; entry; entry = entry->next) {
+ if(entry == timeout) {
+ if(prev)
+ prev->next = entry->next;
+ else
+ first_timeout = entry->next;
+ break;
+ } else
+ prev = entry;
+ }
+ if(last_timeout == timeout)
+ last_timeout = prev;
+ free(timeout->nick);
+ free(timeout->chan);
+ free(timeout);
+}
--- /dev/null
+/* cmd_neonserv_inviteme.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* no arguments
+*/
+
+CMD_BIND(neonserv_cmd_inviteme) {
+ if(getChanUser(user, chan)) {
+ reply(getTextBot(), user, "NS_INVITEME_ON_CHAN", chan->name);
+ /* BUG
+ This check does not work if the user is invisible (CHMODE +D/+d)
+ to fix this we'd need to request the full userlist...
+ this is really senseless to invite a simple user so we simply mark this bug as unsolvable.
+ */
+ return;
+ }
+ putsock(client, "INVITE %s %s", user->nick, chan->name);
+ reply(getTextBot(), user, "NS_INVITEME_DONE", chan->name);
+}
--- /dev/null
+/* cmd_neonserv_kick.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* argv[0] nick[,*auth[,*!*@mask[...]]]
+* argv[1-*] reason
+*/
+static USERLIST_CALLBACK(neonserv_cmd_kick_userlist_lookup);
+static void neonserv_cmd_kick_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nicks, char *reason);
+
+struct neonserv_cmd_kick_cache {
+ struct ClientSocket *client, *textclient;
+ struct UserNode *user;
+ struct Event *event;
+ char *nicks;
+ char *reason;
+};
+
+CMD_BIND(neonserv_cmd_kick) {
+ struct neonserv_cmd_kick_cache *cache = malloc(sizeof(*cache));
+ if (!cache) {
+ perror("malloc() failed");
+ return;
+ }
+ cache->client = client;
+ cache->textclient = getTextBot();
+ cache->user = user;
+ cache->event = event;
+ cache->nicks = strdup(argv[0]);
+ if(argc > 1) {
+ cache->reason = strdup(merge_argv(argv, 1, argc));
+ } else
+ cache->reason = NULL;
+ get_userlist_with_invisible(chan, neonserv_cmd_kick_userlist_lookup, cache);
+}
+
+static USERLIST_CALLBACK(neonserv_cmd_kick_userlist_lookup) {
+ struct neonserv_cmd_kick_cache *cache = data;
+ neonserv_cmd_kick_async1(cache->client, cache->textclient, cache->user, chan, cache->event, cache->nicks, (cache->reason ? cache->reason : "Bye."));
+ free(cache->nicks);
+ if(cache->reason)
+ free(cache->reason);
+ free(cache);
+}
+
+static void neonserv_cmd_kick_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nicks, char *reason) {
+ int i, kicked_users = 0, provided_nicks = 0;
+ char *nick, *nextnick;
+ struct UserNode *cuser;
+ struct ChanUser *chanuser;
+ nextnick = nicks;
+ while((nick = nextnick)) {
+ nextnick = strstr(nick, ",");
+ if(nextnick) {
+ *nextnick = '\0';
+ nextnick++;
+ }
+ if(!*nick) continue;
+ if(is_ircmask(nick)) {
+ //KICK HOSTMASK
+ char usermask[NICKLEN+USERLEN+HOSTLEN+3];
+ struct ChanUser *kick_chanuser[chan->usercount];
+ int kick_chanuser_pos = 0;
+ for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
+ cuser = chanuser->user;
+ sprintf(usermask, "%s!%s@%s", cuser->nick, cuser->ident, cuser->host);
+ if(!match(nick, usermask)) {
+ provided_nicks++;
+ if(isNetworkService(chanuser->user)) {
+ reply(textclient, user, "NS_SERVICE_IMMUNE", chanuser->user->nick);
+ continue;
+ }
+ if(cuser == user || ((cuser->flags & USERFLAG_ISAUTHED) && !stricmp(user->auth, cuser->auth))) {
+ reply(textclient, user, "NS_YOU_PROTECTED");
+ continue;
+ }
+ if(isUserProtected(chan, cuser, user)) {
+ reply(textclient, user, "NS_USER_PROTECTED", cuser->nick);
+ continue;
+ }
+ kick_chanuser[kick_chanuser_pos++] = chanuser;
+ if(kick_chanuser_pos > 4 && (kick_chanuser_pos * 3) > chan->usercount && !isGodMode(user)) {
+ kick_chanuser_pos = 0;
+ reply(textclient, user, "NS_LAME_MASK", nick);
+ break;
+ }
+ }
+ }
+ for(i = 0; i < kick_chanuser_pos; i++) {
+ kicked_users++;
+ putsock(client, "KICK %s %s :(%s) %s", chan->name, kick_chanuser[i]->user->nick, user->nick, reason);
+ }
+ } else if(*nick == '*') {
+ //KICK AUTH
+ nick++;
+ cuser = NULL;
+ if(!stricmp(user->auth, nick)) {
+ reply(textclient, user, "NS_YOU_PROTECTED");
+ continue;
+ }
+ for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
+ if((chanuser->user->flags & USERFLAG_ISAUTHED) && !stricmp(chanuser->user->auth, nick)) {
+ provided_nicks++;
+ if(isNetworkService(chanuser->user)) {
+ reply(textclient, user, "NS_SERVICE_IMMUNE", chanuser->user->nick);
+ continue;
+ }
+ if(!cuser) {
+ //check if the user is protected
+ if(isUserProtected(chan, chanuser->user, user)) {
+ reply(textclient, user, "NS_USER_PROTECTED", chanuser->user->nick);
+ break; //all other users are also protected...
+ }
+ cuser = chanuser->user;
+ }
+ kicked_users++;
+ putsock(client, "KICK %s %s :(%s) %s", chan->name, cuser->nick, user->nick, reason);
+ }
+ }
+ } else {
+ provided_nicks++;
+ cuser = NULL;
+ for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
+ if(!stricmp(chanuser->user->nick, nick)) {
+ cuser = chanuser->user;
+ }
+ }
+ if(!cuser) continue;
+ if(isNetworkService(cuser)) {
+ reply(textclient, user, "NS_SERVICE_IMMUNE", cuser->nick);
+ continue;
+ }
+ if(cuser == user || ((cuser->flags & USERFLAG_ISAUTHED) && !stricmp(user->auth, cuser->auth))) {
+ reply(textclient, user, "NS_YOU_PROTECTED");
+ continue;
+ }
+ if(isUserProtected(chan, cuser, user)) {
+ reply(textclient, user, "NS_USER_PROTECTED", cuser->nick);
+ continue;
+ }
+ kicked_users++;
+ putsock(client, "KICK %s %s :(%s) %s", chan->name, cuser->nick, user->nick, reason);
+ }
+ }
+ if(kicked_users == provided_nicks)
+ reply(getTextBot(), user, "NS_KICK_DONE", kicked_users, chan->name);
+ else
+ reply(getTextBot(), user, "NS_KICK_FAIL", client->user->nick);
+ if(kicked_users)
+ logEvent(event);
+}
--- /dev/null
+/* cmd_neonserv_kickban.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* argv[0] nick[,*auth[,*!*@mask[...]]]
+* argv[1-*] reason
+*/
+static USERLIST_CALLBACK(neonserv_cmd_kickban_userlist_lookup);
+static void neonserv_cmd_kickban_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nicks, char *reason);
+
+struct neonserv_cmd_kickban_cache {
+ struct ClientSocket *client, *textclient;
+ struct UserNode *user;
+ struct Event *event;
+ char *nicks;
+ char *reason;
+};
+
+CMD_BIND(neonserv_cmd_kickban) {
+ struct neonserv_cmd_kickban_cache *cache = malloc(sizeof(*cache));
+ if (!cache) {
+ perror("malloc() failed");
+ return;
+ }
+ cache->client = client;
+ cache->textclient = getTextBot();
+ cache->user = user;
+ cache->event = event;
+ cache->nicks = strdup(argv[0]);
+ if(argc > 1) {
+ cache->reason = strdup(merge_argv(argv, 1, argc));
+ } else
+ cache->reason = NULL;
+ get_userlist_with_invisible(chan, neonserv_cmd_kickban_userlist_lookup, cache);
+}
+
+static USERLIST_CALLBACK(neonserv_cmd_kickban_userlist_lookup) {
+ struct neonserv_cmd_kickban_cache *cache = data;
+ neonserv_cmd_kickban_async1(cache->client, cache->textclient, cache->user, chan, cache->event, cache->nicks, (cache->reason ? cache->reason : "Bye."));
+ free(cache->nicks);
+ if(cache->reason)
+ free(cache->reason);
+ free(cache);
+}
+
+static void neonserv_cmd_kickban_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nicks, char *reason) {
+ int i, kicked_users = 0, provided_nicks = 0;
+ char *nick, *nextnick;
+ struct UserNode *cuser;
+ struct ChanUser *chanuser;
+ char usermask[NICKLEN+USERLEN+HOSTLEN+3];
+ nextnick = nicks;
+ while((nick = nextnick)) {
+ nextnick = strstr(nick, ",");
+ if(nextnick) {
+ *nextnick = '\0';
+ nextnick++;
+ }
+ if(!*nick) continue;
+ if(is_ircmask(nick)) {
+ //KICK HOSTMASK
+ struct ChanUser *kickban_chanuser[chan->usercount];
+ int kick_chanuser_pos = 0;
+ for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
+ cuser = chanuser->user;
+ sprintf(usermask, "%s!%s@%s", cuser->nick, cuser->ident, cuser->host);
+ if(!match(nick, usermask)) {
+ provided_nicks++;
+ if(isNetworkService(chanuser->user)) {
+ reply(textclient, user, "NS_SERVICE_IMMUNE", chanuser->user->nick);
+ continue;
+ }
+ if(cuser == user || ((cuser->flags & USERFLAG_ISAUTHED) && !stricmp(user->auth, cuser->auth))) {
+ reply(textclient, user, "NS_YOU_PROTECTED");
+ continue;
+ }
+ if(isUserProtected(chan, cuser, user)) {
+ reply(textclient, user, "NS_USER_PROTECTED", cuser->nick);
+ continue;
+ }
+ kickban_chanuser[kick_chanuser_pos++] = chanuser;
+ if(kick_chanuser_pos > 4 && (kick_chanuser_pos * 3) > chan->usercount && !isGodMode(user)) {
+ kick_chanuser_pos = 0;
+ reply(textclient, user, "NS_LAME_MASK", nick);
+ break;
+ }
+ }
+ }
+ for(i = 0; i < kick_chanuser_pos; i++) {
+ if(i == 0) {
+ putsock(client, "MODE %s +b %s", chan->name, nick);
+ }
+ kicked_users++;
+ putsock(client, "KICK %s %s :(%s) %s", chan->name, kickban_chanuser[i]->user->nick, user->nick, reason);
+ }
+ } else if(*nick == '*') {
+ //KICK AUTH
+ nick++;
+ cuser = NULL;
+ if(!stricmp(user->auth, nick)) {
+ reply(textclient, user, "NS_YOU_PROTECTED");
+ continue;
+ }
+ for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
+ if((chanuser->user->flags & USERFLAG_ISAUTHED) && !stricmp(chanuser->user->auth, nick)) {
+ provided_nicks++;
+ if(isNetworkService(chanuser->user)) {
+ reply(textclient, user, "NS_SERVICE_IMMUNE", chanuser->user->nick);
+ continue;
+ }
+ if(!cuser) {
+ //check if the user is protected
+ if(isUserProtected(chan, chanuser->user, user)) {
+ reply(textclient, user, "NS_USER_PROTECTED", chanuser->user->nick);
+ break; //all other users are also protected...
+ }
+ cuser = chanuser->user;
+ }
+ kicked_users++;
+ putsock(client, "MODE %s +b %s", chan->name, generate_banmask(cuser, usermask));
+ putsock(client, "KICK %s %s :(%s) %s", chan->name, cuser->nick, user->nick, reason);
+ }
+ }
+ } else {
+ provided_nicks++;
+ cuser = searchUserByNick(nick);
+ if(!cuser) continue;
+ chanuser = getChanUser(cuser, chan);
+ if(!chanuser) continue;
+ if(isNetworkService(cuser)) {
+ reply(textclient, user, "NS_SERVICE_IMMUNE", cuser->nick);
+ continue;
+ }
+ if(cuser == user || ((cuser->flags & USERFLAG_ISAUTHED) && !stricmp(user->auth, cuser->auth))) {
+ reply(textclient, user, "NS_YOU_PROTECTED");
+ continue;
+ }
+ if(isUserProtected(chan, cuser, user)) {
+ reply(textclient, user, "NS_USER_PROTECTED", cuser->nick);
+ continue;
+ }
+ kicked_users++;
+ putsock(client, "MODE %s +b %s", chan->name, generate_banmask(cuser, usermask));
+ putsock(client, "KICK %s %s :(%s) %s", chan->name, cuser->nick, user->nick, reason);
+ }
+ }
+ if(kicked_users == provided_nicks)
+ reply(getTextBot(), user, "NS_KICKBAN_DONE", kicked_users, chan->name);
+ else
+ reply(getTextBot(), user, "NS_KICKBAN_FAIL", client->user->nick);
+ if(kicked_users)
+ logEvent(event);
+}
--- /dev/null
+/* cmd_neonserv_listrank.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* no arguments
+*/
+
+CMD_BIND(neonserv_cmd_listrank) {
+ MYSQL_RES *res, *res2;
+ MYSQL_ROW row, row2;
+ struct Table *table;
+ int ranks = 0;
+ printf_mysql_query("SELECT `rank_id`, `rank_name` FROM `support_ranks` ORDER BY `rank_order` ASC");
+ res = mysql_use();
+ table = table_init(3, mysql_num_rows(res) + 1, 0);
+ char *content[3];
+ content[0] = get_language_string(user, "NS_LISTRANK_ID");
+ content[1] = get_language_string(user, "NS_LISTRANK_NAME");
+ content[2] = get_language_string(user, "NS_LISTRANK_ASSIGNED");
+ table_add(table, content);
+ char usersBuf[MAXLEN];
+ int usersPos, userCount;
+ char assignedBuf[MAXLEN];
+ while ((row = mysql_fetch_row(res)) != NULL) {
+ ranks++;
+ content[0] = row[0];
+ content[1] = row[1];
+ printf_mysql_query("SELECT `user_user`, `user_god` FROM `users` WHERE `user_rank` = '%s'", row[0]);
+ res2 = mysql_use();
+ usersPos = 0;
+ userCount = 0;
+ while((row2 = mysql_fetch_row(res2)) != NULL) {
+ usersPos += sprintf(usersBuf+usersPos, (usersPos ? ", %s%s" : "%s%s"), (strcmp(row2[1], "0") ? "@" : ""), row2[0]);
+ userCount++;
+ }
+ sprintf(assignedBuf, (userCount ? "%d (%s)" : "%d"), userCount, usersBuf);
+ content[2] = assignedBuf;
+ table_add(table, content);
+ }
+ //send the table
+ char **table_lines = table_end(table);
+ int i;
+ for(i = 0; i < table->entrys; i++) {
+ reply(getTextBot(), user, table_lines[i]);
+ }
+ if(!ranks)
+ reply(getTextBot(), user, "NS_TABLE_NONE");
+ table_free(table);
+ printf_mysql_query("SELECT `user_user` FROM `users` WHERE `user_rank` = '0' AND `user_access` > 0");
+ res2 = mysql_use();
+ usersPos = 0;
+ userCount = 0;
+ while((row2 = mysql_fetch_row(res2)) != NULL) {
+ usersPos += sprintf(usersBuf+usersPos, (usersPos ? ", %s%s" : "%s%s"), (strcmp(row2[1], "0") ? "@" : ""), row2[0]);
+ userCount++;
+ }
+ reply(getTextBot(), user, "NS_LISTRANK_UNRANKED", userCount);
+ if(userCount) {
+ reply(getTextBot(), user, " %s", usersBuf);
+ }
+}
--- /dev/null
+/* cmd_neonserv_mdeluser.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* argv[0] access (format: minaccess-maxaccess)
+* argv[1] pattern
+*/
+
+CMD_BIND(neonserv_cmd_mdeluser) {
+ int min_access, max_access;
+ char *seperator = strstr(argv[0], "-");
+ if(seperator) {
+ *seperator = '\0';
+ seperator++;
+ min_access = atoi(argv[0]);
+ max_access = atoi(seperator);
+ if(max_access < min_access) {
+ reply(getTextBot(), user, "NS_INVALID_ACCESS_RANGE", min_access, max_access);
+ return;
+ }
+ } else {
+ min_access = atoi(argv[0]);
+ max_access = min_access;
+ }
+ if(max_access >= getChannelAccess(user, chan)) {
+ if(isGodMode(user)) {
+ event->flags |= CMDFLAG_OPLOG;
+ } else {
+ reply(getTextBot(), user, "NS_NO_ACCESS");
+ return;
+ }
+ }
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ int del_count = 0;
+ printf_mysql_query("SELECT `user_user`, `chanuser_id` FROM `chanusers` LEFT JOIN `users` ON `chanuser_uid` = `user_id` WHERE `chanuser_cid` = '%d' AND `chanuser_access` >= '%d' AND `chanuser_access` <= '%d'", chan->channel_id, min_access, max_access);
+ res = mysql_use();
+ while((row = mysql_fetch_row(res)) != NULL) {
+ if(!match(argv[1], row[0])) {
+ del_count++;
+ printf_mysql_query("DELETE FROM `chanusers` WHERE `chanuser_id` = '%s'", row[1]);
+ }
+ }
+ reply(getTextBot(), user, "NS_MDELUSER_DONE", del_count, argv[1], min_access, max_access, chan->name);
+ if(del_count)
+ logEvent(event);
+}
+
--- /dev/null
+/* cmd_neonserv_mode.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* argv[0] - modes
+* argv[1-*] - parameters
+*/
+static USERLIST_CALLBACK(neonserv_cmd_mode_userlist_lookup);
+static void neonserv_cmd_mode_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *mode);
+
+struct neonserv_cmd_mode_cache {
+ struct ClientSocket *client, *textclient;
+ struct UserNode *user;
+ struct Event *event;
+ char *mode;
+};
+
+CMD_BIND(neonserv_cmd_mode) {
+ struct neonserv_cmd_mode_cache *cache = malloc(sizeof(*cache));
+ if (!cache) {
+ perror("malloc() failed");
+ return;
+ }
+ cache->client = client;
+ cache->textclient = getTextBot();
+ cache->user = user;
+ cache->event = event;
+ cache->mode = strdup(merge_argv(argv, 0, argc));
+ get_userlist_with_invisible(chan, neonserv_cmd_mode_userlist_lookup, cache);
+}
+
+static USERLIST_CALLBACK(neonserv_cmd_mode_userlist_lookup) {
+ struct neonserv_cmd_mode_cache *cache = data;
+ neonserv_cmd_mode_async1(cache->client, cache->textclient, cache->user, chan, cache->event, cache->mode);
+ free(cache->mode);
+ free(cache);
+}
+
+static void neonserv_cmd_mode_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *mode) {
+ MYSQL_ROW row, defaults = NULL;
+ int i, arg, add = 1, skip = 0;
+ unsigned int modetype;
+ int db_canop, db_canvoice, db_canban, db_enfmodes;
+ struct ModeNode *modelock = createModeNode(NULL), *changemodes = createModeNode(NULL);
+ struct ModeBuffer *modeBuf;
+ struct UserNode *cuser;
+ struct ChanUser *chanuser;
+ modeBuf = initModeBuffer(client, chan);
+ printf_mysql_query("SELECT `channel_canop`, `channel_canvoice`, `channel_canban`, `channel_enfmodes`, `channel_modes` FROM `channels` WHERE `channel_id` = '%d'", chan->channel_id);
+ row = mysql_fetch_row(mysql_use());
+ if(row[0] == NULL || row[1] == NULL || row[2] == NULL || row[3] == NULL) {
+ printf_mysql_query("SELECT `channel_canop`, `channel_canvoice`, `channel_canban`, `channel_enfmodes`, `channel_modes` FROM `channels` WHERE `channel_name` = 'defaults'");
+ defaults = mysql_fetch_row(mysql_use());
+ }
+ db_canop = atoi((row[0] ? row[0] : defaults[0]));
+ db_canvoice = atoi((row[1] ? row[1] : defaults[1]));
+ db_canban = atoi((row[2] ? row[2] : defaults[2]));
+ db_enfmodes = atoi((row[3] ? row[3] : defaults[3]));
+ if(row[4])
+ parseModeString(modelock, row[4]);
+ else if(defaults[4])
+ parseModeString(modelock, defaults[4]);
+ int uaccess = getChannelAccess(user, chan);
+ char *a, *b = mode;
+ char *argv[MAXNUMPARAMS];
+ char *carg;
+ char tmp[MAXLEN];
+ int argc = 0;
+ do {
+ a = strstr(b, " ");
+ if(a) *a = '\0';
+ argv[argc++] = b;
+ if(argc == MAXNUMPARAMS) break;
+ if(a) b = a+1;
+ } while(a);
+ arg = 0;
+ while(arg < argc) {
+ char *modeStr = argv[arg++];
+ for(i = 0; i < strlen(modeStr); i++) {
+ switch(modeStr[i]) {
+ case '+':
+ add = 1;
+ break;
+ case '-':
+ add = 0;
+ break;
+ case 'o':
+ case 'v':
+ if(arg == argc) {
+ reply(textclient, user, "NS_MODE_INVALID", modeStr[i]);
+ return;
+ }
+ carg = argv[arg++];
+ if(modeStr[i] == 'o') {
+ if(uaccess < db_canop) {
+ reply(textclient, user, "NS_MODE_ENFOPS", chan->name);
+ db_canop = -1;
+ break;
+ }
+ if(db_canop == -1) break;
+ } else {
+ if(uaccess < db_canvoice) {
+ reply(textclient, user, "NS_MODE_ENFVOICE", chan->name);
+ db_canvoice = -1;
+ break;
+ }
+ if(db_canvoice == -1) break;
+ }
+ cuser = searchUserByNick(carg);
+ if(!cuser) {
+ //check for an invisible user
+ for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
+ if(!stricmp(chanuser->user->nick, carg)) {
+ cuser = chanuser->user;
+ break;
+ }
+ }
+ if(!cuser) break;
+ } else {
+ chanuser = getChanUser(cuser, chan);
+ if(!chanuser) break;
+ }
+ if(!(add ^ (chanuser->flags & (modeStr[i] == 'o' ? CHANUSERFLAG_OPPED : CHANUSERFLAG_VOICED)))) break;
+ if(!add) {
+ //check protection
+ if(modeStr[i] == 'o' && isNetworkService(cuser)) {
+ reply(textclient, user, "NS_SERVICE_IMMUNE", cuser->nick);
+ break;
+ }
+ if(isUserProtected(chan, cuser, user)) {
+ reply(textclient, user, "NS_USER_PROTECTED", cuser->nick);
+ break;
+ }
+ }
+ modeBufferSet(modeBuf, add, modeStr[i], carg);
+ break;
+ case 'b':
+ if(arg == argc) {
+ reply(textclient, user, "NS_MODE_INVALID", modeStr[i]);
+ return;
+ }
+ carg = argv[arg++];
+ if(uaccess < db_canban) {
+ reply(textclient, user, "NS_MODE_CANBAN", chan->name);
+ db_canban = -1;
+ break;
+ }
+ if(db_canban == -1) break;
+ char hostmask_buffer[NICKLEN+USERLEN+HOSTLEN+3];
+ char usermask[NICKLEN+USERLEN+HOSTLEN+3];
+ struct BanNode *ban;
+ int match_count = 0;
+ carg = make_banmask(carg, hostmask_buffer);
+ if(add) {
+ for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
+ cuser = chanuser->user;
+ sprintf(usermask, "%s!%s@%s", cuser->nick, cuser->ident, cuser->host);
+ if(!match(carg, usermask)) {
+ if(isNetworkService(chanuser->user)) {
+ reply(textclient, user, "NS_SERVICE_IMMUNE", chanuser->user->nick);
+ skip = 1;
+ break;
+ }
+ if(isUserProtected(chan, cuser, user)) {
+ reply(textclient, user, "NS_USER_PROTECTED", cuser->nick);
+ skip = 1;
+ break;
+ }
+ match_count++;
+ if(match_count > 4 && (match_count * 3) > chan->usercount && !isGodMode(user)) {
+ skip = 1;
+ reply(textclient, user, "NS_LAME_MASK", carg);
+ break;
+ }
+ }
+ }
+ } else {
+ skip = 1;
+ for(ban = chan->bans; ban; ban = ban->next) {
+ if(!match(carg, ban->mask)) {
+ skip = 0;
+ break;
+ }
+ }
+ }
+ if(!skip) {
+ modeBufferSet(modeBuf, add, 'b', carg);
+ }
+ break;
+ default:
+ modetype = getModeType(modelock, modeStr[i]);
+ if(modetype == 0) {
+ reply(textclient, user, "NS_MODE_INVALID", modeStr[i]);
+ return;
+ }
+ if(isModeAffected(modelock, modeStr[i]) && add == !isModeSet(modelock, modeStr[i]) && uaccess < db_enfmodes) {
+ if(isGodMode(user))
+ event->flags |= CMDFLAG_OPLOG;
+ else {
+ getFullModeString(modelock, tmp);
+ reply(textclient, user, "NS_MODE_LOCKED", tmp, chan->name);
+ return;
+ }
+ }
+ if(add && (modetype & CHANNEL_MODE_TYPE) != CHANNEL_MODE_TYPE_D) {
+ if(arg == argc) {
+ reply(textclient, user, "NS_MODE_INVALID", modeStr[i]);
+ return;
+ }
+ carg = argv[arg++];
+ if((modetype & CHANNEL_MODE_VALUE) == CHANNEL_MODE_VALUE_STRING && isModeSet(modelock, modeStr[i])) {
+ char *modelock_val = getModeValue(modelock, modeStr[i]);
+ if(stricmp(carg, modelock_val)) {
+ if(isGodMode(user))
+ event->flags |= CMDFLAG_OPLOG;
+ else {
+ getFullModeString(modelock, tmp);
+ reply(textclient, user, "NS_MODE_LOCKED", tmp, chan->name);
+ return;
+ }
+ }
+ }
+ if((modetype & CHANNEL_MODE_VALUE) == CHANNEL_MODE_VALUE_STRING && isModeSet(modelock, modeStr[i])) {
+ int *modelock_val = getModeValue(modelock, modeStr[i]);
+ if(atoi(carg) != *modelock_val) {
+ if(isGodMode(user))
+ event->flags |= CMDFLAG_OPLOG;
+ else {
+ getFullModeString(modelock, tmp);
+ reply(textclient, user, "NS_MODE_LOCKED", tmp, chan->name);
+ return;
+ }
+ }
+ }
+ } else if(!add && (modetype & CHANNEL_MODE_TYPE) == CHANNEL_MODE_TYPE_B) {
+ if(arg == argc && !(modetype & CHANNEL_MODE_KEY)) {
+ reply(textclient, user, "NS_MODE_INVALID", modeStr[i]);
+ return;
+ }
+ carg = (arg == argc ? NULL : argv[arg++]);
+ } else
+ carg = NULL;
+ if((modetype & CHANNEL_MODE_TYPE) == CHANNEL_MODE_TYPE_D && isModeSet(chan->modes, modeStr[i]) == add)
+ break;
+ if(!isModeAffected(changemodes, modeStr[i])) {
+ if(!add && (modetype & CHANNEL_MODE_KEY)) {
+ if(isModeSet(chan->modes, modeStr[i])) {
+ char *current_val = getModeValue(chan->modes, modeStr[i]);
+ carg = current_val;
+ }
+ }
+ if(parseMode(changemodes, add, modeStr[i], carg)) {
+ if(carg) {
+ if(add && (modetype & CHANNEL_MODE_KEY) && isModeSet(chan->modes, modeStr[i])) {
+ char *current_val = getModeValue(chan->modes, modeStr[i]);
+ modeBufferSet(modeBuf, 0, modeStr[i], current_val);
+ flushModeBuffer(modeBuf);
+ }
+ if(!add && !isModeSet(chan->modes, modeStr[i])) break;
+ modeBufferSet(modeBuf, add, modeStr[i], carg);
+ } else {
+ modeBufferSimpleMode(modeBuf, add, modeStr[i]);
+ }
+ } else {
+ reply(textclient, user, "NS_MODE_INVALID", modeStr[i]);
+ return;
+ }
+ }
+ break;
+ }
+ }
+ }
+ getFullModeString(changemodes, tmp);
+ freeModeBuffer(modeBuf);
+ if(strcmp(tmp, "+"))
+ reply(textclient, user, "NS_MODE_DONE", tmp);
+
+ logEvent(event);
+ freeModeNode(modelock);
+ freeModeNode(changemodes);
+}
--- /dev/null
+/* cmd_neonserv_move.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* argv[0] - channel
+* argv[1] - new channel
+*/
+CMD_BIND(neonserv_cmd_move) {
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ char *channel = argv[0];
+ char *new_channel = argv[1];
+ if(!is_valid_chan(new_channel)) {
+ reply(getTextBot(), user, "NS_INVALID_CHANNEL_NAME", new_channel);
+ return;
+ }
+ if(!stricmp(channel, new_channel)) {
+ reply(getTextBot(), user, "NS_MOVE_SELF");
+ return;
+ }
+ printf_mysql_query("SELECT `channel_id` FROM `bot_channels` LEFT JOIN `channels` ON `channel_id` = `chanid` WHERE `channel_name` = '%s'", escape_string(new_channel));
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) != NULL) {
+ reply(getTextBot(), user, "NS_REGISTER_ALREADY", new_channel, client->user->nick);
+ 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 {
+ reply(getTextBot(), user, "NS_UNREGISTER_NOT_REGISTERED", argv[0], client->user->nick);
+ return;
+ }
+ printf_mysql_query("SELECT `botid`, `bot_channels`.`id`, `suspended` FROM `bot_channels` LEFT JOIN `bots` ON `bot_channels`.`botid` = `bots`.`id` WHERE `chanid` = '%d' AND `botclass` = '%d'", chanid, client->botid);
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) == NULL) {
+ reply(getTextBot(), user, "NS_UNREGISTER_NOT_REGISTERED", argv[0], client->user->nick);
+ return;
+ }
+ if(!strcmp(row[2], "1")) {
+ reply(getTextBot(), user, "NS_MOVE_SUSPENDED");
+ return;
+ }
+ int botid = atoi(row[0]);
+ 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, "PART %s :Channel moved to %s.", channel, new_channel);
+ putsock(bot, "JOIN %s", new_channel);
+ }
+ printf_mysql_query("SELECT `channel_id` FROM `channels` WHERE `channel_name` = '%s'", escape_string(new_channel));
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) != NULL) {
+ chanid = atoi(row[0]);
+ printf_mysql_query("DELETE FROM `chanusers` WHERE `chanuser_cid` = '%d'", chanid);
+ printf_mysql_query("DELETE FROM `bans` WHERE `ban_channel` = '%d'", chanid);
+ printf_mysql_query("DELETE FROM `events` WHERE `cid` = '%d'", chanid);
+ printf_mysql_query("DELETE FROM `noinvite` WHERE `cid` = '%d'", chanid);
+ printf_mysql_query("DELETE FROM `owner_history` WHERE `owner_history_cid` = '%d'", chanid);
+ printf_mysql_query("DELETE FROM `channels` WHERE `channel_id` = '%d'", chanid);
+ }
+ printf_mysql_query("UPDATE `channels` SET `channel_name` = '%s' WHERE `channel_name` = '%s'", escape_string(new_channel), escape_string(channel));
+ struct ChanNode *channode = getChanByName(channel);
+ if(channode && channode->flags & CHANFLAG_REQUESTED_CHANINFO) {
+ channode->flags &= ~CHANFLAG_CHAN_REGISTERED;
+ channode->channel_id = 0;
+ }
+ reply(getTextBot(), user, "NS_MOVE_DONE", channel, new_channel);
+ logEvent(event);
+}
--- /dev/null
+/* cmd_neonserv_myaccess.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* argv[0] - nick / *auth
+*/
+static USERAUTH_CALLBACK(neonserv_cmd_myaccess_nick_lookup);
+static void neonserv_cmd_myaccess_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, char *nick, char *auth, char *chanmatch);
+
+struct neonserv_cmd_myaccess_cache {
+ struct ClientSocket *client, *textclient;
+ struct UserNode *user;
+ struct ChanNode *chan;
+ char *nick;
+ char *chanmatch;
+};
+
+CMD_BIND(neonserv_cmd_myaccess) {
+ char *chanmatch = NULL;
+ if(argc == 0 || argv[0][0] == '#') {
+ if(argc != 0) {
+ chanmatch = argv[0];
+ }
+ if(!(user->flags & USERFLAG_ISAUTHED)) {
+ struct neonserv_cmd_myaccess_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->chanmatch = (chanmatch ? strdup(chanmatch) : NULL);
+ get_userauth(user, neonserv_cmd_myaccess_nick_lookup, cache);
+ } else
+ neonserv_cmd_myaccess_async1(client, getTextBot(), user, chan, user->nick, user->auth, chanmatch);
+ }
+ else if(argv[0][0] == '*') {
+ //we've got an auth
+ if(argc > 1 && argv[1][0] == '#') {
+ chanmatch = argv[1];
+ }
+ argv[0]++;
+ neonserv_cmd_myaccess_async1(client, getTextBot(), user, chan, NULL, argv[0], chanmatch);
+ } else {
+ if(argc > 1 && argv[1][0] == '#') {
+ chanmatch = argv[1];
+ }
+ struct UserNode *cuser = getUserByNick(argv[0]);
+ if(!cuser) {
+ cuser = createTempUser(argv[0]);
+ if(!cuser) {
+ reply(getTextBot(), user, "NS_USER_UNKNOWN", argv[0]);
+ return;
+ }
+ cuser->flags |= USERFLAG_ISTMPUSER;
+ }
+ if(cuser->flags & USERFLAG_ISAUTHED) {
+ neonserv_cmd_myaccess_async1(client, getTextBot(), user, chan, argv[0], cuser->auth, chanmatch);
+ } else {
+ struct neonserv_cmd_myaccess_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->chanmatch = (chanmatch ? strdup(chanmatch) : NULL);
+ get_userauth(cuser, neonserv_cmd_myaccess_nick_lookup, cache);
+ }
+ }
+}
+
+static USERAUTH_CALLBACK(neonserv_cmd_myaccess_nick_lookup) {
+ struct neonserv_cmd_myaccess_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
+ if(!strcmp(cache->nick, cache->user->nick))
+ reply(cache->textclient, cache->user, "NS_YOU_NEED_AUTH");
+ else
+ reply(cache->textclient, cache->user, "NS_USER_NEED_AUTH", cache->nick);
+ }
+ else
+ neonserv_cmd_myaccess_async1(cache->client, cache->textclient, cache->user, cache->chan, user->nick, user->auth, cache->chanmatch);
+ if(cache->chanmatch)
+ free(cache->chanmatch);
+ free(cache->nick);
+ free(cache);
+}
+
+static void neonserv_cmd_myaccess_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, char *nick, char *auth, char *chanmatch) {
+ //we've got a valid auth now...
+ if(stricmp(user->auth, auth) && !isGodMode(user)) {
+ reply(textclient, user, "NS_MYACCESS_SELF_ONLY");
+ return;
+ }
+ MYSQL_RES *res, *default_res;
+ MYSQL_ROW user_row, chanuser_row, default_chan = NULL;
+ char flagBuf[5];
+ int userid, cflags, caccess, flagPos;
+ int i, total_count = 0, match_count = 0, owner_count = 0;
+ struct Table *table = NULL;
+ printf_mysql_query("SELECT `user_id`, `user_access`, `user_god` FROM `users` WHERE `user_user` = '%s'", escape_string(auth));
+ res = mysql_use();
+ char *content[4];
+ content[0] = get_language_string(user, "NS_MYACCESS_HEADER_NAME");
+ content[1] = get_language_string(user, "NS_MYACCESS_HEADER_ACCESS");
+ content[2] = get_language_string(user, "NS_MYACCESS_HEADER_FLAGS");
+ content[3] = get_language_string(user, "NS_MYACCESS_HEADER_INFO");
+ if(chanmatch)
+ reply(textclient, user, "NS_MYACCESS_HEADER_MATCH", auth, chanmatch);
+ else
+ reply(textclient, user, "NS_MYACCESS_HEADER", auth);
+ if ((user_row = mysql_fetch_row(res)) != NULL) {
+ userid = atoi(user_row[0]);
+ //check if the user is already added
+ printf_mysql_query("SELECT `chanuser_access`, `chanuser_flags`, `chanuser_infoline`, `channel_name`, `channel_getop`, `channel_getvoice`, `botid` FROM `chanusers` LEFT JOIN `channels` ON `chanuser_cid` = `channel_id` LEFT JOIN `bot_channels` ON `chanuser_cid` = `chanid` LEFT JOIN `bots` ON `bots`.`id` = `botid` WHERE `chanuser_uid` = '%d' AND `botclass` = '%d' AND `active` = '1' ORDER BY `chanuser_access` DESC, `channel_name` ASC", userid, client->botid);
+ res = mysql_use();
+ total_count = mysql_num_rows(res);
+ table = table_init(4, total_count + 1, 0);
+ table_add(table, content);
+ while ((chanuser_row = mysql_fetch_row(res)) != NULL) {
+ if(!strcmp(chanuser_row[0], "500")) owner_count++;
+ if(chanmatch && match(chanmatch, chanuser_row[0])) continue;
+ match_count++;
+ if((!chanuser_row[4] || !chanuser_row[5]) && !default_chan) {
+ printf_mysql_query("SELECT `channel_getop`, `channel_getvoice` FROM `channels` WHERE `channel_name` = 'defaults'");
+ default_res = mysql_use();
+ default_chan = mysql_fetch_row(default_res);
+ }
+ flagPos = 0;
+ content[0] = chanuser_row[3];
+ content[1] = chanuser_row[0];
+ cflags = atoi(chanuser_row[1]);
+ caccess = atoi(chanuser_row[0]);
+ if((cflags & DB_CHANUSER_SUSPENDED))
+ flagPos += sprintf(flagBuf + flagPos, "s");
+ if(caccess >= (chanuser_row[4] ? atoi(chanuser_row[4]) : atoi(default_chan[0])))
+ flagPos += sprintf(flagBuf + flagPos, "o");
+ if(caccess >= (chanuser_row[5] ? atoi(chanuser_row[5]) : atoi(default_chan[1])))
+ flagPos += sprintf(flagBuf + flagPos, "v");
+ if((cflags & DB_CHANUSER_AUTOINVITE))
+ flagPos += sprintf(flagBuf + flagPos, "i");
+ content[2] = (flagPos ? flagBuf : "");
+ content[3] = chanuser_row[2];
+ table_add(table, content);
+ }
+ } else {
+ table = table_init(4, 1, 0);
+ table_add(table, content);
+ }
+ //send the table
+ char **table_lines = table_end(table);
+ for(i = 0; i < table->entrys; i++) {
+ reply(textclient, user, table_lines[i]);
+ }
+ if(!match_count)
+ reply(textclient, user, "NS_TABLE_NONE");
+ if(chanmatch) {
+ reply(textclient, user, "NS_MYACCESS_COUNT_MATCH", auth, total_count, owner_count, match_count, chanmatch);
+ } else {
+ reply(textclient, user, "NS_MYACCESS_COUNT", auth, total_count, owner_count);
+ }
+ table_free(table);
+}
--- /dev/null
+/* cmd_neonserv_nicklist.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* argv[0] "force"
+* argv[1] (optional) nick mask
+*/
+static USERLIST_CALLBACK(neonserv_cmd_nicklist_userlist_lookup);
+static void neonserv_cmd_nicklist_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nickmask, int syncusers);
+static void neonserv_cmd_nicklist_synchronize_user(struct ChanNode *chan, struct UserNode *user, int access);
+
+struct neonserv_cmd_nicklist_cache {
+ struct ClientSocket *client, *textclient;
+ struct UserNode *user;
+ struct Event *event;
+ char *nickmask;
+ int syncusers;
+};
+
+CMD_BIND(neonserv_cmd_nicklist) {
+ int syncusers = 0;
+ if(argc && !stricmp(argv[0], "sync")) {
+ if(!checkChannelAccess(user, chan, "channel_canadd", 0)) {
+ if(isGodMode(user)) {
+ event->flags |= CMDFLAG_OPLOG;
+ } else {
+ reply(getTextBot(), user, "NS_ACCESS_DENIED");
+ return;
+ }
+ }
+ argv++;
+ argc--;
+ syncusers = 1;
+ event->flags |= CMDFLAG_LOG;
+ }
+ if(argc && !stricmp(argv[0], "nowho") && isGodMode(user)) {
+ argv++;
+ argc--;
+ neonserv_cmd_nicklist_async1(client, getTextBot(), user, chan, event, (argc ? argv[0] : NULL), syncusers);
+ return;
+ }
+ struct neonserv_cmd_nicklist_cache *cache = malloc(sizeof(*cache));
+ if (!cache) {
+ perror("malloc() failed");
+ return;
+ }
+ cache->client = client;
+ cache->textclient = getTextBot();
+ cache->user = user;
+ cache->event = event;
+ if(argc) {
+ cache->nickmask = strdup(argv[0]);
+ } else
+ cache->nickmask = NULL;
+ cache->syncusers = syncusers;
+ get_userlist_with_invisible(chan, neonserv_cmd_nicklist_userlist_lookup, cache);
+}
+
+static USERLIST_CALLBACK(neonserv_cmd_nicklist_userlist_lookup) {
+ struct neonserv_cmd_nicklist_cache *cache = data;
+ neonserv_cmd_nicklist_async1(cache->client, cache->textclient, cache->user, chan, cache->event, cache->nickmask, cache->syncusers);
+ if(cache->nickmask)
+ free(cache->nickmask);
+ free(cache);
+}
+
+static void neonserv_cmd_nicklist_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nickmask, int syncusers) {
+ MYSQL_RES *res;
+ MYSQL_ROW row, defaults = NULL;
+ struct Table *table;
+ table = table_init(3, chan->usercount + 1, 0);
+ char *content[3];
+ content[0] = get_language_string(user, "NS_NICKLIST_NICK");
+ content[1] = get_language_string(user, "NS_NICKLIST_STATE");
+ content[2] = get_language_string(user, "NS_NICKLIST_ACCESS");
+ table_add(table, content);
+ printf_mysql_query("SELECT `chanuser_access`, `user_user`, `chanuser_flags` FROM `chanusers` LEFT JOIN `users` ON `chanuser_uid` = `user_id` WHERE `chanuser_cid` = '%d'", chan->channel_id);
+ res = mysql_use();
+ int userlistlen = mysql_num_rows(res);
+ int i = 0;
+ MYSQL_ROW userlist[userlistlen];
+ while ((row = mysql_fetch_row(res)) != NULL) {
+ userlist[i++] = row;
+ }
+ int db_enfops, db_enfvoice;
+ printf_mysql_query("SELECT `channel_getop`, `channel_getvoice` FROM `channels` WHERE `channel_id` = '%d'", chan->channel_id);
+ row = mysql_fetch_row(mysql_use());
+ if(row[0] == NULL || row[1] == NULL) {
+ printf_mysql_query("SELECT `channel_getop`, `channel_getvoice` FROM `channels` WHERE `channel_name` = 'defaults'");
+ defaults = mysql_fetch_row(mysql_use());
+ }
+ db_enfops = atoi((row[0] ? row[0] : defaults[0]));
+ db_enfvoice = atoi((row[1] ? row[1] : defaults[1]));
+ int caccess = getChannelAccess(user, chan);
+ int synced_user = 0;
+ struct ChanUser *chanuser;
+ int sort_nicklist[] = {
+ CHANUSERFLAG_OPPED | CHANUSERFLAG_HALFOPPED | CHANUSERFLAG_VOICED,
+ CHANUSERFLAG_OPPED | CHANUSERFLAG_HALFOPPED,
+ CHANUSERFLAG_OPPED | CHANUSERFLAG_VOICED,
+ CHANUSERFLAG_OPPED,
+ CHANUSERFLAG_HALFOPPED | CHANUSERFLAG_VOICED,
+ CHANUSERFLAG_HALFOPPED,
+ CHANUSERFLAG_VOICED,
+ CHANUSERFLAG_INVISIBLE,
+ 0
+ };
+ int *sort_pos = sort_nicklist;
+ int sort_flags;
+ do {
+ sort_flags = *(sort_pos++);
+ char statebuf[5];
+ char accessbuf[9];
+ int uaccess;
+ int stateset = 0;
+ for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
+ if((chanuser->flags & (CHANUSERFLAG_OPPED | CHANUSERFLAG_VOICED | CHANUSERFLAG_INVISIBLE)) != sort_flags) continue;
+ if(nickmask && match(nickmask, chanuser->user->nick)) continue;
+ if(!stateset) {
+ if((chanuser->flags & CHANUSERFLAG_INVISIBLE)) statebuf[stateset++] = '<';
+ if((chanuser->flags & CHANUSERFLAG_OPPED)) statebuf[stateset++] = '@';
+ if((chanuser->flags & CHANUSERFLAG_HALFOPPED)) statebuf[stateset++] = '%';
+ if((chanuser->flags & CHANUSERFLAG_VOICED)) statebuf[stateset++] = '+';
+ statebuf[stateset++] = '\0';
+ }
+ content[0] = chanuser->user->nick;
+ content[1] = statebuf;
+ uaccess = 0;
+ if(chanuser->user->flags & USERFLAG_ISAUTHED) {
+ for(i = 0; i < userlistlen; i++) {
+ if(!stricmp(chanuser->user->auth, userlist[i][1])) {
+ uaccess = atoi(userlist[i][0]);
+ if((((chanuser->flags & CHANUSERFLAG_OPPED) && uaccess < db_enfops) || ((chanuser->flags & CHANUSERFLAG_VOICED) && uaccess < db_enfvoice)) && !isNetworkService(chanuser->user)) {
+ if(syncusers) {
+ if((chanuser->flags & CHANUSERFLAG_OPPED) && (db_enfops < caccess || isGodMode(user))) {
+ if(db_enfops >= caccess)
+ event->flags |= CMDFLAG_OPLOG;
+ uaccess = db_enfops;
+ } else if((chanuser->flags & CHANUSERFLAG_VOICED) && (caccess < db_enfvoice || isGodMode(user))) {
+ if(db_enfvoice >= caccess)
+ event->flags |= CMDFLAG_OPLOG;
+ uaccess = db_enfvoice;
+ } else {
+ //fail...
+ sprintf(accessbuf, "\00307%d\003", uaccess);
+ break;
+ }
+ neonserv_cmd_nicklist_synchronize_user(chan, chanuser->user, uaccess);
+ sprintf(accessbuf, "\00309%d\003", uaccess);
+ synced_user = 1;
+ } else {
+ synced_user = 1;
+ sprintf(accessbuf, "\00307%d\003", uaccess);
+ }
+ } else if((uaccess >= db_enfops && !(chanuser->flags & CHANUSERFLAG_OPPED)) || (uaccess >= db_enfvoice && !(chanuser->flags & CHANUSERFLAG_OPPED_OR_VOICED)))
+ sprintf(accessbuf, "\00303%d\003", uaccess);
+ else
+ sprintf(accessbuf, "%d", uaccess);
+ break;
+ }
+ }
+ }
+ if(!uaccess && (chanuser->flags & CHANUSERFLAG_OPPED_OR_VOICED) && !isNetworkService(chanuser->user)) {
+ if(syncusers) {
+ if((chanuser->flags & CHANUSERFLAG_OPPED) && (db_enfops < caccess || isGodMode(user))) {
+ if(db_enfops >= caccess)
+ event->flags |= CMDFLAG_OPLOG;
+ uaccess = db_enfops;
+ } else if((chanuser->flags & CHANUSERFLAG_VOICED) && (db_enfvoice < caccess || isGodMode(user))) {
+ if(db_enfvoice >= caccess)
+ event->flags |= CMDFLAG_OPLOG;
+ uaccess = db_enfvoice;
+ } else {
+ uaccess = 0;
+ sprintf(accessbuf, "\003040\003");
+ }
+ if(uaccess && (chanuser->user->flags & USERFLAG_ISAUTHED)) {
+ neonserv_cmd_nicklist_synchronize_user(chan, chanuser->user, uaccess);
+ sprintf(accessbuf, "\00309%d\003", uaccess);
+ synced_user = 1;
+ } else if(uaccess) {
+ sprintf(accessbuf, "\003040\003");
+ }
+ } else {
+ synced_user = 1;
+ sprintf(accessbuf, "\003040\003");
+ }
+ } else if(!uaccess)
+ sprintf(accessbuf, "0");
+ content[2] = accessbuf;
+ table_add(table, content);
+ }
+ } while(sort_flags != 0);
+ //send the table
+ char **table_lines = table_end(table);
+ for(i = 0; i < table->entrys; i++) {
+ reply(textclient, user, table_lines[i]);
+ }
+ if(table->length == 1)
+ reply(textclient, user, "NS_TABLE_NONE");
+ reply(textclient, user, "NS_TABLE_COUNT", table->length - 1);
+ table_free(table);
+ if(synced_user) {
+ if(!syncusers)
+ reply(textclient, user, "NS_NICKLIST_SYNC", db_enfops, db_enfvoice);
+ else
+ logEvent(event);
+ }
+}
+
+static void neonserv_cmd_nicklist_synchronize_user(struct ChanNode *chan, struct UserNode *user, int caccess) {
+ if(!(user->flags & USERFLAG_ISAUTHED)) return;
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ int userid;
+ printf_mysql_query("SELECT `user_id` FROM `users` WHERE `user_user` = '%s'", escape_string(user->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(user->auth));
+ userid = (int) mysql_insert_id(get_mysql_conn());
+ }
+ //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;
+ printf_mysql_query("UPDATE `chanusers` SET `chanuser_access` = '%d' WHERE `chanuser_id` = '%s'", caccess, row[1]);
+ } else
+ printf_mysql_query("INSERT INTO `chanusers` (`chanuser_cid`, `chanuser_uid`, `chanuser_access`) VALUES ('%d', '%d', '%d')", chan->channel_id, userid, caccess);
+}
--- /dev/null
+/* cmd_neonserv_noregister.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* argv[0] *auth/#channel
+* argv[1] duration
+* argv[2-*] reason
+*/
+
+static AUTHLOOKUP_CALLBACK(neonserv_cmd_noregister_auth_lookup);
+static USERAUTH_CALLBACK(neonserv_cmd_noregister_nick_lookup);
+static void neonserv_cmd_noregister_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event,char *auth, int duration, char *reason);
+static void neonserv_cmd_noregister_list(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, char **argv, int argc);
+
+struct neonserv_cmd_noregister_cache {
+ struct ClientSocket *client, *textclient;
+ struct UserNode *user;
+ struct ChanNode *chan;
+ struct Event *event;
+ int duration;
+ char *reason, *nick;
+};
+
+CMD_BIND(neonserv_cmd_noregister) {
+ if(argc < 3) {
+ neonserv_cmd_noregister_list(client, user, chan, event, argv, argc);
+ return;
+ }
+ int duration = strToTime(user, argv[1]);
+ if(duration == 0 && strcmp(argv[1], "0")) {
+ reply(getTextBot(), user, "NS_NOREGISTER_INVALID_DURATION", argv[1]);
+ return;
+ }
+ char *reason = merge_argv(argv, 2, argc);
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ if(argv[0][0] == '#') {
+ printf_mysql_query("SELECT `botid` FROM `bot_channels` LEFT JOIN `channels` ON `bot_channels`.`chanid` = `channels`.`channel_id` WHERE `channel_name` = '%s'", escape_string(argv[0]));
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) != NULL) {
+ reply(getTextBot(), user, "NS_NOREGISTER_REGISTERED", argv[0]);
+ return;
+ }
+ neonserv_cmd_noregister_async1(client, getTextBot(), user, chan, event, argv[0], duration, reason);
+ } else 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_noregister_async1(client, getTextBot(), user, chan, event, row[0], duration, reason);
+ } else {
+ //we need to create a new user...
+ //but first lookup the auth to check if it really exists
+ struct neonserv_cmd_noregister_cache *cache = malloc(sizeof(*cache));
+ if (!cache) {
+ perror("malloc() failed");
+ return;
+ }
+ cache->client = client;
+ cache->textclient = getTextBot();
+ cache->user = user;
+ cache->chan = chan;
+ cache->event = event;
+ cache->nick = strdup(argv[0]);
+ cache->duration = duration;
+ cache->reason = strdup(reason);
+ lookup_authname(argv[0], neonserv_cmd_noregister_auth_lookup, cache);
+ }
+ } else {
+ struct UserNode *cuser = getUserByNick(argv[0]);
+ if(!cuser) {
+ cuser = createTempUser(argv[0]);
+ if(!cuser) {
+ reply(getTextBot(), user, "NS_USER_UNKNOWN", argv[0]);
+ return;
+ }
+ cuser->flags |= USERFLAG_ISTMPUSER;
+ }
+ if(cuser->flags & USERFLAG_ISAUTHED) {
+ neonserv_cmd_noregister_async1(client, getTextBot(), user, chan, event, cuser->auth, duration, reason);
+ } else {
+ struct neonserv_cmd_noregister_cache *cache = malloc(sizeof(*cache));
+ if (!cache) {
+ perror("malloc() failed");
+ return;
+ }
+ cache->client = client;
+ cache->textclient = getTextBot();
+ cache->user = user;
+ cache->chan = chan;
+ cache->event = event;
+ cache->nick = strdup(user->nick);
+ cache->duration = duration;
+ cache->reason = strdup(reason);
+ get_userauth(cuser, neonserv_cmd_noregister_nick_lookup, cache);
+ }
+ }
+}
+
+static AUTHLOOKUP_CALLBACK(neonserv_cmd_noregister_auth_lookup) {
+ struct neonserv_cmd_noregister_cache *cache = data;
+ if(!exists) {
+ //AUTH_DOES_NOT_EXIST
+ reply(cache->textclient, cache->user, "NS_AUTH_UNKNOWN", cache->nick);
+ } else
+ neonserv_cmd_noregister_async1(cache->client, cache->textclient, cache->user, cache->chan, cache->event, auth, cache->duration, cache->reason);
+ free(cache->reason);
+ free(cache->nick);
+ free(cache);
+}
+
+static USERAUTH_CALLBACK(neonserv_cmd_noregister_nick_lookup) {
+ struct neonserv_cmd_noregister_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_noregister_async1(cache->client, cache->textclient, cache->user, cache->chan, cache->event, user->auth, cache->duration, cache->reason);
+ free(cache->reason);
+ free(cache->nick);
+ free(cache);
+}
+
+static void neonserv_cmd_noregister_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event,char *auth, int duration, char *reason) {
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ printf_mysql_query("SELECT `dnr_id` FROM `donotregister` WHERE `dnr_target` = '%s'", escape_string(auth));
+ res = mysql_use();
+ if((row = mysql_fetch_row(res)) != NULL) {
+ printf_mysql_query("DELETE FROM `donotregister` WHERE `dnr_id` = '%s'", row[0]);
+ }
+ int userid;
+ printf_mysql_query("SELECT `user_id` FROM `users` WHERE `user_user` = '%s'", escape_string(user->auth));
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) != NULL)
+ userid = atoi(row[0]);
+ else
+ userid = 0;
+ printf_mysql_query("INSERT INTO `donotregister` (`dnr_target`, `dnr_timeout`, `dnr_user`, `dnr_reason`) VALUES ('%s', '%lu', '%d', '%s')", escape_string(auth), (duration ? (time(0)+duration) : 0), userid, escape_string(reason));
+ reply(getTextBot(), user, "NS_NOREGISTER_DONE", auth);
+}
+
+static void neonserv_cmd_noregister_list(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, char **argv, int argc) {
+ struct Table *table;
+ int entrys = 0;
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ printf_mysql_query("SELECT `dnr_target`, `dnr_timeout`, `user_user`, `dnr_reason` FROM `donotregister` LEFT JOIN `users` ON `dnr_user` = `user_id` ORDER BY `dnr_target` ASC");
+ res = mysql_use();
+ table = table_init(4, mysql_num_rows(res) + 1, 0);
+ char *content[4];
+ content[0] = get_language_string(user, "NS_DNR_TARGET");
+ content[1] = get_language_string(user, "NS_DNR_USER");
+ content[2] = get_language_string(user, "NS_DNR_EXPIRES");
+ content[3] = get_language_string(user, "NS_DNR_REASON");
+ table_add(table, content);
+ int duration;
+ char expires_str[MAXLEN];
+ while ((row = mysql_fetch_row(res)) != NULL) {
+ entrys++;
+ content[0] = row[0];
+ content[1] = row[2];
+ duration = atoi(row[1]);
+ content[2] = (duration ? timeToStr(user, (duration - time(0)), 2, expires_str) : get_language_string(user, "NS_USERS_SEEN_NEVER"));
+ content[3] = row[3];
+ table_add(table, content);
+ }
+ //send the table
+ char **table_lines = table_end(table);
+ int i;
+ for(i = 0; i < table->entrys; i++) {
+ reply(getTextBot(), user, table_lines[i]);
+ }
+ if(!entrys)
+ reply(getTextBot(), user, "NS_TABLE_NONE");
+ table_free(table);
+}
--- /dev/null
+/* cmd_neonserv_op.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* argv[0-*] nicks
+*/
+static USERLIST_CALLBACK(neonserv_cmd_op_userlist_lookup);
+static void neonserv_cmd_op_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nicks);
+
+struct neonserv_cmd_op_cache {
+ struct ClientSocket *client, *textclient;
+ struct UserNode *user;
+ struct Event *event;
+ char *nicks;
+};
+
+CMD_BIND(neonserv_cmd_op) {
+ struct neonserv_cmd_op_cache *cache = malloc(sizeof(*cache));
+ if (!cache) {
+ perror("malloc() failed");
+ return;
+ }
+ cache->client = client;
+ cache->textclient = getTextBot();
+ cache->user = user;
+ cache->event = event;
+ cache->nicks = strdup(merge_argv(argv, 0, argc));
+ get_userlist_if_invisible(chan, neonserv_cmd_op_userlist_lookup, cache);
+}
+
+static USERLIST_CALLBACK(neonserv_cmd_op_userlist_lookup) {
+ struct neonserv_cmd_op_cache *cache = data;
+ neonserv_cmd_op_async1(cache->client, cache->textclient, cache->user, chan, cache->event, cache->nicks);
+ free(cache->nicks);
+ free(cache);
+}
+
+static void neonserv_cmd_op_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nicks) {
+ int total_users = 0, done_users = 0;
+ struct UserNode *cuser;
+ struct ChanUser *chanuser;
+ struct ModeBuffer *modeBuf;
+ modeBuf = initModeBuffer(client, chan);
+ char *a, *b = nicks;
+ do {
+ a = strstr(b, " ");
+ if(a) *a = '\0';
+ total_users++;
+ cuser = searchUserByNick(b);
+ if(!cuser) {
+ //check for an invisible user
+ for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
+ if(!stricmp(chanuser->user->nick, b)) {
+ cuser = chanuser->user;
+ break;
+ }
+ }
+ if(!cuser) continue;
+ } else {
+ chanuser = getChanUser(cuser, chan);
+ if(!chanuser) continue;
+ }
+ done_users++;
+ if(chanuser->flags & CHANUSERFLAG_OPPED) continue;
+ modeBufferOp(modeBuf, b);
+ if(a) {
+ b = a+1;
+ }
+ } while(a);
+ freeModeBuffer(modeBuf);
+ if(done_users == total_users)
+ reply(textclient, user, "NS_OP_DONE", chan->name);
+ else
+ reply(textclient, user, "NS_OP_FAIL", client->user->nick);
+ if(done_users)
+ logEvent(event);
+}
--- /dev/null
+/* cmd_neonserv_opall.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* argv[0] "force"
+* argv[1] (optional) nick mask
+*/
+static USERLIST_CALLBACK(neonserv_cmd_opall_userlist_lookup);
+static void neonserv_cmd_opall_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nickmask);
+
+struct neonserv_cmd_opall_cache {
+ struct ClientSocket *client, *textclient;
+ struct UserNode *user;
+ struct Event *event;
+ char *nickmask;
+};
+
+CMD_BIND(neonserv_cmd_opall) {
+ if(!argc || strcmp(argv[0], "FORCE")) {
+ reply(getTextBot(), user, "NS_OPALL_SECURITY", chan->name);
+ return;
+ }
+ struct neonserv_cmd_opall_cache *cache = malloc(sizeof(*cache));
+ if (!cache) {
+ perror("malloc() failed");
+ return;
+ }
+ cache->client = client;
+ cache->textclient = getTextBot();
+ cache->user = user;
+ cache->event = event;
+ if(argc > 1) {
+ cache->nickmask = strdup(argv[1]);
+ } else
+ cache->nickmask = NULL;
+ get_userlist_if_invisible(chan, neonserv_cmd_opall_userlist_lookup, cache);
+}
+
+static USERLIST_CALLBACK(neonserv_cmd_opall_userlist_lookup) {
+ struct neonserv_cmd_opall_cache *cache = data;
+ neonserv_cmd_opall_async1(cache->client, cache->textclient, cache->user, chan, cache->event, cache->nickmask);
+ if(cache->nickmask)
+ free(cache->nickmask);
+ free(cache);
+}
+
+static void neonserv_cmd_opall_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nickmask) {
+ int done_users = 0;
+ struct ChanUser *chanuser;
+ struct ModeBuffer *modeBuf;
+ modeBuf = initModeBuffer(client, chan);
+ for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
+ if(nickmask && match(nickmask, chanuser->user->nick)) continue;
+ if(chanuser->flags & CHANUSERFLAG_OPPED) continue;
+ modeBufferOp(modeBuf, chanuser->user->nick);
+ done_users++;
+ }
+ freeModeBuffer(modeBuf);
+ reply(textclient, user, "NS_OPALL_DONE", done_users, chan->name);
+ if(done_users)
+ logEvent(event);
+}
--- /dev/null
+/* cmd_neonserv_oplog.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* argv[0] time
+* argv[1-*] match
+*/
+
+CMD_BIND(neonserv_cmd_oplog) {
+ char *str_match;
+ int duration = (argc ? strToTime(user, argv[0]) : 0);
+ if(argc > (duration ? 1 : 0))
+ str_match = merge_argv(argv, (duration ? 1 : 0), argc);
+ else
+ str_match = "";
+ if(!duration) duration = (60*60*24);
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ printf_mysql_query("SELECT `godlog_time`, `user_user`, `channel_name`, `godlog_cmd` FROM `godlog` LEFT JOIN `channels` ON `godlog_cid` = `channel_id` LEFT JOIN `users` ON `godlog_uid` = `user_id` WHERE `godlog_time` > '%lu' ORDER BY `godlog_time` ASC", ((unsigned long) time(0) - duration));
+ res = mysql_use();
+ int skip = mysql_num_rows(res) - 100;
+ int count = 0;
+ char timeBuf[50];
+ struct tm *timeinfo;
+ time_t event_time;
+ if(skip < 0) skip = 0;
+ reply(getTextBot(), user, "NS_EVENTS_HEADER");
+ while ((row = mysql_fetch_row(res)) != NULL) {
+ if(skip) {
+ skip--;
+ continue;
+ }
+ if(*str_match && match(str_match, row[3])) continue;
+ count++;
+ event_time = (time_t) atol(row[0]);
+ timeinfo = localtime(&event_time);
+ strftime(timeBuf, 80, "%X %x", timeinfo);
+ reply(getTextBot(), user, "[%s] [%s%s%s]: %s", timeBuf, row[1], (row[2] ? ":" : ""), (row[2] ? row[2] : ""), row[3]);
+ }
+ reply(getTextBot(), user, "NS_TABLE_COUNT", count);
+}
--- /dev/null
+/* cmd_neonserv_peek.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* no parameters
+*/
+static USERLIST_CALLBACK(neonserv_cmd_peek_userlist_lookup);
+static void neonserv_cmd_peek_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan);
+
+struct neonserv_cmd_peek_cache {
+ struct ClientSocket *client, *textclient;
+ struct UserNode *user;
+};
+
+CMD_BIND(neonserv_cmd_peek) {
+ struct neonserv_cmd_peek_cache *cache = malloc(sizeof(*cache));
+ if (!cache) {
+ perror("malloc() failed");
+ return;
+ }
+ cache->client = client;
+ cache->textclient = getTextBot();
+ cache->user = user;
+ get_userlist_if_invisible(chan, neonserv_cmd_peek_userlist_lookup, cache);
+}
+
+static USERLIST_CALLBACK(neonserv_cmd_peek_userlist_lookup) {
+ struct neonserv_cmd_peek_cache *cache = data;
+ neonserv_cmd_peek_async1(cache->client, cache->textclient, cache->user, chan);
+ free(cache);
+}
+
+static void neonserv_cmd_peek_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan) {
+ reply(textclient, user, "NS_PEEK_HEADER", chan->name);
+ reply(textclient, user, "NS_PEEK_TOPIC", chan->topic);
+ char tmpStr[MAXLEN];
+ getModeString(chan->modes, tmpStr);
+ reply(textclient, user, "NS_PEEK_MODES", tmpStr);
+ struct ChanUser *chanuser;
+ int with_halfops = get_int_field("General.have_halfop");
+ int op_count = 0, halfop_count = 0, voice_count = 0, normal_count = 0, invi_count = 0;
+ for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
+ if(chanuser->flags & CHANUSERFLAG_OPPED)
+ op_count++;
+ else if(with_halfops && (chanuser->flags & CHANUSERFLAG_HALFOPPED))
+ halfop_count++;
+ else if(chanuser->flags & CHANUSERFLAG_VOICED)
+ voice_count++;
+ else if(chanuser->flags & CHANUSERFLAG_INVISIBLE)
+ invi_count++;
+ else
+ normal_count++;
+ }
+ if(with_halfops)
+ reply(textclient, user, "NS_PEEK_USERS_HALFOP", op_count+halfop_count+voice_count+invi_count+normal_count, op_count, halfop_count, voice_count, normal_count, invi_count);
+ else
+ reply(textclient, user, "NS_PEEK_USERS", op_count+voice_count+invi_count+normal_count, op_count, voice_count, normal_count, invi_count);
+ int tmpStrPos = 0;
+ int headerlen = 10 + strlen(user->nick);
+ for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
+ if(chanuser->flags & CHANUSERFLAG_OPPED) {
+ if(tmpStrPos + headerlen + strlen(chanuser->user->nick) + 2 >= 512) {
+ //clear buffer
+ reply(textclient, user, "%s", tmpStr);
+ tmpStrPos = 0;
+ }
+ tmpStrPos += sprintf(tmpStr + tmpStrPos, (tmpStrPos ? ", %s" : "%s"), chanuser->user->nick);
+ }
+ }
+ if(tmpStrPos) {
+ reply(textclient, user, "%s", tmpStr);
+ }
+}
--- /dev/null
+/* cmd_neonserv_recover.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* argv[0] - channel
+*/
+CMD_BIND(neonserv_cmd_recover) {
+ MYSQL_RES *res;
+ MYSQL_ROW row, row2;
+ char *channel = argv[0];
+ if(!is_valid_chan(channel)) {
+ reply(getTextBot(), user, "NS_INVALID_CHANNEL_NAME", argv[0]);
+ return;
+ }
+ printf_mysql_query("SELECT `botid`, `bot_channels`.`id` 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;
+ }
+ 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 {
+ reply(getTextBot(), user, "NS_UNREGISTER_NOT_REGISTERED", argv[0], client->user->nick);
+ return;
+ }
+ printf_mysql_query("SELECT `id`, `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(getTextBot(), user, "NS_REGISTER_FULL");
+ return;
+ }
+ 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(getTextBot(), user, "NS_REGISTER_DISCONNECTED");
+ printf_mysql_query("INSERT INTO `bot_channels` (`botid`, `chanid`, `trigger`) VALUES ('%d', '%d', '%s')", botid, chanid, bottrigger);
+ reply(getTextBot(), user, "NS_RECOVER_DONE", channel);
+ logEvent(event);
+}
--- /dev/null
+/* cmd_neonserv_rename.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* argv[0] old auth
+* argv[1] new auth
+*/
+
+struct neonserv_cmd_rename_cache {
+ struct ClientSocket *client, *textclient;
+ struct UserNode *user;
+ struct Event *event;
+ char *oldauth, *newauth;
+};
+
+static AUTHLOOKUP_CALLBACK(neonserv_cmd_rename_auth_lookup);
+static void neonserv_cmd_rename_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct Event *event, char *oldauth, char *newauth);
+
+CMD_BIND(neonserv_cmd_rename) {
+ struct neonserv_cmd_rename_cache *cache = malloc(sizeof(*cache));
+ if (!cache) {
+ perror("malloc() failed");
+ return;
+ }
+ cache->client = client;
+ cache->textclient = getTextBot();
+ cache->user = user;
+ cache->event = event;
+ cache->oldauth = strdup(argv[0]);
+ cache->newauth = strdup(argv[1]);
+ lookup_authname(argv[1], neonserv_cmd_rename_auth_lookup, cache);
+}
+
+static AUTHLOOKUP_CALLBACK(neonserv_cmd_rename_auth_lookup) {
+ struct neonserv_cmd_rename_cache *cache = data;
+ if(!exists) {
+ //AUTH_DOES_NOT_EXIST
+ reply(cache->textclient, cache->user, "NS_AUTH_UNKNOWN", cache->newauth);
+ } else
+ neonserv_cmd_rename_async1(cache->client, cache->textclient, cache->user, cache->event, cache->oldauth, auth);
+ free(cache->oldauth);
+ free(cache->newauth);
+ free(cache);
+}
+
+static void neonserv_cmd_rename_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct Event *event, char *oldauth, char *newauth) {
+ if(renameAccount(oldauth, newauth)) {
+ reply(textclient, user, "NS_RENAME_DONE", oldauth, newauth);
+ } else {
+ reply(textclient, user, "NS_RENAME_FAIL", oldauth);
+ }
+}
--- /dev/null
+/* cmd_neonserv_resync.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* argv[0] - (optional) usermask
+* argv[1] - (optional) min access
+* argv[2] - (optional) max access
+* argv[1/3] - (optional) FORCE (override NoAutoOp)
+*/
+static USERLIST_CALLBACK(neonserv_cmd_resync_userlist_lookup);
+static void neonserv_cmd_resync_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, char *usermask, int min_access, int max_access, char override_noautoop);
+
+struct neonserv_cmd_resync_cache {
+ struct ClientSocket *client, *textclient;
+ struct UserNode *user;
+ char *usermask;
+ int min_access;
+ int max_access;
+ char override_noautoop;
+};
+
+CMD_BIND(neonserv_cmd_resync) {
+ int min_access = 0, max_access = 500;
+ char *usermask = NULL;
+ char override_noautoop = 0;
+ if(argc > 0) {
+ usermask = argv[0];
+ if(argc > 2) {
+ min_access = atoi(argv[1]);
+ max_access = atoi(argv[2]);
+ if(argc > 3)
+ override_noautoop = (!stricmp(argv[3], "FORCE") ? 1 : 0);
+ } else if(argc > 1)
+ override_noautoop = (!stricmp(argv[1], "FORCE") ? 1 : 0);
+ }
+ struct neonserv_cmd_resync_cache *cache = malloc(sizeof(*cache));
+ if (!cache) {
+ perror("malloc() failed");
+ return;
+ }
+ cache->client = client;
+ cache->textclient = getTextBot();
+ cache->user = user;
+ cache->usermask = (usermask ? strdup(usermask) : NULL);
+ cache->min_access = min_access;
+ cache->max_access = max_access;
+ cache->override_noautoop = override_noautoop;
+ get_userlist_with_invisible(chan, neonserv_cmd_resync_userlist_lookup, cache);
+}
+
+static USERLIST_CALLBACK(neonserv_cmd_resync_userlist_lookup) {
+ struct neonserv_cmd_resync_cache *cache = data;
+ neonserv_cmd_resync_async1(cache->client, cache->textclient, cache->user, chan, cache->usermask, cache->min_access, cache->max_access, cache->override_noautoop);
+ if(cache->usermask)
+ free(cache->usermask);
+ free(cache);
+}
+
+static void neonserv_cmd_resync_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, char *usermask, int min_access, int max_access, char override_noautoop) {
+ MYSQL_RES *res;
+ MYSQL_ROW row, defaults = NULL;
+ int i;
+ int resync_op = 1;
+ int with_halfop = get_int_field("General.have_halfop");
+ int resync_halfop = with_halfop;
+ int resync_voice = 1;
+ if(usermask && usermask[0] == '@') {
+ resync_voice = 0;
+ resync_halfop = 0;
+ usermask++;
+ if(!*usermask) usermask = NULL;
+ } else if(usermask && with_halfop && usermask[0] == 'h') {
+ resync_op = 0;
+ resync_voice = 0;
+ usermask++;
+ if(!*usermask) usermask = NULL;
+ } else if(usermask && usermask[0] == '+') {
+ resync_op = 0;
+ resync_halfop = 0;
+ usermask++;
+ if(!*usermask) usermask = NULL;
+ }
+ struct ChanUser *chanuser;
+ int db_enfops, db_enfhalfop, db_enfvoice;
+ printf_mysql_query("SELECT `channel_getop`, `channel_getvoice`, `channel_gethalfop` FROM `channels` WHERE `channel_id` = '%d'", chan->channel_id);
+ row = mysql_fetch_row(mysql_use());
+ if(row[0] == NULL || row[1] == NULL) {
+ printf_mysql_query("SELECT `channel_getop`, `channel_getvoice`, `channel_gethalfop` FROM `channels` WHERE `channel_name` = 'defaults'");
+ defaults = mysql_fetch_row(mysql_use());
+ }
+ db_enfops = atoi((row[0] ? row[0] : defaults[0]));
+ db_enfvoice = atoi((row[1] ? row[1] : defaults[1]));
+ db_enfhalfop = (with_halfop ? atoi((row[2] ? row[2] : defaults[2])) : 0);
+ printf_mysql_query("SELECT `chanuser_access`, `user_user`, `chanuser_flags` FROM `chanusers` LEFT JOIN `users` ON `chanuser_uid` = `user_id` WHERE `chanuser_cid` = '%d' ORDER BY `chanuser_access` DESC, `user_user` ASC", chan->channel_id);
+ res = mysql_use();
+ char *db_users[mysql_num_rows(res)];
+ int db_access[mysql_num_rows(res)];
+ int db_flags[mysql_num_rows(res)];
+ int db_count = 0;
+ while ((row = mysql_fetch_row(res)) != NULL) {
+ db_users[db_count] = row[1];
+ db_access[db_count] = atoi(row[0]);
+ db_flags[db_count] = atoi(row[2]);
+ db_count++;
+ }
+ int caccess, cflags;
+ struct ModeBuffer *modeBuf;
+ modeBuf = initModeBuffer(client, chan);
+ for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
+ caccess = 0;
+ cflags = 0;
+ if((chanuser->user->flags & USERFLAG_ISAUTHED)) {
+ for(i = 0; i < db_count; i++) {
+ if(!stricmp(db_users[i], chanuser->user->auth)) {
+ caccess = db_access[i];
+ cflags = db_flags[i];
+ if(cflags & DB_CHANUSER_SUSPENDED)
+ caccess = 0;
+ break;
+ }
+ }
+ }
+ if((usermask && *usermask && match(usermask, chanuser->user->nick)) || caccess < min_access || caccess > max_access) continue;
+ if(caccess >= db_enfops) {
+ if(!(chanuser->flags & CHANUSERFLAG_OPPED) && resync_op && (override_noautoop || !(cflags & DB_CHANUSER_NOAUTOOP)))
+ modeBufferOp(modeBuf, chanuser->user->nick);
+ } else if(with_halfop && caccess >= db_enfhalfop) {
+ if((chanuser->flags & CHANUSERFLAG_OPPED) && resync_op && !(chanuser->user->flags & (USERFLAG_ISBOT | USERFLAG_ISIRCOP)))
+ modeBufferDeop(modeBuf, chanuser->user->nick);
+ if(!(chanuser->flags & CHANUSERFLAG_HALFOPPED) && resync_halfop && (override_noautoop || !(cflags & DB_CHANUSER_NOAUTOOP)))
+ modeBufferHalfop(modeBuf, chanuser->user->nick);
+ } else if(caccess >= db_enfvoice) {
+ if((chanuser->flags & CHANUSERFLAG_OPPED) && resync_op && !(chanuser->user->flags & (USERFLAG_ISBOT | USERFLAG_ISIRCOP)))
+ modeBufferDeop(modeBuf, chanuser->user->nick);
+ if((chanuser->flags & CHANUSERFLAG_HALFOPPED) && resync_halfop && !(chanuser->user->flags & (USERFLAG_ISBOT | USERFLAG_ISIRCOP)))
+ modeBufferDehalfop(modeBuf, chanuser->user->nick);
+ if(!(chanuser->flags & CHANUSERFLAG_VOICED) && resync_voice && (override_noautoop || !(cflags & DB_CHANUSER_NOAUTOOP)))
+ modeBufferVoice(modeBuf, chanuser->user->nick);
+ } else {
+ if((chanuser->flags & CHANUSERFLAG_OPPED) && resync_op && !(chanuser->user->flags & (USERFLAG_ISBOT | USERFLAG_ISIRCOP)))
+ modeBufferDeop(modeBuf, chanuser->user->nick);
+ if((chanuser->flags & CHANUSERFLAG_HALFOPPED) && resync_halfop && !(chanuser->user->flags & (USERFLAG_ISBOT | USERFLAG_ISIRCOP)))
+ modeBufferDehalfop(modeBuf, chanuser->user->nick);
+ if((chanuser->flags & CHANUSERFLAG_VOICED) && resync_voice && !(chanuser->user->flags & (USERFLAG_ISBOT | USERFLAG_ISIRCOP)))
+ modeBufferDevoice(modeBuf, chanuser->user->nick);
+ }
+
+ }
+ freeModeBuffer(modeBuf);
+ reply(textclient, user, "NS_RESYNC_DONE", chan->name);
+}
--- /dev/null
+/* cmd_neonserv_search.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+#define CMD_SEARCH_FLAG_HAS_NODELETE 0x001
+#define CMD_SEARCH_FLAG_NOT_NODELETE 0x002
+#define CMD_SEARCH_FLAG_HAS_SUSPENDED 0x004
+#define CMD_SEARCH_FLAG_NOT_SUSPENDED 0x008
+#define CMD_SEARCH_FLAG_IS_JOINED 0x010
+#define CMD_SEARCH_FLAG_NOT_JOINED 0x020
+#define CMD_SEARCH_FLAG_IS_OPPED 0x040
+#define CMD_SEARCH_FLAG_NOT_OPPED 0x080
+#define CMD_SEARCH_FLAG_IS_VOICED 0x100
+#define CMD_SEARCH_FLAG_NOT_VOICED 0x200
+#define CMD_SEARCH_FLAG_STATES 0x3f0
+
+struct neonserv_cmd_search_criteria {
+ char *name;
+ char *registrar;
+ char *onchan;
+ unsigned int flags : 16;
+ unsigned int unvisited;
+ unsigned int registered;
+ unsigned int limit : 16;
+};
+
+CMD_BIND(neonserv_cmd_search) {
+ //ok parse the criterias
+ struct neonserv_cmd_search_criteria criteria;
+ memset(&criteria, 0, sizeof(criteria));
+ criteria.limit = 50;
+ int i, show_chans = 0, positive;
+ if(!stricmp(argv[0], "print")) {
+ show_chans = 1;
+ }
+ for(i = 1; i < argc; i += 2) {
+ if(argc <= i+1) {
+ reply(getTextBot(), user, "MODCMD_LESS_PARAM_COUNT");
+ return;
+ }
+ if(!stricmp(argv[i], "name")) criteria.name = argv[i+1];
+ else if(!stricmp(argv[i], "registrar")) criteria.registrar = argv[i+1];
+ else if(!stricmp(argv[i], "onchan")) criteria.onchan = argv[i+1];
+ else if(!stricmp(argv[i], "unvisited")) criteria.unvisited = strToTime(user, argv[i+1]);
+ else if(!stricmp(argv[i], "registered")) criteria.registered = strToTime(user, argv[i+1]);
+ else if(!stricmp(argv[i], "flags")) {
+ if(argv[i+1][0] == '+') {
+ positive = 1;
+ argv[i+1]++;
+ } else if(argv[i+1][0] == '-') {
+ positive = 0;
+ argv[i+1]++;
+ } else
+ positive = 1;
+ if(!stricmp(argv[i+1], "nodelete")) {
+ if(positive)
+ criteria.flags |= CMD_SEARCH_FLAG_HAS_NODELETE;
+ else
+ criteria.flags |= CMD_SEARCH_FLAG_NOT_NODELETE;
+ } else if(!stricmp(argv[i+1], "suspended")) {
+ if(positive)
+ criteria.flags |= CMD_SEARCH_FLAG_HAS_SUSPENDED;
+ else
+ criteria.flags |= CMD_SEARCH_FLAG_NOT_SUSPENDED;
+ }
+ }
+ else if(!stricmp(argv[i], "state")) {
+ if(argv[i+1][0] == '+') {
+ positive = 1;
+ argv[i+1]++;
+ } else if(argv[i+1][0] == '-') {
+ positive = 0;
+ argv[i+1]++;
+ } else
+ positive = 1;
+ if(!stricmp(argv[i+1], "joined")) {
+ if(positive)
+ criteria.flags |= CMD_SEARCH_FLAG_IS_JOINED;
+ else
+ criteria.flags |= CMD_SEARCH_FLAG_NOT_JOINED;
+ } else if(!stricmp(argv[i+1], "opped")) {
+ if(positive)
+ criteria.flags |= CMD_SEARCH_FLAG_IS_OPPED;
+ else
+ criteria.flags |= CMD_SEARCH_FLAG_NOT_OPPED;
+ } else if(!stricmp(argv[i+1], "voiced")) {
+ if(positive)
+ criteria.flags |= CMD_SEARCH_FLAG_IS_VOICED;
+ else
+ criteria.flags |= CMD_SEARCH_FLAG_NOT_VOICED;
+ }
+ }
+ else if(!stricmp(argv[i], "limit")) {
+ criteria.limit = atoi(argv[i+1]);
+ }
+ }
+ int matches = 0;
+ reply(getTextBot(), user, "NS_SEARCH_HEADER");
+ MYSQL_RES *res, *res2;
+ MYSQL_ROW row, row2;
+ printf_mysql_query("SELECT `channel_name`, `user_user`, `channel_registered`, `channel_nodelete`, `suspended`, `channel_id` FROM `bot_channels` LEFT JOIN `bots` ON `bots`.`id` = `botid` LEFT JOIN `channels` ON `chanid` = `channel_id` LEFT JOIN `users` ON `channel_registrator` = `user_id` WHERE `botclass` = '%d' AND `active` = '1'", client->botid);
+ res = mysql_use();
+ while ((row = mysql_fetch_row(res)) != NULL) {
+ if(show_chans && matches == criteria.limit) {
+ //too many
+ break;
+ }
+ if(criteria.name && match(criteria.name, row[0])) continue;
+ if(criteria.registrar && row[1] && match(criteria.registrar, row[1])) continue;
+ if(criteria.unvisited) {
+ printf_mysql_query("SELECT `chanuser_seen` FROM `chanusers` WHERE `chanuser_cid` = '%s' ORDER BY `chanuser_seen` DESC LIMIT 1", row[5]);
+ res2 = mysql_use();
+ row2 = mysql_fetch_row(res2);
+ if(!row2) continue;
+ if((time(0) - atoi(row2[0])) < criteria.unvisited) continue;
+ }
+ if(criteria.registered && (time(0) - atoi(row[2])) < criteria.registered) continue;
+
+ if((criteria.flags & CMD_SEARCH_FLAG_HAS_NODELETE) && strcmp(row[3], "1")) continue;
+ if((criteria.flags & CMD_SEARCH_FLAG_NOT_NODELETE) && strcmp(row[3], "0")) continue;
+ if((criteria.flags & CMD_SEARCH_FLAG_HAS_SUSPENDED) && strcmp(row[4], "1")) continue;
+ if((criteria.flags & CMD_SEARCH_FLAG_NOT_SUSPENDED) && strcmp(row[4], "0")) continue;
+ if((criteria.flags & CMD_SEARCH_FLAG_STATES) || criteria.onchan) {
+ struct ChanNode *channel = getChanByName(row[0]);
+ if(criteria.onchan) {
+ if(!channel) continue;
+ struct ChanUser *chanuser = NULL;
+ for(chanuser = getChannelUsers(channel, NULL); chanuser; chanuser = getChannelUsers(channel, chanuser)) {
+ if(!match(criteria.onchan, chanuser->user->nick)) break;
+ }
+ if(!chanuser) continue;
+ }
+ if((criteria.flags & CMD_SEARCH_FLAG_IS_JOINED) && !channel) continue;
+ if((criteria.flags & CMD_SEARCH_FLAG_NOT_JOINED) && channel) continue;
+ if(channel && (criteria.flags & (CMD_SEARCH_FLAG_IS_OPPED | CMD_SEARCH_FLAG_NOT_OPPED | CMD_SEARCH_FLAG_IS_VOICED | CMD_SEARCH_FLAG_NOT_VOICED))) {
+ int flags = 0;
+ struct ClientSocket *bot;
+ for(bot = getBots(SOCKET_FLAG_READY, NULL); bot; bot = getBots(SOCKET_FLAG_READY, bot)) {
+ if(bot->botid == client->botid) {
+ struct ChanUser *chanuser = getChanUser(bot->user, channel);
+ if(chanuser) {
+ flags = chanuser->flags;
+ break;
+ }
+ }
+ }
+ if((criteria.flags & CMD_SEARCH_FLAG_IS_OPPED) && !(flags & CHANUSERFLAG_OPPED)) continue;
+ if((criteria.flags & CMD_SEARCH_FLAG_NOT_OPPED) && (flags & CHANUSERFLAG_OPPED)) continue;
+ if((criteria.flags & CMD_SEARCH_FLAG_IS_VOICED) && !(flags & CHANUSERFLAG_VOICED)) continue;
+ if((criteria.flags & CMD_SEARCH_FLAG_NOT_VOICED) && (flags & CHANUSERFLAG_VOICED)) continue;
+ }
+ }
+ matches++;
+ //output
+ if(show_chans) {
+ reply(getTextBot(), user, "%s", row[0]);
+ }
+ }
+ reply(getTextBot(), user, "NS_TABLE_COUNT", matches);
+}
--- /dev/null
+/* cmd_neonserv_set.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+typedef char* neonserv_cmd_set_function(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *argument);
+static void neonserv_cmd_set_setting(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int setting, char *argument);
+static char* neonserv_cmd_set_trigger(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *argument);
+static char* neonserv_cmd_set_modes(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *argument);
+static char* neonserv_cmd_set_dynlimit(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *argument);
+static char* neonserv_cmd_set_nodelete(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *argument);
+
+#define NS_VALID_FUNCTION 0x01
+#define NS_VALID_STRING 0x02
+#define NS_VALID_ACCESS 0x04
+#define NS_VALID_NO501 0x08
+#define NS_VALID_OPTIONS 0x10
+#define NS_VALID_NUMERIC 0x20
+#define NS_VALID_BOOLEAN 0x40
+#define NS_VALID_IF_HALFOP 0x80
+
+#define NS_HAS_OPT 0x100 /* options (SET_OPTION_{NAME}_{VALUE}) */
+#define NS_HAS_HELP 0x200 /* help (SET_HELP_{NAME}) - only shown if help is requested */
+
+static const struct {
+ const char *setting;
+ const char *chanfield;
+ unsigned int valid;
+ void *parameter;
+} channel_settings[] = {
+ {"TRIGGER", NULL, NS_VALID_FUNCTION, neonserv_cmd_set_trigger},
+ {"DEFAULTTOPIC", "channel_defaulttopic", NS_VALID_STRING, NULL},
+ {"TOPICMASK", "channel_topicmask", NS_VALID_STRING, NULL},
+ {"ADVANCEDTOPIC", "channel_exttopic", NS_VALID_BOOLEAN | NS_HAS_OPT, NULL},
+ {"GREETING", "channel_greeting", NS_VALID_STRING, NULL},
+ {"USERGREETING", "channel_usergreeting", NS_VALID_STRING, NULL},
+ {"USERINFO", "channel_userinfo", NS_VALID_ACCESS | NS_HAS_HELP, NULL},
+ {"WIPEINFO", "channel_wipeinfo", NS_VALID_ACCESS | NS_HAS_HELP, NULL},
+ {"MODES", "channel_modes", NS_VALID_FUNCTION, neonserv_cmd_set_modes},
+ {"INVITEME", "channel_getinvite", NS_VALID_ACCESS, NULL},
+ {"GIVEOPS", "channel_getop", NS_VALID_ACCESS | NS_HAS_HELP, NULL},
+ {"GIVEHALFOPS", "channel_gethalfop", NS_VALID_ACCESS | NS_HAS_HELP | NS_VALID_IF_HALFOP, NULL},
+ {"GIVEVOICE", "channel_getvoice", NS_VALID_ACCESS | NS_HAS_HELP, NULL},
+ {"ENFOPS", "channel_canop", NS_VALID_ACCESS | NS_HAS_HELP, NULL},
+ {"ENFHALFOPS", "channel_canhalfop", NS_VALID_ACCESS | NS_HAS_HELP | NS_VALID_IF_HALFOP, NULL},
+ {"ENFVOICE", "channel_canvoice", NS_VALID_ACCESS | NS_HAS_HELP, NULL},
+ {"KICK", "channel_cankick", NS_VALID_ACCESS | NS_HAS_HELP, NULL},
+ {"BAN", "channel_canban", NS_VALID_ACCESS | NS_HAS_HELP, NULL},
+ {"STATICBAN", "channel_staticban", NS_VALID_ACCESS | NS_HAS_HELP, NULL},
+ {"PUBCMD", "channel_pubcmd", NS_VALID_ACCESS, NULL},
+ {"ENFMODES", "channel_enfmodes", NS_VALID_ACCESS, NULL},
+ {"ENFTOPIC", "channel_enftopic", NS_VALID_ACCESS, NULL},
+ {"TOPICSNARF", "channel_topicsnarf", NS_VALID_ACCESS | NS_HAS_HELP, NULL},
+ {"CHANGETOPIC", "channel_changetopic", NS_VALID_ACCESS | NS_HAS_HELP, NULL},
+ {"SETTERS", "channel_setters", NS_VALID_ACCESS | NS_VALID_NO501 | NS_HAS_HELP, NULL},
+ {"ADDUSER", "channel_canadd", NS_VALID_ACCESS | NS_HAS_HELP, NULL},
+ {"DELUSER", "channel_candel", NS_VALID_ACCESS | NS_HAS_HELP, NULL},
+ {"CLVL", "channel_canclvl", NS_VALID_ACCESS | NS_HAS_HELP, NULL},
+ {"RESYNC", "channel_canresync", NS_VALID_ACCESS | NS_HAS_HELP, NULL},
+ {"SUSPEND", "channel_cansuspend", NS_VALID_ACCESS | NS_HAS_HELP, NULL},
+ {"NOTICEUSERS", "channel_notice", NS_VALID_ACCESS, NULL},
+ {"NOTICEREACTION", "channel_noticereaction", NS_VALID_OPTIONS | NS_HAS_OPT, "4"},
+ {"CTCPUSERS", "channel_ctcp", NS_VALID_ACCESS, NULL},
+ {"CTCPREACTION", "channel_ctcpreaction", NS_VALID_OPTIONS | NS_HAS_OPT, "4"},
+ {"PROTECT", "channel_protect", NS_VALID_OPTIONS | NS_HAS_OPT, "4"},
+ {"TOYS", "channel_toys", NS_VALID_OPTIONS | NS_HAS_OPT, "3"},
+ {"DYNLIMIT", "channel_dynlimit", NS_VALID_NUMERIC | NS_VALID_FUNCTION | NS_HAS_OPT, neonserv_cmd_set_dynlimit},
+ {"NODELETE", "channel_nodelete", NS_VALID_BOOLEAN | NS_VALID_FUNCTION, neonserv_cmd_set_nodelete},
+ {NULL, NULL, 0, NULL}
+};
+
+#define MAX_QUERY_LEN 1024
+CMD_BIND(neonserv_cmd_set) {
+ int i, j;
+ if(argc && !strcmp(argv[0], "defaults")) {
+ //reset channel settings
+ int uaccess = getChannelAccess(user, chan);
+ if(uaccess < 500) {
+ if(isGodMode(user)) {
+ event->flags |= CMDFLAG_OPLOG;
+ } else {
+ reply(getTextBot(), user, "NS_SET_DEFAULTS_OWNER", chan->name);
+ return;
+ }
+ }
+ int seed = 0;
+ char *tmp;
+ 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;
+ 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);
+ logEvent(event);
+ } 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;
+ char *args = (argc > 1 ? merge_argv(argv, 1, argc) : NULL);
+ int with_halfops = get_int_field("General.have_halfop");
+ while(channel_settings[i].setting) {
+ if(!stricmp(channel_settings[i].setting, argv[0]) && (!(channel_settings[i].valid & NS_VALID_IF_HALFOP) || with_halfops)) {
+ //setting found
+ if(channel_settings[i].valid & NS_VALID_FUNCTION) {
+ neonserv_cmd_set_function *func = channel_settings[i].parameter;
+ func(client, user, chan, event, channel_settings[i].setting, args);
+ } else {
+ neonserv_cmd_set_setting(client, user, chan, event, i, args);
+ }
+ j = 1;
+ break;
+ }
+ i++;
+ }
+ if(j == 0) {
+ //unknown setting
+ reply(getTextBot(), user, "NS_SET_UNKNOWN_SETTING", argv[0]);
+ }
+ } else {
+ char query[MAX_QUERY_LEN], *value, *org_value, *tmp, nameBuf[64];
+ int querypos = 0;
+ MYSQL_RES *res, *defaults_res;
+ MYSQL_ROW row, defaults;
+ struct Table *table;
+ char *content[2];
+ int with_halfops = get_int_field("General.have_halfop");
+ i = 0;
+ j = 0;
+ while(channel_settings[i].setting) {
+ if((channel_settings[i].valid & NS_VALID_IF_HALFOP) && !with_halfops) {
+ j++;
+ i++;
+ continue;
+ }
+ if(channel_settings[i].chanfield)
+ querypos += sprintf(query + querypos, ", `%s`", channel_settings[i].chanfield);
+ i++;
+ }
+ table = table_init(2, i-j, 0);
+ table_set_bold(table, 0, 1);
+ printf_mysql_query("SELECT `channel_id` %s FROM `channels` WHERE `channel_name` = 'defaults'", query);
+ defaults_res = mysql_use();
+ defaults = mysql_fetch_row(defaults_res);
+ printf_mysql_query("SELECT `channel_name` %s FROM `channels` WHERE `channel_id` = '%d'", query, chan->channel_id);
+ res = mysql_use();
+ row = mysql_fetch_row(res);
+ i = 0;
+ j = 0;
+ reply(getTextBot(), user, "NS_SET_HEADER", chan->name);
+ while(channel_settings[i].setting) {
+ if((channel_settings[i].valid & NS_VALID_IF_HALFOP) && !with_halfops) {
+ i++;
+ continue;
+ }
+ if(channel_settings[i].chanfield) {
+ j++;
+ 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, event, NULL, NULL);
+ } else
+ org_value = "0";
+ value = org_value;
+ if(channel_settings[i].valid & NS_VALID_BOOLEAN) {
+ if(!strcmp(value, "0"))
+ value = get_language_string(user, "NS_SET_OFF");
+ else
+ value = get_language_string(user, "NS_SET_ON");
+ }
+ strcpy(query, value);
+ querypos = strlen(query);
+ if(channel_settings[i].valid & NS_HAS_OPT) {
+ sprintf(nameBuf, "NS_SET_OPTION_%s_%s", channel_settings[i].setting, org_value);
+ tmp = get_language_string(user, nameBuf);
+ if(tmp) {
+ querypos += sprintf(query+querypos, " - %s", tmp);
+ }
+ }
+ if(argc && channel_settings[i].valid & NS_HAS_HELP) {
+ sprintf(nameBuf, "NS_SET_HELP_%s", channel_settings[i].setting);
+ tmp = get_language_string(user, nameBuf);
+ if(tmp) {
+ querypos += sprintf(query+querypos, " - %s", tmp);
+ }
+ }
+ content[0] = (char*)channel_settings[i].setting;
+ content[1] = query;
+ table_add(table, content);
+ i++;
+ }
+ char **table_lines = table_end(table);
+ for(i = 0; i < table->entrys; i++) {
+ reply(getTextBot(), user, table_lines[i]);
+ }
+ table_free(table);
+ }
+}
+
+static void neonserv_cmd_set_setting(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int setting, char *args) {
+ char *value;
+ char nameBuf[64];
+ //get current value
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ 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(args) {
+ //change the channel setting
+ //check the new argument
+ int valid = channel_settings[setting].valid;
+ if(valid & NS_VALID_STRING) {
+ if(!strcmp(args, "*")) {
+ args = "";
+ }
+ }
+ if(valid & NS_VALID_ACCESS) {
+ int caccess = atoi(args);
+ 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);
+ if(uaccess == 500) uaccess++;
+ if(atoi(value) > uaccess) {
+ if(isGodMode(user)) {
+ event->flags |= CMDFLAG_OPLOG;
+ } else {
+ reply(getTextBot(), user, "NS_SET_CANNOT_SET");
+ return;
+ }
+ }
+ if(caccess > uaccess) {
+ if(isGodMode(user)) {
+ event->flags |= CMDFLAG_OPLOG;
+ } else {
+ reply(getTextBot(), user, "NS_SET_BADLEVEL");
+ return;
+ }
+ }
+ sprintf(nameBuf, "%d", caccess);
+ args = nameBuf;
+ }
+ if(valid & NS_VALID_OPTIONS) {
+ int options = atoi((char *) channel_settings[setting].parameter);
+ int coption = atoi(args);
+ if(coption < 0 || coption >= options) {
+ reply(getTextBot(), user, "NS_SET_INVALID_OPTION", coption);
+ int i;
+ int nameBufPos = 0;
+ if(valid & NS_HAS_OPT) {
+ for(i = 0; i < options; i++) {
+ sprintf(nameBuf, "NS_SET_OPTION_%s_%d", 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(args));
+ args = nameBuf;
+ }
+ if(valid & NS_VALID_BOOLEAN) {
+ if(!strcmp(args, "0") || !stricmp(args, "off") || !stricmp(args, get_language_string(user, "NS_SET_OFF"))) {
+ args = "0";
+ } else if(!strcmp(args, "1") || !stricmp(args, "on") || !stricmp(args, get_language_string(user, "NS_SET_ON"))) {
+ args = "1";
+ } else {
+ reply(getTextBot(), user, "NS_SET_INVALID_BOOLEAN", args);
+ return;
+ }
+ }
+ //valid - set it
+ value = args;
+ printf_mysql_query("UPDATE `channels` SET `%s` = '%s' WHERE `channel_id` = '%d'", channel_settings[setting].chanfield, escape_string(value), chan->channel_id);
+ logEvent(event);
+ }
+ if(channel_settings[setting].valid & NS_HAS_OPT) {
+ sprintf(nameBuf, "NS_SET_OPTION_%s_%s", channel_settings[setting].setting, value);
+ char *tmp = get_language_string(user, nameBuf);
+ if(tmp)
+ reply(getTextBot(), user, "\002%s\002 %s - %s", channel_settings[setting].setting, value, tmp);
+ else
+ reply(getTextBot(), user, "\002%s\002 %s", channel_settings[setting].setting, value);
+ } else
+ 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[setting].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, struct Event *event, const char *setting, char *argument) {
+ char *trigger;
+ //get current trigger
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ printf_mysql_query("SELECT `trigger`, `defaulttrigger` FROM `bot_channels` LEFT JOIN `bots` ON `botid` = `bots`.`id` WHERE `chanid` = '%d' AND `botid` = '%d'", chan->channel_id, client->clientid);
+ res = mysql_use();
+ row = mysql_fetch_row(res);
+ trigger = (row[0] ? row[0] : row[1]);
+ if(argument) {
+ int uaccess = getChannelAccess(user, chan);
+ if(uaccess < 500) {
+ if(isGodMode(user)) {
+ event->flags |= CMDFLAG_OPLOG;
+ } else {
+ 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);
+ logEvent(event);
+ }
+ 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, struct Event *event, const char *setting, char *argument) {
+ char *value;
+ char valueBuf[MAXLEN];
+ //get current value
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ 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
+ struct ModeNode *modenode = createModeNode(NULL);
+ parseModeString(modenode, argument);
+ getFullModeString(modenode, valueBuf);
+ value = valueBuf;
+ printf_mysql_query("UPDATE `channels` SET `channel_modes` = '%s' WHERE `channel_id` = '%d'", escape_string(value), chan->channel_id);
+ //TODO: set modelock
+ freeModeNode(modenode);
+ }
+ 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, struct Event *event, const char *setting, char *argument) {
+ char *value;
+ char tmp[64];
+ //get current value
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ 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->modes, 'l'))
+ putsock(client, "MODE %s -l", chan->name);
+ value = argument;
+ logEvent(event);
+ }
+ 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, struct Event *event, const char *setting, char *argument) {
+ char *value;
+ //get current value
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ 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);
+ event->flags |= CMDFLAG_OPLOG;
+ value = argument;
+ logEvent(event);
+ }
+ if(setting) {
+ reply(getTextBot(), user, "\002%s\002 %s", setting, value);
+ }
+ return value;
+}
+
+#undef MAX_QUERY_LEN
--- /dev/null
+/* cmd_neonserv_setrank.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* argv[0] rank id
+* argv[1] setting
+* argv[2-*] value
+*/
+
+static void neonserv_cmd_setrank_name(struct UserNode *user, int rank_id, char *current, char *value);
+static void neonserv_cmd_setrank_info(struct UserNode *user, int rank_id, char *current, char *value);
+static void neonserv_cmd_setrank_access(struct UserNode *user, int rank_id, char *current, char *value);
+static void neonserv_cmd_setrank_order(struct UserNode *user, int rank_id, char *current, char *value);
+
+CMD_BIND(neonserv_cmd_setrank) {
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ printf_mysql_query("SELECT `rank_id`, `rank_name`, `rank_info`, `rank_access`, `rank_order` FROM `support_ranks` WHERE `rank_id` = '%s'", escape_string(argv[0]));
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) == NULL) {
+ reply(getTextBot(), user, "NS_SETRANK_NOT_FOUND", argv[0]);
+ return;
+ }
+ if(argc < 2) {
+ reply(getTextBot(), user, "NS_SETRANK_HEAD", row[0]);
+ reply(getTextBot(), user, "\002NAME \002 %s", row[1]);
+ reply(getTextBot(), user, "\002INFO \002 %s", row[2]);
+ reply(getTextBot(), user, "\002ACCESS \002 %s", row[3]);
+ reply(getTextBot(), user, "\002ORDER \002 %s", row[4]);
+ } else {
+ char *value = NULL;
+ if(argc > 2) {
+ value = merge_argv(argv, 2, argc);
+ }
+ if(!stricmp(argv[1], "name"))
+ neonserv_cmd_setrank_name(user, atoi(row[0]), row[1], value);
+ else if(!stricmp(argv[1], "info"))
+ neonserv_cmd_setrank_info(user, atoi(row[0]), row[2], value);
+ else if(!stricmp(argv[1], "access"))
+ neonserv_cmd_setrank_access(user, atoi(row[0]), row[3], value);
+ else if(!stricmp(argv[1], "order"))
+ neonserv_cmd_setrank_order(user, atoi(row[0]), row[4], value);
+ else
+ reply(getTextBot(), user, "NS_SETRANK_UNKNOWN_SETTING", row[1]);
+ }
+}
+
+static void neonserv_cmd_setrank_name(struct UserNode *user, int rank_id, char *current, char *value) {
+ if(value && stricmp(value, current)) {
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ printf_mysql_query("SELECT `rank_id` FROM `support_ranks` WHERE `rank_name` = '%s'", escape_string(value));
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) != NULL) {
+ reply(getTextBot(), user, "NS_ADDRANK_EXISTS", value);
+ return;
+ }
+ printf_mysql_query("UPDATE `support_ranks` SET `rank_name` = '%s' WHERE `rank_id` = '%d'", escape_string(value), rank_id);
+ current = value;
+ }
+ reply(getTextBot(), user, "\002NAME\002 %s", current);
+}
+
+static void neonserv_cmd_setrank_info(struct UserNode *user, int rank_id, char *current, char *value) {
+ if(value && stricmp(value, current)) {
+ printf_mysql_query("UPDATE `support_ranks` SET `rank_info` = '%s' WHERE `rank_id` = '%d'", escape_string(value), rank_id);
+ current = value;
+ }
+ reply(getTextBot(), user, "\002INFO\002 %s", current);
+}
+
+static void neonserv_cmd_setrank_access(struct UserNode *user, int rank_id, char *current, char *value) {
+ if(value && stricmp(value, current)) {
+ int new_access = atoi(value);
+ if(new_access <= 0 || new_access > 1000) {
+ reply(getTextBot(), user, "NS_INVALID_ACCESS", new_access);
+ return;
+ }
+ printf_mysql_query("UPDATE `users` SET `user_access` = '%d' WHERE `user_rank` = '%d'", new_access, rank_id);
+ printf_mysql_query("UPDATE `support_ranks` SET `rank_access` = '%d' WHERE `rank_id` = '%d'", new_access, rank_id);
+ current = value;
+ }
+ reply(getTextBot(), user, "\002ACCESS\002 %s", current);
+}
+
+static void neonserv_cmd_setrank_order(struct UserNode *user, int rank_id, char *current, char *value) {
+ if(value && stricmp(value, current)) {
+ int new_order = atoi(value);
+ if(new_order <= 0 || new_order > 99) {
+ reply(getTextBot(), user, "NS_SETRANK_ORDER_INVALID", new_order);
+ return;
+ }
+ printf_mysql_query("UPDATE `support_ranks` SET `rank_order` = '%d' WHERE `rank_id` = '%d'", new_order, rank_id);
+ current = value;
+ }
+ reply(getTextBot(), user, "\002ORDER\002 %s", current);
+}
--- /dev/null
+/* cmd_neonserv_suspend.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* argv[0] - nick / *auth
+*/
+static USERAUTH_CALLBACK(neonserv_cmd_suspend_nick_lookup);
+static void neonserv_cmd_suspend_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nick, char *auth);
+
+struct neonserv_cmd_suspend_cache {
+ struct ClientSocket *client, *textclient;
+ struct UserNode *user;
+ struct ChanNode *chan;
+ struct Event *event;
+ char *nick;
+};
+
+CMD_BIND(neonserv_cmd_suspend) {
+ if(argv[0][0] == '*') {
+ //we've got an auth
+ argv[0]++;
+ neonserv_cmd_suspend_async1(client, getTextBot(), user, chan, event, argv[0], argv[0]);
+ } else {
+ struct UserNode *cuser = getUserByNick(argv[0]);
+ if(!cuser) {
+ cuser = createTempUser(argv[0]);
+ if(!cuser) {
+ reply(getTextBot(), user, "NS_USER_UNKNOWN", argv[0]);
+ return;
+ }
+ cuser->flags |= USERFLAG_ISTMPUSER;
+ }
+ if(cuser->flags & USERFLAG_ISAUTHED) {
+ neonserv_cmd_suspend_async1(client, getTextBot(), user, chan, event, argv[0], cuser->auth);
+ } else {
+ struct neonserv_cmd_suspend_cache *cache = malloc(sizeof(*cache));
+ if (!cache) {
+ perror("malloc() failed");
+ return;
+ }
+ cache->client = client;
+ cache->textclient = getTextBot();
+ cache->user = user;
+ cache->chan = chan;
+ cache->event = event;
+ cache->nick = strdup(argv[0]);
+ get_userauth(cuser, neonserv_cmd_suspend_nick_lookup, cache);
+ }
+ }
+}
+
+static USERAUTH_CALLBACK(neonserv_cmd_suspend_nick_lookup) {
+ struct neonserv_cmd_suspend_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_suspend_async1(cache->client, cache->textclient, cache->user, cache->chan, cache->event, user->nick, user->auth);
+ free(cache->nick);
+ free(cache);
+}
+
+static void neonserv_cmd_suspend_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nick, char *auth) {
+ //we've got a valid auth now...
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ int userid, cflags;
+ 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]);
+ //check if the user is added
+ printf_mysql_query("SELECT `chanuser_access`, `chanuser_id`, `chanuser_flags` FROM `chanusers` WHERE `chanuser_cid` = '%d' AND `chanuser_uid` = '%d'", chan->channel_id, userid);
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) != NULL) {
+ if(atoi(row[0]) >= getChannelAccess(user, chan)) {
+ if(isGodMode(user)) {
+ event->flags |= CMDFLAG_OPLOG;
+ } else {
+ reply(textclient, user, "NS_USER_OUTRANKED", nick);
+ return;
+ }
+ }
+ //suspend
+ cflags = atoi(row[2]);
+ if(cflags & DB_CHANUSER_SUSPENDED) {
+ reply(textclient, user, "NS_SUSPEND_ALREADY", nick);
+ return;
+ }
+ cflags |= DB_CHANUSER_SUSPENDED;
+ printf_mysql_query("UPDATE `chanusers` SET `chanuser_flags` = '%d' WHERE `chanuser_id` = '%s'", cflags, row[1]);
+ reply(textclient, user, "NS_SUSPEND_DONE", nick, chan->name);
+ logEvent(event);
+ return;
+ }
+ }
+ reply(textclient, user, "NS_NOT_ON_USERLIST", nick, chan->name);
+}
--- /dev/null
+/* cmd_neonserv_topic.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* ADVANCEDTOPIC enabled
+* argv[0] topic id
+* argv[1-*] topic
+*
+* ADVANCEDTOPIC disabled
+* argv[0-*] topic
+*/
+
+#define ADVANCEDTOPIC_MAXID 9
+
+CMD_BIND(neonserv_cmd_topic) {
+ MYSQL_RES *res;
+ MYSQL_ROW row, default_row = NULL;
+ int advanced_topic, i;
+ char *newtopic;
+ char *a,*b;
+
+ printf_mysql_query("SELECT `channel_exttopic`, `channel_exttopic_topic`, `channel_topicmask`, `channel_enftopic`, `channel_topicsnarf`, `channel_defaulttopic` FROM `channels` WHERE `channel_id` = '%d'", chan->channel_id);
+ res = mysql_use();
+ row = mysql_fetch_row(res);
+ if(!row[0] || !row[3] || !row[4]) {
+ printf_mysql_query("SELECT `channel_exttopic`, `channel_enftopic`, `channel_topicsnarf` FROM `channels` WHERE `channel_name` = 'defaults'");
+ default_row = mysql_fetch_row(mysql_use());
+ }
+
+ if(row[0] == NULL) {
+ advanced_topic = atoi(default_row[0]);
+ } else
+ advanced_topic = atoi(row[0]);
+ if(argc == 0) {
+ //default topic!
+ putsock(client, "TOPIC %s :%s", chan->name, row[5]);
+ reply(getTextBot(), user, "NS_TOPIC_DONE", row[5]);
+ logEvent(event);
+ return;
+ }
+ int uaccess = getChannelAccess(user, chan);
+ if(uaccess >= atoi((row[3] ? row[3] : default_row[1]))) {
+ //just set the topic
+ newtopic = merge_argv(argv, 0, argc);
+ if(uaccess >= atoi((row[4] ? row[4] : default_row[2]))) {
+ //set the default topic
+ printf_mysql_query("UPDATE `channels` SET `channel_defaulttopic` = '%s' WHERE `channel_id` = '%d'", escape_string(newtopic), chan->channel_id);
+ }
+ putsock(client, "TOPIC %s :%s", chan->name, newtopic);
+ reply(getTextBot(), user, "NS_TOPIC_DONE", newtopic);
+ logEvent(event);
+ return;
+ }
+ if(advanced_topic) {
+ char *advtopics[ADVANCEDTOPIC_MAXID];
+ int topic_id = 0;
+ topic_id = atoi(argv[0]);
+ if(!topic_id || topic_id > ADVANCEDTOPIC_MAXID) {
+ reply(getTextBot(), user, "NS_EXTTOPIC_INVALID_ID", argv[0]);
+ return;
+ }
+ //parse topics
+ i = 0;
+ b = row[1];
+ while((a = strstr(b, "\n")) != NULL) {
+ *a = '\0';
+ if(i == ADVANCEDTOPIC_MAXID-1) break;
+ advtopics[i++] = b;
+ b = a+1;
+ }
+ advtopics[i++] = b;
+ for(;i < ADVANCEDTOPIC_MAXID;i++)
+ advtopics[i] = "";
+ if(argc < 2) {
+ //just show the topic with this id
+ reply(getTextBot(), user, "NS_EXTTOPIC_TOPICID", topic_id, advtopics[topic_id-1]);
+ return;
+ }
+ newtopic = merge_argv(argv, 1, argc);
+ if(!strcmp(newtopic, "*"))
+ newtopic = "";
+ advtopics[topic_id-1] = newtopic;
+ char topiclist[MAXLEN*2];
+ topiclist[0] = '\0';
+ int topiclistpos = 0;
+ for(i = 0; i < ADVANCEDTOPIC_MAXID; i++) {
+ if(topiclistpos + strlen(advtopics[i]) + 2 >= MAXLEN) break;
+ topiclistpos += sprintf(topiclist+topiclistpos, (i ? "\n%s" : "%s"), advtopics[i]);
+ }
+ printf_mysql_query("UPDATE `channels` SET `channel_exttopic_topic` = '%s' WHERE `channel_id` = '%d'", escape_string(topiclist), chan->channel_id);
+ //now build the new topic and set it...
+ topiclistpos = 0;
+ b = row[2];
+ char *topicpart, *debugbb;
+ while((a = strstr(b, "%")) != NULL) {
+ *a = '\0';
+ if(isdigit(a[1]) && a[1] - 48 > 0) {
+ topicpart = advtopics[a[1] - 49];
+ if(isdigit(topicpart[0]) && isdigit(b[strlen(b)-1]))
+ debugbb = "\002\002"; //double bold to prevent following digits used as color code
+ else
+ debugbb = "";
+ topiclistpos += sprintf(topiclist + topiclistpos, "%s%s%s", b, debugbb, topicpart);
+ b = a+2;
+ } else {
+ topiclistpos += sprintf(topiclist + topiclistpos, "%s%%", b);
+ b = a+1;
+ }
+ }
+ topiclistpos += sprintf(topiclist + topiclistpos, "%s", b);
+ if(topiclistpos > MAXLEN)
+ topiclist[MAXLEN] = '\0';
+ putsock(client, "TOPIC %s :%s", chan->name, topiclist);
+ reply(getTextBot(), user, "NS_TOPIC_DONE", topiclist);
+ logEvent(event);
+ } else {
+ newtopic = merge_argv(argv, 0, argc);
+ char topiclist[MAXLEN*2];
+ topiclist[0] = '\0';
+ int topiclistpos = 0;
+ b = row[2];
+ char *debugbb;
+ while((a = strstr(b, "*")) != NULL) {
+ *a = '\0';
+ if(isdigit(newtopic[0]) && isdigit(b[strlen(b)-1]))
+ debugbb = "\002\002"; //double bold to prevent following digits used as color code
+ else
+ debugbb = "";
+ topiclistpos += sprintf(topiclist + topiclistpos, "%s%s%s", b, debugbb, newtopic);
+ b = a+1;
+ }
+ topiclistpos += sprintf(topiclist + topiclistpos, "%s", b);
+ if(topiclistpos > MAXLEN)
+ topiclist[MAXLEN] = '\0';
+ putsock(client, "TOPIC %s :%s", chan->name, topiclist);
+ reply(getTextBot(), user, "NS_TOPIC_DONE", topiclist);
+ logEvent(event);
+ }
+}
+
+#undef ADVANCEDTOPIC_MAXID
\ No newline at end of file
--- /dev/null
+/* cmd_neonserv_trace.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+#define NS_TRACE_CRITERIA_AUTHED 0x01
+#define NS_TRACE_CRITERIA_NUMCHAN 0x02
+
+struct neonserv_cmd_trace_criteria {
+ char *mask;
+ char *nick;
+ char *ident;
+ char *host;
+ char *account;
+ unsigned int flags : 4;
+ unsigned int authed : 1;
+ unsigned int used_channel : 5; //32 max
+ char *channel[10];
+ unsigned int numchannels;
+ unsigned int limit : 16;
+};
+
+CMD_BIND(neonserv_cmd_trace) {
+ //ok parse the criterias
+ struct neonserv_cmd_trace_criteria *criteria = malloc(sizeof(*criteria));
+ if (!criteria) {
+ perror("malloc() failed");
+ return;
+ }
+ memset(criteria, 0, sizeof(*criteria));
+ criteria->limit = 50;
+ int i, show_user = 0;
+ if(!stricmp(argv[0], "print")) {
+ show_user = 1;
+ }
+ for(i = 1; i < argc; i += 2) {
+ if(argc <= i+1) {
+ reply(getTextBot(), user, "MODCMD_LESS_PARAM_COUNT");
+ return;
+ }
+ if(!stricmp(argv[i], "mask")) criteria->mask = argv[i+1];
+ else if(!stricmp(argv[i], "nick")) criteria->nick = argv[i+1];
+ else if(!stricmp(argv[i], "ident")) criteria->ident = argv[i+1];
+ else if(!stricmp(argv[i], "host")) criteria->host = argv[i+1];
+ else if(!stricmp(argv[i], "account")) criteria->account = argv[i+1];
+ else if(!stricmp(argv[i], "authed")) {
+ if(!strcmp(argv[i+1], "0") || !strcmp(argv[i+1], "off") || !strcmp(argv[i+1], get_language_string(user, "NS_SET_OFF"))) {
+ criteria->authed = 1;
+ } else if(!strcmp(argv[i+1], "0") || !strcmp(argv[i+1], "off") || !strcmp(argv[i+1], get_language_string(user, "NS_SET_OFF"))) {
+ criteria->authed = 0;
+ } else {
+ reply(getTextBot(), user, "NS_SET_INVALID_BOOLEAN", argv[i+1]);
+ return;
+ }
+ criteria->flags |= NS_TRACE_CRITERIA_AUTHED;
+ }
+ else if(!stricmp(argv[i], "channel")) criteria->channel[criteria->used_channel++] = argv[i+1];
+ else if(!stricmp(argv[i], "numchannels")) {
+ criteria->numchannels = atoi(argv[i+1]);
+ criteria->flags |= NS_TRACE_CRITERIA_NUMCHAN;
+ }
+ else if(!stricmp(argv[i], "limit")) {
+ criteria->limit = atoi(argv[i+1]);
+ }
+ }
+ char tmp[MAXLEN];
+ int matches = 0;
+ struct UserNode *cuser;
+ reply(getTextBot(), user, "NS_TRACE_HEADER");
+ for(cuser = getAllUsers(NULL); cuser; cuser = getAllUsers(cuser)) {
+ if(show_user && matches == criteria->limit) {
+ //too many
+ break;
+ }
+ if(criteria->mask) {
+ sprintf(tmp, "%s!%s@%s", cuser->nick, cuser->ident, cuser->host);
+ if(match(criteria->mask, tmp)) continue;
+ }
+ if(criteria->nick && match(criteria->nick, cuser->nick)) continue;
+ if(criteria->ident && match(criteria->ident, cuser->ident)) continue;
+ if(criteria->host && match(criteria->host, cuser->host)) continue;
+ if(criteria->account && (!(cuser->flags & USERFLAG_ISAUTHED) || match(criteria->account, cuser->auth))) continue;
+ if((criteria->flags & NS_TRACE_CRITERIA_AUTHED) && (criteria->authed ^ (cuser->flags & USERFLAG_ISAUTHED))) continue;
+ if((criteria->flags & NS_TRACE_CRITERIA_NUMCHAN)) {
+ int ccount = 0;
+ struct ChanUser *chanuser;
+ for(chanuser = getUserChannels(cuser, NULL); chanuser; chanuser = getUserChannels(cuser, chanuser))
+ ccount++;
+ if(ccount < criteria->numchannels)
+ continue;
+ }
+ matches++;
+ //output
+ if(show_user) {
+ reply(getTextBot(), user, "%s!%s@%s %s", cuser->nick, cuser->ident, cuser->host, ((cuser->flags & USERFLAG_ISAUTHED) ? cuser->auth : "*"));
+ }
+ }
+ reply(getTextBot(), user, "NS_TABLE_COUNT", matches);
+}
--- /dev/null
+/* cmd_neonserv_trim.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* argv[0] target (format: minaccess-maxaccess/users/bans)
+* argv[1] duration
+*/
+static USERLIST_CALLBACK(neonserv_cmd_trim_userlist_lookup);
+static void neonserv_cmd_trim_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, int min_access, int max_access, int duration);
+
+struct neonserv_cmd_trim_cache {
+ struct ClientSocket *client, *textclient;
+ struct UserNode *user;
+ struct Event *event;
+ int min_access;
+ int max_access;
+ int duration;
+};
+
+CMD_BIND(neonserv_cmd_trim) {
+ if(stricmp(argv[0], "bans") && !checkChannelAccess(user, chan, "channel_candel", 0)) {
+ if(isGodMode(user)) {
+ event->flags |= CMDFLAG_OPLOG;
+ } else {
+ reply(getTextBot(), user, "NS_ACCESS_DENIED");
+ return;
+ }
+ }
+ int min_access, max_access;
+ int duration = strToTime(user, argv[1]);
+ if(duration < 30) {
+ reply(getTextBot(), user, "NS_TRIM_DURATION_TOO_SHORT", 30);
+ return;
+ }
+ if(!stricmp(argv[0], "users")) {
+ min_access = 1;
+ max_access = getChannelAccess(user, chan) - 1;
+ } else if(!stricmp(argv[0], "bans")) {
+ if(!checkChannelAccess(user, chan, "channel_staticban", 0)) {
+ if(isGodMode(user)) {
+ event->flags |= CMDFLAG_OPLOG;
+ } else {
+ reply(getTextBot(), user, "NS_ACCESS_DENIED");
+ return;
+ }
+ }
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ char nameBuf[20];
+ printf_mysql_query("SELECT `ban_mask`, `ban_id`, `ban_timeout` FROM `bans` WHERE `ban_channel` = '%d' AND `ban_triggered` < %d", chan->channel_id, (int) (time(0) - duration));
+ res = mysql_use();
+ int bancount = mysql_num_rows(res);
+ struct ModeBuffer *modenode = initModeBuffer(client, chan);
+ while ((row = mysql_fetch_row(res)) != NULL) {
+ if(strcmp(row[2], "0")) {
+ sprintf(nameBuf, "ban_%s", row[1]);
+ timeq_del_name(nameBuf);
+ }
+ printf_mysql_query("DELETE FROM `bans` WHERE `ban_id` = '%s'", row[1]);
+ modeBufferUnban(modenode, row[0]);
+ }
+ freeModeBuffer(modenode);
+ char timeBuf[MAXLEN];
+ reply(getTextBot(), user, "NS_TRIM_BAN_DONE", bancount, chan->name, timeToStr(user, duration, 3, timeBuf));
+ if(bancount)
+ logEvent(event);
+ return;
+ } else {
+ char *seperator = strstr(argv[0], "-");
+ if(seperator) {
+ *seperator = '\0';
+ seperator++;
+ min_access = atoi(argv[0]);
+ max_access = atoi(seperator);
+ if(max_access < min_access) {
+ reply(getTextBot(), user, "NS_INVALID_ACCESS_RANGE", min_access, max_access);
+ return;
+ }
+ } else {
+ min_access = atoi(argv[0]);
+ max_access = min_access;
+ }
+ if(max_access >= getChannelAccess(user, chan)) {
+ if(isGodMode(user)) {
+ event->flags |= CMDFLAG_OPLOG;
+ } else {
+ reply(getTextBot(), user, "NS_NO_ACCESS");
+ return;
+ }
+ }
+ }
+ struct neonserv_cmd_trim_cache *cache = malloc(sizeof(*cache));
+ if (!cache) {
+ perror("malloc() failed");
+ return;
+ }
+ cache->client = client;
+ cache->textclient = getTextBot();
+ cache->user = user;
+ cache->event = event;
+ cache->min_access = min_access;
+ cache->max_access = max_access;
+ cache->duration = duration;
+ get_userlist_with_invisible(chan, neonserv_cmd_trim_userlist_lookup, cache);
+}
+
+static USERLIST_CALLBACK(neonserv_cmd_trim_userlist_lookup) {
+ struct neonserv_cmd_trim_cache *cache = data;
+ //got userlist
+ neonserv_cmd_trim_async1(cache->client, cache->textclient, cache->user, chan, cache->event, cache->min_access, cache->max_access, cache->duration);
+ free(cache);
+}
+
+static void neonserv_cmd_trim_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, int min_access, int max_access, int duration) {
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ int trim_count = 0, is_here;
+ struct ChanUser *chanuser;
+ printf_mysql_query("SELECT `chanuser_seen`, `user_user`, `chanuser_id` FROM `chanusers` LEFT JOIN `users` ON `chanuser_uid` = `user_id` WHERE `chanuser_cid` = '%d' AND `chanuser_access` >= '%d' AND `chanuser_access` <= '%d'", chan->channel_id, min_access, max_access);
+ res = mysql_use();
+ while ((row = mysql_fetch_row(res)) != NULL) {
+ if(!strcmp(row[0], "0") || time(0) - atoi(row[0]) >= duration) {
+ //check if the user is currently in the channel
+ is_here = 0;
+ for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
+ if((chanuser->user->flags & USERFLAG_ISAUTHED) && !strcmp(chanuser->user->auth, row[1])) {
+ is_here = 1;
+ break;
+ }
+ }
+ if(!is_here) {
+ //delete the user
+ trim_count++;
+ printf_mysql_query("DELETE FROM `chanusers` WHERE `chanuser_id` = '%s'", row[2]);
+ }
+ }
+ }
+ char timeBuf[MAXLEN];
+ reply(getTextBot(), user, "NS_TRIM_DONE", trim_count, min_access, max_access, chan->name, timeToStr(user, duration, 3, timeBuf));
+ if(trim_count)
+ logEvent(event);
+}
--- /dev/null
+/* cmd_neonserv_unban.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* argv[0-*] nick[,*auth[,*!*@mask[...]]]
+*/
+struct neonserv_cmd_unban_cache {
+ struct ClientSocket *client, *textclient;
+ struct UserNode *user;
+ struct ChanNode *chan;
+ struct Event *event;
+ struct ModeBuffer *modeBuf;
+ int provided_masks, done_masks, pending_whos, unbanned_masks;
+};
+
+static USERAUTH_CALLBACK(neonserv_cmd_unban_userauth_lookup);
+static void neonserv_cmd_unban_nick(struct neonserv_cmd_unban_cache *cache, struct UserNode *user);
+static void neonserv_cmd_unban_mask(struct neonserv_cmd_unban_cache *cache, char *mask);
+static void neonserv_cmd_unban_finish(struct neonserv_cmd_unban_cache *cache);
+
+CMD_BIND(neonserv_cmd_unban) {
+ char *mask, *nextmask;
+ struct ModeBuffer *modeBuf;
+ modeBuf = initModeBuffer(client, chan);
+ nextmask = merge_argv_char(argv, 0, argc, ',');
+ struct neonserv_cmd_unban_cache *cache = malloc(sizeof(*cache));
+ if (!cache) {
+ perror("malloc() failed");
+ return;
+ }
+ cache->client = client;
+ cache->textclient = getTextBot();
+ cache->user = user;
+ cache->chan = chan;
+ cache->event = event;
+ cache->modeBuf = modeBuf;
+ cache->done_masks = 0;
+ cache->provided_masks = 0;
+ cache->unbanned_masks = 0;
+ while((mask = nextmask)) {
+ nextmask = strstr(mask, ",");
+ if(nextmask) {
+ *nextmask = '\0';
+ nextmask++;
+ }
+ cache->provided_masks++;
+ if(is_valid_nick(mask)) {
+ struct UserNode *cuser = getUserByNick(mask);
+ if(!cuser) {
+ cuser = createTempUserMask(mask);
+ if(!cuser) {
+ break; //internal bot error
+ }
+ cuser->flags |= USERFLAG_ISTMPUSER;
+ get_userauth(cuser, neonserv_cmd_unban_userauth_lookup, cache);
+ cache->pending_whos++;
+ } else {
+ neonserv_cmd_unban_nick(cache, cuser);
+ }
+ } else {
+ neonserv_cmd_unban_mask(cache, mask);
+ }
+ }
+ if(!cache->pending_whos)
+ neonserv_cmd_unban_finish(cache);
+}
+
+static USERAUTH_CALLBACK(neonserv_cmd_unban_userauth_lookup) {
+ struct neonserv_cmd_unban_cache *cache = data;
+ cache->pending_whos--;
+ if(user)
+ neonserv_cmd_unban_nick(cache, user);
+ else
+ neonserv_cmd_unban_mask(cache, user_nick);
+ if(!cache->pending_whos)
+ neonserv_cmd_unban_finish(cache);
+}
+
+static void neonserv_cmd_unban_nick(struct neonserv_cmd_unban_cache *cache, struct UserNode *user) {
+ int matches = 0;
+ struct BanNode *ban;
+ char usermask[NICKLEN+USERLEN+HOSTLEN+3];
+ sprintf(usermask, "%s!%s@%s", user->nick, user->ident, user->host);
+ for(ban = cache->chan->bans; ban; ban = ban->next) {
+ if(!match(ban->mask, usermask)) {
+ modeBufferUnban(cache->modeBuf, ban->mask);
+ cache->unbanned_masks++;
+ matches++;
+ }
+ }
+ if(matches)
+ cache->done_masks++;
+}
+
+static void neonserv_cmd_unban_mask(struct neonserv_cmd_unban_cache *cache, char *mask) {
+ char banmask[NICKLEN+USERLEN+HOSTLEN+3];
+ int matches = 0;
+ struct BanNode *ban;
+ mask = make_banmask(mask, banmask);
+ for(ban = cache->chan->bans; ban; ban = ban->next) {
+ if(!match(mask, ban->mask)) {
+ modeBufferUnban(cache->modeBuf, ban->mask);
+ cache->unbanned_masks++;
+ matches++;
+ }
+ }
+ if(matches)
+ cache->done_masks++;
+ else {
+ for(ban = cache->chan->bans; ban; ban = ban->next) {
+ if(!match(ban->mask, mask)) {
+ reply(cache->textclient, cache->user, "NS_DELBAN_BANNED_BY", mask, ban->mask);
+ break;
+ }
+ }
+ }
+}
+
+static void neonserv_cmd_unban_finish(struct neonserv_cmd_unban_cache *cache) {
+ freeModeBuffer(cache->modeBuf);
+ if(cache->done_masks == cache->provided_masks)
+ reply(cache->textclient, cache->user, "NS_UNBAN_DONE", cache->unbanned_masks, cache->chan->name);
+ else
+ reply(cache->textclient, cache->user, "NS_UNBAN_FAIL", cache->client->user->nick);
+ if(cache->done_masks)
+ logEvent(cache->event);
+ free(cache);
+}
+
--- /dev/null
+/* cmd_neonserv_unbanall.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* argv[0-*] nothing
+*/
+
+CMD_BIND(neonserv_cmd_unbanall) {
+ struct ModeBuffer *modeBuf;
+ int bans = 0;
+ struct BanNode *ban;
+ modeBuf = initModeBuffer(client, chan);
+ for(ban = chan->bans; ban; ban = ban->next) {
+ modeBufferUnban(modeBuf, ban->mask);
+ bans++;
+ }
+ freeModeBuffer(modeBuf);
+ if(bans) {
+ reply(getTextBot(), user, "NS_UNBANALL_DONE", bans, chan->name);
+ logEvent(event);
+ } else
+ reply(getTextBot(), user, "NS_UNBANALL_FAIL", client->user->nick, chan->name);
+}
--- /dev/null
+/* cmd_neonserv_unbanme.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* argv[0-*] nothing
+*/
+
+CMD_BIND(neonserv_cmd_unbanme) {
+ struct ModeBuffer *modeBuf;
+ int bans = 0;
+ struct BanNode *ban;
+ modeBuf = initModeBuffer(client, chan);
+ char usermask[NICKLEN+USERLEN+HOSTLEN+3];
+ sprintf(usermask, "%s!%s@%s", user->nick, user->ident, user->host);
+ for(ban = chan->bans; ban; ban = ban->next) {
+ if(!match(ban->mask, usermask)) {
+ modeBufferUnban(modeBuf, ban->mask);
+ bans++;
+ }
+ }
+ freeModeBuffer(modeBuf);
+ if(bans) {
+ reply(getTextBot(), user, "NS_UNBANME_DONE", bans, chan->name);
+ logEvent(event);
+ } else
+ reply(getTextBot(), user, "NS_UNBANME_FAIL", client->user->nick, usermask);
+}
--- /dev/null
+/* cmd_neonserv_unsuspend.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* argv[0] - nick / *auth
+*/
+static USERAUTH_CALLBACK(neonserv_cmd_unsuspend_nick_lookup);
+static void neonserv_cmd_unsuspend_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nick, char *auth);
+
+struct neonserv_cmd_unsuspend_cache {
+ struct ClientSocket *client, *textclient;
+ struct UserNode *user;
+ struct ChanNode *chan;
+ struct Event *event;
+ char *nick;
+};
+
+CMD_BIND(neonserv_cmd_unsuspend) {
+ if(argv[0][0] == '*') {
+ //we've got an auth
+ argv[0]++;
+ neonserv_cmd_unsuspend_async1(client, getTextBot(), user, chan, event, argv[0], argv[0]);
+ } else {
+ struct UserNode *cuser = getUserByNick(argv[0]);
+ if(!cuser) {
+ cuser = createTempUser(argv[0]);
+ if(!cuser) {
+ reply(getTextBot(), user, "NS_USER_UNKNOWN", argv[0]);
+ return;
+ }
+ cuser->flags |= USERFLAG_ISTMPUSER;
+ }
+ if(cuser->flags & USERFLAG_ISAUTHED) {
+ neonserv_cmd_unsuspend_async1(client, getTextBot(), user, chan, event, argv[0], cuser->auth);
+ } else {
+ struct neonserv_cmd_unsuspend_cache *cache = malloc(sizeof(*cache));
+ if (!cache) {
+ perror("malloc() failed");
+ return;
+ }
+ cache->client = client;
+ cache->textclient = getTextBot();
+ cache->user = user;
+ cache->chan = chan;
+ cache->event = event;
+ cache->nick = strdup(argv[0]);
+ get_userauth(cuser, neonserv_cmd_unsuspend_nick_lookup, cache);
+ }
+ }
+}
+
+static USERAUTH_CALLBACK(neonserv_cmd_unsuspend_nick_lookup) {
+ struct neonserv_cmd_unsuspend_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_unsuspend_async1(cache->client, cache->textclient, cache->user, cache->chan, cache->event, user->nick, user->auth);
+ free(cache->nick);
+ free(cache);
+}
+
+static void neonserv_cmd_unsuspend_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nick, char *auth) {
+ //we've got a valid auth now...
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ int userid, cflags;
+ 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]);
+ //check if the user is added
+ printf_mysql_query("SELECT `chanuser_access`, `chanuser_id`, `chanuser_flags` FROM `chanusers` WHERE `chanuser_cid` = '%d' AND `chanuser_uid` = '%d'", chan->channel_id, userid);
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) != NULL) {
+ if(atoi(row[0]) >= getChannelAccess(user, chan)) {
+ if(isGodMode(user)) {
+ event->flags |= CMDFLAG_OPLOG;
+ } else {
+ reply(textclient, user, "NS_USER_OUTRANKED", nick);
+ return;
+ }
+ }
+ //unsuspend
+ cflags = atoi(row[2]);
+ if(!(cflags & DB_CHANUSER_SUSPENDED)) {
+ reply(textclient, user, "NS_SUSPEND_NOT", nick);
+ return;
+ }
+ cflags &= ~DB_CHANUSER_SUSPENDED;
+ printf_mysql_query("UPDATE `chanusers` SET `chanuser_flags` = '%d' WHERE `chanuser_id` = '%s'", cflags, row[1]);
+ reply(textclient, user, "NS_SUSPEND_RESTORED", nick, chan->name);
+ logEvent(event);
+ return;
+ }
+ }
+ reply(textclient, user, "NS_NOT_ON_USERLIST", nick, chan->name);
+}
--- /dev/null
+/* cmd_neonserv_unvisited.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+struct neonserv_cmd_unvisited_cache {
+ struct ClientSocket *client, *textclient;
+ struct UserNode *user;
+ int duration;
+ int who_count, matches;
+};
+
+static USERLIST_CALLBACK(neonserv_cmd_unvisited_userlist_lookup);
+static int neonserv_cmd_unvisited_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, int duration);
+static void neonserv_cmd_unvisited_async2(struct neonserv_cmd_unvisited_cache *cache);
+
+CMD_BIND(neonserv_cmd_unvisited) {
+ int duration = (argc ? strToTime(user, argv[0]) : 60*60*24*7*3);
+ reply(getTextBot(), user, "NS_SEARCH_HEADER");
+ MYSQL_RES *res, *res2;
+ MYSQL_ROW row, row2;
+ struct ChanNode *channel;
+ struct neonserv_cmd_unvisited_cache *cache = malloc(sizeof(*cache));
+ if (!cache) {
+ perror("malloc() failed");
+ return;
+ }
+ cache->client = client;
+ cache->textclient = getTextBot();
+ cache->user = user;
+ cache->duration = duration;
+ cache->who_count = 1; /* small fake to prevent the cache to be freed too early */
+ cache->matches = 0;
+ printf_mysql_query("SELECT `channel_id`, `channel_name`, `channel_nodelete` FROM `bot_channels` LEFT JOIN `channels` ON `chanid` = `channel_id` LEFT JOIN `users` ON `channel_registrator` = `user_id` WHERE `botid` = '%d'", client->botid);
+ res = mysql_use();
+ while ((row = mysql_fetch_row(res)) != NULL) {
+ if(!strcmp(row[2], "1")) continue;
+ printf_mysql_query("SELECT `chanuser_seen` FROM `chanusers` WHERE `chanuser_cid` = '%s' AND `chanuser_access` >= 300 ORDER BY `chanuser_seen` DESC LIMIT 1", row[0]);
+ res2 = mysql_use();
+ row2 = mysql_fetch_row(res2);
+ if(row2 && atol(row2[0]) > (time(0) - duration)) continue;
+ channel = getChanByName(row[1]);
+ if(channel) {
+ cache->who_count++;
+ channel->channel_id = atoi(row[0]);
+ get_userlist_with_invisible(channel, neonserv_cmd_unvisited_userlist_lookup, cache);
+ } else {
+ reply(getTextBot(), user, "%s", row[1]);
+ cache->matches++;
+ }
+ }
+ cache->who_count--; //see fix on line 46
+ if(cache->who_count == 0) {
+ neonserv_cmd_unvisited_async2(cache);
+ }
+}
+
+static USERLIST_CALLBACK(neonserv_cmd_unvisited_userlist_lookup) {
+ struct neonserv_cmd_unvisited_cache *cache = data;
+ if(neonserv_cmd_unvisited_async1(cache->client, cache->textclient, cache->user, chan, cache->duration))
+ cache->matches++;
+ cache->who_count--;
+ if(cache->who_count == 0) {
+ neonserv_cmd_unvisited_async2(cache);
+ }
+}
+
+static int neonserv_cmd_unvisited_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, int duration) {
+ struct ChanUser *chanuser;
+ MYSQL_RES *res2;
+ MYSQL_ROW row2;
+ int active = 0;
+ for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
+ if(isBot(chanuser->user)) continue;
+ if((chanuser->user->flags & USERFLAG_ISAUTHED)) {
+ printf_mysql_query("SELECT `chanuser_id`, `chanuser_access` FROM `chanusers` LEFT JOIN `users` ON `user_id` = `chanuser_uid` WHERE `chanuser_cid` = '%d' AND `user_user` = '%s'", chan->channel_id, escape_string(chanuser->user->auth));
+ res2 = mysql_use();
+ row2 = mysql_fetch_row(res2);
+ if(row2 && atoi(row2[1]) >= 300) {
+ printf_mysql_query("UPDATE `chanusers` SET `chanuser_seen` = UNIX_TIMESTAMP() WHERE `chanuser_id` = '%s'", row2[0]);
+ active = 1;
+ }
+ }
+ }
+ if(!active) {
+ reply(textclient, user, "%s", chan->name);
+ }
+ return !active;
+}
+
+static void neonserv_cmd_unvisited_async2(struct neonserv_cmd_unvisited_cache *cache) {
+ reply(cache->textclient, cache->user, "NS_TABLE_COUNT", cache->matches);
+ free(cache);
+}
--- /dev/null
+/* cmd_neonserv_up.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* no arguments
+*/
+
+struct neonserv_cmd_up_cache {
+ struct ClientSocket *client;
+ struct ClientSocket *textclient;
+ struct UserNode *user;
+ struct Event *event;
+};
+
+static void neonserv_cmd_up_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event);
+static USERLIST_CALLBACK(neonserv_cmd_up_userlist_lookup);
+
+CMD_BIND(neonserv_cmd_up) {
+ if(isModeSet(chan->modes, 'd') || isModeSet(chan->modes, 'D')) {
+ struct neonserv_cmd_up_cache *cache = malloc(sizeof(*cache));
+ if (!cache) {
+ perror("malloc() failed");
+ return;
+ }
+ cache->client = client;
+ cache->textclient = getTextBot();
+ cache->user = user;
+ cache->event = event;
+ get_userlist_if_invisible(chan, neonserv_cmd_up_userlist_lookup, cache);
+ } else {
+ neonserv_cmd_up_async1(client, getTextBot(), user, chan, event);
+ }
+}
+
+static USERLIST_CALLBACK(neonserv_cmd_up_userlist_lookup) {
+ struct neonserv_cmd_up_cache *cache = data;
+ neonserv_cmd_up_async1(cache->client, cache->textclient, cache->user, chan, cache->event);
+ free(cache);
+}
+
+static void neonserv_cmd_up_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event) {
+ struct ChanUser *chanuser = getChanUser(user, chan);
+ if(!chanuser) {
+ reply(getTextBot(), user, "NS_NOT_ON_CHANNEL_YOU", chan->name);
+ return;
+ }
+ loadChannelSettings(chan);
+ MYSQL_RES *res, *default_res;
+ MYSQL_ROW row, default_row;
+ int chan_getop, chan_getvoice, caccess;
+ printf_mysql_query("SELECT `channel_getop`, `channel_getvoice` FROM `channels` WHERE `channel_id` = '%d'", chan->channel_id);
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) == NULL) return;
+ if(!row[0] || !row[1]) {
+ printf_mysql_query("SELECT `channel_getop`, `channel_getvoice` FROM `channels` WHERE `channel_name` = 'defaults'");
+ default_res = mysql_use();
+ if ((default_row = mysql_fetch_row(default_res)) == NULL) return;
+ chan_getop = (row[0] ? atoi(row[0]) : atoi(default_row[0]));
+ chan_getvoice = (row[1] ? atoi(row[1]) : atoi(default_row[1]));
+ } else {
+ chan_getop = atoi(row[0]);
+ chan_getvoice = atoi(row[1]);
+ }
+ caccess = getChannelAccess(user, chan);
+ if(caccess >= chan_getop) {
+ if(!(chanuser->flags & CHANUSERFLAG_OPPED)) {
+ putsock(client, "MODE %s +o %s", chan->name, user->nick);
+ logEvent(event);
+ } else
+ reply(getTextBot(), user, "NS_UP_ALREADY_OP", chan->name);
+ } else if(caccess >= chan_getvoice) {
+ if(!(chanuser->flags & CHANUSERFLAG_VOICED)) {
+ putsock(client, "MODE %s +v %s", chan->name, user->nick);
+ logEvent(event);
+ } else
+ reply(getTextBot(), user, "NS_UP_ALREADY_VOICE", chan->name);
+ } else
+ reply(getTextBot(), user, "NS_NOT_ON_USERLIST_YOU", chan->name);
+}
--- /dev/null
+/* cmd_neonserv_upall.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* no arguments
+*/
+
+CMD_BIND(neonserv_cmd_upall) {
+ MYSQL_RES *res, *default_res;
+ MYSQL_ROW row, default_row;
+ struct ChanUser *chanuser;
+ int userid, chan_getop, chan_getvoice, caccess;
+ int botid = client->botid;
+ printf_mysql_query("SELECT `user_id` FROM `users` WHERE `user_user` = '%s'", user->auth);
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) == NULL)
+ return;
+ userid = atoi(row[0]);
+ printf_mysql_query("SELECT `chanuser_access`, `channel_getop`, `channel_getvoice`, `channel_name`, `channel_id` FROM `chanusers` LEFT JOIN `channels` ON `chanuser_cid` = `channel_id` WHERE `chanuser_uid` = '%d'", userid);
+ res = mysql_use();
+ while ((row = mysql_fetch_row(res)) != NULL) {
+ chan = getChanByName(row[3]);
+ if(!chan) continue;
+ printf_mysql_query("SELECT `botid` FROM `bot_channels` LEFT JOIN `bots` ON `bot_channels`.`botid` = `bots`.`id` WHERE `chanid` = '%s' AND `botclass` = '%d'", row[4], client->botid);
+ if (mysql_fetch_row(mysql_use()) == NULL) continue;
+ if(!(chanuser = getChanUser(user, chan))) continue;
+ if(!row[1] || !row[2]) {
+ printf_mysql_query("SELECT `channel_getop`, `channel_getvoice` FROM `channels` WHERE `channel_name` = 'defaults'");
+ default_res = mysql_use();
+ if ((default_row = mysql_fetch_row(default_res)) == NULL) return;
+ chan_getop = (row[1] ? atoi(row[1]) : atoi(default_row[0]));
+ chan_getvoice = (row[2] ? atoi(row[2]) : atoi(default_row[1]));
+ } else {
+ chan_getop = atoi(row[1]);
+ chan_getvoice = atoi(row[2]);
+ }
+ caccess = atoi(row[0]);
+ int done = 0;
+ client = getChannelBot(chan, botid);
+ if(!client) continue;
+ if(caccess >= chan_getop) {
+ if(!(chanuser->flags & CHANUSERFLAG_OPPED)) {
+ putsock(client, "MODE %s +o %s", chan->name, user->nick);
+ done = 1;
+ }
+ } else if(caccess >= chan_getvoice) {
+ if(!(chanuser->flags & CHANUSERFLAG_VOICED)) {
+ putsock(client, "MODE %s +v %s", chan->name, user->nick);
+ done = 1;
+ }
+ }
+ if(done) {
+ event->chan = chan;
+ logEvent(event);
+ }
+ }
+}
--- /dev/null
+/* cmd_neonserv_users.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* argv[0] - usermask
+* argv[1] - min access
+* argv[2] - max access
+*/
+static USERLIST_CALLBACK(neonserv_cmd_users_userlist_lookup);
+static void neonserv_cmd_users_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, char *usermask, int min_access, int max_access);
+
+struct neonserv_cmd_users_cache {
+ struct ClientSocket *client, *textclient;
+ struct UserNode *user;
+ char *usermask;
+ int min_access;
+ int max_access;
+};
+
+CMD_BIND(neonserv_cmd_users) {
+ int min_access = 1, max_access = 500;
+ char *usermask = NULL;
+ if(argc > 0)
+ usermask = argv[0];
+ if(argc > 2) {
+ min_access = atoi(argv[1]);
+ max_access = atoi(argv[2]);
+ }
+ struct neonserv_cmd_users_cache *cache = malloc(sizeof(*cache));
+ if (!cache) {
+ perror("malloc() failed");
+ return;
+ }
+ cache->client = client;
+ cache->textclient = getTextBot();
+ cache->user = user;
+ cache->usermask = (usermask ? strdup(usermask) : NULL);
+ cache->min_access = min_access;
+ cache->max_access = max_access;
+ get_userlist_with_invisible(chan, neonserv_cmd_users_userlist_lookup, cache);
+}
+
+static USERLIST_CALLBACK(neonserv_cmd_users_userlist_lookup) {
+ struct neonserv_cmd_users_cache *cache = data;
+ neonserv_cmd_users_async1(cache->client, cache->textclient, cache->user, chan, cache->usermask, cache->min_access, cache->max_access);
+ if(cache->usermask)
+ free(cache->usermask);
+ free(cache);
+}
+
+static void neonserv_cmd_users_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, char *usermask, int min_access, int max_access) {
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ int content_count = 0, cflags, is_here, caccess, i;
+ char seenstr[MAXLEN];
+ struct Table *table;
+ struct ChanUser *chanuser;
+ printf_mysql_query("SELECT `chanuser_access`, `user_user`, `chanuser_seen`, `chanuser_flags` FROM `chanusers` LEFT JOIN `users` ON `chanuser_uid` = `user_id` WHERE `chanuser_cid` = '%d' ORDER BY `chanuser_access` DESC, `user_user` ASC", chan->channel_id);
+ res = mysql_use();
+ table = table_init(4, mysql_num_rows(res) + 1, 0);
+ if(usermask)
+ reply(textclient, user, "NS_USERS_HEADER_MATCH", chan->name, min_access, max_access, usermask);
+ else
+ reply(textclient, user, "NS_USERS_HEADER", chan->name, min_access, max_access);
+ char *content[4];
+ content[0] = get_language_string(user, "NS_USERS_HEADER_ACCESS");
+ content[1] = get_language_string(user, "NS_USERS_HEADER_ACCOUNT");
+ content[2] = get_language_string(user, "NS_USERS_HEADER_SEEN");
+ content[3] = get_language_string(user, "NS_USERS_HEADER_STATE");
+ table_add(table, content);
+ while ((row = mysql_fetch_row(res)) != NULL) {
+ caccess = atoi(row[0]);
+ if((!usermask || !match(usermask, row[1])) && caccess >= min_access && caccess <= max_access) {
+ content[0] = row[0];
+ content[1] = row[1];
+ is_here = 0;
+ for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
+ if((chanuser->user->flags & USERFLAG_ISAUTHED) && !stricmp(chanuser->user->auth, row[1])) {
+ if((chanuser->flags & CHANUSERFLAG_INVISIBLE))
+ is_here = 2;
+ else {
+ is_here = 1;
+ break;
+ }
+ }
+ }
+ if(is_here) {
+ content[2] = get_language_string(user, (is_here == 2 ? "NS_USERS_SEEN_INVISIBLE" : "NS_USERS_SEEN_HERE"));
+ } else if(!strcmp(row[2], "0")) {
+ content[2] = get_language_string(user, "NS_USERS_SEEN_NEVER");
+ } else {
+ timeToStr(user, (time(0) - atoi(row[2])), 2, seenstr);
+ content[2] = seenstr; //generate time
+ }
+ cflags = atoi(row[3]);
+ if(cflags & DB_CHANUSER_SUSPENDED)
+ content[3] = get_language_string(user, "NS_USERS_STATE_SUSPENDED");
+ else
+ content[3] = get_language_string(user, "NS_USERS_STATE_NORMAL");
+ content_count++;
+ table_add(table, content);
+ }
+ }
+ //send the table
+ char **table_lines = table_end(table);
+ for(i = 0; i < table->entrys; i++) {
+ reply(textclient, user, table_lines[i]);
+ }
+ if(!content_count)
+ reply(textclient, user, "NS_TABLE_NONE");
+ if(usermask || min_access != 1 || max_access != 500)
+ reply(textclient, user, (table->length == 2 ? "NS_USERS_COUNT_MATCH_1" : "NS_USERS_COUNT_MATCH"), table->length - 1, chan->name, content_count);
+ else
+ reply(textclient, user, (table->length == 2 ? "NS_USERS_COUNT_1" : "NS_USERS_COUNT"), table->length - 1, chan->name);
+ table_free(table);
+}
--- /dev/null
+/* cmd_neonserv_uset.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+CMD_BIND(neonserv_cmd_uset) {
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ loadUserSettings(user);
+ if(argc > 0) {
+ if(!stricmp(argv[0], "language")) {
+ struct language* lang;
+ if(argc > 1) {
+ if((lang = get_language_by_tag(argv[1])) == NULL && (lang = get_language_by_name(argv[1])) == NULL) {
+ lang = user->language;
+ } else {
+ printf_mysql_query("SELECT `user_id` FROM `users` WHERE `user_user` = '%s'", escape_string(user->auth));
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) != NULL) {
+ printf_mysql_query("UPDATE `users` SET `user_lang` = '%s' WHERE `user_id` = '%s'", escape_string(lang->langtag), row[0]);
+ } else {
+ printf_mysql_query("INSERT INTO `users` (`user_user`, `user_lang`) VALUES ('%s', '%s')", escape_string(user->auth), escape_string(lang->langtag));
+ }
+ struct UserNode *cuser;
+ for(cuser = getAllUsers(NULL); cuser; cuser = getAllUsers(cuser)) {
+ if((cuser->flags & USERFLAG_ISAUTHED) && !stricmp(user->auth, cuser->auth))
+ cuser->language = lang;
+ }
+ }
+ } else
+ lang = user->language;
+ reply(getTextBot(), user, "\002Language \002%s", lang->langname);
+ char tmp[MAXLEN];
+ int tmppos = 0;
+ lang = get_default_language();
+ tmppos = sprintf(tmp, "%s (%s)", lang->langname, lang->langtag);
+ printf_mysql_query("SELECT `lang`,`text` FROM `language` WHERE `ident` = 'name'");
+ res = mysql_use();
+ while((row = mysql_fetch_row(res)) != NULL) {
+ tmppos += sprintf(tmp + tmppos, ", %s (%s)", row[1], row[0]);
+ }
+ reply(getTextBot(), user, " %s", tmp);
+ } else if(!stricmp(argv[0], "noinvite") && chan) {
+ loadChannelSettings(chan);
+ if(!(chan->flags & CHANFLAG_CHAN_REGISTERED)) {
+ reply(getTextBot(), user, "MODCMD_CHAN_REQUIRED");
+ return;
+ }
+ 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));
+ res = mysql_use();
+ row = mysql_fetch_row(res);
+ int noinvite = (row ? 1 : 0);
+ if(argc > 1) {
+ if(!strcmp(argv[1], "0") || !stricmp(argv[1], "off") || !stricmp(argv[1], get_language_string(user, "NS_SET_OFF"))) {
+ if(noinvite) {
+ printf_mysql_query("DELETE FROM `noinvite` WHERE `id` = '%s'", row[0]);
+ noinvite = 0;
+ }
+ } else if(!strcmp(argv[1], "1") || !stricmp(argv[1], "on") || !stricmp(argv[1], get_language_string(user, "NS_SET_ON"))) {
+ if(!noinvite) {
+ int userid;
+ printf_mysql_query("SELECT `user_id` FROM `users` WHERE `user_user` = '%s'", escape_string(user->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(user->auth));
+ userid = (int) mysql_insert_id(get_mysql_conn());
+ }
+ printf_mysql_query("INSERT INTO `noinvite` (`uid`, `cid`) VALUES ('%d', '%d')", userid, chan->channel_id);
+ noinvite = 1;
+ }
+ }
+ }
+ reply(getTextBot(), user, "\002NoInvite \002%s", (noinvite ? get_language_string(user, "NS_SET_ON") : get_language_string(user, "NS_SET_OFF")));
+ } else if((!stricmp(argv[0], "autoinvite") || !stricmp(argv[0], "noautoop") || !stricmp(argv[0], "info")) && chan) {
+ loadChannelSettings(chan);
+ if(!(chan->flags & CHANFLAG_CHAN_REGISTERED)) {
+ reply(getTextBot(), user, "MODCMD_CHAN_REQUIRED");
+ return;
+ }
+ 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));
+ res = mysql_use();
+ row = mysql_fetch_row(res);
+ if(row) {
+ int flags = atoi(row[0]);
+ if(!stricmp(argv[0], "autoinvite")) {
+ int getInvite = 0;
+ if(!row[3] && atoi(row[2]) >= atoi(getChanDefault("channel_getinvite")))
+ getInvite = 1;
+ else if(row[3] && atoi(row[2]) >= atoi(row[3]))
+ getInvite = 1;
+ if(getInvite && argc > 1) {
+ if(!strcmp(argv[1], "0") || !stricmp(argv[1], "off") || !stricmp(argv[1], get_language_string(user, "NS_SET_OFF"))) {
+ if(flags & DB_CHANUSER_AUTOINVITE) {
+ flags &= ~DB_CHANUSER_AUTOINVITE;
+ printf_mysql_query("UPDATE `chanusers` SET `chanuser_flags` = '%d' WHERE `chanuser_id` = '%s'", flags, row[4]);
+ }
+ } else if(!strcmp(argv[1], "1") || !stricmp(argv[1], "on") || !stricmp(argv[1], get_language_string(user, "NS_SET_ON"))) {
+ if(!(flags & DB_CHANUSER_AUTOINVITE)) {
+ flags |= DB_CHANUSER_AUTOINVITE;
+ printf_mysql_query("UPDATE `chanusers` SET `chanuser_flags` = '%d' WHERE `chanuser_id` = '%s'", flags, row[4]);
+ }
+ }
+ }
+ if(getInvite)
+ reply(getTextBot(), user, "\002AutoInvite \002%s", ((flags & DB_CHANUSER_AUTOINVITE) ? get_language_string(user, "NS_SET_ON") : get_language_string(user, "NS_SET_OFF")));
+ else
+ reply(getTextBot(), user, "\002AutoInvite \002%s", get_language_string(user, "NS_USET_NO_ACCESS"));
+ } else if(!stricmp(argv[0], "noautoop")) {
+ if(argc > 1) {
+ if(!strcmp(argv[1], "0") || !stricmp(argv[1], "off") || !stricmp(argv[1], get_language_string(user, "NS_SET_OFF"))) {
+ if(flags & DB_CHANUSER_NOAUTOOP) {
+ flags &= ~DB_CHANUSER_NOAUTOOP;
+ printf_mysql_query("UPDATE `chanusers` SET `chanuser_flags` = '%d' WHERE `chanuser_id` = '%s'", flags, row[4]);
+ }
+ } else if(!strcmp(argv[1], "1") || !stricmp(argv[1], "on") || !stricmp(argv[1], get_language_string(user, "NS_SET_ON"))) {
+ if(!(flags & DB_CHANUSER_NOAUTOOP)) {
+ flags |= DB_CHANUSER_NOAUTOOP;
+ printf_mysql_query("UPDATE `chanusers` SET `chanuser_flags` = '%d' WHERE `chanuser_id` = '%s'", flags, row[4]);
+ }
+ }
+ }
+ reply(getTextBot(), user, "\002NoAutoOp \002%s", ((flags & DB_CHANUSER_NOAUTOOP) ? get_language_string(user, "NS_SET_ON") : get_language_string(user, "NS_SET_OFF")));
+ } else if(!stricmp(argv[0], "info")) {
+ char *infoline;
+ if(argc > 1) {
+ infoline = merge_argv(argv, 1, argc);
+ if(!strcmp(infoline, "*"))
+ infoline = "";
+ printf_mysql_query("UPDATE `chanusers` SET `chanuser_infoline` = '%s' WHERE `chanuser_id` = '%s'", escape_string(infoline), row[4]);
+ } else
+ infoline = row[1];
+ reply(getTextBot(), user, "\002Info \002%s", infoline);
+ }
+ } else
+ reply(getTextBot(), user, "NS_NOT_ON_USERLIST_YOU", chan);
+ } else
+ reply(getTextBot(), user, "NS_USET_UNKNOWN_SETTING", argv[0]);
+ } else {
+ //view all options
+ reply(getTextBot(), user, "NS_USET_GLOBAL");
+ reply(getTextBot(), user, "\002Language \002%s", user->language->langname);
+ if(!chan) return;
+ loadChannelSettings(chan);
+ if(!(chan->flags & CHANFLAG_CHAN_REGISTERED)) return;
+ reply(getTextBot(), user, "NS_USET_CHANNEL");
+ 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));
+ res = mysql_use();
+ row = mysql_fetch_row(res);
+ reply(getTextBot(), user, "\002NoInvite \002%s", (row ? get_language_string(user, "NS_SET_ON") : get_language_string(user, "NS_SET_OFF")));
+ printf_mysql_query("SELECT `chanuser_flags`, `chanuser_infoline`, `chanuser_access`, `channel_getinvite` 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));
+ res = mysql_use();
+ row = mysql_fetch_row(res);
+ if(row) {
+ int flags = atoi(row[0]);
+ int getInvite = 0;
+ if(!row[3] && atoi(row[2]) >= atoi(getChanDefault("channel_getinvite")))
+ getInvite = 1;
+ else if(row[3] && atoi(row[2]) >= atoi(row[3]))
+ getInvite = 1;
+ if(getInvite)
+ reply(getTextBot(), user, "\002AutoInvite \002%s", ((flags & DB_CHANUSER_AUTOINVITE) ? get_language_string(user, "NS_SET_ON") : get_language_string(user, "NS_SET_OFF")));
+ else
+ reply(getTextBot(), user, "\002AutoInvite \002%s", get_language_string(user, "NS_USET_NO_ACCESS"));
+ reply(getTextBot(), user, "\002NoAutoOp \002%s", ((flags & DB_CHANUSER_NOAUTOOP) ? get_language_string(user, "NS_SET_ON") : get_language_string(user, "NS_SET_OFF")));
+ reply(getTextBot(), user, "\002Info \002%s", row[1]);
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+/* cmd_neonserv_voice.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* argv[0-*] nicks
+*/
+static USERLIST_CALLBACK(neonserv_cmd_voice_userlist_lookup);
+static void neonserv_cmd_voice_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nicks);
+
+struct neonserv_cmd_voice_cache {
+ struct ClientSocket *client, *textclient;
+ struct UserNode *user;
+ struct Event *event;
+ char *nicks;
+};
+
+CMD_BIND(neonserv_cmd_voice) {
+ struct neonserv_cmd_voice_cache *cache = malloc(sizeof(*cache));
+ if (!cache) {
+ perror("malloc() failed");
+ return;
+ }
+ cache->client = client;
+ cache->textclient = getTextBot();
+ cache->user = user;
+ cache->event = event;
+ cache->nicks = strdup(merge_argv(argv, 0, argc));
+ get_userlist_if_invisible(chan, neonserv_cmd_voice_userlist_lookup, cache);
+}
+
+static USERLIST_CALLBACK(neonserv_cmd_voice_userlist_lookup) {
+ struct neonserv_cmd_voice_cache *cache = data;
+ neonserv_cmd_voice_async1(cache->client, cache->textclient, cache->user, chan, cache->event, cache->nicks);
+ free(cache->nicks);
+ free(cache);
+}
+
+static void neonserv_cmd_voice_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nicks) {
+ int total_users = 0, done_users = 0;
+ struct UserNode *cuser;
+ struct ChanUser *chanuser;
+ struct ModeBuffer *modeBuf;
+ modeBuf = initModeBuffer(client, chan);
+ char *a, *b = nicks;
+ do {
+ a = strstr(b, " ");
+ if(a) *a = '\0';
+ total_users++;
+ cuser = searchUserByNick(b);
+ if(!cuser) {
+ //check for an invisible user
+ for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
+ if(!stricmp(chanuser->user->nick, b)) {
+ cuser = chanuser->user;
+ break;
+ }
+ }
+ if(!cuser) continue;
+ } else {
+ chanuser = getChanUser(cuser, chan);
+ if(!chanuser) continue;
+ }
+ done_users++;
+ if(chanuser->flags & CHANUSERFLAG_VOICED) continue;
+ modeBufferVoice(modeBuf, b);
+ if(a) {
+ b = a+1;
+ }
+ } while(a);
+ freeModeBuffer(modeBuf);
+ if(done_users == total_users)
+ reply(textclient, user, "NS_VOICE_DONE", chan->name);
+ else
+ reply(textclient, user, "NS_VOICE_FAIL", client->user->nick);
+ if(done_users)
+ logEvent(event);
+}
--- /dev/null
+/* cmd_neonserv_voiceall.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* argv[0] (optional) nick mask
+*/
+static USERLIST_CALLBACK(neonserv_cmd_voiceall_userlist_lookup);
+static void neonserv_cmd_voiceall_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nickmask);
+
+struct neonserv_cmd_voiceall_cache {
+ struct ClientSocket *client, *textclient;
+ struct UserNode *user;
+ struct Event *event;
+ char *nickmask;
+};
+
+CMD_BIND(neonserv_cmd_voiceall) {
+ struct neonserv_cmd_voiceall_cache *cache = malloc(sizeof(*cache));
+ if (!cache) {
+ perror("malloc() failed");
+ return;
+ }
+ cache->client = client;
+ cache->textclient = getTextBot();
+ cache->user = user;
+ cache->event = event;
+ if(argc > 0) {
+ cache->nickmask = strdup(argv[0]);
+ } else
+ cache->nickmask = NULL;
+ get_userlist_if_invisible(chan, neonserv_cmd_voiceall_userlist_lookup, cache);
+}
+
+static USERLIST_CALLBACK(neonserv_cmd_voiceall_userlist_lookup) {
+ struct neonserv_cmd_voiceall_cache *cache = data;
+ neonserv_cmd_voiceall_async1(cache->client, cache->textclient, cache->user, chan, cache->event, cache->nickmask);
+ if(cache->nickmask)
+ free(cache->nickmask);
+ free(cache);
+}
+
+static void neonserv_cmd_voiceall_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nickmask) {
+ int done_users = 0;
+ struct ChanUser *chanuser;
+ struct ModeBuffer *modeBuf;
+ modeBuf = initModeBuffer(client, chan);
+ for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
+ if(nickmask && match(nickmask, chanuser->user->nick)) continue;
+ if(chanuser->flags & CHANUSERFLAG_VOICED) continue;
+ modeBufferVoice(modeBuf, chanuser->user->nick);
+ done_users++;
+ }
+ freeModeBuffer(modeBuf);
+ reply(textclient, user, "NS_VOICEALL_DONE", done_users, chan->name);
+ if(done_users)
+ logEvent(event);
+}
--- /dev/null
+/* cmd_neonserv_wipeinfo.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* argv[0] - nick / *auth
+*/
+static USERAUTH_CALLBACK(neonserv_cmd_wipeinfo_nick_lookup);
+static void neonserv_cmd_wipeinfo_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nick, char *auth);
+
+struct neonserv_cmd_wipeinfo_cache {
+ struct ClientSocket *client, *textclient;
+ struct UserNode *user;
+ struct ChanNode *chan;
+ struct Event *event;
+ char *nick;
+};
+
+CMD_BIND(neonserv_cmd_wipeinfo) {
+ if(argv[0][0] == '*') {
+ //we've got an auth
+ argv[0]++;
+ neonserv_cmd_wipeinfo_async1(client, getTextBot(), user, chan, event, argv[0], argv[0]);
+ } else {
+ struct UserNode *cuser = getUserByNick(argv[0]);
+ if(!cuser) {
+ cuser = createTempUser(argv[0]);
+ if(!cuser) {
+ reply(getTextBot(), user, "NS_USER_UNKNOWN", argv[0]);
+ return;
+ }
+ cuser->flags |= USERFLAG_ISTMPUSER;
+ }
+ if(cuser->flags & USERFLAG_ISAUTHED) {
+ neonserv_cmd_wipeinfo_async1(client, getTextBot(), user, chan, event, argv[0], cuser->auth);
+ } else {
+ struct neonserv_cmd_wipeinfo_cache *cache = malloc(sizeof(*cache));
+ if (!cache) {
+ perror("malloc() failed");
+ return;
+ }
+ cache->client = client;
+ cache->textclient = getTextBot();
+ cache->user = user;
+ cache->chan = chan;
+ cache->event = event;
+ cache->nick = strdup(argv[0]);
+ get_userauth(cuser, neonserv_cmd_wipeinfo_nick_lookup, cache);
+ }
+ }
+}
+
+static USERAUTH_CALLBACK(neonserv_cmd_wipeinfo_nick_lookup) {
+ struct neonserv_cmd_wipeinfo_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_wipeinfo_async1(cache->client, cache->textclient, cache->user, cache->chan, cache->event, user->nick, user->auth);
+ free(cache->nick);
+ free(cache);
+}
+
+static void neonserv_cmd_wipeinfo_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nick, char *auth) {
+ //we've got a valid auth now...
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ 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]);
+ //check if the user is already added
+ printf_mysql_query("SELECT `chanuser_access`, `chanuser_id` FROM `chanusers` WHERE `chanuser_cid` = '%d' AND `chanuser_uid` = '%d'", chan->channel_id, userid);
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) != NULL) {
+ if(atoi(row[0]) >= getChannelAccess(user, chan)) {
+ if(isGodMode(user)) {
+ event->flags |= CMDFLAG_OPLOG;
+ } else {
+ reply(textclient, user, "NS_USER_OUTRANKED", nick);
+ return;
+ }
+ }
+ //delete
+ printf_mysql_query("UPDATE `chanusers` SET `chanuser_infoline` = '' WHERE `chanuser_id` = '%s'", row[1]);
+ reply(textclient, user, "NS_WIPEINFO_DONE", nick, chan->name);
+ logEvent(event);
+ return;
+ }
+ }
+ reply(textclient, user, "NS_NOT_ON_USERLIST", nick, chan->name);
+}
--- /dev/null
+/* event_neonserv_ctcp.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+struct neonserv_event_ctcp_cache {
+ struct ClientSocket *client;
+ struct UserNode *user;
+ struct ChanNode *chan;
+ char *command;
+ char *text;
+};
+
+static USERAUTH_CALLBACK(neonserv_event_ctcp_nick_lookup);
+static void neonserv_event_ctcp_async1(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, char *command, char *text);
+
+static void neonserv_event_chanctcp(struct UserNode *user, struct ChanNode *chan, char *command, char *text) {
+ if(!stricmp(command, "ACTION")) return; //always allow CTCP ACTION (/me)
+ struct ClientSocket *client = getBotForChannel(chan);
+ if(!client) return; //we can't "see" this event
+ if(isNetworkService(user)) return;
+ loadChannelSettings(chan);
+ if(!(chan->flags & CHANFLAG_CHAN_REGISTERED)) return;
+ if(!(user->flags & USERFLAG_ISAUTHED)) {
+ struct neonserv_event_ctcp_cache *cache = malloc(sizeof(*cache));
+ if (!cache) {
+ perror("malloc() failed");
+ return;
+ }
+ cache->client = client;
+ cache->user = user;
+ cache->chan = chan;
+ cache->command = strdup(command);
+ cache->text = (text ? strdup(text) : NULL);
+ get_userauth(user, neonserv_event_ctcp_nick_lookup, cache);
+ } else
+ neonserv_event_ctcp_async1(client, user, chan, command, text);
+}
+
+static USERAUTH_CALLBACK(neonserv_event_ctcp_nick_lookup) {
+ struct neonserv_event_ctcp_cache *cache = data;
+ if(user) {
+ neonserv_event_ctcp_async1(cache->client, cache->user, cache->chan, cache->command, cache->text);
+ }
+ free(cache->command);
+ if(cache->text)
+ free(cache->text);
+ free(cache);
+}
+
+static void neonserv_event_ctcp_async1(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, char *command, char *text) {
+ MYSQL_RES *res;
+ MYSQL_ROW row, defaultrow = NULL, chanuser;
+ int uaccess = 0;
+ printf_mysql_query("SELECT `channel_ctcp`, `channel_ctcpreaction` FROM `channels` WHERE `channel_id` = '%d'", chan->channel_id);
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) == NULL) return;
+ if(!row[0] || !row[1]) {
+ printf_mysql_query("SELECT `channel_ctcp`, `channel_ctcpreaction` FROM `channels` WHERE `channel_name` = 'defaults'");
+ res = mysql_use();
+ defaultrow = mysql_fetch_row(res);
+ }
+ int ctcpaccess = atoi((row[0] ? row[0] : defaultrow[0]));
+ if((user->flags & USERFLAG_ISAUTHED)) {
+ printf_mysql_query("SELECT `chanuser_access`, `chanuser_flags` FROM `chanusers` LEFT JOIN `users` ON `chanuser_uid` = `user_id` WHERE `chanuser_cid` = '%d' AND `user_user` = '%s'", chan->channel_id, escape_string(user->auth));
+ res = mysql_use();
+ chanuser = mysql_fetch_row(res);
+ if(chanuser)
+ uaccess = ((atoi(chanuser[1]) & DB_CHANUSER_SUSPENDED) ? 0 : atoi(chanuser[0]));
+ }
+ int duration = 0;
+ char banmaskBuf[NICKLEN+USERLEN+HOSTLEN+3];
+ char *banmask = NULL;
+ char *reason = "disallowed channel CTCP";
+ if(uaccess < ctcpaccess) {
+ switch(atoi((row[1] ? row[1] : defaultrow[1]))) {
+ case 2: //TIMEBAN: 3min
+ duration = 180;
+ case 3: //TIMEBAN: 1h
+ if(!duration)
+ duration = 3600;
+ banmask = generate_banmask(user, banmaskBuf);
+ printf_mysql_query("INSERT INTO `bans` (`ban_channel`, `ban_mask`, `ban_triggered`, `ban_timeout`, `ban_owner`, `ban_reason`) VALUES ('%d', '%s', UNIX_TIMESTAMP(), '%lu', '%d', '%s')", chan->channel_id, escape_string(banmask), (unsigned long) (time(0) + duration), 0, escape_string(reason));
+ int banid = (int) mysql_insert_id(get_mysql_conn());
+ char nameBuf[MAXLEN];
+ char banidBuf[20];
+ sprintf(nameBuf, "ban_%d", banid);
+ sprintf(banidBuf, "%d", banid);
+ timeq_add_name(nameBuf, duration, channel_ban_timeout, strdup(banidBuf));
+ case 1: //KICKBAN
+ if(!banmask)
+ banmask = generate_banmask(user, banmaskBuf);
+ putsock(client, "MODE %s +b %s", chan->name, banmask);
+ case 0: //KICK
+ putsock(client, "KICK %s %s :%s", chan->name, user->nick, reason);
+ break;
+ }
+ }
+}
+
--- /dev/null
+/* event_neonserv_invite.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+static void neonserv_event_invite(struct ClientSocket *client, struct UserNode *user, char *channel) {
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ printf_mysql_query("SELECT `botid`, `bot_channels`.`id`, `suspended` FROM `bot_channels` LEFT JOIN `bots` ON `bot_channels`.`botid` = `bots`.`id` LEFT JOIN `channels` ON `chanid` = `channel_id` WHERE `channel_name` = '%s' AND `botclass` = '%d'", escape_string(channel), client->botid);
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) == NULL) {
+ reply(client, user, "NS_INVITE_FAIL", channel, client->user->nick);
+ return;
+ }
+ if(!strcmp(row[2], "1")) {
+ reply(client, user, "MODCMD_CHAN_SUSPENDED");
+ return;
+ }
+ int botid = atoi(row[0]);
+ struct ClientSocket *bot;
+ for(bot = getBots(SOCKET_FLAG_READY, NULL); bot; bot = getBots(SOCKET_FLAG_READY, bot)) {
+ if(bot->clientid == botid)
+ break;
+ }
+ if(bot) {
+ struct ChanNode *chan = getChanByName(channel);
+ if(chan && isUserOnChan(bot->user, chan)) {
+ reply(client, user, "NS_INVITE_ON_CHAN", bot->user->nick, chan->name);
+ } else
+ putsock(bot, "JOIN %s", channel);
+ }
+}
+
--- /dev/null
+/* event_neonserv_join.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+struct neonserv_event_join_cache {
+ struct ClientSocket *client;
+ struct ChanUser *chanuser;
+ int was_registering;
+};
+
+static USERAUTH_CALLBACK(neonserv_event_join_nick_lookup);
+static void neonserv_event_join_async1(struct ClientSocket *client, struct ChanUser *chanuser, int was_registering);
+static TIMEQ_CALLBACK(neonserv_event_join_dynlimit);
+
+static void neonserv_event_join(struct ChanUser *chanuser) {
+ struct UserNode *user = chanuser->user;
+ struct ClientSocket *client = getBotForChannel(chanuser->chan);
+ if(!client) return; //we can't "see" this event
+ if(chanuser->user == client->user) {
+ requestOp(client->user, chanuser->chan);
+ return;
+ }
+ if(chanuser->user->flags & USERFLAG_ISBOT) return;
+ loadChannelSettings(chanuser->chan);
+ if(!(chanuser->chan->flags & CHANFLAG_CHAN_REGISTERED)) return;
+ char *ban;
+ char usermask[NICKLEN+USERLEN+HOSTLEN+3];
+ sprintf(usermask, "%s!%s@%s", user->nick, user->ident, user->host);
+ if((ban = getBanAffectingMask(chanuser->chan, usermask)) != NULL && !(user->flags & (USERFLAG_ISBOT | USERFLAG_ISIRCOP))) {
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ printf_mysql_query("SELECT `ban_reason`, `user_user` FROM `bans` LEFT JOIN `users` ON `ban_owner` = `user_id` WHERE `ban_channel` = '%d' AND `ban_mask` = '%s'", chanuser->chan->channel_id, escape_string(ban));
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) != NULL) {
+ putsock(client, "MODE %s +b %s", chanuser->chan->name, ban);
+ putsock(client, "KICK %s %s :(%s) %s", chanuser->chan->name, chanuser->user->nick, (row[1] ? row[1] : client->user->nick), row[0]);
+ return;
+ }
+ }
+ if(!(user->flags & USERFLAG_ISAUTHED)) {
+ struct neonserv_event_join_cache *cache = malloc(sizeof(*cache));
+ if (!cache) {
+ perror("malloc() failed");
+ return;
+ }
+ cache->client = client;
+ cache->chanuser = chanuser;
+ cache->was_registering = (user->flags & USERFLAG_WAS_REGISTRING);
+ get_userauth(user, neonserv_event_join_nick_lookup, cache);
+ } else
+ neonserv_event_join_async1(client, chanuser, (user->flags & USERFLAG_WAS_REGISTRING));
+}
+
+static USERAUTH_CALLBACK(neonserv_event_join_nick_lookup) {
+ struct neonserv_event_join_cache *cache = data;
+ if(user) {
+ neonserv_event_join_async1(cache->client, cache->chanuser, cache->was_registering);
+ }
+ free(cache);
+}
+
+static void neonserv_event_join_async1(struct ClientSocket *client, struct ChanUser *chanuser, int was_registering) {
+ struct ClientSocket *textclient = ((client->flags & SOCKET_FLAG_PREFERRED) ? client : get_prefered_bot(client->botid));
+ struct ChanNode *chan = chanuser->chan;
+ struct UserNode *user = chanuser->user;
+ struct ModeBuffer *modeBuf;
+ int with_halfops = get_int_field("General.have_halfop");
+ MYSQL_RES *res;
+ MYSQL_ROW row, chanuserrow, defaultrow = NULL;
+ printf_mysql_query("SELECT `channel_maxusers`, `channel_greeting`, `channel_usergreeting`, `channel_getop`, `channel_getvoice`, `channel_userinfo`, `channel_dynlimit`, `channel_gethalfop` FROM `channels` WHERE `channel_id` = '%d'", chan->channel_id);
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) == NULL) return;
+ if(!row[3] || !row[4] || !row[5] || (!row[7] && with_halfops)) {
+ printf_mysql_query("SELECT `channel_getop`, `channel_getvoice`, `channel_userinfo`, `channel_gethalfop` FROM `channels` WHERE `channel_name` = 'defaults'");
+ res = mysql_use();
+ defaultrow = mysql_fetch_row(res);
+ }
+ if(chan->usercount > atoi(row[0])) {
+ //update maxusers
+ printf_mysql_query("UPDATE `channels` SET `channel_maxusers` = '%d' WHERE `channel_id` = '%d'", chan->usercount, chan->channel_id);
+ }
+ if((user->flags & USERFLAG_ISAUTHED)) {
+ printf_mysql_query("SELECT `chanuser_access`, `chanuser_flags`, `chanuser_infoline`, `chanuser_seen`, `chanuser_id` FROM `chanusers` LEFT JOIN `users` ON `chanuser_uid` = `user_id` WHERE `chanuser_cid` = '%d' AND `user_user` = '%s'", chan->channel_id, escape_string(user->auth));
+ res = mysql_use();
+ chanuserrow = mysql_fetch_row(res);
+ } else
+ chanuserrow = NULL;
+ if(!chanuserrow)
+ printf_mysql_query("UPDATE `channels` SET `channel_lastvisit` = UNIX_TIMESTAMP() WHERE `channel_id` = '%d'", chan->channel_id);
+ int userflags = (chanuserrow ? atoi(chanuserrow[1]) : 0);
+ int uaccess = ((chanuserrow && !(userflags & DB_CHANUSER_SUSPENDED)) ? atoi(chanuserrow[0]) : 0);
+ //GREETING
+ char greeting[MAXLEN];
+ int greetingPos = 0;
+ char *a, *b = (chanuserrow && *row[2] ? row[2] : row[1]);
+ do {
+ if(!b) break;
+ a = strstr(b, "$");
+ if(a) *a = '\0';
+ greetingPos += sprintf(greeting + greetingPos, "%s", b);
+ if(!a) break;
+ switch(a[1]) {
+ case '\0':
+ a = NULL;
+ break;
+ case 'A':
+ greetingPos += sprintf(greeting + greetingPos, "%d", uaccess);
+ break;
+ case 'B':
+ greetingPos += sprintf(greeting + greetingPos, "%s", client->user->nick);
+ break;
+ case 'N':
+ greetingPos += sprintf(greeting + greetingPos, "%s", user->nick);
+ break;
+ case 'H':
+ greetingPos += sprintf(greeting + greetingPos, "%s@%s", user->ident, user->host);
+ break;
+ case 'U':
+ greetingPos += sprintf(greeting + greetingPos, "%s", ((user->flags & USERFLAG_ISAUTHED) ? user->auth : "*"));
+ break;
+ default:
+ greeting[greetingPos++] = '$';
+ greeting[greetingPos++] = a[1];
+ break;
+ }
+ if(a)
+ b = a+2;
+ } while(a);
+ if(greetingPos && (!was_registering || *row[2]))
+ reply(textclient, user, "[%s] %s", chan->name, greeting);
+ //USER RIGHTS
+ if(!(userflags & DB_CHANUSER_NOAUTOOP)) {
+ int getop = atoi((row[3] ? row[3] : defaultrow[0]));
+ int gethalfop = (with_halfops ? atoi((row[7] ? row[7] : defaultrow[3])) : 0);
+ int getvoice = atoi((row[4] ? row[4] : defaultrow[1]));
+ modeBuf = initModeBuffer(client, chan);
+ if(uaccess >= getop && uaccess != 0) { //we disallow auto op for all users
+ modeBufferOp(modeBuf, user->nick);
+ } else if(with_halfops && uaccess >= gethalfop) {
+ modeBufferHalfop(modeBuf, user->nick);
+ } else if(uaccess >= getvoice) {
+ modeBufferVoice(modeBuf, user->nick);
+ }
+ freeModeBuffer(modeBuf);
+ }
+ //INFOLINE
+ int userinfoaccess = atoi((row[5] ? row[5] : defaultrow[2]));
+ if(chanuserrow && strcmp(chanuserrow[2], "") && uaccess > userinfoaccess) {
+ if(!strcmp(chanuserrow[3], "0") || time(0) - atol(chanuserrow[3]) >= 30) {
+ putsock(client, "PRIVMSG %s :[%s] %s", chan->name, user->nick, chanuserrow[2]);
+ }
+ }
+ //SEEN
+ if(chanuserrow) {
+ printf_mysql_query("UPDATE `chanusers` SET `chanuser_seen` = UNIX_TIMESTAMP() WHERE `chanuser_id` = '%s'", chanuserrow[4]);
+ }
+ //DYNLIMIT
+ if(row[6] && strcmp(row[6], "0")) {
+ char nameBuf[CHANNELLEN + 10];
+ sprintf(nameBuf, "dynlimit_%s", chan->name);
+ if(!timeq_name_exists(nameBuf)) {
+ //neonserv_event_join_dynlimit
+ timeq_add_name(nameBuf, 30, neonserv_event_join_dynlimit, strdup(chan->name));
+ }
+ }
+ //AUTOINVITE
+ if((user->flags & USERFLAG_ISAUTHED) && (!chanuserrow || !strcmp(chanuserrow[3], "0") || time(0) - atol(chanuserrow[3]) >= 30)) {
+ //check if it's the first channel, the user is seen by the bot (IMPORTANT: ignore other bot's channel!)
+ char first_chan = 1;
+ char bot_in_chan;
+ struct ChanUser *cchanuser, *bchanuser;
+ struct ClientSocket *bot;
+ for(cchanuser = getUserChannels(user, NULL); cchanuser; cchanuser = getUserChannels(user, cchanuser)) {
+ if(chanuser == cchanuser) continue; //ignore this one ;)
+ //check if this bot is in the specific channel
+ bot_in_chan = 0;
+ for(bchanuser = getChannelUsers(cchanuser->chan, NULL); bchanuser; bchanuser = getChannelUsers(cchanuser->chan, bchanuser)) {
+ if(bchanuser->user->flags & USERFLAG_ISBOT) {
+ //get the botid
+ for(bot = getBots(SOCKET_FLAG_READY, NULL); bot; bot = getBots(SOCKET_FLAG_READY, bot)) {
+ if(bot->user == bchanuser->user) {
+ if(bot->botid == client->botid)
+ bot_in_chan = 1;
+ break;
+ }
+ }
+ if(bot_in_chan) break;
+ }
+ }
+ if(!bot_in_chan) continue;
+ first_chan = 0;
+ break;
+ }
+ if(first_chan) {
+ //autoinvite :)
+ defaultrow = NULL;
+ printf_mysql_query("SELECT `chanuser_access`, `chanuser_flags`, `channel_name`, `channel_getinvite` FROM `chanusers` LEFT JOIN `channels` ON `chanuser_cid` = `channel_id` LEFT JOIN `users` ON `chanuser_uid` = `user_id` WHERE `user_user` = '%s' AND `chanuser_flags` >= '%d'", escape_string(user->auth), DB_CHANUSER_AUTOINVITE);
+ res = mysql_use();
+ int getinvite;
+ while((chanuserrow = mysql_fetch_row(res)) != NULL) {
+ userflags = atoi(chanuserrow[1]);
+ if(!(userflags & DB_CHANUSER_AUTOINVITE)) continue;
+ if(!(chan = getChanByName(chanuserrow[2]))) continue; //no bot is in the channel
+ if((bchanuser = getChanUser(client->user, chan)) && (bchanuser->flags & CHANUSERFLAG_OPPED))
+ bot = client;
+ else {
+ bot = getBotForChannel(chan);
+ }
+ if(chanuserrow[3] == NULL && defaultrow == NULL) {
+ printf_mysql_query("SELECT `channel_getinvite` FROM `channels` WHERE `channel_name` = 'defaults'");
+ res = mysql_use();
+ defaultrow = mysql_fetch_row(res);
+ }
+ getinvite = atoi((chanuserrow[3] ? chanuserrow[3] : defaultrow[0]));
+ if(atoi(chanuserrow[0]) >= getinvite) {
+ putsock(bot, "INVITE %s %s", user->nick, chan->name);
+ }
+ }
+ }
+ }
+}
+
+static TIMEQ_CALLBACK(neonserv_event_join_dynlimit) {
+ char *chanName = data;
+ struct ChanNode *chan = getChanByName(chanName);
+ free(chanName);
+ struct ClientSocket *client = getBotForChannel(chan);
+ if(!client) return;
+ loadChannelSettings(chan);
+ if(!(chan->flags & CHANFLAG_CHAN_REGISTERED)) return;
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ printf_mysql_query("SELECT `channel_dynlimit` FROM `channels` WHERE `channel_id` = '%d'", chan->channel_id);
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) == NULL) return;
+ if(row[0] && strcmp(row[0], "0")) {
+ putsock(client, "MODE %s +l %d", chan->name, chan->usercount + atoi(row[0]));
+ }
+}
--- /dev/null
+/* event_neonserv_kick.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+struct neonserv_event_kick_cache {
+ struct ClientSocket *client;
+ struct UserNode *user;
+ struct UserNode *target;
+ struct ChanNode *chan;
+ int userauth_pending;
+};
+
+static USERAUTH_CALLBACK(neonserv_event_kick_nick_lookup);
+static void neonserv_event_kick_async1(struct neonserv_event_kick_cache *cache);
+static void neonserv_event_kick_async2(struct ClientSocket *client, struct UserNode *user, struct UserNode *target, struct ChanNode *chan);
+
+static void neonserv_event_kick(struct UserNode *user, struct ChanUser *target, char *reason) {
+ struct ChanNode *chan = target->chan;
+ struct ClientSocket *client;
+ if(isBot(target->user)) {
+ client = getChannelBot(chan, 0);
+ struct ClientSocket *bot = client;
+ for(client = getBots(SOCKET_FLAG_READY, NULL); client; client = getBots(SOCKET_FLAG_READY, client)) {
+ if(client->user == target->user) {
+ break;
+ }
+ }
+ if(!client) return;
+ if(bot && bot != client && (isModeSet(chan->modes, 'i') || isModeSet(chan->modes, 'a') || isModeSet(chan->modes, 'l'))) {
+ struct ChanUser *chanuser = getChanUser(bot->user, chan);
+ if(chanuser && chanuser->flags & CHANUSERFLAG_OPPED)
+ putsock(bot, "INVITE %s %s", target->user->nick, chan->name);
+ }
+ char *key = "";
+ if(isModeSet(chan->modes, 'k')) {
+ key = getModeValue(chan->modes, 'k');
+ }
+ putsock(client, "JOIN %s %s", chan->name, key);
+ return;
+ }
+ client = getBotForChannel(chan);
+ if(!client) return; //we can't "see" this event
+ if(isNetworkService(user)) return;
+ loadChannelSettings(chan);
+ if(!(chan->flags & CHANFLAG_CHAN_REGISTERED)) return;
+ struct neonserv_event_kick_cache *cache = malloc(sizeof(*cache));
+ if (!cache) {
+ perror("malloc() failed");
+ return;
+ }
+ cache->client = client;
+ cache->user = user;
+ cache->target = target->user;
+ cache->chan = target->chan;
+ cache->userauth_pending = 0;
+ if(!(user->flags & USERFLAG_ISAUTHED)) {
+ get_userauth(user, neonserv_event_kick_nick_lookup, cache);
+ cache->userauth_pending++;
+ }
+ if(!(target->user->flags & USERFLAG_ISAUTHED)) {
+ get_userauth(target->user, neonserv_event_kick_nick_lookup, cache);
+ cache->userauth_pending++;
+ }
+ neonserv_event_kick_async1(cache);
+}
+
+static USERAUTH_CALLBACK(neonserv_event_kick_nick_lookup) {
+ struct neonserv_event_kick_cache *cache = data;
+ cache->userauth_pending--;
+ neonserv_event_kick_async1(cache);
+}
+
+static void neonserv_event_kick_async1(struct neonserv_event_kick_cache *cache) {
+ if(cache->userauth_pending == 0) {
+ neonserv_event_kick_async2(cache->client, cache->user, cache->target, cache->chan);
+ free(cache);
+ }
+}
+
+static void neonserv_event_kick_async2(struct ClientSocket *client, struct UserNode *user, struct UserNode *target, struct ChanNode *chan) {
+ if(isUserProtected(chan, target, user)) {
+ char buf[MAXLEN];
+ putsock(client, "KICK %s %s :%s", chan->name, user->nick, build_language_string(user, buf, "NS_USER_PROTECTED", target->nick));
+ putsock(client, "INVITE %s %s", target->nick, chan->name);
+ }
+}
--- /dev/null
+/* event_neonserv_mode.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+static USERLIST_CALLBACK(neonserv_event_mode_userlist_lookup);
+static void neonserv_event_mode_async1(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, char *modes, char **argv, int argc);
+static int neonserv_cmd_mode_botwar_detect(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, int *botwar_detect_executed);
+
+struct neonserv_event_mode_cache {
+ struct ClientSocket *client;
+ struct UserNode *user;
+ char *modes;
+ char **argv;
+ int argc;
+};
+
+static void neonserv_event_mode(struct UserNode *user, struct ChanNode *chan, char *modes, char **argv, int argc) {
+ struct ClientSocket *client = getBotForChannel(chan);
+ if(!client) return; //we can't "see" this event
+ if(isNetworkService(user)) return;
+ loadChannelSettings(chan);
+ if(!(chan->flags & CHANFLAG_CHAN_REGISTERED)) return;
+ struct neonserv_event_mode_cache *cache = malloc(sizeof(*cache));
+ char **temp_argv = NULL;
+ if(argc)
+ temp_argv = malloc(argc*sizeof(*temp_argv));
+ if (!cache || (argc && !temp_argv)) {
+ perror("malloc() failed");
+ return;
+ }
+ if(argc) {
+ int i;
+ for(i = 0; i < argc; i++) {
+ temp_argv[i] = strdup(argv[i]);
+ }
+ }
+ cache->client = client;
+ cache->user = user;
+ cache->modes = strdup(modes);
+ cache->argv = temp_argv;
+ cache->argc = argc;
+ get_userlist_with_invisible(chan, neonserv_event_mode_userlist_lookup, cache);
+}
+
+static USERLIST_CALLBACK(neonserv_event_mode_userlist_lookup) {
+ struct neonserv_event_mode_cache *cache = data;
+ neonserv_event_mode_async1(cache->client, cache->user, chan, cache->modes, cache->argv, cache->argc);
+ if(cache->argc) {
+ int i;
+ for(i = 0; i < cache->argc; i++) {
+ free(cache->argv[i]);
+ }
+ free(cache->argv);
+ }
+ free(cache->modes);
+ free(cache);
+}
+
+static void neonserv_event_mode_async1(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, char *modes, char **argv, int argc) {
+ struct ClientSocket *textclient = ((client->flags & SOCKET_FLAG_PREFERRED) ? client : get_prefered_bot(client->botid));
+ int botwar_detect_executed = 0;
+ MYSQL_ROW row, defaults = NULL;
+ int i, arg, add = 1, skip = 0;
+ unsigned int modetype;
+ int db_canop, db_canhalfop, db_canvoice, db_canban, db_enfmodes, db_getop, db_gethalfop, db_getvoice;
+ struct ModeNode *modelock = createModeNode(NULL);
+ struct ModeBuffer *modeBuf;
+ struct UserNode *cuser;
+ struct ChanUser *chanuser;
+ int with_halfops = get_int_field("General.have_halfop");
+ modeBuf = initModeBuffer(client, chan);
+ printf_mysql_query("SELECT `channel_canop`, `channel_canvoice`, `channel_canban`, `channel_enfmodes`, `channel_modes`, `channel_getop`, `channel_getvoice`, `channel_gethalfop`, `channel_canhalfop` FROM `channels` WHERE `channel_id` = '%d'", chan->channel_id);
+ row = mysql_fetch_row(mysql_use());
+ if(row[0] == NULL || row[1] == NULL || row[2] == NULL || row[3] == NULL || row[4] == NULL || row[5] == NULL || row[6] == NULL || (row[7] == NULL && with_halfops) || (row[8] == NULL && with_halfops)) {
+ printf_mysql_query("SELECT `channel_canop`, `channel_canvoice`, `channel_canban`, `channel_enfmodes`, `channel_modes`, `channel_getop`, `channel_getvoice`, `channel_gethalfop`, `channel_canhalfop` FROM `channels` WHERE `channel_name` = 'defaults'");
+ defaults = mysql_fetch_row(mysql_use());
+ }
+ db_canop = atoi((row[0] ? row[0] : defaults[0]));
+ db_canvoice = atoi((row[1] ? row[1] : defaults[1]));
+ db_canban = atoi((row[2] ? row[2] : defaults[2]));
+ db_enfmodes = atoi((row[3] ? row[3] : defaults[3]));
+ db_getop = atoi((row[5] ? row[5] : defaults[5]));
+ db_getvoice = atoi((row[6] ? row[6] : defaults[6]));
+ db_gethalfop = (with_halfops ? atoi((row[7] ? row[7] : defaults[7])) : 0);
+ db_canhalfop = (with_halfops ? atoi((row[8] ? row[8] : defaults[8])) : 0);
+ if(row[4])
+ parseModeString(modelock, row[4]);
+ else if(defaults[4])
+ parseModeString(modelock, defaults[4]);
+ int uaccess = getChannelAccess(user, chan);
+ int caccess;
+ char *carg;
+ int sent_modes_locked = 0;
+ char deop_user = 0;
+ char tmp[MAXLEN];
+ arg = 0;
+ for(i = 0; i < strlen(modes); i++) {
+ switch(modes[i]) {
+ case '+':
+ add = 1;
+ break;
+ case '-':
+ add = 0;
+ break;
+ case 'o':
+ case 'h':
+ case 'v':
+ if(arg == argc) {
+ break;
+ }
+ carg = argv[arg++];
+ cuser = searchUserByNick(carg);
+ if(!cuser) {
+ break; //internal Bot error - this should never happen
+ }
+ caccess = getChannelAccess(cuser, chan);
+ if(modes[i] == 'o' && !add && cuser == client->user) {
+ //someone deopped the bot???
+ if(!neonserv_cmd_mode_botwar_detect(client, user, chan, &botwar_detect_executed))
+ requestOp(client->user, chan);
+ }
+ if((modes[i] == 'o' || (modes[i] == 'h' && !with_halfops)) && !(add && isBot(cuser))) {
+ if(uaccess < db_canop) {
+ reply(textclient, user, "NS_MODE_ENFOPS", chan->name);
+ db_canop = -1;
+ if(uaccess < db_getop)
+ deop_user = 1;
+ }
+ if(db_canop == -1 && caccess < db_getop) {
+ if(!neonserv_cmd_mode_botwar_detect(client, user, chan, &botwar_detect_executed))
+ modeBufferSet(modeBuf, !add, modes[i], carg);
+ break;
+ }
+ } else if(modes[i] == 'h' && with_halfops && !(add && isBot(cuser))) {
+ if(uaccess < db_canhalfop) {
+ reply(textclient, user, "NS_MODE_ENFOPS", chan->name);
+ db_canhalfop = -1;
+ if(uaccess < db_gethalfop)
+ deop_user = 1;
+ }
+ if(db_canhalfop == -1 && caccess < db_gethalfop) {
+ if(!neonserv_cmd_mode_botwar_detect(client, user, chan, &botwar_detect_executed))
+ modeBufferSet(modeBuf, !add, modes[i], carg);
+ break;
+ }
+ } else if(modes[i] == 'v' && !(add && isBot(cuser))) {
+ if(uaccess < db_canvoice) {
+ reply(textclient, user, "NS_MODE_ENFVOICE", chan->name);
+ db_canvoice = -1;
+ if(uaccess < db_getop)
+ deop_user = 1;
+ }
+ if(db_canvoice == -1 && caccess < db_getvoice) {
+ if(!neonserv_cmd_mode_botwar_detect(client, user, chan, &botwar_detect_executed))
+ modeBufferSet(modeBuf, !add, modes[i], carg);
+ break;
+ }
+ }
+ if(!add) {
+ //check protection
+ if(isBot(cuser)) {
+ //don't send this - just try to reop
+ //reply(textclient, user, "NS_SERVICE_IMMUNE", cuser->nick);
+ if(!neonserv_cmd_mode_botwar_detect(client, user, chan, &botwar_detect_executed))
+ modeBufferSet(modeBuf, !add, modes[i], carg);
+ break;
+ }
+ if(isUserProtected(chan, cuser, user)) {
+ reply(textclient, user, "NS_USER_PROTECTED", cuser->nick);
+ if(!neonserv_cmd_mode_botwar_detect(client, user, chan, &botwar_detect_executed))
+ modeBufferSet(modeBuf, !add, modes[i], carg);
+ if(uaccess < db_getop)
+ deop_user = 1;
+ break;
+ }
+ }
+ break;
+ case 'b':
+ if(arg == argc) {
+ break;
+ }
+ carg = argv[arg++];
+ if(uaccess < db_canban) {
+ reply(textclient, user, "NS_MODE_CANBAN", chan->name);
+ db_canban = -1;
+ }
+ if(db_canban == -1) {
+ if(!neonserv_cmd_mode_botwar_detect(client, user, chan, &botwar_detect_executed))
+ modeBufferSet(modeBuf, !add, modes[i], carg);
+ if(uaccess < db_getop)
+ deop_user = 1;
+ break;
+ }
+ char hostmask_buffer[NICKLEN+USERLEN+HOSTLEN+3];
+ char usermask[NICKLEN+USERLEN+HOSTLEN+3];
+ int match_count = 0;
+ carg = make_banmask(carg, hostmask_buffer);
+ if(add) {
+ for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
+ cuser = chanuser->user;
+ sprintf(usermask, "%s!%s@%s", cuser->nick, cuser->ident, cuser->host);
+ if(!match(carg, usermask)) {
+ if(isUserProtected(chan, cuser, user)) {
+ reply(textclient, user, "NS_USER_PROTECTED", cuser->nick);
+ skip = 1;
+ break;
+ }
+ match_count++;
+ }
+ }
+ if(match_count > 4 && (match_count * 3) > chan->usercount) {
+ reply(textclient, user, "NS_LAME_MASK_WARNING", carg, match_count);
+ }
+ }
+ if(skip) {
+ if(!neonserv_cmd_mode_botwar_detect(client, user, chan, &botwar_detect_executed))
+ modeBufferSet(modeBuf, !add, modes[i], carg);
+ if(uaccess < db_getop)
+ deop_user = 1;
+ }
+ break;
+ default:
+ modetype = getModeType(modelock, modes[i]);
+ if(modetype == 0) {
+ break; //unknown mode
+ }
+
+ if(add && (modetype & CHANNEL_MODE_TYPE) != CHANNEL_MODE_TYPE_D) {
+ if(arg == argc) {
+ break;
+ }
+ carg = argv[arg++];
+ if((modetype & CHANNEL_MODE_VALUE) == CHANNEL_MODE_VALUE_STRING && isModeSet(modelock, modes[i])) {
+ char *modelock_val = getModeValue(modelock, modes[i]);
+ if(stricmp(carg, modelock_val) && uaccess < db_enfmodes && !isGodMode(user)) {
+ if(!sent_modes_locked) {
+ getFullModeString(modelock, tmp);
+ reply(textclient, user, "NS_MODE_LOCKED", tmp, chan->name);
+ sent_modes_locked = 1;
+ if(uaccess < db_getop)
+ deop_user = 1;
+ }
+ if(!neonserv_cmd_mode_botwar_detect(client, user, chan, &botwar_detect_executed))
+ modeBufferSet(modeBuf, add, modes[i], modelock_val);
+ break;
+ }
+ }
+ if((modetype & CHANNEL_MODE_VALUE) == CHANNEL_MODE_VALUE_STRING && isModeSet(modelock, modes[i])) {
+ int *modelock_val = getModeValue(modelock, modes[i]);
+ if(atoi(carg) != *modelock_val && uaccess < db_enfmodes && !isGodMode(user)) {
+ if(!sent_modes_locked) {
+ getFullModeString(modelock, tmp);
+ reply(textclient, user, "NS_MODE_LOCKED", tmp, chan->name);
+ sent_modes_locked = 1;
+ if(uaccess < db_getop)
+ deop_user = 1;
+ }
+ sprintf(tmp, "%d", *modelock_val);
+ if(!neonserv_cmd_mode_botwar_detect(client, user, chan, &botwar_detect_executed))
+ modeBufferSet(modeBuf, add, modes[i], tmp);
+ break;
+ }
+ }
+ } else if(!add && (modetype & CHANNEL_MODE_TYPE) == CHANNEL_MODE_TYPE_B) {
+ if(arg == argc) {
+ break;
+ }
+ carg = argv[arg++];
+ } else
+ carg = NULL;
+ if(isModeAffected(modelock, modes[i]) && add == !isModeSet(modelock, modes[i]) && uaccess < db_enfmodes && !isGodMode(user)) {
+ if(!sent_modes_locked) {
+ getFullModeString(modelock, tmp);
+ reply(textclient, user, "NS_MODE_LOCKED", tmp, chan->name);
+ sent_modes_locked = 1;
+ if(uaccess < db_getop)
+ deop_user = 1;
+ }
+ if(!neonserv_cmd_mode_botwar_detect(client, user, chan, &botwar_detect_executed))
+ modeBufferSet(modeBuf, !add, modes[i], carg);
+ break;
+ }
+ break;
+ }
+ }
+ if(deop_user && !neonserv_cmd_mode_botwar_detect(client, user, chan, &botwar_detect_executed)) {
+ modeBufferDeop(modeBuf, user->nick);
+ }
+ freeModeBuffer(modeBuf);
+ freeModeNode(modelock);
+}
+
+static int neonserv_cmd_mode_botwar_detect(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, int *botwar_detect_executed) {
+ struct ChanUser *chanuser = getChanUser(user, chan);
+ if(!chanuser) return 0; //flying super cow?
+ if(time(0) - chanuser->changeTime > BOTWAR_DETECTION_TIME) {
+ chanuser->changeTime = time(0);
+ chanuser->chageEvents = 1;
+ } else {
+ if(!*botwar_detect_executed)
+ chanuser->chageEvents++;
+ *botwar_detect_executed = 1;
+ if(chanuser->chageEvents >= BOTWAR_DETECTION_EVENTS || chanuser->chageEvents < 0) {
+ //BOTWAR!
+ chanuser->changeTime = time(0);
+ if(chanuser->chageEvents > 0) {
+ char *alertchan = get_string_field("General.alertchan");
+ putsock(client, "NOTICE @%s :%s %s", chan->name, get_language_string(user, "NS_BOTWAR_DETECTED"), (alertchan ? get_language_string(user, "NS_BOTWAR_REPORTED") : ""));
+ if(alertchan) {
+ struct ChanNode *alertchan_chan = getChanByName(alertchan);
+ struct ClientSocket *alertclient;
+ if(alertchan_chan && (alertclient = getBotForChannel(chan)) != NULL) {
+ char msgBuf[MAXLEN];
+ putsock(alertclient, "PRIVMSG %s :%s", alertchan_chan->name, build_language_string(NULL, msgBuf, "NS_BOTWAR_ALERT", chan->name, user->nick));
+ }
+ }
+ }
+ chanuser->chageEvents = -2;
+ return 1;
+ }
+ }
+ return 0;
+}
+
--- /dev/null
+/* event_neonserv_notice.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+struct neonserv_event_notice_cache {
+ struct ClientSocket *client;
+ struct UserNode *user;
+ struct ChanNode *chan;
+ char *message;
+};
+
+static USERAUTH_CALLBACK(neonserv_event_notice_nick_lookup);
+static void neonserv_event_notice_async1(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, char *message);
+
+static void neonserv_event_channotice(struct UserNode *user, struct ChanNode *chan, char *message) {
+ struct ClientSocket *client = getBotForChannel(chan);
+ if(!client) return; //we can't "see" this event
+ if(isNetworkService(user)) return;
+ loadChannelSettings(chan);
+ if(!(chan->flags & CHANFLAG_CHAN_REGISTERED)) return;
+ if(!(user->flags & USERFLAG_ISAUTHED)) {
+ struct neonserv_event_notice_cache *cache = malloc(sizeof(*cache));
+ if (!cache) {
+ perror("malloc() failed");
+ return;
+ }
+ cache->client = client;
+ cache->user = user;
+ cache->chan = chan;
+ cache->message = strdup(message);
+ get_userauth(user, neonserv_event_notice_nick_lookup, cache);
+ } else
+ neonserv_event_notice_async1(client, user, chan, message);
+}
+
+static USERAUTH_CALLBACK(neonserv_event_notice_nick_lookup) {
+ struct neonserv_event_notice_cache *cache = data;
+ if(user) {
+ neonserv_event_notice_async1(cache->client, cache->user, cache->chan, cache->message);
+ }
+ free(cache->message);
+ free(cache);
+}
+
+static void neonserv_event_notice_async1(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, char *message) {
+ MYSQL_RES *res;
+ MYSQL_ROW row, defaultrow = NULL, chanuser;
+ int uaccess = 0;
+ printf_mysql_query("SELECT `channel_ctcp`, `channel_ctcpreaction` FROM `channels` WHERE `channel_id` = '%d'", chan->channel_id);
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) == NULL) return;
+ if(!row[0] || !row[1]) {
+ printf_mysql_query("SELECT `channel_ctcp`, `channel_ctcpreaction` FROM `channels` WHERE `channel_name` = 'defaults'");
+ res = mysql_use();
+ defaultrow = mysql_fetch_row(res);
+ }
+ int noticeaccess = atoi((row[0] ? row[0] : defaultrow[0]));
+ if((user->flags & USERFLAG_ISAUTHED)) {
+ printf_mysql_query("SELECT `chanuser_access`, `chanuser_flags` FROM `chanusers` LEFT JOIN `users` ON `chanuser_uid` = `user_id` WHERE `chanuser_cid` = '%d' AND `user_user` = '%s'", chan->channel_id, escape_string(user->auth));
+ res = mysql_use();
+ chanuser = mysql_fetch_row(res);
+ if(chanuser)
+ uaccess = ((atoi(chanuser[1]) & DB_CHANUSER_SUSPENDED) ? 0 : atoi(chanuser[0]));
+ }
+ int duration = 0;
+ char banmaskBuf[NICKLEN+USERLEN+HOSTLEN+3];
+ char *banmask = NULL;
+ char *reason = "disallowed channel NOTICE";
+ if(uaccess < noticeaccess) {
+ switch(atoi((row[1] ? row[1] : defaultrow[1]))) {
+ case 2: //TIMEBAN: 3min
+ duration = 180;
+ case 3: //TIMEBAN: 1h
+ if(!duration)
+ duration = 3600;
+ banmask = generate_banmask(user, banmaskBuf);
+ printf_mysql_query("INSERT INTO `bans` (`ban_channel`, `ban_mask`, `ban_triggered`, `ban_timeout`, `ban_owner`, `ban_reason`) VALUES ('%d', '%s', UNIX_TIMESTAMP(), '%lu', '%d', '%s')", chan->channel_id, escape_string(banmask), (unsigned long) (time(0) + duration), 0, escape_string(reason));
+ int banid = (int) mysql_insert_id(get_mysql_conn());
+ char nameBuf[MAXLEN];
+ char banidBuf[20];
+ sprintf(nameBuf, "ban_%d", banid);
+ sprintf(banidBuf, "%d", banid);
+ timeq_add_name(nameBuf, duration, channel_ban_timeout, strdup(banidBuf));
+ case 1: //KICKBAN
+ if(!banmask)
+ banmask = generate_banmask(user, banmaskBuf);
+ putsock(client, "MODE %s +b %s", chan->name, banmask);
+ case 0: //KICK
+ putsock(client, "KICK %s %s :%s", chan->name, user->nick, reason);
+ break;
+ }
+ }
+}
+
--- /dev/null
+/* event_neonserv_part.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+static void neonserv_event_part(struct ChanUser *chanuser, char *reason) {
+ struct ChanNode *chan = chanuser->chan;
+ struct UserNode *user = chanuser->user;
+ MYSQL_RES *res;
+ MYSQL_ROW chanuserrow;
+ loadChannelSettings(chan);
+ if(!(chan->flags & CHANFLAG_CHAN_REGISTERED)) return;
+ if((user->flags & USERFLAG_ISAUTHED)) {
+ printf_mysql_query("SELECT `chanuser_id` FROM `chanusers` LEFT JOIN `users` ON `chanuser_uid` = `user_id` WHERE `chanuser_cid` = '%d' AND `user_user` = '%s'", chan->channel_id, escape_string(user->auth));
+ res = mysql_use();
+ if((chanuserrow = mysql_fetch_row(res)) != NULL)
+ printf_mysql_query("UPDATE `chanusers` SET `chanuser_seen` = UNIX_TIMESTAMP() WHERE `chanuser_id` = '%s'", chanuserrow[0]);
+ }
+}
--- /dev/null
+/* event_neonserv_quit.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+static void neonserv_event_quit(struct UserNode *user, char *reason) {
+ MYSQL_RES *res;
+ MYSQL_ROW chanuserrow;
+ struct ChanUser *chanuser;
+ if((user->flags & USERFLAG_ISAUTHED)) {
+ for(chanuser = getUserChannels(user, NULL); chanuser; chanuser = getUserChannels(user, chanuser)) {
+ printf_mysql_query("SELECT `chanuser_id` FROM `chanusers` LEFT JOIN `users` ON `chanuser_uid` = `user_id` LEFT JOIN `channels` ON `chanuser_cid` = `channel_id` WHERE `channel_name` = '%s' AND `user_user` = '%s'", escape_string(chanuser->chan->name), escape_string(user->auth));
+ res = mysql_use();
+ if((chanuserrow = mysql_fetch_row(res)) != NULL)
+ printf_mysql_query("UPDATE `chanusers` SET `chanuser_seen` = UNIX_TIMESTAMP() WHERE `chanuser_id` = '%s'", chanuserrow[0]);
+ }
+ }
+}
--- /dev/null
+/* event_neonserv_topic.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+struct neonserv_event_topic_cache {
+ struct ClientSocket *client;
+ struct UserNode *user;
+ struct ChanNode *chan;
+ char *new_topic;
+};
+
+static USERAUTH_CALLBACK(neonserv_event_topic_nick_lookup);
+static void neonserv_event_topic_async1(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, const char *new_topic);
+
+static void neonserv_event_topic(struct UserNode *user, struct ChanNode *chan, const char *new_topic) {
+ struct ClientSocket *client = getBotForChannel(chan);
+ if(!client) return; //we can't "see" this event
+ if(isNetworkService(user)) return;
+ loadChannelSettings(chan);
+ if(!(chan->flags & CHANFLAG_CHAN_REGISTERED)) return;
+ if(!(user->flags & USERFLAG_ISAUTHED)) {
+ struct neonserv_event_topic_cache *cache = malloc(sizeof(*cache));
+ if (!cache) {
+ perror("malloc() failed");
+ return;
+ }
+ cache->client = client;
+ cache->user = user;
+ cache->chan = chan;
+ cache->new_topic = strdup(new_topic);
+ get_userauth(user, neonserv_event_topic_nick_lookup, cache);
+ } else
+ neonserv_event_topic_async1(client, user, chan, new_topic);
+}
+
+static USERAUTH_CALLBACK(neonserv_event_topic_nick_lookup) {
+ struct neonserv_event_topic_cache *cache = data;
+ if(user) {
+ neonserv_event_topic_async1(cache->client, cache->user, cache->chan, cache->new_topic);
+ }
+ free(cache->new_topic);
+ free(cache);
+}
+
+static void neonserv_event_topic_async1(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, const char *new_topic) {
+ MYSQL_RES *res;
+ MYSQL_ROW row, defaultrow = NULL, chanuserrow;
+ int uaccess = 0;
+ printf_mysql_query("SELECT `channel_changetopic`, `channel_topicsnarf` FROM `channels` WHERE `channel_id` = '%d'", chan->channel_id);
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) == NULL) return;
+ if(!row[0] || !row[1]) {
+ printf_mysql_query("SELECT `channel_changetopic`, `channel_topicsnarf` FROM `channels` WHERE `channel_name` = 'defaults'");
+ res = mysql_use();
+ defaultrow = mysql_fetch_row(res);
+ }
+ int changetopic = atoi((row[0] ? row[0] : defaultrow[0]));
+ int topicsnarf = atoi((row[1] ? row[1] : defaultrow[1]));
+ if((user->flags & USERFLAG_ISAUTHED)) {
+ printf_mysql_query("SELECT `chanuser_access`, `chanuser_flags` FROM `chanusers` LEFT JOIN `users` ON `chanuser_uid` = `user_id` WHERE `chanuser_cid` = '%d' AND `user_user` = '%s'", chan->channel_id, escape_string(user->auth));
+ res = mysql_use();
+ chanuserrow = mysql_fetch_row(res);
+ if(chanuserrow)
+ uaccess = ((atoi(chanuserrow[1]) & DB_CHANUSER_SUSPENDED) ? 0 : atoi(chanuserrow[0]));
+ }
+ if(uaccess < changetopic) {
+ //undo topic change
+ struct ClientSocket *textclient = ((client->flags & SOCKET_FLAG_PREFERRED) ? client : get_prefered_bot(client->botid));
+ struct ChanUser *chanuser = getChanUser(user, chan);
+ if(!chanuser) return; //flying super cow?
+ if(time(0) - chanuser->changeTime > BOTWAR_DETECTION_TIME) {
+ chanuser->changeTime = time(0);
+ chanuser->chageEvents = 1;
+ } else {
+ chanuser->chageEvents++;
+ if(chanuser->chageEvents >= BOTWAR_DETECTION_EVENTS || chanuser->chageEvents < 0) {
+ //BOTWAR!
+ chanuser->changeTime = time(0);
+ if(chanuser->chageEvents > 0) {
+ char *alertchan = get_string_field("General.alertchan");
+ putsock(client, "NOTICE @%s :%s %s", chan->name, get_language_string(user, "NS_BOTWAR_DETECTED"), (alertchan ? get_language_string(user, "NS_BOTWAR_REPORTED") : ""));
+ if(alertchan) {
+ struct ChanNode *alertchan_chan = getChanByName(alertchan);
+ struct ClientSocket *alertclient;
+ if(alertchan_chan && (alertclient = getBotForChannel(chan)) != NULL) {
+ char msgBuf[MAXLEN];
+ putsock(alertclient, "PRIVMSG %s :%s", alertchan_chan->name, build_language_string(NULL, msgBuf, "NS_BOTWAR_ALERT", chan->name, user->nick));
+ }
+ }
+ }
+ chanuser->chageEvents = -2;
+ return;
+ }
+ }
+ reply(textclient, user, "NS_TOPIC_ACCESS", chan->name);
+ putsock(client, "TOPIC %s :%s", chan->name, chan->topic);
+ } else if(uaccess >= topicsnarf) {
+ printf_mysql_query("UPDATE `channels` SET `channel_defaulttopic` = '%s' WHERE `channel_id` = '%d'", escape_string(new_topic), chan->channel_id);
+ }
+}
+
--- /dev/null
+/* module.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "../module.h"
+#include "bot_NeonServ.h"
+#include "cmd_neonserv.h"
+
+static int module_initialize() {
+ register_commands();
+ return 0;
+}
+
+static void module_start(int type) {
+ init_NeonServ(type);
+}
+
+static void module_loop() {
+ loop_NeonServ();
+}
+
+static void module_stop(int type) {
+ free_NeonServ(type);
+}
+
+MODULE_HEADER(module_initialize, module_start, module_loop, module_stop);
--- /dev/null
+/* bot_NeonSpam.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "../module.h"
+
+#include "bot_NeonSpam.h"
+#include "modcmd.h"
+#include "IRCParser.h"
+#include "IRCEvents.h"
+#include "UserNode.h"
+#include "ChanNode.h"
+#include "ChanUser.h"
+#include "ModeNode.h"
+#include "BanNode.h"
+#include "ClientSocket.h"
+#include "mysqlConn.h"
+#include "lang.h"
+#include "HandleInfoHandler.h"
+#include "WHOHandler.h"
+#include "DBHelper.h"
+#include "tools.h"
+#include "timeq.h"
+#include "version.h"
+#include "EventLogger.h"
+#include "bots.h"
+#include "cmd_neonserv.h"
+#include "cmd_neonspam.h"
+
+#define BOTID 2
+#define BOTALIAS "NeonSpam"
+
+static const struct default_language_entry msgtab[] = {
+ {"SS_SET_PERCENT", "%u is an invalid percent value (valid: 0-100)"}, /* {ARGS: 120} */
+ {"SS_SET_SENSIBILITY", "%s is an invalid sensibility format. (valid: amount:time e.g. 5:10)"}, /* {ARGS: "möp"} */
+ {"SS_SET_SENSIBILITY_AMOUNT", "%d is an invalid amount value. (valid: %d-%d)"}, /* {ARGS: 120, 1, 5} */
+ {"SS_SET_SENSIBILITY_TIME", "%d is an invalid time value. (valid: %d-%d)"}, /* {ARGS: 300, 15, 180} */
+ {"SS_SET_SPAMLIMIT", "%d is an invalid spamlimit value. (valid: %d-%d)"}, /* {ARGS: 120, 2, 8} */
+ {"SS_SET_OPTION_SpamReaction_0", "Kick"},
+ {"SS_SET_OPTION_SpamReaction_1", "KickBan"},
+ {"SS_SET_OPTION_SpamReaction_2", "Timed Ban"},
+ {"SS_SET_OPTION_FloodReaction_0", "Kick"},
+ {"SS_SET_OPTION_FloodReaction_1", "KickBan"},
+ {"SS_SET_OPTION_FloodReaction_2", "Timed Ban"},
+ {"SS_SET_OPTION_JoinReaction_0", "Kick"},
+ {"SS_SET_OPTION_JoinReaction_1", "KickBan"},
+ {"SS_SET_OPTION_JoinReaction_2", "Timed Ban"},
+ {"SS_SET_OPTION_CapsReaction_0", "Kick"},
+ {"SS_SET_OPTION_CapsReaction_1", "KickBan"},
+ {"SS_SET_OPTION_CapsReaction_2", "Timed Ban"},
+ {"SS_SET_OPTION_DigitReaction_0", "Kick"},
+ {"SS_SET_OPTION_DigitReaction_1", "KickBan"},
+ {"SS_SET_OPTION_DigitReaction_2", "Timed Ban"},
+ {NULL, NULL}
+};
+
+static unsigned int convertNeonSpamSettingsToFlags(char *str);
+static void createSpamNode(struct ChanUser *chanuser);
+static void freeJoinNode(struct NeonSpamJoinNode *joinnode);
+static struct NeonSpamJoinNode *getNeonSpamJoinNode(struct ChanUser *chanuser);
+
+#define SPAMSERV_CHECK_IGNORE 0
+#define SPAMSERV_CHECK_WARN 1
+#define SPAMSERV_CHECK_PUNISH 2
+#define SPAMSERV_CHECK_DEAD 3 /* scanner has already killed the user */
+
+#define SPAMSERV_MSG_SPAM "Spamming"
+#define SPAMSERV_MSG_FLOOD "Flooding the channel/network"
+#define SPAMSERV_MSG_ADV "Advertising"
+#define SPAMSERV_MSG_JOINFLOOD "Join flooding the channel"
+#define SPAMSERV_MSG_WARNING "%s is against the channel rules"
+#define SPAMSERV_MSG_BOTNET "BotNet detected."
+#define SPAMSERV_MSG_CAPS "Using too many chars in UPPER CASE"
+#define SPAMSERV_MSG_DIGIT "Using too many numeric chars"
+
+//EVENTS
+#include "event_neonspam_join.c"
+#include "event_neonspam_chanmsg.c"
+
+static void neonspam_event_kick(struct UserNode *user, struct ChanUser *target, char *reason) {
+ struct ChanNode *chan = target->chan;
+ if(isBot(target->user)) {
+ struct ClientSocket *client = getChannelBot(chan, 0);
+ struct ClientSocket *bot = client;
+ for(client = getBots(SOCKET_FLAG_READY, NULL); client; client = getBots(SOCKET_FLAG_READY, client)) {
+ if(client->user == target->user) {
+ break;
+ }
+ }
+ if(!client) return;
+ if(bot && bot != client && (isModeSet(chan->modes, 'i') || isModeSet(chan->modes, 'a') || isModeSet(chan->modes, 'l'))) {
+ struct ChanUser *chanuser = getChanUser(bot->user, chan);
+ if(chanuser && chanuser->flags & CHANUSERFLAG_OPPED)
+ putsock(bot, "INVITE %s %s", target->user->nick, chan->name);
+ }
+ char *key = "";
+ if(isModeSet(chan->modes, 'k')) {
+ key = getModeValue(chan->modes, 'k');
+ }
+ putsock(client, "JOIN %s %s", chan->name, key);
+ return;
+ }
+}
+
+static void neonspam_bot_ready(struct ClientSocket *client) {
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+
+ printf_mysql_query("SELECT `automodes` FROM `bots` WHERE `id` = '%d'", client->clientid);
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) != NULL) {
+ putsock(client, "MODE %s +%s", client->user->nick, row[0]);
+ }
+
+ printf_mysql_query("SELECT `channel_name`, `channel_key` FROM `bot_channels` LEFT JOIN `channels` ON `chanid` = `channel_id` WHERE `botid` = '%d' AND `suspended` = '0'", client->clientid);
+ res = mysql_use();
+
+ while ((row = mysql_fetch_row(res)) != NULL) {
+ putsock(client, "JOIN %s %s", row[0], row[1]);
+ }
+}
+
+static void neonspam_trigger_callback(int clientid, struct ChanNode *chan, char *trigger) {
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ loadChannelSettings(chan);
+ if(!(chan->flags & CHANFLAG_CHAN_REGISTERED)) {
+ strcpy(trigger, "~");
+ return;
+ }
+ printf_mysql_query("SELECT `trigger`, `defaulttrigger` FROM `bot_channels` LEFT JOIN `bots` ON `botid` = `bots`.`id` WHERE `chanid` = '%d' AND `botclass` = '%d'", chan->channel_id, BOTID);
+ res = mysql_use();
+ if(!(row = mysql_fetch_row(res))) {
+ strcpy(trigger, "~");
+ return;
+ }
+ if(row[0] && *row[0])
+ strcpy(trigger, row[0]);
+ else
+ strcpy(trigger, ((row[1] && *row[1]) ? row[1] : "~"));
+}
+
+static void start_bots(int type) {
+ struct ClientSocket *client;
+ MYSQL_RES *res, *res2;
+ MYSQL_ROW row;
+
+ if(type == MODSTATE_STARTSTOP) {
+ printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `textbot`, `id`, `queue`, `ssl`, `bind` FROM `bots` WHERE `botclass` = '%d' AND `active` = '1'", BOTID);
+ res = mysql_use();
+
+ while ((row = mysql_fetch_row(res)) != NULL) {
+ client = create_socket(row[3], atoi(row[4]), row[10], row[5], row[0], row[1], row[2]);
+ client->flags |= (strcmp(row[6], "0") ? SOCKET_FLAG_PREFERRED : 0);
+ client->flags |= (strcmp(row[8], "0") ? SOCKET_FLAG_USE_QUEUE : 0);
+ client->flags |= (strcmp(row[9], "0") ? SOCKET_FLAG_SSL : 0);
+ client->botid = BOTID;
+ client->clientid = atoi(row[7]);
+ connect_socket(client);
+ }
+ }
+
+ printf_mysql_query("SELECT `command`, `function`, `parameters`, `global_access`, `chan_access`, `flags` FROM `bot_binds` WHERE `botclass` = '%d'", BOTID);
+ res2 = mysql_use();
+ while ((row = mysql_fetch_row(res2)) != NULL) {
+ if(bind_cmd_to_command(BOTID, row[0], row[1])) {
+ if(row[2] && strcmp(row[2], "")) {
+ bind_set_parameters(BOTID, row[0], row[2]);
+ }
+ if(row[3]) {
+ bind_set_global_access(BOTID, row[0], atoi(row[3]));
+ }
+ if(row[4]) {
+ bind_set_channel_access(BOTID, row[0], row[4]);
+ }
+ if(strcmp(row[5], "0"))
+ bind_set_bind_flags(BOTID, row[0], atoi(row[5]));
+ }
+ }
+ bind_unbound_required_functions(BOTID);
+}
+
+char* convertNeonSpamSettingsToString(unsigned int flags, char *buffer) {
+ int pos = 0;
+ unsigned int i;
+ int j = 0;
+ char *chars = SPAMSETTINGS_CHARS;
+ for(i = 1; i <= SPAMSETTINGS_FLAGS; i = i << 1) {
+ if(flags & i)
+ buffer[pos++] = chars[j];
+ j++;
+ }
+ buffer[pos] = '\0';
+ return buffer;
+}
+
+static unsigned int convertNeonSpamSettingsToFlags(char *str) {
+ unsigned int i = 1, flags = 0;
+ int j = 0;
+ char *chars = SPAMSETTINGS_CHARS;
+ while(*str) {
+ for(; i <= SPAMSETTINGS_FLAGS; i = i << 1) {
+ if(*str == chars[j]) {
+ flags |= i;
+ j++;
+ i = i << 1;
+ break;
+ }
+ j++;
+ }
+ str++;
+ }
+ return flags;
+}
+
+int loadNeonSpamSettings(struct ChanNode *chan) {
+ if(chan->spam_settings) return 0;
+ struct NeonSpamSettings *settings = malloc(sizeof(*settings));
+ if(!settings) {
+ perror("malloc() failed");
+ return 0;
+ }
+ MYSQL_RES *res;
+ MYSQL_ROW row, defaults = NULL;
+ loadChannelSettings(chan);
+ printf_mysql_query("SELECT `channel_scanner`, `channel_spam_limit`, `channel_spam_except`, `channel_flood_limit`, `channel_flood_time`, `channel_flood_except`, `channel_join_limit`, `channel_join_time`, `channel_join_except`, `channel_caps_percent`, `channel_caps_except`, `channel_digit_percent`, `channel_digit_except` FROM `channels` WHERE `channel_id` = '%d'", chan->channel_id);
+ res = mysql_use();
+ row = mysql_fetch_row(res);
+ if(!row[0] || !row[1] || !row[2] || !row[3] || !row[4] || !row[5] || !row[6] || !row[7] || !row[8] || !row[9] || !row[10] || !row[11] || !row[12]) {
+ printf_mysql_query("SELECT `channel_scanner`, `channel_spam_limit`, `channel_spam_except`, `channel_flood_limit`, `channel_flood_time`, `channel_flood_except`, `channel_join_limit`, `channel_join_time`, `channel_join_except`, `channel_caps_percent`, `channel_caps_except`, `channel_digit_percent`, `channel_digit_except` FROM `channels` WHERE `channel_name` = 'defaults'");
+ res = mysql_use();
+ defaults = mysql_fetch_row(res);
+ }
+ settings->flags = convertNeonSpamSettingsToFlags(row[0] ? row[0] : defaults[0]);
+ settings->spam_amount = atoi(row[1] ? row[1] : defaults[1]);
+ settings->exceptlevel[SPAMSETTINGS_SPAMEXCINDEX] = atoi(row[2] ? row[2] : defaults[2]);
+ settings->sensibility_amount[SPAMSETTINGS_FLOODSENINDEX] = atoi(row[3] ? row[3] : defaults[3]);
+ settings->sensibility_time[SPAMSETTINGS_FLOODSENINDEX] = atoi(row[4] ? row[4] : defaults[4]);
+ settings->exceptlevel[SPAMSETTINGS_FLOODEXCINDEX] = atoi(row[5] ? row[5] : defaults[5]);
+ settings->sensibility_amount[SPAMSETTINGS_JOINSENINDEX] = atoi(row[6] ? row[6] : defaults[6]);
+ settings->sensibility_time[SPAMSETTINGS_JOINSENINDEX] = atoi(row[7] ? row[7] : defaults[7]);
+ settings->exceptlevel[SPAMSETTINGS_JOINEXCINDEX] = atoi(row[8] ? row[8] : defaults[8]);
+ settings->percent[SPAMSETTINGS_CAPSPERCENTINDEX] = atoi(row[9] ? row[9] : defaults[9]);
+ settings->exceptlevel[SPAMSETTINGS_CAPSEXCINDEX] = atoi(row[10] ? row[10] : defaults[10]);
+ settings->percent[SPAMSETTINGS_DIGITPERCENTINDEX] = atoi(row[11] ? row[11] : defaults[11]);
+ settings->exceptlevel[SPAMSETTINGS_DIGITEXCINDEX] = atoi(row[12] ? row[12] : defaults[12]);
+ settings->join_nodes = NULL;
+ settings->lastmsg_time = 0;
+ int i;
+ for(i = 0; i < BOTNETSCAN_USERS; i++)
+ settings->botnicks[i] = NULL;
+ chan->spam_settings = settings;
+ return 1;
+}
+
+void freeNeonSpamSettings(struct NeonSpamSettings *settings) {
+ struct NeonSpamJoinNode *joinnode, *nextjoinnode;
+ for(joinnode = settings->join_nodes; joinnode; joinnode = nextjoinnode) {
+ nextjoinnode = joinnode->next;
+ freeJoinNode(joinnode);
+ }
+ free(settings);
+}
+
+static void freeJoinNode(struct NeonSpamJoinNode *joinnode) {
+ free(joinnode->ident);
+ free(joinnode->host);
+ free(joinnode);
+}
+
+static struct NeonSpamJoinNode *getNeonSpamJoinNode(struct ChanUser *chanuser) {
+ struct NeonSpamJoinNode *joinnode, *prevjoinnode = NULL, *nextjoinnode, *result = NULL;
+ for(joinnode = chanuser->chan->spam_settings->join_nodes; joinnode; joinnode = nextjoinnode) {
+ nextjoinnode = joinnode->next;
+ if(!stricmp(joinnode->ident, chanuser->user->ident) && !stricmp(joinnode->host, chanuser->user->host)) {
+ prevjoinnode = joinnode;
+ result = joinnode;
+ } else if(time(0) - joinnode->last_penalty_update > MAX_JOIN_TIME) {
+ freeJoinNode(joinnode);
+ if(prevjoinnode)
+ prevjoinnode->next = nextjoinnode;
+ else
+ chanuser->chan->spam_settings->join_nodes = nextjoinnode;
+ } else
+ prevjoinnode = joinnode;
+ }
+ if(result)
+ return result;
+ joinnode = malloc(sizeof(*joinnode));
+ if(!joinnode) {
+ perror("malloc() failed");
+ return NULL;
+ }
+ joinnode->ident = strdup(chanuser->user->ident);
+ joinnode->host = strdup(chanuser->user->host);
+ joinnode->last_penalty_update = time(0);
+ joinnode->joinpenalty = 0;
+ joinnode->next = chanuser->chan->spam_settings->join_nodes;
+ chanuser->chan->spam_settings->join_nodes = joinnode;
+ return joinnode;
+}
+
+static void createSpamNode(struct ChanUser *chanuser) {
+ struct NeonSpamNode *spamnode = malloc(sizeof(*spamnode));
+ if(!spamnode) {
+ perror("malloc() failed");
+ return;
+ }
+ spamnode->lastmsg = 0;
+ spamnode->spamcount = 0;
+ spamnode->floodpenalty = 0;
+ spamnode->last_penalty_update = time(0);
+ chanuser->spamnode = spamnode;
+}
+
+void init_NeonSpam(int type) {
+
+ set_bot_alias(BOTID, BOTALIAS);
+ start_bots(type);
+
+ if(type == MODSTATE_REBIND) return;
+
+ //register events
+ bind_bot_ready(neonspam_bot_ready);
+ bind_join(neonspam_event_join);
+ bind_chanmsg(neonspam_event_chanmsg);
+ bind_privctcp(general_event_privctcp);
+ bind_kick(neonspam_event_kick);
+
+ set_trigger_callback(BOTID, neonspam_trigger_callback);
+
+ register_default_language_table(msgtab);
+}
+
+void loop_NeonSpam() {
+
+}
+
+void free_NeonSpam(int type) {
+ unbind_allcmd(BOTID);
+ if(type == MODSTATE_STARTSTOP) {
+ //disconnect all our bots
+ struct ClientSocket *client;
+ for(client = getBots(0, NULL); client; client = getBots(0, client)) {
+ if(client->botid == BOTID) {
+ unbind_botwise_allcmd(0, client->clientid);
+ close_socket(client);
+ break;
+ }
+ }
+ }
+}
+
+#undef BOTID
+#undef BOTALIAS
--- /dev/null
+/* bot_NeonSpam.h - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _bot_NeonSpam_h
+#define _bot_NeonSpam_h
+
+#include "main.h"
+
+struct ChanNode;
+
+//SPAMSCAN
+#define SPAMSETTINGS_SPAMSCAN 0x000001
+#define SPAMSETTINGS_SPAMSCAN_OPS 0x000002
+#define SPAMSETTINGS_SPAMSCAN_VOICE 0x000004
+#define SPAMSETTINGS_SPAMCHARS "abc"
+#define SPAMSETTINGS_SPAMEXCINDEX 0
+
+//FLOODSCAN
+#define SPAMSETTINGS_FLOODSCAN 0x000008
+#define SPAMSETTINGS_FLOODSCAN_OPS 0x000010
+#define SPAMSETTINGS_FLOODSCAN_VOICE 0x000020
+#define SPAMSETTINGS_FLOODCHARS "def"
+#define SPAMSETTINGS_FLOODEXCINDEX 1
+#define SPAMSETTINGS_FLOODSENINDEX 0
+
+//JOINSCAN
+#define SPAMSETTINGS_JOINSCAN 0x000040
+#define SPAMSETTINGS_JOINSCAN_OPS 0x000080
+#define SPAMSETTINGS_JOINSCAN_VOICE 0x000100
+#define SPAMSETTINGS_JOINCHARS "ghi"
+#define SPAMSETTINGS_JOINEXCINDEX 2
+#define SPAMSETTINGS_JOINSENINDEX 1
+
+//BOTNET SCAN
+#define SPAMSETTINGS_BOTNETSCAN 0x000200
+#define SPAMSETTINGS_BOTNETSCAN_OPS 0x000400
+#define SPAMSETTINGS_BOTNETSCAN_VOICE 0x000800
+#define SPAMSETTINGS_BOTNETSCAN_STRIPCC 0x001000
+#define SPAMSETTINGS_BOTNETCHARS "jklm"
+#define SPAMSETTINGS_BOTNETEXCINDEX 3
+
+//CAPSSCAN
+#define SPAMSETTINGS_CAPSSCAN 0x002000
+#define SPAMSETTINGS_CAPSSCAN_OPS 0x004000
+#define SPAMSETTINGS_CAPSSCAN_VOICE 0x008000
+#define SPAMSETTINGS_CAPSCHARS "nop"
+#define SPAMSETTINGS_CAPSEXCINDEX 4
+#define SPAMSETTINGS_CAPSPERCENTINDEX 0
+
+//DIGITSCAN
+#define SPAMSETTINGS_DIGITSCAN 0x010000
+#define SPAMSETTINGS_DIGITSCAN_OPS 0x020000
+#define SPAMSETTINGS_DIGITSCAN_VOICE 0x040000
+#define SPAMSETTINGS_DIGITCHARS "qrs"
+#define SPAMSETTINGS_DIGITEXCINDEX 5
+#define SPAMSETTINGS_DIGITPERCENTINDEX 1
+
+
+#define SPAMSETTINGS_CHARS SPAMSETTINGS_SPAMCHARS SPAMSETTINGS_FLOODCHARS SPAMSETTINGS_JOINCHARS SPAMSETTINGS_BOTNETCHARS SPAMSETTINGS_CAPSCHARS SPAMSETTINGS_DIGITCHARS
+#define SPAMSETTINGS_FLAGS 0x07ffff /* all flags that can be stored in the database */
+#define SPAMSETTINGS_EXCEPTINDEXES 6
+#define SPAMSETTINGS_SENSIBILITYINDEXES 2
+#define SPAMSETTINGS_PERCENTINDEXES 2
+
+//SCRIPT FLAGS
+#define SPAMSETTINGS_KICKEDBOTQUEUE 0x080000
+#define SPAMSETTINGS_ISTIMEBAN 0x100000
+#define SPAMSETTINGS_SETTIMEBAN 0x200000
+
+#define MAX_FLOOD_AMOUNT 300
+#define MIN_FLOOD_AMOUNT 2
+#define MAX_FLOOD_TIME 200
+
+#define MAX_JOIN_AMOUNT 300
+#define MIN_JOIN_AMOUNT 2
+#define MAX_JOIN_TIME 200
+
+#define BOTNETSCAN_USERS 4
+#define BOTNETSCAN_TIME 2
+
+struct NeonSpamSettings {
+ unsigned int flags;
+ unsigned char spam_amount;
+ unsigned char sensibility_amount[SPAMSETTINGS_SENSIBILITYINDEXES];
+ unsigned char sensibility_time[SPAMSETTINGS_SENSIBILITYINDEXES];
+ unsigned int exceptlevel[SPAMSETTINGS_EXCEPTINDEXES];
+ unsigned char percent[SPAMSETTINGS_PERCENTINDEXES];
+
+ //joinflood
+ struct NeonSpamJoinNode *join_nodes;
+
+ //botnet
+ unsigned long lastmsg; //crc32 hash
+ time_t lastmsg_time;
+ char *botnicks[BOTNETSCAN_USERS];
+
+
+};
+/* PENALTY SYSTEM
+* user gets MAX_FLOOD_TIME points per message
+* points get removed each loop
+* pounts to be removed each second:
+* MAX_FLOOD_TIME/flood_time
+*
+* the floodlimit is reached, if the penalty points
+* are bigger than MAX_FLOOD_TIME * flood_amount
+*/
+
+#define NEONSPAMNODE_FLAG_CAPSSCAN_WARNED 0x01
+#define NEONSPAMNODE_FLAG_DIGITSCAN_WARNED 0x02
+
+struct NeonSpamNode {
+ unsigned long lastmsg; //crc32 hash
+ unsigned char spamcount;
+ int floodpenalty;
+ time_t last_penalty_update;
+ unsigned char flags;
+};
+
+struct NeonSpamJoinNode {
+ char *ident;
+ char *host;
+ int joinpenalty;
+ time_t last_penalty_update;
+ struct NeonSpamJoinNode *next;
+};
+
+void init_NeonSpam(int type);
+void loop_NeonSpam();
+void free_NeonSpam(int type);
+
+void freeNeonSpamSettings(struct NeonSpamSettings *settings);
+char* convertNeonSpamSettingsToString(unsigned int flags, char *buffer);
+int loadNeonSpamSettings(struct ChanNode *chan);
+
+#endif
\ No newline at end of file
--- /dev/null
+/* cmd_neonspam.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "../module.h"
+
+#include "cmd_neonspam.h"
+#include "modcmd.h"
+#include "ConfigParser.h"
+
+void register_commands() {
+ //NeonSpam Commands
+ register_command_alias(2, "NeonSpam");
+
+ #define USER_COMMAND(NAME,FUNCTION,PARAMCOUNT,PRIVS,FLAGS) register_command(2, NAME, FUNCTION, PARAMCOUNT, PRIVS, 0, FLAGS)
+ // NAME FUNCTION PARAMS PRIVS FLAGS
+ USER_COMMAND("set", neonspam_cmd_set, 0, "#channel_setters", CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
+ #undef USER_COMMAND
+
+}
\ No newline at end of file
--- /dev/null
+/* cmd_neonspam.h - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef _cmd_neonspam_h
+#define _cmd_neonspam_h
+#include "main.h"
+#include "modcmd.h"
+#include "IRCParser.h"
+#include "IRCEvents.h"
+#include "UserNode.h"
+#include "ChanNode.h"
+#include "ChanUser.h"
+#include "ModeNode.h"
+#include "BanNode.h"
+#include "ClientSocket.h"
+#include "mysqlConn.h"
+#include "lang.h"
+#include "HandleInfoHandler.h"
+#include "WHOHandler.h"
+#include "DBHelper.h"
+#include "tools.h"
+#include "timeq.h"
+#include "version.h"
+#include "EventLogger.h"
+#include "bots.h"
+#include "bot_NeonSpam.h"
+
+CMD_BIND(neonspam_cmd_set);
+
+#endif
\ No newline at end of file
--- /dev/null
+/* cmd_neonspam_set.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_neonspam.h"
+
+typedef char* neonspam_cmd_set_function(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int intparam, char *charparam, char *argument, char *retBuf);
+static char* neonspam_cmd_set_trigger(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int intparam, char *charparam, char *argument, char *retBuf);
+static char* neonspam_cmd_setflags(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int intparam, char *charparam, char *argument, char *retBuf);
+static char* neonspam_cmd_setexcept(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int intparam, char *charparam, char *argument, char *retBuf);
+static char* neonspam_cmd_set_reaction(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int intparam, char *charparam, char *argument, char *retBuf);
+static char* neonspam_cmd_set_reaction_time(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int intparam, char *charparam, char *argument, char *retBuf);
+static char* neonspam_cmd_setpercent(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int intparam, char *charparam, char *argument, char *retBuf);
+static char* neonspam_cmd_setsensibility(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int intparam, char *charparam, char *argument, char *retBuf);
+static char* neonspam_cmd_set_spamlimit(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int intparam, char *charparam, char *argument, char *retBuf);
+static char* neonspam_cmd_setscanops(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int intparam, char *charparam, char *argument, char *retBuf);
+static char* neonspam_cmd_setscanvoice(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int intparam, char *charparam, char *argument, char *retBuf);
+static char* neonspam_cmd_setscanexcept(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int intparam, char *charparam, char *argument, char *retBuf);
+
+static MYSQL_ROW neonspam_settings_row, neonspam_settings_defaults;
+#define SPAMSERV_SETTINGS_QUERY "`channel_spam_reaction`, `channel_spam_reaction_duration`, `channel_flood_reaction`, `channel_flood_reaction_duration`, `channel_join_reaction`, `channel_join_reaction_duration`, `channel_botnet_bantime`, `channel_caps_reaction`, `channel_caps_reaction_duration`, `channel_digit_reaction`, `channel_digit_reaction_duration`"
+#define SPAMSERV_SETTINGS_RESET "\
+`channel_scanner` = NULL, \
+`channel_spam_limit` = NULL, \
+`channel_spam_reaction` = NULL, \
+`channel_spam_reaction_duration` = NULL, \
+`channel_spam_except` = NULL, \
+`channel_flood_limit` = NULL, \
+`channel_flood_time` = NULL, \
+`channel_flood_reaction` = NULL, \
+`channel_flood_reaction_duration` = NULL, \
+`channel_flood_except` = NULL, \
+`channel_join_limit` = NULL, \
+`channel_join_time` = NULL, \
+`channel_join_reaction` = NULL, \
+`channel_join_reaction_duration` = NULL, \
+`channel_join_except` = NULL, \
+`channel_botnet_bantime` = NULL, \
+`channel_botnet_except` = NULL, \
+`channel_caps_percent` = NULL, \
+`channel_caps_reaction` = NULL, \
+`channel_caps_reaction_duration` = NULL, \
+`channel_caps_except` = NULL,\
+`channel_digit_percent` = NULL, \
+`channel_digit_reaction` = NULL, \
+`channel_digit_reaction_duration` = NULL, \
+`channel_digit_except` = NULL "
+
+#define SET_HELP 0x0001
+#define SET_BOOL 0x0002
+#define SET_OPT 0x0004
+
+#define SET_SCANOPS 0x0010
+#define SET_SCANVOICE 0x0020
+#define SET_SCANEXCEPT 0x0040
+
+#define SET_OPT_MAX 0xff00
+#define SET_OPT_SHIFT 8
+
+static const struct {
+ unsigned int if_flag;
+ unsigned int indent;
+ const char *setting;
+ void *function;
+ int intparam;
+ char *charparam;
+ int flags;
+} neonspam_settings[] = {
+ {0, 0, "Trigger", neonspam_cmd_set_trigger, 0, NULL, SET_HELP},
+
+ {0, 0, "SpamScan", neonspam_cmd_setflags, SPAMSETTINGS_SPAMSCAN, NULL, SET_BOOL},
+ {SPAMSETTINGS_SPAMSCAN, 2, "SpamLimit", neonspam_cmd_set_spamlimit, 0, NULL, SET_HELP},
+ {SPAMSETTINGS_SPAMSCAN | SPAMSETTINGS_SETTIMEBAN, 2, "SpamReaction", neonspam_cmd_set_reaction, 0, "channel_spam_reaction", SET_OPT | (3 << SET_OPT_SHIFT)},
+ {SPAMSETTINGS_SPAMSCAN | SPAMSETTINGS_ISTIMEBAN, 4, "SpamBanDuration", neonspam_cmd_set_reaction_time, 1, "channel_spam_reaction_duration", 0},
+ {SPAMSETTINGS_SPAMSCAN, 2, "SpamScanChanOps", neonspam_cmd_setflags, SPAMSETTINGS_SPAMSCAN_OPS, NULL, SET_BOOL | SET_SCANOPS},
+ {SPAMSETTINGS_SPAMSCAN, 2, "SpamScanVoiced", neonspam_cmd_setflags, SPAMSETTINGS_SPAMSCAN_VOICE, NULL, SET_BOOL | SET_SCANVOICE},
+ {SPAMSETTINGS_SPAMSCAN, 2, "SpamScanExcept", neonspam_cmd_setexcept, SPAMSETTINGS_SPAMEXCINDEX, "channel_spam_except", SET_HELP | SET_SCANEXCEPT},
+
+ {0, 0, "FloodScan", neonspam_cmd_setflags, SPAMSETTINGS_FLOODSCAN, NULL, SET_BOOL},
+ {SPAMSETTINGS_FLOODSCAN, 2, "FloodSensibility", neonspam_cmd_setsensibility, SPAMSETTINGS_FLOODSENINDEX, "channel_flood_", SET_HELP},
+ {SPAMSETTINGS_FLOODSCAN | SPAMSETTINGS_SETTIMEBAN, 2, "FloodReaction", neonspam_cmd_set_reaction, 2, "channel_flood_reaction", SET_OPT | (3 << SET_OPT_SHIFT)},
+ {SPAMSETTINGS_FLOODSCAN | SPAMSETTINGS_ISTIMEBAN, 4, "FloodBanDuration", neonspam_cmd_set_reaction_time, 3, "channel_flood_reaction_duration",0},
+ {SPAMSETTINGS_FLOODSCAN, 2, "FloodScanChanOps", neonspam_cmd_setflags, SPAMSETTINGS_FLOODSCAN_OPS, NULL, SET_BOOL | SET_SCANOPS},
+ {SPAMSETTINGS_FLOODSCAN, 2, "FloodScanVoiced", neonspam_cmd_setflags, SPAMSETTINGS_FLOODSCAN_VOICE, NULL, SET_BOOL | SET_SCANVOICE},
+ {SPAMSETTINGS_FLOODSCAN, 2, "FloodScanExcept", neonspam_cmd_setexcept, SPAMSETTINGS_FLOODEXCINDEX, "channel_flood_except", SET_HELP | SET_SCANEXCEPT},
+
+ {0, 0, "JoinScan", neonspam_cmd_setflags, SPAMSETTINGS_JOINSCAN, NULL, SET_BOOL},
+ {SPAMSETTINGS_JOINSCAN, 2, "JoinSensibility", neonspam_cmd_setsensibility, SPAMSETTINGS_JOINSENINDEX, "channel_join_", SET_HELP},
+ {SPAMSETTINGS_JOINSCAN | SPAMSETTINGS_SETTIMEBAN, 2, "JoinReaction", neonspam_cmd_set_reaction, 4, "channel_join_reaction", SET_OPT | (3 << SET_OPT_SHIFT)},
+ {SPAMSETTINGS_JOINSCAN | SPAMSETTINGS_ISTIMEBAN, 4, "JoinBanDuration", neonspam_cmd_set_reaction_time, 5, "channel_join_reaction_duration", 0},
+ {SPAMSETTINGS_JOINSCAN, 2, "JoinScanChanOps", neonspam_cmd_setflags, SPAMSETTINGS_JOINSCAN_OPS, NULL, SET_BOOL | SET_SCANOPS},
+ {SPAMSETTINGS_JOINSCAN, 2, "JoinScanVoiced", neonspam_cmd_setflags, SPAMSETTINGS_JOINSCAN_VOICE, NULL, SET_BOOL | SET_SCANVOICE},
+ {SPAMSETTINGS_JOINSCAN, 2, "JoinScanExcept", neonspam_cmd_setexcept, SPAMSETTINGS_JOINEXCINDEX, "channel_join_except", SET_HELP | SET_SCANEXCEPT},
+
+ {0, 0, "BotNetScan", neonspam_cmd_setflags, SPAMSETTINGS_BOTNETSCAN, NULL, SET_BOOL},
+ {SPAMSETTINGS_BOTNETSCAN, 4, "BotNetBanDuration", neonspam_cmd_set_reaction_time, 6, "channel_botnet_bantime", 0},
+ {SPAMSETTINGS_BOTNETSCAN, 2, "BotNetScanChanOps", neonspam_cmd_setflags, SPAMSETTINGS_BOTNETSCAN_OPS, NULL, SET_BOOL | SET_SCANOPS},
+ {SPAMSETTINGS_BOTNETSCAN, 2, "BotNetScanVoiced", neonspam_cmd_setflags, SPAMSETTINGS_BOTNETSCAN_VOICE, NULL, SET_BOOL | SET_SCANVOICE},
+ //{SPAMSETTINGS_BOTNETSCAN, 2, "BotNetScanExcept", neonspam_cmd_setexcept, SPAMSETTINGS_BOTNETEXCINDEX, "channel_botnet_except", SET_HELP},
+
+ {0, 0, "CapsScan", neonspam_cmd_setflags, SPAMSETTINGS_CAPSSCAN, NULL, SET_BOOL},
+ {SPAMSETTINGS_CAPSSCAN, 2, "CapsPercent", neonspam_cmd_setpercent, SPAMSETTINGS_CAPSPERCENTINDEX, "channel_caps_percent", SET_HELP},
+ {SPAMSETTINGS_CAPSSCAN | SPAMSETTINGS_SETTIMEBAN, 2, "CapsReaction", neonspam_cmd_set_reaction, 7, "channel_caps_reaction", SET_OPT | (3 << SET_OPT_SHIFT)},
+ {SPAMSETTINGS_CAPSSCAN | SPAMSETTINGS_ISTIMEBAN, 4, "CapsBanDuration", neonspam_cmd_set_reaction_time, 8, "channel_caps_reaction_duration", 0},
+ {SPAMSETTINGS_CAPSSCAN, 2, "CapsScanChanOps", neonspam_cmd_setflags, SPAMSETTINGS_CAPSSCAN_OPS, NULL, SET_BOOL | SET_SCANOPS},
+ {SPAMSETTINGS_CAPSSCAN, 2, "CapsScanVoiced", neonspam_cmd_setflags, SPAMSETTINGS_CAPSSCAN_VOICE, NULL, SET_BOOL | SET_SCANVOICE},
+ {SPAMSETTINGS_CAPSSCAN, 2, "CapsScanExcept", neonspam_cmd_setexcept, SPAMSETTINGS_CAPSEXCINDEX, "channel_caps_except", SET_HELP | SET_SCANEXCEPT},
+
+ {0, 0, "DigitScan", neonspam_cmd_setflags, SPAMSETTINGS_DIGITSCAN, NULL, SET_BOOL},
+ {SPAMSETTINGS_DIGITSCAN, 2, "DigitPercent", neonspam_cmd_setpercent, SPAMSETTINGS_DIGITPERCENTINDEX, "channel_digit_percent", SET_HELP},
+ {SPAMSETTINGS_DIGITSCAN | SPAMSETTINGS_SETTIMEBAN, 2, "DigitReaction", neonspam_cmd_set_reaction, 9, "channel_digit_reaction", SET_OPT | (3 << SET_OPT_SHIFT)},
+ {SPAMSETTINGS_DIGITSCAN | SPAMSETTINGS_ISTIMEBAN, 4, "DigitBanDuration", neonspam_cmd_set_reaction_time, 10, "channel_digit_reaction_duration", 0},
+ {SPAMSETTINGS_DIGITSCAN, 2, "DigitScanChanOps", neonspam_cmd_setflags, SPAMSETTINGS_DIGITSCAN_OPS, NULL, SET_BOOL | SET_SCANOPS},
+ {SPAMSETTINGS_DIGITSCAN, 2, "DigitScanVoiced", neonspam_cmd_setflags, SPAMSETTINGS_DIGITSCAN_VOICE, NULL, SET_BOOL | SET_SCANVOICE},
+ {SPAMSETTINGS_DIGITSCAN, 2, "DigitScanExcept", neonspam_cmd_setexcept, SPAMSETTINGS_DIGITEXCINDEX, "channel_digit_except", SET_HELP | SET_SCANEXCEPT},
+
+ {0, 0, "GlobalScanChanOps", neonspam_cmd_setscanops, 0, NULL, SET_BOOL},
+ {0, 0, "GlobalScanVoice", neonspam_cmd_setscanvoice, 0, NULL, SET_BOOL},
+ {0, 0, "GlobalScanExcept", neonspam_cmd_setscanexcept, 0, NULL, SET_HELP},
+
+ {0, 0, NULL, NULL, 0, NULL, 0}
+};
+
+#define MAX_QUERY_LEN 1024
+CMD_BIND(neonspam_cmd_set) {
+ int i, j;
+ loadNeonSpamSettings(chan);
+ if(argc && !strcmp(argv[0], "defaults")) {
+ //reset channel settings
+ int uaccess = getChannelAccess(user, chan);
+ if(uaccess < 500) {
+ if(isGodMode(user)) {
+ event->flags |= CMDFLAG_OPLOG;
+ } else {
+ reply(getTextBot(), user, "NS_SET_DEFAULTS_OWNER", chan->name);
+ return;
+ }
+ }
+ int seed = 0;
+ char *tmp;
+ 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)) {
+ printf_mysql_query("UPDATE `channels` SET " SPAMSERV_SETTINGS_RESET " WHERE `channel_id` = '%d'", chan->channel_id);
+ reply(getTextBot(), user, "NS_SET_DEFAULTS_DONE", chan->name);
+ logEvent(event);
+ } 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;
+ char *args = (argc > 1 ? merge_argv(argv, 1, argc) : NULL);
+ neonspam_settings_row = NULL;
+ neonspam_settings_defaults = NULL;
+ while(neonspam_settings[i].setting) {
+ if(!stricmp(neonspam_settings[i].setting, argv[0])) {
+ //setting found
+ char valueBuf[MAXLEN], nameBuf[MAXLEN];
+ char *value, *optimized_value, *option_help;
+ neonspam_cmd_set_function *func = neonspam_settings[i].function;
+ value = func(client, user, chan, event, neonspam_settings[i].intparam, neonspam_settings[i].charparam, args, valueBuf);
+ if(value) {
+ optimized_value = value;
+ if(neonspam_settings[i].flags & SET_BOOL) {
+ if(!strcmp(value, "0"))
+ optimized_value = get_language_string(user, "NS_SET_OFF");
+ else if(!strcmp(value, "1"))
+ optimized_value = get_language_string(user, "NS_SET_ON");
+ }
+ if(neonspam_settings[i].flags & SET_OPT) {
+ sprintf(nameBuf, "SS_SET_OPTION_%s_%s", neonspam_settings[i].setting, value);
+ option_help = get_language_string(user, nameBuf);
+ } else
+ option_help = NULL;
+ reply(getTextBot(), user, "\002%s\002 %s%s%s", neonspam_settings[i].setting, optimized_value, (option_help ? " - " : ""), (option_help ? option_help : ""));
+ if(neonspam_settings[i].flags & SET_OPT) {
+ int maxoption = (neonspam_settings[i].flags & SET_OPT_MAX) >> SET_OPT_SHIFT;
+ for(j = 0; j < maxoption; j++) {
+ sprintf(nameBuf, "SS_SET_OPTION_%s_%d", neonspam_settings[i].setting, j);
+
+ reply(getTextBot(), user, " \002%d\002 - %s", j, option_help);
+ }
+ }
+ if((neonspam_settings[i].flags & SET_HELP) && argc && !strcmp(argv[0], "help")) {
+ char *tmp;
+ sprintf(nameBuf, "SS_SET_HELP_%s", neonspam_settings[i].setting);
+ tmp = get_language_string(user, nameBuf);
+ if(tmp) {
+ reply(getTextBot(), user, " %s", tmp);
+ }
+ }
+ }
+ j = 1;
+ break;
+ }
+ i++;
+ }
+ if(j == 0) {
+ //unknown setting
+ reply(getTextBot(), user, "NS_SET_UNKNOWN_SETTING", argv[0]);
+ }
+ } else {
+ char valueBuf[MAXLEN], nameBuf[MAXLEN];
+ char *value;
+ int namePos, boolflag = 0;
+ MYSQL_RES *res, *defaults_res;
+ struct Table *table;
+ char *content[2];
+ i = 0;
+ while(neonspam_settings[i].setting)
+ i++;
+ table = table_init(2, i, 0);
+ table_set_bold(table, 0, 1);
+ printf_mysql_query("SELECT " SPAMSERV_SETTINGS_QUERY " FROM `channels` WHERE `channel_name` = 'defaults'");
+ defaults_res = mysql_use();
+ neonspam_settings_defaults = mysql_fetch_row(defaults_res);
+ printf_mysql_query("SELECT " SPAMSERV_SETTINGS_QUERY " FROM `channels` WHERE `channel_id` = '%d'", chan->channel_id);
+ res = mysql_use();
+ neonspam_settings_row = mysql_fetch_row(res);
+ i = -1;
+ reply(getTextBot(), user, "NS_SET_HEADER", chan->name);
+ while(neonspam_settings[++i].setting) {
+ if((chan->spam_settings->flags & (neonspam_settings[i].if_flag & SPAMSETTINGS_FLAGS)) != (neonspam_settings[i].if_flag & SPAMSETTINGS_FLAGS))
+ continue;
+ if((neonspam_settings[i].if_flag & SPAMSETTINGS_ISTIMEBAN) && !boolflag)
+ continue;
+ neonspam_cmd_set_function *func = neonspam_settings[i].function;
+ value = func(client, user, chan, event, neonspam_settings[i].intparam, neonspam_settings[i].charparam, NULL, valueBuf);
+ if(neonspam_settings[i].if_flag & SPAMSETTINGS_SETTIMEBAN)
+ boolflag = !strcmp(value, "2");
+ //TODO: append option or help info
+ strcpy(valueBuf, value);
+ if(neonspam_settings[i].flags & SET_BOOL) {
+ if(!strcmp(value, "0"))
+ strcpy(valueBuf, get_language_string(user, "NS_SET_OFF"));
+ else if(!strcmp(value, "1"))
+ strcpy(valueBuf, get_language_string(user, "NS_SET_ON"));
+ }
+ if(neonspam_settings[i].flags & SET_OPT) {
+ char *tmp;
+ sprintf(nameBuf, "SS_SET_OPTION_%s_%s", neonspam_settings[i].setting, value);
+ tmp = get_language_string(user, nameBuf);
+ if(tmp) {
+ sprintf(valueBuf + strlen(valueBuf), " - %s", tmp);
+ }
+ }
+ if((neonspam_settings[i].flags & SET_HELP) && argc && !strcmp(argv[0], "help")) {
+ char *tmp;
+ sprintf(nameBuf, "SS_SET_HELP_%s", neonspam_settings[i].setting);
+ tmp = get_language_string(user, nameBuf);
+ if(tmp) {
+ sprintf(valueBuf + strlen(valueBuf), " - %s", tmp);
+ }
+ }
+ namePos = 0;
+ for(j = 0; j < neonspam_settings[i].indent; j++) {
+ nameBuf[namePos++] = ' ';
+ }
+ sprintf(nameBuf + namePos, "%s", neonspam_settings[i].setting);
+ content[0] = nameBuf;
+ content[1] = valueBuf;
+ table_add(table, content);
+ }
+ char **table_lines = table_end(table);
+ for(i = 0; i < table->entrys; i++) {
+ reply(getTextBot(), user, table_lines[i]);
+ }
+ table_free(table);
+ }
+}
+
+static char* neonspam_cmd_set_trigger(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int intparam, char *charparam, char *argument, char *retBuf) {
+ char *trigger;
+ //get current trigger
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ printf_mysql_query("SELECT `trigger`, `defaulttrigger` FROM `bot_channels` LEFT JOIN `bots` ON `botid` = `bots`.`id` WHERE `chanid` = '%d' AND `botid` = '%d'", chan->channel_id, client->clientid);
+ res = mysql_use();
+ row = mysql_fetch_row(res);
+ trigger = (row[0] ? row[0] : row[1]);
+ if(argument) {
+ int uaccess = getChannelAccess(user, chan);
+ if(uaccess < 500) {
+ if(isGodMode(user)) {
+ event->flags |= CMDFLAG_OPLOG;
+ } else {
+ 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);
+ logEvent(event);
+ }
+ return trigger;
+}
+
+static char* neonspam_cmd_setflags(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int flag, char *charparam, char *argument, char *retBuf) {
+ char *value = ((chan->spam_settings->flags & flag) ? "1" : "0");
+ if(argument) {
+ //binary argument...
+ if(!strcmp(argument, "0") || !stricmp(argument, "off") || !stricmp(argument, get_language_string(user, "NS_SET_OFF"))) {
+ chan->spam_settings->flags &= ~flag;
+ } else if(!strcmp(argument, "1") || !stricmp(argument, "on") || !stricmp(argument, get_language_string(user, "NS_SET_ON"))) {
+ chan->spam_settings->flags |= flag;
+ } else {
+ reply(getTextBot(), user, "NS_SET_INVALID_BOOLEAN", argument);
+ return NULL;
+ }
+ char str_flags[50];
+ convertNeonSpamSettingsToString(chan->spam_settings->flags, str_flags);
+ printf_mysql_query("UPDATE `channels` SET `channel_scanner` = '%s' WHERE `channel_id` = '%d' ", str_flags, chan->channel_id);
+ value = argument;
+ }
+ return value;
+}
+
+static char* neonspam_cmd_setexcept(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int exceptlvl_index, char *field, char *argument, char *retBuf) {
+ unsigned int value = chan->spam_settings->exceptlevel[exceptlvl_index];
+ if(argument) {
+ //numeric argument... (access)
+ int caccess = atoi(argument);
+ if(caccess < 0 || caccess > 501) {
+ reply(getTextBot(), user, "NS_INVALID_ACCESS", caccess);
+ return NULL;
+ }
+ int uaccess = getChannelAccess(user, chan);
+ if(uaccess == 500) uaccess++;
+ if(value > uaccess) {
+ if(isGodMode(user)) {
+ event->flags |= CMDFLAG_OPLOG;
+ } else {
+ reply(getTextBot(), user, "NS_SET_CANNOT_SET");
+ return NULL;
+ }
+ }
+ if(caccess > uaccess) {
+ if(isGodMode(user)) {
+ event->flags |= CMDFLAG_OPLOG;
+ } else {
+ reply(getTextBot(), user, "NS_SET_BADLEVEL");
+ return NULL;
+ }
+ }
+ value = caccess;
+ chan->spam_settings->exceptlevel[exceptlvl_index] = value;
+ printf_mysql_query("UPDATE `channels` SET `%s` = '%u' WHERE `channel_id` = '%d' ", field, value, chan->channel_id);
+ }
+ sprintf(retBuf, "%u", value);
+ return retBuf;
+}
+
+static char* neonspam_cmd_set_reaction(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int mysqlindex, char *mysqlfield, char *argument, char *retBuf) {
+ if(argument) {
+ /* valid options:
+ * 0/kick - kick
+ * 1/kickban - kickban
+ * 2/ban - timed ban
+ */
+ if(!strcmp(argument, "0") || !stricmp(argument, "kick")) {
+ argument = "0";
+ } else if(!strcmp(argument, "1") || !stricmp(argument, "kickban")) {
+ argument = "1";
+ } else if(!strcmp(argument, "2") || !stricmp(argument, "ban")) {
+ argument = "2";
+ } else {
+ reply(getTextBot(), user, "NS_SET_INVALID_OPTION_STR", argument);
+ return NULL;
+ }
+ printf_mysql_query("UPDATE `channels` SET `%s` = '%s' WHERE `channel_id` = '%d' ", mysqlfield, argument, chan->channel_id);
+ return argument;
+ } else {
+ if(neonspam_settings_row) {
+ return (neonspam_settings_row[mysqlindex] ? neonspam_settings_row[mysqlindex] : neonspam_settings_defaults[mysqlindex]);
+ } else {
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ printf_mysql_query("SELECT `%s` FROM `channels` WHERE `channel_id` = '%d'", mysqlfield, chan->channel_id);
+ res = mysql_use();
+ row = mysql_fetch_row(res);
+ return row[0];
+ }
+ }
+}
+
+static char* neonspam_cmd_set_reaction_time(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int mysqlindex, char *mysqlfield, char *argument, char *retBuf) {
+ int duration;
+ if(argument) {
+ duration = strToTime(user, argument);
+ if(duration < 30) {
+ reply(getTextBot(), user, "NS_TIMEBAN_DURATION_TOO_SHORT", 30);
+ return NULL;
+ }
+ printf_mysql_query("UPDATE `channels` SET `%s` = '%s' WHERE `channel_id` = '%d' ", mysqlfield, argument, chan->channel_id);
+ } else {
+ if(neonspam_settings_row) {
+ duration = atoi(neonspam_settings_row[mysqlindex] ? neonspam_settings_row[mysqlindex] : neonspam_settings_defaults[mysqlindex]);
+ } else {
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ printf_mysql_query("SELECT `%s` FROM `channels` WHERE `channel_id` = '%d'", mysqlfield, chan->channel_id);
+ res = mysql_use();
+ row = mysql_fetch_row(res);
+ duration = atoi(row[0]);
+ }
+ }
+ timeToStr(user, duration, 3, retBuf);
+ return retBuf;
+}
+
+static char* neonspam_cmd_setpercent(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int percent_index, char *mysqlfield, char *argument, char *retBuf) {
+ unsigned int value = chan->spam_settings->percent[percent_index];
+ if(argument) {
+ //numeric argument... (access)
+ value = atoi(argument);
+ if(value < 0 || value > 100) {
+ //invalid percent value
+ reply(getTextBot(), user, "SS_SET_PERCENT", value);
+ return NULL;
+ }
+ chan->spam_settings->percent[percent_index] = value;
+ printf_mysql_query("UPDATE `channels` SET `%s` = '%u' WHERE `channel_id` = '%d' ", mysqlfield, value, chan->channel_id);
+ }
+ sprintf(retBuf, "%u", value);
+ return retBuf;
+}
+
+static char* neonspam_cmd_setsensibility(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int sensibility_index, char *mysqlfield, char *argument, char *retBuf) {
+ if(argument) {
+ //change value
+ char *delimiter = strstr(argument, ":");
+ if(!delimiter) {
+ //invalid format
+ reply(getTextBot(), user, "SS_SET_SENSIBILITY", argument);
+ return NULL;
+ }
+ *delimiter = '\0';
+ delimiter++;
+ int amount = atoi(argument);
+ int timep = atoi(delimiter);
+ if(amount > MAX_FLOOD_AMOUNT || amount < MIN_FLOOD_AMOUNT) {
+ //invalid amount
+ reply(getTextBot(), user, "SS_SET_SENSIBILITY_AMOUNT", amount, MIN_FLOOD_AMOUNT, MAX_FLOOD_AMOUNT);
+ return NULL;
+ }
+ if(timep > MAX_FLOOD_TIME || timep < 0) {
+ //invalid time period
+ reply(getTextBot(), user, "SS_SET_SENSIBILITY_TIME", timep, 0, MAX_FLOOD_TIME);
+ return NULL;
+ }
+ char amountfield[50], timefield[50];
+ sprintf(amountfield, "%s%s", mysqlfield, "limit");
+ sprintf(timefield, "%s%s", mysqlfield, "time");
+ printf_mysql_query("UPDATE `channels` SET `%s` = '%d', `%s` = '%d' WHERE `channel_id` = '%d' ", amountfield, amount, timefield, timep, chan->channel_id);
+ sprintf(retBuf, "%d:%d", amount, timep);
+ chan->spam_settings->sensibility_amount[sensibility_index] = amount;
+ chan->spam_settings->sensibility_time[sensibility_index] = timep;
+ } else {
+ sprintf(retBuf, "%d:%d", chan->spam_settings->sensibility_amount[sensibility_index], chan->spam_settings->sensibility_time[sensibility_index]);
+ }
+ return retBuf;
+}
+
+static char* neonspam_cmd_set_spamlimit(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int intparam, char *charparam, char *argument, char *retBuf) {
+ if(argument) {
+ //change value
+ int amount = atoi(argument);
+ if(amount > 10 || amount < 2) {
+ //invalid amount
+ reply(getTextBot(), user, "SS_SET_SPAMLIMIT", amount, 2, 10);
+ return NULL;
+ }
+ printf_mysql_query("UPDATE `channels` SET `channel_maxrepeat` = '%d' WHERE `channel_id` = '%d' ", amount, chan->channel_id);
+ sprintf(retBuf, "%d", amount);
+ chan->spam_settings->spam_amount = amount;
+ } else
+ sprintf(retBuf, "%d", chan->spam_settings->spam_amount);
+ return retBuf;
+}
+
+static char* neonspam_cmd_setscanops(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int flag, char *charparam, char *argument, char *retBuf) {
+ int i = 0;
+ int value = -1;
+ int identical = 1;
+ while(neonspam_settings[i].setting) {
+ if(neonspam_settings[i].flags & SET_SCANOPS) {
+ if(value == -1)
+ value = ((chan->spam_settings->flags & neonspam_settings[i].intparam) ? 1 : 0);
+ else {
+ if(((chan->spam_settings->flags & neonspam_settings[i].intparam) ? 1 : 0) != value) {
+ identical = 0;
+ break;
+ }
+ }
+ }
+ i++;
+ }
+ if(argument) {
+ //binary argument...
+ if(!strcmp(argument, "0") || !stricmp(argument, "off") || !stricmp(argument, get_language_string(user, "NS_SET_OFF"))) {
+ value = 0;
+ } else if(!strcmp(argument, "1") || !stricmp(argument, "on") || !stricmp(argument, get_language_string(user, "NS_SET_ON"))) {
+ value = 1;
+ } else {
+ reply(getTextBot(), user, "NS_SET_INVALID_BOOLEAN", argument);
+ return NULL;
+ }
+ i = 0;
+ char valueBuf[MAXLEN];
+ while(neonspam_settings[i].setting) {
+ if(neonspam_settings[i].flags & SET_SCANOPS) {
+ neonspam_cmd_set_function *func = neonspam_settings[i].function;
+ func(client, user, chan, event, neonspam_settings[i].intparam, neonspam_settings[i].charparam, (value ? "1" : "0"), valueBuf);
+ }
+ i++;
+ }
+ identical = 1;
+ }
+ if(identical && value)
+ return "1";
+ if(identical && !value)
+ return "0";
+ return "?";
+}
+
+static char* neonspam_cmd_setscanvoice(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int flag, char *charparam, char *argument, char *retBuf) {
+ int i = 0;
+ int value = -1;
+ int identical = 1;
+ while(neonspam_settings[i].setting) {
+ if(neonspam_settings[i].flags & SET_SCANVOICE) {
+ if(value == -1)
+ value = ((chan->spam_settings->flags & neonspam_settings[i].intparam) ? 1 : 0);
+ else {
+ if(((chan->spam_settings->flags & neonspam_settings[i].intparam) ? 1 : 0) != value) {
+ identical = 0;
+ break;
+ }
+ }
+ }
+ i++;
+ }
+ if(argument) {
+ //binary argument...
+ if(!strcmp(argument, "0") || !stricmp(argument, "off") || !stricmp(argument, get_language_string(user, "NS_SET_OFF"))) {
+ value = 0;
+ } else if(!strcmp(argument, "1") || !stricmp(argument, "on") || !stricmp(argument, get_language_string(user, "NS_SET_ON"))) {
+ value = 1;
+ } else {
+ reply(getTextBot(), user, "NS_SET_INVALID_BOOLEAN", argument);
+ return NULL;
+ }
+ i = 0;
+ char valueBuf[MAXLEN];
+ while(neonspam_settings[i].setting) {
+ if(neonspam_settings[i].flags & SET_SCANVOICE) {
+ neonspam_cmd_set_function *func = neonspam_settings[i].function;
+ func(client, user, chan, event, neonspam_settings[i].intparam, neonspam_settings[i].charparam, (value ? "1" : "0"), valueBuf);
+ }
+ i++;
+ }
+ identical = 1;
+ }
+ if(identical && value)
+ return "1";
+ if(identical && !value)
+ return "0";
+ return "?";
+}
+
+static char* neonspam_cmd_setscanexcept(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int flag, char *charparam, char *argument, char *retBuf) {
+ int i = 0;
+ int value = -1;
+ int identical = 1;
+ while(neonspam_settings[i].setting) {
+ if(neonspam_settings[i].flags & SET_SCANEXCEPT) {
+ if(value == -1)
+ value = chan->spam_settings->exceptlevel[neonspam_settings[i].intparam];
+ else {
+ if(chan->spam_settings->exceptlevel[neonspam_settings[i].intparam] != value) {
+ identical = 0;
+ break;
+ }
+ }
+ }
+ i++;
+ }
+ if(argument) {
+ //numeric argument... (access)
+ int caccess = atoi(argument);
+ if(caccess < 0 || caccess > 501) {
+ reply(getTextBot(), user, "NS_INVALID_ACCESS", caccess);
+ return NULL;
+ }
+ int uaccess = getChannelAccess(user, chan);
+ if(uaccess == 500) uaccess++;
+ if(identical && value > uaccess) {
+ if(isGodMode(user)) {
+ event->flags |= CMDFLAG_OPLOG;
+ } else {
+ reply(getTextBot(), user, "NS_SET_CANNOT_SET");
+ return NULL;
+ }
+ }
+ if(caccess > uaccess) {
+ if(isGodMode(user)) {
+ event->flags |= CMDFLAG_OPLOG;
+ } else {
+ reply(getTextBot(), user, "NS_SET_BADLEVEL");
+ return NULL;
+ }
+ }
+ i = 0;
+ char valueBuf[MAXLEN];
+ sprintf(retBuf, "%d", caccess);
+ while(neonspam_settings[i].setting) {
+ if(neonspam_settings[i].flags & SET_SCANEXCEPT) {
+ neonspam_cmd_set_function *func = neonspam_settings[i].function;
+ func(client, user, chan, event, neonspam_settings[i].intparam, neonspam_settings[i].charparam, retBuf, valueBuf);
+ }
+ i++;
+ }
+ identical = 1;
+ value = caccess;
+ }
+ if(identical) {
+ sprintf(retBuf, "%d", value);
+ return retBuf;
+ }
+ return "?";
+}
+
+#undef MAX_QUERY_LEN
--- /dev/null
+/* event_neonspam_chanmsg.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+static int neonspam_spamscan(struct NeonSpamSettings *settings, struct ChanUser *chanuser, char *message);
+static int neonspam_floodscan(struct NeonSpamSettings *settings, struct ChanUser *chanuser);
+static int neonspam_botnetscan(struct ClientSocket *client, struct NeonSpamSettings *settings, struct ChanUser *chanuser, char *message);
+static int neonspam_capsscan(struct NeonSpamSettings *settings, struct ChanUser *chanuser, char *message);
+static int neonspam_digitscan(struct NeonSpamSettings *settings, struct ChanUser *chanuser, char *message);
+
+static USERAUTH_CALLBACK(neonspam_event_chanmsg_nick_lookup);
+static void neonspam_event_chanmsg_punish(struct ClientSocket *client, struct ChanUser *chanuser, struct NeonSpamSettings *settings, unsigned int warn, unsigned int punish);
+
+struct neonspam_event_chanmsg_cache {
+ struct ClientSocket *client;
+ struct ChanUser *chanuser;
+ struct NeonSpamSettings *settings;
+ unsigned int warn;
+ unsigned int punish;
+};
+
+
+
+static void neonspam_event_chanmsg(struct UserNode *user, struct ChanNode *chan, char *message) {
+ struct ClientSocket *client = getChannelBot(chan, BOTID);
+ if(!client || (user->flags & USERFLAG_ISBOT)) return; //we can't "see" this event
+ loadNeonSpamSettings(chan);
+ struct NeonSpamSettings *settings = chan->spam_settings;
+ struct ChanUser *chanuser = getChanUser(user, chan);
+ if(!settings || !chanuser) return;
+ #define NEONSPAM_CHANMSG_DO_SCANOPS(FLAG) ((settings->flags & FLAG) || !(chanuser->flags & CHANUSERFLAG_OPPED))
+ #define NEONSPAM_CHANMSG_DO_SCANVOICE(FLAG) ((settings->flags & FLAG) || !(chanuser->flags & CHANUSERFLAG_VOICED))
+ #define NEONSPAM_CHANMSG_DO_EXCEPT(INDEX) (settings->exceptlevel[INDEX] != 0)
+ #define NEONSPAM_CHANMSG_NEED_WHO(INDEX) (settings->exceptlevel[INDEX] != 501)
+ //scan the message
+ int result = 0;
+ unsigned int warn = 0;
+ unsigned int punish = 0;
+ int needwho = 0;
+ if((settings->flags & SPAMSETTINGS_SPAMSCAN) && NEONSPAM_CHANMSG_DO_SCANOPS(SPAMSETTINGS_SPAMSCAN_OPS) && NEONSPAM_CHANMSG_DO_SCANVOICE(SPAMSETTINGS_SPAMSCAN_VOICE) && NEONSPAM_CHANMSG_DO_EXCEPT(SPAMSETTINGS_SPAMEXCINDEX)) {
+ result = neonspam_spamscan(settings, chanuser, message);
+ switch(result) {
+ case SPAMSERV_CHECK_IGNORE:
+ break;
+ case SPAMSERV_CHECK_WARN:
+ warn |= SPAMSETTINGS_SPAMSCAN;
+ if(NEONSPAM_CHANMSG_NEED_WHO(SPAMSETTINGS_SPAMEXCINDEX))
+ needwho = 1;
+ break;
+ case SPAMSERV_CHECK_PUNISH:
+ punish |= SPAMSETTINGS_SPAMSCAN;
+ if(NEONSPAM_CHANMSG_NEED_WHO(SPAMSETTINGS_SPAMEXCINDEX))
+ needwho = 1;
+ break;
+ }
+ }
+ if((settings->flags & SPAMSETTINGS_FLOODSCAN) && NEONSPAM_CHANMSG_DO_SCANOPS(SPAMSETTINGS_FLOODSCAN_OPS) && NEONSPAM_CHANMSG_DO_SCANVOICE(SPAMSETTINGS_FLOODSCAN_VOICE) && NEONSPAM_CHANMSG_DO_EXCEPT(SPAMSETTINGS_FLOODEXCINDEX)) {
+ result = neonspam_floodscan(settings, chanuser);
+ switch(result) {
+ case SPAMSERV_CHECK_IGNORE:
+ break;
+ case SPAMSERV_CHECK_WARN:
+ warn |= SPAMSETTINGS_FLOODSCAN;
+ if(NEONSPAM_CHANMSG_NEED_WHO(SPAMSETTINGS_FLOODEXCINDEX))
+ needwho = 1;
+ break;
+ case SPAMSERV_CHECK_PUNISH:
+ punish |= SPAMSETTINGS_FLOODSCAN;
+ if(NEONSPAM_CHANMSG_NEED_WHO(SPAMSETTINGS_FLOODEXCINDEX))
+ needwho = 1;
+ break;
+ }
+ }
+ if((settings->flags & SPAMSETTINGS_BOTNETSCAN) && NEONSPAM_CHANMSG_DO_SCANOPS(SPAMSETTINGS_BOTNETSCAN_OPS) && NEONSPAM_CHANMSG_DO_SCANVOICE(SPAMSETTINGS_BOTNETSCAN_VOICE)) {
+ result = neonspam_botnetscan(client, settings, chanuser, message);
+ switch(result) {
+ case SPAMSERV_CHECK_DEAD:
+ return;
+ case SPAMSERV_CHECK_IGNORE:
+ break;
+ }
+ }
+ if((settings->flags & SPAMSETTINGS_CAPSSCAN) && NEONSPAM_CHANMSG_DO_SCANOPS(SPAMSETTINGS_CAPSSCAN_OPS) && NEONSPAM_CHANMSG_DO_SCANVOICE(SPAMSETTINGS_CAPSSCAN_VOICE) && NEONSPAM_CHANMSG_DO_EXCEPT(SPAMSETTINGS_CAPSEXCINDEX)) {
+ result = neonspam_capsscan(settings, chanuser, message);
+ switch(result) {
+ case SPAMSERV_CHECK_IGNORE:
+ break;
+ case SPAMSERV_CHECK_WARN:
+ warn |= SPAMSETTINGS_CAPSSCAN;
+ if(NEONSPAM_CHANMSG_NEED_WHO(SPAMSETTINGS_CAPSEXCINDEX))
+ needwho = 1;
+ break;
+ case SPAMSERV_CHECK_PUNISH:
+ punish |= SPAMSETTINGS_CAPSSCAN;
+ if(NEONSPAM_CHANMSG_NEED_WHO(SPAMSETTINGS_CAPSEXCINDEX))
+ needwho = 1;
+ break;
+ }
+ }
+ if((settings->flags & SPAMSETTINGS_DIGITSCAN) && NEONSPAM_CHANMSG_DO_SCANOPS(SPAMSETTINGS_DIGITSCAN_OPS) && NEONSPAM_CHANMSG_DO_SCANVOICE(SPAMSETTINGS_DIGITSCAN_VOICE) && NEONSPAM_CHANMSG_DO_EXCEPT(SPAMSETTINGS_DIGITEXCINDEX)) {
+ result = neonspam_digitscan(settings, chanuser, message);
+ switch(result) {
+ case SPAMSERV_CHECK_IGNORE:
+ break;
+ case SPAMSERV_CHECK_WARN:
+ warn |= SPAMSETTINGS_DIGITSCAN;
+ if(NEONSPAM_CHANMSG_NEED_WHO(SPAMSETTINGS_DIGITEXCINDEX))
+ needwho = 1;
+ break;
+ case SPAMSERV_CHECK_PUNISH:
+ punish |= SPAMSETTINGS_DIGITSCAN;
+ if(NEONSPAM_CHANMSG_NEED_WHO(SPAMSETTINGS_DIGITEXCINDEX))
+ needwho = 1;
+ break;
+ }
+ }
+ //some other checks?
+
+ if(warn || punish) {
+ //whois the user to check against exceptlevel
+ if(!needwho || (user->flags & USERFLAG_ISAUTHED)) {
+ neonspam_event_chanmsg_punish(client, chanuser, settings, warn, punish);
+ } else {
+ struct neonspam_event_chanmsg_cache *cache = malloc(sizeof(*cache));
+ if (!cache) {
+ perror("malloc() failed");
+ return;
+ }
+ cache->client = client;
+ cache->chanuser = chanuser;
+ cache->settings = settings;
+ cache->warn = warn;
+ cache->punish = punish;
+ get_userauth(user, neonspam_event_chanmsg_nick_lookup, cache);
+ }
+
+ }
+ #undef NEONSPAM_CHANMSG_DO_SCANOPS
+ #undef NEONSPAM_CHANMSG_DO_SCANVOICE
+ #undef NEONSPAM_CHANMSG_DO_EXCEPT
+ #undef NEONSPAM_CHANMSG_NEED_WHO
+}
+
+static USERAUTH_CALLBACK(neonspam_event_chanmsg_nick_lookup) {
+ struct neonspam_event_chanmsg_cache *cache = data;
+ neonspam_event_chanmsg_punish(cache->client, cache->chanuser, cache->settings, cache->warn, cache->punish);
+ free(cache);
+}
+
+static void neonspam_event_chanmsg_punish(struct ClientSocket *client, struct ChanUser *chanuser, struct NeonSpamSettings *settings, unsigned int warn, unsigned int punish) {
+ MYSQL_RES *res;
+ MYSQL_ROW row, defaults;
+ loadChannelSettings(chanuser->chan);
+ int uaccess = 0;
+ if(chanuser->user->flags & USERFLAG_ISAUTHED)
+ uaccess = getChannelAccess(chanuser->user, chanuser->chan);
+ char reason[MAXLEN];
+ reason[0] = '\0';
+ int punishment = 0;
+ int punish_time = 0;
+ if(!punishment && (punish & SPAMSETTINGS_SPAMSCAN) && settings->exceptlevel[SPAMSETTINGS_SPAMEXCINDEX] > uaccess) {
+ printf_mysql_query("SELECT `channel_spam_reaction`, `channel_spam_reaction_duration` FROM `channels` WHERE `channel_id` = '%d'", chanuser->chan->channel_id);
+ res = mysql_use();
+ row = mysql_fetch_row(res);
+ if(!row[0] || !row[1]) {
+ printf_mysql_query("SELECT `channel_spam_reaction`, `channel_spam_reaction_duration` FROM `channels` WHERE `channel_name` = 'defaults'");
+ res = mysql_use();
+ defaults = mysql_fetch_row(res);
+ }
+ sprintf(reason, SPAMSERV_MSG_WARNING, SPAMSERV_MSG_SPAM);
+ punishment = atoi((row[0] ? row[0] : defaults[0])) + 1;
+ punish_time = atoi((row[1] ? row[1] : defaults[1]));
+ }
+ if(!punishment && (punish & SPAMSETTINGS_FLOODSCAN) && settings->exceptlevel[SPAMSETTINGS_FLOODEXCINDEX] > uaccess) {
+ printf_mysql_query("SELECT `channel_flood_reaction`, `channel_flood_reaction_duration` FROM `channels` WHERE `channel_id` = '%d'", chanuser->chan->channel_id);
+ res = mysql_use();
+ row = mysql_fetch_row(res);
+ if(!row[0] || !row[1]) {
+ printf_mysql_query("SELECT `channel_flood_reaction`, `channel_flood_reaction_duration` FROM `channels` WHERE `channel_name` = 'defaults'");
+ res = mysql_use();
+ defaults = mysql_fetch_row(res);
+ }
+ sprintf(reason, SPAMSERV_MSG_WARNING, SPAMSERV_MSG_FLOOD);
+ punishment = atoi((row[0] ? row[0] : defaults[0])) + 1;
+ punish_time = atoi((row[1] ? row[1] : defaults[1]));
+ }
+ if(!punishment && (punish & SPAMSETTINGS_CAPSSCAN) && settings->exceptlevel[SPAMSETTINGS_CAPSEXCINDEX] > uaccess) {
+ printf_mysql_query("SELECT `channel_caps_reaction`, `channel_caps_reaction_duration` FROM `channels` WHERE `channel_id` = '%d'", chanuser->chan->channel_id);
+ res = mysql_use();
+ row = mysql_fetch_row(res);
+ if(!row[0] || !row[1]) {
+ printf_mysql_query("SELECT `channel_caps_reaction`, `channel_caps_reaction_duration` FROM `channels` WHERE `channel_name` = 'defaults'");
+ res = mysql_use();
+ defaults = mysql_fetch_row(res);
+ }
+ sprintf(reason, SPAMSERV_MSG_WARNING, SPAMSERV_MSG_CAPS);
+ punishment = atoi((row[0] ? row[0] : defaults[0])) + 1;
+ punish_time = atoi((row[1] ? row[1] : defaults[1]));
+ }
+ if(!punishment && (punish & SPAMSETTINGS_DIGITSCAN) && settings->exceptlevel[SPAMSETTINGS_DIGITEXCINDEX] > uaccess) {
+ printf_mysql_query("SELECT `channel_digit_reaction`, `channel_digit_reaction_duration` FROM `channels` WHERE `channel_id` = '%d'", chanuser->chan->channel_id);
+ res = mysql_use();
+ row = mysql_fetch_row(res);
+ if(!row[0] || !row[1]) {
+ printf_mysql_query("SELECT `channel_digit_reaction`, `channel_digit_reaction_duration` FROM `channels` WHERE `channel_name` = 'defaults'");
+ res = mysql_use();
+ defaults = mysql_fetch_row(res);
+ }
+ sprintf(reason, SPAMSERV_MSG_WARNING, SPAMSERV_MSG_DIGIT);
+ punishment = atoi((row[0] ? row[0] : defaults[0])) + 1;
+ punish_time = atoi((row[1] ? row[1] : defaults[1]));
+ }
+ if(!punishment && (warn & SPAMSETTINGS_SPAMSCAN) && settings->exceptlevel[SPAMSETTINGS_SPAMEXCINDEX] > uaccess) {
+ sprintf(reason, SPAMSERV_MSG_WARNING, SPAMSERV_MSG_SPAM);
+ }
+ if(!punishment && (warn & SPAMSETTINGS_FLOODSCAN) && settings->exceptlevel[SPAMSETTINGS_FLOODEXCINDEX] > uaccess) {
+ sprintf(reason, SPAMSERV_MSG_WARNING, SPAMSERV_MSG_FLOOD);
+ }
+ if(!punishment && (warn & SPAMSETTINGS_CAPSSCAN) && settings->exceptlevel[SPAMSETTINGS_CAPSEXCINDEX] > uaccess) {
+ sprintf(reason, SPAMSERV_MSG_WARNING, SPAMSERV_MSG_CAPS);
+ }
+ if(!punishment && (warn & SPAMSETTINGS_DIGITSCAN) && settings->exceptlevel[SPAMSETTINGS_DIGITEXCINDEX] > uaccess) {
+ sprintf(reason, SPAMSERV_MSG_WARNING, SPAMSERV_MSG_DIGIT);
+ }
+ if(punishment) {
+ char banmaskBuf[NICKLEN+USERLEN+HOSTLEN+3];
+ char *banmask = NULL;
+ switch (punishment) {
+ case 3: //TIMEBAN
+ banmask = generate_banmask(chanuser->user, banmaskBuf);
+ printf_mysql_query("INSERT INTO `bans` (`ban_channel`, `ban_mask`, `ban_triggered`, `ban_timeout`, `ban_owner`, `ban_reason`) VALUES ('%d', '%s', UNIX_TIMESTAMP(), '%lu', '%d', '%s')", chanuser->chan->channel_id, escape_string(banmask), (unsigned long) (punish_time ? (time(0) + punish_time) : 0), 0, escape_string(reason));
+ if(punish_time) {
+ int banid = (int) mysql_insert_id(get_mysql_conn());
+ char nameBuf[MAXLEN];
+ char banidBuf[20];
+ sprintf(nameBuf, "ban_%d", banid);
+ sprintf(banidBuf, "%d", banid);
+ timeq_add_name(nameBuf, punish_time, channel_ban_timeout, strdup(banidBuf));
+ }
+ case 2: //KICKBAN
+ if(!banmask)
+ banmask = generate_banmask(chanuser->user, banmaskBuf);
+ putsock(client, "MODE %s +b %s", chanuser->chan->name, banmask);
+ case 1: //KICK
+ putsock(client, "KICK %s %s :%s", chanuser->chan->name, chanuser->user->nick, reason);
+ break;
+ }
+ } else if(*reason)
+ reply(client, chanuser->user, "%s", reason);
+}
+
+static int neonspam_spamscan(struct NeonSpamSettings *settings, struct ChanUser *chanuser, char *message) {
+ //crc32 hash of the message
+ unsigned long msghash = crc32(message);
+ if(chanuser->spamnode) {
+ if(chanuser->spamnode->lastmsg == msghash) {
+ chanuser->spamnode->spamcount++;
+ if(chanuser->spamnode->spamcount == settings->spam_amount)
+ return SPAMSERV_CHECK_WARN;
+ else if(chanuser->spamnode->spamcount > settings->spam_amount)
+ return SPAMSERV_CHECK_PUNISH;
+ else
+ return SPAMSERV_CHECK_IGNORE;
+ }
+ } else
+ createSpamNode(chanuser);
+ chanuser->spamnode->lastmsg = msghash;
+ chanuser->spamnode->spamcount = 1;
+ return SPAMSERV_CHECK_IGNORE;
+}
+
+static int neonspam_update_penalty(struct NeonSpamSettings *settings, struct ChanUser *chanuser, int addmsg) {
+ int last_update = time(0) - chanuser->spamnode->last_penalty_update;
+ if(last_update) {
+ if(last_update < MAX_FLOOD_TIME && chanuser->spamnode->floodpenalty) {
+ chanuser->spamnode->floodpenalty -= last_update * (MAX_FLOOD_TIME / settings->sensibility_time[SPAMSETTINGS_FLOODSENINDEX]);
+ if(chanuser->spamnode->floodpenalty < 0)
+ chanuser->spamnode->floodpenalty = 0;
+ } else
+ chanuser->spamnode->floodpenalty = 0;
+ chanuser->spamnode->last_penalty_update = time(0);
+ }
+ chanuser->spamnode->floodpenalty += MAX_FLOOD_TIME * addmsg;
+ return chanuser->spamnode->floodpenalty / MAX_FLOOD_TIME + ((chanuser->spamnode->floodpenalty % MAX_FLOOD_TIME) ? 1 : 0);
+}
+
+static int neonspam_floodscan(struct NeonSpamSettings *settings, struct ChanUser *chanuser) {
+ if(!chanuser->spamnode)
+ createSpamNode(chanuser);
+ int messages_pending = neonspam_update_penalty(settings, chanuser, 1);
+ if(messages_pending == settings->sensibility_amount[SPAMSETTINGS_FLOODSENINDEX])
+ return SPAMSERV_CHECK_WARN;
+ else if(messages_pending > settings->sensibility_amount[SPAMSETTINGS_FLOODSENINDEX])
+ return SPAMSERV_CHECK_PUNISH;
+ else
+ return SPAMSERV_CHECK_IGNORE;
+}
+
+static int neonspam_botnetscan(struct ClientSocket *client, struct NeonSpamSettings *settings, struct ChanUser *chanuser, char *message) {
+ //crc32 hash of the message
+ unsigned long msghash = crc32(message);
+ if((time(0) - settings->lastmsg_time) > BOTNETSCAN_TIME || settings->lastmsg != msghash) {
+ int i;
+ for(i = 0; i < BOTNETSCAN_USERS; i++) {
+ if(settings->botnicks[i]) {
+ free(settings->botnicks[i]);
+ settings->botnicks[i] = NULL;
+ }
+ }
+ settings->flags &= ~SPAMSETTINGS_KICKEDBOTQUEUE;
+ settings->lastmsg = msghash;
+ } else if(settings->lastmsg == msghash) {
+ int i;
+ for(i = 0; i < BOTNETSCAN_USERS; i++) {
+ if(!settings->botnicks[i]) {
+ settings->botnicks[i] = strdup(chanuser->user->nick);
+ break;
+ } else if(!stricmp(chanuser->user->nick, settings->botnicks[i])) {
+ return SPAMSERV_CHECK_IGNORE;
+ }
+ }
+ if(i == BOTNETSCAN_USERS) {
+ //BOTNETSCAN_USERS exceeded
+ if(!(settings->flags & SPAMSETTINGS_KICKEDBOTQUEUE)) {
+ for(i = 0; i < BOTNETSCAN_USERS; i++) {
+ putsock(client, "KICK %s %s :%s", chanuser->chan->name, settings->botnicks[i], SPAMSERV_MSG_BOTNET);
+ }
+ settings->flags |= SPAMSETTINGS_KICKEDBOTQUEUE;
+ }
+ putsock(client, "KICK %s %s :%s", chanuser->chan->name, chanuser->user->nick, SPAMSERV_MSG_BOTNET);
+ return SPAMSERV_CHECK_DEAD;
+ }
+ }
+ settings->lastmsg_time = time(0);
+ return SPAMSERV_CHECK_IGNORE;
+}
+
+static int neonspam_capsscan(struct NeonSpamSettings *settings, struct ChanUser *chanuser, char *message) {
+ int caps = 0, msglen = strlen(message);
+ int i;
+ if(msglen <= 4) return SPAMSERV_CHECK_IGNORE;
+ for(i = 0; i < msglen; i++) {
+ if(isupper(message[i])) caps++;
+ }
+ caps = 100*caps/msglen;
+ if(caps >= settings->percent[SPAMSETTINGS_CAPSPERCENTINDEX]) {
+ if(!chanuser->spamnode)
+ createSpamNode(chanuser);
+ if(chanuser->spamnode->flags & NEONSPAMNODE_FLAG_CAPSSCAN_WARNED)
+ return SPAMSERV_CHECK_PUNISH;
+ else {
+ chanuser->spamnode->flags |= NEONSPAMNODE_FLAG_CAPSSCAN_WARNED;
+ return SPAMSERV_CHECK_WARN;
+ }
+ }
+ return SPAMSERV_CHECK_IGNORE;
+}
+
+static int neonspam_digitscan(struct NeonSpamSettings *settings, struct ChanUser *chanuser, char *message) {
+ int digit = 0, msglen = strlen(message);
+ int i;
+ if(msglen <= 4) return SPAMSERV_CHECK_IGNORE;
+ for(i = 0; i < msglen; i++) {
+ if(isdigit(message[i])) digit++;
+ }
+ digit = 100*digit/msglen;
+ if(digit >= settings->percent[SPAMSETTINGS_DIGITPERCENTINDEX]) {
+ if(!chanuser->spamnode)
+ createSpamNode(chanuser);
+ if(chanuser->spamnode->flags & NEONSPAMNODE_FLAG_DIGITSCAN_WARNED)
+ return SPAMSERV_CHECK_PUNISH;
+ else {
+ chanuser->spamnode->flags |= NEONSPAMNODE_FLAG_DIGITSCAN_WARNED;
+ return SPAMSERV_CHECK_WARN;
+ }
+ }
+ return SPAMSERV_CHECK_IGNORE;
+}
+
--- /dev/null
+/* event_neonspam_join.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+static USERAUTH_CALLBACK(neonspam_event_join_nick_lookup);
+static void neonspam_event_join_punish(struct ClientSocket *client, struct ChanUser *chanuser, struct NeonSpamSettings *settings, int action);
+static int neonspam_joinfloodscan(struct NeonSpamSettings *settings, struct ChanUser *chanuser);
+
+struct neonspam_event_join_cache {
+ struct ClientSocket *client;
+ struct ChanUser *chanuser;
+ struct NeonSpamSettings *settings;
+ int action;
+};
+
+static void neonspam_event_join(struct ChanUser *chanuser) {
+ if(chanuser->user->flags & USERFLAG_WAS_REGISTRING) return;
+ struct ClientSocket *client = getChannelBot(chanuser->chan, BOTID);
+ if(!client) return; //we can't "see" this event
+ if(chanuser->user == client->user) {
+ requestOp(client->user, chanuser->chan);
+ return;
+ }
+ if(chanuser->user->flags & USERFLAG_ISBOT) return;
+ loadNeonSpamSettings(chanuser->chan);
+ struct NeonSpamSettings *settings = chanuser->chan->spam_settings;
+ if(!settings || !(settings->flags & SPAMSETTINGS_JOINSCAN)) return;
+ if(settings->exceptlevel[SPAMSETTINGS_JOINEXCINDEX] == 0) return;
+ int result = neonspam_joinfloodscan(settings, chanuser);
+ if(result != SPAMSERV_CHECK_IGNORE) {
+ //whois the user to check against exceptlevel
+ if((chanuser->user->flags & USERFLAG_ISAUTHED) || settings->exceptlevel[SPAMSETTINGS_JOINEXCINDEX] == 501) {
+ neonspam_event_join_punish(client, chanuser, settings, result);
+ } else {
+ struct neonspam_event_join_cache *cache = malloc(sizeof(*cache));
+ if (!cache) {
+ perror("malloc() failed");
+ return;
+ }
+ cache->client = client;
+ cache->chanuser = chanuser;
+ cache->settings = settings;
+ cache->action = result;
+ get_userauth(chanuser->user, neonspam_event_join_nick_lookup, cache);
+ }
+ }
+}
+
+static USERAUTH_CALLBACK(neonspam_event_join_nick_lookup) {
+ struct neonspam_event_join_cache *cache = data;
+ neonspam_event_join_punish(cache->client, cache->chanuser, cache->settings, cache->action);
+ free(cache);
+}
+
+static void neonspam_event_join_punish(struct ClientSocket *client, struct ChanUser *chanuser, struct NeonSpamSettings *settings, int action) {
+ int uaccess = 0;
+ if(chanuser->user->flags & USERFLAG_ISAUTHED)
+ uaccess = getChannelAccess(chanuser->user, chanuser->chan);
+ if(uaccess >= settings->exceptlevel[SPAMSETTINGS_JOINEXCINDEX]) return;
+ //scanops / scanvoiced
+ MYSQL_RES *res;
+ MYSQL_ROW row, defaults = NULL;
+ loadChannelSettings(chanuser->chan);
+ printf_mysql_query("SELECT `channel_flood_reaction`, `channel_flood_reaction_duration`, `channel_getop`, `channel_getvoice` FROM `channels` WHERE `channel_id` = '%d'", chanuser->chan->channel_id);
+ res = mysql_use();
+ row = mysql_fetch_row(res);
+ if(!row[0] || !row[1] || !row[2] || !row[3]) {
+ printf_mysql_query("SELECT `channel_flood_reaction`, `channel_flood_reaction_duration`, `channel_getop`, `channel_getvoice` FROM `channels` WHERE `channel_name` = 'defaults'");
+ res = mysql_use();
+ defaults = mysql_fetch_row(res);
+ }
+ if(!(settings->flags & SPAMSETTINGS_JOINSCAN_OPS) && uaccess >= atoi((row[2] ? row[2] : defaults[2]))) return;
+ if(!(settings->flags & SPAMSETTINGS_JOINSCAN_VOICE) && uaccess >= atoi((row[3] ? row[3] : defaults[3]))) return;
+ char reason[MAXLEN];
+ sprintf(reason, SPAMSERV_MSG_WARNING, SPAMSERV_MSG_JOINFLOOD);
+ if(action == SPAMSERV_CHECK_WARN) {
+ reply(client, chanuser->user, "%s", reason);
+ } else if(action == SPAMSERV_CHECK_PUNISH) {
+ int duration = atoi((row[1] ? row[1] : defaults[1]));
+ char banmaskBuf[NICKLEN+USERLEN+HOSTLEN+3];
+ char *banmask = NULL;
+ switch (atoi((row[0] ? row[0] : defaults[0]))) {
+ case 2: //TIMEBAN
+ banmask = generate_banmask(chanuser->user, banmaskBuf);
+ printf_mysql_query("INSERT INTO `bans` (`ban_channel`, `ban_mask`, `ban_triggered`, `ban_timeout`, `ban_owner`, `ban_reason`) VALUES ('%d', '%s', UNIX_TIMESTAMP(), '%lu', '%d', '%s')", chanuser->chan->channel_id, escape_string(banmask), (unsigned long) (duration ? (time(0) + duration) : 0), 0, escape_string(reason));
+ if(duration) {
+ int banid = (int) mysql_insert_id(get_mysql_conn());
+ char nameBuf[MAXLEN];
+ char banidBuf[20];
+ sprintf(nameBuf, "ban_%d", banid);
+ sprintf(banidBuf, "%d", banid);
+ timeq_add_name(nameBuf, duration, channel_ban_timeout, strdup(banidBuf));
+ }
+ case 1: //KICKBAN
+ if(!banmask)
+ banmask = generate_banmask(chanuser->user, banmaskBuf);
+ putsock(client, "MODE %s +b %s", chanuser->chan->name, banmask);
+ case 0: //KICK
+ putsock(client, "KICK %s %s :%s", chanuser->chan->name, chanuser->user->nick, reason);
+ break;
+ }
+ }
+}
+
+static int neonspam_update_join_penalty(struct NeonSpamSettings *settings, struct NeonSpamJoinNode *joinnode, int addjoin) {
+ int last_update = time(0) - joinnode->last_penalty_update;
+ if(last_update) {
+ if(last_update < MAX_JOIN_TIME && joinnode->joinpenalty) {
+ joinnode->joinpenalty -= last_update * (MAX_JOIN_TIME / settings->sensibility_time[SPAMSETTINGS_JOINSENINDEX]);
+ if(joinnode->joinpenalty < 0)
+ joinnode->joinpenalty = 0;
+ } else
+ joinnode->joinpenalty = 0;
+ joinnode->last_penalty_update = time(0);
+ }
+ joinnode->joinpenalty += MAX_JOIN_TIME * addjoin;
+ return joinnode->joinpenalty / MAX_JOIN_TIME + ((joinnode->joinpenalty % MAX_JOIN_TIME) ? 1 : 0);
+}
+
+static int neonspam_joinfloodscan(struct NeonSpamSettings *settings, struct ChanUser *chanuser) {
+ if(!chanuser->spamnode)
+ createSpamNode(chanuser);
+ int joins_pending = neonspam_update_join_penalty(settings, getNeonSpamJoinNode(chanuser), 1);
+ if(joins_pending == settings->sensibility_amount[SPAMSETTINGS_JOINSENINDEX])
+ return SPAMSERV_CHECK_WARN;
+ else if(joins_pending > settings->sensibility_amount[SPAMSETTINGS_JOINSENINDEX])
+ return SPAMSERV_CHECK_PUNISH;
+ else
+ return SPAMSERV_CHECK_IGNORE;
+}
+
+
--- /dev/null
+/* module.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "../module.h"
+#include "bot_NeonSpam.h"
+#include "cmd_neonspam.h"
+
+static int module_initialize() {
+ register_commands();
+ return 0;
+}
+
+static void module_start(int type) {
+ init_NeonSpam(type);
+}
+
+static void module_loop() {
+ loop_NeonSpam();
+}
+
+static void module_stop(int type) {
+ free_NeonSpam(type);
+}
+
+MODULE_HEADER(module_initialize, module_start, module_loop, module_stop);
--- /dev/null
+/* cmd_funcmds.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "../module.h"
+#include "cmd_funcmds.h"
+#include "modcmd.h"
+#include "mysqlConn.h"
+#include "IRCParser.h"
+#include "ClientSocket.h"
+#include "UserNode.h"
+#include "ChanNode.h"
+#include "lang.h"
+#include "tools.h"
+#include "DBHelper.h"
+
+static const struct default_language_entry msgtab[] = {
+ {"FUN_DICE", "$b%s$b: A $b%d$b shows on the %d-sided die."}, /* {ARGS: "TestUser", 5, 6} */
+ {"FUN_DICE_NUM", "I do not understand $b%s$b. Please use a single number above 1."}, /* {ARGS: "bla"} */
+ {"FUN_8BALL", "$b%s$b: %s"}, /* {ARGS: "TestUser", "Not a chance."} */
+ {"FUN_8BALL_REPLIES", "Not a chance.|In your dreams.|Absolutely!|Could be, could be.|No!"},
+ {"FUN_COOKIE", "gives %1$s a very big chocolate cookie. %1$s has got %2$d cookies until now (%3$d in this channel)."}, /* {ARGS: "TestUser", 20, 50} */
+ {NULL, NULL}
+};
+
+void init_funcmds() {
+ register_default_language_table(msgtab);
+ srand(time(NULL));
+}
+
+void register_commands() {
+ //Fun Commands
+ register_command_alias(3, "FunCMD");
+ #define USER_COMMAND(NAME,FUNCTION,PARAMCOUNT,FLAGS) register_command(3, NAME, FUNCTION, PARAMCOUNT, NULL, 0, FLAGS)
+ // NAME FUNCTION PARAMS FLAGS
+ USER_COMMAND("extscript", neonserv_cmd_extscript, 0, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_EMPTY_ARGS | CMDFLAG_CHAN_PARAM | CMDFLAG_FUNCMD);
+ USER_COMMAND("ping", funcmd_ping, 0, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_FUNCMD);
+ USER_COMMAND("pong", funcmd_pong, 0, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_FUNCMD);
+ USER_COMMAND("dice", funcmd_dice, 1, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_FUNCMD);
+ USER_COMMAND("8ball", funcmd_8ball, 1, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_FUNCMD);
+ USER_COMMAND("cookie", funcmd_cookie, 0, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_FUNCMD);
+ #undef USER_COMMAND
+}
+
+struct current_funcmd_header {
+ struct ClientSocket *client;
+ struct UserNode *user;
+ struct ChanNode *chan;
+ char send_notice;
+};
+
+static struct current_funcmd_header current_funcmd;
+
+#define FUNCMD_HEADER \
+current_funcmd.client = getTextBot(); \
+current_funcmd.user = user; \
+current_funcmd.chan = chan; \
+{\
+ MYSQL_RES *res; \
+ MYSQL_ROW row; \
+ printf_mysql_query("SELECT `channel_toys` FROM `channels` WHERE `channel_name` = '%s'", escape_string(chan->name)); \
+ res = mysql_use(); \
+ row = mysql_fetch_row(res); \
+ if(!row || !strcmp(row[0], "0")) { \
+ reply(getTextBot(), user, "NS_FUN_DISABLED", chan->name); \
+ return; \
+ } else if(!strcmp(row[0], "1")) \
+ current_funcmd.send_notice = 1; \
+ else \
+ current_funcmd.send_notice = 0; \
+}
+
+#define REPLYTYPE_NORMAL 0
+#define REPLYTYPE_ACTION 1
+static void funcmd_reply(const char *text, int type, ...) {
+ if (!(current_funcmd.client->flags & SOCKET_FLAG_CONNECTED)) return;
+ const char *reply_format = get_language_string(current_funcmd.user, text);
+ if(reply_format)
+ text = reply_format;
+ char formatBuf[MAXLEN];
+ if(current_funcmd.send_notice) {
+ if(type == REPLYTYPE_ACTION)
+ sprintf(formatBuf, "NOTICE %s :%s %s", current_funcmd.user->nick, current_funcmd.client->user->nick, text);
+ else
+ sprintf(formatBuf, "NOTICE %s :%s", current_funcmd.user->nick, text);
+ } else {
+ if(type == REPLYTYPE_ACTION)
+ sprintf(formatBuf, "PRIVMSG %s :\001ACTION %s\001", current_funcmd.chan->name, text);
+ else
+ sprintf(formatBuf, "PRIVMSG %s :%s", current_funcmd.chan->name, text);
+ }
+ va_list arg_list;
+ char sendBuf[MAXLEN];
+ int pos;
+ sendBuf[0] = '\0';
+ va_start(arg_list, type);
+ pos = vsnprintf(sendBuf, MAXLEN - 2, formatBuf, arg_list);
+ va_end(arg_list);
+ if (pos < 0 || pos > (MAXLEN - 2)) pos = MAXLEN - 2;
+ sendBuf[pos] = '\n';
+ sendBuf[pos+1] = '\0';
+ write_socket(current_funcmd.client, sendBuf, pos+1);
+}
+
+static char* getSetting(struct UserNode *user, struct ChanNode *chan, const char *setting) {
+ char *uname = "";
+ int cid = 0;
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ if(user) {
+ uname = ((user->flags & USERFLAG_ISAUTHED) ? user->auth : "*");
+ }
+ if(chan) {
+ loadChannelSettings(chan);
+ if(chan->flags & CHANFLAG_CHAN_REGISTERED)
+ cid = chan->channel_id;
+ }
+ printf_mysql_query("SELECT `value` FROM `fundata` WHERE `user` = '%s' AND `cid` = '%d' AND `name` = '%s'", escape_string(uname), cid, escape_string(setting));
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) != NULL) {
+ return row[0];
+ } else
+ return NULL;
+}
+
+static void setSetting(struct UserNode *user, struct ChanNode *chan, const char *setting, const char *value) {
+ char *uname = "";
+ int cid = 0;
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ if(user) {
+ uname = ((user->flags & USERFLAG_ISAUTHED) ? user->auth : "*");
+ }
+ if(chan) {
+ loadChannelSettings(chan);
+ if(chan->flags & CHANFLAG_CHAN_REGISTERED)
+ cid = chan->channel_id;
+ }
+ printf_mysql_query("SELECT `id`, `value` FROM `fundata` WHERE `user` = '%s' AND `cid` = '%d' AND `name` = '%s'", escape_string(uname), cid, escape_string(setting));
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) != NULL) {
+ if(strcmp(row[1], value))
+ printf_mysql_query("UPDATE `fundata` SET `value` = '%s' WHERE `id` = '%s'", escape_string(value), row[0]);
+ } else
+ printf_mysql_query("INSERT INTO `fundata` (`user`, `cid`, `name`, `value`) VALUES ('%s', '%d', '%s', '%s')", escape_string(uname), cid, escape_string(setting), escape_string(value));
+}
+
+CMD_BIND(funcmd_ping) {
+ FUNCMD_HEADER;
+ funcmd_reply("\002%s\002: Pong!", REPLYTYPE_NORMAL, user->nick);
+}
+
+CMD_BIND(funcmd_pong) {
+ FUNCMD_HEADER;
+ funcmd_reply("\002%s\002: Ping!", REPLYTYPE_NORMAL, user->nick);
+}
+
+CMD_BIND(funcmd_dice) {
+ FUNCMD_HEADER;
+ int max = atoi(argv[0]);
+ if(max > 1) {
+ int val = (rand() % max) + 1;
+ funcmd_reply("FUN_DICE", REPLYTYPE_NORMAL, user->nick, val, max);
+ } else
+ funcmd_reply("FUN_DICE_NUM", REPLYTYPE_NORMAL, argv[0]);
+}
+
+CMD_BIND(funcmd_8ball) {
+ FUNCMD_HEADER;
+ char *message = merge_argv(argv, 0, argc);
+ const char *const_replies = get_language_string(current_funcmd.user, "FUN_8BALL_REPLIES");
+ char replies[MAXLEN];
+ int i, reply_count = 1;
+ for(i = 0; const_replies[i]; i++) {
+ if(const_replies[i] == '|')
+ reply_count++;
+ replies[i] = const_replies[i];
+ }
+ replies[i] = '\0';
+ unsigned int crc32_val = (crc32(message)) % reply_count;
+ char *creply = (crc32_val == 0 ? replies : NULL);
+ reply_count = 0;
+ for(i = 0; replies[i]; i++) {
+ if(replies[i] == '|') {
+ if(creply) {
+ replies[i] = '\0';
+ break;
+ } else {
+ reply_count++;
+ if(reply_count == crc32_val) {
+ creply = &replies[i+1];
+ }
+ }
+ }
+ }
+ if(creply) {
+ funcmd_reply("FUN_8BALL", REPLYTYPE_NORMAL, user->nick, creply);
+ }
+}
+
+CMD_BIND(funcmd_cookie) {
+ FUNCMD_HEADER;
+ if(argc) {
+ if(!(user = getUserByNick(argv[0]))) {
+ reply(current_funcmd.client, current_funcmd.user, "NS_USER_UNKNOWN", argv[0]);
+ return;
+ }
+ }
+ char *tmp;
+ int user_count = ((tmp = getSetting(user, chan, "cookies")) ? atoi(tmp) : 0);
+ int total_count = ((tmp = getSetting(user, NULL, "cookies")) ? atoi(tmp) : 0);
+ user_count++;
+ total_count++;
+ char buf[10];
+ sprintf(buf, "%d", user_count);
+ setSetting(user, chan, "cookies", buf);
+ sprintf(buf, "%d", total_count);
+ setSetting(user, NULL, "cookies", buf);
+ funcmd_reply("FUN_COOKIE", REPLYTYPE_ACTION, user->nick, total_count, user_count);
+}
--- /dev/null
+/* cmd_funcmds.h - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef _cmd_funcmds_h
+#define _cmd_funcmds_h
+#include "../module.h"
+#include "main.h"
+#include "modcmd.h"
+
+void init_funcmds();
+void register_commands();
+
+CMD_BIND(funcmd_ping);
+CMD_BIND(funcmd_pong);
+CMD_BIND(funcmd_dice);
+CMD_BIND(funcmd_8ball);
+CMD_BIND(funcmd_cookie);
+
+#endif
\ No newline at end of file
--- /dev/null
+/* module.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "../module.h"
+#include "cmd_funcmds.h"
+
+static int module_initialize() {
+ init_funcmds();
+ register_commands();
+ return 0;
+}
+
+static void module_start(int type) {
+
+}
+
+static void module_loop() {
+
+}
+
+static void module_stop(int type) {
+
+}
+
+MODULE_HEADER(module_initialize, module_start, module_loop, module_stop);
--- /dev/null
+/* cmd_global.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "../module.h"
+#include "cmd_global.h"
+#include "modcmd.h"
+#include "ConfigParser.h"
+
+void register_commands() {
+
+ //Global Commands
+ #define USER_COMMAND(NAME,FUNCTION,PARAMCOUNT,PRIVS,FLAGS) register_command(0, NAME, FUNCTION, PARAMCOUNT, PRIVS, 0, FLAGS)
+ // NAME FUNCTION PARAMS PRIVS FLAGS
+ USER_COMMAND("version", global_cmd_version, 0, NULL, 0);
+ USER_COMMAND("netinfo", global_cmd_netinfo, 0, NULL, 0);
+ USER_COMMAND("commands", global_cmd_commands, 0, NULL, 0);
+ USER_COMMAND("command", global_cmd_command, 1, NULL, CMDFLAG_ESCAPE_ARGS);
+ USER_COMMAND("staff", global_cmd_staff, 0, NULL, 0);
+ USER_COMMAND("motd", global_cmd_motd, 0, NULL, 0);
+ #undef USER_COMMAND
+
+ #define OPER_COMMAND(NAME,FUNCTION,PARAMCOUNT,GACCESS,FLAGS) register_command(0, NAME, FUNCTION, PARAMCOUNT, NULL, GACCESS, FLAGS)
+ // NAME FUNCTION PARAMS ACCS FLAGS
+ OPER_COMMAND("register", global_cmd_register, 1, 200, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_CHAN_PARAM | CMDFLAG_OPLOG);
+ OPER_COMMAND("unregister", global_cmd_unregister,0, 200, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_CHAN_PARAM | CMDFLAG_OPLOG);
+ OPER_COMMAND("say", global_cmd_say, 2, 600, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_CHAN_PARAM | CMDFLAG_OPLOG);
+ OPER_COMMAND("emote", global_cmd_emote, 2, 600, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_CHAN_PARAM | CMDFLAG_OPLOG);
+ OPER_COMMAND("notice", global_cmd_notice, 2, 600, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_CHAN_PARAM | CMDFLAG_OPLOG);
+ OPER_COMMAND("raw", global_cmd_raw, 1, 800, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG);
+ OPER_COMMAND("god", global_cmd_god, 0, 1, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG);
+ OPER_COMMAND("reloadlang", global_cmd_reloadlang,1, 500, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG);
+ OPER_COMMAND("bind", global_cmd_bind, 2, 900, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG | CMDFLAG_REQUIRED | CMDFLAG_ESCAPE_ARGS);
+ OPER_COMMAND("unbind", global_cmd_unbind, 1, 900, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG | CMDFLAG_REQUIRED | CMDFLAG_ESCAPE_ARGS);
+ OPER_COMMAND("setaccess", global_cmd_setaccess, 2, 1000, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG);
+ OPER_COMMAND("bots", global_cmd_bots, 0, 1000, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH);
+ OPER_COMMAND("reload", global_cmd_reload, 0, 1000, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG);
+ OPER_COMMAND("restart", global_cmd_restart, 0, 1000, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG);
+ OPER_COMMAND("die", global_cmd_die, 0, 1000, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG);
+ OPER_COMMAND("setbot", global_cmd_setbot, 1, 1000, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG);
+ OPER_COMMAND("addbot", global_cmd_addbot, 2, 1000, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG);
+ OPER_COMMAND("delbot", global_cmd_delbot, 1, 1000, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG);
+ OPER_COMMAND("reconnect", global_cmd_reconnect, 0, 1000, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG);
+ OPER_COMMAND("modcmd", global_cmd_modcmd, 1, 900, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG | CMDFLAG_REQUIRED | CMDFLAG_ESCAPE_ARGS);
+ OPER_COMMAND("meminfo", global_cmd_meminfo, 0, 1000, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH);
+ #undef OPER_COMMAND
+}
\ No newline at end of file
--- /dev/null
+/* cmd_global.h - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef _cmd_global_h
+#define _cmd_global_h
+#include "../module.h"
+#include "main.h"
+#include "modcmd.h"
+#include "IRCParser.h"
+#include "IRCEvents.h"
+#include "UserNode.h"
+#include "ChanNode.h"
+#include "ChanUser.h"
+#include "ModeNode.h"
+#include "BanNode.h"
+#include "ClientSocket.h"
+#include "mysqlConn.h"
+#include "lang.h"
+#include "HandleInfoHandler.h"
+#include "WHOHandler.h"
+#include "DBHelper.h"
+#include "tools.h"
+#include "timeq.h"
+#include "version.h"
+#include "EventLogger.h"
+#include "bots.h"
+
+void register_commands();
+
+CMD_BIND(global_cmd_addbot);
+CMD_BIND(global_cmd_bind);
+CMD_BIND(global_cmd_bots);
+CMD_BIND(global_cmd_command);
+CMD_BIND(global_cmd_commands);
+CMD_BIND(global_cmd_delbot);
+CMD_BIND(global_cmd_die);
+CMD_BIND(global_cmd_emote);
+CMD_BIND(global_cmd_god);
+CMD_BIND(global_cmd_meminfo);
+CMD_BIND(global_cmd_modcmd);
+CMD_BIND(global_cmd_motd);
+CMD_BIND(global_cmd_netinfo);
+CMD_BIND(global_cmd_notice);
+CMD_BIND(global_cmd_raw);
+CMD_BIND(global_cmd_reconnect);
+CMD_BIND(global_cmd_register);
+CMD_BIND(global_cmd_reload);
+CMD_BIND(global_cmd_restart);
+CMD_BIND(global_cmd_reloadlang);
+CMD_BIND(global_cmd_say);
+CMD_BIND(global_cmd_setaccess);
+CMD_BIND(global_cmd_setbot);
+CMD_BIND(global_cmd_staff);
+CMD_BIND(global_cmd_unbind);
+CMD_BIND(global_cmd_unregister);
+CMD_BIND(global_cmd_version);
+
+#endif
\ No newline at end of file
--- /dev/null
+/* cmd_global_addbot.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_global.h"
+
+/*
+* argv[0] nick
+* argv[1] class
+*/
+
+CMD_BIND(global_cmd_addbot) {
+ MYSQL_RES *res;
+ int botid;
+ if((botid = resolve_botalias(argv[1])) == -1) {
+ reply(getTextBot(), user, "NS_SETBOT_INVALID_CLASS", argv[1]);
+ return;
+ }
+ printf_mysql_query("SELECT `id` FROM `bots` WHERE `nick` = '%s'", escape_string(argv[0]));
+ res = mysql_use();
+ if(mysql_fetch_row(res)) {
+ reply(getTextBot(), user, "NS_ADDBOT_EXISTING", argv[0]);
+ return;
+ }
+ printf_mysql_query("INSERT INTO `bots` (`nick`, `botclass`) VALUES ('%s', '%d')", escape_string(argv[0]), botid);
+ botid = (int) mysql_insert_id(get_mysql_conn());
+ reply(getTextBot(), user, "NS_ADDBOT_DONE", argv[0], botid);
+ logEvent(event);
+}
+
--- /dev/null
+/* cmd_global_bind.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_global.h"
+
+/*
+* argv[0] command name
+* argv[1] command function
+* argv[2-*] parameters (optional)
+*/
+
+CMD_BIND(global_cmd_bind) {
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ if(client->botid == 0)
+ printf_mysql_query("SELECT `function` FROM `bot_binds` WHERE `botclass` = '%d' AND `botid` = '%d' AND `command` = '%s'", client->botid, client->clientid, escape_string(argv[0]));
+ else
+ printf_mysql_query("SELECT `function` FROM `bot_binds` WHERE `botclass` = '%d' AND `command` = '%s'", client->botid, escape_string(argv[0]));
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) != NULL) {
+ reply(getTextBot(), user, "NS_BIND_ALREADY", argv[0], row[0]);
+ return;
+ }
+ char *params;
+ if(argc > 2)
+ params = merge_argv(argv, 2, argc);
+ else
+ params = "";
+ struct cmd_function *function = find_cmd_function(client->botid, argv[1]);
+ if(!function) {
+ reply(getTextBot(), user, "NS_BIND_UNKNOWN", argv[1]);
+ return;
+ }
+ bind_botwise_cmd_to_function(client->botid, client->clientid, argv[0], function);
+ printf_mysql_query("INSERT INTO `bot_binds` (`botclass`, `botid`, `command`, `function`, `parameters`) VALUES ('%d', '%d', '%s', '%s', '%s')", client->botid, (client->botid == 0 ? client->clientid : 0), escape_string(argv[0]), escape_string(argv[1]), params);
+ if(*params)
+ bind_botwise_set_parameters(client->botid, client->clientid, argv[0], params);
+ reply(getTextBot(), user, "NS_BIND_DONE", argv[0], function->name);
+ logEvent(event);
+}
--- /dev/null
+/* cmd_global_bots.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_global.h"
+
+/*
+* argv[0] (optional) class name
+*/
+
+CMD_BIND(global_cmd_bots) {
+ struct Table *table;
+ MYSQL_RES *res, *res2;
+ MYSQL_ROW row, row2;
+ printf_mysql_query("SELECT `active`, `nick`, `server`, `port`, `pass`, `botclass`, `textbot`, `queue`, `defaulttrigger`, `max_channels`, `register_priority`, `id` FROM `bots`");
+ res = mysql_use();
+ table = table_init(7, mysql_num_rows(res) + 1, 0);
+ char *content[7];
+ content[0] = get_language_string(user, "NS_BOTS_ID");
+ content[1] = get_language_string(user, "NS_BOTS_NICK");
+ content[2] = get_language_string(user, "NS_BOTS_SERVER");
+ content[3] = get_language_string(user, "NS_BOTS_CLASS");
+ content[4] = get_language_string(user, "NS_BOTS_FLAGS");
+ content[5] = get_language_string(user, "NS_BOTS_CHANNELS");
+ content[6] = get_language_string(user, "NS_BOTS_TRIGGER");
+ table_add(table, content);
+ char botnick[NICKLEN + 3];
+ char botserver[MAXLEN];
+ char botflags[10];
+ int flagspos;
+ char botchans[20];
+ while ((row = mysql_fetch_row(res)) != NULL) {
+ content[0] = row[11];
+ sprintf(botnick, (strcmp(row[0], "0") ? "%s" : "!%s"), row[1]);
+ content[1] = botnick;
+ sprintf(botserver, (strcmp(row[4], "") ? "%s:%s:*" : "%s:%s"), row[2], row[3]);
+ content[2] = botserver;
+ content[3] = (char *) resolve_botid(atoi(row[5]));
+ flagspos = 0;
+ if(!strcmp(row[6], "1"))
+ botflags[flagspos++] = 't';
+ if(!strcmp(row[7], "1"))
+ botflags[flagspos++] = 'q';
+ botflags[flagspos] = '\0';
+ content[4] = botflags;
+ printf_mysql_query("SELECT COUNT(*) FROM `bot_channels` WHERE `botid` = '%s'", row[11]);
+ res2 = mysql_use();
+ row2 = mysql_fetch_row(res2);
+ sprintf(botchans, "%s/%s", row2[0], row[9]);
+ content[5] = botchans;
+ content[6] = row[8];
+ table_add(table, content);
+ }
+ char **table_lines = table_end(table);
+ int i;
+ for(i = 0; i < table->entrys; i++) {
+ reply(getTextBot(), user, table_lines[i]);
+ }
+ table_free(table);
+}
\ No newline at end of file
--- /dev/null
+/* cmd_global_command.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_global.h"
+
+/*
+* argv[0-1] command
+*/
+static int global_cmd_command_chanaccess(struct cmd_binding *cbind, struct ChanNode *chan);
+static int global_cmd_command_operaccess(struct cmd_binding *cbind);
+
+CMD_BIND(global_cmd_command) {
+ char *ident;
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ struct cmd_binding *cbind = find_botwise_cmd_binding(client->botid, client->clientid, argv[0]);
+ if (!cbind) {
+ reply(getTextBot(), user, "NS_UNBIND_NOT_FOUND", argv[0]);
+ return;
+ }
+ ident = argv[0];
+ char parameters[MAXLEN];
+ if(cbind->paramcount) {
+ int i, parampos = 0;
+ for(i = 0; i < cbind->paramcount; i++) {
+ parampos += sprintf(parameters + parampos, (i ? " %s" : "%s"), cbind->parameters[i]);
+ }
+ } else
+ parameters[0] = '\0';
+ reply(getTextBot(), user, "NS_COMMAND_BINDING", cbind->cmd, cbind->func->name, parameters);
+ if(chan)
+ reply(getTextBot(), user, "NS_COMMAND_ACCESS", global_cmd_command_chanaccess(cbind, chan), global_cmd_command_operaccess(cbind));
+ printf_mysql_query("SELECT `user_lang` FROM `users` WHERE `user_user` = '%s'", escape_string(user->auth));
+ res = mysql_use();
+ char *lang;
+ if ((row = mysql_fetch_row(res)) != NULL)
+ lang = row[0];
+ else
+ lang = "en";
+ printf_mysql_query("SELECT `text` FROM `help` WHERE `lang` = '%s' AND `ident` = '%s'", escape_string(lang), escape_string(ident));
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) == NULL) {
+ if(stricmp(lang, "en")) {
+ printf_mysql_query("SELECT `text` FROM `help` WHERE `lang` = 'en' AND `ident` = '%s'", escape_string(ident));
+ res = mysql_use();
+ }
+ if ((row = mysql_fetch_row(res)) == NULL) {
+ printf_mysql_query("SELECT `text` FROM `help` WHERE `lang` = '%s' AND `ident` = '%s'", escape_string(lang), escape_string(cbind->func->name));
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) == NULL) {
+ if(stricmp(lang, "en")) {
+ printf_mysql_query("SELECT `text` FROM `help` WHERE `lang` = 'en' AND `ident` = '%s'", escape_string(cbind->func->name));
+ res = mysql_use();
+ }
+ if ((row = mysql_fetch_row(res)) == NULL) {
+ return;
+ }
+ }
+ }
+ }
+ char sendBuf[MAXLEN];
+ int sendBufPos = 0;
+ int i;
+ for(i = 0; i < strlen(row[0]); i++) {
+ switch(row[0][i]) {
+ case '\n':
+ if(sendBufPos) {
+ sendBuf[sendBufPos] = '\0';
+ reply(getTextBot(), user, "%s", sendBuf);
+ sendBufPos = 0;
+ }
+ break;
+ case '$':
+ switch(row[0][i+1]) {
+ case 'b':
+ sendBuf[sendBufPos++] = '\002';
+ i++;
+ break;
+ case 'k':
+ sendBuf[sendBufPos++] = '\003';
+ i++;
+ break;
+ case 'u':
+ sendBuf[sendBufPos++] = '\031';
+ i++;
+ break;
+ case 'C':
+ case 'S':
+ sendBufPos += sprintf(sendBuf + sendBufPos, "%s", client->user->nick);
+ i++;
+ break;
+ default:
+ sendBuf[sendBufPos++] = '$';
+ break;
+ }
+ break;
+ default:
+ sendBuf[sendBufPos++] = row[0][i];
+ break;
+ }
+ }
+ if(sendBufPos) {
+ sendBuf[sendBufPos] = '\0';
+ reply(getTextBot(), user, "%s", sendBuf);
+ sendBufPos = 0;
+ }
+}
+
+static int global_cmd_command_chanaccess(struct cmd_binding *cbind, struct ChanNode *chan) {
+ char access_list[256];
+ int access_pos = 0;
+ int access_count = 0;
+ int minaccess = 0;
+ char *str_a, *str_b = cbind->func->channel_access, *str_c;
+ if(cbind->flags & CMDFLAG_OVERRIDE_CHANNEL_ACCESS)
+ str_b = cbind->channel_access;
+ access_list[0] = '\0';
+ if(str_b) {
+ str_c = strdup(str_b);
+ str_b = str_c;
+ while((str_a = str_b)) {
+ str_b = strstr(str_a, ",");
+ if(str_b) {
+ *str_b = '\0';
+ str_b++;
+ }
+ if(*str_a == '@' || *str_a == '+') {
+ //privs can override this access requirement
+ str_a++;
+ }
+ if(*str_a == '#') {
+ str_a++;
+ access_pos += sprintf(access_list+access_pos, (access_pos ? ", `%s`" : "`%s`"), str_a);
+ access_count++;
+ } else {
+ if(atoi(str_a) > minaccess)
+ minaccess = atoi(str_a);
+ }
+ }
+ free(str_c);
+ }
+ if(access_count) {
+ MYSQL_RES *res;
+ MYSQL_ROW row, defaults = NULL;
+ printf_mysql_query("SELECT %s FROM `channels` WHERE `channel_name` = '%s'", access_list, escape_string(chan->name));
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) != NULL) {
+ int i, caccess;
+ for(i = 0; i < access_count; i++) {
+ if(!row[i] && !defaults) {
+ printf_mysql_query("SELECT %s FROM `channels` WHERE `channel_name` = 'defaults'", access_list);
+ defaults = mysql_fetch_row(mysql_use());
+ }
+ caccess = (row[i] ? atoi(row[i]) : atoi(defaults[i]));
+ if(caccess > minaccess)
+ minaccess = caccess;
+ }
+ }
+ }
+ return minaccess;
+}
+
+static int global_cmd_command_operaccess(struct cmd_binding *cbind) {
+ return ((cbind->flags & CMDFLAG_OVERRIDE_GLOBAL_ACCESS) ? cbind->global_access : cbind->func->global_access);
+}
--- /dev/null
+/* cmd_global_commands.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_global.h"
+
+/*
+* argv[0] mask
+*/
+
+static int global_cmd_commands_sort(const void *a, const void *b);
+static int global_cmd_commands_chanaccess(struct cmd_binding *cbind, struct ChanNode *chan);
+static int global_cmd_commands_operaccess(struct cmd_binding *cbind);
+
+CMD_BIND(global_cmd_commands) {
+ struct cmd_binding *cbind;
+ int bindcount = 0;
+ for(cbind = getAllBinds(NULL); cbind; cbind = getAllBinds(cbind)) {
+ if(cbind->botid == client->botid && (cbind->botid || cbind->clientid == client->clientid) && !(cbind->func->flags & CMDFLAG_FUNCMD))
+ bindcount++;
+ }
+ struct cmd_binding *binds[bindcount];
+ bindcount = 0;
+ for(cbind = getAllBinds(NULL); cbind; cbind = getAllBinds(cbind)) {
+ if(cbind->botid == client->botid && (cbind->botid || cbind->clientid == client->clientid) && !(cbind->func->flags & CMDFLAG_FUNCMD))
+ binds[bindcount++] = cbind;
+ }
+ qsort(binds, bindcount, sizeof(struct cmd_binding *), global_cmd_commands_sort);
+ int i;
+ struct Table *table;
+ table = table_init(5, bindcount + 1, 0);
+ char *content[5];
+ content[0] = get_language_string(user, "NS_COMMANDS_NAME");
+ content[1] = get_language_string(user, "NS_COMMANDS_ACCESS");
+ content[2] = get_language_string(user, "NS_COMMANDS_GACCESS");
+ content[3] = get_language_string(user, "NS_COMMANDS_TRIGGERED");
+ content[4] = get_language_string(user, "NS_COMMANDS_FUNCTION");
+ table_add(table, content);
+ char caccess[5];
+ char gaccess[5];
+ char triggered[10];
+ char funcname[MAXLEN];
+ int funcpos;
+ for(i = 0; i < bindcount; i++) {
+ cbind = binds[i];
+ content[0] = cbind->cmd;
+ sprintf(caccess, "%d", global_cmd_commands_chanaccess(cbind, chan));
+ content[1] = caccess;
+ sprintf(gaccess, "%d", global_cmd_commands_operaccess(cbind));
+ content[2] = gaccess;
+ sprintf(triggered, "%d", cbind->triggered);
+ content[3] = triggered;
+ funcpos = sprintf(funcname, "%s", cbind->func->name);
+ if(cbind->paramcount) {
+ int j;
+ for(j = 0; j < cbind->paramcount; j++) {
+ funcpos += sprintf(funcname + funcpos, " %s", cbind->parameters[j]);
+ }
+ }
+ content[4] = funcname;
+ table_add(table, content);
+ }
+ //send the table
+ char **table_lines = table_end(table);
+ for(i = 0; i < table->entrys; i++) {
+ reply(getTextBot(), user, table_lines[i]);
+ }
+ table_free(table);
+}
+
+static int global_cmd_commands_sort(const void *a, const void *b) {
+ const struct cmd_binding *bind_a = *((struct cmd_binding * const *) a);
+ const struct cmd_binding *bind_b = *((struct cmd_binding * const *) b);
+ int i = stricmp(bind_a->func->name, bind_b->func->name);
+ if(i == 0) {
+ return stricmp(bind_a->cmd, bind_b->cmd);
+ } else
+ return i;
+}
+
+static int global_cmd_commands_chanaccess(struct cmd_binding *cbind, struct ChanNode *chan) {
+ char access_list[256];
+ int access_pos = 0;
+ int access_count = 0;
+ int minaccess = 0;
+ char *str_a, *str_b = cbind->func->channel_access, *str_c;
+ if(cbind->flags & CMDFLAG_OVERRIDE_CHANNEL_ACCESS)
+ str_b = cbind->channel_access;
+ access_list[0] = '\0';
+ if(str_b) {
+ str_c = strdup(str_b);
+ str_b = str_c;
+ while((str_a = str_b)) {
+ str_b = strstr(str_a, ",");
+ if(str_b) {
+ *str_b = '\0';
+ str_b++;
+ }
+ if(*str_a == '@' || *str_a == '+') {
+ //privs can override this access requirement
+ str_a++;
+ }
+ if(*str_a == '#') {
+ str_a++;
+ access_pos += sprintf(access_list+access_pos, (access_pos ? ", `%s`" : "`%s`"), str_a);
+ access_count++;
+ } else {
+ if(atoi(str_a) > minaccess)
+ minaccess = atoi(str_a);
+ }
+ }
+ free(str_c);
+ }
+ if(access_count) {
+ if(!chan) {
+ return -1;
+ }
+ MYSQL_RES *res;
+ MYSQL_ROW row, defaults = NULL;
+ printf_mysql_query("SELECT %s FROM `channels` WHERE `channel_name` = '%s'", access_list, escape_string(chan->name));
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) != NULL) {
+ int i, caccess;
+ for(i = 0; i < access_count; i++) {
+ if(!row[i] && !defaults) {
+ printf_mysql_query("SELECT %s FROM `channels` WHERE `channel_name` = 'defaults'", access_list);
+ defaults = mysql_fetch_row(mysql_use());
+ }
+ caccess = (row[i] ? atoi(row[i]) : atoi(defaults[i]));
+ if(caccess > minaccess)
+ minaccess = caccess;
+ }
+ }
+ }
+ return minaccess;
+}
+
+static int global_cmd_commands_operaccess(struct cmd_binding *cbind) {
+ return ((cbind->flags & CMDFLAG_OVERRIDE_GLOBAL_ACCESS) ? cbind->global_access : cbind->func->global_access);
+}
--- /dev/null
+/* cmd_global_delbot.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_global.h"
+
+/*
+* argv[0] nick/botid
+*/
+
+CMD_BIND(global_cmd_delbot) {
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ printf_mysql_query("SELECT `id` FROM `bots` WHERE `nick` = '%s' OR `id` = '%s'", escape_string(argv[0]), escape_string(argv[0]));
+ res = mysql_use();
+ if((row = mysql_fetch_row(res)) == NULL) {
+ reply(getTextBot(), user, "NS_DELBOT_NOT_FOUND", argv[0]);
+ return;
+ }
+ int botid = atoi(row[0]);
+ printf_mysql_query("DELETE FROM `bots` WHERE `id` = '%s'", row[0]);
+ printf_mysql_query("DELETE FROM `bot_binds` WHERE `botid` = '%s'", row[0]);
+ printf_mysql_query("DELETE FROM `bot_channels` WHERE `botid` = '%s'", row[0]);
+ for(client = getBots(0, NULL); client; client = getBots(0, client)) {
+ if(client->clientid == botid) {
+ close_socket(client);
+ break;
+ }
+ }
+ reply(getTextBot(), user, "NS_DELBOT_DONE");
+ logEvent(event);
+}
--- /dev/null
+/* cmd_global_die.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_global.h"
+
+/*
+* no args
+*/
+
+CMD_BIND(global_cmd_die) {
+ //hard work! :D
+ stop_bot();
+}
--- /dev/null
+/* cmd_global_emote.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_global.h"
+
+/*
+* argv[0] target
+* argv[1-*] message
+*/
+
+CMD_BIND(global_cmd_emote) {
+ char *message = merge_argv(argv, 1, argc);
+ putsock(client, "PRIVMSG %s :\001ACTION %s\001", argv[0], message);
+}
\ No newline at end of file
--- /dev/null
+/* cmd_global_god.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_global.h"
+
+/*
+* argv[0] (optional) on/off
+*/
+
+CMD_BIND(global_cmd_god) {
+ if(argc > 0) {
+ if(!strcmp(argv[0], "0") || !stricmp(argv[0], "off") || !stricmp(argv[0], get_language_string(user, "NS_SET_OFF"))) {
+ if(isGodMode(user)) {
+ printf_mysql_query("UPDATE `users` SET `user_god` = '0' WHERE `user_user` = '%s'", escape_string(user->auth));
+ user->flags &= ~USERFLAG_GOD_MODE;
+ }
+ reply(getTextBot(), user, "NS_GOD_OFF");
+ } else if(!strcmp(argv[0], "1") || !stricmp(argv[0], "on") || !stricmp(argv[0], get_language_string(user, "NS_SET_ON"))) {
+ if(!isGodMode(user)) {
+ printf_mysql_query("UPDATE `users` SET `user_god` = '1' WHERE `user_user` = '%s'", escape_string(user->auth));
+ user->flags |= USERFLAG_GOD_MODE;
+ }
+ reply(getTextBot(), user, "NS_GOD_ON");
+ } else {
+ reply(getTextBot(), user, "NS_SET_INVALID_BOOLEAN", argv[0]);
+ return;
+ }
+ } else {
+ if(isGodMode(user)) {
+ printf_mysql_query("UPDATE `users` SET `user_god` = '0' WHERE `user_user` = '%s'", escape_string(user->auth));
+ user->flags &= ~USERFLAG_GOD_MODE;
+ reply(getTextBot(), user, "NS_GOD_OFF");
+ } else {
+ printf_mysql_query("UPDATE `users` SET `user_god` = '1' WHERE `user_user` = '%s'", escape_string(user->auth));
+ user->flags |= USERFLAG_GOD_MODE;
+ reply(getTextBot(), user, "NS_GOD_ON");
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+/* cmd_global_meminfo.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_global.h"
+#include "memoryInfo.h"
+
+/*
+* no arguments
+*/
+
+CMD_BIND(global_cmd_meminfo) {
+ #ifndef ENABLE_MEMORY_DEBUG
+ reply(getTextBot(), user, "NS_MEMINFO_DISABLED");
+ #else
+ if(argc > 0) {
+ struct Table *table;
+ int elementcount = 0;
+ struct memoryInfoLines *element, *elements;
+ elements = getMemoryInfoLines(argv[0]);
+ for(element = elements; element; element = element->next) {
+ elementcount++;
+ }
+ table = table_init(4, elementcount+2, 0);
+ char *content[4];
+ content[0] = get_language_string(user, "NS_MEMINFO_LINE");
+ content[1] = get_language_string(user, "NS_MEMINFO_COUNT");
+ content[2] = get_language_string(user, "NS_MEMINFO_SIZE");
+ content[3] = get_language_string(user, "NS_MEMINFO_TOTAL");
+ table_add(table, content);
+ char lineBuf[20];
+ char countBuf[20];
+ char sizeBuf[20];
+ char totalBuf[50];
+ unsigned int total_allocations = 0;
+ unsigned int total_allocated = 0;
+ for(element = elements; element; element = element->next) {
+ sprintf(lineBuf, "%u", element->line);
+ content[0] = lineBuf;
+ sprintf(countBuf, "%u", element->allocations);
+ total_allocations += element->allocations;
+ content[1] = countBuf;
+ sprintf(sizeBuf, "%uB", element->allocate);
+ content[2] = sizeBuf;
+ sprintf(totalBuf, "%u (%.2f kB)", (element->allocate * element->allocations), ((float)(element->allocate * element->allocations) / 1024));
+ total_allocated += (element->allocate * element->allocations);
+ content[3] = totalBuf;
+ table_add(table, content);
+ }
+ content[0] = "Total";
+ sprintf(countBuf, "%u", total_allocations);
+ content[1] = countBuf;
+ content[2] = "*";
+ sprintf(sizeBuf, "%u (%.2f kB)", total_allocated, ((float)total_allocated / 1024));
+ content[3] = sizeBuf;
+ table_add(table, content);
+ char **table_lines = table_end(table);
+ int i;
+ for(i = 0; i < table->entrys; i++) {
+ reply(getTextBot(), user, table_lines[i]);
+ }
+ table_free(table);
+ } else {
+ struct Table *table;
+ int elementcount = 0;
+ struct memoryInfoFiles *element, *elements;
+ elements = getMemoryInfoFiles();
+ for(element = elements; element; element = element->next) {
+ elementcount++;
+ }
+ table = table_init(3, elementcount+2, 0);
+ char *content[3];
+ content[0] = get_language_string(user, "NS_MEMINFO_NAME");
+ content[1] = get_language_string(user, "NS_MEMINFO_COUNT");
+ content[2] = get_language_string(user, "NS_MEMINFO_SIZE");
+ table_add(table, content);
+ char countBuf[20];
+ char sizeBuf[50];
+ unsigned int total_allocations = 0;
+ unsigned int total_allocated = 0;
+ for(element = elements; element; element = element->next) {
+ content[0] = element->filename;
+ sprintf(countBuf, "%u", element->allocations);
+ total_allocations += element->allocations;
+ content[1] = countBuf;
+ sprintf(sizeBuf, "%u (%.2f kB)", element->allocated, ((float)element->allocated / 1024));
+ total_allocated += element->allocated;
+ content[2] = sizeBuf;
+ table_add(table, content);
+ }
+ content[0] = "Total";
+ sprintf(countBuf, "%u", total_allocations);
+ content[1] = countBuf;
+ sprintf(sizeBuf, "%u (%.2f kB)", total_allocated, ((float)total_allocated / 1024));
+ content[2] = sizeBuf;
+ table_add(table, content);
+ char **table_lines = table_end(table);
+ int i;
+ for(i = 0; i < table->entrys; i++) {
+ reply(getTextBot(), user, table_lines[i]);
+ }
+ table_free(table);
+ }
+ #endif
+}
\ No newline at end of file
--- /dev/null
+/* cmd_global_modcmd.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_global.h"
+
+/*
+* argv[0] command
+* argv[1] setting
+* argv[2] value
+*/
+
+static int global_cmd_modcmd_params(struct UserNode *user, struct cmd_binding *cbind, char *value);
+static int global_cmd_modcmd_flags(struct UserNode *user, struct cmd_binding *cbind, char *value);
+static int global_cmd_modcmd_caccess(struct UserNode *user, struct cmd_binding *cbind, char *value);
+static int global_cmd_modcmd_oaccess(struct UserNode *user, struct cmd_binding *cbind, char *value);
+
+CMD_BIND(global_cmd_modcmd) {
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ struct cmd_binding *cbind = find_botwise_cmd_binding(client->botid, client->clientid, argv[0]);
+ if (!cbind) {
+ reply(getTextBot(), user, "NS_UNBIND_NOT_FOUND", argv[0]);
+ return;
+ }
+ int uaccess = 0;
+ printf_mysql_query("SELECT `user_access` FROM `users` WHERE `user_user` = '%s'", escape_string(user->auth));
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) != NULL) {
+ uaccess = atoi(row[0]);
+ }
+ int gaccess = ((cbind->flags & CMDFLAG_OVERRIDE_GLOBAL_ACCESS) ? cbind->global_access : cbind->func->global_access);
+ if(gaccess > uaccess) {
+ reply(getTextBot(), user, "NS_MODCMD_OUTRANKED", cbind->cmd, gaccess);
+ return;
+ }
+ if(argc > 1) {
+ char *value;
+ if(argc > 2) {
+ value = merge_argv(argv, 2, argc);
+ } else
+ value = NULL;
+ int log_event = 0;
+ if(!stricmp(argv[1], "caccess")) log_event = global_cmd_modcmd_caccess(user, cbind, value);
+ else if(!stricmp(argv[1], "oaccess")) log_event = global_cmd_modcmd_oaccess(user, cbind, value);
+ else if(!stricmp(argv[1], "parameters")) log_event = global_cmd_modcmd_params(user, cbind, value);
+ else if(!stricmp(argv[1], "flags")) log_event = global_cmd_modcmd_flags(user, cbind, value);
+ else {
+ reply(getTextBot(), user, "NS_MODCMD_SETTING", argv[1]);
+ }
+ if(log_event) {
+ logEvent(event);
+ }
+ } else {
+ reply(getTextBot(), user, "NS_MODCMD_HEADER", cbind->cmd);
+ global_cmd_modcmd_params(user, cbind, NULL);
+ global_cmd_modcmd_caccess(user, cbind, NULL);
+ global_cmd_modcmd_oaccess(user, cbind, NULL);
+ global_cmd_modcmd_flags(user, cbind, NULL);
+ }
+}
+
+static int global_cmd_modcmd_params(struct UserNode *user, struct cmd_binding *cbind, char *value) {
+ char parameters[MAXLEN];
+ int ret = 0;
+ if(cbind->paramcount) {
+ int i, parampos = 0;
+ for(i = 0; i < cbind->paramcount; i++) {
+ parampos += sprintf(parameters + parampos, (i ? " %s" : "%s"), cbind->parameters[i]);
+ }
+ } else
+ parameters[0] = '\0';
+ if(value) {
+ if(!strcmp(value, "*"))
+ value = NULL;
+ bind_botwise_set_parameters(cbind->botid, cbind->clientid, cbind->cmd, value);
+ if(cbind->botid == 0)
+ printf_mysql_query("UPDATE `bot_binds` SET `parameters` = '%s' WHERE `botclass` = '0' AND `botid` = '%d' AND `command` = '%s'", (value ? escape_string(value) : ""), cbind->clientid, escape_string(cbind->cmd));
+ else
+ printf_mysql_query("UPDATE `bot_binds` SET `parameters` = '%s' WHERE `botclass` = '%d' AND `command` = '%s'", (value ? escape_string(value) : ""), cbind->botid, escape_string(cbind->cmd));
+ strcpy(parameters, (value ? value : ""));
+ ret = 1;
+ }
+ reply(getTextBot(), user, "\002PARAMETERS \002 %s", parameters);
+ return ret;
+}
+
+static const struct {
+ const char *name;
+ unsigned int flag;
+} global_cmd_modcmd_show_flags[] = {
+ {"REQUIRE_CHAN", CMDFLAG_REQUIRE_CHAN}, //The command requires a valid channel (at least one bot in it)
+ {"REQUIRE_AUTH", CMDFLAG_REQUIRE_AUTH}, //The command requires the user to be authenticated
+ {"REQUIRE_GOD", CMDFLAG_REQUIRE_GOD}, //The command requires the user to have security override enabled
+ {"REQUIRE_REGISTERED", CMDFLAG_REGISTERED_CHAN}, //The command requires the channel to be registered (database entry)
+ {"CHECK_AUTH", CMDFLAG_CHECK_AUTH}, //WHO the user if no auth is known, yet
+ {"CHANNEL_ARGS", CMDFLAG_CHAN_PARAM}, //don't interpret channel arguments as channel - just pass them as a string
+ {"LOG", CMDFLAG_LOG},
+ {"OPLOG", CMDFLAG_OPLOG},
+ {"FUNCMD", CMDFLAG_FUNCMD},
+ {"ESCAPED_ARGS", CMDFLAG_ESCAPE_ARGS}, //allows arguments to be escaped ("a\ b" = "a b" as one argument)
+ {"NO_CROSSCHAN", CMDFLAG_NO_CROSSCHAN},
+ {NULL, 0}
+};
+
+static int global_cmd_modcmd_flags(struct UserNode *user, struct cmd_binding *cbind, char *value) {
+ char flags[MAXLEN];
+ int flagpos = 0;
+ int ret = 0;
+ unsigned int visible_flags = 0;
+ int i = 0;
+ while(global_cmd_modcmd_show_flags[i].name) {
+ if(cbind->func->flags & global_cmd_modcmd_show_flags[i].flag) {
+ flagpos += sprintf(flags + flagpos, (flagpos ? " %s" : "\00314%s"), global_cmd_modcmd_show_flags[i].name);
+ }
+ visible_flags |= global_cmd_modcmd_show_flags[i].flag;
+ i++;
+ }
+ if(flagpos)
+ flags[flagpos++] = '\003';
+ if(value) {
+ int add = 1;
+ unsigned int current_flag = 0;
+ if(value[0] == '+') {
+ value++;
+ } else if(value[0] == '-') {
+ add = 0;
+ value++;
+ }
+ if(*value) {
+ i = 0;
+ while(global_cmd_modcmd_show_flags[i].name) {
+ if(!stricmp(global_cmd_modcmd_show_flags[i].name, value)) {
+ current_flag = global_cmd_modcmd_show_flags[i].flag;
+ break;
+ }
+ i++;
+ }
+ }
+ if(cbind->func->flags & current_flag) {
+ reply(getTextBot(), user, "NS_MODCMD_STATIC_FLAG");
+ return 0;
+ }
+ if(add)
+ cbind->flags |= current_flag;
+ else
+ cbind->flags &= ~current_flag;
+ if(cbind->botid == 0)
+ printf_mysql_query("UPDATE `bot_binds` SET `flags` = '%u' WHERE `botclass` = '0' AND `botid` = '%d' AND `command` = '%s'", (cbind->flags & visible_flags), cbind->clientid, escape_string(cbind->cmd));
+ else
+ printf_mysql_query("UPDATE `bot_binds` SET `flags` = '%u' WHERE `botclass` = '%d' AND `command` = '%s'", (cbind->flags & visible_flags), cbind->botid, escape_string(cbind->cmd));
+ ret = 1;
+ }
+ i = 0;
+ while(global_cmd_modcmd_show_flags[i].name) {
+ if(cbind->flags & global_cmd_modcmd_show_flags[i].flag) {
+ flagpos += sprintf(flags + flagpos, (flagpos ? " %s" : "%s"), global_cmd_modcmd_show_flags[i].name);
+ }
+ i++;
+ }
+ flags[flagpos] = '\0';
+ reply(getTextBot(), user, "\002FLAGS \002 %s", flags);
+ return ret;
+}
+
+static int global_cmd_modcmd_caccess(struct UserNode *user, struct cmd_binding *cbind, char *value) {
+ char caccess[MAXLEN];
+ int ret = 0;
+ if(value) {
+ if(!strcmp(value, "*"))
+ value = NULL;
+ bind_botwise_set_channel_access(cbind->botid, cbind->clientid, cbind->cmd, value);
+ if(cbind->botid == 0)
+ printf_mysql_query("UPDATE `bot_binds` SET `chan_access` = %s%s%s WHERE `botclass` = '0' AND `botid` = '%d' AND `command` = '%s'", (value ? "'" : ""), (value ? escape_string(value) : "NULL"), (value ? "'" : ""), cbind->clientid, escape_string(cbind->cmd));
+ else
+ printf_mysql_query("UPDATE `bot_binds` SET `chan_access` = %s%s%s WHERE `botclass` = '%d' AND `command` = '%s'", (value ? "'" : ""), (value ? escape_string(value) : "NULL"), (value ? "'" : ""), cbind->botid, escape_string(cbind->cmd));
+
+ ret = 1;
+ }
+ if(cbind->flags & CMDFLAG_OVERRIDE_CHANNEL_ACCESS)
+ sprintf(caccess, "%s", cbind->channel_access);
+ else
+ sprintf(caccess, "\00314%s\003", (cbind->func->channel_access ? cbind->func->channel_access : "0"));
+ reply(getTextBot(), user, "\002CACCESS \002 %s", caccess);
+ return ret;
+}
+
+static int global_cmd_modcmd_oaccess(struct UserNode *user, struct cmd_binding *cbind, char *value) {
+ char oaccess[MAXLEN];
+ int ret = 0;
+ if(value) {
+ if(!strcmp(value, "*"))
+ value = NULL;
+ bind_botwise_set_global_access(cbind->botid, cbind->clientid, cbind->cmd, atoi(value));
+ if(cbind->botid == 0)
+ printf_mysql_query("UPDATE `bot_binds` SET `global_access` = %s%s%s WHERE `botclass` = '0' AND `botid` = '%d' AND `command` = '%s'", (value ? "'" : ""), (value ? escape_string(value) : "NULL"), (value ? "'" : ""), cbind->clientid, escape_string(cbind->cmd));
+ else
+ printf_mysql_query("UPDATE `bot_binds` SET `global_access` = %s%s%s WHERE `botclass` = '%d' AND `command` = '%s'", (value ? "'" : ""), (value ? escape_string(value) : "NULL"), (value ? "'" : ""), cbind->botid, escape_string(cbind->cmd));
+
+ ret = 1;
+ }
+ if(cbind->flags & CMDFLAG_OVERRIDE_GLOBAL_ACCESS)
+ sprintf(oaccess, "%d", cbind->global_access);
+ else
+ sprintf(oaccess, "\00314%d\003", (cbind->func->global_access ? cbind->func->global_access : 0));
+ reply(getTextBot(), user, "\002OACCESS \002 %s", oaccess);
+ return ret;
+}
+
--- /dev/null
+/* cmd_global_motd.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_global.h"
+
+/*
+* no args
+*/
+
+CMD_BIND(global_cmd_motd) {
+ FILE *f;
+ f = fopen("motd.txt", "rb");
+ if(!f) return;
+ char line[MAXLEN];
+ char *a;
+ while (fgets(line, MAXLEN, f) != NULL) {
+ if((a = strchr(line, '\n')))
+ *a = '\0';
+ reply(getTextBot(), user, "%s", line);
+ }
+ fclose(f);
+}
\ No newline at end of file
--- /dev/null
+/* cmd_global_netinfo.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_global.h"
+
+/*
+* no args
+*/
+
+CMD_BIND(global_cmd_netinfo) {
+ reply(getTextBot(), user, "NS_NETINFO_HEADER");
+ char tmp[MAXLEN];
+ struct Table *table;
+ table = table_init(2, 19, 0);
+ char *content[2];
+
+ content[0] = get_language_string(user, "NS_NETINFO_UPTIME");
+ content[1] = timeToStr(user, (time(0) - start_time), 3, tmp);
+ table_add(table, content);
+
+ content[0] = get_language_string(user, "NS_NETINFO_BOTS");
+ struct ClientSocket *cclient;
+ int bot_count = 0, connected_bot_count = 0;
+ float traffic_in = 0, traffic_out = 0;
+ for(cclient = getBots(0, NULL); cclient; cclient = getBots(0, cclient)) {
+ bot_count++;
+ if(cclient->flags & SOCKET_FLAG_READY)
+ connected_bot_count++;
+ traffic_in += cclient->traffic_in;
+ traffic_out += cclient->traffic_out;
+ }
+ sprintf(tmp, "%d (%d connected)", bot_count, connected_bot_count);
+ content[1] = tmp;
+ table_add(table, content);
+
+ content[0] = get_language_string(user, "NS_NETINFO_TRAFFIC");
+ sprintf(tmp, "in: %.2f kb out: %.2f kb", traffic_in / 1024, traffic_out / 1024);
+ content[1] = tmp;
+ table_add(table, content);
+
+ int channel_count = getChannelCount();
+ float channel_memory = channel_count * sizeof(struct ChanNode);
+ int channel_ban_count = getChanBanCount();
+ float channel_ban_memory = channel_ban_count * sizeof(struct BanNode);
+ int user_count = getUserCount();
+ float user_memory = user_count * sizeof(struct UserNode);
+ int chanuser_count = getChanUserCount();
+ float chanuser_memory = chanuser_count * sizeof(struct ChanUser);
+ float total_memory = channel_memory + channel_ban_memory + user_memory + chanuser_memory;
+ content[0] = get_language_string(user, "NS_NETINFO_CACHE");
+ sprintf(tmp, "%.2f kB (%.2f MB)", total_memory / 1024, total_memory / 1024 / 1024);
+ content[1] = tmp;
+ table_add(table, content);
+ content[0] = get_language_string(user, "NS_NETINFO_CHANNEL");
+ sprintf(tmp, "%d %.2f kB (%d * %u B = %.2f kB)", channel_count, channel_memory / 1024, channel_count, (unsigned int) sizeof(struct ChanNode), channel_memory / 1024);
+ content[1] = tmp;
+ table_add(table, content);
+ content[0] = get_language_string(user, "NS_NETINFO_CHANNEL_BAN");
+ sprintf(tmp, "%d %.2f kB (%d * %u B = %.2f kB)", channel_ban_count, channel_ban_memory / 1024, channel_ban_count, (unsigned int) sizeof(struct BanNode), channel_ban_memory / 1024);
+ content[1] = tmp;
+ table_add(table, content);
+ content[0] = get_language_string(user, "NS_NETINFO_USER");
+ sprintf(tmp, "%d %.2f kB (%d * %u B = %.2f kB)", user_count, user_memory / 1024, user_count, (unsigned int) sizeof(struct UserNode), user_memory / 1024);
+ content[1] = tmp;
+ table_add(table, content);
+ content[0] = get_language_string(user, "NS_NETINFO_CHANUSER");
+ sprintf(tmp, "%d %.2f kB (%d * %u B = %.2f kB)", chanuser_count, chanuser_memory / 1024, chanuser_count, (unsigned int) sizeof(struct ChanUser), chanuser_memory / 1024);
+ content[1] = tmp;
+ table_add(table, content);
+
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ printf_mysql_query("SHOW TABLE STATUS");
+ res = mysql_use();
+ int mysql_entrys[4];
+ float mysql_length[5];
+ total_memory = 0;
+ mysql_entrys[0] = 0; mysql_entrys[1] = 0; mysql_entrys[2] = 0; mysql_entrys[3] = 0;
+ mysql_length[0] = 0; mysql_length[1] = 0; mysql_length[2] = 0; mysql_length[3] = 0; mysql_length[4] = 0;
+ while ((row = mysql_fetch_row(res)) != NULL) {
+ if(!stricmp(row[0], "channels")) {
+ mysql_entrys[0] = atoi(row[4]);
+ mysql_length[0] = atof(row[6]);
+ total_memory += atof(row[6]);
+ } else if(!stricmp(row[0], "bans")) {
+ mysql_entrys[1] = atoi(row[4]);
+ mysql_length[1] = atof(row[6]);
+ total_memory += atof(row[6]);
+ } else if(!stricmp(row[0], "users")) {
+ mysql_entrys[2] = atoi(row[4]);
+ mysql_length[2] = atof(row[6]);
+ total_memory += atof(row[6]);
+ } else if(!stricmp(row[0], "chanusers")) {
+ mysql_entrys[3] = atoi(row[4]);
+ mysql_length[3] = atof(row[6]);
+ total_memory += atof(row[6]);
+ } else {
+ mysql_length[4] += atof(row[6]);
+ total_memory += atof(row[6]);
+ }
+ }
+
+ content[0] = get_language_string(user, "NS_NETINFO_DATABASE");
+ sprintf(tmp, "%.2f kB (%.2f MB)", total_memory / 1024, total_memory / 1024 / 1024);
+ content[1] = tmp;
+ table_add(table, content);
+
+ content[0] = get_language_string(user, "NS_NETINFO_CHANNEL");
+ sprintf(tmp, "%d %.2f kB", mysql_entrys[0], mysql_length[0] / 1024);
+ content[1] = tmp;
+ table_add(table, content);
+
+ content[0] = get_language_string(user, "NS_NETINFO_CHANNEL_BAN");
+ sprintf(tmp, "%d %.2f kB", mysql_entrys[1], mysql_length[1] / 1024);
+ content[1] = tmp;
+ table_add(table, content);
+
+ content[0] = get_language_string(user, "NS_NETINFO_USER");
+ sprintf(tmp, "%d %.2f kB", mysql_entrys[2], mysql_length[2] / 1024);
+ content[1] = tmp;
+ table_add(table, content);
+
+ content[0] = get_language_string(user, "NS_NETINFO_CHANUSER");
+ sprintf(tmp, "%d %.2f kB", mysql_entrys[3], mysql_length[3] / 1024);
+ content[1] = tmp;
+ table_add(table, content);
+
+ content[0] = get_language_string(user, "NS_NETINFO_OTHER");
+ sprintf(tmp, "* %.2f kB", mysql_length[4] / 1024);
+ content[1] = tmp;
+ table_add(table, content);
+
+ #ifdef HAVE_THREADS
+ content[0] = get_language_string(user, "NS_NETINFO_THREADS");
+ sprintf(tmp, "%d (current thread: %i)", running_threads, getCurrentThreadID());
+ content[1] = tmp;
+ table_add(table, content);
+ #endif
+
+ if(strcmp(revision, ""))
+ sprintf(tmp, "%s.%d (%s)", NEONSERV_VERSION, patchlevel, revision);
+ else
+ sprintf(tmp, "%s.%d", NEONSERV_VERSION, patchlevel);
+ content[0] = get_language_string(user, "NS_NETINFO_VERSION");
+ content[1] = tmp;
+ table_add(table, content);
+
+ content[0] = get_language_string(user, "NS_NETINFO_COMPILER");
+ content[1] = build_language_string(user, tmp, "NS_NETINFO_COMPILER_VALUE", COMPILER, creation);
+ table_add(table, content);
+
+ content[0] = get_language_string(user, "NS_NETINFO_CODE");
+ content[1] = build_language_string(user, tmp, "NS_NETINFO_CODE_VALUE", codelines);
+ table_add(table, content);
+
+ char **table_lines = table_end(table);
+ int i;
+ for(i = 0; i < table->entrys; i++) {
+ reply(getTextBot(), user, table_lines[i]);
+ }
+ table_free(table);
+}
+
--- /dev/null
+/* cmd_global_notice.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_global.h"
+
+/*
+* argv[0] target
+* argv[1-*] message
+*/
+
+CMD_BIND(global_cmd_notice) {
+ char *message = merge_argv(argv, 1, argc);
+ putsock(client, "NOTICE %s :%s", argv[0], message);
+}
\ No newline at end of file
--- /dev/null
+/* cmd_global_raw.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_global.h"
+
+/*
+* argv[0-*] raw
+*/
+
+CMD_BIND(global_cmd_raw) {
+ char *raw = merge_argv(argv, 0, argc);
+ putsock(client, "%s", raw);
+}
\ No newline at end of file
--- /dev/null
+/* cmd_global_reconnect.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_global.h"
+
+/*
+* argv[0] nick/botid
+*/
+
+CMD_BIND(global_cmd_reconnect) {
+ int botid;
+ if(argc) {
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ printf_mysql_query("SELECT `id` FROM `bots` WHERE `nick` = '%s' OR `id` = '%s'", escape_string(argv[0]), escape_string(argv[0]));
+ res = mysql_use();
+ if((row = mysql_fetch_row(res)) == NULL) {
+ reply(getTextBot(), user, "NS_DELBOT_NOT_FOUND", argv[0]);
+ return;
+ }
+ botid = atoi(row[0]);
+ for(client = getBots(0, NULL); client; client = getBots(0, client)) {
+ if(client->clientid == botid) {
+ disconnect_socket(client);
+ client->flags |= SOCKET_FLAG_FAST_JUMP;
+ break;
+ }
+ }
+ } else {
+ disconnect_socket(client);
+ connect_socket(client);
+ }
+ reply(getTextBot(), user, "NS_RECONNECT_DONE");
+ logEvent(event);
+}
--- /dev/null
+/* cmd_global_register.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_global.h"
+
+/*
+* argv[0] - channel
+* argv[1] - nick / *auth
+* argv[2] - (optional) bot nick
+*/
+static AUTHLOOKUP_CALLBACK(global_cmd_register_auth_lookup);
+static USERAUTH_CALLBACK(global_cmd_register_nick_lookup);
+static void global_cmd_register_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *channel, char *auth, int multibot, char *botname);
+
+struct global_cmd_register_cache {
+ struct ClientSocket *client, *textclient;
+ struct UserNode *user;
+ struct ChanNode *chan;
+ struct Event *event;
+ char *nick;
+ char *channel;
+ char *botname;
+ int multibot;
+};
+
+CMD_BIND(global_cmd_register) {
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ char *channel = argv[0];
+ char *botname = (argc > 2 ? argv[2] : NULL);
+ int multibot = 0;
+ if(!is_valid_chan(channel)) {
+ reply(getTextBot(), user, "NS_INVALID_CHANNEL_NAME", argv[0]);
+ return;
+ }
+ printf_mysql_query("SELECT `botid`, `botclass` FROM `bot_channels` LEFT JOIN `bots` ON `bot_channels`.`botid` = `bots`.`id` LEFT JOIN `channels` ON `bot_channels`.`chanid` = `channels`.`channel_id` WHERE `channel_name` = '%s'", escape_string(channel));
+ res = mysql_use();
+ while ((row = mysql_fetch_row(res)) != NULL) {
+ if(atoi(row[1]) == client->botid && (client->botid || client->clientid == atoi(row[0]))) {
+ reply(getTextBot(), user, "NS_REGISTER_ALREADY", argv[0], client->user->nick);
+ return;
+ } else
+ multibot = 1;
+ }
+ printf_mysql_query("SELECT `user_user`, `dnr_timeout`, `dnr_reason`, `dnr_id` FROM `donotregister` LEFT JOIN `users` ON `dnr_user` = `user_id` WHERE `dnr_target` = '%s'", escape_string(channel));
+ res = mysql_use();
+ if((row = mysql_fetch_row(res)) != NULL) {
+ int expire_time = atoi(row[1]);
+ if(expire_time) {
+ if(expire_time - time(0) <= 0) {
+ printf_mysql_query("DELETE FROM `donotregister` WHERE `dnr_id` = '%s'", row[3]);
+ } else {
+ char expireBuf[MAXLEN];
+ reply(getTextBot(), user, "NS_DNR_SET_EXPIRES", channel, row[0], timeToStr(user, (expire_time - time(0)), 2, expireBuf), row[2]);
+ return;
+ }
+ } else {
+ reply(getTextBot(), user, "NS_DNR_SET", channel, row[0], row[2]);
+ return;
+ }
+ }
+ //if theres already another bot in the channel we don't need a owner parameter...
+ if(multibot && argc < 2) {
+ //skip all these owner check lines
+ multibot = 2;
+ global_cmd_register_async1(client, getTextBot(), user, chan, event, channel, NULL, multibot, botname);
+ return;
+ } else if(argc < 2) {
+ global_cmd_register_async1(client, getTextBot(), user, chan, event, channel, user->auth, multibot, botname);
+ return;
+ }
+ //check own access
+ if(argv[1][0] == '*') {
+ //we've got an auth
+ argv[1]++;
+ printf_mysql_query("SELECT `user_user` FROM `users` WHERE `user_user` = '%s'", escape_string(argv[1]));
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) != NULL) {
+ global_cmd_register_async1(client, getTextBot(), user, chan, event, channel, row[0], multibot, botname);
+ } else {
+ //we need to create a new user...
+ //but first lookup the auth to check if it really exists
+ struct global_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->event = event;
+ cache->nick = strdup(argv[1]);
+ cache->channel = strdup(channel);
+ cache->multibot = multibot;
+ cache->botname = (botname ? strdup(botname) : NULL);
+ lookup_authname(argv[1], global_cmd_register_auth_lookup, cache);
+ }
+ } else {
+ struct UserNode *cuser = getUserByNick(argv[1]);
+ if(!cuser) {
+ cuser = createTempUser(argv[1]);
+ if(!cuser) {
+ reply(getTextBot(), user, "NS_USER_UNKNOWN", argv[1]);
+ return;
+ }
+ cuser->flags |= USERFLAG_ISTMPUSER;
+ }
+ if(cuser->flags & USERFLAG_ISAUTHED) {
+ global_cmd_register_async1(client, getTextBot(), user, chan, event, channel, cuser->auth, multibot, botname);
+ } else {
+ struct global_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->event = event;
+ cache->nick = strdup(argv[1]);
+ cache->channel = strdup(channel);
+ cache->multibot = multibot;
+ cache->botname = (botname ? strdup(botname) : NULL);
+ get_userauth(cuser, global_cmd_register_nick_lookup, cache);
+ }
+ }
+}
+
+static AUTHLOOKUP_CALLBACK(global_cmd_register_auth_lookup) {
+ struct global_cmd_register_cache *cache = data;
+ if(!exists) {
+ //AUTH_DOES_NOT_EXIST
+ reply(cache->textclient, cache->user, "NS_AUTH_UNKNOWN", cache->nick);
+ } else
+ global_cmd_register_async1(cache->client, cache->textclient, cache->user, cache->chan, cache->event, cache->channel, auth, cache->multibot, cache->botname);
+ if(cache->botname)
+ free(cache->botname);
+ free(cache->channel);
+ free(cache->nick);
+ free(cache);
+}
+
+static USERAUTH_CALLBACK(global_cmd_register_nick_lookup) {
+ struct global_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
+ global_cmd_register_async1(cache->client, cache->textclient, cache->user, cache->chan, cache->event, cache->channel, user->auth, cache->multibot, cache->botname);
+ if(cache->botname)
+ free(cache->botname);
+ free(cache->channel);
+ free(cache->nick);
+ free(cache);
+}
+
+static void global_cmd_register_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *channel, char *auth, int multibot, char *botname) {
+ //we've got a valid auth now...
+ MYSQL_RES *res;
+ MYSQL_ROW row, row2;
+ int userid = 0, adminid;
+ printf_mysql_query("SELECT `user_id` FROM `users` WHERE `user_user` = '%s'", escape_string(user->auth));
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) != NULL)
+ adminid = atoi(row[0]);
+ else
+ adminid = 0;
+ if(multibot != 2) {
+ printf_mysql_query("SELECT `user_user`, `dnr_timeout`, `dnr_reason`, `dnr_id` FROM `donotregister` LEFT JOIN `users` ON `dnr_user` = `user_id` WHERE `dnr_target` = '%s'", escape_string(auth));
+ res = mysql_use();
+ if((row = mysql_fetch_row(res)) != NULL) {
+ int expire_time = atoi(row[1]);
+ if(expire_time) {
+ if(expire_time - time(0) <= 0) {
+ printf_mysql_query("DELETE FROM `donotregister` WHERE `dnr_id` = '%s'", row[3]);
+ } else {
+ char expireBuf[MAXLEN];
+ reply(getTextBot(), user, "NS_DNR_SET_EXPIRES", auth, row[0], timeToStr(user, (expire_time - time(0)), 2, expireBuf), row[2]);
+ return;
+ }
+ } else {
+ reply(getTextBot(), user, "NS_DNR_SET", auth, row[0], row[2]);
+ return;
+ }
+ }
+ 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(get_mysql_conn());
+ }
+ }
+ if(client->botid)
+ printf_mysql_query("SELECT `id`, `max_channels`, `defaulttrigger`, `nick` FROM `bots` WHERE `botclass` = '%d' AND `active` = '1' ORDER BY `register_priority` DESC", client->botid);
+ else
+ printf_mysql_query("SELECT `id`, `max_channels`, `defaulttrigger`, `nick` FROM `bots` WHERE `id` = '%d' AND `active` = '1'", client->clientid);
+ res = mysql_use();
+ int botid = 0;
+ 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]) && (!botname || !stricmp(botname, row[3]))) {
+ botid = atoi(row[0]);
+ 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]);
+ printf_mysql_query("UPDATE `channels` SET `channel_registered` = UNIX_TIMESTAMP(), `channel_registrator` = '%d' WHERE `channel_id` = '%d'", adminid, chanid);
+ } else {
+ printf_mysql_query("INSERT INTO `channels` (`channel_name`, `channel_registered`, `channel_registrator`) VALUES ('%s', UNIX_TIMESTAMP(), '%d')", escape_string(channel), adminid);
+ chanid = (int) mysql_insert_id(get_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", channel);
+ printf_mysql_query("INSERT INTO `bot_channels` (`botid`, `chanid`, `trigger`) VALUES ('%d', '%d', NULL)", botid, chanid);
+ if(multibot != 2) {
+ if(multibot) {
+ printf_mysql_query("UPDATE `chanusers` SET `chanuser_access` = 499 WHERE `chanuser_cid` = '%d' AND `chanuser_access` = '500'", chanid);
+ printf_mysql_query("DELETE FROM `chanusers` WHERE `chanuser_cid` = '%d' AND `chanuser_uid` = '%d'", chanid, userid);
+ } else
+ 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);
+ } else
+ reply(textclient, user, "NS_REGISTER_DONE_NOAUTH", channel);
+ logEvent(event);
+}
--- /dev/null
+/* cmd_global_reload.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_global.h"
+
+/*
+* argv[0] soft (optional)
+*/
+
+CMD_BIND(global_cmd_reload) {
+ reload_config();
+ reply(client, user, "reloaded.");
+}
--- /dev/null
+/* cmd_global_reloadlang.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_global.h"
+
+/*
+* argv[0] language tag
+*/
+
+CMD_BIND(global_cmd_reloadlang) {
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ printf_mysql_query("SELECT `text`, `lang` FROM `language` WHERE `ident` = 'name' AND `lang` = '%s'", escape_string(argv[0]));
+ res = mysql_use();
+ if((row = mysql_fetch_row(res)) != NULL) {
+ load_language(row[1], row[0]);
+ reply(getTextBot(), user, "NS_RELOADLANG_DONE", row[0], row[1]);
+ } else {
+ reply(getTextBot(), user, "NS_RELOADLANG_UNKNOWN", argv[0]);
+ }
+}
\ No newline at end of file
--- /dev/null
+/* cmd_global_restart.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_global.h"
+
+/*
+* argv[0] soft (optional)
+*/
+
+CMD_BIND(global_cmd_restart) {
+ int hard_restart = 1;
+ if(argc > 0 && !stricmp(argv[0], "soft")) hard_restart = 0;
+ restart_bot(hard_restart);
+}
--- /dev/null
+/* cmd_global_say.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_global.h"
+
+/*
+* argv[0] target
+* argv[1-*] message
+*/
+
+CMD_BIND(global_cmd_say) {
+ char *message = merge_argv(argv, 1, argc);
+ putsock(client, "PRIVMSG %s :%s", argv[0], message);
+}
\ No newline at end of file
--- /dev/null
+/* cmd_global_setaccess.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_global.h"
+
+/*
+* argv[0] - nick / *auth
+* argv[1] - global access
+*/
+static AUTHLOOKUP_CALLBACK(global_cmd_setaccess_auth_lookup);
+static USERAUTH_CALLBACK(global_cmd_setaccess_nick_lookup);
+static void global_cmd_setaccess_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct Event *event, char *nick, char *auth, int access);
+
+struct global_cmd_setaccess_cache {
+ struct ClientSocket *client, *textclient;
+ struct UserNode *user;
+ struct Event *event;
+ int access;
+ char *nick;
+};
+
+CMD_BIND(global_cmd_setaccess) {
+ int caccess;
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ caccess = atoi(argv[1]);
+ if(caccess < 0 || caccess > 1000) {
+ reply(getTextBot(), user, "NS_INVALID_ACCESS", caccess);
+ return;
+ }
+ printf_mysql_query("SELECT `user_access` FROM `users` WHERE `user_user` = '%s'", escape_string(user->auth));
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) == NULL || atoi(row[0]) < caccess) {
+ reply(getTextBot(), user, "NS_ACCESS_OUTRANKED");
+ return;
+ }
+ 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) {
+ global_cmd_setaccess_async1(client, getTextBot(), user, event, argv[0], row[0], caccess);
+ } else {
+ //we need to create a new user...
+ //but first lookup the auth to check if it really exists
+ struct global_cmd_setaccess_cache *cache = malloc(sizeof(*cache));
+ if (!cache) {
+ perror("malloc() failed");
+ return;
+ }
+ cache->client = client;
+ cache->textclient = getTextBot();
+ cache->user = user;
+ cache->event = event;
+ cache->access = caccess;
+ cache->nick = strdup(argv[0]);
+ lookup_authname(argv[0], global_cmd_setaccess_auth_lookup, cache);
+ }
+ } else {
+ struct UserNode *cuser = getUserByNick(argv[0]);
+ if(!cuser) {
+ cuser = createTempUser(argv[0]);
+ if(!cuser) {
+ reply(getTextBot(), user, "NS_USER_UNKNOWN", argv[0]);
+ return;
+ }
+ cuser->flags |= USERFLAG_ISTMPUSER;
+ }
+ if(cuser->flags & USERFLAG_ISAUTHED) {
+ global_cmd_setaccess_async1(client, getTextBot(), user, event, argv[0], cuser->auth, caccess);
+ } else {
+ struct global_cmd_setaccess_cache *cache = malloc(sizeof(*cache));
+ if (!cache) {
+ perror("malloc() failed");
+ return;
+ }
+ cache->client = client;
+ cache->textclient = getTextBot();
+ cache->user = user;
+ cache->event = event;
+ cache->access = caccess;
+ cache->nick = strdup(argv[0]);
+ get_userauth(cuser, global_cmd_setaccess_nick_lookup, cache);
+ }
+ }
+}
+
+static AUTHLOOKUP_CALLBACK(global_cmd_setaccess_auth_lookup) {
+ struct global_cmd_setaccess_cache *cache = data;
+ if(!exists) {
+ //AUTH_DOES_NOT_EXIST
+ reply(cache->textclient, cache->user, "NS_AUTH_UNKNOWN", cache->nick);
+ } else
+ global_cmd_setaccess_async1(cache->client, cache->textclient, cache->user, cache->event, cache->nick, auth, cache->access);
+ free(cache->nick);
+ free(cache);
+}
+
+static USERAUTH_CALLBACK(global_cmd_setaccess_nick_lookup) {
+ struct global_cmd_setaccess_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
+ global_cmd_setaccess_async1(cache->client, cache->textclient, cache->user, cache->event, user->nick, user->auth, cache->access);
+ free(cache->nick);
+ free(cache);
+}
+
+static void global_cmd_setaccess_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct Event *event, char *nick, char *auth, int caccess) {
+ //we've got a valid auth now...
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ printf_mysql_query("SELECT `user_id`, `user_access` FROM `users` WHERE `user_user` = '%s'", escape_string(auth));
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) != NULL) {
+ if(atoi(row[1]) != caccess)
+ printf_mysql_query("UPDATE `users` SET `user_access` = '%d' WHERE `user_id` = '%s'", caccess, row[0]);
+ } else {
+ printf_mysql_query("INSERT INTO `users` (`user_user`, `user_access`) VALUES ('%s', '%d')", escape_string(auth), caccess);
+ }
+ reply(textclient, user, "NS_SETACCESS_DONE", auth, caccess);
+ logEvent(event);
+}
--- /dev/null
+/* cmd_global_setbot.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_global.h"
+
+/*
+* argv[0] botid
+* argv[1] setting
+* argv[2] value
+*/
+
+static int global_cmd_setbot_active(struct UserNode *user, MYSQL_ROW bot, char *value);
+static int global_cmd_setbot_nick(struct UserNode *user, MYSQL_ROW bot, char *value);
+static int global_cmd_setbot_ident(struct UserNode *user, MYSQL_ROW bot, char *value);
+static int global_cmd_setbot_realname(struct UserNode *user, MYSQL_ROW bot, char *value);
+static int global_cmd_setbot_server(struct UserNode *user, MYSQL_ROW bot, char *value);
+static int global_cmd_setbot_port(struct UserNode *user, MYSQL_ROW bot, char *value);
+static int global_cmd_setbot_bind(struct UserNode *user, MYSQL_ROW bot, char *value);
+static int global_cmd_setbot_ssl(struct UserNode *user, MYSQL_ROW bot, char *value);
+static int global_cmd_setbot_serverpass(struct UserNode *user, MYSQL_ROW bot, char *value);
+static int global_cmd_setbot_class(struct UserNode *user, MYSQL_ROW bot, char *value);
+static int global_cmd_setbot_queue(struct UserNode *user, MYSQL_ROW bot, char *value);
+static int global_cmd_setbot_prefered(struct UserNode *user, MYSQL_ROW bot, char *value);
+static int global_cmd_setbot_maxchan(struct UserNode *user, MYSQL_ROW bot, char *value);
+static int global_cmd_setbot_priority(struct UserNode *user, MYSQL_ROW bot, char *value);
+static int global_cmd_setbot_trigger(struct UserNode *user, MYSQL_ROW bot, char *value);
+
+CMD_BIND(global_cmd_setbot) {
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ int botid = atoi(argv[0]);
+ printf_mysql_query("SELECT `active`, `nick`, `server`, `port`, `pass`, `botclass`, `textbot`, `queue`, `defaulttrigger`, `max_channels`, `register_priority`, `bind`, `ident`, `realname`, `ssl`, `id` FROM `bots` WHERE `id` = '%d'", botid);
+ res = mysql_use();
+ if(!(row = mysql_fetch_row(res))) {
+ reply(getTextBot(), user, "NS_SETBOT_UNKNOWN", botid);
+ return;
+ }
+ if(argc > 1) {
+ char *value;
+ if(argc > 2) {
+ value = merge_argv(argv, 2, argc);
+ } else
+ value = NULL;
+ int log_event = 0;
+ if(!stricmp(argv[1], "active")) log_event = global_cmd_setbot_active(user, row, value);
+ else if(!stricmp(argv[1], "nick")) log_event = global_cmd_setbot_nick(user, row, value);
+ else if(!stricmp(argv[1], "ident")) log_event = global_cmd_setbot_ident(user, row, value);
+ else if(!stricmp(argv[1], "realname")) log_event = global_cmd_setbot_realname(user, row, value);
+ else if(!stricmp(argv[1], "server")) log_event = global_cmd_setbot_server(user, row, value);
+ else if(!stricmp(argv[1], "port")) log_event = global_cmd_setbot_port(user, row, value);
+ else if(!stricmp(argv[1], "bind")) log_event = global_cmd_setbot_bind(user, row, value);
+ else if(!stricmp(argv[1], "ssl")) log_event = global_cmd_setbot_ssl(user, row, value);
+ else if(!stricmp(argv[1], "serverpass")) log_event = global_cmd_setbot_serverpass(user, row, value);
+ else if(!stricmp(argv[1], "botclass")) log_event = global_cmd_setbot_class(user, row, value);
+ else if(!stricmp(argv[1], "queue")) log_event = global_cmd_setbot_queue(user, row, value);
+ else if(!stricmp(argv[1], "prefered")) log_event = global_cmd_setbot_prefered(user, row, value);
+ else if(!stricmp(argv[1], "maxchan")) log_event = global_cmd_setbot_maxchan(user, row, value);
+ else if(!stricmp(argv[1], "priority")) log_event = global_cmd_setbot_priority(user, row, value);
+ else if(!stricmp(argv[1], "trigger")) log_event = global_cmd_setbot_trigger(user, row, value);
+ else {
+ reply(getTextBot(), user, "NS_SETBOT_SETTING", argv[1]);
+ }
+ if(log_event) {
+ if(!stricmp(argv[1], "serverpass") && value) { //censor server password
+ char cmd_args[MAXLEN];
+ sprintf(cmd_args, "%d SERVERPASS ***", botid);
+ free(event->arguments);
+ event->arguments = strdup(cmd_args);
+ }
+ logEvent(event);
+ }
+ } else {
+ reply(getTextBot(), user, "NS_SETBOT_HEADER", botid);
+ global_cmd_setbot_active(user, row, NULL);
+ global_cmd_setbot_nick(user, row, NULL);
+ global_cmd_setbot_ident(user, row, NULL);
+ global_cmd_setbot_realname(user, row, NULL);
+ global_cmd_setbot_server(user, row, NULL);
+ global_cmd_setbot_port(user, row, NULL);
+ global_cmd_setbot_bind(user, row, NULL);
+ global_cmd_setbot_ssl(user, row, NULL);
+ global_cmd_setbot_serverpass(user, row, NULL);
+ global_cmd_setbot_class(user, row, NULL);
+ global_cmd_setbot_queue(user, row, NULL);
+ global_cmd_setbot_prefered(user, row, NULL);
+ global_cmd_setbot_maxchan(user, row, NULL);
+ global_cmd_setbot_priority(user, row, NULL);
+ global_cmd_setbot_trigger(user, row, NULL);
+ }
+}
+
+static int global_cmd_setbot_active(struct UserNode *user, MYSQL_ROW bot, char *value) {
+ int val = ((bot[0] && !strcmp(bot[0], "1")) ? 1 : 0);
+ int ret = 0;
+ if(value) {
+ if(!strcmp(value, "0") || !stricmp(value, "off") || !stricmp(value, get_language_string(user, "NS_SET_OFF"))) {
+ val = 0;
+ } else if(!strcmp(value, "1") || !stricmp(value, "on") || !stricmp(value, get_language_string(user, "NS_SET_ON"))) {
+ val = 1;
+ } else {
+ reply(getTextBot(), user, "NS_SET_INVALID_BOOLEAN", value);
+ return 0;
+ }
+ if(val != ((bot[0] && !strcmp(bot[0], "1")) ? 1 : 0)) {
+ if(val) {
+ //add the bot
+ struct ClientSocket *client;
+ client = create_socket(bot[2], atoi(bot[3]), bot[11], bot[4], bot[1], bot[12], bot[13]);
+ client->flags |= (strcmp(bot[6], "0") ? SOCKET_FLAG_PREFERRED : 0);
+ client->flags |= (strcmp(bot[7], "0") ? SOCKET_FLAG_USE_QUEUE : 0);
+ client->flags |= (strcmp(bot[14], "0") ? SOCKET_FLAG_SSL : 0);
+ client->botid = atoi(bot[5]);
+ client->clientid = atoi(bot[15]);
+ connect_socket(client);
+ if(client->botid == 0) {
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ printf_mysql_query("SELECT `command`, `function`, `parameters`, `global_access`, `chan_access` FROM `bot_binds` WHERE `botclass` = '0' AND `botid` = '%d'", client->clientid);
+ res = mysql_use();
+ while ((row = mysql_fetch_row(res)) != NULL) {
+ if(bind_botwise_cmd_to_command(0, client->clientid, row[0], row[1])) {
+ if(row[2] && strcmp(row[2], "")) {
+ bind_botwise_set_parameters(0, client->clientid, row[0], row[2]);
+ }
+ if(row[3]) {
+ bind_botwise_set_global_access(0, client->clientid, row[0], atoi(row[3]));
+ }
+ if(row[4]) {
+ bind_botwise_set_channel_access(0, client->clientid, row[0], row[4]);
+ }
+ }
+ }
+ bind_botwise_unbound_required_functions(0, client->clientid);
+ }
+ } else {
+ //remove the bot
+ struct ClientSocket *client;
+ for(client = getBots(0, NULL); client; client = getBots(0, client)) {
+ if(client->clientid == atoi(bot[15])) {
+ unbind_botwise_allcmd(0, client->clientid);
+ close_socket(client);
+ break;
+ }
+ }
+ }
+ printf_mysql_query("UPDATE `bots` SET `active` = '%d' WHERE `id` = '%s'", val, bot[15]);
+ ret = 1;
+ }
+ }
+ reply(getTextBot(), user, "\002ACTIVE \002 %s", get_language_string(user, (val ? "NS_SET_ON" : "NS_SET_OFF")));
+ return ret;
+}
+
+static int global_cmd_setbot_nick(struct UserNode *user, MYSQL_ROW bot, char *value) {
+ char *val = bot[1];
+ int ret = 0;
+ if(value) {
+ if(!is_valid_nick(value)) {
+ reply(getTextBot(), user, "NS_SETBOT_NICK_INVALID", value);
+ return 0;
+ }
+ //rename the bot
+ struct ClientSocket *client;
+ for(client = getBots(0, NULL); client; client = getBots(0, client)) {
+ if(client->clientid == atoi(bot[15])) {
+ if(client->nick)
+ free(client->nick);
+ client->nick = strdup(value);
+ if(client->flags & SOCKET_FLAG_READY)
+ putsock(client, "NICK %s", value);
+ break;
+ }
+ }
+ printf_mysql_query("UPDATE `bots` SET `nick` = '%s' WHERE `id` = '%s'", escape_string(value), bot[15]);
+ val = value;
+ ret = 1;
+ }
+ reply(getTextBot(), user, "\002NICK \002 %s", val);
+ return ret;
+}
+
+static int global_cmd_setbot_ident(struct UserNode *user, MYSQL_ROW bot, char *value) {
+ char *val = bot[12];
+ int ret = 0;
+ if(value) {
+ if(strlen(value) > 12)
+ value[12] = '\0';
+ //rename the bot
+ struct ClientSocket *client;
+ for(client = getBots(0, NULL); client; client = getBots(0, client)) {
+ if(client->clientid == atoi(bot[15])) {
+ if(client->ident)
+ free(client->ident);
+ client->ident = strdup(value);
+ break;
+ }
+ }
+ printf_mysql_query("UPDATE `bots` SET `ident` = '%s' WHERE `id` = '%s'", escape_string(value), bot[15]);
+ val = value;
+ ret = 1;
+ }
+ reply(getTextBot(), user, "\002IDENT \002 %s", val);
+ return ret;
+}
+
+static int global_cmd_setbot_realname(struct UserNode *user, MYSQL_ROW bot, char *value) {
+ char *val = bot[13];
+ int ret = 0;
+ if(value) {
+ if(strlen(value) > 255)
+ value[255] = '\0';
+ //rename the bot
+ struct ClientSocket *client;
+ for(client = getBots(0, NULL); client; client = getBots(0, client)) {
+ if(client->clientid == atoi(bot[15])) {
+ if(client->ident)
+ free(client->ident);
+ client->ident = strdup(value);
+ break;
+ }
+ }
+ printf_mysql_query("UPDATE `bots` SET `realname` = '%s' WHERE `id` = '%s'", escape_string(value), bot[15]);
+ val = value;
+ ret = 1;
+ }
+ reply(getTextBot(), user, "\002REALNAME \002 %s", val);
+ return ret;
+}
+
+static int global_cmd_setbot_server(struct UserNode *user, MYSQL_ROW bot, char *value) {
+ char *val = bot[2];
+ int ret = 0;
+ if(value) {
+ struct ClientSocket *client;
+ for(client = getBots(0, NULL); client; client = getBots(0, client)) {
+ if(client->clientid == atoi(bot[15])) {
+ if(client->host)
+ free(client->host);
+ client->host = strdup(value);
+ if(client->flags & SOCKET_FLAG_READY)
+ reply(getTextBot(), user, "NS_SETBOT_NEED_RESTART");
+ break;
+ }
+ }
+ printf_mysql_query("UPDATE `bots` SET `server` = '%s' WHERE `id` = '%s'", escape_string(value), bot[15]);
+ val = value;
+ ret = 1;
+ }
+ reply(getTextBot(), user, "\002SERVER \002 %s", val);
+ return ret;
+}
+
+static int global_cmd_setbot_port(struct UserNode *user, MYSQL_ROW bot, char *value) {
+ int val = atoi(bot[3]);
+ int ret = 0;
+ if(value) {
+ val = atoi(value);
+ if(val <= 0 || val > 65534) {
+ reply(getTextBot(), user, "NS_SETBOT_PORT_INVALID", value);
+ return 0;
+ }
+ struct ClientSocket *client;
+ for(client = getBots(0, NULL); client; client = getBots(0, client)) {
+ if(client->clientid == atoi(bot[15])) {
+ client->port = val;
+ if(client->flags & SOCKET_FLAG_READY)
+ reply(getTextBot(), user, "NS_SETBOT_NEED_RESTART");
+ break;
+ }
+ }
+ printf_mysql_query("UPDATE `bots` SET `port` = '%d' WHERE `id` = '%s'", val, bot[15]);
+ ret = 1;
+ }
+ reply(getTextBot(), user, "\002PORT \002 %d", val);
+ return ret;
+}
+
+static int global_cmd_setbot_bind(struct UserNode *user, MYSQL_ROW bot, char *value) {
+ char *val = bot[11];
+ int ret = 0;
+ if(value) {
+ if(!strcmp(value, "*"))
+ value = NULL;
+ struct ClientSocket *client;
+ for(client = getBots(0, NULL); client; client = getBots(0, client)) {
+ if(client->clientid == atoi(bot[15])) {
+ if(client->bind)
+ free(client->bind);
+ client->bind = (value ? strdup(value) : NULL);
+ if(client->flags & SOCKET_FLAG_READY)
+ reply(getTextBot(), user, "NS_SETBOT_NEED_RESTART");
+ break;
+ }
+ }
+ if(value)
+ printf_mysql_query("UPDATE `bots` SET `bind` = '%s' WHERE `id` = '%s'", escape_string(value), bot[15]);
+ else
+ printf_mysql_query("UPDATE `bots` SET `bind` = NULL WHERE `id` = '%s'", bot[15]);
+ val = value;
+ ret = 1;
+ }
+ reply(getTextBot(), user, "\002BIND \002 %s", val);
+ return ret;
+}
+
+static int global_cmd_setbot_ssl(struct UserNode *user, MYSQL_ROW bot, char *value) {
+ int val = (strcmp(bot[14], "0") ? 1 : 0);
+ int ret = 0;
+ if(value) {
+ if(!strcmp(value, "0") || !stricmp(value, "off") || !stricmp(value, get_language_string(user, "NS_SET_OFF"))) {
+ val = 0;
+ } else if(!strcmp(value, "1") || !stricmp(value, "on") || !stricmp(value, get_language_string(user, "NS_SET_ON"))) {
+ val = 1;
+ } else {
+ reply(getTextBot(), user, "NS_SET_INVALID_BOOLEAN", value);
+ return 0;
+ }
+ struct ClientSocket *client;
+ for(client = getBots(0, NULL); client; client = getBots(0, client)) {
+ if(client->clientid == atoi(bot[15])) {
+ if(val)
+ client->flags |= SOCKET_FLAG_SSL;
+ else
+ client->flags &= ~SOCKET_FLAG_SSL;
+ if(client->flags & SOCKET_FLAG_READY)
+ reply(getTextBot(), user, "NS_SETBOT_NEED_RESTART");
+ break;
+ }
+ }
+ printf_mysql_query("UPDATE `bots` SET `ssl` = '%d' WHERE `id` = '%s'", val, bot[15]);
+ ret = 1;
+ }
+ reply(getTextBot(), user, "\002SSL \002 %s", get_language_string(user, (val ? "NS_SET_ON" : "NS_SET_OFF")));
+ return ret;
+}
+
+static int global_cmd_setbot_serverpass(struct UserNode *user, MYSQL_ROW bot, char *value) {
+ char *val = bot[4];
+ int ret = 0;
+ if(value) {
+ if(!strcmp(value, "*"))
+ value = "";
+ struct ClientSocket *client;
+ for(client = getBots(0, NULL); client; client = getBots(0, client)) {
+ if(client->clientid == atoi(bot[15])) {
+ if(client->pass)
+ free(client->pass);
+ client->pass = (value ? strdup(value) : NULL);
+ if(client->flags & SOCKET_FLAG_READY)
+ reply(getTextBot(), user, "NS_SETBOT_NEED_RESTART");
+ break;
+ }
+ }
+ printf_mysql_query("UPDATE `bots` SET `pass` = '%s' WHERE `id` = '%s'", escape_string(value), bot[15]);
+ val = value;
+ ret = 1;
+ }
+ reply(getTextBot(), user, "\002SERVERPASS \002 %s", val);
+ return ret;
+}
+
+static int global_cmd_setbot_class(struct UserNode *user, MYSQL_ROW bot, char *value) {
+ int val = atoi(bot[5]);
+ int ret = 0;
+ if(value) {
+ if((val = resolve_botalias(value)) == -1) {
+ reply(getTextBot(), user, "NS_SETBOT_INVALID_CLASS", value);
+ return 0;
+ }
+ if(val != atoi(bot[5])) {
+ struct ClientSocket *client;
+ for(client = getBots(0, NULL); client; client = getBots(0, client)) {
+ if(client->clientid == atoi(bot[15])) {
+ unbind_botwise_allcmd(client->clientid);
+ client->botid = val;
+ if(client->botid == 0) {
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ printf_mysql_query("SELECT `command`, `function`, `parameters`, `global_access`, `chan_access` FROM `bot_binds` WHERE `botclass` = '0' AND `botid` = '%d'", client->clientid);
+ res = mysql_use();
+ while ((row = mysql_fetch_row(res)) != NULL) {
+ if(bind_botwise_cmd_to_command(client->botid, client->clientid, row[0], row[1])) {
+ if(row[2] && strcmp(row[2], "")) {
+ bind_botwise_set_parameters(client->botid, client->clientid, row[0], row[2]);
+ }
+ if(row[3]) {
+ bind_botwise_set_global_access(client->botid, client->clientid, row[0], atoi(row[3]));
+ }
+ if(row[4]) {
+ bind_botwise_set_channel_access(client->botid, client->clientid, row[0], row[4]);
+ }
+ }
+ }
+ bind_botwise_unbound_required_functions(client->botid, client->clientid);
+ }
+ break;
+ }
+ }
+ printf_mysql_query("UPDATE `bots` SET `botclass` = '%d' WHERE `id` = '%s'", val, bot[15]);
+ ret = 1;
+ }
+ }
+ reply(getTextBot(), user, "\002BOTCLASS \002 %s", resolve_botid(val));
+ return ret;
+}
+
+static int global_cmd_setbot_queue(struct UserNode *user, MYSQL_ROW bot, char *value) {
+ int val = (strcmp(bot[7], "0") ? 1 : 0);
+ int ret = 0;
+ if(value) {
+ if(!strcmp(value, "0") || !stricmp(value, "off") || !stricmp(value, get_language_string(user, "NS_SET_OFF"))) {
+ val = 0;
+ } else if(!strcmp(value, "1") || !stricmp(value, "on") || !stricmp(value, get_language_string(user, "NS_SET_ON"))) {
+ val = 1;
+ } else {
+ reply(getTextBot(), user, "NS_SET_INVALID_BOOLEAN", value);
+ return 0;
+ }
+ struct ClientSocket *client;
+ for(client = getBots(0, NULL); client; client = getBots(0, client)) {
+ if(client->clientid == atoi(bot[15])) {
+ if(val)
+ client->flags |= SOCKET_FLAG_USE_QUEUE;
+ else
+ client->flags &= ~SOCKET_FLAG_USE_QUEUE;
+ break;
+ }
+ }
+ printf_mysql_query("UPDATE `bots` SET `queue` = '%d' WHERE `id` = '%s'", val, bot[15]);
+ ret = 1;
+ }
+ reply(getTextBot(), user, "\002QUEUE \002 %s", get_language_string(user, (val ? "NS_SET_ON" : "NS_SET_OFF")));
+ return ret;
+}
+
+static int global_cmd_setbot_prefered(struct UserNode *user, MYSQL_ROW bot, char *value) {
+ int val = (strcmp(bot[6], "0") ? 1 : 0);
+ int ret = 0;
+ if(value) {
+ if(!strcmp(value, "0") || !stricmp(value, "off") || !stricmp(value, get_language_string(user, "NS_SET_OFF"))) {
+ val = 0;
+ } else if(!strcmp(value, "1") || !stricmp(value, "on") || !stricmp(value, get_language_string(user, "NS_SET_ON"))) {
+ val = 1;
+ } else {
+ reply(getTextBot(), user, "NS_SET_INVALID_BOOLEAN", value);
+ return 0;
+ }
+ struct ClientSocket *client;
+ for(client = getBots(0, NULL); client; client = getBots(0, client)) {
+ if(client->clientid == atoi(bot[15])) {
+ if(val)
+ client->flags |= SOCKET_FLAG_PREFERRED;
+ else
+ client->flags &= ~SOCKET_FLAG_PREFERRED;
+ break;
+ }
+ }
+ printf_mysql_query("UPDATE `bots` SET `prefered` = '%d' WHERE `id` = '%s'", val, bot[15]);
+ ret = 1;
+ }
+ reply(getTextBot(), user, "\002PREFERED \002 %s", get_language_string(user, (val ? "NS_SET_ON" : "NS_SET_OFF")));
+ return ret;
+}
+
+static int global_cmd_setbot_maxchan(struct UserNode *user, MYSQL_ROW bot, char *value) {
+ int val = atoi(bot[9]);
+ int ret = 0;
+ if(value) {
+ val = atoi(value);
+ if(val < 0 || val > 99999) {
+ reply(getTextBot(), user, "NS_SETBOT_MAXCHAN_INVALID", value);
+ return 0;
+ }
+ printf_mysql_query("UPDATE `bots` SET `max_channels` = '%d' WHERE `id` = '%s'", val, bot[15]);
+ ret = 1;
+ }
+ reply(getTextBot(), user, "\002MAXCHAN \002 %d", val);
+ return ret;
+}
+
+static int global_cmd_setbot_priority(struct UserNode *user, MYSQL_ROW bot, char *value) {
+ int val = atoi(bot[10]);
+ int ret = 0;
+ if(value) {
+ val = atoi(value);
+ if(val < 0 || val > 99) {
+ reply(getTextBot(), user, "NS_SETBOT_PRIORITY_INVALID", value);
+ return 0;
+ }
+ printf_mysql_query("UPDATE `bots` SET `register_priority` = '%d' WHERE `id` = '%s'", val, bot[15]);
+ ret = 1;
+ }
+ reply(getTextBot(), user, "\002PRIORITY \002 %d", val);
+ return ret;
+}
+
+static int global_cmd_setbot_trigger(struct UserNode *user, MYSQL_ROW bot, char *value) {
+ char *val = bot[8];
+ int ret = 0;
+ if(value) {
+ if(!*value || strlen(value) > 10) {
+ reply(getTextBot(), user, "NS_SETBOT_TRIGGER_INVALID", value);
+ return 0;
+ }
+ printf_mysql_query("UPDATE `bots` SET `defaulttrigger` = '%s' WHERE `id` = '%s'", escape_string(value), bot[15]);
+ flush_trigger_cache(atoi(bot[5]), atoi(bot[15]));
+ reply(getTextBot(), user, "NS_SETBOT_TRIGGER_NOTE");
+ val = value;
+ ret = 1;
+ }
+ reply(getTextBot(), user, "\002TRIGGER \002 %s", val);
+ return ret;
+}
--- /dev/null
+/* cmd_global_staff.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_global.h"
+
+/*
+* no arguments
+*/
+
+CMD_BIND(global_cmd_staff) {
+ MYSQL_RES *res, *res2;
+ MYSQL_ROW row, row2;
+ printf_mysql_query("SELECT `rank_id`, `rank_name` FROM `support_ranks` ORDER BY `rank_order` ASC");
+ res = mysql_use();
+ while ((row = mysql_fetch_row(res)) != NULL) {
+ printf_mysql_query("SELECT `user_user`, `user_god` FROM `users` WHERE `user_rank` = '%s'", row[0]);
+ res2 = mysql_use();
+ if(mysql_num_rows(res2)) {
+ reply(getTextBot(), user, "\002%s\002", row[1]);
+ while ((row2 = mysql_fetch_row(res2)) != NULL) {
+ if(strcmp(row2[1], "0")) {
+ //god enabled - show nicks
+ char loggedinBuf[MAXLEN];
+ int loggedinPos = 0;
+ struct UserNode *cuser;
+ for(cuser = getUsersWithAuth(row2[0], NULL); cuser; cuser = getUsersWithAuth(row2[0], cuser)) {
+ loggedinPos += sprintf(loggedinBuf+loggedinPos, (loggedinPos ? ", %s" : "%s"), cuser->nick);
+ }
+ if(loggedinPos)
+ reply(getTextBot(), user, " %s (%s: %s)", row2[0], get_language_string(user, "NS_STAFF_LOGGEDIN"), loggedinBuf);
+ else
+ reply(getTextBot(), user, " %s", row2[0]);
+ } else
+ reply(getTextBot(), user, " %s", row2[0]);
+ }
+ }
+ }
+}
--- /dev/null
+/* cmd_global_unbind.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_global.h"
+
+/*
+* argv[0] command name
+*/
+
+CMD_BIND(global_cmd_unbind) {
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ struct cmd_binding *cbind = find_botwise_cmd_binding(client->botid, client->clientid, argv[0]);
+ if(client->botid == 0)
+ printf_mysql_query("SELECT `id`, `function` FROM `bot_binds` WHERE `botclass` = '0' AND `botid` = '%d' AND `command` = '%s'", client->clientid, escape_string(argv[0]));
+ else
+ printf_mysql_query("SELECT `id`, `function` FROM `bot_binds` WHERE `botclass` = '%d' AND `command` = '%s'", client->botid, escape_string(argv[0]));
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) == NULL && (!cbind || !(cbind->flags & CMDFLAG_TEMPONARY_BIND))) {
+ reply(getTextBot(), user, "NS_UNBIND_NOT_FOUND", argv[0]);
+ return;
+ }
+ struct cmd_function *function = find_cmd_function(client->botid, cbind->func->name);
+ if(function && (function->flags & CMDFLAG_REQUIRED)) {
+ if(client->botid == 0)
+ printf_mysql_query("SELECT `id` FROM `bot_binds` WHERE `botclass` = '0' AND `botid` = '%d' AND `function` = '%s'", client->clientid, escape_string(function->name));
+ else
+ printf_mysql_query("SELECT `id` FROM `bot_binds` WHERE `botclass` = '%d' AND `function` = '%s'", client->botid, escape_string(function->name));
+ res = mysql_use();
+ if (mysql_num_rows(res) <= 1) {
+ reply(getTextBot(), user, "NS_UNBIND_REQUIRED", function->name);
+ return;
+ }
+ }
+ unbind_botwise_cmd(client->botid, client->clientid, argv[0]);
+ if(!cbind || !(cbind->flags & CMDFLAG_TEMPONARY_BIND))
+ printf_mysql_query("DELETE FROM `bot_binds` WHERE `id` = '%s'", row[0]);
+ reply(getTextBot(), user, "NS_UNBIND_DONE", argv[0]);
+ logEvent(event);
+}
--- /dev/null
+/* cmd_global_unregister.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_global.h"
+
+/*
+* argv[0] - channel
+*/
+CMD_BIND(global_cmd_unregister) {
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ char *channel;
+ if(argc)
+ channel = argv[0];
+ else
+ channel = (chan ? chan->name : "");
+ if(!is_valid_chan(channel)) {
+ reply(getTextBot(), user, "NS_INVALID_CHANNEL_NAME", argv[0]);
+ 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 {
+ reply(getTextBot(), user, "NS_UNREGISTER_NOT_REGISTERED", argv[0], client->user->nick);
+ return;
+ }
+ if(client->botid == 0)
+ printf_mysql_query("SELECT `botid`, `bot_channels`.`id`, `suspended` FROM `bot_channels` LEFT JOIN `bots` ON `bot_channels`.`botid` = `bots`.`id` WHERE `chanid` = '%d' AND `botclass` = '0' AND `botid` = '%d'", chanid, client->clientid);
+ else
+ printf_mysql_query("SELECT `botid`, `bot_channels`.`id`, `suspended` FROM `bot_channels` LEFT JOIN `bots` ON `bot_channels`.`botid` = `bots`.`id` WHERE `chanid` = '%d' AND `botclass` = '%d'", chanid, client->botid);
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) == NULL) {
+ reply(getTextBot(), user, "NS_UNREGISTER_NOT_REGISTERED", argv[0], client->user->nick);
+ return;
+ }
+ int botid = atoi(row[0]);
+ struct ClientSocket *bot;
+ for(bot = getBots(SOCKET_FLAG_READY, NULL); bot; bot = getBots(SOCKET_FLAG_READY, bot)) {
+ if(bot->clientid == botid)
+ break;
+ }
+ printf_mysql_query("DELETE FROM `bot_channels` WHERE `id` = '%s'", row[1]);
+ reply(getTextBot(), user, "NS_UNREGISTER_DONE", channel);
+ if(bot && strcmp(row[2], "1")) {
+ putsock(bot, "PART %s :Channel unregistered.", channel);
+ }
+ logEvent(event);
+}
--- /dev/null
+/* cmd_global_version.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cmd_global.h"
+
+/*
+* no args
+*/
+
+CMD_BIND(global_cmd_version) {
+ reply(getTextBot(), user, "\002NeonServ %s.%d\002 (%s), written by pk910", NEONSERV_VERSION, patchlevel, (strcmp(revision, "") ? revision : "-"));
+ reply(getTextBot(), user, "Build (#%s) %s (%s lines, " COMPILER ")", compilation, creation, codelines);
+ reply(getTextBot(), user, "NeonServ can be found on: http://dev.pk910.de/NeonServ");
+ //helpers :D
+ reply(getTextBot(), user, "special thanks to:");
+ reply(getTextBot(), user, " Zer0n, TeaTow, Phil (testing and ideas current version)");
+ reply(getTextBot(), user, " Buschman, Zer0n, Neon (translating current version)");
+ reply(getTextBot(), user, " Patschi95, DerGrinch, Darkfly, Zer0n, Buschman (testing and ideas older versions)");
+ reply(getTextBot(), user, " Buschman, Georg, richard (translating older versions)");
+ reply(getTextBot(), user, "and all the other users that reported all these nasty bugs :D");
+ reply(getTextBot(), user, "\002If you found a bug or if you have a good idea report it on http://dev.pk910.de/BugTrack\002");
+
+}
\ No newline at end of file
--- /dev/null
+/* module.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "../module.h"
+#include "cmd_global.h"
+
+static int module_initialize() {
+ register_commands();
+ return 0;
+}
+
+static void module_start(int type) {
+
+}
+
+static void module_loop() {
+
+}
+
+static void module_stop(int type) {
+
+}
+
+MODULE_HEADER(module_initialize, module_start, module_loop, module_stop);
--- /dev/null
+/* module.h - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef _module_h
+#define _module_h
+#define DND_FUNCTIONS 1 /* DoNotDefine_Functions */
+#include "../overall.h"
+#include "../version.h"
+#include "../mysqlConn.h"
+
+extern void **global;
+extern int module_id;
+
+/**** global function list ****/
+/* 000 */ #define getStartTime ((time_t (*)(void))global[0])
+/* 001 */ #define getRunningThreads ((int (*)(void))global[1])
+/* 002 */ #define exit_daemon ((int (*)(void))global[2])
+/* 003 */ #define stricmp ((int (*)(const char *, const char *))global[3])
+/* 004 */ #define stricmplen ((int (*)(const char *, const char *, int))global[4])
+/* 005 */ #define restart_process ((void (*)(void))global[5])
+/* 006 */ #define cleanup ((void (*)(void))global[6])
+/* 007 */ #define restart_bot ((void (*)(int))global[7])
+/* 008 */ #define stop_bot ((void (*)(void))global[8])
+/* 009 */ #define reload_config ((void (*)(void))global[9])
+/* 010 */ #define putlog ((void (*)(int, const char *, ...))global[10])
+#ifdef HAVE_THREADS
+/* 011 */ #define getCurrentThreadID ((int (*)(void))global[11])
+#endif
+/* 012 */ #define getMatchingChannelBan ((struct BanNode* (*)(struct ChanNode *, char *))global[12])
+/* 013 */ #define getChannelBot ((struct ClientSocket* (*)(struct ChanNode *, int))global[13])
+/* 014 */ #define requestOp ((void (*)(struct UserNode *, struct ChanNode *))global[14])
+/* 015 */ #define channel_ban_timeout ((void (*)(void *))global[15])
+/* 016 */ #define general_event_privctcp ((void (*)(struct UserNode *, struct UserNode *, char *, char *))global[16])
+/* 017 */ #define set_bot_alias ((void (*)(int, char *))global[17])
+/* 018 */ #define resolve_botid ((const char * (*)(int))global[18])
+/* 019 */ #define resolve_botalias ((int (*)(const char *))global[19])
+/* 020 */ #define is_valid_chan ((int (*)(const char *))global[20])
+/* 021 */ #define getAllChans ((struct ChanNode* (*)(struct ChanNode *))global[21])
+/* 022 */ #define getChanByName ((struct ChanNode* (*)(const char *))global[22])
+/* 023 */ #define getChannelCount ((int (*)(void))global[23])
+/* 024 */ #define getChanUserCount ((int (*)(void))global[24])
+/* 025 */ #define getChanBanCount ((int (*)(void))global[25])
+/* 026 */ #define isUserOnChan ((int (*)(struct UserNode *, struct ChanNode *))global[26])
+/* 027 */ #define getChanUser ((struct ChanUser* (*)(struct UserNode *, struct ChanNode *))global[27])
+/* 028 */ #define getChannelUsers ((struct ChanUser* (*)(struct ChanNode *, struct ChanUser *))global[28])
+/* 029 */ #define getUserChannels ((struct ChanUser* (*)(struct UserNode *, struct ChanUser *))global[29])
+/* 030 */ #define create_socket ((struct ClientSocket* (*)(char *, int, char *, char *, char *, char *, char *))global[30])
+/* 031 */ #define connect_socket ((int (*)(struct ClientSocket *))global[31])
+/* 032 */ #define close_socket ((int (*)(struct ClientSocket *))global[32])
+/* 033 */ #define disconnect_socket ((int (*)(struct ClientSocket *))global[33])
+/* 034 */ #define write_socket ((int (*)(struct ClientSocket *, char*, int))global[34])
+/* 035 */ #define putsock ((void (*)(struct ClientSocket *, const char *, ...))global[35])
+/* 036 */ #define getBots ((struct ClientSocket* (*)(int, struct ClientSocket *))global[36])
+/* 037 */ #define get_int_field ((int (*)(char *))global[37])
+/* 038 */ #define get_string_field ((char * (*)(char *))global[38])
+/* 039 */ #define _loadUserSettings ((void (*)(struct UserNode *))global[39])
+/* 040 */ #define isGodMode ((int (*)(struct UserNode *))global[40])
+/* 041 */ #define getChanDefault ((char * (*)(char *))global[41])
+/* 042 */ #define getChannelAccess ((int (*)(struct UserNode *, struct ChanNode *))global[42])
+/* 043 */ #define checkChannelAccess ((int (*)(struct UserNode *, struct ChanNode *, char *, int))global[43])
+/* 044 */ #define _loadChannelSettings ((void (*)(struct ChanNode *))global[44])
+/* 045 */ #define isUserProtected ((int (*)(struct ChanNode *, struct UserNode *, struct UserNode *))global[45])
+/* 046 */ #define getBanAffectingMask ((char * (*)(struct ChanNode *, char *))global[46])
+/* 047 */ #define renameAccount ((int (*)(char *, char *))global[47])
+/* 048 */ #define deleteUser ((void (*)(int))global[48])
+/* 049 */ #define logEvent ((void (*)(struct Event *))global[49])
+/* 050 */ #define lookup_authname ((void (*)(char *, authlookup_callback_t, void *))global[50])
+/* 051 */ #define bind_join ((int (*)(join_func_t *, int))global[51])
+/* 052 */ #define unbind_join ((void (*)(join_func_t *))global[52])
+/* 053 */ #define bind_nick ((int (*)(nick_func_t *, int))global[53])
+/* 054 */ #define unbind_nick ((void (*)(nick_func_t *))global[54])
+/* 055 */ #define bind_part ((int (*)(part_func_t *, int))global[55])
+/* 056 */ #define unbind_part ((void (*)(part_func_t *))global[56])
+/* 057 */ #define bind_quit ((int (*)(quit_func_t *, int))global[57])
+/* 058 */ #define unbind_quit ((void (*)(quit_func_t *))global[58])
+/* 059 */ #define bind_kick ((int (*)(kick_func_t *, int))global[59])
+/* 060 */ #define unbind_kick ((void (*)(kick_func_t *))global[60])
+/* 061 */ #define bind_topic ((int (*)(topic_func_t *, int))global[61])
+/* 062 */ #define unbind_topic ((void (*)(topic_func_t *))global[62])
+/* 063 */ #define bind_mode ((int (*)(mode_func_t *, int))global[63])
+/* 064 */ #define unbind_mode ((void (*)(mode_func_t *))global[64])
+/* 065 */ #define bind_chanmsg ((int (*)(chanmsg_func_t *, int))global[65])
+/* 066 */ #define unbind_chanmsg ((void (*)(chanmsg_func_t *))global[66])
+/* 067 */ #define bind_privmsg ((int (*)(privmsg_func_t *, int))global[67])
+/* 068 */ #define unbind_privmsg ((void (*)(privmsg_func_t *))global[68])
+/* 069 */ #define bind_channotice ((int (*)(channotice_func_t *, int))global[69])
+/* 070 */ #define unbind_channotice ((void (*)(channotice_func_t *))global[70])
+/* 071 */ #define bind_privnotice ((int (*)(privnotice_func_t *, int))global[71])
+/* 072 */ #define unbind_privnotice ((void (*)(privnotice_func_t *))global[72])
+/* 073 */ #define bind_chanctcp ((int (*)(chanctcp_func_t *, int))global[73])
+/* 074 */ #define unbind_chanctcp ((void (*)(chanctcp_func_t *))global[74])
+/* 075 */ #define bind_privctcp ((int (*)(privctcp_func_t *, int))global[75])
+/* 076 */ #define unbind_privctcp ((void (*)(privctcp_func_t *))global[76])
+/* 077 */ #define bind_invite ((int (*)(invite_func_t *, int))global[77])
+/* 078 */ #define unbind_invite ((void (*)(invite_func_t *))global[78])
+/* 079 */ #define bind_raw ((int (*)(raw_func_t *, int))global[79])
+/* 080 */ #define unbind_raw ((void (*)(raw_func_t *))global[80])
+/* 081 */ #define bind_bot_ready ((int (*)(bot_ready_func_t *, int))global[81])
+/* 082 */ #define unbind_bot_ready ((void (*)(bot_ready_func_t *))global[82])
+/* 083 */ #define bind_registered ((int (*)(registered_func_t *, int))global[83])
+/* 084 */ #define unbind_registered ((void (*)(registered_func_t *))global[84])
+/* 085 */ #define bind_freeuser ((int (*)(freeuser_func_t *, int))global[85])
+/* 086 */ #define unbind_freeuser ((void (*)(freeuser_func_t *))global[86])
+/* 087 */ #define bind_freechan ((int (*)(freechan_func_t *, int))global[87])
+/* 088 */ #define unbind_freechan ((void (*)(freechan_func_t *))global[88])
+/* 089 */ #define reply ((void (*)(struct ClientSocket *, struct UserNode *, const char *, ...))global[89])
+/* 090 */ #define merge_argv ((char * (*)(char **, int, int))global[90])
+/* 091 */ #define merge_argv_char ((char * (*)(char **, int, int, char))global[91])
+/* 092 */ #define get_language_by_tag ((struct language * (*)(char *))global[92])
+/* 093 */ #define get_language_by_name ((struct language * (*)(char *))global[93])
+/* 094 */ #define get_default_language ((struct language * (*)(void))global[94])
+/* 095 */ #define load_language ((void (*)(char *, char *))global[95])
+/* 096 */ #define register_default_language_table ((void (*)(const struct default_language_entry *))global[96])
+/* 097 */ #define get_language_string ((char * (*)(struct UserNode *, const char *))global[97])
+/* 098 */ #define build_language_string ((char * (*)(struct UserNode *, char *, const char *, ...))global[98])
+#ifdef ENABLE_MEMORY_DEBUG
+/* 099 */ #define xmalloc ((void * (*)(unsigned int, const char *, unsigned int))global[99])
+/* 100 */ #define xcalloc ((void * (*)(unsigned int, unsigned int, const char *, unsigned int))global[100])
+/* 101 */ #define xstrdup ((char * (*)(const char *, const char *, unsigned int))global[101])
+/* 102 */ #define xfree ((void (*)(void *))global[102])
+#endif
+/* 103 */ #define getMemoryInfoFiles ((struct memoryInfoFiles * (*)(void))global[103])
+/* 104 */ #define freeMemoryInfoFiles ((void (*)(struct memoryInfoFiles *))global[104])
+/* 105 */ #define getMemoryInfoLines ((struct memoryInfoLines * (*)(const char *))global[105])
+/* 106 */ #define freeMemoryInfoLines ((void (*)(struct memoryInfoLines *))global[106])
+/* 107 */ #define get_botwise_prefered_bot ((struct ClientSocket * (*)(int, int))global[107])
+/* 108 */ #define register_command ((int (*)(int, char *, int, cmd_bind_t *, int, char *, int, unsigned int))global[108])
+/* 109 */ #define set_trigger_callback ((int (*)(int, int, trigger_callback_t *))global[109])
+/* 110 */ #define flush_trigger_cache ((int (*)(int, int))global[110])
+/* 111 */ #define changeBotwiseChannelTrigger ((int (*)(int, int, struct ChanNode *, char *))global[111])
+/* 112 */ #define bind_botwise_cmd_to_function ((int (*)(int, int, char *, struct cmd_function *))global[112])
+/* 113 */ #define bind_botwise_cmd_to_command ((int (*)(int, int, char *, char *))global[113])
+/* 114 */ #define unbind_botwise_cmd ((int (*)(int, int, char *))global[114])
+/* 115 */ #define unbind_botwise_allcmd ((int (*)(int, int))global[115])
+/* 116 */ #define bind_botwise_set_parameters ((void (*)(int, int, char *, char *))global[116])
+/* 117 */ #define bind_botwise_set_global_access ((void (*)(int, int, char *, int))global[117])
+/* 118 */ #define bind_botwise_set_channel_access ((void (*)(int, int, char *, char *))global[118])
+/* 119 */ #define bind_botwise_set_bind_flags ((void (*)(int, int, char *, unsigned int))global[119])
+/* 120 */ #define find_botwise_cmd_binding ((struct cmd_binding * (*)(int, int, char *))global[120])
+/* 121 */ #define bind_botwise_unbound_required_functions ((void (*)(int, int))global[121])
+/* 122 */ #define find_cmd_function ((struct cmd_function * (*)(int , char *))global[122])
+/* 123 */ #define getTextBot ((struct ClientSocket * (*)(void))global[123])
+/* 124 */ #define register_command_alias ((void (*)(int, char *))global[124])
+/* 125 */ #define getAllBinds ((struct cmd_binding * (*)(struct cmd_binding *))global[125])
+/* 126 */ #define createModeNode ((struct ModeNode * (*)(struct ChanNode *))global[126])
+/* 127 */ #define freeModeNode ((void (*)(struct ModeNode *))global[127])
+/* 128 */ #define isModeSet ((int (*)(struct ModeNode *, char))global[128])
+/* 129 */ #define isModeAffected ((int (*)(struct ModeNode *, char))global[129])
+/* 130 */ #define getModeValue ((void * (*)(struct ModeNode *, char))global[130])
+/* 131 */ #define getModeType ((unsigned int (*)(struct ModeNode *, char))global[131])
+/* 132 */ #define parseModes ((void (*)(struct ModeNode *, char *, char **, int))global[132])
+/* 133 */ #define parseModeString ((void (*)(struct ModeNode *, char *))global[133])
+/* 134 */ #define parseMode ((int (*)(struct ModeNode *, int, char, char *))global[134])
+/* 135 */ #define getModeString ((void (*)(struct ModeNode *, char *))global[135])
+/* 136 */ #define getFullModeString ((void (*)(struct ModeNode *, char *))global[136])
+/* 137 */ #define mysql_use ((MYSQL_RES * (*)(void))global[137])
+/* 138 */ #define mysql_free ((void (*)(void))global[138])
+/* 139 */ #define printf_mysql_query ((void (*)(const char *, ...))global[139])
+/* 140 */ #define printf_long_mysql_query ((void (*)(int, const char *, ...))global[140])
+/* 141 */ #define escape_string ((char * (*)(const char *))global[141])
+/* 142 */ #define get_mysql_conn ((MYSQL * (*)(void))global[142])
+/* 143 */ #define timeq_add ((struct timeq_entry * (*)(int, int, timeq_callback_t *, void *))global[143])
+/* 144 */ #define timeq_uadd ((struct timeq_entry * (*)(int, int, timeq_callback_t *, void *))global[144])
+/* 145 */ #define timeq_add_name ((struct timeq_entry * (*)(char *, int, int, timeq_callback_t *, void *))global[145])
+/* 146 */ #define timeq_uadd_name ((struct timeq_entry * (*)(char *, int, int, timeq_callback_t *, void *))global[146])
+/* 147 */ #define timeq_del ((int (*)(struct timeq_entry *))global[147])
+/* 148 */ #define timeq_del_name ((int (*)(char *))global[148])
+/* 149 */ #define timeq_name_exists ((int (*)(char *))global[149])
+/* 150 */ #define match ((int (*)(const char *, const char *))global[150])
+/* 151 */ #define table_init ((struct Table * (*)(int, int, int))global[151])
+/* 152 */ #define table_add ((int (*)(struct Table *, char **))global[152])
+/* 153 */ #define table_change ((int (*)(struct Table *, int, char **))global[153])
+/* 154 */ #define table_change_field ((int (*)(struct Table *, int, int, char *))global[154])
+/* 155 */ #define table_set_bold ((int (*)(struct Table *, int, int))global[155])
+/* 156 */ #define table_end ((char ** (*)(struct Table *))global[156])
+/* 157 */ #define table_free ((void (*)(struct Table *))global[157])
+/* 158 */ #define timeToStr ((char * (*)(struct UserNode *, int, int, char *))global[158])
+/* 159 */ #define strToTime ((int (*)(struct UserNode *, char *))global[159])
+/* 160 */ #define initModeBuffer ((struct ModeBuffer * (*)(struct ClientSocket *, struct ChanNode *))global[160])
+/* 161 */ #define modeBufferSet ((void (*)(struct ModeBuffer *, int, char, char *))global[161])
+/* 162 */ #define flushModeBuffer ((void (*)(struct ModeBuffer *))global[162])
+/* 163 */ #define freeModeBuffer ((void (*)(struct ModeBuffer *))global[163])
+/* 164 */ #define is_ircmask ((int (*)(const char *))global[164])
+/* 165 */ #define generate_banmask ((char * (*)(struct UserNode *, char *))global[165])
+/* 166 */ #define make_banmask ((char * (*)(char *, char *))global[166])
+/* 167 */ #define isFakeHost ((int (*)(char *))global[167])
+/* 168 */ #define mask_match ((int (*)(char *, struct UserNode *))global[168])
+/* 169 */ #define crc32 ((unsigned long (*)(const char *))global[169])
+/* 170 */ #define is_valid_nick ((int (*)(const char *))global[170])
+/* 171 */ #define getUserByNick ((struct UserNode * (*)(const char *))global[171])
+/* 172 */ #define getUserByMask ((struct UserNode * (*)(const char *))global[172])
+/* 173 */ #define countUsersWithHost ((int (*)(char *))global[173])
+/* 174 */ #define getAuthFakehost ((char * (*)(char *))global[174])
+/* 175 */ #define searchUserByNick ((struct UserNode * (*)(const char *))global[175])
+/* 176 */ #define getAllUsers ((struct UserNode * (*)(struct UserNode *))global[176])
+/* 177 */ #define getUsersWithAuth ((struct UserNode * (*)(const char *, struct UserNode *))global[177])
+/* 178 */ #define getUserCount ((int (*)(void))global[178])
+/* 179 */ #define get_userlist ((void (*)(struct ChanNode *, int, userlist_callback_t, void *))global[179])
+/* 180 */ #define _get_userlist_with_invisible ((void (*)(struct ChanNode *, int, userlist_callback_t, void *, int))global[180])
+/* 181 */ #define get_userauth ((void (*)(struct UserNode *, int, userauth_callback_t, void *))global[181])
+/* 182 */ #define compilation ((const char *) *global[182])
+/* 183 */ #define creation ((const char *) *global[183])
+/* 184 */ #define revision ((const char *) *global[184])
+/* 185 */ #define codelines ((const char *) *global[185])
+/* 186 */ #define patchlevel ((const int) *global[186])
+
+#define MODULE_HEADER(initfunc,startfunc,loopfunc,stopfunc) \
+ void **global = NULL; \
+ int module_id = 0; \
+ int init_module(void **functions, int modid) { \
+ global = functions; \
+ module_id = modid; \
+ return initfunc(data); \
+ } \
+ void start_module(int type) { \
+ startfunc(type); \
+ } \
+ void loop_module() { \
+ loopfunc(); \
+ } \
+ void stop_module(int type) { \
+ stopfunc(type); \
+ } \
+ int modversion() { \
+ return MODULE_VERSION; \
+ }
+
+#endif
\ No newline at end of file
#include "mysqlConn.h"
#define DATABASE_VERSION "15"
+static void show_mysql_error();
+
struct mysql_conn_struct {
unsigned int tid;
MYSQL *mysql_conn;
static pthread_mutex_t synchronized;
#endif
-void check_mysql() {
+static void check_mysql() {
MYSQL *mysql_conn = get_mysql_conn();
int errid;
if((errid = mysql_ping(mysql_conn))) {
mysql_conns = NULL;
}
-void show_mysql_error() {
+static void show_mysql_error() {
MYSQL *mysql_conn = get_mysql_conn();
//show mysql_error()
putlog(LOGLEVEL_ERROR, "MySQL Error: %s\n", mysql_error(mysql_conn));
#define MYSQLMAXLEN 1024
-void check_mysql();
-MYSQL_RES *mysql_use();
-void mysql_free();
+#ifndef DND_FUNCTIONS
+/* MODULAR ACCESSIBLE */ MYSQL_RES *mysql_use();
+/* MODULAR ACCESSIBLE */ void mysql_free();
void init_mysql(char *host, int port, char *user, char *pass, char *base);
void free_mysql();
-void show_mysql_error();
-void printf_mysql_query(const char *text, ...) PRINTF_LIKE(1, 2);
-void printf_long_mysql_query(int len, const char *text, ...) PRINTF_LIKE(2, 3);
-char* escape_string(const char *str);
-MYSQL *get_mysql_conn();
-
-#endif
\ No newline at end of file
+/* MODULAR ACCESSIBLE */ void printf_mysql_query(const char *text, ...) PRINTF_LIKE(1, 2);
+/* MODULAR ACCESSIBLE */ void printf_long_mysql_query(int len, const char *text, ...) PRINTF_LIKE(2, 3);
+/* MODULAR ACCESSIBLE */ char* escape_string(const char *str);
+/* MODULAR ACCESSIBLE */ MYSQL *get_mysql_conn();
+#endif
+#endif
--- /dev/null
+/* overall.h - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _overall_h
+#define _overall_h
+#include "../config.h"
+
+#define NEONSERV_VERSION "5.3"
+#define VERSION_PATCHLEVEL 543
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#ifdef WIN32
+#include <windows.h>
+#include <winsock2.h>
+#include <malloc.h>
+#else
+#include <features.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <sys/wait.h>
+#endif
+#include <unistd.h>
+#include <getopt.h>
+#include <stdarg.h>
+#include <sys/time.h>
+#include <time.h>
+#ifdef HAVE_THREADS
+#include <pthread.h>
+#ifdef WIN32
+#define pthread_self_tid() pthread_self().p
+#else
+#define pthread_self_tid() pthread_self()
+#endif
+#define THREAD_MUTEX_INIT(var) { \
+ pthread_mutexattr_t mutex_attr; \
+ pthread_mutexattr_init(&mutex_attr);\
+ pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_RECURSIVE_NP);\
+ pthread_mutex_init(&var, &mutex_attr); \
+}
+#define THREAD_MUTEX_INIT_TYPE(var, type) { \
+ pthread_mutexattr_t mutex_attr; \
+ pthread_mutexattr_init(&mutex_attr);\
+ pthread_mutexattr_settype(&mutex_attr, type);\
+ pthread_mutex_init(&var, &mutex_attr); \
+}
+#define SYNCHRONIZE(var) pthread_mutex_lock(&var)
+#define SET_SYNCHRONIZE(var) pthread_mutex_trylock(&var)
+#define DESYNCHRONIZE(var) pthread_mutex_unlock(&var)
+#else
+#define THREAD_MUTEX_INIT(var)
+#define SYNCHRONIZE(var)
+#define DESYNCHRONIZE(var)
+#endif
+
+#if __GNUC__
+#define PRINTF_LIKE(M,N) __attribute__((format (printf, M, N)))
+#else
+#define PRINTF_LIKE(M,N)
+#endif
+
+#if __GNUC__ >= 2
+#define UNUSED_ARG(ARG) ARG __attribute__((unused))
+#elif defined(S_SPLINT_S)
+#define UNUSED_ARG(ARG) /*@unused@*/ ARG
+#define const /*@observer@*/ /*@temp@*/
+#else
+#define UNUSED_ARG(ARG) ARG
+#endif
+
+#define STRINGIFY_(x) #x
+#define STRINGIFY(x) STRINGIFY_(x)
+
+#if defined(__GNUC__)
+#if defined(__GNUC_PATCHLEVEL__)
+#define COMPILER "GCC" " " STRINGIFY(__GNUC__) "." STRINGIFY(__GNUC_MINOR__) "." STRINGIFY(__GNUC_PATCHLEVEL__)
+#else
+#define COMPILER "GCC" " " STRINGIFY(__GNUC__) "." STRINGIFY(__GNUC_MINOR__)
+#endif
+#elif defined (__IMAGECRAFT__)
+#define COMPILER "ICCAVR"
+#else
+#define COMPILER "Unknown"
+#endif
+
+#ifdef ENABLE_MEMORY_DEBUG
+#include "memoryDebug.h"
+#endif
+
+#define PID_FILE "neonserv.pid"
+#define CONF_FILE "neonserv.conf"
+#define LOG_FILE "neonserv.log"
+
+#define SOCKET_SELECT_TIME 1
+#define SOCKET_RECONNECT_TIME 20
+
+#define NICKLEN 30
+#define USERLEN 10
+#define AUTHLEN 32
+#define HOSTLEN 63
+#define REALLEN 50
+#define TOPICLEN 500
+#define CHANNELLEN 200
+#define MAXLEN 512
+#define MAXLOGLEN 1024
+#define TRIGGERLEN 50
+#define MAXNUMPARAMS 200 /* maximum number of parameters in one line */
+#define MAXLANGUAGES 5
+#define MAXMODES 6
+#define INVITE_TIMEOUT 30
+#define BOTWAR_DETECTION_TIME 7
+#define BOTWAR_DETECTION_EVENTS 6
+#define REWHO_TIMEOUT 10 /* wait 10 seconds before WHO an unauthed user again */
+#define TICKS_PER_SECOND 10
+
+//valid nick chars
+#define VALID_NICK_CHARS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890{|}~[\\]^-_`"
+//the first char is a little bit different
+// 0 1 2 3 4 5 6
+// 1234567890123456789012345678901234567890123456789012345678 9012 62
+#define VALID_NICK_CHARS_FIRST "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~[\\]^_`"
+#define VALID_NICK_CHARS_FIRST_LEN 62
+
+#define TEMPUSER_LIST_INDEX VALID_NICK_CHARS_FIRST_LEN
+
+#define LOGLEVEL_INFO 0x01
+#define LOGLEVEL_ERROR 0x02
+#define LOGLEVEL_RAW 0x04
+#define LOGLEVEL_MYSQL 0x08
+
+#define timeval_is_bigger(x,y) ((x.tv_sec > y.tv_sec) || (x.tv_sec == y.tv_sec && x.tv_usec > y.tv_usec))
+
+#define perror(errmsg) (putlog(LOGLEVEL_ERROR, "ERROR (%s:%d) %s", __FILE__, __LINE__, errmsg))
+
+#define MODSTATE_RELOAD 0x01
+#define MODSTATE_STARTSTOP 0x02
+#define MODSTATE_REBIND 0x03
+
+#endif
DESYNCHRONIZE(synchronized);
}
-struct timeq_entry* timeq_add(int seconds, timeq_callback_t *callback, void *data) {
- return timeq_uadd(seconds * 1000, callback, data);
+struct timeq_entry* timeq_add(int seconds, int module_id, timeq_callback_t *callback, void *data) {
+ return timeq_uadd(seconds * 1000, module_id, callback, data);
}
-struct timeq_entry* timeq_uadd(int useconds, timeq_callback_t *callback, void *data) {
+struct timeq_entry* timeq_uadd(int useconds, int module_id, timeq_callback_t *callback, void *data) {
struct timeval now;
gettimeofday(&now, NULL);
struct timeq_entry *entry = malloc(sizeof(*entry));
now.tv_usec += (useconds % 1000);
now.tv_sec += (useconds / 1000);
entry->execute = now;
+ entry->module_id = module_id;
entry->callback = callback;
entry->data = data;
entry->name = NULL;
return entry;
}
-struct timeq_entry* timeq_add_name(char *name, int seconds, timeq_callback_t *callback, void *data) {
- return timeq_uadd_name(name, seconds * 1000, callback, data);
+struct timeq_entry* timeq_add_name(char *name, int seconds, int module_id, timeq_callback_t *callback, void *data) {
+ return timeq_uadd_name(name, seconds * 1000, module_id, callback, data);
}
-struct timeq_entry* timeq_uadd_name(char *name, int useconds, timeq_callback_t *callback, void *data) {
+struct timeq_entry* timeq_uadd_name(char *name, int useconds, int module_id, timeq_callback_t *callback, void *data) {
SYNCHRONIZE(synchronized);
- struct timeq_entry *entry = timeq_uadd(useconds, callback, data);
+ struct timeq_entry *entry = timeq_uadd(useconds, module_id, callback, data);
entry->name = strdup(name);
DESYNCHRONIZE(synchronized);
return entry;
DESYNCHRONIZE(synchronized);
return 0;
}
+
+void unregister_module_timers(int module_id) {
+ SYNCHRONIZE(synchronized);
+ struct timeq_entry *centry, *next, *last = NULL;
+ for(centry = timeq_events; centry; centry = next) {
+ next = centry->next;
+ if(centry->module_id == module_id) {
+ if(last)
+ last->next = centry->next;
+ else
+ timeq_events = centry->next;
+ free(centry->name);
+ free(centry);
+ } else
+ last = centry;
+ }
+ DESYNCHRONIZE(synchronized);
+}
struct timeq_entry {
char *name;
+ int module_id;
struct timeval execute;
timeq_callback_t *callback;
void *data;
struct timeq_entry *next;
};
+#ifndef DND_FUNCTIONS
void init_timeq();
void timeq_tick();
-struct timeq_entry* timeq_add(int seconds, timeq_callback_t *callback, void *data);
-struct timeq_entry* timeq_uadd(int useconds, timeq_callback_t *callback, void *data);
-struct timeq_entry* timeq_add_name(char *name, int seconds, timeq_callback_t *callback, void *data);
-struct timeq_entry* timeq_uadd_name(char *name, int useconds, timeq_callback_t *callback, void *data);
-int timeq_del(struct timeq_entry* entry);
-int timeq_del_name(char *name);
-int timeq_name_exists(char *name);
-
-#endif
\ No newline at end of file
+/* MODULAR ACCESSIBLE */ struct timeq_entry* timeq_add(int seconds, int module_id, timeq_callback_t *callback, void *data);
+/* MODULAR ACCESSIBLE */ struct timeq_entry* timeq_uadd(int useconds, int module_id, timeq_callback_t *callback, void *data);
+/* MODULAR ACCESSIBLE */ struct timeq_entry* timeq_add_name(char *name, int seconds, int module_id, timeq_callback_t *callback, void *data);
+/* MODULAR ACCESSIBLE */ struct timeq_entry* timeq_uadd_name(char *name, int useconds, int module_id, timeq_callback_t *callback, void *data);
+/* MODULAR ACCESSIBLE */ int timeq_del(struct timeq_entry* entry);
+/* MODULAR ACCESSIBLE */ int timeq_del_name(char *name);
+/* MODULAR ACCESSIBLE */ int timeq_name_exists(char *name);
+void unregister_module_timers(int module_id);
+#endif
+#endif
int delCount;
};
-int match(const char *mask, const char *name);
-
-struct Table *table_init(int width, int length, int flags);
-int table_add(struct Table *table, char **entry);
-int table_change(struct Table *table, int row, char **entry);
-int table_change_field(struct Table *table, int row, int col, char *entry);
-int table_set_bold(struct Table *table, int collum, int bold);
-char **table_end(struct Table *table);
-void table_free(struct Table *table);
-
-char* timeToStr(struct UserNode *user, int seconds, int items, char *buf);
-int strToTime(struct UserNode *user, char *str);
-
-struct ModeBuffer* initModeBuffer(struct ClientSocket *client, struct ChanNode *chan);
#define modeBufferSimpleMode(MODEBUF,ADD,MODE) modeBufferSet(MODEBUF, ADD, MODE, NULL)
#define modeBufferOp(MODEBUF,USER) modeBufferSet(MODEBUF, 1, 'o', USER)
#define modeBufferDeop(MODEBUF,USER) modeBufferSet(MODEBUF, 0, 'o', USER)
#define modeBufferDevoice(MODEBUF,USER) modeBufferSet(MODEBUF, 0, 'v', USER)
#define modeBufferBan(MODEBUF,MASK) modeBufferSet(MODEBUF, 1, 'b', MASK)
#define modeBufferUnban(MODEBUF,MASK) modeBufferSet(MODEBUF, 0, 'b', MASK)
-void modeBufferSet(struct ModeBuffer *modeBuf, int add, char mode, char *param);
-void flushModeBuffer(struct ModeBuffer *modeBuf);
-void freeModeBuffer(struct ModeBuffer *modeBuf);
-int is_ircmask(const char *text);
+#ifndef DND_FUNCTIONS
+/* MODULAR ACCESSIBLE */ int match(const char *mask, const char *name);
+
+/* MODULAR ACCESSIBLE */ struct Table *table_init(int width, int length, int flags);
+/* MODULAR ACCESSIBLE */ int table_add(struct Table *table, char **entry);
+/* MODULAR ACCESSIBLE */ int table_change(struct Table *table, int row, char **entry);
+/* MODULAR ACCESSIBLE */ int table_change_field(struct Table *table, int row, int col, char *entry);
+/* MODULAR ACCESSIBLE */ int table_set_bold(struct Table *table, int collum, int bold);
+/* MODULAR ACCESSIBLE */ char **table_end(struct Table *table);
+/* MODULAR ACCESSIBLE */ void table_free(struct Table *table);
+
+/* MODULAR ACCESSIBLE */ char* timeToStr(struct UserNode *user, int seconds, int items, char *buf);
+/* MODULAR ACCESSIBLE */ int strToTime(struct UserNode *user, char *str);
+
+/* MODULAR ACCESSIBLE */ struct ModeBuffer* initModeBuffer(struct ClientSocket *client, struct ChanNode *chan);
+/* MODULAR ACCESSIBLE */ void modeBufferSet(struct ModeBuffer *modeBuf, int add, char mode, char *param);
+/* MODULAR ACCESSIBLE */ void flushModeBuffer(struct ModeBuffer *modeBuf);
+/* MODULAR ACCESSIBLE */ void freeModeBuffer(struct ModeBuffer *modeBuf);
+
+/* MODULAR ACCESSIBLE */ int is_ircmask(const char *text);
-char* generate_banmask(struct UserNode *user, char *buffer);
-char* make_banmask(char *input, char* buffer);
-int isFakeHost(char *host);
+/* MODULAR ACCESSIBLE */ char* generate_banmask(struct UserNode *user, char *buffer);
+/* MODULAR ACCESSIBLE */ char* make_banmask(char *input, char* buffer);
+/* MODULAR ACCESSIBLE */ int isFakeHost(char *host);
-int mask_match(char *mask, struct UserNode *user);
+/* MODULAR ACCESSIBLE */ int mask_match(char *mask, struct UserNode *user);
-unsigned long crc32(const char *text);
+/* MODULAR ACCESSIBLE */ unsigned long crc32(const char *text);
void init_tools();
-#endif
\ No newline at end of file
+#endif
+#endif
#include "main.h"
+#define MODULE_VERSION 1
+
+#ifndef DND_FUNCTIONS
extern const char *compilation;
extern const char *creation;
extern const char *revision;
extern const char *codelines;
extern const int patchlevel;
-
-#endif
\ No newline at end of file
+#endif
+#endif