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