CLuaRules::CLuaRules() : CLuaHandleSynced("LuaRules", LUA_HANDLE_ORDER_RULES) { if (!IsValid()) { return; } SetFullCtrl(true, true); SetFullRead(true, true); SetCtrlTeam(AllAccessTeam, true); SetReadTeam(AllAccessTeam, true); SetReadAllyTeam(AllAccessTeam, true); SetSelectTeam(AllAccessTeam, true); Init(LuaRulesSyncedFilename, LuaRulesUnsyncedFilename, SPRING_VFS_MOD); if (!IsValid()) { return; } BEGIN_ITERATE_LUA_STATES(); if (SingleState() || L == L_Sim) { haveCommandFallback = HasCallIn(L, "CommandFallback"); haveAllowCommand = HasCallIn(L, "AllowCommand"); haveAllowUnitCreation = HasCallIn(L, "AllowUnitCreation"); haveAllowUnitTransfer = HasCallIn(L, "AllowUnitTransfer"); haveAllowUnitBuildStep = HasCallIn(L, "AllowUnitBuildStep"); haveAllowFeatureCreation = HasCallIn(L, "AllowFeatureCreation"); haveAllowFeatureBuildStep = HasCallIn(L, "AllowFeatureBuildStep"); haveAllowResourceLevel = HasCallIn(L, "AllowResourceLevel"); haveAllowResourceTransfer = HasCallIn(L, "AllowResourceTransfer"); haveAllowDirectUnitControl = HasCallIn(L, "AllowDirectUnitControl"); haveAllowStartPosition = HasCallIn(L, "AllowStartPosition"); haveMoveCtrlNotify = HasCallIn(L, "MoveCtrlNotify"); haveTerraformComplete = HasCallIn(L, "TerraformComplete"); haveAllowWeaponTargetCheck = HasCallIn(L, "AllowWeaponTargetCheck"); haveAllowWeaponTarget = HasCallIn(L, "AllowWeaponTarget"); haveAllowWeaponInterceptTarget = HasCallIn(L, "AllowWeaponInterceptTarget"); haveUnitPreDamaged = HasCallIn(L, "UnitPreDamaged"); haveFeaturePreDamaged = HasCallIn(L, "FeaturePreDamaged"); haveShieldPreDamaged = HasCallIn(L, "ShieldPreDamaged"); } if (SingleState() || L == L_Draw) { haveDrawUnit = HasCallIn(L, "DrawUnit" ); haveDrawFeature = HasCallIn(L, "DrawFeature" ); haveDrawShield = HasCallIn(L, "DrawShield" ); haveDrawProjectile = HasCallIn(L, "DrawProjectile"); SetupUnsyncedFunction(L, "DrawUnit"); SetupUnsyncedFunction(L, "DrawFeature"); SetupUnsyncedFunction(L, "DrawShield"); SetupUnsyncedFunction(L, "DrawProjectile"); SetupUnsyncedFunction(L, "RecvSkirmishAIMessage"); } END_ITERATE_LUA_STATES(); }
void CLuaHandleSynced::RecvFromSynced(lua_State *srcState, int args) { SELECT_UNSYNCED_LUA_STATE(); #if ((LUA_MT_OPT & LUA_STATE) && (LUA_MT_OPT & LUA_MUTEX)) if (!SingleState() && srcState != L) { // Sim thread sends to unsynced --> delay it DelayRecvFromSynced(srcState, args); return; } // Draw thread, delayed already, execute it #endif static const LuaHashString cmdStr("RecvFromSynced"); //LUA_CALL_IN_CHECK(L); -- not valid here if (!cmdStr.GetRegistryFunc(L)) return; // the call is not defined lua_insert(L, 1); // place the function // call the routine SetAllowChanges(false); SetHandleSynced(L, false); lua_State* L_Prev = ForceUnsyncedState(); RunCallIn(cmdStr, args, 0); RestoreState(L_Prev); SetHandleSynced(L, true); SetAllowChanges(true); }
void CLuaHandleSynced::Init(const string& syncedFile, const string& unsyncedFile, const string& modes) { if (!IsValid()) return; if (GetFullCtrl()) { watchUnitDefs.resize(unitDefHandler->unitDefs.size() + 1, false); watchFeatureDefs.resize(featureHandler->GetFeatureDefs().size(), false); watchWeaponDefs.resize(weaponDefHandler->numWeaponDefs, false); } const string syncedCode = LoadFile(syncedFile, modes); const string unsyncedCode = LoadFile(unsyncedFile, modes); if (syncedCode.empty() && unsyncedCode.empty()) { KillLua(); return; } BEGIN_ITERATE_LUA_STATES(); // 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_pushnil(L); lua_setglobal(L, "rawequal"); lua_pushnil(L); lua_setglobal(L, "rawget"); lua_pushnil(L); lua_setglobal(L, "rawset"); // lua_pushnil(L); lua_setglobal(L, "getfenv"); // lua_pushnil(L); lua_setglobal(L, "setfenv"); lua_pushnil(L); lua_setglobal(L, "newproxy"); lua_pushnil(L); lua_setglobal(L, "gcinfo"); lua_pushnil(L); lua_setglobal(L, "collectgarbage"); // use gs->randFloat() for the synchronized code, and disable randomseed() // (this first copies the original functions to the registry for unsynced) if (!SyncifyRandomFuncs(L)) { KillLua(); return; } SetAllowChanges(true, true); SetSynced(true, true); const bool haveSynced = (SingleState() || L == L_Sim) && SetupSynced(L, syncedCode, syncedFile); if (!IsValid()) return; SetAllowChanges(false, true); SetSynced(false, true); const bool haveUnsynced = (SingleState() || L == L_Draw) && SetupUnsynced(L, unsyncedCode, unsyncedFile); if (!IsValid()) return; SetSynced(true, true); SetAllowChanges(true, true); if (!haveSynced && !haveUnsynced) { KillLua(); return; } // register for call-ins eventHandler.AddClient(this); END_ITERATE_LUA_STATES(); }