📄 comm.c
字号:
perror( "Read_from_descriptor" );
return FALSE;
}
}
#endif
d->inbuf[iStart] = '\0';
return TRUE;
}
/*
* Transfer one line from input buffer to input line.
*/
void read_from_buffer( DESCRIPTOR_DATA *d )
{
int i, j, k;
/*
* Hold horses if pending command already.
*/
if ( d->incomm[0] != '\0' )
return;
/*
* Look for at least one new line.
*/
for ( i = 0; d->inbuf[i] != '\n' && d->inbuf[i] != '\r'; i++ )
{
if ( d->inbuf[i] == '\0' )
return;
}
/*
* Canonical input processing.
*/
for ( i = 0, k = 0; d->inbuf[i] != '\n' && d->inbuf[i] != '\r'; i++ )
{
if ( k >= MAX_INPUT_LENGTH - 2 )
{
write_to_descriptor( d->descriptor, "Line too long.\n\r", 0 );
/* skip the rest of the line */
for ( ; d->inbuf[i] != '\0'; i++ )
{
if ( d->inbuf[i] == '\n' || d->inbuf[i] == '\r' )
break;
}
d->inbuf[i] = '\n';
d->inbuf[i+1] = '\0';
break;
}
if ( d->inbuf[i] == '\b' && k > 0 )
--k;
else if ( isascii(d->inbuf[i]) && isprint(d->inbuf[i]) )
d->incomm[k++] = d->inbuf[i];
}
/*
* Finish off the line.
*/
if ( k == 0 )
d->incomm[k++] = ' ';
d->incomm[k] = '\0';
/*
* Deal with bozos with #repeat 1000 ...
*/
if ( k > 1 || d->incomm[0] == '!' )
{
if ( d->incomm[0] != '!' && strcmp( d->incomm, d->inlast ) )
{
d->repeat = 0;
}
else
{
if ( ++d->repeat >= 20 )
{
sprintf( log_buf, "%s input spamming!", d->host );
log_string( log_buf );
write_to_descriptor( d->descriptor,
"\n\r*** PUT A LID ON IT!!! ***\n\r", 0 );
strcpy( d->incomm, "quit" );
}
}
}
/*
* Do '!' substitution.
*/
if ( d->incomm[0] == '!' )
strcpy( d->incomm, d->inlast );
else
strcpy( d->inlast, d->incomm );
/*
* Shift the input buffer.
*/
while ( d->inbuf[i] == '\n' || d->inbuf[i] == '\r' )
i++;
for ( j = 0; ( d->inbuf[j] = d->inbuf[i+j] ) != '\0'; j++ )
;
return;
}
/*
* Low level output function.
*/
bool process_output( DESCRIPTOR_DATA *d, bool fPrompt )
{
extern bool merc_down;
/*
* Bust a prompt.
*/
if ( fPrompt && !merc_down && d->connected == CON_PLAYING )
if ( d->showstr_point )
write_to_buffer( d,
"[Please type (c)ontinue, (r)efresh, (b)ack, (h)elp, (q)uit, or RETURN]: ",
0 );
else
{
CHAR_DATA *ch;
ch = d->original ? d->original : d->character;
if ( IS_SET(ch->act, PLR_BLANK) )
write_to_buffer( d, "\n\r", 2 );
if ( IS_SET(ch->act, PLR_PROMPT) )
bust_a_prompt( ch );
if ( IS_SET(ch->act, PLR_TELNET_GA) )
write_to_buffer( d, go_ahead_str, 0 );
}
/*
* Short-circuit if nothing to write.
*/
if ( d->outtop == 0 )
return TRUE;
/*
* Snoop-o-rama.
*/
if ( d->snoop_by != NULL )
{
write_to_buffer( d->snoop_by, "% ", 2 );
write_to_buffer( d->snoop_by, d->outbuf, d->outtop );
}
/*
* OS-dependent output.
*/
if ( !write_to_descriptor( d->descriptor, d->outbuf, d->outtop ) )
{
d->outtop = 0;
return FALSE;
}
else
{
d->outtop = 0;
return TRUE;
}
}
/*
* Bust a prompt (player settable prompt)
* coded by Morgenes for Aldara Mud
*/
void bust_a_prompt( CHAR_DATA *ch )
{
char buf[MAX_STRING_LENGTH];
char buf2[MAX_STRING_LENGTH];
const char *str;
const char *i;
char *point;
if( ch->prompt == NULL || ch->prompt[0] == '\0' )
{
send_to_char( "\n\r\n\r", ch );
return;
}
point = buf;
str = ch->prompt;
while( *str != '\0' )
{
if( *str != '%' )
{
*point++ = *str++;
continue;
}
++str;
switch( *str )
{
default :
i = " "; break;
case 'h' :
sprintf( buf2, "%d", ch->hit );
i = buf2; break;
case 'H' :
sprintf( buf2, "%d", ch->max_hit );
i = buf2; break;
case 'm' :
sprintf( buf2, "%d", ch->mana );
i = buf2; break;
case 'M' :
sprintf( buf2, "%d", ch->max_mana );
i = buf2; break;
case 'v' :
sprintf( buf2, "%d", ch->move );
i = buf2; break;
case 'V' :
sprintf( buf2, "%d", ch->max_move );
i = buf2; break;
case 'x' :
sprintf( buf2, "%d", ch->exp );
i = buf2; break;
case 'g' :
sprintf( buf2, "%d", ch->gold);
i = buf2; break;
case 'a' :
if( ch->level < 5 )
sprintf( buf2, "%d", ch->alignment );
else
sprintf( buf2, "%s", IS_GOOD(ch) ? "good" : IS_EVIL(ch) ?
"evil" : "neutral" );
i = buf2; break;
case 'r' :
if( ch->in_room != NULL )
sprintf( buf2, "%s", ch->in_room->name );
else
sprintf( buf2, " " );
i = buf2; break;
case 'R' :
if( IS_IMMORTAL( ch ) && ch->in_room != NULL )
sprintf( buf2, "%d", ch->in_room->vnum );
else
sprintf( buf2, " " );
i = buf2; break;
case 'z' :
if( IS_IMMORTAL( ch ) && ch->in_room != NULL )
sprintf( buf2, "%s", ch->in_room->area->name );
else
sprintf( buf2, " " );
i = buf2; break;
case '%' :
sprintf( buf2, "%%" );
i = buf2; break;
}
++str;
while( (*point = *i) != '\0' )
++point, ++i;
}
write_to_buffer( ch->desc, buf, point - buf );
return;
}
/*
* Append onto an output buffer.
*/
void write_to_buffer( DESCRIPTOR_DATA *d, const char *txt, int length )
{
/*
* Find length in case caller didn't.
*/
if ( length <= 0 )
length = strlen(txt);
/*
* Initial \n\r if needed.
*/
if ( d->outtop == 0 && !d->fcommand )
{
d->outbuf[0] = '\n';
d->outbuf[1] = '\r';
d->outtop = 2;
}
/*
* Expand the buffer as needed.
*/
while ( d->outtop + length >= d->outsize )
{
char *outbuf;
outbuf = alloc_mem( 2 * d->outsize );
strncpy( outbuf, d->outbuf, d->outtop );
free_mem( d->outbuf, d->outsize );
d->outbuf = outbuf;
d->outsize *= 2;
}
/*
* Copy.
*/
strcpy( d->outbuf + d->outtop, txt );
d->outtop += length;
return;
}
/*
* Lowest level output function.
* Write a block of text to the file descriptor.
* If this gives errors on very long blocks (like 'ofind all'),
* try lowering the max block size.
*/
bool write_to_descriptor( int desc, char *txt, int length )
{
int iStart;
int nWrite;
int nBlock;
#if defined(macintosh) || defined(MSDOS)
if ( desc == 0 )
desc = 1;
#endif
if ( length <= 0 )
length = strlen(txt);
for ( iStart = 0; iStart < length; iStart += nWrite )
{
nBlock = UMIN( length - iStart, 4096 );
if ( ( nWrite = write( desc, txt + iStart, nBlock ) ) < 0 )
{ perror( "Write_to_descriptor" ); return FALSE; }
}
return TRUE;
}
/*
* Deal with sockets that haven't logged in yet.
*/
void nanny( DESCRIPTOR_DATA *d, char *argument )
{
char buf[MAX_STRING_LENGTH];
CHAR_DATA *ch;
NOTE_DATA *pnote;
char *pwdnew;
char *p;
int iClass;
int lines;
int notes;
bool fOld;
while ( isspace(*argument) )
argument++;
ch = d->character;
switch ( d->connected )
{
default:
bug( "Nanny: bad d->connected %d.", d->connected );
close_socket( d );
return;
case CON_GET_NAME:
if ( argument[0] == '\0' )
{
close_socket( d );
return;
}
argument[0] = UPPER(argument[0]);
if ( !check_parse_name( argument ) )
{
write_to_buffer( d, "Illegal name, try another.\n\rName: ", 0 );
return;
}
fOld = load_char_obj( d, argument );
ch = d->character;
if ( IS_SET(ch->act, PLR_DENY) )
{
sprintf( log_buf, "Denying access to %s@%s.", argument, d->host );
log_string( log_buf );
write_to_buffer( d, "You are denied access.\n\r", 0 );
close_socket( d );
return;
}
if ( check_reconnect( d, argument, FALSE ) )
{
fOld = TRUE;
}
else
{
if ( wizlock && !IS_HERO( ch ) && !ch->wizbit )
{
write_to_buffer( d, "The game is wizlocked.\n\r", 0 );
close_socket( d );
return;
}
}
if ( fOld )
{
/* Old player */
write_to_buffer( d, "Password: ", 0 );
write_to_buffer( d, echo_off_str, 0 );
d->connected = CON_GET_OLD_PASSWORD;
return;
}
else
{
/* New player */
/* New characters with same name fix by Salem's Lot */
if ( check_playing( d, ch->name ) )
return;
sprintf( buf, "Did I get that right, %s (Y/N)? ", argument );
write_to_buffer( d, buf, 0 );
d->connected = CON_CONFIRM_NEW_NAME;
return;
}
break;
case CON_GET_OLD_PASSWORD:
#if defined(unix)
write_to_buffer( d, "\n\r", 2 );
#endif
if ( strcmp( crypt( argument, ch->pcdata->pwd ), ch->pcdata->pwd ) )
{
write_to_buffer( d, "Wrong password.\n\r", 0 );
close_socket( d );
return;
}
write_to_buffer( d, echo_on_str, 0 );
if ( check_reconnect( d, ch->name, TRUE ) )
return;
if ( check_playing( d, ch->name ) )
return;
sprintf( log_buf, "%s@%s has connected.", ch->name, d->host );
log_string( log_buf );
lines = ch->pcdata->pagelen;
ch->pcdata->pagelen = 20;
if ( IS_HERO(ch) )
do_help( ch, "imotd" );
do_help( ch, "motd" );
ch->pcdata->pagelen = lines;
d->connected = CON_READ_MOTD;
break;
case CON_CONFIRM_NEW_NAME:
switch ( *argument )
{
case 'y': case 'Y':
sprintf( buf, "New character.\n\rGive me a password for %s: %s",
ch->name, echo_off_str );
write_to_buffer( d, buf, 0 );
d->connected = CON_GET_NEW_PASSWORD;
break;
case 'n': case 'N':
write_to_buffer( d, "Ok, what IS it, then? ", 0 );
free_char( d->character );
d->character = NULL;
d->connected = CON_GET_NAME;
break;
default:
write_to_buffer( d, "Please type Yes or No? ", 0 );
break;
}
break;
case CON_GET_NEW_PASSWORD:
#if defined(unix)
write_to_buffer( d, "\n\r", 2 );
#endif
if ( strlen(argument) < 5 )
{
write_to_buffer( d,
"Password must be at least five characters long.\n\rPassword: ",
0 );
return;
}
pwdnew = crypt( argument, ch->name );
for ( p = pwdnew; *p != '\0'; p++ )
{
if ( *p == '~' )
{
write_to_buffer( d,
"New password not acceptable, try again.\n\rPassword: ",
0 );
return;
}
}
free_string( ch->pcdata->pwd );
ch->pcdata->pwd = str_dup( pwdnew );
write_to_buffer( d, "Please retype password: ", 0 );
d->connected = CON_CONFIRM_NEW_PASSWORD;
break;
case CON_CONFIRM_NEW_PASSWORD:
#if defined(unix)
write_to_buffer( d, "\n\r", 2 );
#endif
if ( strcmp( crypt( argument, ch->pcdata->pwd ), ch->pcdata->pwd ) )
{
write_to_buffer( d, "Passwords don't match.\n\rRetype password: ",
0 );
d->connected = CON_GET_NEW_PASSWORD;
return;
}
write_to_buffer( d, echo_on_str, 0 );
write_to_buffer( d, "What is your sex (M/F/N)? ", 0 );
d->connected = CON_GET_NEW_SEX;
break;
case CON_GET_NEW_SEX:
switch ( argument[0] )
{
case 'm': case 'M': ch->sex = SEX_MALE; break;
case 'f': case 'F': ch->sex = SEX_FEMALE; break;
case 'n': case 'N': ch->sex = SEX_NEUTRAL; break;
default:
write_to_buffer( d, "That's not a sex.\n\rWhat IS your sex? ", 0 );
return;
}
strcpy( buf, "Select a class [" );
for ( iClass = 0; iClass < MAX_CLASS; iClass++ )
{
if ( iClass > 0 )
strcat( buf, " " );
strcat( buf, class_table[iClass].who_name );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -