Accept hexadecimal and string values for seeds
authorkwolekr <kwolekr@minetest.net>
Tue, 17 Sep 2013 06:57:10 +0000 (02:57 -0400)
committerkwolekr <kwolekr@minetest.net>
Tue, 5 Nov 2013 04:59:26 +0000 (23:59 -0500)
src/emerge.cpp
src/map.cpp
src/util/numeric.cpp
src/util/numeric.h
src/util/string.cpp
src/util/string.h

index ed9aa9044505329433aced8d84760dd27de3f6ed..569f1b80a3321e2aea69c6ce34f4e2f6a6b7f1c6 100644 (file)
@@ -351,8 +351,11 @@ MapgenParams *EmergeManager::getParamsFromSettings(Settings *settings) {
        if (!mgparams)
                return NULL;
        
+       std::string seedstr = settings->get(settings == g_settings ?
+                                                                       "fixed_map_seed" : "seed");
+       
        mgparams->mg_name     = mg_name;
-       mgparams->seed        = settings->getU64(settings == g_settings ? "fixed_map_seed" : "seed");
+       mgparams->seed        = read_seed(seedstr.c_str());
        mgparams->water_level = settings->getS16("water_level");
        mgparams->chunksize   = settings->getS16("chunksize");
        mgparams->flags       = settings->getFlagStr("mg_flags", flagdesc_mapgen);
index 968897c0c53be88bdf02982b33f49b14d96ebf9f..cea20b0d3b0dd8ca1c50dd63ab93ea02deb37e3e 100644 (file)
@@ -3507,7 +3507,7 @@ void ServerMap::loadMapMeta()
                m_seed = mgparams->seed;
        } else {
                if (params.exists("seed")) {
-                       m_seed = params.getU64("seed");
+                       m_seed = read_seed(params.get("seed").c_str());
                        m_mgparams->seed = m_seed;
                }
        }
index 67df4ffbafe0bf8cfdb201ae3084057cc5e5af3e..0426656a5a93393f765f6584abfea8f5e60491eb 100644 (file)
@@ -22,6 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #include "../log.h"
 #include "../constants.h" // BS, MAP_BLOCKSIZE
+#include <string.h>
 #include <iostream>
 
 // Calculate the borders of a "d-radius" cube
@@ -139,6 +140,49 @@ int myrand_range(int min, int max)
        return (myrand()%(max-min+1))+min;
 }
 
+// 64-bit unaligned version of MurmurHash
+u64 murmur_hash_64_ua(const void *key, int len, unsigned int seed)
+{
+       const u64 m = 0xc6a4a7935bd1e995;
+       const int r = 47;
+       u64 h = seed ^ (len * m);
+
+       const u64 *data = (const u64 *)key;
+       const u64 *end = data + (len / 8);
+
+       while (data != end) {
+               u64 k;
+               memcpy(&k, data, sizeof(u64));
+               data++;
+
+               k *= m; 
+               k ^= k >> r; 
+               k *= m; 
+               
+               h ^= k;
+               h *= m; 
+       }
+
+       const unsigned char *data2 = (const unsigned char *)data;
+       switch (len & 7) {
+               case 7: h ^= (u64)data2[6] << 48;
+               case 6: h ^= (u64)data2[5] << 40;
+               case 5: h ^= (u64)data2[4] << 32;
+               case 4: h ^= (u64)data2[3] << 24;
+               case 3: h ^= (u64)data2[2] << 16;
+               case 2: h ^= (u64)data2[1] << 8;
+               case 1: h ^= (u64)data2[0];
+                               h *= m;
+       }
+       h ^= h >> r;
+       h *= m;
+       h ^= h >> r;
+       
+       return h;
+} 
+
+
 /*
        blockpos: position of block in block coordinates
        camera_pos: position of camera in nodes
index b96c94faa70cad3a14cc89134ab09d7181c03623..8e3a617ffdc0a0a0622c7844e208e38c9f574dbf 100644 (file)
@@ -222,6 +222,8 @@ int myrand_range(int min, int max);
        Miscellaneous functions
 */
 
+u64 murmur_hash_64_ua(const void *key, int len, unsigned int seed);
+
 bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir,
                f32 camera_fov, f32 range, f32 *distance_ptr=NULL);
 
index 2c1dea49706cb97f899a87b6c5dffc8660a4f91d..a2312baf813c6d4360e34cff3548a38ffb891893 100644 (file)
@@ -19,6 +19,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #include "string.h"
 #include "pointer.h"
+#include "numeric.h"
 
 #include "../sha1.h"
 #include "../base64.h"
@@ -136,3 +137,18 @@ char *mystrtok_r(char *s, const char *sep, char **lasts) {
        *lasts = t;
        return s;
 }
+
+u64 read_seed(const char *str) {
+       char *endptr;
+       u64 num;
+       
+       if (str[0] == '0' && str[1] == 'x')
+               num = strtoull(str, &endptr, 16);
+       else
+               num = strtoull(str, &endptr, 10);
+               
+       if (*endptr)
+               num = murmur_hash_64_ua(str, (int)strlen(str), 0x1337);
+               
+       return num;
+}
index 7531600e37ebe2bfb3ca6d1bc58c6ec1c7aa60b1..81855962f971d590f9d4583f1c7a1f23083c4395 100644 (file)
@@ -321,6 +321,7 @@ size_t curl_write_data(char *ptr, size_t size, size_t nmemb, void *userdata);
 u32 readFlagString(std::string str, FlagDesc *flagdesc);
 std::string writeFlagString(u32 flags, FlagDesc *flagdesc);
 char *mystrtok_r(char *s, const char *sep, char **lasts);
+u64 read_seed(const char *str);
 
 #endif