Merge branch 'android_branch' of ssh://git.code.sf.net/p/xwords/git into android_branch

Conflicts:
	xwords4/android/XWords4-dbg/AndroidManifest.xml
	xwords4/android/scripts/mkvariant.sh
This commit is contained in:
Eric House 2015-09-10 18:34:28 -07:00
commit 759cd36162
35 changed files with 1212 additions and 1032 deletions

View file

@ -0,0 +1 @@
strings.xml

View file

@ -0,0 +1 @@
strings.xml

View file

@ -22,7 +22,7 @@
to come from a domain that you own or have control over. -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.eehouse.android.xw4"
android:versionCode="90"
android:versionCode="91"
android:versionName="@string/app_version"
>

File diff suppressed because it is too large Load diff

View file

@ -13,10 +13,10 @@
</style>
</head>
<body>
<h2>Crosswords 4.4 beta 97 release</h2>
<h2>Crosswords 4.4 beta 98 release</h2>
<p>This release changes how networked games are started and
communicate.</p>
<p>This release is mostly to get the new Dutch translation out
there, and to catch up Catalan and French.</p>
<div id="survey">
<p>Please <a href="https://www.surveymonkey.com/s/GX3XLHR">take
@ -26,63 +26,23 @@
<h3>New with this release</h3>
<ul>
<li>Change how games communicate: instead of using only one
means (e.g. Bluetooth, SMS, or the internet/relay) a game can
use all three, switching based on what works at the time</li>
<li>Complete and up-to-date translations into Dutch, French and
Catalan. What langauge is next?</li>
<li>Game creation requires only picking whether you&apos;re
networked or not, not how to communicate (though you can
still control that if you like)</li>
<li>Allow copying invitation URL to clipboard so you can paste
it into any messaging app you like</li>
<li>Separate inviting from playing: e.g. you can invite via
Bluetooth to a game that will be played via SMS</li>
<li>Improvements to in-game chat experience (but more are coming)</li>
<li>A game that needs remote players has a dialog on top of it
at all times you can use to invite players. The dialog goes
away when invited players connect.</li>
<li>Show a "toast" when hint button can't find any moves</li>
<li>But when a game hasn&apos;t connected yet, warn, and
don&apos;t let it send an invitation</li>
<li>Add sms to the list of ways you can invite somebody</li>
<li>On startup, if on a phone configured for other than English,
offer to download an appropriate wordlist</li>
<li>New games are placed in the selected group (if any,
otherwise in default as before)</li>
<li>Add new-games buttons to main screen, and offer to hide them
after a while</li>
<li>Offer to turn Bluetooth and SMS on directly rather than just
take you to the Android prefs app</li>
<li>Hide public rooms interface by default, and add a preference
to turn it back on</li>
<li>Remove option to invite using SMS, since invitations are too
large now. (Will address in a release soon.)</li>
<li>Kill play-via-SMS for non-GSM phones. (Google&apos;s making
it too hard to support this, and non-GSM phones are only
found in one country anyway.)</li>
<li>Deal with deletion of dictionary that&apos;s been set as
default</li>
<li>In popup menu from in-game wordlist button, show only
wordlists in same language as game</li>
<li>When assigning new tiles, don&apos;t sort tiles to left of
tray divider</li>
<li>Remove &quot;Reconnect&quot; button from network status info</li>
<li>Include info for all communication means being used in
network status, and only show an icon in networked games </li>
<li>Show status message after writing to SD card</li>
<li>Fix a few crashes</li>
<li>When displaying Bluetooth-connected devices to invite, skip
stuff like headphones</li>
<li>Turn off email invite attachments. They didn't seem to work anyway,
and aren't needed on modern Android.</li>
<li>Fix very old memory leak</li>
</ul>
<p>(The full changelog
@ -92,7 +52,6 @@
<ul>
<li>Offer &quot;Rematch&quot; when game&apos;s over (Easy via
SMS and Bluetooth; harder via the internet/relay)</li>
<li>Fix invite-by-SMS (and then re-enable)</li>
<li>Look into supporting play via peer-to-peer wifi</li>
</ul>

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="120"
height="120" xml:space="preserve">
<g
id="g12"
transform="matrix(1.25,0,0,-1.25,0,120)">
<g transform='translate(20.24,20.6)' id='g1090'>
<path style='fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none' d='M 0,0 5.287,24.92 38.6,27.24 38.6,27.57 5.287,29.89 0,54.81 55.52,27.4 0,0 z' id='path1092'/>
</g></g>
</svg>

After

Width:  |  Height:  |  Size: 584 B

View file

@ -1,4 +1,4 @@
# -*- mode: Makefile; compile-command: "cd ../; ${NDK_ROOT}/ndk-build -j3"; -*-
# -*- mode: Makefile; -*-
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
@ -41,7 +41,7 @@ LOCAL_DEFINES += \
-DCOMMON_LAYOUT \
-DCOMMS_VERSION=1 \
-DINITIAL_CLIENT_VERS=${INITIAL_CLIENT_VERS} \
-DVARIANT=\"${VARIANT}\" \
-DVARIANT_${VARIANT} \
-DRELAY_ROOM_DEFAULT=\"\" \
-D__LITTLE_ENDIAN \

View file

@ -695,7 +695,13 @@ android_debugf( const char* format, ... )
va_end(ap);
}
(void)__android_log_write( ANDROID_LOG_DEBUG, "xw4", buf );
(void)__android_log_write( ANDROID_LOG_DEBUG,
# if defined VARIANT_xw4
"xw4"
# elif defined VARIANT_xw4dbg
"x4bg"
# endif
, buf );
}
#endif

View file

@ -469,18 +469,17 @@ JNIEXPORT jstring JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_comms_1getUUID
( JNIEnv* env, jclass C )
{
jstring jstr = NULL;
jstring jstr =
#ifdef XWFEATURE_BLUETOOTH
const char* uuid;
if ( 0 == XP_STRCMP( VARIANT, "xw4" ) ) {
uuid = XW_BT_UUID;
} else if ( 0 == XP_STRCMP( VARIANT, "xw4dbg" ) ) {
uuid = XW_BT_UUID_DBG;
} else {
XP_ASSERT(0);
}
jstr = (*env)->NewStringUTF( env, uuid );
# if defined VARIANT_xw4
(*env)->NewStringUTF( env, XW_BT_UUID )
# elif defined VARIANT_xw4dbg
(*env)->NewStringUTF( env, XW_BT_UUID_DBG )
# endif
#else
NULL
#endif
;
return jstr;
}
@ -1690,20 +1689,22 @@ Java_org_eehouse_android_xw4_jni_XwJNI_game_1changeDict
}
#endif
JNIEXPORT void JNICALL
JNIEXPORT jint JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_comms_1resendAll
( JNIEnv* env, jclass C, jint gamePtr, jboolean force, jboolean thenAck )
{
jint result;
XWJNI_START();
CommsCtxt* comms = state->game.comms;
XP_ASSERT( !!comms );
(void)comms_resendAll( comms, force );
result = comms_resendAll( comms, force );
if ( thenAck ) {
#ifdef XWFEATURE_COMMSACK
comms_ackAny( comms );
#endif
}
XWJNI_END();
return result;
}
#ifdef XWFEATURE_COMMSACK

View file

@ -9,7 +9,8 @@
<!-- history is kept in a scrolling list of textview elems so
different style can be applied based on whether they're local or
remote. Inserted at runtime.... -->
<ScrollView android:orientation="vertical"
<ScrollView android:id="@+id/scroll"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
@ -21,24 +22,11 @@
/>
</ScrollView>
<LinearLayout android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<EditText android:id="@+id/chat_edit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:layout_weight="1"
/>
<Button android:id="@+id/send_button"
android:layout_width="wrap_content"
<EditText android:id="@+id/chat_edit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/chat_send"
android:singleLine="false"
android:layout_weight="0"
/>
</LinearLayout>
</LinearLayout>

View file

@ -1,7 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/chat_menu_send"
android:title="@string/chat_send"
android:showAsAction="ifRoom"
android:icon="@drawable/send__gen"
/>
<item android:id="@+id/chat_menu_clear"
android:title="@string/chat_menu_clear"
android:showAsAction="ifRoom"
android:icon="@drawable/content_discard__gen"
/>
</menu>

View file

@ -0,0 +1 @@
/strings.xml

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_version">4.4 beta 97</string>
<string name="app_version">4.4 beta 98</string>
</resources>

View file

@ -113,6 +113,7 @@
<string name="key_na_values">key_na_values</string>
<string name="key_na_studycopy">key_na_studycopy</string>
<string name="key_na_fmt_expl">key_na_fmt_expl</string>
<string name="key_na_clip_expl">key_na_clip_expl</string>
<string name="key_na_dicts">key_na_dicts</string>
<string name="key_enable_debug">key_enable_debug</string>
<string name="key_enable_dup_invite">key_enable_dup_invite</string>

View file

@ -1256,7 +1256,7 @@
-->
<!-- title of the chat screen. The name of the current game is
substituted for %1$s. -->
<string name="chat_title_fmt">%1$s message history</string>
<string name="chat_title_fmt">%1$s messages</string>
<!-- Prefix for local messages -->
<string name="chat_local_id">Me:\u0020</string>
<!-- Prefix for remote messages -->
@ -2532,4 +2532,24 @@
<string name="str_no_hint_found">Cannot find any moves</string>
<!-- Shown after "resend messages" menuitem chosen -->
<plurals name="resent_msgs_fmt">
<item quantity="one">One message sent</item>
<item quantity="other">%1$s messages sent</item>
</plurals>
<string name="confirm_clear_chat">Are you sure you want to delete
all chat history for this game?\n\n(This action cannot be
undone.)</string>
<!-- EXPERIMENTAL: Shown as toast when user chooses "My choice" for
invitation -->
<string name="invite_copied">Invitation ready to paste</string>
<!-- EXPERIMENTAL: "label" for invite on clipboard. If it's shown
it's by some Android utility -->
<string name="clip_label">Invitation URL</string>
<!-- EXPERIMENTAL: Newbie hint next when invite_choice_clip shown
when chosen -->
<string name="not_again_clip_expl_fmt">The \"%1$s\" option copies an
invitation URL to the clipboard. Paste it into the app of your
choice and send it to your friend.</string>
</resources>

View file

@ -1086,7 +1086,7 @@
-->
<!-- title of the chat screen. The name of the current game is
substituted for %1$s. -->
<string name="chat_title_fmt">%1$s egassem yrotsih</string>
<string name="chat_title_fmt">%1$s segassem</string>
<!-- Prefix for local messages -->
<string name="chat_local_id">Em:\u0020</string>
<!-- Prefix for remote messages -->
@ -2181,4 +2181,23 @@
<string name="not_again_comms_bt">Esu Htooteulb ot yalp tsniaga a
ybraen ecived taht\'s \"deriap\" htiw sruoy.</string>
<string name="str_no_hint_found">Tonnac dnif yna sevom</string>
<!-- Shown after "resend messages" menuitem chosen -->
<plurals name="resent_msgs_fmt">
<item quantity="one">Eno egassem tnes</item>
<item quantity="other">%1$s segassem tnes</item>
</plurals>
<string name="confirm_clear_chat">Era uoy erus uoy tnaw ot eteled
lla tahc yrotsih rof siht ?emag\n\nsIht( noitca tonnac eb
enodnu.)</string>
<!-- EXPERIMENTAL: Shown as toast when user chooses "My choice" for
invitation -->
<string name="invite_copied">Noitativni ydaer ot etsap</string>
<!-- EXPERIMENTAL: "label" for invite on clipboard. If it's shown
it's by some Android utility -->
<string name="clip_label">Noitativni LRU</string>
<!-- EXPERIMENTAL: Newbie hint next when invite_choice_clip shown
when chosen -->
<string name="not_again_clip_expl_fmt">Eht \"%1$s\" noitpo seipoc na
noitativni LRU ot eht draobpilc. Etsap ti otni eht ppa fo ruoy
eciohc dna dnes ti ot ruoy dneirf.</string>
</resources>

View file

@ -188,9 +188,9 @@
<string name="summary_relay_gameover_fmt">Partida finalitzada en la sala «%1$s»</string>
<plurals name="moves_fmt">
<item quantity="one">%1$d jugada feta</item>
<item quantity="other">%1$d jugades fetes</item>
</plurals>
<item quantity="one">%1$d jugada feta</item>
<item quantity="other">%1$d jugades fetes</item>
</plurals>
<string name="button_delete">Suprimeix</string>
<string name="button_reset">Reinicialitza</string>
@ -212,14 +212,14 @@
<string name="rename_label_caveat">Canvia el nom d\'aquesta partida (només en aquest aparell) a:</string>
<plurals name="confirm_seldeletes_fmt">
<item quantity="one">Esteu segur de voler suprimir el joc seleccionat? Aquesta acció no es pot desfer.</item>
<item quantity="other">Esteu segur de voler suprimir els %1$d jocs seleccionats? Aquesta acció no es pot desfer.</item>
</plurals>
<item quantity="one">Esteu segur de voler suprimir el joc seleccionat? Aquesta acció no es pot desfer.</item>
<item quantity="other">Esteu segur de voler suprimir els %1$d jocs seleccionats? Aquesta acció no es pot desfer.</item>
</plurals>
<plurals name="confirm_reset_fmt">
<item quantity="one">Esteu segur de voler reinicialitzar el joc seleccionat?\n\n(La reinicialització suprimeix totes les jugades i qualsevol informació de connexió.)</item>
<item quantity="other">Esteu segur de voler reinicialitzar els %1$d jocs seleccionats?\n\n(La reinicialització suprimeix totes les jugades i qualsevol informació de connexió.)</item>
</plurals>
<item quantity="one">Esteu segur de voler reinicialitzar el joc seleccionat?\n\n(La reinicialització suprimeix totes les jugades i qualsevol informació de connexió.)</item>
<item quantity="other">Esteu segur de voler reinicialitzar els %1$d jocs seleccionats?\n\n(La reinicialització suprimeix totes les jugades i qualsevol informació de connexió.)</item>
</plurals>
<string name="loc_builtin">Incorporat</string>
@ -228,9 +228,9 @@
<string name="dicts_item_move">Canvia la ubicació d\'emmagatzematge</string>
<plurals name="confirm_delete_dict_fmt">
<item quantity="one">Esteu segur de voler suprimir el diccionari %1$s?</item>
<item quantity="other">Esteu segur de voler suprimir els diccionaris %1$s?</item>
</plurals>
<item quantity="one">Esteu segur de voler suprimir el diccionari %1$s?</item>
<item quantity="other">Esteu segur de voler suprimir els diccionaris %1$s?</item>
</plurals>
<string name="confirm_deleteonly_dicts_fmt">Si suprimiu %1$s no tindreu cap diccionari %2$s. Una o més partides no es podran obrir (fins que baixeu un diccionari de substitució.)</string>
@ -293,16 +293,16 @@
<string name="no_moves_made">(Encara no s\'ha fet cap jugada)</string>
<plurals name="invite_msg_fmt">
<item quantity="one">Aquesta partida està esperant a %1$d jugador remot. Si encara no ho heu fet, voleu convidar algú a unir-s\'hi?</item>
<item quantity="other">Aquesta partida està esperant a %1$d jugadors remots. Si encara no ho heu fet, voleu convidar algú a unir-s\'hi?</item>
</plurals>
<item quantity="one">Aquesta partida està esperant a %1$d jugador remot. Si encara no ho heu fet, voleu convidar algú a unir-s\'hi?</item>
<item quantity="other">Aquesta partida està esperant a %1$d jugadors remots. Si encara no ho heu fet, voleu convidar algú a unir-s\'hi?</item>
</plurals>
<string name="invite_if_nfc">O simplement toqueu per a convidar, si l\'altre aparell també té Android Beaming i és a prop.</string>
<plurals name="players_miss_fmt">
<item quantity="one">Manca %1$d jugador</item>
<item quantity="other">Manquen %1$d jugadors</item>
</plurals>
<plurals name="players_miss_fmt">
<item quantity="one">Manca %1$d jugador</item>
<item quantity="other">Manquen %1$d jugadors</item>
</plurals>
<string name="invite_multiple">" (Esteu esperant més d\'un jugador remot. No els heu de convidar a tots a la vegada, però aquest avís no desapareixerà fins que hàgiu convidat a tothom i totes les invitacions s\'hagin acceptat.)"</string>
@ -324,13 +324,11 @@
<string name="vs_join">" vs. "</string>
<plurals name="strd_remains_header_fmt">
<item quantity="one">Queden %1$d fitxes al sac.</item>
<item quantity="other"/>
</plurals>
<item quantity="other">Queden %1$d fitxes al sac.</item>
</plurals>
<plurals name="strd_remains_expl_fmt">
<item quantity="one">%1$d fitxes romanents al sac i als faristols:\n</item>
<item quantity="other"/>
</plurals>
<item quantity="other">%1$d fitxes romanents al sac i als faristols:\n</item>
</plurals>
<string name="confirm_undo_last">Esteu segur que voleu desfer l\'últim torn enviat? (No hi ha opció per a refer-lo.)</string>
@ -426,9 +424,8 @@
<string name="invite_chooser_sms">SMS</string>
<plurals name="query_trade_fmt">
<item quantity="one">Esteu segur que voleu canviar les %1$d fitxes seleccionades (%2$s)?</item>
<item quantity="other"/>
</plurals>
<item quantity="other">Esteu segur que voleu canviar les %1$d fitxes seleccionades (%2$s)?</item>
</plurals>
<string name="chat_title_fmt">%1$s historial de missatges</string>
<string name="chat_local_id">"Jo: "</string>
@ -512,13 +509,11 @@
<string name="pick_faceup">Tria les fitxes cara amunt</string>
<plurals name="dict_browse_title_fmt">
<item quantity="one">%1$s (%2$d paraules usant %3$d-%4$d fitxes)</item>
<item quantity="other"/>
</plurals>
<item quantity="other">%1$s (%2$d paraules usant %3$d-%4$d fitxes)</item>
</plurals>
<plurals name="dict_browse_title1_fmt">
<item quantity="one">%1$s (%2$d paraules usant %3$d fitxes)</item>
<item quantity="other"/>
</plurals>
<item quantity="other">%1$s (%2$d paraules usant %3$d fitxes)</item>
</plurals>
<string name="dict_browse_nowords_fmt">No hi ha cap paraula a %1$s que comenci amb %2$s.</string>
<string name="not_again_browse">Aquest botó obre l\'explorador de diccionaris en el diccionari actual del jugador.</string>
<string name="not_again_browseall">Aquest botó obre l\'explorador de diccionaris en el diccionari de la vostra elecció.</string>
@ -633,14 +628,13 @@
<string name="group_new_games">Partides noves</string>
<plurals name="groups_confirm_del_fmt">
<item quantity="one">Esteu segur de voler suprimir els %1$d grups seleccionats?</item>
<item quantity="other"/>
</plurals>
<item quantity="other">Esteu segur de voler suprimir els %1$d grups seleccionats?</item>
</plurals>
<string name="rename_group_label">Canvia el nom d\'aquest grup a:</string>
<plurals name="group_name_fmt">
<item quantity="one">%1$s (%2$d partida)</item>
<item quantity="other">%1$s (%2$d partides)</item>
</plurals>
<item quantity="one">%1$s (%2$d partida)</item>
<item quantity="other">%1$s (%2$d partides)</item>
</plurals>
<string name="button_rematch">Torna a jugar-hi</string>
@ -672,8 +666,7 @@
<string name="slmenu_copy_sel">Copia al porta-retalls</string>
<string name="slmenu_clear_sel">Suprimeix la selecció</string>
<plurals name="paste_done_fmt">
<item quantity="one">S\'han copiat %1$d paraules</item>
<item quantity="other"/>
<item quantity="other">S\'han copiat %1$d paraules</item>
</plurals>
<string name="add_done_fmt">S\'ha afegit %1$s a la llista d\'estudi %2$s</string>
<string name="studylist_title_fmt">Llista d\'estudi per a %1$s</string>
@ -737,9 +730,9 @@
<string name="nag_title">Recordatori: és el vostre torn</string>
<plurals name="nag_minutes_fmt">
<item quantity="one">%1$d minut</item>
<item quantity="other">%1$d minuts</item>
</plurals>
<item quantity="one">%1$d minut</item>
<item quantity="other">%1$d minuts</item>
</plurals>
<string name="lmi_pass_fmt">%1$s ha passat (0 punts)</string>
<string name="lmi_phony_fmt">%1$s ha perdut el torn</string>
<string name="lmi_tiles_fmt">Fitxes assignades a %1$s</string>
@ -752,9 +745,9 @@
<string name="new_game_networked">Partida en xarxa nova</string>
<plurals name="nplayers_fmt">
<item quantity="one">Un jugador</item>
<item quantity="other">%1$d jugadors</item>
</plurals>
<item quantity="one">Un jugador</item>
<item quantity="other">%1$d jugadors</item>
</plurals>
<string name="network_advanced_title">Avançat</string>
<string name="network_advanced_summary">Per a jugadors experimentats</string>
<string name="invite_multi_title">Invitació múltiple</string>
@ -793,28 +786,26 @@
<plurals name="lang_name_fmt">
<item quantity="one">%1$s (%2$d diccionari)</item>
<item quantity="other">%1$s (%2$d diccionaris)</item>
</plurals>
</plurals>
<plurals name="nag_hours_fmt">
<plurals name="nag_hours_fmt">
<item quantity="one">%1$d hora</item>
<item quantity="other">%1$d hores</item>
</plurals>
<plurals name="nag_days_fmt">
</plurals>
<plurals name="nag_days_fmt">
<item quantity="one">%1$d dia</item>
<item quantity="other">%1$d dies</item>
</plurals>
</plurals>
<string name="nag_body_fmt">%1$s ha jugat fa més de %2$s.</string>
<string name="nag_warn_last_fmt">Últim avís: %1$s</string>
<string name="prev_player">Oponent</string>
<plurals name="lmi_move_fmt">
<item quantity="one">%1$s ha jugat %2$s i anota %3$d punts</item>
<item quantity="other"/>
<item quantity="other">%1$s ha jugat %2$s i anota %3$d punts</item>
</plurals>
<plurals name="lmi_trade_fmt">
<item quantity="one">%1$s ha canviat %2$d fitxes</item>
<item quantity="other"/>
</plurals>
<item quantity="other">%1$s ha canviat %2$d fitxes</item>
</plurals>
<string name="new_game_message_nodflt">Cal configurar aquesta partida abans d\'obrir-la.</string>
<string name="use_defaults">Usa els valors predeterminats</string>
@ -841,9 +832,9 @@
<string name="warn_nomobile_fmt">El número %1$s de %2$s no sembla un número de mòbil. Voleu importar-lo igualment?</string>
<string name="get_sms_number">Introduïu el número de telèfon:</string>
<plurals name="confirm_clear_fmt">
<item quantity="one">Esteu segur de voler suprimir el número de telèfon seleccionat?</item>
<item quantity="other">Esteu segur de voler suprimir els %1$d números de telèfon seleccionats?</item>
</plurals>
<item quantity="one">Esteu segur de voler suprimir el número de telèfon seleccionat?</item>
<item quantity="other">Esteu segur de voler suprimir els %1$d números de telèfon seleccionats?</item>
</plurals>
<string name="connect_label_sms">Connexió (via SMS/missatges)</string>
<string name="phone_label">Números connectats:</string>
<string name="summary_conn_sms_fmt">Partida en joc amb %1$s</string>
@ -860,14 +851,12 @@
<string name="game_name_group_title">Anomena el grup</string>
<plurals name="groups_confirm_del_games_fmt">
<item quantity="one">\n\n(també se suprimiran %1$d partides.)</item>
<item quantity="other"/>
</plurals>
<item quantity="other">\n\n(també se suprimiran %1$d partides.)</item>
</plurals>
<plurals name="confirm_studylist_clear_fmt">
<item quantity="one">Esteu segur de voler suprimir les %1$d paraules seleccionades?\n\n(Aquesta acció no es pot desfer.)</item>
<item quantity="other"/>
</plurals>
<item quantity="other">Esteu segur de voler suprimir les %1$d paraules seleccionades?\n\n(Aquesta acció no es pot desfer.)</item>
</plurals>
<string name="study_langpick">Les vostres paraules per a:</string>
<string name="study_no_lang_fmt">Encara no heu desat cap paraula al llistat d\'estudi per a %1$s.</string>
@ -876,9 +865,8 @@
<string name="not_again_studycopy">Les paraules seleccionades s\'han copiat al porta-retalls del sistema. Podeu enganxar-les en qualsevol aplicació que permeti enganxar text, p. e. l\'aplicació de correu.</string>
<plurals name="new_xlations_fmt">
<item quantity="one">Ha instal·lat %1$d traduccions noves</item>
<item quantity="other"/>
</plurals>
<item quantity="other">Ha instal·lat %1$d traduccions noves</item>
</plurals>
<string name="loc_fmts_mismatch">Traducció no permesa: les cadenes traduïdes han de tenir els mateixos indicadors de format (p. e. %1$s) que l\'original.</string>
<string name="not_again_fmt_expl">Aquesta cadena té indicadors de format especials (p. e. %1$s). Assegureu-vos que la traducció té els mateixos que l\'original.\n\n(No podreu desar-la si no ho compleix.)</string>
@ -892,14 +880,13 @@
<string name="sms_bad_proto_fmt">La versió del Crosswords al telèfon amb número «%1$s» no és compatible amb aquest per a jugar via SMS. Heu d\'actualitzar abans de continuar.</string>
<plurals name="invite_bt_desc_fmt">
<item quantity="one">Seleccioneu fins a %1$d aparells que voleu incloure en aquesta partida. Useu el botó «%2$s» si no veieu l\'aparell que espereu.</item>
<item quantity="other"/>
</plurals>
<plurals name="invite_bt_desc_fmt">
<item quantity="other">Seleccioneu fins a %1$d aparells que voleu incloure en aquesta partida. Useu el botó «%2$s» si no veieu l\'aparell que espereu.</item>
</plurals>
<plurals name="invite_sms_desc_fmt">
<item quantity="one">Comproveu el número de telèfon que voleu convidar a la partida nova, aleshores toqueu «%2$s».</item>
<item quantity="other">Comproveu els %1$d números de telèfon que voleu convidar a la partida nova, aleshores toqueu «%2$s».</item>
</plurals>
<item quantity="one">Comproveu el número de telèfon que voleu convidar a la partida nova, aleshores toqueu «%2$s».</item>
<item quantity="other">Comproveu els %1$d números de telèfon que voleu convidar a la partida nova, aleshores toqueu «%2$s».</item>
</plurals>
<string name="warn_unlimited">Esteu segur que aquest número és d\'un compte amb SMS il·limitats? Feu clic a «Cancel·la si no ho esteu.</string>
<string name="square_tiles_summary">Encara que pugin ser més altes</string>
@ -937,9 +924,9 @@
<string name="force_tablet_summary">Encara que la pantalla sigui massa petita</string>
<plurals name="resend_finished_fmt">
<item quantity="one">Reenviament finalitzat, s\'ha enviat %1$d missatge.</item>
<item quantity="other">Reenviament finalitzat, s\'han enviat %1$d missatges.</item>
</plurals>
<item quantity="one">Reenviament finalitzat, s\'ha enviat %1$d missatge.</item>
<item quantity="other">Reenviament finalitzat, s\'han enviat %1$d missatges.</item>
</plurals>
<string name="dup_game_query_fmt">Ja teniu una partida que sembla s\'ha creat (el %1$s) amb la mateixa invitació. Esteu segur de voler crear-ne una altra?</string>
@ -1026,9 +1013,8 @@
<string name="confirm_sms_expl">Atenció: aquesta funcionalitat és per a telèfons amb plans de missatges SMS il·limitats. Si l\'habiliteu, per cada partida jugada, s\'enviaran dotzenes de missatges de text SMS de forma invisible. Si no teniu un pla il·limitat, la vostra operadora us pot cobrar cadascun dels missatges!\n\nVoleu habilitar el joc via SMS?</string>
<plurals name="bt_err_count_fmt">
<item quantity="one">Fins ara, %1$d errors Bluetooth</item>
<item quantity="other"/>
</plurals>
<item quantity="other">Fins ara, %1$d errors Bluetooth</item>
</plurals>
<string name="app_not_found_fmt">No es pot connectar al Crosswords en l\'aparell %1$s. Comproveu que l\'aparell és proper i que té el Crosswords instal·lat.</string>
@ -1045,4 +1031,18 @@
<string name="redir_host">Convida l\'amfitrió redirigit</string>
<string name="str_no_hint_found">No puc trobar cap jugada</string>
<string name="notify_chat_title_fmt">Missatge de xat a la partida %1$s</string>
<string name="invite_choice_clip">Ho triaré</string>
<string name="invite_copied">Invitació preparada per a copiar</string>
<string name="clip_label">URL de la invitació</string>
<string name="not_again_clip_expl_fmt">L\'opció «%1$s» copia un URL d\'invitació al porta-retalls. Enganxeu-lo a l\'aplicació desitjada i envieu-lo al vostre amic.</string>
<string name="notify_chat_body_fmt">%1$s: %2$s</string>
<plurals name="resent_msgs_fmt">
<item quantity="one">S\'ha enviat un missatge</item>
<item quantity="other">S\'han enviat %1$s missatges</item>
</plurals>
<string name="confirm_clear_chat">Esteu segur de voler suprimir tot l\'historial de conversa d\'aquesta partida?\n\n(Aquesta acció no és pot desfer.)</string>
</resources>

View file

@ -1086,7 +1086,7 @@
-->
<!-- title of the chat screen. The name of the current game is
substituted for %1$s. -->
<string name="chat_title_fmt">%1$s MESSAGE HISTORY</string>
<string name="chat_title_fmt">%1$s MESSAGES</string>
<!-- Prefix for local messages -->
<string name="chat_local_id">ME:\u0020</string>
<!-- Prefix for remote messages -->
@ -2181,4 +2181,23 @@
<string name="not_again_comms_bt">USE BLUETOOTH TO PLAY AGAINST A
NEARBY DEVICE THAT\'S \"PAIRED\" WITH YOURS.</string>
<string name="str_no_hint_found">CANNOT FIND ANY MOVES</string>
<!-- Shown after "resend messages" menuitem chosen -->
<plurals name="resent_msgs_fmt">
<item quantity="one">ONE MESSAGE SENT</item>
<item quantity="other">%1$s MESSAGES SENT</item>
</plurals>
<string name="confirm_clear_chat">ARE YOU SURE YOU WANT TO DELETE
ALL CHAT HISTORY FOR THIS GAME?\n\n(THIS ACTION CANNOT BE
UNDONE.)</string>
<!-- EXPERIMENTAL: Shown as toast when user chooses "My choice" for
invitation -->
<string name="invite_copied">INVITATION READY TO PASTE</string>
<!-- EXPERIMENTAL: "label" for invite on clipboard. If it's shown
it's by some Android utility -->
<string name="clip_label">INVITATION URL</string>
<!-- EXPERIMENTAL: Newbie hint next when invite_choice_clip shown
when chosen -->
<string name="not_again_clip_expl_fmt">THE \"%1$s\" OPTION COPIES AN
INVITATION URL TO THE CLIPBOARD. PASTE IT INTO THE APP OF YOUR
CHOICE AND SEND IT TO YOUR FRIEND.</string>
</resources>

View file

@ -1,4 +1,4 @@
<?xml version='1.0' encoding='UTF-8'?>
<?xml version='1.0' encoding='utf-8'?>
<resources>
<!-- What is \u200C? English strings are used as keys, so they all
need to be unique. This glyph is non-printing and of
@ -3475,4 +3475,32 @@ pour la langue</string>
<string name="confirm_drop_relay_sms">Jouer par SMS n\'est pas
possible avec tous les opérateurs.</string>
<string name="notify_chat_title_fmt">Message de discussion dans la partie %1$s</string>
<string name="notify_chat_body_fmt">%1$s : %2$s</string>
<plurals name="confirm_clear_fmt">
<item quantity="one">Êtes-vous sûr de vouloir effacer le numéro de téléphone coché ?</item>
<item quantity="other">Êtes-vous sûr de vouloir effacer les numéros de téléphone cochés ?</item>
</plurals>
<string name="button_enable">Activer</string>
<string name="not_again_comms_relay">Le \"relai\" est un serveur sur Internet qui permet l\'échange de messages entre périphériques qui font tourner Crosswords. Il fonctionne dès que vous avez une connexion à Internet pleinement fonctionnelle, mais peut avoir des problèmes sur des réseaux Wifi restreints.</string>
<string name="not_again_comms_sms">Les parties par SMS utilisent la même technologie que l\'envoi de SMS normaux. Bien que les messages soient invisibles pour vous, votre opérateur les considère comme des messages normaux, donc vous pourriez vouloir éviter cette fonctionnalité si vous n\'avez pas un forfait (ou un budget) illimité.</string>
<string name="not_again_comms_bt">"Utilisez le Bluetooth pour jouer contre un périphérique à proximité appairé avec le votre."</string>
<string name="str_no_hint_found">Ne peut trouver aucun coup</string>
<plurals name="resent_msgs_fmt">
<item quantity="one">Un message envoyé</item>
<item quantity="other">%1$s messages envoyés</item>
</plurals>
<string name="invite_choice_clip">Je choisirai</string>
<string name="invite_copied">Invitation prête à coller</string>
<string name="clip_label">Adresse de l\'invitation</string>
<string name="not_again_clip_expl_fmt">L\'option \"%1$s\" copie une adresse d\'invitation dans le presse-papier. Collez-là dans l\'application de votre choix et envoyez-là à votre ami.</string>
<string name="confirm_clear_chat">Êtes-vous sûr de vouloir effacer tout l\'historique de discussion pour cette partie ?\n\n(Cette action ne peut pas être annulée.)</string>
</resources>

View file

@ -781,4 +781,14 @@
<string name="invite_copied">Uitnodiging kan nu geplakt worden</string>
<string name="clip_label">Uitnodigingsadres</string>
<string name="not_again_clip_expl_fmt">De \"%1$s\" optie kopieert een uitnodigingsadres naar het kladblok. Plak het in een app naar keuze en stuur het naar een vriend.</string>
<string name="notify_chat_title_fmt">Chatbericht in spel %1$s</string>
<string name="notify_chat_body_fmt">%1$s: %2$s</string>
<plurals name="resent_msgs_fmt">
<item quantity="one">Een bericht verstuurd</item>
<item quantity="other">%1$s berichten verstuurd</item>
</plurals>
<string name="confirm_clear_chat">Weet je zeker dat je alle chatberichten voor dit spel wilt verwijderen?\n\n(Deze actie kan niet ongedaan gemaakt worden.)</string>
</resources>

View file

@ -906,7 +906,7 @@ public class BoardDelegate extends DelegateBase
break;
case R.id.board_menu_game_resend:
m_jniThread.handle( JNICmd.CMD_RESEND, true, false );
m_jniThread.handle( JNICmd.CMD_RESEND, true, false, true );
break;
case R.id.gamel_menu_checkmoves:
@ -1046,12 +1046,17 @@ public class BoardDelegate extends DelegateBase
SMS_INVITE_RESULT );
break;
case EMAIL:
case CLIPBOARD:
NetLaunchInfo nli = new NetLaunchInfo( m_summary, m_gi, 1,
1 + m_nGuestDevs );
if ( !m_relayConnected ) {
nli.removeAddress( CommsConnType.COMMS_CONN_RELAY );
}
GameUtils.launchEmailInviteActivity( m_activity, nli );
if ( InviteMeans.EMAIL == means ) {
GameUtils.launchEmailInviteActivity( m_activity, nli );
} else if ( InviteMeans.CLIPBOARD == means ) {
GameUtils.inviteURLToClip( m_activity, nli );
}
break;
default:
Assert.fail();
@ -2011,6 +2016,11 @@ public class BoardDelegate extends DelegateBase
m_dlgTitle = msg.arg1;
showDialog( DlgID.GAME_OVER );
break;
case JNIThread.MSGS_SENT:
int nSent = (Integer)msg.obj;
showToast( getQuantityString( R.plurals.resent_msgs_fmt,
nSent, nSent ) );
break;
}
}
};
@ -2099,7 +2109,8 @@ public class BoardDelegate extends DelegateBase
}
if ( 0 < m_connTypes.size() ) {
m_jniThread.handle( JNIThread.JNICmd.CMD_RESEND, force, true );
m_jniThread.handle( JNIThread.JNICmd.CMD_RESEND, force, true,
false );
}
}

View file

@ -21,19 +21,19 @@
package org.eehouse.android.xw4;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MenuInflater;
import android.view.View;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;
public class ChatDelegate extends DelegateBase
implements View.OnClickListener {
import org.eehouse.android.xw4.DlgDelegate.Action;
public class ChatDelegate extends DelegateBase {
private long m_rowid;
private Activity m_activity;
@ -65,8 +65,13 @@ public class ChatDelegate extends DelegateBase
}
}
((Button)findViewById( R.id.send_button ))
.setOnClickListener( this );
final ScrollView scroll = (ScrollView)findViewById( R.id.scroll );
scroll.post(new Runnable() {
@Override
public void run() {
scroll.fullScroll(View.FOCUS_DOWN);
}
});
String title = getString( R.string.chat_title_fmt,
GameUtils.getName( m_activity, m_rowid ) );
@ -80,29 +85,48 @@ public class ChatDelegate extends DelegateBase
@Override
public boolean onOptionsItemSelected( MenuItem item )
{
boolean handled = R.id.chat_menu_clear == item.getItemId();
if ( handled ) {
DBUtils.clearChatHistory( m_activity, m_rowid );
LinearLayout layout =
(LinearLayout)findViewById( R.id.chat_history );
layout.removeAllViews();
boolean handled = true;
switch ( item.getItemId() ) {
case R.id.chat_menu_clear:
if ( handled ) {
showConfirmThen( R.string.confirm_clear_chat, Action.CLEAR_ACTION );
}
break;
case R.id.chat_menu_send:
EditText edit = (EditText)findViewById( R.id.chat_edit );
String text = edit.getText().toString();
if ( null == text || text.length() == 0 ) {
setResult( Activity.RESULT_CANCELED );
} else {
DBUtils.appendChatHistory( m_activity, m_rowid, text, true );
Intent result = new Intent();
result.putExtra( BoardDelegate.INTENT_KEY_CHAT, text );
setResult( Activity.RESULT_OK, result );
}
finish();
break;
default:
handled = false;
break;
}
return handled;
}
public void onClick( View view )
@Override
public void dlgButtonClicked( Action action, int which, Object[] params )
{
EditText edit = (EditText)findViewById( R.id.chat_edit );
String text = edit.getText().toString();
if ( null == text || text.length() == 0 ) {
setResult( Activity.RESULT_CANCELED );
} else {
DBUtils.appendChatHistory( m_activity, m_rowid, text, true );
Intent result = new Intent();
result.putExtra( BoardDelegate.INTENT_KEY_CHAT, text );
setResult( Activity.RESULT_OK, result );
switch ( action ) {
case CLEAR_ACTION:
if ( AlertDialog.BUTTON_POSITIVE == which ) {
DBUtils.clearChatHistory( m_activity, m_rowid );
LinearLayout layout =
(LinearLayout)findViewById( R.id.chat_history );
layout.removeAllViews();
}
break;
default:
super.dlgButtonClicked( action, which, params );
}
finish();
}
}

View file

@ -142,7 +142,7 @@ public class DBUtils {
DBHelper.ROOMNAME, DBHelper.RELAYID,
/*DBHelper.SMSPHONE,*/ DBHelper.SEED,
DBHelper.DICTLANG, DBHelper.GAMEID,
DBHelper.SCORES, DBHelper.HASMSGS,
DBHelper.SCORES,
DBHelper.LASTPLAY_TIME, DBHelper.REMOTEDEVS,
DBHelper.LASTMOVE, DBHelper.NPACKETSPENDING,
DBHelper.EXTRAS,
@ -255,11 +255,6 @@ public class DBUtils {
col = cursor.getColumnIndex( DBHelper.SERVERROLE );
tmp = cursor.getInt( col );
summary.serverRole = CurGameInfo.DeviceRole.values()[tmp];
col = cursor.getColumnIndex( DBHelper.HASMSGS );
if ( col >= 0 ) {
summary.pendingMsgLevel = cursor.getInt( col );
}
}
cursor.close();
db.close();
@ -307,7 +302,6 @@ public class DBUtils {
values.put( DBHelper.NEXTNAG, nextNag );
values.put( DBHelper.DICTLIST, summary.dictNames(DICTS_SEP) );
values.put( DBHelper.HASMSGS, summary.pendingMsgLevel );
if ( null != inviteID ) {
values.put( DBHelper.INVITEID, inviteID );
}

View file

@ -528,10 +528,9 @@ public class DelegateBase implements DlgClickNotify,
m_dlgDelegate.eventOccurred( event, args );
break;
default:
if ( BuildConfig.DEBUG ) {
DbgUtils.logf( "DelegateBase.eventOccurred(event=%s) (DROPPED)",
event.toString() );
}
DbgUtils.logdf( "DelegateBase.eventOccurred(event=%s) (DROPPED)",
event.toString() );
break;
}
if ( 0 != fmtId ) {

View file

@ -138,7 +138,7 @@ public class DlgDelegate {
public interface DlgClickNotify {
public static enum InviteMeans {
SMS, EMAIL, NFC, BLUETOOTH,
SMS, EMAIL, NFC, BLUETOOTH, CLIPBOARD,
};
void dlgButtonClicked( Action action, int button, Object[] params );
void inviteChoiceMade( Action action, InviteMeans means, Object[] params );
@ -335,6 +335,11 @@ public class DlgDelegate {
showNotAgainDlgThen( msgID, prefsKey, Action.SKIP_CALLBACK );
}
private void showNotAgainDlgThen( String msg, int prefsKey )
{
showNotAgainDlgThen( msg, prefsKey, Action.SKIP_CALLBACK, null, null );
}
public void showConfirmThen( String msg, Action action )
{
showConfirmThen( null, msg, android.R.string.ok, action, null );
@ -626,6 +631,9 @@ public class DlgDelegate {
items.add( getString( R.string.invite_choice_nfc ) );
means.add( DlgClickNotify.InviteMeans.NFC );
}
final int clipPos = means.size();
items.add( getString( R.string.slmenu_copy_sel ) );
means.add( DlgClickNotify.InviteMeans.CLIPBOARD );
final int[] sel = { -1 };
OnClickListener selChanged = new OnClickListener() {
@ -637,6 +645,13 @@ public class DlgDelegate {
.setEnabled( true );
}
sel[0] = view;
if ( view == clipPos ) {
String msg =
getString( R.string.not_again_clip_expl_fmt,
getString(R.string.slmenu_copy_sel) );
showNotAgainDlgThen( msg, R.string.key_na_clip_expl );
}
}
};
OnClickListener okClicked = new OnClickListener() {

View file

@ -49,7 +49,6 @@ import org.eehouse.android.xw4.jni.CommsAddrRec.CommsConnType;
import org.eehouse.android.xw4.jni.CommsAddrRec.CommsConnTypeSet;
import org.eehouse.android.xw4.jni.CurGameInfo.DeviceRole;
import org.eehouse.android.xw4.jni.LastMoveInfo;
import org.eehouse.android.xw4.DlgDelegate.DlgClickNotify.InviteMeans;
public class GameUtils {
@ -163,13 +162,6 @@ public class GameUtils {
}
}
private static GameSummary summarizeAndClose( Context context,
GameLock lock,
int gamePtr, CurGameInfo gi )
{
return summarizeAndClose( context, lock, gamePtr, gi, null );
}
private static int setFromFeedImpl( FeedUtilsImpl feedImpl )
{
int result = GameSummary.MSG_FLAGS_NONE;
@ -186,17 +178,12 @@ public class GameUtils {
}
private static GameSummary summarizeAndClose( Context context,
GameLock lock,
int gamePtr, CurGameInfo gi,
FeedUtilsImpl feedImpl )
GameLock lock, int gamePtr,
CurGameInfo gi )
{
GameSummary summary = new GameSummary( context, gi );
XwJNI.game_summarize( gamePtr, summary );
if ( null != feedImpl ) {
summary.pendingMsgLevel |= setFromFeedImpl( feedImpl );
}
DBUtils.saveSummary( context, lock, summary );
XwJNI.game_dispose( gamePtr );
@ -605,6 +592,33 @@ public class GameUtils {
inviteID, gameID, gameName, isHost );
}
// @SuppressLint({ "NewApi", "NewApi", "NewApi", "NewApi" })
// @SuppressWarnings("deprecation")
// @TargetApi(11)
public static void inviteURLToClip( Context context, NetLaunchInfo nli )
{
Uri gameUri = nli.makeLaunchUri( context );
String asStr = gameUri.toString();
int sdk = android.os.Build.VERSION.SDK_INT;
if ( sdk < android.os.Build.VERSION_CODES.HONEYCOMB ) {
android.text.ClipboardManager clipboard =
(android.text.ClipboardManager)
context.getSystemService(Context.CLIPBOARD_SERVICE);
clipboard.setText( asStr );
} else {
android.content.ClipboardManager clipboard =
(android.content.ClipboardManager)
context.getSystemService(Context.CLIPBOARD_SERVICE);
String label = LocUtils.getString( context, R.string.clip_label );
android.content.ClipData clip = android.content.ClipData
.newPlainText( label, asStr );
clipboard.setPrimaryClip( clip );
}
Utils.showToast( context, R.string.invite_copied );
}
public static void launchEmailInviteActivity( Activity activity, NetLaunchInfo nli )
{
// DbgUtils.logf( "launchEmailInviteActivity: nli=%s", nli.makeLaunchJSON() );
@ -897,12 +911,13 @@ public class GameUtils {
}
saveGame( context, gamePtr, gi, lock, false );
summarizeAndClose( context, lock, gamePtr, gi, feedImpl );
summarizeAndClose( context, lock, gamePtr, gi );
int flags = setFromFeedImpl( feedImpl );
if ( GameSummary.MSG_FLAGS_NONE != flags ) {
draw = true;
DBUtils.setMsgFlags( rowid, flags );
int curFlags = DBUtils.getMsgFlags( context, rowid );
DBUtils.setMsgFlags( rowid, flags | curFlags );
}
}
lock.unlock();

View file

@ -140,6 +140,8 @@ public class NetStateCache {
NetworkInfo ni = (NetworkInfo)intent.
getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
NetworkInfo.State state = ni.getState();
DbgUtils.logdf( "NetStateCache.PvtBroadcastReceiver.onReceive(state=%s)",
state.toString() );
boolean netAvail;
switch ( state ) {
@ -193,6 +195,10 @@ public class NetStateCache {
};
mHandler.postDelayed( mNotifyLater, WAIT_STABLE_MILLIS );
}
} else {
DbgUtils.logdf( "NetStateCache.PvtBroadcastReceiver.onReceive:"
+ " no change; doing nothing; s_netAvail=%b",
s_netAvail );
}
}
}

View file

@ -63,7 +63,6 @@ public class GameSummary {
public String roomName;
public String relayID;
public int seed;
public int pendingMsgLevel;
public long modtime;
public int gameID;
public String[] remoteDevs; // BTAddrs and phone numbers
@ -83,7 +82,6 @@ public class GameSummary {
public GameSummary( Context context ) {
m_context = context;
pendingMsgLevel = 0;
gameID = 0;
}

View file

@ -102,6 +102,7 @@ public class JNIThread extends Thread {
public static final int TOOLBAR_STATES = 4;
public static final int GOT_WORDS = 5;
public static final int GAME_OVER = 6;
public static final int MSGS_SENT = 7;
public class GameStateInfo implements Cloneable {
public int visTileCount;
@ -522,9 +523,13 @@ public class JNIThread extends Thread {
break;
case CMD_RESEND:
XwJNI.comms_resendAll( m_jniGamePtr,
((Boolean)args[0]).booleanValue(),
((Boolean)args[1]).booleanValue() );
int nSent =
XwJNI.comms_resendAll( m_jniGamePtr,
((Boolean)args[0]).booleanValue(),
((Boolean)args[1]).booleanValue() );
if ( ((Boolean)args[2]).booleanValue() ) {
Message.obtain(m_handler, MSGS_SENT, nSent).sendToTarget();
}
break;
// case CMD_ACKANY:
// XwJNI.comms_ackAny( m_jniGamePtr );

View file

@ -317,8 +317,8 @@ public class XwJNI {
public static native void comms_getAddr( int gamePtr, CommsAddrRec addr );
public static native CommsAddrRec[] comms_getAddrs( int gamePtr );
public static native void comms_setAddr( int gamePtr, CommsAddrRec addr );
public static native void comms_resendAll( int gamePtr, boolean force,
boolean andAck );
public static native int comms_resendAll( int gamePtr, boolean force,
boolean andAck );
public static native void comms_ackAny( int gamePtr );
public static native void comms_transportFailed( int gamePtr,
CommsConnType failed );

View file

@ -70,6 +70,10 @@ case $DIRNAME in
;;
esac
# if we're running for the first time in this directory/variant,
# generate local.properties
[ -e local.properties ] || ../scripts/setup_local_props.sh
ant $CMDS
if [ -n "$UNINSTALL" ]; then

View file

@ -1436,9 +1436,10 @@ send_ack( CommsCtxt* comms )
(void)send_via_relay( comms, XWRELAY_ACK, comms->rr.myHostID, NULL, 0 );
}
XP_Bool
XP_S16
comms_resendAll( CommsCtxt* comms, XP_Bool force )
{
XP_S16 count = 0;
XP_Bool success = XP_TRUE;
XP_ASSERT( !!comms );
@ -1452,9 +1453,13 @@ comms_resendAll( CommsCtxt* comms, XP_Bool force )
MsgQueueElem* msg;
for ( msg = comms->msgQueueHead; !!msg; msg = msg->next ) {
if ( 0 > sendMsg( comms, msg ) ) {
XP_S16 len = sendMsg( comms, msg );
if ( 0 > len ) {
success = XP_FALSE;
break;
} else {
XP_ASSERT( 0 < len );
++count;
}
}
@ -1465,9 +1470,9 @@ comms_resendAll( CommsCtxt* comms, XP_Bool force )
comms->nextResend = now + comms->resendBackoff;
}
}
XP_LOGF( TAGFMT() "=>%d", TAGPRMS, success );
return success;
} /* comms_resend */
XP_LOGF( TAGFMT() "=>%d", TAGPRMS, count );
return count;
} /* comms_resendAll */
#ifdef XWFEATURE_COMMSACK
void

View file

@ -214,7 +214,7 @@ void addrFromStream( CommsAddrRec* addr, XWStreamCtxt* stream );
void addrToStream( XWStreamCtxt* stream, const CommsAddrRec* addr );
XP_S16 comms_send( CommsCtxt* comms, XWStreamCtxt* stream );
XP_Bool comms_resendAll( CommsCtxt* comms, XP_Bool force );
XP_S16 comms_resendAll( CommsCtxt* comms, XP_Bool force );
XP_U16 comms_getChannelSeed( CommsCtxt* comms );
#ifdef XWFEATURE_COMMSACK

View file

@ -345,9 +345,6 @@ chooseMove( EngineCtxt* engine, PossibleMove** move )
result = (NULL != chosen) && (chosen->score > 0);
if ( !result ) {
engine_reset( engine );
}
return result;
} /* chooseMove */
@ -381,7 +378,7 @@ normalizeIQ( EngineCtxt* engine, XP_U16 iq )
XP_Bool
engine_findMove( EngineCtxt* engine, const ModelCtxt* model,
XP_U16 turn, const Tile* tiles,
XP_U16 nTiles, XP_Bool usePrev,
const XP_U16 nTiles, XP_Bool usePrev,
#ifdef XWFEATURE_BONUSALL
XP_U16 allTilesBonus,
#endif
@ -394,7 +391,9 @@ engine_findMove( EngineCtxt* engine, const ModelCtxt* model,
XP_Bool result = XP_TRUE;
XP_U16 star_row;
XP_Bool canMove = XP_FALSE;
XP_Bool isRetry = XP_FALSE;
retry:
engine->nTilesMax = XP_MIN( MAX_TRAY_TILES, nTiles );
#ifdef XWFEATURE_BONUSALL
engine->allTilesBonus = allTilesBonus;
@ -542,6 +541,22 @@ engine_findMove( EngineCtxt* engine, const ModelCtxt* model,
newMove->nTiles = 0;
}
/* Gross hack alert: there's an elusive bug in move cacheing that means
when we move forward or back from the highest-scoring move to the
lowest (or vice-versa) no move is found. But the next try succeeds,
because an engine_reset clears the state that makes that happen. So as
a workaround, try doing that when no moves are found. If none is found
for some other reason, e.g. no tiles, at least the search should be
quick. */
if ( !canMove ) {
engine_reset( engine );
if ( !isRetry ) {
isRetry = XP_TRUE;
XP_LOGF( "%s: no moves found so retrying", __func__ );
goto retry;
}
}
*canMoveP = canMove;
return result;
} /* engine_findMove */
@ -1146,23 +1161,24 @@ considerScoreWordHasBlanks( EngineCtxt* engine, XP_U16 blanksLeft,
static void
saveMoveIfQualifies( EngineCtxt* engine, PossibleMove* posmove )
{
XP_S16 mostest = 0;
XP_S16 mostest;
XP_S16 cmpVal;
XP_Bool usePrev = engine->usePrev;
XP_Bool foundEmpty = XP_FALSE;
MoveIterationData* miData = &engine->miData;
if ( 1 == engine->nMovesToSave ) { /* only saving one */
mostest = 0;
} else {
mostest = -1;
/* we're not interested if we've seen this */
cmpVal = CMPMOVES( posmove, &engine->miData.lastSeenMove );
cmpVal = CMPMOVES( posmove, &miData->lastSeenMove );
if ( !usePrev && cmpVal >= 0 ) {
/* XP_LOGF( "%s: dropping %d: higher than %d", __func__, */
/* posmove->score, engine->miData.lastSeenMove.score ); */
/* XP_LOGF( "%s: dropping %d: >= %d", __func__, */
/* posmove->score, miData->lastSeenMove.score ); */
} else if ( usePrev && cmpVal <= 0 ) {
/* XP_LOGF( "%s: dropping %d: lower than %d", __func__, */
/* posmove->score, engine->miData.lastSeenMove.score ); */
/* XP_LOGF( "%s: dropping %d: <= %d", __func__, */
/* posmove->score, miData->lastSeenMove.score ); */
} else {
XP_S16 ii;
/* terminate i at 1 because mostest starts at 0 */
@ -1178,19 +1194,19 @@ saveMoveIfQualifies( EngineCtxt* engine, PossibleMove* posmove )
/* 1/20/2001 I don't see that this assertion is valid. I
simply don't understand why it isn't tripped all the time
in the old crosswords. */
/* XP_ASSERT( (engine->miData.lastSeenMove.score == 0x7fff) */
/* || (engine->miData.savedMoves[i].score */
/* XP_ASSERT( (miData->lastSeenMove.score == 0x7fff) */
/* || (miData->savedMoves[i].score */
/* <= posmove->score) ); */
if ( 0 == engine->miData.savedMoves[ii].score ) {
if ( 0 == miData->savedMoves[ii].score ) {
foundEmpty = XP_TRUE;
mostest = ii;
break;
} else if ( -1 == mostest ) {
mostest = ii;
} else {
cmpVal = CMPMOVES( &engine->miData.savedMoves[mostest],
&engine->miData.savedMoves[ii] );
cmpVal = CMPMOVES( &miData->savedMoves[mostest],
&miData->savedMoves[ii] );
if ( !usePrev && cmpVal > 0 ) {
mostest = ii;
} else if ( usePrev && cmpVal < 0 ) {
@ -1204,14 +1220,14 @@ saveMoveIfQualifies( EngineCtxt* engine, PossibleMove* posmove )
while ( mostest >= 0 ) { /* while: so we can break */
/* record the score we're dumping. No point in considering any scores
lower than this for the rest of this round. */
/* engine->miData.lowestSavedScore = */
/* engine->miData.savedMoves[lowest].score; */
/* miData->lowestSavedScore = */
/* miData->savedMoves[lowest].score; */
/* XP_DEBUGF( "lowestSavedScore now %d\n", */
/* engine->miData.lowestSavedScore ); */
/* miData->lowestSavedScore ); */
if ( foundEmpty ) {
/* we're good */
} else {
cmpVal = CMPMOVES( posmove, &engine->miData.savedMoves[mostest]);
cmpVal = CMPMOVES( posmove, &miData->savedMoves[mostest]);
if ( !usePrev && cmpVal <= 0 ) {
break;
} else if ( usePrev && cmpVal >= 0 ) {
@ -1219,10 +1235,10 @@ saveMoveIfQualifies( EngineCtxt* engine, PossibleMove* posmove )
}
}
/* XP_LOGF( "saving move with score %d at %d (replacing %d)\n", */
/* posmove->score, mostest, */
/* engine->miData.savedMoves[mostest].score ); */
XP_MEMCPY( &engine->miData.savedMoves[mostest], posmove,
sizeof(engine->miData.savedMoves[mostest]) );
/* posmove->score, mostest, */
/* miData->savedMoves[mostest].score ); */
XP_MEMCPY( &miData->savedMoves[mostest], posmove,
sizeof(miData->savedMoves[mostest]) );
break;
}
} /* saveMoveIfQualifies */
@ -1230,15 +1246,16 @@ saveMoveIfQualifies( EngineCtxt* engine, PossibleMove* posmove )
static void
set_search_limits( EngineCtxt* engine )
{
MoveIterationData* miData = &engine->miData;
/* If we're going to be searching backwards we want our highest cached
move as the limit; otherwise the lowest */
if ( 0 < engine->miData.nInMoveCache ) {
if ( 0 < miData->nInMoveCache ) {
XP_U16 srcIndx = engine->usePrev
? engine->nMovesToSave-1 : engine->miData.bottom;
XP_MEMCPY( &engine->miData.lastSeenMove,
&engine->miData.savedMoves[srcIndx],
sizeof(engine->miData.lastSeenMove) );
//engine->miData.lowestSavedScore = 0;
? engine->nMovesToSave-1 : miData->bottom;
XP_MEMCPY( &miData->lastSeenMove,
&miData->savedMoves[srcIndx],
sizeof(miData->lastSeenMove) );
//miData->lowestSavedScore = 0;
} else {
/* we're doing this for first time */
engine_reset( engine );
@ -1249,41 +1266,40 @@ static void
init_move_cache( EngineCtxt* engine )
{
XP_U16 nInMoveCache = engine->nMovesToSave;
MoveIterationData* miData = &engine->miData;
XP_U16 ii;
XP_ASSERT( engine->nMovesToSave == NUM_SAVED_ENGINE_MOVES );
for ( ii = 0; ii < NUM_SAVED_ENGINE_MOVES; ++ii ) {
if ( 0 == engine->miData.savedMoves[ii].score ) {
if ( 0 == miData->savedMoves[ii].score ) {
--nInMoveCache;
} else {
break;
}
}
engine->miData.nInMoveCache = nInMoveCache;
engine->miData.bottom = NUM_SAVED_ENGINE_MOVES - nInMoveCache;
miData->nInMoveCache = nInMoveCache;
miData->bottom = NUM_SAVED_ENGINE_MOVES - nInMoveCache;
if ( engine->usePrev ) {
engine->miData.curCacheIndex =
NUM_SAVED_ENGINE_MOVES - nInMoveCache - 1;
} else {
engine->miData.curCacheIndex = NUM_SAVED_ENGINE_MOVES;
}
miData->curCacheIndex = engine->usePrev
? NUM_SAVED_ENGINE_MOVES - nInMoveCache - 1
: NUM_SAVED_ENGINE_MOVES;
}
static PossibleMove*
next_from_cache( EngineCtxt* engine )
{
MoveIterationData* miData = &engine->miData;
PossibleMove* move;
if ( move_cache_empty( engine ) ) {
move = NULL;
} else {
if ( engine->usePrev ) {
++engine->miData.curCacheIndex;
++miData->curCacheIndex;
} else {
--engine->miData.curCacheIndex;
--miData->curCacheIndex;
}
move = &engine->miData.savedMoves[engine->miData.curCacheIndex];
move = &miData->savedMoves[miData->curCacheIndex];
}
return move;
}
@ -1309,21 +1325,22 @@ scoreQualifies( EngineCtxt* engine, XP_U16 score )
{
XP_Bool qualifies = XP_FALSE;
XP_Bool usePrev = engine->usePrev;
MoveIterationData* miData = &engine->miData;
if ( usePrev && score < engine->miData.lastSeenMove.score ) {
if ( usePrev && score < miData->lastSeenMove.score ) {
/* drop it */
} else if ( !usePrev && score > engine->miData.lastSeenMove.score
/* || (score < engine->miData.lowestSavedScore) */ ) {
} else if ( !usePrev && score > miData->lastSeenMove.score
/* || (score < miData->lowestSavedScore) */ ) {
/* drop it */
} else {
XP_S16 ii;
PossibleMove* savedMoves = engine->miData.savedMoves;
PossibleMove* savedMoves = miData->savedMoves;
/* Look at each saved score, and return true as soon as one's found
with a lower or equal score to this. <eeh> As an optimization,
consider remembering what the lowest score is *once there are
NUM_SAVED_ENGINE_MOVES moves in here* and doing a quick test on
that. Or better, keeping the list in sorted order. */
for ( ii = 0, savedMoves = engine->miData.savedMoves;
for ( ii = 0, savedMoves = miData->savedMoves;
ii < engine->nMovesToSave; ++ii, ++savedMoves ) {
if ( savedMoves->score == 0 ) { /* empty slot */
qualifies = XP_TRUE;

View file

@ -2119,7 +2119,7 @@ cursesmain( XP_Bool isServer, LaunchParams* params )
#ifndef XWFEATURE_STANDALONE_ONLY
/* send any events that need to get off before the event loop begins */
if ( !isServer ) {
if ( !!cGlobals->game.comms && !isServer ) {
(void)server_initClientConnection( cGlobals->game.server,
mem_stream_make( MEMPOOL
params->vtMgr,