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