From 831f9f01fbe4088eb6bd378c0e417d9996b676fd Mon Sep 17 00:00:00 2001 From: scratko Date: Fri, 30 Aug 2024 12:46:56 +0300 Subject: Final version v2.0 Added windows client. SIGPIPE signal was being sent to the server when the client was disconnected. Now there is handling of this signal. Added a delay when displaying some informational messages. --- client/client.c | 322 -------------------------------------------------------- 1 file changed, 322 deletions(-) delete mode 100644 client/client.c (limited to 'client/client.c') diff --git a/client/client.c b/client/client.c deleted file mode 100644 index 20279d8..0000000 --- a/client/client.c +++ /dev/null @@ -1,322 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include /* for debug */ - -#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 = 1025; - -static void clean_up_resources(struct client *cl) -{ - free(cl->cc.number_arr); - clear_stack(&cl->deck); -} - -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); - /* end of file -- closed connection (from server) */ - if(!cl->data_left_in_buffer) { - clean_up_resources(cl); - exit(0); - } -#ifdef DEBUG - printf("%d\n", cl->data_left_in_buffer); - for(i = 0; i < cl->data_left_in_buffer; ++i) - putchar(cl->buffer[i]); - putchar('\n'); -#endif - } - 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 tossing_expectation: - case tossing: - /* last arg will contain pointer to '\n' */ - decrypt_set_base_info(cl, end_p+1, &end_p); - break; - case attack: - case defense: - 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: - case disconnect: - 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 disconnect: - pgf_disconnect(); - break; - case none: - {} - } - cl->display_new_frame = 0; - } -} - -static int check_users_exit(enum client_states state, const char *buffer, - int size) -{ - if((state == first_player || state == confirmation_waiting) && - size == 2 && (buffer[0] == 'q' && buffer[1] == '\n')) - return 1; - - return size == 3 && !strncmp(buffer, "qq", 2) && buffer[2] == '\n'; -} - -static void send_data_to_server(struct client *cl, fd_set *readfds) -{ - int input_result = 0, data_size; - - if(FD_ISSET(0, readfds)) { /* 0 - stdin */ - data_size = read(0, cl->buffer, max_buffer_size); - if(check_users_exit(cl->state, cl->buffer, data_size)) { - close(cl->fd); - clean_up_resources(cl); - pgf_disconnect(); - exit(0); - } - - 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 first_player: - 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; - cl->cc.number_arr_idx = -1; - 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; - - pgf_new_frame(); - pgf_welcome(); - sleep(2); - init_client(&cl); - if(!connect_to_server(&cl)) { - pgf_new_frame(); - pgf_connection(0); - return 1; - } - pgf_new_frame(); - pgf_connection(1); - return main_loop(&cl); -} -- cgit v1.2.3