Skip to content

Commit

Permalink
add lua_kernel_base as a super class of game_lua_kernel
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
cbeck88 committed Nov 9, 2014
1 parent 042b72a commit 4541412
Show file tree
Hide file tree
Showing 6 changed files with 175 additions and 95 deletions.
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions src/SConscript
Expand Up @@ -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
Expand Down
89 changes: 1 addition & 88 deletions src/scripting/game_lua_kernel.cpp
Expand Up @@ -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 },
Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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.
*/
Expand Down Expand Up @@ -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);
Expand Down
12 changes: 5 additions & 7 deletions src/scripting/game_lua_kernel.hpp
Expand Up @@ -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 <string> // for string
Expand All @@ -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();
Expand All @@ -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
131 changes: 131 additions & 0 deletions src/scripting/lua_kernel_base.cpp
@@ -0,0 +1,131 @@
/*
Copyright (C) 2014 by Chris Beck <render787@gmail.com>
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 <cstring>
#include <string>

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);
}
36 changes: 36 additions & 0 deletions src/scripting/lua_kernel_base.hpp
@@ -0,0 +1,36 @@
/*
Copyright (C) 2014 by Chris Beck <render787@gmail.com>
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 <string> // 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

0 comments on commit 4541412

Please sign in to comment.