mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-01-29 08:34:37 +01:00
wip: process moves received
This commit is contained in:
parent
5223ccabe1
commit
3045697d31
7 changed files with 159 additions and 50 deletions
|
@ -338,6 +338,34 @@ game_saveSucceeded( const XWGame* game, XP_U16 saveToken )
|
|||
}
|
||||
}
|
||||
|
||||
XP_Bool
|
||||
game_receiveMessage( XWGame* game, XWStreamCtxt* stream, CommsAddrRec* retAddr )
|
||||
{
|
||||
ServerCtxt* server = game->server;
|
||||
CommsMsgState commsState;
|
||||
XP_Bool result = comms_checkIncomingStream( game->comms, stream, retAddr,
|
||||
&commsState );
|
||||
if ( result ) {
|
||||
(void)server_do( server );
|
||||
|
||||
result = server_receiveMessage( server, stream );
|
||||
}
|
||||
comms_msgProcessed( game->comms, &commsState, !result );
|
||||
|
||||
if ( result ) {
|
||||
/* in case MORE work's pending. Multiple calls are required in at
|
||||
least one case, where I'm a host handling client registration *AND*
|
||||
I'm a robot. Only one server_do and I'll never make that first
|
||||
robot move. That's because comms can't detect a duplicate initial
|
||||
packet (in validateInitialMessage()). */
|
||||
for ( int ii = 0; ii < 5; ++ii ) {
|
||||
(void)server_do( server );
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
game_getState( const XWGame* game, GameStateInfo* gsi )
|
||||
{
|
||||
|
|
|
@ -82,6 +82,10 @@ void game_saveNewGame( MPFORMAL const CurGameInfo* gi, XW_UtilCtxt* util,
|
|||
void game_saveToStream( const XWGame* game, const CurGameInfo* gi,
|
||||
XWStreamCtxt* stream, XP_U16 saveToken );
|
||||
void game_saveSucceeded( const XWGame* game, XP_U16 saveToken );
|
||||
|
||||
XP_Bool game_receiveMessage( XWGame* game, XWStreamCtxt* stream,
|
||||
CommsAddrRec* retAddr );
|
||||
|
||||
void game_dispose( XWGame* game );
|
||||
|
||||
void game_getState( const XWGame* game, GameStateInfo* gsi );
|
||||
|
|
|
@ -1751,6 +1751,28 @@ cursesErrorMsgRcvd( void* closure, const XP_UCHAR* msg )
|
|||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
queryTimerFired( gpointer data )
|
||||
{
|
||||
LOG_FUNC();
|
||||
CursesAppGlobals* globals = (CursesAppGlobals*)data;
|
||||
|
||||
XWGame* game = &globals->cGlobals.game;
|
||||
if ( !!game->comms ) {
|
||||
XP_ASSERT( globals->nextQueryTimeSecs > 0 );
|
||||
if ( checkForMsgs( globals->cGlobals.params, game ) ) {
|
||||
globals->nextQueryTimeSecs = 1;
|
||||
} else {
|
||||
globals->nextQueryTimeSecs *= 2;
|
||||
}
|
||||
|
||||
(void)g_timeout_add_seconds( globals->nextQueryTimeSecs,
|
||||
queryTimerFired, &g_globals );
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
chatsTimerFired( gpointer data )
|
||||
{
|
||||
|
@ -1928,6 +1950,9 @@ cursesmain( XP_Bool isServer, LaunchParams* params )
|
|||
(void)g_timeout_add_seconds( params->chatsInterval, chatsTimerFired,
|
||||
&g_globals );
|
||||
}
|
||||
g_globals.nextQueryTimeSecs = 1;
|
||||
(void)g_timeout_add_seconds( g_globals.nextQueryTimeSecs,
|
||||
queryTimerFired, &g_globals );
|
||||
|
||||
XP_Bool opened = XP_FALSE;
|
||||
initCurses( &g_globals, &width, &height );
|
||||
|
|
|
@ -71,6 +71,7 @@ struct CursesAppGlobals {
|
|||
gchar* lastErr;
|
||||
|
||||
XP_U16 nChatsSent;
|
||||
XP_U16 nextQueryTimeSecs;
|
||||
|
||||
union {
|
||||
struct {
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
void
|
||||
linux_debugf( const char* format, ... )
|
||||
{
|
||||
char buf[1000];
|
||||
char buf[1024*8];
|
||||
va_list ap;
|
||||
struct tm* timp;
|
||||
struct timeval tv;
|
||||
|
@ -50,14 +50,17 @@ linux_debugf( const char* format, ... )
|
|||
gettimeofday( &tv, &tz );
|
||||
timp = localtime( &tv.tv_sec );
|
||||
|
||||
snprintf( buf, sizeof(buf), "<%d>%.2d:%.2d:%.2d:", getpid(),
|
||||
timp->tm_hour, timp->tm_min, timp->tm_sec );
|
||||
size_t len = snprintf( buf, sizeof(buf), "<%d>%.2d:%.2d:%.2d:", getpid(),
|
||||
timp->tm_hour, timp->tm_min, timp->tm_sec );
|
||||
XP_ASSERT( len < sizeof(buf) );
|
||||
|
||||
va_start(ap, format);
|
||||
|
||||
vsprintf(buf+strlen(buf), format, ap);
|
||||
|
||||
len = vsprintf(buf+strlen(buf), format, ap);
|
||||
va_end(ap);
|
||||
|
||||
if ( len >= sizeof(buf) ) {
|
||||
buf[sizeof(buf)-1] = '\0';
|
||||
}
|
||||
|
||||
fprintf( stderr, "%s\n", buf );
|
||||
}
|
||||
|
|
|
@ -63,6 +63,7 @@ static size_t writeVLI( XP_U8* out, uint32_t nn );
|
|||
static size_t un2vli( int nn, uint8_t* buf );
|
||||
static bool vli2un( const uint8_t** inp, uint32_t* outp );
|
||||
|
||||
|
||||
typedef struct _ReadState {
|
||||
gchar* ptr;
|
||||
size_t curSize;
|
||||
|
@ -75,63 +76,110 @@ write_callback(void *contents, size_t size, size_t nmemb, void* data)
|
|||
XP_LOGF( "%s(size=%ld, nmemb=%ld)", __func__, size, nmemb );
|
||||
// void** pp = (void**)data;
|
||||
size_t oldLen = rs->curSize;
|
||||
size_t newLength = size * nmemb;
|
||||
const size_t newLength = size * nmemb;
|
||||
XP_ASSERT( (oldLen + newLength) > 0 );
|
||||
rs->ptr = g_realloc( rs->ptr, oldLen + newLength );
|
||||
memcpy( rs->ptr + oldLen - 1, contents, newLength );
|
||||
rs->ptr[oldLen + newLength - 1] = '\0';
|
||||
size_t result = size * nmemb;
|
||||
// XP_LOGF( "%s() => %ld: (passed: \"%s\")", __func__, result, *strp );
|
||||
return result;
|
||||
return newLength;
|
||||
}
|
||||
|
||||
void
|
||||
checkForMsgs(const XP_UCHAR* id)
|
||||
XP_Bool
|
||||
checkForMsgs( LaunchParams* params, XWGame* game )
|
||||
{
|
||||
ReadState rs = {
|
||||
.ptr = g_malloc0(1),
|
||||
.curSize = 1L
|
||||
};
|
||||
XP_Bool foundAny = false;
|
||||
XP_UCHAR idBuf[64];
|
||||
if ( !!game->comms ) {
|
||||
XP_U16 len = VSIZE(idBuf);
|
||||
if ( comms_getRelayID( game->comms, idBuf, &len ) ) {
|
||||
XP_LOGF( "%s: got %s", __func__, idBuf );
|
||||
} else {
|
||||
idBuf[0] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
/* build a json array of relayIDs, then stringify it */
|
||||
json_object* params = json_object_new_array();
|
||||
json_object* idstr = json_object_new_string(id);
|
||||
json_object_array_add(params, idstr);
|
||||
const char* asStr = json_object_to_json_string( params );
|
||||
XP_LOGF( "%s: added str: %s", __func__, asStr );
|
||||
|
||||
CURLcode res = curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||
XP_ASSERT(res == CURLE_OK);
|
||||
CURL* curl = curl_easy_init();
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL,
|
||||
"http://localhost/xw4/relay.py/query");
|
||||
curl_easy_setopt(curl, CURLOPT_POST, 1L);
|
||||
|
||||
char* curl_params = curl_easy_escape( curl, asStr, strlen(asStr) );
|
||||
char buf[4*1024];
|
||||
size_t buflen = snprintf( buf, sizeof(buf), "ids=%s", curl_params);
|
||||
XP_ASSERT( buflen < sizeof(buf) );
|
||||
curl_free(curl_params);
|
||||
if ( !!idBuf[0] ) {
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, buf);
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)strlen(buf));
|
||||
ReadState rs = {
|
||||
.ptr = g_malloc0(1),
|
||||
.curSize = 1L
|
||||
};
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback );
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &rs );
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
/* build a json array of relayIDs, then stringify it */
|
||||
json_object* ids = json_object_new_array();
|
||||
json_object* idstr = json_object_new_string(idBuf);
|
||||
json_object_array_add(ids, idstr);
|
||||
const char* asStr = json_object_to_json_string( ids );
|
||||
XP_LOGF( "%s: added str: %s", __func__, asStr );
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
CURLcode res = curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||
XP_ASSERT(res == CURLE_OK);
|
||||
CURL* curl = curl_easy_init();
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL,
|
||||
"http://localhost/xw4/relay.py/query");
|
||||
curl_easy_setopt(curl, CURLOPT_POST, 1L);
|
||||
|
||||
char* curl_params = curl_easy_escape( curl, asStr, strlen(asStr) );
|
||||
char buf[4*1024];
|
||||
size_t buflen = snprintf( buf, sizeof(buf), "ids=%s", curl_params);
|
||||
XP_ASSERT( buflen < sizeof(buf) );
|
||||
curl_free(curl_params);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, buf);
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)strlen(buf));
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback );
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &rs );
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
XP_LOGF( "%s(): curl_easy_perform() => %d", __func__, res );
|
||||
/* Check for errors */
|
||||
if (res != CURLE_OK) {
|
||||
XP_LOGF( "curl_easy_perform() failed: %s", curl_easy_strerror(res));
|
||||
}
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
curl_global_cleanup();
|
||||
/* Check for errors */
|
||||
if (res != CURLE_OK) {
|
||||
XP_LOGF( "curl_easy_perform() failed: %s", curl_easy_strerror(res));
|
||||
}
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
curl_global_cleanup();
|
||||
|
||||
XP_LOGF( "%s(): got \"%s\"", __func__, rs.ptr );
|
||||
XP_LOGF( "%s(): got <<%s>>", __func__, rs.ptr );
|
||||
|
||||
if (res == CURLE_OK) {
|
||||
json_object* reply = json_tokener_parse( rs.ptr );
|
||||
json_object_object_foreach(reply, key, val) {
|
||||
int len = json_object_array_length(val);
|
||||
XP_LOGF( "%s: got key: %s of len %d", __func__, key, len );
|
||||
for ( int ii = 0; ii < len; ++ii ) {
|
||||
json_object* forGame = json_object_array_get_idx(val, ii);
|
||||
int len2 = json_object_array_length(forGame);
|
||||
foundAny = foundAny || len2 > 0;
|
||||
for ( int jj = 0; jj < len2; ++jj ) {
|
||||
json_object* oneMove = json_object_array_get_idx(forGame, jj);
|
||||
const char* asStr = json_object_get_string(oneMove);
|
||||
gsize out_len;
|
||||
guchar* buf = g_base64_decode( asStr, &out_len );
|
||||
XWStreamCtxt* stream = mem_stream_make( MPPARM(params->mpool)
|
||||
params->vtMgr, params,
|
||||
CHANNEL_NONE, NULL );
|
||||
stream_putBytes( stream, buf, out_len );
|
||||
g_free(buf);
|
||||
|
||||
CommsAddrRec addr = {0};
|
||||
addr_addType( &addr, COMMS_CONN_RELAY );
|
||||
XP_Bool handled = game_receiveMessage( game, stream, &addr );
|
||||
XP_LOGF( "%s(): game_receiveMessage() => %d", __func__, handled );
|
||||
stream_destroy( stream );
|
||||
|
||||
foundAny = XP_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return foundAny;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -57,5 +57,5 @@ void relaycon_cleanup( LaunchParams* params );
|
|||
XP_U32 makeClientToken( sqlite3_int64 rowid, XP_U16 seed );
|
||||
void rowidFromToken( XP_U32 clientToken, sqlite3_int64* rowid, XP_U16* seed );
|
||||
|
||||
void checkForMsgs(const XP_UCHAR* id);
|
||||
XP_Bool checkForMsgs(LaunchParams* params, XWGame* game);
|
||||
#endif
|
||||
|
|
Loading…
Add table
Reference in a new issue