From a2d696dea797faaa3157046c8ae89cd70e965bff Mon Sep 17 00:00:00 2001 From: scratko Date: Sat, 10 Aug 2024 02:46:56 +0300 Subject: Prefinal version Added client. Moved files to directories. --- client/client.c | 245 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 245 insertions(+) create mode 100644 client/client.c (limited to 'client/client.c') diff --git a/client/client.c b/client/client.c new file mode 100644 index 0000000..d932a51 --- /dev/null +++ b/client/client.c @@ -0,0 +1,245 @@ +#include +#include +#include +#include +#include +#include + +#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 update_info = 0; + /* pointer to delimeter (:) that is behind extract data */ + char *end_p; + + if(FD_ISSET(cl->fd, readfds)) { + read(cl->fd, cl->buffer, max_buffer_size); + decrypt_set_state(cl, &end_p); + update_info = 1; + cl->display_new_frame = 1; + } + 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: + 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); + break; + case card_acceptance_status: + decrypt_set_card_acceptance_status(cl, cl->buffer); + break; + /* no data to extract */ + case tossing_limit_status: + default: + {} + } + } +} + +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); + + 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) { + 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 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; + default: + {} + } + cl->display_new_frame = 0; + } +} + +static void send_data_to_server(struct client *cl, fd_set *readfds) +{ + int input_result; + + 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); + + 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; +} + +/* + * 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); +} -- cgit v1.2.3