diff -r 41017d0a72c5 -r 84f2e380a434 src/server.c --- a/src/server.c Mon Jun 16 13:45:31 2014 +0200 +++ b/src/server.c Mon Jun 16 15:41:06 2014 +0200 @@ -30,6 +30,8 @@ #include "terminal-chess.h" #include "game.h" #include +#include +#include static int server_open(Server *server, char *port) { printw("\nListening for client...\n"); @@ -64,6 +66,31 @@ Server server; dump_gameinfo(&(settings->gameinfo)); + GameState continuegame; + gamestate_init(&continuegame); + if (settings->continuepgn) { + // preload PGN data before handshake + FILE *pgnfile = fopen(settings->continuepgn, "r"); + if (pgnfile) { + int result = read_pgn(pgnfile, &continuegame, + &(settings->gameinfo)); + fclose(pgnfile); + if (result != EXIT_SUCCESS) { + addstr("Invalid PGN file content.\n"); + return EXIT_FAILURE; + } + if (!is_game_running(&continuegame)) { + addstr("Game has ended. Use -S to analyze it.\n"); + return EXIT_FAILURE; + } + addch('\n'); + dump_moveinfo(&continuegame); + addch('\n'); + } else { + printw("Can't read PGN file (%s)\n", strerror(errno)); + return EXIT_FAILURE; + } + } if (server_open(&server, settings->port)) { net_destroy(&server); @@ -76,16 +103,49 @@ } int fd = server.client->fd; - net_send_data(fd, NETCODE_GAMEINFO, - &(settings->gameinfo), sizeof(GameInfo)); + if (settings->continuepgn) { + // Continue game, send PGN data + uint16_t mc = 0; + MoveList *movelist = continuegame.movelist; + while (movelist) { + mc++; + movelist = movelist->next; + } + + Move* moves = calloc(mc, sizeof(Move)); + + movelist = continuegame.movelist; + mc = 0; + while (movelist) { + moves[mc] = movelist->move; + mc++; + movelist = movelist->next; + } + + size_t pgndata_size = sizeof(GameInfo)+sizeof(mc)+mc*sizeof(Move); + char *pgndata = malloc(pgndata_size); + memcpy(pgndata, &(settings->gameinfo), sizeof(GameInfo)); + memcpy(pgndata+sizeof(GameInfo), &mc, sizeof(mc)); + memcpy(pgndata+sizeof(GameInfo)+sizeof(mc), moves, mc*sizeof(Move)); + free(moves); + net_send_data(fd, NETCODE_PGNDATA, pgndata, pgndata_size); + free(pgndata); + } else { + // Start new game + net_send_data(fd, NETCODE_GAMEINFO, + &(settings->gameinfo), sizeof(GameInfo)); + } addstr("\rClient connected - awaiting challenge acceptance..."); refresh(); int code = net_recieve_code(fd); if (code == NETCODE_ACCEPT) { addstr("\rClient connected - challenge accepted."); clrtoeol(); - - game_start(settings, fd); + if (settings->continuepgn) { + game_continue(settings, fd, &continuegame); + } else { + game_start(settings, fd); + } } else if (code == NETCODE_DECLINE) { addstr("\rClient connected - challenge declined."); clrtoeol();