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
--- a/conf.mk	Sun Feb 23 21:03:35 2014 +0100
+++ b/conf.mk	Thu Mar 06 15:03:06 2014 +0100
@@ -35,5 +35,5 @@
 CC      = gcc
 CFLAGS  = -g -O2 -std=gnu99 -Wall -Werror -pedantic
 LD      = gcc
-LDFLAGS =
+LDFLAGS = -lncurses
 OBJ_EXT = .o
--- a/src/Makefile	Sun Feb 23 21:03:35 2014 +0100
+++ b/src/Makefile	Thu Mar 06 15:03:06 2014 +0100
@@ -30,6 +30,7 @@
 
 SRC  = main.c
 SRC += network.c
+SRC += input.c
 
 OBJ = $(SRC:%.c=../build/%$(OBJ_EXT))
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/input.c	Thu Mar 06 15:03:06 2014 +0100
@@ -0,0 +1,42 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2014 Mike Becker. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "input.h"
+#include <ncurses.h>
+
+int prompt_yesno() {
+    noecho();
+    int ch;
+    do {
+        ch = getch();
+    } while (ch != 'y' && ch != 'n');
+    echo();
+    
+    return ch == 'y';
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/input.h	Thu Mar 06 15:03:06 2014 +0100
@@ -0,0 +1,45 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2014 Mike Becker. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef INPUT_H
+#define	INPUT_H
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+int prompt_yesno();
+
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* INPUT_H */
+
--- a/src/main.c	Sun Feb 23 21:03:35 2014 +0100
+++ b/src/main.c	Thu Mar 06 15:03:06 2014 +0100
@@ -30,6 +30,8 @@
 #include "terminal-chess.h"
 #include <string.h>
 #include <time.h>
+#include <ncurses.h>
+#include "input.h"
 
 int get_settings(int argc, char **argv, Settings *settings) {
     char *valid;
@@ -104,25 +106,28 @@
 
 void dump_gameinfo(Gameinfo *gameinfo) {
     int serverwhite = gameinfo->servercolor == WHITE;
-    printf(
-        "Game details:\n"
-        "  Server plays %s  -  Client plays %s\n",
+    attron(A_UNDERLINE);
+    printw("Game details\n");
+    attroff(A_UNDERLINE);
+    printw("  Server:     %s\n  Client:     %s\n",
         serverwhite?"white":"black", serverwhite?"black":"White"
     );
     if (gameinfo->time > 0) {
         if (gameinfo->time % 60) {
-            printf("  Time limit: %ds + %ds\n",
+            printw("  Time limit: %ds + %ds\n",
                 gameinfo->time, gameinfo->addtime);
         } else {
-            printf("  Time limit: %dm + %ds\n",
+            printw("  Time limit: %dm + %ds\n",
                 gameinfo->time/60, gameinfo->addtime);
         }
     } else {
-        printf("  No time limit\n");
+        printw("  No time limit\n");
     }
+    refresh();
 }
 
 int cleanup(Settings *settings, int exitcode) {
+
     if (settings->server) {
         if (net_destroy(settings->server)) {
             perror("Server shutdown failed");
@@ -162,12 +167,17 @@
         return EXIT_SUCCESS;
     }
     
+    initscr();
+    cbreak();
+    atexit((void(*)(void)) endwin);
+    
     Server server;
     settings.server = &server;
     
     if (is_server(&settings)) {
         dump_gameinfo(&(settings.gameinfo));
-        printf("\nListening for client...\n");
+        printw("\nListening for client...\n");
+        refresh();
         if (net_create(&server, settings.port)) {
             perror("Server creation failed");
             return cleanup(&settings, EXIT_FAILURE);
@@ -178,12 +188,36 @@
             return cleanup(&settings, EXIT_FAILURE);
         }
         
-        printf("Client connected - transmitting gameinfo...\n");
-        net_send(server.client->fd, NETCODE_GAMEINFO,
-            &(settings.gameinfo), sizeof(settings.gameinfo));
+        /* net version handshake */
+        int fd = server.client->fd;
+        net_send_code(fd, NETCODE_VERSION);
+        if (net_recieve_code(fd) != NETCODE_VERSION) {
+            fprintf(stderr, "Client uses an incompatible software version.\n");
+            return cleanup(&settings, EXIT_FAILURE);
+        }
+        
+        printw("Client connected - transmitting gameinfo...");
+        refresh();
+        
+        
+        net_send_code(fd, NETCODE_GAMEINFO);
+        net_send_data(fd, &(settings.gameinfo), sizeof(settings.gameinfo));
+        printw("\rClient connected - awaiting challenge acceptance...");
+        refresh();
+        int code = net_recieve_code(fd);
+        if (code == NETCODE_ACCEPT) {
+            printw("\rClient connected - challenge accepted.");
+            clrtoeol();
+        } else if (code == NETCODE_DECLINE) {
+            printw("\rClient connected - challenge declined.");
+            clrtoeol();
+        } else {
+            fprintf(stderr, "Invalid client response\n");
+            return cleanup(&settings, EXIT_FAILURE);
+        }
     } else {
         if (net_find(&server, settings.serverhost, settings.port)) {
-            perror("Can't find server");
+            fprintf(stderr, "Can't find server\n");
             return cleanup(&settings, EXIT_FAILURE);
         }
         
@@ -191,17 +225,35 @@
             perror("Can't connect to server");
             return cleanup(&settings, EXIT_FAILURE);
         }
+        
+        int fd = server.fd;
+        if (net_recieve_code(fd) != NETCODE_VERSION) {
+            fprintf(stderr, "Server uses an incompatible software version.\n");
+            return cleanup(&settings, EXIT_FAILURE);
+        } else {
+            net_send_code(fd, NETCODE_VERSION);
+        }
 
-        printf("Connection established!\n\n");
-        if (net_recieve_code(server.fd) == NETCODE_GAMEINFO) {
-            net_recieve_data(server.fd, &(settings.gameinfo),
+        printw("Connection established!\n\n");
+        refresh();
+        
+        if (net_recieve_code(fd) == NETCODE_GAMEINFO) {
+            net_recieve_data(fd, &(settings.gameinfo),
                 sizeof(settings.gameinfo));
             dump_gameinfo(&(settings.gameinfo));
+            printw("Accept challenge (y/n)? ");
+            if (prompt_yesno()) {
+                net_send_code(fd, NETCODE_ACCEPT);
+                // TODO: start game
+            } else {
+                net_send_code(fd, NETCODE_DECLINE);
+            }
         } else {
             fprintf(stderr, "Server sent invalid gameinfo.\n");
         }
     }
     
+    getch(); /* TODO: remove */
     return cleanup(&settings, EXIT_SUCCESS);
 }
 
--- a/src/network.c	Sun Feb 23 21:03:35 2014 +0100
+++ b/src/network.c	Thu Mar 06 15:03:06 2014 +0100
@@ -113,9 +113,12 @@
     return EXIT_SUCCESS;
 }
 
-void net_send(int socket, uint32_t code, void *data, size_t len) {
+void net_send_code(int socket, uint32_t code) {
     code = htonl(code);
     send(socket, &code, sizeof(uint32_t), 0);
+}
+
+void net_send_data(int socket, void *data, size_t len) {
     send(socket, data, len, 0);
 }
 
--- a/src/network.h	Sun Feb 23 21:03:35 2014 +0100
+++ b/src/network.h	Thu Mar 06 15:03:06 2014 +0100
@@ -37,7 +37,11 @@
 extern "C" {
 #endif
     
-#define NETCODE_GAMEINFO 1
+#define NETCODE_ACCEPT 0x00
+#define NETCODE_DECLINE 0x01
+#define NETCODE_GAMEINFO 0x10
+    
+#define NETCODE_VERSION 1
 
 typedef struct {
     int fd; /* -1, if we are the client */
@@ -58,7 +62,8 @@
 int net_destroy(Server *server);
 int net_connect(Server *server);
 
-void net_send(int socket, uint32_t code, void *data, size_t len);
+void net_send_code(int socket, uint32_t code);
+void net_send_data(int socket, void *data, size_t len);
 int net_recieve_code(int socket);
 void net_recieve_data(int socket, void *data, size_t len);
 

mercurial