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