--- a/src/main.c Wed Feb 05 14:07:43 2014 +0100 +++ b/src/main.c Sun Feb 23 21:03:35 2014 +0100 @@ -29,26 +29,58 @@ #include "terminal-chess.h" #include <string.h> +#include <time.h> int get_settings(int argc, char **argv, Settings *settings) { char *valid; + unsigned long int time, port; + uint8_t timeunit = 60; + size_t len; - for (char opt ; (opt = getopt(argc, argv, "hp:")) != -1 ;) { + for (char opt ; (opt = getopt(argc, argv, "a:bhp:rt:")) != -1 ;) { switch (opt) { - case 'p': - if (strtol(optarg, &valid, 10) < 1025 || *valid != '\0') { - fprintf(stderr, - "Invalid port number (%s) - choose a number > 1024\n", - optarg); - return 1; + case 'b': + settings->gameinfo.servercolor = BLACK; + break; + case 'r': + settings->gameinfo.servercolor = (rand()>>5) & 1 ? WHITE : BLACK; + break; + case 't': + case 'a': + len = strlen(optarg); + if (optarg[len-1] == 's') { + optarg[len-1] = '\0'; + timeunit = 1; + } + + if ((time = strtoul(optarg, &valid, 10)) > TIME_MAX + || *valid != '\0') { + fprintf(stderr, "Specified time is invalid (%s)\n", optarg); + return 1; + } else { + if (opt=='t') { + settings->gameinfo.time = timeunit * time; } else { - settings->port = optarg; + settings->gameinfo.addtime = time; } - break; - case 'h': - case '?': - settings->printhelp = 1; - break; + } + break; + case 'p': + port = strtol(optarg, &valid, 10); + if (port < 1025 || port > 65535 || *valid != '\0') { + fprintf(stderr, + "Invalid port number (%s) - choose a number between " + "1025 and 65535\n", + optarg); + return 1; + } else { + settings->port = optarg; + } + break; + case 'h': + case '?': + settings->printhelp = 1; + break; } } @@ -65,10 +97,31 @@ Settings default_settings() { Settings settings; memset(&settings, 0, sizeof(Settings)); + settings.gameinfo.servercolor = WHITE; settings.port = "27015"; return settings; } +void dump_gameinfo(Gameinfo *gameinfo) { + int serverwhite = gameinfo->servercolor == WHITE; + printf( + "Game details:\n" + " Server plays %s - Client plays %s\n", + serverwhite?"white":"black", serverwhite?"black":"White" + ); + if (gameinfo->time > 0) { + if (gameinfo->time % 60) { + printf(" Time limit: %ds + %ds\n", + gameinfo->time, gameinfo->addtime); + } else { + printf(" Time limit: %dm + %ds\n", + gameinfo->time/60, gameinfo->addtime); + } + } else { + printf(" No time limit\n"); + } +} + int cleanup(Settings *settings, int exitcode) { if (settings->server) { if (net_destroy(settings->server)) { @@ -80,17 +133,32 @@ } int main(int argc, char **argv) { + srand(time(NULL)); Settings settings = default_settings(); - get_settings(argc, argv, &settings); + if (get_settings(argc, argv, &settings)) { + return 1; + } if (settings.printhelp) { printf( - "Usage: %s [OPTION]... [HOST]\n" - "Starts/joins a network chess game\n\n" + "Usage: terminal-chess [OPTION]... [HOST]\n" + "Starts/joins a network chess game\n" + "\nGeneral options\n" " -h This help page\n" - " -p TCP port to use (default: 27015)\n", - argv[0]); + " -p TCP port to use (default: 27015)\n" + "\nServer options\n" + " -a <time> Specifies the time to add after each move\n" + " -b Server plays black pieces (default: white)\n" + " -r Distribute color randomly\n" + " -t <time> Specifies time limit (default: no limit)\n" + "\nNotes\n" + "White pieces are displayed as uppercase and black pieces as " + "lowercase letters.\n" + "The time unit for -a is seconds and for -t minutes by default. To " + "specify\nseconds for the -t option, use the s suffix.\n" + "Example: -t 150s\n" + ); return EXIT_SUCCESS; } @@ -98,6 +166,22 @@ settings.server = &server; if (is_server(&settings)) { + dump_gameinfo(&(settings.gameinfo)); + printf("\nListening for client...\n"); + if (net_create(&server, settings.port)) { + perror("Server creation failed"); + return cleanup(&settings, EXIT_FAILURE); + } + + if (net_listen(&server)) { + perror("Listening for client failed"); + return cleanup(&settings, EXIT_FAILURE); + } + + printf("Client connected - transmitting gameinfo...\n"); + net_send(server.client->fd, NETCODE_GAMEINFO, + &(settings.gameinfo), sizeof(settings.gameinfo)); + } else { if (net_find(&server, settings.serverhost, settings.port)) { perror("Can't find server"); return cleanup(&settings, EXIT_FAILURE); @@ -107,15 +191,14 @@ perror("Can't connect to server"); return cleanup(&settings, EXIT_FAILURE); } - } else { - if (net_create(&server, settings.port)) { - perror("Server creation failed"); - return cleanup(&settings, EXIT_FAILURE); - } - - if (net_listen(&server)) { - perror("Listening for client failed"); - return cleanup(&settings, EXIT_FAILURE); + + printf("Connection established!\n\n"); + if (net_recieve_code(server.fd) == NETCODE_GAMEINFO) { + net_recieve_data(server.fd, &(settings.gameinfo), + sizeof(settings.gameinfo)); + dump_gameinfo(&(settings.gameinfo)); + } else { + fprintf(stderr, "Server sent invalid gameinfo.\n"); } }