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

📄 modes.c

📁 The major functionality added in this release includes: - Rootless mode in X11 - Widget Templt
💻 C
字号:
/* X-Chat * Copyright (C) 1998 Peter Zelezny. * * 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 <string.h>#include <stdlib.h>#include <stdio.h>#include "xchat.h"#include "xchatc.h"#include "modes.h"#include "plugin.h"#include "fe.h"/* does 'chan' have a valid prefix? e.g. # or & */intis_channel (server * serv, char *chan){	if (strchr (serv->chantypes, chan[0]))		return 1;	return 0;}/* is the given char a valid nick mode char? e.g. @ or + */static intis_prefix_char (server * serv, char c){	int pos = 0;	char *np = serv->nick_prefixes;	while (np[0])	{		if (np[0] == c)			return pos;		pos++;		np++;	}	if (serv->bad_prefix)	{		if (strchr (serv->bad_nick_prefixes, c))		/* valid prefix char, but mode unknown */			return -2;	}	return -1;}/* returns '@' for ops etc... */charget_nick_prefix (server * serv, unsigned int access){	int pos;	char c;	for (pos = 0; pos < USERACCESS_SIZE; pos++)	{		c = serv->nick_prefixes[pos];		if (c == 0)			break;		if (access & (1 << pos))			return c;	}	return ' ';}/* returns the access bitfield for a nickname. E.g.	@nick would return 000010 in binary	%nick would return 000100 in binary	+nick would return 001000 in binary */unsigned intnick_access (server * serv, char *nick, int *modechars){	int i;	unsigned int access = 0;	char *orig = nick;	while (*nick)	{		i = is_prefix_char (serv, *nick);		if (i == -1)			break;		/* -2 == valid prefix char, but mode unknown */		if (i != -2)			access |= (1 << i);		nick++;	}	*modechars = nick - orig;	return access;}/* returns the access number for a particular mode. e.g.	mode 'a' returns 0	mode 'o' returns 1	mode 'h' returns 2	mode 'v' returns 3	Also puts the nick-prefix-char in 'prefix' */intmode_access (server * serv, char mode, char *prefix){	int pos = 0;	while (serv->nick_modes[pos])	{		if (serv->nick_modes[pos] == mode)		{			*prefix = serv->nick_prefixes[pos];			return pos;		}		pos++;	}	*prefix = ' ';	return -1;}static intmode_timeout_cb (session *sess){	char outbuf[512];	if (is_session (sess))	{		sess->mode_timeout_tag = 0;		sprintf (outbuf, "MODE %s\r\n", sess->channel);		tcp_send (sess->server, outbuf);		sess->ignore_mode = TRUE;		sess->ignore_date = TRUE;	}	return 0;}static voidrecord_chan_mode (session *sess)/*, char sign, char mode, char *arg)*/{	/* Should we write a routine to add sign,mode to sess->current_modes?		nah! too hard. Lets just issue a MODE #channel and read it back.		We need to find out the new modes for the titlebar, but let's not		flood ourselves off when someone decides to change 100 modes/min. */	if (!sess->mode_timeout_tag)		sess->mode_timeout_tag = fe_timeout_add (15000, mode_timeout_cb, sess);}/* handle one mode, e.g.   handle_single_mode (serv,outbuf,'+','b',"elite","#warez","banneduser",) */static voidhandle_single_mode (server * serv, char *outbuf, char sign, char mode,						  char *nick, char *chan, char *arg, int quiet,						  int is_324){	session *sess;	outbuf[0] = sign;	outbuf[1] = 0;	outbuf[2] = mode;	outbuf[3] = 0;	sess = find_session_from_channel (chan, serv);	if (!sess || !is_channel (serv, chan))	{		/* got modes for a chan we're not in! probably nickmode +isw etc */		sess = serv->front_session;		goto genmode;	}	/* is this a nick mode? */	if (strchr (serv->nick_modes, mode))	{		/* update the user in the userlist */		ul_update_entry (sess, /*nickname */ arg, mode, sign);	} else	{		if (!is_324 && !sess->ignore_mode)			record_chan_mode (sess);/*, sign, mode, arg);*/	}	switch (sign)	{	case '+':		switch (mode)		{		case 'k':			if (EMIT_SIGNAL (XP_CHANSETKEY, sess, chan, nick, arg, NULL, 0) == 1)				return;			strncpy (sess->channelkey, arg, 60);			fe_update_channel_key (sess);			fe_update_mode_buttons (sess, mode, sign);			if (!quiet)				EMIT_SIGNAL (XP_TE_CHANSETKEY, sess, nick, arg, NULL, NULL, 0);			return;		case 'l':			if (EMIT_SIGNAL (XP_CHANSETLIMIT, sess, chan, nick, arg, NULL, 0) == 1)				return;			sess->limit = atoi (arg);			fe_update_channel_limit (sess);			fe_update_mode_buttons (sess, mode, sign);			if (!quiet)				EMIT_SIGNAL (XP_TE_CHANSETLIMIT, sess, nick, arg, NULL, NULL, 0);			return;		case 'o':			if (EMIT_SIGNAL (XP_CHANOP, sess, chan, nick, arg, NULL, 0) == 1)				return;			if (!quiet)				EMIT_SIGNAL (XP_TE_CHANOP, sess, nick, arg, NULL, NULL, 0);			return;		case 'h':			if (EMIT_SIGNAL (XP_CHANHOP, sess, chan, nick, arg, NULL, 0) == 1)				return;			if (!quiet)				EMIT_SIGNAL (XP_TE_CHANHOP, sess, nick, arg, NULL, NULL, 0);			return;		case 'v':			if (EMIT_SIGNAL (XP_CHANVOICE, sess, chan, nick, arg, NULL, 0) == 1)				return;			if (!quiet)				EMIT_SIGNAL (XP_TE_CHANVOICE, sess, nick, arg, NULL, NULL, 0);			return;		case 'b':			if (EMIT_SIGNAL (XP_CHANBAN, sess, chan, nick, arg, NULL, 0) == 1)				return;			if (!quiet)				EMIT_SIGNAL (XP_TE_CHANBAN, sess, nick, arg, NULL, NULL, 0);			return;		case 'e':			if (EMIT_SIGNAL (XP_CHANEXEMPT, sess, chan, nick, arg, NULL, 0) == 1)				return;			if (!quiet)				EMIT_SIGNAL (XP_TE_CHANEXEMPT, sess, nick, arg, NULL, NULL, 0);			return;		case 'I':			if (EMIT_SIGNAL (XP_CHANINVITE, sess, chan, nick, arg, NULL, 0) == 1)				return;			if (!quiet)				EMIT_SIGNAL (XP_TE_CHANINVITE, sess, nick, arg, NULL, NULL, 0);			return;		}		break;	case '-':		switch (mode)		{		case 'k':			if (EMIT_SIGNAL (XP_CHANRMKEY, sess, chan, nick, NULL, NULL, 0) == 1)				return;			sess->channelkey[0] = 0;			fe_update_channel_key (sess);			fe_update_mode_buttons (sess, mode, sign);			if (!quiet)				EMIT_SIGNAL (XP_TE_CHANRMKEY, sess, nick, NULL, NULL, NULL, 0);			return;		case 'l':			if (EMIT_SIGNAL (XP_CHANRMLIMIT, sess, chan, nick, NULL, NULL, 0) == 1)				return;			sess->limit = 0;			fe_update_channel_limit (sess);			fe_update_mode_buttons (sess, mode, sign);			if (!quiet)				EMIT_SIGNAL (XP_TE_CHANRMLIMIT, sess, nick, NULL, NULL, NULL, 0);			return;		case 'o':			if (EMIT_SIGNAL (XP_CHANDEOP, sess, chan, nick, arg, NULL, 0) == 1)				return;			if (!quiet)				EMIT_SIGNAL (XP_TE_CHANDEOP, sess, nick, arg, NULL, NULL, 0);			return;		case 'h':			if (EMIT_SIGNAL (XP_CHANDEHOP, sess, chan, nick, arg, NULL, 0) == 1)				return;			if (!quiet)				EMIT_SIGNAL (XP_TE_CHANDEHOP, sess, nick, arg, NULL, NULL, 0);			return;		case 'v':			if (EMIT_SIGNAL (XP_CHANDEVOICE, sess, chan, nick, arg, NULL, 0) == 1)				return;			if (!quiet)				EMIT_SIGNAL (XP_TE_CHANDEVOICE, sess, nick, arg, NULL, NULL, 0);			return;		case 'b':			if (EMIT_SIGNAL (XP_CHANUNBAN, sess, chan, nick, arg, NULL, 0) == 1)				return;			if (!quiet)				EMIT_SIGNAL (XP_TE_CHANUNBAN, sess, nick, arg, NULL, NULL, 0);			return;		case 'e':			if (EMIT_SIGNAL (XP_CHANRMEXEMPT, sess, chan, nick, arg, NULL, 0) == 1)				return;			if (!quiet)				EMIT_SIGNAL (XP_TE_CHANRMEXEMPT, sess, nick, arg, NULL, NULL, 0);			return;		case 'I':			if (EMIT_SIGNAL (XP_CHANRMINVITE, sess, chan, nick, arg, NULL, 0) == 1)				return;			if (!quiet)				EMIT_SIGNAL (XP_TE_CHANRMINVITE, sess, nick, arg, NULL, NULL, 0);			return;		}	}	fe_update_mode_buttons (sess, mode, sign); genmode:	if (!quiet)	{		if (*arg)		{			char *buf = malloc (strlen (chan) + strlen (arg) + 2);			sprintf (buf, "%s %s", chan, arg);			EMIT_SIGNAL (XP_TE_CHANMODEGEN, sess, nick, outbuf, outbuf + 2, buf, 0);			free (buf);		} else			EMIT_SIGNAL (XP_TE_CHANMODEGEN, sess, nick, outbuf, outbuf + 2, chan, 0);	}}/* does this mode have an arg? like +b +l +o */static intmode_has_arg (server * serv, char sign, char mode){	char *cm;	int type;	/* if it's a nickmode, it must have an arg */	if (strchr (serv->nick_modes, mode))		return 1;	/* see what numeric 005 CHANMODES=xxx said */	cm = serv->chanmodes;	type = 0;	while (*cm)	{		if (*cm == ',')		{			type++;		} else if (*cm == mode)		{			switch (type)			{			case 0:					  /* type A */			case 1:					  /* type B */				return 1;			case 2:					  /* type C */				if (sign == '+')					return 1;			case 3:					  /* type D */				return 0;			}		}		cm++;	}	return 0;}/* handle a MODE or numeric 324 from server */voidhandle_mode (server * serv, char *outbuf, char *word[], char *word_eol[],				 char *nick, int numeric_324){	session *sess;	char *chan;	char *modes;	char *argstr;	char sign;	int len;	int arg;	int i, num_args;	int num_modes;	int offset = 3;	int all_modes_have_args = FALSE;	/* numeric 324 has everything 1 word later (as opposed to MODE) */	if (numeric_324)		offset++;	chan = word[offset];	modes = word[offset + 1];	if (*modes == ':')		modes++;	if (*modes == 0)		return;	/* beyondirc's blank modes */	sess = find_session_from_channel (chan, serv);	if (!sess)		sess = serv->front_session;	/* remove trailing space */	len = strlen (word_eol[offset]) - 1;	if (word_eol[offset][len] == ' ')		word_eol[offset][len] = 0;	if (prefs.raw_modes && !numeric_324)		EMIT_SIGNAL (XP_TE_RAWMODES, sess, nick, word_eol[offset], 0, 0, 0);	if (numeric_324)	{		free (sess->current_modes);		sess->current_modes = strdup (word_eol[offset+1]);		fe_set_title (sess);	}	sign = *modes;	modes++;	arg = 1;	/* count the number of arguments (e.g. after the -o+v) */	num_args = 0;	i = 1;	while (i < PDIWORDS)	{		i++;		if (!(*word[i + offset]))			break;		num_args++;	}	/* count the number of modes (without the -/+ chars */	num_modes = 0;	i = 0;	while (i < strlen (modes))	{		if (modes[i] != '+' && modes[i] != '-')			num_modes++;		i++;	}	if (num_args == num_modes)		all_modes_have_args = TRUE;	while (1)	{		switch (*modes)		{		case 0:			return;		case '-':		case '+':			sign = *modes;			break;		default:			argstr = "";			if (all_modes_have_args || mode_has_arg (serv, sign, *modes))			{				arg++;				argstr = word[arg + offset];			}			handle_single_mode (serv, outbuf, sign, *modes, nick, chan,									  argstr, numeric_324 || prefs.raw_modes,									  numeric_324);		}		modes++;	}}/* handle the 005 numeric */voidhandle_005 (server * serv, char *word[]){	int w;	char *pre;	w = 4;							  /* start at the 4th word */	while (*word[w] && w < PDIWORDS)	{		if (strncmp (word[w], "MODES=", 6) == 0)		{			if (atoi (word[w] + 6) >= 6)				serv->six_modes = TRUE;		} else if (strncmp (word[w], "CHANTYPES=", 10) == 0)		{			free (serv->chantypes);			serv->chantypes = strdup (word[w] + 10);		} else if (strncmp (word[w], "CHANMODES=", 10) == 0)		{			free (serv->chanmodes);			serv->chanmodes = strdup (word[w] + 10);		} else if (strncmp (word[w], "PREFIX=", 7) == 0)		{			pre = strchr (word[w] + 7, ')');			if (pre)			{				pre[0] = 0;			  /* NULL out the ')' */				free (serv->nick_prefixes);				free (serv->nick_modes);				serv->nick_prefixes = strdup (pre + 1);				serv->nick_modes = strdup (word[w] + 8);			} else			{				/* bad! some ircds don't give us the modes. */				/* in this case, we use it only to strip /NAMES */				serv->bad_prefix = TRUE;				if (serv->bad_nick_prefixes)					free (serv->bad_nick_prefixes);				serv->bad_nick_prefixes = strdup (word[w] + 7);			}		} else if (strncmp (word[w], "WATCH=", 6) == 0)		{			serv->supports_watch = TRUE;		}		w++;	}}

⌨️ 快捷键说明

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