⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 m_join.c

📁 Unreal irc 服务器源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *   IRC - Internet Relay Chat, src/modules/m_join.c *   (C) 2005 The UnrealIRCd Team * *   See file AUTHORS in IRC package for additional names of *   the programmers. * *   This program is free software; you can redistribute it and/or modify *   it under the terms of the GNU General Public License as published by *   the Free Software Foundation; either version 1, or (at your option) *   any later version. * *   This program is distributed in the hope that it will be useful, *   but WITHOUT ANY WARRANTY; without even the implied warranty of *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *   GNU 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., 675 Mass Ave, Cambridge, MA 02139, USA. */#include "config.h"#include "struct.h"#include "common.h"#include "sys.h"#include "numeric.h"#include "msg.h"#include "proto.h"#include "channel.h"#include <time.h>#include <sys/stat.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#ifdef _WIN32#include <io.h>#endif#include <fcntl.h>#include "h.h"#ifdef STRIPBADWORDS#include "badwords.h"#endif#ifdef _WIN32#include "version.h"#endif/* Forward declarations */DLLFUNC CMD_FUNC(m_join);DLLFUNC void _join_channel(aChannel *chptr, aClient *cptr, aClient *sptr, int flags);DLLFUNC CMD_FUNC(_do_join);DLLFUNC int _can_join(aClient *cptr, aClient *sptr, aChannel *chptr, char *key, char *link, char *parv[]);static int extended_operoverride(aClient *sptr, aChannel *chptr, char *key, int mval, char mchar);#define MAXBOUNCE   5 /** Most sensible */#ifdef JOINTHROTTLEstatic int isjthrottled(aClient *cptr, aChannel *chptr);static void cmodej_increase_usercounter(aClient *cptr, aChannel *chptr);#endif/* Externs */extern MODVAR int spamf_ugly_vchanoverride;extern int find_invex(aChannel *chptr, aClient *sptr);/* Local vars */static int bouncedtimes = 0;#define MSG_JOIN 	"JOIN"	#define TOK_JOIN 	"C"	ModuleHeader MOD_HEADER(m_join)  = {	"m_join",	"$Id: m_join.c,v 1.1.4.5 2006/12/22 21:10:33 syzop Exp $",	"command /join", 	"3.2-b8-1",	NULL     };DLLFUNC int MOD_TEST(m_join)(ModuleInfo *modinfo){	MARK_AS_OFFICIAL_MODULE(modinfo);	EfunctionAddVoid(modinfo->handle, EFUNC_JOIN_CHANNEL, _join_channel);	EfunctionAdd(modinfo->handle, EFUNC_DO_JOIN, _do_join);	EfunctionAdd(modinfo->handle, EFUNC_CAN_JOIN, _can_join);	return MOD_SUCCESS;}DLLFUNC int MOD_INIT(m_join)(ModuleInfo *modinfo){	CommandAdd(modinfo->handle, MSG_JOIN, TOK_JOIN, m_join, MAXPARA, M_USER);	MARK_AS_OFFICIAL_MODULE(modinfo);	return MOD_SUCCESS;}DLLFUNC int MOD_LOAD(m_join)(int module_load){	return MOD_SUCCESS;}DLLFUNC int MOD_UNLOAD(m_join)(int module_unload){	return MOD_SUCCESS;}/* This function adds as an extra (weird) operoverride. * Currently it's only used if you try to operoverride for a +z channel, * if you then do '/join #chan override' it will put the channel -z and allow you directly in. * This is to avoid attackers from using 'race conditions' to prevent you from joining. * PARAMETERS: sptr = the client, chptr = the channel, mval = mode value (eg MODE_ONLYSECURE), *             mchar = mode char (eg 'z') * RETURNS: 1 if operoverride, 0 if not. */int extended_operoverride(aClient *sptr, aChannel *chptr, char *key, int mval, char mchar){unsigned char invited = 0;Link *lp;	if (!IsAnOper(sptr) || !OPCanOverride(sptr))		return 0;	for (lp = sptr->user->invited; lp; lp = lp->next)		if (lp->value.chptr == chptr)		{			invited = 1;			break;		}	if (invited)	{		if (key && !strcasecmp(key, "override"))		{			sendto_channelprefix_butone(NULL, &me, chptr, PREFIX_OP|PREFIX_ADMIN|PREFIX_OWNER,				":%s NOTICE @%s :setting channel -%c due to OperOverride request from %s",				me.name, chptr->chname, mchar, sptr->name);			sendto_serv_butone(&me, ":%s MODE %s -%c 0", me.name, chptr->chname, mchar);			sendto_channel_butserv(chptr, &me, ":%s MODE %s -%c", me.name, chptr->chname, mchar);			chptr->mode.mode &= ~mval;			return 1;		}	}	return 0;}/* Now let _invited_ people join thru bans, +i and +l. * Checking if an invite exist could be done only if a block exists, * but I'm not too fancy of the complicated structure that'd cause, * when optimization will hopefully take care of it. Most of the time * a user won't have invites on him anyway. -Donwulff */DLLFUNC int _can_join(aClient *cptr, aClient *sptr, aChannel *chptr, char *key, char *link, char *parv[]){Link *lp;Ban *banned;	if ((chptr->mode.mode & MODE_ONLYSECURE) && !(sptr->umodes & UMODE_SECURE))	{		if (!extended_operoverride(sptr, chptr, key, MODE_ONLYSECURE, 'z'))			return (ERR_SECUREONLYCHAN);		else			return 0;	}	if ((chptr->mode.mode & MODE_OPERONLY) && !IsAnOper(sptr))		return (ERR_OPERONLY);	if ((chptr->mode.mode & MODE_ADMONLY) && !IsSkoAdmin(sptr))		return (ERR_ADMONLY);	/* Admin, Coadmin, Netadmin, and SAdmin can still walk +b in +O */	banned = is_banned(sptr, chptr, BANCHK_JOIN);	if (banned && (chptr->mode.mode & MODE_OPERONLY) &&	    IsAnOper(sptr) && !IsSkoAdmin(sptr) && !IsCoAdmin(sptr))		return (ERR_BANNEDFROMCHAN);	/* Only NetAdmin/SAdmin can walk +b in +A */	if (banned && (chptr->mode.mode & MODE_ADMONLY) &&	    IsAnOper(sptr) && !IsNetAdmin(sptr) && !IsSAdmin(sptr))		return (ERR_BANNEDFROMCHAN);	for (lp = sptr->user->invited; lp; lp = lp->next)		if (lp->value.chptr == chptr)			return 0;        if ((chptr->mode.limit && chptr->users >= chptr->mode.limit))        {                if (chptr->mode.link)                {                        if (*chptr->mode.link != '\0')                        {                                /* We are linked. */                                sendto_one(sptr,                                    err_str(ERR_LINKCHANNEL), me.name,                                    sptr->name, chptr->chname,                                    chptr->mode.link);                                parv[0] = sptr->name;                                parv[1] = (chptr->mode.link);                                do_join(cptr, sptr, 2, parv);                                return -1;                        }                }                /* We check this later return (ERR_CHANNELISFULL); */        }        if ((chptr->mode.mode & MODE_RGSTRONLY) && !IsARegNick(sptr))                return (ERR_NEEDREGGEDNICK);        if (*chptr->mode.key && (BadPtr(key) || strcmp(chptr->mode.key, key)))                return (ERR_BADCHANNELKEY);        if ((chptr->mode.mode & MODE_INVITEONLY) && !find_invex(chptr, sptr))                return (ERR_INVITEONLYCHAN);        if ((chptr->mode.limit && chptr->users >= chptr->mode.limit))                return (ERR_CHANNELISFULL);        if (banned)                return (ERR_BANNEDFROMCHAN);#ifndef NO_OPEROVERRIDE#ifdef OPEROVERRIDE_VERIFY        if (IsOper(sptr) && (chptr->mode.mode & MODE_SECRET ||            chptr->mode.mode & MODE_PRIVATE) && !is_autojoin_chan(chptr->chname))                return (ERR_OPERSPVERIFY);#endif#endif#ifdef JOINTHROTTLE		if (!IsAnOper(cptr) &&		    (chptr->mode.extmode & EXTMODE_JOINTHROTTLE) && isjthrottled(cptr, chptr))			return ERR_TOOMANYJOINS;#endif        return 0;}#ifdef JOINTHROTTLEstatic int isjthrottled(aClient *cptr, aChannel *chptr){CmodeParam *m;aJFlood *e;int num=0, t=0;	if (!MyClient(cptr))		return 0;			for (m = chptr->mode.extmodeparam; m; m=m->next)		if (m->flag == 'j')		{			num = ((aModejEntry *)m)->num;			t = ((aModejEntry *)m)->t;			break;		}	if (!num || !t)		return 0;	/* Grab user<->chan entry.. */	for (e = cptr->user->jflood; e; e=e->next_u)		if (e->chptr == chptr)			break;		if (!e)		return 0; /* Not present, so cannot be throttled */	/* Ok... now the actual check:	 * if ([timer valid] && [one more join would exceed num])	 */	if (((TStime() - e->firstjoin) < t) && (e->numjoins == num))		return 1; /* Throttled */	return 0;}static void cmodej_increase_usercounter(aClient *cptr, aChannel *chptr){CmodeParam *m;aJFlood *e;int num=0, t=0;	if (!MyClient(cptr))		return;			for (m = chptr->mode.extmodeparam; m; m=m->next)		if (m->flag == 'j')		{			num = ((aModejEntry *)m)->num;			t = ((aModejEntry *)m)->t;			break;		}	if (!num || !t)		return;	/* Grab user<->chan entry.. */	for (e = cptr->user->jflood; e; e=e->next_u)		if (e->chptr == chptr)			break;		if (!e)	{		/* Allocate one */		e = cmodej_addentry(cptr, chptr);		e->firstjoin = TStime();		e->numjoins = 1;	} else	if ((TStime() - e->firstjoin) < t) /* still valid? */	{		e->numjoins++;	} else {		/* reset :p */		e->firstjoin = TStime();		e->numjoins = 1;	}}#endif/*** m_join**	parv[0] = sender prefix**	parv[1] = channel**	parv[2] = channel password (key)*/DLLFUNC CMD_FUNC(m_join){int r;	if (bouncedtimes)		sendto_realops("m_join: bouncedtimes=%d??? [please report at http://bugs.unrealircd.org/]", bouncedtimes);	bouncedtimes = 0;	if (IsServer(sptr))		return 0;	r = do_join(cptr, sptr, parc, parv);	bouncedtimes = 0;	return r;}/* Routine that actually makes a user join the channel * this does no actual checking (banned, etc.) it just adds the user */DLLFUNC void _join_channel(aChannel *chptr, aClient *cptr, aClient *sptr, int flags){	char *parv[] = { 0, 0 };	/*	   **  Complete user entry to the new channel (if any)	 */	add_user_to_channel(chptr, sptr, flags);	/*	   ** notify all other users on the new channel	 */	if (chptr->mode.mode & MODE_AUDITORIUM)	{		if (MyClient(sptr))			sendto_one(sptr, ":%s!%s@%s JOIN :%s",			    sptr->name, sptr->user->username,			    GetHost(sptr), chptr->chname);		sendto_chanops_butone(NULL, chptr, ":%s!%s@%s JOIN :%s",		    sptr->name, sptr->user->username,		    GetHost(sptr), chptr->chname);	}	else

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -