From 4541412ebce317f0706bfb6578a4cd51dc6c14e9 Mon Sep 17 00:00:00 2001 From: Chris Beck Date: Fri, 29 Aug 2014 19:55:01 -0400 Subject: [PATCH] add lua_kernel_base as a super class of game_lua_kernel This class holds some "basic" initialization and methods that we would want in any lua kernel. It is not pure virtual, it could be instantiated. --- src/CMakeLists.txt | 1 + src/SConscript | 1 + src/scripting/game_lua_kernel.cpp | 89 +------------------- src/scripting/game_lua_kernel.hpp | 12 ++- src/scripting/lua_kernel_base.cpp | 131 ++++++++++++++++++++++++++++++ src/scripting/lua_kernel_base.hpp | 36 ++++++++ 6 files changed, 175 insertions(+), 95 deletions(-) create mode 100644 src/scripting/lua_kernel_base.cpp create mode 100644 src/scripting/lua_kernel_base.hpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7940c135442c..9f1abcf86d62 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -938,6 +938,7 @@ set(wesnoth-main_SRC scripting/debug_lua.cpp scripting/game_lua_kernel.cpp scripting/lua_api.cpp + scripting/lua_kernel_base.cpp scripting/lua_types.cpp settings.cpp side_filter.cpp diff --git a/src/SConscript b/src/SConscript index e10c76637cd2..6e86045cf47c 100644 --- a/src/SConscript +++ b/src/SConscript @@ -522,6 +522,7 @@ wesnoth_sources = Split(""" scripting/debug_lua.cpp scripting/game_lua_kernel.cpp scripting/lua_api.cpp + scripting/lua_kernel_base.cpp scripting/lua_types.cpp settings.cpp side_filter.cpp diff --git a/src/scripting/game_lua_kernel.cpp b/src/scripting/game_lua_kernel.cpp index 2fd954e8f158..540244f1b1fe 100644 --- a/src/scripting/game_lua_kernel.cpp +++ b/src/scripting/game_lua_kernel.cpp @@ -3764,27 +3764,10 @@ static int intf_get_all_vars(lua_State *L) { } LuaKernel::LuaKernel(const config &cfg) - : mState(luaL_newstate()), level_(cfg) + : lua_kernel_base(), level_(cfg) { lua_State *L = mState; - // Open safe libraries. - // Debug and OS are not, but most of their functions will be disabled below. - static const luaL_Reg safe_libs[] = { - { "", luaopen_base }, - { "table", luaopen_table }, - { "string", luaopen_string }, - { "math", luaopen_math }, - { "debug", luaopen_debug }, - { "os", luaopen_os }, - { NULL, NULL } - }; - for (luaL_Reg const *lib = safe_libs; lib->func; ++lib) - { - luaL_requiref(L, lib->name, lib->func, 1); - lua_pop(L, 1); /* remove lib */ - } - // Put some callback functions in the scripting environment. static luaL_Reg const callbacks[] = { { "add_known_unit", &intf_add_known_unit }, @@ -4051,31 +4034,6 @@ LuaKernel::LuaKernel(const config &cfg) lua_remove(L, -2); lua_rawset(L, LUA_REGISTRYINDEX); - // Disable functions from os which we don't want. - lua_getglobal(L, "os"); - lua_pushnil(L); - while(lua_next(L, -2) != 0) { - lua_pop(L, 1); - char const* function = lua_tostring(L, -1); - if(strcmp(function, "clock") == 0 || strcmp(function, "date") == 0 - || strcmp(function, "time") == 0 || strcmp(function, "difftime") == 0) continue; - lua_pushnil(L); - lua_setfield(L, -3, function); - } - lua_pop(L, 1); - - // Disable functions from debug which we don't want. - lua_getglobal(L, "debug"); - lua_pushnil(L); - while(lua_next(L, -2) != 0) { - lua_pop(L, 1); - char const* function = lua_tostring(L, -1); - if(strcmp(function, "traceback") == 0) continue; - lua_pushnil(L); - lua_setfield(L, -3, function); - } - lua_pop(L, 1); - lua_settop(L, 0); } @@ -4263,11 +4221,6 @@ bool LuaKernel::run_event(game_events::queued_event const &ev) return true; } -LuaKernel::~LuaKernel() -{ - lua_close(mState); -} - /** * Executes its upvalue as a wml action. */ @@ -4354,46 +4307,6 @@ bool LuaKernel::run_filter(char const *name, unit const &u) return b; } -/** - * Runs a script on a stack containing @a nArgs arguments. - * @return true if the script was successful and @a nRets return values are available. - */ -bool LuaKernel::execute(char const *prog, int nArgs, int nRets) -{ - lua_State *L = mState; - - // Compile script into a variadic function. - int res = luaL_loadstring(L, prog); - if (res) - { - char const *m = lua_tostring(L, -1); - chat_message("Lua error", m); - ERR_LUA << m << '\n'; - lua_pop(L, 1); - return false; - } - - // Place the function before its arguments. - if (nArgs) - lua_insert(L, -1 - nArgs); - - return luaW_pcall(L, nArgs, nRets); -} - -/** - * Loads the "package" package into the Lua environment. - * This action is inherently unsafe, as Lua scripts will now be able to - * load C libraries on their own, hence granting them the same privileges - * as the Wesnoth binary itsef. - */ -void LuaKernel::load_package() -{ - lua_State *L = mState; - lua_pushcfunction(L, luaopen_package); - lua_pushstring(L, "package"); - lua_call(L, 1, 0); -} - ai::lua_ai_context* LuaKernel::create_lua_ai_context(char const *code, ai::engine_lua *engine) { return ai::lua_ai_context::create(mState,code,engine); diff --git a/src/scripting/game_lua_kernel.hpp b/src/scripting/game_lua_kernel.hpp index b7982d4617f9..6b7f467e1d96 100644 --- a/src/scripting/game_lua_kernel.hpp +++ b/src/scripting/game_lua_kernel.hpp @@ -15,6 +15,8 @@ #ifndef SCRIPTING_LUA_HPP #define SCRIPTING_LUA_HPP +#include "scripting/lua_kernel_base.hpp" // for lua_kernel_base + #include "game_events/action_wml.hpp" // for wml_action, etc #include // for string @@ -30,14 +32,12 @@ struct lua_State; void extract_preload_scripts(config const &); -class LuaKernel +class LuaKernel : public lua_kernel_base { - lua_State *mState; const config &level_; - bool execute(char const *, int, int); + public: LuaKernel(const config &); - ~LuaKernel(); void initialize(); void save_game(config &); void load_game(); @@ -46,11 +46,9 @@ class LuaKernel bool run_wml_action(std::string const &, vconfig const &, game_events::queued_event const &); bool run_filter(char const *name, unit const &u); - /** Runs a plain script. */ - void run(char const *prog) { execute(prog, 0, 0); } + ai::lua_ai_context* create_lua_ai_context(char const *code, ai::engine_lua *engine); ai::lua_ai_action_handler* create_lua_ai_action_handler(char const *code, ai::lua_ai_context &context); - void load_package(); }; #endif diff --git a/src/scripting/lua_kernel_base.cpp b/src/scripting/lua_kernel_base.cpp new file mode 100644 index 000000000000..0648613a05b2 --- /dev/null +++ b/src/scripting/lua_kernel_base.cpp @@ -0,0 +1,131 @@ +/* + Copyright (C) 2014 by Chris Beck + Part of the Battle for Wesnoth Project http://www.wesnoth.org/ + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY. + + See the COPYING file for more details. +*/ + +#include "scripting/lua_kernel_base.hpp" + +#include "global.hpp" + +#include "log.hpp" +#include "lua/lauxlib.h" +#include "lua/lua.h" +#include "lua/lualib.h" + +#ifdef DEBUG_LUA +#include "scripting/debug_lua.hpp" +#endif + +#include "scripting/lua_api.hpp" + +#include +#include + +static lg::log_domain log_scripting_lua("scripting/lua"); +#define LOG_LUA LOG_STREAM(info, log_scripting_lua) +#define WRN_LUA LOG_STREAM(warn, log_scripting_lua) +#define ERR_LUA LOG_STREAM(err, log_scripting_lua) + +lua_kernel_base::lua_kernel_base() + : mState(luaL_newstate()) +{ + lua_State *L = mState; + + // Open safe libraries. + // Debug and OS are not, but most of their functions will be disabled below. + static const luaL_Reg safe_libs[] = { + { "", luaopen_base }, + { "table", luaopen_table }, + { "string", luaopen_string }, + { "math", luaopen_math }, + { "debug", luaopen_debug }, + { "os", luaopen_os }, + { NULL, NULL } + }; + for (luaL_Reg const *lib = safe_libs; lib->func; ++lib) + { + luaL_requiref(L, lib->name, lib->func, 1); + lua_pop(L, 1); /* remove lib */ + } + + // Disable functions from os which we don't want. + lua_getglobal(L, "os"); + lua_pushnil(L); + while(lua_next(L, -2) != 0) { + lua_pop(L, 1); + char const* function = lua_tostring(L, -1); + if(strcmp(function, "clock") == 0 || strcmp(function, "date") == 0 + || strcmp(function, "time") == 0 || strcmp(function, "difftime") == 0) continue; + lua_pushnil(L); + lua_setfield(L, -3, function); + } + lua_pop(L, 1); + + // Disable functions from debug which we don't want. + lua_getglobal(L, "debug"); + lua_pushnil(L); + while(lua_next(L, -2) != 0) { + lua_pop(L, 1); + char const* function = lua_tostring(L, -1); + if(strcmp(function, "traceback") == 0) continue; + lua_pushnil(L); + lua_setfield(L, -3, function); + } + lua_pop(L, 1); + + lua_settop(L, 0); +} + +lua_kernel_base::~lua_kernel_base() +{ + lua_close(mState); +} + +/** + * Runs a script on a stack containing @a nArgs arguments. + * @return true if the script was successful and @a nRets return values are available. + */ +bool lua_kernel_base::execute(char const *prog, int nArgs, int nRets) +{ + lua_State *L = mState; + + // Compile script into a variadic function. + int res = luaL_loadstring(L, prog); + if (res) + { + char const *m = lua_tostring(L, -1); + chat_message("Lua error", m); + ERR_LUA << m << '\n'; + lua_pop(L, 1); + return false; + } + + // Place the function before its arguments. + if (nArgs) + lua_insert(L, -1 - nArgs); + + return luaW_pcall(L, nArgs, nRets); +} + +/** + * Loads the "package" package into the Lua environment. + * This action is inherently unsafe, as Lua scripts will now be able to + * load C libraries on their own, hence granting them the same privileges + * as the Wesnoth binary itsef. + */ +void lua_kernel_base::load_package() +{ + lua_State *L = mState; + lua_pushcfunction(L, luaopen_package); + lua_pushstring(L, "package"); + lua_call(L, 1, 0); +} diff --git a/src/scripting/lua_kernel_base.hpp b/src/scripting/lua_kernel_base.hpp new file mode 100644 index 000000000000..3c4692164746 --- /dev/null +++ b/src/scripting/lua_kernel_base.hpp @@ -0,0 +1,36 @@ +/* + Copyright (C) 2014 by Chris Beck + Part of the Battle for Wesnoth Project http://www.wesnoth.org/ + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY. + + See the COPYING file for more details. +*/ + +#ifndef SCRIPTING_LUA_KERNEL_BASE_HPP +#define SCRIPTING_LUA_KERNEL_BASE_HPP + +#include // for string + +struct lua_State; + +class lua_kernel_base { +protected: + lua_State *mState; + bool execute(char const *, int, int); +public: + lua_kernel_base(); + ~lua_kernel_base(); + + /** Runs a plain script. */ + void run(char const *prog) { execute(prog, 0, 0); } + + void load_package(); +}; + +#endif