diff -c -x *.o -x *.exe -x Makefile* ../Rom24/src/act_comm.c src/act_comm.c *** ../Rom24/src/act_comm.c Thu May 28 09:23:48 1998 --- src/act_comm.c Thu Jul 5 09:43:13 2001 *************** *** 890,896 **** } act( "You tell $N '$t'", ch, argument, victim, TO_CHAR ); ! act_new("$n tells you '$t'",ch,argument,victim,TO_VICT,POS_DEAD); victim->reply = ch; return; --- 890,899 ---- } act( "You tell $N '$t'", ch, argument, victim, TO_CHAR ); ! act_new(MXPTAG ("player $n") ! "$n" ! MXPTAG ("/player") ! " tells you '$t'",ch,argument,victim,TO_VICT,POS_DEAD); victim->reply = ch; return; diff -c -x *.o -x *.exe -x Makefile* ../Rom24/src/act_info.c src/act_info.c *** ../Rom24/src/act_info.c Thu May 28 10:37:17 1998 --- src/act_info.c Thu Jul 5 09:43:13 2001 *************** *** 76,82 **** char * format_obj_to_char args( ( OBJ_DATA *obj, CHAR_DATA *ch, bool fShort ) ); void show_list_to_char args( ( OBJ_DATA *list, CHAR_DATA *ch, ! bool fShort, bool fShowNothing ) ); void show_char_to_char_0 args( ( CHAR_DATA *victim, CHAR_DATA *ch ) ); void show_char_to_char_1 args( ( CHAR_DATA *victim, CHAR_DATA *ch ) ); void show_char_to_char args( ( CHAR_DATA *list, CHAR_DATA *ch ) ); --- 76,82 ---- char * format_obj_to_char args( ( OBJ_DATA *obj, CHAR_DATA *ch, bool fShort ) ); void show_list_to_char args( ( OBJ_DATA *list, CHAR_DATA *ch, ! bool fShort, bool fShowNothing, const int iDefaultAction ) ); void show_char_to_char_0 args( ( CHAR_DATA *victim, CHAR_DATA *ch ) ); void show_char_to_char_1 args( ( CHAR_DATA *victim, CHAR_DATA *ch ) ); void show_char_to_char args( ( CHAR_DATA *list, CHAR_DATA *ch ) ); *************** *** 124,145 **** * Show a list to a character. * Can coalesce duplicated items. */ ! void show_list_to_char( OBJ_DATA *list, CHAR_DATA *ch, bool fShort, bool fShowNothing ) { char buf[MAX_STRING_LENGTH]; BUFFER *output; char **prgpstrShow; int *prgnShow; char *pstrShow; OBJ_DATA *obj; int nShow; int iShow; int count; bool fCombine; if ( ch->desc == NULL ) return; /* * Alloc space for output lines. */ --- 124,159 ---- * Show a list to a character. * Can coalesce duplicated items. */ ! void show_list_to_char( OBJ_DATA *list, CHAR_DATA *ch, bool fShort, bool fShowNothing, const int iDefaultAction ) { char buf[MAX_STRING_LENGTH]; BUFFER *output; char **prgpstrShow; + char **prgpstrName; /* for MXP */ + char **prgpstrShortName; /* for MXP */ int *prgnShow; char *pstrShow; + char *pstrName; /* for MXP */ + char *pstrShortName; /* for MXP */ OBJ_DATA *obj; int nShow; int iShow; int count; bool fCombine; + char * pAction = NULL; if ( ch->desc == NULL ) return; + /* work out which MXP tag to use */ + + switch (iDefaultAction) + { + case eItemGet: pAction = "Get"; break; /* item on ground */ + case eItemDrop: pAction = "Drop"; break; /* item in inventory */ + + } /* end of switch on action */ + /* * Alloc space for output lines. */ *************** *** 149,154 **** --- 163,170 ---- for ( obj = list; obj != NULL; obj = obj->next_content ) count++; prgpstrShow = alloc_mem( count * sizeof(char *) ); + prgpstrName = alloc_mem( count * sizeof(char *) ); + prgpstrShortName = alloc_mem( count * sizeof(char *) ); prgnShow = alloc_mem( count * sizeof(int) ); nShow = 0; *************** *** 160,166 **** if ( obj->wear_loc == WEAR_NONE && can_see_obj( ch, obj )) { pstrShow = format_obj_to_char( obj, ch, fShort ); ! fCombine = FALSE; if ( IS_NPC(ch) || IS_SET(ch->comm, COMM_COMBINE) ) --- 176,183 ---- if ( obj->wear_loc == WEAR_NONE && can_see_obj( ch, obj )) { pstrShow = format_obj_to_char( obj, ch, fShort ); ! pstrName = obj->name; ! pstrShortName = obj->short_descr; fCombine = FALSE; if ( IS_NPC(ch) || IS_SET(ch->comm, COMM_COMBINE) ) *************** *** 186,191 **** --- 203,210 ---- if ( !fCombine ) { prgpstrShow [nShow] = str_dup( pstrShow ); + prgpstrName [nShow] = str_dup( pstrName ); + prgpstrShortName [nShow] = str_dup( pstrShortName ); prgnShow [nShow] = 1; nShow++; } *************** *** 200,205 **** --- 219,226 ---- if (prgpstrShow[iShow][0] == '\0') { free_string(prgpstrShow[iShow]); + free_string(prgpstrName[iShow]); + free_string(prgpstrShortName[iShow]); continue; } *************** *** 215,223 **** --- 236,260 ---- add_buf(output," "); } } + if (pAction) + { + int i = 0; + char * p = prgpstrName[iShow]; + for ( ; *p && !isspace (*p); p++, i++) + ; + sprintf (buf, MXPTAG ("%s '%.*s' '%s'"), pAction, i, prgpstrName[iShow], prgpstrShortName[iShow]); + add_buf(output,buf); + } add_buf(output,prgpstrShow[iShow]); + if (pAction) + { + sprintf (buf, MXPTAG ("/%s"), pAction); + add_buf(output,buf); + } add_buf(output,"\n\r"); free_string( prgpstrShow[iShow] ); + free_string(prgpstrName[iShow]); + free_string(prgpstrShortName[iShow]); } if ( fShowNothing && nShow == 0 ) *************** *** 233,238 **** --- 270,277 ---- */ free_buf(output); free_mem( prgpstrShow, count * sizeof(char *) ); + free_mem( prgpstrName, count * sizeof(char *) ); + free_mem( prgpstrShortName, count * sizeof(char *) ); free_mem( prgnShow, count * sizeof(int) ); return; *************** *** 483,489 **** { send_to_char( "\n\rYou peek at the inventory:\n\r", ch ); check_improve(ch,gsn_peek,TRUE,4); ! show_list_to_char( victim->carrying, ch, TRUE, TRUE ); } return; --- 522,528 ---- { send_to_char( "\n\rYou peek at the inventory:\n\r", ch ); check_improve(ch,gsn_peek,TRUE,4); ! show_list_to_char( victim->carrying, ch, TRUE, TRUE, eItemNothing ); } return; *************** *** 1048,1054 **** do_function(ch, &do_exits, "auto" ); } ! show_list_to_char( ch->in_room->contents, ch, FALSE, FALSE ); show_char_to_char( ch->in_room->people, ch ); return; } --- 1087,1093 ---- do_function(ch, &do_exits, "auto" ); } ! show_list_to_char( ch->in_room->contents, ch, FALSE, FALSE, eItemGet ); show_char_to_char( ch->in_room->people, ch ); return; } *************** *** 1102,1108 **** } act( "$p holds:", ch, obj, NULL, TO_CHAR ); ! show_list_to_char( obj->contains, ch, TRUE, TRUE ); break; } return; --- 1141,1147 ---- } act( "$p holds:", ch, obj, NULL, TO_CHAR ); ! show_list_to_char( obj->contains, ch, TRUE, TRUE, eItemNothing ); break; } return; *************** *** 1347,1353 **** --- 1386,1394 ---- if ( fAuto ) { strcat( buf, " " ); + strcat (buf, MXPTAG ("Ex")); strcat( buf, dir_name[door] ); + strcat (buf, MXPTAG ("/Ex")); } else { *************** *** 2106,2112 **** void do_inventory( CHAR_DATA *ch, char *argument ) { send_to_char( "You are carrying:\n\r", ch ); ! show_list_to_char( ch->carrying, ch, TRUE, TRUE ); return; } --- 2147,2153 ---- void do_inventory( CHAR_DATA *ch, char *argument ) { send_to_char( "You are carrying:\n\r", ch ); ! show_list_to_char( ch->carrying, ch, TRUE, TRUE, eItemDrop ); return; } diff -c -x *.o -x *.exe -x Makefile* ../Rom24/src/act_obj.c src/act_obj.c *** ../Rom24/src/act_obj.c Thu May 28 10:11:12 1998 --- src/act_obj.c Thu Jul 5 09:43:13 2001 *************** *** 35,40 **** --- 35,41 ---- #include #include #include + #include #include "merc.h" #include "interp.h" *************** *** 2798,2804 **** found = FALSE; for ( obj = keeper->carrying; obj; obj = obj->next_content ) { ! if ( obj->wear_loc == WEAR_NONE && can_see_obj( ch, obj ) && ( cost = get_cost( keeper, obj, TRUE ) ) > 0 && ( arg[0] == '\0' --- 2799,2810 ---- found = FALSE; for ( obj = keeper->carrying; obj; obj = obj->next_content ) { ! int i = 0; ! char * p = obj->name; ! for ( ; *p && !isspace (*p); p++, i++) ! ; ! ! if ( obj->wear_loc == WEAR_NONE && can_see_obj( ch, obj ) && ( cost = get_cost( keeper, obj, TRUE ) ) > 0 && ( arg[0] == '\0' *************** *** 2811,2818 **** } if (IS_OBJ_STAT(obj,ITEM_INVENTORY)) ! sprintf(buf,"[%2d %5d -- ] %s\n\r", ! obj->level,cost,obj->short_descr); else { count = 1; --- 2817,2830 ---- } if (IS_OBJ_STAT(obj,ITEM_INVENTORY)) ! sprintf(buf,"[%2d %5d -- ] " ! MXPTAG ("list '%.*s' '%s'") ! "%s" ! MXPTAG ("/list") ! "\n\r", ! obj->level,cost, ! i, obj->name, obj->short_descr, ! obj->short_descr); else { count = 1; *************** *** 2825,2832 **** obj = obj->next_content; count++; } ! sprintf(buf,"[%2d %5d %2d ] %s\n\r", ! obj->level,cost,count,obj->short_descr); } send_to_char( buf, ch ); } --- 2837,2850 ---- obj = obj->next_content; count++; } ! sprintf(buf,"[%2d %5d %2d ] " ! MXPTAG ("list '%.*s' '%s'") ! "%s" ! MXPTAG ("/list") ! "\n\r", ! obj->level,cost,count, ! i, obj->name, obj->short_descr, ! obj->short_descr); } send_to_char( buf, ch ); } diff -c -x *.o -x *.exe -x Makefile* ../Rom24/src/comm.c src/comm.c *** ../Rom24/src/comm.c Thu May 28 10:25:22 1998 --- src/comm.c Thu Jul 5 09:43:13 2001 *************** *** 56,61 **** --- 56,62 ---- #include #include #include + #include #include "merc.h" #include "interp.h" *************** *** 111,121 **** --- 112,129 ---- #include #include #include "telnet.h" + const char echo_off_str [] = { IAC, WILL, TELOPT_ECHO, '\0' }; const char echo_on_str [] = { IAC, WONT, TELOPT_ECHO, '\0' }; const char go_ahead_str [] = { IAC, GA, '\0' }; #endif + #define TELOPT_MXP '\x5B' + + const unsigned char will_mxp_str [] = { IAC, WILL, TELOPT_MXP, '\0' }; + const unsigned char start_mxp_str [] = { IAC, SB, TELOPT_MXP, IAC, SE, '\0' }; + const unsigned char do_mxp_str [] = { IAC, DO, TELOPT_MXP, '\0' }; + const unsigned char dont_mxp_str [] = { IAC, DONT, TELOPT_MXP, '\0' }; /* *************** *** 430,435 **** --- 438,501 ---- } + /* set up MXP */ + void turn_on_mxp (DESCRIPTOR_DATA *d) + { + d->mxp = TRUE; /* turn it on now */ + write_to_buffer( d, start_mxp_str, 0 ); + write_to_buffer( d, MXPMODE (6), 0 ); /* permanent secure mode */ + write_to_buffer( d, MXPTAG ("!-- Set up MXP elements --"), 0); + /* Exit tag */ + write_to_buffer( d, MXPTAG ("!ELEMENT Ex '' FLAG=RoomExit"), 0); + /* Room description tag */ + write_to_buffer( d, MXPTAG ("!ELEMENT rdesc '

' FLAG=RoomDesc"), 0); + /* Get an item tag (for things on the ground) */ + write_to_buffer( d, MXPTAG + ("!ELEMENT Get \"\" ATT='name desc'"), + 0); + /* Drop an item tag (for things in the inventory) */ + write_to_buffer( d, MXPTAG + ("!ELEMENT Drop \"\" ATT='name desc'"), + 0); + /* List an item tag (for things in a shop) */ + write_to_buffer( d, MXPTAG + ("!ELEMENT List \"\" " + "ATT='name desc'"), + 0); + /* Player tag (for who lists, tells etc.) */ + write_to_buffer( d, MXPTAG + ("!ELEMENT Player \"\" " + "ATT='name'"), + 0); + } /* end of turn_on_mxp */ + + #if defined(unix) int init_socket( int port ) *************** *** 893,898 **** --- 959,965 ---- dnew->showstr_point = NULL; dnew->outsize = 2000; dnew->outbuf = alloc_mem( dnew->outsize ); + dnew->mxp = FALSE; /* NJG - initially MXP is off */ size = sizeof(sock); if ( getpeername( desc, (struct sockaddr *) &sock, &size ) < 0 ) *************** *** 1105,1110 **** --- 1172,1178 ---- void read_from_buffer( DESCRIPTOR_DATA *d ) { int i, j, k; + unsigned char * p; /* * Hold horses if pending command already. *************** *** 1112,1117 **** --- 1180,1210 ---- if ( d->incomm[0] != '\0' ) return; + /* + + Look for incoming telnet negotiation + */ + + + for (p = d->inbuf; *p; p++) + if (*p == IAC) + { + if (memcmp (p, do_mxp_str, strlen (do_mxp_str)) == 0) + { + turn_on_mxp (d); + /* remove string from input buffer */ + memmove (p, &p [strlen (do_mxp_str)], strlen (&p [strlen (do_mxp_str)]) + 1); + p--; /* adjust to allow for discarded bytes */ + } /* end of turning on MXP */ + else if (memcmp (p, dont_mxp_str, strlen (dont_mxp_str)) == 0) + { + d->mxp = FALSE; + /* remove string from input buffer */ + memmove (p, &p [strlen (dont_mxp_str)], strlen (&p [strlen (dont_mxp_str)]) + 1); + p--; /* adjust to allow for discarded bytes */ + } /* end of turning off MXP */ + } /* end of finding an IAC */ + /* * Look for at least one new line. */ *************** *** 1327,1332 **** --- 1420,1429 ---- const char *dir_name[] = {"N","E","S","W","U","D"}; int door; + /* reset MXP to default operation */ + if (ch->desc->mxp) + write_to_buffer( ch->desc, ESC "[3z", 0); + point = buf; str = ch->prompt; if (str == NULL || str[0] == '\0') *************** *** 1452,1457 **** --- 1549,1725 ---- return; } + /* + * Count number of mxp tags need converting + * ie. < becomes < + * > becomes > + * & becomes & + */ + + int count_mxp_tags (const int bMXP, const char *txt, int length) + { + char c; + const char * p; + int count; + int bInTag = FALSE; + int bInEntity = FALSE; + + for (p = txt, count = 0; + length > 0; + p++, length--) + { + c = *p; + + if (bInTag) /* in a tag, eg. */ + { + if (!bMXP) + count--; /* not output if not MXP */ + if (c == MXP_ENDc) + bInTag = FALSE; + } /* end of being inside a tag */ + else if (bInEntity) /* in a tag, eg. */ + { + if (!bMXP) + count--; /* not output if not MXP */ + if (c == ';') + bInEntity = FALSE; + } /* end of being inside a tag */ + else switch (c) + { + + case MXP_BEGc: + bInTag = TRUE; + if (!bMXP) + count--; /* not output if not MXP */ + break; + + case MXP_ENDc: /* shouldn't get this case */ + if (!bMXP) + count--; /* not output if not MXP */ + break; + + case MXP_AMPc: + bInEntity = TRUE; + if (!bMXP) + count--; /* not output if not MXP */ + break; + + default: + if (bMXP) + { + switch (c) + { + case '<': /* < becomes < */ + case '>': /* > becomes > */ + count += 3; + break; + + case '&': + count += 4; /* & becomes & */ + break; + + case '"': /* " becomes " */ + count += 5; + break; + + } /* end of inner switch */ + } /* end of MXP enabled */ + } /* end of switch on character */ + + } /* end of counting special characters */ + + return count; + } /* end of count_mxp_tags */ + + void convert_mxp_tags (const int bMXP, char * dest, const char *src, int length) + { + char c; + const char * ps; + char * pd; + int bInTag = FALSE; + int bInEntity = FALSE; + + for (ps = src, pd = dest; + length > 0; + ps++, length--) + { + c = *ps; + if (bInTag) /* in a tag, eg. */ + { + if (c == MXP_ENDc) + { + bInTag = FALSE; + if (bMXP) + *pd++ = '>'; + } + else if (bMXP) + *pd++ = c; /* copy tag only in MXP mode */ + } /* end of being inside a tag */ + else if (bInEntity) /* in a tag, eg. */ + { + if (bMXP) + *pd++ = c; /* copy tag only in MXP mode */ + if (c == ';') + bInEntity = FALSE; + } /* end of being inside a tag */ + else switch (c) + { + case MXP_BEGc: + bInTag = TRUE; + if (bMXP) + *pd++ = '<'; + break; + + case MXP_ENDc: /* shouldn't get this case */ + if (bMXP) + *pd++ = '>'; + break; + + case MXP_AMPc: + bInEntity = TRUE; + if (bMXP) + *pd++ = '&'; + break; + + default: + if (bMXP) + { + switch (c) + { + case '<': + memcpy (pd, "<", 4); + pd += 4; + break; + + case '>': + memcpy (pd, ">", 4); + pd += 4; + break; + + case '&': + memcpy (pd, "&", 5); + pd += 5; + break; + + case '"': + memcpy (pd, """, 6); + pd += 6; + break; + + default: + *pd++ = c; + break; /* end of default */ + + } /* end of inner switch */ + } + else + *pd++ = c; /* not MXP - just copy character */ + break; + + } /* end of switch on character */ + + } /* end of converting special characters */ + } /* end of convert_mxp_tags */ /* *************** *** 1459,1470 **** --- 1727,1745 ---- */ void write_to_buffer( DESCRIPTOR_DATA *d, const char *txt, int length ) { + int origlength; + /* * Find length in case caller didn't. */ if ( length <= 0 ) length = strlen(txt); + origlength = length; + + /* work out how much we need to expand/contract it */ + length += count_mxp_tags (d->mxp, txt, length); + /* * Initial \n\r if needed. */ *************** *** 1498,1504 **** /* * Copy. */ ! strncpy( d->outbuf + d->outtop, txt, length ); d->outtop += length; return; } --- 1773,1779 ---- /* * Copy. */ ! convert_mxp_tags (d->mxp, d->outbuf + d->outtop, txt, origlength ); d->outtop += length; return; } *************** *** 1596,1601 **** --- 1871,1880 ---- close_socket(d); return; } + + /* telnet negotiation to see if they support MXP */ + + write_to_buffer( d, will_mxp_str, 0 ); if ( check_reconnect( d, argument, FALSE ) ) { diff -c -x *.o -x *.exe -x Makefile* ../Rom24/src/merc.h src/merc.h *** ../Rom24/src/merc.h Tue May 26 06:48:53 1998 --- src/merc.h Thu Jul 5 09:43:14 2001 *************** *** 254,259 **** --- 254,260 ---- CHAR_DATA * character; CHAR_DATA * original; bool valid; + bool mxp; char * host; sh_int descriptor; sh_int connected; *************** *** 2325,2327 **** --- 2326,2376 ---- #undef RID #undef SF #undef AD + + + /* mxp stuff - added by Nick Gammon - 18 June 2001 */ + + /* + To simply using MXP we'll use special tags where we want to use MXP tags + and then change them to <, > and & at the last moment. + + eg. MXP_BEG "send" MXP_END becomes: + MXP_AMP "version;" becomes: &version; + + */ + + /* strings */ + #define MXP_BEG "\x03" /* becomes < */ + #define MXP_END "\x04" /* becomes > */ + #define MXP_AMP "\x05" /* becomes & */ + + /* characters */ + #define MXP_BEGc '\x03' /* becomes < */ + #define MXP_ENDc '\x04' /* becomes > */ + #define MXP_AMPc '\x05' /* becomes & */ + + // constructs an MXP tag with < and > around it + #define MXPTAG(arg) MXP_BEG arg MXP_END + + #define ESC "\x1B" /* esc character */ + + #define MXPMODE(arg) ESC "[" #arg "z" + + /* flags for show_list_to_char */ + + enum { + eItemNothing, /* item is not readily accessible */ + eItemGet, /* item on ground */ + eItemDrop, /* item in inventory */ + eItemBid /* auction item */ + }; + + #define MXP_open 0 /* only MXP commands in the "open" category are allowed. */ + #define MXP_secure 1 /* all tags and commands in MXP are allowed within the line. */ + #define MXP_locked 2 /* no MXP or HTML commands are allowed in the line. The line is not parsed for any tags at all. */ + #define MXP_reset 3 /* close all open tags */ + #define MXP_secure_once 4 /* next tag is secure only */ + #define MXP_perm_open 5 /* open mode until mode change */ + #define MXP_perm_secure 6 /* secure mode until mode change */ + #define MXP_perm_locked 7 /* locked mode until mode change */ +