/* MaitreTarot. * (C) 2002 Guillaume Weexsteen * Modified by Yves Mettier * * 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. */ #include #include #include #include #include #include #include #include #include "defs.h" #include #include "playerthread.h" #include "utils.h" #define player_set_type(t,a,b) (t)->type = (a); (t)->value=(b) gint wait_for_data (player_t * player, gint chan, gint size, gint timeout) { gint l; g_message ("Player %s : Waiting for data\n", player->nicks[player->place]); while ((l = libmt_channels_set_has_enough_data_to_read (player->net_data->channels_set, chan, size)) == 0) { usleep (100); } if (l == -1) { g_message ("Player %s : An error occured. close all sockets\n", player->nicks[player->place]); player->ready = MT_PLAYER_READY_CLOSED; return (-1); } return (0); } gpointer player_thread (gpointer p) { player_t *player = p; gpointer buf; gint r; libmt_net_t *net_data = player->net_data; libmt_net_data_type_t type; while (player->ready != MT_PLAYER_READY_END) { switch (player->ready) { case MT_PLAYER_READY_GET_ID: g_message ("Player %s : LIBMT_NET_DATA_TYPE_GET_ID\n", player->nicks[player->place]); if (libmt_read_type (net_data->channels_set, 0, &type) == -1) { player->ready = MT_PLAYER_READY_CLOSED; break; } if (wait_for_data (player, 0, sizeof (gint) * 2, 0) == -1) { player->ready = MT_PLAYER_READY_CLOSED; break; } if (libmt_channels_set_read (net_data->channels_set, 0, net_data->client_id, sizeof (gint) * 2) == -1) { player->ready = MT_PLAYER_READY_CLOSED; break; } player->ready = MT_PLAYER_READY_NO; break; case MT_PLAYER_READY_SEND_ID: g_message ("Player %s : LIBMT_NET_DATA_TYPE_SEND_ID\n", player->nicks[player->place]); player_set_type (&type, LIBMT_NET_DATA_TYPE_SEND_ID, 0); if (libmt_write_type (net_data->channels_set, 0, &type) == -1) { player->ready = MT_PLAYER_READY_CLOSED; break; } if (libmt_channels_set_write (net_data->channels_set, 0, net_data->server_id, sizeof (gint) * 2) == -1) { player->ready = MT_PLAYER_READY_CLOSED; break; } player->ready = MT_PLAYER_READY_NO; break; case MT_PLAYER_READY_SEND_PROTOCOL: g_message ("Player %s : LIBMT_NET_DATA_TYPE_SEND_PROTOCOL\n", player->nicks[player->place]); player_set_type (&type, LIBMT_NET_DATA_TYPE_SEND_PROTOCOL, 0); if (libmt_write_type (net_data->channels_set, 0, &type) == -1) { player->ready = MT_PLAYER_READY_CLOSED; break; } if (libmt_channels_set_write (net_data->channels_set, 0, &(net_data->protocol_version), sizeof (gint)) == -1) { player->ready = MT_PLAYER_READY_CLOSED; break; } buf = g_malloc (sizeof (gint)); if (libmt_read_type (net_data->channels_set, 0, &type) == -1) { g_free (buf); player->ready = MT_PLAYER_READY_CLOSED; break; } if (wait_for_data (player, 0, sizeof (gint), 0) == -1) { g_free (buf); player->ready = MT_PLAYER_READY_CLOSED; break; } if (libmt_channels_set_read (net_data->channels_set, 0, buf, sizeof (gint)) == -1) { g_free (buf); player->ready = MT_PLAYER_READY_CLOSED; break; } g_free (buf); player->ready = MT_PLAYER_READY_NO; break; case MT_PLAYER_READY_SEND_PLACE: g_message ("Player %s : LIBMT_NET_DATA_TYPE_SEND_PLACE\n", player->nicks[player->place]); player_set_type (&type, LIBMT_NET_DATA_TYPE_SEND_PLACE, 0); if (libmt_write_type (net_data->channels_set, 0, &type) == -1) { player->ready = MT_PLAYER_READY_CLOSED; break; } if (libmt_channels_set_write (net_data->channels_set, 0, &(player->place), sizeof (gint)) == -1) { player->ready = MT_PLAYER_READY_CLOSED; break; } player->ready = MT_PLAYER_READY_NO; break; case MT_PLAYER_READY_GET_NICK: g_message ("Player %s : LIBMT_NET_DATA_TYPE_GET_NICK_LEN\n", player->nicks[player->place]); buf = g_malloc (sizeof (gint)); if (libmt_read_type (net_data->channels_set, 0, &type) == -1) { g_free (buf); player->ready = MT_PLAYER_READY_CLOSED; break; } if (wait_for_data (player, 0, sizeof (gint), 0) == -1) { g_free (buf); player->ready = MT_PLAYER_READY_CLOSED; break; } if (libmt_channels_set_read (net_data->channels_set, 0, buf, sizeof (gint)) == -1) { g_free (buf); player->ready = MT_PLAYER_READY_CLOSED; break; } if (*((gint *) buf) == 0) { g_free (buf); player->nicks[player->place] = g_strdup_printf ("Player %d", player->place); player->nicks_len[player->place] = strlen (player->nicks[player->place]); } else { player->nicks_len[player->place] = *((gint *) buf); g_free (buf); player->nicks[player->place] = (gchar *) g_malloc0 (sizeof (gchar) * (player->nicks_len[player->place] + 1)); if (libmt_read_type (net_data->channels_set, 0, &type) == -1) { player->ready = MT_PLAYER_READY_CLOSED; break; } if (wait_for_data (player, 0, sizeof (gchar) * player->nicks_len[player->place], 0) == -1) { player->ready = MT_PLAYER_READY_CLOSED; break; } if (libmt_channels_set_read (net_data->channels_set, 0, player->nicks[player->place], sizeof (gchar) * player->nicks_len[player-> place]) == -1) { player->ready = MT_PLAYER_READY_CLOSED; break; } } player->ready = MT_PLAYER_READY_NO; break; case MT_PLAYER_READY_SEND_NICKS: g_message ("Player %s : LIBMT_NET_DATA_TYPE_SEND_NICK_LEN\n", player->nicks[player->place]); player_set_type (&type, LIBMT_NET_DATA_TYPE_SEND_NICK_LEN, 0); if (libmt_write_type (net_data->channels_set, 0, &type) == -1) { player->ready = MT_PLAYER_READY_CLOSED; break; } if (libmt_channels_set_write (net_data->channels_set, 0, player->nicks_len, sizeof (gint) * 4) == -1) { player->ready = MT_PLAYER_READY_CLOSED; break; } buf = g_malloc (sizeof (gchar) * (player->nicks_len[0] + player->nicks_len[1] + player->nicks_len[2] + player->nicks_len[3])); memcpy (&((gchar *) buf)[0], player->nicks[0], player->nicks_len[0]); memcpy (&((gchar *) buf)[player->nicks_len[0]], player->nicks[1], player->nicks_len[1]); memcpy (&((gchar *) buf) [player->nicks_len[0] + player->nicks_len[1]], player->nicks[2], player->nicks_len[2]); memcpy (&((gchar *) buf) [player->nicks_len[0] + player->nicks_len[1] + player->nicks_len[2]], player->nicks[3], player->nicks_len[3]); g_message ("Player %s : LIBMT_NET_DATA_TYPE_SEND_NICKS\n", player->nicks[player->place]); player_set_type (&type, LIBMT_NET_DATA_TYPE_SEND_NICKS, 0); if (libmt_write_type (net_data->channels_set, 0, &type) == -1) { g_free (buf); player->ready = MT_PLAYER_READY_CLOSED; break; } if (libmt_channels_set_write (net_data->channels_set, 0, buf, sizeof (gchar) * (player->nicks_len[0] + player->nicks_len[1] + player->nicks_len[2] + player->nicks_len[3])) == -1) { g_free (buf); player->ready = MT_PLAYER_READY_CLOSED; break; } g_free (buf); player->ready = MT_PLAYER_READY_NO; break; case MT_PLAYER_READY_DILL_CARDS: g_message ("Player %s : LIBMT_NET_DATA_TYPE_DILL_CARDS\n", player->nicks[player->place]); for (r = 0; r < 18; r++) printf ("%02d ", player->card[r]); printf ("\n"); player_set_type (&type, LIBMT_NET_DATA_TYPE_DILL_CARDS, 0); if (libmt_write_type (net_data->channels_set, 0, &type) == -1) { player->ready = MT_PLAYER_READY_CLOSED; break; } if (libmt_channels_set_write (net_data->channels_set, 0, player->card, sizeof (gint) * 18) == -1) { player->ready = MT_PLAYER_READY_CLOSED; break; } player->ready = MT_PLAYER_READY_NO; break; case MT_PLAYER_READY_SEND_BIDS_AND_ASK_FOR_BID: case MT_PLAYER_READY_SEND_BIDS_ONLY: g_message ("Player %s : LIBMT_NET_DATA_TYPE_SEND_BIDS\n", player->nicks[player->place]); player_set_type (&type, LIBMT_NET_DATA_TYPE_SEND_BIDS, 0); if (libmt_write_type (net_data->channels_set, 0, &type) == -1) { player->ready = MT_PLAYER_READY_CLOSED; break; } if (libmt_channels_set_write (net_data->channels_set, 0, player->bid, sizeof (gint) * 4) == -1) { player->ready = MT_PLAYER_READY_CLOSED; break; } g_message ("Player %s : LIBMT_NET_DATA_TYPE_ASK_BID_QUESTION\n", player->nicks[player->place]); player_set_type (&type, LIBMT_NET_DATA_TYPE_ASK_BID_QUESTION, 0); if (libmt_write_type (net_data->channels_set, 0, &type) == -1) { player->ready = MT_PLAYER_READY_CLOSED; break; } r = ((player->ready == MT_PLAYER_READY_SEND_BIDS_ONLY) ? 0 : 1); if (libmt_channels_set_write (net_data->channels_set, 0, &r, sizeof (gint)) == -1) { player->ready = MT_PLAYER_READY_CLOSED; break; } player->ready = MT_PLAYER_READY_NO; break; case MT_PLAYER_READY_GET_BID: buf = g_malloc (sizeof (gint)); if (libmt_read_type (net_data->channels_set, 0, &type) == -1) { g_free (buf); player->ready = MT_PLAYER_READY_CLOSED; break; } if (wait_for_data (player, 0, sizeof (gint), 0) == -1) { g_free (buf); player->ready = MT_PLAYER_READY_CLOSED; break; } if (libmt_channels_set_read (net_data->channels_set, 0, buf, sizeof (gint)) == -1) { g_free (buf); player->ready = MT_PLAYER_READY_CLOSED; break; } player->bid[player->place] = *((gint *) buf); g_message ("%s : %d", player->nicks[player->place], player->bid[player->place]); g_free (buf); player->ready = MT_PLAYER_READY_NO; break; case MT_PLAYER_READY_SEND_FINAL_BIDS: g_message ("Player %s : LIBMT_NET_DATA_TYPE_SEND_FINAL_BID\n", player->nicks[player->place]); player_set_type (&type, LIBMT_NET_DATA_TYPE_SEND_FINAL_BIDS, 0); if (libmt_write_type (net_data->channels_set, 0, &type) == -1) { player->ready = MT_PLAYER_READY_CLOSED; break; } if (libmt_channels_set_write (net_data->channels_set, 0, (player->bid), sizeof (gint) * 4) == -1) { player->ready = MT_PLAYER_READY_CLOSED; break; } player->ready = MT_PLAYER_READY_NO; break; case MT_PLAYER_READY_SHOW_CHIEN: case MT_PLAYER_READY_SHOW_CHIEN_AT_END: g_message ("Player %s : LIBMT_NET_DATA_TYPE_SHOW_CHIEN\n", player->nicks[player->place]); player_set_type (&type, (player->ready == MT_PLAYER_READY_SHOW_CHIEN) ? LIBMT_NET_DATA_TYPE_SHOW_CHIEN : LIBMT_NET_DATA_TYPE_SHOW_CHIEN_AT_END, 0); if (libmt_write_type (net_data->channels_set, 0, &type) == -1) { player->ready = MT_PLAYER_READY_CLOSED; break; } if (libmt_channels_set_write (net_data->channels_set, 0, (player->chien), sizeof (gint) * 6) == -1) { player->ready = MT_PLAYER_READY_CLOSED; break; } player->ready = MT_PLAYER_READY_NO; break; case MT_PLAYER_READY_SEND_OK_FOR_CHIEN: case MT_PLAYER_READY_SEND_NOK_FOR_CHIEN: g_message ("Player %s : LIBMT_NET_DATA_TYPE_SEND_ACK_FOR_CHIEN\n", player->nicks[player->place]); r = ((player->ready == MT_PLAYER_READY_SEND_NOK_FOR_CHIEN) ? 0 : 1); player_set_type (&type, LIBMT_NET_DATA_TYPE_SEND_ACK_FOR_CHIEN, 0); if (libmt_write_type (net_data->channels_set, 0, &type) == -1) { player->ready = MT_PLAYER_READY_CLOSED; break; } if (libmt_channels_set_write (net_data->channels_set, 0, &r, sizeof (gint)) == -1) { player->ready = MT_PLAYER_READY_CLOSED; break; } player->ready = MT_PLAYER_READY_NO; break; case MT_PLAYER_READY_GET_CHIEN: g_message ("Player %s : LIBMT_NET_DATA_TYPE_GET_CHIEN\n", player->nicks[player->place]); buf = g_malloc (sizeof (gint) * 6); if (libmt_read_type (net_data->channels_set, 0, &type) == -1) { g_free (buf); player->ready = MT_PLAYER_READY_CLOSED; break; } if (wait_for_data (player, 0, sizeof (gint) * 6, 0) == -1) { g_free (buf); player->ready = MT_PLAYER_READY_CLOSED; break; } if (libmt_channels_set_read (net_data->channels_set, 0, buf, sizeof (gint) * 6) == -1) { g_free (buf); player->ready = MT_PLAYER_READY_CLOSED; break; } memcpy (player->chien, buf, sizeof (gint) * 6); g_free (buf); player->ready = MT_PLAYER_READY_NO; break; case MT_PLAYER_READY_SEND_TURN_CARDS: case MT_PLAYER_READY_SEND_TURN_CARDS_ONLY: g_message ("Player %s : LIBMT_NET_DATA_TYPE_SEND_TURN_CARDS\n", player->nicks[player->place]); player_set_type (&type, LIBMT_NET_DATA_TYPE_SEND_TURN_CARDS, 0); if (libmt_write_type (net_data->channels_set, 0, &type) == -1) { player->ready = MT_PLAYER_READY_CLOSED; break; } if (libmt_channels_set_write (net_data->channels_set, 0, (player->turn), sizeof (gint) * 8) == -1) { player->ready = MT_PLAYER_READY_CLOSED; break; } g_message ("Player %s : LIBMT_NET_DATA_TYPE_SEND_TURN_CARDS_QUESTION\n", player->nicks[player->place]); player_set_type (&type, LIBMT_NET_DATA_TYPE_SEND_TURN_CARDS_QUESTION, 0); if (libmt_write_type (net_data->channels_set, 0, &type) == -1) { player->ready = MT_PLAYER_READY_CLOSED; break; } r = ((player->ready == MT_PLAYER_READY_SEND_TURN_CARDS_ONLY) ? 0 : 1); if (libmt_channels_set_write (net_data->channels_set, 0, &r, sizeof (gint)) == -1) { player->ready = MT_PLAYER_READY_CLOSED; break; } player->ready = MT_PLAYER_READY_NO; break; case MT_PLAYER_READY_WAIT_FOR_TURN_CARD: g_message ("Player %s : LIBMT_NET_DATA_TYPE_GET_TURN_CARD\n", player->nicks[player->place]); buf = g_malloc (sizeof (gint)); if (libmt_read_type (net_data->channels_set, 0, &type) == -1) { g_free (buf); player->ready = MT_PLAYER_READY_CLOSED; break; } if (wait_for_data (player, 0, sizeof (gint), 0) == -1) { g_free (buf); player->ready = MT_PLAYER_READY_CLOSED; break; } if (libmt_channels_set_read (net_data->channels_set, 0, buf, sizeof (gint)) == -1) { g_free (buf); player->ready = MT_PLAYER_READY_CLOSED; break; } memcpy (&(player->turn_card), buf, sizeof (gint)); g_free (buf); player->ready = MT_PLAYER_READY_NO; break; case MT_PLAYER_READY_SEND_OK_FOR_CARD: case MT_PLAYER_READY_SEND_NOK_FOR_CARD: g_message ("Player %s : LIBMT_NET_DATA_TYPE_SEND_ACK_FOR_CARD\n", player->nicks[player->place]); r = ((player->ready == MT_PLAYER_READY_SEND_NOK_FOR_CARD) ? 0 : 1); player_set_type (&type, LIBMT_NET_DATA_TYPE_SEND_ACK_FOR_CARD, 0); if (libmt_write_type (net_data->channels_set, 0, &type) == -1) { player->ready = MT_PLAYER_READY_CLOSED; break; } if (libmt_channels_set_write (net_data->channels_set, 0, &r, sizeof (gint)) == -1) { player->ready = MT_PLAYER_READY_CLOSED; break; } player->ready = MT_PLAYER_READY_NO; break; case MT_PLAYER_READY_SEND_LAST_TURN_CARDS: g_message ("Player %s : LIBMT_NET_DATA_TYPE_SEND_LAST_TURN_CARDS\n", player->nicks[player->place]); player_set_type (&type, LIBMT_NET_DATA_TYPE_SEND_LAST_TURN_CARDS, 0); if (libmt_write_type (net_data->channels_set, 0, &type) == -1) { player->ready = MT_PLAYER_READY_CLOSED; break; } if (libmt_channels_set_write (net_data->channels_set, 0, (player->turn), sizeof (gint) * 4) == -1) { player->ready = MT_PLAYER_READY_CLOSED; break; } player->ready = MT_PLAYER_READY_NO; break; case MT_PLAYER_READY_SEND_SCORE: g_message ("Player %s : LIBMT_NET_DATA_TYPE_SEND_SCORE\n", player->nicks[player->place]); player_set_type (&type, LIBMT_NET_DATA_TYPE_SEND_SCORE, 0); if (libmt_write_type (net_data->channels_set, 0, &type) == -1) { player->ready = MT_PLAYER_READY_CLOSED; break; } if (libmt_channels_set_write (net_data->channels_set, 0, &(player->all_scores), 8 * sizeof (gint)) == -1) { player->ready = MT_PLAYER_READY_CLOSED; break; } player->ready = MT_PLAYER_READY_NO; break; case MT_PLAYER_READY_ACK_REPLAY: g_message ("Player %s : LIBMT_NET_DATA_TYPE_ACK_REPLAY\n", player->nicks[player->place]); buf = g_malloc (sizeof (gint)); if (libmt_read_type (net_data->channels_set, 0, &type) == -1) { g_free (buf); player->ready = MT_PLAYER_READY_CLOSED; break; } if (wait_for_data (player, 0, sizeof (gint), 0) == -1) { g_free (buf); player->ready = MT_PLAYER_READY_CLOSED; break; } if (libmt_channels_set_read (net_data->channels_set, 0, buf, sizeof (gint)) == -1) { g_free (buf); player->ready = MT_PLAYER_READY_CLOSED; break; } memcpy (&(player->is_ok_to_play_again), buf, sizeof (gint)); g_free (buf); player->ready = MT_PLAYER_READY_NO; break; case MT_PLAYER_READY_SEND_REPLAY_ANSWER: g_message ("Player %s : LIBMT_NET_DATA_TYPE_SEND_REPLAY_ANSWER\n", player->nicks[player->place]); player_set_type (&type, LIBMT_NET_DATA_TYPE_SEND_REPLAY_ANSWER, 0); if (libmt_write_type (net_data->channels_set, 0, &type) == -1) { player->ready = MT_PLAYER_READY_CLOSED; break; } if (libmt_channels_set_write (net_data->channels_set, 0, &(player->is_ok_to_play_again), sizeof (gint)) == -1) { player->ready = MT_PLAYER_READY_CLOSED; break; } player->ready = MT_PLAYER_READY_NO; break; case MT_PLAYER_READY_CLOSED: case MT_PLAYER_READY_NO: default: my_wait (WAIT_TIME); } } return (NULL); }