mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-01-28 07:58:08 +01:00
Merge branch 'android_branch' into gtk_multigame
Conflicts: xwords4/android/XWords4/src/org/eehouse/android/xw4/GCMIntentService.java xwords4/android/XWords4/src/org/eehouse/android/xw4/RelayService.java
This commit is contained in:
commit
31c443e4b1
7 changed files with 221 additions and 74 deletions
|
@ -36,7 +36,7 @@ local_DEFINES += \
|
||||||
-DHASH_STREAM \
|
-DHASH_STREAM \
|
||||||
-DXWFEATURE_BASE64 \
|
-DXWFEATURE_BASE64 \
|
||||||
-DXWFEATURE_DEVID \
|
-DXWFEATURE_DEVID \
|
||||||
-DINITIAL_CLIENT_VERS=2 \
|
-DINITIAL_CLIENT_VERS=3 \
|
||||||
-DRELAY_ROOM_DEFAULT=\"\" \
|
-DRELAY_ROOM_DEFAULT=\"\" \
|
||||||
-D__LITTLE_ENDIAN \
|
-D__LITTLE_ENDIAN \
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import com.google.android.gcm.GCMBaseIntentService;
|
import com.google.android.gcm.GCMBaseIntentService;
|
||||||
import com.google.android.gcm.GCMRegistrar;
|
import com.google.android.gcm.GCMRegistrar;
|
||||||
|
import org.json.JSONArray;
|
||||||
|
|
||||||
public class GCMIntentService extends GCMBaseIntentService {
|
public class GCMIntentService extends GCMBaseIntentService {
|
||||||
|
|
||||||
|
@ -61,13 +62,31 @@ public class GCMIntentService extends GCMBaseIntentService {
|
||||||
if ( ignoreIt ) {
|
if ( ignoreIt ) {
|
||||||
DbgUtils.logf( "received GCM but ignoring it" );
|
DbgUtils.logf( "received GCM but ignoring it" );
|
||||||
} else {
|
} else {
|
||||||
|
value = intent.getStringExtra( "checkUpdates" );
|
||||||
|
if ( null != value && Boolean.parseBoolean( value ) ) {
|
||||||
|
UpdateCheckReceiver.checkVersions( context, true );
|
||||||
|
}
|
||||||
|
|
||||||
value = intent.getStringExtra( "getMoves" );
|
value = intent.getStringExtra( "getMoves" );
|
||||||
if ( null != value && Boolean.parseBoolean( value ) ) {
|
if ( null != value && Boolean.parseBoolean( value ) ) {
|
||||||
RelayReceiver.RestartTimer( context, true );
|
RelayReceiver.RestartTimer( context, true );
|
||||||
}
|
}
|
||||||
value = intent.getStringExtra( "checkUpdates" );
|
|
||||||
if ( null != value && Boolean.parseBoolean( value ) ) {
|
value = intent.getStringExtra( "msgs64" );
|
||||||
UpdateCheckReceiver.checkVersions( context, true );
|
if ( null != value ) {
|
||||||
|
String connname = intent.getStringExtra( "connname" );
|
||||||
|
if ( null != connname ) {
|
||||||
|
try {
|
||||||
|
JSONArray msgs64 = new JSONArray( value );
|
||||||
|
String[] strs64 = new String[msgs64.length()];
|
||||||
|
for ( int ii = 0; ii < strs64.length; ++ii ) {
|
||||||
|
strs64[ii] = msgs64.optString(ii);
|
||||||
|
}
|
||||||
|
RelayService.processMsgs( context, connname, strs64 );
|
||||||
|
} catch (org.json.JSONException jse ) {
|
||||||
|
DbgUtils.loge( jse );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
value = intent.getStringExtra( "msg" );
|
value = intent.getStringExtra( "msg" );
|
||||||
|
@ -76,6 +95,7 @@ public class GCMIntentService extends GCMBaseIntentService {
|
||||||
if ( null != title ) {
|
if ( null != title ) {
|
||||||
int code = value.hashCode() ^ title.hashCode();
|
int code = value.hashCode() ^ title.hashCode();
|
||||||
Utils.postNotification( context, null, title, value, code );
|
Utils.postNotification( context, null, title, value, code );
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,12 @@ package org.eehouse.android.xw4;
|
||||||
import android.app.Service;
|
import android.app.Service;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
<<<<<<< HEAD
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
|
=======
|
||||||
|
import android.os.AsyncTask;
|
||||||
|
import android.os.IBinder;
|
||||||
|
>>>>>>> android_branch
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
|
@ -43,16 +48,21 @@ import org.eehouse.android.xw4.MultiService.MultiEvent;
|
||||||
import org.eehouse.android.xw4.jni.CommsAddrRec;
|
import org.eehouse.android.xw4.jni.CommsAddrRec;
|
||||||
import org.eehouse.android.xw4.jni.GameSummary;
|
import org.eehouse.android.xw4.jni.GameSummary;
|
||||||
import org.eehouse.android.xw4.jni.UtilCtxt;
|
import org.eehouse.android.xw4.jni.UtilCtxt;
|
||||||
|
import org.eehouse.android.xw4.jni.XwJNI;
|
||||||
|
|
||||||
public class RelayService extends XWService {
|
public class RelayService extends XWService {
|
||||||
private static final int MAX_SEND = 1024;
|
private static final int MAX_SEND = 1024;
|
||||||
private static final int MAX_BUF = MAX_SEND - 2;
|
private static final int MAX_BUF = MAX_SEND - 2;
|
||||||
|
|
||||||
private static final String CMD_STR = "CMD";
|
private static final String CMD_STR = "CMD";
|
||||||
private static final int UDP_CHANGED = 1;
|
|
||||||
private static final int SEND = 2;
|
private static final int PROCESS_MSGS = 1;
|
||||||
private static final int RECEIVE = 3;
|
private static final int UDP_CHANGED = 2;
|
||||||
|
private static final int SEND = 3;
|
||||||
|
private static final int RECEIVE = 4;
|
||||||
|
|
||||||
|
private static final String MSGS = "MSGS";
|
||||||
|
private static final String RELAY_ID = "RELAY_ID";
|
||||||
private static final String ROWID = "ROWID";
|
private static final String ROWID = "ROWID";
|
||||||
private static final String BINBUFFER = "BINBUFFER";
|
private static final String BINBUFFER = "BINBUFFER";
|
||||||
|
|
||||||
|
@ -103,9 +113,9 @@ public class RelayService extends XWService {
|
||||||
|
|
||||||
public static int sendPacket( Context context, long rowid, byte[] buf )
|
public static int sendPacket( Context context, long rowid, byte[] buf )
|
||||||
{
|
{
|
||||||
Intent intent = getIntentTo( context, SEND );
|
Intent intent = getIntentTo( context, SEND )
|
||||||
intent.putExtra( ROWID, rowid );
|
.putExtra( ROWID, rowid )
|
||||||
intent.putExtra( BINBUFFER, buf );
|
.putExtra( BINBUFFER, buf );
|
||||||
context.startService( intent );
|
context.startService( intent );
|
||||||
return buf.length;
|
return buf.length;
|
||||||
}
|
}
|
||||||
|
@ -115,9 +125,9 @@ public class RelayService extends XWService {
|
||||||
{
|
{
|
||||||
DbgUtils.logf( "RelayService::postData: packet of length %d for token %d",
|
DbgUtils.logf( "RelayService::postData: packet of length %d for token %d",
|
||||||
msg.length, rowid );
|
msg.length, rowid );
|
||||||
Intent intent = getIntentTo( context, RECEIVE );
|
Intent intent = getIntentTo( context, RECEIVE )
|
||||||
intent.putExtra( ROWID, rowid );
|
.putExtra( ROWID, rowid )
|
||||||
intent.putExtra( BINBUFFER, msg );
|
.putExtra( BINBUFFER, msg );
|
||||||
context.startService( intent );
|
context.startService( intent );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,6 +136,15 @@ public class RelayService extends XWService {
|
||||||
startService( context );
|
startService( context );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void processMsgs( Context context, String relayId,
|
||||||
|
String[] msgs64 )
|
||||||
|
{
|
||||||
|
Intent intent = getIntentTo( context, PROCESS_MSGS )
|
||||||
|
.putExtra( MSGS, msgs64 )
|
||||||
|
.putExtra( RELAY_ID, relayId );
|
||||||
|
context.startService( intent );
|
||||||
|
}
|
||||||
|
|
||||||
private static Intent getIntentTo( Context context, int cmd )
|
private static Intent getIntentTo( Context context, int cmd )
|
||||||
{
|
{
|
||||||
Intent intent = new Intent( context, RelayService.class );
|
Intent intent = new Intent( context, RelayService.class );
|
||||||
|
@ -183,6 +202,31 @@ public class RelayService extends XWService {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int onStartCommand( Intent intent, int flags, int startId )
|
||||||
|
{
|
||||||
|
int cmd = intent.getIntExtra( CMD_STR, -1 );
|
||||||
|
switch( cmd ) {
|
||||||
|
case PROCESS_MSGS:
|
||||||
|
String[] relayIDs = new String[1];
|
||||||
|
relayIDs[0] = intent.getStringExtra( RELAY_ID );
|
||||||
|
long[] rowIDs = DBUtils.getRowIDsFor( this, relayIDs[0] );
|
||||||
|
if ( 0 < rowIDs.length ) {
|
||||||
|
String[] msgs64 = intent.getStringArrayExtra( MSGS );
|
||||||
|
int count = msgs64.length;
|
||||||
|
|
||||||
|
byte[][][] msgs = new byte[1][count][];
|
||||||
|
for ( int ii = 0; ii < count; ++ii ) {
|
||||||
|
msgs[0][ii] = XwJNI.base64Decode( msgs64[ii] );
|
||||||
|
}
|
||||||
|
process( msgs, rowIDs, relayIDs );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
stopSelf( startId );
|
||||||
|
return Service.START_NOT_STICKY;
|
||||||
|
}
|
||||||
|
|
||||||
private void setupNotification( String[] relayIDs )
|
private void setupNotification( String[] relayIDs )
|
||||||
{
|
{
|
||||||
for ( String relayID : relayIDs ) {
|
for ( String relayID : relayIDs ) {
|
||||||
|
@ -568,67 +612,80 @@ public class RelayService extends XWService {
|
||||||
long[][] rowIDss = new long[1][];
|
long[][] rowIDss = new long[1][];
|
||||||
String[] relayIDs = DBUtils.getRelayIDs( this, rowIDss );
|
String[] relayIDs = DBUtils.getRelayIDs( this, rowIDss );
|
||||||
if ( null != relayIDs && 0 < relayIDs.length ) {
|
if ( null != relayIDs && 0 < relayIDs.length ) {
|
||||||
long[] rowIDs = rowIDss[0];
|
|
||||||
byte[][][] msgs = NetUtils.queryRelay( this, relayIDs );
|
byte[][][] msgs = NetUtils.queryRelay( this, relayIDs );
|
||||||
|
process( msgs, rowIDss[0], relayIDs );
|
||||||
if ( null != msgs ) {
|
|
||||||
RelayMsgSink sink = new RelayMsgSink();
|
|
||||||
int nameCount = relayIDs.length;
|
|
||||||
ArrayList<String> idsWMsgs =
|
|
||||||
new ArrayList<String>( nameCount );
|
|
||||||
for ( int ii = 0; ii < nameCount; ++ii ) {
|
|
||||||
byte[][] forOne = msgs[ii];
|
|
||||||
// if game has messages, open it and feed 'em
|
|
||||||
// to it.
|
|
||||||
if ( null == forOne ) {
|
|
||||||
// Nothing for this relayID
|
|
||||||
} else if ( BoardActivity.feedMessages( rowIDs[ii], forOne )
|
|
||||||
|| GameUtils.feedMessages( this, rowIDs[ii],
|
|
||||||
forOne, null,
|
|
||||||
sink ) ) {
|
|
||||||
idsWMsgs.add( relayIDs[ii] );
|
|
||||||
} else {
|
|
||||||
DbgUtils.logf( "dropping message for %s (rowid %d)",
|
|
||||||
relayIDs[ii], rowIDs[ii] );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( 0 < idsWMsgs.size() ) {
|
|
||||||
String[] tmp = new String[idsWMsgs.size()];
|
|
||||||
idsWMsgs.toArray( tmp );
|
|
||||||
setupNotification( tmp );
|
|
||||||
}
|
|
||||||
sink.send( this );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void sendToRelay( Context context,
|
private void process( byte[][][] msgs, long[] rowIDs, String[] relayIDs )
|
||||||
HashMap<String,ArrayList<byte[]>> msgHash )
|
|
||||||
{
|
{
|
||||||
// format: total msg lenth: 2
|
if ( null != msgs ) {
|
||||||
// number-of-relayIDs: 2
|
RelayMsgSink sink = new RelayMsgSink();
|
||||||
// for-each-relayid: relayid + '\n': varies
|
int nameCount = relayIDs.length;
|
||||||
// message count: 1
|
ArrayList<String> idsWMsgs = new ArrayList<String>( nameCount );
|
||||||
// for-each-message: length: 2
|
|
||||||
// message: varies
|
|
||||||
|
|
||||||
if ( null != msgHash ) {
|
for ( int ii = 0; ii < nameCount; ++ii ) {
|
||||||
|
byte[][] forOne = msgs[ii];
|
||||||
|
|
||||||
|
// if game has messages, open it and feed 'em to it.
|
||||||
|
if ( null == forOne ) {
|
||||||
|
// Nothing for this relayID
|
||||||
|
} else if ( BoardActivity.feedMessages( rowIDs[ii], forOne )
|
||||||
|
|| GameUtils.feedMessages( this, rowIDs[ii],
|
||||||
|
forOne, null,
|
||||||
|
sink ) ) {
|
||||||
|
idsWMsgs.add( relayIDs[ii] );
|
||||||
|
} else {
|
||||||
|
DbgUtils.logf( "message for %s (rowid %d) not consumed",
|
||||||
|
relayIDs[ii], rowIDs[ii] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( 0 < idsWMsgs.size() ) {
|
||||||
|
String[] tmp = new String[idsWMsgs.size()];
|
||||||
|
idsWMsgs.toArray( tmp );
|
||||||
|
setupNotification( tmp );
|
||||||
|
}
|
||||||
|
sink.send( this );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class AsyncSender extends AsyncTask<Void, Void, Void> {
|
||||||
|
private Context m_context;
|
||||||
|
private HashMap<String,ArrayList<byte[]>> m_msgHash;
|
||||||
|
|
||||||
|
public AsyncSender( Context context,
|
||||||
|
HashMap<String,ArrayList<byte[]>> msgHash )
|
||||||
|
{
|
||||||
|
m_context = context;
|
||||||
|
m_msgHash = msgHash;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Void doInBackground( Void... ignored )
|
||||||
|
{
|
||||||
|
// format: total msg lenth: 2
|
||||||
|
// number-of-relayIDs: 2
|
||||||
|
// for-each-relayid: relayid + '\n': varies
|
||||||
|
// message count: 1
|
||||||
|
// for-each-message: length: 2
|
||||||
|
// message: varies
|
||||||
|
|
||||||
|
// Build up a buffer containing everything but the total
|
||||||
|
// message length and number of relayIDs in the message.
|
||||||
try {
|
try {
|
||||||
// Build up a buffer containing everything but the total
|
|
||||||
// message length and number of relayIDs in the message.
|
|
||||||
ByteArrayOutputStream store =
|
ByteArrayOutputStream store =
|
||||||
new ByteArrayOutputStream( MAX_BUF ); // mem
|
new ByteArrayOutputStream( MAX_BUF ); // mem
|
||||||
DataOutputStream outBuf = new DataOutputStream( store );
|
DataOutputStream outBuf = new DataOutputStream( store );
|
||||||
int msgLen = 4; // relayID count + protocol stuff
|
int msgLen = 4; // relayID count + protocol stuff
|
||||||
int nRelayIDs = 0;
|
int nRelayIDs = 0;
|
||||||
|
|
||||||
Iterator<String> iter = msgHash.keySet().iterator();
|
Iterator<String> iter = m_msgHash.keySet().iterator();
|
||||||
while ( iter.hasNext() ) {
|
while ( iter.hasNext() ) {
|
||||||
String relayID = iter.next();
|
String relayID = iter.next();
|
||||||
int thisLen = 1 + relayID.length(); // string and '\n'
|
int thisLen = 1 + relayID.length(); // string and '\n'
|
||||||
thisLen += 2; // message count
|
thisLen += 2; // message count
|
||||||
|
|
||||||
ArrayList<byte[]> msgs = msgHash.get( relayID );
|
ArrayList<byte[]> msgs = m_msgHash.get( relayID );
|
||||||
for ( byte[] msg : msgs ) {
|
for ( byte[] msg : msgs ) {
|
||||||
thisLen += 2 + msg.length;
|
thisLen += 2 + msg.length;
|
||||||
}
|
}
|
||||||
|
@ -649,10 +706,9 @@ public class RelayService extends XWService {
|
||||||
}
|
}
|
||||||
msgLen += thisLen;
|
msgLen += thisLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now open a real socket, write size and proto, and
|
// Now open a real socket, write size and proto, and
|
||||||
// copy in the formatted buffer
|
// copy in the formatted buffer
|
||||||
Socket socket = NetUtils.makeProxySocket( context, 8000 );
|
Socket socket = NetUtils.makeProxySocket( m_context, 8000 );
|
||||||
if ( null != socket ) {
|
if ( null != socket ) {
|
||||||
DataOutputStream outStream =
|
DataOutputStream outStream =
|
||||||
new DataOutputStream( socket.getOutputStream() );
|
new DataOutputStream( socket.getOutputStream() );
|
||||||
|
@ -667,6 +723,15 @@ public class RelayService extends XWService {
|
||||||
} catch ( java.io.IOException ioe ) {
|
} catch ( java.io.IOException ioe ) {
|
||||||
DbgUtils.loge( ioe );
|
DbgUtils.loge( ioe );
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
|
} // doInBackground
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void sendToRelay( Context context,
|
||||||
|
HashMap<String,ArrayList<byte[]>> msgHash )
|
||||||
|
{
|
||||||
|
if ( null != msgHash ) {
|
||||||
|
new AsyncSender( context, msgHash ).execute();
|
||||||
} else {
|
} else {
|
||||||
DbgUtils.logf( "sendToRelay: null msgs" );
|
DbgUtils.logf( "sendToRelay: null msgs" );
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,7 +110,7 @@ dict_getNextTileString( const DictionaryCtxt* dict, Tile tile,
|
||||||
} else {
|
} else {
|
||||||
cur += XP_STRLEN( cur ) + 1;
|
cur += XP_STRLEN( cur ) + 1;
|
||||||
XP_Bool isSpecial = dict_faceIsBitmap( dict, tile );
|
XP_Bool isSpecial = dict_faceIsBitmap( dict, tile );
|
||||||
if ( isSpecial ) {
|
if ( isSpecial || tile == dict->blankTile ) {
|
||||||
const XP_UCHAR* facep = dict_getTileStringRaw( dict, tile );
|
const XP_UCHAR* facep = dict_getTileStringRaw( dict, tile );
|
||||||
if ( cur < dict->charEnds[(XP_U16)*facep] ) {
|
if ( cur < dict->charEnds[(XP_U16)*facep] ) {
|
||||||
result = cur;
|
result = cur;
|
||||||
|
|
|
@ -2856,17 +2856,27 @@ server_formatDictCounts( ServerCtxt* server, XWStreamCtxt* stream,
|
||||||
nChars = dict_numTileFaces( dict );
|
nChars = dict_numTileFaces( dict );
|
||||||
|
|
||||||
for ( tile = 0, nPrinted = 0; ; ) {
|
for ( tile = 0, nPrinted = 0; ; ) {
|
||||||
XP_UCHAR buf[24];
|
XP_UCHAR buf[128];
|
||||||
XP_U16 count, value;
|
XP_U16 count, value;
|
||||||
|
|
||||||
count = dict_numTiles( dict, tile );
|
count = dict_numTiles( dict, tile );
|
||||||
|
|
||||||
if ( count > 0 ) {
|
if ( count > 0 ) {
|
||||||
const XP_UCHAR* face = dict_getTileString( dict, tile );
|
const XP_UCHAR* face = NULL;
|
||||||
|
XP_UCHAR faces[48] = {0};
|
||||||
|
XP_U16 len = 0;
|
||||||
|
for ( ; ; ) {
|
||||||
|
face = dict_getNextTileString( dict, tile, face );
|
||||||
|
if ( !face ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const XP_UCHAR* fmt = len == 0? "%s" : ",%s";
|
||||||
|
len += XP_SNPRINTF( faces + len, sizeof(faces) - len, fmt, face );
|
||||||
|
}
|
||||||
value = dict_getTileValue( dict, tile );
|
value = dict_getTileValue( dict, tile );
|
||||||
|
|
||||||
XP_SNPRINTF( buf, sizeof(buf), (XP_UCHAR*)"%s: %d/%d",
|
XP_SNPRINTF( buf, sizeof(buf), (XP_UCHAR*)"%s: %d/%d",
|
||||||
face, count, value );
|
faces, count, value );
|
||||||
stream_catString( stream, buf );
|
stream_catString( stream, buf );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
XWLANG = PTBR4422
|
XWLANG = PTBR4422
|
||||||
LANGCODE = pt_PT
|
LANGCODE = pt_PT
|
||||||
ENC = UTF-8
|
ENC = UTF-8
|
||||||
|
DICTNOTE = "Lista com as 4422 palavras mais frequentes nas legendas em português brasileiro do site www.opensubtitles.org."
|
||||||
|
|
||||||
TARGET_TYPE ?= WINCE
|
TARGET_TYPE ?= WINCE
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@ g_con = None
|
||||||
g_sent = None
|
g_sent = None
|
||||||
g_debug = False
|
g_debug = False
|
||||||
g_skipSend = False # for debugging
|
g_skipSend = False # for debugging
|
||||||
|
g_columns = [ 'id', 'devid', 'connname', 'hid', 'msg64' ]
|
||||||
DEVTYPE_GCM = 3 # 3 == GCM
|
DEVTYPE_GCM = 3 # 3 == GCM
|
||||||
LINE_LEN = 76
|
LINE_LEN = 76
|
||||||
|
|
||||||
|
@ -55,19 +56,51 @@ def init():
|
||||||
|
|
||||||
def getPendingMsgs( con, typ ):
|
def getPendingMsgs( con, typ ):
|
||||||
cur = con.cursor()
|
cur = con.cursor()
|
||||||
query = """SELECT id, devid FROM msgs
|
query = """SELECT %s FROM msgs
|
||||||
WHERE devid IN (SELECT id FROM devices WHERE devtype=%d and NOT unreg)
|
WHERE devid IN (SELECT id FROM devices WHERE devtype=%d and NOT unreg)
|
||||||
AND NOT connname IN (SELECT connname FROM games WHERE dead); """
|
AND NOT connname IN (SELECT connname FROM games WHERE dead); """
|
||||||
cur.execute(query % typ)
|
cur.execute(query % (",".join( g_columns ), typ))
|
||||||
result = cur.fetchall()
|
|
||||||
|
result = []
|
||||||
|
for row in cur:
|
||||||
|
rowObj = {}
|
||||||
|
for ii in range( len( g_columns ) ):
|
||||||
|
rowObj[g_columns[ii]] = row[ii]
|
||||||
|
result.append( rowObj )
|
||||||
if g_debug: print "getPendingMsgs=>", result
|
if g_debug: print "getPendingMsgs=>", result
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
def addClntVers( con, rows ):
|
||||||
|
query = """select clntVers[%s] from games where connname = '%s';"""
|
||||||
|
cur = con.cursor()
|
||||||
|
for row in rows:
|
||||||
|
cur.execute( query % (row['hid'], row['connname']))
|
||||||
|
if cur.rowcount == 1: row['clntVers'] = cur.fetchone()[0]
|
||||||
|
else: print "bad row count: ", cur.rowcount
|
||||||
|
con.commit()
|
||||||
|
return rows
|
||||||
|
|
||||||
|
def deleteMsgs( con, msgIDs ):
|
||||||
|
if 0 < len( msgIDs ):
|
||||||
|
query = "DELETE from msgs where id in (%s);" % ",".join(msgIDs)
|
||||||
|
try:
|
||||||
|
cur = con.cursor()
|
||||||
|
cur.execute(query)
|
||||||
|
con.commit()
|
||||||
|
except psycopg2.DatabaseError, e:
|
||||||
|
print 'Error %s' % e
|
||||||
|
except Exception as inst:
|
||||||
|
print "failed to execute", query
|
||||||
|
print type(inst)
|
||||||
|
print inst.args
|
||||||
|
print inst
|
||||||
|
|
||||||
def unregister( gcmid ):
|
def unregister( gcmid ):
|
||||||
global g_con
|
global g_con
|
||||||
print "unregister(", gcmid, ")"
|
print "unregister(", gcmid, ")"
|
||||||
query = "UPDATE devices SET unreg=TRUE WHERE devid = '%s' and devtype = 3" % gcmid
|
query = "UPDATE devices SET unreg=TRUE WHERE devid = '%s' and devtype = 3" % gcmid
|
||||||
g_con.cursor().execute( query )
|
g_con.cursor().execute( query )
|
||||||
|
g_con.commit()
|
||||||
|
|
||||||
def asGCMIds(con, devids, typ):
|
def asGCMIds(con, devids, typ):
|
||||||
cur = con.cursor()
|
cur = con.cursor()
|
||||||
|
@ -76,13 +109,22 @@ def asGCMIds(con, devids, typ):
|
||||||
cur.execute( query )
|
cur.execute( query )
|
||||||
return [elem[0] for elem in cur.fetchall()]
|
return [elem[0] for elem in cur.fetchall()]
|
||||||
|
|
||||||
def notifyGCM( devids, typ ):
|
def notifyGCM( devids, typ, target ):
|
||||||
|
success = False
|
||||||
if typ == DEVTYPE_GCM:
|
if typ == DEVTYPE_GCM:
|
||||||
|
if 3 <= target['clntVers']:
|
||||||
|
connname = "%s/%d" % (target['connname'], target['hid'])
|
||||||
|
data = { 'msgs64': [ target['msg64'] ],
|
||||||
|
'connname': connname,
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
data = { 'getMoves': True, }
|
||||||
values = {
|
values = {
|
||||||
'data' : { 'getMoves': True, },
|
'data' : data,
|
||||||
'registration_ids': devids,
|
'registration_ids': devids,
|
||||||
}
|
}
|
||||||
params = json.dumps( values )
|
params = json.dumps( values )
|
||||||
|
|
||||||
req = urllib2.Request("https://android.googleapis.com/gcm/send", params )
|
req = urllib2.Request("https://android.googleapis.com/gcm/send", params )
|
||||||
req.add_header( 'Content-Type' , 'application/x-www-form-urlencoded;charset=UTF-8' )
|
req.add_header( 'Content-Type' , 'application/x-www-form-urlencoded;charset=UTF-8' )
|
||||||
req.add_header( 'Authorization' , 'key=' + mykey.myKey )
|
req.add_header( 'Authorization' , 'key=' + mykey.myKey )
|
||||||
|
@ -92,11 +134,13 @@ def notifyGCM( devids, typ ):
|
||||||
|
|
||||||
if 'success' in asJson and 'failure' in asJson and len(devids) == asJson['success'] and 0 == asJson['failure']:
|
if 'success' in asJson and 'failure' in asJson and len(devids) == asJson['success'] and 0 == asJson['failure']:
|
||||||
print "OK"
|
print "OK"
|
||||||
|
success = True
|
||||||
else:
|
else:
|
||||||
print "Errors: "
|
print "Errors: "
|
||||||
print response
|
print response
|
||||||
else:
|
else:
|
||||||
print "not sending to", len(devids), "devices because typ ==", typ
|
print "not sending to", len(devids), "devices because typ ==", typ
|
||||||
|
return success
|
||||||
|
|
||||||
def shouldSend(val):
|
def shouldSend(val):
|
||||||
return val == 1
|
return val == 1
|
||||||
|
@ -113,14 +157,14 @@ def targetsAfterBackoff( msgs ):
|
||||||
global g_sent
|
global g_sent
|
||||||
targets = {}
|
targets = {}
|
||||||
for row in msgs:
|
for row in msgs:
|
||||||
msgid = row[0]
|
msgid = row['id']
|
||||||
devid = row[1]
|
devid = row['devid']
|
||||||
if not msgid in g_sent:
|
if not msgid in g_sent:
|
||||||
g_sent[msgid] = 0
|
g_sent[msgid] = 0
|
||||||
g_sent[msgid] += 1
|
g_sent[msgid] += 1
|
||||||
if shouldSend( g_sent[msgid] ):
|
if shouldSend( g_sent[msgid] ):
|
||||||
targets[devid] = True
|
targets[devid] = row
|
||||||
return targets.keys()
|
return targets
|
||||||
|
|
||||||
# devids is an array of (msgid, devid) tuples
|
# devids is an array of (msgid, devid) tuples
|
||||||
def pruneSent( devids ):
|
def pruneSent( devids ):
|
||||||
|
@ -129,7 +173,7 @@ def pruneSent( devids ):
|
||||||
lenBefore = len(g_sent)
|
lenBefore = len(g_sent)
|
||||||
msgids = []
|
msgids = []
|
||||||
for row in devids:
|
for row in devids:
|
||||||
msgids.append(row[0])
|
msgids.append(row['id'])
|
||||||
for msgid in g_sent.keys():
|
for msgid in g_sent.keys():
|
||||||
if not msgid in msgids:
|
if not msgid in msgids:
|
||||||
del g_sent[msgid]
|
del g_sent[msgid]
|
||||||
|
@ -181,14 +225,21 @@ def main():
|
||||||
if g_debug: print
|
if g_debug: print
|
||||||
devids = getPendingMsgs( g_con, typ )
|
devids = getPendingMsgs( g_con, typ )
|
||||||
if 0 < len(devids):
|
if 0 < len(devids):
|
||||||
|
devids = addClntVers( g_con, devids )
|
||||||
targets = targetsAfterBackoff( devids )
|
targets = targetsAfterBackoff( devids )
|
||||||
if 0 < len(targets):
|
if 0 < len(targets):
|
||||||
if 0 < emptyCount: print ""
|
if 0 < emptyCount: print ""
|
||||||
emptyCount = 0
|
emptyCount = 0
|
||||||
print strftime("%Y-%m-%d %H:%M:%S", time.localtime()),
|
print strftime("%Y-%m-%d %H:%M:%S", time.localtime()),
|
||||||
print "devices needing notification:", targets, '=>',
|
print "devices needing notification:", targets, '=>',
|
||||||
notifyGCM( asGCMIds( g_con, targets, typ ), typ )
|
toDelete = []
|
||||||
|
for devid in targets.keys():
|
||||||
|
target = targets[devid]
|
||||||
|
if notifyGCM( asGCMIds(g_con, [devid], typ), typ, target )\
|
||||||
|
and 3 <= target['clntVers']:
|
||||||
|
toDelete.append( str(target['id']) )
|
||||||
pruneSent( devids )
|
pruneSent( devids )
|
||||||
|
deleteMsgs( g_con, toDelete )
|
||||||
elif g_debug: print "no targets after backoff"
|
elif g_debug: print "no targets after backoff"
|
||||||
else:
|
else:
|
||||||
emptyCount += 1
|
emptyCount += 1
|
||||||
|
|
Loading…
Add table
Reference in a new issue