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

📄 chwconn.cpp

📁 Windows上的MUD客户端程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*----------------------------------------------------------------------------
                        _                              _ _       
        /\             | |                            | (_)      
       /  \   _ __   __| |_ __ ___  _ __ ___   ___  __| |_  __ _ 
      / /\ \ | '_ \ / _` | '__/ _ \| '_ ` _ \ / _ \/ _` | |/ _` |
     / ____ \| | | | (_| | | | (_) | | | | | |  __/ (_| | | (_| |
    /_/    \_\_| |_|\__,_|_|  \___/|_| |_| |_|\___|\__,_|_|\__,_|

    The contents of this file are subject to the Andromedia Public
	License Version 1.0 (the "License"); you may not use this file
	except in compliance with the License. You may obtain a copy of
	the License at http://www.andromedia.com/APL/

    Software distributed under the License is distributed on an
	"AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
	implied. See the License for the specific language governing
	rights and limitations under the License.

    The Original Code is Pueblo client code, released November 4, 1998.

    The Initial Developer of the Original Code is Andromedia Incorporated.
	Portions created by Andromedia are Copyright (C) 1998 Andromedia
	Incorporated.  All Rights Reserved.

	Andromedia Incorporated                         415.365.6700
	818 Mission Street - 2nd Floor                  415.365.6701 fax
	San Francisco, CA 94103

    Contributor(s):
	--------------------------------------------------------------------------
	   Chaco team:  Dan Greening, Glenn Crocker, Jim Doubek,
	                Coyote Lussier, Pritham Shetty.

					Wrote and designed original codebase.

------------------------------------------------------------------------------

	Defines the ChWorld module for the Pueblo system.  This module is
	used to connect to external virtual worlds.

----------------------------------------------------------------------------*/

// $Header: /home/cvs/chaco/modules/client/msw/ChWorld/ChWConn.cpp,v 2.69 1996/09/12 19:10:09 pritham Exp $

#include "headers.h"

#include <fstream.h>
#include <ctype.h>

#include <ChCore.h>
#include <ChReg.h>
#include <ChHtmWnd.h>

#include <ChSound.h>

#include "World.h"
#include "ChWConn.h"
#if !defined(CH_PUEBLO_PLUGIN)
#include "resource.h"
#else
#include "vwrres.h"
#endif


/*----------------------------------------------------------------------------
	Constants
----------------------------------------------------------------------------*/

#define MAX_LINE_LEN		4096			/* If a line is longer than 4k,
												then give up looking for a
												line ending */
#define ESCAPE				0x1b
#define ANSI_START_1		ESCAPE
#define ANSI_START_2		'['
#define ANSI_SEPARATOR		';'
#define ANSI_END			"m\n\r\0x1b"	// One of these ends sequence
#define ANSI_MODE			'm'
#define ANSI_ERASE			'j'
											/* Telnet commands:
												(from RFC 854:  Telnet protocol
																spec.) */
#define TN_EOR				239				// End-Of-Record
#define TN_SE				240				// End of subnegotiation params
#define TN_NOP				241				// not used
#define TN_DATA_MARK		242				// not used
#define TN_BRK				243				// not used
#define TN_IP				244				// not used
#define TN_AO				245				// not used
#define TN_AYT				246				// not used
#define TN_EC				247				// not used
#define TN_EL				248				// not used
#define TN_GA				249				// Go Ahead
#define TN_SB				250				/* Indicates that what follows is
												subnegotiation of the indicated
                                 				option */
#define TN_WILL				251				// I offer to ~, or ack for DO
#define TN_WONT				252				// I will stop ~ing, or nack for DO
#define TN_DO				253				// Please do ~?, or ack for WILL
#define TN_DONT				254				// Stop ~ing!, or nack for WILL
#define TN_IAC				255				// Is A Command character

											// Telnet options:

#define TN_ECHO				1				// echo option
#define TN_SGA				3				// suppress GOAHEAD option
#define TN_STATUS			5				// not used
#define TN_TIMING_MARK		6				// not used
#define TN_TERMINAL_TYPE	24				// terminal type option
#define TN_EOR_OPT			25				// End Of Record option
#define TN_NAWS				31				// not used
#define TN_TSPEED			32				// not used
#define TN_LINEMODE			34				// not used

											// Other Telnet codes:
#define TN_IS				0
#define TN_SEND				1


/*----------------------------------------------------------------------------
	Types
----------------------------------------------------------------------------*/

typedef enum { betweenSequences, foundIAC, foundModifier } TelnetState;


/*----------------------------------------------------------------------------
	Static arrays
----------------------------------------------------------------------------*/

#if defined( DUMP_TELNET_CODES )

static const char*	pstrTelnetLabel[256];

#endif	// defined( CH_DEBUG )


/*----------------------------------------------------------------------------
	ChBufferString class
----------------------------------------------------------------------------*/

ChBufferString::ChBufferString() :
					m_iBufferSize( initBufferStringSize ),
					m_iActualSize( 0 )
{
	m_pstrBuffer = m_string.GetBuffer( m_iBufferSize );
	m_pstrBufferEnd = m_pstrBuffer;
}


ChBufferString::ChBufferString( const string& strData )
{
	m_iActualSize = strData.GetLength();
	m_iBufferSize = m_iActualSize + growBufferStringSize;
	m_pstrBuffer = m_string.GetBuffer( m_iBufferSize );
	m_pstrBufferEnd = m_pstrBuffer + m_iActualSize;
}


ChBufferString::~ChBufferString()
{
}


ChBufferString& ChBufferString::operator +=( char cChar )
{
	if (m_iActualSize >= m_iBufferSize)
	{
		m_string.ReleaseBuffer( m_iActualSize );

											/* We need to reallocate the
												string to make room for the
												new data */

		m_iBufferSize = m_iActualSize + growBufferStringSize;

											// Get new pointers

		m_pstrBuffer = m_string.GetBuffer( m_iBufferSize );
		m_pstrBufferEnd = m_pstrBuffer + m_iActualSize;
	}

	*m_pstrBufferEnd = cChar;
	m_pstrBufferEnd++;
	*m_pstrBufferEnd = 0;
	m_iActualSize++;

	return *this;
}


ChBufferString& ChBufferString::operator +=( const char* pstrText )
{
	int		iLen = strlen( pstrText );

	if (m_iActualSize + iLen >= m_iBufferSize)
	{										/* We need to reallocate the
												string to make room for the
												new data */
		m_string.ReleaseBuffer( m_iActualSize );

											/* We need to reallocate the
												string to make room for the
												new data */

		m_iBufferSize = m_iActualSize + growBufferStringSize;

											// Get new pointers

		m_pstrBuffer = m_string.GetBuffer( m_iBufferSize );
		m_pstrBufferEnd = m_pstrBuffer + m_iActualSize;
	}

	strncpy( m_pstrBufferEnd, pstrText, iLen );
	m_pstrBufferEnd += iLen;
	m_iActualSize += iLen;
	*m_pstrBufferEnd = 0;

	return *this;
}


/*----------------------------------------------------------------------------
	ChAnsiState class
----------------------------------------------------------------------------*/

ChAnsiState::ChAnsiState() :
				m_boolAnsiBold( false ),
				m_boolAnsiUnderline( false ),
				m_boolAnsiItalic( false ),
				m_boolAnsiColor( false ),
				m_luForeColor( constDefColor ),
				m_luBackColor( constDefColor )
{
}


void ChAnsiState::Reset( string& strHTML )
{
	if (m_boolAnsiBold)
	{
		strHTML += "</b>";
		m_boolAnsiBold = false;
	}

	if (m_boolAnsiUnderline)
	{
		strHTML += "</u>";
		m_boolAnsiUnderline = false;
	}

	if (m_boolAnsiItalic)
	{
		strHTML += "</i>";
		m_boolAnsiItalic = false;
	}

	if (m_boolAnsiColor)
	{
		strHTML += "</font>";
		m_boolAnsiColor = false;
	}
											/* ANSI reset sets the terminal to
												white-on-black */
	strHTML += "<body bgcolor=#000000>\n";
	SetBackColor( COLOR_BLACK, strHTML );
	SetForeColor( COLOR_WHITE, strHTML );
}


void ChAnsiState::SetBold( bool boolBold, string& strHTML )
{
	if (boolBold && !m_boolAnsiBold)
	{
		strHTML += "<b>";
		m_boolAnsiBold = true;
	}
	else if (!boolBold && m_boolAnsiBold)
	{
		strHTML += "</b>";
		m_boolAnsiBold = false;
	}
}


void ChAnsiState::SetUnderline( bool boolUnderline, string& strHTML )
{
	if (boolUnderline && !m_boolAnsiUnderline)
	{
		strHTML += "<u>";
		m_boolAnsiUnderline = true;
	}
	else if (!boolUnderline && m_boolAnsiUnderline)
	{
		strHTML += "</u>";
		m_boolAnsiUnderline = false;
	}
}


void ChAnsiState::SetItalic( bool boolItalic, string& strHTML )
{
	if (boolItalic && !m_boolAnsiItalic)
	{
		strHTML += "<i>";
		m_boolAnsiItalic = true;
	}
	else if (!boolItalic && m_boolAnsiItalic)
	{
		strHTML += "</i>";
		m_boolAnsiItalic = false;
	}
}


void ChAnsiState::SetForeColor( chuint32 luColor, string& strHTML )
{
	m_luForeColor = luColor;
	SetColor( m_luForeColor, m_luBackColor, strHTML );
}


void ChAnsiState::SetBackColor( chuint32 luColor, string& strHTML )
{
	m_luBackColor = luColor;
	SetColor( m_luForeColor, m_luBackColor, strHTML );
}


void ChAnsiState::SetColor( chuint32 luForeColor, chuint32 luBackColor,
							string& strHTML )
{
	string		strTemp;

	if (m_boolAnsiColor)
	{
		strHTML += "</font>";
		m_boolAnsiColor = false;
	}

	if ((luForeColor != constDefColor) || (luBackColor != constDefColor))
	{
		string		strForeHTML;
		string		strBackHTML;

		if (luForeColor != constDefColor)
		{
			strForeHTML.Format( " fgcolor=\"#%6.6lX\"", luForeColor );
		}

		if (luBackColor != constDefColor)
		{
			strBackHTML.Format( " bgcolor=\"#%6.6lX\"", luBackColor );
		}

		strHTML += "<font" + strForeHTML + strBackHTML + ">";
		m_boolAnsiColor = true;
	}
}


/*----------------------------------------------------------------------------
	ChWorldConn class
----------------------------------------------------------------------------*/

ChWorldConn::ChWorldConn( const ChModuleID& idModule,
							ChSocketHandler pHandler,
							ChWorldMainInfo* pMainInfo, chparam userData ) :
				ChConn( pHandler, userData ),
				m_idModule( idModule ),
				m_pMainInfo( pMainInfo ),
				m_state( stateNotConnected ),
				m_textMode( modeText ),
				m_boolRawMode( false ),
				m_boolPuebloEnhanced( false ),
				m_boolTextReceived( false ),
				m_boolAnsiResetReceived( false ),
				m_flTelnetState( telnetStateEcho ),
				m_parseState( parseStateScanning )
{
	UpdatePreferences();
											// Cache text out object

	m_pTextOutput = GetMainInfo()->GetTextOutput();

	#if defined( DUMP_TELNET_CODES )
	{
		int		iLoop;

	    for (iLoop = 0; iLoop < 256; iLoop++)
	    {
	    	pstrTelnetLabel[iLoop] = 0;
		}

		pstrTelnetLabel[TN_ECHO]			= "ECHO";
		pstrTelnetLabel[TN_SGA]				= "SGA";
		pstrTelnetLabel[TN_STATUS]			= "STATUS";
		pstrTelnetLabel[TN_TIMING_MARK]		= "TIMING_MARK";
		pstrTelnetLabel[TN_TERMINAL_TYPE]	= "TERMINAL_TYPE";
		pstrTelnetLabel[TN_EOR_OPT]			= "EOR_OPT";
		pstrTelnetLabel[TN_NAWS]			= "NAWS";
		pstrTelnetLabel[TN_TSPEED]			= "TSPEED";
		pstrTelnetLabel[TN_LINEMODE]		= "LINEMODE";
		pstrTelnetLabel[TN_EOR]				= "EOR";
		pstrTelnetLabel[TN_SE]				= "SE";
		pstrTelnetLabel[TN_NOP]				= "NOP";
		pstrTelnetLabel[TN_DATA_MARK]		= "DATA_MARK";
		pstrTelnetLabel[TN_BRK]				= "BRK";
		pstrTelnetLabel[TN_IP]				= "IP";
		pstrTelnetLabel[TN_AO]				= "AO";
		pstrTelnetLabel[TN_AYT]				= "AYT";
		pstrTelnetLabel[TN_EC]				= "EC";
		pstrTelnetLabel[TN_EL]				= "EL";
		pstrTelnetLabel[TN_GA]				= "GA";
		pstrTelnetLabel[TN_SB]				= "SB";
		pstrTelnetLabel[TN_WILL]			= "WILL";
		pstrTelnetLabel[TN_WONT]			= "WONT";
		pstrTelnetLabel[TN_DO]				= "DO";
		pstrTelnetLabel[TN_DONT]			= "DONT";
		pstrTelnetLabel[TN_IAC]				= "IAC";
	}
	#endif	// defined( CH_DEBUG )
}


ChWorldConn::~ChWorldConn()
{
	if (IsConnected())
	{
		TermConnection();
	}
}


void ChWorldConn::AsyncGetHostByName( const string& strHost,
										ChSocketAsyncHandler pprocHandler,
										chparam userData )
{
	GetChacoSocket()->AsyncGetHostByName( strHost, pprocHandler,
											userData );
}


void ChWorldConn::Connect( const string& strHost, chint16 sPort )
{
	ASSERT( this );
											/* Set flag to indicate that we've
												not yet received any data */
	SetMode( modeText );
											// Start async connect
	SOCKSconnect( strHost, sPort );
}


void ChWorldConn::Connect( chuint32 luAddress, chint16 sPort )
{
										// luAddress is in host order
	ASSERT( this );
										/* Set flag to indicate that we've
											not yet received any data */
	SetMode( modeText );
										// Start async connect

	SOCKSconnect( luAddress, sPort );
}


void ChWorldConn::ProcessOutput()
{											/* Send incoming text to the text
												output module */
	chuint32	luLen;

	ASSERT( this );

	if ((luLen = GetBytesAvailable()) > 0)
	{
		char*	pstrBuffer;
		int		iLen;
		string	strOut;

		if (luLen > INT_MAX)
		{
			iLen = INT_MAX;
		}
		else
		{
			iLen = (int)luLen;
		}
											/* Read the contents of the socket
												to the end of 'inputbuf' */

		pstrBuffer = strOut.GetBufferSetLength( iLen + 1 );

⌨️ 快捷键说明

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