Esempio n. 1
0
File: game.c Progetto: bpa/gamed
void handle_placing(GameInstance *g, const Server *s, Player *p, const char *req, int len) {
    SpeedRiskData *risk;
	int all_ready, i;
    SR_Command *cmd = (SR_Command*)req;
    risk = (SpeedRiskData*)g->data;
    if (cmd->to >= risk->board->territories) {
        player_error(s, p, SR_ERR_INVALID_DESTINATION);
        return;
    }
	switch (cmd->command) {
		case SR_CMD_READY:
			if (risk->players[p->in_game_id].ready)
				return;
			risk->players[p->in_game_id].ready = true;
			all_cmd_f(g, s, SR_CMD_READY, p->in_game_id);
			all_ready = true;
			for (i=0; i<risk->board->max_players; i++) {
				all_ready &= (risk->players[i].player == NULL || risk->players[i].ready);
			}
			if (all_ready) {
				s->change_state(g, &SR_RUNNING);
			}
			break;
		case SR_CMD_NOTREADY:
			if (!risk->players[p->in_game_id].ready)
				return;
			risk->players[p->in_game_id].ready = false;
			all_cmd_f(g, s, SR_CMD_NOTREADY, p->in_game_id);
			break;
		case SR_CMD_PLACE:
			if (not_holds((&risk->status), p, cmd->to)) {
				player_error(s, p, SR_ERR_NOT_OWNER);
			}
			else if (cmd->armies > 
				risk->players[p->in_game_id].armies) {
				player_error(s, p, SR_ERR_NOT_ENOUGH_ARMIES);
			}
			else {
				risk->status.countries[cmd->to].armies += cmd->armies;
				risk->players[p->in_game_id].armies -= cmd ->armies;
				give_country_status(g, s, NULL, cmd->to);
				player_cmd_a(s, p, SR_CMD_GET_ARMIES,
					risk->players[p->in_game_id].armies);
			}
		case SR_CMD_PLAYER_STATUS:
			give_player_status(g, s, p, req, len);
            break;
		case SR_CMD_LIST_THEMES:
			list_themes(g, s, p);
			break;
		default:
			player_error(s, p, SR_ERR_INVALID_CMD);
			break;
	}
}
Esempio n. 2
0
File: game.c Progetto: bpa/gamed
void handle_playing(GameInstance *g, const Server *s, Player *p, const char *req, int len) {
	int armies;
    SpeedRiskData *risk;
    SR_Command *cmd = (SR_Command*)req;
    risk = (SpeedRiskData*)g->data;
	return_if_invalid(cmd);
	switch (cmd->command) {
		case SR_CMD_MOVE:
			do_move(g, s, p, cmd);
			break;
		case SR_CMD_ATTACK:
			do_attack(g, s, p, cmd);
			break;
		case SR_CMD_PLACE:
			if (not_holds((&risk->status), p, cmd->to)) {
				player_error(s, p, SR_ERR_NOT_OWNER);
			}
			else if (cmd->armies > risk->players[p->in_game_id].armies) {
				player_error(s, p, SR_ERR_NOT_ENOUGH_ARMIES);
			}
			else {
				armies = risk->status.countries[cmd->to].armies + cmd->armies;
				if (armies > 255)
					cmd->armies = 255 - risk->status.countries[cmd->to].armies;
				risk->status.countries[cmd->to].armies += cmd->armies;
				risk->players[p->in_game_id].armies -= cmd->armies;
				give_country_status(g, s, NULL, cmd->to);
				player_cmd_a(s, p, SR_CMD_GET_ARMIES,
					risk->players[p->in_game_id].armies);
			}
			break;
		case SR_CMD_GAME_STATUS:
			give_game_status(g, s, p);
			break;
		case SR_CMD_PLAYER_STATUS:
			msg_command.command = SR_CMD_PLAYER_STATUS;
			msg_command.from = p->in_game_id;
			msg_command.to = g->playing;
			msg_command.armies = risk->players[p->in_game_id].armies;
			s->tell_player(p,(char*)&msg_command,4);
			break;
		case SR_CMD_COUNTRY_STATUS:
			give_country_status(g, s, p, cmd->from);
			break;
		default:
			player_error(s, p, SR_ERR_INVALID_CMD);
			break;
	}
}
Esempio n. 3
0
static int _playerbackend_command(PlayerBackend * player, char const * cmd,
		size_t cmd_len)
{
	char * p;

	if(player->pid == -1)
	{
		fputs(PROGNAME ": mplayer not running\n", stderr);
		if(player->timeout_id != 0)
			g_source_remove(player->timeout_id);
		player->timeout_id = g_timeout_add(1000, _command_on_timeout,
				player);
		return -1;
	}
#ifdef DEBUG
	fprintf(stderr, "%s%d%s\"%s\"\n", "DEBUG: pid ", player->pid,
			": write ", cmd);
#endif
	if((p = realloc(player->buf, player->buf_len + cmd_len)) == NULL)
		return -player_error(NULL, "malloc", 1);
	player->buf = p;
	memcpy(&p[player->buf_len], cmd, cmd_len);
	player->buf_len += cmd_len;
	if(player->write_id == 0)
		player->write_id = g_io_add_watch(player->channel[1], G_IO_OUT,
				_command_write, player);
	return 0;
}
Esempio n. 4
0
/* playerbackend_destroy */
void playerbackend_destroy(PlayerBackend * player)
{
	char const cmd[] = "\nquit\n";
	gsize written;
	size_t i;
	int status = 0;
	pid_t res;
	struct timespec ts = { 0, 500000 };

	if(player->read_id != 0)
		g_source_remove(player->read_id);
	if(player->write_id != 0)
		g_source_remove(player->write_id);
	if(player->timeout_id != 0)
		g_source_remove(player->timeout_id);
	g_io_channel_write_chars(player->channel[1], cmd, sizeof(cmd) - 1,
			&written, NULL);
	g_io_channel_shutdown(player->channel[1], FALSE, NULL);
	for(i = 0; i < 6; i++)
	{
		if((res = waitpid(player->pid, &status, WNOHANG)) == -1)
		{
			player_error(NULL, "waitpid", 0);
			break;
		}
		else if(res == 0)
			nanosleep(&ts, NULL);
		else if(WIFEXITED(status) || WIFSIGNALED(status))
			break;
		if(i == 4)
			kill(player->pid, SIGTERM);
	}
	object_delete(player);
}
Esempio n. 5
0
static gboolean _command_read(GIOChannel * source, GIOCondition condition,
		gpointer data)
{
	PlayerBackend * player = data;
	static char buf[512];
	static size_t buf_len = 0;
	gsize read;
	size_t i;
	size_t j;
	GIOStatus status;
	GError * error = NULL;

	if(condition != G_IO_IN)
	{
		player_error(player->player, "", 0); /* FIXME */
		gtk_main_quit();
		return FALSE; /* FIXME report error */
	}
	status = g_io_channel_read_chars(source, &buf[buf_len],
			sizeof(buf) - buf_len, &read, &error);
	if(status == G_IO_STATUS_EOF || read == 0)
	{
		player->read_id = 0;
		return FALSE; /* FIXME end of file? */
	}
	else if(status != G_IO_STATUS_NORMAL)
	{
		player_error(player->player, error->message, 1);
		g_error_free(error);
		/* FIXME recover somehow */
		gtk_main_quit();
		return FALSE;
	}
	buf_len += read;
	j = 0;
	for(i = 0; i < buf_len; i++)
	{
		if(buf[i] != '\n')
			continue;
		buf[i] = '\0';
		_read_parse(player, &buf[j]);
		j = i + 1;
	}
	buf_len -= j;
	memmove(buf, &buf[j], buf_len);
	return TRUE;
}
Esempio n. 6
0
File: game.c Progetto: bpa/gamed
void handle_waiting(GameInstance *g, const Server *s, Player *p, const char *req, int len) {
    SpeedRiskData *risk;
	int all_ready, i;
    SR_Command *cmd = (SR_Command*)req;
    risk = (SpeedRiskData*)g->data;
	switch (cmd->command) {
		case SR_CMD_READY:
			if (g->playing > 1) {
				if (risk->players[p->in_game_id].ready) {
					player_error(s, p, SR_ERR_INVALID_CMD);
					break;
				}
				risk->players[p->in_game_id].ready = true;
				all_cmd_f(g, s, SR_CMD_READY, p->in_game_id);
				all_ready = true;
				for (i=0; i<risk->board->max_players; i++) {
					all_ready &= (risk->players[i].player == NULL || risk->players[i].ready);
				}
				if (all_ready) {
					s->change_state(g, &SR_PLACING);
				}
			}
			else {
				player_error(s, p, SR_ERR_NOT_ENOUGH_PLAYERS);
			}
			break;
		case SR_CMD_NOTREADY:
			if (!risk->players[p->in_game_id].ready) {
				player_error(s, p, SR_ERR_INVALID_CMD);
				break;
			}
			risk->players[p->in_game_id].ready = false;
			all_cmd_f(g, s, SR_CMD_NOTREADY, p->in_game_id);
			break;
		case SR_CMD_PLAYER_STATUS:
			give_player_status(g, s, p, req, len);
			break;
		case SR_CMD_LIST_THEMES:
			list_themes(g, s, p);
			break;
		default:
			player_error(s, p, SR_ERR_INVALID_CMD);
			break;
	}
}
Esempio n. 7
0
File: game.c Progetto: bpa/gamed
void do_attack(GameInstance *g, const Server *s, Player *p, SR_Command *cmd) {
	SpeedRiskData *risk = (SpeedRiskData *)g->data;
    SR_Game_Status *status = &risk->status;
	int attacking, defending, attack_loss, defend_loss, defender;
	if (not_holds(status, p, cmd->from)) {
		player_error(s, p, SR_ERR_NOT_OWNER);
	}
	else if (holds(status, p, cmd->to)) {
		player_error(s, p, SR_ERR_INVALID_DESTINATION);
	}
	else if (!borders(cmd->from, cmd->to)) {
		player_error(s, p, SR_ERR_INVALID_DESTINATION);
	}
	else if (cmd->armies < 1 || cmd->armies >= 
		status->countries[cmd->from].armies) {
		player_error(s, p, SR_ERR_NOT_ENOUGH_ARMIES);
	}
	else {
		attacking = cmd->armies > 3 ? 3 : cmd->armies;
		defending = status->countries[cmd->to].armies > 1 ? 2 : 1;
		roll_for_attack(attacking, defending, s->random, &attack_loss, &defend_loss);
		status->countries[cmd->from].armies -= attack_loss;
		status->countries[cmd->to].armies   -= defend_loss;
		defender = status->countries[cmd->to].owner;
		if (status->countries[cmd->to].armies == 0) {
			attacking = cmd->armies - attack_loss;
			status->countries[cmd->from].armies -= attacking;
			status->countries[cmd->to].armies += attacking;
			status->countries[cmd->to].owner = p->in_game_id;
			risk->players[p->in_game_id].countries_held++;
			risk->players[defender].countries_held--;
		}
		tell_all_mv_at_result(g, s, SR_CMD_ATTACK_RESULT, cmd->from, cmd->to);
		if (risk->players[defender].countries_held == 0) {
			all_cmd_f(g, s, SR_CMD_DEFEAT, defender);
			if (risk->players[defender].player != NULL) {
				s->log(g, "%s defeated", risk->players[defender].player->name);
			}
		}
		if (risk->players[p->in_game_id].countries_held == risk->board->territories) {
			s->change_state(g, &SR_DONE);
		}
	}
}
Esempio n. 8
0
File: game.c Progetto: bpa/gamed
void handle_done (GameInstance *g, const Server *s, Player *p, const char *req, int len) {
    SpeedRiskData *risk;
    SR_Command *cmd = (SR_Command*)req;
    risk = (SpeedRiskData*)g->data;
	switch (cmd->command) {
		case SR_CMD_GAME_STATUS:
			give_game_status(g, s, p);
			break;
		case SR_CMD_COUNTRY_STATUS:
    		if ( cmd->from >= risk->board->territories ) {
        		player_error(s, p, SR_ERR_INVALID_DESTINATION);
        		return;
			}
			give_country_status(g, s, p, cmd->from);
			break;
		default:
			player_error(s, p, SR_ERR_INVALID_CMD);
			break;
	}
}
Esempio n. 9
0
static void _consumer_handle_eof(void)
{
	struct track_info *ti;

	if (ip_is_remote(ip)) {
		_producer_stop();
		_consumer_drain_and_stop();
		player_error("lost connection");
		return;
	}

	if (player_info.ti)
		player_info.ti->play_count++;

	if (player_repeat_current) {
		if (player_cont) {
			ip_seek(ip, 0);
			reset_buffer();
		} else {
			_producer_stop();
			_consumer_drain_and_stop();
			_player_status_changed();
		}
		return;
	}

	if (get_next(&ti) == 0) {
		_producer_unload();
		ip = ip_new(ti->filename);
		_producer_status_update(PS_STOPPED);
		/* PS_STOPPED, CS_PLAYING */
		if (player_cont) {
			_producer_play();
			if (producer_status == PS_UNLOADED) {
				_consumer_stop();
				track_info_unref(ti);
				file_changed(NULL);
			} else {
				/* PS_PLAYING */
				file_changed(ti);
				if (!change_sf(0))
					_prebuffer();
			}
		} else {
			_consumer_drain_and_stop();
			file_changed(ti);
		}
	} else {
		_producer_unload();
		_consumer_drain_and_stop();
		file_changed(NULL);
	}
	_player_status_changed();
}
Esempio n. 10
0
/* playerbackend_start */
int playerbackend_start(PlayerBackend * player)
{
	int ret;
	char const buf[] = "pausing loadfile " PLAYER_SPLASH " 0\nframe_step\n";
	char wid[32];
	char * argv[] = { BINDIR "/mplayer", "mplayer", "-slave", "-wid", NULL,
		"-quiet", "-idle", "-framedrop", "-softvol",
		"-softvol-max", "200", "-identify", "-noconsolecontrols",
		"-nomouseinput", NULL };
	GError * error = NULL;

	argv[4] = wid;
	/* XXX not portable */
	snprintf(wid, sizeof(wid), "%lu", (unsigned long)gtk_socket_get_id(
				GTK_SOCKET(player->view)));
	if(pipe(player->fd[0]) != 0 || pipe(player->fd[1]) != 0)
		return -player_error(player->player, strerror(errno), 1);
	if((player->pid = fork()) == -1)
		return -player_error(player->player, strerror(errno), 1);
	if(player->pid == 0) /* child */
	{
		close(player->fd[0][0]);
		close(player->fd[1][1]);
		if(dup2(player->fd[1][0], 0) == -1)
			exit(player_error(NULL, "dup2", 2));
		if(dup2(player->fd[0][1], 1) == -1)
			exit(player_error(NULL, "dup2", 2));
		execv(argv[0], &argv[1]);
		exit(player_error(NULL, argv[0], 2));
	}
	close(player->fd[0][1]);
	close(player->fd[1][0]);
	player->channel[0] = g_io_channel_unix_new(player->fd[0][0]);
	if(g_io_channel_set_encoding(player->channel[0], NULL, &error)
			!= G_IO_STATUS_NORMAL)
	{
		player_error(player->player, error->message, 1);
		g_error_free(error);
		error = NULL;
	}
	g_io_channel_set_buffered(player->channel[0], FALSE);
	player->read_id = g_io_add_watch(player->channel[0], G_IO_IN,
			_command_read, player);
	player->channel[1] = g_io_channel_unix_new(player->fd[1][1]);
	if(g_io_channel_set_encoding(player->channel[1], NULL, &error)
			!= G_IO_STATUS_NORMAL)
	{
		player_error(player->player, error->message, 1);
		g_error_free(error);
	}
	g_io_channel_set_buffered(player->channel[1], FALSE);
	ret = _playerbackend_command(player, buf, sizeof(buf) - 1);
	player_set_paused(player->player, TRUE);
	return ret;
}
Esempio n. 11
0
/* command_write */
static gboolean _command_write(GIOChannel * source, GIOCondition condition,
		gpointer data)
{
	PlayerBackend * player = data;
	gsize written;
	char * p;
	GError * error = NULL;

	if(condition != G_IO_OUT)
	{
		player_error(player->player, "", 0); /* FIXME */
		gtk_main_quit();
		player->write_id = 0;
		return FALSE; /* FIXME report error */
	}
	if(g_io_channel_write_chars(source, player->buf, player->buf_len,
				&written, &error) != G_IO_STATUS_NORMAL)
	{
		player_error(player->player, error->message, 1);
		g_error_free(error);
		/* FIXME recover somehow */
		gtk_main_quit();
		player->write_id = 0;
		return FALSE;
	}
#ifdef DEBUG
	fprintf(stderr, "DEBUG: wrote %zu bytes\n", written);
#endif
	player->buf_len -= written;
	memmove(player->buf, &player->buf[written], player->buf_len);
	if(player->buf_len == 0)
	{
		player->write_id = 0;
		return FALSE;
	}
	if((p = realloc(player->buf, player->buf_len)) != NULL)
		player->buf = p;
	return TRUE;
}
Esempio n. 12
0
File: game.c Progetto: bpa/gamed
void do_move(GameInstance *g, const Server *s, Player *p, SR_Command *cmd) {
	int armies;
	SpeedRiskData *risk = (SpeedRiskData *)g->data;
	SR_Game_Status *status = &risk->status;
	if (!(holds(status, p, cmd->from) && holds(status, p, cmd->to))) {
		player_error(s, p, SR_ERR_NOT_OWNER);
	}
	else if (!borders(cmd->from, cmd->to)) {
		player_error(s, p, SR_ERR_INVALID_DESTINATION);
	}
	else if (cmd->armies>=status->countries[cmd->from].armies){
		player_error(s, p, SR_ERR_NOT_ENOUGH_ARMIES);
	}
	else {
		armies = status->countries[cmd->to].armies + cmd->armies;
		if (armies > 255)
			cmd->armies = 255 - status->countries[cmd->to].armies;
		status->countries[cmd->from].armies -= cmd->armies;
		status->countries[cmd->to].armies   += cmd->armies;
		tell_all_mv_at_result(g, s, SR_CMD_MOVE_RESULT,
			cmd->from, cmd->to);
	}
}
Esempio n. 13
0
/* playerbackend_on_sigchld */
static int _playerbackend_on_sigchld(PlayerBackend * player)
{
	pid_t pid;
	int status;
	char buf[80];

	if(player->pid == -1)
		return 1;
	if((pid = waitpid(player->pid, &status, WNOHANG)) == -1)
		return player_error(player->player, "waitpid", 1);
	if(pid == 0)
		return 1;
	if(WIFEXITED(status))
	{
		snprintf(buf, sizeof(buf), "mplayer %d: exited with code %u",
				pid, WEXITSTATUS(status));
		player_error(player->player, buf, 1);
	}
	else
		fprintf(stderr, "%s%s%d%s", PROGNAME ": ", "mplayer ", pid,
				": Unknown state\n");
	player->pid = -1;
	return 0;
}
Esempio n. 14
0
static void __FORMAT(2, 3) player_op_error(int rc, const char *format, ...)
{
	char buffer[1024];
	va_list ap;
	char *msg;
	int save = errno;

	va_start(ap, format);
	vsnprintf(buffer, sizeof(buffer), format, ap);
	va_end(ap);

	errno = save;
	msg = op_get_error_msg(rc, buffer);
	player_error(msg);
	free(msg);
}
Esempio n. 15
0
static void _init_signal_handler(int signum)
{
	PlayerBackend * player = _player;
	pid_t pid;
	int status;

	if(signum != SIGCHLD)
		return;
	if(_playerbackend_on_sigchld(player) == 0)
		return;
	if((pid = waitpid(-1, &status, WNOHANG)) == -1)
	{
		player_error(NULL, "waitpid", 1);
		return;
	}
	if(pid == 0)
		return;
	fputs(PROGNAME ": ", stderr);
	if(WIFEXITED(status))
		fprintf(stderr, "%s%d%s%u\n", "child ", pid,
				": exited with code ", WEXITSTATUS(status));
	else
		fprintf(stderr, "%d%s", pid, ": Unknown state\n");
}