add debug-only option for invitee players to be robots

It's useful when testing to have the remote device play without human
interaction. So add an option, and UI to trigger it, for the players
created remotely in response to an invitation to be robots. There are
guards in place to catch the feature slipping into a release build.
This commit is contained in:
Eric House 2019-02-07 08:17:54 -08:00
parent 136fa6ac7d
commit 438e134870
18 changed files with 151 additions and 68 deletions

View file

@ -114,8 +114,9 @@ public class BTInviteDelegate extends InviteDelegate {
RequestCode requestCode )
{
Assert.assertTrue( 0 < nMissing ); // don't call if nMissing == 0
Intent intent = new Intent( activity, BTInviteActivity.class );
intent.putExtra( INTENT_KEY_NMISSING, nMissing );
Intent intent = InviteDelegate
.makeIntent( activity, BTInviteActivity.class,
nMissing, info );
if ( null != info ) {
String lastDev = info.getLastDev( InviteMeans.BLUETOOTH );
if ( null != lastDev ) {

View file

@ -107,6 +107,7 @@ public class BoardDelegate extends DelegateBase
private CommsConnTypeSet m_connTypes = null;
private String[] m_missingDevs;
private int[] m_missingCounts;
private boolean m_remotesAreRobots;
private InviteMeans m_missingMeans = null;
private boolean m_progressShown = false;
private boolean m_isFirstLaunch;
@ -696,6 +697,7 @@ public class BoardDelegate extends DelegateBase
// meaning m_gi etc are still null.
m_missingDevs = data.getStringArrayExtra( InviteDelegate.DEVS );
m_missingCounts = data.getIntArrayExtra( InviteDelegate.COUNTS );
m_remotesAreRobots = data.getBooleanExtra( InviteDelegate.RAR, false );
m_missingMeans = missingMeans;
}
}
@ -1230,12 +1232,12 @@ public class BoardDelegate extends DelegateBase
Action.INVITE_SMS, m_mySIS.nMissing, info );
break;
case RELAY:
RelayInviteDelegate.launchForResult( m_activity, m_mySIS.nMissing,
RelayInviteDelegate.launchForResult( m_activity, m_mySIS.nMissing, info,
RequestCode.RELAY_INVITE_RESULT );
break;
case WIFIDIRECT:
WiDirInviteDelegate.launchForResult( m_activity,
m_mySIS.nMissing,
m_mySIS.nMissing, info,
RequestCode.P2P_INVITE_RESULT );
break;
case EMAIL:
@ -1254,7 +1256,7 @@ public class BoardDelegate extends DelegateBase
break;
default:
Assert.fail();
Assert.assertFalse( BuildConfig.DEBUG );
}
}
}
@ -1348,7 +1350,7 @@ public class BoardDelegate extends DelegateBase
//////////////////////////////////////////////////
// TransportProcs.TPMsgHandler interface
//////////////////////////////////////////////////
@Override
public void tpmRelayConnd( final String room, final int devOrder,
final boolean allHere, final int nMissing )
{
@ -1360,6 +1362,7 @@ public class BoardDelegate extends DelegateBase
} );
}
@Override
public void tpmRelayErrorProc( TransportProcs.XWRELAY_ERROR relayErr )
{
int strID = -1;
@ -1419,6 +1422,7 @@ public class BoardDelegate extends DelegateBase
//////////////////////////////////////////////////
// DwnldActivity.DownloadFinishedListener interface
//////////////////////////////////////////////////
@Override
public void downloadFinished( String lang, final String name,
boolean success )
{
@ -1435,6 +1439,7 @@ public class BoardDelegate extends DelegateBase
//////////////////////////////////////////////////
// NFCUtils.NFCActor
//////////////////////////////////////////////////
@Override
public String makeNFCMessage()
{
String data = null;
@ -2474,7 +2479,9 @@ public class BoardDelegate extends DelegateBase
Assert.assertTrue( 0 <= m_nGuestDevs );
int forceChannel = ii + m_nGuestDevs + 1;
NetLaunchInfo nli = new NetLaunchInfo( m_activity, m_summary, m_gi,
nPlayers, forceChannel );
nPlayers, forceChannel )
.setRemotesAreRobots( m_remotesAreRobots );
if ( m_relayMissing ) {
nli.removeAddress( CommsConnType.COMMS_CONN_RELAY );
}

View file

@ -465,6 +465,7 @@ public class DBUtils {
private ArrayList<String> m_targets;
private ArrayList<Date> m_timestamps;
private int m_cachedCount = 0;
private boolean m_remotesRobots = false;
@Override
public boolean equals( Object other )
@ -590,6 +591,8 @@ public class DBUtils {
return result;
}
void setRemotesRobots() { m_remotesRobots = true; }
boolean getRemotesRobots() { return m_remotesRobots; }
}
public static SentInvitesInfo getInvitesFor( Context context, long rowid )

View file

@ -574,7 +574,7 @@ public class GameUtils {
new String[] { nli.dict }, null, nli.nPlayersT,
nli.nPlayersH, nli.forceChannel,
nli.inviteID(), nli.gameID(),
nli.gameName, false );
nli.gameName, false, nli.remotesAreRobots );
}
public static long makeNewMultiGame( Context context, long groupID,
@ -611,7 +611,7 @@ public class GameUtils {
return makeNewMultiGame( context, (MultiMsgSink)null, (UtilCtxt)null,
groupID, addr, langArray, dictArray, jsonData,
2, 1, forceChannel, inviteID, 0, gameName,
true );
true, false );
}
private static long makeNewMultiGame( Context context, MultiMsgSink sink,
@ -622,7 +622,7 @@ public class GameUtils {
int nPlayersT, int nPlayersH,
int forceChannel, String inviteID,
int gameID, String gameName,
boolean isHost )
boolean isHost, boolean localsRobots )
{
long rowid = DBUtils.ROWID_NOTFOUND;
@ -633,7 +633,7 @@ public class GameUtils {
gi.forceChannel = forceChannel;
lang[0] = gi.dictLang;
dict[0] = gi.dictName;
gi.setNPlayers( nPlayersT, nPlayersH );
gi.setNPlayers( nPlayersT, nPlayersH, localsRobots );
gi.juggle();
if ( 0 != gameID ) {
gi.gameID = gameID;

View file

@ -132,7 +132,9 @@ public class InviteChoicesAlert extends DlgDelegateAlert {
button.setEnabled( true );
}
};
OnClickListener okClicked = new OnClickListener() {
final OnClickListener okClicked = new OnClickListener() {
@Override
public void onClick( DialogInterface dlg, int view ) {
Assert.assertTrue( Action.SKIP_CALLBACK != state.m_action );
int indx = sel[0];
@ -151,6 +153,21 @@ public class InviteChoicesAlert extends DlgDelegateAlert {
sel[0], selChanged )
.setPositiveButton( android.R.string.ok, okClicked )
.setNegativeButton( android.R.string.cancel, null );
if ( BuildConfig.DEBUG ) {
builder.setNeutralButton( R.string.ok_with_robots,
new OnClickListener() {
@Override
public void onClick( DialogInterface dlg,
int view ) {
if ( state.m_params[0] instanceof SentInvitesInfo ) {
SentInvitesInfo sii = (SentInvitesInfo)state.m_params[0];
sii.setRemotesRobots();
}
okClicked.onClick( dlg, view );
}
} );
}
return builder.create();
}

View file

@ -47,6 +47,8 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eehouse.android.xw4.DBUtils.SentInvitesInfo;
abstract class InviteDelegate extends ListDelegateBase
implements View.OnClickListener,
ViewGroup.OnHierarchyChangeListener {
@ -83,7 +85,8 @@ abstract class InviteDelegate extends ListDelegateBase
public static final String DEVS = "DEVS";
public static final String COUNTS = "COUNTS";
protected static final String INTENT_KEY_NMISSING = "NMISSING";
public static final String RAR = "RAR";
private static final String INTENT_KEY_NMISSING = "NMISSING";
protected static final String INTENT_KEY_LASTDEV = "LDEV";
protected int m_nMissing;
@ -96,6 +99,18 @@ abstract class InviteDelegate extends ListDelegateBase
protected Map<InviterItem, Integer> m_counts;
protected Set<InviterItem> m_checked;
private boolean m_setChecked;
private boolean m_remotesAreRobots;
public static Intent makeIntent( Activity activity, Class target,
int nMissing, SentInvitesInfo info )
{
Intent intent = new Intent( activity, target )
.putExtra( INTENT_KEY_NMISSING, nMissing );
if ( null != info ) {
intent.putExtra( RAR, info.getRemotesRobots() );
}
return intent;
}
public InviteDelegate( Delegator delegator, Bundle savedInstanceState )
{
@ -104,6 +119,7 @@ abstract class InviteDelegate extends ListDelegateBase
Intent intent = getIntent();
m_nMissing = intent.getIntExtra( INTENT_KEY_NMISSING, -1 );
m_lastDev = intent.getStringExtra( INTENT_KEY_LASTDEV );
m_remotesAreRobots = intent.getBooleanExtra( RAR, false );
m_counts = new HashMap<InviterItem, Integer>();
m_checked = new HashSet<InviterItem>();
}
@ -193,6 +209,7 @@ abstract class InviteDelegate extends ListDelegateBase
Intent intent = new Intent();
intent.putExtra( DEVS, devs );
intent.putExtra( COUNTS, counts );
intent.putExtra( RAR, m_remotesAreRobots );
setResult( Activity.RESULT_OK, intent );
finish();
}

View file

@ -44,6 +44,7 @@ public class MultiService {
public static final String GAMENAME = "GAMENAME";
public static final String NPLAYERST = "NPLAYERST";
public static final String NPLAYERSH = "NPLAYERSH";
public static final String REMOTES_ROBOTS = "RR";
public static final String INVITER = "INVITER";
private static final String OWNER = "OWNER";
public static final String BT_NAME = "BT_NAME";

View file

@ -72,6 +72,7 @@ public class NetLaunchInfo implements Serializable {
protected int forceChannel;
protected int nPlayersT;
protected int nPlayersH;
protected boolean remotesAreRobots;
protected String room; // relay
protected String btName;
protected String btAddress;
@ -109,6 +110,7 @@ public class NetLaunchInfo implements Serializable {
gameName = bundle.getString( MultiService.GAMENAME );
nPlayersT = bundle.getInt( MultiService.NPLAYERST );
nPlayersH = bundle.getInt( MultiService.NPLAYERSH );
remotesAreRobots = bundle.getBoolean( MultiService.REMOTES_ROBOTS );
gameID = bundle.getInt( MultiService.GAMEID );
btName = bundle.getString( MultiService.BT_NAME );
btAddress = bundle.getString( MultiService.BT_ADDRESS );
@ -341,6 +343,7 @@ public class NetLaunchInfo implements Serializable {
bundle.putString( MultiService.GAMENAME, gameName );
bundle.putInt( MultiService.NPLAYERST, nPlayersT );
bundle.putInt( MultiService.NPLAYERSH, nPlayersH );
bundle.putBoolean( MultiService.REMOTES_ROBOTS, remotesAreRobots );
bundle.putInt( MultiService.GAMEID, gameID() );
bundle.putString( MultiService.BT_NAME, btName );
bundle.putString( MultiService.BT_ADDRESS, btAddress );
@ -364,6 +367,7 @@ public class NetLaunchInfo implements Serializable {
&& forceChannel == other.forceChannel
&& nPlayersT == other.nPlayersT
&& nPlayersH == other.nPlayersH
&& remotesAreRobots == other.remotesAreRobots
&& TextUtils.equals( room, other.room )
&& TextUtils.equals( btName, other.btName )
&& TextUtils.equals( btAddress, other.btAddress )
@ -393,6 +397,7 @@ public class NetLaunchInfo implements Serializable {
.put( MultiService.GAMENAME, gameName )
.put( MultiService.NPLAYERST, nPlayersT )
.put( MultiService.NPLAYERSH, nPlayersH )
.put( MultiService.REMOTES_ROBOTS, remotesAreRobots )
.put( MultiService.GAMEID, gameID() )
.put( MultiService.FORCECHANNEL, forceChannel );
@ -467,6 +472,7 @@ public class NetLaunchInfo implements Serializable {
gameName = json.optString( MultiService.GAMENAME );
nPlayersT = json.optInt( MultiService.NPLAYERST, -1 );
nPlayersH = json.optInt( MultiService.NPLAYERSH, 1 ); // absent ok
remotesAreRobots = json.optBoolean( MultiService.REMOTES_ROBOTS, false );
gameID = json.optInt( MultiService.GAMEID, 0 );
// Try each type
@ -607,6 +613,13 @@ public class NetLaunchInfo implements Serializable {
return m_valid;
}
public NetLaunchInfo setRemotesAreRobots( boolean val )
{
Assert.assertTrue( val == false || BuildConfig.DEBUG );
remotesAreRobots = val;
return this;
}
@Override
public String toString()
{

View file

@ -51,6 +51,7 @@ import java.util.Set;
import org.json.JSONArray;
import org.json.JSONObject;
import org.eehouse.android.xw4.DBUtils.SentInvitesInfo;
import org.eehouse.android.xw4.DlgDelegate.Action;
public class RelayInviteDelegate extends InviteDelegate {
@ -64,22 +65,22 @@ public class RelayInviteDelegate extends InviteDelegate {
R.id.button_edit,
};
// private static final int GET_CONTACT = 1;
private static final String SAVE_NAME = "SAVE_NAME";
private static final String SAVE_NUMBER = "SAVE_NUMBER";
private ArrayList<DevIDRec> m_devIDRecs;
// private RelayDevsAdapter m_adapter;
private boolean m_immobileConfirmed;
private Activity m_activity;
private String m_devIDStr;
public static void launchForResult( Activity activity, int nMissing,
SentInvitesInfo info,
RequestCode requestCode )
{
if ( BuildConfig.RELAYINVITE_SUPPORTED ) {
Intent intent = new Intent( activity, RelayInviteActivity.class );
intent.putExtra( INTENT_KEY_NMISSING, nMissing );
Intent intent =
InviteDelegate.makeIntent( activity, RelayInviteActivity.class,
nMissing, info );
activity.startActivityForResult( intent, requestCode.ordinal() );
}
}

View file

@ -66,8 +66,10 @@ public class SMSInviteDelegate extends InviteDelegate {
SentInvitesInfo info,
RequestCode requestCode )
{
Intent intent = new Intent( activity, SMSInviteActivity.class );
intent.putExtra( INTENT_KEY_NMISSING, nMissing );
Intent intent = InviteDelegate
.makeIntent( activity, SMSInviteActivity.class,
nMissing, info );
if ( null != info ) {
String lastDev = info.getLastDev( InviteMeans.SMS );
intent.putExtra( INTENT_KEY_LASTDEV, lastDev );

View file

@ -33,6 +33,8 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.eehouse.android.xw4.DBUtils.SentInvitesInfo;
public class WiDirInviteDelegate extends InviteDelegate
implements WiDirService.DevSetListener {
private static final String SAVE_NAME = "SAVE_NAME";
@ -40,10 +42,12 @@ public class WiDirInviteDelegate extends InviteDelegate
private Activity m_activity;
public static void launchForResult( Activity activity, int nMissing,
SentInvitesInfo info,
RequestCode requestCode )
{
Intent intent = new Intent( activity, WiDirInviteActivity.class );
intent.putExtra( INTENT_KEY_NMISSING, nMissing );
Intent intent =
InviteDelegate.makeIntent( activity, WiDirInviteActivity.class,
nMissing, info );
activity.startActivityForResult( intent, requestCode.ordinal() );
}

View file

@ -455,7 +455,8 @@ public class CurGameInfo implements Serializable {
return added;
}
public void setNPlayers( int nPlayersTotal, int nPlayersHere )
public void setNPlayers( int nPlayersTotal, int nPlayersHere,
boolean localsAreRobots )
{
assert( nPlayersTotal < MAX_NUM_PLAYERS );
assert( nPlayersHere < nPlayersTotal );
@ -463,8 +464,14 @@ public class CurGameInfo implements Serializable {
nPlayers = nPlayersTotal;
for ( int ii = 0; ii < nPlayersTotal; ++ii ) {
players[ii].isLocal = ii < nPlayersHere;
assert( !players[ii].isRobot() );
boolean isLocal = ii < nPlayersHere;
LocalPlayer player = players[ii];
player.isLocal = isLocal;
if ( isLocal && localsAreRobots ) {
player.setIsRobot( true );
} else {
assert( !player.isRobot() );
}
}
}

View file

@ -1169,6 +1169,9 @@
<string name="invite_choice_relay">Internet/Relay</string>
<string name="invite_choice_p2p">Wifi Direct</string>
<string name="invite_choice_title">Inviting players: How?</string>
<!-- Button, on DEBUG builds only, causes invitee players to be robots -->
<string name="ok_with_robots">OK (robots)</string>
<!-- <string name="sms_or_email">Send invitation using SMS (texting) or -->
<!-- via email?</string> -->
<!-- <string name="nfc_or_email">Send invitation using NFC (Android -->

View file

@ -11,7 +11,7 @@ LOCAL_C_INCLUDES+= \
LOCAL_LDLIBS += -llog
ifeq ($(BUILD_TARGET),debug)
LOCAL_DEBUG = -DMEM_DEBUG -DDEBUG -DENABLE_LOGGING -DCOMMS_CHECKSUM -Wno-unused-variable
LOCAL_DEBUG = -DMEM_DEBUG -DDEBUG -DENABLE_LOGGING -DCOMMS_CHECKSUM -DNLI_VERSION=1 -Wno-unused-variable
endif
LOCAL_DEFINES += \
$(LOCAL_DEBUG) \

View file

@ -425,7 +425,8 @@ static const SetInfo nli_ints[] = {
};
static const SetInfo nli_bools[] = {
ARR_MEMBER( NetLaunchInfo, isGSM )
ARR_MEMBER( NetLaunchInfo, isGSM ),
ARR_MEMBER( NetLaunchInfo, remotesAreRobots ),
};
static const SetInfo nli_strs[] = {

View file

@ -1,6 +1,6 @@
/* -*- compile-command: "cd ../linux && make MEMDEBUG=TRUE -j3"; -*- */
/*
* Copyright 2001 - 2015 by Eric House (xwords@eehouse.org). All rights
* Copyright 2001 - 2019 by Eric House (xwords@eehouse.org). All rights
* reserved.
*
* This program is free software; you can redistribute it and/or
@ -25,6 +25,11 @@
#include "strutils.h"
#include "dbgutil.h"
/* Don't check in other than 0 for a few releases!!! */
#ifndef NLI_VERSION
# define NLI_VERSION 0
#endif
void
nli_init( NetLaunchInfo* nli, const CurGameInfo* gi, const CommsAddrRec* addr,
XP_U16 nPlayers, XP_U16 forceChannel )
@ -41,7 +46,6 @@ nli_init( NetLaunchInfo* nli, const CurGameInfo* gi, const CommsAddrRec* addr,
types_addType( &nli->_conTypes, COMMS_CONN_RELAY );
XP_STRCAT( nli->room, addr->u.ip_relay.invite );
}
}
static XP_U32
@ -71,10 +75,9 @@ nli_setInviteID( NetLaunchInfo* nli, const XP_UCHAR* inviteID )
void
nli_saveToStream( const NetLaunchInfo* nli, XWStreamCtxt* stream )
{
LOG_FUNC();
stream_putU8( stream, nli->version );
stream_putU8( stream, NLI_VERSION );
stream_putU16( stream, nli->_conTypes );
XP_LOGF( "%s: wrote _conTypes: %x", __func__, nli->_conTypes );
stream_putU16( stream, nli->lang );
stringToStream( stream, nli->dict );
stringToStream( stream, nli->gameName );
@ -84,65 +87,67 @@ nli_saveToStream( const NetLaunchInfo* nli, XWStreamCtxt* stream )
stream_putU8( stream, nli->forceChannel );
if ( types_hasType( nli->_conTypes, COMMS_CONN_RELAY ) ) {
XP_LOGF( "%s: writing relay stuff", __func__ );
stringToStream( stream, nli->room );
XP_LOGF( "%s: writing room: %s", __func__, nli->room );
stringToStream( stream, nli->inviteID );
stream_putU32( stream, nli->devID );
}
if ( types_hasType( nli->_conTypes, COMMS_CONN_BT ) ) {
XP_LOGF( "%s: writing bt stuff", __func__ );
stringToStream( stream, nli->btName );
stringToStream( stream, nli->btAddress );
}
if ( types_hasType( nli->_conTypes, COMMS_CONN_SMS ) ) {
XP_LOGF( "%s: writing sms stuff", __func__ );
stringToStream( stream, nli->phone );
stream_putU8( stream, nli->isGSM );
stream_putU8( stream, nli->osType );
stream_putU32( stream, nli->osVers );
}
LOG_RETURN_VOID();
if ( NLI_VERSION > 0 ) {
stream_putBits( stream, 1, nli->remotesAreRobots ? 1 : 0 );
}
}
XP_Bool
nli_makeFromStream( NetLaunchInfo* nli, XWStreamCtxt* stream )
{
XP_Bool success = XP_TRUE;
LOG_FUNC();
XP_MEMSET( nli, 0, sizeof(*nli) );
nli->version = stream_getU8( stream );
XP_Bool success = 0 == nli->version;
if ( success ) {
nli->_conTypes = stream_getU16( stream );
XP_LOGF( "%s: read _conTypes: %x", __func__, nli->_conTypes );
nli->lang = stream_getU16( stream );
stringFromStreamHere( stream, nli->dict, sizeof(nli->dict) );
stringFromStreamHere( stream, nli->gameName, sizeof(nli->gameName) );
nli->nPlayersT = stream_getU8( stream );
nli->nPlayersH = stream_getU8( stream );
nli->gameID = stream_getU32( stream );
nli->forceChannel = stream_getU8( stream );
XP_U16 version = stream_getU8( stream );
XP_LOGF( "%s(): read version: %d", __func__, version );
if ( types_hasType( nli->_conTypes, COMMS_CONN_RELAY ) ) {
XP_LOGF( "%s: reading relay stuff", __func__ );
stringFromStreamHere( stream, nli->room, sizeof(nli->room) );
XP_LOGF( "%s: read room: %s", __func__, nli->room );
stringFromStreamHere( stream, nli->inviteID, sizeof(nli->inviteID) );
nli->devID = stream_getU32( stream );
}
if ( types_hasType( nli->_conTypes, COMMS_CONN_BT ) ) {
XP_LOGF( "%s: reading bt stuff", __func__ );
stringFromStreamHere( stream, nli->btName, sizeof(nli->btName) );
stringFromStreamHere( stream, nli->btAddress, sizeof(nli->btAddress) );
}
if ( types_hasType( nli->_conTypes, COMMS_CONN_SMS ) ) {
XP_LOGF( "%s: reading sms stuff", __func__ );
stringFromStreamHere( stream, nli->phone, sizeof(nli->phone) );
nli->isGSM = stream_getU8( stream );
nli->osType= stream_getU8( stream );
nli->osVers = stream_getU32( stream );
}
nli->_conTypes = stream_getU16( stream );
nli->lang = stream_getU16( stream );
stringFromStreamHere( stream, nli->dict, sizeof(nli->dict) );
stringFromStreamHere( stream, nli->gameName, sizeof(nli->gameName) );
nli->nPlayersT = stream_getU8( stream );
nli->nPlayersH = stream_getU8( stream );
nli->gameID = stream_getU32( stream );
nli->forceChannel = stream_getU8( stream );
if ( types_hasType( nli->_conTypes, COMMS_CONN_RELAY ) ) {
stringFromStreamHere( stream, nli->room, sizeof(nli->room) );
stringFromStreamHere( stream, nli->inviteID, sizeof(nli->inviteID) );
nli->devID = stream_getU32( stream );
}
if ( types_hasType( nli->_conTypes, COMMS_CONN_BT ) ) {
stringFromStreamHere( stream, nli->btName, sizeof(nli->btName) );
stringFromStreamHere( stream, nli->btAddress, sizeof(nli->btAddress) );
}
if ( types_hasType( nli->_conTypes, COMMS_CONN_SMS ) ) {
stringFromStreamHere( stream, nli->phone, sizeof(nli->phone) );
nli->isGSM = stream_getU8( stream );
nli->osType= stream_getU8( stream );
nli->osVers = stream_getU32( stream );
}
if ( version > 0 ) {
nli->remotesAreRobots = 0 != stream_getBits( stream, 1 );
XP_LOGF( "%s(): remotesAreRobots: %d", __func__, nli->remotesAreRobots );
}
XP_ASSERT( 0 == stream_getSize( stream ) );
LOG_RETURNF( "%s", boolToStr(success) );
return success;
}

View file

@ -37,7 +37,6 @@ typedef enum {OSType_NONE, OSType_LINUX, OSType_ANDROID, } XP_OSType;
*/
typedef struct _InviteInfo {
XP_U8 version; /* struct version for backward compatibility */
XP_U16 _conTypes;
XP_UCHAR gameName[MAX_GAME_NAME_LEN];
@ -46,6 +45,7 @@ typedef struct _InviteInfo {
XP_U8 forceChannel;
XP_U8 nPlayersT;
XP_U8 nPlayersH;
XP_Bool remotesAreRobots;
/* Relay */
XP_UCHAR room[MAX_INVITE_LEN + 1];

View file

@ -130,6 +130,7 @@ DEFINES += -DCOMMS_XPORT_FLAGSPROC
DEFINES += -DINITIAL_CLIENT_VERS=3
DEFINES += -DCOMMON_LAYOUT
DEFINES += -DNATIVE_NLI
DEFINES += -DNLI_VERSION=1
# DEFINES += -DRELAY_VIA_HTTP
# MAX_ROWS controls STREAM_VERS_BIGBOARD and with it move hashing