Пример #1
0
/**
* @brief	Executes the Lua script from bytecode.
*
* @param	pUser		   	The user running the script.
* @param	pNpc		   	The NPC attached to the script.
* @param	nEventID	   	Identifier for the event.
* @param	bSelectedReward	The reward selected, if applicable.
* @param	filename	   	The script's filename for debugging purposes.
* @param	bytecode	   	The script's compiled bytecode.
*
* @return	true if it succeeds, false if it fails.
*/
bool CLuaScript::ExecuteScript(CUser * pUser, CNpc * pNpc, int32 nEventID, int8 bSelectedReward, const char * filename, BytecodeBuffer & bytecode)
{
	// Ensure that we wait until the last user's done executing their script.
	FastGuard lock(m_lock);

	/* Attempt to run the script. */

	// Load the buffer with our bytecode.
	int err = luaL_loadbuffer(m_luaState, reinterpret_cast<const char *>(&bytecode[0]), bytecode.size(), nullptr);
	if (err != LUA_OK)
	{
		RetrieveLoadError(err, filename);
		return false;
	}

#if !defined(USE_ORIGINAL_QUESTS) // our quest implementation

	// The user & NPC instances are globals. As is the selected quest reward.
	lua_tsetglobal(m_luaState, LUA_SCRIPT_GLOBAL_USER, pUser);
	lua_tsetglobal(m_luaState, LUA_SCRIPT_GLOBAL_NPC, pNpc);
	lua_tsetglobal(m_luaState, LUA_SCRIPT_GLOBAL_SELECTED_REWARD, bSelectedReward);

	// Find & assign script's entry point to the stack
	lua_getglobal(m_luaState, LUA_SCRIPT_ENTRY_POINT);

	// Entry point requires 1 arguments: the event ID.
	lua_tpush(m_luaState, nEventID);

	// Try calling the script's entry point (Main()).
	err = lua_pcall(m_luaState, 
		1,	// 1 arguments
		0,	// 0 returned values
		0);	// no error handler

#else

	lua_tsetglobal(m_luaState, "UID", pUser->GetID());
	lua_tsetglobal(m_luaState, "STEP", bSelectedReward);
	lua_tsetglobal(m_luaState, "EVENT", nEventID);

	// Try calling the script's entry point
	err = lua_pcall(m_luaState, 
		0,	// no arguments
		0,	// 0 returned values
		0);	// no error handler
#endif

	// Nothing returned, so we can finish up here.
	if (err == LUA_OK)
	{
#if defined(USE_ORIGINAL_QUESTS)
		lua_settop(m_luaState, 0);
#endif
		return true;
	}

	// Attempt to provide somewhat informative errors to help the user figure out what's wrong.
	switch (err)
	{
	case LUA_ERRRUN:
		printf("ERROR: A runtime error occurred within Lua script `%s`.\n", filename);
		break;

	case LUA_ERRMEM:
		printf("ERROR: Unable to allocate memory during execution of Lua script `%s`.\n", filename);
		break;

	case LUA_ERRERR:
		printf("ERROR: An error occurred during Lua script `%s`. Error handler failed.\n", filename);
		break;

	default:
		printf("ERROR: An unknown error occurred in Lua script `%s`.\n", filename);
		break;
	}

	// Is there an error set? That can be more useful than our generic error.
	if (lua_isstring(m_luaState, -1))
	{
		printf("ERROR: [%s] The following error was provided:\n%s\n",
			filename, lua_to<const char *>(m_luaState, -1));
	}

#if defined(USE_ORIGINAL_QUESTS)
	lua_settop(m_luaState, 0);
#endif

	return false;
}
Пример #2
0
/**
* @brief	Executes the Lua script from bytecode.
*
* @param	pUser		   	The user running the script.
* @param	pNpc		   	The NPC attached to the script.
* @param	nEventID	   	Identifier for the event.
* @param	bSelectedReward	The reward selected, if applicable.
* @param	filename	   	The script's filename for debugging purposes.
* @param	bytecode	   	The script's compiled bytecode.
*
* @return	true if it succeeds, false if it fails.
*/
bool CLuaScript::ExecuteScript(CUser * pUser, CNpc * pNpc, int32 nEventID, int8 bSelectedReward, const char * filename, BytecodeBuffer & bytecode)
{
	// Ensure that we wait until the last user's done executing their script.
	Guard lock(m_lock);

	/* Attempt to run the script. */

	// Load the buffer with our bytecode.
	int err = luaL_loadbuffer(m_luaState, reinterpret_cast<const char *>(&bytecode[0]), bytecode.size(), nullptr);
	if (err != LUA_OK)
	{
		RetrieveLoadError(err, filename);
		return false;
	}


	lua_tsetglobal(m_luaState, "UID", pUser->GetID());
	lua_tsetglobal(m_luaState, "STEP", bSelectedReward);
	lua_tsetglobal(m_luaState, "EVENT", nEventID);

	// Try calling the script's entry point
	err = lua_pcall(m_luaState, 
		0,	// no arguments
		0,	// 0 returned values
		0);	// no error handler

	// Nothing returned, so we can finish up here.
	if (err == LUA_OK)
	{
		lua_settop(m_luaState, 0);
		return true;
	}

	// Attempt to provide somewhat informative errors to help the user figure out what's wrong.
	switch (err)
	{
	case LUA_ERRRUN:
		printf("ERROR: A runtime error occurred within Lua script.\n");
		printf("FILE: %s\n", filename);
		printf("USER: %s\n", pUser->GetName().c_str());
		printf("ZONE: %d\n", pUser->GetZoneID());
		printf("NPC ID: %d\n", pNpc->m_sSid);
		printf("-\n");
		break;

	case LUA_ERRMEM:
		printf("ERROR: Unable to allocate memory during execution of Lua script.\n");
		printf("FILE: %s\n", filename);
		printf("USER: %s\n", pUser->GetName().c_str());
		printf("ZONE: %d\n", pUser->GetZoneID());
		printf("NPC ID: %d\n", pNpc->m_sSid);
		printf("-\n");
		break;

	case LUA_ERRERR:
		printf("ERROR: An error occurred during Lua script, Error handler failed.\n");
		printf("FILE: %s\n", filename);
		printf("USER: %s\n", pUser->GetName().c_str());
		printf("ZONE: %d\n", pUser->GetZoneID());
		printf("NPC ID: %d\n", pNpc->m_sSid);
		printf("-\n");
		break;

	default:
		printf("ERROR: An unknown error occurred in Lua script.\n");
		printf("FILE: %s\n", filename);
		printf("USER: %s\n", pUser->GetName().c_str());
		printf("ZONE: %d\n", pUser->GetZoneID());
		printf("NPC ID: %d\n", pNpc->m_sSid);
		printf("-\n");
		break;
	}

	// Is there an error set? That can be more useful than our generic error.
	if (lua_isstring(m_luaState, -1))
	{
		printf("ERROR: [%s] The following error was provided.\n",filename);
		printf("MESSAGE: %s\n", lua_to<const char *>(m_luaState, -1));
		printf("-\n");

	}

	lua_settop(m_luaState, 0);

	return false;
}