back to scratko.xyz
aboutsummaryrefslogtreecommitdiff
path: root/client/client.c
diff options
context:
space:
mode:
authorscratko <m@scratko.xyz>2024-08-10 02:46:56 +0300
committerscratko <m@scratko.xyz>2024-08-10 02:46:56 +0300
commita2d696dea797faaa3157046c8ae89cd70e965bff (patch)
tree74051e828ec401f399b2316a535c200f3afa95c5 /client/client.c
parent9e9919b897b00ff23aee6581471b4d7b4567bf4a (diff)
downloaddurak-a2d696dea797faaa3157046c8ae89cd70e965bff.tar.gz
durak-a2d696dea797faaa3157046c8ae89cd70e965bff.tar.bz2
durak-a2d696dea797faaa3157046c8ae89cd70e965bff.zip
Prefinal version
Added client. Moved files to directories.
Diffstat (limited to 'client/client.c')
-rw-r--r--client/client.c245
1 files changed, 245 insertions, 0 deletions
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 <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+
+#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);
+}