]> git.lizzy.rs Git - dragonblocks_alpha.git/commitdiff
Generate random seed & save it to database
authorElias Fleckenstein <eliasfleckenstein@web.de>
Sat, 25 Sep 2021 19:35:13 +0000 (21:35 +0200)
committerElias Fleckenstein <eliasfleckenstein@web.de>
Sat, 25 Sep 2021 19:35:13 +0000 (21:35 +0200)
src/client/client_commands.c
src/client/client_commands.h
src/client/client_player.c
src/client/debug_menu.c
src/client/debug_menu.h
src/client/game.c
src/perlin.c
src/perlin.h
src/server/database.c
src/server/server_commands.c

index c2cdc60657d8876cfabfed17da68340ebd07fab3..808c47d4b100969946694651b59875e01a8d13dc 100644 (file)
@@ -3,6 +3,7 @@
 #include <dragontype/number.h>
 #include "client/client.h"
 #include "client/client_map.h"
+#include "perlin.h"
 #include "util.h"
 
 static bool disconnect_handler(unused Client *client, bool good)
@@ -68,15 +69,18 @@ static bool block_handler(Client *client, bool good)
        return ret;
 }
 
-static bool simulation_distance_handler(Client *client, bool good)
+static bool info_handler(Client *client, bool good)
 {
        u32 simulation_distance;
+       s32 server_seed;
 
-       if (! read_u32(client->fd, &simulation_distance))
+       if (! (read_u32(client->fd, &simulation_distance) && read_s32(client->fd, &server_seed)))
                return false;
 
-       if (good)
+       if (good) {
                client_map_set_simulation_distance(simulation_distance);
+               seed = server_seed;
+       }
 
        return true;
 }
@@ -86,5 +90,5 @@ CommandHandler command_handlers[CLIENT_COMMAND_COUNT] = {
        {&disconnect_handler, "DISCONNECT", CS_CREATED | CS_AUTH | CS_ACTIVE},
        {&auth_handler, "AUTH", CS_AUTH},
        {&block_handler, "BLOCK", CS_ACTIVE},
-       {&simulation_distance_handler, "SIMULATION_DISTANCE", CS_ACTIVE},
+       {&info_handler, "INFO", CS_ACTIVE},
 };
index 388da66c44550a36a734d416256695dbda5a13bf..d894a4a006a0666880686020bb91b616f37e30a0 100644 (file)
@@ -7,7 +7,7 @@ typedef enum
        CC_DISCONNECT,
        CC_AUTH,
        CC_BLOCK,
-       CC_SIMULATION_DISTANCE,
+       CC_INFO,
        CLIENT_COMMAND_COUNT
 } ClientCommand;
 
index 67e49fea49ee35e44fc29d017549ee33b25e3fd6..4f26e2e5e71c0d1cc46580b3713973cfbd3a2993 100644 (file)
@@ -77,7 +77,7 @@ static bool can_jump()
 // ClientPlayer singleton constructor
 void client_player_init()
 {
-       client_player.pos = (v3f64) {-2500.0, 48.0, -2000.0};
+       client_player.pos = (v3f64) {0.0, 150.0, 0.0};
        client_player.velocity = (v3f64) {0.0, 0.0, 0.0};
        client_player.box = (aabb3f64) {{-0.3, 0.0, -0.3}, {0.3, 1.75, 0.3}};
        client_player.yaw = client_player.pitch = 0.0f;
index 890e9b0505f6bad2acbd27cd4b0e01f644576a39..6eee270932955663b34e4c3e79c66e7f27b7d2d9 100644 (file)
@@ -6,6 +6,7 @@
 #include "client/debug_menu.h"
 #include "client/gui.h"
 #include "client/window.h"
+#include "perlin.h"
 #include "version.h"
 
 typedef enum
@@ -17,6 +18,7 @@ typedef enum
        DME_PITCH,
        DME_HUMIDITY,
        DME_TEMPERATURE,
+       DME_SEED,
        DME_FLIGHT,
        DME_COLLISION,
        DME_FULLSCREEN,
@@ -111,6 +113,13 @@ void debug_menu_update_temperature()
        gui_set_text(gui_elements[DME_TEMPERATURE], text);
 }
 
+void debug_menu_update_seed()
+{
+       char text[BUFSIZ];
+       sprintf(text, "seed = %d", seed);
+       gui_set_text(gui_elements[DME_SEED], text);
+}
+
 void debug_menu_update_flight()
 {
        char text[BUFSIZ];
index db8cbe9c930a78c1d930c1b2a6e4401ccc98051f..a5b5cca0d6d29e3f8ded46b40d8216dc644406b9 100644 (file)
@@ -13,6 +13,7 @@ void debug_menu_update_yaw();
 void debug_menu_update_pitch();
 void debug_menu_update_humidity();
 void debug_menu_update_temperature();
+void debug_menu_update_seed();
 void debug_menu_update_flight();
 void debug_menu_update_collision();
 void debug_menu_update_fullscreen();
index 124eb2b60339501f2f6cb7adc03babac6c2f1074..5b50ad5655201c65f1f82e84a2a6b411f75660bd 100644 (file)
@@ -108,6 +108,7 @@ bool game(Client *client)
        debug_menu_toggle();
        debug_menu_update_fps(0);
        debug_menu_update_version();
+       debug_menu_update_seed();
        debug_menu_update_flight();
        debug_menu_update_collision();
        debug_menu_update_fullscreen();
index d5bd44622a8feea3f41e2f6be9364b6f3fedef0d..d204e4883a7c307eeb4e6518dc88f6d9518105e1 100644 (file)
@@ -1,3 +1,3 @@
 #include "perlin.h"
 
-int seed = 0;
+s32 seed = 0;
index e90b388d00d0ec8a6ae0e3b7e5e108e6043cd8b2..3f13e0ca377c39393adf8429a3cff759eb53710e 100644 (file)
@@ -2,6 +2,7 @@
 #define _PERLIN_H_
 
 #include <perlin/perlin.h>
+#include <dragontype/number.h>
 
 typedef enum
 {
@@ -26,6 +27,6 @@ typedef enum
        SO_VULCANO_CRATER_TOP,
 } SeedOffset;
 
-extern int seed;
+extern s32 seed;
 
 #endif
index 84ad2283fa8ad2550a54db30f0eb76afb116c448..a61af6127e10d02b3d11b1dca4ace7d43e426dc4 100644 (file)
@@ -3,18 +3,27 @@
 #include <stdlib.h>
 #include <string.h>
 #include <sqlite3.h>
+#include <time.h>
 #include "server/database.h"
 #include "server/server_map.h"
+#include "perlin.h"
 #include "util.h"
 
 static sqlite3 *database;
 
 // utility functions
 
+// prepare a SQLite3 statement
+static inline sqlite3_stmt *prepare_statement(const char *sql)
+{
+       sqlite3_stmt *stmt;
+       return sqlite3_prepare_v2(database, sql, -1, &stmt, NULL) == SQLITE_OK ? stmt : NULL;
+}
+
 // print SQLite3 error message for failed block SQL statement
-static void print_block_error(MapBlock *block, const char *action)
+static inline void print_block_error(MapBlock *block, const char *action)
 {
-       printf("Database error with %s block at (%d, %d, %d): %s\n", action, block->pos.x, block->pos.y, block->pos.z, sqlite3_errmsg(database));
+       fprintf(stderr, "Database error with %s block at (%d, %d, %d): %s\n", action, block->pos.x, block->pos.y, block->pos.z, sqlite3_errmsg(database));
 }
 
 // prepare a SQLite3 block statement and bind the position
@@ -22,7 +31,7 @@ static sqlite3_stmt *prepare_block_statement(MapBlock *block, const char *action
 {
        sqlite3_stmt *stmt;
 
-       if (sqlite3_prepare_v2(database, sql, -1, &stmt, NULL) != SQLITE_OK) {
+       if (! (stmt = prepare_statement(sql))) {
                print_block_error(block, action);
                return NULL;
        }
@@ -38,6 +47,59 @@ static sqlite3_stmt *prepare_block_statement(MapBlock *block, const char *action
        return stmt;
 }
 
+// print meta load error
+static inline void print_load_error(const char *key)
+{
+       fprintf(stderr, "Database error with loading %s: %s\n", key, sqlite3_errmsg(database));
+}
+
+// print meta save error
+static inline void print_save_error(const char *key)
+{
+       fprintf(stderr, "Database error with saving %s: %s\n", key, sqlite3_errmsg(database));
+}
+
+// load something from meta
+static bool load_meta(const char *key, int *value_ptr)
+{
+       sqlite3_stmt *stmt;
+
+       if (! (stmt = prepare_statement("SELECT value FROM meta WHERE key=?"))) {
+               print_load_error(key);
+               return false;
+       }
+
+       sqlite3_bind_text(stmt, 1, key, strlen(key), SQLITE_TRANSIENT);
+
+       int rc = sqlite3_step(stmt);
+       bool found = rc == SQLITE_ROW;
+
+       if (found)
+               *value_ptr = sqlite3_column_int(stmt, 0);
+       else if (rc != SQLITE_DONE)
+               print_load_error(key);
+
+       sqlite3_finalize(stmt);
+       return found;
+}
+
+// save something to meta
+static void save_meta(const char *key, int value)
+{
+       sqlite3_stmt *stmt;
+
+       if (! (stmt = prepare_statement("REPLACE INTO meta (key, value) VALUES(?1, ?2)"))) {
+               print_save_error(key);
+               return;
+       }
+
+       sqlite3_bind_text(stmt, 1, key, strlen(key), SQLITE_TRANSIENT);
+       sqlite3_bind_int(stmt, 2, value);
+
+       if (sqlite3_step(stmt) != SQLITE_DONE)
+               print_save_error(key);
+}
+
 // public functions
 
 // open and initialize world SQLite3 database
@@ -46,10 +108,27 @@ void database_init()
        char *err;
 
        if (sqlite3_open_v2("world.sqlite", &database, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX, NULL) != SQLITE_OK) {
-               printf("Failed to open database: %s\n", sqlite3_errmsg(database));
-       } else if (sqlite3_exec(database, "CREATE TABLE IF NOT EXISTS map (pos BLOB PRIMARY KEY, generated INT, size INT, data BLOB, mgsb_size INT, mgsb_data BLOB);", NULL, NULL, &err) != SQLITE_OK) {
-               printf("Failed to initialize database: %s\n", err);
-               sqlite3_free(err);
+               fprintf(stderr, "Failed to open database: %s\n", sqlite3_errmsg(database));
+               return;
+       }
+
+       const char *init_stmts[2]= {
+               "CREATE TABLE IF NOT EXISTS map (pos BLOB PRIMARY KEY, generated INT, size INT, data BLOB, mgsb_size INT, mgsb_data BLOB);",
+               "CREATE TABLE IF NOT EXISTS meta (key TEXT PRIMARY KEY, value INT);",
+       };
+
+       for (int i = 0; i < 2; i++) {
+               if (sqlite3_exec(database, init_stmts[i], NULL, NULL, &err) != SQLITE_OK) {
+                       fprintf(stderr, "Failed to initialize database: %s\n", err);
+                       sqlite3_free(err);
+                       return;
+               }
+       }
+
+       if (! load_meta("seed", &seed)) {
+               srand(time(0));
+               seed = rand();
+               save_meta("seed", seed);
        }
 }
 
index 14254889909a70a59f33981292540aa5a0235d8c..f001f58666f3a2a4eca3686079ab6573ea5101f6 100644 (file)
@@ -2,6 +2,7 @@
 #include <stdlib.h>
 #include "server/server.h"
 #include "server/server_map.h"
+#include "perlin.h"
 #include "util.h"
 
 // command callbacks
@@ -40,7 +41,7 @@ static bool auth_handler(Client *client, bool good)
        pthread_mutex_lock(&client->mtx);
        bool ret = write_u32(client->fd, CC_AUTH) && write_u8(client->fd, success);
        if (ret && success)
-               ret = ret && write_u32(client->fd, CC_SIMULATION_DISTANCE) && write_u32(client->fd, client->server->config.simulation_distance);
+               ret = ret && write_u32(client->fd, CC_INFO) && write_u32(client->fd, client->server->config.simulation_distance) && write_s32(client->fd, seed);
        pthread_mutex_unlock(&client->mtx);
 
        pthread_rwlock_unlock(&client->server->players_rwlck);