]> jfr.im git - irc/gameservirc.git/blob - gameserv/tcpclient.cpp
Fixed some bugs and added VLife as a supported ircd
[irc/gameservirc.git] / gameserv / tcpclient.cpp
1 /*
2 * This file is provided for use with the unix-socket-faq. It is public
3 * domain, and may be copied freely. There is no copyright on it. The
4 * original work was by Vic Metcalfe (vic@brutus.tlug.org), and any
5 * modifications made to that work were made with the understanding that
6 * the finished work would be in the public domain.
7 *
8 * If you have found a bug, please pass it on to me at the above address
9 * acknowledging that there will be no copyright on your work.
10 *
11 * The most recent version of this file, and the unix-socket-faq can be
12 * found at http://www.interlog.com/~vic/sock-faq/.
13 */
14
15 #include "sockhelp.h"
16 #include "options.h"
17 #include "aClient.h"
18 #include "extern.h"
19 #include "flags.h"
20 #include <stdio.h>
21 #include <unistd.h>
22 #include <string.h>
23 #include <fstream>
24 #include <stdlib.h>
25 #include <fcntl.h>
26 #include <signal.h>
27 #include <algorithm>
28
29 //#include <sys/types.h>
30 //#include <sys/wait.h>
31 //#include <errno.h>
32
33 using namespace std;
34
35 char *PACKAGE = "GameServ";
36 char *VERSION = "1.3.3 +devel";
37
38 int sock;
39 long lastrefresh;
40 long lastrollover;
41
42 list<aClient*> clients[U_TABLE_SIZE];
43
44 void save_lastrefresh();
45 void load_lastrefresh();
46 void load_lastrollover();
47 void save_lastrollover();
48 void prettyIntro();
49 void check_idles();
50 void clearClients();
51 void clearPlayers();
52 void clearItems();
53
54 // Make this a daemon
55 int daemon(int nochdir, int noclose);
56
57 // Close all file descriptors from >= fd
58 void closeall(int fd);
59
60 int main(int argc, char *argv[])
61 {
62 char buffer[1024], buf[1024];
63 memset(buffer, 0, 1024);
64 memset(buf, 0, 1024);
65 int connected;
66 long lastidlecheck;
67 char *cmd, *source = NULL, *conf;
68 srand(time(NULL));
69 conf = new char[16];
70 strcpy(conf, "gameserv.conf");
71
72 /*
73 * This needs to be fixed to work for any number of arguments in any
74 * order
75 *
76 */
77 if (argc > 1)
78 {
79 if ( argc > 2 || stricmp(argv[1], "--help") == 0)
80 {
81 cout << "Usage: gameserv [options] [configfile]" << endl;
82 cout << "Options:" << endl;
83 cout << "--help Displays this help dialogue" << endl;
84 delete []conf;
85 return 1;
86 }
87 delete []conf;
88 conf = argv[1];
89 }
90
91 prettyIntro();
92
93 if (load_config_file(conf))
94 {
95 cout << "Config file loaded ok...\n"
96 << "Turning into a daemon" << endl;
97 }
98 else
99 exit(2);
100
101 if (argc <= 1)
102 delete []conf;
103
104 // Turn into a daemon
105 if (daemon(1,0) < 0)
106 {
107 perror("Could not turn into a daemon");
108 exit(3);
109 }
110 if (load_items() == 0)
111 {
112 log("Error loading items");
113 goto end;
114 }
115
116 if (load_store() == 0)
117 {
118 log("Error loading store");
119 goto end;
120 }
121 if (load_tavern() == 0)
122 {
123 log("Error loading tavern");
124 goto end;
125 }
126
127 load_gs_dbase();
128 loadNews(newsdata, todaysnews);
129
130
131 if (load_masters() == false)
132 {
133 log("Error loading masters");
134 goto end;
135 }
136
137 if (load_monsters() == false)
138 {
139 log("Error loading monsters");
140 goto end;
141 }
142
143 if (!load_dragon())
144 {
145 log("Error loading dragon");
146 goto end;
147 }
148
149 if (load_levels() == false)
150 {
151 log("Error loading levels");
152 goto end;
153 }
154
155 shuttingdown = false;
156
157 char ignoreservers[32][256];
158 char *currentserver;
159 currentserver = strtok(ignoreserverslist, " ");
160 for (int server = 0; server < 32 && currentserver != NULL; server++)
161 {
162 strncpy(ignoreservers[server], currentserver, 255);
163 log("Placing %s on the server ignore list", currentserver);
164 currentserver = strtok(NULL, " ");
165 }
166
167 // This loop will retry the connection 3 times
168 for (int retry = 0; retry < 3 && !shuttingdown; retry++)
169 {
170 connected = 1;
171 load_lastrefresh();
172 load_lastrollover();
173
174 long int loadtime = time(NULL);
175 long int currentTime;
176 long int oldTime = loadtime;
177
178 lastidlecheck = loadtime;
179
180 #ifdef DEBUGMODE
181 log("Setting primary Idle Check timestamp: %ld", lastidlecheck);
182 #endif
183 bool loaded = false;
184
185 ignore_pipe();
186 sock = conn(remoteserver, remoteport, localhost, 0);
187 // sock = make_connection(remoteport, SOCK_STREAM, remoteserver);
188 if (sock == -1)
189 {
190 fprintf(stderr,"make_connection failed.\n");
191 unload_config_file();
192 return -1;
193 }
194 log("%S socket connected.");
195
196 #ifdef UNREAL
197 raw("PASS :%s", remotepass);
198 raw("SERVER %s 1 :%s", servername, servername);
199 raw("NICK %S 1 %d %s %s %s %d :%s v%s", time(NULL), gsident, gshost,
200 servername, time(NULL), PACKAGE, VERSION);
201 raw(":%S JOIN %s", c_Forest);
202 raw(":%S MODE %s +tn", c_Forest);
203 #elif defined(BAHAMUT)
204 raw("PASS %s :TS", remotepass);
205 raw("SERVER %s 1 :%s", servername, servername);
206 raw("NICK %S 1 %d +w%s %s %s %s 0 :GameServ", time(NULL), (isBOper() ? "o" : ""),
207 gsident, gshost, servername);
208 raw(":%s SJOIN %d %d %s +nt :@%S", servername, time(NULL), time(NULL), c_Forest);
209 #elif defined(HYBRID)
210 raw("PASS %s :TS", remotepass);
211 raw("SERVER %s 1 :%s", servername, servername);
212 raw("NICK %S 1 %d +w%s %s %s %s :GameServ", time(NULL), (isBOper() ? "o" : ""),
213 gsident, gshost, servername);
214 raw(":%s SJOIN %ld %s +nt :@%S", servername, time(NULL), c_Forest);
215 #elif defined(ULTIMATE2)
216 raw("PASS %s :TS", remotepass);
217 raw("SERVER %s 1 :%s", servername, servername);
218 raw("NICK %S 1 %d %s %s %s 0 :GameServ",
219 time(NULL), gsident, gshost, servername);
220 if (isBOper())
221 raw(":%S mode %S +o");
222 raw(":%S JOIN %s", c_Forest);
223 #elif defined(PTLINK)
224 raw("PASS %s :TS", remotepass);
225 raw("SERVER %s 1 :%s", servername, servername);
226 raw("NICK %S 1 %d %s%s %s %s %s :GameServ", time(NULL), (isBOper() ? "+iow " : ""), gsident, gshost, gshost, servername);
227 raw(":%s SJOIN %d %s +nt :@%S", servername, time(NULL), c_Forest);
228 #elif defined(VLIFE)
229 raw("PASS %s :TS", remotepass);
230 raw("SERVER %s 1 %d :%s", servername, time(NULL), servername);
231 //NNICK Kain 1 1161359175 +G kain 209.204.118.242 virtualife.1413884c.bf6674e.IP PTlink6.server.net :Kain
232 //NNICK Kainazzzo 1 1161359234 +G kain 209.204.118.242 virtualife.1413884c.bf6674e.IP PTlink6.server.net :Kain
233
234 raw("NNICK %S 1 %d +w%s %s %s %s %s :GameServ", time(NULL),(isBOper() ? "o" : ""), gsident, gshost, gshost, servername);
235 raw(":%s SJOIN %d %s +nt :@%S", servername, time(NULL), c_Forest);
236 #elif defined(P10)
237 // Server numeric is: [] <-- must be unique
238 raw("PASS :%s", remotepass);
239 raw("SERVER %s 1 %d %d P10 []AAF :%s", servername, time(NULL), time(NULL), servername);
240 raw("[] N %S 1 %d %s %s %s DAqAoB %s :%S", time(NULL), gsident, gshost,
241 (isBOper() ? "+o" : ""), gsnum);
242 raw("[] B %s %d +tn %s:o", c_Forest, time(NULL) - 864000, gsnum);
243 #endif
244
245 #if defined(P10)
246 raw("%s T %s :%s", gsnum, c_Forest, c_ForestTopic);
247 raw("[] EB"); // End burst
248 #else
249 #ifndef HYBRID
250 #if defined(ULTIMATE2)
251 raw(":%s MODE %s +o %S %ld", servername, c_Forest,
252 time(NULL));
253 #else
254 raw(":%S MODE %s +o %S", c_Forest);
255 #endif
256 #endif
257 raw(":%S TOPIC %s :%s", c_Forest, c_ForestTopic);
258 #endif
259
260 #ifndef P10
261 if (isUseNickServ())
262 {
263 raw(":%S PRIVMSG %s :IDENTIFY %s", nsname, nspass);
264 }
265 #endif
266 sock_gets(sock,buffer,sizeof(buffer)-1); /* -1 added thanks to
267 David Duchene <dave@ltd.com> for pointing out the possible
268 buffer overflow resulting from the linefeed added below. */
269
270
271 #ifdef DEBUGMODE
272 log("Server: %s",buffer);
273 #endif
274
275 while (connected)
276 {
277 if (sock_gets(sock,buffer,sizeof(buffer)) == -1)
278 {
279 connected = 0;
280 }
281 strcpy(buf, buffer);
282
283 #if !defined(P10)
284 if (buffer[0] == ':')
285 {
286 source = strtok(buf, " ");
287 cmd = strtok(NULL, " ");
288 }
289 else
290 {
291 cmd = strtok(buf, " ");
292 }
293 #else
294 source = strtok(buf, " ");
295 cmd = strtok(NULL, " ");
296 #endif
297
298 #ifdef DEBUGMODE
299 log("Server: %s", buffer);
300 #endif
301
302 // Wait N seconds then we're loaded.
303 if (!loaded)
304 {
305 if (time(NULL) >= welcomedelay + loadtime)
306 {
307 loaded = true;
308 retry = 0; // Start the reconnection cycle over
309 }
310 }
311 else
312 {
313 long TIME = time(NULL);
314 if (TIME - lastidlecheck >= idlecheckperiod)
315 {
316 check_idles();
317 lastidlecheck = TIME;
318 }
319 }
320
321 // Refresh players and clear news if the time is up
322 currentTime = time(NULL);
323
324 if (isRolloverForestFights())
325 {
326 if (currentTime - lastrollover >= rolloverperiod)
327 {
328 rolloverall();
329 lastrollover = currentTime;
330 save_lastrollover();
331 notice(s_GameServ, c_Forest, "Adding %d forest fights to all players!", numrolloverfights);
332 }
333 }
334
335 if (currentTime - lastrefresh >= refreshperiod)
336 {
337 refreshall();
338 clearNews(todaysnews);
339 saveNews(newsdata, todaysnews);
340 lastrefresh = currentTime;
341 save_lastrefresh();
342 notice(s_GameServ, c_Forest, "Refreshing all players "\
343 "and resetting news!");
344 }
345
346 // Save the player data every updateperiod seconds
347 if (currentTime - oldTime >= updateperiod)
348 {
349 oldTime = currentTime;
350 log("Saving to %s", playerdata);
351
352 save_gs_dbase();
353 saveNews(newsdata, todaysnews);
354 if (isSavedNotice())
355 {
356 // Send notice to the channel of the update
357 notice(s_GameServ, c_Forest, "%S player data saved");
358 }
359 }
360
361
362 #if !defined(P10)
363 if (stricmp(cmd, "PING") == 0)
364 {
365 char *timestamp;
366 timestamp = strtok(NULL, "");
367 raw("PONG %s", timestamp);
368 }
369 #else
370 // P10 Ping
371 if (stricmp(cmd, "G") == 0)
372 {
373 char *timestamp;
374 timestamp = strtok(NULL, " ");
375 raw("[] Z [] %s 0 %s", timestamp + 1, timestamp);
376 }
377 #endif
378 #ifdef P10
379 else if (stricmp(cmd, "EB") == 0)
380 {
381 raw("[] EA");
382 }
383 #endif
384 else if (stricmp(cmd, "VERSION") == 0)
385 {
386 char *server;
387 server = strtok(NULL, " ");
388 server++;
389 raw(":%s 351 %s %s_%s. %s", servername, source+1, PACKAGE, VERSION, servername);
390 }
391 // Code indenting is clean up until here!
392 #if !defined(P10)
393 else if (strncmp(cmd, "NICK", 4) == 0
394 #ifdef VLIFE
395 || strncmp(cmd, "NNICK", 5) == 0
396 #endif
397 )
398 {
399 if (buffer[0] == ':')
400 {
401 aClient *tempPtr;
402 if ((tempPtr = find((source + 1))))
403 {
404 char *nick;
405 unsigned long oldhv, newhv;
406 nick = strtok(NULL, " ");
407 oldhv = iHASH((unsigned char *) tempPtr->getNick());
408 newhv = iHASH((unsigned char *) nick);
409 tempPtr->setNick(nick);
410 clients[oldhv].remove(tempPtr);
411 clients[newhv].push_back(tempPtr);
412 }
413 }
414 else
415 {
416 char *nick;
417 #else
418 } else if (stricmp(cmd, "N") == 0 && strlen(source) == 2) {
419 {
420 char *nick, *realnick;
421 realnick = strtok(NULL, " ");
422
423 for (int x = 0; x < 5; x++)
424 nick = strtok(NULL, " ");
425
426 if (nick[0] == '+')
427 {
428 #ifdef DEBUGMODE
429 log ("aClient has modes");
430 #endif
431 // Searching for the +r mode (extra parameter)
432 for (unsigned int count = 1; count < strlen(nick); count++)
433 {
434 if (nick[count] == 'r')
435 {
436 nick = strtok(NULL, " ");
437 break;
438 }
439 }
440 nick = strtok(NULL, " ");
441 }
442 #endif
443 aClient *newuser;
444
445 nick = strtok(NULL, " ");
446
447 #ifdef P10
448 newuser = new aClient(nick, realnick);
449 #else
450 newuser = new aClient(nick);
451 #endif
452
453
454 if (loaded)
455 if (isWelcome())
456 {
457 #ifdef P10
458 notice(s_GameServ, nick, welcomemsg, realnick);
459 #else
460 notice(s_GameServ, nick, welcomemsg, nick);
461 #endif
462 }
463 #ifdef P10
464 unsigned long hv = sHASH((unsigned char *) nick);
465 #else
466 unsigned long hv = iHASH((unsigned char *) nick);
467 #endif
468
469 #if defined(HYBRID) || defined(BAHAMUT) || defined(ULTIMATE2) || defined(PTLINK)
470 char *nickserver;
471 strtok(NULL, " ");
472 strtok(NULL, " ");
473 nickserver = strtok(NULL, " ");
474 if (nickserver[0] == '+')
475 strtok(NULL, " ");
476 strtok(NULL, " ");
477 nickserver = strtok(NULL, " ");
478 for (int x = 0; x < 32; x++)
479 {
480 if (stricmp(ignoreservers[x], nickserver) == 0)
481 {
482 setIgnore(newuser);
483 break;
484 }
485 }
486 #elif defined(UNREAL)
487 char *nickserver;
488 strtok(NULL, " ");
489 strtok(NULL, " ");
490 strtok(NULL, " ");
491 strtok(NULL, " ");
492 nickserver = strtok(NULL, " ");
493 for (int x = 0; x < 32; x++)
494 {
495 if (stricmp(ignoreservers[x], nickserver) == 0)
496 {
497 setIgnore(newuser);
498 break;
499 }
500 }
501 #endif
502 clients[hv].push_back(newuser);
503 }
504 #if defined(P10)
505 } else if (stricmp(cmd, "Q") == 0) {
506 // unsigned long hv = sHASH((unsigned char *) source);
507 #else
508 } else if (stricmp(cmd, "QUIT") == 0)
509 {
510
511 #endif
512 aClient *quitter;
513 char z = source[0];
514
515 if (z == ':')
516 source++;
517
518 unsigned long hv = iHASH((unsigned char *) source);
519 if (!(quitter = find(source)))
520 {
521 log("Fatal Error: could not find %s in the "\
522 "clients list", source);
523 goto end;
524 }
525
526 clients[hv].remove(quitter);
527 logout(quitter);
528
529 delete quitter;
530
531 if (z == ':')
532 source--;
533
534 #if defined(P10)
535 }
536 else if (stricmp(cmd, "P") == 0)
537 {
538 char *rest, *dest;
539 char *longname;
540 longname = new char[strlen(s_GameServ) + strlen(servername) + 2];
541
542 sprintf(longname, "%S@%s", servername);
543
544 dest = strtok(NULL, " ");
545 rest = strtok(NULL, "");
546 if (stricmp(dest, gsnum) == 0 || stricmp(dest, longname) == 0)
547 {
548 delete [] longname;
549 gameserv(source, rest);
550 }
551 else if (stricmp(dest, c_Forest) == 0 && isListenOnCF())
552 {
553 delete [] longname;
554 forest(source, rest);
555 }
556 #else
557 }
558 else if (stricmp(cmd, "PRIVMSG") == 0)
559 {
560 char *rest, *dest;
561 dest = strtok(NULL, " ");
562 rest = strtok(NULL, "");
563 if (strnicmp(dest, s_GameServ, strlen(s_GameServ)) == 0)
564 gameserv(source, rest);
565 else if (stricmp(dest, c_Forest) == 0 && isListenOnCF())
566 forest(source, rest);
567 #endif
568 #if defined(P10)
569 } else if (stricmp(cmd, "J") == 0) {
570 #else
571 } else if (stricmp(cmd, "JOIN") == 0) {
572 #endif
573 char *channel;
574 aClient *joiner;
575 channel = strtok(NULL, " ");
576
577 char z = source[0];
578
579 if (z == ':')
580 source++;
581
582 joiner = find(source);
583
584 if (stricmp(channel, c_Forest) == 0 && is_playing(joiner))
585 {
586 #ifdef DEBUGMODE
587 log("Player %s (IRC: %s) joined %s",
588 joiner->stats->getName().c_str(),
589 #ifdef P10
590 joiner->getRealNick(),
591 #else
592 joiner->getNick(),
593 #endif
594 c_Forest);
595 #endif
596 raw(":%S MODE %s +v %s", c_Forest, (source));
597 }
598
599 if (z == ':')
600 source--;
601
602 #if defined(BAHAMUT)
603 } else if (stricmp(cmd, "SJOIN") == 0) {
604 char *channel, *nick, *tmp, *rest;
605 strtok(NULL, " "); // Ignore the TS
606 #ifndef HYBRID
607 strtok(NULL, " "); // Ignore the TS
608 #endif
609 channel = strtok(NULL, " ");
610 rest = strtok(NULL, "");
611 tmp = strchr(rest, ':');
612 tmp++;
613 nick = strtok(tmp, " ");
614 while (nick != NULL)
615 {
616 if (*nick == '@')
617 nick++;
618 if (*nick == '+')
619 nick++; // Assume for users set op and voice, they
620 // are never passed as +@nick
621 if (stricmp(channel, c_Forest) == 0 && is_playing(nick))
622 raw(":%S MODE %s +v %s", channel, nick);
623
624 nick = strtok(NULL, " ");
625 }
626 #endif
627 } else {
628 #ifdef DEBUGMODE
629 log("Unrecognized Message: cmd = %s source = %s", cmd, source);
630 #endif
631 }
632 }
633
634 } // for loop for connection retry
635
636 end:
637
638 save_gs_dbase();
639 save_dragon();
640 saveNews(newsdata, todaysnews);
641 clearClients();
642 clearPlayers();
643 clearItems();
644 delete_monsters();
645
646 #ifdef DEBUGMODE
647 log("<CLOSED>");
648 #endif
649
650 close(sock);
651 unload_config_file();
652 return 0;
653 }
654
655 aClient *find(char *nick)
656 {
657 return findbynick(nick);
658 }
659
660 aClient *find(const char *nick)
661 {
662 return findbynick(nick);
663 }
664
665 #ifdef P10
666
667 aClient *findbyrealnick(char *realnick)
668 {
669 ListNode <aClient> *newPtr;
670 unsigned long hv = sHASH((unsigned char *) realnick);
671 newPtr = clients[hv].First();
672
673 aClient *client = NULL;
674
675 while (newPtr)
676 {
677 client = newPtr->getData();
678 if (stricmp(client->getRealNick(), realnick) == 0)
679 return client;
680 client = NULL;
681 newPtr = newPtr->Next();
682 }
683 return client;
684 }
685
686 #else
687
688 aClient *findbyrealnick(char *realnick)
689 {
690 return findbynick(realnick);
691 }
692
693 #endif
694
695 aClient *findbynick(char *nick)
696 {
697 list<aClient*>::iterator iter;
698 #ifdef P10
699 unsigned long hv = sHASH((unsigned char *) nick);
700 #else
701 unsigned long hv = iHASH((unsigned char *) nick);
702 #endif
703
704 aClient *client = NULL;
705
706 for(iter = clients[hv].begin(); iter != clients[hv].end(); iter++)
707 {
708 client = (*iter);
709 #ifdef P10
710 if (strcmp(client->getNick(), nick) == 0)
711 {
712 #else
713 if (stricmp(client->getNick(), nick) == 0)
714 {
715 #endif
716 return client;
717 }
718 client = NULL;
719 }
720 return client;
721 }
722
723 Player *findplayer(const char *name)
724 {
725 list<Player*>::iterator iter;
726 Player *p;
727 unsigned long hv = iHASH((unsigned char *) name);
728 for (iter = players[hv].begin(); iter != players[hv].end(); iter++)
729 {
730 p = (*iter);
731 if (stricmp(p->getName().c_str(), name) == 0)
732 return p;
733 p = NULL;
734 }
735 return NULL;
736 }
737
738 void check_idles()
739 {
740 list<Player*>::iterator iter;
741 Player *p;
742
743 for (int x = 0; x < U_TABLE_SIZE; x++)
744 {
745 for (iter = players[x].begin(); iter != players[x].end(); iter++)
746 {
747 p = (*iter);
748
749 switch(p->getLevel())
750 {
751 case 1:
752 if ((time(NULL) - p->lastlogin) / 86400 >= level1expire)
753 {
754 logout(p->getClient());
755 return;
756 }
757 break;
758
759 default:
760 if ((time(NULL) - p->lastlogin) / 86400 >= defaultexpire)
761 {
762 logout(p->getClient());
763 return;
764 }
765 break;
766 }
767 if (timedOut(p))
768 {
769 timeOutEvent(p);
770 }
771 }
772 }
773 }
774
775 aClient *findbynick(const char *nick)
776 {
777 list<aClient*>::iterator iter;
778 #ifdef P10
779 unsigned long hv = sHASH((unsigned char *) nick);
780 #else
781 unsigned long hv = iHASH((unsigned char *) nick);
782 #endif
783
784 aClient *client = NULL;
785
786 for (iter = clients[hv].begin(); iter != clients[hv].end(); iter++)
787 {
788 client = (*iter);
789 #ifdef P10
790 if (strcmp(client->getNick(), nick) == 0)
791 #else
792 if (stricmp(client->getNick(), nick) == 0)
793 #endif
794 return client;
795 client = NULL;
796 }
797 return client;
798 }
799
800 /* daemon() - detach process from user and disappear into the background
801 * returns -1 on failure, but you can't do much except exit in that case
802 * since we may already have forked. This is based on the BSD version,
803 * so the caller is responsible for things like the umask, etc.
804 */
805
806 /* believed to work on all Posix systems */
807
808 int daemon(int nochdir, int noclose)
809 {
810 pid_t pid;
811 switch (pid = fork())
812 {
813 case 0: break;
814 case -1: return -1;
815 default: _exit(0); /* exit the original process */
816 }
817
818 if (setsid() < 0) /* shoudn't fail */
819 return -1;
820
821 /* dyke out this switch if you want to acquire a control tty in */
822 /* the future -- not normally advisable for daemons */
823
824 switch (pid = fork())
825 {
826 case 0: break;
827 case -1: return -1;
828 default:
829 ofstream outfile;
830 outfile.open(pidfile);
831 if (outfile.fail())
832 cerr << "Unable to open " << pidfile << endl;
833 outfile << pid << endl;
834 outfile.close();
835
836 _exit(0);
837 }
838
839 if (!nochdir)
840 chdir("/");
841
842 if (!noclose)
843 {
844 closeall(0);
845 open("/dev/null",O_RDWR);
846 dup(0); dup(0);
847 }
848
849 return 0;
850 }
851
852
853 /* closeall() -- close all FDs >= a specified value */
854
855 void closeall(int fd)
856 {
857 int fdlimit = sysconf(_SC_OPEN_MAX);
858
859 while (fd < fdlimit)
860 close(fd++);
861 }
862
863 void prettyIntro()
864 {
865 cout << endl;
866 cout << " GGGG AAA MM MM EEEEEEE SSSSS EEEEEEE RRRRRR VV VV " << endl;
867 cout << " GG GG AAAAA MMM MMM EE SS EE RR RR VV VV " << endl;
868 cout << "GG AA AA MM MM MM EEEEE SSSSS EEEEE RRRRRR VV VV " << endl;
869 cout << "GG GGG AAAAAAA MM MM EE SS EE RR RR VV VV " << endl;
870 cout << "G G AA AA MM MM EEEEEEE SSSSS EEEEEEE RR RR VVV" << endl;
871 cout << " GGGGG V\n\n" << endl;
872 cout << "Version: " << VERSION << endl;
873 cout << "http://www.gameserv.us - http://www.sourceforge.net/projects/gameservirc" << endl;
874 }
875
876 void load_lastrefresh()
877 {
878 ifstream infile;
879 infile.open(".gsrefresh");
880 if (infile.fail())
881 {
882 #ifdef DEBUGMODE
883 log("Error opening .gsrefresh");
884 #endif
885
886 generate:
887 long mytime = time(NULL);
888 #ifdef DEBUGMODE
889 log("Generating new refresh time");
890 #endif
891
892 // Just a safety measure... tho no one should
893 // get anywhere near the actual time as their refreshperiod
894 if (refreshperiod >= mytime)
895 {
896 log("Refresh period is greater than or equal to the actual time... setting it to 86400");
897 refreshperiod = 86400;
898 }
899
900 lastrefresh = mytime - (mytime % refreshperiod);
901
902 refreshall();
903 save_lastrefresh();
904 return;
905 }
906 infile >> lastrefresh;
907
908 infile.close();
909 if (lastrefresh < 0)
910 goto generate;
911 }
912
913 void load_lastrollover()
914 {
915 ifstream infile;
916 infile.open(".gsrollover");
917 if (infile.fail())
918 {
919 #ifdef DEBUGMODE
920 log("Error opening .gsrollover");
921 #endif
922
923 generate:
924 long mytime = time(NULL);
925 #ifdef DEBUGMODE
926 log("Generating new rollover time");
927 #endif
928 lastrollover = mytime;
929 return;
930 }
931 infile >> lastrollover;
932
933 infile.close();
934 if (lastrollover < 0)
935 goto generate;
936 }
937
938 void save_lastrefresh()
939 {
940 ofstream outfile;
941
942 outfile.open(".gsrefresh");
943
944 if (outfile.fail())
945 {
946 log("Error creating new file .gsrefresh");
947 return;
948 }
949 outfile << lastrefresh << endl << lastrollover;
950
951 outfile.close();
952 }
953
954 void save_lastrollover()
955 {
956 ofstream outfile;
957
958 outfile.open(".gsrollover");
959
960 if (outfile.fail())
961 {
962 log("Error creating new file .gsrollover");
963 return;
964 }
965 outfile << lastrollover << endl;
966 outfile.close();
967 }
968 void clearItems()
969 {
970 list<item*>::iterator iter;
971 for (iter = Items.begin(); iter != Items.end(); iter++)
972 {
973 delete (*iter);
974 Items.erase(iter);
975 }
976 }
977 void clearClients()
978 {
979 list<aClient*>::iterator iter;
980 for (unsigned long x = 0; x < U_TABLE_SIZE; x++)
981 {
982 for (iter = clients[x].begin(); iter != clients[x].end(); iter++)
983 {
984 delete (*iter);
985 clients[x].erase(iter);
986 }
987 }
988 }
989
990 void clearPlayers()
991 {
992 list<Player*>::iterator iter;
993 for (unsigned long x = 0; x < U_TABLE_SIZE; x++)
994 {
995 for (iter = players[x].begin(); iter != players[x].end(); iter++)
996 {
997 delete (*iter);
998 players[x].erase(iter);
999 }
1000 }
1001 }