00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 #if defined(macintosh)
00047 #include <types.h>
00048 #else
00049 #include <sys/types.h>
00050 #include <sys/time.h>
00051 #endif
00052
00053 #include <ctype.h>
00054 #include <errno.h>
00055 #include <stdio.h>
00056 #include <string.h>
00057 #include <stdlib.h>
00058 #include <time.h>
00059 #include <signal.h>
00060 #include <unistd.h>
00061 #include <stdarg.h>
00062
00063 #include "merc.h"
00064 #include "interp.h"
00065 #include "recycle.h"
00066 #include "tables.h"
00067
00068
00069
00070
00071 #if defined(sun)
00072 #undef MALLOC_DEBUG
00073 #endif
00074
00075 #if defined(MALLOC_DEBUG)
00076 #include <malloc.h>
00077 extern int malloc_debug args ((int));
00078 extern int malloc_verify args ((void));
00079 #endif
00080
00081
00082
00083
00084
00085
00086
00087
00088 #if defined(apollo)
00089 #define __attribute(x)
00090 #endif
00091
00092 #if defined(unix)
00093 #include <signal.h>
00094 #endif
00095
00096 #if defined(apollo)
00097 #undef __attribute
00098 #endif
00099
00100
00101
00102
00103
00104
00105 #if defined(macintosh) || defined(MSDOS)
00106 const char echo_off_str[] = { '\0' };
00107 const char echo_on_str[] = { '\0' };
00108 const char go_ahead_str[] = { '\0' };
00109 #endif
00110
00111 #if defined(unix)
00112 #include <fcntl.h>
00113 #include <netdb.h>
00114 #include <netinet/in.h>
00115 #include <sys/socket.h>
00116 #include <netinet/in.h>
00117 #include <arpa/inet.h>
00118 #include "telnet.h"
00119 const char echo_off_str[] = { IAC, WILL, TELOPT_ECHO, '\0' };
00120 const char echo_on_str[] = { IAC, WONT, TELOPT_ECHO, '\0' };
00121 const char go_ahead_str[] = { IAC, GA, '\0' };
00122 #endif
00123
00124
00125
00126
00127
00128
00129 #if defined(_AIX)
00130 #include <sys/select.h>
00131 int accept args ((int s, struct sockaddr * addr, int *addrlen));
00132 int bind args ((int s, struct sockaddr * name, int namelen));
00133 void bzero args ((char *b, int length));
00134 int getpeername args ((int s, struct sockaddr * name, int *namelen));
00135 int getsockname args ((int s, struct sockaddr * name, int *namelen));
00136 int gettimeofday args ((struct timeval * tp, struct timezone * tzp));
00137 int listen args ((int s, int backlog));
00138 int setsockopt args ((int s, int level, int optname, void *optval,
00139 int optlen));
00140 int socket args ((int domain, int type, int protocol));
00141 #endif
00142
00143 #if defined(apollo)
00144 #include <unistd.h>
00145 void bzero args ((char *b, int length));
00146 #endif
00147
00148 #if defined(__hpux)
00149 int accept args ((int s, void *addr, int *addrlen));
00150 int bind args ((int s, const void *addr, int addrlen));
00151 void bzero args ((char *b, int length));
00152 int getpeername args ((int s, void *addr, int *addrlen));
00153 int getsockname args ((int s, void *name, int *addrlen));
00154 int gettimeofday args ((struct timeval * tp, struct timezone * tzp));
00155 int listen args ((int s, int backlog));
00156 int setsockopt args ((int s, int level, int optname,
00157 const void *optval, int optlen));
00158 int socket args ((int domain, int type, int protocol));
00159 #endif
00160
00161 #if defined(interactive)
00162 #include <net/errno.h>
00163 #include <sys/fnctl.h>
00164 #endif
00165
00166 #if defined(linux)
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179 int close args ((int fd));
00180 int gettimeofday args ((struct timeval * tp, struct timezone * tzp));
00181
00182 int select args ((int width, fd_set * readfds, fd_set * writefds,
00183 fd_set * exceptfds, struct timeval * timeout));
00184 int socket args ((int domain, int type, int protocol));
00185
00186 #endif
00187
00188 #if defined(macintosh)
00189 #include <console.h>
00190 #include <fcntl.h>
00191 #include <unix.h>
00192 struct timeval {
00193 time_t tv_sec;
00194 time_t tv_usec;
00195 };
00196 #if !defined(isascii)
00197 #define isascii(c) ( (c) < 0200 )
00198 #endif
00199 static long theKeys[4];
00200
00201 int gettimeofday args ((struct timeval * tp, void *tzp));
00202 #endif
00203
00204 #if defined(MIPS_OS)
00205 extern int errno;
00206 #endif
00207
00208 #if defined(MSDOS)
00209 int gettimeofday args ((struct timeval * tp, void *tzp));
00210 int kbhit args ((void));
00211 #endif
00212
00213 #if defined(NeXT)
00214 int close args ((int fd));
00215 int fcntl args ((int fd, int cmd, int arg));
00216 #if !defined(htons)
00217 u_short htons args ((u_short hostshort));
00218 #endif
00219 #if !defined(ntohl)
00220 u_long ntohl args ((u_long hostlong));
00221 #endif
00222 int read args ((int fd, char *buf, int nbyte));
00223 int select args ((int width, fd_set * readfds, fd_set * writefds,
00224 fd_set * exceptfds, struct timeval * timeout));
00225 int write args ((int fd, char *buf, int nbyte));
00226 #endif
00227
00228 #if defined(sequent)
00229 int accept args ((int s, struct sockaddr * addr, int *addrlen));
00230 int bind args ((int s, struct sockaddr * name, int namelen));
00231 int close args ((int fd));
00232 int fcntl args ((int fd, int cmd, int arg));
00233 int getpeername args ((int s, struct sockaddr * name, int *namelen));
00234 int getsockname args ((int s, struct sockaddr * name, int *namelen));
00235 int gettimeofday args ((struct timeval * tp, struct timezone * tzp));
00236 #if !defined(htons)
00237 u_short htons args ((u_short hostshort));
00238 #endif
00239 int listen args ((int s, int backlog));
00240 #if !defined(ntohl)
00241 u_long ntohl args ((u_long hostlong));
00242 #endif
00243 int read args ((int fd, char *buf, int nbyte));
00244 int select args ((int width, fd_set * readfds, fd_set * writefds,
00245 fd_set * exceptfds, struct timeval * timeout));
00246 int setsockopt args ((int s, int level, int optname, caddr_t optval,
00247 int optlen));
00248 int socket args ((int domain, int type, int protocol));
00249 int write args ((int fd, char *buf, int nbyte));
00250 #endif
00251
00252
00253 #if defined(sun)
00254 int accept args ((int s, struct sockaddr * addr, int *addrlen));
00255 int bind args ((int s, struct sockaddr * name, int namelen));
00256 void bzero args ((char *b, int length));
00257 int close args ((int fd));
00258 int getpeername args ((int s, struct sockaddr * name, int *namelen));
00259 int getsockname args ((int s, struct sockaddr * name, int *namelen));
00260 int listen args ((int s, int backlog));
00261 int read args ((int fd, char *buf, int nbyte));
00262 int select args ((int width, fd_set * readfds, fd_set * writefds,
00263 fd_set * exceptfds, struct timeval * timeout));
00264
00265 #if !defined(__SVR4)
00266 int gettimeofday args ((struct timeval * tp, struct timezone * tzp));
00267
00268 #if defined(SYSV)
00269 int setsockopt args ((int s, int level, int optname,
00270 const char *optval, int optlen));
00271 #else
00272 int setsockopt args ((int s, int level, int optname, void *optval,
00273 int optlen));
00274 #endif
00275 #endif
00276 int socket args ((int domain, int type, int protocol));
00277 int write args ((int fd, char *buf, int nbyte));
00278 #endif
00279
00280 #if defined(ultrix)
00281 int accept args ((int s, struct sockaddr * addr, int *addrlen));
00282 int bind args ((int s, struct sockaddr * name, int namelen));
00283 void bzero args ((char *b, int length));
00284 int close args ((int fd));
00285 int getpeername args ((int s, struct sockaddr * name, int *namelen));
00286 int getsockname args ((int s, struct sockaddr * name, int *namelen));
00287 int gettimeofday args ((struct timeval * tp, struct timezone * tzp));
00288 int listen args ((int s, int backlog));
00289 int read args ((int fd, char *buf, int nbyte));
00290 int select args ((int width, fd_set * readfds, fd_set * writefds,
00291 fd_set * exceptfds, struct timeval * timeout));
00292 int setsockopt args ((int s, int level, int optname, void *optval,
00293 int optlen));
00294 int socket args ((int domain, int type, int protocol));
00295 int write args ((int fd, char *buf, int nbyte));
00296 #endif
00297
00298
00299
00300
00301
00302
00303 DESCRIPTOR_DATA *descriptor_list;
00304 DESCRIPTOR_DATA *d_next;
00305 FILE *fpReserve;
00306 bool god;
00307 bool merc_down;
00308 bool global_peace;
00309 bool is_building_area;
00310
00311 bool isAreaPort;
00312
00313 bool wizlock;
00314 bool isCopyover;
00315 int Copyovercount=3;
00316 CHAR_DATA * CopyoverPerson;
00317 char *CopyoverReason;
00318 bool newlock;
00319 char str_boot_time[MAX_INPUT_LENGTH];
00320 time_t current_time;
00321 bool MOBtrigger = TRUE;
00322 bool just_rained;
00323
00324
00325
00326
00327 #if defined(macintosh) || defined(MSDOS)
00328 void game_loop_mac_msdos args ((void));
00329 bool read_from_descriptor args ((DESCRIPTOR_DATA * d));
00330 bool write_to_descriptor args ((int desc, char *txt, int length));
00331 #endif
00332
00333 #if defined(unix)
00334 void game_loop_unix args ((int control));
00335 int init_socket args ((int port));
00336 void init_descriptor args ((int control));
00337 bool read_from_descriptor args ((DESCRIPTOR_DATA * d));
00338 bool write_to_descriptor args ((int desc, char *txt, int length));
00339 #endif
00340
00341
00342
00343
00344
00345
00346
00347 bool check_parse_name args ((char *name));
00348 bool check_reconnect args ((DESCRIPTOR_DATA * d, char *name, bool fConn));
00349 bool check_playing args ((DESCRIPTOR_DATA * d, char *name));
00350 int main args ((int argc, char **argv));
00351 void nanny args ((DESCRIPTOR_DATA * d, char *argument));
00352 bool process_output args ((DESCRIPTOR_DATA * d, bool fPrompt));
00353 void read_from_buffer args ((DESCRIPTOR_DATA * d));
00354 void stop_idling args ((CHAR_DATA * ch));
00355 void bust_a_prompt args ((CHAR_DATA * ch));
00356
00357 void send_to_all_copyover args ((char *argument));
00358 void send_to_all args ((char *cch, char *argument));
00359
00360 int port, control;
00361
00362
00363
00364
00365
00366 int mud_ansiprompt, mud_ansicolor, mud_telnetga;
00367
00368
00369
00370 char *mud_ipaddress = "0.0.0.0";
00371 bool fCopyOver = FALSE;
00372 int main (int argc, char **argv)
00373 {
00374 struct timeval now_time;
00375
00376
00377
00378
00379
00380 #if defined(MALLOC_DEBUG)
00381 malloc_debug (2);
00382 #endif
00383
00384
00385
00386
00387 gettimeofday (&now_time, NULL);
00388 current_time = (time_t) now_time.tv_sec;
00389 strcpy (str_boot_time, ctime (¤t_time));
00390
00391
00392
00393
00394 #if defined(macintosh)
00395 console_options.nrows = 31;
00396 cshow (stdout);
00397 csetmode (C_RAW, stdin);
00398 cecho2file ("log file", 1, stderr);
00399 #endif
00400
00401
00402
00403
00404 if ((fpReserve = fopen (NULL_FILE, "r")) == NULL)
00405 {
00406 perror (NULL_FILE);
00407 exit (1);
00408 }
00409
00410
00411
00412
00413 port = 4000;
00414 if (argc > 1)
00415 {
00416 if (!is_number (argv[1]))
00417 {
00418 fprintf (stderr, "Usage: %s [port #]\n", argv[0]);
00419 exit (1);
00420 }
00421 else if ((port = atoi (argv[1])) <= 1024)
00422 {
00423 fprintf (stderr, "Port number must be above 1024.\n");
00424 exit (1);
00425 }
00426
00427
00428 if (argv[2] && argv[2][0])
00429 {
00430 logf("We're copyovering?");
00431 fCopyOver = TRUE;
00432 control = atoi (argv[3]);
00433 }
00434 else
00435 fCopyOver = FALSE;
00436
00437 }
00438 logf("port: %d", port);
00439
00440
00441
00442
00443 #if defined(macintosh) || defined(MSDOS)
00444 qmconfig_read();
00445 boot_db ();
00446 log_string ("Merc is ready to rock.");
00447 game_loop_mac_msdos ();
00448 #endif
00449
00450 #if defined(unix)
00451
00452 qmconfig_read();
00453 if (!fCopyOver)
00454 control = init_socket (port);
00455
00456 boot_db ();
00457
00458
00459
00460 logf ("ROM is ready to rock on port %d (%s).", port, mud_ipaddress);
00461
00462 if (fCopyOver)
00463 copyover_recover ();
00464
00465 game_loop_unix (control);
00466 save_kingdom_data();
00467 save_clan_data();
00468 save_game_conf();
00469 save_disabled();
00470 close (control);
00471 #endif
00472
00473
00474
00475
00476 log_string ("Normal termination of game.");
00477 exit (0);
00478 return 0;
00479 }
00480
00481
00482
00483 #if defined(unix)
00484 int init_socket (int port)
00485 {
00486 static struct sockaddr_in sa_zero;
00487 struct sockaddr_in sa;
00488 int x = 1;
00489 int fd;
00490
00491 if ((fd = socket (AF_INET, SOCK_STREAM, 0)) < 0)
00492 {
00493 perror ("Init_socket: socket");
00494 exit (1);
00495 }
00496
00497 if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR,
00498 (char *) &x, sizeof (x)) < 0)
00499 {
00500 perror ("Init_socket: SO_REUSEADDR");
00501 close (fd);
00502 exit (1);
00503 }
00504
00505 #if defined(SO_DONTLINGER) && !defined(SYSV)
00506 {
00507 struct linger ld;
00508
00509 ld.l_onoff = 1;
00510 ld.l_linger = 1000;
00511
00512 if (setsockopt (fd, SOL_SOCKET, SO_DONTLINGER,
00513 (char *) &ld, sizeof (ld)) < 0)
00514 {
00515 perror ("Init_socket: SO_DONTLINGER");
00516 close (fd);
00517 exit (1);
00518 }
00519 }
00520 #endif
00521
00522 sa = sa_zero;
00523 sa.sin_family = AF_INET;
00524 sa.sin_port = htons (port);
00525 sa.sin_addr.s_addr = inet_addr( mud_ipaddress );
00526 logf("Set IP address to %s", mud_ipaddress);
00527
00528 if (bind (fd, (struct sockaddr *) &sa, sizeof (sa)) < 0)
00529 {
00530 perror ("Init socket: bind");
00531 close (fd);
00532 exit (1);
00533 }
00534
00535
00536 if (listen (fd, 3) < 0)
00537 {
00538 perror ("Init socket: listen");
00539 close (fd);
00540 exit (1);
00541 }
00542
00543 return fd;
00544 }
00545 #endif
00546
00547
00548
00549 #if defined(macintosh) || defined(MSDOS)
00550 void game_loop_mac_msdos (void)
00551 {
00552 struct timeval last_time;
00553 struct timeval now_time;
00554 static DESCRIPTOR_DATA dcon;
00555
00556 gettimeofday (&last_time, NULL);
00557 current_time = (time_t) last_time.tv_sec;
00558
00559
00560
00561
00562 dcon.descriptor = 0;
00563 if (!mud_ansiprompt)
00564
00565 dcon.connected = CON_SHOW_LOGIN;
00566 else
00567 dcon.connected = CON_ANSI;
00568 dcon.ansi = mud_ansicolor;
00569 dcon.host = str_dup ("localhost");
00570 dcon.outsize = 2000;
00571 dcon.outbuf = alloc_mem (dcon.outsize);
00572 dcon.next = descriptor_list;
00573 dcon.showstr_head = NULL;
00574 dcon.showstr_point = NULL;
00575 dcon.pEdit = NULL;
00576 dcon.pString = NULL;
00577 dcon.editor = 0;
00578 descriptor_list = &dcon;
00579
00580
00581
00582
00583 if (!mud_ansiprompt)
00584 {
00585 extern char * help_greeting;
00586 if ( help_greeting[0] == '.' )
00587 send_to_desc ( help_greeting+1, &dcon );
00588 else
00589 send_to_desc ( help_greeting , &dcon );
00590 }
00591
00592 else
00593 write_to_buffer (&dcon, "Do you want Colour? (Y/n) ", 0);
00594
00595
00596 while (!merc_down)
00597 {
00598 DESCRIPTOR_DATA *d;
00599
00600
00601
00602
00603 for (d = descriptor_list; d != NULL; d = d_next)
00604 {
00605 d_next = d->next;
00606 d->fcommand = FALSE;
00607
00608 #if defined(MSDOS)
00609 if (kbhit ())
00610 #endif
00611 {
00612 if (d->character != NULL)
00613 d->character->timer = 0;
00614 if (!read_from_descriptor (d))
00615 {
00616 if (d->character != NULL && d->connected == CON_PLAYING)
00617 save_char_obj (d->character);
00618 d->outtop = 0;
00619 close_socket (d);
00620 continue;
00621 }
00622 }
00623
00624 if (d->character != NULL && d->character->daze > 0)
00625 --d->character->daze;
00626
00627 if (d->character != NULL && d->character->wait > 0)
00628 {
00629 --d->character->wait;
00630 continue;
00631 }
00632
00633 read_from_buffer (d);
00634 if (d->incomm[0] != '\0')
00635 {
00636 d->fcommand = TRUE;
00637 stop_idling (d->character);
00638
00639
00640 if (d->showstr_point)
00641 show_string (d, d->incomm);
00642 else if (d->pString)
00643 string_add (d->character, d->incomm);
00644 else
00645 switch (d->connected)
00646 {
00647 case CON_PLAYING:
00648 if (!run_olc_editor (d))
00649 substitute_alias (d, d->incomm);
00650 break;
00651 default:
00652 send_to_decriptor("Test.\n\r",d);
00653 nanny (d, d->incomm);
00654 break;
00655 }
00656
00657 d->incomm[0] = '\0';
00658 }
00659 }
00660
00661
00662
00663
00664
00665
00666 update_handler ();
00667
00668
00669
00670
00671
00672
00673 for (d = descriptor_list; d != NULL; d = d_next)
00674 {
00675 d_next = d->next;
00676
00677 if ((d->fcommand || d->outtop > 0))
00678 {
00679 if (!process_output (d, TRUE))
00680 {
00681 if (d->character != NULL && d->connected == CON_PLAYING)
00682 save_char_obj (d->character);
00683 d->outtop = 0;
00684 close_socket (d);
00685 }
00686 }
00687 }
00688
00689
00690
00691
00692
00693
00694
00695 now_time = last_time;
00696 for (;;)
00697 {
00698 int delta;
00699
00700 #if defined(MSDOS)
00701 if (kbhit ())
00702 #endif
00703 {
00704 if (dcon.character != NULL)
00705 dcon.character->timer = 0;
00706 if (!read_from_descriptor (&dcon))
00707 {
00708 if (dcon.character != NULL && d->connected == CON_PLAYING)
00709 save_char_obj (d->character);
00710 dcon.outtop = 0;
00711 close_socket (&dcon);
00712 }
00713 #if defined(MSDOS)
00714 break;
00715 #endif
00716 }
00717
00718 gettimeofday (&now_time, NULL);
00719 delta = (now_time.tv_sec - last_time.tv_sec) * 1000 * 1000
00720 + (now_time.tv_usec - last_time.tv_usec);
00721 if (delta >= 1000000 / PULSE_PER_SECOND)
00722 break;
00723 }
00724 last_time = now_time;
00725 current_time = (time_t) last_time.tv_sec;
00726 }
00727
00728 return;
00729 }
00730 #endif
00731
00732
00733
00734 #if defined(unix)
00735 void game_loop_unix (int control)
00736 {
00737 static struct timeval null_time;
00738 struct timeval last_time;
00739
00740 signal (SIGPIPE, SIG_IGN);
00741 gettimeofday (&last_time, NULL);
00742 current_time = (time_t) last_time.tv_sec;
00743
00744
00745 while (!merc_down)
00746 {
00747 fd_set in_set;
00748 fd_set out_set;
00749 fd_set exc_set;
00750 DESCRIPTOR_DATA *d;
00751 int maxdesc;
00752
00753 #if defined(MALLOC_DEBUG)
00754 if (malloc_verify () != 1)
00755 abort ();
00756 #endif
00757 if (signal(SIGINT, mud_crashing) == SIG_IGN)
00758 signal(SIGINT, SIG_IGN);
00759 if (signal(SIGHUP, mud_crashing) == SIG_IGN)
00760 signal(SIGHUP, SIG_IGN);
00761 if (signal(SIGSEGV, mud_crashing) == SIG_IGN)
00762 signal(SIGSEGV, mud_crashing);
00763
00764
00765
00766
00767
00768 FD_ZERO (&in_set);
00769 FD_ZERO (&out_set);
00770 FD_ZERO (&exc_set);
00771 FD_SET (control, &in_set);
00772 maxdesc = control;
00773 for (d = descriptor_list; d; d = d->next)
00774 {
00775 maxdesc = UMAX (maxdesc, d->descriptor);
00776 FD_SET (d->descriptor, &in_set);
00777 FD_SET (d->descriptor, &out_set);
00778 FD_SET (d->descriptor, &exc_set);
00779 }
00780
00781 if (select (maxdesc + 1, &in_set, &out_set, &exc_set, &null_time) < 0)
00782 {
00783 perror ("Game_loop: select: poll");
00784 exit (1);
00785 }
00786
00787
00788
00789
00790 if (FD_ISSET (control, &in_set))
00791 init_descriptor (control);
00792
00793
00794
00795
00796 for (d = descriptor_list; d != NULL; d = d_next)
00797 {
00798 d_next = d->next;
00799 if (FD_ISSET (d->descriptor, &exc_set))
00800 {
00801 FD_CLR (d->descriptor, &in_set);
00802 FD_CLR (d->descriptor, &out_set);
00803 if (d->character && d->connected == CON_PLAYING)
00804 save_char_obj (d->character);
00805 d->outtop = 0;
00806 close_socket (d);
00807 }
00808 }
00809
00810
00811
00812
00813 for (d = descriptor_list; d != NULL; d = d_next)
00814 {
00815 d_next = d->next;
00816 d->fcommand = FALSE;
00817
00818 if (FD_ISSET (d->descriptor, &in_set))
00819 {
00820 if (d->character != NULL)
00821 d->character->timer = 0;
00822 if (!read_from_descriptor (d))
00823 {
00824 FD_CLR (d->descriptor, &out_set);
00825 if (d->character != NULL && d->connected == CON_PLAYING)
00826 save_char_obj (d->character);
00827 d->outtop = 0;
00828 close_socket (d);
00829 continue;
00830 }
00831 }
00832
00833 if (d->character != NULL && d->character->daze > 0)
00834 --d->character->daze;
00835
00836 if (d->character != NULL && d->character->wait > 0)
00837 {
00838 --d->character->wait;
00839 continue;
00840 }
00841 read_from_buffer(d);
00842
00843
00844
00845 if (d->incomm[0] != '\0')
00846 {
00847 d->fcommand = TRUE;
00848 stop_idling (d->character);
00849
00850
00851 if (d->showstr_point)
00852 show_string (d, d->incomm);
00853 else if (d->pString)
00854 string_add (d->character, d->incomm);
00855 else
00856 switch (d->connected)
00857 {
00858 case CON_PLAYING:
00859 if (!run_olc_editor (d))
00860 substitute_alias (d, d->incomm);
00861 break;
00862 default:
00863 nanny (d, d->incomm);
00864 break;
00865 }
00866
00867 d->incomm[0] = '\0';
00868 }
00869 }
00870
00871
00872
00873
00874
00875
00876 update_handler ();
00877
00878
00879
00880
00881
00882
00883 for (d = descriptor_list; d != NULL; d = d_next)
00884 {
00885 d_next = d->next;
00886
00887 if ((d->fcommand || d->outtop > 0)
00888 && FD_ISSET (d->descriptor, &out_set))
00889 {
00890 if (!process_output (d, TRUE))
00891 {
00892 if (d->character != NULL && d->connected == CON_PLAYING)
00893 save_char_obj (d->character);
00894 d->outtop = 0;
00895 close_socket (d);
00896 }
00897 }
00898 }
00899
00900
00901
00902
00903
00904
00905
00906
00907 {
00908 struct timeval now_time;
00909 long secDelta;
00910 long usecDelta;
00911
00912 gettimeofday (&now_time, NULL);
00913 usecDelta = ((int) last_time.tv_usec) - ((int) now_time.tv_usec)
00914 + 1000000 / PULSE_PER_SECOND;
00915 secDelta = ((int) last_time.tv_sec) - ((int) now_time.tv_sec);
00916 while (usecDelta < 0)
00917 {
00918 usecDelta += 1000000;
00919 secDelta -= 1;
00920 }
00921
00922 while (usecDelta >= 1000000)
00923 {
00924 usecDelta -= 1000000;
00925 secDelta += 1;
00926 }
00927
00928 if (secDelta > 0 || (secDelta == 0 && usecDelta > 0))
00929 {
00930 struct timeval stall_time;
00931
00932 stall_time.tv_usec = usecDelta;
00933 stall_time.tv_sec = secDelta;
00934 if (select (0, NULL, NULL, NULL, &stall_time) < 0)
00935 {
00936 perror ("Game_loop: select: stall");
00937 exit (1);
00938 }
00939 }
00940 }
00941
00942 gettimeofday (&last_time, NULL);
00943 current_time = (time_t) last_time.tv_sec;
00944 }
00945
00946 return;
00947 }
00948 #endif
00949
00950
00951
00952 #if defined(unix)
00953
00954 void init_descriptor (int control)
00955 {
00956 char buf[MAX_STRING_LENGTH];
00957 DESCRIPTOR_DATA *dnew;
00958 struct sockaddr_in sock;
00959 struct hostent *from;
00960 int desc;
00961 int size;
00962
00963 size = sizeof (sock);
00964 getsockname (control, (struct sockaddr *) &sock, &size);
00965 if ((desc = accept (control, (struct sockaddr *) &sock, &size)) < 0)
00966 {
00967 perror ("New_descriptor: accept");
00968 return;
00969 }
00970
00971 #if !defined(FNDELAY)
00972 #define FNDELAY O_NDELAY
00973 #endif
00974
00975 if (fcntl (desc, F_SETFL, FNDELAY) == -1)
00976 {
00977 perror ("New_descriptor: fcntl: FNDELAY");
00978 return;
00979 }
00980
00981
00982
00983
00984 dnew = new_descriptor ();
00985
00986 dnew->descriptor = desc;
00987 if (!mud_ansiprompt)
00988
00989 dnew->connected = CON_SHOW_LOGIN;
00990 else
00991 dnew->connected = CON_ANSI;
00992 dnew->ansi = mud_ansicolor;
00993 dnew->showstr_head = NULL;
00994 dnew->showstr_point = NULL;
00995 dnew->outsize = 2000;
00996 dnew->pEdit = NULL;
00997 dnew->pString = NULL;
00998 dnew->editor = 0;
00999 dnew->outbuf = alloc_mem (dnew->outsize);
01000
01001 size = sizeof (sock);
01002 if (getpeername (desc, (struct sockaddr *) &sock, &size) < 0)
01003 {
01004 perror ("New_descriptor: getpeername");
01005 dnew->host = str_dup ("(unknown)");
01006 }
01007 else
01008 {
01009
01010
01011
01012
01013 int addr;
01014
01015 addr = ntohl (sock.sin_addr.s_addr);
01016 sprintf (buf, "%d.%d.%d.%d",
01017 (addr >> 24) & 0xFF, (addr >> 16) & 0xFF,
01018 (addr >> 8) & 0xFF, (addr) & 0xFF);
01019 sprintf (log_buf, "Sock.sinaddr: %s", buf);
01020 log_string (log_buf);
01021 from = gethostbyaddr ((char *) &sock.sin_addr,
01022 sizeof (sock.sin_addr), AF_INET);
01023 dnew->host = str_dup (from ? from->h_name : buf);
01024 }
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034 if (check_ban (dnew->host, BAN_ALL))
01035 {
01036 write_to_descriptor (desc,
01037 "Your site has been banned. If you feel this is an error, contact\n\rTribul.\n\r",
01038 0);
01039 close (desc);
01040 free_descriptor (dnew);
01041 return;
01042 }
01043
01044
01045
01046 dnew->next = descriptor_list;
01047 descriptor_list = dnew;
01048
01049
01050
01051
01052 if (!mud_ansiprompt)
01053 {
01054 extern char * help_greeting;
01055 if ( help_greeting[0] == '.' )
01056 send_to_desc ( help_greeting+1, dnew );
01057 else
01058 send_to_desc ( help_greeting , dnew );
01059 }
01060 else
01061 send_to_desc ("Do you want Colour? (Y/n) ", dnew);
01062
01063 return;
01064 }
01065 #endif
01066
01067
01068
01069 void close_socket (DESCRIPTOR_DATA * dclose)
01070 {
01071 CHAR_DATA *ch;
01072
01073 if (dclose->outtop > 0)
01074 process_output (dclose, FALSE);
01075
01076 if (dclose->snoop_by != NULL)
01077 {
01078 write_to_buffer (dclose->snoop_by,
01079 "Your victim has left the game.\n\r", 0);
01080 }
01081
01082 {
01083 DESCRIPTOR_DATA *d;
01084
01085 for (d = descriptor_list; d != NULL; d = d->next)
01086 {
01087 if (d->snoop_by == dclose)
01088 d->snoop_by = NULL;
01089 }
01090 }
01091
01092 if ((ch = dclose->character) != NULL)
01093 {
01094 sprintf (log_buf, "Closing link to %s.", ch->name);
01095 log_string (log_buf);
01096
01097
01098 if ((dclose->connected == CON_PLAYING && !merc_down)
01099 || ((dclose->connected >= CON_NOTE_TO)
01100 && (dclose->connected <= CON_NOTE_FINISH)))
01101 {
01102 act ("$n has lost $s link.", ch, NULL, NULL, TO_ROOM);
01103
01104 wiznet ("Net death has claimed $N.", ch, NULL, WIZ_LINKS, 0, 0);
01105 SET_BIT(ch->link_status, LINK_DEAD);
01106 ch->desc = NULL;
01107 }
01108 else
01109 {
01110 free_char (dclose->original ? dclose->original :
01111 dclose->character);
01112 }
01113 }
01114
01115 if (d_next == dclose)
01116 d_next = d_next->next;
01117
01118 if (dclose == descriptor_list)
01119 {
01120 descriptor_list = descriptor_list->next;
01121 }
01122 else
01123 {
01124 DESCRIPTOR_DATA *d;
01125
01126 for (d = descriptor_list; d && d->next != dclose; d = d->next);
01127 if (d != NULL)
01128 d->next = dclose->next;
01129 else
01130 bug ("Close_socket: dclose not found.", 0);
01131 }
01132
01133 close (dclose->descriptor);
01134 free_descriptor (dclose);
01135 #if defined(MSDOS) || defined(macintosh)
01136 exit (1);
01137 #endif
01138 return;
01139 }
01140
01141
01142
01143 bool read_from_descriptor (DESCRIPTOR_DATA * d)
01144 {
01145 int iStart;
01146
01147
01148 if (d->incomm[0] != '\0')
01149 return TRUE;
01150
01151
01152 iStart = strlen (d->inbuf);
01153 if (iStart >= sizeof (d->inbuf) - 10)
01154 {
01155 sprintf (log_buf, "%s input overflow!", d->host);
01156 log_string (log_buf);
01157 write_to_descriptor (d->descriptor,
01158 "\n\r*** PUT A LID ON IT!!! ***\n\r", 0);
01159 return FALSE;
01160 }
01161
01162
01163 #if defined(macintosh)
01164 for (;;)
01165 {
01166 int c;
01167 c = getc (stdin);
01168 if (c == '\0' || c == EOF)
01169 break;
01170 putc (c, stdout);
01171 if (c == '\r')
01172 putc ('\n', stdout);
01173 d->inbuf[iStart++] = c;
01174 if (iStart > sizeof (d->inbuf) - 10)
01175 break;
01176 }
01177 #endif
01178
01179 #if defined(MSDOS) || defined(unix)
01180 for (;;)
01181 {
01182 int nRead;
01183
01184 nRead = read (d->descriptor, d->inbuf + iStart,
01185 sizeof (d->inbuf) - 10 - iStart);
01186 if (nRead > 0)
01187 {
01188 iStart += nRead;
01189 if (d->inbuf[iStart - 1] == '\n' || d->inbuf[iStart - 1] == '\r' || d->inbuf[iStart -1] == '~')
01190 break;
01191 }
01192 else if (nRead == 0)
01193 {
01194 log_string ("EOF encountered on read.");
01195 return FALSE;
01196 }
01197 else if (errno == EWOULDBLOCK)
01198 break;
01199 else
01200 {
01201 perror ("Read_from_descriptor");
01202 return FALSE;
01203 }
01204 }
01205 #endif
01206
01207 d->inbuf[iStart] = '\0';
01208 return TRUE;
01209 }
01210
01211
01212
01213
01214
01215
01216 void read_from_buffer (DESCRIPTOR_DATA * d)
01217 {
01218 int i, j, k;
01219
01220
01221
01222
01223 if (d->incomm[0] != '\0')
01224 return;
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235 for (i = 0; d->inbuf[i] != '\n' && d->inbuf[i] != '\r'; i++)
01236 {
01237 if (d->inbuf[i] == '\0')
01238 return;
01239
01240
01241
01242
01243
01244
01245
01246
01247 }
01248
01249
01250
01251
01252 for (i = 0, k = 0; d->inbuf[i] != '\n' && d->inbuf[i] != '\r'; i++)
01253 {
01254 if (k >= MAX_INPUT_LENGTH - 2)
01255 {
01256 write_to_descriptor (d->descriptor, "Line too long.\n\r", 0);
01257
01258
01259 for (; d->inbuf[i] != '\0'; i++)
01260 {
01261 if (d->inbuf[i] == '\n' || d->inbuf[i] == '\r')
01262 break;
01263 }
01264 d->inbuf[i] = '\n';
01265 d->inbuf[i + 1] = '\0';
01266 break;
01267 }
01268
01269
01270
01271
01272
01273
01274 if (d->inbuf[i] == '\b' && k > 0)
01275 --k;
01276 else if (isascii (d->inbuf[i]) && isprint (d->inbuf[i]))
01277 d->incomm[k++] = d->inbuf[i];
01278 }
01279
01280
01281
01282
01283 if (k == 0)
01284 d->incomm[k++] = ' ';
01285 d->incomm[k] = '\0';
01286
01287
01288
01289
01290
01291 if (k > 1 || d->incomm[0] == '!')
01292 {
01293 if (d->incomm[0] != '!' && strcmp (d->incomm, d->inlast))
01294 {
01295 d->repeat = 0;
01296 }
01297 else
01298 {
01299 if (++d->repeat >= 25 && d->character
01300 && d->connected == CON_PLAYING)
01301 {
01302 sprintf (log_buf, "%s input spamming!", d->host);
01303 log_string (log_buf);
01304 wiznet ("Spam spam spam $N spam spam spam spam spam!",
01305 d->character, NULL, WIZ_SPAM, 0,
01306 get_trust (d->character));
01307 if (d->incomm[0] == '!')
01308 wiznet (d->inlast, d->character, NULL, WIZ_SPAM, 0,
01309 get_trust (d->character));
01310 else
01311 wiznet (d->incomm, d->character, NULL, WIZ_SPAM, 0,
01312 get_trust (d->character));
01313
01314 d->repeat = 0;
01315
01316
01317
01318
01319
01320 }
01321 }
01322 }
01323
01324
01325
01326
01327
01328 if (d->incomm[0] == '!')
01329 strcpy (d->incomm, d->inlast);
01330 else
01331 strcpy (d->inlast, d->incomm);
01332 if (d->incomm[0] == '~')
01333 d->inbuf[0] = '\0';
01334
01335
01336
01337
01338
01339 while (d->inbuf[i] == '\n' || d->inbuf[i] == '\r')
01340 i++;
01341 for (j = 0; (d->inbuf[j] = d->inbuf[i + j]) != '\0'; j++);
01342 return;
01343 }
01344
01345
01346
01347
01348
01349
01350 bool process_output (DESCRIPTOR_DATA * d, bool fPrompt)
01351 {
01352 extern bool merc_down;
01353 int cnt=1;
01354 static char buf[MAX_STRING_LENGTH * 2];
01355 char tmpb[MAX_STRING_LENGTH];
01356 buf[0] = '\0';
01357
01358
01359
01360
01361 if (!merc_down)
01362 {
01363 if (d->showstr_point)
01364 send_to_char ("{x{D[{wHit Return to continue{D]{x\n\r", d->character);
01365 else if (fPrompt && d->pString && d->connected == CON_PLAYING)
01366 {
01367 char *string;
01368 string = *d->pString;
01369 while (*string)
01370 {
01371 string = getline (string, tmpb);
01372 cnt++;
01373
01374
01375
01376 }
01377 sprintf(buf, "{W%3d{c>{x ", cnt);
01378
01379
01380 send_to_char(buf, d->character);
01381 }
01382 else if (fPrompt && d->connected == CON_PLAYING)
01383 {
01384 CHAR_DATA *ch;
01385 CHAR_DATA *victim;
01386
01387 ch = d->character;
01388
01389
01390
01391 if ((victim = ch->fighting) != NULL && can_see (ch, victim))
01392 {
01393 int percent;
01394 char wound[100];
01395 char *pbuff;
01396 char buf[MSL];
01397 char buffer[MSL*2];
01398
01399 if (victim->max_hit > 0)
01400 percent = victim->hit * 100 / victim->max_hit;
01401 else
01402 percent = -1;
01403
01404 if (percent >= 100)
01405 sprintf (wound, "is in excellent condition.");
01406 else if (percent >= 90)
01407 sprintf (wound, "has a few scratches.");
01408 else if (percent >= 75)
01409 sprintf (wound, "has some small wounds and bruises.");
01410 else if (percent >= 50)
01411 sprintf (wound, "has quite a few wounds.");
01412 else if (percent >= 30)
01413 sprintf (wound,
01414 "has some big nasty wounds and scratches.");
01415 else if (percent >= 15)
01416 sprintf (wound, "looks pretty hurt.");
01417 else if (percent >= 0)
01418 sprintf (wound, "is in awful condition.");
01419 else
01420 sprintf (wound, "is bleeding to death.");
01421
01422 sprintf (buf, "%s %s \n\r",
01423 IS_NPC (victim) ? victim->short_descr : victim->name,
01424 wound);
01425 buf[0] = UPPER (buf[0]);
01426 pbuff = buffer;
01427 colourconv (pbuff, buf, CH(d));
01428 write_to_buffer (d, buffer, 0);
01429 }
01430
01431
01432 ch = d->original ? d->original : d->character;
01433 if (!IS_SET (ch->comm, COMM_COMPACT))
01434 write_to_buffer (d, "\n\r", 2);
01435
01436
01437 if (IS_SET (ch->comm, COMM_PROMPT))
01438 bust_a_prompt (d->character);
01439
01440 if (IS_SET (ch->comm, COMM_TELNET_GA))
01441 write_to_buffer (d, go_ahead_str, 0);
01442 }
01443 }
01444
01445
01446
01447
01448 if (d->outtop == 0)
01449 return TRUE;
01450
01451
01452
01453
01454 if (d->snoop_by != NULL)
01455 {
01456 if (d->character != NULL)
01457 write_to_buffer (d->snoop_by, d->character->name, 0);
01458 write_to_buffer (d->snoop_by, "> ", 2);
01459 write_to_buffer (d->snoop_by, d->outbuf, d->outtop);
01460 }
01461
01462
01463
01464
01465 if (!write_to_descriptor (d->descriptor, d->outbuf, d->outtop))
01466 {
01467 d->outtop = 0;
01468 return FALSE;
01469 }
01470 else
01471 {
01472 d->outtop = 0;
01473 return TRUE;
01474 }
01475 }
01476
01477
01478
01479
01480
01481 void bust_a_prompt (CHAR_DATA * ch)
01482 {
01483 char buf[MAX_STRING_LENGTH];
01484 char buf2[MAX_STRING_LENGTH];
01485 const char *str;
01486 const char *i;
01487 char *point;
01488 char *pbuff;
01489 char buffer[MAX_STRING_LENGTH * 2];
01490 char doors[MAX_INPUT_LENGTH];
01491 EXIT_DATA *pexit;
01492 bool found;
01493 const char *dir_name[] = { "N-", "E-", "S-", "W-", "U-", "D-", "Ne-", "Nw-", "Se-", "Sw" };
01494 int door;
01495 extern int port;
01496
01497 point = buf;
01498 str = ch->prompt;
01499 if (str == NULL || str[0] == '\0')
01500 {
01501 sprintf (buf, "{p<%dhp %dm %dmv>{x %s",
01502 ch->hit, ch->mana, ch->move, ch->prefix);
01503 send_to_char (buf, ch);
01504 return;
01505 }
01506 if (!IS_NPC(ch) && ch->desc->editor)
01507 {
01508 send_to_char("{R[{WOLC{R]{x ",ch);
01509 }
01510 if (!IS_NPC(ch) && IS_IMMORTAL(ch) && IS_SET(ch->pcdata->immortal, IMMORTAL_PORT))
01511 {
01512
01513 sprintf(buf, "{r({cPort: {D%d{r){x ",port);
01514 send_to_char(buf,ch);
01515 }
01516
01517
01518
01519 if (IS_SET (ch->comm, COMM_AFK))
01520 {
01521 send_to_char ("{p<AFK>{x ", ch);
01522 return;
01523 }
01524
01525 while (*str != '\0')
01526 {
01527 if (*str != '%')
01528 {
01529 *point++ = *str++;
01530 continue;
01531 }
01532 ++str;
01533 switch (*str)
01534 {
01535 default:
01536 i = " ";
01537 break;
01538 case 'e':
01539 found = FALSE;
01540 doors[0] = '\0';
01541 for (door = 0; door < 10; door++)
01542 {
01543 if ((pexit = ch->in_room->exit[door]) != NULL
01544 && pexit->u1.to_room != NULL
01545 && (can_see_room (ch, pexit->u1.to_room)
01546 || (IS_AFFECTED (ch, AFF_INFRARED)
01547 && !IS_AFFECTED (ch, AFF_BLIND)))
01548 && !IS_SET (pexit->exit_info, EX_CLOSED))
01549 {
01550 found = TRUE;
01551 strcat (doors, dir_name[door]);
01552 }
01553 }
01554 if (!found)
01555 strcat (buf, "none");
01556 sprintf (buf2, "%s", doors);
01557 i = buf2;
01558 break;
01559 case 'c':
01560 sprintf (buf2, "%s", "\n\r");
01561 i = buf2;
01562 break;
01563 case 'h':
01564 sprintf (buf2, "%d", ch->hit);
01565 i = buf2;
01566 break;
01567 case 'H':
01568 sprintf (buf2, "%d", ch->max_hit);
01569 i = buf2;
01570 break;
01571 case 'm':
01572 sprintf (buf2, "%d", ch->mana);
01573 i = buf2;
01574 break;
01575 case 'M':
01576 sprintf (buf2, "%d", ch->max_mana);
01577 i = buf2;
01578 break;
01579 case 'v':
01580 sprintf (buf2, "%d", ch->move);
01581 i = buf2;
01582 break;
01583 case 'V':
01584 sprintf (buf2, "%d", ch->max_move);
01585 i = buf2;
01586 break;
01587 case 'x':
01588 sprintf (buf2, "%d", ch->exp);
01589 i = buf2;
01590 break;
01591 case 'X':
01592 sprintf (buf2, "%d", IS_NPC (ch) ? 0 :
01593 (ch->level + 1) * exp_per_level (ch,
01594 ch->pcdata->
01595 points) - ch->exp);
01596 i = buf2;
01597 break;
01598 case 'g':
01599 sprintf (buf2, "%ld", ch->gold);
01600 i = buf2;
01601 break;
01602 case 's':
01603 sprintf (buf2, "%ld", ch->silver);
01604 i = buf2;
01605 break;
01606 case 'a':
01607 if (ch->level > 9)
01608 sprintf (buf2, "%d", ch->alignment);
01609 else
01610 sprintf (buf2, "%s",
01611 IS_GOOD (ch) ? "good" : IS_EVIL (ch) ? "evil" :
01612 "neutral");
01613 i = buf2;
01614 break;
01615 case 'r':
01616 if (ch->in_room != NULL)
01617 sprintf (buf2, "%s",
01618 ((!IS_NPC
01619 (ch) && IS_SET (ch->act, PLR_HOLYLIGHT))
01620 || (!IS_AFFECTED (ch, AFF_BLIND)
01621 && !room_is_dark (ch->
01622 in_room))) ? ch->in_room->
01623 name : "darkness");
01624 else
01625 sprintf (buf2, " ");
01626 i = buf2;
01627 break;
01628 case 'R':
01629 if (IS_IMMORTAL (ch) && ch->in_room != NULL)
01630 sprintf (buf2, "%d", ch->in_room->vnum);
01631 else
01632 sprintf (buf2, " ");
01633 i = buf2;
01634 break;
01635 case 'z':
01636 if (IS_IMMORTAL (ch) && ch->in_room != NULL)
01637 sprintf (buf2, "%s", ch->in_room->area->name);
01638 else
01639 sprintf (buf2, " ");
01640 i = buf2;
01641 break;
01642 case '%':
01643 sprintf (buf2, "%%");
01644 i = buf2;
01645 break;
01646 case 'o':
01647 sprintf (buf2, "%s", olc_ed_name (ch));
01648 i = buf2;
01649 break;
01650 case 'O':
01651 sprintf (buf2, "%s", olc_ed_vnum (ch));
01652 i = buf2;
01653 break;
01654 }
01655 ++str;
01656 while ((*point = *i) != '\0')
01657 ++point, ++i;
01658 }
01659 *point = '\0';
01660 pbuff = buffer;
01661 colourconv (pbuff, buf, ch);
01662 send_to_char ("{p", ch);
01663 write_to_buffer (ch->desc, buffer, 0);
01664 send_to_char ("{x", ch);
01665
01666 if (ch->prefix[0] != '\0')
01667 write_to_buffer (ch->desc, ch->prefix, 0);
01668 return;
01669 }
01670
01671
01672
01673
01674
01675
01676 void write_to_buffer (DESCRIPTOR_DATA * d, const char *txt, int length)
01677 {
01678
01679
01680
01681 if (length <= 0)
01682 length = strlen (txt);
01683
01684
01685
01686
01687 if (d->outtop == 0 && !d->fcommand)
01688 {
01689 d->outbuf[0] = '\n';
01690 d->outbuf[1] = '\r';
01691 d->outtop = 2;
01692 }
01693
01694
01695
01696
01697 while (d->outtop + length >= d->outsize)
01698 {
01699 char *outbuf;
01700
01701 if (d->outsize >= 32000)
01702 {
01703 bug ("Buffer overflow. Closing.\n\r", 0);
01704 close_socket (d);
01705 return;
01706 }
01707 outbuf = alloc_mem (2 * d->outsize);
01708 strncpy (outbuf, d->outbuf, d->outtop);
01709 free_mem (d->outbuf, d->outsize);
01710 d->outbuf = outbuf;
01711 d->outsize *= 2;
01712 }
01713
01714
01715
01716
01717 strncpy (d->outbuf + d->outtop, txt, length);
01718 d->outtop += length;
01719 return;
01720 }
01721
01722
01723
01724
01725
01726
01727
01728
01729
01730 bool write_to_descriptor (int desc, char *txt, int length)
01731 {
01732 int iStart;
01733 int nWrite;
01734 int nBlock;
01735
01736 #if defined(macintosh) || defined(MSDOS)
01737 if (desc == 0)
01738 desc = 1;
01739 #endif
01740
01741 if (length <= 0)
01742 length = strlen (txt);
01743
01744 for (iStart = 0; iStart < length; iStart += nWrite)
01745 {
01746 nBlock = UMIN (length - iStart, 4096);
01747 if ((nWrite = write (desc, txt + iStart, nBlock)) < 0)
01748 {
01749 perror ("Write_to_descriptor");
01750 return FALSE;
01751 }
01752 }
01753
01754 return TRUE;
01755 }
01756
01757
01758
01759 void