changed UI to ncurses session + added network handshake

Thu, 06 Mar 2014 15:03:06 +0100

author
Mike Becker <universe@uap-core.de>
date
Thu, 06 Mar 2014 15:03:06 +0100
changeset 3
3693fd2eb0e9
parent 2
0a08f79c320d
child 4
560e07f7a6a1

changed UI to ncurses session + added network handshake

conf.mk file | annotate | diff | comparison | revisions
src/Makefile file | annotate | diff | comparison | revisions
src/input.c file | annotate | diff | comparison | revisions
src/input.h file | annotate | diff | comparison | revisions
src/main.c file | annotate | diff | comparison | revisions
src/network.c file | annotate | diff | comparison | revisions
src/network.h file | annotate | diff | comparison | revisions
     1.1 --- a/conf.mk	Sun Feb 23 21:03:35 2014 +0100
     1.2 +++ b/conf.mk	Thu Mar 06 15:03:06 2014 +0100
     1.3 @@ -35,5 +35,5 @@
     1.4  CC      = gcc
     1.5  CFLAGS  = -g -O2 -std=gnu99 -Wall -Werror -pedantic
     1.6  LD      = gcc
     1.7 -LDFLAGS =
     1.8 +LDFLAGS = -lncurses
     1.9  OBJ_EXT = .o
     2.1 --- a/src/Makefile	Sun Feb 23 21:03:35 2014 +0100
     2.2 +++ b/src/Makefile	Thu Mar 06 15:03:06 2014 +0100
     2.3 @@ -30,6 +30,7 @@
     2.4  
     2.5  SRC  = main.c
     2.6  SRC += network.c
     2.7 +SRC += input.c
     2.8  
     2.9  OBJ = $(SRC:%.c=../build/%$(OBJ_EXT))
    2.10  
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/src/input.c	Thu Mar 06 15:03:06 2014 +0100
     3.3 @@ -0,0 +1,42 @@
     3.4 +/*
     3.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     3.6 + *
     3.7 + * Copyright 2014 Mike Becker. All rights reserved.
     3.8 + *
     3.9 + * Redistribution and use in source and binary forms, with or without
    3.10 + * modification, are permitted provided that the following conditions are met:
    3.11 + *
    3.12 + *   1. Redistributions of source code must retain the above copyright
    3.13 + *      notice, this list of conditions and the following disclaimer.
    3.14 + *
    3.15 + *   2. Redistributions in binary form must reproduce the above copyright
    3.16 + *      notice, this list of conditions and the following disclaimer in the
    3.17 + *      documentation and/or other materials provided with the distribution.
    3.18 + *
    3.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    3.20 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    3.21 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    3.22 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
    3.23 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    3.24 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    3.25 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    3.26 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    3.27 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    3.28 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    3.29 + * POSSIBILITY OF SUCH DAMAGE.
    3.30 + *
    3.31 + */
    3.32 +
    3.33 +#include "input.h"
    3.34 +#include <ncurses.h>
    3.35 +
    3.36 +int prompt_yesno() {
    3.37 +    noecho();
    3.38 +    int ch;
    3.39 +    do {
    3.40 +        ch = getch();
    3.41 +    } while (ch != 'y' && ch != 'n');
    3.42 +    echo();
    3.43 +    
    3.44 +    return ch == 'y';
    3.45 +}
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/src/input.h	Thu Mar 06 15:03:06 2014 +0100
     4.3 @@ -0,0 +1,45 @@
     4.4 +/*
     4.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     4.6 + *
     4.7 + * Copyright 2014 Mike Becker. All rights reserved.
     4.8 + *
     4.9 + * Redistribution and use in source and binary forms, with or without
    4.10 + * modification, are permitted provided that the following conditions are met:
    4.11 + *
    4.12 + *   1. Redistributions of source code must retain the above copyright
    4.13 + *      notice, this list of conditions and the following disclaimer.
    4.14 + *
    4.15 + *   2. Redistributions in binary form must reproduce the above copyright
    4.16 + *      notice, this list of conditions and the following disclaimer in the
    4.17 + *      documentation and/or other materials provided with the distribution.
    4.18 + *
    4.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    4.20 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    4.21 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    4.22 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
    4.23 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    4.24 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    4.25 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    4.26 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    4.27 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    4.28 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    4.29 + * POSSIBILITY OF SUCH DAMAGE.
    4.30 + *
    4.31 + */
    4.32 +
    4.33 +#ifndef INPUT_H
    4.34 +#define	INPUT_H
    4.35 +
    4.36 +#ifdef	__cplusplus
    4.37 +extern "C" {
    4.38 +#endif
    4.39 +
    4.40 +int prompt_yesno();
    4.41 +
    4.42 +
    4.43 +#ifdef	__cplusplus
    4.44 +}
    4.45 +#endif
    4.46 +
    4.47 +#endif	/* INPUT_H */
    4.48 +
     5.1 --- a/src/main.c	Sun Feb 23 21:03:35 2014 +0100
     5.2 +++ b/src/main.c	Thu Mar 06 15:03:06 2014 +0100
     5.3 @@ -30,6 +30,8 @@
     5.4  #include "terminal-chess.h"
     5.5  #include <string.h>
     5.6  #include <time.h>
     5.7 +#include <ncurses.h>
     5.8 +#include "input.h"
     5.9  
    5.10  int get_settings(int argc, char **argv, Settings *settings) {
    5.11      char *valid;
    5.12 @@ -104,25 +106,28 @@
    5.13  
    5.14  void dump_gameinfo(Gameinfo *gameinfo) {
    5.15      int serverwhite = gameinfo->servercolor == WHITE;
    5.16 -    printf(
    5.17 -        "Game details:\n"
    5.18 -        "  Server plays %s  -  Client plays %s\n",
    5.19 +    attron(A_UNDERLINE);
    5.20 +    printw("Game details\n");
    5.21 +    attroff(A_UNDERLINE);
    5.22 +    printw("  Server:     %s\n  Client:     %s\n",
    5.23          serverwhite?"white":"black", serverwhite?"black":"White"
    5.24      );
    5.25      if (gameinfo->time > 0) {
    5.26          if (gameinfo->time % 60) {
    5.27 -            printf("  Time limit: %ds + %ds\n",
    5.28 +            printw("  Time limit: %ds + %ds\n",
    5.29                  gameinfo->time, gameinfo->addtime);
    5.30          } else {
    5.31 -            printf("  Time limit: %dm + %ds\n",
    5.32 +            printw("  Time limit: %dm + %ds\n",
    5.33                  gameinfo->time/60, gameinfo->addtime);
    5.34          }
    5.35      } else {
    5.36 -        printf("  No time limit\n");
    5.37 +        printw("  No time limit\n");
    5.38      }
    5.39 +    refresh();
    5.40  }
    5.41  
    5.42  int cleanup(Settings *settings, int exitcode) {
    5.43 +
    5.44      if (settings->server) {
    5.45          if (net_destroy(settings->server)) {
    5.46              perror("Server shutdown failed");
    5.47 @@ -162,12 +167,17 @@
    5.48          return EXIT_SUCCESS;
    5.49      }
    5.50      
    5.51 +    initscr();
    5.52 +    cbreak();
    5.53 +    atexit((void(*)(void)) endwin);
    5.54 +    
    5.55      Server server;
    5.56      settings.server = &server;
    5.57      
    5.58      if (is_server(&settings)) {
    5.59          dump_gameinfo(&(settings.gameinfo));
    5.60 -        printf("\nListening for client...\n");
    5.61 +        printw("\nListening for client...\n");
    5.62 +        refresh();
    5.63          if (net_create(&server, settings.port)) {
    5.64              perror("Server creation failed");
    5.65              return cleanup(&settings, EXIT_FAILURE);
    5.66 @@ -178,12 +188,36 @@
    5.67              return cleanup(&settings, EXIT_FAILURE);
    5.68          }
    5.69          
    5.70 -        printf("Client connected - transmitting gameinfo...\n");
    5.71 -        net_send(server.client->fd, NETCODE_GAMEINFO,
    5.72 -            &(settings.gameinfo), sizeof(settings.gameinfo));
    5.73 +        /* net version handshake */
    5.74 +        int fd = server.client->fd;
    5.75 +        net_send_code(fd, NETCODE_VERSION);
    5.76 +        if (net_recieve_code(fd) != NETCODE_VERSION) {
    5.77 +            fprintf(stderr, "Client uses an incompatible software version.\n");
    5.78 +            return cleanup(&settings, EXIT_FAILURE);
    5.79 +        }
    5.80 +        
    5.81 +        printw("Client connected - transmitting gameinfo...");
    5.82 +        refresh();
    5.83 +        
    5.84 +        
    5.85 +        net_send_code(fd, NETCODE_GAMEINFO);
    5.86 +        net_send_data(fd, &(settings.gameinfo), sizeof(settings.gameinfo));
    5.87 +        printw("\rClient connected - awaiting challenge acceptance...");
    5.88 +        refresh();
    5.89 +        int code = net_recieve_code(fd);
    5.90 +        if (code == NETCODE_ACCEPT) {
    5.91 +            printw("\rClient connected - challenge accepted.");
    5.92 +            clrtoeol();
    5.93 +        } else if (code == NETCODE_DECLINE) {
    5.94 +            printw("\rClient connected - challenge declined.");
    5.95 +            clrtoeol();
    5.96 +        } else {
    5.97 +            fprintf(stderr, "Invalid client response\n");
    5.98 +            return cleanup(&settings, EXIT_FAILURE);
    5.99 +        }
   5.100      } else {
   5.101          if (net_find(&server, settings.serverhost, settings.port)) {
   5.102 -            perror("Can't find server");
   5.103 +            fprintf(stderr, "Can't find server\n");
   5.104              return cleanup(&settings, EXIT_FAILURE);
   5.105          }
   5.106          
   5.107 @@ -191,17 +225,35 @@
   5.108              perror("Can't connect to server");
   5.109              return cleanup(&settings, EXIT_FAILURE);
   5.110          }
   5.111 +        
   5.112 +        int fd = server.fd;
   5.113 +        if (net_recieve_code(fd) != NETCODE_VERSION) {
   5.114 +            fprintf(stderr, "Server uses an incompatible software version.\n");
   5.115 +            return cleanup(&settings, EXIT_FAILURE);
   5.116 +        } else {
   5.117 +            net_send_code(fd, NETCODE_VERSION);
   5.118 +        }
   5.119  
   5.120 -        printf("Connection established!\n\n");
   5.121 -        if (net_recieve_code(server.fd) == NETCODE_GAMEINFO) {
   5.122 -            net_recieve_data(server.fd, &(settings.gameinfo),
   5.123 +        printw("Connection established!\n\n");
   5.124 +        refresh();
   5.125 +        
   5.126 +        if (net_recieve_code(fd) == NETCODE_GAMEINFO) {
   5.127 +            net_recieve_data(fd, &(settings.gameinfo),
   5.128                  sizeof(settings.gameinfo));
   5.129              dump_gameinfo(&(settings.gameinfo));
   5.130 +            printw("Accept challenge (y/n)? ");
   5.131 +            if (prompt_yesno()) {
   5.132 +                net_send_code(fd, NETCODE_ACCEPT);
   5.133 +                // TODO: start game
   5.134 +            } else {
   5.135 +                net_send_code(fd, NETCODE_DECLINE);
   5.136 +            }
   5.137          } else {
   5.138              fprintf(stderr, "Server sent invalid gameinfo.\n");
   5.139          }
   5.140      }
   5.141      
   5.142 +    getch(); /* TODO: remove */
   5.143      return cleanup(&settings, EXIT_SUCCESS);
   5.144  }
   5.145  
     6.1 --- a/src/network.c	Sun Feb 23 21:03:35 2014 +0100
     6.2 +++ b/src/network.c	Thu Mar 06 15:03:06 2014 +0100
     6.3 @@ -113,9 +113,12 @@
     6.4      return EXIT_SUCCESS;
     6.5  }
     6.6  
     6.7 -void net_send(int socket, uint32_t code, void *data, size_t len) {
     6.8 +void net_send_code(int socket, uint32_t code) {
     6.9      code = htonl(code);
    6.10      send(socket, &code, sizeof(uint32_t), 0);
    6.11 +}
    6.12 +
    6.13 +void net_send_data(int socket, void *data, size_t len) {
    6.14      send(socket, data, len, 0);
    6.15  }
    6.16  
     7.1 --- a/src/network.h	Sun Feb 23 21:03:35 2014 +0100
     7.2 +++ b/src/network.h	Thu Mar 06 15:03:06 2014 +0100
     7.3 @@ -37,7 +37,11 @@
     7.4  extern "C" {
     7.5  #endif
     7.6      
     7.7 -#define NETCODE_GAMEINFO 1
     7.8 +#define NETCODE_ACCEPT 0x00
     7.9 +#define NETCODE_DECLINE 0x01
    7.10 +#define NETCODE_GAMEINFO 0x10
    7.11 +    
    7.12 +#define NETCODE_VERSION 1
    7.13  
    7.14  typedef struct {
    7.15      int fd; /* -1, if we are the client */
    7.16 @@ -58,7 +62,8 @@
    7.17  int net_destroy(Server *server);
    7.18  int net_connect(Server *server);
    7.19  
    7.20 -void net_send(int socket, uint32_t code, void *data, size_t len);
    7.21 +void net_send_code(int socket, uint32_t code);
    7.22 +void net_send_data(int socket, void *data, size_t len);
    7.23  int net_recieve_code(int socket);
    7.24  void net_recieve_data(int socket, void *data, size_t len);
    7.25  

mercurial