📄 chwconn.cpp
字号:
/*----------------------------------------------------------------------------
_ _ _
/\ | | | (_)
/ \ _ __ __| |_ __ ___ _ __ ___ ___ __| |_ __ _
/ /\ \ | '_ \ / _` | '__/ _ \| '_ ` _ \ / _ \/ _` | |/ _` |
/ ____ \| | | | (_| | | | (_) | | | | | | __/ (_| | | (_| |
/_/ \_\_| |_|\__,_|_| \___/|_| |_| |_|\___|\__,_|_|\__,_|
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 + -