summaryrefslogtreecommitdiff
path: root/src/irc/bot/bot-events.c
diff options
context:
space:
mode:
authorTimo Sirainen <cras@irssi.org>2000-05-25 11:30:47 +0000
committercras <cras@dbcabf3a-b0e7-0310-adc4-f8d773084564>2000-05-25 11:30:47 +0000
commit76605ad0aed7e53c4a9dab686474235f547a5837 (patch)
tree078c0ebf5f7099daaa2dcf9ff252f418dedcce34 /src/irc/bot/bot-events.c
parent487da4174504f797171f12a01636c54272ec6a62 (diff)
downloadirssi-76605ad0aed7e53c4a9dab686474235f547a5837.zip
Added bot plugin, it also has almost-functional botnet.
Changed configure.in's functionality so that you could tell what modules you want to build in main irssi binary and it will create automatically the .c files that need to call the module_init()/deinit() functions. Fixed several minor things.. git-svn-id: http://svn.irssi.org/repos/irssi/trunk@230 dbcabf3a-b0e7-0310-adc4-f8d773084564
Diffstat (limited to 'src/irc/bot/bot-events.c')
-rw-r--r--src/irc/bot/bot-events.c199
1 files changed, 199 insertions, 0 deletions
diff --git a/src/irc/bot/bot-events.c b/src/irc/bot/bot-events.c
new file mode 100644
index 00000000..ebbe0660
--- /dev/null
+++ b/src/irc/bot/bot-events.c
@@ -0,0 +1,199 @@
+/*
+ bot-events.c : IRC bot plugin for irssi
+
+ Copyright (C) 1999 Timo Sirainen
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include "module.h"
+#include "signals.h"
+#include "commands.h"
+
+#include "irc.h"
+#include "irc-server.h"
+#include "channels.h"
+#include "nicklist.h"
+#include "modes.h"
+#include "netsplit.h"
+
+#include "bot-users.h"
+
+static int get_flags(USER_REC *user, CHANNEL_REC *channel)
+{
+ USER_CHAN_REC *userchan;
+
+ g_return_val_if_fail(user != NULL, 0);
+ g_return_val_if_fail(channel != NULL, 0);
+
+ userchan = g_hash_table_lookup(user->channels, channel->name);
+ return (user->flags | (userchan == NULL ? 0 : userchan->flags)) &
+ (~user->not_flags);
+}
+
+static void event_massjoin(CHANNEL_REC *channel, GSList *users)
+{
+ USER_REC *user;
+ USER_CHAN_REC *userchan;
+ NICK_REC *nick;
+ GString *modestr, *nickstr;
+ int flags;
+
+ g_return_if_fail(channel != NULL);
+ g_return_if_fail(users != NULL);
+
+ modestr = g_string_new(NULL);
+ nickstr = g_string_new(NULL);
+
+ for (; users != NULL; users = users->next) {
+ user = users->data;
+ userchan = g_hash_table_lookup(user->channels, channel->name);
+ nick = userchan->nickrec;
+
+ flags = get_flags(user, channel);
+ if (!nick->op && (flags & USER_AUTO_OP)) {
+ g_string_sprintfa(modestr, "+o");
+ g_string_sprintfa(nickstr, "%s,", nick->nick);
+ }
+
+ if (!nick->voice && !nick->op && (flags & USER_AUTO_VOICE)) {
+ g_string_sprintfa(modestr, "+v");
+ g_string_sprintfa(nickstr, "%s,", nick->nick);
+ }
+ }
+
+ if (nickstr->len > 0) {
+ g_string_truncate(nickstr, nickstr->len-1);
+ g_string_sprintfa(modestr, " %s", nickstr->str);
+
+ channel_set_mode(channel->server, channel->name, modestr->str);
+ }
+
+ g_string_free(modestr, TRUE);
+ g_string_free(nickstr, TRUE);
+}
+
+/* Parse channel mode string */
+static void parse_channel_mode(CHANNEL_REC *channel, const char *mode,
+ const char *nick, const char *address)
+{
+ NICK_REC *nickrec, *splitnick;
+ USER_REC *user;
+ GString *str;
+ char *ptr, *curmode, type, *dup, *modestr;
+ int flags;
+
+ g_return_if_fail(channel != NULL);
+ g_return_if_fail(nick != NULL);
+ g_return_if_fail(modestr != NULL);
+
+ user = botuser_find(nick, address);
+ flags = user == NULL ? 0 : get_flags(user, channel);
+
+ if (!channel->chanop || (flags & USER_MASTER) ||
+ g_strcasecmp(nick, channel->server->nick) == 0) {
+ /* can't do anything or we/master did mode change,
+ don't bother checking what */
+ return;
+ }
+
+ str = g_string_new(NULL);
+ dup = modestr = g_strdup(mode);
+
+ type = '+';
+ curmode = cmd_get_param(&modestr);
+ for (; *curmode != '\0'; curmode++) {
+ if (*curmode == '+' || *curmode == '-') {
+ type = *curmode;
+ continue;
+ }
+
+ if (!HAS_MODE_ARG(*curmode))
+ ptr = NULL;
+ else {
+ ptr = cmd_get_param(&modestr);
+ if (*ptr == '\0') continue;
+ }
+
+ if (*curmode != 'o')
+ continue;
+
+ if (type == '-' && strcmp(channel->server->nick, ptr) == 0) {
+ /* we aren't chanop anymore .. */
+ g_string_truncate(str, 0);
+ break;
+ }
+
+ if (type != '+')
+ continue;
+
+ /* check that op is valid */
+ nickrec = nicklist_find(channel, ptr);
+ if (nickrec == NULL || nickrec->host == NULL)
+ continue;
+
+ user = botuser_find(ptr, nickrec->host);
+ flags = user == NULL ? 0 : get_flags(user, channel);
+ if (flags & USER_OP)
+ continue;
+
+ if (address == NULL) {
+ /* server opped, check if user was opped before netsplit. */
+ splitnick = netsplit_find_channel(channel->server, nickrec->nick, nickrec->host, channel->name);
+ if (splitnick != NULL && splitnick->op)
+ continue;
+ }
+
+ /* this one isn't supposed to get ops! */
+ g_string_sprintfa(str, "%s ", ptr);
+ }
+ g_free(dup);
+
+ if (str->len != 0)
+ signal_emit("command deop", 3, str->str, channel->server, channel);
+ g_string_free(str, TRUE);
+}
+
+static void event_mode(const char *data, IRC_SERVER_REC *server,
+ const char *nick, const char *address)
+{
+ CHANNEL_REC *chanrec;
+ char *params, *channel, *mode;
+
+ g_return_if_fail(data != NULL);
+
+ params = event_get_params(data, 2 | PARAM_FLAG_GETREST, &channel, &mode);
+
+ if (ischannel(*channel)) {
+ /* channel mode change */
+ chanrec = channel_find(server, channel);
+ if (chanrec != NULL)
+ parse_channel_mode(chanrec, mode, nick, address);
+ }
+
+ g_free(params);
+}
+
+void bot_events_init(void)
+{
+ signal_add_last("bot massjoin", (SIGNAL_FUNC) event_massjoin);
+ signal_add("event mode", (SIGNAL_FUNC) event_mode);
+}
+
+void bot_events_deinit(void)
+{
+ signal_remove("bot massjoin", (SIGNAL_FUNC) event_massjoin);
+ signal_remove("event mode", (SIGNAL_FUNC) event_mode);
+}