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

📄 win32srv.c

📁 MUD服务器程序
💻 C
📖 第 1 页 / 共 3 页
字号:
#include <time.h>
#include <stdio.h>
#include <stdlib.h>

#include <windows.h>

#include "merc.h"
#include "merc-win.rh"

/*
 * Global variables.
 */
DESCRIPTOR_DATA *   descriptor_free;	/* Free list for descriptors	*/
DESCRIPTOR_DATA *   descriptor_list;	/* All open descriptors		*/
DESCRIPTOR_DATA *   d_next;		/* Next descriptor in loop	*/
FILE *		    fpReserve;		/* Reserved file handle		*/
bool		    god;		/* All new chars are gods!	*/
bool		    merc_down;		/* Shutdown			*/
bool		    wizlock;		/* Game is wizlocked		*/
char		    str_boot_time[MAX_INPUT_LENGTH];
time_t		    current_time;	/* Time of this pulse		*/

/*
 * Other local functions (OS-independent).
 */
bool	check_parse_name	args( ( char *name ) );
bool	check_reconnect		args( ( DESCRIPTOR_DATA *d, char *name,
				    bool fConn ) );
bool	check_playing		args( ( DESCRIPTOR_DATA *d, char *name ) );
int	main			args( ( int argc, char **argv ) );
void	nanny			args( ( DESCRIPTOR_DATA *d, char *argument ) );
bool	process_output		args( ( DESCRIPTOR_DATA *d, bool fPrompt ) );
void	read_from_buffer	args( ( DESCRIPTOR_DATA *d ) );
void	stop_idling		args( ( CHAR_DATA *ch ) );
void    bust_a_prompt           args( ( CHAR_DATA *ch ) );

const	char	echo_off_str	[] = { '\0' };
const	char	echo_on_str	[] = { '\0' };
const	char 	go_ahead_str	[] = { '\0' };
bool	write_to_descriptor	args( ( int desc, char *txt, int length ) );
void	send_to_char	args( ( const char *txt, CHAR_DATA *ch ) )
{
    if ( txt == NULL || ch->desc == NULL )
        return;
    ch->desc->showstr_head = alloc_mem( strlen( txt ) + 1 );
    strcpy( ch->desc->showstr_head, txt );
    ch->desc->showstr_point = ch->desc->showstr_head;
    show_string( ch->desc, "" );
}

void gettimeofday( struct timeval *tp, void *tzp )
{
    tp->tv_sec  = time( NULL );
    tp->tv_usec = 0;
}

bool read_from_descriptor( DESCRIPTOR_DATA *d )
{
    int iStart;

    /* Hold horses if pending command already. */
    if ( d->incomm[0] != '\0' )
	return TRUE;

    /* Check for overflow. */
    iStart = strlen(d->inbuf);
    if ( iStart >= sizeof(d->inbuf) - 10 )
    {
	sprintf( log_buf, "%s input overflow!", d->host );
	log_string( log_buf );
	write_to_descriptor( d->descriptor,
	    "\n\r*** PUT A LID ON IT!!! ***\n\r", 0 );
	return FALSE;
    }

#if 0
    /* Snarf input. */
    for ( ; ; )
    {
	int c;
	c = getc( stdin );
	if ( c == '\0' || c == EOF )
	    break;
	putc( c, stdout );
	if ( c == '\r' )
	    putc( '\n', stdout );
	d->inbuf[iStart++] = c;
	if ( iStart > sizeof(d->inbuf) - 10 )
	    break;
    }
#else
    if (fUserReady)
       {
       int nLen = strlen(UserMessage);
       fUserReady = FALSE;
       if (iStart + nLen <= sizeof d->inbuf - 10)
          {
          memcpy(d->inbuf + iStart, UserMessage, nLen);
          iStart += nLen;
          d->inbuf[iStart++] = '\r';
          }
       }
#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;
}

void CloseMerc(void)
{
}

HINSTANCE hInst;
HWND      hQryDlgBox;                         // handle of modeless dialog box
HWND      hWndMain;
HWND      hWndOutput;
char      UserMessage[512];
BOOL      fUserReady;

LRESULT CALLBACK _export MercWndProc(HWND hWnd, UINT message,
                             WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
        case WM_MOVE:
            // Move the dialog box on top of our main window every
            // time the main window moves.
            if (IsWindow(hQryDlgBox))
                SendMessage(hQryDlgBox, message, wParam, lParam);
            break;

        case WM_SETFOCUS:
            // Always set the input focus to the dialog box.
            if (IsWindow(hQryDlgBox))
                SendMessage(hQryDlgBox, message, wParam, lParam);
            break;

        case WM_CLOSE:
            // Tell windows to destroy our window.
            DestroyWindow(hWnd);
            break;

        case WM_QUERYENDSESSION:
            // If we return TRUE we are saying it's ok with us to end the
				// windows session.
            return((long) TRUE);  // we agree to end session.

        case WM_ENDSESSION:
            // If wParam is not zero, it meany every application said ok
            // to WM_QUERYENDSESSION messages, so we are really ending.
            if (wParam)           // if all apps aggreed to end session.
                CloseMerc();     // This is the end. We will not get a
                                   // WM_DESTROY message on end session.
            break;

        case WM_DESTROY:
            // This is the end if we were closed by a DestroyWindow call.

            CloseMerc();
				PostQuitMessage(0);
            break;

        default:
            if (message == uMercOpen)
               new_descriptor( (HWND) wParam )
            else if (message == uMercClose)
               MessageBox(hWnd, "Somebody went down", "MercServ", MB_OK);
//            else if (message == uMercSend)
//               @@@
            else
               return(DefWindowProc(hWnd, message, wParam, lParam));

            break;
    }

    return(0L);
}

#if 0
BOOL CALLBACK _export MercDlgProc(HWND hDlg, UINT message,
                           WPARAM wParam, LPARAM lParam)
{
    static RECT   wrect;

    int           x, y, w, h, i;
    long          rc;
//    char         *cp, *cpd, tmp[30], sdrives[30];
//    HANDLE        hCursor;
    HWND hWndInput;

    switch (message)
    {
        case WM_INITDIALOG:
            // Save the handle of this proc for use by main window proc.
            hQryDlgBox = hDlg;

            // Save the handle to the output window
            hWndOutput = GetDlgItem(hDlg, 102);
            SetFocus(GetDlgItem(hDlg, 101));

            // Get position of dialog box window.
            GetWindowRect(hDlg, (LPRECT) &wrect);
            w = wrect.right - wrect.left;
            h = wrect.bottom - wrect.top;

            // Move main application window to same position.
            SetWindowPos(hWndMain, hDlg,
                         wrect.left, wrect.top, w, h,
                         0);
            break;

        case WM_MOVE:
            // Always keep this dialog box on top of main window.
            GetWindowRect(hWndMain, (LPRECT) &wrect);
            x = wrect.left;
            y = wrect.top;
            w = wrect.right - wrect.left;
            h = wrect.bottom - wrect.top;
            MoveWindow(hDlg, x, y, w, h, 1);
            break;

        case WM_SYSCOMMAND:
            // Pass WM_SYSCOMMAND messages on to main window so both
            // main window and dialog box get iconized, minimized etc.
            // in parallel.
            SendMessage(hWndMain, message, wParam, lParam);
            break;

        case WM_COMMAND:
            switch (LOWORD(wParam))
            {
                case IDOK:
                    hWndInput = GetDlgItem(hDlg, 101);
                    SendMessage(hWndInput, WM_GETTEXT, sizeof UserMessage, (LPARAM) UserMessage);
                    SendMessage(hWndInput, WM_SETTEXT, 0, (LPARAM) "");
                    SetFocus(hWndInput);
                    fUserReady = TRUE;
                    break;

                case IDCANCEL:                  // Cancel button
                    // Tell main application window we want to quit.
                    SendMessage(hWndMain, WM_CLOSE, 0, 0L);
                    break;

                default:
                    break;
            }
            break;

        case WM_CLOSE:
            // Unlock dialog resource we locked above.

            // Zero handle to this dialog window.
            hQryDlgBox = 0;

            // Tell main window to close.
            PostMessage(hWndMain, WM_CLOSE, 0, 0L);

            // Destroy ourseleves.
            DestroyWindow(hDlg);
            break;

        default:
            return FALSE;
    }

    return(TRUE);
}
#endif

void InitMerc22(HINSTANCE hInstance, int cmdShow)
{
    WNDCLASS wcMercClass;

    // Define the window class for this application.
    wcMercClass.lpszClassName = "Merc22";
    wcMercClass.hInstance     = hInstance;
    wcMercClass.lpfnWndProc   = MercWndProc;
    wcMercClass.hCursor       = LoadCursor(NULL, IDC_ARROW);
//    wcMercClass.hIcon         = LoadIcon(hInstance, SetUpData.szAppName);
    wcMercClass.hIcon         = 0;
    wcMercClass.lpszMenuName  = (LPSTR) NULL;
    wcMercClass.hbrBackground = GetStockObject(WHITE_BRUSH);
    wcMercClass.style         = CS_HREDRAW | CS_VREDRAW;
    wcMercClass.cbClsExtra    = 0;
    wcMercClass.cbWndExtra    = 0;

    // Register the class
    if (RegisterClass(&wcMercClass) == 0)
       {
       MessageBox(0, "Could not create Window", "@@@", MB_ICONHAND|MB_OK);
       exit(1);
       }

    hInst = hInstance;       // save for use by window procs

    // Create applications main window.
    hWndMain = CreateWindow(
                  "Merc22",
                  "Welcome to Merc22/Win32",
                    WS_BORDER |
                    WS_CAPTION |
                    WS_SYSMENU |
                    WS_MINIMIZEBOX,
                  10,
                  19,
                  256,
                  123,
                  NULL,
                  NULL,
                  hInstance,
                  NULL
                  );

    CreateDialog(hInst, MAKEINTRESOURCE(1), hWndMain, (DLGPROC) MercDlgProc);
    ShowWindow(hWndMain, cmdShow);
    UpdateWindow(hWndMain);
}

void new_descriptor( HWND hWnd )
{
    static DESCRIPTOR_DATA d_zero;
    char buf[MAX_STRING_LENGTH];
    DESCRIPTOR_DATA *dnew;
    BAN_DATA *pban;
    struct sockaddr_in sock;
    struct hostent *from;
//    int desc;
    int size;

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

    *dnew		= d_zero;
    dnew->descriptor	= (sh_int) hWnd;
    dnew->connected	= CON_GET_NAME;
    dnew->showstr_head  = NULL;
    dnew->showstr_point = NULL;
    dnew->outsize	= 2000;
    dnew->outbuf	= alloc_mem( dnew->outsize );

   sprintf(buf, "HWND: 0x%x", hWnd);
	dnew->host = str_dup( buf );

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

    /*
     * 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 );
    }

    return;
}

WPARAM game_loop_win32(HINSTANCE hInstance, HINSTANCE hPrevInstance, int nCmdShow)
{
    struct timeval last_time;
    struct timeval now_time;
    static DESCRIPTOR_DATA dcon;
    DESCRIPTOR_DATA *d;
    MSG   msg;
//    DWORD dwTick = -1;
    BOOL  fBackground;

    gettimeofday( &last_time, NULL );
    current_time = (time_t) last_time.tv_sec;

#if 0
    /*
     * New_descriptor analogue.
     */
    dcon.descriptor	= 0;
    dcon.connected	= CON_GET_NAME;
    dcon.host		= str_dup( "localhost" );
    dcon.outsize	= 2000;
    dcon.outbuf		= alloc_mem( dcon.outsize );
    dcon.next		= descriptor_list;
    descriptor_list	= &dcon;

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

    /* Main loop */
#if 1

    // Go init this application.
    InitMerc22(hInstance, nCmdShow);

    // Get and dispatch messages for this applicaton.
    fBackground = FALSE;
    for ( ;; )
       {
       if (PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE))
          {
          if (msg.message == WM_QUIT)
             break;

          if (!IsDialogMessage(hQryDlgBox, &msg))
             {
             TranslateMessage(&msg);
             DispatchMessage(&msg);
             }
          }
       else if (/*GetTickCount() > dwTick + 1000 &&*/ !fBackground)
          {
          fBackground++;
//          dwTick = GetTickCount();

	/*
	 * Process input.
	 */
	for ( d = descriptor_list; d != NULL; d = d_next )
	{
       if (PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE))
          {
          if (msg.message == WM_QUIT)
             goto merc_done;

          if (!IsDialogMessage(hQryDlgBox, &msg))
             {
             TranslateMessage(&msg);
             DispatchMessage(&msg);
             }
          }

	    d_next	= d->next;
	    d->fcommand	= FALSE;

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

      // Did the user break connection?
		if ( !read_from_descriptor( d ) )
		{
		    if ( d->character != NULL )
			save_char_obj( d->character );
		    d->outtop	= 0;
		    close_socket( d );
		    continue;
		}

	    if ( d->character != NULL && d->character->wait > 0 )
	    {
		--d->character->wait;
		continue;
	    }

	    read_from_buffer( d );
	    if ( d->incomm[0] != '\0' )
	    {
		d->fcommand	= TRUE;
		stop_idling( d->character );

		if ( d->connected == CON_PLAYING )
		    if ( d->showstr_point )
		        show_string( d, d->incomm );
		    else
		        interpret( d->character, d->incomm );
		else
		    nanny( d, d->incomm );

		d->incomm[0]	= '\0';
	    }
	}



	/*
	 * Autonomous game motion.
	 */
	update_handler( );



	/*
	 * Output.
	 */
	for ( d = descriptor_list; d != NULL; d = d_next )
	{
	    d_next = d->next;

	    if ( ( d->fcommand || d->outtop > 0 ) )
	    {
		if ( !process_output( d, TRUE ) )
		{
		    if ( d->character != NULL )
			save_char_obj( d->character );
		    d->outtop	= 0;
		    close_socket( d );
		}
	    }
	}



	/*
	 * Synchronize to a clock.
	 * Busy wait (blargh).
	 */
	now_time = last_time;
	for ( ; ; )
	{
	    int delta;

	    {
		if ( dcon.character != NULL )
		    dcon.character->timer = 0;
		if ( !read_from_descriptor( &dcon ) )
		{
		    if ( dcon.character != NULL )
			save_char_obj( d->character );
		    dcon.outtop	= 0;
		    close_socket( &dcon );

⌨️ 快捷键说明

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