34 log_msg(ERROR,
"GameState",
"Database connection is not open");
41 if (current_time == NULL) {
42 log_msg(ERROR,
"GameState",
"Failed to get current time");
48 int rc = sqlite3_prepare_v2(db_connection->db, SQL_INSERT_GAME_STATE, -1, &stmt, NULL);
49 if (rc != SQLITE_OK) {
50 log_msg(ERROR,
"GameState",
"Failed to prepare statement: %s", sqlite3_errmsg(db_connection->db));
56 rc = sqlite3_bind_text(stmt, 1, current_time, -1, SQLITE_TRANSIENT);
57 if (rc != SQLITE_OK) {
58 log_msg(ERROR,
"GameState",
"Failed to bind time: %s", sqlite3_errmsg(db_connection->db));
59 sqlite3_finalize(stmt);
68 rc = sqlite3_bind_text(stmt, 2, save_name, -1, SQLITE_TRANSIENT);
69 if (rc != SQLITE_OK) {
70 log_msg(ERROR,
"GameState",
"Failed to bind save name: %s", sqlite3_errmsg(db_connection->db));
71 sqlite3_finalize(stmt);
76 rc = sqlite3_step(stmt);
77 if (rc != SQLITE_DONE) {
78 log_msg(ERROR,
"GameState",
"Failed to execute statement: %s", sqlite3_errmsg(db_connection->db));
81 const sqlite3_int64 game_state_id = sqlite3_last_insert_rowid(db_connection->db);
84 sqlite3_finalize(stmt);
89 if (map_json == NULL || revealed_map_json == NULL) {
91 free(revealed_map_json);
96 sqlite3_stmt* stmt_map;
97 rc = sqlite3_prepare_v2(db_connection->db, SQL_INSERT_MAP_STATE, -1, &stmt_map, NULL);
98 if (rc != SQLITE_OK) {
99 log_msg(ERROR,
"GameState",
"Failed to prepare statement: %s", sqlite3_errmsg(db_connection->db));
101 free(revealed_map_json);
106 rc = sqlite3_bind_text(stmt_map, 1, map_json, -1, SQLITE_TRANSIENT);
107 if (rc != SQLITE_OK) {
108 log_msg(ERROR,
"GameState",
"Failed to bind map: %s", sqlite3_errmsg(db_connection->db));
109 sqlite3_finalize(stmt_map);
111 free(revealed_map_json);
115 rc = sqlite3_bind_text(stmt_map, 2, revealed_map_json, -1, SQLITE_TRANSIENT);
116 if (rc != SQLITE_OK) {
117 log_msg(ERROR,
"GameState",
"Failed to bind revealed map: %s", sqlite3_errmsg(db_connection->db));
118 sqlite3_finalize(stmt_map);
120 free(revealed_map_json);
126 free(revealed_map_json);
128 rc = sqlite3_bind_int(stmt_map, 3, height);
129 if (rc != SQLITE_OK) {
130 log_msg(ERROR,
"GameState",
"Failed to bind height: %s", sqlite3_errmsg(db_connection->db));
131 sqlite3_finalize(stmt_map);
134 rc = sqlite3_bind_int(stmt_map, 4, width);
135 if (rc != SQLITE_OK) {
136 log_msg(ERROR,
"GameState",
"Failed to bind width: %s", sqlite3_errmsg(db_connection->db));
137 sqlite3_finalize(stmt_map);
140 rc = sqlite3_bind_int64(stmt_map, 5, game_state_id);
141 if (rc != SQLITE_OK) {
142 log_msg(ERROR,
"GameState",
"Failed to bind game state ID: %s", sqlite3_errmsg(db_connection->db));
143 sqlite3_finalize(stmt_map);
147 rc = sqlite3_step(stmt_map);
148 if (rc != SQLITE_DONE) {
149 log_msg(ERROR,
"GameState",
"Failed to execute statement: %s", sqlite3_errmsg(db_connection->db));
152 sqlite3_finalize(stmt_map);
155 sqlite3_stmt* stmt_player;
156 rc = sqlite3_prepare_v2(db_connection->db, SQL_INSERT_PLAYER_STATE, -1, &stmt_player, NULL);
157 if (rc != SQLITE_OK) {
158 log_msg(ERROR,
"GameState",
"Failed to prepare statement: %s", sqlite3_errmsg(db_connection->db));
162 rc = sqlite3_bind_int(stmt_player, 1, player.dx);
163 if (rc != SQLITE_OK) {
164 log_msg(ERROR,
"GameState",
"Failed to bind player x: %s", sqlite3_errmsg(db_connection->db));
165 sqlite3_finalize(stmt_player);
168 rc = sqlite3_bind_int(stmt_player, 2, player.dy);
169 if (rc != SQLITE_OK) {
170 log_msg(ERROR,
"GameState",
"Failed to bind player y: %s", sqlite3_errmsg(db_connection->db));
171 sqlite3_finalize(stmt_player);
174 rc = sqlite3_bind_int64(stmt_player, 3, game_state_id);
175 if (rc != SQLITE_OK) {
176 log_msg(ERROR,
"GameState",
"Failed to bind game state ID: %s", sqlite3_errmsg(db_connection->db));
177 sqlite3_finalize(stmt_player);
181 rc = sqlite3_step(stmt_player);
182 if (rc != SQLITE_DONE) {
183 log_msg(ERROR,
"GameState",
"Failed to execute statement: %s", sqlite3_errmsg(db_connection->db));
186 sqlite3_finalize(stmt_player);
187 return game_state_id;
235int get_game_state_by_id(
const db_connection_t* db_connection,
const int game_state_id,
int* map,
int* revealed_map,
const int width,
const int height,
const player_pos_setter_t setter) {
237 sqlite3_stmt* stmt_map;
238 int rc = sqlite3_prepare_v2(db_connection->db, SQL_SELECT_MAP_STATE, -1, &stmt_map, NULL);
239 if (rc != SQLITE_OK) {
240 log_msg(ERROR,
"GameState",
"Failed to prepare statement: %s", sqlite3_errmsg(db_connection->db));
244 rc = sqlite3_bind_int64(stmt_map, 1, game_state_id);
245 if (rc != SQLITE_OK) {
246 log_msg(ERROR,
"GameState",
"Failed to bind game state ID: %s", sqlite3_errmsg(db_connection->db));
247 sqlite3_finalize(stmt_map);
251 rc = sqlite3_step(stmt_map);
252 if (rc != SQLITE_ROW) {
253 log_msg(ERROR,
"GameState",
"Failed to execute statement: %s", sqlite3_errmsg(db_connection->db));
254 sqlite3_finalize(stmt_map);
258 sqlite3_finalize(stmt_map);
261 sqlite3_stmt* stmt_map_data;
262 rc = sqlite3_prepare_v2(db_connection->db, SQL_SELECT_MAP, -1, &stmt_map_data, NULL);
263 if (rc != SQLITE_OK) {
264 log_msg(ERROR,
"GameState",
"Failed to prepare statement: %s", sqlite3_errmsg(db_connection->db));
268 rc = sqlite3_bind_int64(stmt_map_data, 1, game_state_id);
269 if (rc != SQLITE_OK) {
270 log_msg(ERROR,
"GameState",
"Failed to bind game state ID: %s", sqlite3_errmsg(db_connection->db));
271 sqlite3_finalize(stmt_map_data);
275 rc = sqlite3_step(stmt_map_data);
276 if (rc != SQLITE_ROW) {
277 log_msg(ERROR,
"GameState",
"Failed to execute statement: %s", sqlite3_errmsg(db_connection->db));
278 sqlite3_finalize(stmt_map_data);
283 const int total_cells = width * height;
284 while (index < total_cells && rc == SQLITE_ROW) {
285 map[index] = sqlite3_column_int(stmt_map_data, 0);
287 rc = sqlite3_step(stmt_map_data);
290 if (index != total_cells) {
291 log_msg(ERROR,
"GameState",
"Didn't get all map data. Expected %d, got %d", total_cells, index);
292 sqlite3_finalize(stmt_map_data);
296 sqlite3_finalize(stmt_map_data);
299 sqlite3_stmt* stmt_revealed_map_data;
300 rc = sqlite3_prepare_v2(db_connection->db, SQL_SELECT_REVEALED_MAP, -1, &stmt_revealed_map_data, NULL);
301 if (rc != SQLITE_OK) {
302 log_msg(ERROR,
"GameState",
"Failed to prepare statement: %s", sqlite3_errmsg(db_connection->db));
306 rc = sqlite3_bind_int64(stmt_revealed_map_data, 1, game_state_id);
307 if (rc != SQLITE_OK) {
308 log_msg(ERROR,
"GameState",
"Failed to bind game state ID: %s", sqlite3_errmsg(db_connection->db));
309 sqlite3_finalize(stmt_revealed_map_data);
313 rc = sqlite3_step(stmt_revealed_map_data);
314 if (rc != SQLITE_ROW) {
315 log_msg(ERROR,
"GameState",
"Failed to execute statement: %s", sqlite3_errmsg(db_connection->db));
316 sqlite3_finalize(stmt_revealed_map_data);
322 while (index < total_cells && rc == SQLITE_ROW) {
323 revealed_map[index] = sqlite3_column_int(stmt_revealed_map_data, 0);
325 rc = sqlite3_step(stmt_revealed_map_data);
328 if (index != total_cells) {
329 log_msg(ERROR,
"GameState",
"Didn't get all revealed map data. Expected %d, got %d", total_cells, index);
330 sqlite3_finalize(stmt_revealed_map_data);
334 sqlite3_finalize(stmt_revealed_map_data);
337 sqlite3_stmt* stmt_player_data;
338 rc = sqlite3_prepare_v2(db_connection->db, SQL_SELECT_PLAYER_STATE, -1, &stmt_player_data, NULL);
339 if (rc != SQLITE_OK) {
340 log_msg(ERROR,
"GameState",
"Failed to prepare statement: %s", sqlite3_errmsg(db_connection->db));
344 rc = sqlite3_bind_int64(stmt_player_data, 1, game_state_id);
345 if (rc != SQLITE_OK) {
346 log_msg(ERROR,
"GameState",
"Failed to bind game state ID: %s", sqlite3_errmsg(db_connection->db));
347 sqlite3_finalize(stmt_player_data);
351 rc = sqlite3_step(stmt_player_data);
352 if (rc != SQLITE_ROW) {
353 log_msg(ERROR,
"GameState",
"Failed to execute statement: %s", sqlite3_errmsg(db_connection->db));
354 sqlite3_finalize(stmt_player_data);
358 const int player_x = sqlite3_column_int(stmt_player_data, 0);
359 const int player_y = sqlite3_column_int(stmt_player_data, 1);
360 setter(player_x, player_y);
361 sqlite3_finalize(stmt_player_data);
367 const int rc = sqlite3_prepare_v2(db_connection->db, SQL_SELECT_ALL_GAME_STATES, -1, &stmt, NULL);
368 if (rc != SQLITE_OK) {
369 log_msg(ERROR,
"GameState",
"Failed to prepare statement: %s", sqlite3_errmsg(db_connection->db));
375 while (sqlite3_step(stmt) == SQLITE_ROW) {
383 if (save_infos == NULL) {
384 log_msg(ERROR,
"GameState",
"Failed to allocate memory for save info container");
385 sqlite3_finalize(stmt);
389 if (save_count == 0) {
390 sqlite3_finalize(stmt);
391 save_infos->count = 0;
392 save_infos->infos = NULL;
396 save_infos->count = save_count;
397 save_infos->infos = malloc(
sizeof(
save_info_t) * save_count);
398 if (save_infos->infos == NULL) {
399 log_msg(ERROR,
"GameState",
"Failed to allocate memory for save infos");
401 sqlite3_finalize(stmt);
408 while (sqlite3_step(stmt) == SQLITE_ROW) {
409 save_infos->infos[index].id = sqlite3_column_int(stmt, 0);
411 snprintf(save_infos->infos[index].timestamp, TIMESTAMP_LENGTH,
"%s", (
const char*) sqlite3_column_text(stmt, 1));
412 snprintf(save_infos->infos[index].name, MAX_STRING_LENGTH,
"%s", (
const char*) sqlite3_column_text(stmt, 2));
416 sqlite3_finalize(stmt);
432 log_msg(ERROR,
"GameState",
"Database is not open");
438 int rc = sqlite3_prepare_v2(db_connection->db, SQL_CREATE_TABLES_GAMESTATE_GS, -1, &stmt, NULL);
439 if (rc != SQLITE_OK) {
440 log_msg(ERROR,
"GameState",
"Failed to prepare statement: %s", sqlite3_errmsg(db_connection->db));
443 rc = sqlite3_step(stmt);
444 if (rc != SQLITE_DONE) {
445 log_msg(ERROR,
"GameState",
"Failed to execute statement: %s", sqlite3_errmsg(db_connection->db));
447 sqlite3_finalize(stmt);
450 rc = sqlite3_prepare_v2(db_connection->db, SQL_CREATE_TABLES_GAMESTATE_MS, -1, &stmt, NULL);
451 if (rc != SQLITE_OK) {
452 log_msg(ERROR,
"GameState",
"Failed to prepare statement: %s", sqlite3_errmsg(db_connection->db));
455 rc = sqlite3_step(stmt);
456 if (rc != SQLITE_DONE) {
457 log_msg(ERROR,
"GameState",
"Failed to execute statement: %s", sqlite3_errmsg(db_connection->db));
459 sqlite3_finalize(stmt);
462 rc = sqlite3_prepare_v2(db_connection->db, SQL_CREATE_TABLES_GAMESTATE_PS, -1, &stmt, NULL);
463 if (rc != SQLITE_OK) {
464 log_msg(ERROR,
"GameState",
"Failed to prepare statement: %s", sqlite3_errmsg(db_connection->db));
467 rc = sqlite3_step(stmt);
468 if (rc != SQLITE_DONE) {
469 log_msg(ERROR,
"GameState",
"Failed to execute statement: %s", sqlite3_errmsg(db_connection->db));
471 sqlite3_finalize(stmt);