mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-01-15 15:41:24 +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;
|
||||
|
||||
#define DELIM "\1"
|
||||
#define MAX_NUM_PLAYERS 4
|
||||
|
||||
static void formatParams( char* paramValues[], int nParams, const char* fmt,
|
||||
char* buf, int bufLen, ... );
|
||||
|
@ -149,6 +150,54 @@ DBMgr::FindGame( const char* connName, char* cookieBuf, int bufLen,
|
|||
return cid;
|
||||
} /* 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
|
||||
DBMgr::SeenSeed( const char* cookie, unsigned short seed,
|
||||
int langCode, int nPlayersT, bool wantsPublic,
|
||||
|
@ -295,7 +344,8 @@ DBMgr::RegisterDevice( const DevID* host )
|
|||
NULL, NULL, 0 );
|
||||
success = PGRES_COMMAND_OK == PQresultStatus(result);
|
||||
if ( !success ) {
|
||||
logf( XW_LOGERROR, "PQexec=>%s;%s", PQresStatus(PQresultStatus(result)),
|
||||
logf( XW_LOGERROR, "PQexec=>%s;%s",
|
||||
PQresStatus(PQresultStatus(result)),
|
||||
PQresultErrorMessage(result) );
|
||||
}
|
||||
PQclear( result );
|
||||
|
@ -315,7 +365,8 @@ DBMgr::updateDevice( DevIDRelay relayID, bool check )
|
|||
}
|
||||
|
||||
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_printf( query, fmt, relayID );
|
||||
execSql( query );
|
||||
|
|
|
@ -47,6 +47,9 @@ class DBMgr {
|
|||
void AddNew( const char* cookie, const char* connName, CookieID cid,
|
||||
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,
|
||||
int* langP, int* nPlayersTP, int* nPlayersHP,
|
||||
bool* isDead );
|
||||
|
|
|
@ -271,6 +271,24 @@ getNetString( const unsigned char** bufpp, const unsigned char* end, string& out
|
|||
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
|
||||
getHeader( const unsigned char** bufpp, const unsigned char* end,
|
||||
UDPHeader* header )
|
||||
|
@ -1284,6 +1302,7 @@ msgToStr( XWRelayReg msg )
|
|||
CASE_STR(XWPDEV_BADREG);
|
||||
CASE_STR(XWPDEV_ALERT); // should not receive this....
|
||||
CASE_STR(XWPDEV_ACK);
|
||||
CASE_STR(XWPDEV_DELGAME);
|
||||
default:
|
||||
str = "<unknown>";
|
||||
break;
|
||||
|
@ -1318,20 +1337,12 @@ udp_thread_proc( UdpThreadClosure* utc )
|
|||
switch( header.cmd ) {
|
||||
case XWPDEV_REG: {
|
||||
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.m_devIDString.append( (const char*)ptr, idLen );
|
||||
ptr += idLen;
|
||||
registerDevice( &devID, utc->saddr() );
|
||||
}
|
||||
if ( getRelayDevID( &ptr, end, devID ) ) {
|
||||
registerDevice( &devID, utc->saddr() );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case XWPDEV_MSG: {
|
||||
AddrInfo::ClientToken clientToken;
|
||||
memcpy( &clientToken, ptr, sizeof(clientToken) );
|
||||
|
@ -1393,14 +1404,30 @@ udp_thread_proc( UdpThreadClosure* utc )
|
|||
}
|
||||
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:
|
||||
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
|
||||
handle_udp_packet( int udpsock )
|
||||
{
|
||||
|
|
|
@ -27,7 +27,12 @@
|
|||
/* Set if device is acting a server; cleared if as client */
|
||||
#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
|
||||
#ifndef CANT_DO_TYPEDEF
|
||||
typedef
|
||||
|
@ -86,6 +91,9 @@ enum { XWPDEV_NONE /* 0 is an illegal value */
|
|||
msgID: 4
|
||||
*/
|
||||
|
||||
,XWPDEV_DELGAME /* dev->relay: game's been deleted. format:
|
||||
header, relayid: 4, clientToken: 4 */
|
||||
|
||||
}
|
||||
#ifndef CANT_DO_TYPEDEF
|
||||
XWRelayReg
|
||||
|
@ -176,6 +184,7 @@ typedef enum {
|
|||
,ID_TYPE_LINUX
|
||||
,ID_TYPE_ANDROID_GCM
|
||||
,ID_TYPE_ANDROID_OTHER
|
||||
,ID_TYPE_ANON /* please assign me one based on nothing */
|
||||
|
||||
,ID_TYPE_NTYPES
|
||||
} DevIDType;
|
||||
|
|
Loading…
Reference in a new issue