mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-01-18 22:26:30 +01:00
Merge branch 'android_branch' into android_translate
This commit is contained in:
commit
36c9e8c93b
31 changed files with 385 additions and 443 deletions
|
@ -1,6 +1,6 @@
|
||||||
def INITIAL_CLIENT_VERS = 8
|
def INITIAL_CLIENT_VERS = 8
|
||||||
def VERSION_CODE_BASE = 129
|
def VERSION_CODE_BASE = 130
|
||||||
def VERSION_NAME = '4.4.133'
|
def VERSION_NAME = '4.4.134'
|
||||||
def FABRIC_API_KEY = System.getenv("FABRIC_API_KEY")
|
def FABRIC_API_KEY = System.getenv("FABRIC_API_KEY")
|
||||||
def GCM_SENDER_ID = System.getenv("GCM_SENDER_ID")
|
def GCM_SENDER_ID = System.getenv("GCM_SENDER_ID")
|
||||||
def BUILD_INFO_NAME = "build-info.txt"
|
def BUILD_INFO_NAME = "build-info.txt"
|
||||||
|
|
|
@ -13,9 +13,9 @@
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h2>CrossWords 4.4.133 release</h2>
|
<h2>CrossWords 4.4.134 release</h2>
|
||||||
|
|
||||||
<p>This release fixes a crash closing the wordlist browser.</p>
|
<p>This release makes a few UI tweaks.</p>
|
||||||
|
|
||||||
<div id="survey">
|
<div id="survey">
|
||||||
<p>Please <a href="https://www.surveymonkey.com/s/GX3XLHR">take
|
<p>Please <a href="https://www.surveymonkey.com/s/GX3XLHR">take
|
||||||
|
@ -25,12 +25,12 @@
|
||||||
|
|
||||||
<h3>New with this release</h3>
|
<h3>New with this release</h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Don't crash (even occasionally) when closing the wordlist
|
<li>For better navigation with lots of saved games, make the
|
||||||
browser. (Reported via Google; thanks!)</li>
|
scrollbar thumb draggable (and move it to the left side
|
||||||
<li>Prevent setting wordlist browser min word length higher than
|
where it doesn't obscure anything)</li>
|
||||||
max</li>
|
<li>When space is limited in Games List display, truncate player
|
||||||
<li>Don't include current player's tiles in remaining
|
name rather than score</li>
|
||||||
tiles display</li>
|
<li>Include latest Catalan translations (from Weblate)</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p>(The full changelog
|
<p>(The full changelog
|
||||||
|
|
|
@ -1095,60 +1095,29 @@ public class BTService extends XWService {
|
||||||
m_sender = null;
|
m_sender = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void postNotification( String device, int gameID, long rowid )
|
||||||
|
{
|
||||||
|
String body = LocUtils.getString( this, R.string.new_bt_body_fmt,
|
||||||
|
device );
|
||||||
|
|
||||||
|
GameUtils.postInvitedNotification( this, gameID, body, rowid );
|
||||||
|
|
||||||
|
postEvent( MultiEvent.BT_GAME_CREATED, rowid );
|
||||||
|
}
|
||||||
|
|
||||||
private BTCmd makeOrNotify( NetLaunchInfo nli, String btName,
|
private BTCmd makeOrNotify( NetLaunchInfo nli, String btName,
|
||||||
String btAddr )
|
String btAddr )
|
||||||
{
|
{
|
||||||
BTCmd result;
|
BTCmd result;
|
||||||
if ( checkNotDupe( nli ) ) {
|
if ( handleInvitation( nli, btName, DictFetchOwner.OWNER_BT ) ) {
|
||||||
if ( DictLangCache.haveDict( this, nli.lang, nli.dict ) ) {
|
result = BTCmd.INVITE_ACCPT;
|
||||||
result = makeGame( nli, btName, btAddr );
|
|
||||||
} else {
|
|
||||||
Intent intent = MultiService
|
|
||||||
.makeMissingDictIntent( this, nli,
|
|
||||||
DictFetchOwner.OWNER_BT );
|
|
||||||
// NetLaunchInfo.putExtras( intent, gameID, btName, btAddr );
|
|
||||||
MultiService.postMissingDictNotification( this, intent,
|
|
||||||
nli.gameID() );
|
|
||||||
result = BTCmd.INVITE_ACCPT; // ???
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
result = BTCmd.INVITE_DUP_INVITE; // dupe of rematch
|
result = BTCmd.INVITE_DUP_INVITE; // dupe of rematch
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private BTCmd makeGame( NetLaunchInfo nli, String sender,
|
|
||||||
String senderAddress )
|
|
||||||
{
|
|
||||||
BTCmd result;
|
|
||||||
long[] rowids = DBUtils.getRowIDsFor( BTService.this, nli.gameID() );
|
|
||||||
if ( null == rowids || 0 == rowids.length ) {
|
|
||||||
CommsAddrRec addr = nli.makeAddrRec( BTService.this );
|
|
||||||
long rowid = GameUtils.makeNewMultiGame( BTService.this, nli,
|
|
||||||
m_btMsgSink,
|
|
||||||
getUtilCtxt() );
|
|
||||||
if ( DBUtils.ROWID_NOTFOUND == rowid ) {
|
|
||||||
result = BTCmd.INVITE_FAILED;
|
|
||||||
} else {
|
|
||||||
if ( null != nli.gameName && 0 < nli.gameName.length() ) {
|
|
||||||
DBUtils.setName( BTService.this, rowid, nli.gameName );
|
|
||||||
}
|
|
||||||
result = BTCmd.INVITE_ACCPT;
|
|
||||||
String body = LocUtils.getString( BTService.this,
|
|
||||||
R.string.new_bt_body_fmt,
|
|
||||||
sender );
|
|
||||||
|
|
||||||
GameUtils.postInvitedNotification( this, nli.gameID(), body,
|
|
||||||
rowid );
|
|
||||||
|
|
||||||
postEvent( MultiEvent.BT_GAME_CREATED, rowid );
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
result = BTCmd.INVITE_DUPID;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private DataOutputStream connect( BluetoothSocket socket, BTCmd cmd )
|
private DataOutputStream connect( BluetoothSocket socket, BTCmd cmd )
|
||||||
{
|
{
|
||||||
String name = socket.getRemoteDevice().getName();
|
String name = socket.getRemoteDevice().getName();
|
||||||
|
|
|
@ -510,7 +510,9 @@ public class BoardCanvas extends Canvas implements DrawCtx {
|
||||||
public void score_pendingScore( Rect rect, int score, int playerNum,
|
public void score_pendingScore( Rect rect, int score, int playerNum,
|
||||||
int curTurn, int flags )
|
int curTurn, int flags )
|
||||||
{
|
{
|
||||||
String text = score >= 0? String.format( "%d", score ) : "??";
|
Log.d( TAG, "pendingScore(playerNum=%d, curTurn=%d)",
|
||||||
|
playerNum, curTurn );
|
||||||
|
|
||||||
int otherIndx = (0 == (flags & CELL_ISCURSOR))
|
int otherIndx = (0 == (flags & CELL_ISCURSOR))
|
||||||
? CommonPrefs.COLOR_BACKGRND : CommonPrefs.COLOR_FOCUS;
|
? CommonPrefs.COLOR_BACKGRND : CommonPrefs.COLOR_FOCUS;
|
||||||
++rect.top;
|
++rect.top;
|
||||||
|
@ -522,6 +524,7 @@ public class BoardCanvas extends Canvas implements DrawCtx {
|
||||||
}
|
}
|
||||||
m_fillPaint.setColor( playerColor );
|
m_fillPaint.setColor( playerColor );
|
||||||
|
|
||||||
|
String text = score >= 0? String.format( "%d", score ) : "??";
|
||||||
rect.bottom -= rect.height() / 2;
|
rect.bottom -= rect.height() / 2;
|
||||||
drawCentered( text, rect, null );
|
drawCentered( text, rect, null );
|
||||||
|
|
||||||
|
|
|
@ -20,18 +20,24 @@
|
||||||
|
|
||||||
package org.eehouse.android.xw4;
|
package org.eehouse.android.xw4;
|
||||||
|
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.database.DatabaseUtils;
|
import android.database.DatabaseUtils;
|
||||||
|
import android.os.Bundle;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
|
import android.text.TextUtils;
|
||||||
import android.text.format.Time;
|
import android.text.format.Time;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Formatter;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import junit.framework.Assert;
|
import junit.framework.Assert;
|
||||||
|
|
||||||
import org.eehouse.android.xw4.loc.LocUtils;
|
import org.eehouse.android.xw4.loc.LocUtils;
|
||||||
|
|
||||||
import java.util.Formatter;
|
|
||||||
|
|
||||||
public class DbgUtils {
|
public class DbgUtils {
|
||||||
private static final String TAG = DbgUtils.class.getSimpleName();
|
private static final String TAG = DbgUtils.class.getSimpleName();
|
||||||
|
@ -117,21 +123,17 @@ public class DbgUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// public static void printIntent( Intent intent )
|
static String extrasToString( Intent intent )
|
||||||
// {
|
{
|
||||||
// if ( s_doLog ) {
|
Bundle bundle = intent.getExtras();
|
||||||
// Bundle bundle = intent.getExtras();
|
ArrayList<String> al = new ArrayList<String>();
|
||||||
// ArrayList<String> al = new ArrayList<String>();
|
if ( null != bundle ) {
|
||||||
// if ( null != bundle ) {
|
for ( String key : bundle.keySet() ) {
|
||||||
// Set<String> keys = bundle.keySet();
|
al.add( key + ":" + bundle.get(key) );
|
||||||
// Iterator<String> iter = keys.iterator();
|
}
|
||||||
// while ( iter.hasNext() ) {
|
}
|
||||||
// al.add( iter.next() );
|
return TextUtils.join( ", ", al );
|
||||||
// }
|
}
|
||||||
// }
|
|
||||||
// DbgUtils.logf( "intent extras: %s", TextUtils.join( ", ", al ) );
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
public static void dumpCursor( Cursor cursor )
|
public static void dumpCursor( Cursor cursor )
|
||||||
{
|
{
|
||||||
|
|
|
@ -1257,7 +1257,6 @@ public class GameUtils {
|
||||||
|
|
||||||
private static class ResendTask extends AsyncTask<Void, Void, Void> {
|
private static class ResendTask extends AsyncTask<Void, Void, Void> {
|
||||||
private Context m_context;
|
private Context m_context;
|
||||||
private HashMap<Long,CommsConnTypeSet> m_games;
|
|
||||||
private ResendDoneProc m_doneProc;
|
private ResendDoneProc m_doneProc;
|
||||||
private CommsConnType m_filter;
|
private CommsConnType m_filter;
|
||||||
private int m_nSent = 0;
|
private int m_nSent = 0;
|
||||||
|
@ -1273,15 +1272,16 @@ public class GameUtils {
|
||||||
@Override
|
@Override
|
||||||
protected Void doInBackground( Void... unused )
|
protected Void doInBackground( Void... unused )
|
||||||
{
|
{
|
||||||
m_games = DBUtils.getGamesWithSendsPending( m_context );
|
HashMap<Long,CommsConnTypeSet> games
|
||||||
|
= DBUtils.getGamesWithSendsPending( m_context );
|
||||||
|
|
||||||
Iterator<Long> iter = m_games.keySet().iterator();
|
Iterator<Long> iter = games.keySet().iterator();
|
||||||
while ( iter.hasNext() ) {
|
while ( iter.hasNext() ) {
|
||||||
long rowid = iter.next();
|
long rowid = iter.next();
|
||||||
|
|
||||||
// If we're looking for a specific type, check
|
// If we're looking for a specific type, check
|
||||||
if ( null != m_filter ) {
|
if ( null != m_filter ) {
|
||||||
CommsConnTypeSet gameSet = m_games.get( rowid );
|
CommsConnTypeSet gameSet = games.get( rowid );
|
||||||
if ( gameSet != null && ! gameSet.contains( m_filter ) ) {
|
if ( gameSet != null && ! gameSet.contains( m_filter ) ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2476,6 +2476,7 @@ public class GamesListDelegate extends ListDelegateBase
|
||||||
|
|
||||||
private void tryStartsFromIntent( Intent intent )
|
private void tryStartsFromIntent( Intent intent )
|
||||||
{
|
{
|
||||||
|
Log.d( TAG, "tryStartsFromIntent(extras={%s})", DbgUtils.extrasToString( intent ) );
|
||||||
startFirstHasDict( intent );
|
startFirstHasDict( intent );
|
||||||
startNewNetGame( intent );
|
startNewNetGame( intent );
|
||||||
startHasGameID( intent );
|
startHasGameID( intent );
|
||||||
|
|
|
@ -23,7 +23,6 @@ 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;
|
||||||
import android.os.AsyncTask;
|
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
@ -267,51 +266,16 @@ public class RelayService extends XWService
|
||||||
{
|
{
|
||||||
Log.d( TAG, "receiveInvitation: got nli from %d: %s", srcDevID,
|
Log.d( TAG, "receiveInvitation: got nli from %d: %s", srcDevID,
|
||||||
nli.toString() );
|
nli.toString() );
|
||||||
if ( checkNotDupe( nli ) ) {
|
if ( !handleInvitation( nli, null, DictFetchOwner.OWNER_RELAY ) ) {
|
||||||
makeOrNotify( nli );
|
Log.d( TAG, "handleInvitation() failed" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void makeOrNotify( NetLaunchInfo nli )
|
@Override
|
||||||
|
void postNotification( String device, int gameID, long rowid )
|
||||||
{
|
{
|
||||||
if ( DictLangCache.haveDict( this, nli.lang, nli.dict ) ) {
|
String body = LocUtils.getString( this, R.string.new_relay_body );
|
||||||
makeGame( nli );
|
GameUtils.postInvitedNotification( this, gameID, body, rowid );
|
||||||
} else {
|
|
||||||
Intent intent = MultiService
|
|
||||||
.makeMissingDictIntent( this, nli,
|
|
||||||
DictFetchOwner.OWNER_RELAY );
|
|
||||||
MultiService.postMissingDictNotification( this, intent,
|
|
||||||
nli.gameID() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void makeGame( NetLaunchInfo nli )
|
|
||||||
{
|
|
||||||
long[] rowids = DBUtils.getRowIDsFor( this, nli.gameID() );
|
|
||||||
if ( (null == rowids || 0 == rowids.length)
|
|
||||||
|| XWPrefs.getRelayInviteToSelfEnabled( this )) {
|
|
||||||
|
|
||||||
if ( DictLangCache.haveDict( this, nli.lang, nli.dict ) ) {
|
|
||||||
long rowid = GameUtils.makeNewMultiGame( this, nli,
|
|
||||||
new RelayMsgSink(),
|
|
||||||
getUtilCtxt() );
|
|
||||||
if ( DBUtils.ROWID_NOTFOUND != rowid ) {
|
|
||||||
if ( null != nli.gameName && 0 < nli.gameName.length() ) {
|
|
||||||
DBUtils.setName( this, rowid, nli.gameName );
|
|
||||||
}
|
|
||||||
String body = LocUtils.getString( this,
|
|
||||||
R.string.new_relay_body );
|
|
||||||
GameUtils.postInvitedNotification( this, nli.gameID(), body,
|
|
||||||
rowid );
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Intent intent = MultiService
|
|
||||||
.makeMissingDictIntent( this, nli,
|
|
||||||
DictFetchOwner.OWNER_RELAY );
|
|
||||||
MultiService.postMissingDictNotification( this, intent,
|
|
||||||
nli.gameID() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exists to get incoming data onto the main thread
|
// Exists to get incoming data onto the main thread
|
||||||
|
@ -1268,19 +1232,18 @@ public class RelayService extends XWService
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class AsyncSender extends AsyncTask<Void, Void, Void> {
|
private static class AsyncSender extends Thread {
|
||||||
private Context m_context;
|
private Context m_context;
|
||||||
private HashMap<String,ArrayList<byte[]>> m_msgHash;
|
private HashMap<String,ArrayList<byte[]>> m_msgHash;
|
||||||
|
|
||||||
public AsyncSender( Context context,
|
AsyncSender( Context context, HashMap<String, ArrayList<byte[]>> msgHash )
|
||||||
HashMap<String,ArrayList<byte[]>> msgHash )
|
|
||||||
{
|
{
|
||||||
m_context = context;
|
m_context = context;
|
||||||
m_msgHash = msgHash;
|
m_msgHash = msgHash;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Void doInBackground( Void... ignored )
|
public void run()
|
||||||
{
|
{
|
||||||
// format: total msg lenth: 2
|
// format: total msg lenth: 2
|
||||||
// number-of-relayIDs: 2
|
// number-of-relayIDs: 2
|
||||||
|
@ -1327,9 +1290,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( m_context, 8000 );
|
Socket socket = NetUtils.makeProxySocket( m_context, 8000 );
|
||||||
if ( null != socket ) {
|
if ( null != socket ) {
|
||||||
DataOutputStream outStream =
|
DataOutputStream outStream =
|
||||||
|
@ -1345,15 +1308,14 @@ public class RelayService extends XWService
|
||||||
} catch ( java.io.IOException ioe ) {
|
} catch ( java.io.IOException ioe ) {
|
||||||
Log.ex( TAG, ioe );
|
Log.ex( TAG, ioe );
|
||||||
}
|
}
|
||||||
return null;
|
} // run
|
||||||
} // doInBackground
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void sendToRelay( Context context,
|
private static void sendToRelay( Context context,
|
||||||
HashMap<String,ArrayList<byte[]>> msgHash )
|
HashMap<String,ArrayList<byte[]>> msgHash )
|
||||||
{
|
{
|
||||||
if ( null != msgHash ) {
|
if ( null != msgHash ) {
|
||||||
new AsyncSender( context, msgHash ).execute();
|
new AsyncSender( context, msgHash ).start();
|
||||||
} else {
|
} else {
|
||||||
Log.w( TAG, "sendToRelay: null msgs" );
|
Log.w( TAG, "sendToRelay: null msgs" );
|
||||||
}
|
}
|
||||||
|
|
|
@ -504,20 +504,7 @@ public class SMSService extends XWService {
|
||||||
switch( cmd ) {
|
switch( cmd ) {
|
||||||
case INVITE:
|
case INVITE:
|
||||||
String nliData = dis.readUTF();
|
String nliData = dis.readUTF();
|
||||||
NetLaunchInfo nli = new NetLaunchInfo( this, nliData );
|
makeForInvite( phone, new NetLaunchInfo( this, nliData ) );
|
||||||
if ( nli.isValid() && checkNotDupe( nli ) ) {
|
|
||||||
if ( DictLangCache.haveDict( this, nli.lang, nli.dict ) ) {
|
|
||||||
makeForInvite( phone, nli );
|
|
||||||
} else {
|
|
||||||
Intent intent = MultiService
|
|
||||||
.makeMissingDictIntent( this, nli,
|
|
||||||
DictFetchOwner.OWNER_SMS );
|
|
||||||
MultiService.postMissingDictNotification( this, intent,
|
|
||||||
nli.gameID() );
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.w( TAG, "invalid nli from: %s", nliData );
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case DATA:
|
case DATA:
|
||||||
int gameID = dis.readInt();
|
int gameID = dis.readInt();
|
||||||
|
@ -632,7 +619,8 @@ public class SMSService extends XWService {
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void postNotification( String phone, int gameID, long rowid )
|
@Override
|
||||||
|
protected void postNotification( String phone, int gameID, long rowid )
|
||||||
{
|
{
|
||||||
String owner = Utils.phoneToContact( this, phone, true );
|
String owner = Utils.phoneToContact( this, phone, true );
|
||||||
String body = LocUtils.getString( this, R.string.new_name_body_fmt,
|
String body = LocUtils.getString( this, R.string.new_name_body_fmt,
|
||||||
|
@ -642,11 +630,9 @@ public class SMSService extends XWService {
|
||||||
|
|
||||||
private void makeForInvite( String phone, NetLaunchInfo nli )
|
private void makeForInvite( String phone, NetLaunchInfo nli )
|
||||||
{
|
{
|
||||||
long rowid = GameUtils.makeNewMultiGame( this, nli,
|
if ( handleInvitation( nli, phone, DictFetchOwner.OWNER_SMS ) ) {
|
||||||
new SMSMsgSink( this ),
|
ackInvite( phone, nli.gameID() );
|
||||||
getUtilCtxt() );
|
}
|
||||||
postNotification( phone, nli.gameID(), rowid );
|
|
||||||
ackInvite( phone, nli.gameID() );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private PendingIntent makeStatusIntent( String msg )
|
private PendingIntent makeStatusIntent( String msg )
|
||||||
|
|
|
@ -762,19 +762,18 @@ public class WiDirService extends XWService {
|
||||||
String nliData = intent.getStringExtra( KEY_NLI );
|
String nliData = intent.getStringExtra( KEY_NLI );
|
||||||
NetLaunchInfo nli = new NetLaunchInfo( this, nliData );
|
NetLaunchInfo nli = new NetLaunchInfo( this, nliData );
|
||||||
String returnMac = intent.getStringExtra( KEY_SRC );
|
String returnMac = intent.getStringExtra( KEY_SRC );
|
||||||
if ( checkNotDupe( nli ) ) {
|
|
||||||
if ( DictLangCache.haveDict( this, nli.lang, nli.dict ) ) {
|
if ( !handleInvitation( nli, returnMac, DictFetchOwner.OWNER_P2P ) ) {
|
||||||
makeGame( nli, returnMac );
|
Log.d( TAG, "handleInvitation() failed" );
|
||||||
} else {
|
|
||||||
Intent dictIntent = MultiService
|
|
||||||
.makeMissingDictIntent( this, nli,
|
|
||||||
DictFetchOwner.OWNER_P2P );
|
|
||||||
MultiService.postMissingDictNotification( this, dictIntent,
|
|
||||||
nli.gameID() );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void postNotification( String device, int gameID, long rowid )
|
||||||
|
{
|
||||||
|
Log.e( TAG, "postNotification() doing nothing" );
|
||||||
|
}
|
||||||
|
|
||||||
private void handleGameGone( Intent intent )
|
private void handleGameGone( Intent intent )
|
||||||
{
|
{
|
||||||
int gameID = intent.getIntExtra( KEY_GAMEID, 0 );
|
int gameID = intent.getIntExtra( KEY_GAMEID, 0 );
|
||||||
|
|
|
@ -77,11 +77,6 @@ public class XWPrefs {
|
||||||
return getPrefsBoolean( context, R.string.key_show_gcm, false );
|
return getPrefsBoolean( context, R.string.key_show_gcm, false );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean getRelayInviteToSelfEnabled( Context context )
|
|
||||||
{
|
|
||||||
return getPrefsBoolean( context, R.string.key_enable_relay_toself, false );
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean getSMSToSelfEnabled( Context context )
|
public static boolean getSMSToSelfEnabled( Context context )
|
||||||
{
|
{
|
||||||
return getPrefsBoolean( context, R.string.key_enable_sms_toself, false );
|
return getPrefsBoolean( context, R.string.key_enable_sms_toself, false );
|
||||||
|
|
|
@ -27,6 +27,7 @@ import android.os.IBinder;
|
||||||
|
|
||||||
import junit.framework.Assert;
|
import junit.framework.Assert;
|
||||||
|
|
||||||
|
import org.eehouse.android.xw4.MultiService.DictFetchOwner;
|
||||||
import org.eehouse.android.xw4.MultiService.MultiEvent;
|
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.JNIThread;
|
import org.eehouse.android.xw4.jni.JNIThread;
|
||||||
|
@ -36,7 +37,7 @@ import org.eehouse.android.xw4.jni.UtilCtxtImpl;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
class XWService extends Service {
|
abstract class XWService extends Service {
|
||||||
private static final String TAG = XWService.class.getSimpleName();
|
private static final String TAG = XWService.class.getSimpleName();
|
||||||
public static enum ReceiveResult { OK, GAME_GONE, UNCONSUMED };
|
public static enum ReceiveResult { OK, GAME_GONE, UNCONSUMED };
|
||||||
|
|
||||||
|
@ -72,7 +73,7 @@ class XWService extends Service {
|
||||||
|
|
||||||
// Check that we aren't already processing an invitation with this
|
// Check that we aren't already processing an invitation with this
|
||||||
// inviteID.
|
// inviteID.
|
||||||
protected boolean checkNotDupe( NetLaunchInfo nli )
|
private boolean checkNotDupe( NetLaunchInfo nli )
|
||||||
{
|
{
|
||||||
String inviteID = nli.inviteID();
|
String inviteID = nli.inviteID();
|
||||||
boolean isDupe;
|
boolean isDupe;
|
||||||
|
@ -86,6 +87,40 @@ class XWService extends Service {
|
||||||
return !isDupe;
|
return !isDupe;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract void postNotification( String device, int gameID, long rowid );
|
||||||
|
|
||||||
|
protected boolean handleInvitation( NetLaunchInfo nli, String device,
|
||||||
|
DictFetchOwner dfo )
|
||||||
|
{
|
||||||
|
boolean success = false;
|
||||||
|
long[] rowids = DBUtils.getRowIDsFor( this, nli.gameID() );
|
||||||
|
if ( 0 == rowids.length
|
||||||
|
|| ( rowids.length < nli.nPlayersT // will break for two-per-device game
|
||||||
|
&& XWPrefs.getSecondInviteAllowed( this ) ) ) {
|
||||||
|
|
||||||
|
if ( nli.isValid() && checkNotDupe( nli ) ) {
|
||||||
|
|
||||||
|
if ( DictLangCache.haveDict( this, nli.lang, nli.dict ) ) {
|
||||||
|
long rowid = GameUtils.makeNewMultiGame( this, nli,
|
||||||
|
getSink( 0 ),
|
||||||
|
getUtilCtxt() );
|
||||||
|
|
||||||
|
if ( null != nli.gameName && 0 < nli.gameName.length() ) {
|
||||||
|
DBUtils.setName( this, rowid, nli.gameName );
|
||||||
|
}
|
||||||
|
|
||||||
|
postNotification( device, nli.gameID(), rowid );
|
||||||
|
} else {
|
||||||
|
Intent intent = MultiService
|
||||||
|
.makeMissingDictIntent( this, nli, dfo );
|
||||||
|
MultiService.postMissingDictNotification( this, intent,
|
||||||
|
nli.gameID() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
protected UtilCtxt getUtilCtxt()
|
protected UtilCtxt getUtilCtxt()
|
||||||
{
|
{
|
||||||
if ( null == m_utilCtxt ) {
|
if ( null == m_utilCtxt ) {
|
||||||
|
@ -128,8 +163,7 @@ class XWService extends Service {
|
||||||
consumed = true;
|
consumed = true;
|
||||||
jniThread.receive( msg, addr ).release();
|
jniThread.receive( msg, addr ).release();
|
||||||
} else {
|
} else {
|
||||||
GameUtils.BackMoveResult bmr =
|
GameUtils.BackMoveResult bmr = new GameUtils.BackMoveResult();
|
||||||
new GameUtils.BackMoveResult();
|
|
||||||
if ( null == sink ) {
|
if ( null == sink ) {
|
||||||
sink = getSink( rowid );
|
sink = getSink( rowid );
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,7 +125,6 @@
|
||||||
<string name="key_enable_dup_invite">key_enable_dup_invite</string>
|
<string name="key_enable_dup_invite">key_enable_dup_invite</string>
|
||||||
<string name="key_enable_nfc_toself">key_enable_nfc_toself</string>
|
<string name="key_enable_nfc_toself">key_enable_nfc_toself</string>
|
||||||
<string name="key_enable_sms_toself">key_enable_sms_toself</string>
|
<string name="key_enable_sms_toself">key_enable_sms_toself</string>
|
||||||
<string name="key_enable_relay_toself">key_enable_relay_toself</string>
|
|
||||||
<string name="key_ignore_gcm">key_ignore_gcm</string>
|
<string name="key_ignore_gcm">key_ignore_gcm</string>
|
||||||
<string name="key_show_gcm">key_show_gcm</string>
|
<string name="key_show_gcm">key_show_gcm</string>
|
||||||
<string name="key_nag_intervals">key_nag_intervals</string>
|
<string name="key_nag_intervals">key_nag_intervals</string>
|
||||||
|
|
|
@ -2600,9 +2600,6 @@
|
||||||
devices and I think it\'s rare that people play with more than
|
devices and I think it\'s rare that people play with more than
|
||||||
two. Let me know if I\'m wrong and I\'ll up the priority.</string>
|
two. Let me know if I\'m wrong and I\'ll up the priority.</string>
|
||||||
|
|
||||||
<string name="enable_relay_toself_title">Enable relay invites to self</string>
|
|
||||||
<string name="enable_relay_toself_summary">(To aid testing and debugging)</string>
|
|
||||||
|
|
||||||
<string name="ignore_gcm_title">Ignore incoming GCM messages</string>
|
<string name="ignore_gcm_title">Ignore incoming GCM messages</string>
|
||||||
<string name="ignore_gcm_summary">Mimic life without a google account</string>
|
<string name="ignore_gcm_summary">Mimic life without a google account</string>
|
||||||
|
|
||||||
|
|
|
@ -393,11 +393,6 @@
|
||||||
<PreferenceScreen android:title="@string/pref_group_relay_title"
|
<PreferenceScreen android:title="@string/pref_group_relay_title"
|
||||||
android:summary="@string/pref_group_relay_summary"
|
android:summary="@string/pref_group_relay_summary"
|
||||||
>
|
>
|
||||||
<CheckBoxPreference android:key="@string/key_enable_relay_toself"
|
|
||||||
android:title="@string/enable_relay_toself_title"
|
|
||||||
android:summary="@string/enable_relay_toself_summary"
|
|
||||||
android:defaultValue="false"
|
|
||||||
/>
|
|
||||||
<CheckBoxPreference android:key="@string/key_ignore_gcm"
|
<CheckBoxPreference android:key="@string/key_ignore_gcm"
|
||||||
android:title="@string/ignore_gcm_title"
|
android:title="@string/ignore_gcm_title"
|
||||||
android:summary="@string/ignore_gcm_summary"
|
android:summary="@string/ignore_gcm_summary"
|
||||||
|
|
|
@ -2177,6 +2177,7 @@ board_requestHint( BoardCtxt* board,
|
||||||
board_popTimerSave( board );
|
board_popTimerSave( board );
|
||||||
|
|
||||||
if ( searchComplete && canMove ) {
|
if ( searchComplete && canMove ) {
|
||||||
|
juggleMoveIfDebug( &newMove );
|
||||||
model_makeTurnFromMoveInfo( model, selPlayer, &newMove);
|
model_makeTurnFromMoveInfo( model, selPlayer, &newMove);
|
||||||
} else {
|
} else {
|
||||||
result = XP_FALSE;
|
result = XP_FALSE;
|
||||||
|
|
|
@ -2704,7 +2704,7 @@ logAddrs( const CommsCtxt* comms, const char* caller )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
augmentChannelAddr( CommsCtxt* comms, AddressRecord * const rec,
|
augmentChannelAddr( CommsCtxt* XP_UNUSED_DBG(comms), AddressRecord * const rec,
|
||||||
const CommsAddrRec* addr, XWHostID hostID )
|
const CommsAddrRec* addr, XWHostID hostID )
|
||||||
{
|
{
|
||||||
if ( !!addr ) {
|
if ( !!addr ) {
|
||||||
|
|
|
@ -123,7 +123,6 @@ struct EngineCtxt {
|
||||||
static void findMovesOneRow( EngineCtxt* engine );
|
static void findMovesOneRow( EngineCtxt* engine );
|
||||||
static Tile localGetBoardTile( EngineCtxt* engine, XP_U16 col,
|
static Tile localGetBoardTile( EngineCtxt* engine, XP_U16 col,
|
||||||
XP_U16 row, XP_Bool substBlank );
|
XP_U16 row, XP_Bool substBlank );
|
||||||
static XP_Bool scoreQualifies( EngineCtxt* engine, XP_U16 score );
|
|
||||||
static void findMovesForAnchor( EngineCtxt* engine, XP_S16* prevAnchor,
|
static void findMovesForAnchor( EngineCtxt* engine, XP_S16* prevAnchor,
|
||||||
XP_U16 col, XP_U16 row ) ;
|
XP_U16 col, XP_U16 row ) ;
|
||||||
static void figureCrosschecks( EngineCtxt* engine, XP_U16 col,
|
static void figureCrosschecks( EngineCtxt* engine, XP_U16 col,
|
||||||
|
@ -1115,33 +1114,37 @@ considerScoreWordHasBlanks( EngineCtxt* engine, XP_U16 blanksLeft,
|
||||||
XP_U16 ii;
|
XP_U16 ii;
|
||||||
|
|
||||||
if ( blanksLeft == 0 ) {
|
if ( blanksLeft == 0 ) {
|
||||||
XP_U16 score;
|
/* Hack: When a single-tile move involves two words it'll be found by
|
||||||
XP_U16 nTiles = posmove->moveInfo.nTiles;
|
both the horizontal and vertical passes. Since it's really the same
|
||||||
|
move both times we don't want both. It'd be better I think to
|
||||||
|
change the move comparison code to detect it as a duplicate, but
|
||||||
|
that's a lot of work. Instead, add a callback in the single-tile
|
||||||
|
vertical case to count words, and when the count it > 1 drop the
|
||||||
|
move.*/
|
||||||
WordNotifierInfo* wiip = NULL;
|
WordNotifierInfo* wiip = NULL;
|
||||||
WordNotifierInfo wii;
|
WordNotifierInfo wii;
|
||||||
XP_U16 wordCount = 0;
|
XP_U16 singleTileWordCount = 0;
|
||||||
if ( 1 == nTiles ) {
|
if ( !engine->searchHorizontal && 1 == posmove->moveInfo.nTiles ) {
|
||||||
wii.proc = countWords;
|
wii.proc = countWords;
|
||||||
wii.closure = &wordCount;
|
wii.closure = &singleTileWordCount;
|
||||||
wiip = &wii;
|
wiip = &wii;
|
||||||
}
|
}
|
||||||
|
|
||||||
score = figureMoveScore( engine->model, engine->turn,
|
XP_U16 score = figureMoveScore( engine->model, engine->turn,
|
||||||
&posmove->moveInfo,
|
&posmove->moveInfo,
|
||||||
engine, (XWStreamCtxt*)NULL, wiip );
|
engine, (XWStreamCtxt*)NULL, wiip );
|
||||||
#ifdef XWFEATURE_BONUSALL
|
|
||||||
if ( 0 != engine->allTilesBonus && 0 == engine->nTilesMax ) {
|
if ( singleTileWordCount > 1 ) { /* only set by special-case code above */
|
||||||
XP_LOGF( "%s: adding bonus: %d becoming %d", __func__, score ,
|
XP_ASSERT( singleTileWordCount == 2 ); /* I think this is the limit */
|
||||||
score + engine->allTilesBonus );
|
|
||||||
score += engine->allTilesBonus;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/* First, check that the score is even what we're interested in. If
|
|
||||||
it is, then go to the expense of filling in a PossibleMove to be
|
|
||||||
compared in full */
|
|
||||||
if ( 1 == nTiles && 1 < wordCount && !engine->searchHorizontal ) {
|
|
||||||
// XP_LOGF( "%s(): dropping", __func__ );
|
// XP_LOGF( "%s(): dropping", __func__ );
|
||||||
} else if ( scoreQualifies( engine, score ) ) {
|
} else {
|
||||||
|
#ifdef XWFEATURE_BONUSALL
|
||||||
|
if ( 0 != engine->allTilesBonus && 0 == engine->nTilesMax ) {
|
||||||
|
XP_LOGF( "%s: adding bonus: %d becoming %d", __func__, score ,
|
||||||
|
score + engine->allTilesBonus );
|
||||||
|
score += engine->allTilesBonus;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
posmove->score = score;
|
posmove->score = score;
|
||||||
XP_MEMSET( &posmove->blankVals, 0, sizeof(posmove->blankVals) );
|
XP_MEMSET( &posmove->blankVals, 0, sizeof(posmove->blankVals) );
|
||||||
for ( ii = 0; ii < usedBlanksCount; ++ii ) {
|
for ( ii = 0; ii < usedBlanksCount; ++ii ) {
|
||||||
|
@ -1342,43 +1345,6 @@ move_cache_empty( const EngineCtxt* engine )
|
||||||
return empty;
|
return empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
static XP_Bool
|
|
||||||
scoreQualifies( EngineCtxt* engine, XP_U16 score )
|
|
||||||
{
|
|
||||||
XP_Bool qualifies = XP_FALSE;
|
|
||||||
XP_Bool usePrev = engine->usePrev;
|
|
||||||
MoveIterationData* miData = &engine->miData;
|
|
||||||
|
|
||||||
if ( usePrev && score < miData->lastSeenMove.score ) {
|
|
||||||
/* drop it */
|
|
||||||
} else if ( !usePrev && score > miData->lastSeenMove.score
|
|
||||||
/* || (score < miData->lowestSavedScore) */ ) {
|
|
||||||
/* drop it */
|
|
||||||
} else {
|
|
||||||
XP_S16 ii;
|
|
||||||
PossibleMove* savedMoves = miData->savedMoves;
|
|
||||||
/* Look at each saved score, and return true as soon as one's found
|
|
||||||
with a lower or equal score to this. <eeh> As an optimization,
|
|
||||||
consider remembering what the lowest score is *once there are
|
|
||||||
NUM_SAVED_ENGINE_MOVES moves in here* and doing a quick test on
|
|
||||||
that. Or better, keeping the list in sorted order. */
|
|
||||||
for ( ii = 0, savedMoves = miData->savedMoves;
|
|
||||||
ii < engine->nMovesToSave; ++ii, ++savedMoves ) {
|
|
||||||
if ( savedMoves->score == 0 ) { /* empty slot */
|
|
||||||
qualifies = XP_TRUE;
|
|
||||||
} else if ( usePrev && score <= savedMoves->score ) {
|
|
||||||
qualifies = XP_TRUE;
|
|
||||||
break;
|
|
||||||
} else if ( !usePrev && score >= savedMoves->score ) {
|
|
||||||
qualifies = XP_TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//XP_LOGF( "%s(%d)->%d", __func__, score, qualifies );
|
|
||||||
return qualifies;
|
|
||||||
} /* scoreQualifies */
|
|
||||||
|
|
||||||
static array_edge*
|
static array_edge*
|
||||||
edge_from_tile( const DictionaryCtxt* dict, array_edge* from, Tile tile )
|
edge_from_tile( const DictionaryCtxt* dict, array_edge* from, Tile tile )
|
||||||
{
|
{
|
||||||
|
|
|
@ -1120,6 +1120,28 @@ model_makeTurnFromStream( ModelCtxt* model, XP_U16 playerNum,
|
||||||
return success;
|
return success;
|
||||||
} /* model_makeTurnFromStream */
|
} /* model_makeTurnFromStream */
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
void
|
||||||
|
juggleMoveIfDebug( MoveInfo* move )
|
||||||
|
{
|
||||||
|
XP_U16 nTiles = move->nTiles;
|
||||||
|
// XP_LOGF( "%s(): move len: %d", __func__, nTiles );
|
||||||
|
MoveInfoTile tiles[MAX_TRAY_TILES];
|
||||||
|
XP_MEMCPY( tiles, move->tiles, sizeof(tiles) );
|
||||||
|
|
||||||
|
for ( int ii = 0; ii < nTiles; ++ii ) {
|
||||||
|
int last = nTiles - ii;
|
||||||
|
int choice = XP_RANDOM() % last;
|
||||||
|
move->tiles[ii] = tiles[choice];
|
||||||
|
// XP_LOGF( "%s(): setting %d to %d", __func__, ii, choice );
|
||||||
|
if ( choice != --last ) {
|
||||||
|
tiles[choice] = tiles[last];
|
||||||
|
// XP_LOGF( "%s(): replacing %d with %d", __func__, choice, last );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
model_makeTurnFromMoveInfo( ModelCtxt* model, XP_U16 playerNum,
|
model_makeTurnFromMoveInfo( ModelCtxt* model, XP_U16 playerNum,
|
||||||
const MoveInfo* newMove )
|
const MoveInfo* newMove )
|
||||||
|
@ -1127,11 +1149,8 @@ model_makeTurnFromMoveInfo( ModelCtxt* model, XP_U16 playerNum,
|
||||||
XP_U16 col, row, ii;
|
XP_U16 col, row, ii;
|
||||||
XP_U16* other;
|
XP_U16* other;
|
||||||
const MoveInfoTile* tinfo;
|
const MoveInfoTile* tinfo;
|
||||||
Tile blank;
|
Tile blank = dict_getBlankTile( model_getDictionary( model ) );
|
||||||
XP_U16 numTiles;
|
XP_U16 numTiles = newMove->nTiles;
|
||||||
|
|
||||||
blank = dict_getBlankTile( model_getDictionary( model ) );
|
|
||||||
numTiles = newMove->nTiles;
|
|
||||||
|
|
||||||
col = row = newMove->commonCoord; /* just assign both */
|
col = row = newMove->commonCoord; /* just assign both */
|
||||||
other = newMove->isHorizontal? &col: &row;
|
other = newMove->isHorizontal? &col: &row;
|
||||||
|
@ -1667,15 +1686,7 @@ static XP_S16
|
||||||
commitTurn( ModelCtxt* model, XP_S16 turn, const TrayTileSet* newTiles,
|
commitTurn( ModelCtxt* model, XP_S16 turn, const TrayTileSet* newTiles,
|
||||||
XWStreamCtxt* stream, WordNotifierInfo* wni, XP_Bool useStack )
|
XWStreamCtxt* stream, WordNotifierInfo* wni, XP_Bool useStack )
|
||||||
{
|
{
|
||||||
XP_U16 ii;
|
|
||||||
PlayerCtxt* player;
|
|
||||||
PendingTile* pt;
|
|
||||||
XP_S16 score = -1;
|
XP_S16 score = -1;
|
||||||
XP_Bool isHorizontal;
|
|
||||||
const Tile* newTilesP;
|
|
||||||
XP_U16 nTiles;
|
|
||||||
|
|
||||||
nTiles = newTiles->nTiles;
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
XP_ASSERT( getCurrentMoveScoreIfLegal( model, turn, (XWStreamCtxt*)NULL,
|
XP_ASSERT( getCurrentMoveScoreIfLegal( model, turn, (XWStreamCtxt*)NULL,
|
||||||
|
@ -1687,10 +1698,11 @@ commitTurn( ModelCtxt* model, XP_S16 turn, const TrayTileSet* newTiles,
|
||||||
|
|
||||||
clearLastMoveInfo( model );
|
clearLastMoveInfo( model );
|
||||||
|
|
||||||
player = &model->players[turn];
|
PlayerCtxt* player = &model->players[turn];
|
||||||
|
|
||||||
if ( useStack ) {
|
if ( useStack ) {
|
||||||
MoveInfo moveInfo = {0};
|
MoveInfo moveInfo = {0};
|
||||||
|
XP_Bool isHorizontal;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
XP_Bool inLine =
|
XP_Bool inLine =
|
||||||
#endif
|
#endif
|
||||||
|
@ -1701,19 +1713,16 @@ commitTurn( ModelCtxt* model, XP_S16 turn, const TrayTileSet* newTiles,
|
||||||
stack_addMove( model->vol.stack, turn, &moveInfo, newTiles );
|
stack_addMove( model->vol.stack, turn, &moveInfo, newTiles );
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( ii = 0, pt=player->pendingTiles; ii < player->nPending;
|
/* Where's it removed from tray? Need to assert there! */
|
||||||
++ii, ++pt ) {
|
for ( int ii = 0; ii < player->nPending; ++ii ) {
|
||||||
XP_U16 col, row;
|
const PendingTile* pt = &player->pendingTiles[ii];
|
||||||
CellTile tile;
|
XP_U16 col = pt->col;
|
||||||
XP_U16 val;
|
XP_U16 row = pt->row;
|
||||||
|
CellTile tile = getModelTileRaw( model, col, row );
|
||||||
col = pt->col;
|
|
||||||
row = pt->row;
|
|
||||||
tile = getModelTileRaw( model, col, row );
|
|
||||||
|
|
||||||
XP_ASSERT( (tile & TILE_PENDING_BIT) != 0 );
|
XP_ASSERT( (tile & TILE_PENDING_BIT) != 0 );
|
||||||
|
|
||||||
val = tile & TILE_VALUE_MASK;
|
XP_U16 val = tile & TILE_VALUE_MASK;
|
||||||
if ( val > 1 ) { /* somebody else is using this square too! */
|
if ( val > 1 ) { /* somebody else is using this square too! */
|
||||||
putBackOtherPlayersTiles( model, turn, col, row );
|
putBackOtherPlayersTiles( model, turn, col, row );
|
||||||
}
|
}
|
||||||
|
@ -1734,17 +1743,18 @@ commitTurn( ModelCtxt* model, XP_S16 turn, const TrayTileSet* newTiles,
|
||||||
player->score += score;
|
player->score += score;
|
||||||
|
|
||||||
/* Why is this next loop necessary? */
|
/* Why is this next loop necessary? */
|
||||||
for ( ii = 0; ii < model->nPlayers; ++ii ) {
|
for ( int ii = 0; ii < model->nPlayers; ++ii ) {
|
||||||
invalidateScore( model, ii );
|
invalidateScore( model, ii );
|
||||||
}
|
}
|
||||||
|
|
||||||
player->nPending = 0;
|
player->nPending = 0;
|
||||||
player->nUndone = 0;
|
player->nUndone = 0;
|
||||||
|
|
||||||
newTilesP = newTiles->tiles;
|
/* Move new tiles into tray */
|
||||||
while ( nTiles-- ) {
|
for ( int ii = newTiles->nTiles - 1; ii >= 0; --ii ) {
|
||||||
model_addPlayerTile( model, turn, -1, *newTilesP++ );
|
model_addPlayerTile( model, turn, -1, newTiles->tiles[ii] );
|
||||||
}
|
}
|
||||||
|
|
||||||
return score;
|
return score;
|
||||||
} /* commitTurn */
|
} /* commitTurn */
|
||||||
|
|
||||||
|
@ -2045,72 +2055,67 @@ static void
|
||||||
printMovePre( ModelCtxt* model, XP_U16 XP_UNUSED(moveN), const StackEntry* entry,
|
printMovePre( ModelCtxt* model, XP_U16 XP_UNUSED(moveN), const StackEntry* entry,
|
||||||
void* p_closure )
|
void* p_closure )
|
||||||
{
|
{
|
||||||
XWStreamCtxt* stream;
|
if ( entry->moveType != ASSIGN_TYPE ) {
|
||||||
const XP_UCHAR* format;
|
const XP_UCHAR* format;
|
||||||
XP_UCHAR buf[64];
|
XP_UCHAR buf[64];
|
||||||
XP_UCHAR traybuf[MAX_TRAY_TILES+1];
|
XP_UCHAR traybuf[MAX_TRAY_TILES+1];
|
||||||
MovePrintClosure* closure = (MovePrintClosure*)p_closure;
|
MovePrintClosure* closure = (MovePrintClosure*)p_closure;
|
||||||
|
XWStreamCtxt* stream = closure->stream;
|
||||||
|
|
||||||
if ( entry->moveType == ASSIGN_TYPE ) {
|
XP_SNPRINTF( buf, sizeof(buf), (XP_UCHAR*)"%d:%d ", ++closure->nPrinted,
|
||||||
return;
|
entry->playerNum+1 );
|
||||||
}
|
|
||||||
|
|
||||||
stream = closure->stream;
|
|
||||||
|
|
||||||
XP_SNPRINTF( buf, sizeof(buf), (XP_UCHAR*)"%d:%d ", ++closure->nPrinted,
|
|
||||||
entry->playerNum+1 );
|
|
||||||
printString( stream, (XP_UCHAR*)buf );
|
|
||||||
|
|
||||||
if ( entry->moveType == TRADE_TYPE ) {
|
|
||||||
} else {
|
|
||||||
XP_UCHAR letter[2] = {'\0','\0'};
|
|
||||||
XP_Bool isHorizontal = entry->u.move.moveInfo.isHorizontal;
|
|
||||||
XP_U16 col, row;
|
|
||||||
const MoveInfo* mi;
|
|
||||||
XP_Bool isPass = XP_FALSE;
|
|
||||||
|
|
||||||
if ( entry->moveType == PHONY_TYPE ) {
|
|
||||||
mi = &entry->u.phony.moveInfo;
|
|
||||||
} else {
|
|
||||||
mi = &entry->u.move.moveInfo;
|
|
||||||
if ( mi->nTiles == 0 ) {
|
|
||||||
isPass = XP_TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( isPass ) {
|
|
||||||
format = util_getUserString( model->vol.util, STR_PASS );
|
|
||||||
XP_SNPRINTF( buf, VSIZE(buf), "%s", format );
|
|
||||||
} else {
|
|
||||||
if ( isHorizontal ) {
|
|
||||||
format = util_getUserString( model->vol.util, STRS_MOVE_ACROSS );
|
|
||||||
} else {
|
|
||||||
format = util_getUserString( model->vol.util, STRS_MOVE_DOWN );
|
|
||||||
}
|
|
||||||
|
|
||||||
row = mi->commonCoord;
|
|
||||||
col = mi->tiles[0].varCoord;
|
|
||||||
if ( !isHorizontal ) {
|
|
||||||
XP_U16 tmp = col; col = row; row = tmp;
|
|
||||||
}
|
|
||||||
letter[0] = 'A' + col;
|
|
||||||
|
|
||||||
XP_SNPRINTF( traybuf, sizeof(traybuf), (XP_UCHAR *)"%s%d",
|
|
||||||
letter, row + 1 );
|
|
||||||
XP_SNPRINTF( buf, sizeof(buf), format, traybuf );
|
|
||||||
}
|
|
||||||
printString( stream, (XP_UCHAR*)buf );
|
printString( stream, (XP_UCHAR*)buf );
|
||||||
}
|
|
||||||
|
|
||||||
if ( !closure->keepHidden ) {
|
if ( entry->moveType == TRADE_TYPE ) {
|
||||||
format = util_getUserString( model->vol.util, STRS_TRAY_AT_START );
|
} else {
|
||||||
formatTray( model_getPlayerTiles( model, entry->playerNum ),
|
XP_UCHAR letter[2] = {'\0','\0'};
|
||||||
closure->dict, (XP_UCHAR*)traybuf, sizeof(traybuf),
|
XP_Bool isHorizontal = entry->u.move.moveInfo.isHorizontal;
|
||||||
XP_FALSE );
|
XP_U16 col, row;
|
||||||
XP_SNPRINTF( buf, sizeof(buf), format, traybuf );
|
const MoveInfo* mi;
|
||||||
printString( stream, buf );
|
XP_Bool isPass = XP_FALSE;
|
||||||
}
|
|
||||||
|
|
||||||
|
if ( entry->moveType == PHONY_TYPE ) {
|
||||||
|
mi = &entry->u.phony.moveInfo;
|
||||||
|
} else {
|
||||||
|
mi = &entry->u.move.moveInfo;
|
||||||
|
if ( mi->nTiles == 0 ) {
|
||||||
|
isPass = XP_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( isPass ) {
|
||||||
|
format = util_getUserString( model->vol.util, STR_PASS );
|
||||||
|
XP_SNPRINTF( buf, VSIZE(buf), "%s", format );
|
||||||
|
} else {
|
||||||
|
if ( isHorizontal ) {
|
||||||
|
format = util_getUserString( model->vol.util, STRS_MOVE_ACROSS );
|
||||||
|
} else {
|
||||||
|
format = util_getUserString( model->vol.util, STRS_MOVE_DOWN );
|
||||||
|
}
|
||||||
|
|
||||||
|
row = mi->commonCoord;
|
||||||
|
col = mi->tiles[0].varCoord;
|
||||||
|
if ( !isHorizontal ) {
|
||||||
|
XP_U16 tmp = col; col = row; row = tmp;
|
||||||
|
}
|
||||||
|
letter[0] = 'A' + col;
|
||||||
|
|
||||||
|
XP_SNPRINTF( traybuf, sizeof(traybuf), (XP_UCHAR *)"%s%d",
|
||||||
|
letter, row + 1 );
|
||||||
|
XP_SNPRINTF( buf, sizeof(buf), format, traybuf );
|
||||||
|
}
|
||||||
|
printString( stream, (XP_UCHAR*)buf );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !closure->keepHidden ) {
|
||||||
|
format = util_getUserString( model->vol.util, STRS_TRAY_AT_START );
|
||||||
|
formatTray( model_getPlayerTiles( model, entry->playerNum ),
|
||||||
|
closure->dict, (XP_UCHAR*)traybuf, sizeof(traybuf),
|
||||||
|
XP_FALSE );
|
||||||
|
XP_SNPRINTF( buf, sizeof(buf), format, traybuf );
|
||||||
|
printString( stream, buf );
|
||||||
|
}
|
||||||
|
}
|
||||||
} /* printMovePre */
|
} /* printMovePre */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -2118,69 +2123,66 @@ printMovePost( ModelCtxt* model, XP_U16 XP_UNUSED(moveN),
|
||||||
const StackEntry* entry, XP_S16 XP_UNUSED(score),
|
const StackEntry* entry, XP_S16 XP_UNUSED(score),
|
||||||
void* p_closure )
|
void* p_closure )
|
||||||
{
|
{
|
||||||
MovePrintClosure* closure = (MovePrintClosure*)p_closure;
|
if ( entry->moveType != ASSIGN_TYPE ) {
|
||||||
XWStreamCtxt* stream = closure->stream;
|
MovePrintClosure* closure = (MovePrintClosure*)p_closure;
|
||||||
DictionaryCtxt* dict = closure->dict;
|
XWStreamCtxt* stream = closure->stream;
|
||||||
const XP_UCHAR* format;
|
DictionaryCtxt* dict = closure->dict;
|
||||||
XP_U16 nTiles;
|
const XP_UCHAR* format;
|
||||||
XP_S16 totalScore;
|
XP_U16 nTiles;
|
||||||
XP_UCHAR buf[100];
|
|
||||||
XP_UCHAR traybuf1[MAX_TRAY_TILES+1];
|
|
||||||
XP_UCHAR traybuf2[MAX_TRAY_TILES+1];
|
|
||||||
const MoveInfo* mi;
|
|
||||||
|
|
||||||
if ( entry->moveType == ASSIGN_TYPE ) {
|
XP_UCHAR buf[100];
|
||||||
return;
|
XP_UCHAR traybuf1[MAX_TRAY_TILES+1];
|
||||||
}
|
XP_UCHAR traybuf2[MAX_TRAY_TILES+1];
|
||||||
|
const MoveInfo* mi;
|
||||||
|
XP_S16 totalScore = model_getPlayerScore( model, entry->playerNum );
|
||||||
|
|
||||||
totalScore = model_getPlayerScore( model, entry->playerNum );
|
switch( entry->moveType ) {
|
||||||
|
case TRADE_TYPE:
|
||||||
|
formatTray( (const TrayTileSet*)&entry->u.trade.oldTiles,
|
||||||
|
dict, traybuf1, sizeof(traybuf1), closure->keepHidden );
|
||||||
|
formatTray( (const TrayTileSet*) &entry->u.trade.newTiles,
|
||||||
|
dict, traybuf2, sizeof(traybuf2), closure->keepHidden );
|
||||||
|
|
||||||
switch( entry->moveType ) {
|
format = util_getUserString( model->vol.util, STRSS_TRADED_FOR );
|
||||||
case TRADE_TYPE:
|
XP_SNPRINTF( buf, sizeof(buf), format, traybuf1, traybuf2 );
|
||||||
formatTray( (const TrayTileSet*)&entry->u.trade.oldTiles,
|
printString( stream, buf );
|
||||||
dict, traybuf1, sizeof(traybuf1), closure->keepHidden );
|
printString( stream, (XP_UCHAR*)XP_CR );
|
||||||
formatTray( (const TrayTileSet*) &entry->u.trade.newTiles,
|
break;
|
||||||
dict, traybuf2, sizeof(traybuf2), closure->keepHidden );
|
|
||||||
|
|
||||||
format = util_getUserString( model->vol.util, STRSS_TRADED_FOR );
|
case PHONY_TYPE:
|
||||||
XP_SNPRINTF( buf, sizeof(buf), format, traybuf1, traybuf2 );
|
format = util_getUserString( model->vol.util, STR_PHONY_REJECTED );
|
||||||
printString( stream, buf );
|
printString( stream, format );
|
||||||
printString( stream, (XP_UCHAR*)XP_CR );
|
case MOVE_TYPE:
|
||||||
break;
|
format = util_getUserString( model->vol.util, STRD_CUMULATIVE_SCORE );
|
||||||
|
XP_SNPRINTF( buf, sizeof(buf), format, totalScore );
|
||||||
case PHONY_TYPE:
|
printString( stream, buf );
|
||||||
format = util_getUserString( model->vol.util, STR_PHONY_REJECTED );
|
|
||||||
printString( stream, format );
|
|
||||||
case MOVE_TYPE:
|
|
||||||
format = util_getUserString( model->vol.util, STRD_CUMULATIVE_SCORE );
|
|
||||||
XP_SNPRINTF( buf, sizeof(buf), format, totalScore );
|
|
||||||
printString( stream, buf );
|
|
||||||
|
|
||||||
if ( entry->moveType == PHONY_TYPE ) {
|
|
||||||
mi = &entry->u.phony.moveInfo;
|
|
||||||
} else {
|
|
||||||
mi = &entry->u.move.moveInfo;
|
|
||||||
}
|
|
||||||
nTiles = mi->nTiles;
|
|
||||||
if ( nTiles > 0 ) {
|
|
||||||
|
|
||||||
if ( entry->moveType == PHONY_TYPE ) {
|
if ( entry->moveType == PHONY_TYPE ) {
|
||||||
/* printString( stream, (XP_UCHAR*)"phony rejected " ); */
|
mi = &entry->u.phony.moveInfo;
|
||||||
} else if ( !closure->keepHidden ) {
|
} else {
|
||||||
format = util_getUserString(model->vol.util, STRS_NEW_TILES);
|
mi = &entry->u.move.moveInfo;
|
||||||
XP_SNPRINTF( buf, sizeof(buf), format,
|
|
||||||
formatTray( &entry->u.move.newTiles, dict,
|
|
||||||
traybuf1, sizeof(traybuf1),
|
|
||||||
XP_FALSE ) );
|
|
||||||
printString( stream, buf );
|
|
||||||
stream_catString( stream, (XP_UCHAR*)XP_CR );
|
|
||||||
}
|
}
|
||||||
|
nTiles = mi->nTiles;
|
||||||
|
if ( nTiles > 0 ) {
|
||||||
|
|
||||||
|
if ( entry->moveType == PHONY_TYPE ) {
|
||||||
|
/* printString( stream, (XP_UCHAR*)"phony rejected " ); */
|
||||||
|
} else if ( !closure->keepHidden ) {
|
||||||
|
format = util_getUserString(model->vol.util, STRS_NEW_TILES);
|
||||||
|
XP_SNPRINTF( buf, sizeof(buf), format,
|
||||||
|
formatTray( &entry->u.move.newTiles, dict,
|
||||||
|
traybuf1, sizeof(traybuf1),
|
||||||
|
XP_FALSE ) );
|
||||||
|
printString( stream, buf );
|
||||||
|
stream_catString( stream, (XP_UCHAR*)XP_CR );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
printString( stream, (XP_UCHAR*)XP_CR );
|
||||||
}
|
}
|
||||||
|
|
||||||
printString( stream, (XP_UCHAR*)XP_CR );
|
|
||||||
} /* printMovePost */
|
} /* printMovePost */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -221,6 +221,12 @@ XP_Bool model_makeTurnFromStream( ModelCtxt* model, XP_U16 playerNum,
|
||||||
void model_makeTurnFromMoveInfo( ModelCtxt* model, XP_U16 playerNum,
|
void model_makeTurnFromMoveInfo( ModelCtxt* model, XP_U16 playerNum,
|
||||||
const MoveInfo* newMove );
|
const MoveInfo* newMove );
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
void juggleMoveIfDebug( MoveInfo* move );
|
||||||
|
#else
|
||||||
|
# define juggleMoveIfDebug(newMove)
|
||||||
|
#endif
|
||||||
|
|
||||||
void model_resetCurrentTurn( ModelCtxt* model, XP_S16 turn );
|
void model_resetCurrentTurn( ModelCtxt* model, XP_S16 turn );
|
||||||
XP_S16 model_getNMoves( const ModelCtxt* model );
|
XP_S16 model_getNMoves( const ModelCtxt* model );
|
||||||
|
|
||||||
|
|
|
@ -316,10 +316,9 @@ void
|
||||||
stack_addMove( StackCtxt* stack, XP_U16 turn, const MoveInfo* moveInfo,
|
stack_addMove( StackCtxt* stack, XP_U16 turn, const MoveInfo* moveInfo,
|
||||||
const TrayTileSet* newTiles )
|
const TrayTileSet* newTiles )
|
||||||
{
|
{
|
||||||
StackEntry move;
|
StackEntry move = {.playerNum = (XP_U8)turn,
|
||||||
|
.moveType = MOVE_TYPE,
|
||||||
move.playerNum = (XP_U8)turn;
|
};
|
||||||
move.moveType = MOVE_TYPE;
|
|
||||||
|
|
||||||
XP_MEMCPY( &move.u.move.moveInfo, moveInfo, sizeof(move.u.move.moveInfo));
|
XP_MEMCPY( &move.u.move.moveInfo, moveInfo, sizeof(move.u.move.moveInfo));
|
||||||
move.u.move.newTiles = *newTiles;
|
move.u.move.newTiles = *newTiles;
|
||||||
|
@ -330,10 +329,9 @@ stack_addMove( StackCtxt* stack, XP_U16 turn, const MoveInfo* moveInfo,
|
||||||
void
|
void
|
||||||
stack_addPhony( StackCtxt* stack, XP_U16 turn, const MoveInfo* moveInfo )
|
stack_addPhony( StackCtxt* stack, XP_U16 turn, const MoveInfo* moveInfo )
|
||||||
{
|
{
|
||||||
StackEntry move;
|
StackEntry move = {.playerNum = (XP_U8)turn,
|
||||||
|
.moveType = PHONY_TYPE,
|
||||||
move.playerNum = (XP_U8)turn;
|
};
|
||||||
move.moveType = PHONY_TYPE;
|
|
||||||
|
|
||||||
XP_MEMCPY( &move.u.phony.moveInfo, moveInfo,
|
XP_MEMCPY( &move.u.phony.moveInfo, moveInfo,
|
||||||
sizeof(move.u.phony.moveInfo));
|
sizeof(move.u.phony.moveInfo));
|
||||||
|
@ -345,10 +343,9 @@ void
|
||||||
stack_addTrade( StackCtxt* stack, XP_U16 turn,
|
stack_addTrade( StackCtxt* stack, XP_U16 turn,
|
||||||
const TrayTileSet* oldTiles, const TrayTileSet* newTiles )
|
const TrayTileSet* oldTiles, const TrayTileSet* newTiles )
|
||||||
{
|
{
|
||||||
StackEntry move;
|
StackEntry move = { .playerNum = (XP_U8)turn,
|
||||||
|
.moveType = TRADE_TYPE,
|
||||||
move.playerNum = (XP_U8)turn;
|
};
|
||||||
move.moveType = TRADE_TYPE;
|
|
||||||
|
|
||||||
move.u.trade.oldTiles = *oldTiles;
|
move.u.trade.oldTiles = *oldTiles;
|
||||||
move.u.trade.newTiles = *newTiles;
|
move.u.trade.newTiles = *newTiles;
|
||||||
|
@ -359,10 +356,9 @@ stack_addTrade( StackCtxt* stack, XP_U16 turn,
|
||||||
void
|
void
|
||||||
stack_addAssign( StackCtxt* stack, XP_U16 turn, const TrayTileSet* tiles )
|
stack_addAssign( StackCtxt* stack, XP_U16 turn, const TrayTileSet* tiles )
|
||||||
{
|
{
|
||||||
StackEntry move;
|
StackEntry move = { .playerNum = (XP_U8)turn,
|
||||||
|
.moveType = ASSIGN_TYPE,
|
||||||
move.playerNum = (XP_U8)turn;
|
};
|
||||||
move.moveType = ASSIGN_TYPE;
|
|
||||||
|
|
||||||
move.u.assign.tiles = *tiles;
|
move.u.assign.tiles = *tiles;
|
||||||
|
|
||||||
|
|
|
@ -615,9 +615,13 @@ scoreWord( const ModelCtxt* model, XP_U16 turn,
|
||||||
* each time through in the debug case */
|
* each time through in the debug case */
|
||||||
if ( 0 ) { /* makes keeping parens balanced easier */
|
if ( 0 ) { /* makes keeping parens balanced easier */
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
/* Always run in DEBUG case */
|
||||||
} else if ( 1 ) {
|
} else if ( 1 ) {
|
||||||
#else
|
#else
|
||||||
} else if ( engine == NULL ) {
|
/* If notifyInfo is set, we're counting on the side-effect of its
|
||||||
|
proc getting called. So skip caching in that case even on
|
||||||
|
release builds. */
|
||||||
|
} else if ( engine == NULL || notifyInfo != NULL ) {
|
||||||
#endif
|
#endif
|
||||||
Tile checkWordBuf[MAX_ROWS];
|
Tile checkWordBuf[MAX_ROWS];
|
||||||
Tile* curTile = checkWordBuf;
|
Tile* curTile = checkWordBuf;
|
||||||
|
@ -688,7 +692,8 @@ scoreWord( const ModelCtxt* model, XP_U16 turn,
|
||||||
#else
|
#else
|
||||||
} else { /* non-debug case we know it's non-null */
|
} else { /* non-debug case we know it's non-null */
|
||||||
#endif
|
#endif
|
||||||
XP_ASSERT( nTiles==1 );
|
XP_ASSERT( nTiles == 1 );
|
||||||
|
XP_ASSERT( notifyInfo == NULL );
|
||||||
XP_ASSERT( engine_getScoreCache( engine, movei->commonCoord )
|
XP_ASSERT( engine_getScoreCache( engine, movei->commonCoord )
|
||||||
== restScore );
|
== restScore );
|
||||||
restScore = engine_getScoreCache( engine, movei->commonCoord );
|
restScore = engine_getScoreCache( engine, movei->commonCoord );
|
||||||
|
|
|
@ -929,6 +929,7 @@ makeRobotMove( ServerCtxt* server )
|
||||||
/* if canMove is false, this is a fake move, a pass */
|
/* if canMove is false, this is a fake move, a pass */
|
||||||
|
|
||||||
if ( canMove || NPASSES_OK(server) ) {
|
if ( canMove || NPASSES_OK(server) ) {
|
||||||
|
juggleMoveIfDebug( &newMove );
|
||||||
model_makeTurnFromMoveInfo( model, turn, &newMove );
|
model_makeTurnFromMoveInfo( model, turn, &newMove );
|
||||||
XP_LOGF( "%s: robot making %d tile move", __func__, newMove.nTiles );
|
XP_LOGF( "%s: robot making %d tile move", __func__, newMove.nTiles );
|
||||||
|
|
||||||
|
@ -1832,10 +1833,7 @@ fetchTiles( ServerCtxt* server, XP_U16 playerNum, XP_U16 nToFetch,
|
||||||
{
|
{
|
||||||
XP_Bool ask;
|
XP_Bool ask;
|
||||||
XP_U16 nSoFar = resultTiles->nTiles;
|
XP_U16 nSoFar = resultTiles->nTiles;
|
||||||
XP_U16 nLeft;
|
|
||||||
PoolContext* pool = server->pool;
|
PoolContext* pool = server->pool;
|
||||||
TrayTileSet oneTile;
|
|
||||||
PickInfo pi;
|
|
||||||
const XP_UCHAR* curTray[MAX_TRAY_TILES];
|
const XP_UCHAR* curTray[MAX_TRAY_TILES];
|
||||||
#ifdef FEATURE_TRAY_EDIT
|
#ifdef FEATURE_TRAY_EDIT
|
||||||
DictionaryCtxt* dict = model_getDictionary( server->vol.model );
|
DictionaryCtxt* dict = model_getDictionary( server->vol.model );
|
||||||
|
@ -1849,22 +1847,22 @@ fetchTiles( ServerCtxt* server, XP_U16 playerNum, XP_U16 nToFetch,
|
||||||
ask = XP_FALSE;
|
ask = XP_FALSE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
nLeft = pool_getNTilesLeft( pool );
|
XP_U16 nLeft = pool_getNTilesLeft( pool );
|
||||||
if ( nLeft < nToFetch ) {
|
if ( nLeft < nToFetch ) {
|
||||||
nToFetch = nLeft;
|
nToFetch = nLeft;
|
||||||
}
|
}
|
||||||
|
|
||||||
oneTile.nTiles = 1;
|
TrayTileSet oneTile = {.nTiles = 1};
|
||||||
|
PickInfo pi = { .nTotal = nToFetch,
|
||||||
pi.nTotal = nToFetch;
|
.thisPick = 0,
|
||||||
pi.thisPick = 0;
|
.curTiles = curTray,
|
||||||
pi.curTiles = curTray;
|
};
|
||||||
|
|
||||||
curTrayAsTexts( server, playerNum, tradedTiles, &pi.nCurTiles, curTray );
|
curTrayAsTexts( server, playerNum, tradedTiles, &pi.nCurTiles, curTray );
|
||||||
|
|
||||||
#ifdef FEATURE_TRAY_EDIT /* good compiler would note ask==0, but... */
|
#ifdef FEATURE_TRAY_EDIT /* good compiler would note ask==0, but... */
|
||||||
/* First ask until cancelled */
|
/* First ask until cancelled */
|
||||||
for ( ; ask && nSoFar < nToFetch; ) {
|
while ( ask && nSoFar < nToFetch ) {
|
||||||
const XP_UCHAR* texts[MAX_UNIQUE_TILES];
|
const XP_UCHAR* texts[MAX_UNIQUE_TILES];
|
||||||
Tile tiles[MAX_UNIQUE_TILES];
|
Tile tiles[MAX_UNIQUE_TILES];
|
||||||
XP_S16 chosen;
|
XP_S16 chosen;
|
||||||
|
@ -1901,12 +1899,7 @@ fetchTiles( ServerCtxt* server, XP_U16 playerNum, XP_U16 nToFetch,
|
||||||
/* Then fetch the rest without asking */
|
/* Then fetch the rest without asking */
|
||||||
if ( nSoFar < nToFetch ) {
|
if ( nSoFar < nToFetch ) {
|
||||||
XP_U8 nLeft = nToFetch - nSoFar;
|
XP_U8 nLeft = nToFetch - nSoFar;
|
||||||
Tile tiles[MAX_TRAY_TILES];
|
pool_requestTiles( pool, &resultTiles->tiles[nSoFar], &nLeft );
|
||||||
|
|
||||||
pool_requestTiles( pool, tiles, &nLeft );
|
|
||||||
|
|
||||||
XP_MEMCPY( &resultTiles->tiles[nSoFar], tiles,
|
|
||||||
nLeft * sizeof(resultTiles->tiles[0]) );
|
|
||||||
nSoFar += nLeft;
|
nSoFar += nLeft;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2462,8 +2455,9 @@ server_commitMove( ServerCtxt* server, TrayTileSet* newTilesP )
|
||||||
if client, send to server. */
|
if client, send to server. */
|
||||||
XP_ASSERT( turn >= 0 );
|
XP_ASSERT( turn >= 0 );
|
||||||
|
|
||||||
nTilesMoved = model_getCurrentMoveCount( model, turn );
|
|
||||||
pool_removeTiles( server->pool, &newTiles );
|
pool_removeTiles( server->pool, &newTiles );
|
||||||
|
|
||||||
|
nTilesMoved = model_getCurrentMoveCount( model, turn );
|
||||||
fetchTiles( server, turn, nTilesMoved, NULL, &newTiles );
|
fetchTiles( server, turn, nTilesMoved, NULL, &newTiles );
|
||||||
|
|
||||||
#ifndef XWFEATURE_STANDALONE_ONLY
|
#ifndef XWFEATURE_STANDALONE_ONLY
|
||||||
|
|
|
@ -1372,8 +1372,8 @@ curses_util_getVTManager(XW_UtilCtxt* uc)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
curses_util_informNeedPassword( XW_UtilCtxt* XP_UNUSED(uc),
|
curses_util_informNeedPassword( XW_UtilCtxt* XP_UNUSED(uc),
|
||||||
XP_U16 playerNum,
|
XP_U16 XP_UNUSED_DBG(playerNum),
|
||||||
const XP_UCHAR* name )
|
const XP_UCHAR* XP_UNUSED_DBG(name) )
|
||||||
{
|
{
|
||||||
XP_WARNF( "curses_util_informNeedPassword(num=%d, name=%s", playerNum, name );
|
XP_WARNF( "curses_util_informNeedPassword(num=%d, name=%s", playerNum, name );
|
||||||
} /* curses_util_askPassword */
|
} /* curses_util_askPassword */
|
||||||
|
@ -1391,7 +1391,7 @@ curses_util_yOffsetChange( XW_UtilCtxt* XP_UNUSED(uc),
|
||||||
|
|
||||||
#ifdef XWFEATURE_TURNCHANGENOTIFY
|
#ifdef XWFEATURE_TURNCHANGENOTIFY
|
||||||
static void
|
static void
|
||||||
curses_util_turnChanged( XW_UtilCtxt* XP_UNUSED(uc), XP_S16 newTurn )
|
curses_util_turnChanged( XW_UtilCtxt* XP_UNUSED(uc), XP_S16 XP_UNUSED_DBG(newTurn) )
|
||||||
{
|
{
|
||||||
XP_LOGF( "%s(turn=%d)", __func__, newTurn );
|
XP_LOGF( "%s(turn=%d)", __func__, newTurn );
|
||||||
}
|
}
|
||||||
|
@ -1725,7 +1725,7 @@ cursesGotBuf( void* closure, const CommsAddrRec* addr,
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cursesGotForRow( void* closure, const CommsAddrRec* from,
|
cursesGotForRow( void* closure, const CommsAddrRec* from,
|
||||||
sqlite3_int64 rowid, const XP_U8* buf,
|
sqlite3_int64 XP_UNUSED_DBG(rowid), const XP_U8* buf,
|
||||||
XP_U16 len )
|
XP_U16 len )
|
||||||
{
|
{
|
||||||
LOG_FUNC();
|
LOG_FUNC();
|
||||||
|
|
|
@ -31,8 +31,8 @@ static void getColumnText( sqlite3_stmt *ppStmt, int iCol, XP_UCHAR* buf,
|
||||||
int len );
|
int len );
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
static char* sqliteErr2str( int err );
|
static char* sqliteErr2str( int err );
|
||||||
static void assertPrintResult( sqlite3* pDb, int result, int expect );
|
|
||||||
#endif
|
#endif
|
||||||
|
static void assertPrintResult( sqlite3* pDb, int result, int expect );
|
||||||
|
|
||||||
sqlite3*
|
sqlite3*
|
||||||
openGamesDB( const char* dbName )
|
openGamesDB( const char* dbName )
|
||||||
|
@ -590,17 +590,15 @@ sqliteErr2str( int err )
|
||||||
}
|
}
|
||||||
return "<unknown>";
|
return "<unknown>";
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
assertPrintResult( sqlite3* pDb, int result, int expect )
|
assertPrintResult( sqlite3* pDb, int XP_UNUSED_DBG(result), int expect )
|
||||||
{
|
{
|
||||||
int code = sqlite3_errcode( pDb );
|
int code = sqlite3_errcode( pDb );
|
||||||
XP_ASSERT( code == result ); /* do I need to pass it? */
|
XP_ASSERT( code == result ); /* do I need to pass it? */
|
||||||
if ( code != expect ) {
|
if ( code != expect ) {
|
||||||
const char* msg = sqlite3_errmsg( pDb );
|
XP_LOGF( "sqlite3 error: %s", sqlite3_errmsg( pDb ) );
|
||||||
XP_LOGF( "sqlite3 error: %s", msg );
|
|
||||||
XP_ASSERT(0);
|
XP_ASSERT(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -435,7 +435,7 @@ tryConnectToServer(CommonGlobals* cGlobals)
|
||||||
{
|
{
|
||||||
LaunchParams* params = cGlobals->params;
|
LaunchParams* params = cGlobals->params;
|
||||||
XWStreamCtxt* stream =
|
XWStreamCtxt* stream =
|
||||||
mem_stream_make( cGlobals->util->mpool, params->vtMgr,
|
mem_stream_make( MPPARM(cGlobals->util->mpool) params->vtMgr,
|
||||||
cGlobals, CHANNEL_NONE,
|
cGlobals, CHANNEL_NONE,
|
||||||
sendOnClose );
|
sendOnClose );
|
||||||
(void)server_initClientConnection( cGlobals->game.server,
|
(void)server_initClientConnection( cGlobals->game.server,
|
||||||
|
|
|
@ -1460,8 +1460,7 @@ gtkDrawCtxtMake( GtkWidget* drawing_area, GtkGameGlobals* globals )
|
||||||
dctx->drawing_area = drawing_area;
|
dctx->drawing_area = drawing_area;
|
||||||
dctx->globals = globals;
|
dctx->globals = globals;
|
||||||
|
|
||||||
GdkWindow* window = gtk_widget_get_window(drawing_area);
|
XP_ASSERT( !!gtk_widget_get_window(drawing_area) );
|
||||||
XP_ASSERT( !!window );
|
|
||||||
#ifdef USE_CAIRO
|
#ifdef USE_CAIRO
|
||||||
/* dctx->cairo = gdk_cairo_create( window ); */
|
/* dctx->cairo = gdk_cairo_create( window ); */
|
||||||
/* XP_LOGF( "dctx->cairo=%p", dctx->cairo ); */
|
/* XP_LOGF( "dctx->cairo=%p", dctx->cairo ); */
|
||||||
|
@ -1514,6 +1513,7 @@ removeSurface( GtkDrawCtx* dctx )
|
||||||
dctx->surface = NULL;
|
dctx->surface = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
static cairo_status_t
|
static cairo_status_t
|
||||||
write_func( void *closure, const unsigned char *data,
|
write_func( void *closure, const unsigned char *data,
|
||||||
unsigned int length )
|
unsigned int length )
|
||||||
|
@ -1522,16 +1522,19 @@ write_func( void *closure, const unsigned char *data,
|
||||||
stream_putBytes( stream, data, length );
|
stream_putBytes( stream, data, length );
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
getImage( GtkDrawCtx* dctx, XWStreamCtxt* stream )
|
getImage( GtkDrawCtx* XP_UNUSED_DBG(dctx), XWStreamCtxt* XP_UNUSED_DBG(stream) )
|
||||||
{
|
{
|
||||||
LOG_FUNC();
|
LOG_FUNC();
|
||||||
XP_ASSERT( !!dctx->surface );
|
XP_ASSERT( !!dctx->surface );
|
||||||
|
#ifdef DEBUG
|
||||||
cairo_status_t status =
|
cairo_status_t status =
|
||||||
cairo_surface_write_to_png_stream( dctx->surface,
|
cairo_surface_write_to_png_stream( dctx->surface,
|
||||||
write_func, stream );
|
write_func, stream );
|
||||||
XP_ASSERT( CAIRO_STATUS_SUCCESS == status );
|
XP_ASSERT( CAIRO_STATUS_SUCCESS == status );
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -1242,7 +1242,7 @@ linux_reset( void* closure )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
XP_S16
|
XP_S16
|
||||||
linux_send( const XP_U8* buf, XP_U16 buflen, const XP_UCHAR* msgNo,
|
linux_send( const XP_U8* buf, XP_U16 buflen, const XP_UCHAR* XP_UNUSED_DBG(msgNo),
|
||||||
const CommsAddrRec* addrRec, CommsConnType conType, XP_U32 gameID,
|
const CommsAddrRec* addrRec, CommsConnType conType, XP_U32 gameID,
|
||||||
void* closure )
|
void* closure )
|
||||||
{
|
{
|
||||||
|
|
|
@ -480,8 +480,9 @@ relayThread( void* arg )
|
||||||
while ( !storage->relayTaskList ) {
|
while ( !storage->relayTaskList ) {
|
||||||
pthread_cond_wait( &storage->relayCondVar, &storage->relayMutex );
|
pthread_cond_wait( &storage->relayCondVar, &storage->relayMutex );
|
||||||
}
|
}
|
||||||
|
#ifdef DEBUG
|
||||||
int len = g_slist_length( storage->relayTaskList );
|
int len = g_slist_length( storage->relayTaskList );
|
||||||
|
#endif
|
||||||
gchar* strs = listTasks( storage->relayTaskList );
|
gchar* strs = listTasks( storage->relayTaskList );
|
||||||
GSList* head = storage->relayTaskList;
|
GSList* head = storage->relayTaskList;
|
||||||
storage->relayTaskList = g_slist_remove_link( storage->relayTaskList,
|
storage->relayTaskList = g_slist_remove_link( storage->relayTaskList,
|
||||||
|
@ -740,12 +741,16 @@ relaycon_cleanup( LaunchParams* params )
|
||||||
RelayConStorage* storage = (RelayConStorage*)params->relayConStorage;
|
RelayConStorage* storage = (RelayConStorage*)params->relayConStorage;
|
||||||
if ( storage->params->useHTTP ) {
|
if ( storage->params->useHTTP ) {
|
||||||
pthread_mutex_lock( &storage->relayMutex );
|
pthread_mutex_lock( &storage->relayMutex );
|
||||||
|
#ifdef DEBUG
|
||||||
int nRelayTasks = g_slist_length( storage->relayTaskList );
|
int nRelayTasks = g_slist_length( storage->relayTaskList );
|
||||||
|
#endif
|
||||||
gchar* taskStrs = listTasks( storage->relayTaskList );
|
gchar* taskStrs = listTasks( storage->relayTaskList );
|
||||||
pthread_mutex_unlock( &storage->relayMutex );
|
pthread_mutex_unlock( &storage->relayMutex );
|
||||||
|
|
||||||
pthread_mutex_lock( &storage->gotDataMutex );
|
pthread_mutex_lock( &storage->gotDataMutex );
|
||||||
|
#ifdef DEBUG
|
||||||
int nDataTasks = g_slist_length( storage->gotDataTaskList );
|
int nDataTasks = g_slist_length( storage->gotDataTaskList );
|
||||||
|
#endif
|
||||||
gchar* gotStrs = listTasks( storage->gotDataTaskList );
|
gchar* gotStrs = listTasks( storage->gotDataTaskList );
|
||||||
pthread_mutex_unlock( &storage->gotDataMutex );
|
pthread_mutex_unlock( &storage->gotDataMutex );
|
||||||
|
|
||||||
|
@ -905,17 +910,16 @@ onGotQueryData( RelayTask* task )
|
||||||
if ( !!reply ) {
|
if ( !!reply ) {
|
||||||
CommsAddrRec addr = {0};
|
CommsAddrRec addr = {0};
|
||||||
addr_addType( &addr, COMMS_CONN_RELAY );
|
addr_addType( &addr, COMMS_CONN_RELAY );
|
||||||
|
#ifdef DEBUG
|
||||||
GList* ids = g_hash_table_get_keys( task->u.query.map );
|
GList* ids = g_hash_table_get_keys( task->u.query.map );
|
||||||
const char* xxx = ids->data;
|
#endif
|
||||||
|
|
||||||
json_object* jMsgs;
|
json_object* jMsgs;
|
||||||
if ( json_object_object_get_ex( reply, "msgs", &jMsgs ) ) {
|
if ( json_object_object_get_ex( reply, "msgs", &jMsgs ) ) {
|
||||||
/* Currently there's an array of arrays for each relayID (value) */
|
/* Currently there's an array of arrays for each relayID (value) */
|
||||||
XP_LOGF( "%s: got result of len %d", __func__, json_object_object_length(jMsgs) );
|
XP_LOGF( "%s: got result of len %d", __func__, json_object_object_length(jMsgs) );
|
||||||
XP_ASSERT( json_object_object_length(jMsgs) <= 1 );
|
XP_ASSERT( json_object_object_length(jMsgs) <= 1 );
|
||||||
json_object_object_foreach(jMsgs, relayID, arrOfArrOfMoves) {
|
json_object_object_foreach(jMsgs, relayID, arrOfArrOfMoves) {
|
||||||
XP_ASSERT( 0 == strcmp( relayID, xxx ) );
|
XP_ASSERT( 0 == strcmp( relayID, ids->data ) );
|
||||||
int len1 = json_object_array_length( arrOfArrOfMoves );
|
int len1 = json_object_array_length( arrOfArrOfMoves );
|
||||||
if ( len1 > 0 ) {
|
if ( len1 > 0 ) {
|
||||||
sqlite3_int64 rowid = *(sqlite3_int64*)g_hash_table_lookup( task->u.query.map, relayID );
|
sqlite3_int64 rowid = *(sqlite3_int64*)g_hash_table_lookup( task->u.query.map, relayID );
|
||||||
|
|
|
@ -220,7 +220,7 @@ CRefMgr::getMakeCookieRef( const char* cookie, int nPlayersH, int nPlayersT,
|
||||||
int langCode, int seed, int clientIndx,
|
int langCode, int seed, int clientIndx,
|
||||||
bool wantsPublic, bool makePublic, bool* seenSeed )
|
bool wantsPublic, bool makePublic, bool* seenSeed )
|
||||||
{
|
{
|
||||||
CidInfo* cinfo;
|
CidInfo* cinfo = NULL;
|
||||||
|
|
||||||
/* We have a cookie from a new connection or from a reconnect. This may
|
/* We have a cookie from a new connection or from a reconnect. This may
|
||||||
be the first time it's been seen, or there may be a game currently in
|
be the first time it's been seen, or there may be a game currently in
|
||||||
|
@ -229,8 +229,8 @@ CRefMgr::getMakeCookieRef( const char* cookie, int nPlayersH, int nPlayersT,
|
||||||
a new one. Pass the connName which will be used if set, but if not set
|
a new one. Pass the connName which will be used if set, but if not set
|
||||||
we'll be generating another later when the game is complete.
|
we'll be generating another later when the game is complete.
|
||||||
*/
|
*/
|
||||||
for ( ; ; ) {
|
for ( int ii = 0; ; ++ii ) {
|
||||||
/* What's this for loop thing. It's to fix a race condition. One
|
/* What's this for loop thing? It's to fix a race condition. One
|
||||||
thread has "claim" on cid <N>, which is in the DB. Another comes
|
thread has "claim" on cid <N>, which is in the DB. Another comes
|
||||||
into this function and looks it up in the DB, retrieving <N>, but
|
into this function and looks it up in the DB, retrieving <N>, but
|
||||||
progress is blocked inside getCookieRef_impl which calls Claim().
|
progress is blocked inside getCookieRef_impl which calls Claim().
|
||||||
|
@ -238,6 +238,13 @@ CRefMgr::getMakeCookieRef( const char* cookie, int nPlayersH, int nPlayersT,
|
||||||
cref before calling Relinquish so that when Claim() returns there's
|
cref before calling Relinquish so that when Claim() returns there's
|
||||||
no cref. So we test for that case and retry. */
|
no cref. So we test for that case and retry. */
|
||||||
|
|
||||||
|
/* I'm now seeing an infinte loop here. Until it's tracked down, let's
|
||||||
|
assert out. Note that I've seen it here, not at any of the other
|
||||||
|
places where I'm replacing FOREVER loops with this test*/
|
||||||
|
if ( ii > 5 ) {
|
||||||
|
assert(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
CookieID cid;
|
CookieID cid;
|
||||||
char connNameBuf[MAX_CONNNAME_LEN+1] = {0};
|
char connNameBuf[MAX_CONNNAME_LEN+1] = {0};
|
||||||
|
@ -295,7 +302,13 @@ CRefMgr::getMakeCookieRef( const char* connName, const char* cookie,
|
||||||
CookieRef* cref = NULL;
|
CookieRef* cref = NULL;
|
||||||
CidInfo* cinfo = NULL;
|
CidInfo* cinfo = NULL;
|
||||||
|
|
||||||
for ( ; ; ) { /* for: see comment above */
|
for ( int ii = 0; ; ++ii ) { /* for: see comment above */
|
||||||
|
|
||||||
|
if ( ii > 5 ) {
|
||||||
|
assert(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* fetch these from DB */
|
/* fetch these from DB */
|
||||||
char curCookie[MAX_INVITE_LEN+1];
|
char curCookie[MAX_INVITE_LEN+1];
|
||||||
int curLangCode;
|
int curLangCode;
|
||||||
|
@ -346,7 +359,12 @@ CRefMgr::getMakeCookieRef( const char* const connName, HostID hid, bool* isDead
|
||||||
int nPlayersT = 0;
|
int nPlayersT = 0;
|
||||||
int nAlreadyHere = 0;
|
int nAlreadyHere = 0;
|
||||||
|
|
||||||
for ( ; ; ) { /* for: see comment above */
|
for ( int ii = 0; ; ++ii ) { /* for: see comment above */
|
||||||
|
if ( ii > 5 ) {
|
||||||
|
assert(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
CookieID cid = m_db->FindGame( connName, hid, curCookie, sizeof(curCookie),
|
CookieID cid = m_db->FindGame( connName, hid, curCookie, sizeof(curCookie),
|
||||||
&curLangCode, &nPlayersT, &nAlreadyHere,
|
&curLangCode, &nPlayersT, &nAlreadyHere,
|
||||||
isDead );
|
isDead );
|
||||||
|
@ -385,7 +403,12 @@ CRefMgr::getMakeCookieRef( const AddrInfo::ClientToken clientToken, HostID srcID
|
||||||
int nPlayersT = 0;
|
int nPlayersT = 0;
|
||||||
int nAlreadyHere = 0;
|
int nAlreadyHere = 0;
|
||||||
|
|
||||||
for ( ; ; ) { /* for: see comment above */
|
for ( int ii = 0; ; ++ii ) { /* for: see comment above */
|
||||||
|
if ( ii > 5 ) {
|
||||||
|
assert(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
char connName[MAX_CONNNAME_LEN+1] = {0};
|
char connName[MAX_CONNNAME_LEN+1] = {0};
|
||||||
CookieID cid = m_db->FindGame( clientToken, srcID,
|
CookieID cid = m_db->FindGame( clientToken, srcID,
|
||||||
connName, sizeof(connName),
|
connName, sizeof(connName),
|
||||||
|
|
|
@ -691,12 +691,14 @@ send_msg_via_udp( const AddrInfo* addr, AddrInfo::ClientToken clientToken,
|
||||||
uint32_t asNetTok = htonl(clientToken);
|
uint32_t asNetTok = htonl(clientToken);
|
||||||
ssize_t nSent = send_via_udp( addr, packetIDP, XWPDEV_MSG, &asNetTok,
|
ssize_t nSent = send_via_udp( addr, packetIDP, XWPDEV_MSG, &asNetTok,
|
||||||
sizeof(asNetTok), buf, bufLen, NULL );
|
sizeof(asNetTok), buf, bufLen, NULL );
|
||||||
logf( XW_LOGINFO, "%s: sent %d bytes (plus header) on UDP socket, "
|
|
||||||
"token=%x(%d)", __func__, bufLen, clientToken,
|
|
||||||
clientToken );
|
|
||||||
result = 0 < nSent;
|
result = 0 < nSent;
|
||||||
logf( XW_LOGINFO, "%s()=>%d", __func__, result );
|
if (result) {
|
||||||
|
logf( XW_LOGINFO, "%s: sent %d bytes (plus header) on UDP socket, "
|
||||||
|
"token=%x(%d)", __func__, bufLen, clientToken,
|
||||||
|
clientToken );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
// logf( XW_LOGINFO, "%s()=>%d", __func__, result );
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1802,8 +1804,8 @@ handle_udp_packet( PacketThreadClosure* ptc )
|
||||||
handlePutMessage( scr, hid, &addr, end - ptr, &ptr, end );
|
handlePutMessage( scr, hid, &addr, end - ptr, &ptr, end );
|
||||||
assert( ptr == end ); // DON'T CHECK THIS IN!!!
|
assert( ptr == end ); // DON'T CHECK THIS IN!!!
|
||||||
} else {
|
} else {
|
||||||
logf( XW_LOGERROR, "%s: invalid scr for %s", __func__,
|
logf( XW_LOGERROR, "%s: invalid scr for %s/%d", __func__,
|
||||||
connName );
|
connName, hid );
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
logf( XW_LOGERROR, "no clientToken found!!!" );
|
logf( XW_LOGERROR, "no clientToken found!!!" );
|
||||||
|
|
Loading…
Reference in a new issue