Replace UDP-based messaging with TCP. Stream protocol says distinct

message is length plus data.  Use non-deprecated gtk select-like
function.  With these changes can play full games through the relay on
gtk.  Untested on ncurses but probably broken.
This commit is contained in:
ehouse 2005-03-06 18:07:00 +00:00
parent cb3a3854e9
commit 897caf4e88
6 changed files with 124 additions and 194 deletions

View file

@ -871,6 +871,7 @@ cursesmain( XP_Bool isServer, LaunchParams* params )
globals.amServer = isServer; globals.amServer = isServer;
globals.cGlobals.params = params; globals.cGlobals.params = params;
globals.cGlobals.socket = -1;
globals.cp.showBoardArrow = XP_TRUE; globals.cp.showBoardArrow = XP_TRUE;
globals.cp.showRobotScores = params->showRobotScores; globals.cp.showRobotScores = params->showRobotScores;
@ -879,7 +880,7 @@ cursesmain( XP_Bool isServer, LaunchParams* params )
setupCursesUtilCallbacks( &globals, params->util ); setupCursesUtilCallbacks( &globals, params->util );
globals.cGlobals.defaultServerName = params->info.clientInfo.serverName; globals.cGlobals.defaultServerName = params->relayName;
cursesListenOnSocket( &globals, 0, NULL ); /* stdin */ cursesListenOnSocket( &globals, 0, NULL ); /* stdin */
@ -888,8 +889,8 @@ cursesmain( XP_Bool isServer, LaunchParams* params )
cursesListenOnSocket( &globals, globals.timepipe[0], NULL ); /* reader pipe */ cursesListenOnSocket( &globals, globals.timepipe[0], NULL ); /* reader pipe */
sock = initListenerSocket( params->defaultListenPort ); sock = linux_init_socket( &globals.cGlobals );
cursesListenOnSocket( &globals, sock, NULL ); cursesListenOnSocket( &globals, sock, NULL );
signal( SIGWINCH, SIGWINCH_handler ); signal( SIGWINCH, SIGWINCH_handler );
initCurses( &globals ); initCurses( &globals );
@ -899,7 +900,7 @@ cursesmain( XP_Bool isServer, LaunchParams* params )
gameID = (XP_U16)util_getCurSeconds( globals.cGlobals.params->util ); gameID = (XP_U16)util_getCurSeconds( globals.cGlobals.params->util );
game_makeNewGame( MEMPOOL &globals.cGlobals.game, &params->gi, game_makeNewGame( MEMPOOL &globals.cGlobals.game, &params->gi,
params->util, (DrawCtx*)globals.draw, params->util, (DrawCtx*)globals.draw,
gameID, &globals.cp, linux_udp_send, &globals ); gameID, &globals.cp, linux_tcp_send, &globals );
addr.conType = COMMS_CONN_IP; addr.conType = COMMS_CONN_IP;
addr.u.ip.ipAddr = 0; /* ??? */ addr.u.ip.ipAddr = 0; /* ??? */

View file

@ -244,7 +244,7 @@ createOrLoadObjects( GtkAppGlobals* globals, GtkWidget *widget )
params->dict, params->util, params->dict, params->util,
(DrawCtx*)globals->draw, (DrawCtx*)globals->draw,
&globals->cp, &globals->cp,
linux_udp_send, globals ); linux_tcp_send, globals );
stream_destroy( stream ); stream_destroy( stream );
@ -252,17 +252,15 @@ createOrLoadObjects( GtkAppGlobals* globals, GtkWidget *widget )
XP_U16 gameID = (XP_U16)util_getCurSeconds( globals->cGlobals.params->util ); XP_U16 gameID = (XP_U16)util_getCurSeconds( globals->cGlobals.params->util );
CommsAddrRec addr; CommsAddrRec addr;
if ( serverRole == SERVER_ISCLIENT ) { XP_ASSERT( !!params->relayName );
globals->cGlobals.defaultServerName = globals->cGlobals.defaultServerName = params->relayName;
params->info.clientInfo.serverName;
}
params->gi.gameID = util_getCurSeconds(globals->cGlobals.params->util); params->gi.gameID = util_getCurSeconds(globals->cGlobals.params->util);
XP_STATUSF( "grabbed gameID: %ld\n", params->gi.gameID ); XP_STATUSF( "grabbed gameID: %ld\n", params->gi.gameID );
game_makeNewGame( MEMPOOL &globals->cGlobals.game, &params->gi, game_makeNewGame( MEMPOOL &globals->cGlobals.game, &params->gi,
params->util, (DrawCtx*)globals->draw, params->util, (DrawCtx*)globals->draw,
gameID, &globals->cp, linux_udp_send, globals ); gameID, &globals->cp, linux_tcp_send, globals );
addr.conType = COMMS_CONN_IP; addr.conType = COMMS_CONN_IP;
addr.u.ip.ipAddr = 0; /* ??? */ addr.u.ip.ipAddr = 0; /* ??? */
@ -307,13 +305,10 @@ configure_event( GtkWidget *widget, GdkEventConfigure *event,
firstTime = (globals->draw == NULL); firstTime = (globals->draw == NULL);
if ( firstTime ) { if ( firstTime ) {
int listenSocket = int listenSocket = linux_init_socket( &globals->cGlobals );
initListenerSocket(globals->cGlobals.params->defaultListenPort);
gtkListenOnSocket( globals, listenSocket ); gtkListenOnSocket( globals, listenSocket );
createOrLoadObjects( globals, widget ); createOrLoadObjects( globals, widget );
} else {
/* gdk_pixmap_unref( ((GtkDrawCtx*)globals->draw)->pixmap ); */
} }
width = widget->allocation.width - (RIGHT_MARGIN + BOARD_LEFT_MARGIN); width = widget->allocation.width - (RIGHT_MARGIN + BOARD_LEFT_MARGIN);
@ -544,7 +539,7 @@ new_game( GtkWidget* widget, GtkAppGlobals* globals )
XP_STATUSF( "grabbed gameID: %ld\n", gameID ); XP_STATUSF( "grabbed gameID: %ld\n", gameID );
game_reset( MEMPOOL &globals->cGlobals.game, gi, gameID, &globals->cp, game_reset( MEMPOOL &globals->cGlobals.game, gi, gameID, &globals->cp,
linux_udp_send, globals ); linux_tcp_send, globals );
if ( isClient ) { if ( isClient ) {
XWStreamCtxt* stream = XWStreamCtxt* stream =
@ -1406,92 +1401,80 @@ setupGtkUtilCallbacks( GtkAppGlobals* globals, XW_UtilCtxt* util )
util->closure = globals; util->closure = globals;
} /* setupGtkUtilCallbacks */ } /* setupGtkUtilCallbacks */
static void
newConnectionInput( gpointer data, gint source, static gboolean
GdkInputCondition condition ) newConnectionInput( GIOChannel *source,
GIOCondition condition,
gpointer data )
{ {
int sock = g_io_channel_unix_get_fd( source );
GtkAppGlobals* globals = (GtkAppGlobals*)data; GtkAppGlobals* globals = (GtkAppGlobals*)data;
struct sockaddr_in addr_sock;
int flen, nBytes;
char buf[256];
char* bufPtr = buf;
XP_LOGF( "Incomming message!!!" ); XP_ASSERT( sock == globals->cGlobals.socket );
memset( buf, 0, sizeof(buf) ); if ( (condition & G_IO_HUP) != 0 ) {
flen = sizeof(struct sockaddr_in);
nBytes = recvfrom( source, buf, sizeof(buf), 0,
(struct sockaddr *)&addr_sock, &flen );
XP_ASSERT( nBytes != -1 );
if ( !globals->dropIncommingMsgs && nBytes != -1 ) { globals->cGlobals.socket = -1;
XWStreamCtxt* inboundS; return FALSE; /* remove the event source */
XP_Bool redraw = XP_FALSE;
/* somehow, we need to associate a return address with a client. This } else if ( (condition & G_IO_IN) != 0 ) {
is the address we'll be using from now on. So when a connection is ssize_t nRead;
made, pass the return address to the comms module. It can decide unsigned short packetSize;
from the message if it's seen the message source before.*/ unsigned short tmp;
unsigned char buf[512];
/* inboundS = linux_make_inbound_socketStream( */ XP_LOGF( "activity on socket %d", sock );
/* inboundSocket, &returnSockAddr, addrLen ); */ nRead = recv( sock, &tmp, sizeof(tmp), 0 );
assert( nRead == 2 );
inboundS = stream_from_msgbuf( &globals->cGlobals, bufPtr, nBytes ); packetSize = ntohs( tmp );
if ( !!inboundS ) { nRead = recv( sock, buf, packetSize, 0 );
CommsAddrRec addrRec;
XP_MEMSET( &addrRec, 0, sizeof(addrRec) ); if ( !globals->dropIncommingMsgs && nRead > 0 ) {
addrRec.conType = COMMS_CONN_IP; XWStreamCtxt* inboundS;
XP_Bool redraw = XP_FALSE;
addrRec.u.ip.ipAddr = ntohl(addr_sock.sin_addr.s_addr);
XP_LOGF( "captured incomming ip address: 0x%lx", inboundS = stream_from_msgbuf( &globals->cGlobals, buf, nRead );
addrRec.u.ip.ipAddr ); if ( !!inboundS ) {
if ( comms_checkIncommingStream( globals->cGlobals.game.comms,
if ( comms_checkIncommingStream( globals->cGlobals.game.comms, inboundS, NULL ) ) {
inboundS, &addrRec ) ) { redraw = server_receiveMessage(globals->cGlobals.game.server
redraw = server_receiveMessage( globals->cGlobals.game.server, , inboundS );
inboundS ); }
stream_destroy( inboundS );
} }
stream_destroy( inboundS );
}
/* if there's something to draw resulting from the message, we need to /* if there's something to draw resulting from the message, we
give the main loop time to reflect that on the screen before giving need to give the main loop time to reflect that on the screen
the server another shot. So just call the idle proc. */ before giving the server another shot. So just call the idle
if ( redraw ) { proc. */
gtk_util_requestTime( globals->cGlobals.params->util ); if ( redraw ) {
gtk_util_requestTime( globals->cGlobals.params->util );
} else {
redraw = server_do( globals->cGlobals.game.server );
}
if ( redraw ) {
board_draw( globals->cGlobals.game.board );
}
} else { } else {
redraw = server_do( globals->cGlobals.game.server ); XP_LOGF( "errno from read: %d", errno );
} }
if ( redraw ) {
board_draw( globals->cGlobals.game.board );
}
} else {
XP_LOGF( "errno from accept: %d", errno );
} }
return TRUE; /* FALSE means to remove event source */
} /* newConnectionInput */ } /* newConnectionInput */
static void
newConnectionDestroy( gpointer data )
{
XP_LOGF( "newConnectionDestroy called" );
} /* newConnectionDestroy */
/* Make gtk listen for events on the socket that clients will use to /* Make gtk listen for events on the socket that clients will use to
* connect to us. * connect to us.
*/ */
static void static void
gtkListenOnSocket( GtkAppGlobals* globals, int newSock ) gtkListenOnSocket( GtkAppGlobals* globals, int newSock )
{ {
guint result = gtk_input_add_full( newSock, GIOChannel* channel = g_io_channel_unix_new( newSock );
GDK_INPUT_READ, guint result = g_io_add_watch( channel,
newConnectionInput, G_IO_IN | G_IO_HUP,
(GtkCallbackMarshal)0L, newConnectionInput,
globals, globals );
newConnectionDestroy ); XP_LOGF( "g_io_add_watch => %d", result );
globals->listenSockKey = result;
} /* gtkListenOnSocket */ } /* gtkListenOnSocket */
static void static void
@ -1529,6 +1512,7 @@ gtkmain( XP_Bool isServer, LaunchParams* params, int argc, char *argv[] )
globals.cGlobals.params = params; globals.cGlobals.params = params;
globals.cGlobals.lastNTilesToUse = MAX_TRAY_TILES; globals.cGlobals.lastNTilesToUse = MAX_TRAY_TILES;
globals.cGlobals.socket = -1;
globals.cp.showBoardArrow = XP_TRUE; globals.cp.showBoardArrow = XP_TRUE;
globals.cp.showRobotScores = params->showRobotScores; globals.cp.showRobotScores = params->showRobotScores;

View file

@ -70,7 +70,6 @@ typedef struct GtkAppGlobals {
GtkAdjustment* adjustment; GtkAdjustment* adjustment;
ClientStreamRec clientRecs[MAX_NUM_PLAYERS]; ClientStreamRec clientRecs[MAX_NUM_PLAYERS];
guint listenSockKey; /* save return from gtk_input_add_full */
CommonPrefs cp; CommonPrefs cp;

View file

@ -28,7 +28,6 @@
#include <fcntl.h> #include <fcntl.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <netinet/in.h>
#include <time.h> #include <time.h>
#include "linuxmain.h" #include "linuxmain.h"
@ -200,7 +199,6 @@ usage( char* appName, char* msg )
"\t [-c] # explain robot scores after each move\n" "\t [-c] # explain robot scores after each move\n"
"\t\t # (max of four players total, local and remote)\n" "\t\t # (max of four players total, local and remote)\n"
"\t [-b boardSize] # number of columns and rows\n" "\t [-b boardSize] # number of columns and rows\n"
"\t [-l listen_port] # port for inet connection (4999 default)\n"
"\t [-e random_seed] \n" "\t [-e random_seed] \n"
"\t [-t initial_minutes_on_timer] \n" "\t [-t initial_minutes_on_timer] \n"
"# --------------- choose client or server ----------\n" "# --------------- choose client or server ----------\n"
@ -208,106 +206,83 @@ usage( char* appName, char* msg )
"\t -d xwd_file # provides tile counts & values\n" "\t -d xwd_file # provides tile counts & values\n"
"\t\t # list each player as local or remote\n" "\t\t # list each player as local or remote\n"
"\t [-N]* # remote client (listen for connection)\n" "\t [-N]* # remote client (listen for connection)\n"
"# --------------- OR client-only ----------\n" "\t [-a relay_addr] # use relay (via port spec'd above)\n"
"\t [-a server_addr] # be a client (on port spec'd above)\n"
"\t [-p client_port] # must != server's port if on same device"
"" " (default localhost)\n" "" " (default localhost)\n"
"\t [-p relay_port] # relay is at this port\n"
/* "# --------------- OR client-only ----------\n" */
/* "\t [-p client_port] # must != server's port if on same device" */
"\nexample: \n" "\nexample: \n"
"\tserver: ./xwords -d dict.xwd -s -r Eric -N\n" "\tserver: ./xwords -d dict.xwd -s -a localhost -p 10999 -r Eric -N\n"
"\tclient: ./xwords -d dict.xwd -r Kati -p 4998 -l 6000\n" "\tclient: ./xwords -d dict.xwd -a localhost -p 10999 -r Kati\n"
, appName ); , appName );
exit(1); exit(1);
} }
XP_S16 XP_S16
linux_udp_send( XP_U8* buf, XP_U16 buflen, CommsAddrRec* addrRec, linux_tcp_send( XP_U8* buf, XP_U16 buflen, CommsAddrRec* addrRec,
void* closure ) void* closure )
{ {
CommonGlobals* globals = (CommonGlobals*)closure; CommonGlobals* globals = (CommonGlobals*)closure;
XP_S16 result = 0;
int socket = globals->socket;
if ( socket == -1 ) {
XP_STATUSF( "linux_tcp_send: socket uninitialized" );
} else {
XP_U16 netLen = htons( buflen );
errno = 0;
(void)send( socket, &netLen, sizeof(netLen), 0 );
result = send( socket, buf, buflen, 0 );
XP_STATUSF( "linux_tcp_send: send returned %d of %d (err=%d)",
result, buflen, errno );
}
return result;
} /* linux_tcp_send */
int
linux_init_socket( CommonGlobals* cGlobals )
{
struct sockaddr_in to_sock; struct sockaddr_in to_sock;
struct hostent* host; struct hostent* host;
XP_S16 result; int sock = cGlobals->socket;
int sock;
/* XP_U8* msg; */
XP_LOGF( "linux_udp_send" );
/* make a local copy of the address to send to */
sock = socket( AF_INET, SOCK_DGRAM, 0 );
if ( sock == -1 ) { if ( sock == -1 ) {
XP_DEBUGF( "socket returned -1\n" );
return -1;
}
if ( !!addrRec ) { /* make a local copy of the address to send to */
sock = socket( AF_INET, SOCK_STREAM, 0 );
if ( sock == -1 ) {
XP_DEBUGF( "socket returned -1\n" );
return -1;
}
XP_ASSERT( addrRec->conType == COMMS_CONN_IP ); to_sock.sin_port = htons(cGlobals->params->defaultSendPort);
XP_MEMSET( &to_sock, 0, sizeof(to_sock) );
XP_STATUSF( "target IP = 0x%lx", addrRec->u.ip.ipAddr );
to_sock.sin_addr.s_addr = htonl(addrRec->u.ip.ipAddr);
to_sock.sin_port = htons(addrRec->u.ip.port);
XP_STATUSF( "0: sending to port %d(0x%x)",
addrRec->u.ip.port, addrRec->u.ip.port );
} else {
to_sock.sin_port = htons(globals->params->defaultSendPort);
XP_STATUSF( "1: sending to port %d", XP_STATUSF( "1: sending to port %d",
globals->params->defaultSendPort ); cGlobals->params->defaultSendPort );
if (( host = gethostbyname(globals->defaultServerName) ) == NULL ) { if (( host = gethostbyname(cGlobals->params->relayName) ) == NULL ) {
XP_WARNF( "gethostbyname returned -1\n" ); XP_WARNF( "gethostbyname returned -1\n" );
return -1; return -1;
} else { } else {
XP_WARNF( "gethostbyname for %s worked", XP_WARNF( "gethostbyname for %s worked",
globals->defaultServerName ); cGlobals->defaultServerName );
} }
memcpy( &(to_sock.sin_addr.s_addr), host->h_addr_list[0], memcpy( &(to_sock.sin_addr.s_addr), host->h_addr_list[0],
sizeof(struct in_addr)); sizeof(struct in_addr));
to_sock.sin_family = AF_INET;
errno = 0;
if ( 0 == connect( sock, (const struct sockaddr*)&to_sock,
sizeof(to_sock) ) ) {
cGlobals->socket = sock;
} else {
close( sock );
XP_STATUSF( "connect failed: %d", errno );
}
} }
to_sock.sin_family = AF_INET;
/* msg = malloc( buflen ); */ return sock;
/* XP_MEMCPY( msg, buf, buflen ); */ } /* linux_init_socket */
errno = 0;
XP_STATUSF( "checking: errno=%d", (short)errno );
result = sendto( sock, buf, buflen, 0,
(struct sockaddr *)&to_sock, sizeof(to_sock) );
XP_STATUSF( "foo: sendto returned %d of %d (err=%d)",
result, buflen, errno );
close(sock);
/* free( msg ); */
return result;
} /* linux_udp_send */
int
initListenerSocket( int port )
{
int newSocket;
int result;
struct sockaddr_in sockAddr;
XP_DEBUGF( "opening socket to listen on port %d", port );
newSocket = socket( AF_INET, DGRAM_TYPE, 0 );
XP_DEBUGF( "socket returned %d", newSocket );
sockAddr.sin_family = AF_INET;
sockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
sockAddr.sin_port = htons(port);
result = bind( newSocket, (struct sockaddr*)&sockAddr, sizeof(sockAddr) );
XP_LOGF( "bind on port %d returned %d; errno=%d",
port, result, errno );
/* result = listen( newSocket, 5 ); */
/* XP_DEBUGF( "listen returned %d; errno=%d\n", result, errno ); */
return newSocket;
} /* initListenerSocket */
/* Create a stream for the incomming message buffer, and read in any /* Create a stream for the incomming message buffer, and read in any
information specific to our platform's comms layer (return address, say) information specific to our platform's comms layer (return address, say)
@ -485,9 +460,8 @@ main( int argc, char** argv )
int opt; int opt;
int totalPlayerCount = 0; int totalPlayerCount = 0;
XP_Bool isServer = XP_FALSE; XP_Bool isServer = XP_FALSE;
char* listenPortNumString = NULL;
char* sendPortNumString = NULL; char* sendPortNumString = NULL;
char* serverName = "localhost"; char* relayName = "localhost";
unsigned int seed = defaultRandomSeed(); unsigned int seed = defaultRandomSeed();
LaunchParams mainParams; LaunchParams mainParams;
XP_U16 robotCount = 0; XP_U16 robotCount = 0;
@ -592,9 +566,6 @@ main( int argc, char** argv )
mainParams.gi.players[index].isLocal = XP_FALSE; mainParams.gi.players[index].isLocal = XP_FALSE;
++mainParams.info.serverInfo.nRemotePlayers; ++mainParams.info.serverInfo.nRemotePlayers;
break; break;
case 'l':
listenPortNumString = optarg;
break;
case 'p': case 'p':
sendPortNumString = optarg; sendPortNumString = optarg;
break; break;
@ -622,7 +593,7 @@ main( int argc, char** argv )
break; break;
case 'a': case 'a':
/* mainParams.info.clientInfo.serverName = */ /* mainParams.info.clientInfo.serverName = */
serverName = optarg; relayName = optarg;
break; break;
case 'q': case 'q':
mainParams.quitAfter = XP_TRUE; mainParams.quitAfter = XP_TRUE;
@ -667,9 +638,6 @@ main( int argc, char** argv )
} }
/* convert strings to whatever */ /* convert strings to whatever */
if ( listenPortNumString ) {
mainParams.defaultListenPort = atoi( listenPortNumString );
}
if ( sendPortNumString != NULL ) { if ( sendPortNumString != NULL ) {
mainParams.defaultSendPort = atoi( sendPortNumString ); mainParams.defaultSendPort = atoi( sendPortNumString );
} }
@ -706,31 +674,7 @@ main( int argc, char** argv )
} }
} }
/* setup sockets and any other stuff not specific to GTK or ncurses */ mainParams.relayName = relayName;
if ( isServer ) {
} else {
/* struct hostent* hostinfo; */
/* hostinfo = gethostbyname( serverName ); */
/* if ( !hostinfo ) { */
/* fprintf( stderr, "unable to get host info for %s\n", serverName ); */
/* exit( 0 ); */
/* } else { */
/* char* hostName = inet_ntoa( *(struct in_addr*)hostinfo->h_addr ); */
/* unsigned long int serverAddr; */
/* fprintf( stderr, "gethostbyname returned %s\n", hostName ); */
/* serverAddr = inet_addr(hostName); */
/* fprintf( stderr, "inet_addr returned %lu\n", serverAddr ); */
/* mainParams.info.clientInfo.stream = */
/* linux_make_outbound_socketStream( serverAddr, serverPort ); */
/* if ( !stream_open( mainParams.info.clientInfo.stream ) { */
/* fprintf( stderr, "ERROR: unable to connect to server\n" ); */
/* exit(0); */
/* } */
/* } */
mainParams.info.clientInfo.serverName = serverName;
}
/* mainParams.pipe = linuxCommPipeCtxtMake( isServer ); */ /* mainParams.pipe = linuxCommPipeCtxtMake( isServer ); */

View file

@ -37,9 +37,10 @@ typedef struct LinuxBMStruct {
DictionaryCtxt* linux_dictionary_make( MPFORMAL char* dictFileName ); DictionaryCtxt* linux_dictionary_make( MPFORMAL char* dictFileName );
int initListenerSocket( int port ); int initListenerSocket( int port );
XP_S16 linux_udp_send( XP_U8* buf, XP_U16 buflen, CommsAddrRec* addrRec, XP_S16 linux_tcp_send( XP_U8* buf, XP_U16 buflen, CommsAddrRec* addrRec,
void* closure ); void* closure );
XWStreamCtxt* stream_from_msgbuf( CommonGlobals* globals, char* bufPtr, int linux_init_socket( CommonGlobals* cGlobals );
XWStreamCtxt* stream_from_msgbuf( CommonGlobals* cGlobals, char* bufPtr,
XP_U16 nBytes ); XP_U16 nBytes );
XP_UCHAR* linux_getErrString( UtilErrID id ); XP_UCHAR* linux_getErrString( UtilErrID id );
XP_UCHAR* strFromStream( XWStreamCtxt* stream ); XP_UCHAR* strFromStream( XWStreamCtxt* stream );

View file

@ -31,7 +31,6 @@ typedef struct ServerInfo {
} ServerInfo; } ServerInfo;
typedef struct ClientInfo { typedef struct ClientInfo {
char* serverName; /* still need this? */
} ClientInfo; } ClientInfo;
typedef struct LinuxUtilCtxt { typedef struct LinuxUtilCtxt {
@ -59,6 +58,7 @@ typedef struct LaunchParams {
Connectedness serverRole; Connectedness serverRole;
char* relayName;
union { union {
ServerInfo serverInfo; ServerInfo serverInfo;
ClientInfo clientInfo; ClientInfo clientInfo;
@ -76,6 +76,7 @@ typedef struct CommonGlobals {
XP_U16 lastNTilesToUse; XP_U16 lastNTilesToUse;
/* UDP comms stuff */ /* UDP comms stuff */
char* defaultServerName; char* defaultServerName;
int socket;
} CommonGlobals; } CommonGlobals;
#endif #endif