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

📄 m_message.c

📁 Unreal irc 服务器源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *   Unreal Internet Relay Chat Daemon, src/modules/m_message.c *   (C) 2000-2001 Carsten V. Munk and the UnrealIRCd Team *   Moved to modules by Fish (Justin Hammond) * *   This program is free software; you can 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 "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"#include "proto.h"#ifdef STRIPBADWORDS#include "badwords.h"#endif#ifdef _WIN32#include "version.h"#endif#include "badwords.h"int _is_silenced(aClient *, aClient *);char *_stripbadwords_channel(char *str, int *blocked);char *_stripbadwords_message(char *str, int *blocked);char *_stripbadwords_quit(char *str, int *blocked);char *_StripColors(unsigned char *text);char *_StripControlCodes(unsigned char *text);DLLFUNC int m_message(aClient *cptr, aClient *sptr, int parc, char *parv[], int notice);DLLFUNC int  m_notice(aClient *cptr, aClient *sptr, int parc, char *parv[]);DLLFUNC int  m_private(aClient *cptr, aClient *sptr, int parc, char *parv[]);extern int webtv_parse(aClient *sptr, char *string);/* Place includes here */#define MSG_PRIVATE     "PRIVMSG"       /* PRIV */#define TOK_PRIVATE     "!"     /* 33 */#define MSG_NOTICE      "NOTICE"        /* NOTI */#define TOK_NOTICE      "B"     /* 66 */ModuleHeader MOD_HEADER(m_message)  = {	"message",	/* Name of module */	"$Id: m_message.c,v 1.1.6.10 2006/12/22 21:10:33 syzop Exp $", /* Version */	"private message and notice", /* Short description of module */	"3.2-b8-1",	NULL     };DLLFUNC int MOD_TEST(m_message)(ModuleInfo *modinfo){	MARK_AS_OFFICIAL_MODULE(modinfo);	EfunctionAddPChar(modinfo->handle, EFUNC_STRIPBADWORDS_CHANNEL, _stripbadwords_channel);	EfunctionAddPChar(modinfo->handle, EFUNC_STRIPBADWORDS_MESSAGE, _stripbadwords_message);	EfunctionAddPChar(modinfo->handle, EFUNC_STRIPBADWORDS_QUIT, _stripbadwords_quit);	EfunctionAddPChar(modinfo->handle, EFUNC_STRIPCOLORS, _StripColors);	EfunctionAddPChar(modinfo->handle, EFUNC_STRIPCONTROLCODES, _StripControlCodes);	EfunctionAdd(modinfo->handle, EFUNC_IS_SILENCED, _is_silenced);	return MOD_SUCCESS;}/* This is called on module init, before Server Ready */DLLFUNC int MOD_INIT(m_message)(ModuleInfo *modinfo){	/*	 * We call our add_Command crap here	*/	add_CommandX(MSG_PRIVATE, TOK_PRIVATE, m_private, 2, M_USER|M_SERVER|M_RESETIDLE|M_VIRUS);	add_Command(MSG_NOTICE, TOK_NOTICE, m_notice, 2);	MARK_AS_OFFICIAL_MODULE(modinfo);	return MOD_SUCCESS;	}/* Is first run when server is 100% ready */DLLFUNC int MOD_LOAD(m_message)(int module_load){	return MOD_SUCCESS;}/* Called when module is unloaded */DLLFUNC int MOD_UNLOAD(m_message)(int module_unload){	if (del_Command(MSG_PRIVATE, TOK_PRIVATE, m_private) < 0)	{		sendto_realops("Failed to delete command privmsg when unloading %s",				MOD_HEADER(m_message).name);	}	if (del_Command(MSG_NOTICE, TOK_NOTICE, m_notice) < 0)	{		sendto_realops("Failed to delete command notice when unloading %s",				MOD_HEADER(m_message).name);	}	return MOD_SUCCESS;}static int check_dcc(aClient *sptr, char *target, aClient *targetcli, char *text);static int check_dcc_soft(aClient *from, aClient *to, char *text);#define CANPRIVMSG_CONTINUE		100#define CANPRIVMSG_SEND			101/** Check if PRIVMSG's are permitted from a person to another person. * cptr:	.. * sptr:	.. * acptr:	target client * notice:	1 if notice, 0 if privmsg * text:	Pointer to a pointer to a text [in, out] * cmd:		Pointer to a pointer which contains the command to use [in, out] * * RETURN VALUES: * CANPRIVMSG_CONTINUE: issue a 'continue' in target nickname list (aka: skip further processing this target) * CANPRIVMSG_SEND: send the message (use text/newcmd!) * Other: return with this value (can be anything like 0, -1, FLUSH_BUFFER, etc) */static int can_privmsg(aClient *cptr, aClient *sptr, aClient *acptr, int notice, char **text, char **cmd){char *ctcp;int ret;	if (IsVirus(sptr))	{		sendnotice(sptr, "You are only allowed to talk in '%s'", SPAMFILTER_VIRUSCHAN);		return CANPRIVMSG_CONTINUE;	}	/* Umode +R (idea from Bahamut) */	if (IsRegNickMsg(acptr) && !IsRegNick(sptr) && !IsULine(sptr) && !IsOper(sptr) && !IsServer(sptr)) {		sendto_one(sptr, err_str(ERR_NONONREG), me.name, sptr->name,			acptr->name);		return 0;	}	if (IsNoCTCP(acptr) && !IsOper(sptr) && **text == 1 && acptr != sptr)	{		ctcp = *text + 1; /* &*text[1]; */		if (myncmp(ctcp, "ACTION ", 7) && myncmp(ctcp, "DCC ", 4))		{			sendto_one(sptr, err_str(ERR_NOCTCP), me.name, sptr->name, acptr->name);			return 0;		}	}	if (MyClient(sptr) && !strncasecmp(*text, "\001DCC", 4))	{		ret = check_dcc(sptr, acptr->name, acptr, *text);		if (ret < 0)			return ret;		if (ret == 0)			return CANPRIVMSG_CONTINUE;	}	if (MyClient(acptr) && !strncasecmp(*text, "\001DCC", 4) &&	    !check_dcc_soft(sptr, acptr, *text))		return CANPRIVMSG_CONTINUE;	if (MyClient(sptr) && check_for_target_limit(sptr, acptr, acptr->name))		return CANPRIVMSG_CONTINUE;	if (!is_silenced(sptr, acptr))	{#ifdef STRIPBADWORDS		int blocked = 0;#endif		Hook *tmphook;				if (notice && IsWebTV(acptr) && **text != '\1')			*cmd = MSG_PRIVATE;		if (!notice && MyConnect(sptr) &&		    acptr->user && acptr->user->away)			sendto_one(sptr, rpl_str(RPL_AWAY),			    me.name, sptr->name, acptr->name,			    acptr->user->away);#ifdef STRIPBADWORDS		if (MyClient(sptr) && !IsULine(acptr) && IsFilteringWords(acptr))		{			*text = stripbadwords_message(*text, &blocked);			if (blocked)			{				if (!notice && MyClient(sptr))					sendto_one(sptr, rpl_str(ERR_NOSWEAR),						me.name, sptr->name, acptr->name);				return CANPRIVMSG_CONTINUE;			}		}#endif		if (MyClient(sptr))		{			ret = dospamfilter(sptr, *text, (notice ? SPAMF_USERNOTICE : SPAMF_USERMSG), acptr->name, 0, NULL);			if (ret < 0)				return ret;		}		for (tmphook = Hooks[HOOKTYPE_USERMSG]; tmphook; tmphook = tmphook->next) {			*text = (*(tmphook->func.pcharfunc))(cptr, sptr, acptr, *text, notice);			if (!*text)				break;		}		if (!*text)			return CANPRIVMSG_CONTINUE;				return CANPRIVMSG_SEND;	} else {		/* Silenced */		RunHook4(HOOKTYPE_SILENCED, cptr, sptr, acptr, notice);	}	return CANPRIVMSG_CONTINUE;}/*** m_message (used in m_private() and m_notice())** the general function to deliver MSG's between users/channels****	parv[0] = sender prefix**	parv[1] = receiver list**	parv[2] = message text**** massive cleanup** rev argv 6/91***/static int recursive_webtv = 0;DLLFUNC int m_message(aClient *cptr, aClient *sptr, int parc, char *parv[], int notice){	aClient *acptr, *srvptr;	char *s;	aChannel *chptr;	char *nick, *server, *p, *cmd, *ctcp, *p2, *pc, *text, *newcmd;	int  cansend = 0;	int  prefix = 0;	char pfixchan[CHANNELLEN + 4];	int ret;	/*	 * Reasons why someone can't send to a channel	 */	static char *err_cantsend[] = {		"You need voice (+v)",		"No external channel messages",		"Color is not permitted in this channel",		"You are banned",		"CTCPs are not permitted in this channel",		"You must have a registered nick (+r) to talk on this channel",		"Swearing is not permitted in this channel",		"NOTICEs are not permitted in this channel",		NULL	};	if (IsHandshake(sptr))		return 0;	cmd = notice ? MSG_NOTICE : MSG_PRIVATE;	if (parc < 2 || *parv[1] == '\0')	{		sendto_one(sptr, err_str(ERR_NORECIPIENT),		    me.name, parv[0], cmd);		return -1;	}	if (parc < 3 || *parv[2] == '\0')	{		sendto_one(sptr, err_str(ERR_NOTEXTTOSEND), me.name, parv[0]);		return -1;	}	if (MyConnect(sptr))		parv[1] = (char *)canonize(parv[1]);			for (p = NULL, nick = strtoken(&p, parv[1], ","); nick;	    nick = strtoken(&p, NULL, ","))	{		if (IsVirus(sptr) && (!strcasecmp(nick, "ircd") || !strcasecmp(nick, "irc")))		{			sendnotice(sptr, "IRC command(s) unavailable because you are suspected to have a virus");			continue;		}		/*		   ** nickname addressed?		 */		if (!strcasecmp(nick, "ircd") && MyClient(sptr))		{			ret = 0;			if (!recursive_webtv)			{				recursive_webtv = 1;				ret = parse(sptr, parv[2], (parv[2] + strlen(parv[2])));				recursive_webtv = 0;			}			return ret;		}		if (!strcasecmp(nick, "irc") && MyClient(sptr))		{			if (!recursive_webtv)			{				recursive_webtv = 1;				ret = webtv_parse(sptr, parv[2]);				if (ret == -99)				{					ret = parse(sptr, parv[2], (parv[2] + strlen(parv[2])));				}				recursive_webtv = 0;				return ret;			}		}				if (*nick != '#' && (acptr = find_person(nick, NULL)))		{			text = parv[2];			newcmd = cmd;			ret = can_privmsg(cptr, sptr, acptr, notice, &text, &newcmd);			if (ret == CANPRIVMSG_SEND)			{				sendto_message_one(acptr, sptr, parv[0], newcmd, nick, text);				continue;			} else			if (ret == CANPRIVMSG_CONTINUE)				continue;			else				return ret;		}		p2 = (char *)strchr(nick, '#');		prefix = 0;		if (p2 && (chptr = find_channel(p2, NullChn)))		{			if (p2 != nick)			{				for (pc = nick; pc != p2; pc++)				{#ifdef PREFIX_AQ #define PREFIX_REST (PREFIX_ADMIN|PREFIX_OWNER)#else #define PREFIX_REST (0)#endif					switch (*pc)					{					  case '+':						  prefix |= PREFIX_VOICE | PREFIX_HALFOP | PREFIX_OP | PREFIX_REST;						  break;					  case '%':						  prefix |= PREFIX_HALFOP | PREFIX_OP | PREFIX_REST;						  break;					  case '@':						  prefix |= PREFIX_OP | PREFIX_REST;						  break;#ifdef PREFIX_AQ					  case '&':						  prefix |= PREFIX_ADMIN | PREFIX_OWNER;					  	  break;					  case '~':						  prefix |= PREFIX_OWNER;						  break;#else					  case '&':						  prefix |= PREFIX_OP | PREFIX_REST;					  	  break;					  case '~':						  prefix |= PREFIX_OP | PREFIX_REST;						  break;#endif					  default:						  break;	/* ignore it :P */					}				}								if (prefix)				{					if (MyClient(sptr) && !op_can_override(sptr))					{						Membership *lp = find_membership_link(sptr->user->channel, chptr);						/* Check if user is allowed to send. RULES:						 * Need at least voice (+) in order to send to +,% or @						 * Need at least ops (@) in order to send to & or ~						 */						if (!lp || !(lp->flags & (CHFL_VOICE|CHFL_HALFOP|CHFL_CHANOP|CHFL_CHANOWNER|CHFL_CHANPROT)))						{							sendto_one(sptr, err_str(ERR_CHANOPRIVSNEEDED),								me.name, sptr->name, chptr->chname);							return 0;						}						if (!(prefix & PREFIX_OP) && ((prefix & PREFIX_OWNER) || (prefix & PREFIX_ADMIN)) &&						    !(lp->flags & (CHFL_CHANOP|CHFL_CHANOWNER|CHFL_CHANPROT)))						{							sendto_one(sptr, err_str(ERR_CHANOPRIVSNEEDED),								me.name, sptr->name, chptr->chname);							return 0;						}					}					/* Now find out the lowest prefix and use that.. (so @&~#chan becomes @#chan) */					if (prefix & PREFIX_VOICE)						pfixchan[0] = '+';					else if (prefix & PREFIX_HALFOP)						pfixchan[0] = '%';					else if (prefix & PREFIX_OP)						pfixchan[0] = '@';#ifdef PREFIX_AQ					else if (prefix & PREFIX_ADMIN)						pfixchan[0] = '&';					else if (prefix & PREFIX_OWNER)						pfixchan[0] = '~';#endif					else						abort();					strlcpy(pfixchan+1, p2, sizeof(pfixchan)-1);					nick = pfixchan;				} else {					strlcpy(pfixchan, p2, sizeof(pfixchan));					nick = pfixchan;				}			}						if (MyClient(sptr) && (*parv[2] == 1))			{				ret = check_dcc(sptr, chptr->chname, NULL, parv[2]);				if (ret < 0)					return ret;				if (ret == 0)					continue;			}			if (IsVirus(sptr) && strcasecmp(chptr->chname, SPAMFILTER_VIRUSCHAN))			{				sendnotice(sptr, "You are only allowed to talk in '%s'", SPAMFILTER_VIRUSCHAN);				continue;			}						cansend =			    !IsULine(sptr) ? can_send(sptr, chptr, parv[2], notice) : 0;			if (!cansend)			{

⌨️ 快捷键说明

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