Crossfire Server, Trunk
check_asset_load_write.cpp
Go to the documentation of this file.
1 #include <stdlib.h>
2 #include <string.h>
3 #include <check.h>
4 #include "global.h"
5 #include <toolkit_common.h>
6 #include <math.h>
7 #include "Archetypes.h"
8 #include "Treasures.h"
9 #include "TreasureLoader.h"
10 #include "TreasureWriter.h"
11 #include "AnimationWriter.h"
12 #include "FaceLoader.h"
13 #include "FaceWriter.h"
14 #include "Faces.h"
15 #include "Animations.h"
16 #include "assets.h"
17 #include "Quests.h"
18 #include "QuestLoader.h"
19 #include "QuestWriter.h"
20 
21 static void setup(void) {
23  assets_init();
24 }
25 
26 static void teardown(void) {
27  assets_free();
28 }
29 
30 char *generate_name(size_t max_length) {
31  static char buf[250];
32  size_t len = rndm(5, MIN(max_length, sizeof(buf) - 1));
33  buf[len] = 0;
34  for (size_t c = 0; c < len; c++) {
35  buf[c] = 'a' + rndm(0, 25);
36  }
37  return buf;
38 }
39 
40 template<class T>
41 static void write_load(T *asset, AssetWriter<T> &writer, AssetLoader &loader) {
43 
44  writer.write(asset, sb);
45 
46  auto length = stringbuffer_length(sb);
47  auto data = stringbuffer_finish(sb);
48  BufferReader *br = bufferreader_init_from_memory(NULL, data, length);
49 
50  loader.load(br, "dummy");
51 
53  free(data);
54 }
55 
56 treasure *generate_random_treasure(Archetypes &arches, int depth, bool single) {
57  treasure *trs = static_cast<treasure *>(calloc(1, sizeof(treasure)));
58  trs->chance = rndm(0, 15);
59  if (rndm(0, 1)) {
60  trs->name = add_string(generate_name(50));
61  trs->list_magic_adjustment = rndm(-3, 8);
62  trs->list_magic_value = rndm(0, 10);
63  } else {
64  trs->item = arches.get(generate_name(50));
65  trs->artifact = add_string(generate_name(49));
66  }
67  trs->magic = rndm(0, 6);
68  trs->nrof = rndm(0, 5);
69  if (rndm(0, 5 - depth) != 0) {
70  trs->next = generate_random_treasure(arches, depth + 1, single);
71  }
72  if (!single && rndm(0, 2) == 0) {
73  trs->next_no = generate_random_treasure(arches, depth + 1, single);
74  }
75  if (!single && rndm(0, 2) == 0) {
76  trs->next_yes = generate_random_treasure(arches, depth + 1, single);
77  }
78  return trs;
79 }
80 
82  treasurelist *list = static_cast<treasurelist *>(calloc(1, sizeof(treasurelist)));
83  list->name = add_string(generate_name(50));
84  bool single = rndm(0, 1) == 0;
85  list->items = generate_random_treasure(arches, 0, single);
86  if (single) {
87  auto i = list->items;
88  while (i) {
89  list->total_chance += i->chance;
90  i = i->next;
91  }
92  }
93  return list;
94 }
95 
96 bool equal(const treasure *left, treasure *right) {
97  if (left == nullptr) {
98  fail_unless(right == nullptr, "left treasure == null but right treasure != null");
99  return true;
100  }
101  fail_unless(right != nullptr, "left treasure != null but right treasure == null");
102  fail_unless(left->item == right->item, "different arch");
103  fail_unless(left->artifact == right->artifact, "different artifacts");
104  fail_unless(left->name == right->name, "different list");
105  fail_unless(left->chance == right->chance, "different chance %d %d", left->chance, right->chance);
106  fail_unless(left->magic == right->magic, "different magic %d %d", left->magic, right->magic);
107  fail_unless(left->nrof == right->nrof, "different nrof %d %d", left->nrof, right->nrof);
108  fail_unless(left->list_magic_value == right->list_magic_value, "different list_magic_value %d %d", left->list_magic_value, right->list_magic_value);
109  fail_unless(left->list_magic_adjustment == right->list_magic_adjustment, "different list_magic_adjustment %d %d", left->list_magic_adjustment, right->list_magic_adjustment);
110  return true;
111 }
112 
113 bool equal(const treasurelist *left, const treasurelist *right) {
114  if (left == nullptr) {
115  fail_unless(right == nullptr, "left list == null but right list != null");
116  return true;
117  }
118  fail_unless(right != nullptr, "left list != null but right list == null");
119  fail_unless(strcmp(left->name, right->name) == 0, "left list name %s != right list name %s", left->name, right->name);
120  fail_unless(equal(left->items, right->items), "left list items != right list items");
121  fail_unless(left->total_chance == right->total_chance, "left list total_chance %d != right list total_chance %d", left->total_chance, right->total_chance);
122  return true;
123 }
124 
125 START_TEST(test_treasure) {
127  Treasures trs;
128  TreasureLoader loader(&trs, &arch, nullptr);
129  TreasureWriter writer;
130 
131  auto generated = generate_random_list(arch);
132 
133  write_load(generated, writer, loader);
134 
135  auto loaded = trs.find(generated->name);
136  fail_unless(loaded, "Treasurelist should have been loaded!");
137  fail_unless(equal(generated, loaded), "loaded treasurelist isn't the same as generated one");
138 
139  trs.define(generated->name, generated);
140  trs.clear();
141  arch.clear();
142 }
143 END_TEST
144 
146  auto anim = static_cast<Animations *>(calloc(1, sizeof(Animations)));
147  anim->name = generate_name(50);
148  anim->facings = pow(2, rndm(0, 3));
149  anim->num_animations = rndm(1, 16);
150  anim->faces = static_cast<const Face **>(calloc(anim->num_animations, sizeof(const Face *)));
151  for (uint8_t f = 0; f < anim->num_animations; f++) {
152  anim->faces[f] = faces.get(generate_name(25));
153  }
154  return anim;
155 }
156 
157 START_TEST(test_animation) {
158  Faces faces;
161 
162  AnimationWriter writer;
163  FaceLoader loader(&faces, &anims, nullptr);
164 
165  write_load(anim, writer, loader);
166 
167  auto loaded = anims.find(anim->name);
168  fail_unless(loaded, "face should have been loaded");
169  ck_assert_str_eq(anim->name, loaded->name);
170  ck_assert_int_eq(anim->num_animations, loaded->num_animations);
171  for (uint8_t f = 0; f < anim->num_animations; f++) {
172  ck_assert_str_eq(anim->faces[f]->name, loaded->faces[f]->name);
173  }
174  ck_assert_int_eq(anim->facings, loaded->facings);
175 
176  anims.define(anim->name, anim);
177  faces.clear();
178  anims.clear();
179 }
180 END_TEST
181 
183  Face *face = static_cast<Face *>(calloc(1, sizeof(Face)));
184  face->name = generate_name(50);
185  if (rndm(0, 10) == 0) {
186  face->smoothface = faces.get(generate_name(50));
187  return face;
188  }
189 
190  face->magicmap = rndm(0, 10);
191  if (rndm(0, 3) == 0) {
192  face->magicmap |= FACE_FLOOR;
193  }
194  face->visibility = rndm(0, 50);
195  if (rndm(0, 3) == 0) {
196  face->smoothface = faces.get(generate_name(50));
197  }
198  return face;
199 }
200 
201 START_TEST(test_face) {
202  Faces faces;
204  FaceWriter writer;
205  FaceLoader loader(&faces, &anims, nullptr);
206 
207  Face *face = generate_face(faces);
208  write_load(face, writer, loader);
209 
210  auto loaded = faces.find(face->name);
211  ck_assert_int_eq(face->magicmap, loaded->magicmap);
212  ck_assert_int_eq(face->visibility, loaded->visibility);
213  if (face->smoothface) {
214  ck_assert(loaded->smoothface);
215  ck_assert_str_eq(face->smoothface->name, loaded->smoothface->name);
216  } else {
217  ck_assert(loaded->smoothface == nullptr);
218  }
219 
220  faces.define(face->name, face);
221  faces.clear();
222  anims.clear();
223 }
224 END_TEST
225 
227  auto c = static_cast<quest_condition *>(calloc(1, sizeof(quest_condition)));
228  c->quest_code = generate_name(33);
229  if (rndm(0, 3) == 0) {
230  c->minstep = -1;
231  c->maxstep = -1;
232  } else if (rndm(0, 2) == 0) {
233  c->minstep = rndm(4, 15);
234  c->maxstep = c->minstep;
235  } else if (rndm(0, 1)) {
236  c->maxstep = rndm(4, 15);
237  } else {
238  c->minstep = rndm(0, 14);
239  c->maxstep = c->minstep + rndm(1, 10);
240  }
241  return c;
242 }
243 
245  auto s = static_cast<quest_step_definition *>(calloc(1, sizeof(quest_step_definition)));
246  s->is_completion_step = rndm(0, 1);
247  s->step = rndm(1, 50);
248  s->step_description = rndm(0, 1) ? generate_name(40) : nullptr;
249  for (int i = rndm(0, 2); i != 0; i--) {
250  auto c = generate_condition();
251  s->conditions.push_back(c);
252  }
253  return s;
254 }
255 
257  auto q = static_cast<quest_definition *>(calloc(1, sizeof(quest_definition)));
258  q->quest_code = add_string(generate_name(30));
259  q->quest_description = add_string(generate_name(100));
260  q->quest_is_system = rndm(0, 1);
261  q->quest_restart = rndm(0, 1);
262  q->quest_title = add_string(generate_name(100));
263  q->quest_comment = rndm(0, 1) ? add_string(generate_name(90)) : nullptr;
264  if (rndm(0, 1)) {
265  q->parent = quests.get(generate_name(25));
266  }
267  if (rndm(0, 1)) {
268  q->face = faces.get(generate_name(25));
269  } else {
270  q->face = faces.get("quest_generic.111");
271  }
272  for (int i = rndm(0, 5); i != 0; i--) {
273  q->steps.push_back(generate_step());
274  }
275  return q;
276 }
277 
279  if (!lc) {
280  ck_assert(rc == nullptr);
281  return;
282  }
283  ck_assert(rc);
284  ck_assert_str_eq(lc->quest_code, rc->quest_code);
285  ck_assert_int_eq(lc->minstep, rc->minstep);
286  ck_assert_int_eq(lc->maxstep, rc->maxstep);
287 }
288 
290  if (!ls) {
291  ck_assert(rs == nullptr);
292  return;
293  }
294  ck_assert(rs);
295  if (ls->step_description)
296  ck_assert_str_eq(ls->step_description, rs->step_description);
297  else
298  ck_assert(rs->step_description == nullptr);
299  ck_assert_int_eq(ls->is_completion_step, rs->is_completion_step);
300  ck_assert_int_eq(ls->step, rs->step);
301 
302  ck_assert_int_eq(ls->conditions.size(), rs->conditions.size());
303  auto li = ls->conditions.cbegin(), ri = rs->conditions.cbegin();
304  while (li != ls->conditions.cend()) {
305  check_conditions(*li, *ri);
306  ++li;
307  ++ri;
308  }
309 }
310 
311 void check_steps(const std::vector<quest_step_definition *> &ls, const std::vector<quest_step_definition *> &rs) {
312  ck_assert(ls.size() == rs.size());
313  for (size_t i = 0; i < ls.size(); i++) {
314  check_step(ls[i], rs[i]);
315  }
316 }
317 
318 START_TEST(test_quest) {
319  Faces faces;
320  Quests quests;
321  QuestWriter writer;
322  QuestLoader loader(&quests, &faces, nullptr);
323 
324  auto quest = generate_quest(quests, faces);
325  write_load(quest, writer, loader);
326 
327  auto loaded = quests.find(quest->quest_code);
328  ck_assert_str_eq(quest->quest_description, loaded->quest_description);
329  ck_assert_str_eq(quest->quest_title, loaded->quest_title);
330  if (quest->quest_comment)
331  ck_assert_str_eq(quest->quest_comment, loaded->quest_comment);
332  else
333  ck_assert(loaded->quest_comment == nullptr);
334  ck_assert_int_eq(quest->quest_restart, loaded->quest_restart);
335  ck_assert_int_eq(quest->quest_is_system, loaded->quest_is_system);
336  ck_assert(quest->face == loaded->face);
337  ck_assert(quest->parent == loaded->parent);
338  check_steps(quest->steps, loaded->steps);
339 
340  quests.define(quest->quest_code, quest);
341  faces.clear();
342  quests.clear();
343 }
344 END_TEST
345 
346 static Suite *shstr_suite(void) {
347  Suite *s = suite_create("asset_load_write");
348  TCase *tc_core = tcase_create("Core");
349 
350  /*setup and teardown will be called before each test in testcase 'tc_core' */
351  tcase_add_checked_fixture(tc_core, setup, teardown);
352 
353  suite_add_tcase(s, tc_core);
354  tcase_add_loop_test(tc_core, test_treasure, 0, 25);
355  tcase_add_loop_test(tc_core, test_animation, 0, 25);
356  tcase_add_loop_test(tc_core, test_face, 0, 25);
357  tcase_add_loop_test(tc_core, test_quest, 0, 25);
358 
359  return s;
360 }
361 
362 int main(void) {
363  int nf;
364  Suite *s = shstr_suite();
365  SRunner *sr = srunner_create(s);
366 
367  srunner_set_xml(sr, LOGDIR "/unit/common/asset_load_write.xml");
368  srunner_set_log(sr, LOGDIR "/unit/common/asset_load_write.out");
369  srunner_set_fork_status(sr, CK_NOFORK);
370  srunner_run_all(sr, CK_ENV); /*verbosity from env variable*/
371  nf = srunner_ntests_failed(sr);
372  srunner_free(sr);
373  return (nf == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
374 }
generate_step
quest_step_definition * generate_step()
Definition: check_asset_load_write.cpp:244
global.h
make_face_from_files.anims
list anims
Definition: make_face_from_files.py:59
TreasureWriter
Definition: TreasureWriter.h:19
stringbuffer_length
size_t stringbuffer_length(StringBuffer *sb)
Definition: stringbuffer.cpp:218
quest_condition::quest_code
sstring quest_code
Definition: quest.h:21
setup
static void setup(void)
Definition: check_asset_load_write.cpp:21
FaceWriter.h
treasure::chance
uint8_t chance
Definition: treasure.h:73
quest_condition::maxstep
int maxstep
Definition: quest.h:24
QuestLoader
Definition: QuestLoader.h:24
AssetsCollection::get
T * get(const Key &name)
Definition: AssetsCollection.h:89
archininventory.arch
arch
DIALOGCHECK MINARGS 1 MAXARGS 1
Definition: archininventory.py:16
treasurelist::items
treasure * items
Definition: treasure.h:92
Treasures.h
c
static event_registration c
Definition: citylife.cpp:425
stringbuffer_new
StringBuffer * stringbuffer_new(void)
Definition: stringbuffer.cpp:57
treasurelist::total_chance
int16_t total_chance
Definition: treasure.h:87
guildoracle.list
list
Definition: guildoracle.py:87
AssetWriter
Definition: AssetWriter.h:22
treasure::list_magic_value
uint8_t list_magic_value
Definition: treasure.h:68
MIN
#define MIN(x, y)
Definition: compat.h:21
bufferreader_destroy
void bufferreader_destroy(BufferReader *br)
Definition: bufferreader.cpp:40
START_TEST
START_TEST(test_treasure)
Definition: check_asset_load_write.cpp:125
main
int main(void)
Definition: check_asset_load_write.cpp:362
quest_step_definition::step
int step
Definition: quest.h:30
Faces.h
FaceWriter
Definition: FaceWriter.h:19
FaceLoader.h
generate_random_list
treasurelist * generate_random_list(Archetypes &arches)
Definition: check_asset_load_write.cpp:81
TreasureLoader
Definition: TreasureLoader.h:25
assets_free
void assets_free()
Definition: assets.cpp:72
buf
StringBuffer * buf
Definition: readable.cpp:1552
TreasureWriter.h
quest_step_definition
Definition: quest.h:29
shstr_suite
static END_TEST Suite * shstr_suite(void)
Definition: check_asset_load_write.cpp:346
AssetsCollection::clear
void clear()
Definition: AssetsCollection.h:69
check_conditions
void check_conditions(const quest_condition *lc, const quest_condition *rc)
Definition: check_asset_load_write.cpp:278
quest
Definition: quest.py:1
stringbuffer_finish
char * stringbuffer_finish(StringBuffer *sb)
Definition: stringbuffer.cpp:76
item.q
q
Definition: item.py:32
toolkit_common.h
treasure::name
sstring name
Definition: treasure.h:66
quest_step_definition::is_completion_step
int is_completion_step
Definition: quest.h:32
treasurelist
Definition: treasure.h:85
add_string
sstring add_string(const char *str)
Definition: shstr.cpp:124
Face::name
sstring name
Definition: face.h:19
write_load
static void write_load(T *asset, AssetWriter< T > &writer, AssetLoader &loader)
Definition: check_asset_load_write.cpp:41
treasurelist::name
sstring name
Definition: treasure.h:86
AssetsCollection::find
T * find(const Key &name)
Definition: AssetsCollection.h:108
treasure::nrof
uint16_t nrof
Definition: treasure.h:79
loaded
pluglist shows those as well as a short text describing each the list will simply appear empty The keyword for the Python plugin is Python plugout< keyword > Unloads a given identified by its _keyword_ So if you want to unload the Python you need to do plugout Python plugin< libname > Loads a given whose _filename_ is libname So in the case of you d have to do a plugin cfpython so Note that all filenames are relative to the default plugin it tries to load all available files in the SHARE plugins directory as plugin libraries It first displays the Initializing the plugin has the opportunity to signal itself by a message on the console Then the server displays an informative message containing both the plugin content and its keyword For the Python the standard load process thus GreenGoblin When a plugin has been loaded
Definition: plugins.txt:42
QuestLoader.h
generate_face
static END_TEST Face * generate_face(Faces &faces)
Definition: check_asset_load_write.cpp:182
QuestWriter
Definition: QuestWriter.h:19
treasure::item
struct archetype * item
Definition: treasure.h:64
FACE_FLOOR
#define FACE_FLOOR
Definition: newclient.h:292
navar-midane_time.data
data
Definition: navar-midane_time.py:11
Faces
Definition: Faces.h:19
generate_random_treasure
treasure * generate_random_treasure(Archetypes &arches, int depth, bool single)
Definition: check_asset_load_write.cpp:56
animate.anim
string anim
Definition: animate.py:20
treasure::next
treasure * next
Definition: treasure.h:69
Face::magicmap
uint8_t magicmap
Definition: face.h:17
quest_condition::minstep
int minstep
Definition: quest.h:22
AnimationWriter
Definition: AnimationWriter.h:19
generate_animation
static END_TEST Animations * generate_animation(Faces &faces)
Definition: check_asset_load_write.cpp:145
equal
bool equal(const treasure *left, treasure *right)
Definition: check_asset_load_write.cpp:96
treasure::next_yes
treasure * next_yes
Definition: treasure.h:70
Face::visibility
uint8_t visibility
Definition: face.h:16
Quests.h
treasure::magic
uint8_t magic
Definition: treasure.h:74
FaceLoader
Definition: FaceLoader.h:23
AssetsCollection::define
T * define(const Key &name, T *asset)
Definition: AssetsCollection.h:120
AssetWriter::write
virtual void write(const T *asset, StringBuffer *buf)=0
bufferreader_init_from_memory
BufferReader * bufferreader_init_from_memory(BufferReader *br, const char *data, size_t length)
Definition: bufferreader.cpp:93
Animations.h
init_hash_table
void init_hash_table(void)
Definition: shstr.cpp:55
QuestWriter.h
quest_condition
Definition: quest.h:20
teardown
static void teardown(void)
Definition: check_asset_load_write.cpp:26
Archetypes.h
BufferReader
Definition: bufferreader.cpp:21
check_step
void check_step(const quest_step_definition *ls, const quest_step_definition *rs)
Definition: check_asset_load_write.cpp:289
generate_quest
quest_definition * generate_quest(Quests &quests, Faces &faces)
Definition: check_asset_load_write.cpp:256
Quests
Definition: Quests.h:19
quest_definition
Definition: quest.h:37
generate_condition
END_TEST quest_condition * generate_condition()
Definition: check_asset_load_write.cpp:226
assets.h
AllAnimations
Definition: Animations.h:19
dragon_attune.faces
dictionary faces
Definition: dragon_attune.py:31
TreasureLoader.h
generate_name
char * generate_name(size_t max_length)
Definition: check_asset_load_write.cpp:30
check_steps
void check_steps(const std::vector< quest_step_definition * > &ls, const std::vector< quest_step_definition * > &rs)
Definition: check_asset_load_write.cpp:311
Face
Definition: face.h:14
treasure::next_no
treasure * next_no
Definition: treasure.h:71
quest_step_definition::conditions
std::vector< quest_condition * > conditions
Definition: quest.h:33
Treasures
Definition: Treasures.h:21
quest_step_definition::step_description
sstring step_description
Definition: quest.h:31
rndm
int rndm(int min, int max)
Definition: utils.cpp:162
Animations
Definition: face.h:25
treasure
Definition: treasure.h:63
AssetLoader::load
virtual void load(BufferReader *reader, const std::string &filename)=0
StringBuffer
Definition: stringbuffer.cpp:25
Face::smoothface
Face * smoothface
Definition: face.h:18
Archetypes
Definition: Archetypes.h:23
quests
static struct_quest ** quests
Definition: mapper.cpp:894
treasure::artifact
sstring artifact
Definition: treasure.h:65
AssetLoader
Definition: AssetLoader.h:24
assets_init
void assets_init()
Definition: assets.cpp:65
AnimationWriter.h
treasure::list_magic_adjustment
int8_t list_magic_adjustment
Definition: treasure.h:67