📄 chwconn.cpp
字号:
read( pstrBuffer, iLen );
strOut.ReleaseBuffer( iLen );
ASSERT( strOut.GetLength() == iLen );
ParseText( strOut, (GetMode() == modeHtml) );
// Display the text
OutputBuffer( strOut );
if (!IsAnyTextReceived())
{
SetAnyTextReceived();
GetMainInfo()->DoAutoLogin();
}
}
}
void ChWorldConn::InitConnection()
{
string strOut;
m_state = stateConnected;
/* Make the default text output
mode HTML, rather than <pre> */
strOut = "<html>";
/* Indicate that we will be using
preformatted text */
TurnHtmlOff( strOut );
OutputBuffer( strOut, false );
}
void ChWorldConn::TermConnection()
{
if (IsConnected())
{
string strOut;
m_state = stateNotConnected;
TurnHtmlOn( strOut );
/* Indicating that we are finished
using preformatted text */
OutputBuffer( strOut );
}
}
void ChWorldConn::SendWorldCommand( const string& strCommand,
bool boolUserCommand )
{
SendLine( strCommand );
if (boolUserCommand)
{
EchoState echo = GetMainInfo()->GetEchoState();
if (m_boolEcho && (echoOn == echo))
{
string strCommandOut( strCommand );
string strOut;
TurnHtmlOn( strOut );
if (m_boolBold)
{
strOut += "<b>";
}
if (m_boolItalic)
{
strOut += "<i>";
}
/* Append the users' text to the
output buffer */
Display( strOut, strCommandOut );
if (m_boolItalic)
{
strOut += "</i>";
}
if (m_boolBold)
{
strOut += "</b>";
}
strOut += "<br>";
TurnHtmlOff( strOut );
OutputBuffer( strOut, false );
}
else if (m_boolEcho && (echoOn != echo))
{ // Just send a line break
OutputBuffer( "\n" );
}
}
}
void ChWorldConn::Display( const string& strText )
{
string strOut;
TurnHtmlOn( strOut );
strOut += "<b>";
Display( strOut, strText );
strOut += "</b><br>";
TurnHtmlOff( strOut );
OutputBuffer( strOut, false );
}
void ChWorldConn::Display( string& strOut, const string& strText )
{
string strTextOut( strText );
chuint32 luBackColor = m_ansiState.GetBackColor();
chuint32 luForeColor = GetTextOutput()->GetDefForeColor();
string strColor;
if (luForeColor == luBackColor)
{
luForeColor = (~luForeColor) & 0xffffff;
}
strColor.Format( "#%06lx", luForeColor );
strOut += "<font text=\"" + strColor + "\">";
/* Strip out HTML from the users'
text and append it to the
output buffer */
ChHtmlWnd::EscapeForHTML( strTextOut );
strOut += strTextOut;
strOut += "</font>";
}
void ChWorldConn::UpdatePreferences()
{
ChRegistry worldPrefsReg( WORLD_PREFS_GROUP );
worldPrefsReg.ReadBool( WORLD_PREFS_ECHO, m_boolEcho, true );
worldPrefsReg.ReadBool( WORLD_PREFS_ECHO_BOLD, m_boolBold, true );
worldPrefsReg.ReadBool( WORLD_PREFS_ECHO_ITALIC, m_boolItalic, false );
}
/*----------------------------------------------------------------------------
ChWorldConn protected methods
----------------------------------------------------------------------------*/
void ChWorldConn::ParseText( string& strText, bool boolNewlinesToBreaks )
{
string strWorking;
const char* pstrOriginText;
int iStartOfLine = 0;
ChBufferString strParsedBuffer;
pstrOriginText = strText;
while (*pstrOriginText)
{
bool boolMoveToNextChar = true;
switch (m_parseState)
{
case parseStateScanning:
{
switch( (unsigned char)*pstrOriginText )
{
case ESCAPE:
{
m_parseState = parseStateEscape;
break;
}
case TN_IAC: // 0xff
{
m_parseState = parseTelnetIAC;
break;
}
case '\n':
{
if (*(pstrOriginText + 1) == '\r')
{
pstrOriginText++;
}
ParseEndOfLine( strParsedBuffer, iStartOfLine, true );
// Append a newline or <br>
if (boolNewlinesToBreaks)
{
strParsedBuffer += "<br>";
}
else
{
strParsedBuffer += '\n';
}
iStartOfLine = strParsedBuffer.GetLength();
break;
}
case '\r':
{
if (*(pstrOriginText + 1) == '\n')
{
pstrOriginText++;
}
ParseEndOfLine( strParsedBuffer, iStartOfLine, true );
// Append a newline or <br>
if (boolNewlinesToBreaks)
{
strParsedBuffer += "<br>";
}
else
{
strParsedBuffer += '\n';
}
iStartOfLine = strParsedBuffer.GetLength();
break;
}
default:
{
if (isprint( *pstrOriginText ) || ('\t' == *pstrOriginText))
{
strParsedBuffer += *pstrOriginText;
}
break;
}
}
break;
}
case parseStateEscape:
{
switch( *pstrOriginText )
{
case '[':
{
m_parseState = parseStateAnsi;
break;
}
default:
{
strParsedBuffer += ESCAPE;
strParsedBuffer += *pstrOriginText;
/* Set the state back to being
between sequences */
m_parseState = parseStateScanning;
break;
}
}
break;
}
case parseStateAnsi:
{
bool boolEndOfPacket;
ASSERT( *pstrOriginText );
/* Search for the end of the ANSI
sequence (which may contain
digits or semi-colons) */
while ((ANSI_SEPARATOR == *pstrOriginText) ||
isdigit( *pstrOriginText ))
{
m_strAnsiSequence += *pstrOriginText;
pstrOriginText++;
}
/* Figure out if we've hit the end
of the packet before
encountering the end of the
ANSI sequence */
boolEndOfPacket = (0 == *pstrOriginText);
if (!boolEndOfPacket)
{ /* Move to processing the ANSI
terminating character */
m_parseState = parseStateAnsiTerm;
}
boolMoveToNextChar = false;
break;
}
case parseStateAnsiTerm:
{
char cTerm = *pstrOriginText;
bool boolValidSequence = true;
if (cTerm == '\n' || cTerm == '\r' || cTerm == ESCAPE)
{
/* Don't strip off newline or
ESCAPE terms */
boolMoveToNextChar = false;
boolValidSequence = false;
}
else if (m_strAnsiSequence.IsEmpty())
{
#if defined( DUMP_ANSI_CODES )
{
string strSequence;
strSequence.Format( "ANSI(unknown: [%c)",
(char)*pstrOriginText );
AnsiDisplay( strSequence );
}
#endif // defined( DUMP_ANSI_CODES )
boolValidSequence = false;
}
if (boolValidSequence)
{
ProcessAnsiCodes( cTerm, m_strAnsiSequence,
strParsedBuffer );
}
// State goes back to 'scanning'
m_strAnsiSequence = "";
m_parseState = parseStateScanning;
break;
}
case parseTelnetIAC:
{
m_iTelnetCmd = (unsigned char)*pstrOriginText;
if ((TN_WILL == m_iTelnetCmd) || (TN_WONT == m_iTelnetCmd) ||
(TN_DO == m_iTelnetCmd) || (TN_DONT == m_iTelnetCmd))
{
m_parseState = parseTelnetCmd;
}
else if ((TN_GA == m_iTelnetCmd) || (TN_EOR == m_iTelnetCmd))
{
// This is definitely a prompt
#if defined( DUMP_TELNET_CODES )
{
string strSequence;
string strOut;
strSequence.Format( "rcvd IAC %s\n",
pstrTelnetLabel[m_iTelnetCmd] );
TelnetDisplay( strSequence );
}
#endif // defined( DUMP_TELNET_CODES )
// State goes back to 'scanning'
m_parseState = parseStateScanning;
}
else
{
strParsedBuffer += (char)TN_IAC;
strParsedBuffer += *pstrOriginText;
m_parseState = parseStateScanning;
}
break;
}
case parseTelnetCmd:
{
DoTelnetCmd( m_iTelnetCmd, (unsigned char)*pstrOriginText );
m_parseState = parseStateScanning;
break;
}
default:
{
TRACE( "Error in parse state!\n" );
ASSERT( false );
break;
}
}
if (boolMoveToNextChar && *pstrOriginText)
{
pstrOriginText++;
}
}
ParseEndOfLine( strParsedBuffer, iStartOfLine, false );
// Return the parsed buffer
strText = strParsedBuffer;
}
void ChWorldConn::ParseEndOfLine( ChBufferString& strBuffer, int iStartOfLine,
bool boolEndOfLine )
{
register int iBufferLen = strBuffer.GetLength();
ASSERT( iBufferLen >= iStartOfLine );
if (iStartOfLine != iBufferLen)
{
const char* pstrBuffer = strBuffer;
int iLen = iBufferLen - iStartOfLine;
pstrBuffer += iStartOfLine;
AddToTextBlock( pstrBuffer, iLen, boolEndOfLine );
}
}
void ChWorldConn::ProcessAnsiCodes( char cCodeType, const char* pstrCodes,
ChBufferString& strBuffer )
{
string strAnsiHTML;
cCodeType = (char)tolower( cCodeType );
if ((cCodeType != ANSI_MODE) && (cCodeType != ANSI_ERASE))
{
/* Right now we only support two
types of ANSI sequence */
return;
}
while (*pstrCodes != 0)
{
while (*pstrCodes == ANSI_SEPARATOR)
{ // Strip out separators
pstrCodes++;
}
if (isdigit( *pstrCodes ))
{ // There's a code here
int iCode = 0;
string strAnsiOutput;
while (isdigit( *pstrCodes ))
{
iCode = (iCode * 10) + (int)(*pstrCodes - '0');
pstrCodes++;
}
ProcessAnsiCode( cCodeType, iCode, strAnsiHTML );
}
}
if (strAnsiHTML.GetLength() > 0)
{
string strTemp;
// Add HTML
TurnHtmlOn( strTemp );
strTemp += strAnsiHTML;
TurnHtmlOff( strTemp );
strBuffer += strTemp;
}
}
void ChWorldConn::ProcessAnsiCode( char cCodeType, int iCode,
string& strOutput )
{
string strCodeHTML;
switch( cCodeType )
{
case ANSI_MODE:
{
switch( iCode )
{
case 0: // Reset all
{
AnsiDisplay( "ANSI(reset)" );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -