⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wsckcomm.c

📁 MUD服务器程序
💻 C
📖 第 1 页 / 共 5 页
字号:
         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;
   }
   
        /* battle prompt */
        if ((victim = ch->fighting) != NULL)

          {
            int percent;
            char wound[100];
            char buf[MAX_STRING_LENGTH];
 
            write_to_buffer( d, "\n\r", 0);
                if (victim->max_hit > 0)
                percent = victim->hit * 100 / victim->max_hit;
            else
                percent = -1;
 
            if (percent >= 100)
                sprintf(wound,"is in excellent condition.");
            else if (percent >= 90)
                sprintf(wound,"has a few scratches.");
            else if (percent >= 75)
                sprintf(wound,"has some small wounds and bruises.");
            else if (percent >= 50)
                sprintf(wound,"has quite a few wounds.");
            else if (percent >= 30)
                sprintf(wound,"has some big nasty wounds and scratches.");
            else if (percent >= 15)
                sprintf(wound,"looks pretty hurt.");
            else if (percent >= 0)
                sprintf(wound,"is in awful condition.");
            else
                sprintf(wound,"is bleeding to death.");
 
            sprintf(buf,"%s %s \n\r",
                    IS_NPC(victim) ? victim->short_descr : victim->name,wound);
            buf[0] = UPPER(buf[0]);
            write_to_buffer( d, buf, 0);
          }

   write_to_buffer( ch->desc, buf, point - buf );
   return;
}

/* The heart of the pager.  Thanks to N'Atas-Ha, ThePrincedom
   for porting this SillyMud code for MERC 2.0 and laying down the groundwork.
   Thanks to Blackstar, hopper.cs.uiowa.edu 4000 for which
   the improvements to the pager was modeled from.  - Kahn */

void show_string(struct descriptor_data *d, char *input)
{
  char buffer[ MAX_STRING_LENGTH ];
  char buf[ MAX_INPUT_LENGTH ];
  register char *scan, *chk;
  int lines /*= 0*/, toggle=1;

  one_argument(input, buf);

  switch( UPPER( buf[0] ) )
  {
  case '\0':
  case 'C': /* show next page of text */
    lines = 0;
    break;

  case 'R': /* refresh current page of text */
    lines = - 1 - (d->character->pcdata->pagelen);
    break;

  case 'B': /* scroll back a page of text */
    lines = -(2*d->character->pcdata->pagelen);
    break;

  case 'H': /* Show some help */
    write_to_buffer( d,
        "C, or Return = continue, R = redraw this page,\n\r", 0 );
    write_to_buffer( d,
        "B = back one page, H = this help, Q or other keys = exit.\n\r\n\r",
		    0 );
    lines = - 1 - (d->character->pcdata->pagelen);
    break;

  default: /*otherwise, stop the text viewing */
    // @@@ Sands had some changes here that lead to double freeing
    if ( d->showstr_head )
    {
      free_string( d->showstr_head );
//      d->showstr_head = str_dup( "" );
      d->showstr_head = 0;
    }
//    free_string( d->showstr_point );
//    d->showstr_point = str_dup( "" );
    d->showstr_point = 0;
    return;

  }

  /* do any backing up necessary */
  if (lines < 0)
  {
    for ( scan = d->showstr_point; scan > d->showstr_head; scan-- )
         if ( ( *scan == '\n' ) || ( *scan == '\r' ) )
	 {
	     toggle = -toggle;
	     if ( toggle < 0 )
	         if ( !( ++lines ) )
		     break;
	 }
    d->showstr_point = scan;
  }

  /* show a chunk */
  lines  = 0;
  toggle = 1;
  for ( scan = buffer; ; scan++, d->showstr_point++ )
       if ( ( ( *scan = *d->showstr_point ) == '\n' || *scan == '\r' )
	   && ( toggle = -toggle ) < 0 )
	   lines++;
       else
	   if ( !*scan || ( d->character && !IS_NPC( d->character )
			  && lines >= d->character->pcdata->pagelen) )
	   {

	       *scan = '\0';
	       write_to_buffer( d, buffer, strlen( buffer ) );

	     /* See if this is the end (or near the end) of the string */
	       for ( chk = d->showstr_point; isspace( *chk ); chk++ );
	       if ( !*chk )
	       {
		   if ( d->showstr_head )
		   {
		      free_string( d->showstr_head );
		      d->showstr_head  = 0;
		   }
		   d->showstr_point = 0;
	       }
	       return;
	   }

//@@@  return;
}

SOCKET init_socket( int port )
{
   // Assume there aren't any sockets
//@@@   fSockets = FALSE;
    static struct sockaddr_in sa_zero;
    struct sockaddr_in sa;
    SOCKET newsock;
    int x = 1;

#if 0
   WORD wVersionRequested = MAKEWORD( 1, 1 );

   WSADATA wsaData;
   int err = WSAStartup( wVersionRequested, &wsaData );
   if ( err != 0 ) {
      MessageBox(0, "No useable WINSOCK.DLL, not loading sockets", "Serv",
         MB_ICONHAND|MB_OK);

      return INVALID_SOCKET;
      }

   /* Confirm that the Windows Sockets DLL supports 1.1.*/
   /* Note that if the DLL supports versions greater    */
   /* than 1.1 in addition to 1.1, it will still return */
   /* 1.1 in wVersion since that is the version we      */
   /* requested.                                        */

   if ( LOBYTE( wsaData.wVersion ) != 1 ||
         HIBYTE( wsaData.wVersion ) != 1 ) {
      /* Tell the user that we couldn't find a useable */
      /* winsock.dll.                                  */
      WSACleanup( );
      MessageBox(0, "Windows sockets version not 1.1, not loading sockets", "Serv",
         MB_ICONHAND|MB_OK);

      return INVALID_SOCKET;
      }

   /* Make sure that the version requested is >= 1.1.   */
   /* The low byte is the major version and the high    */
   /* byte is the minor version.                        */

   if ( LOBYTE( wVersionRequested ) < 1 ||
        ( LOBYTE( wVersionRequested ) == 1 &&
          HIBYTE( wVersionRequested ) < 1 )) {
      MessageBox(0, "Windows sockets version not 1.1, not loading sockets", "Serv",
         MB_ICONHAND|MB_OK);

       return INVALID_SOCKET;
   }

   /* Since we only support 1.1, set both wVersion and  */
   /* wHighVersion to 1.1.                              */

   wsaData.wVersion = MAKEWORD( 1, 1 );
   wsaData.wHighVersion = MAKEWORD( 1, 1 );
#endif
//   fSockets = TRUE;


    if ( ( newsock = socket( PF_INET, SOCK_STREAM, 0 ) ) == INVALID_SOCKET )
       {
	    MessageBox(0, "Init_socket: socket", __FILE__, MB_OK);
	    return INVALID_SOCKET;
       }

    if ( setsockopt( newsock, SOL_SOCKET, SO_REUSEADDR, (char *) &x, sizeof(x) )
             == SOCKET_ERROR )
       {
	    MessageBox(0, "Init_socket: SO_REUSEADDR", __FILE__, MB_OK);
       closesocket(newsock);
       return INVALID_SOCKET;
       }

#if 0
    {
   struct	linger	ld;

	ld.l_onoff  = 1;
	ld.l_linger = 1000;

	if ( setsockopt( fd, SOL_SOCKET, SO_DONTLINGER, (char *) &ld, sizeof(ld) ) < 0 )
	{
	    MessageBox(0, 0, "Init_socket: SO_DONTLINGER", __FILE__, MB_OK );
	    closesocket( fd );
	    return INVALID_SOCKET;
	}
    }
#endif

    sa		    = sa_zero;
    sa.sin_family   = AF_INET;
    sa.sin_port	    = htons( port );

    if ( bind( newsock, (struct sockaddr *) &sa, sizeof(sa) ) == SOCKET_ERROR )
    {
	MessageBox(0, "Init_socket: bind", __FILE__, MB_OK );
	closesocket( newsock );
	return INVALID_SOCKET;
    }

    if ( listen( newsock, 3 ) == SOCKET_ERROR )
    {
	MessageBox(0, "Init_socket: listen", __FILE__, MB_OK );
	closesocket( newsock );
	return INVALID_SOCKET;
    }

    return newsock;
}

LRESULT SocketAccept (WPARAM wParam, LPARAM lParam)
{
    static DESCRIPTOR_DATA d_zero;
      SOCKET	sSocket;
	   SOCKADDR_IN	saPeer;
	   int		iAddrSize;
//	   int		iError;
		char     buf[512];
         DESCRIPTOR_DATA *dnew;

	switch(WSAGETSELECTEVENT(lParam))
		{
      default:
         MessageBeep(-1);
         break;

		case FD_ACCEPT:
		   {
//			LPSOCKADDR_IN	lpsaHostAddr;
//         LPHOSTENT	   lpheHostEnt;

//      	struct sockaddr_in isa;
//      	int i = sizeof(isa);
//       	getsockname(s, &isa, &i);
         struct sockaddr_in sock;
         int size = sizeof(sock);

//         MessageBeep(-1);

			/* Get a pending accept */
			iAddrSize = sizeof(SOCKADDR_IN);
			sSocket = accept( control, (LPSOCKADDR) &saPeer, (LPINT) &iAddrSize );
			if ( sSocket == INVALID_SOCKET )
			   {
//            MessageBox(0, "Couldn't accept() connection.", "Serv",
//               MB_ICONHAND|MB_OK);
            log_string("Couldn't accept() connection");
				return FALSE;
			   }

         // Cons a new descriptor.
         if ( descriptor_free )
            {
            dnew = descriptor_free;
            descriptor_free = descriptor_free->next;
            dnew->descriptor = sSocket;
            }
         else
         	dnew = alloc_perm( sizeof(*dnew) );

         *dnew		= d_zero;
         dnew->descriptor	= sSocket;
         dnew->connected	= CON_GET_NAME;
         dnew->showstr_head  = NULL;
         dnew->showstr_point = NULL;
         dnew->outsize	= 2000;
         dnew->outbuf	= alloc_mem( dnew->outsize );
         dnew->host_and_name = alloc_mem( sizeof *dnew->host_and_name );
         strcpy(dnew->host_and_name->username, "<waiting>");

         if ( getpeername( sSocket, (struct sockaddr *) &sock, &size ) == SOCKET_ERROR )
            {
#if 1
            wsprintf(buf, "new_descriptor(): getpeername() == %d",
               WSAGetLastError());
            log_string( buf );
#else
            log_string("New_descriptor: getpeername");
#endif
         	dnew->host = str_dup( "(unknown)" );
            }
         else
            {
            int ulen = sizeof dnew->host_and_name->us;

            // Get the caller's machine in quad format
            u_long addr = ntohl( sock.sin_addr.s_addr );
            struct hostent *from;
            wsprintf( buf, "%d.%d.%d.%d",
               ( addr >> 24 ) & 0xFF, ( addr >> 16 ) & 0xFF,
               ( addr >>  8 ) & 0xFF, ( addr       ) & 0xFF);
            wsprintf( log_buf, "Sock.sinaddr:  %s", buf );
            log_string( log_buf );

            // Request the name of the caller's machine from DNS
            dnew->host = str_dup( buf );
            dnew->host_and_name->sin_addr = sock.sin_addr;
            dnew->host_and_name->hRequestHandle = WSAAsyncGetHostByAddr( hQryDlgBox,
               WM_NET_GETHOST, (LPSTR) &dnew->host_and_name->sin_addr, sizeof dnew->host_and_name->sin_addr,
               PF_INET, dnew->host_and_name->hostdata, sizeof dnew->host_and_name->hostdata);

            // Look up the local name for this socket
            if (getsockname(sSocket, (struct sockaddr *)&dnew->host_and_name->us, &ulen) ==
                                                                 SOCKET_ERROR)
               {
               wsprintf(dnew->host_and_name->username, "(getsockname)#%d", WSAGetLastError());
               goto failure;
               }

            // Create a socket to connect to the user's ident port
            if ((dnew->host_and_name->sAuth = socket(PF_INET, SOCK_STREAM, AF_UNSPEC)) ==
                                                               INVALID_SOCKET)
               {
               wsprintf(dnew->host_and_name->username, "(socket)#%d", WSAGetLastError());
               goto failure;
               }

            // Save the address of their side of the socket
            dnew->host_and_name->them = sock;

            // htons convers a u_short from host to network byte order. 113 is
            //  the auth socket
            dnew->host_and_name->authsock.sin_port = htons(113);
            // Use Internet protocol
            dnew->host_and_name->authsock.sin_family = AF_INET;
            // Look up the other end of our socket
            dnew->host_and_name->authsock.sin_addr = sock.sin_addr;

            WSAAsyncSelect(dnew->host_and_name->sAuth, hQryDlgBox, WM_NET_AUTHCONNECT,
               FD_CONNECT|FD_READ|FD_WRITE);
            if (connect(dnew->host_and_name->sAuth, (struct sockaddr *)&dnew->host_and_name->authsock,
                                       sizeof(dnew->host_and_name->authsock)) == SOCKET_ERROR)
               {
               int nError = WSAGetLastError();
               if (nError != WSAEWOULDBLOCK)
                  {
                  wsprintf(dnew->host_and_name->username, "(connect)#%d", nError);
                  goto failure;
                  }
               }

            }
failure:

         // Init descriptor data.
         dnew->next	= descriptor_list;
         descriptor_list = dnew;
         nPlayers++;

			// OK now get messages from this socket
         BlastedTrumpet(sSocket);

         // Send the greeting.
         {
      	extern char * help_greeting;
      	if ( help_greeting[0] == '.' )
     	    write_to_buffer( dnew, help_greeting+1, 0 );
      	else
   	    write_to_buffer( dnew, help_greeting  , 0 );
         }
		   } // FD_ACCEPT
		}

   return FALSE;
}

LRESULT SocketReadWrite (WPARAM wParam, LPARAM lParam)
{
	SOCKET	sSocket = (SOCKET) wParam;
//	SOCKADDR_IN	saPeer;
//	int		iAddrSize;
//	int		iError;
//   char     szBuffer[64];
//   int      len;

	switch(WSAGETSELECTEVENT(lParam))
    	{
      default:
         MessageBeep(-1);
         break;

		case FD_READ:	// WinSock has something for us
		   {
	      // Find the descriptor for this FD_READ
         DESCRIPTOR_DATA *d;
         for (d = descriptor_list; d; d = d_next )
            {
            d_next = d->next;

            if (d->descriptor == sSocket)
               {
               d->fcommand	= FALSE;

               if ( d->character != NULL )
                  d->character->timer = 0;

               if ( !read_from_descriptor( d ) )
            		{
//@@@Dunno what this does?                  FD_CLR( d->descriptor, 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -