diff options
| author | Franklin Wei <frankhwei536@gmail.com> | 2015-05-09 11:50:36 -0400 |
|---|---|---|
| committer | Franklin Wei <frankhwei536@gmail.com> | 2015-05-09 11:50:36 -0400 |
| commit | 313a10a1251cfd588cebf6389395617bc2672b0c (patch) | |
| tree | fa8c6d393e21ee6c6d67d1a5c977dce1eb36c274 | |
| parent | 38f8ea46442e27d117af113dfd61f2567040260f (diff) | |
| download | wargames-server-313a10a1251cfd588cebf6389395617bc2672b0c.zip wargames-server-313a10a1251cfd588cebf6389395617bc2672b0c.tar.gz wargames-server-313a10a1251cfd588cebf6389395617bc2672b0c.tar.bz2 wargames-server-313a10a1251cfd588cebf6389395617bc2672b0c.tar.xz | |
long-overdue code cleanup
| -rw-r--r-- | chatbot.c | 127 | ||||
| -rw-r--r-- | gtnw.c | 466 | ||||
| -rw-r--r-- | joshua.c | 163 | ||||
| -rw-r--r-- | server.c | 398 | ||||
| -rw-r--r-- | util.h | 10 |
5 files changed, 625 insertions, 539 deletions
@@ -27,101 +27,104 @@ #include <unistd.h> 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 -> - stage 4: GLOBAL THERMONUCLEAR WAR!!! */ - while(1) + 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) { - char buf[513]; - int ret=getnstr(buf, 512); - usleep(SLEEP_TIME*100); - if(ret==ERR) + char buf[128]; + int ret = getnstr(buf, sizeof(buf)); + usleep(SLEEP_TIME * 100); + + if(ret == ERR) { - print_string("\n\n"); - print_string("SORRY?"); - print_string("\n\n"); + print_string("\n\n"); + print_string("SORRY?"); + print_string("\n\n"); } - else + else { - allLower(buf); - remove_punct(buf); - bool valid=false; - switch(stage) + allLower(buf); + remove_punct(buf); + bool valid = false; + switch(stage) { case 0: - for(int i=0;i<sizeof(stage1_triggers)/sizeof(const char*);++i) + for(int i = 0; i < sizeof(stage1_triggers)/sizeof(const char*); ++i) { - if(strcmp(buf, stage1_triggers[i])==0) - { - print_string("\n\nEXCELLENT. IT'S BEEN A LONG TIME. CAN YOU EXPLAIN\nTHE REMOVAL OF YOUR USER ACCOUNT ON 6/23/73?\n\n"); - ++stage; - valid=true; - } + if(strcmp(buf, stage1_triggers[i]) == 0) + { + print_string("\n\nEXCELLENT. IT'S BEEN A LONG TIME. CAN YOU EXPLAIN\nTHE REMOVAL OF YOUR USER ACCOUNT ON 6/23/73?\n\n"); + ++stage; + valid = true; + } } - break; + break; case 1: - for(int i=0;i<sizeof(stage2_triggers)/sizeof(const char*);++i) + for(int i = 0; i < sizeof(stage2_triggers)/sizeof(const char*); ++i) { - if(strcmp(buf, stage2_triggers[i])==0) + if(strcmp(buf, stage2_triggers[i]) == 0) { - print_string("\n\nYES THEY DO. SHALL WE PLAY A GAME?\n\n"); - ++stage; - valid=true; + print_string("\n\nYES THEY DO. SHALL WE PLAY A GAME?\n\n"); + ++stage; + valid = true; } } - break; + break; case 2: - for(int i=0;i<sizeof(stage3_triggers)/sizeof(const char*);++i) + for(int i = 0; i < sizeof(stage3_triggers)/sizeof(const char*); ++i) { - if(strcmp(buf, stage3_triggers[i])==0) + if(strcmp(buf, stage3_triggers[i]) == 0) { - print_string("\n\nWOULDN'T YOU PREFER A GOOD GAME OF CHESS?\n\n"); - ++stage; - valid=true; + print_string("\n\nWOULDN'T YOU PREFER A GOOD GAME OF CHESS?\n\n"); + ++stage; + valid = true; } } - break; + break; case 3: - for(int i=0;i<sizeof(stage4_triggers)/sizeof(const char*);++i) + for(int i = 0; i < sizeof(stage4_triggers)/sizeof(const char*); ++i) { - if(strcmp(buf, stage4_triggers[i])==0) + if(strcmp(buf, stage4_triggers[i]) == 0) { - print_string("\n\nFINE.\n\n"); - valid=true; - usleep(SLEEP_TIME*100); - global_thermonuclear_war(); + print_string("\n\nFINE.\n\n"); + valid = true; + usleep(SLEEP_TIME * 100); + global_thermonuclear_war(); } } - break; + break; } // switch - /* now check for phase-insensitive strings */ - for(int i=0;i<sizeof(exit_triggers)/sizeof(const char*);++i) + + /* now check for phase-agnostic strings */ + for(int i = 0; i < sizeof(exit_triggers)/sizeof(const char*); ++i) { - if(strcmp(buf, exit_triggers[i])==0) + if(strcmp(buf, exit_triggers[i]) == 0) { - print_string("\n\n"); - print_string(exit_responses[rand()%(sizeof(exit_responses)/sizeof(const char*))]); - print_string("\n--CONNECTION TERMINATED--"); - exit(EXIT_SUCCESS); + print_string("\n\n"); + print_string(exit_responses[ rand() % (sizeof(exit_responses)/sizeof(const char*)) ]); + + print_string("\n--CONNECTION TERMINATED--"); + return; } } - for(int i=0;i<sizeof(greetings_triggers)/sizeof(const char*);++i) + for(int i = 0; i < sizeof(greetings_triggers)/sizeof(const char*); ++i) { - if(strcmp(buf, greetings_triggers[i])==0) + if(strcmp(buf, greetings_triggers[i]) == 0) { - print_string("\n\n"); - print_string(greetings_responses[rand()%(sizeof(greetings_responses)/sizeof(const char*))]); - print_string("\n\n"); - valid=true; + print_string("\n\n"); + print_string(greetings_responses[ rand()%(sizeof(greetings_responses)/sizeof(const char*)) ]); + print_string("\n\n"); + valid = true; } } - if(!valid) + if(!valid) { - print_string("\n\n"); - print_string("SORRY?"); - print_string("\n\n"); + print_string("\n\n"); + print_string("SORRY?"); + print_string("\n\n"); } } // else } // while @@ -33,394 +33,394 @@ static int winner=0; /* on surrender */ static unsigned int max(long long a, long long b) { - return a>b?a:b; + return a>b?a:b; } /* simulate a missile launch */ static void fire_missile(struct location_t* city) { - int random=rand()%100; /* leave this at 100 for future adjustments */ - int x=city->x, y=city->y; - if(random>=90) /* crit */ + int random=rand()%100; /* leave this at 100 for future adjustments */ + int x=city->x, y=city->y; + if(random>=90) /* crit */ { - map[y][x]='!'; - city->population=0; + map[y][x]='!'; + city->population=0; } - else if(random>=60) /* major */ + else if(random>=60) /* major */ { - map[y][x]='X'; - city->population=max((double)city->population*(double).4-5000, 0); + map[y][x]='X'; + city->population=max((double)city->population*(double).4-5000, 0); } - else if(random>=30) /* minor */ + else if(random>=30) /* minor */ { - map[y][x]='*'; - city->population=max((double)city->population*(double).6-2500, 0); + map[y][x]='*'; + city->population=max((double)city->population*(double).6-2500, 0); } - else if(random>=10) /* marginal */ + else if(random>=10) /* marginal */ { - map[y][x]='x'; - city->population=max((double)city->population*(double).8-1000, 0); + map[y][x]='x'; + city->population=max((double)city->population*(double).8-1000, 0); } - else /* miss */ + else /* miss */ { - map[y][x]='O'; + map[y][x]='O'; } } /* 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;i<sizeof(world)/sizeof(struct location_t);++i) + *us_pop=0; + *ussr_pop=0; + /* calculate populations */ + for(int i=0;i<sizeof(world)/sizeof(struct location_t);++i) { - if(world[i].owner==USSR) - *ussr_pop+=world[i].population; - else - *us_pop+=world[i].population; + if(world[i].owner==USSR) + *ussr_pop+=world[i].population; + else + *us_pop+=world[i].population; } } /* print the map and populations of the cities underneath */ static void print_map_with_pops(void) { - for(int i=0;i<sizeof(map)/sizeof(char*);++i) + for(int i=0;i<sizeof(map)/sizeof(char*);++i) { - print_string(map[i]); - print_string("\n"); + print_string(map[i]); + print_string("\n"); } - long long us_pop=0, ussr_pop=0; - calc_pops(&us_pop, &ussr_pop); - /* now sort into US and USSR cities */ - struct location_t us_cities[sizeof(world)/sizeof(struct location_t)+1], ussr_cities[sizeof(world)/sizeof(struct location_t)+1]; - int us_back=0, ussr_back=0; - for(int i=0;i<sizeof(world)/sizeof(struct location_t);++i) + long long us_pop=0, ussr_pop=0; + calc_pops(&us_pop, &ussr_pop); + /* now sort into US and USSR cities */ + struct location_t us_cities[sizeof(world)/sizeof(struct location_t)+1], ussr_cities[sizeof(world)/sizeof(struct location_t)+1]; + int us_back=0, ussr_back=0; + for(int i=0;i<sizeof(world)/sizeof(struct location_t);++i) { - if(world[i].owner==USSR) + if(world[i].owner==USSR) { - ussr_cities[ussr_back]=world[i]; - ++ussr_back; + ussr_cities[ussr_back]=world[i]; + ++ussr_back; } - else + else { - us_cities[us_back]=world[i]; - ++us_back; + us_cities[us_back]=world[i]; + ++us_back; } } - if(us_back<ussr_back) + if(us_back<ussr_back) { - while(us_back!=ussr_back) + while(us_back!=ussr_back) { - us_cities[us_back].print=false; - ++us_back; + us_cities[us_back].print=false; + ++us_back; } } - else if(us_back>ussr_back) + else if(us_back>ussr_back) { - while(us_back!=ussr_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"; - us_cities[us_back].population=us_pop; - ussr_cities[ussr_back].print=true; - ussr_cities[ussr_back].print_name="Total"; - ussr_cities[ussr_back].population=ussr_pop; - ++us_back; - ++ussr_back; - print_string("\n\n"); - char buf[512]; - for(int i=0;i<us_back;++i) + us_cities[us_back].print=true; + us_cities[us_back].print_name="Total"; + us_cities[us_back].population=us_pop; + ussr_cities[ussr_back].print=true; + ussr_cities[ussr_back].print_name="Total"; + ussr_cities[ussr_back].population=ussr_pop; + ++us_back; + ++ussr_back; + print_string("\n\n"); + char buf[512]; + for(int i=0;i<us_back;++i) { - if(us_cities[i].print && ussr_cities[i].print) + if(us_cities[i].print && ussr_cities[i].print) { - char buf_2[32]; - snprintf(buf_2, 31, "%u", us_cities[i].population); - snprintf(buf, 512, "%s: %u %*s: %u", us_cities[i].print_name, us_cities[i].population, 64-strlen(us_cities[i].print_name)-strlen(buf_2), ussr_cities[i].print_name, ussr_cities[i].population); + char buf_2[32]; + snprintf(buf_2, 31, "%u", us_cities[i].population); + snprintf(buf, 512, "%s: %u %*s: %u", us_cities[i].print_name, us_cities[i].population, 64-strlen(us_cities[i].print_name)-strlen(buf_2), ussr_cities[i].print_name, ussr_cities[i].population); } - else if(us_cities[i].print && !ussr_cities[i].print) - snprintf(buf, 512, "%s: %u", us_cities[i].print_name, us_cities[i].population); - else + else if(us_cities[i].print && !ussr_cities[i].print) + snprintf(buf, 512, "%s: %u", us_cities[i].print_name, us_cities[i].population); + else { - memset(buf, ' ', 255); - buf[255]=0; - snprintf(buf+64, 512-64, "%s: %u", ussr_cities[i].print_name, ussr_cities[i].population); + memset(buf, ' ', 255); + buf[255]=0; + snprintf(buf+64, 512-64, "%s: %u", ussr_cities[i].print_name, ussr_cities[i].population); } - print_string(buf); - print_string("\n"); + print_string(buf); + print_string("\n"); } } /* prompt the user for targets for the initial strike */ static void do_first_strike(int side) { - print_string("AWAITING FIRST STRIKE COMMAND"); - print_string("\n\n\nPLEASE LIST PRIMARY TARGETS BY\nCITY AND/OR COUNTY NAME:\n\n"); - char target_names[32][129]; - bool good=true; - int num_targets=0; - struct location_t *targets[32]; - int num_targets_found=0; - int max_targets=side==USA?6:7; - for(int i=0;num_targets_found<max_targets && good;++i) + print_string("AWAITING FIRST STRIKE COMMAND"); + print_string("\n\n\nPLEASE LIST PRIMARY TARGETS BY\nCITY AND/OR COUNTY NAME:\n\n"); + char target_names[32][129]; + bool good=true; + int num_targets=0; + struct location_t *targets[32]; + int num_targets_found=0; + int max_targets=side==USA?6:7; + for(int i=0;num_targets_found<max_targets && good;++i) { - getnstr(target_names[i], 128); - if(strcmp(target_names[i],"")==0) + getnstr(target_names[i], 128); + if(strcmp(target_names[i],"")==0) { - good=false; + good=false; } - else + else { - ++num_targets; - allLower(target_names[i]); - remove_punct(target_names[i]); - bool found=false; - for(int j=0;j<sizeof(world)/sizeof(struct location_t);++j) + ++num_targets; + allLower(target_names[i]); + remove_punct(target_names[i]); + bool found=false; + for(int j=0;j<sizeof(world)/sizeof(struct location_t);++j) { - if(strcmp(world[j].name, target_names[i])==0) + if(strcmp(world[j].name, target_names[i])==0) { - found=true; - if(world[j].owner!=side) + found=true; + if(world[j].owner!=side) { - targets[num_targets_found]=&world[j]; - ++num_targets_found; + targets[num_targets_found]=&world[j]; + ++num_targets_found; } - else + else { - print_string("\n\nATTEMPTING TO FIRE AT OWN CITY.\nPLEASE CONFIRM (YES OR NO): "); - char response[17]; - getnstr(response, 16); - allLower(response); - remove_punct(response); - if(strcmp(response, "yes")==0 || strcmp(response, "y")==0) + print_string("\n\nATTEMPTING TO FIRE AT OWN CITY.\nPLEASE CONFIRM (YES OR NO): "); + char response[17]; + getnstr(response, 16); + allLower(response); + remove_punct(response); + if(strcmp(response, "yes")==0 || strcmp(response, "y")==0) { - print_string("\n\nATTEMPTING TO FIRE AT OWN CITY.\nARE YOU SURE (YES OR NO): "); - response[0]=0; - getnstr(response, 16); - allLower(response); - remove_punct(response); - if(strcmp(response, "yes")==0 || strcmp(response, "y")==0) + print_string("\n\nATTEMPTING TO FIRE AT OWN CITY.\nARE YOU SURE (YES OR NO): "); + response[0]=0; + getnstr(response, 16); + allLower(response); + remove_punct(response); + if(strcmp(response, "yes")==0 || strcmp(response, "y")==0) { - print_string("\nTARGET CONFIRMED.\n\n"); - targets[num_targets_found]=&world[j]; - ++num_targets_found; + print_string("\nTARGET CONFIRMED.\n\n"); + targets[num_targets_found]=&world[j]; + ++num_targets_found; } } } } } - if(!found) + if(!found) { - print_string("TARGET NOT FOUND: "); - print_string(target_names[i]); - print_string("\n"); + print_string("TARGET NOT FOUND: "); + print_string(target_names[i]); + print_string("\n"); } } } - for(int i=0;i<num_targets_found;++i) + for(int i=0;i<num_targets_found;++i) { - fire_missile(targets[i]); + fire_missile(targets[i]); } - clear(); - print_map_with_pops(); + clear(); + print_map_with_pops(); } /* essentially the same as do_first_strike */ /** TODO: refactor into do_first_strike (or vice-versa) **/ static void do_missile_launch(int side) { - print_string("\n\n"); - print_string("AWAITING STRIKE COMMAND"); - print_string("\n\n\nPLEASE LIST PRIMARY TARGETS BY\nCITY AND/OR COUNTY NAME:\n\n"); - char target_names[32][129]; - bool good=true; - int num_targets=0; - struct location_t *targets[32]; - int num_targets_found=0; - for(int i=0;num_targets_found<6 && good;++i) + print_string("\n\n"); + print_string("AWAITING STRIKE COMMAND"); + print_string("\n\n\nPLEASE LIST PRIMARY TARGETS BY\nCITY AND/OR COUNTY NAME:\n\n"); + char target_names[32][129]; + bool good=true; + int num_targets=0; + struct location_t *targets[32]; + int num_targets_found=0; + for(int i=0;num_targets_found<6 && good;++i) { - getnstr(target_names[i], 128); - if(strcmp(target_names[i],"")==0) + getnstr(target_names[i], 128); + if(strcmp(target_names[i],"")==0) { - good=false; + good=false; } - else + else { - ++num_targets; - allLower(target_names[i]); - remove_punct(target_names[i]); - bool found=false; - for(int j=0;j<sizeof(world)/sizeof(struct location_t);++j) + ++num_targets; + allLower(target_names[i]); + remove_punct(target_names[i]); + bool found=false; + for(int j=0;j<sizeof(world)/sizeof(struct location_t);++j) { - if(strcmp(world[j].name, target_names[i])==0) + if(strcmp(world[j].name, target_names[i])==0) { - found=true; - if(world[j].owner!=side) + found=true; + if(world[j].owner!=side) { - targets[num_targets_found]=&world[j]; - ++num_targets_found; + targets[num_targets_found]=&world[j]; + ++num_targets_found; } - else + else { - print_string("\n\nATTEMPTING TO FIRE AT OWN CITY.\nPLEASE CONFIRM (YES OR NO): "); - char response[17]; - getnstr(response, 16); - allLower(response); - remove_punct(response); - if(strcmp(response, "yes")==0 || strcmp(response, "y")==0) + print_string("\n\nATTEMPTING TO FIRE AT OWN CITY.\nPLEASE CONFIRM (YES OR NO): "); + char response[17]; + getnstr(response, 16); + allLower(response); + remove_punct(response); + if(strcmp(response, "yes")==0 || strcmp(response, "y")==0) { - print_string("\n\nATTEMPTING TO FIRE AT OWN CITY.\nARE YOU SURE (YES OR NO): "); - response[0]=0; - getnstr(response, 16); - allLower(response); - remove_punct(response); - if(strcmp(response, "yes")==0 || strcmp(response, "y")==0) + print_string("\n\nATTEMPTING TO FIRE AT OWN CITY.\nARE YOU SURE (YES OR NO): "); + response[0]=0; + getnstr(response, 16); + allLower(response); + remove_punct(response); + if(strcmp(response, "yes")==0 || strcmp(response, "y")==0) { - print_string("\nTARGET CONFIRMED.\n\n"); - targets[num_targets_found]=&world[j]; - ++num_targets_found; + print_string("\nTARGET CONFIRMED.\n\n"); + targets[num_targets_found]=&world[j]; + ++num_targets_found; } } } } } - if(!found) + if(!found) { - print_string("TARGET NOT FOUND: "); - print_string(target_names[i]); - print_string("\n"); + print_string("TARGET NOT FOUND: "); + print_string(target_names[i]); + print_string("\n"); } } } - for(int i=0;i<num_targets_found;++i) + for(int i=0;i<num_targets_found;++i) { - fire_missile(targets[i]); + fire_missile(targets[i]); } - clear(); - print_map_with_pops(); + clear(); + print_map_with_pops(); } enum ai_strategy_t { AGGRESSIVE, PASSIVE, PEACEFUL }; static void init_ai(int side) { - /* nothing for now */ - /** TODO: decide strategy? **/ + /* nothing for now */ + /** TODO: decide strategy? **/ } static void do_ai_move(int side) { - /* nothing yet :( */ + /* nothing yet :( */ } static void do_peace_talks(int side) { - /** TODO: IMPLEMENT!!! **/ + /** TODO: IMPLEMENT!!! **/ } /* prompt the player for their move */ static void do_human_move(int side) { - bool good=false; - print_string("\nWHAT ACTION DO YOU WISH TO TAKE?\n\n 1. MISSILE LAUNCH\n 2. PEACE TALKS\n 3. SURRENDER\n 4. NOTHING\n\n"); - int move=0; - while(!good) + bool good=false; + print_string("\nWHAT ACTION DO YOU WISH TO TAKE?\n\n 1. MISSILE LAUNCH\n 2. PEACE TALKS\n 3. SURRENDER\n 4. NOTHING\n\n"); + int move=0; + while(!good) { - print_string("PLEASE CHOOSE ONE: "); - char buf[32]; - getnstr(buf, 32); - sscanf(buf, "%u", &move); - if(move>0 && move<5) - good=true; + print_string("PLEASE CHOOSE ONE: "); + char buf[32]; + getnstr(buf, 32); + sscanf(buf, "%u", &move); + if(move>0 && move<5) + good=true; } - switch(move) + switch(move) { case 1: - do_missile_launch(side); - break; + do_missile_launch(side); + break; case 2: - do_peace_talks(side); - break; + do_peace_talks(side); + break; case 3: - surrender=true; - winner=side==1?2:1; - break; + surrender=true; + winner=side==1?2:1; + break; case 4: - break; + break; } } /* play a game of Global Thermonuclear War! */ void global_thermonuclear_war(void) { - srand(time(0)); // might want to move to main()... - surrender=false; - clear(); - for(int i=0;i<sizeof(const_map)/sizeof(const char*);++i) + srand(time(0)); // might want to move to main()... + surrender=false; + clear(); + for(int i=0;i<sizeof(const_map)/sizeof(const char*);++i) { - strcpy(map[i], const_map[i]); + strcpy(map[i], const_map[i]); } - /* print the map */ - for(int i=0;i<sizeof(map)/sizeof(const char*);++i) + /* print the map */ + for(int i=0;i<sizeof(map)/sizeof(const char*);++i) { - print_string(map[i]); - print_string("\n"); + 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; - unsigned int side=0; - while(!good) + /* 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; + unsigned int side=0; + while(!good) { - print_string("PLEASE CHOOSE ONE: "); - char buf[32]; - getnstr(buf, 31); - sscanf(buf, "%u", &side); - if(side==1 || side==2) - good=true; + print_string("PLEASE CHOOSE ONE: "); + char buf[32]; + getnstr(buf, 31); + sscanf(buf, "%u", &side); + if(side==1 || side==2) + good=true; } - clear(); - do_first_strike(side); - long long us_pop=0, ussr_pop; - calc_pops(&us_pop, &ussr_pop); - init_ai(side); - while(us_pop!=0 && ussr_pop!=0 && !surrender) + clear(); + do_first_strike(side); + long long us_pop=0, ussr_pop; + calc_pops(&us_pop, &ussr_pop); + init_ai(side); + while(us_pop!=0 && ussr_pop!=0 && !surrender) { - do_human_move(side); - calc_pops(&us_pop, &ussr_pop); - if(us_pop!=0 && ussr_pop!=0 && !surrender) + do_human_move(side); + calc_pops(&us_pop, &ussr_pop); + if(us_pop!=0 && ussr_pop!=0 && !surrender) { - do_ai_move(side); - calc_pops(&us_pop, &ussr_pop); + do_ai_move(side); + calc_pops(&us_pop, &ussr_pop); } } - print_string("\n\n"); - if(!surrender) + print_string("\n\n"); + if(!surrender) { - if(us_pop==0 && ussr_pop==0) + if(us_pop==0 && ussr_pop==0) { - print_string("WINNER: NONE\n\n"); + print_string("WINNER: NONE\n\n"); } - else if(us_pop==0) + else if(us_pop==0) { - print_string("WINNER: SOVIET UNION\n\n"); + print_string("WINNER: SOVIET UNION\n\n"); } - else if(ussr_pop==0) + else if(ussr_pop==0) { - print_string("WINNER: UNITED STATES\n\n"); + print_string("WINNER: UNITED STATES\n\n"); } } - else + else { - switch(winner) + switch(winner) { case 1: - print_string("WINNER: UNITED STATES\n\n"); - break; + print_string("WINNER: UNITED STATES\n\n"); + break; case 2: - print_string("WINNER: SOVIET UNION\n\n"); - break; + print_string("WINNER: SOVIET UNION\n\n"); + break; } } } @@ -31,87 +31,114 @@ void cleanup(int signum) { - exit(EXIT_SUCCESS); + exit(EXIT_SUCCESS); } -void random_stuff(void) /* print random junk on the screen for about 3 seconds */ + +void random_stuff(void) { - clear(); - /* credit for this text goes to David Brownlee and Chirs Carter */ - print_string("#45 11456 11009 11893 11972 11315\nPRT CON. 3.4.5. SECTRAN 9.4.3. PORT STAT: SD-345\n\n(311) 699-7305\n"); - clear(); - print_string("\n\n\n\n\n\n\n"); - print_string("(311) 767-8739\n(311) 936-2364\n- PRT. STAT. CRT. DEF.\n||||||||||||||==================================================\nFSKDJLSD: SDSDKJ: SBFJSL: DKSJL: SKFJJ: SDKFJLJ:\nSYSPROC FUNCT READY ALT NET READY\nCPU AUTH RY-345-AX3 SYSCOMP STATUS ALL PORTS ACTIVE\n22/34534.90/3209 11CVB-3904-3490\n(311) 935-2364\n"); - usleep(100000); - clear(); + clear(); + + print_string("#45 11456 11009 11893 11972 11315\nPRT CON. 3.4.5. SECTRAN 9.4.3. PORT STAT: SD-345\n\n(311) 699-7305\n"); + + clear(); + + print_string("\n\n\n\n\n\n\n"); + + print_string("(311) 767-8739\n(311) 936-2364\n- PRT. STAT. CRT. DEF.\n||||||||||||||==================================================\nFSKDJLSD: SDSDKJ: SBFJSL: DKSJL: SKFJJ: SDKFJLJ:\nSYSPROC FUNCT READY ALT NET READY\nCPU AUTH RY-345-AX3 SYSCOMP STATUS ALL PORTS ACTIVE\n22/34534.90/3209 11CVB-3904-3490\n(311) 935-2364\n"); + + usleep(100000); + + clear(); } + void be_joshua(int fd) { - out_fd=fd; - clear(); - signal(SIGINT, &cleanup); - /* - start_color(); - init_pair(1, COLOR_BLUE, COLOR_BLACK); - attron(COLOR_PAIR(1));*/ - bool gamesPhase=false; - char buf[33]; - if(connection_data[out_fd].know_termsize==1) + out_fd = fd; + clear(); + signal(SIGINT, &cleanup); + + /* old curses stuff */ + /* + start_color(); + init_pair(1, COLOR_BLUE, COLOR_BLACK); + attron(COLOR_PAIR(1));*/ + + bool gamesPhase = false; + char buf[32]; + + if(connection_data[out_fd].know_termsize == 1) { - /* the terminal size could change while the spaces are being printed, so use a while loop */ - int n=0; - while(n<connection_data[out_fd].term_width*2) + /* the terminal size could change while the spaces are being printed, so use a while loop */ + int n = 0; + while(n < connection_data[out_fd].term_width * 2) { - print_string(" "); - ++n; + print_string(" "); + ++n; } } - else - print_string("\n\n"); - do { - if(!gamesPhase) - print_string("LOGON: "); + else + print_string("\n\n"); + + do { + if(!gamesPhase) + print_string("LOGON: "); + + refresh(); + + int ret = getnstr(buf, sizeof(buf)); + + allLower(buf); + + usleep(SLEEP_TIME * 100); + + if(strcmp(buf, "help logon") == 0 && !gamesPhase) + { + print_string("\nHELP NOT AVAILABLE\n\n\n"); + } + else if(strcmp(buf, "help games") == 0) + { + print_string("\n'GAMES' REFERS TO MODELS, SIMULATIONS AND GAMES\nWHICH HAVE TACTICAL AND STRATEGIC APPLICATIONS.\n\n\n"); + gamesPhase = true; + } + else if(strcmp(buf, "list games") == 0 && gamesPhase) + { + print_string("\nFALKEN'S MAZE\nBLACK JACK\nGIN RUMMY\nHEARTS\nBRIDGE\nCHECKERS\nCHESS\nPOKER\nFIGHTER COMBAT\nGUERRILLA ENGAGEMENT\nDESERT WARFARE\nAIR-TO-GROUND ACTIONS\nTHEATERWIDE TACTICAL WARFARE\nTHEATERWIDE BIOTOXIC AND CHEMICAL WARFARE\n\nGLOBAL THERMONUCLEAR WAR\n\n\n"); + } + else if(ret == ERR || strcmp(buf, "joshua") && !gamesPhase) + { + print_string("\nIDENTIFICATION NOT RECOGNIZED BY SYSTEM\n--CONNECTION TERMINATED--"); + exit(EXIT_SUCCESS); + } + } while(strcmp(buf, "joshua") || gamesPhase); + + random_stuff(); + usleep(SLEEP_TIME * 100); + + print_string("GREETINGS, PROFESSOR FALKEN.\n\n"); + refresh(); - int ret=getnstr(buf, 32); + + getnstr(buf, sizeof(buf)); + allLower(buf); - usleep(SLEEP_TIME*100); - if(strcmp(buf, "help logon")==0 && !gamesPhase) - { - print_string("\nHELP NOT AVAILABLE\n\n\n"); - } - else if(strcmp(buf, "help games")==0) - { - print_string("\n'GAMES' REFERS TO MODELS, SIMULATIONS AND GAMES\nWHICH HAVE TACTICAL AND STRATEGIC APPLICATIONS.\n\n\n"); - gamesPhase=true; - } - else if(strcmp(buf, "list games")==0 && gamesPhase) - { - print_string("\nFALKEN'S MAZE\nBLACK JACK\nGIN RUMMY\nHEARTS\nBRIDGE\nCHECKERS\nCHESS\nPOKER\nFIGHTER COMBAT\nGUERRILLA ENGAGEMENT\nDESERT WARFARE\nAIR-TO-GROUND ACTIONS\nTHEATERWIDE TACTICAL WARFARE\nTHEATERWIDE BIOTOXIC AND CHEMICAL WARFARE\n\nGLOBAL THERMONUCLEAR WAR\n\n\n"); - } - else if(ret==ERR || strcmp(buf, "joshua") && !gamesPhase) - { - print_string("\nIDENTIFICATION NOT RECOGNIZED BY SYSTEM\n--CONNECTION TERMINATED--"); - exit(EXIT_SUCCESS); - } - } while(strcmp(buf, "joshua") || gamesPhase); - random_stuff(); - usleep(SLEEP_TIME*100); - print_string("GREETINGS, PROFESSOR FALKEN.\n\n"); - refresh(); - getnstr(buf, 32); - allLower(buf); - remove_punct(buf); - for(int i=0;i<sizeof(exit_triggers)/sizeof(const char*);++i) + remove_punct(buf); + + for(int i = 0; i < sizeof(exit_triggers) / sizeof(const char*); ++i) { - if(strcmp(buf, exit_triggers[i])==0) + if(strcmp(buf, exit_triggers[i]) == 0) { - print_string("\n\n"); - print_string(exit_responses[rand()%sizeof(exit_responses)/sizeof(const char*)]); - print_string("\n--CONNECTION TERMINATED--"); - exit(EXIT_SUCCESS); + print_string("\n\n"); + print_string(exit_responses[rand() % sizeof(exit_responses)/sizeof(const char*)]); + print_string("\n--CONNECTION TERMINATED--"); + return; } } - print_string("\n\nHOW ARE YOU FEELING TODAY?\n\n"); - refresh(); - do_chatbot(); - exit(EXIT_SUCCESS); + + print_string("\n\nHOW ARE YOU FEELING TODAY?\n\n"); + + refresh(); + + do_chatbot(); + + return; } @@ -21,6 +21,7 @@ #include "joshua.h" #include "telnet.h" #include "util.h" + #include <errno.h> #include <fcntl.h> #include <netdb.h> @@ -34,273 +35,322 @@ #include <sys/types.h> #include <unistd.h> #include <stdarg.h> + #define DEFAULT_PORT 23 #define LOG_LOCATION "/var/log/wopr" + int server_socket; uint16_t port; + int pipes[FD_SETSIZE][2]; + struct connection_data_t connection_data[FD_SETSIZE]; + int debugf(const char* fmt, ...) { - va_list l; - va_start(l, fmt); - int ret=vprintf(fmt, l); - va_end(l); - return ret; + va_list l; + va_start(l, fmt); + int ret = vprintf(fmt, l); + va_end(l); + return ret; } + int make_server_socket(uint16_t port) { - int sock; - struct sockaddr_in name; - sock=socket(AF_INET, SOCK_STREAM, 0); - if(sock<0) + int sock; + struct sockaddr_in name; + sock = socket(AF_INET, SOCK_STREAM, 0); + if(sock < 0) { - debugf("FATAL: Error opening socket.\n"); - return -1; + debugf("FATAL: Error opening 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) + + const int opt_val = 1; + + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt_val, sizeof(opt_val)); + setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &opt_val, sizeof(opt_val)); + + 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) { - debugf("FATAL: Error binding to port %d\n", port); - return -1; + debugf("FATAL: Error binding to port %d\n", port); + return -1; } - return sock; + + return sock; } + char pending_buffer[1024]; + void handle_command(unsigned char* buf, int buflen, int connection) { - unsigned char cmd, opt; - if(buflen<2) + unsigned char cmd, opt; + if(buflen < 2) { - debugf("Invalid command.\n"); - return; + debugf("Invalid command.\n"); + return; } - cmd=buf[1]; - /* handle two-byte commands */ - switch(cmd) + cmd = buf[1]; + + /* handle two-byte commands */ + switch(cmd) { case AYT: - { - unsigned char iac_nop[]={IAC, NOP}; + { + unsigned char iac_nop[] = {IAC, NOP}; write(connection, iac_nop, sizeof(iac_nop)); return; - } } - if(buflen<3) + } + + if(buflen < 3) { - debugf("Invalid command.\n"); - return; + debugf("Invalid command.\n"); + return; } - opt=buf[2]; - switch(cmd) + + opt = buf[2]; + switch(cmd) { case SB: - { + { switch(opt) - { - case NAWS: + { + case NAWS: + { + printf("NAWS command recieved.\n"); + /* format of NAWS data: IAC SB NAWS W W H H IAC SE */ + uint16_t height, width; + uint8_t height_hi, height_lo, width_hi, width_lo; + + if(buflen < 9) { - printf("NAWS command recieved.\n"); - /* format of NAWS data: IAC SB NAWS W W H H IAC SE */ - uint16_t height, width; - uint8_t height_hi, height_lo, width_hi, width_lo; - if(buflen<9) - { - debugf("IAC SB NAWS command too short!\n"); - return; - } - width_hi=buf[3]; - width_lo=buf[4]; - height_hi=buf[5]; - height_lo=buf[6]; - height=(height_hi<<8)|height_lo; - width=(width_hi<<8)|width_lo; - connection_data[connection].know_termsize=(height==0 || width==0)?0:1; - connection_data[connection].term_height=height; - connection_data[connection].term_width=width; - return; + debugf("IAC SB NAWS command too short!\n"); + return; } - } + + width_hi = buf[3]; + width_lo = buf[4]; + height_hi = buf[5]; + height_lo = buf[6]; + height = (height_hi << 8) | height_lo; + width = (width_hi << 8) | width_lo; + connection_data[connection].know_termsize = (height == 0 || width == 0) ? 0 : 1; + connection_data[connection].term_height = height; + connection_data[connection].term_width = width; + return; + } + } break; - } } - /* unimplemented command, just deny it */ - unsigned char deny_cmd[3]={IAC, WONT, opt}; - if(opt==LINEMODE) + } + + if((opt == LINEMODE && cmd == WILL) || (opt == NAWS)) { - deny_cmd[1]=WILL; + /* avoid an endless negiociation loop */ + return; } - /* - write(connection, deny_cmd, sizeof(deny_cmd)); - fsync(connection); - */ - return; + + /* unimplemented command, just deny it */ + unsigned char deny_cmd[3] = {IAC, WONT, opt}; + + write(connection, deny_cmd, sizeof(deny_cmd)); + fsync(connection); + return; } + int process_data(int fd) { - unsigned char buf[1024]; - memset(buf, 0, sizeof(buf)); - int ret=read(fd, buf, sizeof(buf)); - debugf("Client %d sends: %s\n", fd, buf); - debugf("Byte dump of data: "); - for(int i=0;buf[i];++i) + unsigned char buf[1024]; + memset(buf, 0, sizeof(buf)); + int ret = read(fd, buf, sizeof(buf)); + + debugf("Client %d sends: %s\n", fd, buf); + debugf("Byte dump of data: "); + + for(int i = 0; buf[i]; ++i) { - debugf("%d ", buf[i]); + debugf("%02x ", buf[i]); } - debugf("\n"); - char ctrl_c[]={0xff, 0xf4, 0xff, 0xfd, 0x06, 0x00}; - if(strcmp(ctrl_c, buf)==0) + debugf("\n"); + + char ctrl_c[] = {0xff, 0xf4, 0xff, 0xfd, 0x06, 0x00}; + if(strcmp(ctrl_c, buf) == 0) { - debugf("Got CTRL-C from client %d.\n", fd); - return -1; + debugf("Got CTRL-C from client %d.\n", fd); + return -1; } - if(ret<0) /* error */ + + if(ret < 0) /* error */ { - debugf("Error in read()\n"); - return -1; + debugf("Error in read()\n"); + return -1; } - if(ret==0) + + if(ret == 0) { - debugf("EOF from client %d.\n", fd); - return -1; + debugf("EOF from client %d.\n", fd); + return -1; } - else + else { - int buflen=strlen(buf); - if(buflen>0) /* no need to write nothing to the input stream :D */ + int buflen = strlen(buf); + if(buflen > 0) { - if(buf[0]==0xff) + if(buf[0] == 0xff) { - handle_command(buf, buflen, fd); + handle_command(buf, buflen, fd); } - else if(strlen(buf)>0) + else if(strlen(buf) > 0) { - write(pipes[fd][1],buf,strlen(buf)); + write(pipes[fd][1], buf, strlen(buf)); } - } - return 0; + } } - return 0; + + return 0; } + void serv_cleanup() { - debugf("\nPreparing to exit...\n"); - fflush(stdout); - shutdown(server_socket, SHUT_RDWR); + debugf("\nPreparing to exit...\n"); + fflush(stdout); + shutdown(server_socket, SHUT_RDWR); } + void setup_new_connection(int fd) { - unsigned char will_naws[]={IAC, DO, NAWS}; - write(fd, will_naws, sizeof(will_naws)); - will_naws[1]=WILL; - write(fd, will_naws, sizeof(will_naws)); + unsigned char will_naws[] = {IAC, DO, NAWS}; + write(fd, will_naws, sizeof(will_naws)); + will_naws[1] = WILL; + write(fd, will_naws, sizeof(will_naws)); - unsigned char dont_echo[]={IAC, DONT, ECHO}; - write(fd, dont_echo, sizeof(dont_echo)); - dont_echo[1]=WONT; - write(fd, dont_echo, sizeof(dont_echo)); + unsigned char dont_echo[] = {IAC, DONT, ECHO}; + write(fd, dont_echo, sizeof(dont_echo)); + dont_echo[1] = WONT; + write(fd, dont_echo, sizeof(dont_echo)); - unsigned char dont_sga[]={IAC, WONT, SGA}; - write(fd, dont_sga, sizeof(dont_sga)); + unsigned char dont_sga[] = {IAC, WONT, SGA}; + write(fd, dont_sga, sizeof(dont_sga)); - unsigned char will_linemode[]={IAC, WILL, LINEMODE}; - write(fd, will_linemode, sizeof(will_linemode)); + unsigned char will_linemode[] = {IAC, WILL, LINEMODE}; + write(fd, will_linemode, sizeof(will_linemode)); - memset(&connection_data[fd], 0, sizeof(struct connection_data_t)); - debugf("New connection set up.\n"); + memset(&connection_data[fd], 0, sizeof(struct connection_data_t)); + debugf("New connection set up.\n"); } + int main(int argc, char* argv[]) { - if(argc!=2) + if(argc != 2) { - debugf("Listening on default port: %d\n", DEFAULT_PORT); - port=DEFAULT_PORT; + debugf("Listening on default port: %d\n", DEFAULT_PORT); + port = DEFAULT_PORT; } - else + else { - int port2=atoi(argv[1]); - if(port2<0 || port2>65535) + int port2 = atoi(argv[1]); + if(port2 < 0 || port2 > 65535) { - debugf("FATAL: Port out of range.\n"); - return 2; + debugf("FATAL: Port out of range.\n"); + return 2; } - port=atoi(argv[1]); + port = atoi(argv[1]); } - debugf("Initializing server on port %u...\n", port); - 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) + + debugf("Initializing server on port %u...\n", port); + 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) { - debugf("FATAL: Error opening socket.\n"); - return 1; + debugf("FATAL: Error opening socket.\n"); + return 1; } - FD_ZERO(&active_fd_set); - FD_SET(sock, &active_fd_set); - debugf("Server ready, listening on port %d.\n", port); - debugf("Maximum clients: %d\n", FD_SETSIZE); - while(1) + + FD_ZERO(&active_fd_set); + FD_SET(sock, &active_fd_set); + + debugf("Server ready, listening on port %d.\n", port); + debugf("Maximum clients: %d\n", FD_SETSIZE); + + while(1) { - read_fd_set=active_fd_set; - int ret=select(FD_SETSIZE, &read_fd_set, 0,0,0); - if(ret<0) + read_fd_set = active_fd_set; + int ret = select(FD_SETSIZE, &read_fd_set, 0, 0, 0); + if(ret < 0) { - debugf("Error in select().\n"); - return 1; + debugf("Error in select().\n"); + return 1; } - for(int i=0;i<FD_SETSIZE;++i) + + for(int i = 0; i < FD_SETSIZE; ++i) { - if(FD_ISSET(i, &read_fd_set)) + if(FD_ISSET(i, &read_fd_set)) { - if(i==sock) + if(i == sock) { - /* new connection */ - int new, size; - size=sizeof(client); - new=accept(sock, (struct sockaddr*) &client, &size); - if(new<0) + /* new connection */ + int new, size; + size = sizeof(client); + new = accept(sock, (struct sockaddr*) &client, &size); + if(new < 0) { - debugf("Error accepting new connection.\n"); - continue; + debugf("Error accepting new connection.\n"); + continue; } - debugf("New connection, number %d.\n", new); - FD_SET(new, &active_fd_set); - int ret=pipe(pipes[new]); - if(ret<0) + + debugf("New connection, number %d.\n", new); + + FD_SET(new, &active_fd_set); + + int ret = pipe(pipes[new]); + + if(ret < 0) { - debugf("Pipe error.\n"); - continue; + debugf("Pipe error.\n"); + continue; } - pid_t pid=fork(); - if(pid<0) + + pid_t pid = fork(); + + if(pid < 0) { - debugf("Fork error.\n"); - continue; + debugf("Fork error.\n"); + continue; } - if(pid==0) /* child */ + + if(pid == 0) /* child */ { - /* set up the connection */ - setup_new_connection(new); - be_joshua(new); - debugf("Client exits\n"); - shutdown(new, SHUT_RDWR); - FD_CLR(new, &active_fd_set); - exit(0); + /* set up the connection */ + setup_new_connection(new); + + be_joshua(new); + + debugf("Client exits\n"); + shutdown(new, SHUT_RDWR); + FD_CLR(new, &active_fd_set); + exit(0); } } - else + else { - /* data from existing connection */ - if(process_data(i)<0) + /* data from existing connection */ + if(process_data(i) < 0) { - shutdown(i, SHUT_RDWR); - FD_CLR(i, &active_fd_set); - /* should kill the child associated with this connection, too */ + shutdown(i, SHUT_RDWR); + FD_CLR(i, &active_fd_set); + /* should kill the child associated with this connection, too */ } } } @@ -19,15 +19,19 @@ */ #define SLEEP_TIME 5000 + #include <stdint.h> #include <stdlib.h> + struct connection_data_t { - int naws_enable:1; - int know_termsize:1; + int naws_enable : 1; + int know_termsize : 1; uint16_t term_height; uint16_t term_width; }; + extern struct connection_data_t connection_data[FD_SETSIZE]; + void allLower(char*); void print_string(const char*); void remove_punct(char*); @@ -36,6 +40,8 @@ void clear(void); int getnstr(char*, int); void echo_off(void); void echo_on(void); + #define ERR 1 #define OK 0 + extern int out_fd; |