The formatting of /NAMES and /SCAN output has been substantially reworked. The old /FSETs NAMES_BOTCOLOR, NAMES_FRIENDCOLOR, NAMES_NICKCOLOR, NAMES_OPCOLOR, NAMES_SHITCOLOR and NAMES_VOICECOLOR have been replaced with these new /FSETs: ....................NAMES_NICK %B$[10]0 ................NAMES_NICK_BOT %G$[10]0 .............NAMES_NICK_FRIEND %Y$[10]0 .................NAMES_NICK_ME %W$[10]0 ...............NAMES_NICK_SHIT %R$[10]0 ....................NAMES_USER %K[ %n$1-%K] .............NAMES_USER_CHANOP %K[%C$0%n$1-%K] ..............NAMES_USER_IRCOP %K[%R$0%n$1-%K] ..............NAMES_USER_VOICE %K[%M$0%n$1-%K] The NAMES_NICK formats control how the nick itself is displayed, depending on the status of the nick as recognised by BitchX (the priority order is NAMES_NICK_ME > NAMES_NICK_BOT > NAMES_NICK_FRIEND > NAMES_NICK_SHIT > NAMES_NICK). The NAMES_USER formats control how the overall entry appears in the /NAMES or /SCAN line, depending on the channel status of the nick (the priority order is NAMES_USER_CHANOP > NAMES_USER_VOICE > NAMES_USER_IRCOP > NAMES_USER). You'll need to update any scripts or custom formats that altered the old formats. If you just use the defaults, the main difference you'll see is that your own nick is now shown in white, and voiced users are shown with the '+' sent by the server instead of the 'v'. You can go back to the old look by setting these formats: /FSET NAMES_NICK_ME %B$[10]0 /FSET NAMES_USER_VOICE %K[%Mv%n$1-%K] git-svn-id: svn://svn.code.sf.net/p/bitchx/code/trunk@46 13b04d17-f746-0410-82c6-800466cd88b0
470 lines
12 KiB
C
470 lines
12 KiB
C
/*
|
||
* funny.c: Well, I put some stuff here and called it funny. So sue me.
|
||
*
|
||
* written by michael sandrof
|
||
*
|
||
* copyright(c) 1990
|
||
*
|
||
* see the copyright file, or do a help ircii copyright
|
||
*/
|
||
|
||
|
||
#include "irc.h"
|
||
static char cvsrevision[] = "$Id$";
|
||
CVS_REVISION(funny_c)
|
||
#include "struct.h"
|
||
|
||
#include "ircaux.h"
|
||
#include "hook.h"
|
||
#include "vars.h"
|
||
#include "funny.h"
|
||
#include "names.h"
|
||
#include "server.h"
|
||
#include "lastlog.h"
|
||
#include "ircterm.h"
|
||
#include "output.h"
|
||
#include "numbers.h"
|
||
#include "parse.h"
|
||
#include "status.h"
|
||
#include "misc.h"
|
||
#include "screen.h"
|
||
#define MAIN_SOURCE
|
||
#include "modval.h"
|
||
|
||
static char *match_str = NULL;
|
||
|
||
static int funny_min;
|
||
static int funny_max;
|
||
static int funny_flags;
|
||
|
||
void funny_match(char *stuff)
|
||
{
|
||
malloc_strcpy(&match_str, stuff);
|
||
}
|
||
|
||
void set_funny_flags(int min, int max, int flags)
|
||
{
|
||
funny_min = min;
|
||
funny_max = max;
|
||
funny_flags = flags;
|
||
}
|
||
|
||
struct WideListInfoStru
|
||
{
|
||
char *channel;
|
||
int users;
|
||
};
|
||
|
||
typedef struct WideListInfoStru WideList;
|
||
|
||
static WideList **wide_list = NULL;
|
||
static int wl_size = 0;
|
||
static int wl_elements = 0;
|
||
|
||
static int funny_widelist_users (WideList **, WideList **);
|
||
static int funny_widelist_names (WideList **, WideList **);
|
||
|
||
static int funny_widelist_users(WideList **left, WideList **right)
|
||
{
|
||
if ((**left).users > (**right).users)
|
||
return -1;
|
||
else if ((**right).users > (**left).users)
|
||
return 1;
|
||
else
|
||
return my_stricmp((**left).channel, (**right).channel);
|
||
}
|
||
|
||
static int funny_widelist_names(WideList **left, WideList **right)
|
||
{
|
||
int comp;
|
||
|
||
if (!(comp = my_stricmp((**left).channel, (**right).channel)))
|
||
return comp;
|
||
else if ((**left).users > (**right).users)
|
||
return -1;
|
||
else if ((**right).users > (**left).users)
|
||
return 1;
|
||
else
|
||
return 0;
|
||
}
|
||
|
||
|
||
void funny_print_widelist(void)
|
||
{
|
||
int i;
|
||
char buffer1[BIG_BUFFER_SIZE];
|
||
char buffer2[BIG_BUFFER_SIZE];
|
||
char *ptr;
|
||
|
||
if (!wide_list)
|
||
return;
|
||
|
||
if (funny_flags & FUNNY_NAME)
|
||
qsort((void *) wide_list, wl_elements, sizeof(WideList *),
|
||
(int (*) (const void *, const void *)) funny_widelist_names);
|
||
else if (funny_flags & FUNNY_USERS)
|
||
qsort((void *) wide_list, wl_elements, sizeof(WideList *),
|
||
(int (*) (const void *, const void *)) funny_widelist_users);
|
||
|
||
set_display_target(NULL, LOG_CRAP);
|
||
*buffer1 = '\0';
|
||
for (i = 1; i < wl_elements; i++)
|
||
{
|
||
sprintf(buffer2, "%s(%d) ", wide_list[i]->channel,
|
||
wide_list[i]->users);
|
||
ptr = strchr(buffer1, '\0');
|
||
if (strlen(buffer1) + strlen(buffer2) > current_term->TI_cols - 5)
|
||
{
|
||
if (do_hook(WIDELIST_LIST, "%s", buffer1))
|
||
put_it("%s", convert_output_format(fget_string_var(FORMAT_WIDELIST_FSET), "%s %s", update_clock(GET_TIME), buffer1));
|
||
*buffer1 = 0;
|
||
strcat(buffer1, buffer2);
|
||
}
|
||
else
|
||
strcpy(ptr, buffer2);
|
||
}
|
||
if (*buffer1 && do_hook(WIDELIST_LIST, "%s", buffer1))
|
||
put_it("%s", convert_output_format(fget_string_var(FORMAT_WIDELIST_FSET), "%s %s", update_clock(GET_TIME), buffer1));
|
||
|
||
reset_display_target();
|
||
for (i = 0; i < wl_elements; i++)
|
||
{
|
||
new_free(&wide_list[i]->channel);
|
||
new_free((char **)&wide_list[i]);
|
||
}
|
||
new_free((char **)&wide_list);
|
||
wl_elements = wl_size = 0;
|
||
}
|
||
|
||
void funny_list(char *from, char **ArgList)
|
||
{
|
||
char *channel,
|
||
*user_cnt,
|
||
*line;
|
||
WideList **new_list;
|
||
int cnt;
|
||
static char format[30];
|
||
static int last_width = -1;
|
||
|
||
if (last_width != get_int_var(CHANNEL_NAME_WIDTH_VAR))
|
||
{
|
||
if ((last_width = get_int_var(CHANNEL_NAME_WIDTH_VAR)) != 0)
|
||
snprintf(format, 25, "%%s %%-%u.%us %%-5s %%s", /*thing_ansi,*/
|
||
(unsigned char) last_width,
|
||
(unsigned char) last_width);
|
||
else
|
||
snprintf(format, 25, "%%s %%s %%-5s %%s"/*, thing_ansi*/);
|
||
}
|
||
channel = ArgList[0];
|
||
user_cnt = ArgList[1];
|
||
line = PasteArgs(ArgList, 2);
|
||
if (funny_flags & FUNNY_TOPIC && !(line && *line))
|
||
return;
|
||
cnt = my_atol(user_cnt);
|
||
if (funny_min && (cnt < funny_min))
|
||
return;
|
||
if (funny_max && (cnt > funny_max))
|
||
return;
|
||
if ((funny_flags & FUNNY_PRIVATE) && (*channel != '*'))
|
||
return;
|
||
if ((funny_flags & FUNNY_PUBLIC) && ((*channel == '*') || (*channel == '@')))
|
||
return;
|
||
if (match_str)
|
||
{
|
||
if (wild_match(match_str, channel) == 0)
|
||
return;
|
||
}
|
||
if (funny_flags & FUNNY_WIDE)
|
||
{
|
||
if (wl_elements >= wl_size)
|
||
{
|
||
new_list = (WideList **) new_malloc(sizeof(WideList *) *
|
||
(wl_size + 50));
|
||
memset(new_list, 0, sizeof(WideList *) * (wl_size + 50));
|
||
if (wl_size)
|
||
memcpy(new_list, wide_list, sizeof(WideList *) * wl_size);
|
||
wl_size += 50;
|
||
new_free((char **)&wide_list);
|
||
wide_list = new_list;
|
||
}
|
||
wide_list[wl_elements] = (WideList *)
|
||
new_malloc(sizeof(WideList));
|
||
wide_list[wl_elements]->channel = NULL;
|
||
wide_list[wl_elements]->users = cnt;
|
||
malloc_strcpy(&wide_list[wl_elements]->channel,
|
||
(*channel != '*') ? channel : "Prv");
|
||
wl_elements++;
|
||
return;
|
||
}
|
||
set_display_target(channel, LOG_CRAP);
|
||
if (do_hook(current_numeric, "%s %s %s %s", from, channel, user_cnt,
|
||
line) && do_hook(LIST_LIST, "%s %s %s", channel, user_cnt, line))
|
||
{
|
||
if (channel && user_cnt)
|
||
put_it("%s", convert_output_format(fget_string_var(FORMAT_LIST_FSET),"%s %s %s %s", update_clock(GET_TIME), *channel == '*'?"Prv":channel, user_cnt, line));
|
||
}
|
||
reset_display_target();
|
||
}
|
||
|
||
/* print_funny_names
|
||
*
|
||
* This handles presenting the output of a NAMES reply. It is a cut-down
|
||
* version of the /SCAN output formatting.
|
||
*/
|
||
void print_funny_names(char *line)
|
||
{
|
||
char *t;
|
||
int count = 0;
|
||
char buffer[BIG_BUFFER_SIZE];
|
||
int cols = get_int_var(NAMES_COLUMNS_VAR);
|
||
|
||
if (!cols)
|
||
cols = 1;
|
||
|
||
if (line && *line)
|
||
{
|
||
*buffer = 0;
|
||
|
||
while (t = next_arg(line, &line)) {
|
||
char *nick;
|
||
char *nick_format;
|
||
char nick_buffer[BIG_BUFFER_SIZE];
|
||
|
||
if (!count && fget_string_var(FORMAT_NAMES_BANNER_FSET))
|
||
strlcat(buffer, convert_output_format(
|
||
fget_string_var(FORMAT_NAMES_BANNER_FSET), NULL, NULL),
|
||
sizeof buffer);
|
||
|
||
/* Seperate the nick and the possible status presets that might
|
||
* preceede it. */
|
||
nick = t + strspn(t, "@%+~-");
|
||
nick_format = fget_string_var(isme(nick) ?
|
||
FORMAT_NAMES_NICK_ME_FSET : FORMAT_NAMES_NICK_FSET);
|
||
strlcpy(nick_buffer,
|
||
convert_output_format(nick_format, "%s", nick),
|
||
sizeof nick_buffer);
|
||
|
||
if (nick != t)
|
||
{
|
||
char special = *t;
|
||
|
||
if (special == '+')
|
||
strlcat(buffer,
|
||
convert_output_format(
|
||
fget_string_var(FORMAT_NAMES_USER_VOICE_FSET),
|
||
"%c %s", special, nick_buffer), sizeof buffer);
|
||
else
|
||
strlcat(buffer,
|
||
convert_output_format(
|
||
fget_string_var(FORMAT_NAMES_USER_CHANOP_FSET),
|
||
"%c %s", special, nick_buffer), sizeof buffer);
|
||
}
|
||
else
|
||
strlcat(buffer,
|
||
convert_output_format(
|
||
fget_string_var(FORMAT_NAMES_USER_FSET), ". %s",
|
||
nick_buffer), sizeof buffer);
|
||
|
||
strlcat(buffer, space, sizeof buffer);
|
||
|
||
if (++count >= cols)
|
||
{
|
||
put_it("%s", buffer);
|
||
*buffer = 0;
|
||
count = 0;
|
||
}
|
||
}
|
||
|
||
if (count)
|
||
put_it("%s", buffer);
|
||
}
|
||
}
|
||
|
||
void funny_namreply(char *from, char **Args)
|
||
{
|
||
char *type,
|
||
*channel;
|
||
static char format[40];
|
||
static int last_width = -1;
|
||
register char *ptr;
|
||
register char *line;
|
||
int user_count = 0;
|
||
|
||
PasteArgs(Args, 2);
|
||
type = Args[0];
|
||
channel = Args[1];
|
||
line = Args[2];
|
||
|
||
/* protocol violation by server */
|
||
if (!channel || !line)
|
||
return;
|
||
|
||
ptr = line;
|
||
while (*ptr)
|
||
{
|
||
while (*ptr && (*ptr != ' '))
|
||
ptr++;
|
||
user_count++;
|
||
while (*ptr && (*ptr == ' '))
|
||
ptr++;
|
||
}
|
||
|
||
if (in_join_list(channel, from_server))
|
||
{
|
||
set_display_target(channel, LOG_CRAP);
|
||
if (do_hook(current_numeric, "%s %s %s %s", from, type, channel,line)
|
||
&& do_hook(NAMES_LIST, "%s %s", channel, line)
|
||
&& get_int_var(SHOW_CHANNEL_NAMES_VAR))
|
||
{
|
||
put_it("%s", convert_output_format(fget_string_var(FORMAT_NAMES_FSET), "%s %s %d",update_clock(GET_TIME), channel, user_count));
|
||
print_funny_names(line);
|
||
}
|
||
if ((user_count == 1) && (*line == '@'))
|
||
{
|
||
ChannelList *chan;
|
||
if ((chan = lookup_channel(channel, from_server, CHAN_NOUNLINK)))
|
||
if ((ptr = get_cset_str_var(chan->csets, CHANMODE_CSET)))
|
||
my_send_to_server(from_server, "MODE %s %s", channel, ptr);
|
||
}
|
||
got_info(channel, from_server, GOTNAMES);
|
||
reset_display_target();
|
||
return;
|
||
}
|
||
if (last_width != get_int_var(CHANNEL_NAME_WIDTH_VAR))
|
||
{
|
||
if ((last_width = get_int_var(CHANNEL_NAME_WIDTH_VAR)) != 0)
|
||
sprintf(format, "%%s: %%-%u.%us %%s",
|
||
(unsigned char) last_width,
|
||
(unsigned char) last_width);
|
||
else
|
||
strcpy(format, "%s: %s\t%s");
|
||
}
|
||
if (funny_min && (user_count < funny_min))
|
||
return;
|
||
else if (funny_max && (user_count > funny_max))
|
||
return;
|
||
if ((funny_flags & FUNNY_PRIVATE) && (*type == '='))
|
||
return;
|
||
if ((funny_flags & FUNNY_PUBLIC) && ((*type == '*') || (*type == '@')))
|
||
return;
|
||
if (type && channel)
|
||
{
|
||
if (match_str)
|
||
{
|
||
if (wild_match(match_str, channel) == 0)
|
||
return;
|
||
}
|
||
if (do_hook(current_numeric, "%s %s %s %s", from, type, channel, line) && do_hook(NAMES_LIST, "%s %s", channel, line))
|
||
{
|
||
set_display_target(channel, LOG_CRAP);
|
||
if (fget_string_var(FORMAT_NAMES_FSET))
|
||
{
|
||
put_it("%s", convert_output_format(fget_string_var(FORMAT_NAMES_FSET), "%s %s %d", update_clock(GET_TIME), channel, user_count));
|
||
print_funny_names(line);
|
||
}
|
||
else
|
||
{
|
||
switch (*type)
|
||
{
|
||
case '=':
|
||
if (last_width &&(strlen(channel) > last_width))
|
||
{
|
||
channel[last_width-1] = '>';
|
||
channel[last_width] = (char) 0;
|
||
}
|
||
put_it(format, "Pub", channel, line);
|
||
break;
|
||
case '*':
|
||
put_it(format, "Prv", channel, line);
|
||
break;
|
||
case '@':
|
||
put_it(format, "Sec", channel, line);
|
||
break;
|
||
}
|
||
}
|
||
reset_display_target();
|
||
}
|
||
}
|
||
}
|
||
|
||
void funny_mode(char *from, char **ArgList)
|
||
{
|
||
char *mode, *channel;
|
||
ChannelList *chan = NULL;
|
||
|
||
if (!ArgList[0]) return;
|
||
|
||
channel = ArgList[0];
|
||
mode = ArgList[1];
|
||
PasteArgs(ArgList, 1);
|
||
|
||
if((channel && in_join_list(channel, from_server)) || get_chan_from_join_list(from_server))
|
||
{
|
||
if (!channel)
|
||
channel = get_chan_from_join_list(from_server);
|
||
update_channel_mode(from, channel, from_server, mode, chan);
|
||
update_all_status(current_window, NULL, 0);
|
||
got_info(channel, from_server, GOTMODE);
|
||
}
|
||
else
|
||
{
|
||
if (channel)
|
||
{
|
||
set_display_target(channel, LOG_CRAP);
|
||
if (do_hook(current_numeric, "%s %s %s", from, channel, mode))
|
||
put_it("%s", convert_output_format(fget_string_var(FORMAT_MODE_CHANNEL_FSET), "%s %s %s %s %s", update_clock(GET_TIME), from, *FromUserHost ? FromUserHost:"<EFBFBD>", channel, mode));
|
||
reset_display_target();
|
||
}
|
||
else
|
||
{
|
||
if (do_hook(current_numeric, "%s %s", from, mode))
|
||
put_it("%s", convert_output_format(fget_string_var(FORMAT_MODE_CHANNEL_FSET), "%s %s %s %s", update_clock(GET_TIME), from, *FromUserHost ? FromUserHost:"<EFBFBD>", mode));
|
||
}
|
||
}
|
||
}
|
||
|
||
void update_user_mode(char *modes)
|
||
{
|
||
int onoff = 1;
|
||
char *p_umodes = get_possible_umodes(from_server);
|
||
|
||
for (; *modes; modes++)
|
||
{
|
||
if (*modes == '-')
|
||
onoff = 0;
|
||
else if (*modes == '+')
|
||
onoff = 1;
|
||
|
||
else if ((*modes >= 'a' && *modes <= 'z')
|
||
|| (*modes >= 'A' && *modes <= 'Z'))
|
||
{
|
||
size_t idx;
|
||
int c = *modes;
|
||
|
||
idx = ccspan(p_umodes, c);
|
||
if (p_umodes[idx] == 0)
|
||
ircpanic("Invalid user mode referenced");
|
||
set_server_flag(from_server, idx, onoff);
|
||
|
||
if (c == 'o' || c == 'O')
|
||
set_server_operator(from_server, onoff);
|
||
#if 0
|
||
char c = tolower(*modes);
|
||
size_t idx = (size_t) (strchr(umodes, c) - umodes);
|
||
|
||
set_server_flag(from_server, USER_MODE << idx, onoff);
|
||
|
||
if (c == 'o' || c == 'O')
|
||
set_server_operator(from_server, onoff);
|
||
#endif
|
||
}
|
||
}
|
||
}
|
||
|
||
void reinstate_user_modes (void)
|
||
{
|
||
char *modes = get_umode(from_server);
|
||
if (modes && *modes)
|
||
send_to_server("MODE %s +%s", get_server_nickname(from_server), modes);
|
||
}
|