Galactic Bloodshed
files_shl.cc
Go to the documentation of this file.
1 // Copyright 2014 The Galactic Bloodshed Authors. All rights reserved.
2 // Use of this source code is governed by a license that can be
3 // found in the COPYING file.
4 
5 /* disk input/output routines & msc stuff
6  * all read routines lock the data they just accessed (the file is not
7  * closed). write routines close and thus unlock that area.
8  */
9 
10 #include "gb/files_shl.h"
11 
12 #include <fcntl.h>
13 #include <sqlite3.h>
14 #include <sys/stat.h>
15 #include <unistd.h>
16 
17 #include <cerrno>
18 #include <cstdio>
19 #include <cstdlib>
20 #include <cstring>
21 #include <iostream>
22 #include <memory>
23 #include <stdexcept>
24 
25 #include "gb/files.h"
26 #include "gb/files_rw.h"
27 #include "gb/power.h"
28 #include "gb/races.h"
29 #include "gb/ships.h"
30 #include "gb/tweakables.h"
31 #include "gb/vars.h"
32 
34 
35 sqlite3 *dbconn;
36 
37 static void start_bulk_insert();
38 static void end_bulk_insert();
39 
40 void close_file(int fd) { close(fd); }
41 
42 void initsqldata() { // __attribute__((no_sanitize_memory)) {
43  const char *tbl_create = R"(
44  CREATE TABLE tbl_planet(
45  planet_id INT PRIMARY KEY NOT NULL, star_id INT NOT NULL,
46  planet_order INT NOT NULL, name TEXT NOT NULL, xpos DOUBLE,
47  ypos DOUBLE, ships INT64, Maxx INT, Maxy INT, popn INT64,
48  troops INT64, maxpopn INT64, total_resources INT64, slaved_to INT,
49  type INT, expltimer INT, condition_rtemp INT, condition_temp INT,
50  condition_methane INT, condition_oxygen INT, condition_co2 INT,
51  condition_hydrogen INT, condition_nitrogen INT, condition_sulfur INT,
52  condition_helium INT, condition_other INT, condition_toxic INT,
53  explored INT);
54 
55  CREATE INDEX star_planet ON tbl_planet (star_id, planet_order);
56 
57  CREATE TABLE
58  tbl_sector(planet_id INT NOT NULL, xpos INT NOT NULL, ypos INT NOT NULL,
59  eff INT, fert INT, mobilization INT, crystals INT, resource INT,
60  popn INT64, troops INT64, owner INT, race INT, type INT,
61  condition INT, PRIMARY KEY(planet_id, xpos, ypos));
62 
63  CREATE TABLE tbl_plinfo(
64  planet_id INT PRIMARY KEY NOT NULL, player_id INT NOT NULL, fuel INT,
65  destruct INT, resource INT, popn INT64, troops INT64, crystals INT,
66  prod_res INT, prod_fuel INT, prod_dest INT, prod_crystals INT,
67  prod_money INT64, prod_tech DOUBLE, tech_invest INT, numsectsowned INT,
68  comread INT, mob_set INT, tox_thresh INT, explored INT, autorep INT,
69  tax INT, newtax INT, guns INT, mob_points INT64, est_production DOUBLE);
70 
71  CREATE TABLE tbl_plinfo_routes(planet_id INT PRIMARY KEY NOT NULL,
72  player_id INT, routenum INT,
73  order_set INT, dest_star INT, dest_planet INT,
74  load INT, unload INT, x INT, y INT);
75 
76  CREATE TABLE tbl_star(star_id INT NOT NULL PRIMARY KEY, ships INT, name TEXT,
77  xpos DOUBLE, ypos DOUBLE, numplanets INT, stability INT,
78  nova_stage INT, temperature INT, gravity DOUBLE);
79 
80  CREATE TABLE tbl_star_governor(star_id INT NOT NULL, player_id INT NOT NULL,
81  governor_id INT NOT NULL,
82  PRIMARY KEY(star_id, player_id));
83 
84  CREATE TABLE
85  tbl_star_explored(star_id INT NOT NULL, player_id INT NOT NULL, explored INT,
86  PRIMARY KEY(star_id, player_id));
87 
88  CREATE TABLE
89  tbl_star_inhabited(star_id INT NOT NULL, player_id INT NOT NULL, explored INT,
90  PRIMARY KEY(star_id, player_id));
91 
92  CREATE TABLE tbl_star_playerap(star_id INT NOT NULL, player_id INT NOT NULL,
93  ap INT NOT NULL,
94  PRIMARY KEY(star_id, player_id));
95 
96  CREATE TABLE tbl_stardata(indexnum INT PRIMARY KEY NOT NULL, ships INT);
97 
98  CREATE TABLE tbl_stardata_perplayer(
99  player_id INT PRIMARY KEY NOT NULL, ap INT NOT NULL,
100  VN_hitlist INT NOT NULL, VN_index1 INT NOT NULL, VN_index2 INT NOT NULL);
101 
102  CREATE TABLE tbl_ship(
103  ship_id INT PRIMARY KEY NOT NULL,
104  player_id INT NOT NULL,
105  governor_id INT NOT NULL,
106  name TEXT NOT NULL,
107  shipclass TEXT NOT NULL,
108  race INT NOT NULL,
109  xpos DOUBLE NOT NULL,
110  ypos DOUBLE NOT NULL,
111  mass DOUBLE NOT NULL,
112  land_x INT,
113  land_y INT,
114  destshipno INT,
115  nextship INT,
116  ships INT,
117  armor INT,
118  size INT,
119 
120  max_crew INT,
121  max_resource INT,
122  max_destruct INT,
123  max_fuel INT,
124  max_speed INT,
125  build_type INT,
126  build_cost INT,
127 
128  base_mass DOUBLE,
129  tech DOUBLE,
130  complexity DOUBLE,
131 
132  destruct INT,
133  resource INT,
134  population INT64,
135  troops INT64,
136  crystals INT,
137 
138  aimed_shipno INT,
139  aimed_snum INT,
140  aimed_intensity INT,
141  aimed_pnum INT,
142  aimed_level INT,
143 
144  mind_progenitor INT,
145  mind_target INT,
146  mind_generation INT,
147  mind_busy INT,
148  mind_tampered INT,
149  mind_who_killed INT,
150 
151  pod_decay INT,
152  pod_temperature INT,
153 
154  timer_count INT,
155 
156  impact_x INT,
157  impact_y INT,
158  impact_scatter INT,
159 
160  trigger_radius INT,
161 
162  terraform_index INT,
163 
164  transport_target INT,
165 
166  waste_toxic INT,
167 
168  who_killed INT,
169 
170  navigate_on INT,
171  navigate_speed INT,
172  navigate_turns INT,
173  navigate_bearing INT,
174 
175  protect_maxrng DOUBLE,
176  protect_on INT,
177  protect_planet INT,
178  protect_self INT,
179  protect_evade INT,
180  protect_ship INT,
181 
182  hyper_drive_charge INT,
183  hyper_drive_ready INT,
184  hyper_drive_on INT,
185  hyper_drive_has INT,
186 
187  cew INT,
188  cew_range INT,
189  cloak INT,
190  laser INT,
191  focus INT,
192  fire_laser INT,
193  storbits INT,
194  deststar INT,
195  destpnum INT,
196  pnumorbits INT,
197  whatdest INT,
198  whatorbits INT,
199 
200  damage INT,
201  rad INT,
202  retaliate INT,
203  target INT,
204 
205  type INT,
206  speed INT,
207 
208  active INT,
209  alive INT,
210  mode INT,
211  bombard INT,
212  mounted INT,
213  cloaked INT,
214  sheep INT,
215  docked INT,
216  notified INT,
217  examined INT,
218  on_off INT,
219 
220  merchant INT,
221  guns INT,
222  primary_gun INT,
223  primtype INT,
224  secondary_gun INT,
225  sectype INT,
226 
227  hanger INT,
228  max_hanger INT,
229  mount INT);
230 )";
231  char *err_msg = nullptr;
232  int err = sqlite3_exec(dbconn, tbl_create, nullptr, nullptr, &err_msg);
233  if (err != SQLITE_OK) {
234  fprintf(stderr, "SQL error: %s\n", err_msg);
235  sqlite3_free(err_msg);
236  }
237 }
238 
239 void openstardata(int *fd) {
240  /*printf(" openstardata\n");*/
241  if ((*fd = open(STARDATAFL, O_RDWR | O_CREAT, 0777)) < 0) {
242  perror("openstardata");
243  printf("unable to open %s\n", STARDATAFL);
244  exit(-1);
245  }
246 }
247 
248 void openshdata(int *fd) {
249  if ((*fd = open(SHIPDATAFL, O_RDWR | O_CREAT, 0777)) < 0) {
250  perror("openshdata");
251  printf("unable to open %s\n", SHIPDATAFL);
252  exit(-1);
253  }
254 }
255 
256 void opencommoddata(int *fd) {
257  if ((*fd = open(COMMODDATAFL, O_RDWR | O_CREAT, 0777)) < 0) {
258  perror("opencommoddata");
259  printf("unable to open %s\n", COMMODDATAFL);
260  exit(-1);
261  }
262 }
263 
264 void openracedata(int *fd) {
265  if ((*fd = open(RACEDATAFL, O_RDWR | O_CREAT, 0777)) < 0) {
266  perror("openrdata");
267  printf("unable to open %s\n", RACEDATAFL);
268  exit(-1);
269  }
270 }
271 
272 void getsdata(struct stardata *S) {
273  Fileread(stdata, (char *)S, sizeof(struct stardata), 0);
274 }
275 
276 void getrace(Race **r, int rnum) {
277  *r = (Race *)malloc(sizeof(Race));
278  Fileread(racedata, (char *)*r, sizeof(Race), (rnum - 1) * sizeof(Race));
279 }
280 
281 void getstar(startype **s, int star) {
282  if (s >= &Stars[0] && s < &Stars[NUMSTARS])
283  ; /* Do nothing */
284  else {
285  *s = (startype *)malloc(sizeof(startype));
286  }
287  memset(*s, 0, sizeof(startype));
288  Fileread(stdata, (char *)*s, sizeof(startype),
289  (int)(sizeof(Sdata) + star * sizeof(startype)));
290  const char *tail;
291 
292  {
293  sqlite3_stmt *stmt;
294  const char *sql =
295  "SELECT ships, name, xpos, ypos, "
296  "numplanets, stability, nova_stage, temperature, gravity "
297  "FROM tbl_star WHERE star_id=?1 LIMIT 1";
298  sqlite3_prepare_v2(dbconn, sql, -1, &stmt, &tail);
299 
300  sqlite3_bind_int(stmt, 1, star);
301  sqlite3_step(stmt);
302  (*s)->ships = static_cast<short>(sqlite3_column_int(stmt, 0));
303  strcpy((*s)->name,
304  reinterpret_cast<const char *>(sqlite3_column_text(stmt, 1)));
305  (*s)->xpos = sqlite3_column_double(stmt, 2);
306  (*s)->ypos = sqlite3_column_double(stmt, 3);
307  (*s)->numplanets = static_cast<short>(sqlite3_column_int(stmt, 4));
308  (*s)->stability = static_cast<short>(sqlite3_column_int(stmt, 5));
309  (*s)->nova_stage = static_cast<short>(sqlite3_column_int(stmt, 6));
310  (*s)->temperature = static_cast<short>(sqlite3_column_int(stmt, 7));
311  (*s)->gravity = sqlite3_column_double(stmt, 8);
312 
313  sqlite3_clear_bindings(stmt);
314  sqlite3_reset(stmt);
315  }
316  {
317  sqlite3_stmt *stmt;
318  const char *sql =
319  "SELECT player_id, governor_id FROM tbl_star_governor "
320  "WHERE star_id=?1";
321  sqlite3_prepare_v2(dbconn, sql, -1, &stmt, &tail);
322 
323  sqlite3_bind_int(stmt, 1, star);
324 
325  while (sqlite3_step(stmt) == SQLITE_ROW) {
326  player_t p = sqlite3_column_int(stmt, 0);
327  (*s)->governor[p - 1] = sqlite3_column_int(stmt, 1);
328  }
329 
330  sqlite3_clear_bindings(stmt);
331  sqlite3_reset(stmt);
332  }
333 }
334 
335 Planet getplanet(const starnum_t star, const planetnum_t pnum) {
336  const char *tail;
337  const char *plinfo_tail;
338  const char *plinfo_routes_tail;
339  sqlite3_stmt *stmt;
340  sqlite3_stmt *plinfo_stmt;
341  sqlite3_stmt *plinfo_routes_stmt;
342  const char *sql =
343  "SELECT planet_id, star_id, planet_order, name, "
344  "xpos, ypos, ships, maxx, maxy, popn, troops, maxpopn, total_resources, "
345  "slaved_to, type, expltimer, condition_rtemp, condition_temp, "
346  "condition_methane, condition_oxygen, condition_co2, "
347  "condition_hydrogen, condition_nitrogen, condition_sulfur, "
348  "condition_helium, condition_other, condition_toxic, "
349  "explored FROM tbl_planet WHERE star_id=?1 AND planet_order=?2";
350  sqlite3_prepare_v2(dbconn, sql, -1, &stmt, &tail);
351 
352  sqlite3_bind_int(stmt, 1, star);
353  sqlite3_bind_int(stmt, 2, pnum);
354 
355  auto result = sqlite3_step(stmt);
356  if (result != SQLITE_ROW) {
357  throw std::runtime_error("Database unable to return the requested planet");
358  }
359 
360  Planet p;
361  p.planet_id = sqlite3_column_int(stmt, 0);
362  p.xpos = sqlite3_column_double(stmt, 4);
363  p.ypos = sqlite3_column_double(stmt, 5);
364  p.ships = sqlite3_column_int(stmt, 6);
365  p.Maxx = sqlite3_column_int(stmt, 7);
366  p.Maxy = sqlite3_column_int(stmt, 8);
367  p.popn = sqlite3_column_int(stmt, 9);
368  p.troops = sqlite3_column_int(stmt, 10);
369  p.maxpopn = sqlite3_column_int(stmt, 11);
370  p.total_resources = sqlite3_column_int(stmt, 12);
371  p.slaved_to = sqlite3_column_int(stmt, 13);
372  int p_type = sqlite3_column_int(stmt, 14);
373  switch (p_type) {
374  case 0:
375  p.type = PlanetType::EARTH;
376  break;
377  case 1:
378  p.type = PlanetType::ASTEROID;
379  break;
380  case 2:
381  p.type = PlanetType::MARS;
382  break;
383  case 3:
384  p.type = PlanetType::ICEBALL;
385  break;
386  case 4:
387  p.type = PlanetType::GASGIANT;
388  break;
389  case 5:
390  p.type = PlanetType::WATER;
391  break;
392  case 6:
393  p.type = PlanetType::FOREST;
394  break;
395  case 7:
396  p.type = PlanetType::DESERT;
397  break;
398  default:
399  throw std::runtime_error("Bad data in type field");
400  }
401  p.expltimer = sqlite3_column_int(stmt, 15);
402  p.conditions[RTEMP] = sqlite3_column_int(stmt, 16);
403  p.conditions[TEMP] = sqlite3_column_int(stmt, 17);
404  p.conditions[METHANE] = sqlite3_column_int(stmt, 18);
405  p.conditions[OXYGEN] = sqlite3_column_int(stmt, 19);
406  p.conditions[CO2] = sqlite3_column_int(stmt, 20);
407  p.conditions[HYDROGEN] = sqlite3_column_int(stmt, 21);
408  p.conditions[NITROGEN] = sqlite3_column_int(stmt, 22);
409  p.conditions[SULFUR] = sqlite3_column_int(stmt, 23);
410  p.conditions[HELIUM] = sqlite3_column_int(stmt, 24);
411  p.conditions[OTHER] = sqlite3_column_int(stmt, 25);
412  p.conditions[TOXIC] = sqlite3_column_int(stmt, 26);
413 
414  const char *plinfo_sql =
415  "SELECT planet_id, player_id, fuel, destruct, "
416  "resource, popn, troops, crystals, prod_res, "
417  "prod_fuel, prod_dest, prod_crystals, prod_money, "
418  "prod_tech, tech_invest, numsectsowned, comread, "
419  "mob_set, tox_thresh, explored, autorep, tax, "
420  "newtax, guns, mob_points, est_production FROM tbl_plinfo "
421  "WHERE planet_id=?1";
422  sqlite3_prepare_v2(dbconn, plinfo_sql, -1, &plinfo_stmt, &plinfo_tail);
423  sqlite3_bind_int(plinfo_stmt, 1, p.planet_id);
424  while (sqlite3_step(stmt) == SQLITE_ROW) {
425  int player_id = sqlite3_column_int(plinfo_stmt, 1);
426  p.info[player_id].fuel = sqlite3_column_int(plinfo_stmt, 2);
427  p.info[player_id].destruct = sqlite3_column_int(plinfo_stmt, 3);
428  p.info[player_id].resource = sqlite3_column_int(plinfo_stmt, 4);
429  p.info[player_id].popn = sqlite3_column_int(plinfo_stmt, 5);
430  p.info[player_id].troops = sqlite3_column_int(plinfo_stmt, 6);
431  p.info[player_id].crystals = sqlite3_column_int(plinfo_stmt, 7);
432  p.info[player_id].prod_res = sqlite3_column_int(plinfo_stmt, 8);
433  p.info[player_id].prod_fuel = sqlite3_column_int(plinfo_stmt, 9);
434  p.info[player_id].prod_dest = sqlite3_column_int(plinfo_stmt, 10);
435  p.info[player_id].prod_crystals = sqlite3_column_int(plinfo_stmt, 11);
436  p.info[player_id].prod_money = sqlite3_column_int(plinfo_stmt, 12);
437  p.info[player_id].prod_tech = sqlite3_column_int(plinfo_stmt, 13);
438  p.info[player_id].tech_invest = sqlite3_column_int(plinfo_stmt, 14);
439  p.info[player_id].numsectsowned = sqlite3_column_int(plinfo_stmt, 15);
440  p.info[player_id].comread = sqlite3_column_int(plinfo_stmt, 16);
441  p.info[player_id].mob_set = sqlite3_column_int(plinfo_stmt, 17);
442  p.info[player_id].tox_thresh = sqlite3_column_int(plinfo_stmt, 18);
443  p.info[player_id].explored = sqlite3_column_int(plinfo_stmt, 19);
444  p.info[player_id].autorep = sqlite3_column_int(plinfo_stmt, 20);
445  p.info[player_id].tax = sqlite3_column_int(plinfo_stmt, 21);
446  p.info[player_id].newtax = sqlite3_column_int(plinfo_stmt, 22);
447  p.info[player_id].guns = sqlite3_column_int(plinfo_stmt, 23);
448  p.info[player_id].mob_points = sqlite3_column_int(plinfo_stmt, 24);
449  p.info[player_id].est_production = sqlite3_column_int(plinfo_stmt, 25);
450  }
451 
452  const char *plinfo_routes_sql =
453  "SELECT planet_id, player_id, routenum, order_set, dest_star, "
454  "dest_planet, load, unload, x, y FROM tbl_plinfo_routes WHERE "
455  "planet_id=1";
456  sqlite3_prepare_v2(dbconn, plinfo_routes_sql, -1, &plinfo_routes_stmt,
457  &plinfo_routes_tail);
458  sqlite3_bind_int(plinfo_routes_stmt, 1, p.planet_id);
459  while (sqlite3_step(stmt) == SQLITE_ROW) {
460  int player_id = sqlite3_column_int(plinfo_routes_stmt, 1);
461  int routenum = sqlite3_column_int(plinfo_routes_stmt, 2);
462  p.info[player_id].route[routenum].set =
463  sqlite3_column_int(plinfo_routes_stmt, 3);
464  p.info[player_id].route[routenum].dest_star =
465  sqlite3_column_int(plinfo_routes_stmt, 4);
466  p.info[player_id].route[routenum].dest_planet =
467  sqlite3_column_int(plinfo_routes_stmt, 5);
468  p.info[player_id].route[routenum].load =
469  sqlite3_column_int(plinfo_routes_stmt, 6);
470  p.info[player_id].route[routenum].unload =
471  sqlite3_column_int(plinfo_routes_stmt, 7);
472  p.info[player_id].route[routenum].x =
473  sqlite3_column_int(plinfo_routes_stmt, 8);
474  p.info[player_id].route[routenum].y =
475  sqlite3_column_int(plinfo_routes_stmt, 9);
476  }
477  return p;
478 }
479 
480 Sector getsector(const Planet &p, const int x, const int y) {
481  const char *tail;
482  sqlite3_stmt *stmt;
483  const char *sql =
484  "SELECT planet_id, xpos, ypos, eff, fert, "
485  "mobilization, crystals, resource, popn, troops, owner, "
486  "race, type, condition FROM tbl_sector "
487  "WHERE planet_id=?1 AND xpos=?2 AND ypos=?3";
488  sqlite3_prepare_v2(dbconn, sql, -1, &stmt, &tail);
489 
490  sqlite3_bind_int(stmt, 1, p.planet_id);
491  sqlite3_bind_int(stmt, 2, x);
492  sqlite3_bind_int(stmt, 3, y);
493 
494  auto result = sqlite3_step(stmt);
495  if (result != SQLITE_ROW) {
496  throw std::runtime_error("Database unable to return the requested sector");
497  }
498 
499  Sector s(sqlite3_column_int(stmt, 1), // xpos
500  sqlite3_column_int(stmt, 2), // ypos
501  sqlite3_column_int(stmt, 3), // eff
502  sqlite3_column_int(stmt, 4), // fert
503  sqlite3_column_int(stmt, 5), // mobilization
504  sqlite3_column_int(stmt, 6), // crystals
505  sqlite3_column_int(stmt, 7), // resource
506  sqlite3_column_int(stmt, 8), // popn
507  sqlite3_column_int(stmt, 9), // troops
508  sqlite3_column_int(stmt, 10), // owner
509  sqlite3_column_int(stmt, 11), // race
510  sqlite3_column_int(stmt, 12), // type
511  sqlite3_column_int(stmt, 13) // condition
512  );
513 
514  int err = sqlite3_finalize(stmt);
515  if (err != SQLITE_OK) {
516  fprintf(stderr, "SQLite Error: %s\n", sqlite3_errmsg(dbconn));
517  }
518 
519  return s;
520 }
521 
522 SectorMap getsmap(const Planet &p) {
523  const char *tail = nullptr;
524  sqlite3_stmt *stmt;
525  const char *sql =
526  "SELECT planet_id, xpos, ypos, eff, fert, "
527  "mobilization, crystals, resource, popn, troops, owner, "
528  "race, type, condition FROM tbl_sector "
529  "WHERE planet_id=?1 ORDER BY ypos, xpos";
530  sqlite3_prepare_v2(dbconn, sql, -1, &stmt, &tail);
531 
532  sqlite3_bind_int(stmt, 1, p.planet_id);
533 
534  SectorMap smap(p);
535 
536  while (sqlite3_step(stmt) == SQLITE_ROW) {
537  Sector s(sqlite3_column_int(stmt, 1), // xpos
538  sqlite3_column_int(stmt, 2), // ypos
539  sqlite3_column_int(stmt, 3), // eff
540  sqlite3_column_int(stmt, 4), // fert
541  sqlite3_column_int(stmt, 5), // mobilization
542  sqlite3_column_int(stmt, 6), // crystals
543  sqlite3_column_int(stmt, 7), // resource
544  sqlite3_column_int(stmt, 8), // popn
545  sqlite3_column_int(stmt, 9), // troops
546  sqlite3_column_int(stmt, 10), // owner
547  sqlite3_column_int(stmt, 11), // race
548  sqlite3_column_int(stmt, 12), // type
549  sqlite3_column_int(stmt, 13) // condition
550  );
551  smap.put(std::move(s));
552  }
553 
554  sqlite3_clear_bindings(stmt);
555  sqlite3_reset(stmt);
556 
557  return smap;
558 }
559 
561  return getship(nullptr, shipnum);
562 }
563 
565  struct stat buffer;
566 
567  if (shipnum <= 0) return {};
568 
569  fstat(shdata, &buffer);
570  if (buffer.st_size / sizeof(Ship) < shipnum) return {};
571 
572  Ship tmpship;
573  Ship *tmpship1;
574  if (s == nullptr) {
575  tmpship1 = &tmpship;
576  s = &tmpship1;
577  } else if ((*s = (Ship *)malloc(sizeof(Ship))) == nullptr) {
578  printf("getship:malloc() error \n");
579  exit(0);
580  }
581 
582  Fileread(shdata, (char *)*s, sizeof(Ship), (shipnum - 1) * sizeof(Ship));
583 
584  const char *tail;
585  sqlite3_stmt *stmt;
586  const char *sql =
587  "SELECT ship_id, player_id, governor_id, name, "
588  "shipclass, race, xpos, ypos, mass,"
589  "land_x, land_y, destshipno, nextship, ships, armor, size,"
590  "max_crew, max_resource, max_destruct, max_fuel, max_speed, build_type,"
591  "build_cost, base_mass, tech, complexity,"
592  "destruct, resource, population, troops, crystals,"
593  "who_killed,"
594  "navigate_on, navigate_speed, navigate_turns, navigate_bearing,"
595  "protect_maxrng, protect_on, protect_planet, protect_self,"
596  "protect_evade, protect_ship,"
597  "hyper_drive_charge, hyper_drive_ready, hyper_drive_on,"
598  "hyper_drive_has,"
599  "cew, cew_range, cloak, laser, focus, fire_laser,"
600  "storbits, deststar, destpnum, pnumorbits, whatdest,"
601  "whatorbits,"
602  "damage, rad, retaliate, target,"
603  "type, speed,"
604  "active, alive, mode, bombard, mounted, cloaked,"
605  "sheep, docked, notified, examined, on_off,"
606  "merchant, guns, primary_gun, primtype,"
607  "secondary_gun, sectype,"
608  "hanger, max_hanger, mount,"
609  "aimed_shipno, aimed_snum,"
610  "aimed_intensity, aimed_pnum, aimed_level,"
611  "mind_progenitor, mind_target,"
612  "mind_generation, mind_busy, mind_tampered,"
613  "mind_who_killed,"
614  "pod_decay, pod_temperature,"
615  "timer_count,"
616  "impact_x, impact_y, impact_scatter,"
617  "trigger_radius,"
618  "terraform_index,"
619  "transport_target,"
620  "waste_toxic "
621  "FROM tbl_ship WHERE ship_id=?1 LIMIT 1";
622 
623  sqlite3_prepare_v2(dbconn, sql, -1, &stmt, &tail);
624  sqlite3_bind_int(stmt, 1, shipnum);
625 
626  auto result = sqlite3_step(stmt);
627  if (result != SQLITE_ROW) {
628  int err = sqlite3_finalize(stmt);
629  if (err != SQLITE_OK) {
630  fprintf(stderr, "SQLite Error: %s\n", sqlite3_errmsg(dbconn));
631  }
632  return {};
633  }
634 
635  (*s)->number = sqlite3_column_int(stmt, 0);
636  (*s)->owner = sqlite3_column_int(stmt, 1);
637  (*s)->governor = sqlite3_column_int(stmt, 2);
638  strcpy((*s)->name,
639  reinterpret_cast<const char *>(sqlite3_column_text(stmt, 3)));
640  strcpy((*s)->shipclass,
641  reinterpret_cast<const char *>(sqlite3_column_text(stmt, 4)));
642  (*s)->race = sqlite3_column_int(stmt, 5);
643  (*s)->xpos = sqlite3_column_double(stmt, 6);
644  (*s)->ypos = sqlite3_column_double(stmt, 7);
645  (*s)->mass = sqlite3_column_double(stmt, 8);
646  (*s)->land_x = sqlite3_column_int(stmt, 9);
647  (*s)->land_y = sqlite3_column_int(stmt, 10);
648  (*s)->destshipno = sqlite3_column_int(stmt, 11);
649  (*s)->nextship = sqlite3_column_int(stmt, 12);
650  (*s)->ships = sqlite3_column_int(stmt, 13);
651  (*s)->armor = sqlite3_column_int(stmt, 14);
652  (*s)->size = sqlite3_column_int(stmt, 15);
653  (*s)->max_crew = sqlite3_column_int(stmt, 16);
654  (*s)->max_resource = sqlite3_column_int(stmt, 17);
655  (*s)->max_destruct = sqlite3_column_int(stmt, 18);
656  (*s)->max_fuel = sqlite3_column_int(stmt, 19);
657  (*s)->max_speed = sqlite3_column_int(stmt, 20);
658  (*s)->build_type = static_cast<ShipType>(sqlite3_column_int(stmt, 21));
659  (*s)->build_cost = sqlite3_column_int(stmt, 22);
660  (*s)->base_mass = sqlite3_column_int(stmt, 23);
661  (*s)->tech = sqlite3_column_int(stmt, 24);
662  (*s)->complexity = sqlite3_column_int(stmt, 25);
663  (*s)->destruct = sqlite3_column_int(stmt, 26);
664  (*s)->resource = sqlite3_column_int(stmt, 27);
665  (*s)->popn = sqlite3_column_int(stmt, 28);
666  (*s)->troops = sqlite3_column_int(stmt, 29);
667  (*s)->crystals = sqlite3_column_int(stmt, 30);
668  (*s)->who_killed = sqlite3_column_int(stmt, 31);
669  (*s)->navigate.on = sqlite3_column_int(stmt, 32);
670  (*s)->navigate.speed = sqlite3_column_int(stmt, 33);
671  (*s)->navigate.turns = sqlite3_column_int(stmt, 34);
672  (*s)->navigate.bearing = sqlite3_column_int(stmt, 35);
673  (*s)->protect.maxrng = sqlite3_column_int(stmt, 36);
674  (*s)->protect.on = sqlite3_column_int(stmt, 37);
675  (*s)->protect.planet = sqlite3_column_int(stmt, 38);
676  (*s)->protect.self = sqlite3_column_int(stmt, 39);
677  (*s)->protect.evade = sqlite3_column_int(stmt, 40);
678  (*s)->protect.ship = sqlite3_column_int(stmt, 41);
679  (*s)->hyper_drive.charge = sqlite3_column_int(stmt, 42);
680  (*s)->hyper_drive.ready = sqlite3_column_int(stmt, 43);
681  (*s)->hyper_drive.on = sqlite3_column_int(stmt, 44);
682  (*s)->hyper_drive.has = sqlite3_column_int(stmt, 45);
683  (*s)->cew = sqlite3_column_int(stmt, 46);
684  (*s)->cew_range = sqlite3_column_int(stmt, 47);
685  (*s)->cloak = sqlite3_column_int(stmt, 48);
686  (*s)->laser = sqlite3_column_int(stmt, 49);
687  (*s)->focus = sqlite3_column_int(stmt, 50);
688  (*s)->fire_laser = sqlite3_column_int(stmt, 51);
689  (*s)->storbits = sqlite3_column_int(stmt, 52);
690  (*s)->deststar = sqlite3_column_int(stmt, 53);
691  (*s)->destpnum = sqlite3_column_int(stmt, 54);
692  (*s)->pnumorbits = sqlite3_column_int(stmt, 55);
693  (*s)->whatdest = static_cast<ScopeLevel>(sqlite3_column_int(stmt, 56));
694  (*s)->whatorbits = static_cast<ScopeLevel>(sqlite3_column_int(stmt, 57));
695  (*s)->damage = sqlite3_column_int(stmt, 58);
696  (*s)->rad = sqlite3_column_int(stmt, 59);
697  (*s)->retaliate = sqlite3_column_int(stmt, 60);
698  (*s)->target = sqlite3_column_int(stmt, 61);
699  (*s)->type = static_cast<ShipType>(sqlite3_column_int(stmt, 62));
700  (*s)->speed = sqlite3_column_int(stmt, 63);
701  (*s)->active = sqlite3_column_int(stmt, 64);
702  (*s)->alive = sqlite3_column_int(stmt, 65);
703  (*s)->mode = sqlite3_column_int(stmt, 66);
704  (*s)->bombard = sqlite3_column_int(stmt, 67);
705  (*s)->mounted = sqlite3_column_int(stmt, 68);
706  (*s)->cloaked = sqlite3_column_int(stmt, 69);
707  (*s)->sheep = sqlite3_column_int(stmt, 70);
708  (*s)->docked = sqlite3_column_int(stmt, 71);
709  (*s)->notified = sqlite3_column_int(stmt, 72);
710  (*s)->examined = sqlite3_column_int(stmt, 73);
711  (*s)->on = sqlite3_column_int(stmt, 74);
712  (*s)->merchant = sqlite3_column_int(stmt, 75);
713  (*s)->guns = sqlite3_column_int(stmt, 76);
714  (*s)->primary = sqlite3_column_int(stmt, 77);
715  (*s)->primtype = sqlite3_column_int(stmt, 78);
716  (*s)->secondary = sqlite3_column_int(stmt, 79);
717  (*s)->sectype = sqlite3_column_int(stmt, 80);
718  (*s)->hanger = sqlite3_column_int(stmt, 81);
719  (*s)->max_hanger = sqlite3_column_int(stmt, 82);
720  (*s)->mount = sqlite3_column_int(stmt, 83);
721 
722  int err = sqlite3_finalize(stmt);
723  if (err != SQLITE_OK) {
724  fprintf(stderr, "SQLite Error: %s\n", sqlite3_errmsg(dbconn));
725  }
726 
727  return **s;
728 }
729 
730 int getcommod(commodtype **c, commodnum_t commodnum) {
731  struct stat buffer;
732 
733  if (commodnum <= 0) return 0;
734 
735  fstat(commoddata, &buffer);
736  if (buffer.st_size / sizeof(commodtype) < commodnum) return 0;
737 
738  if ((*c = (commodtype *)malloc(sizeof(commodtype))) == nullptr) {
739  printf("getcommod:malloc() error \n");
740  exit(0);
741  }
742 
743  Fileread(commoddata, (char *)*c, sizeof(commodtype),
744  (commodnum - 1) * sizeof(commodtype));
745  return 1;
746 }
747 
748 /* gets the ship # listed in the top of the file SHIPFREEDATAFL. this
749 ** might have no other uses besides build().
750 */
751 int getdeadship() {
752  struct stat buffer;
753  short shnum;
754  int fd;
755  int abort;
756 
757  if ((fd = open(SHIPFREEDATAFL, O_RDWR, 0777)) < 0) {
758  perror("getdeadship");
759  printf("unable to open %s\n", SHIPFREEDATAFL);
760  exit(-1);
761  }
762  abort = 1;
763  fstat(fd, &buffer);
764 
765  if (buffer.st_size && (abort == 1)) {
766  /* put topmost entry in fpos */
767  Fileread(fd, (char *)&shnum, sizeof(short), buffer.st_size - sizeof(short));
768  /* erase that entry, since it will now be filled */
769  ftruncate(fd, (long)(buffer.st_size - sizeof(short)));
770  close_file(fd);
771  return (int)shnum;
772  }
773  close_file(fd);
774  return -1;
775 }
776 
778  struct stat buffer;
779  short commodnum;
780  int fd;
781  int abort;
782 
783  if ((fd = open(COMMODFREEDATAFL, O_RDWR, 0777)) < 0) {
784  perror("getdeadcommod");
785  printf("unable to open %s\n", COMMODFREEDATAFL);
786  exit(-1);
787  }
788  abort = 1;
789  fstat(fd, &buffer);
790 
791  if (buffer.st_size && (abort == 1)) {
792  /* put topmost entry in fpos */
793  Fileread(fd, (char *)&commodnum, sizeof(short),
794  buffer.st_size - sizeof(short));
795  /* erase that entry, since it will now be filled */
796  ftruncate(fd, (long)(buffer.st_size - sizeof(short)));
797  close_file(fd);
798  return (int)commodnum;
799  }
800  close_file(fd);
801  return -1;
802 }
803 
804 void putsdata(struct stardata *S) {
805  Filewrite(stdata, (char *)S, sizeof(struct stardata), 0);
806 }
807 
808 void putrace(Race *r) {
809  Filewrite(racedata, (char *)r, sizeof(Race),
810  (r->Playernum - 1) * sizeof(Race));
811 }
812 
813 void putstar(startype *s, starnum_t snum) {
814  Filewrite(stdata, (char *)s, sizeof(startype),
815  (int)(sizeof(Sdata) + snum * sizeof(startype)));
816 
818 
819  {
820  const char *tail = nullptr;
821  sqlite3_stmt *stmt;
822 
823  const char *sql =
824  "REPLACE INTO tbl_star (star_id, ships, name, xpos, ypos, "
825  "numplanets, stability, nova_stage, temperature, gravity) "
826  "VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10)";
827  sqlite3_prepare_v2(dbconn, sql, -1, &stmt, &tail);
828 
829  sqlite3_bind_int(stmt, 1, snum);
830  sqlite3_bind_int(stmt, 2, s->ships);
831  sqlite3_bind_text(stmt, 3, s->name, -1, SQLITE_TRANSIENT);
832  sqlite3_bind_double(stmt, 4, s->xpos);
833  sqlite3_bind_double(stmt, 5, s->ypos);
834  sqlite3_bind_int(stmt, 6, s->numplanets);
835  sqlite3_bind_int(stmt, 7, s->stability);
836  sqlite3_bind_int(stmt, 8, s->nova_stage);
837  sqlite3_bind_int(stmt, 9, s->temperature);
838  sqlite3_bind_double(stmt, 10, s->gravity);
839 
840  sqlite3_step(stmt);
841 
842  sqlite3_reset(stmt);
843  }
844 
845  {
846  const char *tail = nullptr;
847  sqlite3_stmt *stmt;
848  const char *sql =
849  "REPLACE INTO tbl_star_governor (star_id, player_id, governor_id) "
850  "VALUES (?1, ?2, ?3)";
851 
852  sqlite3_prepare_v2(dbconn, sql, -1, &stmt, &tail);
853  for (player_t i = 1; i <= MAXPLAYERS; i++) {
854  sqlite3_bind_int(stmt, 1, snum);
855  sqlite3_bind_int(stmt, 2, i);
856  sqlite3_bind_int(stmt, 3, s->governor[i - 1]);
857 
858  sqlite3_step(stmt);
859 
860  sqlite3_reset(stmt);
861  }
862  }
863 
864  {
865  const char *tail = nullptr;
866  sqlite3_stmt *stmt;
867  const char *sql =
868  "REPLACE INTO tbl_star_playerap (star_id, player_id, ap) "
869  "VALUES (?1, ?2, ?3)";
870 
871  sqlite3_prepare_v2(dbconn, sql, -1, &stmt, &tail);
872  for (player_t i = 1; i <= MAXPLAYERS; i++) {
873  sqlite3_bind_int(stmt, 1, snum);
874  sqlite3_bind_int(stmt, 2, i);
875  sqlite3_bind_int(stmt, 3, s->AP[i - 1]);
876 
877  sqlite3_step(stmt);
878 
879  sqlite3_reset(stmt);
880  }
881  }
882 
883  {
884  const char *tail = nullptr;
885  sqlite3_stmt *stmt;
886  const char *sql =
887  "REPLACE INTO tbl_star_explored (star_id, player_id, explored) "
888  "VALUES (?1, ?2, ?3)";
889 
890  sqlite3_prepare_v2(dbconn, sql, -1, &stmt, &tail);
891  for (player_t i = 1; i <= MAXPLAYERS; i++) {
892  sqlite3_bind_int(stmt, 1, snum);
893  sqlite3_bind_int(stmt, 2, i);
894  sqlite3_bind_int(stmt, 3, isset(s->explored, i - 1) ? 1 : 0);
895 
896  sqlite3_step(stmt);
897 
898  sqlite3_reset(stmt);
899  }
900  }
901 
902  {
903  const char *tail = nullptr;
904  sqlite3_stmt *stmt;
905  const char *sql =
906  "REPLACE INTO tbl_star_inhabited (star_id, player_id, explored) "
907  "VALUES (?1, ?2, ?3)";
908 
909  sqlite3_prepare_v2(dbconn, sql, -1, &stmt, &tail);
910  for (player_t i = 1; i <= MAXPLAYERS; i++) {
911  sqlite3_bind_int(stmt, 1, snum);
912  sqlite3_bind_int(stmt, 2, i);
913  sqlite3_bind_int(stmt, 3, isset(s->inhabited, i - 1) ? 1 : 0);
914 
915  sqlite3_step(stmt);
916 
917  sqlite3_reset(stmt);
918  }
919  }
920 
922 }
923 
924 static void start_bulk_insert() {
925  char *err_msg = nullptr;
926  sqlite3_exec(dbconn, "BEGIN TRANSACTION", nullptr, nullptr, &err_msg);
927 }
928 
929 static void end_bulk_insert() {
930  char *err_msg = nullptr;
931  sqlite3_exec(dbconn, "END TRANSACTION", nullptr, nullptr, &err_msg);
932 }
933 
934 void putplanet(const Planet &p, startype *star, const int pnum) {
936 
937  const char *tail = nullptr;
938  const char *plinfo_tail = nullptr;
939  const char *plinfo_route_tail = nullptr;
940  sqlite3_stmt *stmt;
941  sqlite3_stmt *plinfo_stmt;
942  sqlite3_stmt *plinfo_route_stmt;
943  const char *sql =
944  "REPLACE INTO tbl_planet (planet_id, star_id, planet_order, name, "
945  "xpos, ypos, ships, maxx, maxy, popn, troops, maxpopn, total_resources, "
946  "slaved_to, type, expltimer, condition_rtemp, condition_temp, "
947  "condition_methane, condition_oxygen, condition_co2, "
948  "condition_hydrogen, condition_nitrogen, condition_sulfur, "
949  "condition_helium, condition_other, condition_toxic, "
950  "explored) "
951  "VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, "
952  "?11, ?12, ?13, ?14, ?15, ?16, ?17, ?18, ?19, ?20, "
953  "?21, ?22, ?23, ?24, ?25, ?26, ?27, ?28)";
954  sqlite3_prepare_v2(dbconn, sql, -1, &stmt, &tail);
955 
956  const char *plinfo_sql =
957  "REPLACE INTO tbl_plinfo (planet_id, player_id, fuel, destruct, "
958  "resource, popn, troops, crystals, prod_res, "
959  "prod_fuel, prod_dest, prod_crystals, prod_money, "
960  "prod_tech, tech_invest, numsectsowned, comread, "
961  "mob_set, tox_thresh, explored, autorep, tax, "
962  "newtax, guns, mob_points, est_production) VALUES "
963  "(?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, "
964  "?11, ?12, ?13, ?14, ?15, ?16, ?17, ?18, ?19, ?20, "
965  "?21, ?22, ?23, ?24, ?25, ?26)";
966  if (sqlite3_prepare_v2(dbconn, plinfo_sql, -1, &plinfo_stmt, &plinfo_tail) !=
967  SQLITE_OK) {
968  fprintf(stderr, "PLINFO %s\n", sqlite3_errmsg(dbconn));
969  }
970 
971  const char *plinfo_route_sql =
972  "REPLACE INTO tbl_plinfo_routes (planet_id, player_id, routenum, "
973  "order_set, dest_star, dest_planet, "
974  "load, unload, x, y) VALUES "
975  "(?1, ?2, ?3, ?4, 5, ?6, ?7, ?8, ?9, ?10)";
976  sqlite3_prepare_v2(dbconn, plinfo_route_sql, -1, &plinfo_route_stmt,
977  &plinfo_route_tail);
978 
979  sqlite3_bind_int(stmt, 1, p.planet_id);
980  sqlite3_bind_int(stmt, 2, star->star_id);
981  sqlite3_bind_int(stmt, 3, pnum);
982  sqlite3_bind_text(stmt, 4, star->pnames[pnum], strlen(star->pnames[pnum]),
983  SQLITE_TRANSIENT);
984  sqlite3_bind_double(stmt, 5, p.xpos);
985  sqlite3_bind_double(stmt, 6, p.ypos);
986  sqlite3_bind_int(stmt, 7, p.ships);
987  sqlite3_bind_int(stmt, 8, p.Maxx);
988  sqlite3_bind_int(stmt, 9, p.Maxy);
989  sqlite3_bind_int(stmt, 10, p.popn);
990  sqlite3_bind_int(stmt, 11, p.troops);
991  sqlite3_bind_int(stmt, 12, p.maxpopn);
992  sqlite3_bind_int(stmt, 13, p.total_resources);
993  sqlite3_bind_int(stmt, 14, p.slaved_to);
994  sqlite3_bind_int(stmt, 15, p.type);
995  sqlite3_bind_int(stmt, 16, p.expltimer);
996  sqlite3_bind_int(stmt, 17, p.conditions[RTEMP]);
997  sqlite3_bind_int(stmt, 18, p.conditions[TEMP]);
998  sqlite3_bind_int(stmt, 19, p.conditions[METHANE]);
999  sqlite3_bind_int(stmt, 20, p.conditions[OXYGEN]);
1000  sqlite3_bind_int(stmt, 21, p.conditions[CO2]);
1001  sqlite3_bind_int(stmt, 22, p.conditions[HYDROGEN]);
1002  sqlite3_bind_int(stmt, 23, p.conditions[NITROGEN]);
1003  sqlite3_bind_int(stmt, 24, p.conditions[SULFUR]);
1004  sqlite3_bind_int(stmt, 25, p.conditions[HELIUM]);
1005  sqlite3_bind_int(stmt, 26, p.conditions[OTHER]);
1006  sqlite3_bind_int(stmt, 27, p.conditions[TOXIC]);
1007  sqlite3_bind_int(stmt, 28, p.explored);
1008 
1009  if (sqlite3_step(stmt) != SQLITE_DONE) {
1010  fprintf(stderr, "XXX %s\n", sqlite3_errmsg(dbconn));
1011  }
1012 
1013  {
1014  for (player_t i = 0; i < MAXPLAYERS; i++) {
1015  sqlite3_bind_int(plinfo_stmt, 1, p.planet_id);
1016  sqlite3_bind_int(plinfo_stmt, 2, i);
1017  sqlite3_bind_int(plinfo_stmt, 3, p.info[i].fuel);
1018  sqlite3_bind_int(plinfo_stmt, 4, p.info[i].destruct);
1019  sqlite3_bind_int(plinfo_stmt, 5, p.info[i].resource);
1020  sqlite3_bind_int(plinfo_stmt, 6, p.info[i].popn);
1021  sqlite3_bind_int(plinfo_stmt, 7, p.info[i].troops);
1022  sqlite3_bind_int(plinfo_stmt, 8, p.info[i].crystals);
1023  sqlite3_bind_int(plinfo_stmt, 9, p.info[i].prod_res);
1024  sqlite3_bind_int(plinfo_stmt, 10, p.info[i].prod_fuel);
1025  sqlite3_bind_int(plinfo_stmt, 11, p.info[i].prod_dest);
1026  sqlite3_bind_int(plinfo_stmt, 12, p.info[i].prod_crystals);
1027  sqlite3_bind_int(plinfo_stmt, 13, p.info[i].prod_money);
1028  sqlite3_bind_double(plinfo_stmt, 14, p.info[i].prod_tech);
1029  sqlite3_bind_int(plinfo_stmt, 15, p.info[i].tech_invest);
1030  sqlite3_bind_int(plinfo_stmt, 16, p.info[i].numsectsowned);
1031  sqlite3_bind_int(plinfo_stmt, 17, p.info[i].comread);
1032  sqlite3_bind_int(plinfo_stmt, 18, p.info[i].mob_set);
1033  sqlite3_bind_int(plinfo_stmt, 19, p.info[i].tox_thresh);
1034  sqlite3_bind_int(plinfo_stmt, 20, p.info[i].explored);
1035  sqlite3_bind_int(plinfo_stmt, 21, p.info[i].autorep);
1036  sqlite3_bind_int(plinfo_stmt, 22, p.info[i].tax);
1037  sqlite3_bind_int(plinfo_stmt, 23, p.info[i].newtax);
1038  sqlite3_bind_int(plinfo_stmt, 24, p.info[i].guns);
1039  sqlite3_bind_int(plinfo_stmt, 25, p.info[i].mob_points);
1040  sqlite3_bind_double(plinfo_stmt, 26, p.info[i].est_production);
1041 
1042  if (sqlite3_step(plinfo_stmt) != SQLITE_DONE) {
1043  fprintf(stderr, "YYY %s\n", sqlite3_errmsg(dbconn));
1044  }
1045  sqlite3_reset(plinfo_stmt);
1046 
1047  {
1048  for (int j = 0; j < MAX_ROUTES; j++) {
1049  sqlite3_bind_int(plinfo_route_stmt, 1, p.planet_id);
1050  sqlite3_bind_int(plinfo_route_stmt, 2, i);
1051  sqlite3_bind_int(plinfo_route_stmt, 3, j);
1052  sqlite3_bind_int(plinfo_route_stmt, 4, p.info[i].route[j].set);
1053  sqlite3_bind_int(plinfo_route_stmt, 5, p.info[i].route[j].dest_star);
1054  sqlite3_bind_int(plinfo_route_stmt, 6,
1055  p.info[i].route[j].dest_planet);
1056  sqlite3_bind_int(plinfo_route_stmt, 7, p.info[i].route[j].load);
1057  sqlite3_bind_int(plinfo_route_stmt, 8, p.info[i].route[j].unload);
1058  sqlite3_bind_int(plinfo_route_stmt, 9, p.info[i].route[j].x);
1059  sqlite3_bind_int(plinfo_route_stmt, 10, p.info[i].route[j].y);
1060 
1061  if (sqlite3_step(plinfo_route_stmt) != SQLITE_DONE) {
1062  fprintf(stderr, "ZZZ %s\n", sqlite3_errmsg(dbconn));
1063  }
1064  sqlite3_reset(plinfo_route_stmt);
1065  }
1066  }
1067  }
1068  }
1069  sqlite3_finalize(stmt);
1070  sqlite3_finalize(plinfo_stmt);
1071  sqlite3_finalize(plinfo_route_stmt);
1072 
1074 }
1075 
1076 void putsector(const Sector &s, const Planet &p, const int x, const int y) {
1077  const char *tail = nullptr;
1078  sqlite3_stmt *stmt;
1079  const char *sql =
1080  "REPLACE INTO tbl_sector (planet_id, xpos, ypos, eff, fert, "
1081  "mobilization, crystals, resource, popn, troops, owner, "
1082  "race, type, condition) "
1083  "VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14)";
1084 
1085  sqlite3_prepare_v2(dbconn, sql, -1, &stmt, &tail);
1086  sqlite3_bind_int(stmt, 1, p.planet_id);
1087  sqlite3_bind_int(stmt, 2, x);
1088  sqlite3_bind_int(stmt, 3, y);
1089  sqlite3_bind_int(stmt, 4, s.eff);
1090  sqlite3_bind_int(stmt, 5, s.fert);
1091  sqlite3_bind_int(stmt, 6, s.mobilization);
1092  sqlite3_bind_int(stmt, 7, s.crystals);
1093  sqlite3_bind_int(stmt, 8, s.resource);
1094  sqlite3_bind_int(stmt, 9, s.popn);
1095  sqlite3_bind_int(stmt, 10, s.troops);
1096  sqlite3_bind_int(stmt, 11, s.owner);
1097  sqlite3_bind_int(stmt, 12, s.race);
1098  sqlite3_bind_int(stmt, 13, s.type);
1099  sqlite3_bind_int(stmt, 14, s.condition);
1100 
1101  if (sqlite3_step(stmt) != SQLITE_DONE) {
1102  fprintf(stderr, "000 %s\n", sqlite3_errmsg(dbconn));
1103  }
1104 
1105  sqlite3_reset(stmt);
1106 }
1107 
1108 void putsmap(SectorMap &map, Planet &p) {
1110 
1111  for (int y = 0; y < p.Maxy; y++) {
1112  for (int x = 0; x < p.Maxx; x++) {
1113  auto &sec = map.get(x, y);
1114  putsector(sec, p, x, y);
1115  }
1116  }
1117 
1119 }
1120 
1121 static void putship_aimed(const Ship &s) {
1122  const char *tail;
1123  sqlite3_stmt *stmt;
1124  const char *sql =
1125  "REPLACE INTO tbl_ship (ship_id, aimed_shipno, aimed_snum, "
1126  "aimed_intensity, aimed_pnum, aimed_level)"
1127  "VALUES (?1, ?2, ?3, ?4, ?5, ?6);";
1128 
1129  sqlite3_prepare_v2(dbconn, sql, -1, &stmt, &tail);
1130  sqlite3_bind_int(stmt, 1, s.number);
1131  sqlite3_bind_int(stmt, 2, s.special.aimed_at.shipno);
1132  sqlite3_bind_int(stmt, 3, s.special.aimed_at.snum);
1133  sqlite3_bind_int(stmt, 4, s.special.aimed_at.intensity);
1134  sqlite3_bind_int(stmt, 5, s.special.aimed_at.pnum);
1135  sqlite3_bind_int(stmt, 6, s.special.aimed_at.level);
1136 
1137  if (sqlite3_step(stmt) != SQLITE_DONE) {
1138  fprintf(stderr, "XXX %s\n", sqlite3_errmsg(dbconn));
1139  }
1140 
1141  int err = sqlite3_finalize(stmt);
1142  if (err != SQLITE_OK) {
1143  fprintf(stderr, "SQLite Error: %s\n", sqlite3_errmsg(dbconn));
1144  }
1145 }
1146 static void putship_mind(const Ship &s) {
1147  const char *tail;
1148  sqlite3_stmt *stmt;
1149  const char *sql =
1150  "REPLACE INTO tbl_ship (ship_id, mind_progenitor, mind_target, "
1151  "mind_generation, mind_busy, mind_tampered,"
1152  "mind_who_killed)"
1153  "VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7);";
1154 
1155  sqlite3_prepare_v2(dbconn, sql, -1, &stmt, &tail);
1156  sqlite3_bind_int(stmt, 1, s.number);
1157  sqlite3_bind_int(stmt, 2, s.special.mind.progenitor);
1158  sqlite3_bind_int(stmt, 3, s.special.mind.target);
1159  sqlite3_bind_int(stmt, 4, s.special.mind.generation);
1160  sqlite3_bind_int(stmt, 5, s.special.mind.busy);
1161  sqlite3_bind_int(stmt, 6, s.special.mind.tampered);
1162  sqlite3_bind_int(stmt, 7, s.special.mind.who_killed);
1163 
1164  if (sqlite3_step(stmt) != SQLITE_DONE) {
1165  fprintf(stderr, "XXX %s\n", sqlite3_errmsg(dbconn));
1166  }
1167 
1168  int err = sqlite3_finalize(stmt);
1169  if (err != SQLITE_OK) {
1170  fprintf(stderr, "SQLite Error: %s\n", sqlite3_errmsg(dbconn));
1171  }
1172 }
1173 static void putship_pod(const Ship &s) {
1174  const char *tail;
1175  sqlite3_stmt *stmt;
1176  const char *sql =
1177  "REPLACE INTO tbl_ship (ship_id, pod_decay, pod_temperature)"
1178  "VALUES (?1, ?2, ?3);";
1179 
1180  sqlite3_prepare_v2(dbconn, sql, -1, &stmt, &tail);
1181  sqlite3_bind_int(stmt, 1, s.number);
1182  sqlite3_bind_int(stmt, 2, s.special.pod.decay);
1183  sqlite3_bind_int(stmt, 3, s.special.pod.temperature);
1184 
1185  if (sqlite3_step(stmt) != SQLITE_DONE) {
1186  fprintf(stderr, "XXX %s\n", sqlite3_errmsg(dbconn));
1187  }
1188 
1189  int err = sqlite3_finalize(stmt);
1190  if (err != SQLITE_OK) {
1191  fprintf(stderr, "SQLite Error: %s\n", sqlite3_errmsg(dbconn));
1192  }
1193 }
1194 static void putship_timer(const Ship &s) {
1195  const char *tail;
1196  sqlite3_stmt *stmt;
1197  const char *sql =
1198  "REPLACE INTO tbl_ship (ship_id, timer_count)"
1199  "VALUES (?1, ?2);";
1200 
1201  sqlite3_prepare_v2(dbconn, sql, -1, &stmt, &tail);
1202  sqlite3_bind_int(stmt, 1, s.number);
1203  sqlite3_bind_int(stmt, 2, s.special.timer.count);
1204 
1205  if (sqlite3_step(stmt) != SQLITE_DONE) {
1206  fprintf(stderr, "XXX %s\n", sqlite3_errmsg(dbconn));
1207  }
1208 
1209  int err = sqlite3_finalize(stmt);
1210  if (err != SQLITE_OK) {
1211  fprintf(stderr, "SQLite Error: %s\n", sqlite3_errmsg(dbconn));
1212  }
1213 }
1214 static void putship_impact(const Ship &s) {
1215  const char *tail;
1216  sqlite3_stmt *stmt;
1217  const char *sql =
1218  "REPLACE INTO tbl_ship (ship_id, impact_x, impact_y, impact_scatter)"
1219  "VALUES (?1, ?2, ?3, ?4);";
1220 
1221  sqlite3_prepare_v2(dbconn, sql, -1, &stmt, &tail);
1222  sqlite3_bind_int(stmt, 1, s.number);
1223  sqlite3_bind_int(stmt, 2, s.special.impact.x);
1224  sqlite3_bind_int(stmt, 3, s.special.impact.y);
1225  sqlite3_bind_int(stmt, 4, s.special.impact.scatter);
1226 
1227  if (sqlite3_step(stmt) != SQLITE_DONE) {
1228  fprintf(stderr, "XXX %s\n", sqlite3_errmsg(dbconn));
1229  }
1230 
1231  int err = sqlite3_finalize(stmt);
1232  if (err != SQLITE_OK) {
1233  fprintf(stderr, "SQLite Error: %s\n", sqlite3_errmsg(dbconn));
1234  }
1235 }
1236 static void putship_trigger(const Ship &s) {
1237  const char *tail;
1238  sqlite3_stmt *stmt;
1239  const char *sql =
1240  "REPLACE INTO tbl_ship (ship_id, trigger_radius)"
1241  "VALUES (?1, ?2);";
1242 
1243  sqlite3_prepare_v2(dbconn, sql, -1, &stmt, &tail);
1244  sqlite3_bind_int(stmt, 1, s.number);
1245  sqlite3_bind_int(stmt, 2, s.special.trigger.radius);
1246 
1247  if (sqlite3_step(stmt) != SQLITE_DONE) {
1248  fprintf(stderr, "XXX %s\n", sqlite3_errmsg(dbconn));
1249  }
1250 
1251  int err = sqlite3_finalize(stmt);
1252  if (err != SQLITE_OK) {
1253  fprintf(stderr, "SQLite Error: %s\n", sqlite3_errmsg(dbconn));
1254  }
1255 }
1256 static void putship_terraform(const Ship &s) {
1257  const char *tail;
1258  sqlite3_stmt *stmt;
1259  const char *sql =
1260  "REPLACE INTO tbl_ship (ship_id, terraform_index)"
1261  "VALUES (?1, ?2);";
1262 
1263  sqlite3_prepare_v2(dbconn, sql, -1, &stmt, &tail);
1264  sqlite3_bind_int(stmt, 1, s.number);
1265  sqlite3_bind_int(stmt, 2, s.special.terraform.index);
1266 
1267  if (sqlite3_step(stmt) != SQLITE_DONE) {
1268  fprintf(stderr, "XXX %s\n", sqlite3_errmsg(dbconn));
1269  }
1270 
1271  int err = sqlite3_finalize(stmt);
1272  if (err != SQLITE_OK) {
1273  fprintf(stderr, "SQLite Error: %s\n", sqlite3_errmsg(dbconn));
1274  }
1275 }
1276 static void putship_transport(const Ship &s) {
1277  const char *tail;
1278  sqlite3_stmt *stmt;
1279  const char *sql =
1280  "REPLACE INTO tbl_ship (ship_id, transport_target)"
1281  "VALUES (?1, ?2);";
1282 
1283  sqlite3_prepare_v2(dbconn, sql, -1, &stmt, &tail);
1284  sqlite3_bind_int(stmt, 1, s.number);
1285  sqlite3_bind_int(stmt, 2, s.special.transport.target);
1286 
1287  if (sqlite3_step(stmt) != SQLITE_DONE) {
1288  fprintf(stderr, "XXX %s\n", sqlite3_errmsg(dbconn));
1289  }
1290 
1291  int err = sqlite3_finalize(stmt);
1292  if (err != SQLITE_OK) {
1293  fprintf(stderr, "SQLite Error: %s\n", sqlite3_errmsg(dbconn));
1294  }
1295 }
1296 static void putship_waste(const Ship &s) {
1297  const char *tail;
1298  sqlite3_stmt *stmt;
1299  const char *sql =
1300  "REPLACE INTO tbl_ship (ship_id, waste_toxic)"
1301  "VALUES (?1, ?2);";
1302 
1303  sqlite3_prepare_v2(dbconn, sql, -1, &stmt, &tail);
1304  sqlite3_bind_int(stmt, 1, s.number);
1305  sqlite3_bind_int(stmt, 2, s.special.waste.toxic);
1306 
1307  if (sqlite3_step(stmt) != SQLITE_DONE) {
1308  fprintf(stderr, "XXX %s\n", sqlite3_errmsg(dbconn));
1309  }
1310 
1311  int err = sqlite3_finalize(stmt);
1312  if (err != SQLITE_OK) {
1313  fprintf(stderr, "SQLite Error: %s\n", sqlite3_errmsg(dbconn));
1314  }
1315 }
1316 
1317 void putship(Ship *s) {
1318  const char *tail;
1319  Filewrite(shdata, (char *)s, sizeof(Ship), (s->number - 1) * sizeof(Ship));
1321 
1322  sqlite3_stmt *stmt;
1323  const char *sql =
1324  "REPLACE INTO tbl_ship (ship_id, player_id, governor_id, name, "
1325  "shipclass, race, xpos, ypos, mass,"
1326  "land_x, land_y, destshipno, nextship, ships, armor, size,"
1327  "max_crew, max_resource, max_destruct, max_fuel, max_speed, build_type,"
1328  "build_cost, base_mass, tech, complexity,"
1329  "destruct, resource, population, troops, crystals,"
1330  "who_killed,"
1331  "navigate_on, navigate_speed, navigate_turns, navigate_bearing,"
1332  "protect_maxrng, protect_on, protect_planet, protect_self,"
1333  "protect_evade, protect_ship,"
1334  "hyper_drive_charge, hyper_drive_ready, hyper_drive_on,"
1335  "hyper_drive_has,"
1336  "cew, cew_range, cloak, laser, focus, fire_laser,"
1337  "storbits, deststar, destpnum, pnumorbits, whatdest,"
1338  "whatorbits,"
1339  "damage, rad, retaliate, target,"
1340  "type, speed,"
1341  "active, alive, mode, bombard, mounted, cloaked,"
1342  "sheep, docked, notified, examined, on_off,"
1343  "merchant, guns, primary_gun, primtype,"
1344  "secondary_gun, sectype,"
1345  "hanger, max_hanger, mount)"
1346  "VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9,"
1347  "?10, ?11, ?12, ?13, ?14, ?15, ?16,"
1348  "?17, ?18, ?19, ?20, ?21, ?22, ?23, ?24, ?25, ?26,"
1349  "?27, ?28, ?29, ?30, ?31,"
1350  "?32,"
1351  "?33, ?34, ?35, ?36,"
1352  "?37, ?38, ?39, ?40,"
1353  "?41, ?42,"
1354  "?43, ?44, ?45,"
1355  "?46,"
1356  "?47, ?48, ?49, ?50, ?51, ?52,"
1357  "?53, ?54, ?55, ?56, ?57,"
1358  "?58,"
1359  "?59, ?60, ?61, ?62,"
1360  "?63, ?64,"
1361  "?65, ?66, ?67, ?68, ?69, ?70,"
1362  "?71, ?72, ?73, ?74, ?75,"
1363  "?76, ?77, ?78, ?79,"
1364  "?80, ?81,"
1365  "?82, ?83, ?84);";
1366 
1367  sqlite3_prepare_v2(dbconn, sql, -1, &stmt, &tail);
1368  sqlite3_bind_int(stmt, 1, s->number);
1369  sqlite3_bind_int(stmt, 2, s->owner);
1370  sqlite3_bind_int(stmt, 3, s->governor);
1371  sqlite3_bind_text(stmt, 4, s->name, strlen(s->name), SQLITE_TRANSIENT);
1372  sqlite3_bind_text(stmt, 5, s->shipclass, strlen(s->shipclass),
1373  SQLITE_TRANSIENT);
1374  sqlite3_bind_int(stmt, 6, s->race);
1375  sqlite3_bind_double(stmt, 7, s->xpos);
1376  sqlite3_bind_double(stmt, 8, s->ypos);
1377  sqlite3_bind_double(stmt, 9, s->mass);
1378  sqlite3_bind_int(stmt, 10, s->land_x);
1379  sqlite3_bind_int(stmt, 11, s->land_y);
1380  sqlite3_bind_int(stmt, 12, s->destshipno);
1381  sqlite3_bind_int(stmt, 13, s->nextship);
1382  sqlite3_bind_int(stmt, 14, s->ships);
1383  sqlite3_bind_int(stmt, 15, s->armor);
1384  sqlite3_bind_int(stmt, 16, s->size);
1385  sqlite3_bind_int(stmt, 17, s->max_crew);
1386  sqlite3_bind_int(stmt, 18, s->max_resource);
1387  sqlite3_bind_int(stmt, 19, s->max_destruct);
1388  sqlite3_bind_int(stmt, 20, s->max_fuel);
1389  sqlite3_bind_int(stmt, 21, s->max_speed);
1390  sqlite3_bind_int(stmt, 22, s->build_type);
1391  sqlite3_bind_int(stmt, 23, s->build_cost);
1392  sqlite3_bind_double(stmt, 24, s->base_mass);
1393  sqlite3_bind_double(stmt, 25, s->tech);
1394  sqlite3_bind_double(stmt, 26, s->complexity);
1395  sqlite3_bind_int(stmt, 27, s->destruct);
1396  sqlite3_bind_int(stmt, 28, s->resource);
1397  sqlite3_bind_int(stmt, 29, s->popn);
1398  sqlite3_bind_int(stmt, 30, s->troops);
1399  sqlite3_bind_int(stmt, 31, s->crystals);
1400  sqlite3_bind_int(stmt, 32, s->who_killed);
1401  sqlite3_bind_int(stmt, 33, s->navigate.on);
1402  sqlite3_bind_int(stmt, 34, s->navigate.speed);
1403  sqlite3_bind_int(stmt, 35, s->navigate.turns);
1404  sqlite3_bind_int(stmt, 36, s->navigate.bearing);
1405  sqlite3_bind_double(stmt, 37, s->protect.maxrng);
1406  sqlite3_bind_int(stmt, 38, s->protect.on);
1407  sqlite3_bind_int(stmt, 39, s->protect.planet);
1408  sqlite3_bind_int(stmt, 40, s->protect.self);
1409  sqlite3_bind_int(stmt, 41, s->protect.evade);
1410  sqlite3_bind_int(stmt, 42, s->protect.ship);
1411  sqlite3_bind_int(stmt, 43, s->hyper_drive.charge);
1412  sqlite3_bind_int(stmt, 44, s->hyper_drive.ready);
1413  sqlite3_bind_int(stmt, 45, s->hyper_drive.on);
1414  sqlite3_bind_int(stmt, 46, s->hyper_drive.has);
1415  sqlite3_bind_int(stmt, 47, s->cew);
1416  sqlite3_bind_int(stmt, 48, s->cew_range);
1417  sqlite3_bind_int(stmt, 49, s->cloak);
1418  sqlite3_bind_int(stmt, 50, s->laser);
1419  sqlite3_bind_int(stmt, 51, s->focus);
1420  sqlite3_bind_int(stmt, 52, s->fire_laser);
1421  sqlite3_bind_int(stmt, 53, s->storbits);
1422  sqlite3_bind_int(stmt, 54, s->deststar);
1423  sqlite3_bind_int(stmt, 55, s->destpnum);
1424  sqlite3_bind_int(stmt, 56, s->pnumorbits);
1425  sqlite3_bind_int(stmt, 57, s->whatdest);
1426  sqlite3_bind_int(stmt, 58, s->whatorbits);
1427  sqlite3_bind_int(stmt, 59, s->damage);
1428  sqlite3_bind_int(stmt, 60, s->rad);
1429  sqlite3_bind_int(stmt, 61, s->retaliate);
1430  sqlite3_bind_int(stmt, 62, s->target);
1431  sqlite3_bind_int(stmt, 63, s->type);
1432  sqlite3_bind_int(stmt, 64, s->speed);
1433  sqlite3_bind_int(stmt, 65, s->active);
1434  sqlite3_bind_int(stmt, 66, s->alive);
1435  sqlite3_bind_int(stmt, 67, s->mode);
1436  sqlite3_bind_int(stmt, 68, s->bombard);
1437  sqlite3_bind_int(stmt, 69, s->mounted);
1438  sqlite3_bind_int(stmt, 70, s->cloaked);
1439  sqlite3_bind_int(stmt, 71, s->sheep);
1440  sqlite3_bind_int(stmt, 72, s->docked);
1441  sqlite3_bind_int(stmt, 73, s->notified);
1442  sqlite3_bind_int(stmt, 74, s->examined);
1443  sqlite3_bind_int(stmt, 75, s->on);
1444  sqlite3_bind_int(stmt, 76, s->merchant);
1445  sqlite3_bind_int(stmt, 77, s->guns);
1446  sqlite3_bind_int(stmt, 78, s->primary);
1447  sqlite3_bind_int(stmt, 79, s->primtype);
1448  sqlite3_bind_int(stmt, 80, s->secondary);
1449  sqlite3_bind_int(stmt, 81, s->sectype);
1450  sqlite3_bind_int(stmt, 82, s->hanger);
1451  sqlite3_bind_int(stmt, 83, s->max_hanger);
1452  sqlite3_bind_int(stmt, 84, s->mount);
1453 
1454  if (sqlite3_step(stmt) != SQLITE_DONE) {
1455  fprintf(stderr, "XXX %s\n", sqlite3_errmsg(dbconn));
1456  }
1457 
1458  int err = sqlite3_finalize(stmt);
1459  if (err != SQLITE_OK) {
1460  fprintf(stderr, "SQLite Error: %s\n", sqlite3_errmsg(dbconn));
1461  }
1462 
1463  switch (s->type) {
1464  case ShipType::STYPE_MIRROR:
1465  putship_aimed(*s);
1466  break;
1467  case ShipType::OTYPE_BERS:
1468  [[fallthrough]];
1469  case ShipType::OTYPE_VN:
1470  putship_mind(*s);
1471  break;
1472  case ShipType::STYPE_POD:
1473  putship_pod(*s);
1474  break;
1475  case ShipType::OTYPE_CANIST:
1476  [[fallthrough]];
1477  case ShipType::OTYPE_GREEN:
1478  putship_timer(*s);
1479  break;
1480  case ShipType::STYPE_MISSILE:
1481  putship_impact(*s);
1482  break;
1483  case ShipType::STYPE_MINE:
1485  break;
1486  case ShipType::OTYPE_TERRA:
1487  [[fallthrough]];
1488  case ShipType::OTYPE_PLOW:
1490  break;
1491  case ShipType::OTYPE_TRANSDEV:
1493  break;
1494  case ShipType::OTYPE_TOXWC:
1495  putship_waste(*s);
1496  break;
1497  default:
1498  break;
1499  }
1500 
1502 }
1503 
1504 void putcommod(commodtype *c, int commodnum) {
1505  Filewrite(commoddata, (char *)c, sizeof(commodtype),
1506  (commodnum - 1) * sizeof(commodtype));
1507 }
1508 
1509 int Numraces() {
1510  struct stat buffer;
1511 
1512  fstat(racedata, &buffer);
1513  return ((int)(buffer.st_size / sizeof(Race)));
1514 }
1515 
1516 shipnum_t Numships() /* return number of ships */
1517 {
1518  const char *tail = nullptr;
1519  sqlite3_stmt *stmt;
1520 
1521  const auto sql = "SELECT COUNT(*) FROM tbl_ship;";
1522  sqlite3_prepare_v2(dbconn, sql, -1, &stmt, &tail);
1523 
1524  auto result = sqlite3_step(stmt);
1525  if (result != SQLITE_ROW) {
1526  throw std::runtime_error("Database unable to return the requested planet");
1527  }
1528 
1529  return sqlite3_column_int(stmt, 0);
1530  // TODO(jeffbailey): Pretty certain we have to free stmt
1531 }
1532 
1533 int Numcommods() {
1534  struct stat buffer;
1535 
1536  fstat(commoddata, &buffer);
1537  return ((int)(buffer.st_size / sizeof(commodtype)));
1538 }
1539 
1540 int Newslength(int type) {
1541  struct stat buffer;
1542  FILE *fp;
1543 
1544  switch (type) {
1545  case DECLARATION:
1546  if ((fp = fopen(DECLARATIONFL, "r")) == nullptr)
1547  fp = fopen(DECLARATIONFL, "w+");
1548  break;
1549 
1550  case TRANSFER:
1551  if ((fp = fopen(TRANSFERFL, "r")) == nullptr)
1552  fp = fopen(TRANSFERFL, "w+");
1553  break;
1554  case COMBAT:
1555  if ((fp = fopen(COMBATFL, "r")) == nullptr) fp = fopen(COMBATFL, "w+");
1556  break;
1557  case ANNOUNCE:
1558  if ((fp = fopen(ANNOUNCEFL, "r")) == nullptr)
1559  fp = fopen(ANNOUNCEFL, "w+");
1560  break;
1561  default:
1562  return 0;
1563  }
1564  fstat(fileno(fp), &buffer);
1565  fclose(fp);
1566  return ((int)buffer.st_size);
1567 }
1568 
1569 /* delete contents of dead ship file */
1570 void clr_shipfree() { fclose(fopen(SHIPFREEDATAFL, "w+")); }
1571 
1572 void clr_commodfree() { fclose(fopen(COMMODFREEDATAFL, "w+")); }
1573 
1574 /*
1575 ** writes the ship to the dead ship file at its end.
1576 */
1577 void makeshipdead(int shipnum) {
1578  int fd;
1579  unsigned short shipno;
1580  struct stat buffer;
1581 
1582  shipno = shipnum; /* conv to u_short */
1583 
1584  if (shipno == 0) return;
1585 
1586  if ((fd = open(SHIPFREEDATAFL, O_WRONLY, 0777)) < 0) {
1587  printf("fd = %d \n", fd);
1588  printf("errno = %d \n", errno);
1589  perror("openshfdata");
1590  printf("unable to open %s\n", SHIPFREEDATAFL);
1591  exit(-1);
1592  }
1593 
1594  /* write the ship # at the very end of SHIPFREEDATAFL */
1595  fstat(fd, &buffer);
1596 
1597  Filewrite(fd, (char *)&shipno, sizeof(shipno), buffer.st_size);
1598  close_file(fd);
1599 }
1600 
1601 void makecommoddead(int commodnum) {
1602  int fd;
1603  unsigned short commodno;
1604  struct stat buffer;
1605 
1606  commodno = commodnum; /* conv to u_short */
1607 
1608  if (commodno == 0) return;
1609 
1610  if ((fd = open(COMMODFREEDATAFL, O_WRONLY, 0777)) < 0) {
1611  printf("fd = %d \n", fd);
1612  printf("errno = %d \n", errno);
1613  perror("opencommodfdata");
1614  printf("unable to open %s\n", COMMODFREEDATAFL);
1615  exit(-1);
1616  }
1617 
1618  /* write the commod # at the very end of COMMODFREEDATAFL */
1619  fstat(fd, &buffer);
1620 
1621  Filewrite(fd, (char *)&commodno, sizeof(commodno), buffer.st_size);
1622  close_file(fd);
1623 }
1624 
1625 void Putpower(struct power p[MAXPLAYERS]) {
1626  int power_fd;
1627 
1628  if ((power_fd = open(POWFL, O_RDWR, 0777)) < 0) {
1629  perror("open power data");
1630  printf("unable to open %s\n", POWFL);
1631  return;
1632  }
1633  write(power_fd, (char *)p, sizeof(*p) * MAXPLAYERS);
1634  close_file(power_fd);
1635 }
1636 
1637 void Getpower(struct power p[MAXPLAYERS]) {
1638  int power_fd;
1639 
1640  if ((power_fd = open(POWFL, O_RDONLY, 0777)) < 0) {
1641  perror("open power data");
1642  printf("unable to open %s\n", POWFL);
1643  return;
1644  }
1645  read(power_fd, (char *)p, sizeof(*p) * MAXPLAYERS);
1646  close_file(power_fd);
1647 }
1648 
1649 void Putblock(struct block b[MAXPLAYERS]) {
1650  int block_fd;
1651 
1652  if ((block_fd = open(BLOCKDATAFL, O_RDWR, 0777)) < 0) {
1653  perror("open block data");
1654  printf("unable to open %s\n", BLOCKDATAFL);
1655  return;
1656  }
1657  write(block_fd, (char *)b, sizeof(*b) * MAXPLAYERS);
1658  close_file(block_fd);
1659 }
1660 
1661 void Getblock(struct block b[MAXPLAYERS]) {
1662  int block_fd;
1663 
1664  if ((block_fd = open(BLOCKDATAFL, O_RDONLY, 0777)) < 0) {
1665  perror("open block data");
1666  printf("unable to open %s\n", BLOCKDATAFL);
1667  return;
1668  }
1669  read(block_fd, (char *)b, sizeof(*b) * MAXPLAYERS);
1670  close_file(block_fd);
1671 }
1672 
1673 Db::Db() {
1678 }
1679 
1680 Db::~Db() {
1685 }
#define COMMODFREEDATAFL
Definition: files.h:43
static int shdata
Definition: files_shl.cc:33
static void putship_pod(const Ship &s)
Definition: files_shl.cc:1173
#define HELIUM
Definition: tweakables.h:37
int Newslength(int type)
Definition: files_shl.cc:1540
static int racedata
Definition: files_shl.cc:33
#define TRANSFERFL
Definition: files.h:39
static int commoddata
Definition: files_shl.cc:33
#define SULFUR
Definition: tweakables.h:36
void initsqldata()
Definition: files_shl.cc:42
int getdeadcommod()
Definition: files_shl.cc:777
#define METHANE
Definition: tweakables.h:31
#define SHIPFREEDATAFL
Definition: files.h:31
Planet getplanet(const starnum_t star, const planetnum_t pnum)
Definition: files_shl.cc:335
void makecommoddead(int commodnum)
Definition: files_shl.cc:1601
int Numcommods()
Definition: files_shl.cc:1533
std::optional< Ship > getship(const shipnum_t shipnum)
Definition: files_shl.cc:560
#define TRANSFER
Definition: files.h:18
#define OXYGEN
Definition: tweakables.h:32
#define isset(a, i)
Definition: vars.h:312
void putsector(const Sector &s, const Planet &p, const int x, const int y)
Definition: files_shl.cc:1076
#define POWFL
Definition: files.h:36
static void putship_trigger(const Ship &s)
Definition: files_shl.cc:1236
shipnum_t Numships()
Definition: files_shl.cc:1516
#define ANNOUNCEFL
Definition: files.h:41
void openstardata(int *fd)
Definition: files_shl.cc:239
static void putship_timer(const Ship &s)
Definition: files_shl.cc:1194
#define TOXIC
Definition: tweakables.h:39
static void putship_waste(const Ship &s)
Definition: files_shl.cc:1296
void makeshipdead(int shipnum)
Definition: files_shl.cc:1577
void clr_shipfree()
Definition: files_shl.cc:1570
#define ANNOUNCE
Definition: files.h:20
#define CO2
Definition: tweakables.h:33
void putsmap(SectorMap &map, Planet &p)
Definition: files_shl.cc:1108
void clr_commodfree()
Definition: files_shl.cc:1572
#define TEMP
Definition: tweakables.h:30
void putcommod(commodtype *c, int commodnum)
Definition: files_shl.cc:1504
static void putship_mind(const Ship &s)
Definition: files_shl.cc:1146
void openracedata(int *fd)
Definition: files_shl.cc:264
#define OTHER
Definition: tweakables.h:38
void Getpower(struct power p[MAXPLAYERS])
Definition: files_shl.cc:1637
#define COMBATFL
Definition: files.h:40
void Getblock(struct block b[MAXPLAYERS])
Definition: files_shl.cc:1661
#define DECLARATION
Definition: files.h:17
void Putblock(struct block b[MAXPLAYERS])
Definition: files_shl.cc:1649
void putstar(startype *s, starnum_t snum)
Definition: files_shl.cc:813
static void start_bulk_insert()
Definition: files_shl.cc:924
void getsdata(struct stardata *S)
Definition: files_shl.cc:272
#define BLOCKDATAFL
Definition: files.h:29
static void putship_impact(const Ship &s)
Definition: files_shl.cc:1214
static void putship_terraform(const Ship &s)
Definition: files_shl.cc:1256
void putplanet(const Planet &p, startype *star, const int pnum)
Definition: files_shl.cc:934
#define SHIPDATAFL
Definition: files.h:30
void getstar(startype **s, int star)
Definition: files_shl.cc:281
#define STARDATAFL
Definition: files.h:26
#define HYDROGEN
Definition: tweakables.h:34
static void putship_aimed(const Ship &s)
Definition: files_shl.cc:1121
static int stdata
Definition: files_shl.cc:33
static void end_bulk_insert()
Definition: files_shl.cc:929
void putship(Ship *s)
Definition: files_shl.cc:1317
SectorMap getsmap(const Planet &p)
Definition: files_shl.cc:522
#define NITROGEN
Definition: tweakables.h:35
void opencommoddata(int *fd)
Definition: files_shl.cc:256
#define RTEMP
Definition: tweakables.h:29
void openshdata(int *fd)
Definition: files_shl.cc:248
int getcommod(commodtype **c, commodnum_t commodnum)
Definition: files_shl.cc:730
int getdeadship()
Definition: files_shl.cc:751
#define COMBAT
Definition: files.h:19
void putsdata(struct stardata *S)
Definition: files_shl.cc:804
#define RACEDATAFL
Definition: files.h:28
#define NUMSTARS
Definition: tweakables.h:71
int Numraces()
Definition: files_shl.cc:1509
#define COMMODDATAFL
Definition: files.h:42
void getrace(Race **r, int rnum)
Definition: files_shl.cc:276
std::optional< Ship > getship(Ship **s, const shipnum_t shipnum)
Definition: files_shl.cc:564
void Putpower(struct power p[MAXPLAYERS])
Definition: files_shl.cc:1625
#define MAXPLAYERS
Definition: vars.h:45
void close_file(int fd)
Definition: files_shl.cc:40
Sector getsector(const Planet &p, const int x, const int y)
Definition: files_shl.cc:480
static void putship_transport(const Ship &s)
Definition: files_shl.cc:1276
sqlite3 * dbconn
Definition: files_shl.cc:35
void putrace(Race *r)
Definition: files_shl.cc:808
#define DECLARATIONFL
Definition: files.h:38