diff --git a/source/glest_game/facilities/auto_test.cpp b/source/glest_game/facilities/auto_test.cpp index 99172ab6..ff2167f0 100644 --- a/source/glest_game/facilities/auto_test.cpp +++ b/source/glest_game/facilities/auto_test.cpp @@ -70,7 +70,7 @@ void AutoTest::updateNewGame(Program *program, MainMenu *mainMenu) { mainMenu->setState(new MenuStateCustomGame(program, mainMenu, false, pNewGame, true, &gameSettings)); } else { - mainMenu->setState(new MenuStateScenario(program, mainMenu, + mainMenu->setState(new MenuStateScenario(program, mainMenu, false, Config::getInstance().getPathListForType(ptScenarios))); } } diff --git a/source/glest_game/game/script_manager.cpp b/source/glest_game/game/script_manager.cpp index 5d051c14..9fc9c71e 100644 --- a/source/glest_game/game/script_manager.cpp +++ b/source/glest_game/game/script_manager.cpp @@ -356,6 +356,24 @@ void ScriptManager::init(World* world, GameCamera *gameCamera, const XmlNode *ro luaScript.loadCode("function " + script->getName() + "()" + script->getCode() + "end\n", script->getName()); } + + //!!! +// string data_path= getGameReadWritePath(GameConstants::path_data_CacheLookupKey); +// if(data_path != ""){ +// endPathWithSlash(data_path); +// } +// string sandboxScriptFilename = data_path + "data/core/scripts/sandbox.lua"; +// string sandboxLuaCode = getFileTextContents(sandboxScriptFilename); +// +// //luaScript.loadCode(sandboxLuaCode + "\n", "megaglest_lua_sandbox"); +// luaScript.setSandboxWrapperFunctionName("runsandboxed"); +// luaScript.setSandboxCode(sandboxLuaCode); +// luaScript.runCode(sandboxLuaCode); + +// // Setup the lua security sandbox here +// luaScript.beginCall("megaglest_lua_sandbox"); +// luaScript.endCall(); + //setup message box messageBox.init( Lang::getInstance().get("Ok") ); messageBox.setEnabled(false); diff --git a/source/glest_game/main/program.cpp b/source/glest_game/main/program.cpp index 3cf0edfe..ac4700b9 100644 --- a/source/glest_game/main/program.cpp +++ b/source/glest_game/main/program.cpp @@ -269,7 +269,8 @@ void Program::initScenario(WindowGl *window, string autoloadScenarioName) { init(window); mainMenu= new MainMenu(this); setState(mainMenu); - mainMenu->setState(new MenuStateScenario(this, mainMenu, Config::getInstance().getPathListForType(ptScenarios),autoloadScenarioName)); + mainMenu->setState(new MenuStateScenario(this, mainMenu, false, + Config::getInstance().getPathListForType(ptScenarios),autoloadScenarioName)); } Program::~Program(){ diff --git a/source/glest_game/menu/menu_state_new_game.cpp b/source/glest_game/menu/menu_state_new_game.cpp index e339b5da..cb723990 100644 --- a/source/glest_game/menu/menu_state_new_game.cpp +++ b/source/glest_game/menu/menu_state_new_game.cpp @@ -96,7 +96,8 @@ void MenuStateNewGame::mouseClick(int x, int y, MouseButton mouseButton){ } else if(buttonScenario.mouseClick(x, y)){ soundRenderer.playFx(coreData.getClickSoundB()); - mainMenu->setState(new MenuStateScenario(program, mainMenu, Config::getInstance().getPathListForType(ptScenarios))); + mainMenu->setState(new MenuStateScenario(program, mainMenu, false, + Config::getInstance().getPathListForType(ptScenarios))); } else if(buttonJoinGame.mouseClick(x, y)){ soundRenderer.playFx(coreData.getClickSoundB()); @@ -108,7 +109,8 @@ void MenuStateNewGame::mouseClick(int x, int y, MouseButton mouseButton){ } else if(buttonTutorial.mouseClick(x, y)){ soundRenderer.playFx(coreData.getClickSoundB()); - mainMenu->setState(new MenuStateScenario(program, mainMenu, Config::getInstance().getPathListForType(ptTutorials))); + mainMenu->setState(new MenuStateScenario(program, mainMenu, true, + Config::getInstance().getPathListForType(ptTutorials))); } else if(buttonReturn.mouseClick(x, y)){ soundRenderer.playFx(coreData.getClickSoundB()); diff --git a/source/glest_game/menu/menu_state_scenario.cpp b/source/glest_game/menu/menu_state_scenario.cpp index 335724de..b9b12c4e 100644 --- a/source/glest_game/menu/menu_state_scenario.cpp +++ b/source/glest_game/menu/menu_state_scenario.cpp @@ -31,10 +31,13 @@ using namespace Shared::Xml; // class MenuStateScenario // ===================================================== -MenuStateScenario::MenuStateScenario(Program *program, MainMenu *mainMenu, const vector &dirList, string autoloadScenarioName): +MenuStateScenario::MenuStateScenario(Program *program, MainMenu *mainMenu, + bool isTutorialMode, const vector &dirList, string autoloadScenarioName) : MenuState(program, mainMenu, "scenario") { containerName = "Scenario"; + this->isTutorialMode = isTutorialMode; + enableScenarioTexturePreview = Config::getInstance().getBool("EnableScenarioTexturePreview","true"); scenarioLogoTexture=NULL; previewLoadDelayTimer=time(NULL); @@ -88,7 +91,12 @@ MenuStateScenario::MenuStateScenario(Program *program, MainMenu *mainMenu, const buttonReturn.setText(lang.get("Return")); buttonPlayNow.setText(lang.get("PlayNow")); - labelScenario.setText(lang.get("Scenario")); + if(this->isTutorialMode == true) { + labelScenario.setText(lang.get("Tutorial")); + } + else { + labelScenario.setText(lang.get("Scenario")); + } //scenario listbox findDirs(dirList, results); @@ -96,7 +104,14 @@ MenuStateScenario::MenuStateScenario(Program *program, MainMenu *mainMenu, const //printf("scenarioFiles[0] [%s]\n",scenarioFiles[0].c_str()); if(results.empty() == true) { - throw megaglest_runtime_error("There are no scenarios found to load"); + //throw megaglest_runtime_error("There are no scenarios found to load"); + mainMessageBoxState=1; + if(this->isTutorialMode == true) { + showMessageBox( "Error: There are no tutorials found to load", "Error detected", false); + } + else { + showMessageBox( "Error: There are no scenarios found to load", "Error detected", false); + } } for(int i= 0; i 0) { + loadScenarioInfo(Scenario::getScenarioPath(dirList, scenarioFiles[listBoxScenario.getSelectedItemIndex()]), &scenarioInfo ); + labelInfo.setText(scenarioInfo.desc); + } GraphicComponent::applyAllCustomProperties(containerName); } @@ -281,23 +298,25 @@ void MenuStateScenario::loadScenarioInfo(string file, ScenarioInfo *scenarioInfo void MenuStateScenario::loadScenarioPreviewTexture(){ if(enableScenarioTexturePreview == true) { - GameSettings gameSettings; - loadGameSettings(&scenarioInfo, &gameSettings); + if(listBoxScenario.getSelectedItemIndex() >= 0) { + GameSettings gameSettings; + loadGameSettings(&scenarioInfo, &gameSettings); - string scenarioLogo = ""; - bool loadingImageUsed = false; + string scenarioLogo = ""; + bool loadingImageUsed = false; - Game::extractScenarioLogoFile(&gameSettings, scenarioLogo, loadingImageUsed); + Game::extractScenarioLogoFile(&gameSettings, scenarioLogo, loadingImageUsed); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] scenarioLogo [%s]\n",__FILE__,__FUNCTION__,__LINE__,scenarioLogo.c_str()); + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] scenarioLogo [%s]\n",__FILE__,__FUNCTION__,__LINE__,scenarioLogo.c_str()); - if(scenarioLogo != "") { - cleanupPreviewTexture(); - scenarioLogoTexture = Renderer::findFactionLogoTexture(scenarioLogo); - } - else { - cleanupPreviewTexture(); - scenarioLogoTexture = NULL; + if(scenarioLogo != "") { + cleanupPreviewTexture(); + scenarioLogoTexture = Renderer::findFactionLogoTexture(scenarioLogo); + } + else { + cleanupPreviewTexture(); + scenarioLogoTexture = NULL; + } } } } diff --git a/source/glest_game/menu/menu_state_scenario.h b/source/glest_game/menu/menu_state_scenario.h index f1e23027..175d227c 100644 --- a/source/glest_game/menu/menu_state_scenario.h +++ b/source/glest_game/menu/menu_state_scenario.h @@ -47,8 +47,10 @@ private: bool enableScenarioTexturePreview; Texture2D *scenarioLogoTexture; + bool isTutorialMode; + public: - MenuStateScenario(Program *program, MainMenu *mainMenu, const vector &dirList, string autoloadScenarioName=""); + MenuStateScenario(Program *program, MainMenu *mainMenu, bool isTutorialMode, const vector &dirList, string autoloadScenarioName=""); virtual ~MenuStateScenario(); void mouseClick(int x, int y, MouseButton mouseButton); diff --git a/source/shared_lib/include/lua/lua_script.h b/source/shared_lib/include/lua/lua_script.h index f6228ea7..60c8f946 100644 --- a/source/shared_lib/include/lua/lua_script.h +++ b/source/shared_lib/include/lua/lua_script.h @@ -39,6 +39,8 @@ private: int argumentCount; string currentLuaFunction; bool currentLuaFunctionIsValid; + string sandboxWrapperFunctionName; + string sandboxCode; void DumpGlobals(); @@ -46,12 +48,16 @@ public: LuaScript(); ~LuaScript(); - void loadCode(const string &code, const string &name); + void loadCode(string code, string name); - void beginCall(const string& functionName); + void beginCall(string functionName); void endCall(); - void registerFunction(LuaFunction luaFunction, const string &functionName); + int runCode(const string code); + void setSandboxWrapperFunctionName(string name); + void setSandboxCode(string code); + + void registerFunction(LuaFunction luaFunction, string functionName); void saveGame(XmlNode *rootNode); void loadGame(const XmlNode *rootNode); diff --git a/source/shared_lib/include/platform/common/platform_common.h b/source/shared_lib/include/platform/common/platform_common.h index 00b072bc..9115e751 100644 --- a/source/shared_lib/include/platform/common/platform_common.h +++ b/source/shared_lib/include/platform/common/platform_common.h @@ -265,6 +265,8 @@ string executable_path(string exeName,bool includeExeNameInPath=false); bool valid_utf8_file(const char* file_name); +string getFileTextContents(string path); + class ValueCheckerVault { protected: diff --git a/source/shared_lib/sources/lua/lua_script.cpp b/source/shared_lib/sources/lua/lua_script.cpp index 17e49165..3a3864e1 100644 --- a/source/shared_lib/sources/lua/lua_script.cpp +++ b/source/shared_lib/sources/lua/lua_script.cpp @@ -50,6 +50,8 @@ LuaScript::LuaScript() { currentLuaFunction = ""; currentLuaFunctionIsValid = false; + sandboxWrapperFunctionName = ""; + sandboxCode = ""; luaState= luaL_newstate(); luaL_openlibs(luaState); @@ -409,7 +411,7 @@ LuaScript::~LuaScript() { lua_close(luaState); } -void LuaScript::loadCode(const string &code, const string &name){ +void LuaScript::loadCode(string code, string name){ Lua_STREFLOP_Wrapper streflopWrapper; //printf("Code [%s]\nName [%s]\n",code.c_str(),name.c_str()); @@ -443,7 +445,22 @@ void LuaScript::loadCode(const string &code, const string &name){ if(SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA,"In [%s::%s Line: %d] name [%s], errorCode = %d\n",__FILE__,__FUNCTION__,__LINE__,name.c_str(),errorCode); } -void LuaScript::beginCall(const string& functionName) { +void LuaScript::setSandboxWrapperFunctionName(string name) { + sandboxWrapperFunctionName = name; +} + +void LuaScript::setSandboxCode(string code) { + sandboxCode = code; +} + +int LuaScript::runCode(string code) { + Lua_STREFLOP_Wrapper streflopWrapper; + + int errorCode = luaL_dostring(luaState,code.c_str()); + return errorCode; +} + +void LuaScript::beginCall(string functionName) { Lua_STREFLOP_Wrapper streflopWrapper; currentLuaFunction = functionName; @@ -451,8 +468,19 @@ void LuaScript::beginCall(const string& functionName) { if(SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA,"In [%s::%s Line: %d] functionName [%s]\n",__FILE__,__FUNCTION__,__LINE__,functionName.c_str()); if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] functionName [%s]\n",__FILE__,__FUNCTION__,__LINE__,functionName.c_str()); + //string funcLuaFunction = functionName; +// if(sandboxWrapperFunctionName != "" && sandboxCode != "") { +// int errorCode= runCode(sandboxCode); +// if(errorCode !=0 ) { +// throw megaglest_runtime_error("Error calling lua function [" + currentLuaFunction + "] error: " + errorToString(errorCode)); +// } +// //functionName = sandboxWrapperFunctionName; +// } lua_getglobal(luaState, functionName.c_str()); + currentLuaFunctionIsValid = lua_isfunction(luaState,lua_gettop(luaState)); + + //printf("currentLuaFunctionIsValid = %d functionName [%s]\n",currentLuaFunctionIsValid,functionName.c_str()); argumentCount= 0; } @@ -462,9 +490,32 @@ void LuaScript::endCall() { if(SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA,"In [%s::%s Line: %d] currentLuaFunction [%s], currentLuaFunctionIsValid = %d\n",__FILE__,__FUNCTION__,__LINE__,currentLuaFunction.c_str(),currentLuaFunctionIsValid); if(currentLuaFunctionIsValid == true) { - int errorCode= lua_pcall(luaState, argumentCount, 0, 0); - if(errorCode !=0 ) { - throw megaglest_runtime_error("Error calling lua function [" + currentLuaFunction + "] error: " + errorToString(errorCode)); + if(sandboxWrapperFunctionName != "" && sandboxCode != "") { + //lua_pushstring(luaState, currentLuaFunction.c_str()); // push 1st argument, the real lua function + //argumentCount = 1; + + string safeWrapper = sandboxWrapperFunctionName + " [[" + currentLuaFunction + "()]]"; + printf("Trying to execute [%s]\n",safeWrapper.c_str()); + int errorCode= runCode(safeWrapper); + if(errorCode !=0 ) { + throw megaglest_runtime_error("Error calling lua function [" + currentLuaFunction + "] error: " + errorToString(errorCode)); + } + + //printf("Trying to execute [%s]\n",currentLuaFunction.c_str()); + //lua_getglobal(luaState, sandboxWrapperFunctionName.c_str()); + //argumentCount = 1; + //lua_pushstring( luaState, currentLuaFunction.c_str() ); + +// int errorCode= lua_pcall(luaState, argumentCount, 0, 0); +// if(errorCode !=0 ) { +// throw megaglest_runtime_error("Error calling lua function [" + currentLuaFunction + "] error: " + errorToString(errorCode)); +// } + } + else { + int errorCode= lua_pcall(luaState, argumentCount, 0, 0); + if(errorCode !=0 ) { + throw megaglest_runtime_error("Error calling lua function [" + currentLuaFunction + "] error: " + errorToString(errorCode)); + } } } else @@ -473,7 +524,7 @@ void LuaScript::endCall() { } } -void LuaScript::registerFunction(LuaFunction luaFunction, const string &functionName) { +void LuaScript::registerFunction(LuaFunction luaFunction, string functionName) { Lua_STREFLOP_Wrapper streflopWrapper; if(SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA,"In [%s::%s Line: %d] functionName [%s]\n",__FILE__,__FUNCTION__,__LINE__,functionName.c_str()); diff --git a/source/shared_lib/sources/platform/common/platform_common.cpp b/source/shared_lib/sources/platform/common/platform_common.cpp index 2e072bdb..b52fb0be 100644 --- a/source/shared_lib/sources/platform/common/platform_common.cpp +++ b/source/shared_lib/sources/platform/common/platform_common.cpp @@ -2114,6 +2114,33 @@ bool valid_utf8_file(const char* file_name) { return result; } +string getFileTextContents(string path) { +#if defined(WIN32) && !defined(__MINGW32__) + FILE *fp = _wfopen(utf8_decode(path).c_str(), L"rb"); + ifstream xmlFile(fp); +#else + ifstream xmlFile(path.c_str(),ios::binary); +#endif + if(xmlFile.is_open() == false) { + throw megaglest_runtime_error("Can not open file: [" + path + "]"); + } + + xmlFile.unsetf(ios::skipws); + + // Determine stream size + xmlFile.seekg(0, ios::end); + streampos size = xmlFile.tellg(); + xmlFile.seekg(0); + + // Load data and add terminating 0 + vector buffer; + buffer.resize(size + (streampos)1); + xmlFile.read(&buffer.front(), static_cast(size)); + buffer[size] = 0; + + return &buffer.front(); +} + // ===================================== // ModeInfo // =====================================