📄 wsckcomm.c
字号:
{
if ( ( to->desc == NULL
&& ( IS_NPC( to ) && !(to->pIndexData->progtypes & ACT_PROG ) ) )
|| !IS_AWAKE(to) )
continue;
if ( type == TO_CHAR && to != ch )
continue;
if ( type == TO_VICT && ( to != vch || to == ch ) )
continue;
if ( type == TO_ROOM && to == ch )
continue;
if ( type == TO_NOTVICT && (to == ch || to == vch) )
continue;
point = buf;
str = format;
while ( *str != '\0' )
{
if ( *str != '$' )
{
*point++ = *str++;
continue;
}
++str;
if ( arg2 == NULL && *str >= 'A' && *str <= 'Z' )
{
bug( "Act: missing arg2 for code %d.", *str );
i = " <@@@> ";
}
else
{
switch ( *str )
{
default: bug( "Act: bad code %d.", *str );
i = " <@@@> "; break;
/* Thx alex for 't' idea */
case 't': i = (char *) arg1; break;
case 'T': i = (char *) arg2; break;
case 'n': i = PERS( ch, to ); break;
case 'N': i = PERS( vch, to ); break;
case 'e': i = he_she [URANGE(0, ch ->sex, 2)]; break;
case 'E': i = he_she [URANGE(0, vch ->sex, 2)]; break;
case 'm': i = him_her [URANGE(0, ch ->sex, 2)]; break;
case 'M': i = him_her [URANGE(0, vch ->sex, 2)]; break;
case 's': i = his_her [URANGE(0, ch ->sex, 2)]; break;
case 'S': i = his_her [URANGE(0, vch ->sex, 2)]; break;
case 'p':
i = can_see_obj( to, obj1 )
? obj1->short_descr
: "something";
break;
case 'P':
i = can_see_obj( to, obj2 )
? obj2->short_descr
: "something";
break;
case 'd':
if ( arg2 == NULL || ((char *) arg2)[0] == '\0' )
{
i = "door";
}
else
{
one_argument( (char *) arg2, fname );
i = fname;
}
break;
}
}
++str;
while ( ( *point = *i ) != '\0' )
++point, ++i;
}
*point++ = '\n';
*point++ = '\r';
// @@@ Following line added by Slash, to prevent bugs where stuff in the
// buffers fires mobprogs. Particularly bad when a player enters the game
// and gets the greet_prog over and over.
*point = '\0';
buf[0] = UPPER(buf[0]);
if (to->desc)
write_to_buffer( to->desc, buf, point - buf );
#ifdef MOBPROGS
if (MOBtrigger)
mprog_act_trigger( buf, to, ch, obj1, vch );
/* Added by Kahn */
#endif
}
#ifdef MOBPROGS
MOBtrigger = TRUE;
#endif
return;
}
/*
* Append onto an output buffer.
*/
void write_to_buffer( DESCRIPTOR_DATA *d, const char *txt, int length )
{
/* @@@ ECS */
if (d == 0)
return;
/*
* Find length in case caller didn't.
*/
if ( length <= 0 )
length = strlen(txt);
// @@@
// else if (length < strlen(txt))
// MessageBox(0, "Length Error", "Merc22Sv", MB_ICONHAND|MB_OK);
/*
* 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 );
#if 1 // @@@ Deal with too large a memory increment...
if (!outbuf)
{
length = d->outsize - d->outtop - 1;
break;
}
#endif
strncpy( outbuf, d->outbuf, d->outtop );
free_mem( d->outbuf, d->outsize );
d->outbuf = outbuf;
d->outsize *= 2;
}
/*
* Copy.
*/
//@@@ Ack! strcpy( d->outbuf + d->outtop, txt );
#if 1
if (length > 0)
{
#endif
memcpy(d->outbuf + d->outtop, txt, length);
d->outtop += length;
#if 1
}
#endif
#ifdef WIN32
// Tell Winsock to wake us when the socket becomes ready
if (!BlastedTrumpet(d->descriptor))
{
if ( d->character != NULL )
save_char_obj( d->character );
d->outtop = 0;
close_socket( d );
}
#endif
return;
}
void close_socket( DESCRIPTOR_DATA *dclose )
{
CHAR_DATA *ch;
if ( dclose->outtop > 0 )
process_output( dclose, FALSE );
if ( dclose->snoop_by != NULL )
{
write_to_buffer( dclose->snoop_by,
"Your victim has left the game.\n\r", 0 );
}
{
DESCRIPTOR_DATA *d;
for ( d = descriptor_list; d != NULL; d = d->next )
{
if ( d->snoop_by == dclose )
d->snoop_by = NULL;
}
}
if ( ( ch = dclose->character ) != NULL )
{
sprintf( log_buf, "Closing link to %s.", ch->name );
log_string( log_buf );
if ( dclose->connected == CON_PLAYING )
{
act( "$n has lost $s link.", ch, NULL, NULL, TO_ROOM );
ch->desc = NULL;
}
else
{
free_char( dclose->character );
}
}
if ( d_next == dclose )
d_next = d_next->next;
if ( dclose == descriptor_list )
{
descriptor_list = descriptor_list->next;
}
else
{
DESCRIPTOR_DATA *d;
for ( d = descriptor_list; d && d->next != dclose; d = d->next )
;
if ( d != NULL )
d->next = dclose->next;
else
bug( "Close_socket: dclose not found.", 0 );
}
closesocket( dclose->descriptor );
free_string( dclose->host );
dclose->next = descriptor_free;
descriptor_free = dclose;
nPlayers--;
return;
}
// Write_to_descriptor bypasses the whole buffered output system. Blech!
bool write_to_descriptor( int desc, char *txt, int length )
{
int iStart;
int nWrite;
int nBlock;
if ( length <= 0 )
length = strlen(txt);
for ( iStart = 0; iStart < length; iStart += nWrite )
{
nBlock = UMIN( length - iStart, 4096 );
// @@@ Should check WSAEWOULDBLOCK, and we don't want MessageBox...
if ( ( nWrite = send( desc, txt + iStart, nBlock, 0 ) ) == SOCKET_ERROR ||
nWrite != nBlock)
{
log_string( "Write_to_descriptor" );
return FALSE;
}
}
#ifdef WIN32
// Tell Winsock to wake us when the socket becomes ready
BlastedTrumpet(desc);
#endif
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 iRace;
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) < 3 )
{
write_to_buffer( d,
"Password must be at least three 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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -