Freeciv21
Develop your civilization from humble roots to a global empire
aiiface.cpp
Go to the documentation of this file.
1 /*__ ___ ***************************************
2 / \ / \ Copyright (c) 1996-2020 Freeciv21 and Freeciv
3 \_ \ / __/ contributors. This file is part of Freeciv21.
4  _\ \ / /__ Freeciv21 is free software: you can redistribute it
5  \___ \____/ __/ and/or modify it under the terms of the GNU General
6  \_ _/ Public License as published by the Free Software
7  | @ @ \_ Foundation, either version 3 of the License,
8  | or (at your option) any later version.
9  _/ /\ You should have received a copy of the GNU
10  /o) (o/\ \_ General Public License along with Freeciv21.
11  \_____/ / If not, see https://www.gnu.org/licenses/.
12  \____/ ********************************************************/
13 
14 #include <fc_config.h>
15 
16 #ifdef AI_MODULES
17 #include <ltdl.h>
18 #endif
19 
20 // utility
21 #include "support.h"
22 
23 // common
24 #include "ai.h"
25 #include "player.h"
26 
27 /* server/advisors */
28 #include "autosettlers.h"
29 
30 /* ai/classic */
31 #include "classicai.h"
32 
33 #include "aiiface.h"
34 
35 #ifdef AI_MOD_STATIC_THREADED
36 bool fc_ai_threaded_setup(struct ai_type *ai);
37 #endif
38 
39 #ifdef AI_MOD_STATIC_TEX
40 bool fc_ai_tex_setup(struct ai_type *ai);
41 #endif
42 
43 #ifdef AI_MOD_STATIC_STUB
44 bool fc_ai_stub_setup(struct ai_type *ai);
45 #endif
46 
47 static struct ai_type *default_ai = nullptr;
48 
49 #ifdef AI_MODULES
53 static const char *fc_module_error(void)
54 {
55  static char def_err[] = "Unknown error";
56  const char *errtxt = lt_dlerror();
57 
58  if (errtxt == nullptr) {
59  return def_err;
60  }
61 
62  return errtxt;
63 }
64 
68 bool load_ai_module(const char *modname)
69 {
70  struct ai_type *ai = ai_type_alloc();
71  bool setup_success;
72  lt_dlhandle handle;
73  bool (*setup_func)(struct ai_type * ai);
74  const char *(*capstr_func)(void);
75  const char *capstr;
76  char buffer[2048];
77  char filename[1024];
78 
79  if (ai == nullptr) {
80  return false;
81  }
82 
83  init_ai(ai);
84 
85  fc_snprintf(filename, sizeof(filename), "fc_ai_%s", modname);
86  fc_snprintf(buffer, sizeof(buffer), "%s", filename);
87  handle = lt_dlopenext(buffer);
88  if (handle == nullptr) {
89  qCritical(_("Cannot open AI module %s (%s)"), filename,
90  fc_module_error());
91  return false;
92  }
93 
94  fc_snprintf(buffer, sizeof(buffer), "%s_capstr", filename);
95  capstr_func = lt_dlsym(handle, buffer);
96  if (capstr_func == nullptr) {
97  qCritical(_("Cannot find capstr function from ai module %s (%s)"),
98  filename, fc_module_error());
99  return false;
100  }
101 
102  capstr = capstr_func();
103  if (strcmp(FC_AI_MOD_CAPSTR, capstr)) {
104  qCritical(_("Incompatible ai module %s:"), filename);
105  qCritical(_(" Module options: %s"), capstr);
106  qCritical(_(" Supported options: %s"), FC_AI_MOD_CAPSTR);
107 
108  return false;
109  }
110 
111  fc_snprintf(buffer, sizeof(buffer), "%s_setup", filename);
112  setup_func = lt_dlsym(handle, buffer);
113  if (setup_func == nullptr) {
114  qCritical(_("Cannot find setup function from ai module %s (%s)"),
115  filename, fc_module_error());
116  return false;
117  }
118  setup_success = setup_func(ai);
119 
120  if (!setup_success) {
121  qCritical(_("Setup of ai module %s failed."), filename);
122  return false;
123  }
124 
125  return TRUE;
126 }
127 #endif // AI_MODULES
128 
132 void ai_init()
133 {
134  bool failure = false;
135 #if !defined(AI_MODULES) || defined(AI_MOD_STATIC_CLASSIC) \
136  || defined(AI_MOD_STATIC_THREADED) || defined(AI_MOD_STATIC_TEX) \
137  || defined(AI_MOD_STATIC_STUB)
138  // First !defined(AI_MODULES) case is for default ai support.
139  struct ai_type *ai;
140 #endif
141 
142 #ifdef AI_MODULES
143  if (lt_dlinit()) {
144  failure = TRUE;
145  }
146  if (!failure) {
147 #ifdef FREECIV_DEBUG
148  /* First search ai modules under directory ai/<module> under
149  current directory. This allows us to run freeciv without
150  installing it. */
151  const char *moduledirs[] = {"classic", "threaded", "tex", "stub",
152  nullptr};
153  int i;
154 
155  for (i = 0; moduledirs[i] != nullptr; i++) {
156  char buf[2048];
157 
158  fc_snprintf(buf, sizeof(buf), "ai/%s", moduledirs[i]);
159  lt_dladdsearchdir(buf);
160  }
161 #endif // FREECIV_DEBUG
162 
163  // Then search ai modules from their installation directory.
164  lt_dladdsearchdir(AI_MODULEDIR);
165  }
166 #endif // AI_MODULES
167 
168 #ifdef AI_MOD_STATIC_CLASSIC
169  ai = ai_type_alloc();
170  if (ai != nullptr) {
171  init_ai(ai);
172  if (!fc_ai_classic_setup(ai)) {
173  qCritical(_("Failed to setup \"%s\" AI module"), "classic");
174  ai_type_dealloc();
175  }
176  }
177 #endif // AI_MOD_STATIC_CLASSIC
178 
179 #ifdef AI_MOD_STATIC_THREADED
180  ai = ai_type_alloc();
181  if (ai != nullptr) {
182  init_ai(ai);
183  if (!fc_ai_threaded_setup(ai)) {
184  qCritical(_("Failed to setup \"%s\" AI module"), "threaded");
185  ai_type_dealloc();
186  }
187  }
188 #endif // AI_MOD_STATIC_THREADED
189 
190 #ifdef AI_MOD_STATIC_TEX
191  ai = ai_type_alloc();
192  if (ai != nullptr) {
193  init_ai(ai);
194  if (!fc_ai_tex_setup(ai)) {
195  qCritical(_("Failed to setup \"%s\" AI module"), "tex");
196  ai_type_dealloc();
197  }
198  }
199 #endif // AI_MOD_STATIC_TEX
200 
201 #ifdef AI_MOD_STATIC_STUB
202  ai = ai_type_alloc();
203  if (ai != nullptr) {
204  init_ai(ai);
205  if (!fc_ai_stub_setup(ai)) {
206  qCritical(_("Failed to setup \"%s\" AI module"), "stub");
207  ai_type_dealloc();
208  }
209  }
210 #endif // AI_MOD_STATIC_STUB
211 
212  default_ai = ai_type_by_name(AI_MOD_DEFAULT);
213 #ifdef AI_MODULES
214  if (default_ai == nullptr) {
215  // Wasn't among statically linked. Try to load dynamic module.
216  if (!failure && !load_ai_module(AI_MOD_DEFAULT)) {
217  failure = TRUE;
218  }
219  if (!failure) {
220  default_ai = ai_type_by_name(AI_MOD_DEFAULT);
221  }
222  }
223 #endif // AI_MODULES
224  if (default_ai == nullptr || failure) {
225  qCritical(
226  _("Failed to setup default AI module \"%s\", cannot continue."),
227  AI_MOD_DEFAULT);
228  exit(EXIT_FAILURE);
229  }
230 }
231 
235 void call_incident(enum incident_type type, enum casus_belli_range scope,
236  const struct action *paction, struct player *violator,
237  struct player *victim)
238 {
239  if (scope == CBR_VICTIM_ONLY) {
240  CALL_PLR_AI_FUNC(incident, victim, type, scope, paction, victim,
241  violator, victim);
242  } else {
243  fc_assert(scope == CBR_INTERNATIONAL_OUTRAGE);
244  players_iterate(receiver)
245  {
246  CALL_PLR_AI_FUNC(incident, receiver, type, scope, paction, receiver,
247  violator, victim);
248  }
249  }
251 }
252 
257 {
258  players_iterate(pplayer) { CALL_PLR_AI_FUNC(refresh, pplayer, pplayer); }
260 }
261 
265 const char *default_ai_type_name() { return default_ai->name; }
void init_ai(struct ai_type *ai)
Initializes AI structure.
Definition: ai.cpp:42
void ai_type_dealloc()
Free latest ai_type.
Definition: ai.cpp:89
struct ai_type * ai_type_by_name(const char *search)
Find ai type with given name.
Definition: ai.cpp:59
struct ai_type * ai_type_alloc()
Return next free ai_type.
Definition: ai.cpp:75
#define FC_AI_MOD_CAPSTR
Definition: ai.h:22
incident_type
Definition: ai.h:40
#define CALL_PLR_AI_FUNC(_func, _player,...)
Definition: ai.h:383
void call_ai_refresh()
Call ai refresh() callback for all players.
Definition: aiiface.cpp:256
void call_incident(enum incident_type type, enum casus_belli_range scope, const struct action *paction, struct player *violator, struct player *victim)
Call incident function of victim.
Definition: aiiface.cpp:235
void ai_init()
Initialize ai stuff.
Definition: aiiface.cpp:132
static struct ai_type * default_ai
Definition: aiiface.cpp:47
const char * default_ai_type_name()
Return name of default ai type.
Definition: aiiface.cpp:265
bool load_ai_module(const char *modname)
bool fc_ai_classic_setup(struct ai_type *ai)
Setup player ai_funcs function pointers.
Definition: classicai.cpp:573
#define _(String)
Definition: fcintl.h:50
#define fc_assert(condition)
Definition: log.h:89
#define players_iterate_end
Definition: player.h:520
#define players_iterate(_pplayer)
Definition: player.h:514
Definition: ai.h:42
void(* refresh)(struct player *pplayer)
Definition: ai.h:309
void(* incident)(enum incident_type type, enum casus_belli_range scope, const struct action *paction, struct player *receiver, struct player *violator, struct player *victim)
Definition: ai.h:281
char name[MAX_LEN_NAME]
Definition: ai.h:43
Definition: player.h:231
bool fc_ai_stub_setup(struct ai_type *ai)
Setup player ai_funcs function pointers.
Definition: stubai.c:39
int fc_snprintf(char *str, size_t n, const char *format,...)
See also fc_utf8_snprintf_trunc(), fc_utf8_snprintf_rep().
Definition: support.cpp:537
bool fc_ai_tex_setup(struct ai_type *ai)
Setup player ai_funcs function pointers.
Definition: texai.c:568
bool fc_ai_threaded_setup(struct ai_type *ai)
Setup player ai_funcs function pointers.
Definition: threadedai.c:563