src/main.c

changeset 184
93c81539b702
parent 183
39aa77b7188b
equal deleted inserted replaced
183:39aa77b7188b 184:93c81539b702
353 addch(' '); 353 addch(' ');
354 } 354 }
355 } 355 }
356 } 356 }
357 357
358 static void eval_move_failed_msg(uint32_t code) { 358 static void eval_move_failed_msg(int code) {
359 switch (code) { 359 switch (code) {
360 case AMBIGUOUS_MOVE: 360 case AMBIGUOUS_MOVE:
361 printw("Ambiguous move - please specify the piece to move."); 361 printw("Ambiguous move - please specify the piece to move.");
362 break; 362 break;
363 case PIECE_NOT_FOUND: 363 case PIECE_NOT_FOUND:
494 } 494 }
495 } 495 }
496 } 496 }
497 } 497 }
498 498
499 static NetMove hton_move(const Move *move) { 499 #define NETMOVE_LEN 14
500 #define NETGI_LEN 8
501
502 static NetGameInfo hton_gi(GameInfo gi) {
503 return (NetGameInfo) {
504 .servercolor = gi.servercolor,
505 .timecontrol = gi.timecontrol ? 1 : 0,
506 .time = net_htons(gi.time),
507 .addtime = net_htons(gi.addtime),
508 .delay = net_htons(gi.delay)
509 };
510 }
511
512 static GameInfo ntoh_gi(NetGameInfo gi) {
513 return (GameInfo) {
514 .servercolor = gi.servercolor,
515 .timecontrol = gi.timecontrol,
516 .time = net_ntohs(gi.time),
517 .addtime = net_ntohs(gi.addtime),
518 .delay = net_ntohs(gi.delay)
519 };
520 }
521
522 static NetMove hton_move(Move move) {
500 return (NetMove) { 523 return (NetMove) {
501 .mtime_sec = net_htonl(move->movetime / 1000000ull), 524 .mtime_sec = net_htonl(move.movetime / 1000000ull),
502 .mtime_usec = net_htonl(move->movetime % 1000000ull), 525 .mtime_usec = net_htonl(move.movetime % 1000000ull),
503 .piece = move->piece, 526 .piece = move.piece,
504 .fromfile = move->fromfile, .fromrow = move->fromrow, 527 .fromfile = move.fromfile, .fromrow = move.fromrow,
505 .tofile = move->tofile, .torow = move->torow, 528 .tofile = move.tofile, .torow = move.torow,
506 .promotion = move->promotion 529 .promotion = move.promotion
507 }; 530 };
508 } 531 }
509 532
510 static Move ntoh_move(const NetMove *move) { 533 static Move ntoh_move(NetMove move) {
511 return (Move) { 534 return (Move) {
512 .string = {0}, /* calculated before applying the move */ 535 .string = {0}, /* calculated before applying the move */
513 .timestamp = {0}, /* planned to be removed */ 536 .timestamp = {0}, /* planned to be removed */
514 .movetime = (uint64_t)net_ntohl(move->mtime_sec) 537 .movetime = (uint64_t)net_ntohl(move.mtime_sec)
515 * 1000000ull + net_ntohl(move->mtime_usec), 538 * 1000000ull + net_ntohl(move.mtime_usec),
516 .piece = move->piece, 539 .piece = move.piece,
517 .fromfile = move->fromfile, .fromrow = move->fromrow, 540 .fromfile = move.fromfile, .fromrow = move.fromrow,
518 .tofile = move->tofile, .torow = move->torow, 541 .tofile = move.tofile, .torow = move.torow,
519 .promotion = move->promotion, 542 .promotion = move.promotion,
520 /* flags are also calculated before applying the move */ 543 /* flags are also calculated before applying the move */
521 0 544 0
522 }; 545 };
523 } 546 }
524 547
635 Move move; 658 Move move;
636 int eval_result = eval_move(gamestate, 659 int eval_result = eval_move(gamestate,
637 movestr, mycolor, &move); 660 movestr, mycolor, &move);
638 switch (eval_result) { 661 switch (eval_result) {
639 case VALID_MOVE_SYNTAX: 662 case VALID_MOVE_SYNTAX:
640 NetMove nmove = hton_move(&move); 663 NetMove nmove = hton_move(move);
641 net_send_data(opponent, NETCODE_MOVE, &nmove, NETMOVE_LEN); 664 net_send_data(opponent, NETCODE_MOVE, &nmove, NETMOVE_LEN);
642 code = net_recieve_code(opponent); 665 code = net_recieve_code(opponent);
643 /* we could validate the move's check/checkmate flag with 666 /* we could validate the move's check/checkmate flag with
644 * the network response code, but we choose not to do it */ 667 * the network response code, but we choose not to do it */
645 gamestate->checkmate = code == NETCODE_CHECKMATE; 668 gamestate->checkmate = code == NETCODE_CHECKMATE;
646 gamestate->stalemate = code == NETCODE_STALEMATE; 669 gamestate->stalemate = code == NETCODE_STALEMATE;
647 if (code == NETCODE_DECLINE_MOVE) { 670 if (code == NETCODE_DECLINE_MOVE) {
648 uint32_t reason; 671 uint8_t reason;
649 net_recieve_data(opponent, &reason, sizeof(uint32_t)); 672 net_recieve_data(opponent, &reason, 1);
650 reason = net_ntohl(reason);
651 eval_move_failed_msg(reason); 673 eval_move_failed_msg(reason);
652 } else if (code == NETCODE_ACCEPT 674 } else if (code == NETCODE_ACCEPT
653 || code == NETCODE_CHECK 675 || code == NETCODE_CHECK
654 || code == NETCODE_CHECKMATE 676 || code == NETCODE_CHECKMATE
655 || code == NETCODE_STALEMATE 677 || code == NETCODE_STALEMATE
787 } 809 }
788 break; 810 break;
789 case NETCODE_MOVE: { 811 case NETCODE_MOVE: {
790 NetMove nmove; 812 NetMove nmove;
791 net_recieve_data(opponent, &nmove, NETMOVE_LEN); 813 net_recieve_data(opponent, &nmove, NETMOVE_LEN);
792 Move move = ntoh_move(&nmove); 814 Move move = ntoh_move(nmove);
793 format_move(gamestate, &move); 815 format_move(gamestate, &move);
794 code = validate_move(gamestate, &move); 816 code = validate_move(gamestate, &move);
795 if (code == VALID_MOVE_SEMANTICS) { 817 if (code == VALID_MOVE_SEMANTICS) {
796 apply_move(gamestate, &move); 818 apply_move(gamestate, &move);
797 if (gamestate->checkmate) { 819 if (gamestate->checkmate) {
830 } 852 }
831 } else { 853 } else {
832 return 0; 854 return 0;
833 } 855 }
834 } else { 856 } else {
835 uint32_t reason = net_htonl(code); 857 net_send_data(opponent, NETCODE_DECLINE_MOVE, &code, 1);
836 net_send_data(opponent, NETCODE_DECLINE_MOVE,
837 &reason, sizeof(uint32_t));
838 } 858 }
839 break; 859 break;
840 } 860 }
841 case NETCODE_ERROR: 861 case NETCODE_ERROR:
842 printw("\rCannot perform asynchronous network IO"); 862 printw("\rCannot perform asynchronous network IO");
1073 net_destroy(&server); 1093 net_destroy(&server);
1074 return 1; 1094 return 1;
1075 } 1095 }
1076 1096
1077 int fd = server.client->fd; 1097 int fd = server.client->fd;
1098 NetGameInfo gi = hton_gi(gamestate->info);
1078 if (settings.continuepgn) { 1099 if (settings.continuepgn) {
1079 /* Continue game, send PGN data */ 1100 /* Continue game, send PGN data */
1080 uint16_t mc = gamestate->movecount; 1101 uint16_t mc = gamestate->movecount;
1081 size_t pgndata_size = sizeof(GameInfo) + 2 + mc * NETMOVE_LEN; 1102 size_t pgndata_size = NETGI_LEN + 2 + mc * NETMOVE_LEN;
1082 char *pgndata = malloc(pgndata_size); 1103 char *pgndata = malloc(pgndata_size);
1083 memcpy(pgndata, &(gamestate->info), sizeof(GameInfo)); 1104 memcpy(pgndata, &gi, NETGI_LEN);
1084 unsigned offset = sizeof(GameInfo); 1105 unsigned offset = NETGI_LEN;
1085 uint16_t mcn = net_htons(mc); 1106 uint16_t mcn = net_htons(mc);
1086 memcpy(pgndata+offset, &mcn, 2); 1107 memcpy(pgndata+offset, &mcn, 2);
1087 offset += 2; 1108 offset += 2;
1088 for (unsigned i = 0 ; i < mc ; i++) { 1109 for (unsigned i = 0 ; i < mc ; i++) {
1089 NetMove nmove = hton_move(gamestate->moves + i); 1110 NetMove nmove = hton_move(gamestate->moves[i]);
1090 memcpy(pgndata+offset, &nmove, NETMOVE_LEN); 1111 memcpy(pgndata+offset, &nmove, NETMOVE_LEN);
1091 offset += NETMOVE_LEN; 1112 offset += NETMOVE_LEN;
1092 } 1113 }
1093 net_send_data(fd, NETCODE_PGNDATA, pgndata, pgndata_size); 1114 net_send_data(fd, NETCODE_PGNDATA, pgndata, pgndata_size);
1094 free(pgndata); 1115 free(pgndata);
1095 } else { 1116 } else {
1096 /* Start new game */ 1117 /* Start new game */
1097 net_send_data(fd, NETCODE_GAMEINFO, 1118 net_send_data(fd, NETCODE_GAMEINFO, &gi, NETGI_LEN);
1098 &(gamestate->info), sizeof(GameInfo));
1099 } 1119 }
1100 addstr("\rClient connected - awaiting challenge acceptance..."); 1120 addstr("\rClient connected - awaiting challenge acceptance...");
1101 refresh(); 1121 refresh();
1102 int code = net_recieve_code(fd); 1122 int code = net_recieve_code(fd);
1103 if (code == NETCODE_ACCEPT) { 1123 if (code == NETCODE_ACCEPT) {
1169 1189
1170 uint8_t code = net_recieve_code(server.fd); 1190 uint8_t code = net_recieve_code(server.fd);
1171 bool played = false; 1191 bool played = false;
1172 if (code == NETCODE_GAMEINFO) { 1192 if (code == NETCODE_GAMEINFO) {
1173 /* Start new game */ 1193 /* Start new game */
1174 net_recieve_data(server.fd, &(gamestate->info), sizeof(GameInfo)); 1194 NetGameInfo gi;
1195 net_recieve_data(server.fd, &gi, NETGI_LEN);
1196 gamestate->info = ntoh_gi(gi);
1175 dump_gameinfo(gamestate); 1197 dump_gameinfo(gamestate);
1176 if (prompt_yesno("Accept challenge")) { 1198 if (prompt_yesno("Accept challenge")) {
1177 net_send_code(server.fd, NETCODE_ACCEPT); 1199 net_send_code(server.fd, NETCODE_ACCEPT);
1178 game_play(gamestate, server.fd, true); 1200 game_play(gamestate, server.fd, true);
1179 played = true; 1201 played = true;
1180 } else { 1202 } else {
1181 net_send_code(server.fd, NETCODE_DECLINE); 1203 net_send_code(server.fd, NETCODE_DECLINE);
1182 } 1204 }
1183 } else if (code == NETCODE_PGNDATA) { 1205 } else if (code == NETCODE_PGNDATA) {
1184 net_recieve_data(server.fd, &(gamestate->info), sizeof(GameInfo)); 1206 NetGameInfo gi;
1207 net_recieve_data(server.fd, &gi, NETGI_LEN);
1208 gamestate->info = ntoh_gi(gi);
1185 uint16_t mc; 1209 uint16_t mc;
1186 net_recieve_data(server.fd, &mc, sizeof(mc)); 1210 net_recieve_data(server.fd, &mc, 2);
1187 mc = net_ntohs(mc); 1211 mc = net_ntohs(mc);
1188 char *movedata = malloc(mc * NETMOVE_LEN); 1212 char *movedata = malloc(mc * NETMOVE_LEN);
1189 net_recieve_data(server.fd, movedata, mc*NETMOVE_LEN); 1213 net_recieve_data(server.fd, movedata, mc*NETMOVE_LEN);
1190 unsigned offset = 0; 1214 unsigned offset = 0;
1191 for (size_t i = 0 ; i < mc ; i++) { 1215 for (size_t i = 0 ; i < mc ; i++) {
1192 NetMove nmove; 1216 NetMove nmove;
1193 memcpy(&nmove, movedata+offset, NETMOVE_LEN); 1217 memcpy(&nmove, movedata+offset, NETMOVE_LEN);
1194 offset += NETMOVE_LEN; 1218 offset += NETMOVE_LEN;
1195 Move move = ntoh_move(&nmove); 1219 Move move = ntoh_move(nmove);
1196 format_move(gamestate, &move); 1220 format_move(gamestate, &move);
1197 apply_move(gamestate, &move); 1221 apply_move(gamestate, &move);
1198 } 1222 }
1199 free(movedata); 1223 free(movedata);
1200 dump_gameinfo(gamestate); 1224 dump_gameinfo(gamestate);

mercurial