mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-02-09 22:00:39 +01:00
break connect and reconnect into separate paths to simplify. Be
consistent: nJoined in DB tracks players "ever seen and issued connName" rather than "currently connected". Next step: debug game between two devices never connected at same time.
This commit is contained in:
parent
8961910263
commit
a870cac86d
5 changed files with 138 additions and 206 deletions
|
@ -594,6 +594,7 @@ CookieRef::handleEvents()
|
||||||
case XWA_SEND_RERSP:
|
case XWA_SEND_RERSP:
|
||||||
sendResponse( &evt, false );
|
sendResponse( &evt, false );
|
||||||
sendAnyStored( &evt );
|
sendAnyStored( &evt );
|
||||||
|
increasePlayerCounts( &evt, true );
|
||||||
// postCheckAllHere();
|
// postCheckAllHere();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -776,9 +777,6 @@ CookieRef::increasePlayerCounts( const CRefEvent* evt, bool reconn )
|
||||||
int nPlayersH = evt->u.con.nPlayersH;
|
int nPlayersH = evt->u.con.nPlayersH;
|
||||||
int socket = evt->u.con.socket;
|
int socket = evt->u.con.socket;
|
||||||
int seed = evt->u.con.seed;
|
int seed = evt->u.con.seed;
|
||||||
bool addHost = false;
|
|
||||||
bool addAck = false;
|
|
||||||
/* XW_RELAY_EVENT newEvt = XWE_NONE; */
|
|
||||||
|
|
||||||
assert( m_nPlayersSought > 0 );
|
assert( m_nPlayersSought > 0 );
|
||||||
assert( m_nPlayersSought == evt->u.con.nPlayersS );
|
assert( m_nPlayersSought == evt->u.con.nPlayersS );
|
||||||
|
@ -797,65 +795,19 @@ CookieRef::increasePlayerCounts( const CRefEvent* evt, bool reconn )
|
||||||
recommend a new game as things must be pretty f*cked up. Or somebody's
|
recommend a new game as things must be pretty f*cked up. Or somebody's
|
||||||
mucking with me. */
|
mucking with me. */
|
||||||
|
|
||||||
if ( reconn ) {
|
if ( !reconn ) {
|
||||||
if ( 0 != m_nPlayersSought &&
|
|
||||||
m_nPlayersHere + nPlayersH > m_nPlayersSought ) {
|
|
||||||
logf( XW_LOGERROR, "too many new players provided: %d > %d",
|
|
||||||
m_nPlayersHere + nPlayersH, m_nPlayersSought );
|
|
||||||
goto drop;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_nPlayersHere += nPlayersH;
|
|
||||||
/* if ( m_nPlayersHere == m_nPlayersSought ) { */
|
|
||||||
/* newEvt = XWE_ALLHERE; */
|
|
||||||
/* } else { */
|
|
||||||
/* newEvt = XWE_SOMEMISSING; */
|
|
||||||
/* } */
|
|
||||||
addHost = true;
|
|
||||||
} else { /* a host; init values */
|
|
||||||
m_nPlayersHere += nPlayersH;
|
m_nPlayersHere += nPlayersH;
|
||||||
assert( m_nPlayersHere <= m_nPlayersSought );
|
assert( m_nPlayersHere <= m_nPlayersSought );
|
||||||
addAck = true;
|
|
||||||
DBMgr::Get()->AddPlayers( ConnName(), nPlayersH );
|
DBMgr::Get()->AddPlayers( ConnName(), nPlayersH );
|
||||||
|
|
||||||
/* if ( m_nPlayersHere == m_nPlayersSought ) { /\* complete! *\/ */
|
|
||||||
/* newEvt = XWE_ALLHERE; */
|
|
||||||
/* } else { */
|
|
||||||
/* newEvt = XWE_SOMEMISSING; */
|
|
||||||
/* } */
|
|
||||||
/* } else { /\* a guest *\/ */
|
|
||||||
/* assert( reconn || m_nPlayersSought != 0 ); /\* host better be here *\/ */
|
|
||||||
|
|
||||||
/* if ( m_nPlayersSought < m_nPlayersHere + nPlayersH ) { /\* too many; */
|
|
||||||
/* reject *\/ */
|
|
||||||
/* newEvt = XWE_TOO_MANY; */
|
|
||||||
/* } else { */
|
|
||||||
/* m_nPlayersHere += nPlayersH; */
|
|
||||||
/* if ( m_nPlayersHere == m_nPlayersSought ) { /\* complete! *\/ */
|
|
||||||
/* newEvt = XWE_ALLHERE; */
|
|
||||||
/* m_gameFull = true; */
|
|
||||||
/* } else { */
|
|
||||||
/* newEvt = XWE_SOMEMISSING; */
|
|
||||||
/* } */
|
|
||||||
/* addHost = true; */
|
|
||||||
/* } */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if ( newEvt != XWE_NONE ) { */
|
|
||||||
/* CRefEvent evt( newEvt ); */
|
|
||||||
/* m_eventQueue.push_back( evt ); */
|
|
||||||
/* } else { */
|
|
||||||
/* logf( XW_LOGERROR, "%s: not pushing an event", __func__ ); */
|
|
||||||
/* } */
|
|
||||||
|
|
||||||
if ( addHost || addAck ) {
|
|
||||||
HostID hostid = evt->u.con.srcID;
|
HostID hostid = evt->u.con.srcID;
|
||||||
/* first add the rec here, whether it'll stay for not */
|
/* first add the rec here, whether it'll get ack'd or not */
|
||||||
logf( XW_LOGINFO, "%s: remembering pair: hostid=%x, "
|
logf( XW_LOGINFO, "%s: remembering pair: hostid=%x, "
|
||||||
"socket=%d (size=%d)",
|
"socket=%d (size=%d)",
|
||||||
__func__, hostid, socket, m_sockets.size());
|
__func__, hostid, socket, m_sockets.size());
|
||||||
|
|
||||||
HostRec hr( hostid, socket, nPlayersH, seed, addAck );
|
HostRec hr( hostid, socket, nPlayersH, seed, !reconn );
|
||||||
m_sockets.push_back( hr );
|
m_sockets.push_back( hr );
|
||||||
|
|
||||||
assert( !AlreadyHere( evt->u.con.seed, -1 ) );
|
assert( !AlreadyHere( evt->u.con.seed, -1 ) );
|
||||||
|
@ -863,11 +815,8 @@ CookieRef::increasePlayerCounts( const CRefEvent* evt, bool reconn )
|
||||||
|
|
||||||
logf( XW_LOGVERBOSE1, "%s: here=%d; total=%d", __func__,
|
logf( XW_LOGVERBOSE1, "%s: here=%d; total=%d", __func__,
|
||||||
m_nPlayersHere, m_nPlayersSought );
|
m_nPlayersHere, m_nPlayersSought );
|
||||||
} else {
|
|
||||||
assert( 0 );
|
return true;
|
||||||
}
|
|
||||||
drop:
|
|
||||||
return addHost || addAck;
|
|
||||||
} /* increasePlayerCounts */
|
} /* increasePlayerCounts */
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1143,20 +1092,20 @@ void
|
||||||
CookieRef::checkSomeMissing( void )
|
CookieRef::checkSomeMissing( void )
|
||||||
{
|
{
|
||||||
logf( XW_LOGINFO, "%s", __func__ );
|
logf( XW_LOGINFO, "%s", __func__ );
|
||||||
int count = 0;
|
/* int count = 0; */
|
||||||
|
|
||||||
vector<HostRec>::iterator iter;
|
/* vector<HostRec>::iterator iter; */
|
||||||
for ( iter = m_sockets.begin(); iter != m_sockets.end(); ++iter ) {
|
/* for ( iter = m_sockets.begin(); iter != m_sockets.end(); ++iter ) { */
|
||||||
count += iter->m_nPlayersH;
|
/* count += iter->m_nPlayersH; */
|
||||||
}
|
/* } */
|
||||||
/* Don't really need the iterator above.... */
|
/* /\* Don't really need the iterator above.... *\/ */
|
||||||
assert( count == m_nPlayersHere );
|
/* assert( count == m_nPlayersHere ); */
|
||||||
|
|
||||||
logf( XW_LOGINFO, "%s; count=%d; nPlayersS=%d", __func__,
|
logf( XW_LOGINFO, "%s; count=%d; nPlayersS=%d", __func__,
|
||||||
count, m_nPlayersSought );
|
m_nPlayersHere, m_nPlayersSought );
|
||||||
|
|
||||||
assert( count <= m_nPlayersSought );
|
assert( m_nPlayersHere <= m_nPlayersSought );
|
||||||
if ( count < m_nPlayersSought ) {
|
if ( m_nPlayersHere < m_nPlayersSought ) {
|
||||||
CRefEvent evt( XWE_SOMEMISSING );
|
CRefEvent evt( XWE_SOMEMISSING );
|
||||||
m_eventQueue.push_back( evt );
|
m_eventQueue.push_back( evt );
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,111 +107,6 @@ CRefMgr::CloseAll()
|
||||||
}
|
}
|
||||||
} /* CloseAll */
|
} /* CloseAll */
|
||||||
|
|
||||||
/* Find a game to which this guy belongs. Return NULL if none's found and
|
|
||||||
* presumably a new one will be created.
|
|
||||||
*
|
|
||||||
* Match by connName if provided. If I match, great. But what if there isn't
|
|
||||||
* room, which would normally mean I'm already there and this is a duplicate
|
|
||||||
* packet. Should a dup be simply dropped, or should I reply? If the dup
|
|
||||||
* happened because our earlier reply was dropped then we should in fact
|
|
||||||
* reply.
|
|
||||||
*
|
|
||||||
* If match is by cookie (called Room in the UI) we need to be careful. If
|
|
||||||
* this is an established game, meaning that at some point all devices were
|
|
||||||
* there and a connName was established, then check if the incoming seed is in
|
|
||||||
* that connName, otherwise reject it (to form its own game.) But otherwise,
|
|
||||||
* if either we can't match seeds yet or this guy's does match, let him in.
|
|
||||||
* Again there's the duplicate packet issue if the game is "full" already.
|
|
||||||
*
|
|
||||||
* Match can also occur on cookie only -- device has no connName perhaps
|
|
||||||
* because the relay crashed before sending it -- where the device belongs in
|
|
||||||
* an existing game. That we detect by checking if the new arrival's seed is
|
|
||||||
* a component of the candidate's connName.
|
|
||||||
*/
|
|
||||||
|
|
||||||
CookieRef*
|
|
||||||
CRefMgr::FindOpenGameFor( const char* cookie, const char* connName,
|
|
||||||
HostID hid, int socket, int nPlayersH, int nPlayersT,
|
|
||||||
int gameSeed, int langCode, bool wantsPublic,
|
|
||||||
bool* alreadyHere )
|
|
||||||
{
|
|
||||||
#if 1
|
|
||||||
CookieRef* found = NULL;
|
|
||||||
CookieID cid = m_db->FindOpen( cookie, langCode, nPlayersT, nPlayersH, wantsPublic );
|
|
||||||
if ( cid > 0 ) {
|
|
||||||
found = getCookieRef_impl( cid );
|
|
||||||
}
|
|
||||||
return found;
|
|
||||||
#else
|
|
||||||
logf( XW_LOGINFO, "%s(cookie=%s,connName=%s,hid=%d,seed=%x,socket=%d,"
|
|
||||||
"here=%d,total=%d)", __func__, cookie, connName, hid, gameSeed,
|
|
||||||
socket, nPlayersH, nPlayersT );
|
|
||||||
CookieRef* found = NULL;
|
|
||||||
|
|
||||||
assert( !!cookie || !!connName );
|
|
||||||
RWReadLock rwl( &m_cookieMapRWLock );
|
|
||||||
|
|
||||||
CookieMap::iterator iter;
|
|
||||||
for ( iter = m_cookieMap.begin();
|
|
||||||
NULL == found && iter != m_cookieMap.end();
|
|
||||||
++iter ) {
|
|
||||||
CookieRef* cref = iter->second;
|
|
||||||
|
|
||||||
/* Reject immediately if language code or proposed game size don't
|
|
||||||
match. */
|
|
||||||
if ( (cref->GetLangCode() != langCode)
|
|
||||||
|| (cref->GetPlayersSought() != nPlayersT) ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !!connName && 0 == strcmp( cref->ConnName(), connName ) ) {
|
|
||||||
found = cref;
|
|
||||||
/* if ( cref->Lock() ) { */
|
|
||||||
|
|
||||||
/* assert( !cookie || */
|
|
||||||
/* 0 == strcasecmp( cookie, cref->Cookie() ) ); */
|
|
||||||
/* if ( cref->SeedBelongs( gameSeed ) ) { */
|
|
||||||
/* logf( XW_LOGINFO, "%s: SeedBelongs: dup packet?", */
|
|
||||||
/* __func__ ); */
|
|
||||||
/* *alreadyHere = true; */
|
|
||||||
/* found = cref; */
|
|
||||||
/* } else if ( cref->GameOpen( cookie, false, */
|
|
||||||
/* alreadyHere ) ) { */
|
|
||||||
/* found = cref; */
|
|
||||||
/* } else { */
|
|
||||||
/* /\* drop if we match on connName and it's not */
|
|
||||||
/* wanted; must be dup. *\/ */
|
|
||||||
/* *alreadyHere = true; */
|
|
||||||
/* } */
|
|
||||||
/* cref->Unlock(); */
|
|
||||||
/* } */
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !found && !!cookie ) {
|
|
||||||
if ( 0 == strcasecmp( cref->Cookie(), cookie ) ) {
|
|
||||||
if ( cref->Lock() ) {
|
|
||||||
assert( cref->ConnName()[0] );
|
|
||||||
if ( cref->AlreadyHere( gameSeed, -1 ) ) {
|
|
||||||
found = cref;
|
|
||||||
*alreadyHere = true;
|
|
||||||
} else if ( cref->GameOpen( cookie ) ) {
|
|
||||||
found = cref;
|
|
||||||
} else if ( cref->HasSocket_locked(socket) ) {
|
|
||||||
assert( 0 ); /* should have dumped the socket */
|
|
||||||
logf( XW_LOGINFO, "%s: HasSocket case", __func__);
|
|
||||||
found = cref;
|
|
||||||
}
|
|
||||||
cref->Unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} /* for */
|
|
||||||
|
|
||||||
logf( XW_LOGINFO, "%s=>%p", __func__, found );
|
|
||||||
return found;
|
|
||||||
#endif
|
|
||||||
} /* FindOpenGameFor */
|
|
||||||
|
|
||||||
CookieID
|
CookieID
|
||||||
CRefMgr::nextCID( const char* connName )
|
CRefMgr::nextCID( const char* connName )
|
||||||
{
|
{
|
||||||
|
@ -334,10 +229,10 @@ CRefMgr::getFromFreeList( void )
|
||||||
|
|
||||||
|
|
||||||
CookieRef*
|
CookieRef*
|
||||||
CRefMgr::getMakeCookieRef_locked( const char* cookie, const char* connName,
|
CRefMgr::getMakeCookieRef_locked( const char* cookie, HostID hid, int socket,
|
||||||
HostID hid, int socket, int nPlayersH,
|
int nPlayersH, int nPlayersT, int langCode,
|
||||||
int nPlayersT, int langCode, int gameSeed,
|
int gameSeed, bool wantsPublic,
|
||||||
bool wantsPublic, bool makePublic )
|
bool makePublic )
|
||||||
{
|
{
|
||||||
CookieRef* cref;
|
CookieRef* cref;
|
||||||
|
|
||||||
|
@ -349,18 +244,49 @@ CRefMgr::getMakeCookieRef_locked( const char* cookie, const char* connName,
|
||||||
later when the game is complete.
|
later when the game is complete.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool alreadyHere;
|
char connNameBuf[MAX_CONNNAME_LEN+1] = {0};
|
||||||
cref = FindOpenGameFor( cookie, connName, hid, socket, nPlayersH, nPlayersT,
|
CookieID cid = m_db->FindOpen( cookie, langCode, nPlayersT, nPlayersH,
|
||||||
gameSeed, langCode, wantsPublic, &alreadyHere );
|
wantsPublic,
|
||||||
if ( cref == NULL && !alreadyHere ) {
|
connNameBuf, sizeof(connNameBuf) );
|
||||||
CookieID cid = nextCID( NULL );
|
if ( cid > 0 ) {
|
||||||
cref = AddNew( cookie, connName, cid, langCode, nPlayersT );
|
cref = getCookieRef_impl( cid );
|
||||||
m_db->AddNew( cookie, cref->ConnName(), cid, langCode, nPlayersT, makePublic );
|
} else {
|
||||||
|
cid = nextCID( NULL );
|
||||||
|
cref = AddNew( cookie, connNameBuf, cid, langCode, nPlayersT );
|
||||||
|
if ( !connNameBuf[0] ) { /* didn't exist in DB */
|
||||||
|
m_db->AddNew( cookie, cref->ConnName(), cid, langCode, nPlayersT,
|
||||||
|
wantsPublic || makePublic );
|
||||||
|
} else {
|
||||||
|
m_db->AddCID( connNameBuf, cid );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return cref;
|
return cref;
|
||||||
} /* getMakeCookieRef_locked */
|
} /* getMakeCookieRef_locked */
|
||||||
|
|
||||||
|
CookieRef*
|
||||||
|
CRefMgr::getMakeCookieRef_locked( const char* connName, HostID hid, int socket,
|
||||||
|
int nPlayersH, int seed )
|
||||||
|
{
|
||||||
|
CookieRef* cref = NULL;
|
||||||
|
|
||||||
|
/* fetch these from DB */
|
||||||
|
char cookie[MAX_INVITE_LEN+1];
|
||||||
|
int langCode;
|
||||||
|
int nPlayersT;
|
||||||
|
|
||||||
|
CookieID cid = m_db->FindGame( connName, cookie, sizeof(cookie),
|
||||||
|
&langCode, &nPlayersT );
|
||||||
|
if ( 0 != cid ) { /* already open */
|
||||||
|
cref = getCookieRef_impl( cid );
|
||||||
|
} else {
|
||||||
|
CookieID cid = nextCID( NULL );
|
||||||
|
cref = AddNew( cookie, connName, cid, langCode, nPlayersT );
|
||||||
|
m_db->AddCID( connName, cid );
|
||||||
|
}
|
||||||
|
return cref;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
CRefMgr::Associate( int socket, CookieRef* cref )
|
CRefMgr::Associate( int socket, CookieRef* cref )
|
||||||
{
|
{
|
||||||
|
@ -510,6 +436,9 @@ CookieRef*
|
||||||
CRefMgr::AddNew( const char* cookie, const char* connName, CookieID id,
|
CRefMgr::AddNew( const char* cookie, const char* connName, CookieID id,
|
||||||
int langCode, int nPlayers )
|
int langCode, int nPlayers )
|
||||||
{
|
{
|
||||||
|
if ( 0 == connName[0] ) {
|
||||||
|
connName = NULL;
|
||||||
|
}
|
||||||
/* PENDING: should this return a locked cref? */
|
/* PENDING: should this return a locked cref? */
|
||||||
logf( XW_LOGINFO, "%s( cookie=%s, connName=%s, cid=%d)", __func__,
|
logf( XW_LOGINFO, "%s( cookie=%s, connName=%s, cid=%d)", __func__,
|
||||||
cookie, connName, id );
|
cookie, connName, id );
|
||||||
|
@ -684,7 +613,7 @@ SafeCref::SafeCref( const char* cookie, int socket, int nPlayersH, int nPlayersS
|
||||||
{
|
{
|
||||||
CookieRef* cref;
|
CookieRef* cref;
|
||||||
|
|
||||||
cref = m_mgr->getMakeCookieRef_locked( cookie, NULL, 0, socket,
|
cref = m_mgr->getMakeCookieRef_locked( cookie, 0, socket,
|
||||||
nPlayersH, nPlayersS, langCode,
|
nPlayersH, nPlayersS, langCode,
|
||||||
gameSeed, wantsPublic, makePublic );
|
gameSeed, wantsPublic, makePublic );
|
||||||
if ( cref != NULL ) {
|
if ( cref != NULL ) {
|
||||||
|
@ -704,8 +633,8 @@ SafeCref::SafeCref( const char* connName, HostID hid,
|
||||||
{
|
{
|
||||||
CookieRef* cref;
|
CookieRef* cref;
|
||||||
|
|
||||||
cref = m_mgr->getMakeCookieRef_locked( NULL, connName, hid, socket, nPlayersH,
|
cref = m_mgr->getMakeCookieRef_locked( connName, hid, socket, nPlayersH,
|
||||||
nPlayersS, langCode, gameSeed, false, false );
|
gameSeed );
|
||||||
if ( cref != NULL ) {
|
if ( cref != NULL ) {
|
||||||
m_locked = cref->Lock();
|
m_locked = cref->Lock();
|
||||||
m_cref = cref;
|
m_cref = cref;
|
||||||
|
|
|
@ -135,11 +135,17 @@ class CRefMgr {
|
||||||
void addToFreeList( CookieRef* cref );
|
void addToFreeList( CookieRef* cref );
|
||||||
CookieRef* getFromFreeList( void );
|
CookieRef* getFromFreeList( void );
|
||||||
|
|
||||||
|
/* connect case */
|
||||||
CookieRef* getMakeCookieRef_locked( const char* cookie,
|
CookieRef* getMakeCookieRef_locked( const char* cookie,
|
||||||
const char* connName,
|
|
||||||
HostID hid, int socket, int nPlayersH,
|
HostID hid, int socket, int nPlayersH,
|
||||||
int nPlayersS, int langCode, int seed,
|
int nPlayersS, int langCode, int seed,
|
||||||
bool wantsPublic, bool makePublic );
|
bool wantsPublic, bool makePublic );
|
||||||
|
|
||||||
|
/* reconnect case; just the stuff we don't have in db */
|
||||||
|
CookieRef* getMakeCookieRef_locked( const char* connName,
|
||||||
|
HostID hid, int socket, int nPlayersH,
|
||||||
|
int seed );
|
||||||
|
|
||||||
CookieRef* getCookieRef( CookieID cookieID );
|
CookieRef* getCookieRef( CookieID cookieID );
|
||||||
CookieRef* getCookieRef( int socket );
|
CookieRef* getCookieRef( int socket );
|
||||||
bool checkCookieRef_locked( CookieRef* cref );
|
bool checkCookieRef_locked( CookieRef* cref );
|
||||||
|
|
|
@ -82,7 +82,7 @@ DBMgr::AddNew( const char* cookie, const char* connName, CookieID cid,
|
||||||
if ( !connName ) connName = "";
|
if ( !connName ) connName = "";
|
||||||
|
|
||||||
const char* fmt = "INSERT INTO " TABLE_NAME
|
const char* fmt = "INSERT INTO " TABLE_NAME
|
||||||
"(cid, cookie, connName, nTotal, nHere, lang, ispublic, ctime) "
|
"(cid, cookie, connName, nTotal, nJoined, lang, ispublic, ctime) "
|
||||||
"VALUES( %d, '%s', '%s', %d, %d, %d, %s, 'now' )";
|
"VALUES( %d, '%s', '%s', %d, %d, %d, %s, 'now' )";
|
||||||
char buf[256];
|
char buf[256];
|
||||||
snprintf( buf, sizeof(buf), fmt, cid/*m_nextCID++*/, cookie, connName,
|
snprintf( buf, sizeof(buf), fmt, cid/*m_nextCID++*/, cookie, connName,
|
||||||
|
@ -113,14 +113,41 @@ DBMgr::AddNew( const char* cookie, const char* connName, CookieID cid,
|
||||||
}
|
}
|
||||||
|
|
||||||
CookieID
|
CookieID
|
||||||
DBMgr::FindOpen( const char* cookie, int lang, int nPlayersT, int nPlayersH, bool wantsPublic )
|
DBMgr::FindGame( const char* connName, char* cookieBuf, int bufLen,
|
||||||
|
int* langP, int* nPlayersTP )
|
||||||
{
|
{
|
||||||
CookieID cid = 0;
|
CookieID cid = 0;
|
||||||
|
|
||||||
const char* fmt = "SELECT cid from " TABLE_NAME " where cookie = '%s' "
|
const char* fmt = "SELECT cid, cookie, lang, nTotal from " TABLE_NAME " where connName = '%s' "
|
||||||
|
"LIMIT 1";
|
||||||
|
char query[256];
|
||||||
|
snprintf( query, sizeof(query), fmt, connName );
|
||||||
|
logf( XW_LOGINFO, "query: %s", query );
|
||||||
|
|
||||||
|
PGresult* result = PQexec( m_pgconn, query );
|
||||||
|
if ( 1 == PQntuples( result ) ) {
|
||||||
|
cid = atoi( PQgetvalue( result, 0, 0 ) );
|
||||||
|
snprintf( cookieBuf, bufLen, "%s", PQgetvalue( result, 0, 1 ) );
|
||||||
|
*langP = atoi( PQgetvalue( result, 0, 2 ) );
|
||||||
|
*nPlayersTP = atoi( PQgetvalue( result, 0, 3 ) );
|
||||||
|
}
|
||||||
|
PQclear( result );
|
||||||
|
|
||||||
|
logf( XW_LOGINFO, "%s(%s)=>%d", __func__, connName, cid );
|
||||||
|
return cid;
|
||||||
|
}
|
||||||
|
|
||||||
|
CookieID
|
||||||
|
DBMgr::FindOpen( const char* cookie, int lang, int nPlayersT, int nPlayersH,
|
||||||
|
bool wantsPublic, char* connNameBuf, int bufLen )
|
||||||
|
{
|
||||||
|
CookieID cid = 0;
|
||||||
|
|
||||||
|
const char* fmt = "SELECT cid, connName FROM " TABLE_NAME " "
|
||||||
|
"WHERE cookie = '%s' "
|
||||||
"AND lang = %d "
|
"AND lang = %d "
|
||||||
"AND nTotal = %d "
|
"AND nTotal = %d "
|
||||||
"AND %d <= nTotal-nHere "
|
"AND %d <= nTotal-nJoined "
|
||||||
"AND %s = ispublic "
|
"AND %s = ispublic "
|
||||||
"LIMIT 1";
|
"LIMIT 1";
|
||||||
char query[256];
|
char query[256];
|
||||||
|
@ -131,17 +158,18 @@ DBMgr::FindOpen( const char* cookie, int lang, int nPlayersT, int nPlayersH, boo
|
||||||
PGresult* result = PQexec( m_pgconn, query );
|
PGresult* result = PQexec( m_pgconn, query );
|
||||||
if ( 1 == PQntuples( result ) ) {
|
if ( 1 == PQntuples( result ) ) {
|
||||||
cid = atoi( PQgetvalue( result, 0, 0 ) );
|
cid = atoi( PQgetvalue( result, 0, 0 ) );
|
||||||
assert( cid > 0 );
|
snprintf( connNameBuf, bufLen, "%s", PQgetvalue( result, 0, 1 ) );
|
||||||
|
/* cid may be 0, but should use game anyway */
|
||||||
}
|
}
|
||||||
PQclear( result );
|
PQclear( result );
|
||||||
logf( XW_LOGINFO, "%s=>%d", __func__, cid );
|
logf( XW_LOGINFO, "%s=>%d", __func__, cid );
|
||||||
return cid;
|
return cid;
|
||||||
}
|
} /* FindOpen */
|
||||||
|
|
||||||
void
|
void
|
||||||
DBMgr::AddPlayers( const char* connName, int nToAdd )
|
DBMgr::AddPlayers( const char* connName, int nToAdd )
|
||||||
{
|
{
|
||||||
const char* fmt = "UPDATE " TABLE_NAME " SET nHere = nHere+%d "
|
const char* fmt = "UPDATE " TABLE_NAME " SET nJoined = nJoined+%d "
|
||||||
"WHERE connName = '%s'";
|
"WHERE connName = '%s'";
|
||||||
char query[256];
|
char query[256];
|
||||||
snprintf( query, sizeof(query), fmt, nToAdd, connName );
|
snprintf( query, sizeof(query), fmt, nToAdd, connName );
|
||||||
|
@ -150,16 +178,32 @@ DBMgr::AddPlayers( const char* connName, int nToAdd )
|
||||||
execSql( query );
|
execSql( query );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
DBMgr::AddCID( const char* const connName, CookieID cid )
|
||||||
|
{
|
||||||
|
const char* fmt = "UPDATE " TABLE_NAME " SET cid = %d "
|
||||||
|
"WHERE connName = '%s'";
|
||||||
|
char query[256];
|
||||||
|
snprintf( query, sizeof(query), fmt, cid, connName );
|
||||||
|
logf( XW_LOGINFO, "%s: query: %s", __func__, query );
|
||||||
|
|
||||||
|
execSql( query );
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
DBMgr::ClearCIDs( void )
|
DBMgr::ClearCIDs( void )
|
||||||
{
|
{
|
||||||
execSql( "UPDATE " TABLE_NAME " set cid = 0" );
|
execSql( "UPDATE " TABLE_NAME " set cid = null" );
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
DBMgr::execSql( const char* query )
|
DBMgr::execSql( const char* query )
|
||||||
{
|
{
|
||||||
PGresult* result = PQexec( m_pgconn, query );
|
PGresult* result = PQexec( m_pgconn, query );
|
||||||
|
if ( PGRES_COMMAND_OK != PQresultStatus(result) ) {
|
||||||
|
logf( XW_LOGERROR, "PQEXEC=>%s", PQresultErrorMessage(result) );
|
||||||
|
assert( 0 );
|
||||||
|
}
|
||||||
PQclear( result );
|
PQclear( result );
|
||||||
logf( XW_LOGINFO, "PQexecParams=>%d", result );
|
logf( XW_LOGINFO, "PQexecParams=>%d", result );
|
||||||
}
|
}
|
||||||
|
@ -171,7 +215,7 @@ DBMgr::execSql( const char* query )
|
||||||
cookie VARCHAR(32),
|
cookie VARCHAR(32),
|
||||||
connName VARCHAR(64) UNIQUE PRIMARY KEY,
|
connName VARCHAR(64) UNIQUE PRIMARY KEY,
|
||||||
nTotal INTEGER,
|
nTotal INTEGER,
|
||||||
nHere INTEGER,
|
nJoined INTEGER,
|
||||||
lang INTEGER,
|
lang INTEGER,
|
||||||
ctime TIMESTAMP,
|
ctime TIMESTAMP,
|
||||||
mtime TIMESTAMP
|
mtime TIMESTAMP
|
||||||
|
|
|
@ -35,10 +35,14 @@ 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 );
|
||||||
|
|
||||||
|
CookieID FindGame( const char* connName, char* cookieBuf, int bufLen,
|
||||||
|
int* langP, int* nPlayersTP );
|
||||||
CookieID FindOpen( const char* cookie, int lang, int nPlayersT,
|
CookieID FindOpen( const char* cookie, int lang, int nPlayersT,
|
||||||
int nPlayersH, bool wantsPublic );
|
int nPlayersH, bool wantsPublic,
|
||||||
|
char* connNameBuf, int bufLen );
|
||||||
|
|
||||||
void AddPlayers( const char* connName, int nToAdd );
|
void AddPlayers( const char* const connName, int nToAdd );
|
||||||
|
void AddCID( const char* connName, CookieID cid );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DBMgr();
|
DBMgr();
|
||||||
|
|
Loading…
Add table
Reference in a new issue