src/server.c

Wed, 29 Aug 2018 13:55:18 +0200

author
Mike Becker <universe@uap-core.de>
date
Wed, 29 Aug 2018 13:55:18 +0200
changeset 64
4eda5df55f86
parent 60
0c50aac49e55
permissions
-rw-r--r--

fixes castling not printed correctly to PGN

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@64 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@60 77 long position = ftell(pgnfile);
universe@51 78 fclose(pgnfile);
universe@59 79 if (result) {
universe@60 80 printw("Invalid PGN file content at position %ld:\n%s\n",
universe@60 81 position, pgn_error_str(result));
universe@59 82 return 1;
universe@51 83 }
universe@51 84 if (!is_game_running(&continuegame)) {
universe@51 85 addstr("Game has ended. Use -S to analyze it.\n");
universe@59 86 return 1;
universe@51 87 }
universe@51 88 addch('\n');
universe@51 89 dump_moveinfo(&continuegame);
universe@51 90 addch('\n');
universe@51 91 } else {
universe@51 92 printw("Can't read PGN file (%s)\n", strerror(errno));
universe@59 93 return 1;
universe@51 94 }
universe@51 95 }
universe@6 96
universe@6 97 if (server_open(&server, settings->port)) {
universe@6 98 net_destroy(&server);
universe@59 99 return 1;
universe@6 100 }
universe@6 101
universe@6 102 if (server_handshake(server.client)) {
universe@6 103 net_destroy(&server);
universe@59 104 return 1;
universe@6 105 }
universe@5 106
universe@6 107 int fd = server.client->fd;
universe@51 108 if (settings->continuepgn) {
universe@64 109 /* Continue game, send PGN data */
universe@51 110 uint16_t mc = 0;
universe@51 111 MoveList *movelist = continuegame.movelist;
universe@51 112 while (movelist) {
universe@51 113 mc++;
universe@51 114 movelist = movelist->next;
universe@51 115 }
universe@51 116
universe@51 117 Move* moves = calloc(mc, sizeof(Move));
universe@51 118
universe@51 119 movelist = continuegame.movelist;
universe@51 120 mc = 0;
universe@51 121 while (movelist) {
universe@51 122 moves[mc] = movelist->move;
universe@51 123 mc++;
universe@51 124 movelist = movelist->next;
universe@51 125 }
universe@51 126
universe@51 127 size_t pgndata_size = sizeof(GameInfo)+sizeof(mc)+mc*sizeof(Move);
universe@51 128 char *pgndata = malloc(pgndata_size);
universe@51 129 memcpy(pgndata, &(settings->gameinfo), sizeof(GameInfo));
universe@51 130 memcpy(pgndata+sizeof(GameInfo), &mc, sizeof(mc));
universe@51 131 memcpy(pgndata+sizeof(GameInfo)+sizeof(mc), moves, mc*sizeof(Move));
universe@51 132 free(moves);
universe@51 133 net_send_data(fd, NETCODE_PGNDATA, pgndata, pgndata_size);
universe@51 134 free(pgndata);
universe@51 135 } else {
universe@64 136 /* Start new game */
universe@51 137 net_send_data(fd, NETCODE_GAMEINFO,
universe@51 138 &(settings->gameinfo), sizeof(GameInfo));
universe@51 139 }
universe@46 140 addstr("\rClient connected - awaiting challenge acceptance...");
universe@5 141 refresh();
universe@5 142 int code = net_recieve_code(fd);
universe@5 143 if (code == NETCODE_ACCEPT) {
universe@46 144 addstr("\rClient connected - challenge accepted.");
universe@5 145 clrtoeol();
universe@51 146 if (settings->continuepgn) {
universe@51 147 game_continue(settings, fd, &continuegame);
universe@51 148 } else {
universe@51 149 game_start(settings, fd);
universe@51 150 }
universe@5 151 } else if (code == NETCODE_DECLINE) {
universe@46 152 addstr("\rClient connected - challenge declined.");
universe@46 153 clrtoeol();
universe@46 154 } else if (code == NETCODE_CONNLOST) {
universe@46 155 addstr("\rClient connected - but gave no response.");
universe@5 156 clrtoeol();
universe@5 157 } else {
universe@34 158 addstr("\rInvalid client response");
universe@34 159 clrtoeol();
universe@34 160
universe@6 161 net_destroy(&server);
universe@59 162 return 1;
universe@5 163 }
universe@5 164
universe@5 165 net_destroy(&server);
universe@59 166 return 0;
universe@5 167 }

mercurial