Esempio n. 1
0
bool CLuaHandleSynced::SetupUnsyncedFunction(const char* funcName)
{
	// copy the function from UNSYNCED into
	// the registry, and setfenv() it to UNSYNCED
	lua_settop(L, 0);
	unsyncedStr.GetRegistry(L);
	if (!lua_istable(L, -1)) {
		lua_settop(L, 0);
//FIXME		logOutput.Print("ERROR: missing UNSYNCED table for %s", name.c_str());
		return false;
	}
	const int unsynced = lua_gettop(L);

	lua_pushstring(L, funcName);

	lua_pushstring(L, funcName);
	lua_gettable(L, unsynced);
	if (lua_isnil(L, -1)) {
		lua_rawset(L, LUA_REGISTRYINDEX);
		lua_settop(L, 0);
		return true;
	}
	else if (!lua_isfunction(L, -1)) {
		lua_settop(L, 0);
		logOutput.Print("%s in %s is not a function", funcName, GetName().c_str());
		return false;
	}
	lua_pushvalue(L, unsynced);
	lua_setfenv(L, -2);

	lua_rawset(L, LUA_REGISTRYINDEX);

	lua_settop(L, 0);
	return true;
}
Esempio n. 2
0
bool CLuaHandleSynced::LoadUnsyncedCode(const string& code, const string& debug)
{
	lua_settop(L, 0);

	int error;
	error = luaL_loadbuffer(L, code.c_str(), code.size(), debug.c_str());
	if (error != 0) {
		logOutput.Print("error = %i, %s, %s\n",
		                error, debug.c_str(), lua_tostring(L, -1));
		lua_settop(L, 0);
		return false;
	}

	unsyncedStr.GetRegistry(L);
	if (!lua_istable(L, -1)) {
		lua_settop(L, 0);
		return false;
	}
	lua_setfenv(L, -2);

	CLuaHandle* orig = activeHandle;
	SetActiveHandle();
	error = lua_pcall(L, 0, 0, 0);
	SetActiveHandle(orig);

	if (error != 0) {
		logOutput.Print("error = %i, %s, %s\n",
		                error, debug.c_str(), lua_tostring(L, -1));
		lua_settop(L, 0);
		return false;
	}

	return true;
}
Esempio n. 3
0
bool CLuaHandleSynced::LoadUnsyncedCode(lua_State *L, const string& code, const string& debug)
{
	lua_settop(L, 0);

	int error;
	error = luaL_loadbuffer(L, code.c_str(), code.size(), debug.c_str());
	if (error != 0) {
		LOG_L(L_ERROR, "error = %i, %s, %s",
				error, debug.c_str(), lua_tostring(L, -1));
		lua_settop(L, 0);
		return false;
	}

	unsyncedStr.GetRegistry(L);
	if (!lua_istable(L, -1)) {
		lua_settop(L, 0);
		return false;
	}
	lua_setfenv(L, -2);

	SetRunning(L, true);
	error = lua_pcall(L, 0, 0, 0);
	SetRunning(L, false);

	if (error != 0) {
		LOG_L(L_ERROR, "error = %i, %s, %s",
				error, debug.c_str(), lua_tostring(L, -1));
		lua_settop(L, 0);
		return false;
	}

	return true;
}
Esempio n. 4
0
int CLuaHandleSynced::UnsyncedXCall(lua_State* srcState, const string& funcName)
{
	const bool prevSynced = synced;
	synced = false;
	unsyncedStr.GetRegistry(L); // push the UNSYNCED table
	const int retval = XCall(srcState, funcName);
	synced = prevSynced;
	return retval;
}
Esempio n. 5
0
bool CLuaHandleSynced::HasUnsyncedXCall(const string& funcName)
{
	unsyncedStr.GetRegistry(L); // push the UNSYNCED table
	if (!lua_istable(L, -1)) {
		lua_pop(L, 1);
		return false;
	}
	lua_pushstring(L, funcName.c_str()); // push the function name
	lua_rawget(L, -2);                   // get the function
	const bool haveFunc = lua_isfunction(L, -1);
	lua_pop(L, 2);
	return haveFunc;
}
Esempio n. 6
0
bool CLuaHandleSynced::CopyGlobalToUnsynced(const char* name)
{
	lua_settop(L, 0);
	unsyncedStr.GetRegistry(L);
	const int unsynced = lua_gettop(L);

	lua_pushstring(L, name);
	lua_getglobal(L, name);
	lua_rawset(L, unsynced);

	lua_settop(L, 0);
	return true;
}
Esempio n. 7
0
int CLuaHandleSynced::UnsyncedXCall(lua_State* srcState, const string& funcName)
{
	SELECT_UNSYNCED_LUA_STATE();

	GML_DRCMUTEX_LOCK(lua); // UnsyncedXCall

	const bool prevSynced = GetHandleSynced(L);
	SetHandleSynced(L, false);
	unsyncedStr.GetRegistry(L); // push the UNSYNCED table
	const int retval = XCall(L, srcState, funcName);
	SetHandleSynced(L, prevSynced);
	return retval;
}
Esempio n. 8
0
bool CLuaHandleSynced::HasUnsyncedXCall(lua_State* srcState, const string& funcName)
{
	SELECT_UNSYNCED_LUA_STATE();

	GML_DRCMUTEX_LOCK(lua); // HasUnsyncedXCall

	unsyncedStr.GetRegistry(L); // push the UNSYNCED table
	if (!lua_istable(L, -1)) {
		lua_pop(L, 1);
		return false;
	}
	lua_pushsstring(L, funcName); // push the function name
	lua_rawget(L, -2);                   // get the function
	const bool haveFunc = lua_isfunction(L, -1);
	lua_pop(L, 2);
	return haveFunc;
}
Esempio n. 9
0
bool CLuaHandleSynced::SetupUnsynced(const string& code, const string& filename)
{
	if ((L == NULL) || code.empty()) {
		return false;
	}

	// make the UNSYNCED table
	unsyncedStr.Push(L);
	lua_newtable(L);
	lua_rawset(L, LUA_REGISTRYINDEX);

	unsyncedStr.GetRegistry(L);

	AddBasicCalls(); // into UNSYNCED

	// remove Script.Kill()
	lua_pushstring(L, "Script");
	lua_rawget(L, -2);
	lua_pushstring(L, "Kill");
	lua_pushnil(L);
	lua_rawset(L, -3);
	LuaPushNamedCFunc(L, "UpdateCallIn", CallOutUnsyncedUpdateCallIn);
	lua_pop(L, 1);

	lua_pushstring(L, "_G");
	unsyncedStr.GetRegistry(L);
	lua_rawset(L, -3);

	LuaPushNamedCFunc(L, "loadstring",   LoadStringData);
	LuaPushNamedCFunc(L, "CallAsTeam",   CallAsTeam);

	// load our libraries
	if (!LuaSyncedTable::PushEntries(L)                                    ||
	    !AddEntriesToTable(L, "VFS",         LuaVFS::PushUnsynced)         ||
	    !AddEntriesToTable(L, "UnitDefs",    LuaUnitDefs::PushEntries)     ||
	    !AddEntriesToTable(L, "WeaponDefs",  LuaWeaponDefs::PushEntries)   ||
	    !AddEntriesToTable(L, "FeatureDefs", LuaFeatureDefs::PushEntries)  ||
	    !AddEntriesToTable(L, "Script",      LuaUnsyncedCall::PushEntries) ||
	    !AddEntriesToTable(L, "Script",      LuaScream::PushEntries)       ||
	    !AddEntriesToTable(L, "Spring",      LuaSyncedRead::PushEntries)   ||
	    !AddEntriesToTable(L, "Spring",      LuaUnsyncedCtrl::PushEntries) ||
	    !AddEntriesToTable(L, "Spring",      LuaUnsyncedRead::PushEntries) ||
	    !AddEntriesToTable(L, "gl",          LuaOpenGL::PushEntries)       ||
	    !AddEntriesToTable(L, "GL",          LuaConstGL::PushEntries)      ||
	    !AddEntriesToTable(L, "Game",        LuaConstGame::PushEntries)    ||
	    !AddEntriesToTable(L, "CMD",         LuaConstCMD::PushEntries)     ||
	    !AddEntriesToTable(L, "CMDTYPE",     LuaConstCMDTYPE::PushEntries)) {
		KillLua();
		return false;
	}

	lua_pushstring(L, "math"); lua_newtable(L);
	lua_getglobal(L, "math"); LightCopyTable(-2, -1); lua_pop(L, 1);
	lua_rawset(L, -3);

	lua_pushstring(L, "table"); lua_newtable(L);
	lua_getglobal(L, "table"); LightCopyTable(-2, -1); lua_pop(L, 1);
	lua_rawset(L, -3);

	lua_pushstring(L, "string"); lua_newtable(L);
	lua_getglobal(L, "string"); LightCopyTable(-2, -1); lua_pop(L, 1);
	lua_rawset(L, -3);

	if (!CopyRealRandomFuncs()) {
		KillLua();
		return false;
	}

	lua_settop(L, 0);

	// note the absence of loadstring() -- global access
	const char* labels[] = {
		"assert",         "error",
		"print",
		"next",           "pairs",        "ipairs",
		"tonumber",       "tostring",     "type",
		"collectgarbage", "gcinfo",
		"unpack",
		"getmetatable",   "setmetatable",
		"rawequal",       "rawget",       "rawset",
		"getfenv",        "setfenv",
		"pcall",          "xpcall",
		"_VERSION",
		NULL
	};
	for (const char** l = labels; *l != NULL; l++) {
		CopyGlobalToUnsynced(*l);
	}

	// add code from the sub-class
	unsyncedStr.GetRegistry(L);
	if (!AddUnsyncedCode()) {
		KillLua();
		return false;
	}
	lua_settop(L, 0);

	if (!LoadUnsyncedCode(code, filename)) {
		KillLua();
		return false;
	}

	if (!SetupUnsyncedFunction("RecvFromSynced")      ||
	    !SetupUnsyncedFunction("Update")              ||
	    !SetupUnsyncedFunction("DrawGenesis")         ||
	    !SetupUnsyncedFunction("DrawWorld")           ||
	    !SetupUnsyncedFunction("DrawWorldPreUnit")    ||
	    !SetupUnsyncedFunction("DrawWorldShadow")     ||
	    !SetupUnsyncedFunction("DrawWorldReflection") ||
	    !SetupUnsyncedFunction("DrawWorldRefraction") ||
	    !SetupUnsyncedFunction("DrawScreenEffects")   ||
	    !SetupUnsyncedFunction("DrawScreen")          ||
	    !SetupUnsyncedFunction("DrawInMiniMap")) {
		return false;
	}

	return true;
}