mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-02-06 20:45:54 +01:00
Merge tag 'android_beta_100' into android_branch
ready for release
This commit is contained in:
commit
22dde029c8
26 changed files with 319 additions and 197 deletions
|
@ -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.xw4dbg"
|
||||
android:versionCode="93"
|
||||
android:versionCode="94"
|
||||
android:versionName="@string/app_version"
|
||||
>
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
<!-- extension targets. Uncomment the ones where you want to do custom work
|
||||
in between standard targets -->
|
||||
|
||||
<property name="INITIAL_CLIENT_VERS" value="4"/>
|
||||
<property name="INITIAL_CLIENT_VERS" value="7"/>
|
||||
<property name="VARIANT_NAME" value="xw4dbg"/>
|
||||
<property name="APP_NAME" value="CrossDbg"/>
|
||||
|
||||
|
|
|
@ -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="93"
|
||||
android:versionCode="94"
|
||||
android:versionName="@string/app_version"
|
||||
>
|
||||
|
||||
|
|
|
@ -13,10 +13,10 @@
|
|||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h2>Crosswords 4.4 beta 99 release</h2>
|
||||
<h2>Crosswords 4.4 beta 100 release</h2>
|
||||
|
||||
<p>This is a quick-fix release for Bluetooth on Android
|
||||
Marshmallow.</p>
|
||||
<p>This is the first of two releases that together fix stalling
|
||||
issues in network games.</p>
|
||||
|
||||
<div id="survey">
|
||||
<p>Please <a href="https://www.surveymonkey.com/s/GX3XLHR">take
|
||||
|
@ -26,10 +26,9 @@
|
|||
|
||||
<h3>New with this release</h3>
|
||||
<ul>
|
||||
<li>Work around "security" change that broke Bluetooth
|
||||
invitations and gameplay on the latest Android release
|
||||
("Marshmallow").</li>
|
||||
<li>Fix crash choosing menu at the wrong time</li>
|
||||
<li>Fix to recognize (but not yet send) correct identifier for
|
||||
game state. (Once this upgrade is out I'll do a new release that
|
||||
also sends the correct identifier.)</li>
|
||||
</ul>
|
||||
|
||||
<p>(The full changelog
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
<!-- extension targets. Uncomment the ones where you want to do custom work
|
||||
in between standard targets -->
|
||||
|
||||
<property name="INITIAL_CLIENT_VERS" value="6"/>
|
||||
<property name="INITIAL_CLIENT_VERS" value="7"/>
|
||||
<property name="VARIANT_NAME" value="xw4"/>
|
||||
<property name="APP_NAME" value="Crosswords"/>
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* -*- compile-command: "cd ..; ../scripts/ndkbuild.sh -j3"; -*- */
|
||||
/* -*- compile-command: "find-and-ant.sh debug install"; -*- */
|
||||
/*
|
||||
* Copyright © 2009 - 2011 by Eric House (xwords@eehouse.org). All rights
|
||||
* Copyright © 2009 - 2016 by Eric House (xwords@eehouse.org). All rights
|
||||
* reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
|
@ -648,7 +648,7 @@ makeDict( MPFORMAL JNIEnv *env, DictMgrCtxt* dictMgr, JNIUtilCtxt* jniutil, jstr
|
|||
anddict->super.langName = getStringCopy( MPPARM(mpool)
|
||||
env, jlangname );
|
||||
|
||||
XP_U32 numEdges;
|
||||
XP_U32 numEdges = 0;
|
||||
XP_Bool parses = parseDict( anddict, (XP_U8*)anddict->bytes,
|
||||
bytesSize, &numEdges );
|
||||
if ( !parses || (check && !checkSanity( &anddict->super,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<resources>
|
||||
<string name="app_version">4.4 beta 99</string>
|
||||
<string name="app_version">4.4 beta 100</string>
|
||||
</resources>
|
||||
|
|
|
@ -1738,7 +1738,7 @@
|
|||
<string name="about_vers_fmt">Crosswords for Android, Version %1$s,
|
||||
rev %2$s, built on %3$s.</string>
|
||||
<!-- copyright info -->
|
||||
<string name="about_copyright">Copyright (C) 1998-2015 by Eric
|
||||
<string name="about_copyright">Copyright (C) 1998-2016 by Eric
|
||||
House. This free/open source software is released under the GNU Public
|
||||
License.</string>
|
||||
|
||||
|
|
|
@ -1495,7 +1495,7 @@
|
|||
<string name="about_vers_fmt">Sdrowssorc rof ,diordna Noisrev %1$s,
|
||||
ver %2$s, tliub no %3$s.</string>
|
||||
<!-- copyright info -->
|
||||
<string name="about_copyright">Thgirypoc )C( 5102-8991 yb Cire
|
||||
<string name="about_copyright">Thgirypoc )C( 6102-8991 yb Cire
|
||||
Esuoh. Siht nepo/eerf ecruos erawtfos si desaeler rednu eht UNG Cilbup
|
||||
Esnecil.</string>
|
||||
<!-- Another paragraph in the about dialog -->
|
||||
|
|
|
@ -1495,7 +1495,7 @@
|
|||
<string name="about_vers_fmt">CROSSWORDS FOR ANDROID, VERSION %1$s,
|
||||
REV %2$s, BUILT ON %3$s.</string>
|
||||
<!-- copyright info -->
|
||||
<string name="about_copyright">COPYRIGHT (C) 1998-2015 BY ERIC
|
||||
<string name="about_copyright">COPYRIGHT (C) 1998-2016 BY ERIC
|
||||
HOUSE. THIS FREE/OPEN SOURCE SOFTWARE IS RELEASED UNDER THE GNU PUBLIC
|
||||
LICENSE.</string>
|
||||
<!-- Another paragraph in the about dialog -->
|
||||
|
|
|
@ -48,7 +48,7 @@ public class NetStateCache {
|
|||
private static boolean s_netAvail = false;
|
||||
private static boolean s_isWifi;
|
||||
private static PvtBroadcastReceiver s_receiver;
|
||||
private static final boolean s_onSim = XWApp.onEmulator();
|
||||
private static final boolean s_onSDKSim = Build.PRODUCT.contains("sdk"); // not genymotion
|
||||
|
||||
public static void register( Context context, StateChangedIf proc )
|
||||
{
|
||||
|
@ -69,11 +69,23 @@ public class NetStateCache {
|
|||
public static boolean netAvail( Context context )
|
||||
{
|
||||
initIfNot( context );
|
||||
boolean result = s_netAvail || s_onSim;
|
||||
if ( BuildConfig.DEBUG ) {
|
||||
checkSame( context, result );
|
||||
|
||||
// Cache is returning false negatives. Don't trust it.
|
||||
if ( !s_netAvail ) {
|
||||
boolean netAvail = getIsConnected( context );
|
||||
if ( netAvail ) {
|
||||
String msg = "netAvail(): second-guessing successful!!!";
|
||||
DbgUtils.logf( msg );
|
||||
Utils.showToast( context, msg );
|
||||
s_netAvail = true;
|
||||
if ( null != s_receiver ) {
|
||||
s_receiver.notifyStateChanged( context );
|
||||
}
|
||||
}
|
||||
}
|
||||
DbgUtils.logf( "NetStateCache.netAvail() => %b", result );
|
||||
|
||||
boolean result = s_netAvail || s_onSDKSim;
|
||||
DbgUtils.logf( "netAvail() => %b", result );
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -94,6 +106,19 @@ public class NetStateCache {
|
|||
}
|
||||
}
|
||||
|
||||
private static boolean getIsConnected( Context context )
|
||||
{
|
||||
boolean result = false;
|
||||
NetworkInfo ni = ((ConnectivityManager)
|
||||
context.getSystemService( Context.CONNECTIVITY_SERVICE ))
|
||||
.getActiveNetworkInfo();
|
||||
if ( null != ni && ni.isConnectedOrConnecting() ) {
|
||||
result = true;
|
||||
}
|
||||
DbgUtils.logf( "NetStateCache.getConnected() => %b", result );
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void initIfNot( Context context )
|
||||
{
|
||||
synchronized( s_haveReceiver ) {
|
||||
|
@ -150,7 +175,7 @@ public class NetStateCache {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onReceive( final Context context, Intent intent )
|
||||
public void onReceive( Context context, Intent intent )
|
||||
{
|
||||
DbgUtils.assertOnUIThread();
|
||||
|
||||
|
@ -180,41 +205,7 @@ public class NetStateCache {
|
|||
|
||||
if ( s_netAvail != netAvail ) {
|
||||
s_netAvail = netAvail; // keep current in case we're asked
|
||||
|
||||
// We want to wait for WAIT_STABLE_MILLIS of inactivity
|
||||
// before informing listeners. So each time there's a
|
||||
// change, kill any existing timer then set another, which
|
||||
// will only fire if we go that long without coming
|
||||
// through here again.
|
||||
|
||||
if ( null != mNotifyLater ) {
|
||||
mHandler.removeCallbacks( mNotifyLater );
|
||||
mNotifyLater = null;
|
||||
}
|
||||
if ( mLastStateSent != s_netAvail ) {
|
||||
mNotifyLater = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Assert.assertTrue( mLastStateSent != s_netAvail );
|
||||
mLastStateSent = s_netAvail;
|
||||
|
||||
synchronized( s_ifs ) {
|
||||
Iterator<StateChangedIf> iter = s_ifs.iterator();
|
||||
while ( iter.hasNext() ) {
|
||||
iter.next().netAvail( s_netAvail );
|
||||
}
|
||||
}
|
||||
|
||||
if ( s_netAvail ) {
|
||||
CommsConnType typ = CommsConnType
|
||||
.COMMS_CONN_RELAY;
|
||||
GameUtils.resendAllIf( context, typ,
|
||||
false );
|
||||
}
|
||||
}
|
||||
};
|
||||
mHandler.postDelayed( mNotifyLater, WAIT_STABLE_MILLIS );
|
||||
}
|
||||
notifyStateChanged( context );
|
||||
} else {
|
||||
DbgUtils.logdf( "NetStateCache.PvtBroadcastReceiver.onReceive:"
|
||||
+ " no change; doing nothing; s_netAvail=%b",
|
||||
|
@ -222,6 +213,46 @@ public class NetStateCache {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void notifyStateChanged( final Context context )
|
||||
{
|
||||
// We want to wait for WAIT_STABLE_MILLIS of inactivity
|
||||
// before informing listeners. So each time there's a
|
||||
// change, kill any existing timer then set another, which
|
||||
// will only fire if we go that long without coming
|
||||
// through here again.
|
||||
|
||||
if ( null != mNotifyLater ) {
|
||||
mHandler.removeCallbacks( mNotifyLater );
|
||||
mNotifyLater = null;
|
||||
}
|
||||
if ( mLastStateSent != s_netAvail ) {
|
||||
mNotifyLater = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Assert.assertTrue( mLastStateSent != s_netAvail );
|
||||
mLastStateSent = s_netAvail;
|
||||
|
||||
DbgUtils.logf( "NetStateCache.notifyStateChanged(%b)",
|
||||
s_netAvail );
|
||||
|
||||
synchronized( s_ifs ) {
|
||||
Iterator<StateChangedIf> iter = s_ifs.iterator();
|
||||
while ( iter.hasNext() ) {
|
||||
iter.next().netAvail( s_netAvail );
|
||||
}
|
||||
}
|
||||
|
||||
if ( s_netAvail ) {
|
||||
CommsConnType typ = CommsConnType
|
||||
.COMMS_CONN_RELAY;
|
||||
GameUtils.resendAllIf( context, typ, false );
|
||||
}
|
||||
}
|
||||
};
|
||||
mHandler.postDelayed( mNotifyLater, WAIT_STABLE_MILLIS );
|
||||
}
|
||||
}
|
||||
} // class PvtBroadcastReceiver
|
||||
|
||||
}
|
||||
|
|
|
@ -6,6 +6,9 @@ $(DEST_PATH)/%.java : $(SRC_PATH)/%.java
|
|||
-e "s,\(import org.eehouse.android.\)xw4\(.*\);,\1$(VARIANT)\2;," \
|
||||
< $< > $@
|
||||
|
||||
$(DEST_PATH)/icon48x48.png : $(SRC_PATH)/icon48x48.png
|
||||
convert $< -fill red -gravity Center -annotate +0+5 ' Dbg ' $@
|
||||
|
||||
$(DEST_PATH)/%.png : $(SRC_PATH)/%.png
|
||||
@cp $< $@
|
||||
|
||||
|
|
|
@ -94,9 +94,9 @@ dbg_logstream( const XWStreamCtxt* stream, const char* func, int line )
|
|||
if ( !!stream ) {
|
||||
XP_U16 len = 0;
|
||||
XWStreamPos end = stream_getPos( stream, POS_WRITE );
|
||||
stream_copyBits( stream, 0, end, NULL, &len );
|
||||
stream_copyBits( stream, end, NULL, &len );
|
||||
XP_U8 buf[len];
|
||||
stream_copyBits( stream, 0, end, buf, &len );
|
||||
stream_copyBits( stream, end, buf, &len );
|
||||
char comment[128];
|
||||
XP_SNPRINTF( comment, VSIZE(comment), "%s line %d", func, line );
|
||||
LOG_HEX( buf, len, comment );
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "comtypes.h"
|
||||
#include "memstream.h"
|
||||
#include "vtabmgr.h"
|
||||
#include "strutils.h"
|
||||
|
||||
#ifdef CPLUS
|
||||
extern "C" {
|
||||
|
@ -184,10 +185,10 @@ mem_stream_getBits( XWStreamCtxt* p_sctx, XP_U16 nBits )
|
|||
return result;
|
||||
} /* stream_getBits */
|
||||
|
||||
#if defined HASH_STREAM || defined DEBUG
|
||||
#if defined DEBUG
|
||||
static void
|
||||
mem_stream_copyBits( const XWStreamCtxt* p_sctx, XWStreamPos XP_UNUSED(startPos),
|
||||
XWStreamPos endPos, XP_U8* buf, XP_U16* lenp )
|
||||
mem_stream_copyBits( const XWStreamCtxt* p_sctx, XWStreamPos endPos,
|
||||
XP_U8* buf, XP_U16* lenp )
|
||||
{
|
||||
MemStreamCtxt* stream = (MemStreamCtxt*)p_sctx;
|
||||
XP_U16 len = BYTE_PART(endPos);
|
||||
|
@ -195,7 +196,7 @@ mem_stream_copyBits( const XWStreamCtxt* p_sctx, XWStreamPos XP_UNUSED(startPos)
|
|||
XP_ASSERT( len <= stream->nBytesAllocated );
|
||||
XP_MEMCPY( buf, stream->buf, len );
|
||||
if ( 0 != BIT_PART(endPos) ) {
|
||||
buf[len-1] &= 1 << BIT_PART(endPos);
|
||||
buf[len-1] &= ~(0xFF << BIT_PART(endPos));
|
||||
}
|
||||
}
|
||||
*lenp = len;
|
||||
|
@ -371,6 +372,36 @@ mem_stream_getSize( const XWStreamCtxt* p_sctx )
|
|||
return size;
|
||||
} /* mem_stream_getSize */
|
||||
|
||||
static XP_U32
|
||||
mem_stream_getHash( const XWStreamCtxt* p_sctx, XWStreamPos pos,
|
||||
XP_Bool correct )
|
||||
{
|
||||
XP_U32 hash = 0;
|
||||
const MemStreamCtxt* stream = (const MemStreamCtxt*)p_sctx;
|
||||
const XP_U8* ptr = stream->buf;
|
||||
XP_U16 len = BYTE_PART(pos);
|
||||
XP_U16 bits = BIT_PART(pos);
|
||||
if ( 0 != bits ) {
|
||||
XP_ASSERT( 0 < len );
|
||||
--len;
|
||||
}
|
||||
|
||||
hash = augmentHash( 0, ptr, len );
|
||||
if ( 0 != bits ) {
|
||||
XP_U8 byt = ptr[len];
|
||||
if ( correct ) {
|
||||
byt &= ~(0xFF << bits);
|
||||
} else {
|
||||
byt &= 1 << bits;
|
||||
}
|
||||
hash = augmentHash( hash, &byt, 1 );
|
||||
}
|
||||
hash = finishHash( hash );
|
||||
|
||||
LOG_RETURNF( "%X(%d:%d)", hash, len, bits );
|
||||
return hash;
|
||||
} /* mem_stream_getHash */
|
||||
|
||||
static const XP_U8*
|
||||
mem_stream_getPtr( const XWStreamCtxt* p_sctx )
|
||||
{
|
||||
|
@ -476,7 +507,7 @@ make_vtable( MemStreamCtxt* stream )
|
|||
SET_VTABLE_ENTRY( vtable, stream_getU16, mem );
|
||||
SET_VTABLE_ENTRY( vtable, stream_getU32, mem );
|
||||
SET_VTABLE_ENTRY( vtable, stream_getBits, mem );
|
||||
#if defined HASH_STREAM || defined DEBUG
|
||||
#if defined DEBUG
|
||||
SET_VTABLE_ENTRY( vtable, stream_copyBits, mem );
|
||||
#endif
|
||||
|
||||
|
@ -497,6 +528,7 @@ make_vtable( MemStreamCtxt* stream )
|
|||
SET_VTABLE_ENTRY( vtable, stream_close, mem );
|
||||
|
||||
SET_VTABLE_ENTRY( vtable, stream_getSize, mem );
|
||||
SET_VTABLE_ENTRY( vtable, stream_getHash, mem );
|
||||
SET_VTABLE_ENTRY( vtable, stream_getPtr, mem );
|
||||
SET_VTABLE_ENTRY( vtable, stream_getAddress, mem );
|
||||
SET_VTABLE_ENTRY( vtable, stream_setAddress, mem );
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* -*- compile-command: "cd ../linux && make -j3 MEMDEBUG=TRUE"; -*- */
|
||||
/*
|
||||
* Copyright 2000-2011 by Eric House (xwords@eehouse.org). All rights
|
||||
* Copyright 2000-2015 by Eric House (xwords@eehouse.org). All rights
|
||||
* reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
|
@ -312,36 +312,67 @@ model_destroy( ModelCtxt* model )
|
|||
} /* model_destroy */
|
||||
|
||||
XP_U32
|
||||
model_getHash( const ModelCtxt* model, XP_U16 version )
|
||||
model_getHash( const ModelCtxt* model )
|
||||
{
|
||||
#ifndef STREAM_VERS_HASHSTREAM
|
||||
XP_USE(version);
|
||||
#endif
|
||||
StackCtxt* stack = model->vol.stack;
|
||||
XP_ASSERT( !!stack );
|
||||
XP_U32 hash =
|
||||
#ifdef STREAM_VERS_HASHSTREAM
|
||||
STREAM_VERS_HASHSTREAM <= version ?
|
||||
stack_getHash( stack ) :
|
||||
#endif
|
||||
stack_getHashOld( stack );
|
||||
/* XP_LOGF( "%s(version=%x)=>%.8X", __func__, version, */
|
||||
/* (unsigned int)hash ); */
|
||||
return hash;
|
||||
return stack_getHash( stack, XP_FALSE );
|
||||
}
|
||||
|
||||
XP_Bool
|
||||
model_hashMatches( const ModelCtxt* model, const XP_U32 hash )
|
||||
{
|
||||
StackCtxt* stack = model->vol.stack;
|
||||
XP_Bool matches =
|
||||
#ifdef STREAM_VERS_HASHSTREAM
|
||||
(hash == stack_getHash( stack )) ||
|
||||
#endif
|
||||
(hash == stack_getHashOld( stack ));
|
||||
XP_Bool matches = hash == stack_getHash( stack, XP_TRUE )
|
||||
|| hash == stack_getHash( stack, XP_FALSE );
|
||||
return matches;
|
||||
}
|
||||
|
||||
XP_Bool
|
||||
model_popToHash( ModelCtxt* model, const XP_U32 hash, PoolContext* pool )
|
||||
{
|
||||
XP_U16 nPopped = 0;
|
||||
StackCtxt* stack = model->vol.stack;
|
||||
const XP_U16 nEntries = stack_getNEntries( stack );
|
||||
StackEntry entries[nEntries];
|
||||
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 ) ) {
|
||||
foundAt = ii;
|
||||
break;
|
||||
}
|
||||
if ( ! stack_popEntry( stack, &entries[ii] ) ) {
|
||||
break;
|
||||
}
|
||||
++nPopped;
|
||||
}
|
||||
|
||||
for ( XP_S16 ii = nPopped - 1; ii >= 0; --ii ) {
|
||||
stack_redo( stack, &entries[ii] );
|
||||
}
|
||||
|
||||
XP_Bool found = -1 != foundAt;
|
||||
if ( found ) {
|
||||
XP_LOGF( "%s: undoing %d turns to match hash %X", __func__,
|
||||
foundAt, hash );
|
||||
#ifdef DEBUG
|
||||
XP_Bool success =
|
||||
#endif
|
||||
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 ) );
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
#ifdef STREAM_VERS_BIGBOARD
|
||||
void
|
||||
model_setSquareBonuses( ModelCtxt* model, XWBonusType* bonuses, XP_U16 nBonuses )
|
||||
|
|
|
@ -122,8 +122,11 @@ void model_writeToTextStream( const ModelCtxt* model, XWStreamCtxt* stream );
|
|||
|
||||
void model_setSize( ModelCtxt* model, XP_U16 boardSize );
|
||||
void model_destroy( ModelCtxt* model );
|
||||
XP_U32 model_getHash( const ModelCtxt* model, XP_U16 version );
|
||||
XP_U32 model_getHash( const ModelCtxt* model );
|
||||
XP_Bool model_hashMatches( const ModelCtxt* model, XP_U32 hash );
|
||||
XP_Bool model_popToHash( ModelCtxt* model, const XP_U32 hash,
|
||||
PoolContext* pool );
|
||||
|
||||
void model_setNPlayers( ModelCtxt* model, XP_U16 numPlayers );
|
||||
XP_U16 model_getNPlayers( const ModelCtxt* model );
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* -*- compile-command: "cd ../linux && make -j3 MEMDEBUG=TRUE"; -*- */
|
||||
/* -*- compile-command: "cd ../linux && make -j5 MEMDEBUG=TRUE"; -*- */
|
||||
/*
|
||||
* Copyright 2001, 2006-2012 by Eric House (xwords@eehouse.org). All rights
|
||||
* Copyright 2001-2015 by Eric House (xwords@eehouse.org). All rights
|
||||
* reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
|
@ -67,88 +67,14 @@ stack_init( StackCtxt* stack )
|
|||
shrunk to fit as soon as we serialize/deserialize anyway. */
|
||||
} /* stack_init */
|
||||
|
||||
static XP_U32
|
||||
augmentHash( XP_U32 hash, const XP_U8* ptr, XP_U16 len )
|
||||
{
|
||||
XP_ASSERT( 0 < len );
|
||||
// see http://en.wikipedia.org/wiki/Jenkins_hash_function
|
||||
XP_U16 ii;
|
||||
for ( ii = 0; ii < len; ++ii ) {
|
||||
hash += *ptr++;
|
||||
hash += (hash << 10);
|
||||
hash ^= (hash >> 6);
|
||||
}
|
||||
// XP_LOGF( "%s: hashed %d bytes -> %X", __func__, len, (unsigned int)hash );
|
||||
return hash;
|
||||
}
|
||||
|
||||
static XP_U32
|
||||
finishHash( XP_U32 hash )
|
||||
{
|
||||
hash += (hash << 3);
|
||||
hash ^= (hash >> 11);
|
||||
hash += (hash << 15);
|
||||
return hash;
|
||||
}
|
||||
|
||||
static XP_U32
|
||||
augmentFor( XP_U32 hash, const StackEntry* entry )
|
||||
{
|
||||
switch( entry->moveType ) {
|
||||
case ASSIGN_TYPE: {
|
||||
TrayTileSet tiles;
|
||||
sortTiles( &tiles, &entry->u.assign.tiles, 0 );
|
||||
hash = augmentHash( hash, (XP_U8*)&tiles, sizeof(tiles) );
|
||||
}
|
||||
break;
|
||||
case MOVE_TYPE:
|
||||
hash = augmentHash( hash, (XP_U8*)&entry->u.move,
|
||||
sizeof(entry->u.move) );
|
||||
break;
|
||||
case TRADE_TYPE:
|
||||
hash = augmentHash( hash, (XP_U8*)&entry->u.trade,
|
||||
sizeof(entry->u.trade) );
|
||||
break;
|
||||
case PHONY_TYPE:
|
||||
hash = augmentHash( hash, (XP_U8*)&entry->u.phony,
|
||||
sizeof(entry->u.phony) );
|
||||
break;
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
XP_U32
|
||||
stack_getHashOld( StackCtxt* stack )
|
||||
{
|
||||
XP_U16 nn, nEntries = stack->nEntries;
|
||||
XP_U32 hash = 0L;
|
||||
for ( nn = 0; nn < nEntries; ++nn ) {
|
||||
StackEntry entry;
|
||||
XP_MEMSET( &entry, 0, sizeof(entry) );
|
||||
if ( !stack_getNthEntry( stack, nn, &entry ) ) {
|
||||
XP_ASSERT( 0 );
|
||||
}
|
||||
hash = augmentFor( hash, &entry );
|
||||
// XP_LOGF( "hash after %d: %.8X", nn, (unsigned int)hash );
|
||||
}
|
||||
XP_ASSERT( 0 != hash );
|
||||
hash = finishHash( hash );
|
||||
LOG_RETURNF( "%.8X", (unsigned int)hash );
|
||||
return hash;
|
||||
} /* stack_getHashOld */
|
||||
|
||||
#ifdef STREAM_VERS_HASHSTREAM
|
||||
XP_U32
|
||||
stack_getHash( const StackCtxt* stack )
|
||||
stack_getHash( const StackCtxt* stack, XP_Bool correct )
|
||||
{
|
||||
XP_U32 hash;
|
||||
XP_U16 len = 0;
|
||||
stream_copyBits( stack->data, 0, stack->top, NULL, &len );
|
||||
XP_U8 buf[len];
|
||||
stream_copyBits( stack->data, 0, stack->top, buf, &len );
|
||||
// LOG_HEX( buf, len, __func__ );
|
||||
hash = finishHash( augmentHash( 0L, buf, len ) );
|
||||
// LOG_RETURNF( "%.8X", (unsigned int)hash );
|
||||
XP_U32 hash = 0;
|
||||
if ( !!stack->data ) {
|
||||
hash = stream_getHash( stack->data, stack->top, correct );
|
||||
}
|
||||
return hash;
|
||||
} /* stack_getHash */
|
||||
#endif
|
||||
|
@ -250,7 +176,7 @@ stack_copy( const StackCtxt* stack )
|
|||
}
|
||||
|
||||
static void
|
||||
pushEntry( StackCtxt* stack, const StackEntry* entry )
|
||||
pushEntryImpl( StackCtxt* stack, const StackEntry* entry )
|
||||
{
|
||||
XP_U16 ii, bitsPerTile;
|
||||
XWStreamPos oldLoc;
|
||||
|
@ -308,9 +234,33 @@ pushEntry( StackCtxt* stack, const StackEntry* entry )
|
|||
++stack->nEntries;
|
||||
stack->highWaterMark = stack->nEntries;
|
||||
stack->top = stream_setPos( stream, POS_WRITE, oldLoc );
|
||||
// XP_LOGSTREAM( stack->data );
|
||||
#ifdef DEBUG_HASHING
|
||||
XP_LOGSTREAM( stack->data );
|
||||
#endif
|
||||
SET_DIRTY( stack );
|
||||
} /* pushEntry */
|
||||
} /* pushEntryImpl */
|
||||
|
||||
static void
|
||||
pushEntry( StackCtxt* stack, const StackEntry* entry )
|
||||
{
|
||||
#ifdef DEBUG_HASHING
|
||||
XP_Bool correct = XP_TRUE;
|
||||
XP_U32 origHash = stack_getHash( stack, correct );
|
||||
#endif
|
||||
|
||||
pushEntryImpl( stack, entry );
|
||||
|
||||
#ifdef DEBUG_HASHING
|
||||
XP_U32 newHash = stack_getHash( stack, XP_TRUE );
|
||||
StackEntry lastEntry;
|
||||
if ( stack_popEntry( stack, &lastEntry ) ) {
|
||||
XP_ASSERT( origHash == stack_getHash( stack, correct ) );
|
||||
pushEntryImpl( stack, &lastEntry );
|
||||
XP_ASSERT( newHash == stack_getHash( stack, correct ) );
|
||||
XP_LOGF( "%s: all ok", __func__ );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
readEntry( const StackCtxt* stack, StackEntry* entry )
|
||||
|
@ -482,7 +432,9 @@ stack_popEntry( StackCtxt* stack, StackEntry* entry )
|
|||
setCacheReadyFor( stack, nn ); /* set cachedPos by side-effect */
|
||||
stack->top = stack->cachedPos;
|
||||
}
|
||||
// XP_LOGSTREAM( stack->data );
|
||||
#ifdef DEBUG_HASHING
|
||||
XP_LOGSTREAM( stack->data );
|
||||
#endif
|
||||
return found;
|
||||
} /* stack_popEntry */
|
||||
|
||||
|
|
|
@ -69,8 +69,7 @@ StackCtxt* stack_make( MPFORMAL VTableMgr* vtmgr );
|
|||
void stack_destroy( StackCtxt* stack );
|
||||
|
||||
void stack_init( StackCtxt* stack );
|
||||
XP_U32 stack_getHashOld( StackCtxt* stack );
|
||||
XP_U32 stack_getHash( const StackCtxt* stack );
|
||||
XP_U32 stack_getHash( const StackCtxt* stack, XP_Bool correct );
|
||||
void stack_setBitsPerTile( StackCtxt* stack, XP_U16 bitsPerTile );
|
||||
|
||||
void stack_loadFromStream( StackCtxt* stack, XWStreamCtxt* stream );
|
||||
|
|
|
@ -2032,8 +2032,10 @@ sendMoveTo( ServerCtxt* server, XP_U16 devIndex, XP_U16 turn,
|
|||
XP_U16 version = stream_getVersion( stream );
|
||||
if ( STREAM_VERS_BIGBOARD <= version ) {
|
||||
XP_ASSERT( version == server->nv.streamVersion );
|
||||
XP_U32 hash = model_getHash( server->vol.model, version );
|
||||
// XP_LOGF( "%s: adding hash %x", __func__, (unsigned int)hash );
|
||||
XP_U32 hash = model_getHash( server->vol.model );
|
||||
#ifdef DEBUG_HASHING
|
||||
XP_LOGF( "%s: adding hash %x", __func__, (unsigned int)hash );
|
||||
#endif
|
||||
stream_putU32( stream, hash );
|
||||
}
|
||||
#endif
|
||||
|
@ -2084,10 +2086,16 @@ readMoveInfo( ServerCtxt* server, XWStreamCtxt* stream,
|
|||
#ifdef STREAM_VERS_BIGBOARD
|
||||
if ( STREAM_VERS_BIGBOARD <= stream_getVersion( stream ) ) {
|
||||
XP_U32 hashReceived = stream_getU32( stream );
|
||||
success = model_hashMatches( server->vol.model, hashReceived );
|
||||
if ( !success ) {
|
||||
XP_LOGF( "%s: hash mismatch",__func__);
|
||||
success = model_hashMatches( server->vol.model, hashReceived )
|
||||
|| model_popToHash( server->vol.model, hashReceived, server->pool );
|
||||
// XP_ASSERT( success ); /* I need to understand when this can fail */
|
||||
#ifdef DEBUG_HASHING
|
||||
if ( success ) {
|
||||
XP_LOGF( "%s: hash match: %X",__func__, hashReceived );
|
||||
} else {
|
||||
XP_LOGF( "%s: hash mismatch: %X not found",__func__, hashReceived );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
if ( success ) {
|
||||
|
|
|
@ -228,6 +228,30 @@ p_replaceStringIfDifferent( MPFORMAL XP_UCHAR** curLoc, const XP_UCHAR* newStr
|
|||
*curLoc = curStr;
|
||||
} /* replaceStringIfDifferent */
|
||||
|
||||
XP_U32
|
||||
augmentHash( XP_U32 hash, const XP_U8* ptr, XP_U16 len )
|
||||
{
|
||||
// see http://en.wikipedia.org/wiki/Jenkins_hash_function
|
||||
for ( XP_U16 ii = 0; ii < len; ++ii ) {
|
||||
hash += *ptr++;
|
||||
hash += (hash << 10);
|
||||
hash ^= (hash >> 6);
|
||||
}
|
||||
#ifdef DEBUG_HASHING
|
||||
XP_LOGF( "%s: hashed %d bytes -> %X", __func__, len, (unsigned int)hash );
|
||||
#endif
|
||||
return hash;
|
||||
}
|
||||
|
||||
XP_U32
|
||||
finishHash( XP_U32 hash )
|
||||
{
|
||||
hash += (hash << 3);
|
||||
hash ^= (hash >> 11);
|
||||
hash += (hash << 15);
|
||||
return hash;
|
||||
}
|
||||
|
||||
/*
|
||||
* A wrapper for printing etc. potentially null strings.
|
||||
*/
|
||||
|
|
|
@ -68,6 +68,8 @@ XP_UCHAR* p_copyString( MPFORMAL const XP_UCHAR* instr
|
|||
# define copyString( p, in ) p_copyString( in )
|
||||
#endif
|
||||
|
||||
XP_U32 augmentHash( XP_U32 hash, const XP_U8* ptr, XP_U16 len );
|
||||
XP_U32 finishHash( XP_U32 hash );
|
||||
|
||||
void p_replaceStringIfDifferent( MPFORMAL XP_UCHAR** curLoc,
|
||||
const XP_UCHAR* newStr
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/* -*-mode: C; fill-column: 78; c-basic-offset: 4; -*- */
|
||||
/*
|
||||
* Copyright 1997 - 2000 by Eric House (xwords@eehouse.org). All rights reserved.
|
||||
* Copyright 1997 - 2015 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
|
||||
|
@ -48,9 +49,9 @@ typedef struct StreamCtxVTable {
|
|||
XP_U16 (*m_stream_getU16)( XWStreamCtxt* dctx );
|
||||
XP_U32 (*m_stream_getU32)( XWStreamCtxt* dctx );
|
||||
XP_U32 (*m_stream_getBits)( XWStreamCtxt* dctx, XP_U16 nBits );
|
||||
#if defined HASH_STREAM || defined DEBUG
|
||||
void (*m_stream_copyBits)( const XWStreamCtxt* dctx, XWStreamPos startPos,
|
||||
XWStreamPos endPos, XP_U8* buf, XP_U16* len );
|
||||
#if defined DEBUG
|
||||
void (*m_stream_copyBits)( const XWStreamCtxt* dctx, XWStreamPos endPos,
|
||||
XP_U8* buf, XP_U16* len );
|
||||
#endif
|
||||
|
||||
void (*m_stream_putU8)( XWStreamCtxt* dctx, XP_U8 byt );
|
||||
|
@ -73,6 +74,8 @@ 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 );
|
||||
|
||||
const XP_U8* (*m_stream_getPtr)( const XWStreamCtxt* dctx );
|
||||
|
||||
|
@ -113,9 +116,9 @@ struct XWStreamCtxt {
|
|||
#define stream_getBits(sc, n) \
|
||||
(sc)->vtable->m_stream_getBits((sc), (n))
|
||||
|
||||
#if defined HASH_STREAM || defined DEBUG
|
||||
#define stream_copyBits(sc, s, e, b, l) \
|
||||
(sc)->vtable->m_stream_copyBits((sc), (s), (e), (b), (l))
|
||||
#if defined DEBUG
|
||||
#define stream_copyBits(sc, e, b, l) \
|
||||
(sc)->vtable->m_stream_copyBits((sc), (e), (b), (l))
|
||||
#endif
|
||||
|
||||
#define stream_putU8(sc, b) \
|
||||
|
@ -154,6 +157,9 @@ 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_getPtr(sc) \
|
||||
(sc)->vtable->m_stream_getPtr((sc))
|
||||
|
||||
|
|
32
xwords4/dawg/French/Makefile.ODS7
Normal file
32
xwords4/dawg/French/Makefile.ODS7
Normal file
|
@ -0,0 +1,32 @@
|
|||
# -*-mode: Makefile -*-
|
||||
# Copyright 2002 by Eric House (xwords@eehouse.org). All rights reserved.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
XWLANG=ODS7
|
||||
LANGCODE=fr_FR
|
||||
|
||||
TARGET_TYPE ?= WINCE
|
||||
|
||||
include ../Makefile.langcommon
|
||||
|
||||
$(XWLANG)Main.dict.gz: $(XWDICTPATH)/French/ods7.txt
|
||||
cat $< | tr -d '\r' | tr a-z A-Z | grep '^[A-Z]*$$' | gzip >$@
|
||||
|
||||
# Everything but creating of the Main.dict file is inherited from the
|
||||
# "parent" Makefile.langcommon in the parent directory.
|
||||
|
||||
clean: clean_common
|
||||
rm -f $(XWLANG)Main.dict.gz *.bin $(XWLANG)*.pdb $(XWLANG)*.seb
|
|
@ -22,6 +22,7 @@ ifeq ($(MEMDEBUG),TRUE)
|
|||
DEFINES = -DMEM_DEBUG -DDEBUG -DENABLE_LOGGING -DNUMBER_KEY_AS_INDEX
|
||||
DEFINES += -DCOMMS_CHECKSUM
|
||||
CFLAGS += -g $(GPROFFLAG) -Wall -Wunused-parameter -Wcast-align -Werror -O0
|
||||
# DEFINES += -DDEBUG_HASHING
|
||||
CFLAGS += -DDEBUG_TS -rdynamic
|
||||
PLATFORM = obj_linux_memdbg
|
||||
else
|
||||
|
@ -119,7 +120,7 @@ DEFINES += -DXWFEATURE_DEVID
|
|||
DEFINES += -DXWFEATURE_COMMSACK
|
||||
#DEFINES += -DXWFEATURE_ACTIVERECT
|
||||
DEFINES += -DCOMMS_XPORT_FLAGSPROC
|
||||
DEFINES += -DINITIAL_CLIENT_VERS=2
|
||||
DEFINES += -DINITIAL_CLIENT_VERS=3
|
||||
DEFINES += -DCOMMON_LAYOUT
|
||||
DEFINES += -DNATIVE_NLI
|
||||
|
||||
|
|
|
@ -554,7 +554,7 @@ secondTimerFired( gpointer data )
|
|||
if ( !!game->server && !!game->board ) {
|
||||
XP_U16 undoRatio = cGlobals->params->undoRatio;
|
||||
if ( 0 != undoRatio ) {
|
||||
if ( (XP_RANDOM() % 100) < undoRatio ) {
|
||||
if ( (XP_RANDOM() % 1000) < undoRatio ) {
|
||||
XP_LOGF( "%s: calling server_handleUndo", __func__ );
|
||||
if ( server_handleUndo( game->server, 1 ) ) {
|
||||
board_draw( game->board );
|
||||
|
@ -2443,8 +2443,8 @@ main( int argc, char** argv )
|
|||
#ifdef USE_GLIBLOOP
|
||||
case CMD_UNDOPCT:
|
||||
mainParams.undoRatio = atoi( optarg );
|
||||
if ( mainParams.undoRatio < 0 || mainParams.undoRatio > 100 ) {
|
||||
usage(argv[0], "must be 0 <= n <= 100" );
|
||||
if ( mainParams.undoRatio < 0 || mainParams.undoRatio > 1000 ) {
|
||||
usage(argv[0], "must be 0 <= n <= 1000" );
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
|
|
@ -6,7 +6,7 @@ APP_NEW=""
|
|||
DO_CLEAN=""
|
||||
APP_NEW_PARAMS=""
|
||||
NGAMES=""
|
||||
UDP_PCT_START=5
|
||||
UDP_PCT_START=100
|
||||
UDP_PCT_INCR=10
|
||||
UPGRADE_ODDS=""
|
||||
NROOMS=""
|
||||
|
@ -68,7 +68,7 @@ function cleanup() {
|
|||
|
||||
function connName() {
|
||||
LOG=$1
|
||||
grep 'got_connect_cmd: connName' $LOG | \
|
||||
grep -a 'got_connect_cmd: connName' $LOG | \
|
||||
tail -n 1 | \
|
||||
sed 's,^.*connName: \"\(.*\)\" (reconnect=.)$,\1,'
|
||||
}
|
||||
|
@ -356,7 +356,7 @@ maybe_resign() {
|
|||
if [ "$RESIGN_RATIO" -gt 0 ]; then
|
||||
KEY=$1
|
||||
LOG=${LOGS[$KEY]}
|
||||
if grep -q XWRELAY_ALLHERE $LOG; then
|
||||
if grep -aq XWRELAY_ALLHERE $LOG; then
|
||||
if [ 0 -eq $(($RANDOM % $RESIGN_RATIO)) ]; then
|
||||
echo "making $LOG $(connName $LOG) resign..."
|
||||
kill_from_log $LOG && close_device $KEY $DEADDIR "resignation forced" || /bin/true
|
||||
|
@ -397,14 +397,13 @@ check_game() {
|
|||
CONNNAME="$(connName $LOG)"
|
||||
OTHERS=""
|
||||
if [ -n "$CONNNAME" ]; then
|
||||
if grep -q '\[unused tiles\]' $LOG; then
|
||||
ALL_DONE=TRUE
|
||||
if grep -aq '\[unused tiles\]' $LOG ; then
|
||||
for INDX in ${!LOGS[*]}; do
|
||||
[ $INDX -eq $KEY ] && continue
|
||||
ALOG=${LOGS[$INDX]}
|
||||
CONNNAME2="$(connName $ALOG)"
|
||||
if [ "$CONNNAME2" = "$CONNNAME" ]; then
|
||||
if ! grep -q '\[unused tiles\]' $ALOG; then
|
||||
if ! grep -aq '\[unused tiles\]' $ALOG; then
|
||||
OTHERS=""
|
||||
break
|
||||
fi
|
||||
|
@ -424,11 +423,11 @@ check_game() {
|
|||
done
|
||||
echo ""
|
||||
# XWRELAY_ERROR_DELETED may be old
|
||||
elif grep -q 'relay_error_curses(XWRELAY_ERROR_DELETED)' $LOG; then
|
||||
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 -q 'relay_error_curses(XWRELAY_ERROR_DEADGAME)' $LOG; then
|
||||
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"
|
||||
|
@ -474,7 +473,7 @@ summarizeTileCounts() {
|
|||
for KEY in ${KEYS[@]}; do
|
||||
local LOG=${LOGS[$KEY]}
|
||||
|
||||
local LINE=$(grep pool_removeTiles $LOG | tail -n 1)
|
||||
local LINE=$(grep -a pool_removeTiles $LOG | tail -n 1)
|
||||
if [ -n "$LINE" ]; then
|
||||
local NUM=$(echo $LINE | sed 's,^.*removeTiles: \(.*\) tiles.*$,\1,')
|
||||
STR="${STR} ${KEY}:${NUM}"
|
||||
|
@ -482,7 +481,7 @@ summarizeTileCounts() {
|
|||
done
|
||||
|
||||
if [ -n "${STR}" ]; then
|
||||
echo "$(date +%r) tiles left: $STR"
|
||||
echo "** $(date +%r) tiles left: $STR"
|
||||
fi
|
||||
}
|
||||
|
||||
|
@ -613,7 +612,7 @@ function usage() {
|
|||
echo " [--seed <int>] \\" >&2
|
||||
echo " [--send-chat <interval-in-seconds> \\" >&2
|
||||
echo " [--udp-incr <pct>] \\" >&2
|
||||
echo " [--udp-start <pct>] \\" >&2
|
||||
echo " [--udp-start <pct>] # default: $UDP_PCT_START \\" >&2
|
||||
echo " [--undo-pct <int>] \\" >&2
|
||||
|
||||
exit 1
|
||||
|
|
Loading…
Add table
Reference in a new issue