mirror of
https://github.com/glest/glest-source.git
synced 2025-02-25 12:12:25 +01:00
see Table glestserver now has the field: gameUUID Table glestgamestats has game header stats Table glestgameplayerstats has game player stats
364 lines
9.2 KiB
C++
364 lines
9.2 KiB
C++
// ==============================================================
|
|
// This file is part of Glest Shared Library (www.glest.org)
|
|
//
|
|
// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
|
|
//
|
|
// You can redistribute this code and/or modify it under
|
|
// the terms of the GNU General Public License as published
|
|
// by the Free Software Foundation; either version 2 of the
|
|
// License, or (at your option) any later version
|
|
// ==============================================================
|
|
/* what follows is a somewhat stripped-down version of the sample
|
|
implementation of UUID generation from RFC 4122. */
|
|
|
|
/*
|
|
** Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.
|
|
** Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. &
|
|
** Digital Equipment Corporation, Maynard, Mass.
|
|
** Copyright (c) 1998 Microsoft.
|
|
** To anyone who acknowledges that this file is provided "AS IS"
|
|
** without any express or implied warranty: permission to use, copy,
|
|
** modify, and distribute this file for any purpose is hereby
|
|
** granted without fee, provided that the above copyright notices and
|
|
** this notice appears in all source code copies, and that none of
|
|
** the names of Open Software Foundation, Inc., Hewlett-Packard
|
|
** Company, Microsoft, or Digital Equipment Corporation be used in
|
|
** advertising or publicity pertaining to distribution of the software
|
|
** without specific, written prior permission. Neither Open Software
|
|
** Foundation, Inc., Hewlett-Packard Company, Microsoft, nor Digital
|
|
** Equipment Corporation makes any representations about the
|
|
** suitability of this software for any purpose.
|
|
*/
|
|
|
|
#ifndef _SHARED_PLATFORM_UUID_H_
|
|
#define _SHARED_PLATFORM_UUID_H_
|
|
|
|
//#ifdef HAVE_CONFIG_H
|
|
//#include "config.h"
|
|
//#endif
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
namespace Shared { namespace Util {
|
|
|
|
//#if defined(HAVE_INTTYPES_H)
|
|
//#include <inttypes.h>
|
|
//#endif
|
|
|
|
/* set the following to the number of 100ns ticks of the actual
|
|
resolution of your system's clock */
|
|
#define UUIDS_PER_TICK 1024
|
|
|
|
//#ifdef WIN32
|
|
//#include <windows.h>
|
|
//#include "missing\stdint.h"
|
|
//#define snprintf _snprintf
|
|
//#else
|
|
//
|
|
//#if HAVE_SYS_TYPES_H
|
|
//#include <sys/types.h>
|
|
//#else
|
|
//# if HAVE_STDINT_H
|
|
//# include <stdint.h>
|
|
//# endif
|
|
//#endif
|
|
//
|
|
//#if HAVE_SYS_TIME_H
|
|
//#include <sys/time.h>
|
|
//#endif
|
|
//
|
|
//#if HAVE_SYS_SYSINFO_H
|
|
//#include <sys/sysinfo.h>
|
|
//#endif
|
|
//
|
|
//#endif
|
|
|
|
/* system dependent call to get the current system time. Returned as
|
|
100ns ticks since UUID epoch, but resolution may be less than
|
|
100ns. */
|
|
|
|
#ifdef WIN32
|
|
#define I64(C) C
|
|
#else
|
|
#define I64(C) C##LL
|
|
#endif
|
|
|
|
typedef uint64_t uuid_time_t;
|
|
|
|
typedef struct {
|
|
char nodeID[6];
|
|
} uuid_node_t;
|
|
|
|
#undef uuid_t
|
|
typedef struct {
|
|
uint32_t time_low;
|
|
uint16_t time_mid;
|
|
uint16_t time_hi_and_version;
|
|
uint8_t clock_seq_hi_and_reserved;
|
|
uint8_t clock_seq_low;
|
|
uint8_t node[6];
|
|
} uuid_t;
|
|
|
|
/* some forward declarations. kind of wimpy to do that but heck, we
|
|
are all friends here right? raj 20081024 */
|
|
inline static uint16_t true_random(void);
|
|
|
|
#ifdef WIN32
|
|
|
|
inline static void get_system_time(uuid_time_t *uuid_time) {
|
|
ULARGE_INTEGER time;
|
|
|
|
/* NT keeps time in FILETIME format which is 100ns ticks since
|
|
Jan 1, 1601. UUIDs use time in 100ns ticks since Oct 15, 1582.
|
|
The difference is 17 Days in Oct + 30 (Nov) + 31 (Dec)
|
|
+ 18 years and 5 leap days. */
|
|
GetSystemTimeAsFileTime((FILETIME *)&time);
|
|
time.QuadPart +=
|
|
|
|
(unsigned __int64) (1000*1000*10) // seconds
|
|
* (unsigned __int64) (60 * 60 * 24) // days
|
|
* (unsigned __int64) (17+30+31+365*18+5); // # of days
|
|
*uuid_time = time.QuadPart;
|
|
}
|
|
|
|
/* Sample code, not for use in production; see RFC 1750 */
|
|
inline static void get_random_info(char seed[16]) {
|
|
uint16_t myrand;
|
|
int i;
|
|
|
|
i = 0;
|
|
do {
|
|
myrand = true_random();
|
|
seed[i++] = myrand & 0xff;
|
|
seed[i++] = myrand >> 8;
|
|
} while (i < 14);
|
|
}
|
|
|
|
#else
|
|
|
|
inline static void get_system_time(uuid_time_t *uuid_time) {
|
|
struct timeval tp;
|
|
gettimeofday(&tp, (struct timezone *)0);
|
|
|
|
/* Offset between UUID formatted times and Unix formatted times.
|
|
UUID UTC base time is October 15, 1582.
|
|
Unix base time is January 1, 1970.*/
|
|
*uuid_time = ((uint64_t)tp.tv_sec * 10000000)
|
|
+ ((uint64_t)tp.tv_usec * 10)
|
|
+ I64(0x01B21DD213814000);
|
|
}
|
|
|
|
/* Sample code, not for use in production; see RFC 1750 */
|
|
inline static void get_random_info(char seed[16]) {
|
|
FILE *fp;
|
|
uint16_t myrand;
|
|
int i;
|
|
|
|
/* we aren't all that picky, and we would rather not block so we
|
|
will use urandom */
|
|
fp = fopen("/dev/urandom","rb");
|
|
|
|
if (NULL != fp) {
|
|
size_t bytes = fread(seed,sizeof(char),16,fp);
|
|
fclose(fp);
|
|
return;
|
|
}
|
|
|
|
/* ok, now what? */
|
|
|
|
i = 0;
|
|
do {
|
|
myrand = true_random();
|
|
seed[i++] = myrand & 0xff;
|
|
seed[i++] = myrand >> 8;
|
|
} while (i < 14);
|
|
|
|
fclose(fp);
|
|
}
|
|
|
|
#endif
|
|
|
|
/* true_random -- generate a crypto-quality random number.
|
|
**This sample doesn't do that.** */
|
|
inline static uint16_t true_random(void) {
|
|
static int inited = 0;
|
|
uuid_time_t time_now;
|
|
|
|
if (!inited) {
|
|
get_system_time(&time_now);
|
|
time_now = time_now / UUIDS_PER_TICK;
|
|
srand((unsigned int) (((time_now >> 32) ^ time_now) & 0xffffffff));
|
|
inited = 1;
|
|
}
|
|
|
|
return (uint16_t)rand();
|
|
}
|
|
|
|
/* puid -- print a UUID */
|
|
inline void puid(uuid_t u) {
|
|
int i;
|
|
|
|
printf("%8.8x-%4.4x-%4.4x-%2.2x%2.2x-", u.time_low, u.time_mid,
|
|
u.time_hi_and_version, u.clock_seq_hi_and_reserved,
|
|
u.clock_seq_low);
|
|
for (i = 0; i < 6; i++)
|
|
printf("%2.2x", u.node[i]);
|
|
printf("\n");
|
|
}
|
|
|
|
/* snpuid -- print a UUID in the supplied buffer */
|
|
inline void snpuid(char *str, size_t size, uuid_t u) {
|
|
int i;
|
|
char *tmp = str;
|
|
|
|
if (size < 38) {
|
|
snprintf(tmp,size,"%s","uuid string too small");
|
|
return;
|
|
}
|
|
|
|
/* perhaps this is a trifle optimistic but what the heck */
|
|
sprintf(tmp,
|
|
"%8.8x-%4.4x-%4.4x-%2.2x%2.2x-",
|
|
u.time_low,
|
|
u.time_mid,
|
|
u.time_hi_and_version,
|
|
u.clock_seq_hi_and_reserved,
|
|
u.clock_seq_low);
|
|
tmp += 24;
|
|
for (i = 0; i < 6; i++) {
|
|
sprintf(tmp,"%2.2x", u.node[i]);
|
|
tmp += 2;
|
|
}
|
|
*tmp = 0;
|
|
}
|
|
|
|
/* get-current_time -- get time as 60-bit 100ns ticks since UUID epoch.
|
|
Compensate for the fact that real clock resolution is
|
|
less than 100ns. */
|
|
inline static void get_current_time(uuid_time_t *timestamp) {
|
|
static int inited = 0;
|
|
static uuid_time_t time_last;
|
|
static uint16_t uuids_this_tick;
|
|
uuid_time_t time_now;
|
|
|
|
if (!inited) {
|
|
get_system_time(&time_now);
|
|
uuids_this_tick = UUIDS_PER_TICK;
|
|
inited = 1;
|
|
}
|
|
|
|
for ( ; ; ) {
|
|
get_system_time(&time_now);
|
|
|
|
/* if clock reading changed since last UUID generated, */
|
|
if (time_last != time_now) {
|
|
/* reset count of uuids gen'd with this clock reading */
|
|
uuids_this_tick = 0;
|
|
time_last = time_now;
|
|
break;
|
|
}
|
|
if (uuids_this_tick < UUIDS_PER_TICK) {
|
|
uuids_this_tick++;
|
|
break;
|
|
}
|
|
/* going too fast for our clock; spin */
|
|
}
|
|
/* add the count of uuids to low order bits of the clock reading */
|
|
*timestamp = time_now + uuids_this_tick;
|
|
}
|
|
|
|
|
|
/* system dependent call to get IEEE node ID.
|
|
This sample implementation generates a random node ID. */
|
|
/* netperf mod - don't bother trying to read or write the nodeid */
|
|
inline static void get_ieee_node_identifier(uuid_node_t *node) {
|
|
static int inited = 0;
|
|
static uuid_node_t saved_node;
|
|
char seed[16];
|
|
|
|
if (!inited) {
|
|
get_random_info(seed);
|
|
seed[0] |= 0x01;
|
|
memcpy(&saved_node, seed, sizeof saved_node);
|
|
}
|
|
inited = 1;
|
|
|
|
*node = saved_node;
|
|
}
|
|
|
|
/* format_uuid_v1 -- make a UUID from the timestamp, clockseq,
|
|
and node ID */
|
|
inline static void format_uuid_v1(uuid_t* uuid, uint16_t clock_seq,
|
|
uuid_time_t timestamp, uuid_node_t node) {
|
|
/* Construct a version 1 uuid with the information we've gathered
|
|
plus a few constants. */
|
|
uuid->time_low = (unsigned long)(timestamp & 0xFFFFFFFF);
|
|
uuid->time_mid = (unsigned short)((timestamp >> 32) & 0xFFFF);
|
|
uuid->time_hi_and_version =
|
|
(unsigned short)((timestamp >> 48) & 0x0FFF);
|
|
uuid->time_hi_and_version |= (1 << 12);
|
|
uuid->clock_seq_low = clock_seq & 0xFF;
|
|
uuid->clock_seq_hi_and_reserved = (clock_seq & 0x3F00) >> 8;
|
|
uuid->clock_seq_hi_and_reserved |= 0x80;
|
|
memcpy(&uuid->node, &node, sizeof uuid->node);
|
|
}
|
|
|
|
/* uuid_create -- generator a UUID */
|
|
inline int uuid_create(uuid_t *uuid) {
|
|
uuid_time_t timestamp;
|
|
uint16_t clockseq;
|
|
uuid_node_t node;
|
|
|
|
/* get time, node ID, saved state from non-volatile storage */
|
|
get_current_time(×tamp);
|
|
get_ieee_node_identifier(&node);
|
|
|
|
/* for us clockseq is always to be random as we have no state */
|
|
clockseq = true_random();
|
|
|
|
/* stuff fields into the UUID */
|
|
format_uuid_v1(uuid, clockseq, timestamp, node);
|
|
return 1;
|
|
}
|
|
|
|
inline void get_uuid_string(char *uuid_str, size_t size) {
|
|
uuid_t u;
|
|
|
|
uuid_create(&u);
|
|
snpuid(uuid_str,size,u);
|
|
|
|
return;
|
|
}
|
|
|
|
inline string getUUIDAsString() {
|
|
char uuid_str[38];
|
|
get_uuid_string(uuid_str,sizeof(uuid_str));
|
|
return uuid_str;
|
|
}
|
|
|
|
//#ifdef NETPERF_STANDALONE_DEBUG
|
|
//
|
|
//int
|
|
//main(int argc, char *argv[])
|
|
//{
|
|
// uuid_t u;
|
|
// char uuid_str[38];
|
|
//#if 0
|
|
// uuid_create(&u);
|
|
// printf("uuid_create(): "); puid(u);
|
|
// snpuid(uuid_str,sizeof(uuid_str),u);
|
|
// printf("\nas a string %s\n",uuid_str);
|
|
//#endif
|
|
// get_uuid_string(uuid_str,sizeof(uuid_str));
|
|
// printf("uuid_str is %s\n",uuid_str);
|
|
// return 0;
|
|
//}
|
|
//
|
|
//#endif
|
|
|
|
}};
|
|
|
|
#endif
|