Merge branch 'android_branch' into android_translate
|
@ -4,7 +4,7 @@ language: android
|
|||
jdk: oraclejdk8
|
||||
env:
|
||||
global:
|
||||
- ANDROID_TARGET=android-14
|
||||
- ANDROID_TARGET=android-28
|
||||
- ANDROID_ABI=armeabi-v7a,x86
|
||||
- secure: d8PwteM+xp1IRU3QkvmHtxh+1Ta9n/kl/SJ3EZa3iColVVXY1etzjY3cKrEGKKMJuI4be30kPzvNw9/BVTawDpnU9/NtWqykJ8QHXNWnZIvUQ/kxHBS1DbcstmcYU9gvR83EFb8BT+Y9frpNfMcZDlSvBpEGqDQEPmxiDzSmjdUmJJQWStncxL9pE+lCdM6lHBgtfYoMMiqCQF/DxkQisjyUVF4mbTGuT9JOOWjVsTGPA7ehzsWDHoJ3p2ai8UKHAYucUWZcTt4rkq9l35ExvgKd3L8luk8U3X3Fk9yzVhPJC56T0XNbNrsQ2W7/7oGRv6EQFV3aKDZimJ7CVjBcEjZmPxeUVvCsMW8XB41ZvYcy6xsjF96oyjn1gb0r/2mZbTaWP0izSTwMYZ5vFNKUamDtRZgrneD0lfvXgfTzirrCU7FqO2RH7ZK5PQpSgSoZxKsKyeyFPEa2ihivc95rz1MS6mamle9wrIlSAgEGcaZMIYvKiOnCLk7CZCKuwm2dhYPgzCHW3PUopay59BBwMsSqWpxsiHEr5jYGpb0pHGbzPTJNUpg1LNQX5eMQOMlEt7rfpoC7JG24hR9vxl4Yf9LhxYlSwUiPy7TYHdbA0kUS68skfzxU6+ekWZF2QFM+L4vWCYmEHDy7n+I0df+PavycgNW989ROlAKhQjtMyqM=
|
||||
android:
|
||||
|
|
|
@ -164,7 +164,7 @@ public class BoardCanvas extends Canvas implements DrawCtx {
|
|||
m_strokePaint = new Paint();
|
||||
m_strokePaint.setStyle( Paint.Style.STROKE );
|
||||
|
||||
m_origin = res.getDrawable( R.drawable.origin );
|
||||
m_origin = res.getDrawable( R.drawable.ic_origin );
|
||||
|
||||
m_prefs = CommonPrefs.get( m_context );
|
||||
m_playerColors = m_prefs.playerColors;
|
||||
|
@ -487,12 +487,12 @@ public class BoardCanvas extends Canvas implements DrawCtx {
|
|||
Drawable arrow;
|
||||
if ( vert ) {
|
||||
if ( null == m_downArrow ) {
|
||||
m_downArrow = loadAndRecolor( R.drawable.downarrow, useDark );
|
||||
m_downArrow = loadAndRecolor( R.drawable.ic_downarrow, useDark );
|
||||
}
|
||||
arrow = m_downArrow;
|
||||
} else {
|
||||
if ( null == m_rightArrow ) {
|
||||
m_rightArrow = loadAndRecolor( R.drawable.rightarrow, useDark );
|
||||
m_rightArrow = loadAndRecolor( R.drawable.ic_rightarrow, useDark );
|
||||
}
|
||||
arrow = m_rightArrow;
|
||||
}
|
||||
|
|
|
@ -1147,7 +1147,7 @@ public class BoardDelegate extends DelegateBase
|
|||
launchLookup( m_mySIS.words, m_gi.dictLang );
|
||||
break;
|
||||
case DROP_RELAY_ACTION:
|
||||
dropConViaAndRestart(CommsConnType.COMMS_CONN_RELAY);
|
||||
dropConViaAndRestart( CommsConnType.COMMS_CONN_RELAY );
|
||||
break;
|
||||
case DELETE_AND_EXIT:
|
||||
deleteAndClose( m_gi.gameID );
|
||||
|
@ -1241,7 +1241,7 @@ public class BoardDelegate extends DelegateBase
|
|||
m_dropRelayOnDismiss = true;
|
||||
break;
|
||||
case DROP_SMS_ACTION:
|
||||
dropConViaAndRestart(CommsConnType.COMMS_CONN_SMS);
|
||||
dropConViaAndRestart( CommsConnType.COMMS_CONN_SMS );
|
||||
break;
|
||||
case DELETE_AND_EXIT:
|
||||
finish();
|
||||
|
@ -1666,10 +1666,7 @@ public class BoardDelegate extends DelegateBase
|
|||
|
||||
private void dropConViaAndRestart( CommsConnType typ )
|
||||
{
|
||||
CommsAddrRec addr = new CommsAddrRec();
|
||||
XwJNI.comms_getAddr( m_jniGamePtr, addr );
|
||||
addr.remove( typ );
|
||||
XwJNI.comms_setAddr( m_jniGamePtr, addr );
|
||||
XwJNI.comms_dropHostAddr( m_jniGamePtr, typ );
|
||||
|
||||
finish();
|
||||
|
||||
|
|
|
@ -472,7 +472,7 @@ public class ConnStatusHandler {
|
|||
Assert.assertTrue( !BuildConfig.DEBUG
|
||||
|| 1 >= Math.abs(scratchR.width()
|
||||
- scratchR.height()) );
|
||||
drawIn( canvas, res, R.drawable.multigame__gen, scratchR );
|
||||
drawIn( canvas, res, R.drawable.ic_multigame, scratchR );
|
||||
|
||||
if ( 0 < s_moveCount && XWPrefs.moveCountEnabled( context ) ) {
|
||||
String str = String.format( "%d", s_moveCount );
|
||||
|
@ -499,7 +499,7 @@ public class ConnStatusHandler {
|
|||
{
|
||||
boolean showSuccesses = s_showSuccesses[isIn? SUCCESS_IN : SUCCESS_OUT];
|
||||
int color = showSuccesses ? ORANGE : Color.WHITE;
|
||||
int arrowID = isIn ? R.drawable.in_arrow__gen : R.drawable.out_arrow__gen;
|
||||
int arrowID = isIn ? R.drawable.ic_in_arrow : R.drawable.ic_out_arrow;
|
||||
drawIn( canvas, res, arrowID, rect, color );
|
||||
}
|
||||
|
||||
|
|
|
@ -324,7 +324,7 @@ public class GameListItem extends LinearLayout
|
|||
m_modTime.setText( df.format( new Date( lastMoveTime ) ) );
|
||||
|
||||
int iconID = summary.isMultiGame() ?
|
||||
R.drawable.multigame__gen : R.drawable.sologame__gen;
|
||||
R.drawable.ic_multigame : R.drawable.ic_sologame;
|
||||
m_gameTypeImage.setImageResource( iconID );
|
||||
|
||||
boolean hasChat = summary.isMultiGame();
|
||||
|
|
|
@ -153,7 +153,7 @@ public class GameUtils {
|
|||
}
|
||||
|
||||
if ( null != addr ) {
|
||||
XwJNI.comms_setAddr( gamePtr, addr );
|
||||
XwJNI.comms_augmentHostAddr( gamePtr, addr );
|
||||
}
|
||||
|
||||
if ( null == lockDest ) {
|
||||
|
@ -1183,7 +1183,7 @@ public class GameUtils {
|
|||
GameLock lock, GamePtr gamePtr )
|
||||
{
|
||||
if ( null != car ) {
|
||||
XwJNI.comms_setAddr( gamePtr, car );
|
||||
XwJNI.comms_augmentHostAddr( gamePtr, car );
|
||||
}
|
||||
|
||||
if ( BuildConfig.DEBUG && null != disab ) {
|
||||
|
|
|
@ -869,7 +869,7 @@ public class GamesListDelegate extends ListDelegateBase
|
|||
|
||||
boolean canDoDefaults = solo ||
|
||||
0 < XWPrefs.getAddrTypes( m_activity ).size();
|
||||
int iconResID = solo ? R.drawable.sologame__gen : R.drawable.multigame__gen;
|
||||
int iconResID = solo ? R.drawable.ic_sologame : R.drawable.ic_multigame;
|
||||
int titleID = solo ? R.string.new_game : R.string.new_game_networked;
|
||||
|
||||
String msg = getString( canDoDefaults ? R.string.new_game_message
|
||||
|
@ -908,13 +908,13 @@ public class GamesListDelegate extends ListDelegateBase
|
|||
case GAMES_LIST_NAME_REMATCH: {
|
||||
final LinearLayout view = (LinearLayout)
|
||||
LocUtils.inflate( m_activity, R.layout.msg_label_and_edit );
|
||||
int iconResID = R.drawable.sologame__gen;
|
||||
int iconResID = R.drawable.ic_sologame;
|
||||
if ( null != m_rematchExtras ) {
|
||||
EditWClear edit = (EditWClear)view.findViewById( R.id.edit );
|
||||
edit.setText( m_rematchExtras.getString( REMATCH_NEWNAME_EXTRA ));
|
||||
boolean solo = m_rematchExtras.getBoolean( REMATCH_IS_SOLO, true );
|
||||
if ( !solo ) {
|
||||
iconResID = R.drawable.multigame__gen;
|
||||
iconResID = R.drawable.ic_multigame;
|
||||
}
|
||||
view.findViewById( R.id.msg ).setVisibility( View.GONE );
|
||||
}
|
||||
|
|
|
@ -297,7 +297,8 @@ public class NFCUtils {
|
|||
result = msgs.toArray( new byte[msgs.size()][] );
|
||||
}
|
||||
}
|
||||
Log.d( TAG, "getMsgsFor() => %d msgs", result == null ? 0 : result.length );
|
||||
Log.d( TAG, "getMsgsFor(gameID=%d) => %d msgs", gameID,
|
||||
result == null ? 0 : result.length );
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -409,7 +409,8 @@ public class XwJNI {
|
|||
public static native void comms_resetSame( GamePtr gamePtr );
|
||||
public static native void comms_getAddr( GamePtr gamePtr, CommsAddrRec addr );
|
||||
public static native CommsAddrRec[] comms_getAddrs( GamePtr gamePtr );
|
||||
public static native void comms_setAddr( GamePtr gamePtr, CommsAddrRec addr );
|
||||
public static native void comms_augmentHostAddr( GamePtr gamePtr, CommsAddrRec addr );
|
||||
public static native void comms_dropHostAddr( GamePtr gamePtr, CommsConnType typ );
|
||||
public static native int comms_resendAll( GamePtr gamePtr, boolean force,
|
||||
CommsConnType filter,
|
||||
boolean andAck );
|
||||
|
|
Before Width: | Height: | Size: 141 B |
15
xwords4/android/app/src/main/res/drawable/ic_downarrow.xml
Normal file
|
@ -0,0 +1,15 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="200dp"
|
||||
android:height="200dp"
|
||||
android:viewportWidth="200"
|
||||
android:viewportHeight="200">
|
||||
<path
|
||||
android:pathData="m63.5,14.792 l74.083,0L137.583,104.75L190.5,104.75L100.542,194.708 10.583,104.75L63.5,104.75Z"
|
||||
android:strokeAlpha="1"
|
||||
android:strokeLineJoin="miter"
|
||||
android:strokeWidth="0.26458332"
|
||||
android:fillColor="#000000"
|
||||
android:strokeColor="#000000"
|
||||
android:fillAlpha="1"
|
||||
android:strokeLineCap="butt"/>
|
||||
</vector>
|
23
xwords4/android/app/src/main/res/drawable/ic_in_arrow.xml
Normal file
|
@ -0,0 +1,23 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="195.92358dp"
|
||||
android:height="79.11178dp"
|
||||
android:viewportWidth="195.92358"
|
||||
android:viewportHeight="79.11178">
|
||||
<path
|
||||
android:pathData="M10.958,11.225L187.089,11.225v24.856l-124.013,0.267 0.267,33.141z"
|
||||
android:strokeAlpha="1"
|
||||
android:strokeLineJoin="miter"
|
||||
android:strokeWidth="0.26458332"
|
||||
android:fillColor="#ffffff"
|
||||
android:strokeColor="#000000"
|
||||
android:fillAlpha="1"
|
||||
android:strokeLineCap="butt"/>
|
||||
<path
|
||||
android:pathData="M55.592,38.754Z"
|
||||
android:strokeAlpha="1"
|
||||
android:strokeLineJoin="miter"
|
||||
android:strokeWidth="0.26458332"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#000000"
|
||||
android:strokeLineCap="butt"/>
|
||||
</vector>
|
22
xwords4/android/app/src/main/res/drawable/ic_multigame.xml
Normal file
|
@ -0,0 +1,22 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="120dp"
|
||||
android:height="120dp"
|
||||
android:viewportWidth="120"
|
||||
android:viewportHeight="120">
|
||||
<path
|
||||
android:pathData="m94.003,53.556c-1.138,-0.181 -1.164,-3.31 -1.164,-3.31 0,0 3.343,-3.31 4.072,-7.761 1.96,0 3.171,-4.732 1.211,-6.397 0.082,-1.753 2.52,-13.757 -9.822,-13.757 -12.342,0 -9.904,12.005 -9.822,13.757 -1.96,1.665 -0.75,6.397 1.211,6.397 0.729,4.451 4.072,7.761 4.072,7.761 0,0 -0.026,3.129 -1.164,3.31 -3.665,0.583 -17.352,6.62 -17.352,13.24H88.299,111.355c0,-6.62 -13.687,-12.656 -17.352,-13.24z"
|
||||
android:fillColor="#ffffff"
|
||||
android:fillAlpha="1"/>
|
||||
<path
|
||||
android:pathData="M112.01,-0L64.979,-0C61.061,-0 57.854,2.835 57.854,6.305L57.854,87.036c0,3.47 3.207,6.307 7.125,6.307h47.031c3.918,0 7.125,-2.835 7.125,-6.305L119.135,6.305c0,-3.47 -3.207,-6.305 -7.125,-6.305zM80.972,4.545h15.046c0.476,0 0.862,0.341 0.862,0.765 0,0.421 -0.386,0.763 -0.862,0.763L80.972,6.073c-0.476,0 -0.862,-0.341 -0.862,-0.763 0,-0.424 0.386,-0.765 0.862,-0.765zM88.495,90.191c-1.968,0 -3.563,-1.411 -3.563,-3.152 0,-1.742 1.594,-3.152 3.563,-3.152 1.968,0 3.563,1.411 3.563,3.152 0,1.742 -1.594,3.152 -3.563,3.152zM114.177,81.676L62.812,81.676L62.812,9.998L114.177,9.998L114.177,81.676z"
|
||||
android:fillColor="#ffffff"
|
||||
android:fillAlpha="1"/>
|
||||
<path
|
||||
android:pathData="m36.8,78.821c-1.138,-0.181 -1.164,-3.31 -1.164,-3.31 0,0 3.343,-3.31 4.072,-7.761 1.96,0 3.171,-4.732 1.211,-6.397 0.082,-1.753 2.52,-13.757 -9.822,-13.757 -12.342,0 -9.904,12.005 -9.822,13.757 -1.96,1.665 -0.75,6.397 1.211,6.397 0.729,4.451 4.072,7.761 4.072,7.761 0,0 -0.026,3.129 -1.164,3.31C21.728,79.404 8.041,85.441 8.041,92.061H31.096,54.152c0,-6.62 -13.687,-12.656 -17.352,-13.24z"
|
||||
android:fillColor="#ffffff"
|
||||
android:fillAlpha="1"/>
|
||||
<path
|
||||
android:pathData="M54.807,25.266L7.776,25.266c-3.918,0 -7.125,2.835 -7.125,6.305v80.732c0,3.47 3.207,6.307 7.125,6.307L54.807,118.609c3.918,0 7.125,-2.835 7.125,-6.305L61.932,31.57c0,-3.47 -3.207,-6.305 -7.125,-6.305zM23.769,29.81h15.046c0.476,0 0.862,0.341 0.862,0.765 0,0.421 -0.386,0.763 -0.862,0.763L23.769,31.338c-0.476,0 -0.862,-0.341 -0.862,-0.763 0,-0.424 0.386,-0.765 0.862,-0.765zM31.292,115.457c-1.968,0 -3.563,-1.411 -3.563,-3.152 0,-1.742 1.594,-3.152 3.563,-3.152 1.968,0 3.563,1.411 3.563,3.152 0,1.742 -1.594,3.152 -3.563,3.152zM56.974,106.941L5.609,106.941L5.609,35.264L56.974,35.264v71.677z"
|
||||
android:fillColor="#ffffff"
|
||||
android:fillAlpha="1"/>
|
||||
</vector>
|
22
xwords4/android/app/src/main/res/drawable/ic_origin.xml
Normal file
|
@ -0,0 +1,22 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="200dp"
|
||||
android:height="200dp"
|
||||
android:viewportWidth="200"
|
||||
android:viewportHeight="200">
|
||||
<path
|
||||
android:pathData="M24.342,25.375 L177.8,173.542v0"
|
||||
android:strokeAlpha="1"
|
||||
android:strokeLineJoin="miter"
|
||||
android:strokeWidth="20.95265579"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#000000"
|
||||
android:strokeLineCap="butt"/>
|
||||
<path
|
||||
android:pathData="M177.8,25.375 L24.342,173.542v0"
|
||||
android:strokeAlpha="1"
|
||||
android:strokeLineJoin="miter"
|
||||
android:strokeWidth="20.95265579"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#000000"
|
||||
android:strokeLineCap="butt"/>
|
||||
</vector>
|
23
xwords4/android/app/src/main/res/drawable/ic_out_arrow.xml
Normal file
|
@ -0,0 +1,23 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="195.92358dp"
|
||||
android:height="79.11178dp"
|
||||
android:viewportWidth="195.92358"
|
||||
android:viewportHeight="79.11178">
|
||||
<path
|
||||
android:pathData="M187.089,69.49L10.958,69.49L10.958,44.634L134.971,44.367 134.704,11.225Z"
|
||||
android:strokeAlpha="1"
|
||||
android:strokeLineJoin="miter"
|
||||
android:strokeWidth="0.26458332"
|
||||
android:fillColor="#ffffff"
|
||||
android:strokeColor="#000000"
|
||||
android:fillAlpha="1"
|
||||
android:strokeLineCap="butt"/>
|
||||
<path
|
||||
android:pathData="M55.592,38.754Z"
|
||||
android:strokeAlpha="1"
|
||||
android:strokeLineJoin="miter"
|
||||
android:strokeWidth="0.26458332"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#000000"
|
||||
android:strokeLineCap="butt"/>
|
||||
</vector>
|
15
xwords4/android/app/src/main/res/drawable/ic_rightarrow.xml
Normal file
|
@ -0,0 +1,15 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="200dp"
|
||||
android:height="200dp"
|
||||
android:viewportWidth="200"
|
||||
android:viewportHeight="200">
|
||||
<path
|
||||
android:pathData="M10.583,141.792L10.583,67.708L100.542,67.708L100.542,14.792L190.5,104.75 100.542,194.708v-52.917z"
|
||||
android:strokeAlpha="1"
|
||||
android:strokeLineJoin="miter"
|
||||
android:strokeWidth="0.26458332"
|
||||
android:fillColor="#000000"
|
||||
android:strokeColor="#000000"
|
||||
android:fillAlpha="1"
|
||||
android:strokeLineCap="butt"/>
|
||||
</vector>
|
18
xwords4/android/app/src/main/res/drawable/ic_sologame.xml
Normal file
|
@ -0,0 +1,18 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="120dp"
|
||||
android:height="120dp"
|
||||
android:viewportWidth="120"
|
||||
android:viewportHeight="120">
|
||||
<path
|
||||
android:pathData="m50.973,60.401c7.206,0 21.618,0 21.618,0m-5.688,-7c0,0 -4.813,-4.284 -10.583,-5.414 -1.06,-0.208 -1.091,-3.104 -1.091,-3.104 0,0 3.135,-3.104 3.818,-7.277 1.838,0 2.973,-4.437 1.135,-5.998 0.077,-1.643 2.363,-12.9 -9.21,-12.9 -11.573,0 -9.287,11.257 -9.21,12.9 -1.838,1.561 -0.703,5.998 1.135,5.998 0.683,4.173 3.818,7.277 3.818,7.277 0,0 -0.024,2.934 -1.091,3.104 -3.437,0.547 -16.27,6.207 -16.27,12.414l26.868,0c1.519,-5.688 6.1,-7.438 10.681,-7z"
|
||||
android:fillColor="#ffffff"
|
||||
android:fillAlpha="1"/>
|
||||
<path
|
||||
android:pathData="M89.475,-0H29.014C23.977,-0 19.854,3.645 19.854,8.105V111.891c0,4.461 4.123,8.109 9.16,8.109h60.461c5.037,0 9.16,-3.645 9.16,-8.105V8.105C98.635,3.645 94.512,-0 89.475,-0zM49.573,5.842h19.343c0.612,0 1.108,0.439 1.108,0.984 0,0.542 -0.496,0.981 -1.108,0.981H49.573c-0.612,0 -1.108,-0.439 -1.108,-0.981 0,-0.545 0.496,-0.984 1.108,-0.984zM59.245,115.947c-2.53,0 -4.58,-1.814 -4.58,-4.053 0,-2.239 2.05,-4.053 4.58,-4.053 2.53,0 4.58,1.814 4.58,4.053 0,2.239 -2.05,4.053 -4.58,4.053zM92.261,105H26.228V12.854H92.261V105z"
|
||||
android:fillColor="#ffffff"
|
||||
android:fillAlpha="1"/>
|
||||
<path
|
||||
android:pathData="m72.748,85.793c-1.142,-0.182 -1.168,-3.321 -1.168,-3.321 0,0 3.354,-3.321 4.085,-7.786 1.967,0 3.181,-4.747 1.214,-6.418 0.082,-1.758 2.528,-13.802 -9.854,-13.802 -12.382,0 -9.936,12.044 -9.855,13.802 -1.967,1.67 -0.752,6.418 1.214,6.418 0.731,4.465 4.085,7.786 4.085,7.786 0,0 -0.026,3.139 -1.168,3.321 -3.677,0.585 -17.409,6.642 -17.409,13.283h23.131,23.131c0,-6.641 -13.731,-12.698 -17.409,-13.283z"
|
||||
android:fillColor="#ffffff"
|
||||
android:fillAlpha="1"/>
|
||||
</vector>
|
Before Width: | Height: | Size: 152 B |
Before Width: | Height: | Size: 147 B |
|
@ -41,7 +41,7 @@
|
|||
<ImageView android:id="@+id/game_type_marker"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:src="@drawable/multigame__gen"
|
||||
android:src="@drawable/ic_multigame"
|
||||
/>
|
||||
<ImageView android:id="@+id/has_chat_marker"
|
||||
android:layout_width="wrap_content"
|
||||
|
|
|
@ -90,12 +90,10 @@
|
|||
<!-- Group items -->
|
||||
<item android:id="@+id/games_group_moveup"
|
||||
android:title="@string/list_group_moveup"
|
||||
android:icon="@drawable/up__gen"
|
||||
android:showAsAction="ifRoom"
|
||||
/>
|
||||
<item android:id="@+id/games_group_movedown"
|
||||
android:title="@string/list_group_movedown"
|
||||
android:icon="@drawable/down__gen"
|
||||
android:showAsAction="ifRoom"
|
||||
/>
|
||||
<item android:id="@+id/games_group_delete"
|
||||
|
|
|
@ -2394,11 +2394,11 @@
|
|||
<string name="summary_enable_stallnotify">Notify when Android\'s
|
||||
slow to process outgoing invitations and moves</string>
|
||||
<string name="notify_stall_title">Message sending is stalled</string>
|
||||
<string name="notify_stall_body_fmt">Could not send outbound messages for %1$d seconds.
|
||||
<string name="notify_stall_body_fmt">%1$s could not send outbound messages for %2$d seconds.
|
||||
\n
|
||||
\nIf it happens again, e-mail the developer logs and info about your device.
|
||||
\n
|
||||
\nThis message will be seen at most once every %2$d minutes.</string>
|
||||
\nThis message will be seen at most once every %3$d minutes.</string>
|
||||
|
||||
<string name="sms_banned_ok_only">The Google Play version of CrossWords no longer supports invitations or play via data SMS.</string>
|
||||
<string name="button_more_info">Read more</string>
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
width="120"
|
||||
height="120"
|
||||
xml:space="preserve"
|
||||
id="svg2"
|
||||
inkscape:version="0.48.3.1 r9886"
|
||||
sodipodi:docname="down.svg"><metadata
|
||||
id="metadata11"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs9" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="640"
|
||||
inkscape:window-height="480"
|
||||
id="namedview7"
|
||||
showgrid="false"
|
||||
inkscape:zoom="1.9666667"
|
||||
inkscape:cx="60"
|
||||
inkscape:cy="60"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="24"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="svg2" />
|
||||
<g
|
||||
id="g12"
|
||||
transform="matrix(1.25,0,0,-1.25,0,120)">
|
||||
<g
|
||||
transform="translate(47.72,32.35)"
|
||||
id="g676">
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m -1.163978,-15.143535 -23.537465,32.092623 14.683237,0 0,29.964616 17.5617961,0 0,-29.964616 14.8298969,0 z"
|
||||
id="path678"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccccc" />
|
||||
</g></g>
|
||||
</svg>
|
Before Width: | Height: | Size: 1.7 KiB |
67
xwords4/android/img_src/downarrow.svg
Normal file
|
@ -0,0 +1,67 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="200mm"
|
||||
height="200mm"
|
||||
viewBox="0 0 200 200"
|
||||
version="1.1"
|
||||
id="svg1593"
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)"
|
||||
sodipodi:docname="downarrow.svg">
|
||||
<defs
|
||||
id="defs1587" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.7"
|
||||
inkscape:cx="-180"
|
||||
inkscape:cy="560"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1016"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid6508" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata1590">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-97)">
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 63.5,111.79167 74.08333,0 V 201.75 H 190.5 L 100.54167,291.70833 10.583333,201.75 H 63.5 Z"
|
||||
id="path7105"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccccc" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2 KiB |
|
@ -26,7 +26,7 @@
|
|||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.9899495"
|
||||
inkscape:cx="266.75131"
|
||||
inkscape:cx="-143.37062"
|
||||
inkscape:cy="51.719447"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
|
@ -54,16 +54,15 @@
|
|||
id="layer1"
|
||||
transform="translate(-6.7984033,-83.405656)">
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.24818733px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M 191.75867,98.253193 H 18.036751 l 0.250672,23.805047 49.181436,31.70363 -3.87143,-30.38207 128.420741,3.3716 z"
|
||||
id="path3898"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M 17.756454,94.630975 H 193.88707 v 24.856065 l -124.013059,0.26726 0.267269,33.14143 z"
|
||||
id="path113"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccccc" />
|
||||
sodipodi:nodetypes="cccccc" />
|
||||
<path
|
||||
style="stroke-width:0.42193675"
|
||||
d="m 191.88842,112.50226 0.12975,14.24913 -14.71489,-0.19817 c -21.90426,-0.29498 -90.295127,-0.92186 -100.512257,-0.9213 l -8.900147,5.7e-4 v 14.06469 c 0,7.95668 -0.183273,14.06469 -0.422017,14.06469 -0.232125,0 -11.392904,-7.13332 -24.801736,-15.85181 l -24.3797,-15.85182 -0.125341,-11.90249 -0.125331,-11.902557 h 86.860959 86.86096 z"
|
||||
id="path3900"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccsccssscccccc" />
|
||||
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M 62.390464,122.15973 Z"
|
||||
id="path136"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</svg>
|
||||
|
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.2 KiB |
|
@ -17,7 +17,7 @@
|
|||
height="120"
|
||||
viewBox="0 0 120 120"
|
||||
xml:space="preserve"
|
||||
inkscape:version="0.48.4 r9939"
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)"
|
||||
sodipodi:docname="multigame.svg"><metadata
|
||||
id="metadata3234"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
|
@ -32,14 +32,14 @@
|
|||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1453"
|
||||
inkscape:window-height="1057"
|
||||
inkscape:window-height="1016"
|
||||
id="namedview3230"
|
||||
showgrid="false"
|
||||
inkscape:zoom="6.8571429"
|
||||
inkscape:cx="40.031592"
|
||||
inkscape:cx="10.427426"
|
||||
inkscape:cy="59.0625"
|
||||
inkscape:window-x="1850"
|
||||
inkscape:window-y="28"
|
||||
inkscape:window-x="467"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="Capa_1"
|
||||
showborder="true"
|
||||
|
@ -49,193 +49,287 @@
|
|||
fit-margin-bottom="0" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 94.002662,53.555566 c -1.137946,-0.181047 -1.163883,-3.309782 -1.163883,-3.309782 0,0 3.343439,-3.309884 4.072153,-7.760699 1.960218,0 3.171038,-4.731803 1.210508,-6.396627 0.08192,-1.752516 2.51972,-13.757253 -9.822199,-13.757253 -12.341922,0 -9.904024,12.004737 -9.822404,13.757253 -1.960427,1.664824 -0.749814,6.396627 1.210509,6.396627 0.728611,4.450814 4.072152,7.760699 4.072152,7.760699 0,0 -0.02593,3.128735 -1.163781,3.309782 -3.665184,0.583177 -17.35183,6.619871 -17.35183,13.239538 H 88.29924 111.3546 c 0,-6.619667 -13.686651,-12.656361 -17.351938,-13.239538 z"
|
||||
id="path4374" /><path
|
||||
id="path4374"
|
||||
style="fill:#ffffff;fill-opacity:1" /><path
|
||||
d="M 112.00996,-2.3030773e-7 H 64.979295 C 61.061077,-2.3030773e-7 57.854167,2.8349848 57.854167,6.3047069 V 87.036428 c 0,3.469722 3.20691,6.307373 7.125128,6.307373 h 47.030665 c 3.91822,0 7.12513,-2.834983 7.12513,-6.304704 V 6.3047069 c 0,-3.4697221 -3.20691,-6.30470713030773 -7.12513,-6.30470713030773 z M 80.971652,4.5445097 h 15.045956 c 0.476213,0 0.862005,0.3413722 0.862005,0.7654191 0,0.4213804 -0.385792,0.7627527 -0.862005,0.7627527 H 80.971652 c -0.476215,0 -0.862009,-0.3413723 -0.862009,-0.7627527 0,-0.4240469 0.385794,-0.7654191 0.862009,-0.7654191 z m 7.522977,85.6469393 c -1.968151,0 -3.562564,-1.410829 -3.562564,-3.152352 0,-1.741531 1.594413,-3.152353 3.562564,-3.152353 1.96815,0 3.562565,1.410822 3.562565,3.152353 0,1.741523 -1.594415,3.152352 -3.562565,3.152352 z M 114.17704,81.675826 H 62.812219 V 9.9984551 H 114.17704 V 81.675826 z"
|
||||
id="path3198"
|
||||
inkscape:connector-curvature="0" /><g
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
id="g3200"
|
||||
transform="matrix(3.0140138,0,0,2.6669657,1.854167,-5.1159404e-8)" /><g
|
||||
transform="matrix(3.0140138,0,0,2.6669657,1.854167,-5.1159404e-8)"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
id="g3202"
|
||||
transform="matrix(3.0140138,0,0,2.6669657,1.854167,-5.1159404e-8)" /><g
|
||||
transform="matrix(3.0140138,0,0,2.6669657,1.854167,-5.1159404e-8)"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
id="g3204"
|
||||
transform="matrix(3.0140138,0,0,2.6669657,1.854167,-5.1159404e-8)" /><g
|
||||
transform="matrix(3.0140138,0,0,2.6669657,1.854167,-5.1159404e-8)"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
id="g3206"
|
||||
transform="matrix(3.0140138,0,0,2.6669657,1.854167,-5.1159404e-8)" /><g
|
||||
transform="matrix(3.0140138,0,0,2.6669657,1.854167,-5.1159404e-8)"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
id="g3208"
|
||||
transform="matrix(3.0140138,0,0,2.6669657,1.854167,-5.1159404e-8)" /><g
|
||||
transform="matrix(3.0140138,0,0,2.6669657,1.854167,-5.1159404e-8)"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
id="g3210"
|
||||
transform="matrix(3.0140138,0,0,2.6669657,1.854167,-5.1159404e-8)" /><g
|
||||
transform="matrix(3.0140138,0,0,2.6669657,1.854167,-5.1159404e-8)"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
id="g3212"
|
||||
transform="matrix(3.0140138,0,0,2.6669657,1.854167,-5.1159404e-8)" /><g
|
||||
transform="matrix(3.0140138,0,0,2.6669657,1.854167,-5.1159404e-8)"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
id="g3214"
|
||||
transform="matrix(3.0140138,0,0,2.6669657,1.854167,-5.1159404e-8)" /><g
|
||||
transform="matrix(3.0140138,0,0,2.6669657,1.854167,-5.1159404e-8)"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
id="g3216"
|
||||
transform="matrix(3.0140138,0,0,2.6669657,1.854167,-5.1159404e-8)" /><g
|
||||
transform="matrix(3.0140138,0,0,2.6669657,1.854167,-5.1159404e-8)"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
id="g3218"
|
||||
transform="matrix(3.0140138,0,0,2.6669657,1.854167,-5.1159404e-8)" /><g
|
||||
transform="matrix(3.0140138,0,0,2.6669657,1.854167,-5.1159404e-8)"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
id="g3220"
|
||||
transform="matrix(3.0140138,0,0,2.6669657,1.854167,-5.1159404e-8)" /><g
|
||||
transform="matrix(3.0140138,0,0,2.6669657,1.854167,-5.1159404e-8)"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
id="g3222"
|
||||
transform="matrix(3.0140138,0,0,2.6669657,1.854167,-5.1159404e-8)" /><g
|
||||
transform="matrix(3.0140138,0,0,2.6669657,1.854167,-5.1159404e-8)"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
id="g3224"
|
||||
transform="matrix(3.0140138,0,0,2.6669657,1.854167,-5.1159404e-8)" /><g
|
||||
transform="matrix(3.0140138,0,0,2.6669657,1.854167,-5.1159404e-8)"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
id="g3226"
|
||||
transform="matrix(3.0140138,0,0,2.6669657,1.854167,-5.1159404e-8)" /><g
|
||||
transform="matrix(3.0140138,0,0,2.6669657,1.854167,-5.1159404e-8)"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
id="g3228"
|
||||
transform="matrix(3.0140138,0,0,2.6669657,1.854167,-5.1159404e-8)" /><g
|
||||
transform="matrix(3.0140138,0,0,2.6669657,1.854167,-5.1159404e-8)"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,9.4449192,20.45164)"
|
||||
id="g3316" /><g
|
||||
id="g3316"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,9.4449192,20.45164)"
|
||||
id="g3318" /><g
|
||||
id="g3318"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,9.4449192,20.45164)"
|
||||
id="g3320" /><g
|
||||
id="g3320"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,9.4449192,20.45164)"
|
||||
id="g3322" /><g
|
||||
id="g3322"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,9.4449192,20.45164)"
|
||||
id="g3324" /><g
|
||||
id="g3324"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,9.4449192,20.45164)"
|
||||
id="g3326" /><g
|
||||
id="g3326"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,9.4449192,20.45164)"
|
||||
id="g3328" /><g
|
||||
id="g3328"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,9.4449192,20.45164)"
|
||||
id="g3330" /><g
|
||||
id="g3330"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,9.4449192,20.45164)"
|
||||
id="g3332" /><g
|
||||
id="g3332"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,9.4449192,20.45164)"
|
||||
id="g3334" /><g
|
||||
id="g3334"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,9.4449192,20.45164)"
|
||||
id="g3336" /><g
|
||||
id="g3336"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,9.4449192,20.45164)"
|
||||
id="g3338" /><g
|
||||
id="g3338"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,9.4449192,20.45164)"
|
||||
id="g3340" /><g
|
||||
id="g3340"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,9.4449192,20.45164)"
|
||||
id="g3342" /><g
|
||||
id="g3342"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,9.4449192,20.45164)"
|
||||
id="g3344" /><g
|
||||
id="g3344"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,32.657275,24.227219)"
|
||||
id="g3316-8" /><g
|
||||
id="g3316-8"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,32.657275,24.227219)"
|
||||
id="g3318-8" /><g
|
||||
id="g3318-8"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,32.657275,24.227219)"
|
||||
id="g3320-6" /><g
|
||||
id="g3320-6"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,32.657275,24.227219)"
|
||||
id="g3322-3" /><g
|
||||
id="g3322-3"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,32.657275,24.227219)"
|
||||
id="g3324-3" /><g
|
||||
id="g3324-3"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,32.657275,24.227219)"
|
||||
id="g3326-2" /><g
|
||||
id="g3326-2"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,32.657275,24.227219)"
|
||||
id="g3328-4" /><g
|
||||
id="g3328-4"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,32.657275,24.227219)"
|
||||
id="g3330-8" /><g
|
||||
id="g3330-8"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,32.657275,24.227219)"
|
||||
id="g3332-7" /><g
|
||||
id="g3332-7"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,32.657275,24.227219)"
|
||||
id="g3334-4" /><g
|
||||
id="g3334-4"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,32.657275,24.227219)"
|
||||
id="g3336-6" /><g
|
||||
id="g3336-6"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,32.657275,24.227219)"
|
||||
id="g3338-3" /><g
|
||||
id="g3338-3"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,32.657275,24.227219)"
|
||||
id="g3340-3" /><g
|
||||
id="g3340-3"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,32.657275,24.227219)"
|
||||
id="g3342-8" /><g
|
||||
id="g3342-8"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,32.657275,24.227219)"
|
||||
id="g3344-0" /><path
|
||||
id="g3344-0"
|
||||
style="fill:#ffffff;fill-opacity:1" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 36.799699,78.82117 c -1.137946,-0.18105 -1.163883,-3.309786 -1.163883,-3.309786 0,0 3.343439,-3.309884 4.072153,-7.760699 1.960218,0 3.171037,-4.731803 1.210508,-6.396627 0.08192,-1.752516 2.519723,-13.757253 -9.822199,-13.757253 -12.341922,0 -9.904024,12.004737 -9.822404,13.757253 -1.960427,1.664824 -0.749814,6.396627 1.210509,6.396627 0.728611,4.450814 4.072152,7.760699 4.072152,7.760699 0,0 -0.02593,3.128736 -1.163781,3.309786 C 21.72757,79.40434 8.040924,85.44104 8.040924,92.0607 H 31.096277 54.15163 c 0,-6.61966 -13.686644,-12.65636 -17.351931,-13.23953 z"
|
||||
id="path4374-2" /><path
|
||||
id="path4374-2"
|
||||
style="fill:#ffffff;fill-opacity:1" /><path
|
||||
d="M 54.807,25.2656 H 7.776331 c -3.918217,0 -7.125127,2.834985 -7.125127,6.304707 v 80.731723 c 0,3.46972 3.20691,6.30737 7.125127,6.30737 H 54.807 c 3.91822,0 7.12513,-2.83498 7.12513,-6.3047 V 31.570307 c 0,-3.469722 -3.20691,-6.304707 -7.12513,-6.304707 z m -31.038311,4.54451 h 15.045956 c 0.476213,0 0.862005,0.341372 0.862005,0.765419 0,0.42138 -0.385792,0.762752 -0.862005,0.762752 H 23.768689 c -0.476215,0 -0.862009,-0.341372 -0.862009,-0.762752 0,-0.424047 0.385794,-0.765419 0.862009,-0.765419 z m 7.522977,85.64694 c -1.968151,0 -3.562564,-1.41083 -3.562564,-3.15235 0,-1.74153 1.594413,-3.15236 3.562564,-3.15236 1.96815,0 3.562565,1.41083 3.562565,3.15236 0,1.74152 -1.594415,3.15235 -3.562565,3.15235 z M 56.97408,106.94143 H 5.609256 V 35.264055 H 56.97408 v 71.677375 z"
|
||||
id="path3198-0"
|
||||
inkscape:connector-curvature="0" /><g
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
id="g3200-5"
|
||||
transform="matrix(3.0140138,0,0,2.6669657,56.651204,25.2656)" /><g
|
||||
transform="matrix(3.0140138,0,0,2.6669657,56.651204,25.2656)"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
id="g3202-7"
|
||||
transform="matrix(3.0140138,0,0,2.6669657,56.651204,25.2656)" /><g
|
||||
transform="matrix(3.0140138,0,0,2.6669657,56.651204,25.2656)"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
id="g3204-5"
|
||||
transform="matrix(3.0140138,0,0,2.6669657,56.651204,25.2656)" /><g
|
||||
transform="matrix(3.0140138,0,0,2.6669657,56.651204,25.2656)"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
id="g3206-2"
|
||||
transform="matrix(3.0140138,0,0,2.6669657,56.651204,25.2656)" /><g
|
||||
transform="matrix(3.0140138,0,0,2.6669657,56.651204,25.2656)"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
id="g3208-4"
|
||||
transform="matrix(3.0140138,0,0,2.6669657,56.651204,25.2656)" /><g
|
||||
transform="matrix(3.0140138,0,0,2.6669657,56.651204,25.2656)"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
id="g3210-6"
|
||||
transform="matrix(3.0140138,0,0,2.6669657,56.651204,25.2656)" /><g
|
||||
transform="matrix(3.0140138,0,0,2.6669657,56.651204,25.2656)"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
id="g3212-4"
|
||||
transform="matrix(3.0140138,0,0,2.6669657,56.651204,25.2656)" /><g
|
||||
transform="matrix(3.0140138,0,0,2.6669657,56.651204,25.2656)"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
id="g3214-2"
|
||||
transform="matrix(3.0140138,0,0,2.6669657,56.651204,25.2656)" /><g
|
||||
transform="matrix(3.0140138,0,0,2.6669657,56.651204,25.2656)"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
id="g3216-7"
|
||||
transform="matrix(3.0140138,0,0,2.6669657,56.651204,25.2656)" /><g
|
||||
transform="matrix(3.0140138,0,0,2.6669657,56.651204,25.2656)"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
id="g3218-6"
|
||||
transform="matrix(3.0140138,0,0,2.6669657,56.651204,25.2656)" /><g
|
||||
transform="matrix(3.0140138,0,0,2.6669657,56.651204,25.2656)"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
id="g3220-0"
|
||||
transform="matrix(3.0140138,0,0,2.6669657,56.651204,25.2656)" /><g
|
||||
transform="matrix(3.0140138,0,0,2.6669657,56.651204,25.2656)"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
id="g3222-7"
|
||||
transform="matrix(3.0140138,0,0,2.6669657,56.651204,25.2656)" /><g
|
||||
transform="matrix(3.0140138,0,0,2.6669657,56.651204,25.2656)"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
id="g3224-8"
|
||||
transform="matrix(3.0140138,0,0,2.6669657,56.651204,25.2656)" /><g
|
||||
transform="matrix(3.0140138,0,0,2.6669657,56.651204,25.2656)"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
id="g3226-0"
|
||||
transform="matrix(3.0140138,0,0,2.6669657,56.651204,25.2656)" /><g
|
||||
transform="matrix(3.0140138,0,0,2.6669657,56.651204,25.2656)"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
id="g3228-4"
|
||||
transform="matrix(3.0140138,0,0,2.6669657,56.651204,25.2656)" /><g
|
||||
transform="matrix(3.0140138,0,0,2.6669657,56.651204,25.2656)"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,64.241956,45.71724)"
|
||||
id="g3316-7" /><g
|
||||
id="g3316-7"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,64.241956,45.71724)"
|
||||
id="g3318-2" /><g
|
||||
id="g3318-2"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,64.241956,45.71724)"
|
||||
id="g3320-9" /><g
|
||||
id="g3320-9"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,64.241956,45.71724)"
|
||||
id="g3322-0" /><g
|
||||
id="g3322-0"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,64.241956,45.71724)"
|
||||
id="g3324-1" /><g
|
||||
id="g3324-1"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,64.241956,45.71724)"
|
||||
id="g3326-23" /><g
|
||||
id="g3326-23"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,64.241956,45.71724)"
|
||||
id="g3328-9" /><g
|
||||
id="g3328-9"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,64.241956,45.71724)"
|
||||
id="g3330-9" /><g
|
||||
id="g3330-9"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,64.241956,45.71724)"
|
||||
id="g3332-8" /><g
|
||||
id="g3332-8"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,64.241956,45.71724)"
|
||||
id="g3334-3" /><g
|
||||
id="g3334-3"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,64.241956,45.71724)"
|
||||
id="g3336-0" /><g
|
||||
id="g3336-0"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,64.241956,45.71724)"
|
||||
id="g3338-4" /><g
|
||||
id="g3338-4"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,64.241956,45.71724)"
|
||||
id="g3340-7" /><g
|
||||
id="g3340-7"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,64.241956,45.71724)"
|
||||
id="g3342-5" /><g
|
||||
id="g3342-5"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,64.241956,45.71724)"
|
||||
id="g3344-4" /><g
|
||||
id="g3344-4"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,87.454312,49.492819)"
|
||||
id="g3316-8-2" /><g
|
||||
id="g3316-8-2"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,87.454312,49.492819)"
|
||||
id="g3318-8-2" /><g
|
||||
id="g3318-8-2"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,87.454312,49.492819)"
|
||||
id="g3320-6-2" /><g
|
||||
id="g3320-6-2"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,87.454312,49.492819)"
|
||||
id="g3322-3-6" /><g
|
||||
id="g3322-3-6"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,87.454312,49.492819)"
|
||||
id="g3324-3-8" /><g
|
||||
id="g3324-3-8"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,87.454312,49.492819)"
|
||||
id="g3326-2-8" /><g
|
||||
id="g3326-2-8"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,87.454312,49.492819)"
|
||||
id="g3328-4-3" /><g
|
||||
id="g3328-4-3"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,87.454312,49.492819)"
|
||||
id="g3330-8-2" /><g
|
||||
id="g3330-8-2"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,87.454312,49.492819)"
|
||||
id="g3332-7-8" /><g
|
||||
id="g3332-7-8"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,87.454312,49.492819)"
|
||||
id="g3334-4-9" /><g
|
||||
id="g3334-4-9"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,87.454312,49.492819)"
|
||||
id="g3336-6-3" /><g
|
||||
id="g3336-6-3"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,87.454312,49.492819)"
|
||||
id="g3338-3-5" /><g
|
||||
id="g3338-3-5"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,87.454312,49.492819)"
|
||||
id="g3340-3-9" /><g
|
||||
id="g3340-3-9"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,87.454312,49.492819)"
|
||||
id="g3342-8-5" /><g
|
||||
id="g3342-8-5"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(3.9718007,0,0,3.5144686,87.454312,49.492819)"
|
||||
id="g3344-0-0" /></svg>
|
||||
id="g3344-0-0"
|
||||
style="fill:#ffffff;fill-opacity:1" /></svg>
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 16 KiB |
71
xwords4/android/img_src/origin.svg
Normal file
|
@ -0,0 +1,71 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="200mm"
|
||||
height="200mm"
|
||||
viewBox="0 0 200 200"
|
||||
version="1.1"
|
||||
id="svg1593"
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)"
|
||||
sodipodi:docname="origin.svg">
|
||||
<defs
|
||||
id="defs1587" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.7"
|
||||
inkscape:cx="-180"
|
||||
inkscape:cy="560"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1016"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid6508" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata1590">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-97)">
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:20.95265579;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 24.341669,122.375 177.80002,270.54167 v 0"
|
||||
id="path6510"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:20.95265579;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 177.80002,122.375 24.341669,270.54167 v 0"
|
||||
id="path6512"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.2 KiB |
|
@ -26,7 +26,7 @@
|
|||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.9899495"
|
||||
inkscape:cx="463.73105"
|
||||
inkscape:cx="-143.37062"
|
||||
inkscape:cy="51.719447"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
|
@ -54,16 +54,15 @@
|
|||
id="layer1"
|
||||
transform="translate(-6.7984033,-83.405656)">
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.24740678px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M 18.283263,143.90286 H 192.0312 l -0.25071,-23.652 -49.1888,-31.499813 3.87201,30.186753 -128.439977,-3.34993 z"
|
||||
id="path3898"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M 193.88707,152.89573 H 17.756455 V 128.03966 L 141.76951,127.7724 141.50224,94.630975 Z"
|
||||
id="path113"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccccc" />
|
||||
sodipodi:nodetypes="cccccc" />
|
||||
<path
|
||||
style="stroke-width:0.42060974"
|
||||
d="m 18.153493,129.7454 -0.12977,-14.15753 14.717103,0.19689 c 21.907537,0.2931 90.308644,0.91595 100.527304,0.91538 l 8.90148,-5.5e-4 v -13.97427 c 0,-7.905537 0.1833,-13.974273 0.42208,-13.974273 0.23216,0 11.39461,7.087454 24.80545,15.749903 l 24.38335,15.74991 0.12536,11.82597 0.12535,11.82603 H 105.15723 18.283263 Z"
|
||||
id="path3900"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccsccssscccccc" />
|
||||
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M 62.390464,122.15973 Z"
|
||||
id="path136"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</svg>
|
||||
|
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.2 KiB |
67
xwords4/android/img_src/rightarrow.svg
Normal file
|
@ -0,0 +1,67 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="200mm"
|
||||
height="200mm"
|
||||
viewBox="0 0 200 200"
|
||||
version="1.1"
|
||||
id="svg1593"
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)"
|
||||
sodipodi:docname="downarrow.svg">
|
||||
<defs
|
||||
id="defs1587" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.7"
|
||||
inkscape:cx="-180"
|
||||
inkscape:cy="560"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1016"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid6508" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata1590">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-97)">
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M 10.583336,238.79167 V 164.70834 H 100.54167 V 111.79167 L 190.5,201.75 100.54167,291.70833 v -52.91666 z"
|
||||
id="path7105"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccccc" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2 KiB |
|
@ -17,7 +17,7 @@
|
|||
height="120"
|
||||
viewBox="0 0 120 120"
|
||||
xml:space="preserve"
|
||||
inkscape:version="0.48.4 r9939"
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)"
|
||||
sodipodi:docname="sologame.svg"><metadata
|
||||
id="metadata3234"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
|
@ -31,16 +31,16 @@
|
|||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1453"
|
||||
inkscape:window-height="1057"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1016"
|
||||
id="namedview3230"
|
||||
showgrid="false"
|
||||
inkscape:zoom="6.8571429"
|
||||
inkscape:cx="40.031592"
|
||||
inkscape:cx="10.427426"
|
||||
inkscape:cy="59.0625"
|
||||
inkscape:window-x="1850"
|
||||
inkscape:window-y="28"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="Capa_1"
|
||||
showborder="true"
|
||||
fit-margin-top="0"
|
||||
|
@ -50,100 +50,148 @@
|
|||
inkscape:connector-curvature="0"
|
||||
d="m 50.97261,60.401038 c 7.206148,0 21.618443,0 21.618443,0 m -5.6875,-7 c 0,0 -4.812801,-4.284226 -10.582984,-5.41439 -1.060298,-0.207673 -1.091345,-3.103502 -1.091345,-3.103502 0,0 3.135061,-3.103596 3.818358,-7.277017 1.838049,0 2.973404,-4.436896 1.135064,-5.99796 0.07682,-1.643291 2.362683,-12.899839 -9.210035,-12.899839 -11.572718,0 -9.286761,11.256548 -9.210228,12.899839 -1.838244,1.561064 -0.703082,5.99796 1.135065,5.99796 0.683201,4.17342 3.818357,7.277017 3.818357,7.277017 0,0 -0.02432,2.933739 -1.091249,3.103502 -3.436753,0.546831 -16.270386,6.207291 -16.270386,12.41439 l 26.86844,0 c 1.518648,-5.6875 6.099795,-7.4375 10.680943,-7 z"
|
||||
id="path4374"
|
||||
sodipodi:nodetypes="cccscccscccsccc" /><path
|
||||
sodipodi:nodetypes="cccscccscccsccc"
|
||||
style="fill:#ffffff;fill-opacity:1" /><path
|
||||
d="M 89.475241,-2.3030773e-7 H 29.014018 C 23.976875,-2.3030773e-7 19.854167,3.6445718 19.854167,8.1051428 V 111.89143 c 0,4.46057 4.122708,8.10857 9.159851,8.10857 h 60.461223 c 5.037143,0 9.159851,-3.64457 9.159851,-8.10514 V 8.1051428 C 98.635092,3.6445718 94.512384,-2.3030773e-7 89.475241,-2.3030773e-7 z M 49.573314,5.8422858 h 19.342631 c 0.612206,0 1.108169,0.438858 1.108169,0.984 0,0.541714 -0.495963,0.980572 -1.108169,0.980572 H 49.573314 c -0.612207,0 -1.108172,-0.438858 -1.108172,-0.980572 0,-0.545142 0.495965,-0.984 1.108172,-0.984 z M 59.244629,115.94743 c -2.530196,0 -4.579926,-1.81372 -4.579926,-4.05257 0,-2.23886 2.04973,-4.05257 4.579926,-4.05257 2.530195,0 4.579927,1.81371 4.579927,4.05257 0,2.23885 -2.049732,4.05257 -4.579927,4.05257 z M 92.261168,105 H 26.228091 V 12.853715 H 92.261168 V 105 z"
|
||||
id="path3198"
|
||||
inkscape:connector-curvature="0" /><g
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
id="g3200"
|
||||
transform="matrix(3.874726,0,0,3.4285714,19.854167,0)" /><g
|
||||
transform="matrix(3.874726,0,0,3.4285714,19.854167,0)"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
id="g3202"
|
||||
transform="matrix(3.874726,0,0,3.4285714,19.854167,0)" /><g
|
||||
transform="matrix(3.874726,0,0,3.4285714,19.854167,0)"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
id="g3204"
|
||||
transform="matrix(3.874726,0,0,3.4285714,19.854167,0)" /><g
|
||||
transform="matrix(3.874726,0,0,3.4285714,19.854167,0)"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
id="g3206"
|
||||
transform="matrix(3.874726,0,0,3.4285714,19.854167,0)" /><g
|
||||
transform="matrix(3.874726,0,0,3.4285714,19.854167,0)"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
id="g3208"
|
||||
transform="matrix(3.874726,0,0,3.4285714,19.854167,0)" /><g
|
||||
transform="matrix(3.874726,0,0,3.4285714,19.854167,0)"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
id="g3210"
|
||||
transform="matrix(3.874726,0,0,3.4285714,19.854167,0)" /><g
|
||||
transform="matrix(3.874726,0,0,3.4285714,19.854167,0)"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
id="g3212"
|
||||
transform="matrix(3.874726,0,0,3.4285714,19.854167,0)" /><g
|
||||
transform="matrix(3.874726,0,0,3.4285714,19.854167,0)"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
id="g3214"
|
||||
transform="matrix(3.874726,0,0,3.4285714,19.854167,0)" /><g
|
||||
transform="matrix(3.874726,0,0,3.4285714,19.854167,0)"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
id="g3216"
|
||||
transform="matrix(3.874726,0,0,3.4285714,19.854167,0)" /><g
|
||||
transform="matrix(3.874726,0,0,3.4285714,19.854167,0)"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
id="g3218"
|
||||
transform="matrix(3.874726,0,0,3.4285714,19.854167,0)" /><g
|
||||
transform="matrix(3.874726,0,0,3.4285714,19.854167,0)"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
id="g3220"
|
||||
transform="matrix(3.874726,0,0,3.4285714,19.854167,0)" /><g
|
||||
transform="matrix(3.874726,0,0,3.4285714,19.854167,0)"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
id="g3222"
|
||||
transform="matrix(3.874726,0,0,3.4285714,19.854167,0)" /><g
|
||||
transform="matrix(3.874726,0,0,3.4285714,19.854167,0)"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
id="g3224"
|
||||
transform="matrix(3.874726,0,0,3.4285714,19.854167,0)" /><g
|
||||
transform="matrix(3.874726,0,0,3.4285714,19.854167,0)"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
id="g3226"
|
||||
transform="matrix(3.874726,0,0,3.4285714,19.854167,0)" /><g
|
||||
transform="matrix(3.874726,0,0,3.4285714,19.854167,0)"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
id="g3228"
|
||||
transform="matrix(3.874726,0,0,3.4285714,19.854167,0)" /><g
|
||||
transform="matrix(3.874726,0,0,3.4285714,19.854167,0)"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(5.1060282,0,0,4.5180958,29.612611,26.292017)"
|
||||
id="g3316" /><g
|
||||
id="g3316"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(5.1060282,0,0,4.5180958,29.612611,26.292017)"
|
||||
id="g3318" /><g
|
||||
id="g3318"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(5.1060282,0,0,4.5180958,29.612611,26.292017)"
|
||||
id="g3320" /><g
|
||||
id="g3320"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(5.1060282,0,0,4.5180958,29.612611,26.292017)"
|
||||
id="g3322" /><g
|
||||
id="g3322"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(5.1060282,0,0,4.5180958,29.612611,26.292017)"
|
||||
id="g3324" /><g
|
||||
id="g3324"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(5.1060282,0,0,4.5180958,29.612611,26.292017)"
|
||||
id="g3326" /><g
|
||||
id="g3326"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(5.1060282,0,0,4.5180958,29.612611,26.292017)"
|
||||
id="g3328" /><g
|
||||
id="g3328"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(5.1060282,0,0,4.5180958,29.612611,26.292017)"
|
||||
id="g3330" /><g
|
||||
id="g3330"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(5.1060282,0,0,4.5180958,29.612611,26.292017)"
|
||||
id="g3332" /><g
|
||||
id="g3332"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(5.1060282,0,0,4.5180958,29.612611,26.292017)"
|
||||
id="g3334" /><g
|
||||
id="g3334"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(5.1060282,0,0,4.5180958,29.612611,26.292017)"
|
||||
id="g3336" /><g
|
||||
id="g3336"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(5.1060282,0,0,4.5180958,29.612611,26.292017)"
|
||||
id="g3338" /><g
|
||||
id="g3338"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(5.1060282,0,0,4.5180958,29.612611,26.292017)"
|
||||
id="g3340" /><g
|
||||
id="g3340"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(5.1060282,0,0,4.5180958,29.612611,26.292017)"
|
||||
id="g3342" /><g
|
||||
id="g3342"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(5.1060282,0,0,4.5180958,29.612611,26.292017)"
|
||||
id="g3344" /><g
|
||||
id="g3344"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(5.1060282,0,0,4.5180958,59.453721,31.145788)"
|
||||
id="g3316-8" /><g
|
||||
id="g3316-8"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(5.1060282,0,0,4.5180958,59.453721,31.145788)"
|
||||
id="g3318-8" /><g
|
||||
id="g3318-8"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(5.1060282,0,0,4.5180958,59.453721,31.145788)"
|
||||
id="g3320-6" /><g
|
||||
id="g3320-6"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(5.1060282,0,0,4.5180958,59.453721,31.145788)"
|
||||
id="g3322-3" /><g
|
||||
id="g3322-3"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(5.1060282,0,0,4.5180958,59.453721,31.145788)"
|
||||
id="g3324-3" /><g
|
||||
id="g3324-3"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(5.1060282,0,0,4.5180958,59.453721,31.145788)"
|
||||
id="g3326-2" /><g
|
||||
id="g3326-2"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(5.1060282,0,0,4.5180958,59.453721,31.145788)"
|
||||
id="g3328-4" /><g
|
||||
id="g3328-4"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(5.1060282,0,0,4.5180958,59.453721,31.145788)"
|
||||
id="g3330-8" /><g
|
||||
id="g3330-8"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(5.1060282,0,0,4.5180958,59.453721,31.145788)"
|
||||
id="g3332-7" /><g
|
||||
id="g3332-7"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(5.1060282,0,0,4.5180958,59.453721,31.145788)"
|
||||
id="g3334-4" /><g
|
||||
id="g3334-4"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(5.1060282,0,0,4.5180958,59.453721,31.145788)"
|
||||
id="g3336-6" /><g
|
||||
id="g3336-6"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(5.1060282,0,0,4.5180958,59.453721,31.145788)"
|
||||
id="g3338-3" /><g
|
||||
id="g3338-3"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(5.1060282,0,0,4.5180958,59.453721,31.145788)"
|
||||
id="g3340-3" /><g
|
||||
id="g3340-3"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(5.1060282,0,0,4.5180958,59.453721,31.145788)"
|
||||
id="g3342-8" /><g
|
||||
id="g3342-8"
|
||||
style="fill:#ffffff;fill-opacity:1" /><g
|
||||
transform="matrix(5.1060282,0,0,4.5180958,59.453721,31.145788)"
|
||||
id="g3344-0" /><path
|
||||
id="g3344-0"
|
||||
style="fill:#ffffff;fill-opacity:1" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 72.747542,85.792667 c -1.141669,-0.181639 -1.167691,-3.320612 -1.167691,-3.320612 0,0 3.354379,-3.320712 4.085477,-7.78609 1.966632,0 3.181411,-4.747285 1.214468,-6.417555 0.08219,-1.758249 2.527968,-13.802264 -9.854334,-13.802264 -12.382303,0 -9.936429,12.044015 -9.854542,13.802264 -1.96684,1.67027 -0.752267,6.417555 1.21447,6.417555 0.730995,4.465377 4.085475,7.78609 4.085475,7.78609 0,0 -0.02603,3.138973 -1.167588,3.320612 -3.677176,0.585084 -17.408602,6.64153 -17.408602,13.282853 h 23.130786 23.130788 c 0,-6.641323 -13.731427,-12.697769 -17.408707,-13.282853 z"
|
||||
id="path4374-1" /></svg>
|
||||
id="path4374-1"
|
||||
style="fill:#ffffff;fill-opacity:1" /></svg>
|
Before Width: | Height: | Size: 7.7 KiB After Width: | Height: | Size: 9.7 KiB |
|
@ -1,53 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
width="120"
|
||||
height="120"
|
||||
xml:space="preserve"
|
||||
id="svg2"
|
||||
inkscape:version="0.48.3.1 r9886"
|
||||
sodipodi:docname="up.svg"><metadata
|
||||
id="metadata11"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs9" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="640"
|
||||
inkscape:window-height="480"
|
||||
id="namedview7"
|
||||
showgrid="false"
|
||||
inkscape:zoom="1.9666667"
|
||||
inkscape:cx="60.000001"
|
||||
inkscape:cy="60.000001"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="24"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="svg2" />
|
||||
<g
|
||||
id="g12"
|
||||
transform="matrix(-1.25,0,0,1.25,116.39005,-0.58771313)">
|
||||
<g
|
||||
transform="translate(47.72,32.35)"
|
||||
id="g676">
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m -1.163978,-15.143535 -23.537465,32.092623 14.683237,0 0,29.964616 17.5617961,0 0,-29.964616 14.8298969,0 z"
|
||||
id="path678"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccccc" />
|
||||
</g></g>
|
||||
</svg>
|
Before Width: | Height: | Size: 1.7 KiB |
|
@ -763,11 +763,10 @@ deleteLocalRefs( JNIEnv* env, ... )
|
|||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void
|
||||
android_debugf( const char* format, ... )
|
||||
static void
|
||||
debugf( const char* format, va_list ap )
|
||||
{
|
||||
char buf[1024];
|
||||
va_list ap;
|
||||
int len;
|
||||
struct tm* timp;
|
||||
struct timeval tv;
|
||||
|
@ -779,9 +778,7 @@ android_debugf( const char* format, ... )
|
|||
len = snprintf( buf, sizeof(buf), "%.2d:%.2d:%.2d: ",
|
||||
timp->tm_hour, timp->tm_min, timp->tm_sec );
|
||||
if ( len < sizeof(buf) ) {
|
||||
va_start(ap, format);
|
||||
vsnprintf( buf + len, sizeof(buf)-len, format, ap );
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
(void)__android_log_write( ANDROID_LOG_DEBUG,
|
||||
|
@ -795,6 +792,27 @@ android_debugf( const char* format, ... )
|
|||
, buf );
|
||||
}
|
||||
|
||||
void
|
||||
android_debugf( const char* format, ... )
|
||||
{
|
||||
va_list ap;
|
||||
va_start( ap, format );
|
||||
debugf( format, ap );
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void
|
||||
android_debugff(const char* func, const char* file, const char* fmt, ...)
|
||||
{
|
||||
char buf[256];
|
||||
snprintf( buf, sizeof(buf), "%s:%s(): %s", file, func, fmt );
|
||||
|
||||
va_list ap;
|
||||
va_start( ap, fmt );
|
||||
debugf( buf, ap );
|
||||
va_end( ap );
|
||||
}
|
||||
|
||||
/* Print an object's class name into buffer.
|
||||
*
|
||||
* NOTE: this must be called in advance of any jni error, because methods on
|
||||
|
|
|
@ -91,12 +91,16 @@ void and_assert( const char* test, int line, const char* file, const char* func
|
|||
|
||||
#ifdef ENABLE_LOGGING
|
||||
void android_debugf(const char*, ...) __attribute__ ((format (printf, 1, 2)));
|
||||
void android_debugff(const char* func, const char* file, const char* fmt, ...)
|
||||
__attribute__ ((format (printf, 3, 4)));
|
||||
#define XP_DEBUGF(...) android_debugf( __VA_ARGS__ )
|
||||
#define XP_LOGF(...) android_debugf( __VA_ARGS__ )
|
||||
#define XP_LOGFF(...) android_debugff( __func__, __FILE__, __VA_ARGS__ )
|
||||
#define XP_WARNF(...) android_debugf( __VA_ARGS__ )
|
||||
#else
|
||||
#define XP_DEBUGF(...)
|
||||
#define XP_LOGF(...)
|
||||
#define XP_LOGFF(...)
|
||||
#define XP_WARNF(...)
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1805,14 +1805,14 @@ Java_org_eehouse_android_xw4_jni_XwJNI_comms_1getAddrs
|
|||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_org_eehouse_android_xw4_jni_XwJNI_comms_1setAddr
|
||||
Java_org_eehouse_android_xw4_jni_XwJNI_comms_1augmentHostAddr
|
||||
( JNIEnv* env, jclass C, GamePtrType gamePtr, jobject jaddr )
|
||||
{
|
||||
XWJNI_START();
|
||||
if ( state->game.comms ) {
|
||||
CommsAddrRec addr = {0};
|
||||
getJAddrRec( env, &addr, jaddr );
|
||||
comms_setAddr( state->game.comms, &addr );
|
||||
comms_augmentHostAddr( state->game.comms, &addr );
|
||||
} else {
|
||||
XP_LOGF( "%s: no comms this game", __func__ );
|
||||
}
|
||||
|
@ -2207,6 +2207,20 @@ Java_org_eehouse_android_xw4_jni_XwJNI_comms_1getStats
|
|||
return result;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_org_eehouse_android_xw4_jni_XwJNI_comms_1dropHostAddr
|
||||
( JNIEnv* env, jclass C, GamePtrType gamePtr, jobject jConnTyp )
|
||||
{
|
||||
LOG_FUNC();
|
||||
XWJNI_START();
|
||||
if ( NULL != state->game.comms ) {
|
||||
CommsConnType connType = jEnumToInt( env, jConnTyp );
|
||||
comms_dropHostAddr( state->game.comms, connType );
|
||||
}
|
||||
XWJNI_END();
|
||||
LOG_RETURN_VOID();
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
JNIEXPORT void JNICALL
|
||||
Java_org_eehouse_android_xw4_jni_XwJNI_comms_1setAddrDisabled
|
||||
|
|
|
@ -985,11 +985,11 @@
|
|||
<string name="title_enable_stallnotify">Gesperrte Netzwerkbenachrichtigung anzeigen</string>
|
||||
<string name="summary_enable_stallnotify">Benachrichtigen, wenn Android nur langsam ausgehende Einladungen und Züge verarbeitet</string>
|
||||
<string name="notify_stall_title">Das Senden von Nachrichten ist gesperrt</string>
|
||||
<string name="notify_stall_body_fmt">Obwohl es normalerweise weniger als eine Sekunde dauert, konnte Android die ausgehenden Nachrichten von CrossWords für mehr als %1$d Sekunden nicht verarbeiten. Dies kann daran liegen, dass Ihr Gerät besonders ausgelastet ist, oder weil CrossWords eine Weile nicht im Vordergrund gelaufen ist.
|
||||
<string name="notify_stall_body_fmt">%1$s: Obwohl es normalerweise weniger als eine Sekunde dauert, konnte Android die ausgehenden Nachrichten von CrossWords für mehr als %2$d Sekunden nicht verarbeiten. Dies kann daran liegen, dass Ihr Gerät besonders ausgelastet ist, oder weil CrossWords eine Weile nicht im Vordergrund gelaufen ist.
|
||||
\n
|
||||
\nWenn das Problem weiterhin besteht (d.h. Sie sehen es häufig), senden Sie mir bitte eine E-Mail mit Informationen über Ihr Gerät, damit ich versuchen kann, es zu reproduzieren und zu beheben.
|
||||
\n
|
||||
\nDiese Meldung wird höchstens einmal alle %2$d Minuten angezeigt.</string>
|
||||
\nDiese Meldung wird höchstens einmal alle %3$d Minuten angezeigt.</string>
|
||||
<string name="sms_banned_ok_only">Die Google Play-Version von CrossWords unterstützt keine Einladungen mehr oder das Spielen per Daten-SMS.</string>
|
||||
<string name="button_more_info">Mehr erfahren</string>
|
||||
<string name="banned_nbs_perms">Dieses Spiel ist für die Kommunikation per Daten-SMS eingerichtet, aber Apps aus dem Google Play Store dürfen dies (bis auf wenige Ausnahmen) nicht mehr tun. Sie können das Spiel immer noch öffnen, aber es ist mehr möglicherweise, Züge zu senden oder zu empfangen.
|
||||
|
|
|
@ -982,11 +982,11 @@ WiFi ダイレクト経由で接続可能なデバイスはありません。</s
|
|||
<string name="title_enable_stallnotify">停止したネットワーク通知を表示</string>
|
||||
<string name="summary_enable_stallnotify">Android が招待の発信や移動を処理するのが遅いときに通知します</string>
|
||||
<string name="notify_stall_title">メッセージの送信が停止しています</string>
|
||||
<string name="notify_stall_body_fmt">%1$d 秒間メッセージを 送信できませんでした。
|
||||
<string name="notify_stall_body_fmt">%1$s: %2$d 秒間メッセージを 送信できませんでした。
|
||||
\n
|
||||
\n再度発生する場合は、開発者ログとデバイスに関する情報をメールで送ってください。
|
||||
\n
|
||||
\nこのメッセージは、最大 %2$d 分に 1 回表示されます。</string>
|
||||
\nこのメッセージは、最大 %3$d 分に 1 回表示されます。</string>
|
||||
<string name="sms_banned_ok_only">Google Play バージョンのクロスワードは、データ SMS 経由で招待やプレイできなくなりました。</string>
|
||||
<string name="button_more_info">続きを読む</string>
|
||||
<string name="banned_nbs_perms">このゲームは、データSMSを介して通信するように設定されていますが、Google Playストアのアプリは、もはや (まれな例外を除いて) 許可されていません。まだゲームを開くことはできますが、移動を送受信できない場合があります。
|
||||
|
|
|
@ -983,11 +983,11 @@
|
|||
<string name="title_enable_stallnotify">Vis merknad for stagnert nettverk</string>
|
||||
<string name="summary_enable_stallnotify">Merknad når Android er treg med å behandle utgående invitasjoner og trekk</string>
|
||||
<string name="notify_stall_title">Meldingsforsendelse har stagnert</string>
|
||||
<string name="notify_stall_body_fmt">Kunne ikke sende utgående meldinger i løpet av %1$d sekunder.
|
||||
<string name="notify_stall_body_fmt">%1$s: Kunne ikke sende utgående meldinger i løpet av %2$d sekunder.
|
||||
\n
|
||||
\nHvis dette skjer igjen, send en e-post til utvikleren inneholdende logger og info om din enhet.
|
||||
\n
|
||||
\nDenne meldingen vil vises toppen én gang hvert %2$d minutt.</string>
|
||||
\nDenne meldingen vil vises toppen én gang hvert %3$d minutt.</string>
|
||||
<string name="relay_poll_name_no_fcm">Kun prøv: Ingen FCM-meldinger</string>
|
||||
<string name="relay_poll_name_no_polling">Kun FCM: Ingen prøving</string>
|
||||
<string name="relay_poll_name_both">Forvalg: Miks prøving og FCM</string>
|
||||
|
|
|
@ -984,11 +984,11 @@
|
|||
<string name="title_enable_stallnotify">Pokaż zablokowane powiadomienie sieciowe</string>
|
||||
<string name="summary_enable_stallnotify">Powiadom kiedy Android powoli przetwarza wychodzące zaproszenia i ruchy</string>
|
||||
<string name="notify_stall_title">Wysyłanie wiadomości jest wstrzymane</string>
|
||||
<string name="notify_stall_body_fmt">Chociaż zwykle zajmuje mniej niż sekundę, Android nie był w stanie przetworzyć wiadomości wychodzących CrossWords więcej niż %1$d sekund. Może to być spowodowane tym, że urządzenie jest szczególnie zajęte lub CrossWords nie działa na pierwszym planie na chwilę.
|
||||
<string name="notify_stall_body_fmt">%1$s: Chociaż zwykle zajmuje mniej niż sekundę, Android nie był w stanie przetworzyć wiadomości wychodzących CrossWords więcej niż %2$d sekund. Może to być spowodowane tym, że urządzenie jest szczególnie zajęte lub CrossWords nie działa na pierwszym planie na chwilę.
|
||||
\n
|
||||
\nJeśli problem będzie się powtarzał (tzn. widzisz to często), rozważ wysłanie mi wiadomości e-mail z informacjami o twoim urządzeniu, abym mógł spróbować je odtworzyć i naprawić.
|
||||
\n
|
||||
\nWiadomość tę zobaczysz co najwyżej raz na %2$d minut..</string>
|
||||
\nWiadomość tę zobaczysz co najwyżej raz na %3$d minut..</string>
|
||||
<string name="sms_banned_ok_only">Wersja CrossWords w sklepie Google Play nie obsługuje już zapraszania lub grania za pomocą Data SMS.</string>
|
||||
<string name="button_more_info">Czytaj więcej</string>
|
||||
<string name="banned_nbs_perms">Ta gra jest skonfigurowana do komunikacji za pośrednictwem Data SMS, ale aplikacje ze sklepu Google Play Store nie mogą już tego robić (z rzadkimi wyjątkami). Możesz jeszcze otworzyć grę, ale może nie być w stanie wysyłać lub odbierać ruchów.
|
||||
|
|
|
@ -4,12 +4,36 @@ IMG_SRC = ./img_src
|
|||
IMG_DEST = app/src/main/res
|
||||
PARAMS = -transparent white -negate
|
||||
|
||||
# $(IMG_DEST)/drawable/%_gen.png:
|
||||
# pwd
|
||||
# touch $@
|
||||
SRC_SVGS = \
|
||||
archive.svg \
|
||||
clear_all.svg \
|
||||
content_copy.svg \
|
||||
content_discard.svg \
|
||||
content_new_net.svg \
|
||||
content_new_solo.svg \
|
||||
dict.svg \
|
||||
download.svg \
|
||||
email.svg \
|
||||
new_group.svg \
|
||||
prefs.svg \
|
||||
relabel.svg \
|
||||
rematch.svg \
|
||||
reset.svg \
|
||||
save.svg \
|
||||
search.svg \
|
||||
select_all.svg \
|
||||
send.svg \
|
||||
trade.svg \
|
||||
untrade.svg \
|
||||
|
||||
# $(IMG_DEST)/drawable/%_gen.png: $(IMG_SRC)/%.svg
|
||||
# convert -extent 48x48 $< $@
|
||||
XHDPI_IMGS:=$(foreach img,$(SRC_SVGS:.svg=__gen.png),$(IMG_DEST)/drawable-xhdpi/$(img))
|
||||
MDPI_IMGS:=$(foreach img,$(SRC_SVGS:.svg=__gen.png),$(IMG_DEST)/drawable-mdpi/$(img))
|
||||
HDPI_IMGS:=$(foreach img,$(SRC_SVGS:.svg=__gen.png),$(IMG_DEST)/drawable-hdpi/$(img))
|
||||
|
||||
all: $(XHDPI_IMGS) $(MDPI_IMGS) $(HDPI_IMGS)
|
||||
|
||||
clean:
|
||||
rm -f $(XHDPI_IMGS) $(MDPI_IMGS) $(HDPI_IMGS)
|
||||
|
||||
$(IMG_DEST)/drawable-xhdpi/%__gen.png: $(IMG_SRC)/%.svg
|
||||
convert $(PARAMS) -scale 64x64 $< $@
|
||||
|
|
|
@ -98,11 +98,11 @@ def languageCodeFor( lang ):
|
|||
|
||||
def getInternalSum( filePath ):
|
||||
filePath = k_filebase + "and_wordlists/" + filePath
|
||||
proc = subprocess.Popen(['/usr/bin/perl',
|
||||
proc = subprocess.Popen(['/usr/bin/python3',
|
||||
'--',
|
||||
k_filebase + 'xw4/dawg2dict.pl',
|
||||
'-get-sum',
|
||||
'-dict', filePath ],
|
||||
k_filebase + 'xw4/dawg2dict.py',
|
||||
'--get-sum',
|
||||
'--dict', filePath ],
|
||||
stdout = subprocess.PIPE,
|
||||
stderr = subprocess.PIPE)
|
||||
results = proc.communicate()
|
||||
|
|
|
@ -28,21 +28,7 @@ done
|
|||
|
||||
# There needs to be target in the makefile for each of these (giving
|
||||
# the output .png size)
|
||||
|
||||
TARGET_DIRS="drawable-hdpi drawable-mdpi drawable-xhdpi"
|
||||
|
||||
for SVG in img_src/*.svg; do
|
||||
for DIR in $TARGET_DIRS; do
|
||||
SVG=$(basename $SVG)
|
||||
OUT=app/src/main/res/$DIR/${SVG/.svg/__gen.png}
|
||||
mkdir -p $(dirname $OUT)
|
||||
if [ -z "$CLEAN" ]; then
|
||||
make -f $(dirname $0)/images.mk $OUT >/dev/null 2>&1
|
||||
else
|
||||
rm -f $OUT
|
||||
fi
|
||||
done
|
||||
done
|
||||
make -f $(dirname $0)/images.mk >/dev/null 2>&1
|
||||
|
||||
OTHER_IMAGES="app/src/main/res/drawable/green_chat__gen.png"
|
||||
for IMAGE in $OTHER_IMAGES; do
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* -*- compile-command: "cd ../linux && make MEMDEBUG=TRUE -j3"; -*- */
|
||||
/*
|
||||
* Copyright 2001 - 2014 by Eric House (xwords@eehouse.org). All rights
|
||||
* Copyright 2001 - 2020 by Eric House (xwords@eehouse.org). All rights
|
||||
* reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
|
@ -190,8 +190,9 @@ static AddressRecord* rememberChannelAddress( CommsCtxt* comms,
|
|||
XP_PlayerAddr channelNo,
|
||||
XWHostID id,
|
||||
const CommsAddrRec* addr );
|
||||
static void augmentChannelAddr( CommsCtxt* comms, AddressRecord* rec,
|
||||
const CommsAddrRec* addr, XWHostID hostID );
|
||||
static void augmentChannelAddr( AddressRecord* rec, const CommsAddrRec* addr,
|
||||
XWHostID hostID );
|
||||
static void augmentAddr( CommsAddrRec* dest, const CommsAddrRec* src );
|
||||
static XP_Bool channelToAddress( CommsCtxt* comms, XP_PlayerAddr channelNo,
|
||||
const CommsAddrRec** addr );
|
||||
static AddressRecord* getRecordFor( CommsCtxt* comms, const CommsAddrRec* addr,
|
||||
|
@ -231,7 +232,8 @@ static void logAddrs( const CommsCtxt* comms, const char* caller );
|
|||
|
||||
# else
|
||||
# define printQueue( comms )
|
||||
# define logAddr( comms, addr, caller )
|
||||
# define logAddr( comms, addr, caller)
|
||||
# define logAddrs( comms, caller )
|
||||
# endif
|
||||
#endif
|
||||
#if defined RELAY_HEARTBEAT || defined COMMS_HEARTBEAT
|
||||
|
@ -828,7 +830,7 @@ sendConnect( CommsCtxt* comms, XP_Bool breakExisting )
|
|||
}
|
||||
|
||||
setHeartbeatTimer( comms );
|
||||
} /* comms_start */
|
||||
} /* sendConnect */
|
||||
|
||||
static void
|
||||
addrToStreamOne( XWStreamCtxt* stream, CommsConnType typ, const CommsAddrRec* addrP )
|
||||
|
@ -962,7 +964,7 @@ comms_writeToStream( CommsCtxt* comms, XWStreamCtxt* stream,
|
|||
static void
|
||||
resetBackoff( CommsCtxt* comms )
|
||||
{
|
||||
XP_LOGF( "%s: resetting backoff", __func__ );
|
||||
XP_LOGFF( "%s", "resetting backoff" );
|
||||
comms->resendBackoff = 0;
|
||||
comms->nextResend = 0;
|
||||
}
|
||||
|
@ -994,17 +996,28 @@ comms_getAddr( const CommsCtxt* comms, CommsAddrRec* addr )
|
|||
} /* comms_getAddr */
|
||||
|
||||
void
|
||||
comms_setAddr( CommsCtxt* comms, const CommsAddrRec* addr )
|
||||
comms_augmentHostAddr( CommsCtxt* comms, const CommsAddrRec* addr )
|
||||
{
|
||||
logAddr( comms, addr, __func__ );
|
||||
XP_ASSERT( comms != NULL );
|
||||
util_addrChange( comms->util, &comms->addr, addr );
|
||||
XP_MEMCPY( &comms->addr, addr, sizeof(comms->addr) );
|
||||
|
||||
XP_Bool addingRelay = addr_hasType( addr, COMMS_CONN_RELAY )
|
||||
&& ! addr_hasType( &comms->addr, COMMS_CONN_RELAY );
|
||||
|
||||
CommsAddrRec tmp = comms->addr;
|
||||
augmentAddr( &tmp, addr );
|
||||
util_addrChange( comms->util, &comms->addr, &tmp );
|
||||
comms->addr = tmp;
|
||||
|
||||
logAddr( comms, &comms->addr, "after" );
|
||||
|
||||
#ifdef COMMS_HEARTBEAT
|
||||
setDoHeartbeat( comms );
|
||||
#endif
|
||||
sendConnect( comms, XP_TRUE );
|
||||
} /* comms_setAddr */
|
||||
if ( addingRelay ) {
|
||||
sendConnect( comms, XP_TRUE );
|
||||
}
|
||||
} /* comms_setHostAddr */
|
||||
|
||||
void
|
||||
comms_getAddrs( const CommsCtxt* comms, CommsAddrRec addr[], XP_U16* nRecs )
|
||||
|
@ -1139,6 +1152,12 @@ comms_getConTypes( const CommsCtxt* comms )
|
|||
return typ;
|
||||
} /* comms_getConTypes */
|
||||
|
||||
void
|
||||
comms_dropHostAddr( CommsCtxt* comms, CommsConnType typ )
|
||||
{
|
||||
addr_rmType( &comms->addr, typ );
|
||||
}
|
||||
|
||||
XP_Bool
|
||||
comms_getIsServer( const CommsCtxt* comms )
|
||||
{
|
||||
|
@ -1210,7 +1229,7 @@ comms_getChannelSeed( CommsCtxt* comms )
|
|||
result = XP_RANDOM() & ~CHANNEL_MASK;
|
||||
result |= comms->forceChannel;
|
||||
CNO_FMT( cbuf, result );
|
||||
XP_LOGF( "%s: made seed: %s(%d)", __func__, cbuf, result );
|
||||
XP_LOGFF( "made seed: %s(%d)", cbuf, result );
|
||||
comms->channelSeed = result;
|
||||
}
|
||||
return result;
|
||||
|
@ -1443,8 +1462,22 @@ sendMsg( CommsCtxt* comms, MsgQueueElem* elem, const CommsConnType filter )
|
|||
elem->len, cbuf, elem->checksum );
|
||||
#endif
|
||||
|
||||
CommsAddrRec addr;
|
||||
const CommsAddrRec* addrP;
|
||||
(void)channelToAddress( comms, channelNo, &addrP );
|
||||
if ( NULL == addrP ) {
|
||||
XP_LOGF( TAGFMT() "no addr for channel so using comms'", TAGPRMS );
|
||||
comms_getAddr( comms, &addr );
|
||||
logAddr( comms, &addr, "default case" );
|
||||
} else {
|
||||
addr = *addrP;
|
||||
if ( addr_hasType( &comms->addr, COMMS_CONN_NFC ) ) {
|
||||
addr_addType( &addr, COMMS_CONN_NFC );
|
||||
}
|
||||
}
|
||||
|
||||
CommsConnType typ;
|
||||
for ( XP_U32 st = 0; addr_iter( &comms->addr, &typ, &st ); ) {
|
||||
for ( XP_U32 st = 0; addr_iter( &addr, &typ, &st ); ) {
|
||||
XP_S16 nSent = -1;
|
||||
if ( comms_getAddrDisabled( comms, typ, XP_TRUE ) ) {
|
||||
XP_LOGF( "%s: dropping message because %s disabled", __func__,
|
||||
|
@ -1468,7 +1501,7 @@ sendMsg( CommsCtxt* comms, MsgQueueElem* elem, const CommsConnType filter )
|
|||
XP_UCHAR msgNo[16];
|
||||
formatMsgNo( comms, elem, msgNo, sizeof(msgNo) );
|
||||
if ( send_via_relay( comms, XWRELAY_MSG_TORELAY, destID,
|
||||
elem->msg, elem->len, msgNo ) ){
|
||||
elem->msg, elem->len, msgNo ) ) {
|
||||
nSent = elem->len;
|
||||
}
|
||||
} else {
|
||||
|
@ -1488,17 +1521,6 @@ sendMsg( CommsCtxt* comms, MsgQueueElem* elem, const CommsConnType filter )
|
|||
break;
|
||||
#endif
|
||||
default: {
|
||||
CommsAddrRec addr;
|
||||
const CommsAddrRec* addrP;
|
||||
(void)channelToAddress( comms, channelNo, &addrP );
|
||||
|
||||
if ( NULL == addrP || !addr_hasType( addrP, typ ) ) {
|
||||
XP_LOGF( TAGFMT() "no addr for channel or addr type %s"
|
||||
" so using comms'", TAGPRMS, ConnType2Str(typ) );
|
||||
comms_getAddr( comms, &addr );
|
||||
} else {
|
||||
addr = *addrP;
|
||||
}
|
||||
XP_ASSERT( addr_hasType( &addr, typ ) );
|
||||
|
||||
XP_ASSERT( !!comms->procs.send );
|
||||
|
@ -1527,8 +1549,8 @@ sendMsg( CommsCtxt* comms, MsgQueueElem* elem, const CommsConnType filter )
|
|||
elem->sendCount );
|
||||
}
|
||||
CNO_FMT( cbuf1, elem->channelNo );
|
||||
XP_LOGF( "%s(%s; msgID=" XP_LD ", len=%d)=>%d", __func__,
|
||||
cbuf1, elem->msgID, elem->len, result );
|
||||
XP_LOGFF( "(%s; msgID=" XP_LD ", len=%d)=>%d", cbuf1, elem->msgID,
|
||||
elem->len, result );
|
||||
XP_ASSERT( result < 0 || elem->len == result );
|
||||
return result;
|
||||
} /* sendMsg */
|
||||
|
@ -2177,7 +2199,7 @@ validateInitialMessage( CommsCtxt* comms,
|
|||
XP_LOGF( TAGFMT() "looking at %s", TAGPRMS, cbuf );
|
||||
rec = getRecordFor( comms, addr, *channelNo, XP_TRUE );
|
||||
if ( !!rec ) {
|
||||
augmentChannelAddr( comms, rec, addr, senderID );
|
||||
augmentChannelAddr( rec, addr, senderID );
|
||||
/* reject: we've already seen init message on channel */
|
||||
XP_LOGF( TAGFMT() "rejecting duplicate INIT message", TAGPRMS );
|
||||
rec = NULL;
|
||||
|
@ -2252,7 +2274,7 @@ validateChannelMessage( CommsCtxt* comms, const CommsAddrRec* addr,
|
|||
if ( !!rec ) {
|
||||
removeFromQueue( comms, channelNo, lastMsgRcd );
|
||||
|
||||
augmentChannelAddr( comms, rec, addr, senderID );
|
||||
augmentChannelAddr( rec, addr, senderID );
|
||||
|
||||
if ( msgID == rec->lastMsgRcd + 1 ) {
|
||||
XP_LOGF( TAGFMT() "expected %d AND got %d", TAGPRMS,
|
||||
|
@ -2289,10 +2311,10 @@ comms_checkIncomingStream( CommsCtxt* comms, XWStreamCtxt* stream,
|
|||
if ( comms_getAddrDisabled( comms, addrType, XP_FALSE ) ) {
|
||||
XP_LOGF( "%s: dropping message because %s disabled", __func__,
|
||||
ConnType2Str( addrType ) );
|
||||
} else if (0 == (comms->addr._conTypes & retAddr->_conTypes)) {
|
||||
/* we don't expect messages with that address type; drop it */
|
||||
XP_LOGF( "%s: not expecting %s messages", __func__,
|
||||
ConnType2Str( addrType ) );
|
||||
/* } else if (0 == (comms->addr._conTypes & retAddr->_conTypes)) { */
|
||||
/* /\* we don't expect messages with that address type; drop it *\/ */
|
||||
/* XP_LOGF( "%s: not expecting %s messages", __func__, */
|
||||
/* ConnType2Str( addrType ) ); */
|
||||
} else {
|
||||
XWHostID senderID = 0; /* unset; default for non-relay cases */
|
||||
XP_Bool usingRelay = XP_FALSE;
|
||||
|
@ -2416,15 +2438,14 @@ comms_msgProcessed( CommsCtxt* comms, CommsMsgState* state, XP_Bool rejected )
|
|||
removeAddrRec( comms, state->rec );
|
||||
}
|
||||
#ifdef LOG_COMMS_MSGNOS
|
||||
XP_LOGF( "%s(): msg rejected; NOT upping lastMsgRcd to %d", __func__,
|
||||
state->msgID );
|
||||
XP_LOGFF( "msg rejected; NOT upping lastMsgRcd to %d", state->msgID );
|
||||
#endif
|
||||
} else {
|
||||
AddressRecord* rec = getRecordFor( comms, NULL, state->channelNo, XP_TRUE );
|
||||
XP_ASSERT( !!rec );
|
||||
if ( !!rec && rec->lastMsgRcd < state->msgID ) {
|
||||
#ifdef LOG_COMMS_MSGNOS
|
||||
XP_LOGF( "%s(): upping lastMsgRcd from %d to %d", __func__, rec->lastMsgRcd, state->msgID );
|
||||
XP_LOGFF( "upping lastMsgRcd from %d to %d", rec->lastMsgRcd, state->msgID );
|
||||
#endif
|
||||
rec->lastMsgRcd = state->msgID;
|
||||
}
|
||||
|
@ -2808,59 +2829,57 @@ logAddrs( const CommsCtxt* comms, const char* caller )
|
|||
#endif
|
||||
|
||||
static void
|
||||
augmentChannelAddr( CommsCtxt* XP_UNUSED_DBG(comms), AddressRecord * const rec,
|
||||
const CommsAddrRec* addr, XWHostID hostID )
|
||||
augmentChannelAddr( AddressRecord* const rec, const CommsAddrRec* addr,
|
||||
XWHostID hostID )
|
||||
{
|
||||
if ( !!addr ) {
|
||||
XP_Bool augmented = XP_FALSE;
|
||||
augmentAddr( &rec->addr, addr );
|
||||
if ( addr_hasType( &rec->addr, COMMS_CONN_RELAY ) ) {
|
||||
if ( 0 != hostID ) {
|
||||
rec->rr.hostID = hostID;
|
||||
XP_LOGF( "%s: set hostID for rec %p to %d", __func__, rec, hostID );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
augmentAddr( CommsAddrRec* destAddr, const CommsAddrRec* srcAddr )
|
||||
{
|
||||
if ( !!srcAddr ) {
|
||||
CommsConnType typ;
|
||||
for ( XP_U32 st = 0; addr_iter( addr, &typ, &st ); ) {
|
||||
if ( ! addr_hasType( &rec->addr, typ ) ) {
|
||||
CNO_FMT( cbuf, rec->channelNo );
|
||||
XP_LOGF( "%s: adding type %s to rec %p with %s", __func__,
|
||||
ConnType2Str(typ), rec, cbuf );
|
||||
}
|
||||
|
||||
if ( ! addr_hasType( &rec->addr, typ ) ) {
|
||||
augmented = XP_TRUE;
|
||||
logAddr( comms, &rec->addr, __func__ );
|
||||
logAddr( comms, addr, __func__ );
|
||||
|
||||
addr_addType( &rec->addr, typ );
|
||||
for ( XP_U32 st = 0; addr_iter( srcAddr, &typ, &st ); ) {
|
||||
if ( ! addr_hasType( destAddr, typ ) ) {
|
||||
XP_LOGFF( "adding new type %s to rec", ConnType2Str(typ) );
|
||||
addr_addType( destAddr, typ );
|
||||
}
|
||||
|
||||
const void* src = NULL;
|
||||
void* dest = NULL;
|
||||
XP_U32 siz;
|
||||
size_t siz;
|
||||
|
||||
switch( typ ) {
|
||||
case COMMS_CONN_RELAY:
|
||||
dest = &rec->addr.u.ip_relay;
|
||||
src = &addr->u.ip_relay;
|
||||
siz = sizeof( rec->addr.u.ip_relay );
|
||||
if ( 0 != hostID ) {
|
||||
rec->rr.hostID = hostID;
|
||||
XP_LOGF( "%s: set hostID for rec %p to %d", __func__, rec, hostID );
|
||||
}
|
||||
dest = &destAddr->u.ip_relay;
|
||||
src = &srcAddr->u.ip_relay;
|
||||
siz = sizeof( destAddr->u.ip_relay );
|
||||
break;
|
||||
case COMMS_CONN_SMS:
|
||||
XP_ASSERT( 0 != addr->u.sms.port );
|
||||
XP_ASSERT( '\0' != addr->u.sms.phone[0] );
|
||||
dest = &rec->addr.u.sms;
|
||||
src = &addr->u.sms;
|
||||
siz = sizeof(rec->addr.u.sms);
|
||||
XP_ASSERT( 0 != srcAddr->u.sms.port );
|
||||
XP_ASSERT( '\0' != srcAddr->u.sms.phone[0] );
|
||||
dest = &destAddr->u.sms;
|
||||
src = &srcAddr->u.sms;
|
||||
siz = sizeof(destAddr->u.sms);
|
||||
break;
|
||||
case COMMS_CONN_P2P:
|
||||
XP_ASSERT( '\0' != addr->u.p2p.mac_addr[0] );
|
||||
dest = &rec->addr.u.p2p;
|
||||
src = &addr->u.p2p;
|
||||
siz = sizeof(rec->addr.u.p2p);
|
||||
XP_ASSERT( '\0' != srcAddr->u.p2p.mac_addr[0] );
|
||||
dest = &destAddr->u.p2p;
|
||||
src = &srcAddr->u.p2p;
|
||||
siz = sizeof(destAddr->u.p2p);
|
||||
break;
|
||||
#ifdef XWFEATURE_BLUETOOTH
|
||||
case COMMS_CONN_BT:
|
||||
dest = &rec->addr.u.bt;
|
||||
src = &addr->u.bt;
|
||||
siz = sizeof(rec->addr.u.bt);
|
||||
dest = &destAddr->u.bt;
|
||||
src = &srcAddr->u.bt;
|
||||
siz = sizeof(destAddr->u.bt);
|
||||
break;
|
||||
#endif
|
||||
case COMMS_CONN_NFC:
|
||||
|
@ -2871,15 +2890,11 @@ augmentChannelAddr( CommsCtxt* XP_UNUSED_DBG(comms), AddressRecord * const rec,
|
|||
}
|
||||
if ( !!dest ) {
|
||||
if ( 0 != XP_MEMCMP( dest, src, siz ) ) {
|
||||
XP_LOGF( "%s: actually changing addr info for typ %s",
|
||||
__func__, ConnType2Str(typ) );
|
||||
XP_LOGFF( "actually changing addr info for typ %s", ConnType2Str(typ) );
|
||||
XP_MEMCPY( dest, src, siz );
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( augmented ) {
|
||||
logAddr( comms, &rec->addr, __func__ );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -211,7 +211,7 @@ XP_Bool comms_checkAddr( DeviceRole role, const CommsAddrRec* addr,
|
|||
XW_UtilCtxt* util );
|
||||
|
||||
void comms_getAddr( const CommsCtxt* comms, CommsAddrRec* addr );
|
||||
void comms_setAddr( CommsCtxt* comms, const CommsAddrRec* addr );
|
||||
void comms_augmentHostAddr( CommsCtxt* comms, const CommsAddrRec* addr );
|
||||
void comms_getAddrs( const CommsCtxt* comms, CommsAddrRec addr[],
|
||||
XP_U16* nRecs );
|
||||
XP_Bool comms_formatRelayID( const CommsCtxt* comms, XP_U16 indx,
|
||||
|
@ -225,6 +225,7 @@ XP_Bool comms_getRelayID( const CommsCtxt* comms, XP_UCHAR* buf, XP_U16* len );
|
|||
#endif
|
||||
|
||||
CommsConnTypes comms_getConTypes( const CommsCtxt* comms );
|
||||
void comms_dropHostAddr( CommsCtxt* comms, CommsConnType typ );
|
||||
XP_Bool comms_getIsServer( const CommsCtxt* comms );
|
||||
|
||||
CommsCtxt* comms_makeFromStream( MPFORMAL XWStreamCtxt* stream,
|
||||
|
|
|
@ -309,8 +309,8 @@ typedef struct _PlayerDicts {
|
|||
|
||||
#endif
|
||||
|
||||
#define LOG_FUNC() XP_LOGF( "IN: %s", __func__ )
|
||||
#define LOG_RETURNF(fmt, ...) XP_LOGF( "%s => " fmt, __func__, __VA_ARGS__ )
|
||||
#define LOG_FUNC() XP_LOGFF( "%s", "IN" )
|
||||
#define LOG_RETURNF(fmt, ...) XP_LOGFF( "OUT: => " fmt, __VA_ARGS__ )
|
||||
#define LOG_RETURN_VOID() LOG_RETURNF("%s","void")
|
||||
#define XP_LOGLOC() XP_LOGF( "%s(), line %d", __func__, __LINE__ )
|
||||
#define LOG_POS(strm) XP_LOGF( "%s(); line %d; read_pos: %X", __func__, __LINE__, \
|
||||
|
|
|
@ -86,8 +86,6 @@ StackMoveType_2str( StackMoveType typ )
|
|||
}
|
||||
}
|
||||
|
||||
#undef CASESTR
|
||||
|
||||
#endif /* ENABLE_LOGGING */
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -108,4 +106,25 @@ dbg_logstream( const XWStreamCtxt* stream, const char* func, int line )
|
|||
line, func );
|
||||
}
|
||||
}
|
||||
|
||||
const char*
|
||||
devIDTypeToStr(DevIDType typ)
|
||||
{
|
||||
switch( typ ) {
|
||||
CASESTR(ID_TYPE_NONE);
|
||||
CASESTR(ID_TYPE_RELAY);
|
||||
CASESTR(ID_TYPE_LINUX);
|
||||
CASESTR(ID_TYPE_ANDROID_GCM_UNUSED);
|
||||
CASESTR(ID_TYPE_ANDROID_OTHER);
|
||||
CASESTR(ID_TYPE_ANON);
|
||||
CASESTR(ID_TYPE_ANDROID_FCM);
|
||||
|
||||
CASESTR(ID_TYPE_NTYPES);
|
||||
default:
|
||||
XP_ASSERT(0);
|
||||
}
|
||||
}
|
||||
|
||||
#undef CASESTR
|
||||
|
||||
#endif
|
||||
|
|
|
@ -31,10 +31,12 @@ const char* StackMoveType_2str( StackMoveType typ );
|
|||
|
||||
# ifdef DEBUG
|
||||
void dbg_logstream( const XWStreamCtxt* stream, const char* func, int line );
|
||||
const char* devIDTypeToStr(DevIDType typ);
|
||||
# define XP_LOGSTREAM( s ) \
|
||||
dbg_logstream( s, __func__, __LINE__ )
|
||||
# else
|
||||
# define XP_LOGSTREAM( s )
|
||||
# define devIDTypeToStr(s) ""
|
||||
# endif
|
||||
|
||||
#define boolToStr(b) ((b)?"true" : "false")
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "engine.h"
|
||||
#include "dictnry.h"
|
||||
#include "util.h"
|
||||
#include "dbgutil.h"
|
||||
|
||||
#ifdef CPLUS
|
||||
extern "C" {
|
||||
|
@ -416,7 +417,8 @@ engine_findMove( EngineCtxt* engine, const ModelCtxt* model,
|
|||
engine->nTilesMaxUser = nTilesMax;
|
||||
} else {
|
||||
*canMoveP = XP_FALSE;
|
||||
return XP_TRUE;
|
||||
result = XP_TRUE;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -557,12 +559,16 @@ engine_findMove( EngineCtxt* engine, const ModelCtxt* model,
|
|||
engine_reset( engine );
|
||||
if ( !isRetry ) {
|
||||
isRetry = XP_TRUE;
|
||||
XP_LOGF( "%s: no moves found so retrying", __func__ );
|
||||
XP_LOGFF( "%s", "no moves found so retrying" );
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
|
||||
*canMoveP = canMove;
|
||||
#ifdef XWFEATURE_SEARCHLIMIT
|
||||
exit:
|
||||
#endif
|
||||
LOG_RETURNF( "%s", boolToStr(result) );
|
||||
return result;
|
||||
} /* engine_findMove */
|
||||
|
||||
|
@ -1147,7 +1153,7 @@ considerScoreWordHasBlanks( EngineCtxt* engine, XP_U16 blanksLeft,
|
|||
} else {
|
||||
#ifdef XWFEATURE_BONUSALL
|
||||
if ( 0 != engine->allTilesBonus && 0 == engine->nTilesMax ) {
|
||||
XP_LOGF( "%s: adding bonus: %d becoming %d", __func__, score ,
|
||||
XP_LOGFF( "adding bonus: %d becoming %d", score,
|
||||
score + engine->allTilesBonus );
|
||||
score += engine->allTilesBonus;
|
||||
}
|
||||
|
|
|
@ -536,15 +536,25 @@ gi_copy( MPFORMAL CurGameInfo* destGI, const CurGameInfo* srcGI )
|
|||
void
|
||||
gi_setNPlayers( CurGameInfo* gi, XP_U16 nTotal, XP_U16 nHere )
|
||||
{
|
||||
XP_ASSERT( nTotal < MAX_NUM_PLAYERS );
|
||||
XP_ASSERT( nTotal <= MAX_NUM_PLAYERS );
|
||||
XP_ASSERT( nHere < nTotal );
|
||||
|
||||
gi->nPlayers = nTotal;
|
||||
|
||||
XP_U16 ii;
|
||||
for ( ii = 0; ii < nTotal; ++ii ) {
|
||||
gi->players[ii].isLocal = ii < nHere;
|
||||
XP_ASSERT( !LP_IS_ROBOT(&gi->players[ii]) );
|
||||
XP_U16 curLocal = 0;
|
||||
for ( XP_U16 ii = 0; ii < nTotal; ++ii ) {
|
||||
if ( gi->players[ii].isLocal ) {
|
||||
++curLocal;
|
||||
}
|
||||
}
|
||||
|
||||
if ( nHere != curLocal ) {
|
||||
/* This will happen when a device has more than on player. Not sure I
|
||||
handle that correctly, but don't assert for now. */
|
||||
XP_LOGFF( "nHere: %d; curLocal: %d; a problem?", nHere, curLocal );
|
||||
/* for ( XP_U16 ii = 0; ii < nTotal; ++ii ) { */
|
||||
/* gi->players[ii].isLocal = ii < nHere; */
|
||||
/* } */
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -750,6 +760,25 @@ player_timePenalty( CurGameInfo* gi, XP_U16 playerNum )
|
|||
return result;
|
||||
} /* player_timePenalty */
|
||||
|
||||
#ifdef DEBUG
|
||||
void
|
||||
game_logGI( const CurGameInfo* gi, const char* msg )
|
||||
{
|
||||
XP_LOGFF( "msg: %s", msg );
|
||||
|
||||
XP_LOGF( " nPlayers: %d", gi->nPlayers );
|
||||
for ( XP_U16 ii = 0; ii < gi->nPlayers; ++ii ) {
|
||||
const LocalPlayer* lp = &gi->players[ii];
|
||||
XP_LOGF( " player[%d]: local: %d; robotIQ: %d; name: %s", ii,
|
||||
lp->isLocal, lp->robotIQ, lp->name );
|
||||
}
|
||||
XP_LOGF( " forceChannel: %d", gi->forceChannel );
|
||||
XP_LOGF( " serverRole: %d", gi->serverRole );
|
||||
XP_LOGF( " gameID: %d", gi->gameID );
|
||||
XP_LOGF( " dictName: %s", gi->dictName );
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CPLUS
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -63,6 +63,12 @@ typedef struct CurGameInfo {
|
|||
XP_Bool confirmBTConnect; /* only used for BT */
|
||||
} CurGameInfo;
|
||||
|
||||
#ifdef DEBUG
|
||||
void game_logGI( const CurGameInfo* gi, const char* msg );
|
||||
#else
|
||||
# define game_logGI(gi, msg)
|
||||
#endif
|
||||
|
||||
#ifdef CPLUS
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -391,8 +391,7 @@ mem_stream_getSize( const XWStreamCtxt* p_sctx )
|
|||
} /* mem_stream_getSize */
|
||||
|
||||
static XP_U32
|
||||
mem_stream_getHash( const XWStreamCtxt* p_sctx, XWStreamPos pos,
|
||||
XP_Bool correct )
|
||||
mem_stream_getHash( const XWStreamCtxt* p_sctx, XWStreamPos pos )
|
||||
{
|
||||
XP_U32 hash = 0;
|
||||
const MemStreamCtxt* stream = (const MemStreamCtxt*)p_sctx;
|
||||
|
@ -404,18 +403,11 @@ mem_stream_getHash( const XWStreamCtxt* p_sctx, XWStreamPos pos,
|
|||
--len;
|
||||
}
|
||||
|
||||
LOG_HEX( ptr, len, __func__ );
|
||||
|
||||
hash = augmentHash( 0, ptr, len );
|
||||
if ( 0 != bits ) {
|
||||
XP_U8 byt = ptr[len];
|
||||
if ( correct ) {
|
||||
byt &= ~(0xFF << bits);
|
||||
} else {
|
||||
byt &= 1 << bits;
|
||||
}
|
||||
byt &= ~(0xFF << bits);
|
||||
hash = augmentHash( hash, &byt, 1 );
|
||||
LOG_HEX( &byt, 1, __func__ );
|
||||
}
|
||||
hash = finishHash( hash );
|
||||
|
||||
|
|
|
@ -270,7 +270,7 @@ model_writeToTextStream( const ModelCtxt* model, XWStreamCtxt* stream )
|
|||
void
|
||||
model_setSize( ModelCtxt* model, XP_U16 nCols )
|
||||
{
|
||||
ModelVolatiles vol = model->vol; /* save vol so we don't wipe it out */
|
||||
ModelVolatiles saveVol = model->vol; /* save vol so we don't wipe it out */
|
||||
XP_U16 oldSize = model->nCols; /* zero when called from model_make() */
|
||||
|
||||
XP_ASSERT( MAX_COLS >= nCols );
|
||||
|
@ -279,22 +279,23 @@ model_setSize( ModelCtxt* model, XP_U16 nCols )
|
|||
|
||||
model->nCols = nCols;
|
||||
model->nRows = nCols;
|
||||
model->vol = vol;
|
||||
model->vol = saveVol;
|
||||
|
||||
ModelVolatiles* vol = &model->vol;
|
||||
if ( oldSize != nCols ) {
|
||||
if ( !!model->vol.tiles ) {
|
||||
XP_FREE( model->vol.mpool, model->vol.tiles );
|
||||
if ( !!vol->tiles ) {
|
||||
XP_FREE( vol->mpool, vol->tiles );
|
||||
}
|
||||
model->vol.tiles = XP_MALLOC( model->vol.mpool, TILES_SIZE(model, nCols) );
|
||||
vol->tiles = XP_MALLOC( vol->mpool, TILES_SIZE(model, nCols) );
|
||||
}
|
||||
XP_MEMSET( model->vol.tiles, TILE_EMPTY_BIT, TILES_SIZE(model, nCols) );
|
||||
XP_MEMSET( vol->tiles, TILE_EMPTY_BIT, TILES_SIZE(model, nCols) );
|
||||
|
||||
if ( !!model->vol.stack ) {
|
||||
stack_init( model->vol.stack, model->vol.gi->inDuplicateMode );
|
||||
if ( !!vol->stack ) {
|
||||
stack_init( vol->stack, vol->gi->nPlayers, vol->gi->inDuplicateMode );
|
||||
} else {
|
||||
model->vol.stack = stack_make( MPPARM(model->vol.mpool)
|
||||
dutil_getVTManager(model->vol.dutil),
|
||||
model->vol.gi->inDuplicateMode );
|
||||
vol->stack = stack_make( MPPARM(vol->mpool)
|
||||
dutil_getVTManager(vol->dutil),
|
||||
vol->gi->nPlayers, vol->gi->inDuplicateMode );
|
||||
}
|
||||
} /* model_setSize */
|
||||
|
||||
|
@ -319,21 +320,22 @@ model_getHash( const ModelCtxt* model )
|
|||
#endif
|
||||
StackCtxt* stack = model->vol.stack;
|
||||
XP_ASSERT( !!stack );
|
||||
return stack_getHash( stack, XP_TRUE );
|
||||
return stack_getHash( stack );
|
||||
}
|
||||
|
||||
XP_Bool
|
||||
model_hashMatches( const ModelCtxt* model, const XP_U32 hash )
|
||||
{
|
||||
StackCtxt* stack = model->vol.stack;
|
||||
XP_Bool matches = hash == stack_getHash( stack, XP_TRUE )
|
||||
|| hash == stack_getHash( stack, XP_FALSE );
|
||||
XP_Bool matches = hash == stack_getHash( stack );
|
||||
XP_LOGFF( "(hash=%X) => %d", hash, matches );
|
||||
return matches;
|
||||
}
|
||||
|
||||
XP_Bool
|
||||
model_popToHash( ModelCtxt* model, const XP_U32 hash, PoolContext* pool )
|
||||
{
|
||||
LOG_FUNC();
|
||||
XP_U16 nPopped = 0;
|
||||
StackCtxt* stack = model->vol.stack;
|
||||
const XP_U16 nEntries = stack_getNEntries( stack );
|
||||
|
@ -341,13 +343,16 @@ model_popToHash( ModelCtxt* model, const XP_U32 hash, PoolContext* pool )
|
|||
XP_S16 foundAt = -1;
|
||||
|
||||
for ( XP_U16 ii = 0; ii < nEntries; ++ii ) {
|
||||
if ( hash == stack_getHash( stack, XP_TRUE )
|
||||
|| hash == stack_getHash( stack, XP_FALSE ) ) {
|
||||
XP_U32 hash1 = stack_getHash( stack );
|
||||
XP_LOGFF( "comparing %X with entry #%d %X", hash, nEntries - ii, hash1 );
|
||||
if ( hash == hash1 ) {
|
||||
foundAt = ii;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( ! stack_popEntry( stack, &entries[ii] ) ) {
|
||||
XP_LOGFF( "stack_popEntry(%d) failed", ii );
|
||||
XP_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
++nPopped;
|
||||
|
@ -360,25 +365,22 @@ model_popToHash( ModelCtxt* model, const XP_U32 hash, PoolContext* pool )
|
|||
|
||||
XP_Bool found = -1 != foundAt;
|
||||
if ( found ) {
|
||||
XP_LOGF( "%s: undoing %d turns to match hash %X", __func__,
|
||||
foundAt, hash );
|
||||
if ( 0 < foundAt ) { /* if 0, nothing to do */
|
||||
XP_LOGF( "%s: undoing %d turns to match hash %X", __func__,
|
||||
foundAt, hash );
|
||||
#ifdef DEBUG
|
||||
XP_Bool success =
|
||||
XP_Bool success =
|
||||
#endif
|
||||
model_undoLatestMoves( model, pool, foundAt, NULL, NULL );
|
||||
XP_ASSERT( success );
|
||||
model_undoLatestMoves( model, pool, foundAt, NULL, NULL );
|
||||
XP_ASSERT( success );
|
||||
}
|
||||
/* Assert not needed for long */
|
||||
XP_ASSERT( hash == stack_getHash( model->vol.stack, XP_TRUE )
|
||||
|| hash == stack_getHash( model->vol.stack, XP_FALSE ) );
|
||||
XP_ASSERT( hash == stack_getHash( model->vol.stack ) );
|
||||
} else {
|
||||
XP_ASSERT( nEntries == stack_getNEntries(stack) );
|
||||
}
|
||||
|
||||
#ifdef DEBUG_HASHING
|
||||
XP_LOGF( "%s(%X) => %s (nEntries=%d)", __func__, hash, boolToStr(found),
|
||||
nEntries );
|
||||
#endif
|
||||
|
||||
LOG_RETURNF( "%s (hash=%X, nEntries=%d)", boolToStr(found), hash, nEntries );
|
||||
return found;
|
||||
} /* model_popToHash */
|
||||
|
||||
|
@ -935,6 +937,7 @@ XP_Bool
|
|||
model_undoLatestMoves( ModelCtxt* model, PoolContext* pool,
|
||||
XP_U16 nMovesSought, XP_U16* turnP, XP_S16* moveNumP )
|
||||
{
|
||||
XP_ASSERT( 0 < nMovesSought ); /* this case isn't handled correctly */
|
||||
StackCtxt* stack = model->vol.stack;
|
||||
XP_Bool success;
|
||||
XP_S16 moveSought = !!moveNumP ? *moveNumP : -1;
|
||||
|
@ -942,9 +945,17 @@ model_undoLatestMoves( ModelCtxt* model, PoolContext* pool,
|
|||
const XP_U16 assignCount = model->vol.gi->inDuplicateMode
|
||||
? 1 : model->nPlayers;
|
||||
|
||||
if ( (0 <= moveSought && moveSought >= nStackEntries)
|
||||
|| ( nStackEntries < nMovesSought )
|
||||
|| ( nStackEntries <= assignCount ) ) {
|
||||
if ( 0 <= moveSought && moveSought >= nStackEntries ) {
|
||||
XP_LOGFF( "BAD: moveSought (%d) >= nStackEntries (%d)", moveSought,
|
||||
nStackEntries );
|
||||
success = XP_FALSE;
|
||||
} else if ( nStackEntries < nMovesSought ) {
|
||||
XP_LOGFF( "BAD: nStackEntries (%d) < nMovesSought (%d)", nStackEntries,
|
||||
nMovesSought );
|
||||
success = XP_FALSE;
|
||||
} else if ( nStackEntries <= assignCount ) {
|
||||
XP_LOGFF( "BAD: nStackEntries (%d) <= assignCount (%d)", nStackEntries,
|
||||
assignCount );
|
||||
success = XP_FALSE;
|
||||
} else {
|
||||
XP_U16 nMovesUndone = 0;
|
||||
|
@ -2104,6 +2115,14 @@ model_assignPlayerTiles( ModelCtxt* model, XP_S16 turn,
|
|||
model_addNewTiles( model, turn, &sorted );
|
||||
} /* model_assignPlayerTiles */
|
||||
|
||||
XP_S16
|
||||
model_getNextTurn( const ModelCtxt* model )
|
||||
{
|
||||
XP_S16 result = stack_getNextTurn( model->vol.stack );
|
||||
// LOG_RETURNF( "%d", result );
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
model_assignDupeTiles( ModelCtxt* model, const TrayTileSet* tiles )
|
||||
{
|
||||
|
|
|
@ -348,6 +348,8 @@ void model_packTilesUtil( ModelCtxt* model, PoolContext* pool,
|
|||
|
||||
Tile model_askBlankTile( ModelCtxt* model, XP_U16 turn, XP_U16 col, XP_U16 row);
|
||||
|
||||
XP_S16 model_getNextTurn( const ModelCtxt* model );
|
||||
|
||||
#ifdef CPLUS
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -49,6 +49,7 @@ struct StackCtxt {
|
|||
XP_U16 bitsPerTile;
|
||||
XP_U16 highWaterMark;
|
||||
XP_U16 typeBits;
|
||||
XP_U16 nPlayers;
|
||||
XP_U8 flags;
|
||||
|
||||
XP_Bool inDuplicateMode;
|
||||
|
@ -59,11 +60,14 @@ struct StackCtxt {
|
|||
|
||||
#define HAVE_FLAGS_MASK ((XP_U16)0x8000)
|
||||
|
||||
static XP_Bool popEntryImpl( StackCtxt* stack, StackEntry* entry );
|
||||
|
||||
void
|
||||
stack_init( StackCtxt* stack, XP_Bool inDuplicateMode )
|
||||
stack_init( StackCtxt* stack, XP_U16 nPlayers, XP_Bool inDuplicateMode )
|
||||
{
|
||||
stack->nEntries = stack->highWaterMark = 0;
|
||||
stack->top = START_OF_STREAM;
|
||||
stack->nPlayers = nPlayers;
|
||||
stack->inDuplicateMode = inDuplicateMode;
|
||||
|
||||
/* I see little point in freeing or shrinking stack->data. It'll get
|
||||
|
@ -72,11 +76,11 @@ stack_init( StackCtxt* stack, XP_Bool inDuplicateMode )
|
|||
|
||||
#ifdef STREAM_VERS_HASHSTREAM
|
||||
XP_U32
|
||||
stack_getHash( const StackCtxt* stack, XP_Bool correct )
|
||||
stack_getHash( const StackCtxt* stack )
|
||||
{
|
||||
XP_U32 hash = 0;
|
||||
if ( !!stack->data ) {
|
||||
hash = stream_getHash( stack->data, stack->top, correct );
|
||||
hash = stream_getHash( stack->data, stack->top );
|
||||
}
|
||||
return hash;
|
||||
} /* stack_getHash */
|
||||
|
@ -91,13 +95,14 @@ stack_setBitsPerTile( StackCtxt* stack, XP_U16 bitsPerTile )
|
|||
}
|
||||
|
||||
StackCtxt*
|
||||
stack_make( MPFORMAL VTableMgr* vtmgr, XP_Bool inDuplicateMode )
|
||||
stack_make( MPFORMAL VTableMgr* vtmgr, XP_U16 nPlayers, XP_Bool inDuplicateMode )
|
||||
{
|
||||
StackCtxt* result = (StackCtxt*)XP_MALLOC( mpool, sizeof( *result ) );
|
||||
if ( !!result ) {
|
||||
XP_MEMSET( result, 0, sizeof(*result) );
|
||||
MPASSIGN(result->mpool, mpool);
|
||||
result->vtmgr = vtmgr;
|
||||
result->nPlayers = nPlayers;
|
||||
result->inDuplicateMode = inDuplicateMode;
|
||||
}
|
||||
|
||||
|
@ -193,7 +198,7 @@ stack_copy( const StackCtxt* stack )
|
|||
stack_writeToStream( stack, stream );
|
||||
|
||||
newStack = stack_make( MPPARM(stack->mpool) stack->vtmgr,
|
||||
stack->inDuplicateMode );
|
||||
stack->nPlayers, stack->inDuplicateMode );
|
||||
stack_loadFromStream( newStack, stream );
|
||||
stack_setBitsPerTile( newStack, stack->bitsPerTile );
|
||||
stream_destroy( stream );
|
||||
|
@ -205,8 +210,8 @@ pushEntryImpl( StackCtxt* stack, const StackEntry* entry )
|
|||
{
|
||||
XWStreamCtxt* stream = stack->data;
|
||||
|
||||
XP_LOGF( "%s(typ=%s, player=%d)", __func__,
|
||||
StackMoveType_2str(entry->moveType), entry->playerNum );
|
||||
XP_LOGFF( "(typ=%s, player=%d)", StackMoveType_2str(entry->moveType),
|
||||
entry->playerNum );
|
||||
|
||||
if ( !stream ) {
|
||||
stream = mem_stream_make_raw( MPPARM(stack->mpool) stack->vtmgr );
|
||||
|
@ -258,9 +263,6 @@ pushEntryImpl( StackCtxt* stack, const StackEntry* entry )
|
|||
++stack->nEntries;
|
||||
stack->highWaterMark = stack->nEntries;
|
||||
stack->top = stream_setPos( stream, POS_WRITE, oldLoc );
|
||||
#ifdef DEBUG_HASHING
|
||||
XP_LOGSTREAM( stack->data );
|
||||
#endif
|
||||
SET_DIRTY( stack );
|
||||
} /* pushEntryImpl */
|
||||
|
||||
|
@ -268,22 +270,32 @@ static void
|
|||
pushEntry( StackCtxt* stack, const StackEntry* entry )
|
||||
{
|
||||
#ifdef DEBUG_HASHING
|
||||
XP_Bool correct = XP_TRUE;
|
||||
XP_U32 origHash = stack_getHash( stack, correct );
|
||||
XP_U32 origHash = stack_getHash( stack );
|
||||
|
||||
StackEntry prevTop;
|
||||
if ( 1 < stack->nPlayers &&
|
||||
stack_getNthEntry( stack, stack->nEntries - 1, &prevTop ) ) {
|
||||
XP_ASSERT( prevTop.playerNum != entry->playerNum );
|
||||
}
|
||||
#endif
|
||||
|
||||
pushEntryImpl( stack, entry );
|
||||
|
||||
#ifdef DEBUG_HASHING
|
||||
XP_U32 newHash = stack_getHash( stack, XP_TRUE );
|
||||
XP_U32 newHash = stack_getHash( stack );
|
||||
StackEntry lastEntry;
|
||||
if ( stack_popEntry( stack, &lastEntry ) ) {
|
||||
XP_ASSERT( origHash == stack_getHash( stack, correct ) );
|
||||
if ( popEntryImpl( stack, &lastEntry ) ) {
|
||||
XP_ASSERT( origHash == stack_getHash( stack ) );
|
||||
pushEntryImpl( stack, &lastEntry );
|
||||
XP_ASSERT( newHash == stack_getHash( stack, correct ) );
|
||||
XP_LOGF( "%s: all ok", __func__ );
|
||||
XP_ASSERT( newHash == stack_getHash( stack ) );
|
||||
XP_LOGFF( "all ok; pushed type %s for player %d into pos #%d, hash now %X (was %X)",
|
||||
StackMoveType_2str(entry->moveType), entry->playerNum,
|
||||
stack->nEntries, newHash, origHash );
|
||||
} else {
|
||||
XP_ASSERT(0);
|
||||
}
|
||||
#endif
|
||||
XP_LOGFF( "hash now %X", stack_getHash( stack ) );
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -492,8 +504,8 @@ stack_getNthEntry( StackCtxt* stack, const XP_U16 nn, StackEntry* entry )
|
|||
return found;
|
||||
} /* stack_getNthEntry */
|
||||
|
||||
XP_Bool
|
||||
stack_popEntry( StackCtxt* stack, StackEntry* entry )
|
||||
static XP_Bool
|
||||
popEntryImpl( StackCtxt* stack, StackEntry* entry )
|
||||
{
|
||||
XP_U16 nn = stack->nEntries - 1;
|
||||
XP_Bool found = stack_getNthEntry( stack, nn, entry );
|
||||
|
@ -503,12 +515,35 @@ stack_popEntry( StackCtxt* stack, StackEntry* entry )
|
|||
setCacheReadyFor( stack, nn ); /* set cachedPos by side-effect */
|
||||
stack->top = stack->cachedPos;
|
||||
}
|
||||
#ifdef DEBUG_HASHING
|
||||
XP_LOGSTREAM( stack->data );
|
||||
#endif
|
||||
return found;
|
||||
}
|
||||
|
||||
XP_Bool
|
||||
stack_popEntry( StackCtxt* stack, StackEntry* entry )
|
||||
{
|
||||
XP_Bool result = popEntryImpl( stack, entry );
|
||||
if ( result ) {
|
||||
XP_LOGFF( "hash now %X", stack_getHash( stack ) );
|
||||
}
|
||||
return result;
|
||||
} /* stack_popEntry */
|
||||
|
||||
XP_S16
|
||||
stack_getNextTurn( StackCtxt* stack )
|
||||
{
|
||||
XP_S16 result = -1;
|
||||
XP_U16 nn = stack->nEntries - 1;
|
||||
|
||||
StackEntry dummy;
|
||||
if ( stack_getNthEntry( stack, nn, &dummy ) ) {
|
||||
result = (dummy.playerNum + 1) % stack->nPlayers;
|
||||
stack_freeEntry( stack, &dummy );
|
||||
}
|
||||
|
||||
LOG_RETURNF( "%d", result );
|
||||
return result;
|
||||
}
|
||||
|
||||
XP_Bool
|
||||
stack_redo( StackCtxt* stack, StackEntry* entry )
|
||||
{
|
||||
|
|
|
@ -82,11 +82,11 @@ typedef struct StackEntry {
|
|||
|
||||
typedef struct StackCtxt StackCtxt;
|
||||
|
||||
StackCtxt* stack_make( MPFORMAL VTableMgr* vtmgr, XP_Bool inDuplicateMode );
|
||||
StackCtxt* stack_make( MPFORMAL VTableMgr* vtmgr, XP_U16 nPlayers, XP_Bool inDuplicateMode );
|
||||
void stack_destroy( StackCtxt* stack );
|
||||
|
||||
void stack_init( StackCtxt* stack, XP_Bool inDuplicateMode );
|
||||
XP_U32 stack_getHash( const StackCtxt* stack, XP_Bool correct );
|
||||
void stack_init( StackCtxt* stack, XP_U16 nPlayers, XP_Bool inDuplicateMode );
|
||||
XP_U32 stack_getHash( const StackCtxt* stack );
|
||||
void stack_setBitsPerTile( StackCtxt* stack, XP_U16 bitsPerTile );
|
||||
|
||||
void stack_loadFromStream( StackCtxt* stack, XWStreamCtxt* stream );
|
||||
|
@ -116,6 +116,7 @@ XP_U16 stack_getNEntries( const StackCtxt* stack );
|
|||
XP_Bool stack_getNthEntry( StackCtxt* stack, XP_U16 n, StackEntry* entry );
|
||||
|
||||
XP_Bool stack_popEntry( StackCtxt* stack, StackEntry* entry );
|
||||
XP_S16 stack_getNextTurn( StackCtxt* stack );
|
||||
XP_Bool stack_redo( StackCtxt* stack, StackEntry* entry );
|
||||
|
||||
void stack_freeEntry( StackCtxt* stack, StackEntry* entry );
|
||||
|
|
|
@ -234,7 +234,7 @@ logNewState( XW_State old, XW_State newst, const char* caller )
|
|||
if ( old != newst ) {
|
||||
char* oldStr = getStateStr(old);
|
||||
char* newStr = getStateStr(newst);
|
||||
XP_LOGF( "state transition %s => %s (from %s())", oldStr, newStr, caller );
|
||||
XP_LOGFF( "state transition %s => %s (from %s())", oldStr, newStr, caller );
|
||||
}
|
||||
}
|
||||
# define SETSTATE( s, st ) { \
|
||||
|
@ -679,7 +679,10 @@ server_initClientConnection( ServerCtxt* server, XWStreamCtxt* stream )
|
|||
XP_UCHAR* name;
|
||||
XP_U8 len;
|
||||
|
||||
XP_ASSERT( ii++ < MAX_NUM_PLAYERS );
|
||||
#ifdef DEBUG
|
||||
XP_ASSERT( ii < MAX_NUM_PLAYERS );
|
||||
++ii;
|
||||
#endif
|
||||
if ( !lp->isLocal ) {
|
||||
continue;
|
||||
}
|
||||
|
@ -1278,6 +1281,7 @@ mkServerStream( ServerCtxt* server )
|
|||
static XP_Bool
|
||||
makeRobotMove( ServerCtxt* server )
|
||||
{
|
||||
LOG_FUNC();
|
||||
XP_Bool result = XP_FALSE;
|
||||
XP_Bool searchComplete;
|
||||
XP_S16 turn;
|
||||
|
@ -1334,7 +1338,7 @@ makeRobotMove( ServerCtxt* server )
|
|||
XWStreamCtxt* stream = NULL;
|
||||
|
||||
XP_Bool trade = forceTrade ||
|
||||
((newMove.nTiles == 0) && canMove &&
|
||||
((newMove.nTiles == 0) && !canMove &&
|
||||
(server_countTilesInPool( server ) >= MAX_TRAY_TILES));
|
||||
|
||||
server->vol.showPrevMove = XP_TRUE;
|
||||
|
@ -1345,7 +1349,7 @@ makeRobotMove( ServerCtxt* server )
|
|||
/* trade if unable to find a move */
|
||||
if ( trade ) {
|
||||
TrayTileSet oldTiles = *model_getPlayerTiles( model, turn );
|
||||
XP_LOGF( "%s: robot trading %d tiles", __func__, oldTiles.nTiles );
|
||||
XP_LOGFF( "robot trading %d tiles", oldTiles.nTiles );
|
||||
result = server_commitTrade( server, &oldTiles, NULL );
|
||||
|
||||
/* Quick hack to fix gremlin bug where all-robot game seen none
|
||||
|
@ -1369,7 +1373,7 @@ makeRobotMove( ServerCtxt* server )
|
|||
if ( canMove || NPASSES_OK(server) ) {
|
||||
juggleMoveIfDebug( &newMove );
|
||||
model_makeTurnFromMoveInfo( model, turn, &newMove );
|
||||
XP_LOGF( "%s: robot making %d tile move", __func__, newMove.nTiles );
|
||||
XP_LOGFF( "robot making %d tile move for player %d", newMove.nTiles, turn );
|
||||
|
||||
if ( !!stream ) {
|
||||
XWStreamCtxt* wordsStream = mkServerStream( server );
|
||||
|
@ -1394,6 +1398,7 @@ makeRobotMove( ServerCtxt* server )
|
|||
XP_ASSERT( gi->players[turn].secondsUsed == 0 );
|
||||
}
|
||||
|
||||
LOG_RETURNF( "%s", boolToStr(result) );
|
||||
return result; /* always return TRUE after robot move? */
|
||||
} /* makeRobotMove */
|
||||
|
||||
|
@ -1560,7 +1565,7 @@ server_do( ServerCtxt* server )
|
|||
} else {
|
||||
XP_Bool moreToDo = XP_FALSE;
|
||||
server->serverDoing = XP_TRUE;
|
||||
XP_LOGF( "%s(): gameState: %s", __func__, getStateStr(server->nv.gameState) );
|
||||
XP_LOGFF( "gameState: %s", getStateStr(server->nv.gameState) );
|
||||
switch( server->nv.gameState ) {
|
||||
case XWSTATE_BEGIN:
|
||||
if ( server->nv.pendingRegistrations == 0 ) { /* all players on
|
||||
|
@ -2503,30 +2508,34 @@ getPlayerTime( ServerCtxt* server, XWStreamCtxt* stream, XP_U16 turn )
|
|||
static void
|
||||
nextTurn( ServerCtxt* server, XP_S16 nxtTurn )
|
||||
{
|
||||
LOG_FUNC();
|
||||
XP_LOGFF( "(nxtTurn=%d)", nxtTurn );
|
||||
CurGameInfo* gi = server->vol.gi;
|
||||
XP_U16 nPlayers = gi->nPlayers;
|
||||
XP_Bool playerTilesLeft = XP_FALSE;
|
||||
XP_S16 currentTurn = server->nv.currentTurn;
|
||||
XP_Bool moreToDo = XP_FALSE;
|
||||
|
||||
if ( nxtTurn == PICK_NEXT ) {
|
||||
XP_ASSERT( server->nv.gameState == XWSTATE_INTURN ); /* fired.... */
|
||||
if ( currentTurn >= 0 ) {
|
||||
if ( server->nv.gameState != XWSTATE_INTURN ) {
|
||||
XP_LOGFF( "doing nothing; state %s != XWSTATE_INTURN",
|
||||
getStateStr(server->nv.gameState) );
|
||||
XP_ASSERT( !moreToDo );
|
||||
goto exit;
|
||||
} else if ( currentTurn >= 0 ) {
|
||||
playerTilesLeft = tileCountsOk( server );
|
||||
if ( inDuplicateMode(server) ) {
|
||||
nxtTurn = dupe_nextTurn( server );
|
||||
} else {
|
||||
nxtTurn = (currentTurn+1) % nPlayers;
|
||||
nxtTurn = model_getNextTurn( server->vol.model );
|
||||
}
|
||||
} else {
|
||||
XP_LOGF( "%s(): turn == -1 so dropping", __func__ );
|
||||
XP_LOGFF( "%s", "turn == -1 so dropping" );
|
||||
}
|
||||
} else {
|
||||
/* We're doing an undo, and so won't bother figuring out who the
|
||||
previous turn was or how many tiles he had: it's a sure thing he
|
||||
"has" enough to be allowed to take the turn just undone. */
|
||||
playerTilesLeft = XP_TRUE;
|
||||
XP_ASSERT( nxtTurn == model_getNextTurn( server->vol.model ) );
|
||||
}
|
||||
SETSTATE( server, XWSTATE_INTURN ); /* even if game over, if undoing */
|
||||
|
||||
|
@ -2541,8 +2550,7 @@ nextTurn( ServerCtxt* server, XP_S16 nxtTurn )
|
|||
SETSTATE( server, XWSTATE_NEEDSEND_ENDGAME ); /* this is it */
|
||||
moreToDo = XP_TRUE;
|
||||
} else if ( currentTurn >= 0 ) {
|
||||
XP_LOGF( "%s: Doing nothing; waiting for server to end game",
|
||||
__func__ );
|
||||
XP_LOGFF( "%s", "Doing nothing; waiting for server to end game" );
|
||||
setTurn( server, -1 );
|
||||
/* I'm the client. Do ++nothing++. */
|
||||
}
|
||||
|
@ -2568,6 +2576,7 @@ nextTurn( ServerCtxt* server, XP_S16 nxtTurn )
|
|||
moreToDo = XP_TRUE;
|
||||
}
|
||||
|
||||
exit:
|
||||
if ( moreToDo ) {
|
||||
util_requestTime( server->vol.util );
|
||||
}
|
||||
|
@ -2657,7 +2666,7 @@ sendMoveTo( ServerCtxt* server, XP_U16 devIndex, XP_U16 turn,
|
|||
XP_ASSERT( version == server->nv.streamVersion );
|
||||
XP_U32 hash = model_getHash( server->vol.model );
|
||||
#ifdef DEBUG_HASHING
|
||||
XP_LOGF( "%s: adding hash %X", __func__, (unsigned int)hash );
|
||||
XP_LOGFF( "adding hash %X", (unsigned int)hash );
|
||||
#endif
|
||||
stream_putU32( stream, hash );
|
||||
}
|
||||
|
@ -2670,9 +2679,7 @@ sendMoveTo( ServerCtxt* server, XP_U16 devIndex, XP_U16 turn,
|
|||
stream_putBits( stream, 1, isTrade );
|
||||
|
||||
if ( isTrade ) {
|
||||
|
||||
traySetToStream( stream, tradedTiles );
|
||||
|
||||
} else {
|
||||
stream_putBits( stream, 1, legal );
|
||||
|
||||
|
@ -2700,7 +2707,7 @@ static XP_Bool
|
|||
readMoveInfo( ServerCtxt* server, XWStreamCtxt* stream,
|
||||
XP_U16* whoMovedP, XP_Bool* isTradeP,
|
||||
TrayTileSet* newTiles, TrayTileSet* tradedTiles,
|
||||
XP_Bool* legalP )
|
||||
XP_Bool* legalP, XP_Bool* badStackP )
|
||||
{
|
||||
LOG_FUNC();
|
||||
XP_Bool success = XP_TRUE;
|
||||
|
@ -2714,7 +2721,8 @@ readMoveInfo( ServerCtxt* server, XWStreamCtxt* stream,
|
|||
|| model_popToHash( server->vol.model, hashReceived, server->pool );
|
||||
|
||||
if ( !success ) {
|
||||
XP_LOGF( "%s: hash mismatch: %X not found",__func__, hashReceived );
|
||||
XP_LOGFF( "hash mismatch: %X not found", hashReceived );
|
||||
*badStackP = XP_TRUE;
|
||||
#ifdef DEBUG_HASHING
|
||||
} else {
|
||||
XP_LOGF( "%s: hash match: %X",__func__, hashReceived );
|
||||
|
@ -2750,6 +2758,7 @@ readMoveInfo( ServerCtxt* server, XWStreamCtxt* stream,
|
|||
}
|
||||
}
|
||||
}
|
||||
LOG_RETURNF( "%s", boolToStr(success) );
|
||||
return success;
|
||||
} /* readMoveInfo */
|
||||
|
||||
|
@ -2821,14 +2830,14 @@ reflectMoveAndInform( ServerCtxt* server, XWStreamCtxt* stream )
|
|||
|
||||
XP_ASSERT( gi->serverRole == SERVER_ISSERVER );
|
||||
|
||||
XP_Bool badStack = XP_FALSE;
|
||||
success = readMoveInfo( server, stream, &whoMoved, &isTrade, &newTiles,
|
||||
&tradedTiles, &isLegalMove ); /* modifies model */
|
||||
&tradedTiles, &isLegalMove, &badStack ); /* modifies model */
|
||||
XP_ASSERT( !success || isLegalMove ); /* client should always report as true */
|
||||
isLegalMove = XP_TRUE;
|
||||
|
||||
if ( success ) {
|
||||
if ( isTrade ) {
|
||||
|
||||
sendMoveToClientsExcept( server, whoMoved, XP_TRUE, &newTiles,
|
||||
&tradedTiles, sourceClientIndex );
|
||||
|
||||
|
@ -2892,6 +2901,8 @@ reflectMoveAndInform( ServerCtxt* server, XWStreamCtxt* stream )
|
|||
if ( doRequest ) {
|
||||
util_requestTime( server->vol.util );
|
||||
}
|
||||
} else if ( badStack ) {
|
||||
success = XP_TRUE; /* so we don't reject the move forever */
|
||||
}
|
||||
return success;
|
||||
} /* reflectMoveAndInform */
|
||||
|
@ -2899,7 +2910,6 @@ reflectMoveAndInform( ServerCtxt* server, XWStreamCtxt* stream )
|
|||
static XP_Bool
|
||||
reflectMove( ServerCtxt* server, XWStreamCtxt* stream )
|
||||
{
|
||||
XP_Bool moveOk;
|
||||
XP_Bool isTrade;
|
||||
XP_Bool isLegal;
|
||||
XP_U16 whoMoved;
|
||||
|
@ -2909,10 +2919,19 @@ reflectMove( ServerCtxt* server, XWStreamCtxt* stream )
|
|||
XWStreamCtxt* mvStream = NULL;
|
||||
XWStreamCtxt* wordsStream = NULL;
|
||||
|
||||
moveOk = XWSTATE_INTURN == server->nv.gameState
|
||||
&& server->nv.currentTurn >= 0
|
||||
&& readMoveInfo( server, stream, &whoMoved, &isTrade, &newTiles,
|
||||
&tradedTiles, &isLegal ); /* modifies model */
|
||||
XP_Bool badStack = XP_FALSE;
|
||||
XP_Bool moveOk = XP_FALSE;
|
||||
|
||||
if ( XWSTATE_INTURN != server->nv.gameState ) {
|
||||
XP_LOGFF( "BAD: game state: %s, not XWSTATE_INTURN", getStateStr(server->nv.gameState ) );
|
||||
} else if ( server->nv.currentTurn < 0 ) {
|
||||
XP_LOGFF( "BAD: currentTurn %d < 0", server->nv.currentTurn );
|
||||
} else if ( ! readMoveInfo( server, stream, &whoMoved, &isTrade, &newTiles,
|
||||
&tradedTiles, &isLegal, &badStack ) ) { /* modifies model */
|
||||
XP_LOGFF( "%s", "BAD: readMoveInfo() failed" );
|
||||
} else {
|
||||
moveOk = XP_TRUE;
|
||||
}
|
||||
|
||||
if ( moveOk ) {
|
||||
if ( isTrade ) {
|
||||
|
@ -2940,9 +2959,8 @@ reflectMove( ServerCtxt* server, XWStreamCtxt* stream )
|
|||
XP_ASSERT( server->vol.gi->serverRole == SERVER_ISCLIENT );
|
||||
handleIllegalWord( server, stream );
|
||||
}
|
||||
} else {
|
||||
XP_LOGF( "%s: dropping move: state=%s", __func__,
|
||||
getStateStr(server->nv.gameState ) );
|
||||
} else if ( badStack ) {
|
||||
moveOk = XP_TRUE;
|
||||
}
|
||||
return moveOk;
|
||||
} /* reflectMove */
|
||||
|
@ -3580,8 +3598,8 @@ finishMove( ServerCtxt* server, TrayTileSet* newTiles, XP_U16 turn )
|
|||
} else {
|
||||
nextTurn( server, PICK_NEXT );
|
||||
}
|
||||
XP_LOGF( "%s(): player %d now has %d tiles", __func__, turn,
|
||||
model_getNumTilesInTray( model, turn ) );
|
||||
XP_LOGFF( "player %d now has %d tiles", turn,
|
||||
model_getNumTilesInTray( model, turn ) );
|
||||
} /* finishMove */
|
||||
|
||||
/* return XP_TRUE; */
|
||||
|
@ -3815,6 +3833,9 @@ setTurn( ServerCtxt* server, XP_S16 turn )
|
|||
turn = dupe_nextTurn( server );
|
||||
}
|
||||
server->nv.currentTurn = turn;
|
||||
if ( 0 <= turn ) {
|
||||
XP_ASSERT( turn == model_getNextTurn( server->vol.model ) );
|
||||
}
|
||||
server->nv.lastMoveTime = dutil_getCurSeconds( server->vol.dutil );
|
||||
callTurnChangeListener( server );
|
||||
}
|
||||
|
@ -3860,7 +3881,7 @@ handleMoveOk( ServerCtxt* server, XWStreamCtxt* XP_UNUSED(incoming) )
|
|||
|
||||
static void
|
||||
sendUndoTo( ServerCtxt* server, XP_U16 devIndex, XP_U16 nUndone,
|
||||
XP_U16 lastUndone )
|
||||
XP_U16 lastUndone, XP_U32 newHash )
|
||||
{
|
||||
XWStreamCtxt* stream;
|
||||
CurGameInfo* gi = server->vol.gi;
|
||||
|
@ -3871,19 +3892,20 @@ sendUndoTo( ServerCtxt* server, XP_U16 devIndex, XP_U16 nUndone,
|
|||
|
||||
stream_putU16( stream, nUndone );
|
||||
stream_putU16( stream, lastUndone );
|
||||
stream_putU32( stream, newHash );
|
||||
|
||||
stream_destroy( stream );
|
||||
} /* sendUndoTo */
|
||||
|
||||
static void
|
||||
sendUndoToClientsExcept( ServerCtxt* server, XP_U16 skip,
|
||||
XP_U16 nUndone, XP_U16 lastUndone )
|
||||
sendUndoToClientsExcept( ServerCtxt* server, XP_U16 skip, XP_U16 nUndone,
|
||||
XP_U16 lastUndone, XP_U32 newHash )
|
||||
{
|
||||
XP_U16 devIndex;
|
||||
|
||||
for ( devIndex = 1; devIndex < server->nv.nDevices; ++devIndex ) {
|
||||
if ( devIndex != skip ) {
|
||||
sendUndoTo( server, devIndex, nUndone, lastUndone );
|
||||
sendUndoTo( server, devIndex, nUndone, lastUndone, newHash );
|
||||
}
|
||||
}
|
||||
} /* sendUndoToClientsExcept */
|
||||
|
@ -3891,6 +3913,7 @@ sendUndoToClientsExcept( ServerCtxt* server, XP_U16 skip,
|
|||
static XP_Bool
|
||||
reflectUndos( ServerCtxt* server, XWStreamCtxt* stream, XW_Proto code )
|
||||
{
|
||||
LOG_FUNC();
|
||||
XP_U16 nUndone;
|
||||
XP_S16 lastUndone;
|
||||
XP_U16 turn;
|
||||
|
@ -3899,23 +3922,41 @@ reflectUndos( ServerCtxt* server, XWStreamCtxt* stream, XW_Proto code )
|
|||
|
||||
nUndone = stream_getU16( stream );
|
||||
lastUndone = stream_getU16( stream );
|
||||
XP_U32 newHash = 0;
|
||||
if ( 0 < stream_getSize( stream ) ) {
|
||||
newHash = stream_getU32( stream );
|
||||
}
|
||||
XP_ASSERT( 0 == stream_getSize( stream ) );
|
||||
|
||||
if ( 0 == newHash ) {
|
||||
success = model_undoLatestMoves( model, server->pool, nUndone, &turn,
|
||||
&lastUndone );
|
||||
XP_ASSERT( turn == model_getNextTurn( model ) );
|
||||
} else {
|
||||
success = model_popToHash( model, newHash, server->pool );
|
||||
turn = model_getNextTurn( model );
|
||||
}
|
||||
|
||||
success = model_undoLatestMoves( model, server->pool, nUndone, &turn,
|
||||
&lastUndone );
|
||||
if ( success ) {
|
||||
XP_LOGFF( "popped down to %X", model_getHash( model ) );
|
||||
sortTilesIf( server, turn );
|
||||
|
||||
if ( code == XWPROTO_UNDO_INFO_CLIENT ) { /* need to inform */
|
||||
XP_U16 sourceClientIndex = getIndexForStream( server, stream );
|
||||
|
||||
sendUndoToClientsExcept( server, sourceClientIndex, nUndone,
|
||||
lastUndone );
|
||||
lastUndone, newHash );
|
||||
}
|
||||
|
||||
util_informUndo( server->vol.util );
|
||||
nextTurn( server, turn );
|
||||
} else {
|
||||
XP_LOGFF( "unable to pop to hash %X; dropping", newHash );
|
||||
// XP_ASSERT(0);
|
||||
success = XP_TRUE; /* Otherwise we'll stall */
|
||||
}
|
||||
|
||||
LOG_RETURNF( "%s", boolToStr(success) );
|
||||
return success;
|
||||
} /* reflectUndos */
|
||||
#endif
|
||||
|
@ -3923,6 +3964,7 @@ reflectUndos( ServerCtxt* server, XWStreamCtxt* stream, XW_Proto code )
|
|||
XP_Bool
|
||||
server_handleUndo( ServerCtxt* server, XP_U16 limit )
|
||||
{
|
||||
LOG_FUNC();
|
||||
XP_Bool result = XP_FALSE;
|
||||
XP_U16 lastTurnUndone = 0; /* quiet compiler good */
|
||||
XP_U16 nUndone = 0;
|
||||
|
@ -3956,13 +3998,15 @@ server_handleUndo( ServerCtxt* server, XP_U16 limit )
|
|||
|
||||
result = nUndone > 0 ;
|
||||
if ( result ) {
|
||||
XP_U32 newHash = model_getHash( model );
|
||||
#ifndef XWFEATURE_STANDALONE_ONLY
|
||||
XP_ASSERT( lastUndone != 0xFFFF );
|
||||
XP_LOGFF( "popped to hash %X", newHash );
|
||||
if ( server->vol.gi->serverRole == SERVER_ISCLIENT ) {
|
||||
sendUndoTo( server, SERVER_DEVICE, nUndone, lastUndone );
|
||||
sendUndoTo( server, SERVER_DEVICE, nUndone, lastUndone, newHash );
|
||||
} else {
|
||||
sendUndoToClientsExcept( server, SERVER_DEVICE, nUndone,
|
||||
lastUndone );
|
||||
lastUndone, newHash );
|
||||
}
|
||||
#endif
|
||||
sortTilesIf( server, lastTurnUndone );
|
||||
|
@ -3973,6 +4017,7 @@ server_handleUndo( ServerCtxt* server, XP_U16 limit )
|
|||
util_userError( server->vol.util, ERR_CANT_UNDO_TILEASSIGN );
|
||||
}
|
||||
|
||||
LOG_RETURNF( "%s", boolToStr(result) );
|
||||
return result;
|
||||
} /* server_handleUndo */
|
||||
|
||||
|
@ -4017,7 +4062,7 @@ server_receiveMessage( ServerCtxt* server, XWStreamCtxt* incoming )
|
|||
XP_Bool accepted = XP_FALSE;
|
||||
XP_Bool isServer = amServer( server );
|
||||
const XW_Proto code = readProto( server, incoming );
|
||||
XP_LOGF( "%s(code=%s)", __func__, codeToStr(code) );
|
||||
XP_LOGFF( "(code=%s)", codeToStr(code) );
|
||||
|
||||
switch ( code ) {
|
||||
case XWPROTO_DEVICE_REGISTRATION:
|
||||
|
@ -4028,6 +4073,8 @@ server_receiveMessage( ServerCtxt* server, XWStreamCtxt* incoming )
|
|||
established. */
|
||||
XP_LOGF( "%s: somebody's registering!!!", __func__ );
|
||||
accepted = handleRegistrationMsg( server, incoming );
|
||||
} else {
|
||||
XP_LOGFF( "%s", "WTF: I'm not a server!!" );
|
||||
}
|
||||
break;
|
||||
case XWPROTO_CLIENT_SETUP:
|
||||
|
@ -4046,7 +4093,8 @@ server_receiveMessage( ServerCtxt* server, XWStreamCtxt* incoming )
|
|||
if ( XWSTATE_INTURN == server->nv.gameState ) {
|
||||
accepted = reflectMoveAndInform( server, incoming );
|
||||
} else {
|
||||
XP_LOGF( "%s(): bad state: %s", __func__, getStateStr( server->nv.gameState ) );
|
||||
XP_LOGFF( "bad state: %s; dropping", getStateStr( server->nv.gameState ) );
|
||||
accepted = XP_TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -4059,6 +4107,9 @@ server_receiveMessage( ServerCtxt* server, XWStreamCtxt* incoming )
|
|||
}
|
||||
if ( accepted ) {
|
||||
nextTurn( server, PICK_NEXT );
|
||||
} else {
|
||||
accepted = XP_TRUE; /* don't stall.... */
|
||||
XP_LOGFF( "dropping move: state=%s", getStateStr(server->nv.gameState ) );
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -4106,7 +4157,8 @@ server_receiveMessage( ServerCtxt* server, XWStreamCtxt* incoming )
|
|||
XP_ASSERT( isServer == amServer( server ) ); /* caching value is ok? */
|
||||
stream_close( incoming );
|
||||
|
||||
XP_LOGF( "%s() => %d (code=%s)", __func__, accepted, codeToStr(code) );
|
||||
XP_LOGFF( "=> %d (code=%s)", accepted, codeToStr(code) );
|
||||
// XP_ASSERT( accepted ); /* do not commit!!! */
|
||||
return accepted;
|
||||
} /* server_receiveMessage */
|
||||
#endif
|
||||
|
|
|
@ -478,8 +478,8 @@ addToOutRec( SMSProto* state, ToPhoneRec* rec, SMS_CMD cmd,
|
|||
rec->msgs = XP_REALLOC( state->mpool, rec->msgs, (1 + rec->nMsgs) * sizeof(*rec->msgs) );
|
||||
rec->msgs[rec->nMsgs++] = mRec;
|
||||
rec->totalSize += len;
|
||||
XP_LOGF( "%s(): added msg to %s of len %d; total now %d", __func__, rec->phone,
|
||||
len, rec->totalSize );
|
||||
XP_LOGFF( "added msg to %s of len %d; total now %d", rec->phone, len,
|
||||
rec->totalSize );
|
||||
|
||||
if ( rec->nMsgs == 1 ) {
|
||||
rec->createSeconds = nowSeconds;
|
||||
|
@ -543,7 +543,7 @@ static void
|
|||
addMessage( SMSProto* state, const XP_UCHAR* fromPhone, int msgID, int indx,
|
||||
int count, const XP_U8* data, XP_U16 len )
|
||||
{
|
||||
XP_LOGF( "phone=%s, msgID=%d, %d/%d", fromPhone, msgID, indx, count );
|
||||
XP_LOGFF( "phone=%s, msgID=%d, %d/%d", fromPhone, msgID, indx, count );
|
||||
XP_ASSERT( 0 < len );
|
||||
MsgIDRec* msgIDRec;
|
||||
for ( ; ; ) {
|
||||
|
@ -648,7 +648,7 @@ savePartials( SMSProto* state )
|
|||
|
||||
XP_U16 newSize = stream_getSize( stream );
|
||||
if ( state->lastStoredSize == 2 && newSize == 2 ) {
|
||||
XP_LOGF( "%s(): not storing empty again", __func__ );
|
||||
XP_LOGFF( "%s", "not storing empty again" );
|
||||
} else {
|
||||
dutil_storeStream( state->dutil, KEY_PARTIALS, stream );
|
||||
state->lastStoredSize = newSize;
|
||||
|
@ -700,7 +700,7 @@ completeMsgs( SMSProto* state, SMSMsgArray* arr, const XP_UCHAR* fromPhone,
|
|||
MsgIDRec* rec = getMsgIDRec( state, fromPhone, msgID, XP_FALSE,
|
||||
&fromPhoneIndex, &msgIDIndex);
|
||||
if ( !rec ) {
|
||||
XP_LOGF( "%s(): no rec for phone %s, msgID %d", __func__, fromPhone, msgID );
|
||||
XP_LOGFF( "no rec for phone %s, msgID %d", fromPhone, msgID );
|
||||
XP_ASSERT( 0 );
|
||||
}
|
||||
|
||||
|
@ -734,8 +734,7 @@ completeMsgs( SMSProto* state, SMSMsgArray* arr, const XP_UCHAR* fromPhone,
|
|||
if ( stream_gotBytes( stream, msg.data, len ) && port == wantPort ) {
|
||||
arr = appendLocMsg( state, arr, &msg );
|
||||
} else {
|
||||
XP_LOGF( "%s(): expected port %d, got %d", __func__,
|
||||
wantPort, port );
|
||||
XP_LOGFF( "expected port %d, got %d", wantPort, port );
|
||||
XP_FREEP( state->mpool, &msg.data );
|
||||
}
|
||||
}
|
||||
|
@ -773,8 +772,7 @@ toNetMsgs( SMSProto* state, ToPhoneRec* rec, XP_Bool forceOld )
|
|||
if ( last > ii ) {
|
||||
int nMsgs = last - ii;
|
||||
if ( nMsgs > 1 ) {
|
||||
XP_LOGF( "%s(): combining %d through %d (%d msgs)", __func__, ii,
|
||||
last - 1, nMsgs );
|
||||
XP_LOGFF( "combining %d through %d (%d msgs)", ii, last - 1, nMsgs );
|
||||
}
|
||||
int len = 1 + sum + (nMsgs * 2); /* 1: len & msgID */
|
||||
SMSMsgNet newMsg = { .len = len,
|
||||
|
|
|
@ -371,9 +371,6 @@ augmentHash( XP_U32 hash, const XP_U8* ptr, XP_U16 len )
|
|||
hash += (hash << 10);
|
||||
hash ^= (hash >> 6);
|
||||
}
|
||||
#ifdef DEBUG_HASHING
|
||||
XP_LOGF( "%s: hashed %d bytes -> %X", __func__, len, (unsigned int)hash );
|
||||
#endif
|
||||
return hash;
|
||||
}
|
||||
|
||||
|
|
|
@ -88,8 +88,7 @@ typedef struct StreamCtxVTable {
|
|||
void (*m_stream_close)( XWStreamCtxt* dctx );
|
||||
|
||||
XP_U16 (*m_stream_getSize)( const XWStreamCtxt* dctx );
|
||||
XP_U32 (*m_stream_getHash)( const XWStreamCtxt* dctx, XWStreamPos pos,
|
||||
XP_Bool correct );
|
||||
XP_U32 (*m_stream_getHash)( const XWStreamCtxt* dctx, XWStreamPos pos );
|
||||
|
||||
const XP_U8* (*m_stream_getPtr)( const XWStreamCtxt* dctx );
|
||||
|
||||
|
@ -171,8 +170,8 @@ struct XWStreamCtxt {
|
|||
#define stream_getSize(sc) \
|
||||
(sc)->vtable->m_stream_getSize((sc))
|
||||
|
||||
#define stream_getHash(sc, p, c) \
|
||||
(sc)->vtable->m_stream_getHash((sc), (p), (c))
|
||||
#define stream_getHash(sc, p) \
|
||||
(sc)->vtable->m_stream_getHash((sc), (p))
|
||||
|
||||
#define stream_getPtr(sc) \
|
||||
(sc)->vtable->m_stream_getPtr((sc))
|
||||
|
|
|
@ -160,6 +160,10 @@ def process(args):
|
|||
md5Sum = getNullTermParam(header)
|
||||
print( 'header: read sum: {}'.format(md5Sum), file=sys.stderr )
|
||||
|
||||
if args.GET_SUM:
|
||||
print( '{}'.format(md5Sum), file=sys.stdout )
|
||||
sys.exit(0)
|
||||
|
||||
nodeSize = 0
|
||||
isUTF8 = False
|
||||
flags &= ~DICT_SYNONYMS_MASK
|
||||
|
@ -232,7 +236,8 @@ def mkParser():
|
|||
action = 'store_true', help = 'write tile metadata to stdout')
|
||||
parser.add_argument('--dump-msg', dest = 'DUMP_MSG', default = False,
|
||||
action = 'store_true', help = 'write header user-visible message to stdout')
|
||||
|
||||
parser.add_argument('--get-sum', dest = 'GET_SUM', default = False,
|
||||
action = 'store_true', help = 'write md5sum to stdout')
|
||||
|
||||
# [-raw | -json] [-get-sum] [-get-desc] -dict <xwdORpdb>
|
||||
|
||||
|
|
|
@ -32,9 +32,11 @@
|
|||
/* Figure out how many lines there are and how wide the widest is.
|
||||
*/
|
||||
int
|
||||
cursesask( WINDOW* window, const char* question, short numButtons,
|
||||
cursesask( WINDOW* parentWin, const char* question, short numButtons,
|
||||
const char** buttons )
|
||||
{
|
||||
XP_LOGFF( "(question=%s, parentWin=%p)", question, parentWin );
|
||||
XP_ASSERT( !!parentWin );
|
||||
WINDOW* confWin;
|
||||
int x, y, rows, row, nLines;
|
||||
int left, top;
|
||||
|
@ -46,8 +48,8 @@ cursesask( WINDOW* window, const char* question, short numButtons,
|
|||
FormatInfo fi;
|
||||
int len;
|
||||
|
||||
getmaxyx( window, y, x);
|
||||
getbegyx( window, top, left );
|
||||
getmaxyx( parentWin, y, x);
|
||||
getbegyx( parentWin, top, left );
|
||||
|
||||
measureAskText( question, x-2, &fi );
|
||||
len = fi.maxLen;
|
||||
|
@ -122,8 +124,8 @@ cursesask( WINDOW* window, const char* question, short numButtons,
|
|||
delwin( confWin );
|
||||
|
||||
/* this leaves a ghost line, but I can't figure out a better way. */
|
||||
wtouchln( window, (y/2)-(nLines/2), ASK_HEIGHT + rows - 1, 1 );
|
||||
wrefresh( window );
|
||||
wtouchln( parentWin, (y/2)-(nLines/2), ASK_HEIGHT + rows - 1, 1 );
|
||||
wrefresh( parentWin );
|
||||
return curSelButton;
|
||||
} /* cursesask */
|
||||
|
||||
|
|
|
@ -84,6 +84,54 @@ static void setupBoard( CursesBoardGlobals* bGlobals );
|
|||
static void initMenus( CursesBoardGlobals* bGlobals );
|
||||
static void disposeDraw( CursesBoardGlobals* bGlobals );
|
||||
|
||||
#ifdef KEYBOARD_NAV
|
||||
static bool handleLeft( void* closure, int key );
|
||||
static bool handleRight( void* closure, int key );
|
||||
static bool handleUp( void* closure, int key );
|
||||
static bool handleDown( void* closure, int key );
|
||||
static bool handleClose( void* closure, int key );
|
||||
#endif
|
||||
#ifdef ALT_KEYS_WORKING
|
||||
static bool handleAltLeft( void* closure, int key );
|
||||
static bool handleAltRight( void* closure, int key );
|
||||
static bool handleAltUp( void* closure, int key );
|
||||
static bool handleAltDown( void* closure, int key );
|
||||
#endif
|
||||
static bool handleJuggle( void* closure, int key );
|
||||
static bool handleHide( void* closure, int key );
|
||||
/* static bool handleResend( void* closure, int key ); */
|
||||
static bool handleSpace( void* closure, int key );
|
||||
static bool handleRet( void* closure, int key );
|
||||
static bool handleShowVals( void* closure, int key );
|
||||
static bool handleHint( void* closure, int key );
|
||||
static bool handleCommit( void* closure, int key );
|
||||
static bool handleFlip( void* closure, int key );
|
||||
static bool handleToggleValues( void* closure, int key );
|
||||
static bool handleBackspace( void* closure, int key );
|
||||
static bool handleUndo( void* closure, int key );
|
||||
static bool handleReplace( void* closure, int key );
|
||||
#ifdef CURSES_SMALL_SCREEN
|
||||
static bool handleRootKeyShow( void* closure, int key );
|
||||
static bool handleRootKeyHide( void* closure, int key );
|
||||
#endif
|
||||
static bool handleInvite( void* closure, int key );
|
||||
|
||||
static void relay_connd_curses( void* closure, XP_UCHAR* const room,
|
||||
XP_Bool reconnect, XP_U16 devOrder,
|
||||
XP_Bool allHere, XP_U16 nMissing );
|
||||
static void relay_status_curses( void* closure, CommsRelayState state );
|
||||
static void relay_error_curses( void* closure, XWREASON relayErr );
|
||||
static XP_Bool relay_sendNoConn_curses( const XP_U8* msg, XP_U16 len,
|
||||
const XP_UCHAR* msgNo,
|
||||
const XP_UCHAR* relayID, void* closure );
|
||||
static void curses_countChanged( void* closure, XP_U16 newCount );
|
||||
static XP_U32 curses_getFlags( void* closure );
|
||||
#ifdef RELAY_VIA_HTTP
|
||||
static void relay_requestJoin_curses( void* closure, const XP_UCHAR* devID,
|
||||
const XP_UCHAR* room, XP_U16 nPlayersHere,
|
||||
XP_U16 nPlayersTotal, XP_U16 seed, XP_U16 lang );
|
||||
#endif
|
||||
|
||||
CursesBoardState*
|
||||
cb_init( CursesAppGlobals* aGlobals, LaunchParams* params,
|
||||
CursesMenuState* menuState, OnGameSaved onGameSaved )
|
||||
|
@ -106,6 +154,18 @@ cb_resized( CursesBoardState* cbState, const cb_dims* dims )
|
|||
}
|
||||
}
|
||||
|
||||
static gint
|
||||
inviteIdle( gpointer data )
|
||||
{
|
||||
CursesBoardGlobals* bGlobals = (CursesBoardGlobals*)data;
|
||||
LaunchParams* params = bGlobals->cGlobals.params;
|
||||
if ( !!params->connInfo.relay.inviteeRelayIDs
|
||||
|| !!params->connInfo.sms.inviteePhones ) {
|
||||
handleInvite( bGlobals, 0 );
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
cb_open( CursesBoardState* cbState, sqlite3_int64 rowid, const cb_dims* dims )
|
||||
{
|
||||
|
@ -119,6 +179,9 @@ cb_open( CursesBoardState* cbState, sqlite3_int64 rowid, const cb_dims* dims )
|
|||
if ( !!cGlobals->game.comms ) {
|
||||
comms_resendAll( cGlobals->game.comms, COMMS_CONN_NONE, XP_FALSE );
|
||||
}
|
||||
if ( bGlobals->cGlobals.params->forceInvite ) {
|
||||
(void)ADD_ONETIME_IDLE( inviteIdle, bGlobals);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -157,54 +220,6 @@ cb_newFor( CursesBoardState* cbState, const NetLaunchInfo* nli,
|
|||
setupBoard( bGlobals );
|
||||
}
|
||||
|
||||
#ifdef KEYBOARD_NAV
|
||||
static bool handleLeft( void* closure, int key );
|
||||
static bool handleRight( void* closure, int key );
|
||||
static bool handleUp( void* closure, int key );
|
||||
static bool handleDown( void* closure, int key );
|
||||
static bool handleClose( void* closure, int key );
|
||||
#endif
|
||||
#ifdef ALT_KEYS_WORKING
|
||||
static bool handleAltLeft( void* closure, int key );
|
||||
static bool handleAltRight( void* closure, int key );
|
||||
static bool handleAltUp( void* closure, int key );
|
||||
static bool handleAltDown( void* closure, int key );
|
||||
#endif
|
||||
static bool handleJuggle( void* closure, int key );
|
||||
static bool handleHide( void* closure, int key );
|
||||
/* static bool handleResend( void* closure, int key ); */
|
||||
static bool handleSpace( void* closure, int key );
|
||||
static bool handleRet( void* closure, int key );
|
||||
static bool handleShowVals( void* closure, int key );
|
||||
static bool handleHint( void* closure, int key );
|
||||
static bool handleCommit( void* closure, int key );
|
||||
static bool handleFlip( void* closure, int key );
|
||||
static bool handleToggleValues( void* closure, int key );
|
||||
static bool handleBackspace( void* closure, int key );
|
||||
static bool handleUndo( void* closure, int key );
|
||||
static bool handleReplace( void* closure, int key );
|
||||
static bool handleInvite( void* closure, int key );
|
||||
#ifdef CURSES_SMALL_SCREEN
|
||||
static bool handleRootKeyShow( void* closure, int key );
|
||||
static bool handleRootKeyHide( void* closure, int key );
|
||||
#endif
|
||||
|
||||
static void relay_connd_curses( void* closure, XP_UCHAR* const room,
|
||||
XP_Bool reconnect, XP_U16 devOrder,
|
||||
XP_Bool allHere, XP_U16 nMissing );
|
||||
static void relay_status_curses( void* closure, CommsRelayState state );
|
||||
static void relay_error_curses( void* closure, XWREASON relayErr );
|
||||
static XP_Bool relay_sendNoConn_curses( const XP_U8* msg, XP_U16 len,
|
||||
const XP_UCHAR* msgNo,
|
||||
const XP_UCHAR* relayID, void* closure );
|
||||
static void curses_countChanged( void* closure, XP_U16 newCount );
|
||||
static XP_U32 curses_getFlags( void* closure );
|
||||
#ifdef RELAY_VIA_HTTP
|
||||
static void relay_requestJoin_curses( void* closure, const XP_UCHAR* devID,
|
||||
const XP_UCHAR* room, XP_U16 nPlayersHere,
|
||||
XP_U16 nPlayersTotal, XP_U16 seed, XP_U16 lang );
|
||||
#endif
|
||||
|
||||
const MenuList g_allMenuList[] = {
|
||||
{ handleLeft, "Left", "H", 'H' },
|
||||
{ handleRight, "Right", "L", 'L' },
|
||||
|
@ -556,7 +571,7 @@ setupBoard( CursesBoardGlobals* bGlobals )
|
|||
|
||||
static CursesBoardGlobals*
|
||||
initNoDraw( CursesBoardState* cbState, sqlite3_int64 rowid,
|
||||
const CurGameInfo* gi, const CommsAddrRec* addr )
|
||||
const CurGameInfo* gi, const CommsAddrRec* returnAddr )
|
||||
{
|
||||
LOG_FUNC();
|
||||
CursesBoardGlobals* result = commonInit( cbState, rowid, gi );
|
||||
|
@ -576,7 +591,7 @@ initNoDraw( CursesBoardState* cbState, sqlite3_int64 rowid,
|
|||
cGlobals->cp.robotTradePct = params->robotTradePct;
|
||||
#endif
|
||||
|
||||
if ( linuxOpenGame( cGlobals, &result->procs, addr ) ) {
|
||||
if ( linuxOpenGame( cGlobals, &result->procs, returnAddr ) ) {
|
||||
result = ref( result );
|
||||
} else {
|
||||
disposeBoard( result );
|
||||
|
@ -594,15 +609,17 @@ enableDraw( CursesBoardGlobals* bGlobals, const cb_dims* dims )
|
|||
getmaxyx( bGlobals->boardWin, bGlobals->winHeight, bGlobals->winWidth );
|
||||
|
||||
CommonGlobals* cGlobals = &bGlobals->cGlobals;
|
||||
cGlobals->draw = cursesDrawCtxtMake( bGlobals->boardWin );
|
||||
board_setDraw( cGlobals->game.board, cGlobals->draw );
|
||||
if( !!bGlobals->boardWin ) {
|
||||
cGlobals->draw = cursesDrawCtxtMake( bGlobals->boardWin );
|
||||
board_setDraw( cGlobals->game.board, cGlobals->draw );
|
||||
}
|
||||
|
||||
setupBoard( bGlobals );
|
||||
}
|
||||
|
||||
static CursesBoardGlobals*
|
||||
findOrOpen( CursesBoardState* cbState, sqlite3_int64 rowid,
|
||||
const CurGameInfo* gi, const CommsAddrRec* addr )
|
||||
const CurGameInfo* gi, const CommsAddrRec* returnAddr )
|
||||
{
|
||||
CursesBoardGlobals* result = NULL;
|
||||
for ( GSList* iter = cbState->games;
|
||||
|
@ -614,7 +631,7 @@ findOrOpen( CursesBoardState* cbState, sqlite3_int64 rowid,
|
|||
}
|
||||
|
||||
if ( !result ) {
|
||||
result = initNoDraw( cbState, rowid, gi, addr );
|
||||
result = initNoDraw( cbState, rowid, gi, returnAddr );
|
||||
if ( !!result ) {
|
||||
setupBoard( result );
|
||||
cbState->games = g_slist_append( cbState->games, result );
|
||||
|
@ -884,10 +901,12 @@ curses_util_notifyDupStatus( XW_UtilCtxt* uc,
|
|||
}
|
||||
|
||||
static void
|
||||
curses_util_informUndo( XW_UtilCtxt* XP_UNUSED(uc))
|
||||
curses_util_informUndo( XW_UtilCtxt* uc )
|
||||
{
|
||||
XP_ASSERT(0);
|
||||
LOG_FUNC();
|
||||
CursesBoardGlobals* bGlobals = (CursesBoardGlobals*)uc->closure;
|
||||
if ( !!bGlobals->boardWin ) {
|
||||
ca_inform( bGlobals->boardWin, "informUndo(): undo was done" );
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1162,6 +1181,31 @@ handleReplace( void* closure, int XP_UNUSED(key) )
|
|||
return XP_TRUE;
|
||||
} /* handleReplace */
|
||||
|
||||
static bool
|
||||
inviteList( CommonGlobals* cGlobals, CommsAddrRec* addr, GSList* invitees,
|
||||
bool useRelay )
|
||||
{
|
||||
bool haveAddressees = !!invitees;
|
||||
if ( haveAddressees ) {
|
||||
LaunchParams* params = cGlobals->params;
|
||||
for ( int ii = 0; ii < g_slist_length(invitees); ++ii ) {
|
||||
const XP_U16 nPlayers = 1;
|
||||
gint forceChannel = ii + 1;
|
||||
NetLaunchInfo nli = {0};
|
||||
nli_init( &nli, cGlobals->gi, addr, nPlayers, forceChannel );
|
||||
if ( useRelay ) {
|
||||
uint64_t inviteeRelayID = (uint64_t)g_slist_nth_data( invitees, ii );
|
||||
relaycon_invite( params, (XP_U32)inviteeRelayID, NULL, &nli );
|
||||
} else {
|
||||
const gchar* inviteePhone = (const gchar*)g_slist_nth_data( invitees, ii );
|
||||
linux_sms_invite( params, &nli, inviteePhone,
|
||||
params->connInfo.sms.port );
|
||||
}
|
||||
}
|
||||
}
|
||||
return haveAddressees;
|
||||
}
|
||||
|
||||
static bool
|
||||
handleInvite( void* closure, int XP_UNUSED(key) )
|
||||
{
|
||||
|
@ -1184,13 +1228,10 @@ handleInvite( void* closure, int XP_UNUSED(key) )
|
|||
/* Invite first based on an invitee provided. Otherwise, fall back to
|
||||
doing a send-to-self. Let the recipient code reject a duplicate if
|
||||
the user so desires. */
|
||||
} else if ( !!params->connInfo.sms.inviteePhone ) {
|
||||
/* These should both be settable/derivable */
|
||||
linux_sms_invite( params, &nli, params->connInfo.sms.inviteePhone,
|
||||
params->connInfo.sms.port );
|
||||
} else if ( 0 != params->connInfo.relay.inviteeRelayID ) {
|
||||
relaycon_invite( params, params->connInfo.relay.inviteeRelayID, NULL, &nli );
|
||||
|
||||
} else if ( inviteList( cGlobals, &addr, params->connInfo.sms.inviteePhones, false ) ) {
|
||||
/* do nothing */
|
||||
} else if ( inviteList( cGlobals, &addr, params->connInfo.relay.inviteeRelayIDs, true ) ) {
|
||||
/* do nothing */
|
||||
/* Try sending to self, using the phone number or relayID of this device */
|
||||
} else if ( addr_hasType( &addr, COMMS_CONN_SMS ) ) {
|
||||
linux_sms_invite( params, &nli, addr.u.sms.phone, addr.u.sms.port );
|
||||
|
@ -1202,6 +1243,7 @@ handleInvite( void* closure, int XP_UNUSED(key) )
|
|||
} else {
|
||||
ca_inform( bGlobals->boardWin, "Cannot invite via relayID or by \"sms phone\"." );
|
||||
}
|
||||
LOG_RETURNF( "%s", "TRUE" );
|
||||
return XP_TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -190,16 +190,18 @@ static void
|
|||
initCurses( CursesAppGlobals* aGlobals )
|
||||
{
|
||||
/* ncurses man page says most apps want this sequence */
|
||||
aGlobals->mainWin = initscr();
|
||||
cbreak();
|
||||
noecho();
|
||||
nonl();
|
||||
intrflush(stdscr, FALSE);
|
||||
keypad(stdscr, TRUE); /* effects wgetch only? */
|
||||
if ( !aGlobals->cag.params->closeStdin ) {
|
||||
aGlobals->mainWin = initscr();
|
||||
cbreak();
|
||||
noecho();
|
||||
nonl();
|
||||
intrflush(stdscr, FALSE);
|
||||
keypad(stdscr, TRUE); /* effects wgetch only? */
|
||||
|
||||
getmaxyx( aGlobals->mainWin, aGlobals->winHeight, aGlobals->winWidth );
|
||||
XP_LOGF( "%s: getmaxyx()->w:%d; h:%d", __func__, aGlobals->winWidth,
|
||||
aGlobals->winHeight );
|
||||
getmaxyx( aGlobals->mainWin, aGlobals->winHeight, aGlobals->winWidth );
|
||||
XP_LOGF( "%s: getmaxyx()->w:%d; h:%d", __func__, aGlobals->winWidth,
|
||||
aGlobals->winHeight );
|
||||
}
|
||||
|
||||
/* globals->statusLine = height - MENU_WINDOW_HEIGHT - 1; */
|
||||
/* globals->menuWin = newwin( MENU_WINDOW_HEIGHT, width, */
|
||||
|
@ -258,11 +260,10 @@ handleOpenGame( void* closure, int XP_UNUSED(key) )
|
|||
LOG_FUNC();
|
||||
CursesAppGlobals* aGlobals = (CursesAppGlobals*)closure;
|
||||
const GameInfo* gi = cgl_getSel( aGlobals->gameList );
|
||||
if ( !!gi ) {
|
||||
cb_dims dims;
|
||||
figureDims( aGlobals, &dims );
|
||||
cb_open( aGlobals->cbState, gi->rowid, &dims );
|
||||
}
|
||||
XP_ASSERT( !!gi );
|
||||
cb_dims dims;
|
||||
figureDims( aGlobals, &dims );
|
||||
cb_open( aGlobals->cbState, gi->rowid, &dims );
|
||||
return XP_TRUE;
|
||||
}
|
||||
|
||||
|
@ -1152,29 +1153,37 @@ onJoined( void* closure, const XP_UCHAR* connname, XWHostID hid )
|
|||
#endif
|
||||
|
||||
static void
|
||||
relayInviteReceivedCurses( void* closure, NetLaunchInfo* invite )
|
||||
inviteReceivedCurses( CursesAppGlobals* aGlobals, const NetLaunchInfo* invite,
|
||||
const CommsAddrRec* returnAddr )
|
||||
{
|
||||
CursesAppGlobals* aGlobals = (CursesAppGlobals*)closure;
|
||||
|
||||
sqlite3_int64 rowids[1];
|
||||
int nRowIDs = VSIZE(rowids);
|
||||
getRowsForGameID( aGlobals->cag.params->pDb, invite->gameID, rowids, &nRowIDs );
|
||||
bool doIt = 0 == nRowIDs;
|
||||
if ( ! doIt ) {
|
||||
if ( ! doIt && !!aGlobals->mainWin ) {
|
||||
const gchar* question = "Duplicate invitation received. Accept anyway?";
|
||||
const char* buttons[] = { "Yes", "No" };
|
||||
doIt = 0 == cursesask( aGlobals->mainWin, question, VSIZE(buttons), buttons );
|
||||
}
|
||||
if ( doIt ) {
|
||||
CommsAddrRec returnAddr = {0};
|
||||
nli_makeAddrRec( invite, &returnAddr );
|
||||
|
||||
cb_dims dims;
|
||||
figureDims( aGlobals, &dims );
|
||||
cb_newFor( aGlobals->cbState, invite, &returnAddr, &dims );
|
||||
cb_newFor( aGlobals->cbState, invite, returnAddr, &dims );
|
||||
} else {
|
||||
XP_LOGFF( "Not accepting duplicate invitation (nRowIDs(gameID=%d) was %d",
|
||||
invite->gameID, nRowIDs );
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
relayInviteReceivedCurses( void* closure, NetLaunchInfo* invite )
|
||||
{
|
||||
CursesAppGlobals* aGlobals = (CursesAppGlobals*)closure;
|
||||
CommsAddrRec addr = {0};
|
||||
nli_makeAddrRec( invite, &addr );
|
||||
inviteReceivedCurses( aGlobals, invite, &addr );
|
||||
}
|
||||
|
||||
static void
|
||||
cursesGotBuf( void* closure, const CommsAddrRec* addr,
|
||||
const XP_U8* buf, XP_U16 len )
|
||||
|
@ -1210,20 +1219,7 @@ smsInviteReceivedCurses( void* closure, const NetLaunchInfo* nli,
|
|||
const CommsAddrRec* returnAddr )
|
||||
{
|
||||
CursesAppGlobals* aGlobals = (CursesAppGlobals*)closure;
|
||||
/* LaunchParams* params = aGlobals->cag.params; */
|
||||
/* CurGameInfo gi = {0}; */
|
||||
/* gi_copy( MPPARM(params->mpool) &gi, ¶ms->pgi ); */
|
||||
|
||||
/* gi_setNPlayers( &gi, invite->nPlayersT, invite->nPlayersH ); */
|
||||
/* gi.gameID = invite->gameID; */
|
||||
/* gi.dictLang = invite->lang; */
|
||||
/* gi.forceChannel = invite->forceChannel; */
|
||||
/* gi.serverRole = SERVER_ISCLIENT; /\* recipient of invitation is client *\/ */
|
||||
/* replaceStringIfDifferent( params->mpool, &gi.dictName, invite->dict ); */
|
||||
|
||||
cb_dims dims;
|
||||
figureDims( aGlobals, &dims );
|
||||
cb_newFor( aGlobals->cbState, nli, returnAddr, &dims );
|
||||
inviteReceivedCurses( aGlobals, nli, returnAddr );
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1286,10 +1282,9 @@ cursesDevIDReceived( void* closure, const XP_UCHAR* devID,
|
|||
XP_U16 maxInterval )
|
||||
{
|
||||
CursesAppGlobals* aGlobals = (CursesAppGlobals*)closure;
|
||||
// CommonGlobals* cGlobals = &globals->cGlobals;
|
||||
sqlite3* pDb = aGlobals->cag.params->pDb;
|
||||
if ( !!devID ) {
|
||||
XP_LOGF( "%s(devID=%s)", __func__, devID );
|
||||
XP_LOGF( "%s(devID='%s')", __func__, devID );
|
||||
|
||||
/* If we already have one, make sure it's the same! Else store. */
|
||||
gchar buf[64];
|
||||
|
@ -1297,10 +1292,12 @@ cursesDevIDReceived( void* closure, const XP_UCHAR* devID,
|
|||
&& 0 == strcmp( buf, devID );
|
||||
if ( !have ) {
|
||||
db_store( pDb, KEY_RDEVID, devID );
|
||||
XP_LOGFF( "storing new devid: %s", devID );
|
||||
cgl_draw( aGlobals->gameList );
|
||||
}
|
||||
(void)g_timeout_add_seconds( maxInterval, keepalive_timer, aGlobals );
|
||||
} else {
|
||||
XP_LOGF( "%s: bad relayid", __func__ );
|
||||
XP_LOGFF( "%s", "bad relayid" );
|
||||
db_remove( pDb, KEY_RDEVID );
|
||||
|
||||
DevIDType typ;
|
||||
|
@ -1512,7 +1509,9 @@ cursesmain( XP_Bool XP_UNUSED(isServer), LaunchParams* params )
|
|||
#endif
|
||||
|
||||
if ( 0 == cgl_getNGames( g_globals.gameList ) ) {
|
||||
handleNewGame( &g_globals, 0 );
|
||||
if ( params->forceNewGame ) {
|
||||
handleNewGame( &g_globals, 0 );
|
||||
}
|
||||
} else {
|
||||
/* Always open a game. Without that it won't attempt to connect and
|
||||
stalls are likely in the test script case at least. If that's
|
||||
|
|
|
@ -74,7 +74,7 @@ openGamesDB( const char* dbName )
|
|||
const char* createValuesStr =
|
||||
"CREATE TABLE pairs ( key TEXT UNIQUE,value TEXT )";
|
||||
result = sqlite3_exec( pDb, createValuesStr, NULL, NULL, NULL );
|
||||
XP_LOGF( "sqlite3_exec=>%d", result );
|
||||
XP_LOGFF( "sqlite3_exec=>%d", result );
|
||||
XP_USE( result );
|
||||
|
||||
return pDb;
|
||||
|
@ -84,14 +84,14 @@ void
|
|||
closeGamesDB( sqlite3* pDb )
|
||||
{
|
||||
sqlite3_close( pDb );
|
||||
XP_LOGF( "%s finished", __func__ );
|
||||
LOG_RETURN_VOID();
|
||||
}
|
||||
|
||||
static sqlite3_int64
|
||||
writeBlobColumnData( const XP_U8* data, gsize len, XP_U16 strVersion, sqlite3* pDb,
|
||||
sqlite3_int64 curRow, const char* column )
|
||||
{
|
||||
XP_LOGF( "%s(col=%s)", __func__, column );
|
||||
XP_LOGFF( "(col=%s)", column );
|
||||
int result;
|
||||
char buf[256];
|
||||
char* query;
|
||||
|
@ -114,14 +114,14 @@ writeBlobColumnData( const XP_U8* data, gsize len, XP_U16 strVersion, sqlite3* p
|
|||
assertPrintResult( pDb, result, SQLITE_OK );
|
||||
result = sqlite3_step( stmt );
|
||||
if ( SQLITE_DONE != result ) {
|
||||
XP_LOGF( "%s: sqlite3_step => %s", __func__, sqliteErr2str( result ) );
|
||||
XP_LOGFF( "sqlite3_step => %s", sqliteErr2str( result ) );
|
||||
XP_ASSERT(0);
|
||||
}
|
||||
XP_USE( result );
|
||||
|
||||
if ( newGame ) { /* new row; need to insert blob first */
|
||||
curRow = sqlite3_last_insert_rowid( pDb );
|
||||
XP_LOGF( "%s: new rowid: %lld", __func__, curRow );
|
||||
XP_LOGFF( "new rowid: %lld", curRow );
|
||||
}
|
||||
|
||||
sqlite3_blob* blob;
|
||||
|
@ -173,7 +173,7 @@ writeToDB( XWStreamCtxt* stream, void* closure )
|
|||
|
||||
if ( newGame ) { /* new row; need to insert blob first */
|
||||
cGlobals->rowid = selRow;
|
||||
XP_LOGF( "%s(): new game at row %lld", __func__, selRow );
|
||||
XP_LOGFF( "new game at row %lld", selRow );
|
||||
} else {
|
||||
assert( selRow == cGlobals->rowid );
|
||||
}
|
||||
|
@ -315,13 +315,13 @@ summarize( CommonGlobals* cGlobals )
|
|||
gchar* query = g_strdup_printf( "UPDATE games SET %s WHERE rowid=%lld",
|
||||
vals, cGlobals->rowid );
|
||||
g_free( vals );
|
||||
XP_LOGF( "query: %s", query );
|
||||
XP_LOGFF( "query: %s", query );
|
||||
sqlite3_stmt* stmt = NULL;
|
||||
int result = sqlite3_prepare_v2( cGlobals->params->pDb, query, -1, &stmt, NULL );
|
||||
assertPrintResult( cGlobals->params->pDb, result, SQLITE_OK );
|
||||
result = sqlite3_step( stmt );
|
||||
if ( SQLITE_DONE != result ) {
|
||||
XP_LOGF( "sqlite3_step=>%s", sqliteErr2str( result ) );
|
||||
XP_LOGFF( "sqlite3_step=>%s", sqliteErr2str( result ) );
|
||||
XP_ASSERT( 0 );
|
||||
}
|
||||
sqlite3_finalize( stmt );
|
||||
|
@ -351,7 +351,7 @@ listGames( sqlite3* pDb )
|
|||
{
|
||||
sqlite3_int64* data = g_malloc( sizeof( *data ) );
|
||||
*data = sqlite3_column_int64( ppStmt, 0 );
|
||||
XP_LOGF( "%s: got a row; id=%lld", __func__, *data );
|
||||
XP_LOGFF( "got a row; id=%lld", *data );
|
||||
list = g_slist_append( list, data );
|
||||
}
|
||||
break;
|
||||
|
@ -538,6 +538,7 @@ loadGame( XWStreamCtxt* stream, sqlite3* pDb, sqlite3_int64 rowid )
|
|||
return loadBlobColumn( stream, pDb, rowid, "game" );
|
||||
}
|
||||
|
||||
/* Used for rematch only. But do I need it? */
|
||||
void
|
||||
saveInviteAddrs( XWStreamCtxt* stream, sqlite3* pDb, sqlite3_int64 rowid )
|
||||
{
|
||||
|
@ -703,7 +704,7 @@ assertPrintResult( sqlite3* pDb, int XP_UNUSED_DBG(result), int expect )
|
|||
int code = sqlite3_errcode( pDb );
|
||||
XP_ASSERT( code == result ); /* do I need to pass it? */
|
||||
if ( code != expect ) {
|
||||
XP_LOGF( "sqlite3 error: %s", sqlite3_errmsg( pDb ) );
|
||||
XP_LOGFF( "sqlite3 error: %s", sqlite3_errmsg( pDb ) );
|
||||
XP_ASSERT(0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -665,7 +665,7 @@ on_board_window_shown( GtkWidget* XP_UNUSED(widget), GtkGameGlobals* globals )
|
|||
if ( loadInviteAddrs( stream, cGlobals->params->pDb, cGlobals->rowid ) ) {
|
||||
CommsAddrRec addr = {0};
|
||||
addrFromStream( &addr, stream );
|
||||
comms_setAddr( cGlobals->game.comms, &addr );
|
||||
comms_augmentHostAddr( cGlobals->game.comms, &addr );
|
||||
|
||||
XP_U16 nRecs = stream_getU8( stream );
|
||||
XP_LOGF( "%s: got invite info: %d records", __func__, nRecs );
|
||||
|
@ -818,30 +818,12 @@ new_game_impl( GtkGameGlobals* globals, XP_Bool fireConnDlg )
|
|||
#endif
|
||||
};
|
||||
|
||||
if ( !game_reset( MEMPOOL &cGlobals->game, gi,
|
||||
cGlobals->util,
|
||||
&cGlobals->cp, &procs ) ) {
|
||||
/* if ( NULL == globals->draw ) { */
|
||||
/* globals->draw = (GtkDrawCtx*)gtkDrawCtxtMake( globals->drawing_area, */
|
||||
/* globals ); */
|
||||
/* } */
|
||||
/* game_makeNewGame( MEMPOOL &globals->cGlobals.game, gi, */
|
||||
/* globals->cGlobals.params->util, */
|
||||
/* (DrawCtx*)globals->draw, */
|
||||
/* &globals->cGlobals.cp, &procs, */
|
||||
/* globals->cGlobals.params->gameSeed ); */
|
||||
/* ModelCtxt* model = globals->cGlobals.game.model; */
|
||||
/* if ( NULL == model_getDictionary( model ) ) { */
|
||||
/* DictionaryCtxt* dict = */
|
||||
/* linux_dictionary_make( MEMPOOL globals->cGlobals.params, */
|
||||
/* gi->dictName, XP_TRUE ); */
|
||||
/* model_setDictionary( model, dict ); */
|
||||
/* } */
|
||||
}
|
||||
(void)game_reset( MEMPOOL &cGlobals->game, gi, cGlobals->util,
|
||||
&cGlobals->cp, &procs );
|
||||
|
||||
#ifndef XWFEATURE_STANDALONE_ONLY
|
||||
if ( !!cGlobals->game.comms ) {
|
||||
comms_setAddr( cGlobals->game.comms, &addr );
|
||||
comms_augmentHostAddr( cGlobals->game.comms, &addr );
|
||||
} else if ( gi->serverRole != SERVER_STANDALONE ) {
|
||||
XP_ASSERT(0);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* -*- compile-command: "make MEMDEBUG=TRUE -j3"; -*- */
|
||||
/*
|
||||
* Copyright 2000 - 2011 by Eric House (xwords@eehouse.org). All rights
|
||||
* Copyright 2000 - 2020 by Eric House (xwords@eehouse.org). All rights
|
||||
* reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
|
@ -151,6 +151,7 @@ ensureLocalPlayerNames( LaunchParams* XP_UNUSED_DBG(params), CurGameInfo* gi )
|
|||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
static bool
|
||||
canMakeFromGI( const CurGameInfo* gi )
|
||||
{
|
||||
|
@ -171,12 +172,14 @@ canMakeFromGI( const CurGameInfo* gi )
|
|||
result = result && (haveDict || allHaveDicts);
|
||||
|
||||
LOG_RETURNF( "%d", result );
|
||||
XP_ASSERT( result );
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool
|
||||
linuxOpenGame( CommonGlobals* cGlobals, const TransportProcs* procs,
|
||||
const CommsAddrRec* addrP )
|
||||
const CommsAddrRec* returnAddrP )
|
||||
{
|
||||
LOG_FUNC();
|
||||
XWStreamCtxt* stream = NULL;
|
||||
|
@ -204,6 +207,7 @@ linuxOpenGame( CommonGlobals* cGlobals, const TransportProcs* procs,
|
|||
if ( !!stream ) {
|
||||
if ( NULL == cGlobals->dict ) {
|
||||
cGlobals->dict = makeDictForStream( cGlobals, stream );
|
||||
XP_ASSERT( !!cGlobals->dict );
|
||||
}
|
||||
|
||||
opened = game_makeFromStream( MEMPOOL stream, &cGlobals->game,
|
||||
|
@ -215,16 +219,9 @@ linuxOpenGame( CommonGlobals* cGlobals, const TransportProcs* procs,
|
|||
stream_destroy( stream );
|
||||
}
|
||||
|
||||
if ( !opened && canMakeFromGI( cGlobals->gi ) ) {
|
||||
if ( !opened /* && canMakeFromGI( cGlobals->gi )*/ ) {
|
||||
opened = XP_TRUE;
|
||||
|
||||
#ifdef XWFEATURE_RELAY
|
||||
/* if ( addr.conType == COMMS_CONN_RELAY ) { */
|
||||
/* XP_ASSERT( !!params->connInfo.relay.relayName ); */
|
||||
/* globals->cGlobals.defaultServerName */
|
||||
/* = params->connInfo.relay.relayName; */
|
||||
/* } */
|
||||
#endif
|
||||
game_makeNewGame( MEMPOOL &cGlobals->game, cGlobals->gi,
|
||||
cGlobals->util, cGlobals->draw,
|
||||
&cGlobals->cp, procs
|
||||
|
@ -233,70 +230,98 @@ linuxOpenGame( CommonGlobals* cGlobals, const TransportProcs* procs,
|
|||
#endif
|
||||
);
|
||||
|
||||
CommsAddrRec addr = !!addrP ? *addrP : cGlobals->addr;
|
||||
// addr.conType = params->conType;
|
||||
CommsConnType typ;
|
||||
for ( XP_U32 st = 0; addr_iter( &addr, &typ, &st ); ) {
|
||||
if ( params->commsDisableds[typ][0] ) {
|
||||
comms_setAddrDisabled( cGlobals->game.comms, typ, XP_FALSE, XP_TRUE );
|
||||
}
|
||||
if ( params->commsDisableds[typ][1] ) {
|
||||
comms_setAddrDisabled( cGlobals->game.comms, typ, XP_TRUE, XP_TRUE );
|
||||
}
|
||||
switch( typ ) {
|
||||
bool savedGame = false;
|
||||
CommsAddrRec returnAddr = {0};
|
||||
if ( !!returnAddrP ) {
|
||||
returnAddr = *returnAddrP;
|
||||
CommsConnType typ;
|
||||
for ( XP_U32 st = 0; addr_iter( &returnAddr, &typ, &st ); ) {
|
||||
if ( params->commsDisableds[typ][0] ) {
|
||||
comms_setAddrDisabled( cGlobals->game.comms, typ, XP_FALSE, XP_TRUE );
|
||||
}
|
||||
if ( params->commsDisableds[typ][1] ) {
|
||||
comms_setAddrDisabled( cGlobals->game.comms, typ, XP_TRUE, XP_TRUE );
|
||||
}
|
||||
switch( typ ) {
|
||||
#ifdef XWFEATURE_RELAY
|
||||
case COMMS_CONN_RELAY:
|
||||
/* addr.u.ip_relay.ipAddr = 0; */
|
||||
/* addr.u.ip_relay.port = params->connInfo.relay.defaultSendPort; */
|
||||
/* addr.u.ip_relay.seeksPublicRoom = params->connInfo.relay.seeksPublicRoom; */
|
||||
/* addr.u.ip_relay.advertiseRoom = params->connInfo.relay.advertiseRoom; */
|
||||
/* XP_STRNCPY( addr.u.ip_relay.hostName, params->connInfo.relay.relayName, */
|
||||
/* sizeof(addr.u.ip_relay.hostName) - 1 ); */
|
||||
/* XP_STRNCPY( addr.u.ip_relay.invite, params->connInfo.relay.invite, */
|
||||
/* sizeof(addr.u.ip_relay.invite) - 1 ); */
|
||||
break;
|
||||
case COMMS_CONN_RELAY:
|
||||
/* addr.u.ip_relay.ipAddr = 0; */
|
||||
/* addr.u.ip_relay.port = params->connInfo.relay.defaultSendPort; */
|
||||
/* addr.u.ip_relay.seeksPublicRoom = params->connInfo.relay.seeksPublicRoom; */
|
||||
/* addr.u.ip_relay.advertiseRoom = params->connInfo.relay.advertiseRoom; */
|
||||
/* XP_STRNCPY( addr.u.ip_relay.hostName, params->connInfo.relay.relayName, */
|
||||
/* sizeof(addr.u.ip_relay.hostName) - 1 ); */
|
||||
/* XP_STRNCPY( addr.u.ip_relay.invite, params->connInfo.relay.invite, */
|
||||
/* sizeof(addr.u.ip_relay.invite) - 1 ); */
|
||||
break;
|
||||
#endif
|
||||
#ifdef XWFEATURE_BLUETOOTH
|
||||
case COMMS_CONN_BT:
|
||||
XP_ASSERT( sizeof(addr.u.bt.btAddr)
|
||||
>= sizeof(params->connInfo.bt.hostAddr));
|
||||
XP_MEMCPY( &addr.u.bt.btAddr, ¶ms->connInfo.bt.hostAddr,
|
||||
sizeof(params->connInfo.bt.hostAddr) );
|
||||
break;
|
||||
case COMMS_CONN_BT:
|
||||
XP_ASSERT( sizeof(returnAddr.u.bt.btAddr)
|
||||
>= sizeof(params->connInfo.bt.hostAddr));
|
||||
XP_MEMCPY( &returnAddr.u.bt.btAddr, ¶ms->connInfo.bt.hostAddr,
|
||||
sizeof(params->connInfo.bt.hostAddr) );
|
||||
break;
|
||||
#endif
|
||||
#ifdef XWFEATURE_IP_DIRECT
|
||||
case COMMS_CONN_IP_DIRECT:
|
||||
XP_STRNCPY( addr.u.ip.hostName_ip, params->connInfo.ip.hostName,
|
||||
sizeof(addr.u.ip.hostName_ip) - 1 );
|
||||
addr.u.ip.port_ip = params->connInfo.ip.port;
|
||||
break;
|
||||
case COMMS_CONN_IP_DIRECT:
|
||||
XP_STRNCPY( returnAddr.u.ip.hostName_ip, params->connInfo.ip.hostName,
|
||||
sizeof(addr.u.ip.hostName_ip) - 1 );
|
||||
returnAddr.u.ip.port_ip = params->connInfo.ip.port;
|
||||
break;
|
||||
#endif
|
||||
#ifdef XWFEATURE_SMS
|
||||
case COMMS_CONN_SMS:
|
||||
XP_LOGF( "%s(): SMS is on at least", __func__ );
|
||||
/* No! Don't overwrite what may be a return address with local
|
||||
stuff */
|
||||
/* XP_STRNCPY( addr.u.sms.phone, params->connInfo.sms.phone, */
|
||||
/* sizeof(addr.u.sms.phone) - 1 ); */
|
||||
/* addr.u.sms.port = params->connInfo.sms.port; */
|
||||
break;
|
||||
case COMMS_CONN_SMS:
|
||||
XP_LOGF( "%s(): SMS is on at least", __func__ );
|
||||
/* No! Don't overwrite what may be a return address with local
|
||||
stuff */
|
||||
/* XP_STRNCPY( addr.u.sms.phone, params->connInfo.sms.phone, */
|
||||
/* sizeof(addr.u.sms.phone) - 1 ); */
|
||||
/* addr.u.sms.port = params->connInfo.sms.port; */
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
XP_ASSERT( !!cGlobals->dict );
|
||||
model_setDictionary( cGlobals->game.model, cGlobals->dict );
|
||||
setSquareBonuses( cGlobals );
|
||||
model_setPlayerDicts( cGlobals->game.model, &cGlobals->dicts );
|
||||
|
||||
/* Need to save in order to have a valid selRow for the first send */
|
||||
linuxSaveGame( cGlobals );
|
||||
savedGame = true;
|
||||
|
||||
#ifndef XWFEATURE_STANDALONE_ONLY
|
||||
/* This may trigger network activity */
|
||||
if ( !!cGlobals->game.comms ) {
|
||||
comms_setAddr( cGlobals->game.comms, &addr );
|
||||
/* If this is to be a relay connected game, tell it so. Otherwise
|
||||
let the invitation process and receipt of messages populate
|
||||
comms' addressbook */
|
||||
if ( cGlobals->gi->serverRole != SERVER_STANDALONE
|
||||
&& addr_hasType( ¶ms->addr, COMMS_CONN_RELAY ) ) {
|
||||
|
||||
if ( ! savedGame ) {
|
||||
linuxSaveGame( cGlobals );
|
||||
savedGame = true;
|
||||
}
|
||||
CommsAddrRec addr = {0};
|
||||
comms_getInitialAddr( &addr, params->connInfo.relay.relayName,
|
||||
params->connInfo.relay.defaultSendPort );
|
||||
XP_MEMCPY( addr.u.ip_relay.invite, params->connInfo.relay.invite,
|
||||
1 + XP_STRLEN(params->connInfo.relay.invite) );
|
||||
addr.u.ip_relay.seeksPublicRoom = params->connInfo.relay.seeksPublicRoom;
|
||||
addr.u.ip_relay.advertiseRoom = params->connInfo.relay.advertiseRoom;
|
||||
comms_augmentHostAddr( cGlobals->game.comms, &addr ); /* sends stuff */
|
||||
}
|
||||
|
||||
if ( !!returnAddrP ) {
|
||||
/* This may trigger network activity */
|
||||
CommsCtxt* comms = cGlobals->game.comms;
|
||||
if ( !!comms ) {
|
||||
comms_augmentHostAddr( cGlobals->game.comms, &returnAddr );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -314,7 +339,7 @@ linuxOpenGame( CommonGlobals* cGlobals, const TransportProcs* procs,
|
|||
#ifndef XWFEATURE_STANDALONE_ONLY
|
||||
DeviceRole serverRole = cGlobals->gi->serverRole;
|
||||
XP_LOGF( "%s(): server role: %d", __func__, serverRole );
|
||||
if ( serverRole == SERVER_ISCLIENT ) {
|
||||
if ( /*!!returnAddrP && */serverRole == SERVER_ISCLIENT ) {
|
||||
tryConnectToServer( cGlobals );
|
||||
}
|
||||
#endif
|
||||
|
@ -328,7 +353,7 @@ linuxOpenGame( CommonGlobals* cGlobals, const TransportProcs* procs,
|
|||
linuxSaveGame( cGlobals ); /* again, to include address etc. */
|
||||
}
|
||||
return opened;
|
||||
}
|
||||
} /* linuxOpenGame */
|
||||
|
||||
#ifdef USE_SQLITE
|
||||
XWStreamCtxt*
|
||||
|
@ -746,7 +771,7 @@ secondTimerFired( gpointer data )
|
|||
XP_U16 undoRatio = cGlobals->params->undoRatio;
|
||||
if ( 0 != undoRatio ) {
|
||||
if ( (XP_RANDOM() % 1000) < undoRatio ) {
|
||||
XP_LOGF( "%s: calling server_handleUndo", __func__ );
|
||||
XP_LOGFF( "%s", "calling server_handleUndo()" );
|
||||
if ( server_handleUndo( game->server, 1 ) ) {
|
||||
board_draw( game->board );
|
||||
}
|
||||
|
@ -840,6 +865,8 @@ typedef enum {
|
|||
,CMD_SMSFAILPCT
|
||||
,CMD_DROPRCVSMS
|
||||
,CMD_FORCECHANNEL
|
||||
,CMD_FORCE_GAME
|
||||
,CMD_FORCE_INVITE
|
||||
|
||||
#ifdef XWFEATURE_CROSSHAIRS
|
||||
,CMD_NOCROSSHAIRS
|
||||
|
@ -968,6 +995,8 @@ static CmdInfoRec CmdInfoRecs[] = {
|
|||
,{ CMD_SMSFAILPCT, true, "sms-fail-pct", "percent of sms sends, randomly chosen, never arrive" }
|
||||
,{ CMD_DROPRCVSMS, false, "drop-receive-sms", "start new games with sms receive disabled" }
|
||||
,{ CMD_FORCECHANNEL, true, "force-channel", "force (clients) to use this hostid/channel" }
|
||||
,{ CMD_FORCE_GAME, false, "force-game", "if there's no game on launch, create one" }
|
||||
,{ CMD_FORCE_INVITE, false, "force-invite", "if we can, send an invitation by relay or sms" }
|
||||
|
||||
#ifdef XWFEATURE_CROSSHAIRS
|
||||
,{ CMD_NOCROSSHAIRS, false, "hide-crosshairs",
|
||||
|
@ -1484,7 +1513,7 @@ linux_reset( void* closure )
|
|||
#endif
|
||||
|
||||
XP_S16
|
||||
linux_send( const XP_U8* buf, XP_U16 buflen, const XP_UCHAR* XP_UNUSED_DBG(msgNo),
|
||||
linux_send( const XP_U8* buf, XP_U16 buflen, const XP_UCHAR* msgNo,
|
||||
const CommsAddrRec* addrRec, CommsConnType conType, XP_U32 gameID,
|
||||
void* closure )
|
||||
{
|
||||
|
@ -1540,7 +1569,7 @@ linux_send( const XP_U8* buf, XP_U16 buflen, const XP_UCHAR* XP_UNUSED_DBG(msgNo
|
|||
|
||||
// use serverphone if I'm a client, else hope one's provided (this is
|
||||
// a reply)
|
||||
nSent = linux_sms_send( cGlobals->params, buf, buflen,
|
||||
nSent = linux_sms_send( cGlobals->params, buf, buflen, msgNo,
|
||||
addrRec->u.sms.phone, addrRec->u.sms.port,
|
||||
gameID );
|
||||
}
|
||||
|
@ -2715,7 +2744,8 @@ main( int argc, char** argv )
|
|||
addr_addType( &mainParams.addr, COMMS_CONN_SMS );
|
||||
break;
|
||||
case CMD_INVITEE_SMSNUMBER:
|
||||
mainParams.connInfo.sms.inviteePhone = optarg;
|
||||
mainParams.connInfo.sms.inviteePhones =
|
||||
g_slist_append( mainParams.connInfo.sms.inviteePhones, optarg );
|
||||
addr_addType( &mainParams.addr, COMMS_CONN_SMS );
|
||||
break;
|
||||
case CMD_SMSPORT:
|
||||
|
@ -2815,7 +2845,9 @@ main( int argc, char** argv )
|
|||
mainParams.bonusFile = optarg;
|
||||
break;
|
||||
case CMD_INVITEE_RELAYID:
|
||||
mainParams.connInfo.relay.inviteeRelayID = atoi(optarg);
|
||||
mainParams.connInfo.relay.inviteeRelayIDs =
|
||||
g_slist_append(mainParams.connInfo.relay.inviteeRelayIDs,
|
||||
(void*)(uint64_t)atoi(optarg));
|
||||
addr_addType( &mainParams.addr, COMMS_CONN_RELAY );
|
||||
break;
|
||||
#endif
|
||||
|
@ -2891,6 +2923,14 @@ main( int argc, char** argv )
|
|||
mainParams.pgi.forceChannel = atoi( optarg );
|
||||
break;
|
||||
|
||||
case CMD_FORCE_GAME:
|
||||
mainParams.forceNewGame = true;
|
||||
break;
|
||||
|
||||
case CMD_FORCE_INVITE:
|
||||
mainParams.forceInvite = true;
|
||||
break;
|
||||
|
||||
#ifdef XWFEATURE_CROSSHAIRS
|
||||
case CMD_NOCROSSHAIRS:
|
||||
mainParams.hideCrosshairs = XP_TRUE;
|
||||
|
|
|
@ -71,7 +71,7 @@ typedef struct _LinSMSData {
|
|||
static gboolean retrySend( gpointer data );
|
||||
static void sendOrRetry( LaunchParams* params, SMSMsgArray* arr, SMS_CMD cmd,
|
||||
XP_U16 waitSecs, const XP_UCHAR* phone, XP_U16 port,
|
||||
XP_U32 gameID );
|
||||
XP_U32 gameID, const XP_UCHAR* msgNo );
|
||||
static gint check_for_files( gpointer data );
|
||||
static gint check_for_files_once( gpointer data );
|
||||
|
||||
|
@ -107,7 +107,7 @@ unlock_queue( LinSMSData* storage )
|
|||
|
||||
static XP_S16
|
||||
write_fake_sms( LaunchParams* params, const void* buf, XP_U16 buflen,
|
||||
const XP_UCHAR* phone, XP_U16 port )
|
||||
const XP_UCHAR* msgNo, const XP_UCHAR* phone, XP_U16 port )
|
||||
{
|
||||
XP_S16 nSent;
|
||||
XP_U16 pct = XP_RANDOM() % 100;
|
||||
|
@ -115,15 +115,12 @@ write_fake_sms( LaunchParams* params, const void* buf, XP_U16 buflen,
|
|||
|
||||
if ( skipWrite ) {
|
||||
nSent = buflen;
|
||||
XP_LOGF( "%s(): dropping sms msg of len %d to phone %s", __func__,
|
||||
nSent, phone );
|
||||
XP_LOGFF( "dropping sms msg of len %d to phone %s", nSent, phone );
|
||||
} else {
|
||||
LinSMSData* storage = getStorage( params );
|
||||
XP_LOGF( "%s(phone=%s, port=%d, len=%d)", __func__, phone,
|
||||
port, buflen );
|
||||
XP_LOGFF( "(phone=%s, port=%d, len=%d)", phone, port, buflen );
|
||||
|
||||
XP_ASSERT( !!storage );
|
||||
char path[256];
|
||||
|
||||
lock_queue( storage );
|
||||
|
||||
|
@ -131,19 +128,23 @@ write_fake_sms( LaunchParams* params, const void* buf, XP_U16 buflen,
|
|||
gchar* str64 = g_base64_encode( buf, buflen );
|
||||
#endif
|
||||
|
||||
char path[256];
|
||||
formatQueuePath( phone, port, path, sizeof(path) );
|
||||
|
||||
/* Random-number-based name is fine, as we pick based on age. */
|
||||
int rint = makeRandomInt();
|
||||
g_mkdir_with_parents( path, 0777 ); /* just in case */
|
||||
int len = strlen( path );
|
||||
snprintf( &path[len], sizeof(path)-len, "/%u", rint );
|
||||
|
||||
int rint = makeRandomInt();
|
||||
if ( !!msgNo ) {
|
||||
snprintf( &path[len], sizeof(path)-len, "/%s_%u", msgNo, rint );
|
||||
} else {
|
||||
snprintf( &path[len], sizeof(path)-len, "/%u", rint );
|
||||
}
|
||||
XP_UCHAR sms[buflen*2]; /* more like (buflen*4/3) */
|
||||
XP_U16 smslen = sizeof(sms);
|
||||
binToSms( sms, &smslen, buf, buflen );
|
||||
XP_ASSERT( smslen == strlen(sms) );
|
||||
XP_LOGF( "%s: writing msg to %s", __func__, path );
|
||||
XP_LOGFF( "writing msg to %s", path );
|
||||
|
||||
#ifdef DEBUG
|
||||
XP_ASSERT( !strcmp( str64, sms ) );
|
||||
|
@ -194,7 +195,9 @@ decodeAndDelete( LinSMSData* storage, const gchar* name,
|
|||
char phone[32];
|
||||
int port;
|
||||
int matched = sscanf( contents, ADDR_FMT, phone, &port );
|
||||
if ( 2 == matched ) {
|
||||
if ( 2 != matched ) {
|
||||
XP_LOGFF( "ERROR: found %d matches instead of 2", matched );
|
||||
} else {
|
||||
gchar* eol = strstr( contents, "\n" );
|
||||
*eol = '\0';
|
||||
XP_ASSERT( !*eol );
|
||||
|
@ -202,7 +205,7 @@ decodeAndDelete( LinSMSData* storage, const gchar* name,
|
|||
*strstr(eol, "\n" ) = '\0';
|
||||
|
||||
XP_U16 inlen = strlen(eol); /* skip \n */
|
||||
XP_LOGF( "%s(): decoding message from file %s", __func__, name );
|
||||
XP_LOGFF( "decoding message from file %s", name );
|
||||
XP_U8 out[inlen];
|
||||
XP_U16 outlen = sizeof(out);
|
||||
XP_Bool valid = smsToBin( out, &outlen, eol, inlen );
|
||||
|
@ -212,12 +215,9 @@ decodeAndDelete( LinSMSData* storage, const gchar* name,
|
|||
nRead = outlen;
|
||||
addr_setType( addr, COMMS_CONN_SMS );
|
||||
XP_STRNCPY( addr->u.sms.phone, phone, sizeof(addr->u.sms.phone) );
|
||||
XP_LOGF( "%s: message came from phone: %s, port: %d", __func__,
|
||||
phone, port );
|
||||
XP_LOGFF( " message came from phone: %s, port: %d", phone, port );
|
||||
addr->u.sms.port = port;
|
||||
}
|
||||
} else {
|
||||
XP_ASSERT(0);
|
||||
}
|
||||
|
||||
g_free( contents );
|
||||
|
@ -272,7 +272,7 @@ linux_sms_init( LaunchParams* params, const gchar* myPhone, XP_U16 myPort,
|
|||
storage->protoState = smsproto_init( MPPARM(params->mpool) params->dutil );
|
||||
|
||||
formatQueuePath( myPhone, myPort, storage->myQueue, sizeof(storage->myQueue) );
|
||||
XP_LOGF( "%s: my queue: %s", __func__, storage->myQueue );
|
||||
XP_LOGFF( " my queue: %s", storage->myQueue );
|
||||
storage->myPort = params->connInfo.sms.port;
|
||||
|
||||
(void)g_mkdir_with_parents( storage->myQueue, 0777 );
|
||||
|
@ -296,20 +296,21 @@ linux_sms_invite( LaunchParams* params, const NetLaunchInfo* nli,
|
|||
= smsproto_prepOutbound( storage->protoState, INVITE, nli->gameID, nli,
|
||||
sizeof(*nli), toPhone, toPort, XP_FALSE,
|
||||
&waitSecs );
|
||||
sendOrRetry( params, arr, INVITE, waitSecs, toPhone, toPort, nli->gameID );
|
||||
sendOrRetry( params, arr, INVITE, waitSecs, toPhone, toPort,
|
||||
nli->gameID, "invite" );
|
||||
}
|
||||
|
||||
XP_S16
|
||||
linux_sms_send( LaunchParams* params, const XP_U8* buf,
|
||||
XP_U16 buflen, const XP_UCHAR* phone, XP_U16 port,
|
||||
XP_U32 gameID )
|
||||
XP_U16 buflen, const XP_UCHAR* msgNo, const XP_UCHAR* phone,
|
||||
XP_U16 port, XP_U32 gameID )
|
||||
{
|
||||
LinSMSData* storage = getStorage( params );
|
||||
XP_U16 waitSecs;
|
||||
SMSMsgArray* arr = smsproto_prepOutbound( storage->protoState, DATA, gameID,
|
||||
buf, buflen, phone, port,
|
||||
XP_TRUE, &waitSecs );
|
||||
sendOrRetry( params, arr, DATA, waitSecs, phone, port, gameID );
|
||||
sendOrRetry( params, arr, DATA, waitSecs, phone, port, gameID, msgNo );
|
||||
return buflen;
|
||||
}
|
||||
|
||||
|
@ -318,19 +319,20 @@ typedef struct _RetryClosure {
|
|||
SMS_CMD cmd;
|
||||
XP_U16 port;
|
||||
XP_U32 gameID;
|
||||
XP_UCHAR msgNo[32];
|
||||
XP_UCHAR phone[32];
|
||||
} RetryClosure;
|
||||
|
||||
static void
|
||||
sendOrRetry( LaunchParams* params, SMSMsgArray* arr, SMS_CMD cmd,
|
||||
XP_U16 waitSecs, const XP_UCHAR* phone, XP_U16 port,
|
||||
XP_U32 gameID )
|
||||
XP_U32 gameID, const XP_UCHAR* msgNo )
|
||||
{
|
||||
if ( !!arr ) {
|
||||
for ( XP_U16 ii = 0; ii < arr->nMsgs; ++ii ) {
|
||||
const SMSMsgNet* msg = &arr->u.msgsNet[ii];
|
||||
// doSend( params, msg->data, msg->len, phone, port, gameID );
|
||||
(void)write_fake_sms( params, msg->data, msg->len,
|
||||
(void)write_fake_sms( params, msg->data, msg->len, msgNo,
|
||||
phone, port );
|
||||
}
|
||||
|
||||
|
@ -341,6 +343,7 @@ sendOrRetry( LaunchParams* params, SMSMsgArray* arr, SMS_CMD cmd,
|
|||
sizeof(*closure) );
|
||||
closure->params = params;
|
||||
XP_STRCAT( closure->phone, phone );
|
||||
XP_STRCAT( closure->msgNo, msgNo );
|
||||
closure->port = port;
|
||||
closure->gameID = gameID;
|
||||
closure->cmd = cmd;
|
||||
|
@ -359,7 +362,7 @@ retrySend( gpointer data )
|
|||
closure->phone, closure->port,
|
||||
XP_TRUE, &waitSecs );
|
||||
sendOrRetry( closure->params, arr, closure->cmd, waitSecs, closure->phone,
|
||||
closure->port, closure->gameID );
|
||||
closure->port, closure->gameID, closure->msgNo );
|
||||
XP_FREEP( closure->params->mpool, &closure );
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -400,8 +403,7 @@ check_for_files_once( gpointer data )
|
|||
snprintf( fullPath, sizeof(fullPath), "%s/%s", storage->myQueue, name );
|
||||
int err = stat( fullPath, &statbuf );
|
||||
if ( err != 0 ) {
|
||||
XP_LOGF( "%s(); %d from stat (error: %s)", __func__,
|
||||
err, strerror(errno) );
|
||||
XP_LOGF( "%d from stat (error: %s)", err, strerror(errno) );
|
||||
XP_ASSERT( 0 );
|
||||
} else {
|
||||
XP_Bool replace = !oldestFile[0]; /* always replace empty/unset :-) */
|
||||
|
@ -416,7 +418,7 @@ check_for_files_once( gpointer data )
|
|||
if ( replace ) {
|
||||
oldestModTime = statbuf.st_mtim;
|
||||
if ( !!oldestFile[0] ) {
|
||||
XP_LOGF( "%s(): replacing %s with older %s", __func__, oldestFile, name );
|
||||
XP_LOGFF( "replacing %s with older %s", oldestFile, name );
|
||||
}
|
||||
snprintf( oldestFile, sizeof(oldestFile), "%s", name );
|
||||
}
|
||||
|
|
|
@ -39,8 +39,8 @@ typedef struct _SMSProcs {
|
|||
|
||||
void linux_sms_init( LaunchParams* params, const gchar* phone,
|
||||
XP_U16 port, const SMSProcs* procs, void* procClosure );
|
||||
XP_S16 linux_sms_send( LaunchParams* params, const XP_U8* buf,
|
||||
XP_U16 buflen, const XP_UCHAR* phone, XP_U16 port,
|
||||
XP_S16 linux_sms_send( LaunchParams* params, const XP_U8* buf, XP_U16 buflen,
|
||||
const XP_UCHAR* msgNo, const XP_UCHAR* phone, XP_U16 port,
|
||||
XP_U32 gameID );
|
||||
void linux_sms_invite( LaunchParams* params, const NetLaunchInfo* nli,
|
||||
const gchar* phone, int port );
|
||||
|
|
|
@ -42,16 +42,16 @@
|
|||
static void
|
||||
debugf( const char* format, va_list ap )
|
||||
{
|
||||
struct timeval tv;
|
||||
struct timezone tz;
|
||||
gettimeofday( &tv, &tz );
|
||||
struct timespec tp = {0};
|
||||
int res = clock_gettime( CLOCK_REALTIME, &tp );
|
||||
XP_ASSERT( 0 == res );
|
||||
struct tm* timp = localtime( &tp.tv_sec );
|
||||
|
||||
struct tm* timp = localtime( &tv.tv_sec );
|
||||
fprintf( stderr, "<%d:%lx> %.2d:%.2d:%.2d:%03ld ", getpid(),
|
||||
pthread_self(), timp->tm_hour, timp->tm_min, timp->tm_sec,
|
||||
tp.tv_nsec / 1000000 );
|
||||
|
||||
fprintf( stderr, "<%d:%lx>%.2d:%.2d:%.2d:", getpid(),
|
||||
pthread_self(), timp->tm_hour, timp->tm_min, timp->tm_sec );
|
||||
|
||||
vfprintf(stderr, format, ap );
|
||||
vfprintf( stderr, format, ap );
|
||||
fprintf( stderr, "%c", '\n' );
|
||||
}
|
||||
|
||||
|
@ -67,7 +67,7 @@ linux_debugf( const char* format, ... )
|
|||
void
|
||||
linux_debugff( const char* func, const char* file, const char* fmt, ...)
|
||||
{
|
||||
gchar* header = g_strdup_printf( "%s/%s(): %s", file, func, fmt );
|
||||
gchar* header = g_strdup_printf( "%s:%s(): %s", file, func, fmt );
|
||||
|
||||
va_list ap;
|
||||
va_start( ap, fmt );
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#endif
|
||||
|
||||
#include <sqlite3.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "comtypes.h"
|
||||
#include "util.h"
|
||||
|
@ -111,6 +112,8 @@ typedef struct LaunchParams {
|
|||
XP_Bool useHTTP;
|
||||
XP_Bool runSMSTest;
|
||||
XP_Bool noHTTPAuto;
|
||||
bool forceNewGame;
|
||||
bool forceInvite;
|
||||
XP_U16 splitPackets;
|
||||
XP_U16 chatsInterval; /* 0 means disabled */
|
||||
XP_U16 askTimeout;
|
||||
|
@ -139,7 +142,7 @@ typedef struct LaunchParams {
|
|||
short defaultSendPort;
|
||||
XP_Bool seeksPublicRoom;
|
||||
XP_Bool advertiseRoom;
|
||||
XP_U32 inviteeRelayID;
|
||||
GSList* inviteeRelayIDs;
|
||||
} relay;
|
||||
#endif
|
||||
#ifdef XWFEATURE_BLUETOOTH
|
||||
|
@ -157,7 +160,7 @@ typedef struct LaunchParams {
|
|||
#ifdef XWFEATURE_SMS
|
||||
struct {
|
||||
const char* myPhone;
|
||||
const char* inviteePhone;
|
||||
GSList* inviteePhones;
|
||||
int port;
|
||||
} sms;
|
||||
#endif
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/* -*- compile-command: "make MEMDEBUG=TRUE -j3"; -*- */
|
||||
/*
|
||||
* Copyright 2013 by Eric House (xwords@eehouse.org). All rights reserved.
|
||||
* Copyright 2013 - 2020 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
|
||||
|
@ -29,6 +30,7 @@
|
|||
#include "comtypes.h"
|
||||
#include "gamesdb.h"
|
||||
#include "gsrcwrap.h"
|
||||
#include "dbgutil.h"
|
||||
|
||||
#define MAX_MOVE_CHECK_MS ((XP_U16)(1000 * 60 * 60 * 24))
|
||||
#define RELAY_API_PROTO "http"
|
||||
|
@ -154,7 +156,7 @@ write_callback(void *contents, size_t size, size_t nmemb, void* data)
|
|||
ws->curSize = 1L;
|
||||
}
|
||||
|
||||
XP_LOGF( "%s(size=%zd, nmemb=%zd)", __func__, size, nmemb );
|
||||
XP_LOGFF( "(size=%zd, nmemb=%zd)", size, nmemb );
|
||||
size_t oldLen = ws->curSize;
|
||||
const size_t newLength = size * nmemb;
|
||||
XP_ASSERT( (oldLen + newLength) > 0 );
|
||||
|
@ -184,7 +186,7 @@ mkJsonParams( CURL* curl, va_list ap )
|
|||
const char* asStr = json_object_get_string( params );
|
||||
char* curl_params = curl_easy_escape( curl, asStr, strlen(asStr) );
|
||||
gchar* result = g_strdup_printf( "params=%s", curl_params );
|
||||
XP_LOGF( "%s: adding: params=%s (%s)", __func__, asStr, curl_params );
|
||||
XP_LOGFF( "adding: params=%s (%s)", asStr, curl_params );
|
||||
curl_free( curl_params );
|
||||
json_object_put( params );
|
||||
return result;
|
||||
|
@ -219,12 +221,12 @@ runWitCurl( RelayTask* task, const gchar* proc, ...)
|
|||
|
||||
res = curl_easy_perform(curl);
|
||||
XP_Bool success = res == CURLE_OK;
|
||||
XP_LOGF( "%s(): curl_easy_perform(%s) => %d", __func__, proc, res );
|
||||
XP_LOGFF( "curl_easy_perform(%s) => %d", proc, res );
|
||||
/* Check for errors */
|
||||
if ( ! success ) {
|
||||
XP_LOGF( "curl_easy_perform() failed: %s", curl_easy_strerror(res));
|
||||
XP_LOGFF( "curl_easy_perform() failed: %s", curl_easy_strerror(res));
|
||||
} else {
|
||||
XP_LOGF( "%s(): got for %s: \"%s\"", __func__, proc, task->ws.ptr );
|
||||
XP_LOGFF( "got for %s: \"%s\"", proc, task->ws.ptr );
|
||||
}
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
|
@ -290,7 +292,7 @@ void
|
|||
relaycon_reg( LaunchParams* params, const XP_UCHAR* rDevID,
|
||||
DevIDType typ, const XP_UCHAR* devID )
|
||||
{
|
||||
XP_LOGF( "%s(typ=%d)", __func__, typ );
|
||||
XP_LOGFF( "(typ=%s)", devIDTypeToStr(typ) );
|
||||
XP_U8 tmpbuf[256];
|
||||
int indx = 0;
|
||||
|
||||
|
@ -375,7 +377,7 @@ XP_S16
|
|||
relaycon_sendnoconn( LaunchParams* params, const XP_U8* buf, XP_U16 buflen,
|
||||
const XP_UCHAR* relayID, XP_U32 gameToken )
|
||||
{
|
||||
XP_LOGF( "%s(relayID=%s)", __func__, relayID );
|
||||
XP_LOGFF( "(relayID=%s)", relayID );
|
||||
XP_ASSERT( 0 != gameToken );
|
||||
XP_U16 indx = 0;
|
||||
ssize_t nSent = -1;
|
||||
|
@ -402,7 +404,7 @@ relaycon_sendnoconn( LaunchParams* params, const XP_U8* buf, XP_U16 buflen,
|
|||
void
|
||||
relaycon_requestMsgs( LaunchParams* params, const XP_UCHAR* devID )
|
||||
{
|
||||
XP_LOGF( "%s(devID=%s)", __func__, devID );
|
||||
XP_LOGFF( "(devID=%s)", devID );
|
||||
RelayConStorage* storage = getStorage( params );
|
||||
|
||||
XP_U8 tmpbuf[128];
|
||||
|
@ -496,7 +498,7 @@ relayThread( void* arg )
|
|||
|
||||
pthread_mutex_unlock( &storage->relayMutex );
|
||||
|
||||
XP_LOGF( "%s(): processing first of %d (%s)", __func__, len, strs );
|
||||
XP_LOGFF( "processing first of %d (%s)", len, strs );
|
||||
g_free( strs );
|
||||
|
||||
switch ( task->typ ) {
|
||||
|
@ -541,7 +543,7 @@ addTask( RelayConStorage* storage, RelayTask* task )
|
|||
gchar* strs = listTasks( storage->relayTaskList );
|
||||
pthread_cond_signal( &storage->relayCondVar );
|
||||
pthread_mutex_unlock( &storage->relayMutex );
|
||||
XP_LOGF( "%s(): task list now: %s", __func__, strs );
|
||||
XP_LOGFF( "task list now: %s", strs );
|
||||
g_free( strs );
|
||||
}
|
||||
|
||||
|
@ -562,7 +564,7 @@ freeRelayTask( RelayTask* task )
|
|||
{
|
||||
GSList faker = { .next = NULL, .data = task };
|
||||
gchar* str = listTasks(&faker);
|
||||
XP_LOGF( "%s(): deleting %s", __func__, str );
|
||||
XP_LOGFF( "deleting %s", str );
|
||||
g_free( str );
|
||||
g_free( task->ws.ptr );
|
||||
g_free( task );
|
||||
|
@ -622,7 +624,7 @@ process( RelayConStorage* storage, XP_U8* buf, ssize_t nRead )
|
|||
XP_UCHAR devID[len+1];
|
||||
getNetString( &ptr, len, devID );
|
||||
XP_U16 maxInterval = getNetShort( &ptr );
|
||||
XP_LOGF( "%s: maxInterval=%d", __func__, maxInterval );
|
||||
XP_LOGFF( "maxInterval=%d", maxInterval );
|
||||
(*storage->procs.devIDReceived)( storage->procsClosure, devID,
|
||||
maxInterval );
|
||||
}
|
||||
|
@ -644,7 +646,7 @@ process( RelayConStorage* storage, XP_U8* buf, ssize_t nRead )
|
|||
case XWPDEV_UNAVAIL: {
|
||||
#ifdef DEBUG
|
||||
XP_U32 unavail = getNetLong( &ptr );
|
||||
XP_LOGF( "%s: unavail = %u", __func__, unavail );
|
||||
XP_LOGFF( "unavail = %u", unavail );
|
||||
#endif
|
||||
uint32_t len;
|
||||
if ( !vli2un( &ptr, &len ) ) {
|
||||
|
@ -662,7 +664,7 @@ process( RelayConStorage* storage, XP_U8* buf, ssize_t nRead )
|
|||
assert( 0 );
|
||||
}
|
||||
XP_USE( packetID );
|
||||
XP_LOGF( "%s(): got ack for packetID %d", __func__, packetID );
|
||||
XP_LOGFF( "got ack for packetID %d", packetID );
|
||||
break;
|
||||
}
|
||||
case XWPDEV_ALERT: {
|
||||
|
@ -672,11 +674,11 @@ process( RelayConStorage* storage, XP_U8* buf, ssize_t nRead )
|
|||
}
|
||||
XP_UCHAR buf[len + 1];
|
||||
getNetString( &ptr, len, buf );
|
||||
XP_LOGF( "%s: got message: %s", __func__, buf );
|
||||
XP_LOGFF( "got message: %s", buf );
|
||||
break;
|
||||
}
|
||||
case XWPDEV_GOTINVITE: {
|
||||
XP_LOGF( "%s(): got XWPDEV_GOTINVITE", __func__ );
|
||||
XP_LOGFF( "%s", "got XWPDEV_GOTINVITE" );
|
||||
#ifdef DEBUG
|
||||
XP_U32 sender =
|
||||
#endif
|
||||
|
@ -698,13 +700,12 @@ process( RelayConStorage* storage, XP_U8* buf, ssize_t nRead )
|
|||
break;
|
||||
|
||||
default:
|
||||
XP_LOGF( "%s: Unexpected cmd %d", __func__, header.cmd );
|
||||
XP_LOGFF( "Unexpected cmd %d", header.cmd );
|
||||
XP_ASSERT( 0 );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
XP_LOGF( "%s: error reading udp socket: %d (%s)", __func__,
|
||||
errno, strerror(errno) );
|
||||
XP_LOGFF( "error reading udp socket: %d (%s)", errno, strerror(errno) );
|
||||
}
|
||||
LOG_RETURNF( "%d", TRUE );
|
||||
return TRUE;
|
||||
|
@ -729,10 +730,10 @@ relaycon_receive( GIOChannel* source, GIOCondition XP_UNUSED_DBG(condition), gpo
|
|||
((0 <= nRead)? nRead : 0) );
|
||||
#ifdef COMMS_CHECKSUM
|
||||
gchar* sum = g_compute_checksum_for_data( G_CHECKSUM_MD5, buf, nRead );
|
||||
XP_LOGF( "%s: read %zd bytes ('%s')(sum=%s)", __func__, nRead, b64, sum );
|
||||
XP_LOGFF( "read %zd bytes ('%s')(sum=%s)", nRead, b64, sum );
|
||||
g_free( sum );
|
||||
#else
|
||||
XP_LOGF( "%s: read %zd bytes ('%s')", __func__, nRead, b64 );
|
||||
XP_LOGFF( "read %zd bytes ('%s')", nRead, b64 );
|
||||
#endif
|
||||
g_free( b64 );
|
||||
|
||||
|
@ -760,7 +761,7 @@ relaycon_cleanup( LaunchParams* params )
|
|||
gchar* gotStrs = listTasks( storage->gotDataTaskList );
|
||||
pthread_mutex_unlock( &storage->gotDataMutex );
|
||||
|
||||
XP_LOGF( "%s(): sends pending: %d (%s); data tasks pending: %d (%s)", __func__,
|
||||
XP_LOGFF( "sends pending: %d (%s); data tasks pending: %d (%s)",
|
||||
nRelayTasks, gotStrs, nDataTasks, taskStrs );
|
||||
|
||||
g_free( gotStrs );
|
||||
|
@ -787,7 +788,7 @@ hostNameToIP( const XP_UCHAR* name )
|
|||
{
|
||||
XP_U32 ip;
|
||||
struct hostent* host;
|
||||
XP_LOGF( "%s: looking up %s", __func__, name );
|
||||
XP_LOGFF( "looking up %s", name );
|
||||
host = gethostbyname( name );
|
||||
if ( NULL == host ) {
|
||||
XP_WARNF( "gethostbyname returned NULL\n" );
|
||||
|
@ -795,7 +796,7 @@ hostNameToIP( const XP_UCHAR* name )
|
|||
XP_MEMCPY( &ip, host->h_addr_list[0], sizeof(ip) );
|
||||
ip = ntohl(ip);
|
||||
}
|
||||
XP_LOGF( "%s found %x for %s", __func__, ip, name );
|
||||
XP_LOGFF( "found %x for %s", ip, name );
|
||||
return ip;
|
||||
}
|
||||
|
||||
|
@ -807,7 +808,7 @@ onGotJoinData( RelayTask* task )
|
|||
RelayConStorage* storage = task->storage;
|
||||
XP_ASSERT( onMainThread(storage) );
|
||||
if ( !!task->ws.ptr ) {
|
||||
XP_LOGF( "%s(): got json? %s", __func__, task->ws.ptr );
|
||||
XP_LOGFF( "got json? %s", task->ws.ptr );
|
||||
json_object* reply = json_tokener_parse( task->ws.ptr );
|
||||
json_object* jConnname = NULL;
|
||||
json_object* jHID = NULL;
|
||||
|
@ -875,7 +876,7 @@ handleJoin( RelayTask* task )
|
|||
static void
|
||||
handlePost( RelayTask* task )
|
||||
{
|
||||
XP_LOGF( "%s(task.post.len=%d)", __func__, task->u.post.len );
|
||||
XP_LOGFF( "(task.post.len=%d)", task->u.post.len );
|
||||
XP_ASSERT( !onMainThread(task->storage) );
|
||||
char* data = g_base64_encode( task->u.post.msgbuf, task->u.post.len );
|
||||
struct json_object* jstr = json_object_new_string(data);
|
||||
|
@ -896,7 +897,7 @@ handlePost( RelayTask* task )
|
|||
static ssize_t
|
||||
post( RelayConStorage* storage, const XP_U8* msgbuf, XP_U16 len, float timeout )
|
||||
{
|
||||
XP_LOGF( "%s(len=%d)", __func__, len );
|
||||
XP_LOGFF( "(len=%d)", len );
|
||||
RelayTask* task = makeRelayTask( storage, POST );
|
||||
task->u.post.msgbuf = g_malloc(len);
|
||||
task->u.post.timeoutSecs = timeout;
|
||||
|
@ -922,14 +923,14 @@ onGotQueryData( RelayTask* task )
|
|||
json_object* jMsgs;
|
||||
if ( json_object_object_get_ex( reply, "msgs", &jMsgs ) ) {
|
||||
/* 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_LOGFF( "got result of len %d", json_object_object_length(jMsgs) );
|
||||
XP_ASSERT( json_object_object_length(jMsgs) <= 1 );
|
||||
json_object_object_foreach(jMsgs, relayID, arrOfArrOfMoves) {
|
||||
XP_ASSERT( 0 == strcmp( relayID, ids->data ) );
|
||||
int len1 = json_object_array_length( arrOfArrOfMoves );
|
||||
if ( len1 > 0 ) {
|
||||
sqlite3_int64 rowid = *(sqlite3_int64*)g_hash_table_lookup( task->u.query.map, relayID );
|
||||
XP_LOGF( "%s(): got row %lld for relayID %s", __func__, rowid, relayID );
|
||||
XP_LOGFF( "got row %lld for relayID %s", rowid, relayID );
|
||||
for ( int ii = 0; ii < len1; ++ii ) {
|
||||
json_object* forGameArray = json_object_array_get_idx( arrOfArrOfMoves, ii );
|
||||
int len2 = json_object_array_length( forGameArray );
|
||||
|
@ -1045,7 +1046,7 @@ addToGotData( RelayTask* task )
|
|||
RelayConStorage* storage = task->storage;
|
||||
pthread_mutex_lock( &storage->gotDataMutex );
|
||||
storage->gotDataTaskList = g_slist_append( storage->gotDataTaskList, task );
|
||||
XP_LOGF( "%s(): added id %d; len now %d", __func__, task->id,
|
||||
XP_LOGFF( "added id %d; len now %d", task->id,
|
||||
g_slist_length(storage->gotDataTaskList) );
|
||||
pthread_mutex_unlock( &storage->gotDataMutex );
|
||||
}
|
||||
|
@ -1065,7 +1066,7 @@ getFromGotData( RelayConStorage* storage )
|
|||
storage->gotDataTaskList );
|
||||
task = head->data;
|
||||
g_slist_free( head );
|
||||
XP_LOGF( "%s(): got task id %d", __func__, task->id );
|
||||
XP_LOGFF( "got task id %d", task->id );
|
||||
}
|
||||
// XP_LOGF( "%s(): len now %d", __func__, g_slist_length(storage->gotDataTaskList) );
|
||||
pthread_mutex_unlock( &storage->gotDataMutex );
|
||||
|
@ -1119,7 +1120,7 @@ sendIt( RelayConStorage* storage, const XP_U8* msgbuf, XP_U16 len, float timeout
|
|||
XP_LOGFF( "sent %d bytes with sum %s", len, sum );
|
||||
g_free( sum );
|
||||
#else
|
||||
XP_LOGF( "%s()=>%zd", __func__, nSent );
|
||||
XP_LOGFF( "=>%zd", nSent );
|
||||
#endif
|
||||
return nSent;
|
||||
}
|
||||
|
@ -1210,7 +1211,7 @@ writeHeader( RelayConStorage* storage, XP_U8* dest, XWRelayReg cmd )
|
|||
{
|
||||
int indx = 0;
|
||||
dest[indx++] = storage->proto;
|
||||
XP_LOGF( "%s: wrote proto %d", __func__, storage->proto );
|
||||
XP_LOGFF( "wrote proto %d", storage->proto );
|
||||
uint32_t packetNum = 0;
|
||||
if ( XWPDEV_ACK != cmd ) {
|
||||
packetNum = storage->nextID++;
|
||||
|
@ -1236,7 +1237,7 @@ readHeader( const XP_U8** buf, MsgHeader* header )
|
|||
if ( !vli2un( &ptr, &header->packetID ) ) {
|
||||
assert( 0 );
|
||||
}
|
||||
XP_LOGF( "%s: got packet %d", __func__, header->packetID );
|
||||
XP_LOGFF( "got packet %d", header->packetID );
|
||||
|
||||
header->cmd = *ptr++;
|
||||
*buf = ptr;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* -*- compile-command: "make MEMDEBUG=TRUE -j3"; -*- */
|
||||
/*
|
||||
* Copyright 2013 - 2015 by Eric House (xwords@eehouse.org). All rights
|
||||
* Copyright 2013 - 2020 by Eric House (xwords@eehouse.org). All rights
|
||||
* reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
|
|
|
@ -164,11 +164,14 @@ class Device():
|
|||
sTilesLeftPoolPat = re.compile('.*pool_r.*Tiles: (\d+) tiles left in pool')
|
||||
sTilesLeftTrayPat = re.compile('.*player \d+ now has (\d+) tiles')
|
||||
sRelayIDPat = re.compile('.*UPDATE games.*seed=(\d+),.*relayid=\'([^\']+)\'.*')
|
||||
sDevIDPat = re.compile('.*storing new devid: ([\da-fA-F]+).*')
|
||||
sConnPat = re.compile('.*linux_util_informMissing\(isServer.*nMissing=0\).*')
|
||||
|
||||
sScoresDup = []
|
||||
sScoresReg = []
|
||||
|
||||
def __init__(self, args, game, indx, params, room, peers, db,
|
||||
log, script, nInGame, inDupMode):
|
||||
def __init__(self, args, game, indx, params, room, peers, order,
|
||||
db, log, script, nInGame, inDupMode, usePublic):
|
||||
self.game = game
|
||||
self.indx = indx
|
||||
self.args = args
|
||||
|
@ -176,11 +179,13 @@ class Device():
|
|||
self.gameOver = False
|
||||
self.params = params
|
||||
self.room = room
|
||||
self.order = order
|
||||
self.db = db
|
||||
self.logPath = log
|
||||
self.script = script
|
||||
self.nInGame = nInGame
|
||||
self.inDupMode = inDupMode
|
||||
self.usePublic = usePublic
|
||||
# runtime stuff; init now
|
||||
self.app = args.APP_OLD
|
||||
self.proc = None
|
||||
|
@ -191,6 +196,9 @@ class Device():
|
|||
self.nTilesLeftPool = None
|
||||
self.nTilesLeftTray = None
|
||||
self.relayID = None
|
||||
self.inviteeDevID = None
|
||||
self.inviteeDevIDs = [] # only servers use this
|
||||
self.connected = False
|
||||
self.relaySeed = 0
|
||||
self.locked = False
|
||||
|
||||
|
@ -245,6 +253,14 @@ class Device():
|
|||
self.relaySeed = int(match.group(1))
|
||||
self.relayID = match.group(2)
|
||||
|
||||
if self.args.ADD_RELAY and not self.inviteeDevID:
|
||||
match = Device.sDevIDPat.match(line)
|
||||
if match: self.inviteeDevID = int(match.group(1), 16)
|
||||
|
||||
if not self.connected:
|
||||
match = Device.sConnPat.match(line)
|
||||
if match: self.connected = True
|
||||
|
||||
self.locked = False
|
||||
|
||||
# print('logReaderMain done, wrote lines:', nLines, 'to', self.logPath);
|
||||
|
@ -269,6 +285,25 @@ class Device():
|
|||
self.checkScript()
|
||||
self.launchCount += 1
|
||||
args = [ self.script, '--close-stdin' ]
|
||||
|
||||
# If I'm an unconnected server and I know a client's relayid,
|
||||
# append it so invitation can happen. When more than one
|
||||
# device will be invited, the invitations must always go in
|
||||
# the same order so channels will be assigned consistently. So
|
||||
# keep them in an array as they're encountered, and use in
|
||||
# that order
|
||||
if self.args.ADD_RELAY:
|
||||
if not self.usePublic and self.order == 1 and self.inviteeDevID and not self.connected:
|
||||
for peer in self.peers:
|
||||
if peer.inviteeDevID and not peer == self:
|
||||
if not peer.inviteeDevID in self.inviteeDevIDs:
|
||||
self.inviteeDevIDs.append(peer.inviteeDevID)
|
||||
|
||||
if self.inviteeDevIDs:
|
||||
args += [ '--force-invite' ]
|
||||
for inviteeDevID in self.inviteeDevIDs:
|
||||
args += ['--invitee-relayid', str(inviteeDevID)]
|
||||
|
||||
self.proc = subprocess.Popen(args, stdout = subprocess.DEVNULL,
|
||||
stderr = subprocess.PIPE, universal_newlines = True)
|
||||
self.pid = self.proc.pid
|
||||
|
@ -297,7 +332,7 @@ class Device():
|
|||
else:
|
||||
print('NOT killing')
|
||||
self.proc = None
|
||||
self.check_game()
|
||||
self.check_game_over()
|
||||
|
||||
def handleAllDone(self):
|
||||
global gDeadLaunches
|
||||
|
@ -351,7 +386,7 @@ class Device():
|
|||
elif RNUM < 10:
|
||||
self.devID += 'x'
|
||||
|
||||
def check_game(self):
|
||||
def check_game_over(self):
|
||||
if self.gameOver and not self.allDone:
|
||||
allDone = True
|
||||
for dev in self.peers:
|
||||
|
@ -365,51 +400,23 @@ class Device():
|
|||
assert self.game == dev.game
|
||||
dev.allDone = True
|
||||
|
||||
# print('Closing', self.connname, datetime.datetime.now())
|
||||
# for dev in Device.sConnnameMap[self.connname]:
|
||||
# dev.kill()
|
||||
# # kill_from_logs $OTHERS $KEY
|
||||
# for ID in $OTHERS $KEY; do
|
||||
# echo -n "${ID}:${LOGS[$ID]}, "
|
||||
# kill_from_log ${LOGS[$ID]} || /bin/true
|
||||
# send_dead $ID
|
||||
# close_device $ID $DONEDIR "game over"
|
||||
# done
|
||||
# echo ""
|
||||
# # XWRELAY_ERROR_DELETED may be old
|
||||
# elif grep -aq 'relay_error_curses(XWRELAY_ERROR_DELETED)' $LOG; then
|
||||
# echo "deleting $LOG $(connName $LOG) b/c another resigned"
|
||||
# kill_from_log $LOG || /bin/true
|
||||
# close_device $KEY $DEADDIR "other resigned"
|
||||
# elif grep -aq 'relay_error_curses(XWRELAY_ERROR_DEADGAME)' $LOG; then
|
||||
# echo "deleting $LOG $(connName $LOG) b/c another resigned"
|
||||
# kill_from_log $LOG || /bin/true
|
||||
# close_device $KEY $DEADDIR "other resigned"
|
||||
# else
|
||||
# maybe_resign $KEY
|
||||
# fi
|
||||
# }
|
||||
|
||||
def makeSMSPhoneNo( game, dev ):
|
||||
return '{:03d}{:03d}'.format( game, dev )
|
||||
|
||||
def build_cmds(args):
|
||||
devs = []
|
||||
COUNTER = 0
|
||||
PLAT_PARMS = []
|
||||
if not args.USE_GTK:
|
||||
PLAT_PARMS += ['--curses']
|
||||
|
||||
for GAME in range(1, args.NGAMES + 1):
|
||||
peers = set()
|
||||
ROOM = 'ROOM_%.3d' % (GAME % args.NROOMS)
|
||||
PHONE_BASE = '%.4d' % (GAME % args.NROOMS)
|
||||
NDEVS = pick_ndevs(args)
|
||||
LOCALS = figure_locals(args, NDEVS) # as array
|
||||
NPLAYERS = sum(LOCALS)
|
||||
assert(len(LOCALS) == NDEVS)
|
||||
DICT = args.DICTS[GAME % len(args.DICTS)]
|
||||
# make one in three games public
|
||||
PUBLIC = []
|
||||
if random.randint(0, 3) == 0: PUBLIC = ['--make-public', '--join-public']
|
||||
usePublic = args.ADD_RELAY and random.randint(0, 3) == 0
|
||||
useDupeMode = random.randint(0, 100) < args.DUP_PCT
|
||||
DEV = 0
|
||||
for NLOCALS in LOCALS:
|
||||
|
@ -419,7 +426,7 @@ def build_cmds(args):
|
|||
SCRIPT = '{}/start_{:02d}_{:02d}.sh'.format(args.LOGDIR, GAME, DEV)
|
||||
|
||||
PARAMS = player_params(args, NLOCALS, NPLAYERS, DEV)
|
||||
PARAMS += PLAT_PARMS
|
||||
if not args.USE_GTK: PARAMS += ['--curses']
|
||||
PARAMS += ['--board-size', '15', '--trade-pct', args.TRADE_PCT, '--sort-tiles']
|
||||
|
||||
# We SHOULD support having both SMS and relay working...
|
||||
|
@ -428,11 +435,13 @@ def build_cmds(args):
|
|||
if random.randint(0, 100) < g_UDP_PCT_START:
|
||||
PARAMS += ['--use-udp']
|
||||
if args.ADD_SMS:
|
||||
PARAMS += [ '--sms-number', PHONE_BASE + str(DEV - 1) ]
|
||||
PARAMS += [ '--sms-number', makeSMSPhoneNo(GAME, DEV) ]
|
||||
if args.SMS_FAIL_PCT > 0:
|
||||
PARAMS += [ '--sms-fail-pct', args.SMS_FAIL_PCT ]
|
||||
if DEV > 1:
|
||||
PARAMS += [ '--server-sms-number', PHONE_BASE + '0' ]
|
||||
if DEV == 1:
|
||||
PARAMS += [ '--force-invite' ]
|
||||
for dev in range(2, NDEVS + 1):
|
||||
PARAMS += [ '--invitee-sms-number', makeSMSPhoneNo(GAME, dev) ]
|
||||
|
||||
if args.UNDO_PCT > 0:
|
||||
PARAMS += ['--undo-pct', args.UNDO_PCT]
|
||||
|
@ -463,18 +472,18 @@ def build_cmds(args):
|
|||
# passed in the old bash version of this script, so fixing
|
||||
# it isn't a priority.
|
||||
# PARAMS += ['--seed', args.SEED]
|
||||
PARAMS += PUBLIC
|
||||
if DEV > 1:
|
||||
PARAMS += ['--force-channel', DEV - 1]
|
||||
else:
|
||||
PARAMS += ['--server']
|
||||
|
||||
if DEV == 1: PARAMS += ['--server']
|
||||
if DEV == 1 or usePublic: PARAMS += ['--force-game']
|
||||
if DEV > 1: PARAMS += ['--force-channel', DEV - 1]
|
||||
|
||||
if useDupeMode: PARAMS += ['--duplicate-mode']
|
||||
if usePublic: PARAMS += ['--make-public', '--join-public']
|
||||
|
||||
# print('PARAMS:', PARAMS)
|
||||
|
||||
if useDupeMode: PARAMS += ['--duplicate-mode']
|
||||
|
||||
dev = Device(args, GAME, COUNTER, PARAMS, ROOM, peers,
|
||||
DB, LOG, SCRIPT, len(LOCALS), useDupeMode)
|
||||
dev = Device( args, GAME, COUNTER, PARAMS, ROOM, peers,
|
||||
DEV, DB, LOG, SCRIPT, len(LOCALS), useDupeMode, usePublic )
|
||||
peers.add(dev)
|
||||
dev.update_ldevid()
|
||||
devs.append(dev)
|
||||
|
@ -482,7 +491,7 @@ def build_cmds(args):
|
|||
COUNTER += 1
|
||||
return devs
|
||||
|
||||
def summarizeTileCounts(devs, endTime, state):
|
||||
def summarizeTileCounts(devs, endTime, state, changeSecs):
|
||||
global gDeadLaunches
|
||||
shouldGoOn = True
|
||||
data = [dev.getTilesCount() for dev in devs]
|
||||
|
@ -557,21 +566,24 @@ def summarizeTileCounts(devs, endTime, state):
|
|||
state['lastChange'] = now
|
||||
state['tilesStr'] = tilesStr
|
||||
|
||||
return now - state['lastChange'] < datetime.timedelta(seconds = 30)
|
||||
return now - state['lastChange'] < datetime.timedelta(seconds = changeSecs)
|
||||
|
||||
def countCores():
|
||||
return len(glob.glob1('/tmp',"core*"))
|
||||
def countCores(args):
|
||||
count = 0
|
||||
if args.CORE_PAT:
|
||||
count = len( glob.glob(args.CORE_PAT) )
|
||||
return count
|
||||
|
||||
gDone = False
|
||||
|
||||
def run_cmds(args, devs):
|
||||
nCores = countCores()
|
||||
nCores = countCores(args)
|
||||
endTime = datetime.datetime.now() + datetime.timedelta(minutes = args.TIMEOUT_MINS)
|
||||
printState = {}
|
||||
lastPrint = datetime.datetime.now()
|
||||
|
||||
while len(devs) > 0 and not gDone:
|
||||
if countCores() > nCores:
|
||||
if countCores(args) > nCores:
|
||||
print('core file count increased; exiting')
|
||||
break
|
||||
now = datetime.datetime.now()
|
||||
|
@ -582,7 +594,7 @@ def run_cmds(args, devs):
|
|||
# print stats every 5 seconds
|
||||
if now - lastPrint > datetime.timedelta(seconds = 5):
|
||||
lastPrint = now
|
||||
if not summarizeTileCounts(devs, endTime, printState):
|
||||
if not summarizeTileCounts(devs, endTime, printState, args.NO_CHANGE_SECS):
|
||||
print('no change in too long; exiting')
|
||||
break
|
||||
|
||||
|
@ -674,6 +686,8 @@ def mkParser():
|
|||
help = 'number of roooms (default to --num-games)')
|
||||
parser.add_argument('--timeout-mins', dest = 'TIMEOUT_MINS', default = 10000, type = int,
|
||||
help = 'minutes after which to timeout')
|
||||
parser.add_argument('--nochange-secs', dest = 'NO_CHANGE_SECS', default = 30, type = int,
|
||||
help = 'seconds without change after which to timeout')
|
||||
parser.add_argument('--log-root', dest='LOGROOT', default = '.', help = 'where logfiles go')
|
||||
parser.add_argument('--dup-packets', dest = 'DUP_PACKETS', default = False, help = 'send all packet twice')
|
||||
parser.add_argument('--use-gtk', dest = 'USE_GTK', default = False, action = 'store_true',
|
||||
|
@ -718,13 +732,16 @@ def mkParser():
|
|||
parser.add_argument('--http-pct', dest = 'HTTP_PCT', default = 0, type = int,
|
||||
help = 'pct of games to be using web api')
|
||||
|
||||
parser.add_argument('--undo-pct', dest = 'UNDO_PCT', default = 0, type = int)
|
||||
parser.add_argument('--trade-pct', dest = 'TRADE_PCT', default = 0, type = int)
|
||||
parser.add_argument('--undo-pct', dest = 'UNDO_PCT', default = 5, type = int)
|
||||
parser.add_argument('--trade-pct', dest = 'TRADE_PCT', default = 10, type = int)
|
||||
|
||||
parser.add_argument('--add-sms', dest = 'ADD_SMS', default = False, action = 'store_true')
|
||||
parser.add_argument('--sms-fail-pct', dest = 'SMS_FAIL_PCT', default = 0, type = int)
|
||||
parser.add_argument('--remove-relay', dest = 'ADD_RELAY', default = True, action = 'store_false')
|
||||
|
||||
parser.add_argument('--core-pat', dest = 'CORE_PAT', default = "/tmp/core*",
|
||||
help = "pattern for core files that should stop the script" )
|
||||
|
||||
parser.add_argument('--with-valgrind', dest = 'VALGRIND', default = False,
|
||||
action = 'store_true')
|
||||
|
||||
|
|
11
xwords4/linux/scripts/show_sms_inplay.sh
Executable file
|
@ -0,0 +1,11 @@
|
|||
#!/bin/sh
|
||||
|
||||
for MSG in $(find /tmp/xw_sms/ -type f); do
|
||||
NOLOCK=$(echo $MSG | sed 's,.lock,,')
|
||||
if [ $NOLOCK = $MSG ]; then
|
||||
basename $(dirname "$MSG")
|
||||
echo -n "${MSG}: "
|
||||
head -n 1 $MSG
|
||||
fi
|
||||
done
|
||||
# ls -l /tmp/xw_sms/*
|
|
@ -125,7 +125,7 @@ void linux_lowerstr( XP_UCHAR* str );
|
|||
#define XP_ABS(a) ((a)>=0?(a):-(a))
|
||||
|
||||
#ifdef DEBUG
|
||||
# define XP_ASSERT(b) assert(b)
|
||||
# define XP_ASSERT(B) do { if (!(B)) { XP_LOGFF( "%s", "firing assert"); } assert(B); } while (0)
|
||||
void linux_backtrace( void );
|
||||
# define XP_BACKTRACE linux_backtrace
|
||||
#else
|
||||
|
|
|
@ -60,7 +60,7 @@ if [ -n "$LIMIT" ]; then
|
|||
fi
|
||||
|
||||
# Games
|
||||
echo "SELECT dead as d,connname,cid,room,lang as lg,clntVers as cv ,ntotal as t,nperdevice as npd,nsents as snts, seeds,devids,tokens,ack, mtimes "\
|
||||
echo "SELECT dead as d,connname,cid,room,ack,lang as lg,clntVers as cv ,ntotal as t,nperdevice as npd,nsents as snts, seeds,devids,tokens, mtimes "\
|
||||
"FROM games $QUERY $ORDER $LIMIT;" \
|
||||
| psql xwgames
|
||||
|
||||
|
|
|
@ -915,9 +915,9 @@ processConnect( const uint8_t* bufp, int bufLen, const AddrInfo* addr )
|
|||
|
||||
uint8_t clientIndx = getClientIndex( &bufp, end, nPlayersT );
|
||||
|
||||
logf( XW_LOGINFO, "%s(): langCode=%d; nPlayersT=%d; "
|
||||
logf( XW_LOGINFO, "%s(): cookie='%s', langCode=%d; nPlayersT=%d; "
|
||||
"wantsPublic=%d; seed=%.4X; indx=%d",
|
||||
__func__, langCode, nPlayersT, wantsPublic, seed, clientIndx );
|
||||
__func__, cookie, langCode, nPlayersT, wantsPublic, seed, clientIndx );
|
||||
|
||||
/* Make sure second thread can't create new cref for same cookie
|
||||
this one just handled.*/
|
||||
|
|
|
@ -200,15 +200,15 @@ enum { XWRELAY_NONE /* 0 is an illegal value */
|
|||
;
|
||||
|
||||
typedef enum {
|
||||
ID_TYPE_NONE
|
||||
,ID_TYPE_RELAY /* assigned by relay as replacement for one of the below */
|
||||
,ID_TYPE_LINUX
|
||||
,ID_TYPE_ANDROID_GCM
|
||||
,ID_TYPE_ANDROID_OTHER
|
||||
,ID_TYPE_ANON /* please assign me one based on nothing */
|
||||
,ID_TYPE_ANDROID_FCM
|
||||
ID_TYPE_NONE,
|
||||
ID_TYPE_RELAY, /* assigned by relay as replacement for one of the below */
|
||||
ID_TYPE_LINUX,
|
||||
ID_TYPE_ANDROID_GCM_UNUSED,
|
||||
ID_TYPE_ANDROID_OTHER,
|
||||
ID_TYPE_ANON, /* please assign me one based on nothing */
|
||||
ID_TYPE_ANDROID_FCM,
|
||||
|
||||
,ID_TYPE_NTYPES
|
||||
ID_TYPE_NTYPES,
|
||||
} DevIDType;
|
||||
|
||||
#ifndef CANT_DO_TYPEDEF
|
||||
|
|