Freeciv-3.3
Loading...
Searching...
No Matches
script_server.c
Go to the documentation of this file.
1/*****************************************************************************
2 Freeciv - Copyright (C) 2005 - The Freeciv Project
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12*****************************************************************************/
13
14#ifdef HAVE_CONFIG_H
15#include <fc_config.h>
16#endif
17
18#include <stdarg.h>
19#include <stdlib.h>
20#include <time.h>
21
22/* dependencies/lua */
23#include "lua.h"
24#include "lualib.h"
25
26/* dependencies/tolua */
27#include "tolua.h"
28
29/* utility */
30#include "astring.h"
31#include "log.h"
32#include "mem.h"
33#include "registry.h"
34
35/* common/scriptcore */
36#include "api_game_specenum.h"
37#include "luascript.h"
38#include "luascript_signal.h"
39#include "luascript_func.h"
40#include "tolua_common_a_gen.h"
41#include "tolua_common_z_gen.h"
42#include "tolua_game_gen.h"
43#include "tolua_signal_gen.h"
44
45/* server */
46#include "console.h"
47#include "stdinhand.h"
48
49/* server/scripting */
50#include <tolua_server_gen.h> /* <> so looked from the build directory first. */
51
52#include "script_server.h"
53
54/***********************************************************************/
57static struct fc_lua *fcl_main = NULL;
58static struct fc_lua *fcl_unsafe = NULL;
59
60/***********************************************************************/
63static char *script_server_code = NULL;
64
65static void script_server_vars_init(void);
66static void script_server_vars_free(void);
67static void script_server_vars_load(struct section_file *file);
68static void script_server_vars_save(struct section_file *file);
69static void script_server_code_init(void);
70static void script_server_code_free(void);
71static void script_server_code_load(struct section_file *file);
72static void script_server_code_save(struct section_file *file);
73
74static void script_server_signals_create(void);
75static void script_server_functions_define(void);
76
77static void script_server_cmd_reply(struct fc_lua *fcl, enum log_level level,
78 const char *format, ...)
80
81/***********************************************************************/
87 const char *str)
88{
89 int status;
90 struct connection *save_caller;
92
93 /* Set a log callback function which allows to send the results of the
94 * command to the clients. */
95 save_caller = fcl->caller;
96 save_output_fct = fcl->output_fct;
97 fcl->output_fct = script_server_cmd_reply;
98 fcl->caller = caller;
99
101
102 /* Reset the changes. */
103 fcl->caller = save_caller;
104 fcl->output_fct = save_output_fct;
105
106 return (status == 0);
107}
108
109/***********************************************************************/
112bool script_server_do_string(struct connection *caller, const char *str)
113{
115}
116
117/***********************************************************************/
121 const char *str)
122{
124}
125
126/***********************************************************************/
129bool script_server_load_file(const char *filename, char **buf)
130{
131 FILE *ffile;
132 struct stat stats;
133 char *buffer;
134
135 fc_stat(filename, &stats);
136 ffile = fc_fopen(filename, "r");
137
138 if (ffile != NULL) {
139 int len;
140
141 buffer = fc_malloc(stats.st_size + 1);
142
143 len = fread(buffer, 1, stats.st_size, ffile);
144
145 if (len == stats.st_size) {
146 buffer[len] = '\0';
147
148 *buf = buffer;
149 }
150 fclose(ffile);
151 }
152
153 return 1;
154}
155
156/***********************************************************************/
161 struct connection *caller,
162 const char *filename)
163{
164 int status = 1;
165 struct connection *save_caller;
167
168 /* Set a log callback function which allows to send the results of the
169 * command to the clients. */
170 save_caller = fcl->caller;
171 save_output_fct = fcl->output_fct;
172 fcl->output_fct = script_server_cmd_reply;
173 fcl->caller = caller;
174
175 status = luascript_do_file(fcl, filename);
176
177 /* Reset the changes. */
178 fcl->caller = save_caller;
179 fcl->output_fct = save_output_fct;
180
181 return (status == 0);
182}
183
184/***********************************************************************/
188bool script_server_do_file(struct connection *caller, const char *filename)
189{
190 return script_server_do_file_shared(fcl_main, caller, filename);
191}
192
193/***********************************************************************/
197 const char *filename)
198{
199 return script_server_do_file_shared(fcl_unsafe, caller, filename);
200}
201
202/***********************************************************************/
212
213/***********************************************************************/
216static void script_server_vars_init(void)
217{
218 /* nothing */
219}
220
221/***********************************************************************/
224static void script_server_vars_free(void)
225{
226 /* nothing */
227}
228
229/***********************************************************************/
232static void script_server_vars_load(struct section_file *file)
233{
234 luascript_vars_load(fcl_main, file, "script.vars");
235}
236
237/***********************************************************************/
240static void script_server_vars_save(struct section_file *file)
241{
242 luascript_vars_save(fcl_main, file, "script.vars");
243}
244
245/***********************************************************************/
248static void script_server_code_init(void)
249{
251}
252
253/***********************************************************************/
256static void script_server_code_free(void)
257{
258 if (script_server_code) {
261 }
262}
263
264/***********************************************************************/
267static void script_server_code_load(struct section_file *file)
268{
269 if (!script_server_code) {
270 const char *code;
271 const char *section = "script.code";
272
273 code = secfile_lookup_str_default(file, "", "%s", section);
276 }
277}
278
279/***********************************************************************/
282static void script_server_code_save(struct section_file *file)
283{
284 if (script_server_code) {
286 }
287}
288
289/***********************************************************************/
293{
294 if (fcl_main != NULL) {
296
297 return TRUE;
298 }
299
301 if (fcl_main == NULL) {
303 fcl_main = NULL;
304
305 return FALSE;
306 }
307
312
313#ifdef MESON_BUILD
314 /* Tolua adds 'tolua_' prefix to _open() function names,
315 * and we can't pass it a basename where the original
316 * 'tolua_' has been stripped when generating from meson. */
318#else /* MESON_BUILD */
320#endif /* MESON_BUILD */
321
323
326
329
332
333 /* Add the unsafe instance. */
335 if (fcl_unsafe == NULL) {
338
339 return FALSE;
340 }
341
345
346#ifdef MESON_BUILD
347 /* Tolua adds 'tolua_' prefix to _open() function names,
348 * and we can't pass it a basename where the original
349 * 'tolua_' has been stripped when generating from meson. */
351#else /* MESON_BUILD */
353#endif /* MESON_BUILD */
354
356
359
360 return TRUE;
361}
362
363/***********************************************************************/
367{
368 if (fcl_main != NULL) {
371
372 /* luascript_signal_free() is called by luascript_destroy(). */
374 fcl_main = NULL;
375 }
376
377 if (fcl_unsafe != NULL) {
378 /* luascript_signal_free() is called by luascript_destroy(). */
381 }
382}
383
384/***********************************************************************/
388{
390
391 /* Variables must be loaded after code is loaded and executed,
392 * so we restore their saved state properly */
394}
395
396/***********************************************************************/
404
405/***********************************************************************/
409{
410 va_list args;
411
412 va_start(args, signal_name);
414 va_end(args);
415}
416
417/***********************************************************************/
421{
422 struct signal_deprecator *depr;
423
424 luascript_signal_create(fcl_main, "turn_begin", 2,
426
427 /* Deprecated form of the 'turn_begin' signal that counts real turns
428 * starting from 0. */
429 depr = luascript_signal_create(fcl_main, "turn_started", 2,
431 deprecate_signal(depr, "turn_started", "turn_begin", "3.0", NULL);
432
433 luascript_signal_create(fcl_main, "player_phase_begin", 2,
435 luascript_signal_create(fcl_main, "player_alive_phase_end", 1,
437 luascript_signal_create(fcl_main, "player_phase_end", 1,
439
440 luascript_signal_create(fcl_main, "unit_moved", 3,
442
443 /* Includes all newly-built cities. */
444 luascript_signal_create(fcl_main, "city_built", 1,
446
447 luascript_signal_create(fcl_main, "city_size_change", 3,
449
450 /* Deprecated form of the 'city_size_change' signal for the case of growth. */
451 depr = luascript_signal_create(fcl_main, "city_growth", 2,
453 deprecate_signal(depr, "city_growth", "city_size_change", "2.6", NULL);
454
455 /* Only includes units built in cities, for now. */
456 luascript_signal_create(fcl_main, "unit_built", 2,
458 luascript_signal_create(fcl_main, "building_built", 2,
460
461 /* These can happen for various reasons; the third argument gives the
462 * reason (a simple string identifier). Example identifiers:
463 * "pop_cost", "need_tech", "need_building", "need_special",
464 * "need_terrain", "need_government", "need_nation", "never",
465 * "unavailable". */
466 luascript_signal_create(fcl_main, "unit_cant_be_built", 3,
468 luascript_signal_create(fcl_main, "building_cant_be_built", 3,
471
472 /* Third argument gives a reason; "landlocked", "cant_maintain", "obsolete",
473 * "sold", "disaster", "sabotaged", "razed", "city_destroyed",
474 * "conquered" (applicable for small wonders only)
475 * Fourth argument gives unit that caused that, applicable for "sabotaged"
476 */
477 luascript_signal_create(fcl_main, "building_lost", 4,
480
481 /* The third argument contains the source: "researched", "traded",
482 * "stolen", "hut". */
483 luascript_signal_create(fcl_main, "tech_researched", 3,
486
487 /* First player is city owner, second is enemy. */
488 luascript_signal_create(fcl_main, "city_destroyed", 3,
490
491 /* First player is former owner, second new one. */
492 luascript_signal_create(fcl_main, "city_transferred", 4,
495
496 /* Deprecated form of the 'city_transferred' signal for the case of
497 * conquest. */
498 depr = luascript_signal_create(fcl_main, "city_lost", 3,
500 deprecate_signal(depr, "city_lost", "city_transferred", "2.6", NULL);
501
502 luascript_signal_create(fcl_main, "hut_enter", 2,
504 luascript_signal_create(fcl_main, "hut_frighten", 2,
506
507 luascript_signal_create(fcl_main, "unit_lost", 3,
509
510 luascript_signal_create(fcl_main, "disaster_occurred", 3,
512
515
516 /* Deprecated form of the 'disaster_occurred' signal without 'had_internal_effect'
517 * support. */
518 depr = luascript_signal_create(fcl_main, "disaster", 2,
520 deprecate_signal(depr, "disaster", "disaster_occurred", "2.6", NULL);
521
522 luascript_signal_create(fcl_main, "achievement_gained", 3,
525
526 luascript_signal_create(fcl_main, "map_generated", 0);
527
529
530 luascript_signal_create(fcl_main, "unit_transferred", 2,
532
533 luascript_signal_create(fcl_main, "action_started_unit_unit", 3,
536
537 luascript_signal_create(fcl_main, "action_finished_unit_unit", 4,
540
541 luascript_signal_create(fcl_main, "action_started_unit_stack", 3,
544
545 luascript_signal_create(fcl_main, "action_finished_unit_stack", 4,
548
549 luascript_signal_create(fcl_main, "action_started_unit_units", 3,
552 deprecate_signal(depr, "action_started_unit_units",
553 "action_started_unit_stack", "3.3", NULL);
554
555 luascript_signal_create(fcl_main, "action_finished_unit_units", 4,
558 deprecate_signal(depr, "action_finished_unit_units",
559 "action_finished_unit_stack", "3.3", NULL);
560
561 luascript_signal_create(fcl_main, "action_started_unit_city", 3,
564
565 luascript_signal_create(fcl_main, "action_finished_unit_city", 4,
568
569 luascript_signal_create(fcl_main, "action_started_unit_tile", 3,
572
573 luascript_signal_create(fcl_main, "action_finished_unit_tile", 4,
576
577 luascript_signal_create(fcl_main, "action_started_unit_extras", 3,
580
581 luascript_signal_create(fcl_main, "action_finished_unit_extras", 4,
584
585 luascript_signal_create(fcl_main, "action_started_unit_self", 2,
588
589 luascript_signal_create(fcl_main, "action_finished_unit_self", 3,
592}
593
594/***********************************************************************/
602{
603 luascript_func_add(fcl_main, "respawn_callback", FALSE, 1, 0,
605}
606
607/***********************************************************************/
610bool script_server_call(const char *func_name, ...)
611{
612 bool success;
613
614 va_list args;
615 va_start(args, func_name);
617 va_end(args);
618
619 return success;
620}
621
622/***********************************************************************/
626 const char *format, ...)
627{
628 va_list args;
630 char buf[1024];
631
632 va_start(args, format);
633 fc_vsnprintf(buf, sizeof(buf), format, args);
634 va_end(args);
635
636 switch (level) {
637 case LOG_FATAL:
638 /* Special case - will quit the server. */
639 log_fatal("%s", buf);
640 break;
641 case LOG_ERROR:
642 case LOG_WARN:
644 break;
645 case LOG_NORMAL:
647 break;
648 case LOG_VERBOSE:
650 break;
651 case LOG_DEBUG:
653 break;
654 }
655
656 cmd_reply(CMD_LUA, fcl->caller, rfc_status, "%s", buf);
657}
struct @130::my_agent::@131 stats
int api_game_specenum_open(lua_State *L)
#define str
Definition astring.c:76
@ CMD_LUA
Definition commands.h:94
char * incite_cost
Definition comments.c:76
rfc_status
Definition console.h:35
@ C_DEBUG
Definition console.h:39
@ C_OK
Definition console.h:41
@ C_LOG_BASE
Definition console.h:40
@ C_COMMENT
Definition console.h:37
@ C_WARNING
Definition console.h:50
#define fc_assert_ret_val(condition, val)
Definition log.h:195
#define log_fatal(message,...)
Definition log.h:101
log_level
Definition log.h:29
@ LOG_ERROR
Definition log.h:31
@ LOG_DEBUG
Definition log.h:35
@ LOG_NORMAL
Definition log.h:33
@ LOG_FATAL
Definition log.h:30
@ LOG_VERBOSE
Definition log.h:34
@ LOG_WARN
Definition log.h:32
void luascript_remove_exported_object(struct fc_lua *fcl, void *object)
Definition luascript.c:700
int luascript_do_string(struct fc_lua *fcl, const char *str, const char *name)
Definition luascript.c:617
int luascript_do_file(struct fc_lua *fcl, const char *filename)
Definition luascript.c:637
void luascript_vars_load(struct fc_lua *fcl, struct section_file *file, const char *section)
Definition luascript.c:763
void luascript_vars_save(struct fc_lua *fcl, struct section_file *file, const char *section)
Definition luascript.c:737
struct fc_lua * luascript_new(luascript_log_func_t output_fct, bool secured_environment)
Definition luascript.c:332
void luascript_destroy(struct fc_lua *fcl)
Definition luascript.c:386
void(* luascript_log_func_t)(struct fc_lua *fcl, enum log_level level, const char *format,...) fc__attribute((__format__(__printf__
Definition luascript.h:39
bool luascript_func_call_valist(struct fc_lua *fcl, const char *func_name, va_list args)
void luascript_func_init(struct fc_lua *fcl)
void luascript_func_add(struct fc_lua *fcl, const char *func_name, bool required, int nargs, int nreturns,...)
void luascript_signal_init(struct fc_lua *fcl)
void deprecate_signal(struct signal_deprecator *deprecator, char *signal_name, char *replacement, char *deprecated_since, char *retired_since)
struct signal_deprecator * luascript_signal_create(struct fc_lua *fcl, const char *signal_name, int nargs,...)
void luascript_signal_emit_valist(struct fc_lua *fcl, const char *signal_name, va_list args)
#define fc_strdup(str)
Definition mem.h:43
#define fc_malloc(sz)
Definition mem.h:34
int len
Definition packhand.c:127
const char * secfile_lookup_str_default(const struct section_file *secfile, const char *def, const char *path,...)
#define secfile_insert_str_noescape(secfile, string, path,...)
static bool script_server_do_file_shared(struct fc_lua *fcl, struct connection *caller, const char *filename)
bool script_server_unsafe_do_string(struct connection *caller, const char *str)
static char * script_server_code
static void script_server_vars_free(void)
static void static bool script_server_do_string_shared(struct fc_lua *fcl, struct connection *caller, const char *str)
void script_server_signal_emit(const char *signal_name,...)
bool script_server_do_string(struct connection *caller, const char *str)
static void script_server_vars_load(struct section_file *file)
static struct fc_lua * fcl_main
bool script_server_init(void)
static void script_server_vars_init(void)
bool script_server_call(const char *func_name,...)
static void script_server_code_save(struct section_file *file)
static void script_server_code_init(void)
static void script_server_cmd_reply(struct fc_lua *fcl, enum log_level level, const char *format,...) fc__attribute((__format__(__printf__
void script_server_state_save(struct section_file *file)
static void script_server_vars_save(struct section_file *file)
static void script_server_code_free(void)
void script_server_state_load(struct section_file *file)
void script_server_remove_exported_object(void *object)
static struct fc_lua * fcl_unsafe
static void script_server_functions_define(void)
static void script_server_code_load(struct section_file *file)
bool script_server_unsafe_do_file(struct connection *caller, const char *filename)
static void script_server_signals_create(void)
bool script_server_load_file(const char *filename, char **buf)
void script_server_free(void)
bool script_server_do_file(struct connection *caller, const char *filename)
struct setting_list * level[OLEVELS_NUM]
Definition settings.c:190
void cmd_reply(enum command_id cmd, struct connection *caller, enum rfc_status rfc_status, const char *format,...)
Definition stdinhand.c:420
enum auth_status status
Definition connection.h:217
struct connection * caller
Definition luascript.h:49
lua_State * state
Definition luascript.h:45
int fc_vsnprintf(char *str, size_t n, const char *format, va_list ap)
Definition support.c:886
FILE * fc_fopen(const char *filename, const char *opentype)
Definition support.c:505
int fc_stat(const char *filename, struct stat *buf)
Definition support.c:574
#define fc__attribute(x)
Definition support.h:99
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
TOLUA_API int tolua_common_a_open(lua_State *tolua_S)
TOLUA_API int tolua_common_z_open(lua_State *tolua_S)
TOLUA_API int tolua_game_open(lua_State *tolua_S)
TOLUA_API int tolua_server_open(lua_State *tolua_S)
TOLUA_API int tolua_signal_open(lua_State *tolua_S)