mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-01-28 07:58:08 +01:00
add support for udp-based delete and anonymous (relay-provided) regIDs
This commit is contained in:
parent
72e100ccac
commit
9ee16adc3a
4 changed files with 107 additions and 17 deletions
|
@ -43,6 +43,7 @@
|
||||||
static DBMgr* s_instance = NULL;
|
static DBMgr* s_instance = NULL;
|
||||||
|
|
||||||
#define DELIM "\1"
|
#define DELIM "\1"
|
||||||
|
#define MAX_NUM_PLAYERS 4
|
||||||
|
|
||||||
static void formatParams( char* paramValues[], int nParams, const char* fmt,
|
static void formatParams( char* paramValues[], int nParams, const char* fmt,
|
||||||
char* buf, int bufLen, ... );
|
char* buf, int bufLen, ... );
|
||||||
|
@ -149,6 +150,54 @@ DBMgr::FindGame( const char* connName, char* cookieBuf, int bufLen,
|
||||||
return cid;
|
return cid;
|
||||||
} /* FindGame */
|
} /* FindGame */
|
||||||
|
|
||||||
|
bool
|
||||||
|
DBMgr::FindPlayer( DevIDRelay relayID, AddrInfo::ClientToken token,
|
||||||
|
string& connName, HostID* hidp, unsigned short* seed )
|
||||||
|
{
|
||||||
|
int nSuccesses = 0;
|
||||||
|
|
||||||
|
const char* fmt =
|
||||||
|
"SELECT connName FROM %s WHERE %d = ANY(devids) AND %d = ANY(tokens)";
|
||||||
|
string query;
|
||||||
|
string_printf( query, fmt, GAMES_TABLE, relayID, token );
|
||||||
|
|
||||||
|
PGresult* result = PQexec( getThreadConn(), query.c_str() );
|
||||||
|
int nTuples = PQntuples( result );
|
||||||
|
vector<string> names(nTuples);
|
||||||
|
for ( int ii = 0; ii < nTuples; ++ii ) {
|
||||||
|
string name( PQgetvalue( result, ii, 0 ) );
|
||||||
|
names.push_back( name );
|
||||||
|
}
|
||||||
|
PQclear( result );
|
||||||
|
|
||||||
|
for ( vector<string>::const_iterator iter = names.begin();
|
||||||
|
iter != names.end(); ++iter ) {
|
||||||
|
const char* name = iter->c_str();
|
||||||
|
for ( HostID hid = 1; hid <= MAX_NUM_PLAYERS; ++hid ) {
|
||||||
|
fmt = "SELECT seeds[%d] FROM %s WHERE connname = '%s' "
|
||||||
|
"AND devids[%d] = %d AND tokens[%d] = %d";
|
||||||
|
string query;
|
||||||
|
string_printf( query, fmt, hid, GAMES_TABLE, name,
|
||||||
|
hid, relayID, hid, token );
|
||||||
|
result = PQexec( getThreadConn(), query.c_str() );
|
||||||
|
int nTuples2 = PQntuples( result );
|
||||||
|
for ( int jj = 0; jj < nTuples2; ++jj ) {
|
||||||
|
connName = name;
|
||||||
|
*hidp = hid;
|
||||||
|
*seed = atoi( PQgetvalue( result, 0, 0 ) );
|
||||||
|
++nSuccesses;
|
||||||
|
}
|
||||||
|
PQclear( result );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( 1 < nSuccesses ) {
|
||||||
|
logf( XW_LOGERROR, "%s found %d matches!!!", __func__, nSuccesses );
|
||||||
|
}
|
||||||
|
|
||||||
|
return nSuccesses >= 1;
|
||||||
|
} // FindPlayer
|
||||||
|
|
||||||
bool
|
bool
|
||||||
DBMgr::SeenSeed( const char* cookie, unsigned short seed,
|
DBMgr::SeenSeed( const char* cookie, unsigned short seed,
|
||||||
int langCode, int nPlayersT, bool wantsPublic,
|
int langCode, int nPlayersT, bool wantsPublic,
|
||||||
|
@ -295,7 +344,8 @@ DBMgr::RegisterDevice( const DevID* host )
|
||||||
NULL, NULL, 0 );
|
NULL, NULL, 0 );
|
||||||
success = PGRES_COMMAND_OK == PQresultStatus(result);
|
success = PGRES_COMMAND_OK == PQresultStatus(result);
|
||||||
if ( !success ) {
|
if ( !success ) {
|
||||||
logf( XW_LOGERROR, "PQexec=>%s;%s", PQresStatus(PQresultStatus(result)),
|
logf( XW_LOGERROR, "PQexec=>%s;%s",
|
||||||
|
PQresStatus(PQresultStatus(result)),
|
||||||
PQresultErrorMessage(result) );
|
PQresultErrorMessage(result) );
|
||||||
}
|
}
|
||||||
PQclear( result );
|
PQclear( result );
|
||||||
|
@ -315,7 +365,8 @@ DBMgr::updateDevice( DevIDRelay relayID, bool check )
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( exists ) {
|
if ( exists ) {
|
||||||
const char* fmt = "UPDATE " DEVICES_TABLE " SET mtime='now' WHERE id = %d";
|
const char* fmt =
|
||||||
|
"UPDATE " DEVICES_TABLE " SET mtime='now' WHERE id = %d";
|
||||||
string query;
|
string query;
|
||||||
string_printf( query, fmt, relayID );
|
string_printf( query, fmt, relayID );
|
||||||
execSql( query );
|
execSql( query );
|
||||||
|
|
|
@ -47,6 +47,9 @@ class DBMgr {
|
||||||
void AddNew( const char* cookie, const char* connName, CookieID cid,
|
void AddNew( const char* cookie, const char* connName, CookieID cid,
|
||||||
int langCode, int nPlayersT, bool isPublic );
|
int langCode, int nPlayersT, bool isPublic );
|
||||||
|
|
||||||
|
bool FindPlayer( DevIDRelay relayID, AddrInfo::ClientToken,
|
||||||
|
string& connName, HostID* hid, unsigned short* seed );
|
||||||
|
|
||||||
CookieID FindGame( const char* connName, char* cookieBuf, int bufLen,
|
CookieID FindGame( const char* connName, char* cookieBuf, int bufLen,
|
||||||
int* langP, int* nPlayersTP, int* nPlayersHP,
|
int* langP, int* nPlayersTP, int* nPlayersHP,
|
||||||
bool* isDead );
|
bool* isDead );
|
||||||
|
|
|
@ -271,6 +271,24 @@ getNetString( const unsigned char** bufpp, const unsigned char* end, string& out
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
getRelayDevID( const unsigned char** bufpp, const unsigned char* end,
|
||||||
|
DevID& devID )
|
||||||
|
{
|
||||||
|
bool success = false;
|
||||||
|
unsigned short idLen;
|
||||||
|
if ( getNetShort( bufpp, end, &idLen ) ) {
|
||||||
|
if ( end - *bufpp < idLen/* && ID_TYPE_ANON != typ*/ ) {
|
||||||
|
logf( XW_LOGERROR, "full devID not received" );
|
||||||
|
} else {
|
||||||
|
devID.m_devIDString.append( (const char*)*bufpp, idLen );
|
||||||
|
*bufpp += idLen;
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
getHeader( const unsigned char** bufpp, const unsigned char* end,
|
getHeader( const unsigned char** bufpp, const unsigned char* end,
|
||||||
UDPHeader* header )
|
UDPHeader* header )
|
||||||
|
@ -1284,6 +1302,7 @@ msgToStr( XWRelayReg msg )
|
||||||
CASE_STR(XWPDEV_BADREG);
|
CASE_STR(XWPDEV_BADREG);
|
||||||
CASE_STR(XWPDEV_ALERT); // should not receive this....
|
CASE_STR(XWPDEV_ALERT); // should not receive this....
|
||||||
CASE_STR(XWPDEV_ACK);
|
CASE_STR(XWPDEV_ACK);
|
||||||
|
CASE_STR(XWPDEV_DELGAME);
|
||||||
default:
|
default:
|
||||||
str = "<unknown>";
|
str = "<unknown>";
|
||||||
break;
|
break;
|
||||||
|
@ -1318,20 +1337,12 @@ udp_thread_proc( UdpThreadClosure* utc )
|
||||||
switch( header.cmd ) {
|
switch( header.cmd ) {
|
||||||
case XWPDEV_REG: {
|
case XWPDEV_REG: {
|
||||||
DevIDType typ = (DevIDType)*ptr++;
|
DevIDType typ = (DevIDType)*ptr++;
|
||||||
unsigned short idLen;
|
|
||||||
if ( !getNetShort( &ptr, end, &idLen ) ) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if ( end - ptr > idLen ) {
|
|
||||||
logf( XW_LOGERROR, "full devID not received" );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
DevID devID( typ );
|
DevID devID( typ );
|
||||||
devID.m_devIDString.append( (const char*)ptr, idLen );
|
if ( getRelayDevID( &ptr, end, devID ) ) {
|
||||||
ptr += idLen;
|
registerDevice( &devID, utc->saddr() );
|
||||||
registerDevice( &devID, utc->saddr() );
|
}
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case XWPDEV_MSG: {
|
case XWPDEV_MSG: {
|
||||||
AddrInfo::ClientToken clientToken;
|
AddrInfo::ClientToken clientToken;
|
||||||
memcpy( &clientToken, ptr, sizeof(clientToken) );
|
memcpy( &clientToken, ptr, sizeof(clientToken) );
|
||||||
|
@ -1393,14 +1404,30 @@ udp_thread_proc( UdpThreadClosure* utc )
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case XWPDEV_DELGAME: {
|
||||||
|
DevID devID( ID_TYPE_RELAY );
|
||||||
|
if ( !getRelayDevID( &ptr, end, devID ) ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
AddrInfo::ClientToken clientToken;
|
||||||
|
if ( getNetLong( &ptr, end, &clientToken ) && 0 != clientToken ) {
|
||||||
|
unsigned short seed;
|
||||||
|
HostID hid;
|
||||||
|
string connName;
|
||||||
|
if ( DBMgr::Get()->FindPlayer( devID.asRelayID(), clientToken,
|
||||||
|
connName, &hid, &seed ) ) {
|
||||||
|
SafeCref scr( connName.c_str() );
|
||||||
|
scr.DeviceGone( hid, seed );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
logf( XW_LOGERROR, "%s: unexpected msg %d", __func__, header.cmd );
|
logf( XW_LOGERROR, "%s: unexpected msg %d", __func__, header.cmd );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This will need to be done in a thread before there can be simulaneous
|
|
||||||
// connections.
|
|
||||||
static void
|
static void
|
||||||
handle_udp_packet( int udpsock )
|
handle_udp_packet( int udpsock )
|
||||||
{
|
{
|
||||||
|
|
|
@ -27,7 +27,12 @@
|
||||||
/* Set if device is acting a server; cleared if as client */
|
/* Set if device is acting a server; cleared if as client */
|
||||||
#define FLAGS_SERVER_BIT 0x01
|
#define FLAGS_SERVER_BIT 0x01
|
||||||
|
|
||||||
/* message types for the udp-based per-device (not per-game) protocol */
|
/* message types for the udp-based per-device (not per-game) protocol
|
||||||
|
*
|
||||||
|
* A number of these rely on a "clientToken", which is a 32-bit value the
|
||||||
|
* client provides and that it guarantees uniquely identifies a game on the
|
||||||
|
* device. A database rowid works great as long as they aren't reused.
|
||||||
|
*/
|
||||||
#define XWPDEV_PROTO_VERSION 0
|
#define XWPDEV_PROTO_VERSION 0
|
||||||
#ifndef CANT_DO_TYPEDEF
|
#ifndef CANT_DO_TYPEDEF
|
||||||
typedef
|
typedef
|
||||||
|
@ -86,6 +91,9 @@ enum { XWPDEV_NONE /* 0 is an illegal value */
|
||||||
msgID: 4
|
msgID: 4
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
,XWPDEV_DELGAME /* dev->relay: game's been deleted. format:
|
||||||
|
header, relayid: 4, clientToken: 4 */
|
||||||
|
|
||||||
}
|
}
|
||||||
#ifndef CANT_DO_TYPEDEF
|
#ifndef CANT_DO_TYPEDEF
|
||||||
XWRelayReg
|
XWRelayReg
|
||||||
|
@ -176,6 +184,7 @@ typedef enum {
|
||||||
,ID_TYPE_LINUX
|
,ID_TYPE_LINUX
|
||||||
,ID_TYPE_ANDROID_GCM
|
,ID_TYPE_ANDROID_GCM
|
||||||
,ID_TYPE_ANDROID_OTHER
|
,ID_TYPE_ANDROID_OTHER
|
||||||
|
,ID_TYPE_ANON /* please assign me one based on nothing */
|
||||||
|
|
||||||
,ID_TYPE_NTYPES
|
,ID_TYPE_NTYPES
|
||||||
} DevIDType;
|
} DevIDType;
|
||||||
|
|
Loading…
Add table
Reference in a new issue