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