5 #include "gb/racegen.h" 15 #include "gb/enroll.h" 16 #include "gb/game_info.h" 22 #include <arpa/inet.h> 23 #include <netinet/in.h> 24 #include <sys/socket.h> 32 static void execute(
int argc,
char **argv);
35 static void help(
int,
char *[]);
36 static void load(
int,
char *[]);
38 static int modify(
int argc,
char *argv[]);
40 static void print(
int argc,
char *argv[]);
41 static void save(
int argc,
char *argv[]);
42 static void send2(
int argc,
char *argv[]);
43 static void quit(
int argc,
char **argv);
52 if ((argv[1][0] ==
'-') && (isserver = (argv[1][1] ==
's'))) {
58 printf(
"Syntax: racegen [-s [port]]\n");
62 printf(
"Syntax: racegen [-s [port]]\n");
70 struct sockaddr_in cli_addr, serv_addr;
72 if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
73 fprintf(stderr,
"server: can't open stream socket");
76 bzero((
char *)&serv_addr,
sizeof(serv_addr));
77 serv_addr.sin_family = AF_INET;
78 serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
79 serv_addr.sin_port = htons(port);
81 if (bind(sockfd, (
struct sockaddr *)&serv_addr,
sizeof(serv_addr)) < 0) {
82 fprintf(stderr,
"server: can't bind local address");
89 printf(
"Racegen set up on port %d\n", port);
90 printf(
"Now accepting connections.\n\n");
95 clilen =
sizeof(cli_addr);
96 fd = accept(sockfd, (
struct sockaddr *)&cli_addr, &clilen);
97 if (fd < 0) fprintf(stderr,
"server: accept error");
127 {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
139 {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
151 {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
163 {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
175 {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
187 {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
199 {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
211 {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
223 {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
235 {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
247 {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
251 "Earth",
"Forest",
"Desert",
"Water",
"Airless",
"Iceball",
"Jovian"};
260 "Water",
"Land",
"Mountain",
"Gas",
"Ice",
"Forest",
"Desert",
"Plated"};
296 {.003, -.0005, 0.0, 999, 0.0, .001, 0.0},
297 {0.0, 0.0, 0.0, 999, 0.0, 0.0, 0.0, 0.0}};
302 {1.00, 1.00, 2.00, 99.00, 1.01, 1.50, 3.00, 1.01},
304 {1.01, 1.50, 2.00, 99.00, 1.01, 1.00, 3.00, 1.01},
306 {3.00, 1.01, 1.01, 99.00, 1.50, 3.00, 1.00, 1.01},
308 {1.00, 1.50, 3.00, 99.00, 1.01, 1.01, 3.00, 1.01},
310 {1.01, 1.00, 1.00, 99.00, 1.01, 1.01, 1.00, 1.01},
312 {3.00, 1.01, 1.00, 99.00, 1.00, 1.50, 2.00, 1.01},
314 {99.00, 99.00, 99.00, 1.00, 99.00, 99.00, 99.00, 99.00}};
319 struct x race_info, cost_info,
last;
337 #define ROUND(f) ((int)(0.5
+ (f))) 357 race_info
.compat[i] * 0.5 + 10.8 * log(1.0 + race_info
.compat[i]);
445 if (f != nullptr) fprintf 451 (race_info
.attr[i] != 1.0)) {
452 FPRINTF(f,
"%s is boolean valued. Use \"yes\" or \"no\".\n",
468 if (race_info
.attr[i] != ((
double)((
int)race_info
.attr[i])))
470 race_info
.attr[i] = ((
double)((
int)race_info
.attr[i])));
471 }
else if (race_info
.attr[i] !=
472 (((
double)((
int)(100.0 * race_info
.attr[i]))) / 100.0))
473 FPRINTF(f,
"%s truncated to next lowest hundredth (%1.2f).\n",
476 (((
double)((
int)(100.0 * race_info
.attr[i]))) / 100.0));
483 FPRINTF(f,
"Normal races do not absorb their enemies in combat.\n");
487 FPRINTF(f,
"Normal races do not make pods.\n");
494 if (0 == strlen(race_info.name)) {
495 FPRINTF(f,
"Use a non-empty name.\n");
503 FPRINTF(f,
"Privileges out of valid range.\n");
507 FPRINTF(f,
"Players may not create %s races.\n",
516 FPRINTF(f,
"Home planet type out of valid range.\n");
524 FPRINTF(f,
"Home planet type out of valid range.\n");
532 FPRINTF(f,
"Non-jovian races must have 100%% plated compat.\n");
536 if (race_info
.compat[i] < 0.0) {
537 FPRINTF(f,
"Sector compatibility is at minimum 0%%.\n");
540 if (race_info
.compat[i] > 100.0) {
541 FPRINTF(f,
"Sector compatibility may be at most 100%%.\n");
546 FPRINTF(f,
"Non-jovian races may never have gas compatibility!\n");
551 FPRINTF(f,
"Jovian races may have no compatibility other than gas!\n");
556 FPRINTF(f,
"Sector compatibilities are integral; truncated to %1.0f.\n",
560 if (rigorous_checking) {
563 if (strlen(race_info.rejection)) {
570 FPRINTF(f,
"Passwords are required to be at least %d characters long.\n",
573 }
else if (!strcmp(race_info
.password,
"XXXX")) {
574 FPRINTF(f,
"You must change your password from the default.\n");
577 if (!strcmp(race_info
.address,
"Unknown")) {
578 FPRINTF(f,
"You must change your email address.\n");
584 FPRINTF(f,
"You can't have negative points left!\n");
592 "Non-jovian races must be compat with at least one sector " 593 "type besides plated.\n");
598 (race_info
.compat[i] == 100.0))
602 "You must have 100%% compat with at least one sector type " 603 "that is common on\n your home planet type. (Marked with a " 620 bcopy(&last, &race_info,
sizeof(
struct x));
634 bzero(&race_info,
sizeof(race_info));
642 strcpy(race_info
.name,
"Unknown");
643 strcpy(race_info
.address,
"Unknown");
646 bcopy(&race_info, &last,
sizeof(
struct x));
661 static void help(
int argc,
char *argv[]) {
675 enroll = process = helpp = load = modify = print = save = send2 = quit = 1;
678 "To execute a command, type it at the command line. All commands\n");
679 printf(
"and command arguments maybe either upper or lower case, and/or\n");
680 printf(
"abbreviated. The available commands are:\n");
682 enroll = process = helpp = load = modify = print = save = send2 = quit = 0;
683 for (i = 1; i < argc; i++) {
686 if (!strncasecmp(argv[i],
"enroll", j) && (!isserver))
690 if (!strncasecmp(argv[i],
"help", j))
692 else if (!strncasecmp(argv[i],
"load", j) && (!isserver))
694 else if (!strncasecmp(argv[i],
"modify", j))
696 else if (!strncasecmp(argv[i],
"print", j))
699 else if (!strncasecmp(argv[i],
"process", j) && (!isserver))
702 else if (!strncasecmp(argv[i],
"save", j) && (!isserver))
704 else if (!strncasecmp(argv[i],
"send", j))
706 else if (!strncasecmp(argv[i],
"quit", j))
710 printf(
"\"%s\" is not a command.\n", argv[i]);
719 printf(
"\t\t This command will add the current race to the game,\n");
720 printf(
"\t\t after checking to make sure it has all points spent, and\n");
721 printf(
"\t\t other such administrivia.\n");
727 printf(
"Help [command]*\n");
728 printf(
"\t\t This command gives you information about racegen's\n");
729 printf(
"\t\t commands. If called with no arguments, it will print\n");
730 printf(
"\t\t information about all available commands. Otherwise it\n");
731 printf(
"\t\t only prints information about the specified commands.\n");
736 printf(
"Load [filename]\n");
737 printf(
"\t\t This command will load your race from the file specified\n");
738 printf(
"\t\t in the optional first argument, or from the file \"%s\"\n",
740 printf(
"\t\t if no argument is given.\n");
745 printf(
"Modify arg1 arg2\n");
746 printf(
"\t\t This command allows you to change the values of your\n");
748 "\t\t race's name, password, type, attributes, planet, and compats.\n");
749 printf(
"\t\t The syntax is as follows:\n");
750 printf(
"\t\t <modify> ::= modify <attr> <value>\n");
751 printf(
"\t\t | modify address <string>\n");
752 printf(
"\t\t | modify name <string>\n");
753 printf(
"\t\t | modify password <string>\n");
754 printf(
"\t\t | modify planet <planettype>\n");
756 printf(
"\t\t | modify privilege <privtype>\n");
758 printf(
"\t\t | modify race <racetype>\n");
759 printf(
"\t\t | modify <sectortype> <value>\n");
764 if ((i % 3) == 2) printf(
"\n\t\t ");
771 printf(
" | %s", planet_print_name[i]);
787 printf(
" | %s", sector_print_name[i]);
798 printf(
"Print [filename]\n");
799 printf(
"\t\t With no argument, this command prints your race to the\n");
800 printf(
"\t\t screen. It is automatically executed after each modify.\n");
801 printf(
"\t\t Otherwise it saves a text copy of your race to the file\n");
802 printf(
"\t\t specified in the first argument.\n");
808 printf(
"Process filename\n");
809 printf(
"\t\t This command will repeatedly load races from filename,\n");
810 printf(
"\t\t and then try to enroll them. You can thus easily \n");
811 printf(
"\t\t enroll tens of players at once. \n");
817 printf(
"Save [filename]\n");
818 printf(
"\t\t This command will save your race to the file specified in\n");
819 printf(
"\t\t the optional first argument, or to the file \"%s\"\n",
821 printf(
"\t\t if no argument is given.\n");
827 printf(
"\t\t This command will send your race to God, (%s).\n",
TO);
828 printf(
"\t\t It will not work unless you have spent all your points.\n");
834 printf(
"\t\t This command will prompt you to save your work if you\n");
835 printf(
"\t\t haven't already, and then exit this program.\n");
846 char from_address[80];
848 #define FSCANF(file, format, variable) 849 if (EOF
== fscanf((file), (format), (variable))) goto premature_end_of_file 853 if (0 == strcmp(buf,
"From:")) {
855 strcpy(from_address, buf);
879 premature_end_of_file:
880 printf(
"Error: premature end of file.\n");
889 FILE *f = fopen(filename,
"r");
892 printf(
"Unable to open file \"%s\".\n", filename);
900 static void load(
int argc,
char *argv[]) {
904 bcopy(&race_info, &last,
sizeof(
struct x));
906 i =
Dialogue("This race has been altered; load anyway?", "yes", "no", 0
);
914 printf(
"Load from file \"%s\" failed.\n", c);
915 bcopy(&last, &race_info,
sizeof(
struct x));
917 printf(
"Loaded race from file \"%s\".\n", c);
924 static int modify(
int argc,
char *argv[]) {
927 static char *help_strings[2] = {
nullptr,
"modify"};
936 bcopy(&race_info, &last,
sizeof(
struct x));
941 if (!strncasecmp(argv[1], attr[i].print_name, j)) {
944 if (!strncasecmp(argv[2],
"no", j))
946 else if (!strncasecmp(argv[2],
"yes", j))
953 race_info
.attr[i] = f;
960 if (!strncasecmp(argv[1],
"name", j)) {
961 strcpy(race_info
.name, argv[2]);
967 if (!strncasecmp(argv[1],
"address", j)) {
975 if (!strncasecmp(argv[1],
"privilege", j)) {
977 for (i = FIRST_PRIV_TYPE; i <= LAST_PRIV_TYPE; i++)
978 if (!strncasecmp(argv[2], priv_print_name[i], j)) {
979 race_info.priv_type = i;
980 return critique_modification();
982 race_info.priv_type = atof(argv[2]);
983 return critique_modification();
989 if (!strncasecmp(argv[1],
"planet", j)) {
992 if (!strncasecmp(argv[2], planet_print_name[i], j)) {
994 bzero(race_info.compat,
sizeof(race_info.compat));
1003 printf(
"\"%s\" is not a valid planet type.\n", argv[2]);
1009 if (!strncasecmp(argv[1],
"password", j)) {
1016 if (!strncasecmp(argv[1],
"race", j)) {
1017 j = strlen(argv[2]);
1019 if (!strncasecmp(argv[2], race_print_name[i], j)) {
1034 printf(
"\"%s\" is not a valid race type.\n", argv[2]);
1047 if (!strncasecmp(argv[1], sector_print_name[i], j)) {
1048 race_info
.compat[i] = atof(argv[2]);
1055 printf(
"Modify: didn't recognize the first argument \"%s\".\n", argv[1]);
1056 printf(
"Type \"help modify\" for more information on modify.\n");
1063 if (verbose) fprintf 1069 fprintf(f,
" %s", race_info
.address);
1073 fprintf(f,
" %s", race_info
.name);
1081 FPRINTF(f,
"Privileges:");
1083 fprintf(f,
"%11.11s", priv_print_name[race_info.priv_type]);
1112 fprintf(f, (race_info
.attr[i] > 0.0) ?
" yes " :
" no ");
1114 fprintf(f,
" %7.2f", race_info
.attr[i]);
1116 FPRINTF(f, (i & 01) ?
"\n" :
" ");
1125 fprintf(f,
" %3.0f", race_info
.compat[i]);
1130 FPRINTF(f, (i & 01) ?
"\n" :
" ");
1142 FILE *f = fopen(filename,
"w");
1145 printf(
"Unable to open file \"%s\".\n", filename);
1153 static void print(
int argc,
char *argv[]) {
1157 printf(
"Printed race to file \"%s\".\n", argv[1]);
1160 static void save(
int argc,
char *argv[]) {
1166 printf(
"Saved race to file \"%s\".\n", race_info
.filename);
1175 bcopy(&race_info, &last,
sizeof(
struct x));
1180 printf(
"Unable to open file \"%s\".\n", race_info
.password);
1183 fprintf(f,
"From: %s\n", race_info
.address);
1184 fprintf(f,
"Subject: %s Race Submission\n",
GAME);
1190 printf(
"Mailing race to %s : ",
TO);
1197 printf(
"Unable to open file \"%s\".\n", race_info
.password);
1200 fprintf(f,
"From: %s\n", race_info
.address);
1201 fprintf(f,
"Subject: %s Race Submission\n\n",
GAME);
1206 printf(
"Mailing race to %s : ", race_info
.address);
1215 #define INPUTSIZE 512
1223 printf(
"%s", prompt);
1224 va_start(ap, prompt);
1225 while ((carg = va_arg(ap,
char *)) !=
nullptr) {
1227 printf(
" [%s", carg);
1230 printf(
"/%s", carg);
1232 argv[argc++] = carg++;
1235 if (argc) printf(
"]");
1241 if (argc == 0)
return -1;
1242 len = strlen(input) - 1;
1244 for (i = 0; i < argc; i++)
1245 if (!strncasecmp(argv[i], input, len))
return i;
1248 printf(
"Please enter ");
1249 for (i = 0; i < argc - 1; i++) {
1250 printf(
"\"%s\", ", argv[i]);
1252 printf(
"or \"%s\"> ", argv[i]);
1266 i =
Dialogue("Save this race before quitting?", "yes", "no", "abort", 0
);
1286 for (i = 0; i < argc; i++)
1287 printf (
"%d: \"%s\"\n", i, argv[i]);
1290 printf(
"Type \"help\" for help.\n");
1293 i = strlen(argv[0]);
1295 if (!strncasecmp(argv[0],
"enroll", i) && !isserver)
1299 if (!strncasecmp(argv[0],
"help", i))
1301 else if (!strncasecmp(argv[0],
"load", i) && !isserver)
1303 else if (!strncasecmp(argv[0],
"modify", i))
1305 else if (!strncasecmp(argv[0],
"print", i))
1308 else if (!strncasecmp(argv[0],
"process", i) && !isserver)
1309 process(argc, argv);
1311 else if (!strncasecmp(argv[0],
"save", i) && !isserver)
1313 else if (!strncasecmp(argv[0],
"send", i))
1315 else if (!strncasecmp(argv[0],
"quit", i))
1318 printf(
"Unknown command \"%s\". Type \"help\" for help.\n", argv[0]);
1346 printf(
"Command [help/modify/print/send/quit]> ");
1348 printf(
"%s [enroll/help/load/modify/print/process/save/send/quit]> ",
1349 level ?
"Fix" :
"Command");
1351 printf(
"Command [help/load/modify/print/save/send/quit]> ");
1354 com = fgets(buf,
BUFSIZE, stdin);
1355 buf[strlen(buf) - 1] =
'\0';
1357 for (i = 0; i < 4; i++) {
1358 while (*com && (*com ==
' ')) *com++ =
'\0';
1361 while (*com && (*com !=
' ')) com++;
1374 printf(
"Galactic Bloodshed Race Generator %s\n",
VERSION);
1376 printf(
"Finished races will be sent to %s.\n",
TO);
1377 printf(
"***************************************************************\n");
1381 printf(
"Starts: %s\n",
STARTS);
1383 printf(
"Any race may be refused or modified by God for any reason!\n");
1385 printf(
"DEADLINE: %s\n",
DEADLINE);
1386 printf(
"***************************************************************\n");
1387 printf(
"Update schedule:\n");
1390 printf(
"If you cannot make this update schedule, do NOT send in a race!\n");
1391 printf(
"***************************************************************\n");
static attribute attr[N_ATTRIBUTES]
static void execute(int argc, char **argv)
static void print(int argc, char *argv[])
int critique_to_file(FILE *f, int rigorous_checking, int is_player_race)
static int modify(int argc, char *argv[])
static void save(int argc, char *argv[])
#define STATUS_UNBALANCED
double compat[N_SECTOR_TYPES]
struct x race_info cost_info last
const double compat_cov[N_SECTOR_TYPES][N_SECTOR_TYPES]
static int print_to_filename(const char *filename, int verbose)
static void help(int, char *[])
const int planet_cost[N_HOME_PLANET_TYPES]
double attr[N_ATTRIBUTES]
const char * priv_print_name[N_PRIV_TYPES]
int load_from_file(FILE *g)
#define END_RECORD_STRING
const int race_cost[N_RACE_TYPES]
#define FIRST_SECTOR_TYPE
#define FIRST_HOME_PLANET_TYPE
static void send2(int, char **)
#define FSCANF(file, format, variable)
void print_to_file(FILE *f, int verbose)
#define MIN_PASSWORD_LENGTH
const int blah[N_SECTOR_TYPES]
static int load_from_filename(const char *filename)
const char * planet_print_name[N_HOME_PLANET_TYPES]
int Dialogue(const char *,...)
const double planet_compat_cov[N_HOME_PLANET_TYPES][N_SECTOR_TYPES]
static int critique_modification()
#define START_RECORD_STRING
const char * sector_print_name[N_SECTOR_TYPES]
#define N_HOME_PLANET_TYPES
static void load(int, char *[])
void modify_print_loop(int level)
static void quit(int argc, char **argv)
#define LAST_HOME_PLANET_TYPE
const char * race_print_name[N_RACE_TYPES]