Thu, 06 Mar 2014 15:03:06 +0100
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