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