From 79bd2194539aa559078de9afb1500a2e754ee501 Mon Sep 17 00:00:00 2001 From: Franklin Wei Date: Sun, 13 Jul 2014 19:54:47 -0400 Subject: Added server --- GAMESPEC | 6 +- Makefile | 5 +- chatbot.c | 66 +++++++++---------- gtnw.c | 223 +++++++++++++++++++++++++++++++------------------------------- joshua.c | 34 ++++------ joshua.h | 4 +- main.cpp | 31 --------- server.c | 131 ++++++++++++++++++++++++++++++++++++ util.c | 46 ++++++++----- util.h | 6 ++ 10 files changed, 329 insertions(+), 223 deletions(-) delete mode 100644 main.cpp create mode 100644 server.c diff --git a/GAMESPEC b/GAMESPEC index 371aef8..638a131 100644 --- a/GAMESPEC +++ b/GAMESPEC @@ -1,6 +1,5 @@ This file contains a formal definition of Global Thermonuclear War. =======GAMEPLAY======== -Each player starts with 32 ICBMs. The player with population still remaining after the other has been wiped out is the winner. If both players are wiped out, it is a tie. Each turn, the player can either: @@ -11,8 +10,8 @@ Each turn, the player can either: The behavior of each of these options is described below. ICBM launch: - - The USA can launch ICBMs at a maximum of 4 cities at a time. - - The USSR can launch 6 at a time. + - Both sides get 6 ICBMs per turn. + - The USSR gets 7 if it goes first. - When an ICBM is launched, there are 5 possible results: - Miss: 0 casualties - Marginal: 20%+1000 casualties @@ -37,7 +36,6 @@ Negociation: - Peace/Progress - 20% - Surprise attack - 20% - No progress - 60% - - When progress is made, both sides will lose 4 ICBMs - Progress must be made at least 5 times if peace is to be achieved Surrender: diff --git a/Makefile b/Makefile index 76e6fb5..c24d8a6 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,8 @@ -SOURCES=joshua.o main.o util.o chatbot.o gtnw.o strings.o +SOURCES=joshua.o server.o util.o chatbot.o gtnw.o strings.o HEADERS=chatbot.h gtnw.h joshua.h location.h strings.h map.h util.h -CXXFLAGS=-lncurses -g -O3 CFLAGS=-std=gnu99 -g -O3 wargames: $(SOURCES) $(HEADERS) - g++ $(SOURCES) $(CXXFLAGS) -lncurses -o wargames + g++ $(SOURCES) $(CXXFLAGS) -o wargames all: wargames Makefile clean: rm -f $(SOURCES) a.out wargames *~ diff --git a/chatbot.c b/chatbot.c index b2909f5..27bbdca 100644 --- a/chatbot.c +++ b/chatbot.c @@ -14,24 +14,23 @@ * * You should have received a copy of the GNU General Public License * along with this program. If not, see . - * + * * Contact the author at contact@fwei.tk */ #include "gtnw.h" #include "strings.h" #include "util.h" -#include +#include #include #include #include - void do_chatbot(void) { - int stage=0; /* stage 0: i'm fine how are you... -> - stage 1: people sometimes make mistakes -> - stage 2: love to. how about global thermonuclear war? -> - stage 3: no lets play global thermonuclear war -> + int stage=0; /* stage 0: i'm fine how are you... -> + stage 1: people sometimes make mistakes -> + stage 2: love to. how about global thermonuclear war? -> + stage 3: no lets play global thermonuclear war -> stage 4: GLOBAL THERMONUCLEAR WAR!!! */ while(1) { @@ -61,7 +60,7 @@ void do_chatbot(void) valid=true; } } - break; + break; case 1: for(int i=0;i. - * + * * Contact the author at contact@fwei.tk */ @@ -22,8 +22,8 @@ #include "location.h" #include "map.h" #include "util.h" -#include #include +#include #include #include #include @@ -69,16 +69,16 @@ static void fire_missile(struct location_t* city) /* calculate populations of US+USSR by totaling the populations of each of their cities */ static void calc_pops(long long* us_pop, long long* ussr_pop) -{ +{ *us_pop=0; *ussr_pop=0; /* calculate populations */ for(int i=0;iussr_back) { while(us_back!=ussr_back) - { - ussr_cities[ussr_back].print=false; - ++ussr_back; - } + { + ussr_cities[ussr_back].print=false; + ++ussr_back; + } } us_cities[us_back].print=true; us_cities[us_back].print_name="Total"; @@ -137,19 +137,19 @@ static void print_map_with_pops(void) for(int i=0;i0 && move<5) good=true; } @@ -369,7 +366,7 @@ void global_thermonuclear_war(void) print_string(map[i]); print_string("\n"); } - + /* get the side the user wants to be on */ print_string("\nWHICH SIDE DO YOU WANT?\n\n 1. UNITED STATES\n 2. SOVIET UNION\n\n"); bool good=false; @@ -377,7 +374,9 @@ void global_thermonuclear_war(void) while(!good) { print_string("PLEASE CHOOSE ONE: "); - scanw("%u", &side); + char buf[32]; + getnstr(buf, 31); + sscanf(buf, "%u", &side); if(side==1 || side==2) good=true; } diff --git a/joshua.c b/joshua.c index 675f70b..9520ed5 100644 --- a/joshua.c +++ b/joshua.c @@ -14,7 +14,7 @@ * * You should have received a copy of the GNU General Public License * along with this program. If not, see . - * + * * Contact the author at contact@fwei.tk */ @@ -23,16 +23,15 @@ #include "strings.h" /* predefined strings */ #include "util.h" -#include #include +#include #include #include #include void cleanup(int signum) { - endwin(); - exit(0); + exit(EXIT_SUCCESS); } void random_stuff(void) /* print random junk on the screen for about 3 seconds */ { @@ -45,24 +44,19 @@ void random_stuff(void) /* print random junk on the screen for about 3 seconds * usleep(100000); clear(); } -void be_joshua() +void be_joshua(int fd) { - initscr(); + printf("joshua started.\n"); + out_fd=fd; clear(); signal(SIGINT, &cleanup); /* start_color(); init_pair(1, COLOR_BLUE, COLOR_BLACK); attron(COLOR_PAIR(1));*/ - scrollok(stdscr, true); bool gamesPhase=false; char buf[33]; - int maxx, maxy; - getmaxyx(stdscr, maxy, maxx); - for(int i=0;i. - * + * * Contact the author at contact@fwei.tk */ #ifdef __cplusplus extern "C" { #endif -void be_joshua(); +void be_joshua(int); #ifdef __cplusplus }; #endif diff --git a/main.cpp b/main.cpp deleted file mode 100644 index 4c102a2..0000000 --- a/main.cpp +++ /dev/null @@ -1,31 +0,0 @@ -/* - * WarGames - a WOPR emulator written in C - * Copyright (C) 2014 Franklin Wei - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * Contact the author at contact@fwei.tk - */ - -#include "joshua.h" - -#include -#include - -using namespace std; -int main() -{ - be_joshua(); - endwin(); -} diff --git a/server.c b/server.c new file mode 100644 index 0000000..fe8b6f8 --- /dev/null +++ b/server.c @@ -0,0 +1,131 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "joshua.h" +#define PORT 1029 +int server_socket; +int pipes[FD_SETSIZE][2]; +int make_server_socket(uint16_t port) +{ + int sock; + struct sockaddr_in name; + sock=socket(AF_INET, SOCK_STREAM, 0); + if(sock<0) + { + printf("error creating socket.\n"); + return -1; + } + name.sin_family=AF_INET; + name.sin_port=htons(port); + name.sin_addr.s_addr=htonl(INADDR_ANY); + int ret=bind(sock, (struct sockaddr*) &name, sizeof(name)); + if(ret<0) + { + printf("error binding to port %d\n", port); + return -1; + } + return sock; +} +int process_data(int fd) +{ + char buf[1024]; + memset(buf, 0, sizeof(buf)); + int ret=read(fd, buf, sizeof(buf)); + if(ret<0) /* error */ + { + printf("error in read()\n"); + return -1; + } + if(ret==0) + { + printf("EOF from client\n"); + return -1; + } + else + { + write(pipes[fd][1], buf, strlen(buf)); + } +} +void serv_cleanup() +{ + printf("preparing to exit...\n"); + fflush(stdout); + close(server_socket); +} +int main(int argc, char* argv[]) +{ + printf("starting server...\n"); + signal(SIGINT, &serv_cleanup); + int sock=make_server_socket(PORT); + server_socket=sock; + fd_set active_fd_set, read_fd_set; + struct sockaddr_in client; + if(listen(sock, 1)<0) + { + printf("error listening.\n"); + return 1; + } + FD_ZERO(&active_fd_set); + FD_SET(sock, &active_fd_set); + printf("listening on port %d\n", PORT); + while(1) + { + read_fd_set=active_fd_set; + int ret=select(FD_SETSIZE, &read_fd_set, 0,0,0); + if(ret<0) + { + printf("select() returned error.\n"); + return 1; + } + for(int i=0;i. - * + * * Contact the author at contact@fwei.tk */ #include "strings.h" #include "util.h" #include -#include #include #include - - +#include +int out_fd; +extern int pipes[FD_SETSIZE][2]; void allLower(char* str) { for(int i=0;str[i];++i) @@ -35,21 +35,11 @@ void allLower(char* str) } void print_string(const char* str) /* print string, slowly */ { - int window_height; - int junk; - getmaxyx(stdscr, window_height, junk); int i=0; while(str[i]) { - addch(str[i]); - int cursx, cursy; - getyx(stdscr, cursy, cursx); - if(cursy==window_height) - { - scroll(stdscr); - } - usleep(SLEEP_TIME); - refresh(); + write(out_fd, &str[i], 1); + fsync(out_fd); ++i; } } @@ -66,4 +56,28 @@ void remove_punct(char* buf) } } } +void clear(void) +{ +} +void refresh(void) +{ + fsync(out_fd); +} +int getnstr(char* buf, int max) +{ + printf("reading...\n"); + memset(buf, 0, sizeof(buf)); + int back=0; + char c=0; + do { + read(pipes[out_fd][0], &c, 1); + if(c!='\n') + { + buf[back]=c; + ++back; + } + } + while(back