Freeciv21
Develop your civilization from humble roots to a global empire
luascript.cpp
Go to the documentation of this file.
1 /*
2  Copyright (c) 1996-2020 Freeciv21 and Freeciv contributors. This file is
3  part of Freeciv21. Freeciv21 is free software: you can redistribute it
4  and/or modify it under the terms of the GNU General Public License as
5  published by the Free Software Foundation, either version 3 of the
6  License, or (at your option) any later version. You should have received
7  a copy of the GNU General Public License along with Freeciv21. If not,
8  see https://www.gnu.org/licenses/.
9  */
10 
11 #include <cstdarg>
12 #include <ctime>
13 
14 // Qt
15 
16 /* dependencies/lua */
17 extern "C" {
18 #include "lua.h"
19 #include "lualib.h"
20 }
21 
22 /* dependencies/tolua */
23 #include "tolua.h"
24 
25 // Sol
26 #include "sol/sol.hpp"
27 
28 // utility
29 #include "log.h"
30 #include "registry.h"
31 #include "registry_ini.h"
32 
33 // common
34 #include "map.h"
35 
36 /* common/scriptcore */
37 #include "api_common_intl.h"
38 #include "api_common_utilities.h"
39 #include "luascript_func.h"
40 #include "luascript_signal.h"
41 #include "tolua_common_a_gen.h"
42 
43 #include "luascript.h"
44 
49 #define LUASCRIPT_MAX_EXECUTION_TIME_SEC 5.0
50 #define LUASCRIPT_CHECKINTERVAL 10000
51 
52 // The name used for the freeciv lua struct saved in the lua state.
53 #define LUASCRIPT_GLOBAL_VAR_NAME "__fcl"
54 
70 #define LUASCRIPT_SECURE_LUA_VERSION1 503
71 #define LUASCRIPT_SECURE_LUA_VERSION2 504
72 
73 static const char *luascript_unsafe_symbols_secure[] = {"debug", "dofile",
74  "loadfile", nullptr};
75 
76 static const char *luascript_unsafe_symbols_permissive[] = {
77  "debug", "dofile", "loadfile", nullptr};
78 
79 #if LUA_VERSION_NUM != LUASCRIPT_SECURE_LUA_VERSION1 \
80  && LUA_VERSION_NUM != LUASCRIPT_SECURE_LUA_VERSION2
81 #warning "The script runtime's unsafe symbols information is not up to date."
82 #warning "This can be a big security hole!"
83 #endif
84 
89 #if LUA_VERSION_NUM == 503 || LUA_VERSION_NUM == 504
90 static luaL_Reg luascript_lualibs_secure[] = {
91  // Using default libraries excluding: package, io, os, and bit32
92  {"_G", luaopen_base},
93  {LUA_COLIBNAME, luaopen_coroutine},
94  {LUA_TABLIBNAME, luaopen_table},
95  {LUA_STRLIBNAME, luaopen_string},
96  {LUA_UTF8LIBNAME, luaopen_utf8},
97  {LUA_MATHLIBNAME, luaopen_math},
98  {LUA_DBLIBNAME, luaopen_debug},
99  {nullptr, nullptr}};
100 #else // LUA_VERSION_NUM
101 #error "Unsupported lua version"
102 #endif // LUA_VERSION_NUM
103 
104 static int luascript_report(struct fc_lua *fcl, int status,
105  const char *code);
106 static void luascript_traceback_func_save(lua_State *L);
107 static void luascript_traceback_func_push(lua_State *L);
108 static void luascript_exec_check(lua_State *L, lua_Debug *ar);
109 static void luascript_hook_start(lua_State *L);
110 static void luascript_hook_end(lua_State *L);
111 static void luascript_openlibs(lua_State *L, const luaL_Reg *llib);
112 static void luascript_blacklist(lua_State *L, const char *lsymbols[]);
113 
117 static int luascript_report(struct fc_lua *fcl, int status, const char *code)
118 {
120  fc_assert_ret_val(fcl->state, 0);
121 
122  if (status) {
123  QString str;
124  const char *msg;
125 
126  if (!(msg = lua_tostring(fcl->state, -1))) {
127  msg = "(error with no message)";
128  }
129 
130  // Add error message.
131  str = QStringLiteral("lua error:\t") + msg;
132 
133  luascript_log(fcl, LOG_ERROR, "%s", qUtf8Printable(str));
134  lua_pop(fcl->state, 1);
135  }
136 
137  return status;
138 }
139 
143 static void luascript_traceback_func_save(lua_State *L)
144 {
145  // Find the debug.traceback function, if available
146  lua_getglobal(L, "debug");
147  if (lua_istable(L, -1)) {
148  lua_getfield(L, -1, "traceback");
149  lua_setfield(L, LUA_REGISTRYINDEX, "freeciv_traceback");
150  }
151  lua_pop(L, 1); // pop debug
152 }
153 
157 static void luascript_traceback_func_push(lua_State *L)
158 {
159  lua_getfield(L, LUA_REGISTRYINDEX, "freeciv_traceback");
160 }
161 
165 static void luascript_exec_check(lua_State *L, lua_Debug *ar)
166 {
167  Q_UNUSED(ar)
168  lua_Number exec_clock;
169 
170  lua_getfield(L, LUA_REGISTRYINDEX, "freeciv_exec_clock");
171  exec_clock = lua_tonumber(L, -1);
172  lua_pop(L, 1);
173  if (static_cast<float>(clock() - exec_clock) / CLOCKS_PER_SEC
175  luaL_error(L, "Execution time limit exceeded in script");
176  }
177 }
178 
182 static void luascript_hook_start(lua_State *L)
183 {
184 #if LUASCRIPT_CHECKINTERVAL
185  // Store clock timestamp in the registry
186  lua_pushnumber(L, clock());
187  lua_setfield(L, LUA_REGISTRYINDEX, "freeciv_exec_clock");
188  lua_sethook(L, luascript_exec_check, LUA_MASKCOUNT,
190 #endif
191 }
192 
196 static void luascript_hook_end(lua_State *L)
197 {
198 #if LUASCRIPT_CHECKINTERVAL
199  lua_sethook(L, luascript_exec_check, 0, 0);
200 #endif
201 }
202 
206 static void luascript_openlibs(lua_State *L, const luaL_Reg *llib)
207 {
208  // set results to global table
209  for (; llib->func; llib++) {
210  luaL_requiref(L, llib->name, llib->func, 1);
211  lua_pop(L, 1); // remove lib
212  }
213 }
214 
218 static void luascript_blacklist(lua_State *L, const char *lsymbols[])
219 {
220  int i;
221 
222  for (i = 0; lsymbols[i] != nullptr; i++) {
223  lua_pushnil(L);
224  lua_setglobal(L, lsymbols[i]);
225  }
226 }
227 
231 int luascript_error(lua_State *L, const char *format, ...)
232 {
233  va_list vargs;
234  int ret;
235 
236  va_start(vargs, format);
237  ret = luascript_error_vargs(L, format, vargs);
238  va_end(vargs);
239 
240  return ret;
241 }
242 
248 int luascript_error_vargs(lua_State *L, const char *format, va_list vargs)
249 {
250  fc_assert_ret_val(L != nullptr, 0);
251 
252  luaL_where(L, 1);
253  lua_pushvfstring(L, format, vargs);
254  lua_concat(L, 2);
255 
256  return lua_error(L);
257 }
258 
264 int luascript_arg_error(lua_State *L, int narg, const char *msg)
265 {
266  return luaL_argerror(L, narg, msg);
267 }
268 
273  bool secured_environment)
274 {
275  fc_lua *fcl = new fc_lua[1]();
276 
277  fcl->state = luaL_newstate();
278  if (!fcl->state) {
279  delete[] fcl;
280  fcl = nullptr;
281  return nullptr;
282  }
283  fcl->output_fct = output_fct;
284  fcl->caller = nullptr;
285 
286  if (secured_environment) {
287  luascript_openlibs(fcl->state, luascript_lualibs_secure);
290  } else {
291  luaL_openlibs(fcl->state);
294  }
295 
297 
298  return fcl;
299 }
300 
305 {
306  // Save the freeciv lua struct in the lua state.
307  lua_pushstring(fcl->state, LUASCRIPT_GLOBAL_VAR_NAME);
308  lua_pushlightuserdata(fcl->state, fcl);
309  lua_settable(fcl->state, LUA_REGISTRYINDEX);
310 }
311 
315 struct fc_lua *luascript_get_fcl(lua_State *L)
316 {
317  struct fc_lua *fcl;
318 
319  fc_assert_ret_val(L, nullptr);
320 
321  // Get the freeciv lua struct from the lua state.
322  lua_pushstring(L, LUASCRIPT_GLOBAL_VAR_NAME);
323  lua_gettable(L, LUA_REGISTRYINDEX);
324  fcl = static_cast<fc_lua *>(lua_touserdata(L, -1));
325 
326  // This is an error!
327  fc_assert_ret_val(fcl != nullptr, nullptr);
328 
329  return fcl;
330 }
331 
336 {
337  if (fcl) {
338  fc_assert_ret(fcl->caller == nullptr);
339 
340  // Free function data.
342 
343  // Free signal data.
345 
346  // Free lua state.
347  if (fcl->state) {
348  lua_gc(fcl->state, LUA_GCCOLLECT, 0); // Collected garbage
349  lua_close(fcl->state);
350  }
351  delete[] fcl;
352  }
353 }
354 
358 static void luascript_exec_resource(lua_State *L, const QString &filename)
359 {
360  Q_INIT_RESOURCE(scriptcore);
361 
362  QFile in(filename);
363  if (!in.open(QFile::ReadOnly)) {
364  qCritical() << "Could not find resource:" << in.fileName();
365  qFatal("Missing resource");
366  }
367  const auto data = in.readAll();
368 
369  // We trust that it loads.
370  sol::state_view lua(L);
371  lua.script(data.data(), in.fileName().toStdString());
372 
373  Q_CLEANUP_RESOURCE(scriptcore);
374 }
375 
379 static void luascript_common_a_register(sol::state_view state)
380 {
381  // Intl module
382  state["_"] = api_intl__;
383  state["N_"] = api_intl_N_;
384  state["Q_"] = api_intl_Q_;
385  state["PL_"] = api_intl_PL_;
386 
387  // log module
388  // clang-format off
389  sol::table log = state.create_table_with(
390  "base", api_utilities_log_base,
391  "deprecation_warning", api_utilities_deprecation_warning);
392  log.new_enum("level",
393  "FATAL", LOG_FATAL,
394  "ERROR", LOG_ERROR,
395  "WARN", LOG_WARN,
396  "NORMAL", LOG_NORMAL,
397  "VERBOSE", LOG_VERBOSE,
398  "DEBUG", LOG_DEBUG);
399  // clang-format on
400  state["log"] = log;
401 
402  // Global functions
403  state["random"] = api_utilities_random;
404  state["fc_version"] = api_utilities_fc_version;
405 }
406 
410 void luascript_common_a(lua_State *L)
411 {
412  tolua_common_a_open(L);
414  luascript_exec_resource(L, QStringLiteral(":/lua/tolua_common_a.lua"));
415 }
416 
420 void luascript_common_z(lua_State *L)
421 {
422  luascript_exec_resource(L, QStringLiteral(":/lua/tolua_common_z.lua"));
423 }
424 
428 void luascript_log(struct fc_lua *fcl, QtMsgType level, const char *format,
429  ...)
430 {
431  va_list args;
432 
433  va_start(args, format);
434  luascript_log_vargs(fcl, level, format, args);
435  va_end(args);
436 }
437 
441 void luascript_log_vargs(struct fc_lua *fcl, QtMsgType level,
442  const char *format, va_list args)
443 {
444  char buf[1024];
445 
447  fc_assert_ret(level >= QtDebugMsg && level <= QtInfoMsg);
448 
449  fc_vsnprintf(buf, sizeof(buf), format, args);
450 
451  if (fcl->output_fct) {
452  fcl->output_fct(fcl, level, "%s", buf);
453  } else {
454  log_base(level, "%s", buf);
455  }
456 }
457 
461 void luascript_pop_returns(struct fc_lua *fcl, const char *func_name,
462  int nreturns, enum api_types *preturn_types,
463  va_list args)
464 {
465  int i;
466  lua_State *L;
467 
469  fc_assert_ret(fcl->state);
470  L = fcl->state;
471 
472  for (i = 0; i < nreturns; i++) {
473  enum api_types type = preturn_types[i];
474 
475  fc_assert_ret(api_types_is_valid(type));
476 
477  switch (type) {
478  case API_TYPE_INT: {
479  int isnum;
480  int *pres = va_arg(args, int *);
481 
482  *pres = lua_tointegerx(L, -1, &isnum);
483  if (!isnum) {
484  qCritical("Return value from lua function %s is a %s, want int",
485  func_name, lua_typename(L, lua_type(L, -1)));
486  }
487  } break;
488  case API_TYPE_BOOL: {
489  bool *pres = va_arg(args, bool *);
490  *pres = lua_toboolean(L, -1);
491  } break;
492  case API_TYPE_STRING: {
493  char **pres = va_arg(args, char **);
494 
495  if (lua_isstring(L, -1)) {
496  *pres = fc_strdup(lua_tostring(L, -1));
497  }
498  } break;
499  default: {
500  void **pres = va_arg(args, void **);
501 
502  *pres = tolua_tousertype(fcl->state, -1, nullptr);
503  } break;
504  }
505  lua_pop(L, 1);
506  }
507 }
508 
512 void luascript_push_args(struct fc_lua *fcl, int nargs,
513  enum api_types *parg_types, va_list args)
514 {
515  int i;
516 
518  fc_assert_ret(fcl->state);
519 
520  for (i = 0; i < nargs; i++) {
521  enum api_types type = parg_types[i];
522 
523  fc_assert_ret(api_types_is_valid(type));
524 
525  switch (type) {
526  case API_TYPE_INT: {
527  lua_Integer arg = va_arg(args, lua_Integer);
528  lua_pushinteger(fcl->state, arg);
529  } break;
530  case API_TYPE_BOOL: {
531  int arg = va_arg(args, int);
532  lua_pushboolean(fcl->state, arg);
533  } break;
534  case API_TYPE_STRING: {
535  const char *arg = va_arg(args, const char *);
536  lua_pushstring(fcl->state, arg);
537  } break;
538  default: {
539  const char *name;
540  void *arg;
541 
542  name = api_types_name(type);
543 
544  arg = va_arg(args, void *);
545  tolua_pushusertype(fcl->state, arg, name);
546  } break;
547  }
548  }
549 }
550 
554 bool luascript_check_function(struct fc_lua *fcl, const char *funcname)
555 {
556  bool defined;
557 
558  fc_assert_ret_val(fcl, false);
559  fc_assert_ret_val(fcl->state, false);
560 
561  lua_getglobal(fcl->state, funcname);
562  defined = lua_isfunction(fcl->state, -1);
563  lua_pop(fcl->state, 1);
564 
565  return defined;
566 }
567 
580 int luascript_call(struct fc_lua *fcl, int narg, int nret, const char *code)
581 {
582  int status;
583  int base; // Index of function to call
584  int traceback = 0; // Index of traceback function
585 
587  fc_assert_ret_val(fcl->state, 0);
588 
589  base = lua_gettop(fcl->state) - narg;
590 
591  // Find the traceback function, if available
593  if (lua_isfunction(fcl->state, -1)) {
594  lua_insert(fcl->state, base); // insert traceback before function
595  traceback = base;
596  } else {
597  lua_pop(fcl->state, 1); // pop non-function traceback
598  }
599 
600  luascript_hook_start(fcl->state);
601  status = lua_pcall(fcl->state, narg, nret, traceback);
602  luascript_hook_end(fcl->state);
603 
604  if (status) {
605  luascript_report(fcl, status, code);
606  }
607 
608  if (traceback) {
609  lua_remove(fcl->state, traceback);
610  }
611 
612  return status;
613 }
614 
618 int luascript_do_string(struct fc_lua *fcl, const char *str,
619  const char *name)
620 {
621  int status;
622 
624  fc_assert_ret_val(fcl->state, 0);
625 
626  status = luaL_loadbuffer(fcl->state, str, qstrlen(str), name);
627  if (status) {
628  luascript_report(fcl, status, str);
629  } else {
630  status = luascript_call(fcl, 0, 0, str);
631  }
632  return status;
633 }
634 
638 int luascript_do_file(struct fc_lua *fcl, const char *filename)
639 {
640  int status;
641 
643  fc_assert_ret_val(fcl->state, 0);
644 
645  status = luaL_loadfile(fcl->state, filename);
646  if (status) {
647  luascript_report(fcl, status, nullptr);
648  } else {
649  status = luascript_call(fcl, 0, 0, nullptr);
650  }
651  return status;
652 }
653 
657 bool luascript_callback_invoke(struct fc_lua *fcl, const char *callback_name,
658  int nargs, enum api_types *parg_types,
659  va_list args)
660 {
661  bool stop_emission = false;
662 
663  fc_assert_ret_val(fcl, false);
664  fc_assert_ret_val(fcl->state, false);
665 
666  // The function name
667  lua_getglobal(fcl->state, callback_name);
668 
669  if (!lua_isfunction(fcl->state, -1)) {
670  luascript_log(fcl, LOG_ERROR, "lua error: Unknown callback '%s'",
671  callback_name);
672  lua_pop(fcl->state, 1);
673  return false;
674  }
675 
676  luascript_log(fcl, LOG_DEBUG, "lua callback: '%s'", callback_name);
677 
678  luascript_push_args(fcl, nargs, parg_types, args);
679 
680  // Call the function with nargs arguments, return 1 results
681  if (luascript_call(fcl, nargs, 1, nullptr)) {
682  return false;
683  }
684 
685  // Shall we stop the emission of this signal?
686  if (lua_isboolean(fcl->state, -1)) {
687  stop_emission = lua_toboolean(fcl->state, -1);
688  }
689  lua_pop(fcl->state, 1); // pop return value
690 
691  return stop_emission;
692 }
693 
699 void luascript_remove_exported_object(struct fc_lua *fcl, void *object)
700 {
701  if (fcl && fcl->state) {
702  fc_assert_ret(object != nullptr);
703 
704  /* The following is similar to tolua_release(..) in src/lib/tolua_map.c
705  */
706  // Find the userdata representing 'object'
707  lua_pushstring(fcl->state, "tolua_ubox");
708  // stack: ubox
709  lua_rawget(fcl->state, LUA_REGISTRYINDEX);
710  // stack: ubox u
711  lua_pushlightuserdata(fcl->state, object);
712  // stack: ubox ubox[u]
713  lua_rawget(fcl->state, -2);
714 
715  if (!lua_isnil(fcl->state, -1)) {
716  fc_assert(object == tolua_tousertype(fcl->state, -1, nullptr));
717  // Change API type to 'Nonexistent'
718  // stack: ubox ubox[u] mt
719  tolua_getmetatable(fcl->state, "Nonexistent");
720  lua_setmetatable(fcl->state, -2);
721  // Set the userdata payload to nullptr
722  *(static_cast<void **>(lua_touserdata(fcl->state, -1))) = nullptr;
723  // Remove from ubox
724  // stack: ubox ubox[u] u
725  lua_pushlightuserdata(fcl->state, object);
726  // stack: ubox ubox[u] u nil
727  lua_pushnil(fcl->state);
728  lua_rawset(fcl->state, -4);
729  }
730  lua_pop(fcl->state, 2);
731  }
732 }
733 
737 void luascript_vars_save(struct fc_lua *fcl, struct section_file *file,
738  const char *section)
739 {
740  fc_assert_ret(file);
742  fc_assert_ret(fcl->state);
743 
744  lua_getglobal(fcl->state, "_freeciv_state_dump");
745  if (luascript_call(fcl, 0, 1, nullptr) == 0) {
746  const char *vars;
747 
748  vars = lua_tostring(fcl->state, -1);
749  lua_pop(fcl->state, 1);
750 
751  if (vars) {
752  secfile_insert_str_noescape(file, vars, "%s", section);
753  }
754  } else {
755  // _freeciv_state_dump in tolua_game.pkg is busted
756  luascript_log(fcl, LOG_ERROR, "lua error: Failed to dump variables");
757  }
758 }
759 
763 void luascript_vars_load(struct fc_lua *fcl, struct section_file *file,
764  const char *section)
765 {
766  const char *vars;
767 
768  fc_assert_ret(file);
770  fc_assert_ret(fcl->state);
771 
772  vars = secfile_lookup_str_default(file, "", "%s", section);
774 }
775 
776 /* FIXME: tolua-5.2 does not create a destructor for dynamically
777  * allocated objects in non-C++ code but tries to call it. */
778 /* Thus, avoid returning any non-basic types. If you need them, put here
779  * constructors returning them in lua_Object registering their destructor
780  * in tolua system. (None yet.) */
781 
782 /* To avoid the complexity and overheads of creating such objects for
783  * 4-bit enums, here is a helper function to return Direction objects. */
789 const Direction *luascript_dir(enum direction8 dir)
790 {
791  static const Direction etalon[8] = {
792  DIR8_NORTHWEST, DIR8_NORTH, DIR8_NORTHEAST, DIR8_WEST,
793  DIR8_EAST, DIR8_SOUTHWEST, DIR8_SOUTH, DIR8_SOUTHEAST};
794  if (is_valid_dir(dir)) {
795  return &etalon[dir];
796  } else {
797  return nullptr;
798  }
799 }
const char * api_intl_PL_(sol::this_state s, const char *singular, const char *plural, int n)
Translation helper function.
const char * api_intl_N_(sol::this_state s, const char *untranslated)
Translation helper function.
const char * api_intl_Q_(sol::this_state s, const char *untranslated)
Translation helper function.
const char * api_intl__(sol::this_state s, const char *untranslated)
Translation helper function.
void api_utilities_log_base(sol::this_state s, int level, const char *message)
One log message.
int api_utilities_random(int min, int max)
Generate random number.
const char * api_utilities_fc_version()
Return the version of freeciv lua script.
void api_utilities_deprecation_warning(char *method, char *replacement, char *deprecated_since)
Lua script wants to warn about use of deprecated construct.
static void base(QVariant data1, QVariant data2)
Action "Build Base" for choice dialog.
Definition: dialogs.cpp:2393
const char * name
Definition: inputfile.cpp:118
constexpr auto LOG_DEBUG
Definition: log.h:27
#define fc_assert_ret(condition)
Definition: log.h:112
constexpr auto LOG_ERROR
Definition: log.h:23
constexpr auto LOG_VERBOSE
Definition: log.h:26
#define fc_assert(condition)
Definition: log.h:89
constexpr auto LOG_NORMAL
Definition: log.h:25
constexpr auto LOG_WARN
Definition: log.h:24
#define fc_assert_ret_val(condition, val)
Definition: log.h:114
#define log_base(level, message,...)
Definition: log.h:41
constexpr auto LOG_FATAL
Definition: log.h:22
static int luascript_report(struct fc_lua *fcl, int status, const char *code)
Lua libraries to load (all default libraries, excluding operating system and library loading modules)...
Definition: luascript.cpp:117
void luascript_pop_returns(struct fc_lua *fcl, const char *func_name, int nreturns, enum api_types *preturn_types, va_list args)
Pop return values from the Lua stack.
Definition: luascript.cpp:461
const Direction * luascript_dir(enum direction8 dir)
Returns a pointer to a given value of enum direction8 (always the same address for the same value),...
Definition: luascript.cpp:789
void luascript_push_args(struct fc_lua *fcl, int nargs, enum api_types *parg_types, va_list args)
Push arguments into the Lua stack.
Definition: luascript.cpp:512
static void luascript_traceback_func_push(lua_State *L)
Push the traceback function to the stack.
Definition: luascript.cpp:157
static const char * luascript_unsafe_symbols_secure[]
Definition: luascript.cpp:73
void luascript_init(fc_lua *fcl)
Sets the freeciv lua struct for a lua state.
Definition: luascript.cpp:304
bool luascript_check_function(struct fc_lua *fcl, const char *funcname)
Return if the function 'funcname' is define in the lua state 'fcl->state'.
Definition: luascript.cpp:554
int luascript_error_vargs(lua_State *L, const char *format, va_list vargs)
Internal api error function.
Definition: luascript.cpp:248
#define LUASCRIPT_CHECKINTERVAL
Definition: luascript.cpp:50
static void luascript_openlibs(lua_State *L, const luaL_Reg *llib)
Open lua libraries in the array of library definitions in llib.
Definition: luascript.cpp:206
int luascript_arg_error(lua_State *L, int narg, const char *msg)
Like script_error, but using a prefix identifying the called lua function:
Definition: luascript.cpp:264
#define LUASCRIPT_MAX_EXECUTION_TIME_SEC
Configuration for script execution time limits.
Definition: luascript.cpp:49
bool luascript_callback_invoke(struct fc_lua *fcl, const char *callback_name, int nargs, enum api_types *parg_types, va_list args)
Invoke the 'callback_name' Lua function.
Definition: luascript.cpp:657
void luascript_remove_exported_object(struct fc_lua *fcl, void *object)
Mark any, if exported, full userdata representing 'object' in the current script state as 'Nonexisten...
Definition: luascript.cpp:699
int luascript_do_string(struct fc_lua *fcl, const char *str, const char *name)
lua_dostring replacement with error message showing on errors.
Definition: luascript.cpp:618
int luascript_error(lua_State *L, const char *format,...)
Internal api error function - varg version.
Definition: luascript.cpp:231
int luascript_do_file(struct fc_lua *fcl, const char *filename)
Parse and execute the script at filename.
Definition: luascript.cpp:638
static void luascript_common_a_register(sol::state_view state)
Registers tolua_common_a functions and modules.
Definition: luascript.cpp:379
static void luascript_hook_end(lua_State *L)
Clear function execution guard.
Definition: luascript.cpp:196
static void luascript_exec_check(lua_State *L, lua_Debug *ar)
Check currently excecuting lua function for execution time limit.
Definition: luascript.cpp:165
void luascript_vars_load(struct fc_lua *fcl, struct section_file *file, const char *section)
Load lua variables from file.
Definition: luascript.cpp:763
static void luascript_hook_start(lua_State *L)
Setup function execution guard.
Definition: luascript.cpp:182
void luascript_log_vargs(struct fc_lua *fcl, QtMsgType level, const char *format, va_list args)
Print a message to the selected output handle.
Definition: luascript.cpp:441
static const char * luascript_unsafe_symbols_permissive[]
Definition: luascript.cpp:76
void luascript_common_z(lua_State *L)
Runs tolua_common_z.lua.
Definition: luascript.cpp:420
struct fc_lua * luascript_new(luascript_log_func_t output_fct, bool secured_environment)
Initialize the scripting state.
Definition: luascript.cpp:272
void luascript_log(struct fc_lua *fcl, QtMsgType level, const char *format,...)
Print a message to the selected output handle.
Definition: luascript.cpp:428
void luascript_vars_save(struct fc_lua *fcl, struct section_file *file, const char *section)
Save lua variables to file.
Definition: luascript.cpp:737
void luascript_common_a(lua_State *L)
Runs tolua_common_a.lua.
Definition: luascript.cpp:410
static void luascript_exec_resource(lua_State *L, const QString &filename)
Loads a script from a Qt resource file and executes it.
Definition: luascript.cpp:358
struct fc_lua * luascript_get_fcl(lua_State *L)
Get the freeciv lua struct from a lua state.
Definition: luascript.cpp:315
static void luascript_blacklist(lua_State *L, const char *lsymbols[])
Remove global symbols from lua state L.
Definition: luascript.cpp:218
int luascript_call(struct fc_lua *fcl, int narg, int nret, const char *code)
Evaluate a Lua function call or loaded script on the stack.
Definition: luascript.cpp:580
#define LUASCRIPT_GLOBAL_VAR_NAME
Definition: luascript.cpp:53
static void luascript_traceback_func_save(lua_State *L)
Find the debug.traceback function and store in the registry.
Definition: luascript.cpp:143
void luascript_destroy(struct fc_lua *fcl)
Free the scripting data.
Definition: luascript.cpp:335
void(* luascript_log_func_t)(struct fc_lua *fcl, QtMsgType level, const char *format,...) fc__attribute((__format__(__printf__
Definition: luascript.h:33
void luascript_func_free(struct fc_lua *fcl)
Free the function definitions.
void luascript_signal_free(struct fc_lua *fcl)
Free script signals and callbacks.
enum direction8 Direction
bool is_valid_dir(enum direction8 dir)
Returns TRUE iff the given direction is a valid one.
Definition: map.cpp:1199
const char * secfile_lookup_str_default(const struct section_file *secfile, const char *def, const char *path,...)
Lookup a string value in the secfile.
#define secfile_insert_str_noescape(secfile, string, path,...)
Definition: registry_ini.h:170
static void static sol::state * fcl
Lua virtual machine state.
Definition: script_fcdb.cpp:48
struct setting_list * level[OLEVELS_NUM]
Definition: settings.cpp:167
luascript_log_func_t output_fct
Definition: luascript.h:40
lua_State * state
Definition: luascript.h:38
int fc_vsnprintf(char *str, size_t n, const char *format, va_list ap)
Definition: support.cpp:512
#define fc_strdup(str)
Definition: support.h:111