back to scratko.xyz
aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorscratko <m@scratko.xyz>2024-08-17 02:42:19 +0300
committerscratko <m@scratko.xyz>2024-08-17 02:42:19 +0300
commit4b2fdc91d42a438193d15840e10851c3847fbe80 (patch)
tree08c3de6e851ee07463beae6d0a2fbd9e74202662
parenteb90648bdad1443c9cfc72e903a93642e10a0ab7 (diff)
downloaddurak-4b2fdc91d42a438193d15840e10851c3847fbe80.tar.gz
durak-4b2fdc91d42a438193d15840e10851c3847fbe80.tar.bz2
durak-4b2fdc91d42a438193d15840e10851c3847fbe80.zip
Global fixes v3.0
Fixed bug when entering cards incorrectly. Added recognition of disconnection from the server. Added welcome screen and update screen.
-rw-r--r--client/Makefile7
-rw-r--r--client/card_stack.c24
-rw-r--r--client/card_stack.h3
-rw-r--r--client/client.c24
-rw-r--r--client/client.h3
-rw-r--r--client/printing_game_frames.c36
-rw-r--r--client/printing_game_frames.h5
-rw-r--r--client/verification_client_input.c58
-rw-r--r--server/Makefile5
-rw-r--r--server/card_stack.c2
-rw-r--r--server/card_stack.h2
-rw-r--r--server/server.c29
-rw-r--r--server/server.h3
-rw-r--r--server/server_data_processing.c8
-rw-r--r--server/server_data_processing.h1
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,