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