From 9113055ad34ed2a8fde93edbbeec9d389871da36 Mon Sep 17 00:00:00 2001 From: Andrej Bartulin Date: Fri, 25 Nov 2022 22:06:57 +0100 Subject: [PATCH] Networking pt. 3 --- README.md | 4 ++-- client/client | Bin 27808 -> 28072 bytes client/client.c | 24 ++++++++++++++++++++++-- src/Makefile | 2 +- src/executable/uno | Bin 148328 -> 148552 bytes src/gameplay.c | 11 +++-------- src/include/gameplay.h | 3 ++- src/include/runtime.h | 2 ++ src/main.c | 9 ++++++++- src/server.c | 24 +++++++++++++++++++++--- src/settings/default.json | 4 ++-- 11 files changed, 63 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 9de2c3d..81462a6 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ In short, this game mostly uses official Uno rules which you can find on link ab - [x] Basic AI (TODO: get rid of cards guesses) - [x] Colors - [x] Gameplay (most of gameplay) -- [ ] Networking +- [x] Networking (TODO: implement it fully) - [ ] Nice graphics - [x] Settings (in .json files) - [ ] Windows port (Win32 API) @@ -60,7 +60,7 @@ will load default config file) type in your terminal (emulator) `make run`. ``` [ { - "network_sequence": {[0 - disabled, 1 - enabled] per player}, + "network_sequence": {[0 - disabled, 1 - enabled] per player} // also see client.c on how to properly connect client to server, "ip": "127.0.0.1", // example "port": 5956 // example } diff --git a/client/client b/client/client index da4e0bd6e905a003c5cbb2250035b64e4c662c84..ea214bbbe7f60c0befa29fcce8732fe6c5a8c81b 100755 GIT binary patch delta 7176 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 F@V^huki7r^ delta 6469 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 diff --git a/client/client.c b/client/client.c index 16b1be2..b09a154 100644 --- a/client/client.c +++ b/client/client.c @@ -16,6 +16,8 @@ #include #include #include +#include +#include const char* logo_row1 = ".----------------. .-----------------. .----------------. .----------------. .----------------. \n"; const char* logo_row2 = "| .--------------. || .--------------. || .--------------. || .--------------. || .--------------. |\n"; @@ -57,6 +59,14 @@ void str_trim_lf(char *arr, int length) } } +/* Checks does one string starts with another string */ +bool StartsWith(const char *a, const char *b) +{ + if(strncmp(a, b, strlen(b)) == 0) return 1; + return 0; +} + + /* Catches Ctrl-C and exits; actually setting global variable named flag to 1 */ void catch_ctrl_c_and_exit(int sig) { @@ -125,15 +135,25 @@ int main(int argc, char **argv) return EXIT_SUCCESS; } - char *ip = "127.0.0.1"; + char ip[64]; int port = atoi(argv[1]); signal(SIGINT, catch_ctrl_c_and_exit); - printf("Please enter your name: "); + printf("Please IP address: "); + fgets(ip, 64, stdin); + str_trim_lf(ip, strlen(ip)); + + printf("Please enter your name (Player + space + position in network sequence): "); fgets(name, 32, stdin); str_trim_lf(name, strlen(name)); + if (!StartsWith(name, "Player ")) + { + printf("Your name cannot be accepted!\n"); + return EXIT_SUCCESS; + } + if (strlen(name) > 32 || strlen(name) < 2) { printf("Name must be less than 30 and more than 2 characters.\n"); diff --git a/src/Makefile b/src/Makefile index 948bf3a..19212da 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,5 +1,5 @@ CC = gcc -CFLAGS = -Wall -Wextra -Werror -pedantic -g -ljson-c +CFLAGS = -Wall -Wextra -Werror -pedantic -g -lm -ljson-c OBJDIR = objects OBJS = $(addprefix $(OBJDIR)/, $(patsubst %.c, %.o, $(wildcard *.c))) diff --git a/src/executable/uno b/src/executable/uno index 5fde28559c6ad734e4ae5534e28ef100a886107c..2b80de8f381bebae93294f727165a87778ab6134 100755 GIT binary patch delta 34436 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 a-q*RNlSJh6MiirV7Rcff_%uLo^?v{?ozM3G diff --git a/src/gameplay.c b/src/gameplay.c index 5c4d7e9..c69eec1 100644 --- a/src/gameplay.c +++ b/src/gameplay.c @@ -1089,12 +1089,12 @@ void PointsManager(Player player[], Settings* settings, Points* points, int play /** * Entry point for gameplay mechanics, calls all other functions in gameplay.h and gameplay.c. + * @param runtime - struct for holding information during the game, points to runtime_T * @param settings - struct which contains information about settings, points to setting_T * @param points - struct for holding information about points, points to points_T * @param theme - struct for holding graphics (theme releated stuff mostly) informations during runtime, points to theme_t - * @param network - struct which holds all informations on network, points to network_T */ -void Gameplay(Settings* settings, Points* points, Theme* theme) +void Gameplay(Runtime* runtime, Settings* settings, Points* points, Theme* theme) { char tmp_input[20]; time_t t; @@ -1103,11 +1103,6 @@ void Gameplay(Settings* settings, Points* points, Theme* theme) Player player[players]; Stacking* stacking = malloc(sizeof(Stacking)); - Runtime* runtime = malloc(sizeof(Runtime)); - - runtime->current_card_id = 0; - runtime->player_turn = 0; - runtime->isPositive = true; srand((unsigned) time(&t)); cvector_vector_type(Cards) cards = GenerateDeck(runtime, settings); @@ -1239,7 +1234,7 @@ void Gameplay(Settings* settings, Points* points, Theme* theme) else if (runtime->player_turn != 0 && settings->network_sequence[runtime->player_turn] == '1') { - printf("Network is WIP (Work in progress)!!\n\n"); + printf("Network is not yet implemented fully!!\n\n"); NextPlayer(runtime, settings, false); goto again; } diff --git a/src/include/gameplay.h b/src/include/gameplay.h index a3247ec..54dc6b6 100644 --- a/src/include/gameplay.h +++ b/src/include/gameplay.h @@ -136,9 +136,10 @@ void PointsManager(Player player[], Settings* settings, Points* points, int play /** * Entry point for gameplay mechanics, calls all other functions in gameplay.h and gameplay.c. + * @param runtime - struct for holding information during the game, points to runtime_T * @param settings - struct which contains information about settings, points to setting_T * @param points - struct for holding information about points, points to points_T * @param theme - struct for holding graphics (theme releated stuff mostly) informations during runtime, points to theme_T * @param network - struct which holds all informations on network, points to network_T */ -void Gameplay(Settings* settings, Points* points, Theme* theme); +void Gameplay(Runtime* runtime, Settings* settings, Points* points, Theme* theme); diff --git a/src/include/runtime.h b/src/include/runtime.h index e6ee03f..faf23fd 100644 --- a/src/include/runtime.h +++ b/src/include/runtime.h @@ -132,8 +132,10 @@ typedef struct network_T /** * Struct which holds all information which will be passed to server when server is created + * @param runtime - struct for holding information during the game, points to runtime_T * @param network - struct which holds all informations on network, points to network_T */ typedef struct { + Runtime* runtime; Network* network; } Arg; diff --git a/src/main.c b/src/main.c index 46017a9..4c26967 100644 --- a/src/main.c +++ b/src/main.c @@ -94,6 +94,12 @@ int main(int argc, const char** argv) free(temp); } + Runtime* runtime = malloc(sizeof(Runtime)); + + runtime->current_card_id = 0; + runtime->player_turn = 0; + runtime->isPositive = true; + Settings *settings = malloc(sizeof(Settings)); Points *points = malloc(sizeof(Points)); Theme *theme = malloc(sizeof(Theme)); @@ -105,11 +111,12 @@ int main(int argc, const char** argv) { Arg *arg = malloc(sizeof(Arg)); + arg->runtime = runtime; arg->network = network; RunServer(arg); } - Gameplay(settings, points, theme); + Gameplay(runtime, settings, points, theme); /* Frees structs */ free(settings); diff --git a/src/server.c b/src/server.c index 95971a3..5741b30 100644 --- a/src/server.c +++ b/src/server.c @@ -8,6 +8,7 @@ #include "include/server.h" +#include #include static _Atomic unsigned int cli_count = 0; @@ -19,6 +20,7 @@ static pthread_mutex_t clients_mutex = PTHREAD_MUTEX_INITIALIZER; typedef struct { client_t* cli; + Runtime* runtime; Network* network; } Arg2; @@ -225,15 +227,29 @@ void *handle_client(void *arg) str_trim_lf(buff_out, strlen(buff_out)); printf("%s\n", buff_out); - const char* sub = malloc(sizeof(char) * 1024); + const char* sub = malloc(sizeof(char) + strlen(cli->name) + 3); strcat(sub, cli->name); strcat(sub, ": "); - const char* buffer = malloc(sizeof(char) * 1024); + const char* buffer = malloc(strlen(strremove(buff_out, sub))); strcpy(buffer, strremove(buff_out, sub)); printf("%s\n", buffer); free(sub); + + int digits = (actual_arg_2->runtime->player_turn == 0) ? 1 : (log10(actual_arg_2->runtime->player_turn) + 1); + printf("Digits: %d\n", digits); + + if (strrchr(cli->name, '\0') - digits == actual_arg_2->runtime->player_turn) + { + printf("Your turn!\n"); + } + + else + { + printf("Not your turn!\n%d | %d\n", actual_arg_2->runtime->player_turn, strrchr(cli->name, '\0') - digits); + } + free(buffer); } } @@ -333,7 +349,9 @@ void* StartServer(void* arg) Arg2* arg2 = malloc(sizeof(Arg2)); arg2->cli = cli; - arg2->network; + arg2->network = actual_arg->network; + + arg2->runtime = actual_arg->runtime; /* Add client to the queue and fork thread */ queue_add(cli); diff --git a/src/settings/default.json b/src/settings/default.json index 3967adc..0ce7644 100644 --- a/src/settings/default.json +++ b/src/settings/default.json @@ -3,7 +3,7 @@ "points_path": "settings/.points.txt", "debug_mode": 0, "colors": 1, - "players": 3, + "players": 2, "special": [{ "swap_card": 1, "stacking": 1, @@ -11,7 +11,7 @@ }], "ai_sequence": "00", "network": [{ - "network_sequence": "01", + "network_sequence": "00", "ip": "127.0.0.1", "port": 5956 }]