mirror of
https://github.com/irssi/irssi.git
synced 2026-08-10 12:23:37 +02:00
which were part of it. Removed it now and replaced it with saving only op/halfop/voice status. Might have caused some crashes? (hopefully did :) git-svn-id: http://svn.irssi.org/repos/irssi/trunk@2234 dbcabf3a-b0e7-0310-adc4-f8d773084564
201 lines
5.1 KiB
C
201 lines
5.1 KiB
C
/*
|
|
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-servers.h"
|
|
#include "irc-channels.h"
|
|
#include "nicklist.h"
|
|
#include "modes.h"
|
|
#include "netsplit.h"
|
|
|
|
#include "bot-users.h"
|
|
|
|
static int get_flags(USER_REC *user, IRC_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(IRC_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(IRC_CHANNEL_REC *channel, const char *mode,
|
|
const char *nick, const char *address)
|
|
{
|
|
NETSPLIT_CHAN_REC *splitnick;
|
|
NICK_REC *nickrec;
|
|
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(mode != 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;
|
|
}
|
|
|
|
/* check if unwanted people got ops */
|
|
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(type, *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(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(IRC_SERVER_REC *server, const char *data,
|
|
const char *nick, const char *address)
|
|
{
|
|
IRC_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 = irc_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);
|
|
}
|