Skip to content

Commit 6739f43

Browse files
Bamcaneheinrich5991
andcommitted
Uuid from the community
Co-authored-by: heinrich5991 <heinrich5991@gmail.com>
1 parent 8feca48 commit 6739f43

File tree

20 files changed

+638
-26
lines changed

20 files changed

+638
-26
lines changed

CMakeLists.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ if(NOT POLICY CMP0048)
2626
endif()
2727

2828
project(teeworlds VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
29+
project(teeworlds C CXX)
2930

3031
set(ORIGINAL_CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH})
3132
set(ORIGINAL_CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES})
@@ -1272,6 +1273,8 @@ set_src(BASE GLOB_RECURSE src/base
12721273
tl/sorted_array.h
12731274
tl/string.h
12741275
tl/threading.h
1276+
uuid.c
1277+
uuid.h
12751278
vmath.h
12761279
)
12771280
set_src(ENGINE_INTERFACE GLOB src/engine
@@ -1343,11 +1346,16 @@ set_src(ENGINE_SHARED GLOB src/engine/shared
13431346
packer.cpp
13441347
packer.h
13451348
protocol.h
1349+
protocol_ex.cpp
1350+
protocol_ex.h
1351+
protocol_ex_msgs.h
13461352
ringbuffer.cpp
13471353
ringbuffer.h
13481354
snapshot.cpp
13491355
snapshot.h
13501356
storage.cpp
1357+
uuid_manager.cpp
1358+
uuid_manager.h
13511359
)
13521360
set(ENGINE_GENERATED_SHARED src/generated/nethash.cpp src/generated/protocol.cpp src/generated/protocol.h)
13531361
set_src(GAME_SHARED GLOB src/game

datasrc/compile.py

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
import content
44
import network
55

6-
def create_enum_table(names, num):
6+
def create_enum_table(names, num, start = "0"):
77
lines = []
88
lines += ["enum", "{"]
9-
lines += ["\t%s=0,"%names[0]]
9+
lines += [f"\t{names[0]} = {start},"]
1010
for name in names[1:]:
1111
lines += ["\t%s,"%name]
1212
lines += ["\t%s" % num, "};"]
@@ -109,9 +109,16 @@ def EmitFlags(names, num):
109109
for l in create_flags_table(["%s_%s" % (e.name, v) for v in e.values]): print(l)
110110
print("")
111111

112-
for l in create_enum_table(["NETOBJ_INVALID"]+[o.enum_name for o in network.Objects], "NUM_NETOBJTYPES"): print(l)
112+
non_extended = [o for o in network.Objects if o.ex is None]
113+
extended = [o for o in network.Objects if o.ex is not None]
114+
for l in create_enum_table(["NETOBJTYPE_EX"]+[o.enum_name for o in non_extended], "NUM_NETOBJTYPES"): print(l)
115+
for l in create_enum_table(["__NETOBJTYPE_UUID_HELPER"]+[o.enum_name for o in extended], "OFFSET_NETMSGTYPE_UUID", "OFFSET_GAME_UUID - 1"): print(l)
113116
print("")
114-
for l in create_enum_table(["NETMSG_INVALID"]+[o.enum_name for o in network.Messages], "NUM_NETMSGTYPES"): print(l)
117+
118+
non_extended = [o for o in network.Messages if o.ex is None]
119+
extended = [o for o in network.Messages if o.ex is not None]
120+
for l in create_enum_table(["NETMSGTYPE_EX"]+[o.enum_name for o in non_extended], "NUM_NETMSGTYPES"): print(l)
121+
for l in create_enum_table(["__NETMSGTYPE_UUID_HELPER"]+[o.enum_name for o in extended], "OFFSET_MAPITEMTYPE_UUID", "OFFSET_NETMSGTYPE_UUID - 1"): print(l)
115122
print("")
116123

117124
for item in network.Objects + network.Messages:
@@ -267,6 +274,10 @@ class CNetObjHandler
267274
lines += ['{']
268275
lines += ['\tswitch(Type)']
269276
lines += ['\t{']
277+
lines += ['\tcase NETOBJTYPE_EX:']
278+
lines += ['\t{']
279+
lines += ['\t\treturn 0;']
280+
lines += ['\t}']
270281

271282
for item in network.Objects:
272283
base_item = None
@@ -332,6 +343,13 @@ class CNetObjHandler
332343
lines += ['};']
333344
lines += ['']
334345

346+
lines += ['void RegisterGameUuids(CUuidManager *pManager)']
347+
lines += ['{']
348+
349+
for item in network.Objects + network.Messages:
350+
if item.ex is not None:
351+
lines += ['\tpManager->RegisterName(%s, "%s");' % (item.enum_name, item.ex)]
352+
lines += ['}']
335353

336354
for l in lines:
337355
print(l)

datasrc/datatypes.py

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ def __init__(self, name, values):
210210
self.values = values
211211

212212
class NetObject:
213-
def __init__(self, name, variables):
213+
def __init__(self, name, variables, ex=None, fixup=True):
214214
l = name.split(":")
215215
self.name = l[0]
216216
self.base = ""
@@ -220,6 +220,10 @@ def __init__(self, name, variables):
220220
self.struct_name = "CNetObj_%s" % self.name
221221
self.enum_name = "NETOBJTYPE_%s" % self.name.upper()
222222
self.variables = variables
223+
if fixup and ex != None:
224+
ex = "object-{}".format(ex)
225+
self.ex = ex
226+
223227
def emit_declaration(self):
224228
if self.base:
225229
lines = ["struct %s : public %s"%(self.struct_name,self.base_struct_name), "{"]
@@ -245,15 +249,17 @@ def emit_validate(self, base_item):
245249

246250

247251
class NetEvent(NetObject):
248-
def __init__(self, name, variables):
249-
NetObject.__init__(self, name, variables)
252+
def __init__(self, name, variables, ex=None):
253+
NetObject.__init__(self, name, variables, ex=ex)
250254
self.base_struct_name = "CNetEvent_%s" % self.base
251255
self.struct_name = "CNetEvent_%s" % self.name
252256
self.enum_name = "NETEVENTTYPE_%s" % self.name.upper()
253257

254258
class NetMessage(NetObject):
255-
def __init__(self, name, variables):
256-
NetObject.__init__(self, name, variables)
259+
def __init__(self, name, variables, ex=None):
260+
if ex != None:
261+
ex = "message-{}".format(ex)
262+
NetObject.__init__(self, name, variables, ex=ex, fixup=False)
257263
self.base_struct_name = "CNetMsg_%s" % self.base
258264
self.struct_name = "CNetMsg_%s" % self.name
259265
self.enum_name = "NETMSGTYPE_%s" % self.name.upper()
@@ -399,3 +405,15 @@ def emit_unpack_check(self):
399405
self.var.name = self.base_name + "[%d]"%i
400406
lines += self.var.emit_unpack_check()
401407
return lines
408+
409+
class NetObjectEx(NetObject):
410+
def __init__(self, name, ex, variables):
411+
NetObject.__init__(self, name, variables, ex=ex)
412+
413+
class NetEventEx(NetEvent):
414+
def __init__(self, name, ex, variables):
415+
NetEvent.__init__(self, name, variables, ex=ex)
416+
417+
class NetMessageEx(NetMessage):
418+
def __init__(self, name, ex, variables):
419+
NetMessage.__init__(self, name, variables, ex=ex)

datasrc/network.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
RawHeader = '''
2525
2626
#include <engine/message.h>
27+
#include <engine/shared/protocol_ex.h>
2728
2829
enum
2930
{

src/base/system.c

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2908,6 +2908,65 @@ const char *str_find(const char *haystack, const char *needle)
29082908
return 0;
29092909
}
29102910

2911+
static int hexval(char x)
2912+
{
2913+
switch(x)
2914+
{
2915+
case '0': return 0;
2916+
case '1': return 1;
2917+
case '2': return 2;
2918+
case '3': return 3;
2919+
case '4': return 4;
2920+
case '5': return 5;
2921+
case '6': return 6;
2922+
case '7': return 7;
2923+
case '8': return 8;
2924+
case '9': return 9;
2925+
case 'a':
2926+
case 'A': return 10;
2927+
case 'b':
2928+
case 'B': return 11;
2929+
case 'c':
2930+
case 'C': return 12;
2931+
case 'd':
2932+
case 'D': return 13;
2933+
case 'e':
2934+
case 'E': return 14;
2935+
case 'f':
2936+
case 'F': return 15;
2937+
default: return -1;
2938+
}
2939+
}
2940+
2941+
static int byteval(const char *hex, unsigned char *dst)
2942+
{
2943+
int v1 = hexval(hex[0]);
2944+
int v2 = hexval(hex[1]);
2945+
2946+
if(v1 < 0 || v2 < 0)
2947+
return 1;
2948+
2949+
*dst = v1 * 16 + v2;
2950+
return 0;
2951+
}
2952+
2953+
int str_hex_decode(void *dst, int dst_size, const char *src)
2954+
{
2955+
unsigned char *cdst = (unsigned char *) dst;
2956+
int slen = str_length(src);
2957+
int len = slen / 2;
2958+
int i;
2959+
if(slen != dst_size * 2)
2960+
return 2;
2961+
2962+
for(i = 0; i < len && dst_size; i++, dst_size--)
2963+
{
2964+
if(byteval(src + i * 2, cdst++))
2965+
return 1;
2966+
}
2967+
return 0;
2968+
}
2969+
29112970
void str_hex(char *dst, int dst_size, const void *data, int data_size)
29122971
{
29132972
static const char hex[] = "0123456789ABCDEF";

src/base/system.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1402,6 +1402,26 @@ const char *str_find_nocase(const char *haystack, const char *needle);
14021402
*/
14031403
const char *str_find(const char *haystack, const char *needle);
14041404

1405+
/*
1406+
Function: str_hex_decode
1407+
Takes a hex string *without spaces between bytes* and returns a
1408+
byte array.
1409+
1410+
Parameters:
1411+
dst - Buffer for the byte array
1412+
dst_size - size of the buffer
1413+
data - String to decode
1414+
1415+
Returns:
1416+
2 - String doesn't exactly fit the buffer
1417+
1 - Invalid character in string
1418+
0 - Success
1419+
1420+
Remarks:
1421+
- The contents of the buffer is only valid on success
1422+
*/
1423+
int str_hex_decode(void *dst, int dst_size, const char *src);
1424+
14051425
/*
14061426
Function: str_hex
14071427
Takes a datablock and generates a hexstring of it.

src/base/uuid.c

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
2+
/* If you are missing that file, acquire a complete release at teeworlds.com. */
3+
#include <base/hash_ctxt.h>
4+
#include <base/system.h>
5+
6+
#include "uuid.h"
7+
8+
static const Uuid TEEWORLDS_NAMESPACE = {{// "e05ddaaa-c4e6-4cfb-b642-5d48e80c0029"
9+
0xe0, 0x5d, 0xda, 0xaa, 0xc4, 0xe6, 0x4c, 0xfb,
10+
0xb6, 0x42, 0x5d, 0x48, 0xe8, 0x0c, 0x00, 0x29}};
11+
12+
const Uuid UUID_ZEROED = {{// "00000000-0000-0000-0000-000000000000"
13+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
14+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
15+
16+
Uuid random_uuid()
17+
{
18+
Uuid Result;
19+
secure_random_fill(&Result, sizeof(Result));
20+
21+
// set version 4 (UUID is randomly generated)
22+
Result.m_aData[6] &= 0x0f;
23+
Result.m_aData[6] |= 0x40;
24+
25+
// set variant 1 (RFC 4122)
26+
Result.m_aData[8] &= 0x3f;
27+
Result.m_aData[8] |= 0x80;
28+
29+
return Result;
30+
}
31+
32+
Uuid calculate_uuid(const char *name)
33+
{
34+
MD5_CTX Md5;
35+
MD5_DIGEST Digest;
36+
Uuid Result;
37+
38+
md5_init(&Md5);
39+
md5_update(&Md5, TEEWORLDS_NAMESPACE.m_aData, sizeof(TEEWORLDS_NAMESPACE.m_aData));
40+
// Without terminating NUL.
41+
md5_update(&Md5, name, str_length(name));
42+
43+
Digest = md5_finish(&Md5);
44+
45+
for(unsigned i = 0; i < sizeof(Result.m_aData); i++)
46+
{
47+
Result.m_aData[i] = Digest.data[i];
48+
}
49+
50+
// set version 3 (UUID is generated by MD5 hashing a namespace identifier and a name)
51+
Result.m_aData[6] &= 0x0f;
52+
Result.m_aData[6] |= 0x30;
53+
54+
// set variant 1 (RFC 4122)
55+
Result.m_aData[8] &= 0x3f;
56+
Result.m_aData[8] |= 0x80;
57+
58+
return Result;
59+
}
60+
61+
void format_uuid(Uuid uuid, char *buffer, int size)
62+
{
63+
unsigned char *p = uuid.m_aData;
64+
str_format(buffer, size,
65+
"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
66+
p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7],
67+
p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]);
68+
}
69+
70+
int uuid_comp(Uuid uuid1, Uuid uuid2)
71+
{
72+
return mem_comp(uuid1.m_aData, uuid2.m_aData, sizeof(uuid1.m_aData));
73+
}
74+
75+
int ParseUuid(Uuid *uuid, const char *buffer)
76+
{
77+
char copy[UUID_MAXSTRSIZE];
78+
if(str_length(buffer) + 1 != UUID_MAXSTRSIZE)
79+
{
80+
return 2;
81+
}
82+
str_copy(copy, buffer, sizeof(copy));
83+
// 01234567-9012-4567-9012-456789012345
84+
if(copy[8] != '-' || copy[13] != '-' || copy[18] != '-' || copy[23] != '-')
85+
{
86+
return 1;
87+
}
88+
copy[8] = copy[13] = copy[18] = copy[23] = 0;
89+
if(str_hex_decode(uuid->m_aData + 0, 4, copy + 0) ||
90+
str_hex_decode(uuid->m_aData + 4, 2, copy + 9) ||
91+
str_hex_decode(uuid->m_aData + 6, 2, copy + 14) ||
92+
str_hex_decode(uuid->m_aData + 8, 2, copy + 19) ||
93+
str_hex_decode(uuid->m_aData + 10, 6, copy + 24))
94+
{
95+
return 1;
96+
}
97+
return 0;
98+
}

0 commit comments

Comments
 (0)