From fe25060255f02c834b4546bef93a7f4f763196e9 Mon Sep 17 00:00:00 2001 From: Eric House Date: Wed, 1 Jul 2015 05:52:02 -0700 Subject: [PATCH 01/10] fix assertion failure, probably due to some freak accident of missaved timestamp. Whatever. --- .../XWords4/src/org/eehouse/android/xw4/ExpiringDelegate.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/ExpiringDelegate.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/ExpiringDelegate.java index 7a783344e..e5b4045b6 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/ExpiringDelegate.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/ExpiringDelegate.java @@ -201,6 +201,8 @@ public class ExpiringDelegate { m_pct = (int)((100 * passed) / INTERVAL_SECS); if ( m_pct > 100 ) { m_pct = 100; + } else if ( m_pct < 0 ) { + m_pct = 0; } else if ( null != m_handler ) { long onePct = INTERVAL_SECS / 100; long lastStart = m_startSecs + (onePct * m_pct); From 29d8a67c366bb09b761f4c24711337e618594450 Mon Sep 17 00:00:00 2001 From: Eric House Date: Wed, 8 Jul 2015 20:41:13 -0700 Subject: [PATCH 02/10] Makefile for new wordlist --- xwords4/dawg/English/Makefile.CSW15 | 35 +++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 xwords4/dawg/English/Makefile.CSW15 diff --git a/xwords4/dawg/English/Makefile.CSW15 b/xwords4/dawg/English/Makefile.CSW15 new file mode 100644 index 000000000..4c1d1d4c1 --- /dev/null +++ b/xwords4/dawg/English/Makefile.CSW15 @@ -0,0 +1,35 @@ +# -*- mode: makefile; compile-command: "make -f Makefile.CSW12"; -*- +# Copyright 2002 by Eric House (xwords@eehouse.org). All rights reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +XWLANG=CSW15 +LANGCODE=en_US +TARGET_TYPE=WINCE +DICTNOTE = "Submitted by a user, claims equivalence with Collins Scrabble Words 2015" + +include ../Makefile.langcommon + +SOURCEDICT ?= $(XWDICTPATH)/English/CSW15.txt.gz + +$(XWLANG)Main.dict.gz: $(SOURCEDICT) Makefile + zcat $< | tr -d '\r' | awk '{print $$1}' | tr [a-z] [A-Z] | \ + grep -e "^[A-Z]\{2,15\}$$" | gzip -c > $@ + +# Everything but creating of the Main.dict file is inherited from the +# "parent" Makefile.langcommon in the parent directory. + +clean: clean_common + rm -f $(XWLANG)Main.dict.gz *.bin $(XWLANG)*.pdb $(XWLANG)*.seb From dba86a657f8f4f0a87ee59b975478252ae657a75 Mon Sep 17 00:00:00 2001 From: Eric House Date: Wed, 1 Jul 2015 06:34:57 -0700 Subject: [PATCH 03/10] add and handle new INVITE message types. (This can safely be added to shipping relay.) --- xwords4/relay/xwrelay.cpp | 42 +++++++++++++++++++++++++++++++++++---- xwords4/relay/xwrelay.h | 5 +++++ 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/xwords4/relay/xwrelay.cpp b/xwords4/relay/xwrelay.cpp index 1f155a2c8..8ea8c03cd 100644 --- a/xwords4/relay/xwrelay.cpp +++ b/xwords4/relay/xwrelay.cpp @@ -374,10 +374,15 @@ getHeader( const uint8_t** bufpp, const uint8_t* end, uint8_t byt; if ( getNetByte( bufpp, end, &byt ) ) { header->proto = (XWPDevProto)byt; - if ( XWPDEV_PROTO_VERSION_1 == header->proto - && vli2un( bufpp, end, &header->packetID ) - && getNetByte( bufpp, end, &byt ) - && byt < XWPDEV_N_ELEMS ) { + if ( XWPDEV_PROTO_VERSION_1 != header->proto ) { + logf( XW_LOGERROR, "%s: bad proto %d", __func__, header->proto ); + } else if ( !vli2un( bufpp, end, &header->packetID ) ) { + logf( XW_LOGERROR, "%s: can't get packet id", __func__ ); + } else if ( !getNetByte( bufpp, end, &byt ) ) { + logf( XW_LOGERROR, "%s: can't get cmd", __func__ ); + } else if ( XWPDEV_N_ELEMS <= byt ) { + logf( XW_LOGERROR, "%s: cmd %d too high", __func__, byt ); + } else { header->cmd = (XWRelayReg)byt; success = true; } @@ -838,6 +843,22 @@ post_upgrade( DevIDRelay devid ) (void)post_or_store( devid, packet, packetID, NULL, NULL ); } +void +post_invite( DevIDRelay sender, DevIDRelay invitee, const uint8_t* ptr, size_t len ) +{ + vector packet; + uint32_t packetID; + sender = htonl( sender ); + assemble_packet( packet, &packetID, XWPDEV_GOTINVITE, + &sender, sizeof(sender), + ptr, len, + NULL ); + + bool sent = post_or_store( invitee, packet, packetID, NULL, NULL ); + logf( XW_LOGINFO, "%s(): post_or_store => %s", __func__, + sent ? "sent" : "stored"); +} + /* A CONNECT message from a device gives us the hostID and socket we'll * associate with one participant in a relayed session. We'll store this * information with the cookie where other participants can find it when they @@ -1652,6 +1673,7 @@ msgToStr( XWRelayReg msg ) CASE_STR(XWPDEV_UNAVAIL); CASE_STR(XWPDEV_REG); CASE_STR(XWPDEV_REGRSP); + CASE_STR(XWPDEV_INVITE); CASE_STR(XWPDEV_KEEPALIVE); CASE_STR(XWPDEV_HAVEMSGS); CASE_STR(XWPDEV_RQSTMSGS); @@ -1756,6 +1778,18 @@ handle_udp_packet( UdpThreadClosure* utc ) } break; } + + case XWPDEV_INVITE: + DevIDRelay sender; + DevIDRelay invitee; + if ( getNetLong( &ptr, end, &sender ) + && getNetLong( &ptr, end, &invitee) ) { + logf( XW_LOGVERBOSE0, "got invite from %d for %d", + sender, invitee ); + post_invite( sender, invitee, ptr, end - ptr ); + } + break; + case XWPDEV_KEEPALIVE: case XWPDEV_RQSTMSGS: { DevID devID( ID_TYPE_RELAY ); diff --git a/xwords4/relay/xwrelay.h b/xwords4/relay/xwrelay.h index 2eef03edf..a502957c0 100644 --- a/xwords4/relay/xwrelay.h +++ b/xwords4/relay/xwrelay.h @@ -108,6 +108,11 @@ enum { XWPDEV_NONE /* 0 is an illegal value */ to check for upgrades; may eventually replace device needing a timer. */ + ,XWPDEV_INVITE /* dev->relay; format: header, sender relay + id: 4, recipient relay id: 4; nli data: + variable length. */ + ,XWPDEV_GOTINVITE /* relay->dev */ + ,XWPDEV_N_ELEMS /* MUST BE LAST */ } From d605686fd63a8f88e8e1dc91a81c0801c3203f9f Mon Sep 17 00:00:00 2001 From: Relay User Date: Sat, 11 Jul 2015 07:00:51 -0700 Subject: [PATCH 04/10] add teaser to gcm message (matches android client change) --- xwords4/relay/scripts/gcm_msg.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/xwords4/relay/scripts/gcm_msg.py b/xwords4/relay/scripts/gcm_msg.py index 5cacc872c..1ced80f84 100755 --- a/xwords4/relay/scripts/gcm_msg.py +++ b/xwords4/relay/scripts/gcm_msg.py @@ -14,7 +14,8 @@ def usage(): def sendMsg( devid, msg ): values = { 'registration_ids': [ devid ], - 'data' : { 'title' : 'Msg from Darth2', + 'data' : { 'title' : 'Re: CrossWords', + 'teaser' : 'Please tap to read in the app', 'msg' : msg, } } From 8f863f036940213b4d881955ccfe34ab7fcf4bde Mon Sep 17 00:00:00 2001 From: Relay User Date: Sat, 11 Jul 2015 07:02:50 -0700 Subject: [PATCH 05/10] Make it possible to launch relay early in machine boot cycle before postgres is running (e.g. from a @reboot shortcut in a crontab) by having it wait, sleeping periodically, until a connection is available. Requires new flag be passed into main. --- xwords4/relay/xwrelay.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/xwords4/relay/xwrelay.cpp b/xwords4/relay/xwrelay.cpp index 8ea8c03cd..ce035bc85 100644 --- a/xwords4/relay/xwrelay.cpp +++ b/xwords4/relay/xwrelay.cpp @@ -1172,6 +1172,7 @@ usage( char* arg0 ) #ifdef DO_HTTP "\t-w (localhost port for web interface)\\\n" #endif + "\t-b (block until postgres connection available)\\\n" "\t-D (don't become daemon)\\\n" "\t-F (don't fork and wait to respawn child)\\\n" "\t-f (config file)\\\n" @@ -2022,6 +2023,7 @@ main( int argc, char** argv ) const char* maint_str = NULL; bool doDaemon = true; bool doFork = true; + bool doBlock = false; (void)uptime(); /* force capture of start time */ @@ -2033,7 +2035,7 @@ main( int argc, char** argv ) first. */ for ( ; ; ) { - int opt = getopt(argc, argv, "h?c:p:M:m:n:f:l:t:s:u:w:" + int opt = getopt(argc, argv, "bh?c:p:M:m:n:f:l:t:s:u:w:" "DF" ); if ( opt == -1 ) { @@ -2044,6 +2046,9 @@ main( int argc, char** argv ) case 'h': usage( argv[0] ); exit( 0 ); + case 'b': + doBlock = true; + break; case 'c': ctrlport = atoi( optarg ); break; @@ -2194,6 +2199,10 @@ main( int argc, char** argv ) } #endif + if ( doBlock ) { + DBMgr::Get()->WaitDBConn(); + } + if ( -1 != udpport ) { struct sockaddr_in saddr; g_udpsock = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP ); From 9c7213e42bbe85ea9b66ff5bd11454f2f6dbced4 Mon Sep 17 00:00:00 2001 From: Relay User Date: Sat, 11 Jul 2015 07:03:22 -0700 Subject: [PATCH 06/10] Make it possible to launch relay early in machine boot cycle before postgres is running (e.g. from a @reboot shortcut in a crontab) by having it wait, sleeping periodically, until a connection is available. Requires new flag be passed into main. --- xwords4/relay/dbmgr.cpp | 36 +++++++++++++++++++++++++++++++++++- xwords4/relay/dbmgr.h | 2 ++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/xwords4/relay/dbmgr.cpp b/xwords4/relay/dbmgr.cpp index 6249b48fb..f6cf3fb94 100644 --- a/xwords4/relay/dbmgr.cpp +++ b/xwords4/relay/dbmgr.cpp @@ -44,6 +44,7 @@ static DBMgr* s_instance = NULL; #define MAX_NUM_PLAYERS 4 +#define MAX_WAIT_SECONDS (5*60) // five minutes static int here_less_seed( const char* seeds, int perDeviceSum, unsigned short seed ); @@ -747,6 +748,34 @@ DBMgr::KillGame( const char* const connName, int hid ) execSql( query ); } +void +DBMgr::WaitDBConn( void ) +{ + int nSeconds = 0; + int toSleep = 1; + for ( ; ; ) { + PGconn* conn = DBMgr::getThreadConn(); + if ( !!conn ) { + ConnStatusType status = PQstatus( conn ); + if ( CONNECTION_OK == status ) { + break; + } + } + + toSleep *= 2; + if ( toSleep > MAX_WAIT_SECONDS ) { + toSleep = MAX_WAIT_SECONDS; + } + + (void)sleep( toSleep ); + nSeconds += toSleep; + logf( XW_LOGERROR, "%s: waiting for postgres; %d seconds so far", __func__, + nSeconds ); + } + + logf( XW_LOGERROR, "%s() done", __func__ ); +} + void DBMgr::ClearCIDs( void ) { @@ -1330,7 +1359,12 @@ DBMgr::getThreadConn( void ) params.catf( "port = %d ", port ); conn = PQconnectdb( params.c_str() ); - pthread_setspecific( m_conn_key, conn ); + if ( CONNECTION_OK == PQstatus( conn ) ) { + pthread_setspecific( m_conn_key, conn ); + } else { + PQfinish( conn ); + conn = NULL; + } } return conn; } diff --git a/xwords4/relay/dbmgr.h b/xwords4/relay/dbmgr.h index e0fafcaad..2faef2b05 100644 --- a/xwords4/relay/dbmgr.h +++ b/xwords4/relay/dbmgr.h @@ -63,6 +63,8 @@ class DBMgr { ~DBMgr(); + void WaitDBConn( void ); + void ClearCIDs( void ); void AddNew( const char* cookie, const char* connName, CookieID cid, From ec393bc0c8fc903d957ecc004e8c3c8109e2da6e Mon Sep 17 00:00:00 2001 From: Eric House Date: Sat, 11 Jul 2015 07:53:22 -0700 Subject: [PATCH 07/10] don't crash if intent is null --- .../android/XWords4/src/org/eehouse/android/xw4/Utils.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/Utils.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/Utils.java index 8f9b6a8cd..525dbccb2 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/Utils.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/Utils.java @@ -204,9 +204,9 @@ public class Utils { Intents is to send a different second param each time, though the docs say that param's ignored. */ - PendingIntent pi = - PendingIntent.getActivity( context, Utils.nextRandomInt(), intent, - PendingIntent.FLAG_ONE_SHOT ); + PendingIntent pi = null == intent ? null + : PendingIntent.getActivity( context, Utils.nextRandomInt(), intent, + PendingIntent.FLAG_ONE_SHOT ); Notification notification = new Notification( R.drawable.icon48x48, title, From 67f4e4475c0534ebf7dfa4f650d99a1ea1f1e4ac Mon Sep 17 00:00:00 2001 From: Eric House Date: Sat, 11 Jul 2015 08:08:22 -0700 Subject: [PATCH 08/10] manual bring-over of relay changes for invite support --- xwords4/relay/dbmgr.cpp | 13 +++++++++++++ xwords4/relay/dbmgr.h | 2 ++ xwords4/relay/xwrelay.cpp | 19 +++++++++++++------ 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/xwords4/relay/dbmgr.cpp b/xwords4/relay/dbmgr.cpp index f6cf3fb94..5d3309b8c 100644 --- a/xwords4/relay/dbmgr.cpp +++ b/xwords4/relay/dbmgr.cpp @@ -902,6 +902,19 @@ DBMgr::readArray( const char* const connName, const char* column, int arr[] ) / PQclear( result ); } +// parse something created by comms.c's formatRelayID +DevIDRelay +DBMgr::getDevID( string& relayID ) +{ + size_t pos = relayID.find_first_of( '/' ); + string connName = relayID.substr( 0, pos ); + int hid = relayID[pos + 1] - '0'; + DevIDRelay result = getDevID( connName.c_str(), hid ); + // Not an error. Remove or downlog when confirm working + logf( XW_LOGERROR, "%s(%s) => %d", __func__, relayID.c_str(), result ); + return result; +} + DevIDRelay DBMgr::getDevID( const char* connName, int hid ) { diff --git a/xwords4/relay/dbmgr.h b/xwords4/relay/dbmgr.h index 2faef2b05..839f4f3c9 100644 --- a/xwords4/relay/dbmgr.h +++ b/xwords4/relay/dbmgr.h @@ -148,6 +148,8 @@ class DBMgr { void RemoveStoredMessage( const int msgID ); void RemoveStoredMessages( vector& ids ); + DevIDRelay getDevID( string& relayID ); + private: DBMgr(); bool execSql( const string& query ); diff --git a/xwords4/relay/xwrelay.cpp b/xwords4/relay/xwrelay.cpp index ce035bc85..8343b2292 100644 --- a/xwords4/relay/xwrelay.cpp +++ b/xwords4/relay/xwrelay.cpp @@ -1780,17 +1780,24 @@ handle_udp_packet( UdpThreadClosure* utc ) break; } - case XWPDEV_INVITE: + case XWPDEV_INVITE: { DevIDRelay sender; - DevIDRelay invitee; - if ( getNetLong( &ptr, end, &sender ) - && getNetLong( &ptr, end, &invitee) ) { + string relayID; + if ( getNetLong( &ptr, end, &sender ) + && getNetString( &ptr, end, relayID ) ) { + DevIDRelay invitee; + if ( 0 < relayID.size() ) { + invitee = DBMgr::Get()->getDevID( relayID ); + } else if ( !getNetLong( &ptr, end, &invitee ) ) { + break; // failure + } logf( XW_LOGVERBOSE0, "got invite from %d for %d", sender, invitee ); post_invite( sender, invitee, ptr, end - ptr ); } break; - + } + case XWPDEV_KEEPALIVE: case XWPDEV_RQSTMSGS: { DevID devID( ID_TYPE_RELAY ); @@ -2048,7 +2055,7 @@ main( int argc, char** argv ) exit( 0 ); case 'b': doBlock = true; - break; + break; case 'c': ctrlport = atoi( optarg ); break; From 5e63d03e7659c01f2373e32c9a4a8a0d56945886 Mon Sep 17 00:00:00 2001 From: Eric House Date: Sat, 11 Jul 2015 08:23:22 -0700 Subject: [PATCH 09/10] apparently I forgot to check this in --- xwords4/android/XWords4/archive/R.java | 77 +++++++++++++------------- 1 file changed, 37 insertions(+), 40 deletions(-) diff --git a/xwords4/android/XWords4/archive/R.java b/xwords4/android/XWords4/archive/R.java index af3506f91..b95808d60 100644 --- a/xwords4/android/XWords4/archive/R.java +++ b/xwords4/android/XWords4/archive/R.java @@ -41,46 +41,43 @@ public final class R { public static final int content_copy__gen=0x7f020002; public static final int content_discard__gen=0x7f020003; public static final int content_edit=0x7f020004; - public static final int content_new__gen=0x7f020005; - public static final int content_new_net__gen=0x7f020006; - public static final int content_new_solo__gen=0x7f020007; - public static final int dict__gen=0x7f020008; - public static final int dicticon=0x7f020009; - public static final int down__gen=0x7f02000a; - public static final int downarrow=0x7f02000b; - public static final int download__gen=0x7f02000c; - public static final int email__gen=0x7f02000d; - public static final int expander_ic_maximized=0x7f02000e; - public static final int expander_ic_minimized=0x7f02000f; - public static final int flip=0x7f020010; - public static final int icon48x48=0x7f020011; - public static final int in_arrow=0x7f020012; - public static final int in_arrow_active=0x7f020013; - public static final int multigame__gen=0x7f020014; - public static final int multigame_new__gen=0x7f020015; - public static final int new_group__gen=0x7f020016; - public static final int next_hint=0x7f020017; - public static final int origin=0x7f020018; - public static final int out_arrow=0x7f020019; - public static final int out_arrow_active=0x7f02001a; - public static final int prefs__gen=0x7f02001b; - public static final int prev_hint=0x7f02001c; - public static final int refresh=0x7f02001d; - public static final int relabel__gen=0x7f02001e; - public static final int reset__gen=0x7f02001f; - public static final int rightarrow=0x7f020020; - public static final int save__gen=0x7f020021; - public static final int search__gen=0x7f020022; - public static final int select_all__gen=0x7f020023; - public static final int send__gen=0x7f020024; - public static final int shuffle=0x7f020025; - public static final int sologame__gen=0x7f020026; - public static final int stat_notify_chat=0x7f020027; - public static final int stat_notify_sync=0x7f020028; - public static final int undo=0x7f020029; - public static final int up__gen=0x7f02002a; - public static final int values=0x7f02002b; - public static final int zoom=0x7f02002c; + public static final int content_new_net__gen=0x7f020005; + public static final int content_new_solo__gen=0x7f020006; + public static final int dict__gen=0x7f020007; + public static final int dicticon=0x7f020008; + public static final int down__gen=0x7f020009; + public static final int downarrow=0x7f02000a; + public static final int download__gen=0x7f02000b; + public static final int email__gen=0x7f02000c; + public static final int expander_ic_maximized=0x7f02000d; + public static final int expander_ic_minimized=0x7f02000e; + public static final int flip=0x7f02000f; + public static final int icon48x48=0x7f020010; + public static final int in_arrow=0x7f020011; + public static final int in_arrow_active=0x7f020012; + public static final int multigame__gen=0x7f020013; + public static final int new_group__gen=0x7f020014; + public static final int next_hint=0x7f020015; + public static final int origin=0x7f020016; + public static final int out_arrow=0x7f020017; + public static final int out_arrow_active=0x7f020018; + public static final int prefs__gen=0x7f020019; + public static final int prev_hint=0x7f02001a; + public static final int refresh=0x7f02001b; + public static final int relabel__gen=0x7f02001c; + public static final int reset__gen=0x7f02001d; + public static final int rightarrow=0x7f02001e; + public static final int save__gen=0x7f02001f; + public static final int search__gen=0x7f020020; + public static final int select_all__gen=0x7f020021; + public static final int shuffle=0x7f020022; + public static final int sologame__gen=0x7f020023; + public static final int stat_notify_chat=0x7f020024; + public static final int stat_notify_sync=0x7f020025; + public static final int undo=0x7f020026; + public static final int up__gen=0x7f020027; + public static final int values=0x7f020028; + public static final int zoom=0x7f020029; } public static final class id { public static final int about_xlator=0x7f0a0001; From 6851fd9746af25f8d113a14e59159dc83f3b8f9e Mon Sep 17 00:00:00 2001 From: Eric House Date: Sat, 11 Jul 2015 08:25:10 -0700 Subject: [PATCH 10/10] include teaser from server, and launch an alert in-game instead of having the notification display everything. I've committed this before; not sure where it went. --- .../src/org/eehouse/android/xw4/GCMIntentService.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GCMIntentService.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GCMIntentService.java index 08122d902..f6fb0138b 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GCMIntentService.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GCMIntentService.java @@ -101,8 +101,15 @@ public class GCMIntentService extends GCMBaseIntentService { if ( null != value ) { String title = intent.getStringExtra( "title" ); if ( null != title ) { + String teaser = intent.getStringExtra( "teaser" ); + if ( null == teaser ) { + teaser = value; + } + Intent alertIntent = GamesListDelegate + .makeAlertIntent( this, value ); int code = value.hashCode() ^ title.hashCode(); - Utils.postNotification( context, null, title, value, code ); + Utils.postNotification( context, alertIntent, title, + teaser, code ); } } }