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