wip: process moves received

This commit is contained in:
Eric House 2017-10-19 21:20:14 -07:00
parent 5223ccabe1
commit 3045697d31
7 changed files with 159 additions and 50 deletions

View file

@ -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 )
{

View file

@ -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 );

View file

@ -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 );

View file

@ -71,6 +71,7 @@ struct CursesAppGlobals {
gchar* lastErr;
XP_U16 nChatsSent;
XP_U16 nextQueryTimeSecs;
union {
struct {

View file

@ -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 );
}

View file

@ -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

View file

@ -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