cd src && chmod +x version.sh && ./version.sh && cd ..
noinst_PROGRAMS = neonserv
-noinst_LTLIBRARIES = libDummyServ.la libfuncmds.la libglobalcmd.la libNeonHelp.la libNeonServ.la libNeonSpam.la libstats.la libNeonFun.la
+noinst_LTLIBRARIES = libDummyServ.la libfuncmds.la libglobalcmd.la libNeonHelp.la libNeonBackup.la libNeonServ.la libNeonSpam.la libstats.la libNeonFun.la
libDummyServ_la_SOURCES = src/modules/DummyServ.mod/bot_DummyServ.c \
src/modules/DummyServ.mod/module.c
libNeonHelp_la_LDFLAGS = -module -rpath /nowhere -avoid-version -no-undefined
libNeonHelp_la_LIBADD = $(MYSQL_LIBS)
+libNeonBackup_la_SOURCES = src/modules/NeonBackup.mod/bot_NeonBackup.c \
+ src/modules/NeonBackup.mod/cmd_neonbackup.c \
+ src/modules/NeonBackup.mod/module.c
+libNeonBackup_la_LDFLAGS = -module -rpath /nowhere -avoid-version -no-undefined
+libNeonBackup_la_LIBADD = $(MYSQL_LIBS)
+
libNeonServ_la_SOURCES = src/modules/NeonServ.mod/bot_NeonServ.c \
src/modules/NeonServ.mod/cmd_neonserv.c \
src/modules/NeonServ.mod/cmd_neonserv_access.c \
src/QServer.c \
src/modules.c \
src/module_commands.c \
+ src/ModuleFunctions.c \
src/memoryDebug.c
neonserv_LDADD = $(MYSQL_LIBS) $(SYSTEM_LIBS)
"chan_expire_freq" = "3d";
// How long is a channel unvisited (by masters or above) before it can be expired?
"chan_expire_delay" = "30d";
+ // Automatically register a Backup bot with NeonServ
+ "auto_backup_register" = 0;
+ // Automatically unregister all Backup when NeonServ gets removed
+ "auto_backup_unregister" = 1;
+ // BackupServ channel setting
+ "channel_backup_setting" = 1;
+ };
+ "libNeonBackup" {
+ "enabled" = 1;
+ "protected" = 0;
};
"libNeonSpam" {
"enabled" = 1;
#include "main.h"
-#define SOCKET_FLAG_DEAD 0x01
-#define SOCKET_FLAG_CONNECTED 0x02
-#define SOCKET_FLAG_READY 0x04
-#define SOCKET_FLAG_PREFERRED 0x08 /* prefered bot to send datas to the IRC World (NOTICE's WHO's etc pp) */
-#define SOCKET_FLAG_USE_QUEUE 0x10
-#define SOCKET_FLAG_RECONNECT 0x20
-#define SOCKET_FLAG_SSL 0x40
-#define SOCKET_FLAG_HAVE_SSL 0x80
-#define SOCKET_FLAG_QUITTED 0x100
-#define SOCKET_FLAG_FAST_JUMP 0x200
-#define SOCKET_FLAG_SILENT 0x400
-#define SOCKET_FLAG_CHANGENICK 0x800
+#define SOCKET_FLAG_DEAD 0x01
+#define SOCKET_FLAG_CONNECTED 0x02
+#define SOCKET_FLAG_READY 0x04
+#define SOCKET_FLAG_PREFERRED 0x08 /* prefered bot to send datas to the IRC World (NOTICE's WHO's etc pp) */
+#define SOCKET_FLAG_USE_QUEUE 0x10
+#define SOCKET_FLAG_RECONNECT 0x20
+#define SOCKET_FLAG_SSL 0x40
+#define SOCKET_FLAG_HAVE_SSL 0x80
+#define SOCKET_FLAG_QUITTED 0x100
+#define SOCKET_FLAG_FAST_JUMP 0x200
+#define SOCKET_FLAG_SILENT 0x400
+#define SOCKET_FLAG_CHANGENICK 0x800
+#define SOCKET_FLAG_REQUEST_INVITE 0x1000
#define SOCKET_HAVE_BOTCLASSVALUE1 0x10000000
#define SOCKET_HAVE_BOTCLASSVALUE2 0x20000000
#include "BanNode.h"
#include "ModeNode.h"
#include "tools.h"
+#include "bots.h"
struct irc_cmd *irc_commands = NULL;
static struct UserNode *registering_users = NULL;
return 1;
}
+static IRC_CMD(raw_nojoin) {
+ if(from == NULL || argc < 3) return 0;
+ struct ChanNode *chan = getChanByName(argv[1]);
+ if(chan == NULL) return 0;
+ if(client->flags & SOCKET_FLAG_REQUEST_INVITE)
+ requestInvite(client->user, chan);
+ return 1;
+}
+
void init_parser() {
//all the raws we receive...
register_irc_function("437", raw_437);
register_irc_function("324", raw_324);
register_irc_function("332", raw_332);
register_irc_function("367", raw_367);
+ register_irc_function("471", raw_nojoin);
+ register_irc_function("473", raw_nojoin);
+ register_irc_function("474", raw_nojoin);
+ register_irc_function("475", raw_nojoin);
register_irc_function("INVITE", raw_invite);
register_irc_function("NOTICE", raw_notice);
register_irc_function("TOPIC", raw_topic);
--- /dev/null
+/* ModuleFunctions.c - NeonServ v5.4
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * 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 "ModuleFunctions.h"
+#include "modules.h"
+#include "ChanNode.h"
+#ifndef WIN32
+#include <dlfcn.h>
+#endif
+
+#define FUNCTION_GLOBAL_CMD_REGISTER_NEONBACKUP 0
+#define FUNCTION_GLOBAL_CMD_UNREGISTER_NEONBACKUP 1
+#define FUNCTION_NEONBACKUP_RECOVER_CHAN 2
+
+#define TOTAL_FUNCTIONS 3
+
+struct module_function {
+ struct ModuleInfo *module;
+ void *function;
+};
+
+static struct module_function module_functions[TOTAL_FUNCTIONS];
+
+void init_modulefunctions() {
+ int i;
+ for(i = 0; i < TOTAL_FUNCTIONS; i++) {
+ module_functions[i].function = NULL;
+ }
+}
+
+void scan_module(struct ModuleInfo *module) {
+ char *function_names[] = {
+ "global_cmd_register_neonbackup", /* FUNCTION_GLOBAL_CMD_REGISTER_NEONBACKUP */
+ "global_cmd_unregister_neonbackup", /* FUNCTION_GLOBAL_CMD_UNREGISTER_NEONBACKUP */
+ "neonbackup_recover_chan" /* FUNCTION_NEONBACKUP_RECOVER_CHAN */
+ };
+ int i;
+ for(i = 0; i < TOTAL_FUNCTIONS; i++) {
+ #ifndef WIN32
+ void* func = dlsym(module->module, function_names[i]);
+ #else
+ FARPROC func = GetProcAddress(module->module, function_names[i]);
+ #endif
+ if(func) {
+ module_functions[i].module = module;
+ module_functions[i].function = func;
+ }
+ }
+}
+
+void free_module_functions(struct ModuleInfo *module) {
+ int i;
+ for(i = 0; i < TOTAL_FUNCTIONS; i++) {
+ if(module_functions[i].module == module) {
+ module_functions[i].function = NULL;
+ }
+ }
+}
+
+/* function handlers */
+void module_global_cmd_register_neonbackup(char *chan) {
+ if(!module_functions[FUNCTION_GLOBAL_CMD_REGISTER_NEONBACKUP].function)
+ return;
+ ((void (*)(char *)) module_functions[FUNCTION_GLOBAL_CMD_REGISTER_NEONBACKUP].function)(chan);
+}
+
+void module_global_cmd_unregister_neonbackup(char *chan) {
+ if(!module_functions[FUNCTION_GLOBAL_CMD_UNREGISTER_NEONBACKUP].function)
+ return;
+ ((void (*)(char *)) module_functions[FUNCTION_GLOBAL_CMD_UNREGISTER_NEONBACKUP].function)(chan);
+}
+
+void module_neonbackup_recover_chan(struct ChanNode *chan) {
+ if(!module_functions[FUNCTION_NEONBACKUP_RECOVER_CHAN].function)
+ return;
+ ((void (*)(struct ChanNode *)) module_functions[FUNCTION_NEONBACKUP_RECOVER_CHAN].function)(chan);
+}
--- /dev/null
+/* ModuleFunctions.h - NeonServ v5.4
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * 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 _ModuleFunctions_h
+#define _ModuleFunctions_h
+#include "overall.h"
+
+#ifndef DND_FUNCTIONS
+struct ModuleInfo;
+struct ChanNode;
+
+void init_modulefunctions();
+void scan_module(struct ModuleInfo *module);
+void free_module_functions(struct ModuleInfo *module);
+
+/* MODULAR ACCESSIBLE */ void module_global_cmd_register_neonbackup(char *chan);
+/* MODULAR ACCESSIBLE */ void module_global_cmd_unregister_neonbackup(char *chan);
+/* MODULAR ACCESSIBLE */ void module_neonbackup_recover_chan(struct ChanNode *chan);
+
+#endif
+#endif
}
}
+void requestInvite(struct UserNode *user, struct ChanNode *chan) {
+ struct ClientSocket *bot, *userbot = NULL;
+ struct ChanUser *chanuser = getChanUser(user, chan);
+ char invited = 0;
+ if(chanuser) return;
+ for(bot = getBots(SOCKET_FLAG_READY, NULL); bot; bot = getBots(SOCKET_FLAG_READY, bot)) {
+ if(!invited && (chanuser = getChanUser(bot->user, chan)) != NULL && (chanuser->flags & CHANUSERFLAG_OPPED)) {
+ invited = 1;
+ putsock(bot, "INVITE %s %s", user->nick, chan->name);
+ }
+ if(bot->user == user) {
+ userbot = bot;
+ }
+ }
+}
+
TIMEQ_CALLBACK(channel_ban_timeout) {
char *str_banid = data;
MYSQL_RES *res;
/* MODULAR ACCESSIBLE */ struct ClientSocket *getChannelBot(struct ChanNode *chan, int botid);
/* MODULAR ACCESSIBLE */ void requestOp(struct UserNode *user, struct ChanNode *chan);
+/* MODULAR ACCESSIBLE */ void requestInvite(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);
#include "version.h"
#include "modules.h"
#include "module_commands.h"
+#include "ModuleFunctions.h"
time_t start_time;
static int running, hard_restart;
register_module_commands();
init_handleinfohandler();
init_tools();
+ init_modulefunctions();
loadModules();
init_bots();
init_DBHelper();
/* 184-188 */ #include "version.h"
/* 189 */ /* modules.h */
/* 190 */ /* UserNode.h */
+/* 191-193 */ #include "ModuleFunctions.h"
+/* 194 */ /* bots.h */
#define Function void *
/* 187 */ (Function) get_codelines,
/* 188 */ (Function) get_patchlevel,
/* 189 */ (Function) get_module_name,
-/* 190 */ (Function) isUserModeSet
+/* 190 */ (Function) isUserModeSet,
+/* 191 */ (Function) module_global_cmd_register_neonbackup,
+/* 192 */ (Function) module_global_cmd_unregister_neonbackup,
+/* 193 */ (Function) module_neonbackup_recover_chan,
+/* 194 */ (Function) requestInvite
};
static int module_id_counter = 1;
modinfo->state = 0;
modinfo->next = modules;
modules = modinfo;
+ scan_module(modinfo);
return modinfo;
}
unregister_module_hooks(old_modinfo->module_id);
((void (*)(int)) old_modinfo->stopfunc)(MODSTATE_STARTSTOP);
closemodule(old_modinfo->module);
+ free_module_functions(old_modinfo);
free(old_modinfo->name);
free(old_modinfo);
return 1;
unregister_module_hooks(old_modinfo->module_id);
((void (*)(int)) old_modinfo->stopfunc)(MODSTATE_RELOAD);
closemodule(old_modinfo->module);
+ free_module_functions(old_modinfo);
free(old_modinfo->name);
free(old_modinfo);
break;
unregister_module_hooks(modinfo->module_id);
((void (*)(int)) modinfo->stopfunc)(MODSTATE_STARTSTOP);
closemodule(modinfo->module);
+ free_module_functions(modinfo);
free(modinfo->name);
free(modinfo);
}
unregister_module_commands(module_id);
unregister_module_events(module_id);
unregister_module_timers(module_id);
+
}
int module_loaded(int module_id) {
}
return NULL;
}
+
+
bind_unbound_required_functions(BOTID);
}
+static void dummyserv_event_invite(struct ClientSocket *client, struct UserNode *user, char *channel) {
+ if(client->botid != BOTID)
+ return;
+ 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")) {
+ 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)))
+ putsock(bot, "JOIN %s", channel);
+ }
+}
+
void init_DummyServ(int type) {
set_bot_alias(BOTID, BOTALIAS);
start_bots(type);
//register events
bind_bot_ready(dummyserv_bot_ready, module_id);
+ bind_invite(dummyserv_event_invite, module_id);
set_trigger_callback(BOTID, module_id, dummyserv_trigger_callback);
}
--- /dev/null
+/* bot_NeonBackup.c - NeonServ v5.4
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * 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 "../botid.h"
+
+#include "bot_NeonBackup.h"
+#include "../../modcmd.h"
+#include "cmd_neonbackup.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 NEONBACKUP_BOTID
+#define BOTALIAS "NeonBackup"
+
+static const struct default_language_entry msgtab[] = {
+ {NULL, NULL}
+};
+
+static void neonbackup_bot_ready(struct ClientSocket *client) {
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+
+ printf_mysql_query("SELECT `automodes`, `oper_user`, `oper_pass` FROM `bots` WHERE `id` = '%d'", client->clientid);
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) != NULL) {
+ if(row[1] && row[2]) {
+ putsock(client, "OPER %s %s", row[1], row[2]);
+ }
+ 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 neonbackup_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_REQUEST_INVITE;
+ 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 neonbackup_recover_chan(struct ChanNode *chan) {
+
+}
+
+static void neonbackup_event_join(struct ChanUser *chanuser) {
+ 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);
+ neonbackup_recover_chan(chanuser->chan);
+ }
+}
+
+static void neonbackup_event_invite(struct ClientSocket *client, struct UserNode *user, char *channel) {
+ if(client->botid != BOTID)
+ return;
+ 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);
+ }
+}
+
+void init_NeonBackup(int type) {
+ set_bot_alias(BOTID, BOTALIAS);
+ start_bots(type);
+
+ if(type == MODSTATE_REBIND) return;
+
+ //register events
+ bind_bot_ready(neonbackup_bot_ready, module_id);
+ bind_join(neonbackup_event_join, module_id);
+ bind_invite(neonbackup_event_invite, module_id);
+
+ set_trigger_callback(BOTID, module_id, neonbackup_trigger_callback);
+
+ register_default_language_table(msgtab);
+}
+
+void loop_NeonBackup() {
+
+}
+
+void free_NeonBackup(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_NeonBackup.h - NeonServ v5.4
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * 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_NeonBackup_h
+#define _bot_NeonBackup_h
+
+#include "../../main.h"
+
+void init_NeonBackup(int type);
+void loop_NeonBackup();
+void free_NeonBackup(int type);
+
+#endif
\ No newline at end of file
--- /dev/null
+/* cmd_neonbackup.c - NeonServ v5.4
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * 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_neonbackup.h"
+#include "../../modcmd.h"
+#include "../../ConfigParser.h"
+
+void register_commands() {
+ //NeonBackup Commands
+ register_command_alias(6, "NeonBackup");
+
+
+
+}
\ No newline at end of file
--- /dev/null
+/* cmd_neonbackup.h - NeonServ v5.4
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * 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_neonbackup_h
+#define _cmd_neonbackup_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_NeonBackup.h"
+#include "../../lang.h"
+#include "../../tools.h"
+
+void register_commands();
+
+
+#endif
--- /dev/null
+/* module.c - NeonServ v5.4
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * 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_NeonBackup.h"
+#include "cmd_neonbackup.h"
+
+static int module_initialize() {
+ register_commands();
+ return 0;
+}
+
+static void module_start(int type) {
+ init_NeonBackup(type);
+}
+
+static void module_loop() {
+ loop_NeonBackup();
+}
+
+static void module_stop(int type) {
+ free_NeonBackup(type);
+}
+
+MODULE_HEADER(module_initialize, module_start, module_loop, module_stop);
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->flags |= SOCKET_FLAG_REQUEST_INVITE;
client->botid = BOTID;
client->clientid = atoi(row[7]);
connect_socket(client);
return 0;
}
+static void neonfun_event_invite(struct ClientSocket *client, struct UserNode *user, char *channel) {
+ if(client->botid != BOTID)
+ return;
+ 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);
+ }
+}
+
void init_NeonFun(int type) {
set_bot_alias(BOTID, BOTALIAS);
start_bots(type);
bind_part(neonfun_parted, module_id);
bind_quit(neonfun_quitted, module_id);
bind_freechan(neonfun_freechan, module_id);
-
+ bind_invite(neonfun_event_invite, module_id);
+
set_trigger_callback(BOTID, module_id, neonfun_trigger_callback);
}
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->flags |= SOCKET_FLAG_REQUEST_INVITE;
client->botid = BOTID;
client->clientid = atoi(row[7]);
connect_socket(client);
}
}
+static void neonhelp_event_invite(struct ClientSocket *client, struct UserNode *user, char *channel) {
+ if(client->botid != BOTID)
+ return;
+ 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);
+ }
+}
+
void init_NeonHelp(int type) {
set_bot_alias(BOTID, BOTALIAS);
start_bots(type);
bind_part(neonhelp_event_part, module_id);
bind_kick(neonhelp_event_kick, module_id);
bind_quit(neonhelp_event_quit, module_id);
+ bind_invite(neonhelp_event_invite, module_id);
set_trigger_callback(BOTID, module_id, neonhelp_trigger_callback);
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_REQUEST_INVITE;
client->botid = BOTID;
client->clientid = atoi(row[7]);
connect_socket(client);
#ifndef _cmd_neonserv_h
#define _cmd_neonserv_h
#include "../module.h"
+#include "../botid.h"
#include "../../main.h"
#include "../../modcmd.h"
#include "../../IRCParser.h"
if(bot) {
putsock(bot, "PART %s :Channel suspended.", channel);
}
+ if(client->botid == NEONSERV_BOTID) {
+ char setting[128];
+ sprintf(setting, "modules.%s.auto_backup_unregister", get_module_name(module_id));
+ if(get_int_field(setting))
+ module_global_cmd_unregister_neonbackup(channel);
+ }
printf_mysql_query("UPDATE `bot_channels` SET `suspended` = '1' WHERE `id` = '%s'", row[1]);
reply(getTextBot(), user, "NS_CSUSPEND_DONE", channel);
logEvent(event);
if(bot) {
putsock(bot, "JOIN %s", channel);
}
+ if(client->botid == NEONSERV_BOTID) {
+ char setting[128];
+ sprintf(setting, "modules.%s.auto_backup_register", get_module_name(module_id));
+ if(get_int_field(setting))
+ module_global_cmd_register_neonbackup(channel);
+ }
printf_mysql_query("UPDATE `bot_channels` SET `suspended` = '0' WHERE `id` = '%s'", row[1]);
reply(getTextBot(), user, "NS_CUNSUSPEND_DONE", channel);
logEvent(event);
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);
+static char* neonserv_cmd_set_backupbot(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
{"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},
+ {"BACKUPBOT", NULL, NS_VALID_BOOLEAN | NS_VALID_FUNCTION, neonserv_cmd_set_backupbot},
{NULL, NULL, 0, NULL}
};
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(!stricmp(channel_settings[i].setting, "BACKUPBOT")) {
+ char setting[128];
+ sprintf(setting, "modules.%s.channel_backup_setting", get_module_name(module_id));
+ if(!get_int_field(setting)) {
+ i++;
+ continue;
+ }
+ }
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);
struct Table *table;
char *content[2];
int with_halfops = get_int_field("General.have_halfop");
+ int channel_backup_setting;
i = 0;
j = 0;
while(channel_settings[i].setting) {
i++;
continue;
}
+ if(!stricmp(channel_settings[i].setting, "BACKUPBOT")) {
+ char setting[128];
+ sprintf(setting, "modules.%s.channel_backup_setting", get_module_name(module_id));
+ channel_backup_setting = get_int_field(setting);
+ if(!channel_backup_setting) {
+ i++;
+ j++;
+ continue;
+ }
+ }
if(channel_settings[i].chanfield)
querypos += sprintf(query + querypos, ", `%s`", channel_settings[i].chanfield);
i++;
i++;
continue;
}
+ if(!stricmp(channel_settings[i].setting, "BACKUPBOT") && !channel_backup_setting) {
+ i++;
+ continue;
+ }
if(channel_settings[i].chanfield) {
j++;
org_value = (row[j] ? row[j] : defaults[j]);
return value;
}
+static char* neonserv_cmd_set_backupbot(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *argument) {
+ int backupbot;
+ //get current trigger
+ MYSQL_RES *res;
+ printf_mysql_query("SELECT `botid` FROM `bot_channels` LEFT JOIN `bots` ON `botid` = `bots`.`id` WHERE `chanid` = '%d' AND `botclass` = '%d'", chan->channel_id, NEONBACKUP_BOTID);
+ res = mysql_use();
+ if(mysql_fetch_row(res))
+ backupbot = 1;
+ else
+ backupbot = 0;
+ if(argument) {
+ //change the channel setting
+ if(!strcmp(argument, "0") || !strcmp(argument, "off") || !strcmp(argument, get_language_string(user, "NS_SET_OFF"))) {
+ if(backupbot) {
+ module_global_cmd_unregister_neonbackup(chan->name);
+ backupbot = 0;
+ }
+ } else if(!strcmp(argument, "1") || !strcmp(argument, "on") || !strcmp(argument, get_language_string(user, "NS_SET_ON"))) {
+ if(!backupbot) {
+ module_global_cmd_register_neonbackup(chan->name);
+ backupbot = 1;
+ }
+ } else {
+ reply(getTextBot(), user, "NS_SET_INVALID_BOOLEAN", argument);
+ return NULL;
+ }
+ logEvent(event);
+ }
+ if(setting) {
+ reply(getTextBot(), user, "\002%s\002 %s", setting, (backupbot ? "1" : "0"));
+ }
+ return (backupbot ? "1" : "0");
+}
+
#undef MAX_QUERY_LEN
static TIMEQ_CALLBACK(neonserv_check_unvisited_timer) {
char tmp[200];
char *modname = get_module_name(module_id);
- sprintf(tmp, "modules/%s/chan_expire_freq", modname);
+ sprintf(tmp, "modules.%s.chan_expire_freq", modname);
char *check_freq_str = get_string_field(tmp);
int check_freq;
if(!check_freq_str || (check_freq = strToTime(NULL, check_freq_str)) < (60*60)) {
timeq_add_name("neonserv_unvisited", 1800, module_id, neonserv_check_unvisited_timer, NULL);
return;
}
- sprintf(tmp, "modules/%s/chan_expire_delay", modname);
+ sprintf(tmp, "modules.%s.chan_expire_delay", modname);
char *check_expire_str = get_string_field(tmp);
int duration;
if(!check_expire_str || (duration = strToTime(NULL, check_expire_str)) < 60*60*24*7) return;
static void neonserv_cmd_unvisited_unreg(struct ClientSocket *client, char *channel) {
MYSQL_RES *res;
MYSQL_ROW row;
- int sync_neonspam_unreg = get_int_field("General/sync_neonspam_unreg");
+ int sync_neonspam_unreg = get_int_field("General.sync_neonspam_unreg");
int botid;
if(client)
botid = client->botid;
putsock(bot, "PART %s :Channel unregistered.", channel);
}
}
+ if(client->botid == NEONSERV_BOTID) {
+ char setting[128];
+ sprintf(setting, "modules.%s.auto_backup_unregister", get_module_name(module_id));
+ if(get_int_field(setting))
+ module_global_cmd_unregister_neonbackup(channel);
+ }
char *alertchan = get_string_field("General.alertchan");
if(alertchan) {
struct ChanNode *alertchan_chan = getChanByName(alertchan);
*/
static void neonserv_event_invite(struct ClientSocket *client, struct UserNode *user, char *channel) {
+ if(client->botid != BOTID)
+ return;
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);
if(!client) return; //we can't "see" this event
if(chanuser->user == client->user) {
requestOp(client->user, chanuser->chan);
+ module_neonbackup_recover_chan(chanuser->chan);
return;
}
if(chanuser->user->flags & USERFLAG_ISBOT) return;
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_REQUEST_INVITE;
client->botid = BOTID;
client->clientid = atoi(row[7]);
connect_socket(client);
return 1;
}
+static void neonspam_event_invite(struct ClientSocket *client, struct UserNode *user, char *channel) {
+ if(client->botid != BOTID)
+ return;
+ 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);
+ }
+}
+
void init_NeonSpam(int type) {
set_bot_alias(BOTID, BOTALIAS);
bind_privctcp(general_event_privctcp, module_id);
bind_kick(neonspam_event_kick, module_id);
bind_freechan(neonspam_event_freechan, module_id);
-
+ bind_invite(neonspam_event_invite, module_id);
+
set_trigger_callback(BOTID, module_id, neonspam_trigger_callback);
register_default_language_table(msgtab);
#define DUMMYSERV_BOTID 3
#define NEONHELP_BOTID 4
#define NEONFUN_BOTID 5
+#define NEONBACKUP_BOTID 6
#endif
\ No newline at end of file
#ifndef _cmd_global_h
#define _cmd_global_h
#include "../module.h"
+#include "../botid.h"
#include "../../main.h"
#include "../../modcmd.h"
#include "../../IRCParser.h"
CMD_BIND(global_cmd_unregister);
CMD_BIND(global_cmd_version);
+
#endif
\ No newline at end of file
struct UserNode *cuser = getUserByNick(argv[1]);
if(!cuser) {
cuser = createTempUser(argv[1]);
- if(!cuser) {
+ if(!cuser) {
reply(getTextBot(), user, "NS_USER_UNKNOWN", argv[1]);
return;
}
reply(textclient, user, "NS_REGISTER_DONE", channel, auth);
} else
reply(textclient, user, "NS_REGISTER_DONE_NOAUTH", channel);
+ // NeonBackup SubBlock
+ if(client->botid == NEONSERV_BOTID) {
+ char setting[128];
+ sprintf(setting, "modules.%s.auto_backup_register", get_module_name(module_id));
+ if(get_int_field(setting))
+ module_global_cmd_register_neonbackup(channel);
+ }
logEvent(event);
}
+
+void global_cmd_register_neonbackup(char *channel) {
+ MYSQL_RES *res;
+ MYSQL_ROW row, row2;
+ printf_mysql_query("SELECT `botid` 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' AND botclass = '%d'", escape_string(channel), NEONBACKUP_BOTID);
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) != NULL)
+ 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
+ return;
+ printf_mysql_query("SELECT `id`, `max_channels`, `defaulttrigger`, `nick` FROM `bots` WHERE `botclass` = '%d' AND `active` = '1' ORDER BY `register_priority` DESC", NEONBACKUP_BOTID);
+ 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])) {
+ botid = atoi(row[0]);
+ break;
+ }
+ }
+ if(!botid)
+ 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);
+ }
+ printf_mysql_query("INSERT INTO `bot_channels` (`botid`, `chanid`, `trigger`) VALUES ('%d', '%d', NULL)", botid, chanid);
+}
+
reply(getTextBot(), user, "NS_UNREGISTER_NODELETE", channel);
return;
}
- int sync_neonspam_unreg = get_int_field("General/sync_neonspam_unreg");
+ int sync_neonspam_unreg = get_int_field("General.sync_neonspam_unreg");
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
putsock(bot, "PART %s :Channel unregistered.", channel);
}
}
+ // NeonBackup SubBlock
+ if(client->botid == NEONSERV_BOTID) {
+ char setting[128];
+ sprintf(setting, "modules.%s.auto_backup_unregister", get_module_name(module_id));
+ if(get_int_field(setting))
+ module_global_cmd_unregister_neonbackup(channel);
+ }
logEvent(event);
}
+
+void global_cmd_unregister_neonbackup(char *channel) {
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ 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
+ 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, NEONBACKUP_BOTID);
+ res = mysql_use();
+ if ((row = mysql_fetch_row(res)) == NULL)
+ 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]);
+ if(bot && strcmp(row[2], "1")) {
+ putsock(bot, "PART %s :Channel unregistered.", channel);
+ }
+}
/* 188 */ #define get_patchlevel ((const int (*)(void))global[188])
/* 189 */ #define get_module_name ((char * (*)(int))global[189])
/* 190 */ #define isUserModeSet ((int (*)(struct UserNode *, char))global[190])
+/* 191 */ #define module_global_cmd_register_neonbackup ((void (*)(char *))global[191])
+/* 192 */ #define module_global_cmd_unregister_neonbackup ((void (*)(char *))global[192])
+/* 193 */ #define module_neonbackup_recover_chan ((void (*)(struct ChanNode *))global[193])
+/* 194 */ #define requestInvite ((void (*)(struct UserNode *, struct ChanNode *))global[194])
#define MODULE_HEADER(initfunc,startfunc,loopfunc,stopfunc) \
void **global = NULL; \
#include "main.h"
-#define MODULE_VERSION 3
+#define MODULE_VERSION 4
#ifndef DND_FUNCTIONS
extern const char *compilation;