/* * Playground+ - output.c * Enhanced output processor by Mo McKinlay * ---------------------------------------------------------------------------- * * Replaces the two versions of process_output supplied in PG+ * Tweeks to basecode to show social tagging by Silver */ #include <stdlib.h> #include <stdio.h> #include <assert.h> #include <string.h> #include <unistd.h> #include <ctype.h> #include "include/config.h" #include "include/player.h" #include "include/fix.h" #include "include/proto.h" #include "include/output.h" /* tags[] * * This array lists the tag characters which should be used. * If 0 is specified, a tag won't be output. * Place the tags in the order that they should appear on output. * (For example, TT_ECHO preceeding TT_ROOM). */ tagentry_t tags[] = { { TT_LOGIN, ']' }, /* Logins */ { TT_LOGOUT, '[' }, /* Logouts */ { TT_RECON, '%' }, /* Reconnections */ { TT_ECHO, '+' }, /* Echos */ { TT_ITEM, '^' }, /* Items */ { TT_ROOM, '-' }, /* Room messages */ { TT_AUTO, '#' }, /* Automessages */ { TT_FRIEND, '*' }, /* Old-style friend tells */ { TT_OFRIEND, '=' }, /* Old-style friend tells to others */ { TT_MULTI, '&' }, /* Old-style multi-tells */ { TT_NMULTI, '*' }, /* New-style multi-tells */ { TT_SOCIAL, '~' }, /* Socials */ { TT_PIPE, '>' }, /* Pipes */ { TT_TELL, '>' }, /* Tells */ { TT_SHOUT, '!' }, /* Shouts */ { TT_VOID, 0 }, }; /* output_checktags() * * Build a tagtype_t set based on the current global flags and player's * tag_flags settings. */ tagtype_t output_checktags(player *p) { tagtype_t t; if(p==current_player) return TT_VOID; t=TT_VOID; /* Tag logins/logouts/reconnects/echos */ if((command_type&LOGIN_TAG) && (p->tag_flags & TAG_LOGINS)) { t|=TT_LOGIN; } else if((command_type&LOGOUT_TAG) && (p->tag_flags & TAG_LOGINS)) { t|=TT_LOGOUT; } else if((command_type&RECON_TAG) && (p->tag_flags & TAG_LOGINS)) { t|=TT_RECON; } else if((command_type&ECHO_COM) && (p->tag_flags & TAG_ECHO)) { t|=TT_ECHO; }; #ifdef ALLOW_MULTIS if (!(command_type & MULTI_COM)) { #endif if(((command_type&PERSONAL) || (p->flags&TAGGED)) && (p!=current_player)) { if((sys_flags&FRIEND_TAG) && (p->tag_flags&TAG_PERSONAL)) { t|=TT_FRIEND; } else if((sys_flags&OFRIEND_TAG) && (p->tag_flags&TAG_PERSONAL)) { t|=TT_OFRIEND; } else if((sys_flags&REPLY_TAG) && (p->tag_flags&TAG_PERSONAL)) { t|=TT_MULTI; } else if(command_type & PERSONAL) { t|=TT_TELL; } else { t|=TT_PIPE; }; }; #ifdef ALLOW_MULTIS } else { t|=TT_NMULTI; }; #endif if(sys_flags&ITEM_TAG) { if(p->tag_flags & TAG_ITEMS) { t|=TT_ITEM; } else if(p->tag_flags & TAG_ROOM) { t|=TT_ROOM; }; }; if((command_type&SOCIAL) && (p->tag_flags & TAG_ROOM)) { t|=TT_SOCIAL; } else if(((command_type&EVERYONE) || (sys_flags&EVERYONE_TAG)) && (p->tag_flags&TAG_SHOUT)) { t|=TT_SHOUT; } else if((command_type&AUTO) && (p->tag_flags & TAG_AUTOS)) { t|=TT_AUTO; } else if(((command_type&ROOM) || (sys_flags&ROOM_TAG)) && (p->tag_flags & TAG_ROOM) && (p!=current_player)) { t|=TT_ROOM; }; if((command_type&ECHO_COM) && (p->tag_flags&SEEECHO)) { t|=TT_SEEECHO; }; return t; } /* output_tags() * * Append appropriate tags to the stack. */ char *output_tags(player *p, tagtype_t t) { char *oldstack; int c; oldstack=stack; for(c=0; tags[c].type!=TT_VOID; c++) { if((t & tags[c].type) && (tags[c].tag)) { *stack++=tags[c].tag; p->column++; }; }; if(t & TT_SEEECHO) { *stack++='['; strcpy(stack, current_player->name); while(*stack) { stack++; p->column++; }; *stack++=']'; p->column+=2; }; if(oldstack!=stack) { /* Put a space between the tag and the rest of the text */ *stack++=' '; p->column++; }; return stack; } file process_output(player *p, char *str) { file o; int x, l, xstart; char *wstart, *sstart, *t; int scat; o.where=stack; output_tags(p, output_checktags(p)); scat=sys_color_atm; x=p->column; /* * If HIGHLIGHT is set, turn it on here. */ if((p->term) && (command_type&HIGHLIGHT)) { strcpy(stack, terms[(p->term - 1)].bold); stack=strchr(stack, 0); }; if((p->term) && (p->misc_flags & SYSTEM_COLOR)) { strcpy(stack, getcolor(p, p->colorset[sys_color_atm])); stack=strchr(stack, 0); }; wstart=NULL; sstart=NULL; xstart=0; while(*str) { if(*str=='^' && (*(str+1)!='^')) { if(wstart==str) { wstart+=2; sstart+=2; }; str++; if((p->term) && !(p->misc_flags & NOCOLOR)) { if(*str=='N' && !((command_type&HIGHLIGHT) && (sys_color_atm==SYSsc))) { if(p->colorset[sys_color_atm]=='N') { strcpy(stack, terms[(p->term - 1)].off); } else { strcpy(stack, getcolor(p, p->colorset[sys_color_atm])); }; } else { strcpy(stack, getcolor(p, *str)); }; stack=strchr(stack, 0); }; str++; } else if(*str=='\n') { if(!(*(str+1))) { /* Turn colour off before the CRLF */ if((p->term) && (((sys_color_atm!=SYSsc) && (p->misc_flags&SYSTEM_COLOR)) || ((command_type & HIGHLIGHT) && !(p->misc_flags&NOCOLOR)))) { strcpy(stack, getcolor(p, '^')); stack=strchr(stack, 0); sys_color_atm=SYSsc; }; }; *stack++='\r'; *stack++='\n'; x=0; str++; } else { if(*str=='^') { str++; }; if(!isalnum(*str)) { wstart=NULL; sstart=NULL; xstart=0; }; if((x>=p->term_width) && (p->term_width!=0)) { /* This word will take us over the threshold */ if(!wstart) { /* No current word, just wrap now */ strcpy(stack, "\r\n "); stack=strchr(stack, 0); x=4; *stack=*str; stack++; str++; } else { /* Find out the length of the word. If it's less * than p->word_wrap, we cycle backwards, otherwise * we just split the word and carry on */ l=0; for(t=wstart; t!=str; t++) l++; if(l<p->word_wrap) { /* Cycle backwards */ str=wstart; stack=sstart; strcpy(stack, "\r\n "); stack=strchr(stack, 0); x=3; } else { /* Split the word up */ strcpy(stack, "\r\n "); stack=strchr(stack, 0); if(isalnum(*str)) { x=4; wstart=str; sstart=str; xstart=x; *stack=*str; stack++; str++; } else { x=3; str++; wstart=str; sstart=str; xstart=x; }; }; }; } else { if(!isspace(*str) && !wstart) { /* Start of a new word */ wstart=str; sstart=stack; xstart=x; }; *stack=*str; x++; stack++; str++; }; }; }; /* Turn colour off again */ if((p->term) && (p->misc_flags&SYSTEM_COLOR)) { strcpy(stack, getcolor(p, '^')); stack=strchr(stack, 0); }; if((p->term) && (command_type & HIGHLIGHT)) { strcpy(stack, terms[(p->term - 1)].off); stack=strchr(stack, 0); }; *stack=0; o.length = ((int) stack - (int) o.where) * sizeof(char); sys_color_atm=scat; p->column = x; return o; }