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