diff options
-rw-r--r-- | client/Makefile | 7 | ||||
-rw-r--r-- | client/card_stack.c | 24 | ||||
-rw-r--r-- | client/card_stack.h | 3 | ||||
-rw-r--r-- | client/client.c | 24 | ||||
-rw-r--r-- | client/client.h | 3 | ||||
-rw-r--r-- | client/printing_game_frames.c | 36 | ||||
-rw-r--r-- | client/printing_game_frames.h | 5 | ||||
-rw-r--r-- | client/verification_client_input.c | 58 | ||||
-rw-r--r-- | server/Makefile | 5 | ||||
-rw-r--r-- | server/card_stack.c | 2 | ||||
-rw-r--r-- | server/card_stack.h | 2 | ||||
-rw-r--r-- | server/server.c | 29 | ||||
-rw-r--r-- | server/server.h | 3 | ||||
-rw-r--r-- | server/server_data_processing.c | 8 | ||||
-rw-r--r-- | server/server_data_processing.h | 1 |
15 files changed, 165 insertions, 45 deletions
diff --git a/client/Makefile b/client/Makefile index eeae6c6..48e0d92 100644 --- a/client/Makefile +++ b/client/Makefile @@ -2,7 +2,7 @@ SRCMODULES = card_handling.c card_stack.c data_decryption.c\ printing_game_frames.c verification_client_input.c client.c OBJMODULES = $(SRCMODULES:.c=.o) CC = gcc -CFLAGS = -Wall -g -c +CFLAGS = -Wall -g -c -D DEBUG all: client @@ -12,7 +12,12 @@ all: client client: $(OBJMODULES) $(CC) $(LIBS) $^ -o $@ +ifneq (clean, $(MAKECMDGOALS)) -include deps.mk +endif deps.mk: $(SRCMODULES) $(CC) -MM $^ > $@ + +clean: + rm -f *.o client diff --git a/client/card_stack.c b/client/card_stack.c index d9dc273..6f0a673 100644 --- a/client/card_stack.c +++ b/client/card_stack.c @@ -101,6 +101,15 @@ static void mark_all_card_stack(player_cards deck) } } +static void clear_is_usable_status(player_cards deck) +{ + while(deck) { + if(deck->is_usable) + deck->is_usable = 0; + deck = deck->next; + } +} + void mark_card_for_attackers_stack(player_cards deck) { char *card = NULL, *found_card; @@ -108,6 +117,7 @@ void mark_card_for_attackers_stack(player_cards deck) int target_rank, found_rank; player_cards tmp_begin_deck = deck; + clear_is_usable_status(deck); while(deck) { /* is the card already marked? */ if(deck->is_usable) { @@ -204,8 +214,8 @@ void mark_card_for_tossing_stack(player_cards deck, struct cards_on_table *cot) deck = deck->next; } } -/* rename: and_unmarked */ -char* card_search_by_letter(player_cards deck, int letter) + +char* card_search_by_marked_letter(player_cards deck, int letter) { while(deck) { if(deck->tip == letter && deck->is_usable) { @@ -216,3 +226,13 @@ char* card_search_by_letter(player_cards deck, int letter) } return NULL; } + +char* card_search_by_unmarked_letter(player_cards deck, int letter) +{ + while(deck) { + if(deck->tip == letter) + return deck->str; + deck = deck->next; + } + return NULL; +} diff --git a/client/card_stack.h b/client/card_stack.h index ba973f4..0daf40a 100644 --- a/client/card_stack.h +++ b/client/card_stack.h @@ -24,6 +24,7 @@ void mark_card_for_defenders_stack(player_cards deck, struct cards_on_table *cot, char* trump_suit); void mark_card_for_tossing_stack(player_cards deck, struct cards_on_table *cot); -char* card_search_by_letter(player_cards deck, int letter); +char* card_search_by_marked_letter(player_cards deck, int letter); +char* card_search_by_unmarked_letter(player_cards deck, int letter); #endif diff --git a/client/client.c b/client/client.c index a5b3daf..5d49e1a 100644 --- a/client/client.c +++ b/client/client.c @@ -24,10 +24,15 @@ static void get_data_from_server(struct client *cl, fd_set *readfds) 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 */ + if(!cl->data_left_in_buffer) + 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; @@ -69,6 +74,7 @@ static void get_data_from_server(struct client *cl, fd_set *readfds) break; /* no data to extract */ case tossing_limit_status: + case disconnect: default: {} } @@ -147,6 +153,9 @@ static void change_client_frame(struct client *cl) case result: pgf_game_result(cl->durak_position); break; + case disconnect: + pgf_disconnect(); + break; case none: {} } @@ -160,6 +169,11 @@ static void send_data_to_server(struct client *cl, fd_set *readfds) if(FD_ISSET(0, readfds)) { /* 0 - stdin */ read(0, cl->buffer, max_buffer_size); + if(cl->buffer[0] == 'q' && cl->buffer[1] == 'q') { + close(cl->fd); + exit(0); + } + switch(cl->state) { case confirmation_waiting: input_result = vci_confirmation_waiting(cl->fd, cl->buffer); @@ -274,8 +288,16 @@ int main() { struct client cl; + pgf_new_frame(); + pgf_welcome(); + sleep(2); init_client(&cl); - if(!connect_to_server(&cl)) + if(!connect_to_server(&cl)) { + pgf_new_frame(); + pgf_connection(0); return 1; + } + pgf_new_frame(); + pgf_connection(1); return main_loop(&cl); } diff --git a/client/client.h b/client/client.h index 1ff8f82..12ec619 100644 --- a/client/client.h +++ b/client/client.h @@ -25,7 +25,8 @@ enum client_states { card_acceptance_status, tossing_limit_status, spectator, - result + result, + disconnect }; enum spectator_mode { diff --git a/client/printing_game_frames.c b/client/printing_game_frames.c index 5c7deac..bda1208 100644 --- a/client/printing_game_frames.c +++ b/client/printing_game_frames.c @@ -11,6 +11,24 @@ void pgf_new_frame() printf("\n"); } +void pgf_welcome() +{ + printf("======================================================\n" + " Welcome!\n" + "You're playing siege durak/Podkidnoy (Throw-in) durak\n\n" + "If you have any questions, you can contact by email to\n" + " m@scratko.xyz\n" + "======================================================\n"); +} + +void pgf_connection(int status) +{ + if(status) + printf("Connection to the server has been successfully established\n"); + else + printf("Sorry, failed to connect to the server\n"); +} + void pgf_first_player() { printf("=======================================\n" @@ -23,7 +41,7 @@ void pgf_confirmation_waiting(int total_players) { printf("=======================================\n" " To start game press <Enter> key \n" - "Connected players: %u/8 \n" + " Connected players: %u/8 \n" "=======================================\n", total_players); } @@ -71,8 +89,7 @@ void pgf_suggestions(struct client *cl) struct card_stack_item *deck = NULL; if(cl->state == attack || cl->state == tossing) - printf("you can specify more than one card " - "(under certain conditions)\n"); + printf("you can specify more than one card\n"); deck = cl->deck; while(deck) { if(deck->is_usable) @@ -129,8 +146,13 @@ void pgf_spectator_mode(enum spectator_mode sp_mode) void pgf_game_result(int durak_position) { - printf("===============================\n" - " END OF GAME\n" - "player under number %u is durak\n" - "===============================\n", durak_position); + printf("=======================================\n" + " END OF GAME\n" + " player number %u is durak\n" + "=======================================\n", durak_position); +} + +void pgf_disconnect() +{ + printf("Server connection disconnected\n"); } diff --git a/client/printing_game_frames.h b/client/printing_game_frames.h index cd72932..9cbb231 100644 --- a/client/printing_game_frames.h +++ b/client/printing_game_frames.h @@ -3,6 +3,9 @@ #include "client.h" +void pgf_new_frame(); +void pgf_welcome(); +void pgf_connection(int status); void pgf_first_player(); void pgf_confirmation_waiting(int total_players); void pgf_table(struct client *cl); @@ -12,6 +15,6 @@ void pgf_card_acceptance_status(int all_input_cards_accepted); void pgf_tossing_limit_status(); void pgf_spectator_mode(enum spectator_mode sp_mode); void pgf_game_result(int durak_position); -void pgf_new_frame(); +void pgf_disconnect(); #endif diff --git a/client/verification_client_input.c b/client/verification_client_input.c index 1530387..171cd64 100644 --- a/client/verification_client_input.c +++ b/client/verification_client_input.c @@ -1,5 +1,6 @@ #include "verification_client_input.h" #include "card_handling.h" +#include "printing_game_frames.h" #include <stdio.h> #include <unistd.h> @@ -33,7 +34,7 @@ int vci_confirmation_waiting(int fd, char *buffer) int vci_attack_or_tossing(int fd, char *buffer, player_cards deck, enum client_states state) { - int i, free_pos = 0; + int rank = 0, i, free_pos = 0; char * card = NULL; if(state == tossing && buffer[0] == '\n') { /* cancel card tossing */ @@ -41,31 +42,45 @@ int vci_attack_or_tossing(int fd, char *buffer, player_cards deck, return 1; } - for(i = 0; buffer[i] != '\n'; ++i) - if((card = card_search_by_letter(deck, buffer[i])) != NULL) { -#if 0 - if(!rank) - rank = convert_rank_to_int(card); - if(rank == convert_rank_to_int(card)) { -#endif - strncpy(output_buffer + free_pos, card, strlen(card)); - free_pos += strlen(card); - output_buffer[free_pos] = '\\'; - ++free_pos; -#if 0 - } else { - printf("incorrect input\n"); - return 0; + for(i = 0; buffer[i] != '\n'; ++i) { + /* some symbols */ + if(state == attack && buffer[1] != '\n') { + card = card_search_by_marked_letter(deck, buffer[i]); + if(card) { + if(!rank) + rank = convert_rank_to_int(card); + if(rank != convert_rank_to_int(card)) { + printf("incorrect input\n> "); + fflush(stdout); + return 0; + } } -#endif - } else { - printf("incorrect input\n"); + /* one symbol inputed? */ + } else if(state == attack && buffer[1] == '\n') + card = card_search_by_unmarked_letter(deck, buffer[i]); + else if(state == tossing) + card = card_search_by_marked_letter(deck, buffer[i]); + + if(!card) { + printf("incorrect input\n> "); + fflush(stdout); return 0; } + strncpy(output_buffer + free_pos, card, strlen(card)); + free_pos += strlen(card); + output_buffer[free_pos] = '\\'; + ++free_pos; + } + if(state == attack && buffer[0] == '\n') { + printf("incorrect input\n> "); + fflush(stdout); + return 0; + } output_buffer[free_pos] = '\n'; write(fd, output_buffer, free_pos+1); return 1; } + /* * example: 5v'\n' * or: '\n' @@ -80,10 +95,11 @@ int vci_defense(int fd, char *buffer, player_cards deck) return 1; } if(buffer[1] != '\n') { - printf("incorrect input\n"); + printf("incorrect input\n> "); + fflush(stdout); return 0; } - if((card = card_search_by_letter(deck, buffer[0])) != NULL) { + if((card = card_search_by_marked_letter(deck, buffer[0])) != NULL) { strcpy(output_buffer, card); last_idx = strlen(card); output_buffer[last_idx] = '\n'; diff --git a/server/Makefile b/server/Makefile index 6fb2c5c..bdae4ff 100644 --- a/server/Makefile +++ b/server/Makefile @@ -11,7 +11,12 @@ all: server server: $(OBJMODULES) $(CC) $(LIBS) $^ -o $@ +ifneq (clean, $(MAKECMDGOALS)) -include deps.mk +endif deps.mk: $(SRCMODULES) $(CC) -MM $^ > $@ + +clean: + rm -f *.o server diff --git a/server/card_stack.c b/server/card_stack.c index c7c18d9..bce0133 100644 --- a/server/card_stack.c +++ b/server/card_stack.c @@ -59,7 +59,7 @@ const char* remove_card_from_stack(player_cards *deck, const char *str) return 0; } -const char* pop_stack(player_cards *deck) +void pop_stack(player_cards *deck) { struct card_stack_item *tmp; diff --git a/server/card_stack.h b/server/card_stack.h index 321cbf0..8581eec 100644 --- a/server/card_stack.h +++ b/server/card_stack.h @@ -17,6 +17,6 @@ const char* remove_card_from_stack(player_cards *deck, const char *str); struct card_stack_item* get_next_card_from_stack(player_cards deck, player_cards prev); int find_card_in_stack(player_cards involved_cards, const char *str); -const char* pop_stack(player_cards *deck); +void pop_stack(player_cards *deck); #endif diff --git a/server/server.c b/server/server.c index 1655448..f842a70 100644 --- a/server/server.c +++ b/server/server.c @@ -56,6 +56,18 @@ static int accept_client(struct server *serv) static void close_connection(struct server *serv) { + int i; + + for(i = 0; i < serv->max_sess_arr_size; ++i) { + if(!serv->sess_arr[i]) + continue; + serv->sess_arr[i]->state = disconnect; + send_disconnect_status(serv->sess_arr[i]->fd); + close(serv->sess_arr[i]->fd); + free(serv->sess_arr[i]); + serv->sess_arr[i] = NULL; + } + serv->connected_players_counter = 0; } static int check_playable_player_number(struct server *serv) @@ -76,6 +88,7 @@ static void init_new_game(struct server *serv) who_attack = -1; lowest_trump = 0; + serv->shuffled_deck_size = max_shuffled_deck_size; serv->shuffled_deck = get_shuffled_deck(); serv->trump_card = extract_trump_card(serv->shuffled_deck, &serv->shuffled_deck_size); @@ -609,11 +622,6 @@ static void set_up_player_tracking(struct server *serv, fd_set *readfds, switch(serv->state) { case first_player: - if(serv->sess_arr[i]->record) { - FD_SET(i, writefds); - *maxfd = i > *maxfd ? i : *maxfd; - } - break; case confirmation_waiting: FD_SET(i, readfds); *maxfd = i > *maxfd ? i : *maxfd; @@ -695,6 +703,9 @@ static void make_data_transfer(struct server *serv, fd_set *readfds, result = print_message_for_first_player(i); serv->sess_arr[i]->record = 0; } + /* connection was closed? (result == 0) */ + if(FD_ISSET(i, readfds)) + result = read(i, serv->sess_arr[i]->buffer, max_buffer_size); break; case confirmation_waiting: if(FD_ISSET(i, writefds) && serv->sess_arr[i]->record) { @@ -755,13 +766,17 @@ static void make_data_transfer(struct server *serv, fd_set *readfds, break; } } - if(serv->state == start_game || serv->state == table) + if(serv->state == start_game || serv->state == table || + serv->state == end_game) sleep(2); if(check_server_state_change_conditions(serv)) serv->change_server_state = 1; /* connection is closed */ - if(!result) + if(!result) { close_connection(serv); + serv->change_server_state = 0; + serv->state = no_players; + } } int main_loop(struct server *serv) diff --git a/server/server.h b/server/server.h index 3578606..5f7ffcc 100644 --- a/server/server.h +++ b/server/server.h @@ -42,7 +42,8 @@ enum client_game_states { card_acceptance_status, tossing_limit_status, spectator, - result + result, + disconnect }; enum tossing_mode { diff --git a/server/server_data_processing.c b/server/server_data_processing.c index fc81996..df95b7f 100644 --- a/server/server_data_processing.c +++ b/server/server_data_processing.c @@ -45,6 +45,14 @@ int print_connected_players(int fd, int number) return write_to_client(fd, data_size); } +int send_disconnect_status(int fd) +{ + int data_size; + + data_size = sprintf(output_buffer, "%u\n", disconnect); + return write_to_client(fd, data_size); +} + /* * 1 - ready * 0 - buffer overflow or player closed session diff --git a/server/server_data_processing.h b/server/server_data_processing.h index e6c1ab0..1aead51 100644 --- a/server/server_data_processing.h +++ b/server/server_data_processing.h @@ -5,6 +5,7 @@ int print_message_for_first_player(int fd); int print_connected_players(int fd, int number); +int send_disconnect_status(int fd); int check_readiness(struct session *client); /* for define spectator mode */ int print_game_part(const struct session *client, enum server_states ss, |