mirror of
https://github.com/luanti-org/luanti.git
synced 2025-11-02 00:05:26 +01:00
Add persistent unique identifiers for objects (#14135)
This commit is contained in:
@@ -5,6 +5,7 @@ set(util_SRCS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/colorize.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/directiontables.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/enriched_string.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/guid.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/hashing.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ieee_float.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/metricsbackend.cpp
|
||||
|
||||
56
src/util/guid.cpp
Normal file
56
src/util/guid.cpp
Normal file
@@ -0,0 +1,56 @@
|
||||
// Luanti
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
// Copyright (C) 2024 SFENCE
|
||||
|
||||
#include "guid.h"
|
||||
#include <cstring>
|
||||
#include <sstream>
|
||||
#include <string_view>
|
||||
|
||||
#include "exceptions.h"
|
||||
#include "util/base64.h"
|
||||
#include "log.h"
|
||||
#include "porting.h"
|
||||
#include "util/numeric.h"
|
||||
|
||||
std::string MyGUID::base64() const
|
||||
{
|
||||
return base64_encode(std::string_view(&bytes[0], bytes.size()));
|
||||
}
|
||||
|
||||
void MyGUID::serialize(std::ostream &os) const
|
||||
{
|
||||
os.write(&bytes[0], bytes.size());
|
||||
}
|
||||
|
||||
void MyGUID::deSerialize(std::istream &is)
|
||||
{
|
||||
is.read(&bytes[0], bytes.size());
|
||||
if (is.eof())
|
||||
throw SerializationError("GUID data truncated");
|
||||
}
|
||||
|
||||
GUIDGenerator::GUIDGenerator() :
|
||||
m_uniform(0, UINT64_MAX)
|
||||
{
|
||||
u64 seed;
|
||||
if (!porting::secure_rand_fill_buf(&seed, sizeof(seed))) {
|
||||
// main.cpp initializes our internal RNG as good as possible, so fall back to it
|
||||
myrand_bytes(&seed, sizeof(seed));
|
||||
}
|
||||
|
||||
// Make sure we're not losing entropy or providing too few
|
||||
static_assert(sizeof(seed) == sizeof(decltype(m_rand)::result_type), "seed type mismatch");
|
||||
m_rand.seed(seed);
|
||||
}
|
||||
|
||||
MyGUID GUIDGenerator::next()
|
||||
{
|
||||
u64 rand1 = m_uniform(m_rand);
|
||||
u64 rand2 = m_uniform(m_rand);
|
||||
|
||||
std::array<char, 16> bytes;
|
||||
std::memcpy(&bytes[0], reinterpret_cast<char*>(&rand1), 8);
|
||||
std::memcpy(&bytes[8], reinterpret_cast<char*>(&rand2), 8);
|
||||
return MyGUID{bytes};
|
||||
}
|
||||
45
src/util/guid.h
Normal file
45
src/util/guid.h
Normal file
@@ -0,0 +1,45 @@
|
||||
// Luanti
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
// Copyright (C) 2024 SFENCE
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "irrlichttypes.h"
|
||||
#include "util/basic_macros.h"
|
||||
#include <random>
|
||||
#include <string>
|
||||
#include <array>
|
||||
|
||||
class ServerEnvironment;
|
||||
|
||||
/**
|
||||
* A global unique identifier.
|
||||
* It is global because it stays valid forever.
|
||||
* It is unique because there are no collisions.
|
||||
*/
|
||||
struct MyGUID
|
||||
{
|
||||
std::array<char, 16> bytes;
|
||||
|
||||
std::string base64() const;
|
||||
void serialize(std::ostream &os) const;
|
||||
void deSerialize(std::istream &is);
|
||||
};
|
||||
|
||||
class GUIDGenerator
|
||||
{
|
||||
public:
|
||||
GUIDGenerator();
|
||||
|
||||
/**
|
||||
* Generates the next GUID, which it will never return again.
|
||||
* @return the new GUID
|
||||
*/
|
||||
MyGUID next();
|
||||
|
||||
DISABLE_CLASS_COPY(GUIDGenerator)
|
||||
|
||||
private:
|
||||
std::mt19937_64 m_rand;
|
||||
std::uniform_int_distribution<u64> m_uniform;
|
||||
};
|
||||
Reference in New Issue
Block a user