bool LuaBitOps::PushEntries(lua_State* L) { LuaPushNamedCFunc(L, "bit_or", bit_or); LuaPushNamedCFunc(L, "bit_and", bit_and); LuaPushNamedCFunc(L, "bit_xor", bit_xor); LuaPushNamedCFunc(L, "bit_inv", bit_inv); LuaPushNamedCFunc(L, "bit_bits", bit_bits); return true; }
bool CLuaHandleSynced::SetupSynced(const string& code, const string& filename) { if ((L == NULL) || code.empty()) { return false; } lua_pushvalue(L, LUA_GLOBALSINDEX); AddBasicCalls(); // into Global lua_pushstring(L, "Script"); lua_rawget(L, -2); LuaPushNamedCFunc(L, "AddActionFallback", AddSyncedActionFallback); LuaPushNamedCFunc(L, "RemoveActionFallback", RemoveSyncedActionFallback); LuaPushNamedCFunc(L, "UpdateCallIn", CallOutSyncedUpdateCallIn); LuaPushNamedCFunc(L, "GetWatchWeapon", GetWatchWeapon); LuaPushNamedCFunc(L, "SetWatchWeapon", SetWatchWeapon); lua_pop(L, 1); // add the custom file loader LuaPushNamedCFunc(L, "SendToUnsynced", SendToUnsynced); LuaPushNamedCFunc(L, "loadstring", LoadStringData); LuaPushNamedCFunc(L, "CallAsTeam", CallAsTeam); LuaPushNamedCFunc(L, "AllowUnsafeChanges", AllowUnsafeChanges); LuaPushNamedNumber(L, "COBSCALE", COBSCALE); // load our libraries (LuaSyncedCtrl overrides some LuaUnsyncedCtrl entries) if (!AddEntriesToTable(L, "VFS", LuaVFS::PushSynced) || !AddEntriesToTable(L, "UnitDefs", LuaUnitDefs::PushEntries) || !AddEntriesToTable(L, "WeaponDefs", LuaWeaponDefs::PushEntries) || !AddEntriesToTable(L, "FeatureDefs", LuaFeatureDefs::PushEntries) || !AddEntriesToTable(L, "Script", LuaSyncedCall::PushEntries) || !AddEntriesToTable(L, "Spring", LuaUnsyncedCtrl::PushEntries) || !AddEntriesToTable(L, "Spring", LuaSyncedCtrl::PushEntries) || !AddEntriesToTable(L, "Spring", LuaSyncedRead::PushEntries) || !AddEntriesToTable(L, "Game", LuaConstGame::PushEntries) || !AddEntriesToTable(L, "CMD", LuaConstCMD::PushEntries) || !AddEntriesToTable(L, "CMDTYPE", LuaConstCMDTYPE::PushEntries)) { KillLua(); return false; } // add code from the sub-class if (!AddSyncedCode()) { KillLua(); return false; } lua_settop(L, 0); if (!LoadCode(code, filename)) { KillLua(); return false; } return true; }
bool LuaSyncedTable::PushEntries(lua_State* L) { HSTR_PUSH(L, "SYNCED"); lua_pushvalue(L, LUA_GLOBALSINDEX); WrapTable(L); // replace the GLOBAL table with a proxy lua_rawset(L, -3); LuaPushNamedCFunc(L, "snext", Next); LuaPushNamedCFunc(L, "spairs", Pairs); LuaPushNamedCFunc(L, "sipairs", IPairs); return true; }
bool CLuaCob::AddSyncedCode() { lua_getglobal(L, "Spring"); LuaPushNamedCFunc(L, "UnpackCobArg", UnpackCobArg); lua_pop(L, 1); return true; }
bool CLuaGaia::AddSyncedCode() { lua_getglobal(L, "Script"); LuaPushNamedCFunc(L, "GetConfigString", GetConfigString); lua_pop(L, 1); return true; }
static bool PushSyncedTable(lua_State* L) { HSTR_PUSH(L, "SYNCED"); lua_newtable(L); { // the proxy table lua_newtable(L); { // the metatable LuaPushNamedCFunc(L, "__index", SyncTableIndex); LuaPushNamedCFunc(L, "__newindex", SyncTableNewIndex); LuaPushNamedCFunc(L, "__metatable", SyncTableMetatable); } lua_setmetatable(L, -2); } lua_rawset(L, -3); return true; }
bool CLuaRules::AddSyncedCode(lua_State *L) { lua_getglobal(L, "Script"); LuaPushNamedCFunc(L, "PermitHelperAIs", PermitHelperAIs); lua_pop(L, 1); return true; }
bool CLuaGaia::AddUnsyncedCode() { lua_pushstring(L, "UNSYNCED"); lua_gettable(L, LUA_REGISTRYINDEX); lua_pushstring(L, "Script"); lua_rawget(L, -2); LuaPushNamedCFunc(L, "GetConfigString", GetConfigString); lua_pop(L, 1); return true; }
bool CLuaRules::AddSyncedCode() { lua_getglobal(L, "Script"); LuaPushNamedCFunc(L, "GetConfigString", GetConfigString); LuaPushNamedCFunc(L, "PermitHelperAIs", PermitHelperAIs); lua_pop(L, 1); lua_getglobal(L, "Spring"); LuaPushNamedCFunc(L, "SetRulesInfoMap", SetRulesInfoMap); LuaPushNamedCFunc(L, "SetUnitRulesParam", SetUnitRulesParam); LuaPushNamedCFunc(L, "SetTeamRulesParam", SetTeamRulesParam); LuaPushNamedCFunc(L, "SetGameRulesParam", SetGameRulesParam); LuaPushNamedCFunc(L, "CreateUnitRulesParams", CreateUnitRulesParams); LuaPushNamedCFunc(L, "CreateTeamRulesParams", CreateTeamRulesParams); LuaPushNamedCFunc(L, "CreateGameRulesParams", CreateGameRulesParams); lua_pop(L, 1); return true; }
static int SyncTableIndex(lua_State* dstL) { if (lua_isnoneornil(dstL, -1)) return 0; auto slh = CLuaHandleSynced::GetSyncedHandle(dstL); if (!slh->IsValid()) return 0; auto srcL = slh->GetLuaState(); const int srcTop = lua_gettop(srcL); const int dstTop = lua_gettop(dstL); // copy the index & get value lua_pushvalue(srcL, LUA_GLOBALSINDEX); const int keyCopied = LuaUtils::CopyData(srcL, dstL, 1); assert(keyCopied > 0); lua_rawget(srcL, -2); // copy to destination const int valueCopied = LuaUtils::CopyData(dstL, srcL, 1); if (lua_istable(dstL, -1)) { // disallow writing in SYNCED[...] lua_newtable(dstL); { // the metatable LuaPushNamedCFunc(dstL, "__newindex", SyncTableNewIndex); LuaPushNamedCFunc(dstL, "__metatable", SyncTableMetatable); } lua_setmetatable(dstL, -2); } assert(valueCopied == 1); assert(dstTop + 1 == lua_gettop(dstL)); lua_settop(srcL, srcTop); return valueCopied; }
bool CLuaRules::AddUnsyncedCode() { lua_pushstring(L, "UNSYNCED"); lua_gettable(L, LUA_REGISTRYINDEX); lua_pushstring(L, "Script"); lua_rawget(L, -2); LuaPushNamedCFunc(L, "GetConfigString", GetConfigString); lua_pop(L, 1); // Script lua_pushstring(L, "Spring"); lua_rawget(L, -2); lua_pushstring(L, "UnitRendering"); lua_newtable(L); LuaUnitRendering::PushEntries(L); lua_rawset(L, -3); lua_pop(L, 1); // Spring lua_pop(L, 1); // UNSYNCED return true; }
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; }
CLuaIntro::CLuaIntro() : CLuaHandle("LuaIntro", LUA_HANDLE_ORDER_UI, true) { LuaIntro = this; if (!IsValid()) { return; } const std::string file = "LuaIntro/main.lua"; const string code = LoadFile(file); if (code.empty()) { KillLua(); return; } lua_State* L = L_Sim; // load the standard libraries LUA_OPEN_LIB(L, luaopen_base); LUA_OPEN_LIB(L, luaopen_io); LUA_OPEN_LIB(L, luaopen_os); LUA_OPEN_LIB(L, luaopen_math); LUA_OPEN_LIB(L, luaopen_table); LUA_OPEN_LIB(L, luaopen_string); LUA_OPEN_LIB(L, luaopen_debug); // setup the lua IO access check functions lua_set_fopen(L, LuaIO::fopen); lua_set_popen(L, LuaIO::popen, LuaIO::pclose); lua_set_system(L, LuaIO::system); lua_set_remove(L, LuaIO::remove); lua_set_rename(L, LuaIO::rename); // remove a few dangerous calls lua_getglobal(L, "io"); lua_pushstring(L, "popen"); lua_pushnil(L); lua_rawset(L, -3); lua_pop(L, 1); lua_getglobal(L, "os"); { lua_pushliteral(L, "exit"); lua_pushnil(L); lua_rawset(L, -3); lua_pushliteral(L, "execute"); lua_pushnil(L); lua_rawset(L, -3); //lua_pushliteral(L, "remove"); lua_pushnil(L); lua_rawset(L, -3); //lua_pushliteral(L, "rename"); lua_pushnil(L); lua_rawset(L, -3); lua_pushliteral(L, "tmpname"); lua_pushnil(L); lua_rawset(L, -3); lua_pushliteral(L, "getenv"); lua_pushnil(L); lua_rawset(L, -3); //lua_pushliteral(L, "setlocale"); lua_pushnil(L); lua_rawset(L, -3); } lua_pop(L, 1); // os lua_pushvalue(L, LUA_GLOBALSINDEX); AddBasicCalls(L); // into Global lua_pushstring(L, "Script"); lua_rawget(L, -2); LuaPushNamedCFunc(L, "UpdateCallIn", CallOutUnsyncedUpdateCallIn); lua_pop(L, 1); // load the spring libraries if ( !AddEntriesToTable(L, "Spring", LoadUnsyncedCtrlFunctions) || !AddEntriesToTable(L, "Spring", LoadUnsyncedReadFunctions) || !AddEntriesToTable(L, "Spring", LoadSyncedReadFunctions) || !AddEntriesToTable(L, "VFS", LuaVFS::PushUnsynced) || !AddEntriesToTable(L, "VFS", LuaZipFileReader::PushUnsynced) || !AddEntriesToTable(L, "VFS", LuaZipFileWriter::PushUnsynced) || !AddEntriesToTable(L, "Script", LuaScream::PushEntries) || //!AddEntriesToTable(L, "Script", LuaLobby::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) || !AddEntriesToTable(L, "LOG", LuaUtils::PushLogEntries) ) { KillLua(); return; } RemoveSomeOpenGLFunctions(L); lua_settop(L, 0); if (!LoadCode(L, code, file)) { KillLua(); return; } lua_settop(L, 0); // register for call-ins eventHandler.AddClient(this); }
bool CUnsyncedLuaHandle::Init(const string& code, const string& file) { if (!IsValid()) { return false; } // load the standard libraries LUA_OPEN_LIB(L, luaopen_base); LUA_OPEN_LIB(L, luaopen_math); LUA_OPEN_LIB(L, luaopen_table); LUA_OPEN_LIB(L, luaopen_string); //LUA_OPEN_LIB(L, luaopen_io); //LUA_OPEN_LIB(L, luaopen_os); //LUA_OPEN_LIB(L, luaopen_package); //LUA_OPEN_LIB(L, luaopen_debug); // delete some dangerous functions lua_pushnil(L); lua_setglobal(L, "dofile"); lua_pushnil(L); lua_setglobal(L, "loadfile"); lua_pushnil(L); lua_setglobal(L, "loadlib"); lua_pushnil(L); lua_setglobal(L, "loadstring"); // replaced lua_pushnil(L); lua_setglobal(L, "require"); lua_pushvalue(L, LUA_GLOBALSINDEX); AddBasicCalls(L); // remove Script.Kill() lua_getglobal(L, "Script"); LuaPushNamedNil(L, "Kill"); lua_pop(L, 1); LuaPushNamedCFunc(L, "loadstring", CLuaHandleSynced::LoadStringData); LuaPushNamedCFunc(L, "CallAsTeam", CLuaHandleSynced::CallAsTeam); LuaPushNamedNumber(L, "COBSCALE", COBSCALE); // load our libraries if (!LuaSyncedTable::PushEntries(L) || !AddEntriesToTable(L, "VFS", LuaVFS::PushUnsynced) || !AddEntriesToTable(L, "VFS", LuaZipFileReader::PushUnsynced) || !AddEntriesToTable(L, "VFS", LuaZipFileWriter::PushUnsynced) || !AddEntriesToTable(L, "UnitDefs", LuaUnitDefs::PushEntries) || !AddEntriesToTable(L, "WeaponDefs", LuaWeaponDefs::PushEntries) || !AddEntriesToTable(L, "FeatureDefs", LuaFeatureDefs::PushEntries) || !AddEntriesToTable(L, "Script", LuaInterCall::PushEntriesUnsynced) || !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) || !AddEntriesToTable(L, "LOG", LuaUtils::PushLogEntries) ) { KillLua(); return false; } lua_settop(L, 0); // add code from the sub-class if (!base.AddUnsyncedCode(L)) { KillLua(); return false; } lua_settop(L, 0); if (!LoadCode(L, code, file)) { KillLua(); return false; } lua_settop(L, 0); eventHandler.AddClient(this); return true; }
bool CSyncedLuaHandle::Init(const string& code, const string& file) { if (!IsValid()) return false; watchUnitDefs.resize(unitDefHandler->unitDefs.size() + 1, false); watchFeatureDefs.resize(featureHandler->GetFeatureDefs().size(), false); watchWeaponDefs.resize(weaponDefHandler->weaponDefs.size(), false); // load the standard libraries LUA_OPEN_LIB(L, luaopen_base); LUA_OPEN_LIB(L, luaopen_math); LUA_OPEN_LIB(L, luaopen_table); LUA_OPEN_LIB(L, luaopen_string); //LUA_OPEN_LIB(L, luaopen_io); //LUA_OPEN_LIB(L, luaopen_os); //LUA_OPEN_LIB(L, luaopen_package); //LUA_OPEN_LIB(L, luaopen_debug); lua_getglobal(L, "next"); origNextRef = luaL_ref(L, LUA_REGISTRYINDEX); // delete/replace some dangerous functions lua_pushnil(L); lua_setglobal(L, "dofile"); lua_pushnil(L); lua_setglobal(L, "loadfile"); lua_pushnil(L); lua_setglobal(L, "loadlib"); lua_pushnil(L); lua_setglobal(L, "require"); lua_pushnil(L); lua_setglobal(L, "rawequal"); //FIXME not unsafe anymore since split? lua_pushnil(L); lua_setglobal(L, "rawget"); //FIXME not unsafe anymore since split? lua_pushnil(L); lua_setglobal(L, "rawset"); //FIXME not unsafe anymore since split? // lua_pushnil(L); lua_setglobal(L, "getfenv"); // lua_pushnil(L); lua_setglobal(L, "setfenv"); lua_pushnil(L); lua_setglobal(L, "newproxy"); // sync unsafe cause of __gc lua_pushnil(L); lua_setglobal(L, "gcinfo"); lua_pushnil(L); lua_setglobal(L, "collectgarbage"); lua_pushvalue(L, LUA_GLOBALSINDEX); LuaPushNamedCFunc(L, "loadstring", CLuaHandleSynced::LoadStringData); LuaPushNamedCFunc(L, "pairs", SyncedPairs); LuaPushNamedCFunc(L, "next", SyncedNext); lua_pop(L, 1); lua_pushvalue(L, LUA_GLOBALSINDEX); AddBasicCalls(L); // into Global // adjust the math.random() and math.randomseed() calls lua_getglobal(L, "math"); LuaPushNamedCFunc(L, "random", SyncedRandom); LuaPushNamedCFunc(L, "randomseed", SyncedRandomSeed); lua_pop(L, 1); // pop the global math table lua_getglobal(L, "Script"); LuaPushNamedCFunc(L, "AddActionFallback", AddSyncedActionFallback); LuaPushNamedCFunc(L, "RemoveActionFallback", RemoveSyncedActionFallback); LuaPushNamedCFunc(L, "GetWatchUnit", GetWatchUnitDef); LuaPushNamedCFunc(L, "SetWatchUnit", SetWatchUnitDef); LuaPushNamedCFunc(L, "GetWatchFeature", GetWatchFeatureDef); LuaPushNamedCFunc(L, "SetWatchFeature", SetWatchFeatureDef); LuaPushNamedCFunc(L, "GetWatchWeapon", GetWatchWeaponDef); LuaPushNamedCFunc(L, "SetWatchWeapon", SetWatchWeaponDef); lua_pop(L, 1); // add the custom file loader LuaPushNamedCFunc(L, "SendToUnsynced", SendToUnsynced); LuaPushNamedCFunc(L, "CallAsTeam", CLuaHandleSynced::CallAsTeam); LuaPushNamedNumber(L, "COBSCALE", COBSCALE); // load our libraries (LuaSyncedCtrl overrides some LuaUnsyncedCtrl entries) if ( !AddEntriesToTable(L, "VFS", LuaVFS::PushSynced) || !AddEntriesToTable(L, "VFS", LuaZipFileReader::PushSynced) || !AddEntriesToTable(L, "VFS", LuaZipFileWriter::PushSynced) || !AddEntriesToTable(L, "UnitDefs", LuaUnitDefs::PushEntries) || !AddEntriesToTable(L, "WeaponDefs", LuaWeaponDefs::PushEntries) || !AddEntriesToTable(L, "FeatureDefs", LuaFeatureDefs::PushEntries) || !AddEntriesToTable(L, "Script", LuaInterCall::PushEntriesSynced) || !AddEntriesToTable(L, "Spring", LuaUnsyncedCtrl::PushEntries) || !AddEntriesToTable(L, "Spring", LuaSyncedCtrl::PushEntries) || !AddEntriesToTable(L, "Spring", LuaSyncedRead::PushEntries) || !AddEntriesToTable(L, "Game", LuaConstGame::PushEntries) || !AddEntriesToTable(L, "CMD", LuaConstCMD::PushEntries) || !AddEntriesToTable(L, "CMDTYPE", LuaConstCMDTYPE::PushEntries) || !AddEntriesToTable(L, "COB", LuaConstCOB::PushEntries) || !AddEntriesToTable(L, "SFX", LuaConstSFX::PushEntries) || !AddEntriesToTable(L, "LOG", LuaUtils::PushLogEntries) ) { KillLua(); return false; } // add code from the sub-class if (!base.AddSyncedCode(L)) { KillLua(); return false; } lua_settop(L, 0); if (!LoadCode(L, code, file)) { KillLua(); return false; } lua_settop(L, 0); eventHandler.AddClient(this); return true; }
bool CLuaHandleSynced::SetupSynced(lua_State *L, const string& code, const string& filename) { if (!IsValid() || code.empty()) { return false; } lua_pushvalue(L, LUA_GLOBALSINDEX); HSTR_PUSH(L, "EXPORT"); lua_newtable(L); lua_rawset(L, -3); AddBasicCalls(L); // into Global lua_pushliteral(L, "Script"); lua_rawget(L, -2); LuaPushNamedCFunc(L, "AddActionFallback", AddSyncedActionFallback); LuaPushNamedCFunc(L, "RemoveActionFallback", RemoveSyncedActionFallback); LuaPushNamedCFunc(L, "UpdateCallIn", CallOutSyncedUpdateCallIn); LuaPushNamedCFunc(L, "GetWatchUnit", GetWatchUnitDef); LuaPushNamedCFunc(L, "SetWatchUnit", SetWatchUnitDef); LuaPushNamedCFunc(L, "GetWatchFeature", GetWatchFeatureDef); LuaPushNamedCFunc(L, "SetWatchFeature", SetWatchFeatureDef); LuaPushNamedCFunc(L, "GetWatchWeapon", GetWatchWeaponDef); LuaPushNamedCFunc(L, "SetWatchWeapon", SetWatchWeaponDef); lua_pop(L, 1); // add the custom file loader LuaPushNamedCFunc(L, "SendToUnsynced", SendToUnsynced); LuaPushNamedCFunc(L, "loadstring", LoadStringData); LuaPushNamedCFunc(L, "CallAsTeam", CallAsTeam); LuaPushNamedNumber(L, "COBSCALE", COBSCALE); // load our libraries (LuaSyncedCtrl overrides some LuaUnsyncedCtrl entries) if (!AddEntriesToTable(L, "VFS", LuaVFS::PushSynced) || !AddEntriesToTable(L, "VFS", LuaZipFileReader::PushSynced) || !AddEntriesToTable(L, "VFS", LuaZipFileWriter::PushSynced) || !AddEntriesToTable(L, "UnitDefs", LuaUnitDefs::PushEntries) || !AddEntriesToTable(L, "WeaponDefs", LuaWeaponDefs::PushEntries) || !AddEntriesToTable(L, "FeatureDefs", LuaFeatureDefs::PushEntries) || !AddEntriesToTable(L, "Script", LuaSyncedCall::PushEntries) || !AddEntriesToTable(L, "Spring", LuaUnsyncedCtrl::PushEntries) || !AddEntriesToTable(L, "Spring", LuaSyncedCtrl::PushEntries) || !AddEntriesToTable(L, "Spring", LuaSyncedRead::PushEntries) || !AddEntriesToTable(L, "Game", LuaConstGame::PushEntries) || !AddEntriesToTable(L, "CMD", LuaConstCMD::PushEntries) || !AddEntriesToTable(L, "CMDTYPE", LuaConstCMDTYPE::PushEntries) || !AddEntriesToTable(L, "COB", LuaConstCOB::PushEntries) || !AddEntriesToTable(L, "SFX", LuaConstSFX::PushEntries) || !AddEntriesToTable(L, "LOG", LuaUtils::PushLogEntries) ) { KillLua(); return false; } // add code from the sub-class if (!AddSyncedCode(L)) { KillLua(); return false; } lua_settop(L, 0); if (!LoadCode(L, code, filename)) { KillLua(); return false; } return true; }