#include #include #include #include #include #include #include /* test */ #include "client.h" #include "data_decryption.h" #include "printing_game_frames.h" #include "verification_client_input.h" static const char *ip = "127.0.0.1"; static const int port = 8082; static void get_data_from_server(struct client *cl, fd_set *readfds) { int i; int update_info = 0; /* pointer to delimeter (:) that is behind extract data */ char *end_p; if(FD_ISSET(cl->fd, readfds)) { if(!cl->data_left_in_buffer) { cl->data_left_in_buffer = read(cl->fd, cl->buffer, max_buffer_size); printf("%d\n", cl->data_left_in_buffer); for(i = 0; i < cl->data_left_in_buffer; ++i) putchar(cl->buffer[i]); putchar('\n'); } decrypt_set_state(cl, &end_p); update_info = 1; cl->display_new_frame = 1; cl->pending_server_response = 0; } if(update_info) { switch(cl->state) { case first_player: break; case confirmation_waiting: cl->total_players = decrypt_get_number(end_p+1, &end_p); break; case display_only_table: case attack: case defense: case tossing_expectation: case tossing: /* last arg will contain pointer to '\n' */ decrypt_set_base_info(cl, end_p+1, &end_p); break; case attack_expectation: decrypt_set_base_info(cl, end_p+1, &end_p); decrypt_set_position_whose_turn(cl, end_p+1, &end_p); break; case defense_expectation: case spectator: decrypt_set_base_info(cl, end_p+1, &end_p); decrypt_set_position_whose_turn(cl, end_p+1, &end_p); decrypt_set_card_queue(cl, end_p+1, &end_p); if(cl->state == spectator) decrypt_set_spectator_mode(cl, end_p+1); break; case card_acceptance_status: decrypt_set_card_acceptance_status(cl, end_p+1); break; case result: decrypt_set_durak_position(cl, end_p+1); break; /* no data to extract */ case tossing_limit_status: default: {} } for(i = 0; cl->buffer[i] != '\n'; ++i) {} if((cl->buffer+i - cl->buffer + 1) != cl->data_left_in_buffer) { cl->data_left_in_buffer -= i + 1; memmove(cl->buffer, cl->buffer+i+1, cl->data_left_in_buffer); } else cl->data_left_in_buffer = 0; } } static void prepare_tips_for_client(struct client *cl) { char *trump_suit = NULL; if(!is_empty_stack(cl->deck)) add_hint_letters_stack(cl->deck); /* TODO: clear marked cards ??? */ switch(cl->state) { case attack: mark_card_for_attackers_stack(cl->deck); break; case defense: trump_suit = cl->trump_card + strlen(cl->trump_card) - 1; mark_card_for_defenders_stack(cl->deck, &cl->cot, trump_suit); break; case tossing: mark_card_for_tossing_stack(cl->deck, &cl->cot); break; default: {} } } static void change_client_frame(struct client *cl) { if(cl->display_new_frame) { pgf_new_frame(); switch(cl->state) { case first_player: pgf_first_player(); break; case confirmation_waiting: pgf_confirmation_waiting(cl->total_players); break; case display_only_table: case attack_expectation: case defense_expectation: case tossing_expectation: pgf_table(cl); if(cl->state == attack_expectation || cl->state == defense_expectation || cl->state == tossing_expectation) { pgf_select_idle_mode_message(cl->state); } break; case spectator: pgf_table(cl); pgf_spectator_mode(cl->sp_mode); break; case attack: case defense: case tossing: pgf_table(cl); pgf_suggestions(cl); break; case card_acceptance_status: pgf_card_acceptance_status(cl->all_input_cards_accepted); break; case tossing_limit_status: pgf_tossing_limit_status(); break; case result: pgf_game_result(cl->durak_position); break; case none: {} } cl->display_new_frame = 0; } } static void send_data_to_server(struct client *cl, fd_set *readfds) { int input_result = 0; if(FD_ISSET(0, readfds)) { /* 0 - stdin */ read(0, cl->buffer, max_buffer_size); switch(cl->state) { case confirmation_waiting: input_result = vci_confirmation_waiting(cl->fd, cl->buffer); break; case attack: case tossing: input_result = vci_attack_or_tossing(cl->fd, cl->buffer, cl->deck, cl->state); break; case defense: input_result = vci_defense(cl->fd, cl->buffer, cl->deck); break; default: {} } /* if 0, then re-tracking the input client */ if(input_result) cl->pending_server_response = 1; } } static int check_tracking_client_input(enum client_states state, int pending_server_response) { if(pending_server_response) return 0; switch(state) { case confirmation_waiting: case attack: case defense: case tossing: return 1; default: return 0; } return 0; } int main_loop(struct client *cl) { int select_result; fd_set readfds; for(;;) { FD_ZERO(&readfds); FD_SET(cl->fd, &readfds); if(check_tracking_client_input(cl->state, cl->pending_server_response)) FD_SET(0, &readfds); if(!cl->data_left_in_buffer) { select_result = select(cl->fd + 1, &readfds, NULL, NULL, NULL); if(select_result == -1) return 2; } get_data_from_server(cl, &readfds); prepare_tips_for_client(cl); if(cl->display_new_frame) change_client_frame(cl); send_data_to_server(cl, &readfds); } } static void init_client(struct client *cl) { cl->fd = -1; cl->state = none; cl->total_players = 0; cl->total_cards_left = 0; cl->player_position = 0; cl->cc.number_arr = NULL; #if 0 cl->cc.number_arr_idx = -1; #endif cl->cot.card_arr_idx = -1; cl->deck = NULL; cl->pending_server_response = 0; cl->cq.card_arr_idx = -1; cl->position_whose_turn = 0; cl->display_new_frame = 0; cl->all_input_cards_accepted = 0; cl->data_left_in_buffer = 0; cl->sp_mode = spectator_table; cl->durak_position = 0; } /* * 0 - failure * 1 - success */ static int connect_to_server(struct client *cl) { int connect_result; struct sockaddr_in addr; cl->fd = socket(AF_INET, SOCK_STREAM, 0); if(cl->fd == -1) return 0; addr.sin_family = AF_INET; addr.sin_addr.s_addr = inet_addr(ip); addr.sin_port = htons(port); connect_result = connect(cl->fd, (struct sockaddr*) &addr, sizeof(addr)); if(connect_result == -1) return 0; return 1; } int main() { struct client cl; init_client(&cl); if(!connect_to_server(&cl)) return 1; return main_loop(&cl); }