Exemple #1
0
/* To start the game */
TEG_STATUS token_start( int fd )
{
	char strout[PROT_MAX_LEN + PLAYERNAME_MAX_LEN  * TEG_MAX_PLAYERS + 200];
	PSPLAYER pJ;
	PLAY_DEBUG("token_start()\n");

	if( JUEGO_EMPEZADO || g_game.players < 2 )
		goto error;

	if( g_server.with_console && fd != CONSOLE_FD) {
		if( !SPLAYER_HABILITADO_P(fd,&pJ) || !pJ->is_player )
			goto error;
	}

	JUEGO_EN_EMPEZAR;

	g_game.playing = g_game.players;

	con_text_out(M_INF,_("Starting game number: %d with seed: %u\n"),g_game.gamenumber,g_game.seed);

	player_all_set_status ( PLAYER_STATUS_START );
	countries_repartir();

	if(turno_init() != TEG_STATUS_SUCCESS ) {
		con_text_out(M_ERR,_("Error, can't initialize a new turn\n"));
		goto error;
	}

	JUEGO_EN_FICHAS;

	g_game.turno->estado = PLAYER_STATUS_FICHAS;

	aux_token_stasta(strout, sizeof(strout) -1 );

	netall_printf( "%s=%s;%s=%d,%d;%s=%d,%d,%d,%d;%s=%d,%d\n"
			,TOKEN_START
			,strout			/* available players */
			,TOKEN_NEW_ROUND
			,g_game.turno->numjug 	/* who starts the new turn */
			,g_game.round_number	/* the round number */
			,TOKEN_MODALIDAD
			,g_game.mission	/* play with missions ? */
			,g_game.cmission	/* play with common mission */
			,g_game.fog_of_war	/* play with fog of war */
			,g_game.reglas		/* which rules ? */
			,TOKEN_FICHAS
			,g_game.turno->numjug,	/* who starts ? */
			g_game.fichas );	/* how many armies to place */
	return TEG_STATUS_SUCCESS;
error:
	net_print(fd,TOKEN_ERROR"="TOKEN_START"\n");
	return TEG_STATUS_PARSEERROR;
}
Exemple #2
0
/* Called when a player finish his turn */
STATIC TEG_STATUS token_turn( int fd, char *unused )
{
	PSPLAYER pJ;
	PLAY_DEBUG("token_turn()");

	if( player_whoisfd( fd, &pJ ) != TEG_STATUS_SUCCESS ) {
		goto error;
	}

	if( pJ->estado < PLAYER_STATUS_TURNOSTART || pJ->estado > PLAYER_STATUS_TURNOEND )
		goto error;

	if( pJ != g_game.turno ) {
		con_text_out(M_ERR,_("BUG: The server believes that player `%s' does not have the turn"),pJ->name);
		goto error;
	}

	pJ->estado = PLAYER_STATUS_IDLE;

	if( turno_end( pJ ) != TEG_STATUS_SUCCESS )
		goto error;

	/* give turn to the next player */
	if( turno_next() != TEG_STATUS_SUCCESS )
		goto error;

	return TEG_STATUS_SUCCESS;
error:
	net_print(fd,TOKEN_ERROR"="TOKEN_TURNO"\n");
	return TEG_STATUS_PARSEERROR;
}
Exemple #3
0
/* Puts the player in Game Over state */
TEG_STATUS token_surrender( int fd, char *unused )
{
	PSPLAYER pJ;
	PLAY_DEBUG("token_surrender\n");

	if( player_whoisfd( fd, &pJ ) != TEG_STATUS_SUCCESS )
		goto error;

	if( !pJ->is_player )
		goto error;

	if( pJ->estado < PLAYER_STATUS_HABILITADO )
		goto error;

	con_text_out(M_INF,_("Player %s(%d) abandoned the game\n"),pJ->name,pJ->numjug);

	netall_printf("%s=%d\n", TOKEN_SURRENDER, pJ->numjug );

	player_del_soft( pJ );

	return TEG_STATUS_SUCCESS;
error:
	net_print(fd,TOKEN_ERROR"="TOKEN_SURRENDER"\n");
	return TEG_STATUS_PARSEERROR;
}
Exemple #4
0
/* adds a fd to the all_set descriptors */
void fd_add( int fd )
{
	if( g_server.debug )
		con_text_out(M_INF,_("Accepting fd %d\n"),fd);

	FD_SET(fd, &all_set );
	if( fd > max_fd )
		max_fd = fd;
}
Exemple #5
0
/* Clears a fd from the all_set descriptors */
void fd_remove( int fd )
{
	if( g_server.debug )
		con_text_out(M_INF,_("Removing fd %d\n"),fd);

	if( fd > 0 ) {
		net_close(fd);
		FD_CLR(fd,&all_set);
	}
}
Exemple #6
0
TEG_STATUS launch_robot( int *robot_socket, char *mode )
{
    pid_t pid;
    char *args[5];

    int sockets[2];

    // sockets[0] is the client side of the robot
    // sockets[1] is the server side
    sockets[0] = 0;
    while(sockets[0] < 3) {
        int r = socketpair(AF_LOCAL, SOCK_STREAM, 0, sockets );
        if( r != 0 )
            return TEG_STATUS_ERROR;
    }

    // launch the server connected
    if ( (pid = fork()) < 0) {
        perror("tegserver: launch_bot() ");
        return TEG_STATUS_ERROR;
    } else if (pid == 0) {

        close( sockets[1] );
        args[0] = BINDIR"/tegrobot";
        args[1] = mode;
        args[2] = NULL;

        if ( dup2(  sockets[0], 3 ) == -1 )
            return TEG_STATUS_ERROR;

        con_text_out(M_ERR, _("Launching robot with options: %s %s\n"),args[0],args[1]);
        if( execv(args[0], args) < 0) {
            fprintf(stderr,"Launching robot failed. Does the file `%s' exists ?",args[0]);
            perror("exe:");
        }
        exit(1);
    } else {

        close( sockets[0] );
    }

    // return the robot fd
    *robot_socket = sockets[1];

    return TEG_STATUS_SUCCESS;
}
Exemple #7
0
/* Protocol version */
STATIC TEG_STATUS token_pversion( int fd, char *str )
{
	PSPLAYER pJ;
	PARSER p;
	DELIM igualador={ ':', ':', ':' };
	DELIM separador={ ',', ',', ',' };
	int hi,lo;

	PLAY_DEBUG("token_pversion()\n");


	if( strlen(str)==0 )
		goto error;

	p.igualador = &igualador;
	p.separador = &separador;
	p.data = str;

	if( parser_call( &p ) && p.hay_otro ) {
		hi = atoi( p.token );		
	} else goto error;

	if( parser_call( &p ) && !p.hay_otro ) {
		lo = atoi( p.token );		
	} else goto error;

	net_printf(fd,"%s=%i,%i\n", TOKEN_PVERSION, PROTOCOL_HIVER,PROTOCOL_LOVER);

	if( hi != PROTOCOL_HIVER ) {
		con_text_out(M_ERR,_("Client with incompatible protocol version (server:%d , client:%d)\n"),PROTOCOL_HIVER,hi);

		if( player_whoisfd( fd, &pJ ) == TEG_STATUS_SUCCESS )
			player_del_hard( pJ );
		else
			fd_remove(fd);
		return TEG_STATUS_CONNCLOSED;
	}

	return TEG_STATUS_SUCCESS;

error:
	net_print(fd,TOKEN_ERROR"="TOKEN_PVERSION"\n");
	return TEG_STATUS_PARSEERROR;
}
Exemple #8
0
/* Assigns the player a color */
STATIC TEG_STATUS token_color( int fd, char *str )
{
	int color;
	int a;
	PSPLAYER pJ;
	PLAY_DEBUG("token_color()");

	if( player_whoisfd( fd, &pJ ) != TEG_STATUS_SUCCESS ) {
		goto error;
	}

	if(strlen(str)==0)
		goto error;

	if( pJ->estado != PLAYER_STATUS_CONNECTED )
		goto error;

	if( pJ->is_player == FALSE )
		goto error;

	a = atoi( str );
	if (a < 0 ||  a >= TEG_MAX_PLAYERS )
		goto error;

	color = a;
	if ( color_libre( &color )  == FALSE )
		goto error;

	pJ->estado = PLAYER_STATUS_HABILITADO;
	pJ->color = color;
	con_text_out(M_INF,_("Player %s(%d) has color %s\n"),pJ->name,pJ->numjug,_(g_colores[color]));

	netall_printf( "%s=%s,%d,%d\n", TOKEN_NEWPLAYER, pJ->name, pJ->numjug, pJ->color );
	return TEG_STATUS_SUCCESS;
error:
	net_print(fd,TOKEN_ERROR"="TOKEN_COLOR"\n");
	return TEG_STATUS_PARSEERROR;
}
Exemple #9
0
/* A player is attacking from src to dst */
STATIC TEG_STATUS token_attack( int fd, char *str )
{
	PARSER p;
	DELIM igualador={ ':', ':', ':' };
	DELIM separador={ ',', ',', ',' };
	int src,dst,src_lost,dst_lost;
	char d_src[3],d_dst[3];
	PSPLAYER pJ_src, pJ_dst;
	int conq = 0;
	int tropas = 0;
	char buffer[4096];

	PLAY_DEBUG("token_attack()\n");

	if( strlen(str)==0)
		goto error;

	if( !SPLAYER_ATAQUE_P(fd,&pJ_src)) {
		if( SPLAYER_TROPAS_P(fd,&pJ_src)) {
			pJ_src->estado=PLAYER_STATUS_ATAQUE;
			pJ_src->country_src = pJ_src->country_dst = -1;
		} else goto error;
	}

	p.igualador = &igualador;
	p.separador = &separador;
	p.data = str;

	if( parser_call( &p ) && p.hay_otro ) {
		src = atoi( p.token );		
	} else goto error;

	if( parser_call( &p ) && !p.hay_otro ) {
		dst = atoi( p.token );		
	} else goto error;

	if( src >= COUNTRIES_CANT || src < 0 || dst >= COUNTRIES_CANT || dst < 0) {
		goto error;
	}

	if( pJ_src->numjug != g_countries[src].numjug || pJ_src->numjug == g_countries[dst].numjug )  {
		goto error;
	}

	if( g_countries[src].ejercitos < 2 || !countries_eslimitrofe( src, dst) ) {
		goto error;
	}

	if( player_whois( g_countries[dst].numjug, &pJ_dst ) != TEG_STATUS_SUCCESS ){
		goto error;
	}

	if( pactos_attack( src, dst ) != TEG_STATUS_SUCCESS )
		goto error;

	/* aviso a todos que hay un attack */
	if( ! g_game.fog_of_war )
		netall_printf( "%s=%d,%d\n",TOKEN_ATAQUE,src,dst );
	else {
		fow_2_netall_printf( src, dst, "%s=%s,%s\n",TOKEN_ATAQUE,"%d","%d" );
	}

	/* so far, attack... */
	aux_token_attack( g_countries[src].ejercitos, g_countries[dst].ejercitos, &src_lost, &dst_lost, d_src, d_dst );

	g_countries[src].ejercitos -= src_lost;
	g_countries[dst].ejercitos -= dst_lost;
	pJ_src->tot_armies -= src_lost;
	pJ_dst->tot_armies -= dst_lost;

	/* updated statistics */
	pJ_src->player_stats.armies_killed += dst_lost;
	pJ_dst->player_stats.armies_killed += src_lost;
	pJ_dst->player_stats.armies_lost += dst_lost;
	pJ_src->player_stats.armies_lost += src_lost;

	/* conquisto el country | country was conquered */
	if( g_countries[dst].ejercitos == 0) {
		PLIST_ENTRY l;

		conq = 1;

		pJ_src->turno_conq++;
		pJ_src->tot_countries++;

		
		g_countries[dst].numjug = pJ_src->numjug;

		g_countries[dst].ejercitos++;		/* se pasa automaticamente */
		g_countries[src].ejercitos--;		/* un ejercito */

		tropas = g_countries[src].ejercitos - 1;	/* cantidad que se pueden pasar */
		if( tropas > 2 )			/* En verdad son 3, pero ya se le paso 1 */
			tropas =2;

		pJ_src->estado = PLAYER_STATUS_TROPAS;
		pJ_src->country_src = src;
		pJ_src->country_dst = dst;
	
		pJ_dst->tot_countries--;

		l= RemoveHeadList( g_countries[dst].next.Blink );
		InsertTailList( &pJ_src->countries, l);

		/* updated statistics */
		pJ_src->player_stats.countries_won ++;
		pJ_dst->player_stats.countries_lost ++;
	}

	/* update the scores */
	stats_score( &pJ_src->player_stats );
	stats_score( &pJ_dst->player_stats );

	/* tell everybody the result of the attack */

	memset( buffer, 0, sizeof(buffer) );

	if( ! g_game.fog_of_war ) {
		netall_printf( "%s=%d,%d,%d,%d,%d,%d,%d,%d\n", TOKEN_DADOS,
			src,d_src[0],d_src[1],d_src[2], dst,d_dst[0],d_dst[1],d_dst[2] );
	} else {
		fow_2_netall_printf( src, dst, "%s=%s,%d,%d,%d,%s,%d,%d,%d\n"
			, TOKEN_DADOS
			, "%d",d_src[0],d_src[1],d_src[2]
			, "%d",d_dst[0],d_dst[1],d_dst[2] );
	}

	if( ! g_game.fog_of_war ) {
		netall_printf( "%s=%d,%d,%d;%s=%d,%d,%d\n",
			TOKEN_COUNTRY, src, g_countries[src].numjug, g_countries[src].ejercitos,
			TOKEN_COUNTRY, dst, g_countries[dst].numjug, g_countries[dst].ejercitos
			);
	} else {
		fow_netall_printf( src, "%s=%d,%d,%d\n", TOKEN_COUNTRY,
				src, g_countries[src].numjug, g_countries[src].ejercitos );

		fow_netall_printf( dst, "%s=%d,%d,%d\n", TOKEN_COUNTRY,
				dst, g_countries[dst].numjug, g_countries[dst].ejercitos );
	}

	if( conq == 1 ) {

		/* Did 'dst' player lose the game ? */
		if( player_is_lost( pJ_dst ) ) {
			con_text_out(M_INF,_("Player %s(%d) lost the game\n"),pJ_dst->name,pJ_dst->numjug);
			netall_printf( "%s=%d\n",TOKEN_LOST, pJ_dst->numjug );
			player_poner_perdio(pJ_dst);
		}

		/* Did 'src' player win the game ? */
		if( mission_chequear( pJ_src ) == TEG_STATUS_GAMEOVER || game_is_finished() ) {
#ifdef WITH_GGZ
			ggz_server_gameover(pJ_src->fd);
#endif
			con_text_out(M_INF,_("Player %s(%d) is the winner! Game Over\n"),pJ_src->name,pJ_src->numjug);
			pJ_src->estado = PLAYER_STATUS_GAMEOVER;
			game_end( pJ_src );
			return TEG_STATUS_SUCCESS;
		}

		net_printf(fd,"%s=%d,%d,%d\n", TOKEN_TROPAS, src,dst,tropas);


		/* in FOW show the boundaries countries */
		if( g_game.fog_of_war ) {
			char buffer[2048];

			memset( buffer, 0, sizeof(buffer) );
			if( fow_fill_with_boundaries( dst, buffer, sizeof(buffer) ) == TEG_STATUS_SUCCESS )
				net_printf( fd, "%s\n", buffer );
		}
	}

	return TEG_STATUS_SUCCESS;
error:
	net_print(fd,TOKEN_ERROR"="TOKEN_ATAQUE"\n");
	return TEG_STATUS_PARSEERROR;
}
Exemple #10
0
STATIC TEG_STATUS token_cversion( int fd, char *str )
{
	con_text_out(M_INF,_("Using client version: %s\n"),str);
	return TEG_STATUS_SUCCESS;
}
Exemple #11
0
/* Creates a Player */
STATIC TEG_STATUS token_playerid( int fd, char *str )
{
	PARSER p;
	DELIM igualador={ ':', ':', ':' };
	DELIM separador={ ',', ',', ',' };
	SPLAYER j, *pJ;
	char c[TEG_MAX_PLAYERS];
	char colores[100];
	int i;
	int reconnect = FALSE;

	PLAY_DEBUG("token_playerid( fd=%d)\n",fd);

	/* si existe entonces da error, porque no tiene que existir */
	if( player_whoisfd(fd, &pJ ) == TEG_STATUS_SUCCESS )
		goto error;

	if( strlen(str)==0 )
		goto error;

	p.igualador = &igualador;
	p.separador = &separador;
	p.data = str;

	memset( &j, 0, sizeof(SPLAYER));

	/* averigua el name */
	if( parser_call( &p ) && p.hay_otro ) {
#ifdef WITH_GGZ
		if(g_server.with_ggz) {
			if( ggz_server_find_ggzname(fd,j.name,sizeof(j.name)-1) != TEG_STATUS_SUCCESS ) {
				player_fillname( &j, p.token );
			}
		} else
#endif /* WITH_GGZ */
			player_fillname( &j, p.token );
	} else goto error;

	if( parser_call( &p ) && p.hay_otro ) {
		j.is_player = atoi( p.token );		
	} else
		goto error;

	if( parser_call( &p ) && !p.hay_otro ) {
		j.human = atoi( p.token );		
	} else
		goto error;


	if( j.is_player ) {
		if( JUEGO_EMPEZADO ) {
			if( ! (reconnect = player_is_disconnected(&j)) ) {
				net_print(fd,TOKEN_GAMEINPROGRESS"\n");
				fd_remove(fd);
				return TEG_STATUS_CONNCLOSED;
			}
		}
		if( reconnect )
			pJ = player_return_disconnected( &j );
		else
			pJ = player_ins_player( &j );
	} else
		pJ = player_ins_ro( &j );


	if( pJ == NULL ) {
		net_print(fd,TOKEN_SERVERFULL "\n");
		fd_remove(fd);
		return TEG_STATUS_CONNCLOSED;
	}

	pJ->fd = fd;

	aux_find_inaddr( pJ );

	if( reconnect ) {

		pJ->estado = pJ->status_before_discon;

		net_printf(fd,"%s=%s,%d,%d\n", TOKEN_RECONNECT, pJ->name,pJ->numjug,pJ->color);
		con_text_out(M_INF,_("Player %s(%d) is re-connected from %s\n"),pJ->name,pJ->numjug,pJ->addr);

	} else {
		colores_libres( c );
		memset(colores,0,sizeof(colores));

		for(i=0;i<TEG_MAX_PLAYERS;i++) {
			char buf[100];
			sprintf( buf, ",%d",c[i] );
			strncat( colores, buf, sizeof(colores)-1 );
		}

		net_printf(fd,"%s=%s,%d%s\n", TOKEN_PLAYERID, pJ->name,pJ->numjug,colores);

		con_text_out(M_INF,_("Player %s(%d) is connected from %s\n"),pJ->name,pJ->numjug,pJ->addr);
	}
	return TEG_STATUS_SUCCESS;
error:
	net_print(fd,TOKEN_ERROR"="TOKEN_PLAYERID"\n");
	return TEG_STATUS_PARSEERROR;
}
Exemple #12
0
/* find the internet address of a player */
TEG_STATUS aux_find_inaddr( PSPLAYER pJ )
{
    struct sockaddr *sa;
    socklen_t slen = 128;

    assert(pJ);

    strncpy(pJ->addr, _("Unknown"), sizeof(pJ->addr)-1);

#ifdef WITH_GGZ
    if(g_server.with_ggz) {
        strncpy(pJ->addr, _("GGZ Client"), sizeof(pJ->addr)-1);
        return TEG_STATUS_SUCCESS;
    }
#endif /* WITH_GGZ */

    if( pJ->fd <= 0)
        return TEG_STATUS_ERROR;

    if( (sa=malloc(slen)) == NULL )
        return TEG_STATUS_ERROR;

    if( getpeername( pJ->fd, sa, &slen ) == -1) {
        con_text_out(M_ERR,"Error in getpeername()\n");
        pJ->addr[sizeof(pJ->addr)-1]=0;

        free(sa);
        return TEG_STATUS_ERROR;
    }

    switch(sa->sa_family) {
    case AF_INET: {
        struct sockaddr_in *sin = (struct sockaddr_in*) sa;
        my_inet_ntop( AF_INET, &sin->sin_addr,pJ->addr, sizeof(pJ->addr)-1);
        break;
    }
    case AF_INET6: {
        struct sockaddr_in6 *sin6 = (struct sockaddr_in6*) sa;
        my_inet_ntop( AF_INET6, &sin6->sin6_addr,pJ->addr, sizeof(pJ->addr)-1);
        break;
    }
    case AF_UNIX:
        strncpy(pJ->addr,"127.0.0.1",sizeof(pJ->addr)-1);
        break;
#if 0
        {
            struct sockaddr_un *unp = (struct sockaddr_un *) sa;
            if(unp->sun_path[0]==0)
                strncpy(pJ->addr,_("Unknown"),sizeof(pJ->addr)-1);
            else
                snprintf(pJ->addr, sizeof(pJ->addr)-1, "%s", unp->sun_path);
            break;
        }
#endif
    default:
        break;
    }

    pJ->addr[sizeof(pJ->addr)-1]=0;

    strip_invalid(pJ->addr);

    free(sa);

    return TEG_STATUS_SUCCESS;
}