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

📄 main.cpp

📁 MudMaster 2000 的C++源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	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 + -