📄 main.cpp
字号:
if (nResult == SOCKET_ERROR)
{
if (WSAGetLastError() == WSAEWOULDBLOCK)
{
// Timeout value must be 0 or the call will block.
timeval timeout = {0, 0};
// Create socket descriptor arrays for polling the
// connection status.
fd_set fdsWrite;
fd_set fdsExcept;
while(1)
{
// Give the user a chance to abort it.
if (kbhit() && getch() == '\x1b')
{
PrintMessage("Connection attempt cancelled.");
closesocket(_hActiveSocket);
break;
}
// Make sure the array is cleared, the put the handle
// for our socket in the array. A socket is connected
// when is is writable. Have to also poll the exception
// status to determine if there was an error.
FD_ZERO(&fdsWrite);
FD_SET(_hActiveSocket,&fdsWrite);
FD_ZERO(&fdsExcept);
FD_SET(_hActiveSocket,&fdsExcept);
// Select changes the arrays. After the call the arrays
// contain only the handles of the sockets that met
// either the read, write or execption status change.
nResult = select(0,NULL,&fdsWrite,&fdsExcept,&timeout);
// Something changed.
if (nResult > 0)
{
// If writable, we are connected.
if (fdsWrite.fd_count)
{
PrintMessage("Connected.");
_strActiveSession = pszName;
_bConnected = TRUE;
_notifyConnect.Notify(_hActiveSocket);
// Not going to support telnet half-duplex
// connections. Suppress the go ahead signal.
SendText(_szWillSGA,FALSE);
break;
}
// Encountered an error.
if (fdsExcept.fd_count)
{
// Someday would be nice if I could retrieve the
// error code when using this method.
// WSAGetLastError doesn't return anything.
// GetSockOpt just returns a 0.
PrintMessage("Connection Failed.");
closesocket(_hActiveSocket);
break;
}
}
}
}
else
{
PrintError();
closesocket(_hActiveSocket);
}
}
}
void SetFocusUserInput()
{
_tiUserInput.SetFocus();
}
// This function is used only for findind the @PreTrans procedure
// and replacing the vars in it. Pretranlation is used on commands
// that you want a variable to be replaced before it is actually
// executed. For example: /mac f1 $Target, when you press F1
// $Target gets translated. You may want to replace the variable
// when the macro is created, and just store the value in the macro.
// /mac f1 @PreTrans($Target), would replace the variable before
// the macro is defined.
void PretranslateString(CString &strLine)
{
if (_bReadingFile || strLine.Find("@PreTrans(") == -1)
return;
BOOL bFoundProc = FALSE;
BOOL bFoundProcParen = FALSE;
int nProcParenCount = 0;
CString strText;
CString strProcName;
CString strTemp;
int nIndex = 0;
int nLen = strLine.GetLength();
while(nIndex < nLen)
{
if (bFoundProc)
{
if (strLine[nIndex] == '(')
{
bFoundProcParen = TRUE;
nProcParenCount++;
}
// Can use the escape character to force a closing parent without meaning part of the procedure.
if (strLine[nIndex] == _config.chEscape && nIndex+1 < nLen && strLine[nIndex+1] == ')')
{
strProcName += _config.chEscape;
strProcName += ')';
nIndex += 2;
continue;
}
if (strLine[nIndex] == ')')
nProcParenCount--;
// We are collecting a procedure name until we read
// a final closing paren.
if (bFoundProcParen && !nProcParenCount)
{
// No matter what, there is no longer a possibility
// of looking for a variable.
bFoundProc = FALSE;
strProcName += ')';
nIndex++;
// Only procedure we want to process here is the
// @PreTrans procedure.
if (strProcName.Find("PreTrans") == 0)
{
ProcedureVar(strProcName,strText);
strTemp += strText;
continue;
}
strTemp += CString("@") + strProcName;
continue;
}
else
{
strProcName += strLine[nIndex];
nIndex++;
continue;
}
} // if (bFoundProc)
if (strLine[nIndex] == '@')
{
bFoundProc = TRUE;
bFoundProcParen = FALSE;
nProcParenCount = 0;
strProcName.Empty();
nIndex++;
continue;
}
if (strLine[nIndex] == _config.chEscape && nIndex+1 < nLen && strLine[nIndex+1] == '@')
{
strTemp += '@';
nIndex += 2;
continue;
}
strTemp += strLine[nIndex];
nIndex++;
} // while(nIndex < nLen)
strLine = strTemp;
}
void ReplaceVariables(CString &strLine, BOOL bQuoteStrings)
{
// Tintin seems to work like this: If you type a $<text>
// if looks it up in the variable list, if nothing is there
// "$<text>" prints, otherwise replaces it with the variable
// value. It treats the $0 vars differently than I plan to
// though. The $vars are global in MudMaster. You can use
// $0 to print what is in that variable at any time. Tintin
// only allows you to use that var it in a tintin statement
// I think.
// Variables names start with a $ always. They are alpha
// only. If the $ character is what is wanted instead of
// representing a variable, the escape character should be
// used.
// Add procedures to the variable replacement list. The only
// procedure that should be handled during var replacement are
// the ones that evaultate as a BOOL.
// Going to do this a as quick check to see if there are
// any possible vars in the string.
if (strLine.Find('$') == -1 && strLine.Find('@') == -1)
return;
STRING_MAP *pMap;
BOOL bFoundVar = FALSE;
BOOL bFoundProc = FALSE;
BOOL bFoundProcParen = FALSE;
int nProcParenCount = 0;
CString strText;
CString strVarName;
CString strProcName;
CString strTemp;
int nIndex = 0;
int nLen = strLine.GetLength();
while(nIndex < nLen)
{
if (bFoundVar)
{
// As long as we have alpha characters we are collecting
// the variable name.
if (isalnum(strLine[nIndex]))
{
// If we don't have any length to the variable name
// and the character is a digit, they want one of the
// global vars.
if (strVarName.IsEmpty() && isdigit(strLine[nIndex]))
{
if (bQuoteStrings && !IsVarNumber(_strGlobalVars[strLine[nIndex]-'0']))
{
CString strQuoted;
EscapeQuote(_strGlobalVars[strLine[nIndex]-'0'],strQuoted);
strTemp += CString('"') + strQuoted + "\"";
}
else
strTemp += _strGlobalVars[strLine[nIndex]-'0'];
nIndex++;
bFoundVar = FALSE;
continue;
}
strVarName += strLine[nIndex];
nIndex++;
continue;
}
else
{
// No matter what, there is no longer a possibility
// of looking for a variable.
bFoundVar = FALSE;
// If the name is empty here, just print a $, must not
// have been looking for a real variable name. This
// character still needs to be processed, however.
if (strVarName.IsEmpty())
{
strTemp += '$';
continue;
}
// Need to check the user defined and system defined
// variables here. If the variable name is not found
// print the $ and the name we have just collected.
pMap = _mapVars.FindExactByKey(strVarName);
if (pMap != NULL)
{
if (bQuoteStrings && !IsVarNumber(pMap->strText))
{
CString strQuoted;
EscapeQuote(pMap->strText, strQuoted);
strTemp += CString('"') + strQuoted + "\"";
}
else
strTemp += pMap->strText;
continue;
}
else
{
if (SystemVar(strVarName,strText))
{
strTemp += strText;
continue;
}
}
strTemp += CString("$") + strVarName;
continue;
}
} // if (bFoundVar)
if (bFoundProc)
{
if (strLine[nIndex] == '(')
{
bFoundProcParen = TRUE;
nProcParenCount++;
}
// Can use the escape character to force a closing parent without meaning part of the procedure.
if (strLine[nIndex] == _config.chEscape && nIndex+1 < nLen && strLine[nIndex+1] == ')')
{
strProcName += _config.chEscape;
strProcName += ')';
nIndex += 2;
continue;
}
if (strLine[nIndex] == ')')
nProcParenCount--;
// We are collecting a procedure name until we read
// a final closing paren.
if (bFoundProcParen && !nProcParenCount)
{
// No matter what, there is no longer a possibility
// of looking for a variable.
bFoundProc = FALSE;
strProcName += ')';
nIndex++;
// Check to see if the procedure is processed as a
// procedure that returns a value.
if (ProcedureVar(strProcName,strText))
{
strTemp += strText;
continue;
}
strTemp += CString("?") + strProcName;
continue;
}
else
{
strProcName += strLine[nIndex];
nIndex++;
continue;
}
} // if (bFoundProc)
if (strLine[nIndex] == '$')
{
bFoundVar = TRUE;
strVarName.Empty();
nIndex++;
continue;
}
if (strLine[nIndex] == '@')
{
bFoundProc = TRUE;
bFoundProcParen = FALSE;
nProcParenCount = 0;
strProcName.Empty();
nIndex++;
continue;
}
// If the escape character is present, they may be trying
// to force the printing of a $.
if (strLine[nIndex] == _config.chEscape && nIndex+1 < nLen && strLine[nIndex+1] == '$')
{
strTemp += '$';
nIndex += 2;
continue;
}
if (strLine[nIndex] == _config.chEscape && nIndex+1 < nLen && strLine[nIndex+1] == '@')
{
strTemp += '@';
nIndex += 2;
continue;
}
strTemp += strLine[nIndex];
nIndex++;
} // while(nIndex < nLen)
// Var was last thing on the line.
if (bFoundVar)
{
if (strVarName.IsEmpty())
strTemp += '$';
else
{
pMap = _mapVars.FindExactByKey(strVarName);
if (pMap != NULL)
{
if (bQuoteStrings && !IsVarNumber(pMap->strText))
{
CString strQuoted;
EscapeQuote(pMap->strText,strQuoted);
strTemp += CString('"') + strQuoted + "\"";
}
else
strTemp += pMap->strText;
}
else
{
if (SystemVar(strVarName,strText))
strTemp += strText;
else
strTemp += CString("$") + strVarName;
}
}
}
strLine = strTemp;
}
BOOL SystemVar(CString &strVarName, CString &strResult)
{
if (strVarName == "ForeColor")
{
strResult.Format("%d",_nForeColor);
return(TRUE);
}
if (strVarName == "ListItem")
{
strResult = _strListItem;
return(TRUE);
}
if (strVarName == "LoopCount")
{
strResult.Format("%d",_nLoopCount);
return(TRUE);
}
return(FALSE);
}
void EscapeQuote(const char *pszText, CString &strQuoted)
{
// Make a quick check to see if there actual are any quotes
// in the text.
if (strchr(pszText,'"') == NULL)
{
strQuoted = pszText;
return;
}
while(*pszText)
{
if (*pszText == '"')
strQuoted += CString(_config.chEscape) + '"';
else
strQuoted += *pszText;
pszText++;
}
}
BOOL IsVarNumber(const char *pszText)
{
while(*pszText)
{
if (!isdigit(*pszText) && *pszText != '-')
return(FALSE);
pszText++;
}
return(TRUE);
}
///////////////////////////////////////////////////////////////
// Terminal Printing Functions
//
void PrintMessage(const char *pszText, BOOL bCR, BOOL bNoAction)
{
if (bNoAction)
CommandPrintOn();
CString strText;
char *pBuf;
int nResult;
if (bCR)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -