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