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