![]() |
Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members
eol.cppGo to the documentation of this file.00001 #include <stdio.h> 00002 #include <string.h> 00003 #include <sys/types.h> 00004 #include <sys/stat.h> 00005 #include <unistd.h> 00006 #include <pthread.h> 00007 #include <sys/socket.h> 00008 #include <netinet/in.h> 00009 #include <sys/time.h> 00010 #include <signal.h> 00011 #include <stdlib.h> 00012 #include <mysql/mysql.h> 00013 #include <libmysqlwrapped.h> 00014 #include <libeamon.h> 00015 00016 #include "a.h" 00017 #include "ParserIO.h" 00018 #include "Parser.h" 00019 #include "THREAD.h" 00020 #include "eol.h" 00021 00022 00023 ADV *advbase = NULL; 00024 EVENT *eventbase = NULL; 00025 THREAD *threadbase = NULL; 00026 static int quit_listen = 0; 00027 static int quit_main = 0; 00028 pthread_mutex_t event_mutex; 00029 pthread_mutex_t thread_mutex; 00030 00031 00032 #define PRINT(x) if (pThread -> write_text(x) == -1) \ 00033 goto crap; 00034 00035 #define INPUT(x) n = 200; \ 00036 if (pThread -> read_text(x, &n) == -1) \ 00037 { \ 00038 perror("read() failed"); \ 00039 goto crap; \ 00040 } 00041 00042 00043 void *sock_thread(void *zz) 00044 { 00045 Database db("localhost","root","","eamon"); 00046 Query q(db); 00047 THREAD *pThread = (THREAD *)zz; 00048 FILE *fil; 00049 int s = pThread -> socket; 00050 int quit = 0; 00051 int n; 00052 int i; 00053 int menu; 00054 char slask[200]; 00055 char cmd[200]; 00056 00057 pThread -> cmdline.SetParserIO( pThread ); 00058 pThread -> m_more = 1; 00059 pThread -> account = NULL; 00060 00061 while (!pThread -> account) 00062 { 00063 PRINT("--------------------------------------------------\n"); 00064 PRINT(" Welcome to The Wonderful World of Eamon *Online*\n"); 00065 PRINT("--------------------------------------------------\n"); 00066 PRINT(" These are the original Eamon Adventures, being\n"); 00067 PRINT(" run on an applesoft basic interpreter for Linux.\n"); 00068 PRINT(" Some special commands extend your stay here:\n"); 00069 PRINT(" 'hi or \"hi - speak to other players\n"); 00070 PRINT(" /who - see who's online right now\n"); 00071 PRINT(" /emote <something> - emote is cool\n"); 00072 PRINT(" /abort - well, sometimes programs hang\n"); 00073 PRINT(" New user? Just enter your preferred login handle\n"); 00074 PRINT(" at the prompt below, and you will be up & away.\n"); 00075 PRINT("--------------------------------------------------\n"); 00076 PRINT(" My email: eamon@alhem.net\n"); 00077 PRINT("--------------------------------------------------\n"); 00078 PRINT("\n"); 00079 PRINT("Login: "); 00080 pThread -> adjust_case = 1; 00081 INPUT(cmd) else 00082 { 00083 sprintf(slask,"select * from account where login='%s'",cmd); 00084 pThread -> account = new db::Account(&db,slask); 00085 if (!pThread -> account -> num) 00086 { 00087 PRINT("Account '%s' does not exist, create (y,N)? "); 00088 INPUT(slask) 00089 if (*slask == 'Y') 00090 { 00091 PRINT("Enter password: "); 00092 INPUT(slask) 00093 pThread -> account -> password = slask; 00094 PRINT("Verify password: "); 00095 INPUT(slask) 00096 if (!strcmp(slask,pThread -> account -> password.c_str())) 00097 { 00098 pThread -> account -> login = cmd; 00099 pThread -> account -> num_logins = 1; 00100 pThread -> account -> save(); 00101 sprintf(slask,"update account set created_date=curdate() where num=%ld",pThread -> account -> num); 00102 q.execute(slask); 00103 } 00104 else 00105 { 00106 delete pThread -> account; 00107 pThread -> account = NULL; 00108 } 00109 } 00110 else 00111 { 00112 delete pThread -> account; 00113 pThread -> account = NULL; 00114 } 00115 } 00116 else 00117 { 00118 PRINT("Password: "); 00119 INPUT(slask); 00120 if (!strcmp(slask,pThread -> account -> password.c_str())) 00121 { 00122 sprintf(slask,"update account set last_login=curdate(),num_logins=num_logins+1 where num=%ld",pThread -> account -> num); 00123 q.execute(slask); 00124 } 00125 else 00126 { 00127 delete pThread -> account; 00128 pThread -> account = NULL; 00129 } 00130 } 00131 } 00132 } 00133 00134 sprintf(slask,"%s/%s",EA_ACCTS,pThread -> account -> login.c_str()); 00135 if (chdir(slask) == -1) 00136 { 00137 perror("chdir() failed"); 00138 if (mkdir(slask, 0755) == -1) 00139 { 00140 perror("mkdir() failed"); 00141 PRINT("Failed\n"); 00142 goto crap; 00143 } 00144 if (chdir(slask) == -1) 00145 { 00146 perror("chdir() failed again"); 00147 PRINT("Failed\n"); 00148 goto crap; 00149 } 00150 sprintf(slask,"cp -a %s/ea.master .",EA_DISKS); 00151 system(slask); 00152 } 00153 00154 sprintf(slask,"%s/%s/ea.master",EA_ACCTS,pThread -> account -> login.c_str()); 00155 if (chdir(slask) == -1) 00156 { 00157 perror("chdir(ea.master) failed"); 00158 PRINT("Failed\n"); 00159 goto crap; 00160 } 00161 00162 sprintf(slask, "%s has entered.", pThread -> account -> login.c_str()); 00163 pThread -> add_event( slask ); 00164 00165 menu = 1; 00166 while (!quit) 00167 { 00168 PRINT("\n"); 00169 00170 pThread -> adjust_case = 0; 00171 00172 if (menu) 00173 { 00174 sprintf(slask,"*** The Wonderful World of Eamon (Online): %s ***\n",pThread -> account -> login.c_str()); 00175 PRINT(slask); 00176 PRINT(" 1/ Play\n"); 00177 PRINT(" 2/ Display characters\n"); 00178 PRINT(" 3/ Edit (remove) characters\n"); 00179 // PRINT(" 4/ Select adventure\n"); 00180 PRINT(" 5/ Resume adventure\n"); 00181 PRINT(" 6/ Install utility disks\n"); 00182 PRINT(" 7/ BUILD mode (just type HELP after entering)\n"); 00183 PRINT(" 8/ Backup CHARACTERS - BEFORE, not after ;)\n"); 00184 PRINT(" 9/ Restore backup\n"); 00185 PRINT(" 0/ Quit\n"); 00186 menu = 0; 00187 } 00188 PRINT("1-9,0,?> "); 00189 00190 INPUT(slask) 00191 if (!*slask) 00192 strcpy(slask,"7"); 00193 switch (atoi(slask)) 00194 { 00195 case 1: 00196 pThread -> cmdline.finish(); 00197 pThread -> adjust_case = 1; 00198 strcpy(cmd,"RUN HELLO"); 00199 pThread -> cmdline.cmd(cmd); 00200 pThread -> cmdline.finish(); 00201 menu = 1; 00202 break; 00203 case 2: 00204 pThread -> cmdline.finish(); 00205 pThread -> adjust_case = 1; 00206 strcpy(cmd,"RUN DISPLAY CHARACTERS"); 00207 pThread -> cmdline.cmd(cmd); 00208 pThread -> cmdline.finish(); 00209 menu = 1; 00210 break; 00211 case 3: 00212 pThread -> cmdline.finish(); 00213 pThread -> adjust_case = 1; 00214 strcpy(cmd,"RUN EDIT CHARACTERS"); 00215 pThread -> cmdline.cmd(cmd); 00216 pThread -> cmdline.finish(); 00217 menu = 1; 00218 break; 00219 case 4: 00220 if (pThread -> get_adv() == -1) 00221 goto crap; 00222 break; 00223 case 5: 00224 if (pThread -> selected) 00225 { 00226 sprintf(slask,"../%s",pThread -> selected -> dir); 00227 if (chdir(slask) == -1) 00228 perror("chdir() failed"); 00229 } 00230 if ((fil = fopen("EAMON.NAME","rb")) != NULL) 00231 { 00232 unsigned char c; 00233 00234 i = 0; 00235 fread(&c,1,1,fil); 00236 while (!feof(fil) && c && c != 0x8d) 00237 { 00238 slask[i++] = c & 0x7f; 00239 fread(&c,1,1,fil); 00240 } 00241 fclose(fil); 00242 slask[i] = 0; 00243 00244 PRINT("Resuming adventure '"); 00245 PRINT( slask ); 00246 PRINT("'\n"); 00247 00248 pThread -> cmdline.finish(); 00249 pThread -> adjust_case = 1; 00250 sprintf(cmd,"RUN %s",slask); 00251 pThread -> cmdline.cmd( cmd ); 00252 pThread -> cmdline.finish(); 00253 menu = 1; 00254 } 00255 else 00256 { 00257 chdir("../ea.master"); 00258 } 00259 break; 00260 case 6: 00261 sprintf(slask,"cp -a %s/* %s/%s",EA_UTILS,EA_ACCTS,pThread -> account -> login.c_str()); 00262 system(slask); 00263 PRINT("Ok.\n"); 00264 break; 00265 case 7: 00266 PRINT("Just type HELP\n"); 00267 pThread -> cmdline.m_current_line = pThread -> cmdline.m_linebase; 00268 while (1) 00269 { 00270 PRINT("\n>"); 00271 INPUT( slask ) 00272 if (!strncasecmp(slask,"quit",4) || !*slask) 00273 break; 00274 else 00275 pThread -> cmdline.cmd( slask ); 00276 } 00277 break; 00278 case 8: 00279 system("cp CHARACTERS CHARACTERS.BACKUP"); 00280 break; 00281 case 9: 00282 system("cp CHARACTERS.BACKUP CHARACTERS"); 00283 break; 00284 00285 default: 00286 if (*slask == '0') 00287 { 00288 sprintf(slask,"%s has left.",pThread -> account -> login.c_str()); 00289 pThread -> add_event(slask); 00290 quit++; 00291 } 00292 else 00293 if (*slask == '?') 00294 menu = 1; 00295 } 00296 } 00297 crap: 00298 close(s); 00299 delete pThread -> account; 00300 pThread -> account = NULL; 00301 pThread -> running = 0; 00302 return zz; 00303 } 00304 00305 void *listen_thread(void *zz) 00306 { 00307 THREAD *t; 00308 THREAD *prev; 00309 FILE *fil; 00310 void *retval; 00311 struct sockaddr_in sa; 00312 socklen_t len; 00313 struct timeval tv; 00314 fd_set rfds; 00315 long l = 0; 00316 int s = socket(AF_INET, SOCK_STREAM, 0); 00317 int a_s; 00318 int optval; 00319 int n; 00320 00321 sa.sin_family = AF_INET; // hp -> h_addrtype; 00322 sa.sin_port = htons(4444); 00323 // sa.sin_addr.s_addr = 0; 00324 memmove(&sa.sin_addr,&l,4); 00325 // sa.sin_zero[0] = 0; 00326 // sa.sin_zero[1] = 0; 00327 // sa.sin_zero[2] = 0; 00328 // sa.sin_zero[3] = 0; 00329 // sa.sin_zero[4] = 0; 00330 // sa.sin_zero[5] = 0; 00331 // sa.sin_zero[6] = 0; 00332 // sa.sin_zero[7] = 0; 00333 00334 if (s == -1) 00335 { 00336 perror("socket() failed"); 00337 exit(-1); 00338 } 00339 optval = 1; 00340 if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void *)&optval, sizeof(optval)) == -1) 00341 { 00342 perror("setsockopt() failed"); 00343 exit(-1); 00344 } 00345 optval = 1; 00346 if (setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (void *)&optval, sizeof(optval)) == -1) 00347 { 00348 perror("setsockopt() failed"); 00349 exit(-1); 00350 } 00351 if (bind(s, (struct sockaddr *)&sa, sizeof(sa)) == -1) 00352 { 00353 perror("bind() failed"); 00354 exit(-1); 00355 } 00356 if (listen(s, 3) == -1) 00357 { 00358 perror("listen() failed"); 00359 exit(-1); 00360 } 00361 00362 while (!quit_listen) 00363 { 00364 FD_ZERO(&rfds); 00365 FD_SET(s, &rfds); 00366 00367 tv.tv_sec = 1; 00368 tv.tv_usec = 0; 00369 n = select(s + 1, &rfds, NULL, NULL, &tv); 00370 if (n == -1) 00371 { 00372 perror("select() failed"); 00373 } else 00374 if (n > 0) 00375 { 00376 if (FD_ISSET(s, &rfds)) 00377 { 00378 a_s = accept(s, (struct sockaddr *)&sa, &len); 00379 if (a_s == -1) 00380 { 00381 perror("accept() failed"); 00382 } 00383 else 00384 { 00385 fil = fopen("sa_log.bin","ab"); 00386 fwrite(&len,1,sizeof(len),fil); 00387 fwrite(&sa,1,len,fil); 00388 fclose(fil); 00389 00390 for (int i = 0; i < (int)len; i++) 00391 { 00392 if (i) 00393 printf("."); 00394 printf("%d",((unsigned char *)&sa)[i]); 00395 } 00396 printf("\n"); 00397 00398 t = new THREAD; 00399 t -> socket = a_s; 00400 t -> running = 1; 00401 pthread_mutex_lock(&thread_mutex); 00402 t -> next = threadbase; 00403 threadbase = t; 00404 pthread_mutex_unlock(&thread_mutex); 00405 if (pthread_create(&t -> thread, NULL, sock_thread, t)) 00406 { 00407 printf("Couldn't create socket thread\n"); 00408 exit(-1); 00409 } 00410 } 00411 } 00412 } // if (n > 0) 00413 pthread_mutex_lock(&thread_mutex); 00414 do 00415 { 00416 prev = NULL; 00417 for (t = threadbase; t; t = t -> next) 00418 if (!t -> running) 00419 { 00420 if (pthread_join(t -> thread,&retval)) 00421 { 00422 printf("pthread_join failed\n"); 00423 } 00424 if (!prev) 00425 threadbase = t -> next; 00426 else 00427 prev -> next = t -> next; 00428 delete t; 00429 printf("sock_thread() removed\n"); 00430 break; 00431 } 00432 else 00433 { 00434 prev = t; 00435 } 00436 } while (t); 00437 pthread_mutex_unlock(&thread_mutex); 00438 } 00439 close(s); 00440 printf("Listen loop end\n"); 00441 for (t = threadbase; t; t = t -> next) 00442 { 00443 t -> running = 0; 00444 if (pthread_join(t -> thread,&zz)) 00445 { 00446 printf("pthread_join() failed: socket thread\n"); 00447 } 00448 } 00449 pthread_mutex_lock(&thread_mutex); 00450 for (t = threadbase; t; t = prev) 00451 { 00452 prev = t -> next; 00453 delete t; 00454 } 00455 pthread_mutex_unlock(&thread_mutex); 00456 return zz; 00457 } 00458 00459 void sighandler(int sig) 00460 { 00461 printf("Signal: %d\n",sig); 00462 quit_main = 1; 00463 quit_listen = 1; 00464 } 00465 00466 void sigpipe(int sig) 00467 { 00468 } 00469 00470 void strzcpy(char *slask,char *s) 00471 { 00472 strcpy(slask,s ? s : ""); 00473 while (strlen(slask) && slask[strlen(slask) - 1] == ' ') 00474 slask[strlen(slask) - 1] = 0; 00475 } 00476 00477 void read_games(void) 00478 { 00479 FILE *fil; 00480 ADV *adv; 00481 ADV *q; 00482 char *s; 00483 char descr[200]; 00484 char slask[200]; 00485 char dirname[200]; 00486 00487 if ((fil = fopen(EA_GAMES,"rt")) != NULL) 00488 { 00489 fgets(slask,200,fil); 00490 while (!feof(fil)) 00491 { 00492 slask[strlen(slask) - 1] = 0; 00493 adv = new ADV; 00494 s = strtok(slask,";"); 00495 strzcpy(descr,s); 00496 s = strtok(NULL, ";"); 00497 strzcpy(adv -> author,s); 00498 s = strtok(NULL, ";"); 00499 strzcpy(adv -> rating,s); 00500 s = strtok(NULL, ";"); 00501 strzcpy(adv -> flags,s); 00502 s = strtok(NULL, ";"); 00503 strzcpy(dirname,s); 00504 if (*dirname) 00505 { 00506 adv -> next = NULL; 00507 descr[3] = 0; 00508 adv -> num = atoi(descr); 00509 strcpy(adv -> descr,descr + 5); 00510 strcpy(adv -> dir,dirname); 00511 if (!advbase) 00512 advbase = adv; 00513 else 00514 { 00515 q = advbase; 00516 while (q -> next) 00517 q = q -> next; 00518 q -> next = adv; 00519 } 00520 printf("%d: '%s' by '%s' rating '%s'\n", 00521 adv -> num, 00522 adv -> descr, 00523 adv -> author, 00524 adv -> rating); 00525 } 00526 else 00527 { 00528 delete adv; 00529 } 00530 fgets(slask,200,fil); 00531 } 00532 fclose(fil); 00533 } 00534 } 00535 00536 int main(int argc,char *argv[]) 00537 { 00538 void *zz; 00539 pthread_t listen_t; 00540 00541 signal(SIGINT, sighandler); 00542 signal(SIGPIPE, sigpipe); 00543 00544 read_games(); 00545 00546 eventbase = new EVENT; 00547 eventbase -> next = NULL; 00548 strcpy(eventbase -> text,"Startup."); 00549 00550 pthread_mutex_init(&event_mutex, NULL); 00551 pthread_mutex_init(&thread_mutex, NULL); 00552 00553 if (pthread_create(&listen_t, NULL, listen_thread, NULL)) 00554 { 00555 printf("Couldn't create listen thread\n"); 00556 exit(-1); 00557 } 00558 while (!quit_main) 00559 { 00560 sleep(1); 00561 } 00562 printf("Main loop end\n"); 00563 if (pthread_join(listen_t,&zz)) 00564 { 00565 printf("listen thread pthread_join() failed\n"); 00566 } 00567 return 0; 00568 } 00569 |