src/server.c

Tue, 28 Aug 2018 14:16:30 +0200

author
Mike Becker <universe@uap-core.de>
date
Tue, 28 Aug 2018 14:16:30 +0200
changeset 59
3fa1de896666
parent 55
54ea19938d57
child 60
0c50aac49e55
permissions
-rw-r--r--

fixes inappropriate use of EXIT_ macros + adds a sample PGN file

universe@5 1 /*
universe@5 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
universe@5 3 *
universe@55 4 * Copyright 2016 Mike Becker. All rights reserved.
universe@5 5 *
universe@5 6 * Redistribution and use in source and binary forms, with or without
universe@5 7 * modification, are permitted provided that the following conditions are met:
universe@5 8 *
universe@5 9 * 1. Redistributions of source code must retain the above copyright
universe@5 10 * notice, this list of conditions and the following disclaimer.
universe@5 11 *
universe@5 12 * 2. Redistributions in binary form must reproduce the above copyright
universe@5 13 * notice, this list of conditions and the following disclaimer in the
universe@5 14 * documentation and/or other materials provided with the distribution.
universe@5 15 *
universe@5 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
universe@5 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
universe@5 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
universe@5 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
universe@5 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
universe@5 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
universe@5 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
universe@5 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
universe@5 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
universe@5 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
universe@5 26 * POSSIBILITY OF SUCH DAMAGE.
universe@5 27 *
universe@5 28 */
universe@5 29
universe@5 30 #include "terminal-chess.h"
universe@6 31 #include "game.h"
universe@5 32 #include <ncurses.h>
universe@51 33 #include <errno.h>
universe@51 34 #include <string.h>
universe@5 35
universe@6 36 static int server_open(Server *server, char *port) {
universe@5 37 printw("\nListening for client...\n");
universe@5 38 refresh();
universe@6 39 if (net_create(server, port)) {
universe@34 40 addstr("Server creation failed");
universe@6 41 return 1;
universe@5 42 }
universe@5 43
universe@6 44 if (net_listen(server)) {
universe@34 45 addstr("Listening for client failed");
universe@6 46 return 1;
universe@5 47 }
universe@6 48
universe@6 49 return 0;
universe@6 50 }
universe@5 51
universe@6 52 static int server_handshake(Client *client) {
universe@6 53 net_send_code(client->fd, NETCODE_VERSION);
universe@6 54 if (net_recieve_code(client->fd) != NETCODE_VERSION) {
universe@34 55 addstr("Client uses an incompatible software version.");
universe@6 56 return 1;
universe@5 57 }
universe@5 58
universe@46 59 addstr("Client connected - transmitting gameinfo...");
universe@5 60 refresh();
universe@6 61
universe@6 62 return 0;
universe@6 63 }
universe@5 64
universe@6 65 int server_run(Settings *settings) {
universe@6 66 Server server;
universe@6 67
universe@6 68 dump_gameinfo(&(settings->gameinfo));
universe@51 69 GameState continuegame;
universe@51 70 gamestate_init(&continuegame);
universe@51 71 if (settings->continuepgn) {
universe@51 72 // preload PGN data before handshake
universe@51 73 FILE *pgnfile = fopen(settings->continuepgn, "r");
universe@51 74 if (pgnfile) {
universe@51 75 int result = read_pgn(pgnfile, &continuegame,
universe@51 76 &(settings->gameinfo));
universe@51 77 fclose(pgnfile);
universe@59 78 if (result) {
universe@51 79 addstr("Invalid PGN file content.\n");
universe@59 80 return 1;
universe@51 81 }
universe@51 82 if (!is_game_running(&continuegame)) {
universe@51 83 addstr("Game has ended. Use -S to analyze it.\n");
universe@59 84 return 1;
universe@51 85 }
universe@51 86 addch('\n');
universe@51 87 dump_moveinfo(&continuegame);
universe@51 88 addch('\n');
universe@51 89 } else {
universe@51 90 printw("Can't read PGN file (%s)\n", strerror(errno));
universe@59 91 return 1;
universe@51 92 }
universe@51 93 }
universe@6 94
universe@6 95 if (server_open(&server, settings->port)) {
universe@6 96 net_destroy(&server);
universe@59 97 return 1;
universe@6 98 }
universe@6 99
universe@6 100 if (server_handshake(server.client)) {
universe@6 101 net_destroy(&server);
universe@59 102 return 1;
universe@6 103 }
universe@5 104
universe@6 105 int fd = server.client->fd;
universe@51 106 if (settings->continuepgn) {
universe@51 107 // Continue game, send PGN data
universe@51 108 uint16_t mc = 0;
universe@51 109 MoveList *movelist = continuegame.movelist;
universe@51 110 while (movelist) {
universe@51 111 mc++;
universe@51 112 movelist = movelist->next;
universe@51 113 }
universe@51 114
universe@51 115 Move* moves = calloc(mc, sizeof(Move));
universe@51 116
universe@51 117 movelist = continuegame.movelist;
universe@51 118 mc = 0;
universe@51 119 while (movelist) {
universe@51 120 moves[mc] = movelist->move;
universe@51 121 mc++;
universe@51 122 movelist = movelist->next;
universe@51 123 }
universe@51 124
universe@51 125 size_t pgndata_size = sizeof(GameInfo)+sizeof(mc)+mc*sizeof(Move);
universe@51 126 char *pgndata = malloc(pgndata_size);
universe@51 127 memcpy(pgndata, &(settings->gameinfo), sizeof(GameInfo));
universe@51 128 memcpy(pgndata+sizeof(GameInfo), &mc, sizeof(mc));
universe@51 129 memcpy(pgndata+sizeof(GameInfo)+sizeof(mc), moves, mc*sizeof(Move));
universe@51 130 free(moves);
universe@51 131 net_send_data(fd, NETCODE_PGNDATA, pgndata, pgndata_size);
universe@51 132 free(pgndata);
universe@51 133 } else {
universe@51 134 // Start new game
universe@51 135 net_send_data(fd, NETCODE_GAMEINFO,
universe@51 136 &(settings->gameinfo), sizeof(GameInfo));
universe@51 137 }
universe@46 138 addstr("\rClient connected - awaiting challenge acceptance...");
universe@5 139 refresh();
universe@5 140 int code = net_recieve_code(fd);
universe@5 141 if (code == NETCODE_ACCEPT) {
universe@46 142 addstr("\rClient connected - challenge accepted.");
universe@5 143 clrtoeol();
universe@51 144 if (settings->continuepgn) {
universe@51 145 game_continue(settings, fd, &continuegame);
universe@51 146 } else {
universe@51 147 game_start(settings, fd);
universe@51 148 }
universe@5 149 } else if (code == NETCODE_DECLINE) {
universe@46 150 addstr("\rClient connected - challenge declined.");
universe@46 151 clrtoeol();
universe@46 152 } else if (code == NETCODE_CONNLOST) {
universe@46 153 addstr("\rClient connected - but gave no response.");
universe@5 154 clrtoeol();
universe@5 155 } else {
universe@34 156 addstr("\rInvalid client response");
universe@34 157 clrtoeol();
universe@34 158
universe@6 159 net_destroy(&server);
universe@59 160 return 1;
universe@5 161 }
universe@5 162
universe@5 163 net_destroy(&server);
universe@59 164 return 0;
universe@5 165 }

mercurial