2017-05-21 23:07:13 +00:00
|
|
|
#include "uuid_manager.h"
|
|
|
|
|
2019-04-06 00:46:56 +00:00
|
|
|
#include <base/hash_ctxt.h>
|
2017-05-21 23:07:13 +00:00
|
|
|
#include <engine/shared/packer.h>
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
2017-06-02 17:44:01 +00:00
|
|
|
static const CUuid TEEWORLDS_NAMESPACE = {{
|
2017-05-21 23:07:13 +00:00
|
|
|
// "e05ddaaa-c4e6-4cfb-b642-5d48e80c0029"
|
|
|
|
0xe0, 0x5d, 0xda, 0xaa, 0xc4, 0xe6, 0x4c, 0xfb,
|
|
|
|
0xb6, 0x42, 0x5d, 0x48, 0xe8, 0x0c, 0x00, 0x29
|
2017-06-02 17:44:01 +00:00
|
|
|
}};
|
2017-05-21 23:07:13 +00:00
|
|
|
|
2017-09-12 12:58:44 +00:00
|
|
|
CUuid RandomUuid()
|
|
|
|
{
|
|
|
|
CUuid Result;
|
|
|
|
secure_random_fill(&Result, sizeof(Result));
|
|
|
|
|
|
|
|
Result.m_aData[6] &= 0x0f;
|
|
|
|
Result.m_aData[6] |= 0x40;
|
|
|
|
Result.m_aData[8] &= 0x3f;
|
|
|
|
Result.m_aData[8] |= 0x80;
|
|
|
|
|
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
|
2017-05-21 23:07:13 +00:00
|
|
|
CUuid CalculateUuid(const char *pName)
|
|
|
|
{
|
2019-04-06 00:46:56 +00:00
|
|
|
MD5_CTX Md5;
|
2017-05-21 23:07:13 +00:00
|
|
|
md5_init(&Md5);
|
2019-04-06 00:46:56 +00:00
|
|
|
md5_update(&Md5, TEEWORLDS_NAMESPACE.m_aData, sizeof(TEEWORLDS_NAMESPACE.m_aData));
|
2017-05-21 23:07:13 +00:00
|
|
|
// Without terminating NUL.
|
2019-04-06 00:46:56 +00:00
|
|
|
md5_update(&Md5, (const unsigned char *)pName, str_length(pName));
|
|
|
|
MD5_DIGEST Digest = md5_finish(&Md5);
|
2017-05-21 23:07:13 +00:00
|
|
|
|
|
|
|
CUuid Result;
|
|
|
|
for(unsigned i = 0; i < sizeof(Result.m_aData); i++)
|
|
|
|
{
|
2019-04-06 00:46:56 +00:00
|
|
|
Result.m_aData[i] = Digest.data[i];
|
2017-05-21 23:07:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Result.m_aData[6] &= 0x0f;
|
|
|
|
Result.m_aData[6] |= 0x30;
|
|
|
|
Result.m_aData[8] &= 0x3f;
|
|
|
|
Result.m_aData[8] |= 0x80;
|
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
|
|
|
|
void FormatUuid(CUuid Uuid, char *pBuffer, unsigned BufferLength)
|
|
|
|
{
|
|
|
|
unsigned char *p = Uuid.m_aData;
|
|
|
|
str_format(pBuffer, BufferLength,
|
2017-05-27 13:02:32 +00:00
|
|
|
"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
|
2017-05-21 23:07:13 +00:00
|
|
|
p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7],
|
|
|
|
p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]);
|
|
|
|
}
|
|
|
|
|
2020-07-18 19:35:59 +00:00
|
|
|
void ParseUuid(CUuid *pUuid, char *pBuffer)
|
|
|
|
{
|
|
|
|
unsigned char *p = pUuid->m_aData;
|
|
|
|
sscanf(pBuffer, "%02hhX%02hhX%02hhX%02hhX-%02hhX%02hhX-%02hhX%02hhX-%02hhX%02hhX-%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX",
|
|
|
|
&p[0], &p[1], &p[2], &p[3], &p[4], &p[5], &p[6], &p[7],
|
|
|
|
&p[8], &p[9], &p[10], &p[11], &p[12], &p[13], &p[14], &p[15]);
|
|
|
|
}
|
|
|
|
|
2017-05-21 23:07:13 +00:00
|
|
|
bool CUuid::operator==(const CUuid& Other)
|
|
|
|
{
|
|
|
|
return mem_comp(this, &Other, sizeof(*this)) == 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CUuid::operator!=(const CUuid& Other)
|
|
|
|
{
|
|
|
|
return !(*this == Other);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int GetIndex(int ID)
|
|
|
|
{
|
|
|
|
return ID - OFFSET_UUID;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int GetID(int Index)
|
|
|
|
{
|
|
|
|
return Index + OFFSET_UUID;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CUuidManager::RegisterName(int ID, const char *pName)
|
|
|
|
{
|
2017-06-02 18:12:20 +00:00
|
|
|
dbg_assert(GetIndex(ID) == m_aNames.size(), "names must be registered with increasing ID");
|
2017-05-21 23:07:13 +00:00
|
|
|
CName Name;
|
|
|
|
Name.m_pName = pName;
|
|
|
|
Name.m_Uuid = CalculateUuid(pName);
|
|
|
|
dbg_assert(LookupUuid(Name.m_Uuid) == -1, "duplicate uuid");
|
|
|
|
|
|
|
|
m_aNames.add(Name);
|
|
|
|
}
|
|
|
|
|
|
|
|
CUuid CUuidManager::GetUuid(int ID) const
|
|
|
|
{
|
|
|
|
return m_aNames[GetIndex(ID)].m_Uuid;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *CUuidManager::GetName(int ID) const
|
|
|
|
{
|
|
|
|
return m_aNames[GetIndex(ID)].m_pName;
|
|
|
|
}
|
|
|
|
|
|
|
|
int CUuidManager::LookupUuid(CUuid Uuid) const
|
|
|
|
{
|
|
|
|
for(int i = 0; i < m_aNames.size(); i++)
|
|
|
|
{
|
|
|
|
if(Uuid == m_aNames[i].m_Uuid)
|
|
|
|
{
|
|
|
|
return GetID(i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return UUID_UNKNOWN;
|
|
|
|
}
|
|
|
|
|
2017-11-18 02:08:16 +00:00
|
|
|
int CUuidManager::NumUuids() const
|
|
|
|
{
|
|
|
|
return m_aNames.size();
|
|
|
|
}
|
|
|
|
|
2017-05-21 23:07:13 +00:00
|
|
|
int CUuidManager::UnpackUuid(CUnpacker *pUnpacker) const
|
|
|
|
{
|
|
|
|
CUuid Temp;
|
|
|
|
return UnpackUuid(pUnpacker, &Temp);
|
|
|
|
}
|
|
|
|
|
|
|
|
int CUuidManager::UnpackUuid(CUnpacker *pUnpacker, CUuid *pOut) const
|
|
|
|
{
|
|
|
|
const CUuid *pUuid = (const CUuid *)pUnpacker->GetRaw(sizeof(*pUuid));
|
|
|
|
if(pUuid == NULL)
|
|
|
|
{
|
|
|
|
return UUID_INVALID;
|
|
|
|
}
|
|
|
|
*pOut = *pUuid;
|
|
|
|
return LookupUuid(*pUuid);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CUuidManager::PackUuid(int ID, CPacker *pPacker) const
|
|
|
|
{
|
|
|
|
CUuid Uuid = GetUuid(ID);
|
|
|
|
pPacker->AddRaw(&Uuid, sizeof(Uuid));
|
|
|
|
}
|
|
|
|
|
|
|
|
void CUuidManager::DebugDump() const
|
|
|
|
{
|
|
|
|
for(int i = 0; i < m_aNames.size(); i++)
|
|
|
|
{
|
|
|
|
char aBuf[UUID_MAXSTRSIZE];
|
|
|
|
FormatUuid(m_aNames[i].m_Uuid, aBuf, sizeof(aBuf));
|
|
|
|
dbg_msg("uuid", "%s %s", aBuf, m_aNames[i].m_pName);
|
|
|
|
}
|
|
|
|
}
|