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

📄 scriptengine.cpp

📁 是一个基于热血战国协议的网络游戏。现在脱机客户端先放出来给大家研究
💻 CPP
字号:

/*
 * name:		CScriptEngine.cpp
 *
 * desc:		实现文件
 *
*/

#include "StdAfx.h"
#include "..\MainFrm.h"
#include "GameMir.h"

/*
=======================================================================
函数名       : CScriptEngine
功能描述     : 
参数         : void
返回值       : NULL
=======================================================================
*/
// ^如果当前地图名=\[(.+)\]$
// ^那么跳转到第\[(\d+)\]行$
// ^触发器:如果(.+),那么跳转到脚本第\[(\d+)\]行$
// ^如果((\S+)\s*)*$
CScriptEngine::CScriptEngine(CGameMir&Game) : 
m_Game(Game),
m_LastResult(false),
m_RegexIf(L"^如果(.+)$",boost::regbase::normal|boost::regbase::icase),
m_RegexThen(L"^那么(.+)$",boost::regbase::normal|boost::regbase::icase)
{
	InitializeCriticalSection(&m_RunSC);

	// add by zdl. 2007-10-11
	this->bNotifyStop_ = false;		
	this->bRunning_ = false;
	this->bThreadMode_ = false;
	// end of add
}


/*
=======================================================================
函数名       : ~CScriptEngine
功能描述     : 
参数         : void
返回值       : NULL
=======================================================================
*/
// 触发器
// trigger
// 条件
// condition
CScriptEngine::~CScriptEngine(void)
{
	DeleteCriticalSection(&m_RunSC);
}

/*
=======================================================================
函数名       : RegisterCommand
功能描述     : 
参数         : void
返回值       : NULL
=======================================================================
*/
void CScriptEngine::RegisterCommand( std::wstring reg, SCRIPT_COMMAND_PROC proc )
{
	sScriptCommand cmd;
	cmd.second=proc;
	cmd.first.assign(reg,boost::regbase::normal|boost::regbase::icase);
	m_Commands.push_back(cmd);
}

/*
=======================================================================
函数名       : RegisterCondition
功能描述     : 
参数         : void
返回值       : NULL
=======================================================================
*/
void CScriptEngine::RegisterCondition( std::wstring reg, SCRIPT_CONDITION_PROC proc )
{
	sScriptCondition condition;
	condition.second=proc;
	condition.first.assign(reg,boost::regbase::normal|boost::regbase::icase);
	m_Conditions.push_back(condition);
}

/*
=======================================================================
函数名       : LoadFile
功能描述     : 导入脚本文件
参数         : void
返回值       : NULL
=======================================================================
*/
bool CScriptEngine::LoadFile( std::string strFileName )
{
	if(TryEnterCriticalSection(&m_RunSC))
	{
		LeaveCriticalSection(&m_RunSC);
	}
	else
	{
		m_Game.m_FrameWnd.AddLog(crGreen,"脚本: 脚本已经运行了!\n");
		return false;
	}
	if ( strFileName.size()<=0 )
	{
		return false;
	}
	unsigned __int64 t1=timestamp();

	// ReadFile
	m_Scripts.clear();
	CFile fileScript;
	if (fileScript.Open(strFileName.c_str(),CFile::typeBinary|CFile::modeRead|CFile::shareDenyWrite)==FALSE)
	{
		m_Game.m_FrameWnd.AddLog(crGreen,"脚本: 脚本文件不存在!\n");
		return false;
	}
	size_t flen=fileScript.GetLength();
	char*pBuf=new char[flen+1];
	ZeroMemory(pBuf,flen+1);
	fileScript.Read(pBuf,flen);
	pBuf[flen]=static_cast<char>(0);

	std::wstring text;
	LPWSTR UBuf=new WCHAR[flen+1];;
	text=ToUnicode(pBuf,UBuf,flen);
	delete[]pBuf;
	delete[]UBuf;
	std::vector<std::wstring> Lines;
	const boost::wregex reSplit(L"\\s*\\n\\s*",boost::regbase::normal|boost::regbase::icase);
	boost::regex_split(std::back_inserter(Lines),text,reSplit);
	for(std::vector<std::wstring>::iterator pos=Lines.begin();pos!=Lines.end();pos++)
	{
		//匹配语句
		const boost::wregex expression(L"^(?:(\\d+)\\s+)?(.+)$",boost::regbase::normal|boost::regbase::icase);
		boost::wsmatch match;
		std::wstring label;
		sScriptLine line;
		if (boost::regex_match( *pos, match, expression))
		{
			//m_FrameWnd.AddLog(crMessage,"%s\n",pos->c_str());
			label=match.str(1);
			text=match.str(2);
			if ( !text.empty() )
			{
				switch ( text[0] )
				{
				case '*':
					break;
				case '<':
					if ( text[text.length()-1]=='>')
					{
						line.first=text.substr(1,text.length()-2);
						line.second=text;
						m_Scripts.push_back(line);
						//m_Game.m_FrameWnd.AddLog(crMessage,"脚本: % 8s %s \n",line.first.c_str(),line.second.c_str());
					}
					break;
				default:
					if(label.empty())
						line.first.clear();
					else
						line.first=label;
					line.second=text;
					m_Scripts.push_back(line);
					//m_Game.m_FrameWnd.AddLog(crMessage,"脚本: % 8s %s \n",line.first.c_str(),line.second.c_str());
					break;
				}
			}
		}
	}

	m_ip=m_Scripts.begin();
	unsigned __int64 t2=timestamp()-t1;
	m_Game.m_FrameWnd.AddLog(crGreen,"脚本: 加载完成!\n");
	return true;
}

/*
=======================================================================
函数名       : Step
功能描述     : 
参数         : void
返回值       : NULL
=======================================================================
*/
bool CScriptEngine::Step(void)
{
	char buf[STRING_BUFFER_LENGTH];
	
	if (m_Scripts.size()<=0)	
		return false;
	
	if(m_ip==m_Scripts.end())
		return false;

	//sScriptLine line=*m_ip;
	std::wstring str=m_ip->second;
	boost::wsmatch m;
	if (boost::regex_match(str, m, m_RegexIf))
	{
		str=m[1];
		m_Game.m_FrameWnd.AddLog(crGreen,"脚本: 判断: %s !?\n",ToAnsi(str.c_str(),buf,STRING_BUFFER_LENGTH));
		if ( !__do_If( str, m_LastResult ) )
		{
			m_Game.m_FrameWnd.AddLog(crError,"脚本: 未知的判断语句!!!!\n");
			return false;
		}
		m_ip++;
		return true;
	}
	else if (regex_match(str, m, m_RegexThen))
	{
		if (m_LastResult)
		{
			str=m[1];
		}
		else
		{
			m_ip++;
			return true;
		}
	}
	for(CommandList::iterator pos=m_Commands.begin();pos!=m_Commands.end();pos++)
	{
		if (regex_match(str, m, pos->first))
		{
			m_Game.m_FrameWnd.AddLog(crGreen,"脚本: 执行: \"%s\" !\n",ToAnsi(str.c_str(),buf,STRING_BUFFER_LENGTH));
			SCRIPT_COMMAND_PROC cmd=pos->second;
			DWORD dwRetVal=cmd(m_Game,*this,m,m_LastResult);
			if ( (dwRetVal&SR_SUCCESS)!=0 )
			{
				if ( (dwRetVal&SR_NOMOVE)==0 )
					m_ip++;
				return true;
			}
			else
			{
				m_Game.m_FrameWnd.AddLog(crRed,"脚本: 语句\"%s\"执行失败!\n",ToAnsi(str.c_str(),buf,STRING_BUFFER_LENGTH));
				return false;
			}
		}
	}
	m_Game.m_FrameWnd.AddLog(crRed,"脚本: 语法错误: %s !\n",ToAnsi(str.c_str(),buf,STRING_BUFFER_LENGTH));
	return false;
}

/*
=======================================================================
函数名       : Jump
功能描述     : 跳到行
参数         : void
返回值       : NULL
=======================================================================
*/
bool CScriptEngine::Jump( int line )
{
	return Jump(boost::lexical_cast<std::wstring>(line));
}

/*
=======================================================================
函数名       : Jump
功能描述     : 跳到标签
参数         : void
返回值       : NULL
=======================================================================
*/
bool CScriptEngine::Jump( std::wstring label )
{
	for(sScript::iterator pos=m_Scripts.begin();pos!=m_Scripts.end();pos++)
	{
		if ( pos->first == label )
		{
			m_ip=pos;
			return true;
		}
	}
	char buf[STRING_BUFFER_LENGTH];
	m_Game.m_FrameWnd.AddLog(crRed,"脚本: 跳转失败:%d不存在!\n",ToAnsi(label.c_str(),buf,STRING_BUFFER_LENGTH));
	return false;
}

/*
=======================================================================
函数名       : Run
功能描述     : 运行
参数         : void
返回值       : NULL
=======================================================================
*/
void CScriptEngine::Run(bool threadmode)
{
	// add by zdl. 2007-10-11
	bNotifyStop_ = false;		
	bRunning_ = true;
	this->bThreadMode_ = threadmode;
	// end of add

	if ( threadmode )
		pThread_ = AfxBeginThread( ScriptRunThread, (LPVOID)this );
	else
		ScriptRunThread( (LPVOID)this );
}


void CScriptEngine::Stop( )
{
	if (bRunning_)
	{
		this->bNotifyStop_ = true;
		if (this->bThreadMode_)
		{
			DWORD dwWaitRet = ::WaitForSingleObject(pThread_->m_hThread, 5000);
			if ( WAIT_TIMEOUT == dwWaitRet )
			{
				::TerminateThread(pThread_->m_hThread, 0);
			}

			bRunning_ = false;
		}
	}
}


/*
=======================================================================
函数名       : ScriptRunThread
功能描述     : 
参数         : void
返回值       : NULL
=======================================================================
*/
UINT CScriptEngine::ScriptRunThread( LPVOID pParam )
{
	CScriptEngine& se=*static_cast<CScriptEngine*>(pParam);
	if(TryEnterCriticalSection(&se.m_RunSC))
	{
		while(se.Step())
		{
			// add by zdl. 2007-10-11
			if (se.bNotifyStop_)
			{
				break;
			}
			// end of add

			if (!se.m_Game.isInGame())
				break;
		}

		se.m_ip=se.m_Scripts.begin();
		LeaveCriticalSection(&se.m_RunSC);
		se.m_Game.m_FrameWnd.AddLog(crRed,"脚本: 执行结束.\n");
	}
	else
	{
		se.m_Game.m_FrameWnd.AddLog(crRed,"脚本: 已经在运行中!!\n");
	}
	return 0;
}

⌨️ 快捷键说明

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