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