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