]> jfr.im git - irc/gameservirc.git/blob - gameserv/gameserv.cpp
fixed a dragon bug where people could quit while they are fighting the dragon, come...
[irc/gameservirc.git] / gameserv / gameserv.cpp
1 #include "aClient.h"
2 #include "config.h"
3 #include "extern.h"
4 #include "player.h"
5 #include "pouch.h"
6 #include "flags.h"
7 #include "list.h"
8 #include "level.h"
9 #include "sockhelp.h"
10 #include "item.h"
11
12 #include <cctype>
13 #include <fstream>
14 #include <stdlib.h>
15 #include <list>
16 #include <iterator>
17
18 using namespace std;
19
20 #if defined(HAVE_CRYPT_H)
21
22 #include <crypt.h>
23
24 #elif defined(HAVE_UNISTD_H)
25
26 #include <unistd.h>
27
28 #endif
29
30 Monster dragon; // The current dragon
31 Level levels[LEVELS]; // The newest way to store monsters
32 list<item*> Items; // The master list of items
33 list<tavernItem> tavern; // The list of items available at the tavern
34 list<item*> store; // The list of items available at the store
35
36 // Database functions
37 int save_gs_dbase();
38 int load_gs_dbase();
39 int load_items();
40 int load_tavern();
41 int load_store();
42 int load_dragon();
43 int save_dragon();
44
45 item *findItemByID(int id);
46 item *findStoreItemByID(int id);
47 tavernItem *findTavernItemByID(int id);
48
49 // String functions
50 #ifndef HAVE_STRTOK
51 char *strtok(char *str, const char *delim);
52 #endif
53
54 int stricmp(const char *s1, const char *s2);
55 int strnicmp(const char *s1, const char *s2, size_t len);
56 // String Functions
57
58 /********** Password functions **********/
59
60 bool passcmp(const char *encrypted, char *plaintext); // Compares an encrypted pass with a plain text one
61
62 bool check_password(char *name, char *plaintext); // Finds a password for the given name, and checks it with passcmp against the plaintext password given.
63
64 /********** Password functions **********/
65
66
67 /********** GameServ Booleans **********/
68
69 bool shuttingdown;
70 bool timedOut(Player *p);
71 void updateTS(Player *p);
72 void timeOutEvent(Player *p);
73
74 bool is_playing(char *u); // True if the given nickname in the clients list is playing.
75 bool is_playing(aClient *user);
76
77 bool is_fighting(char *u); // True if the given nick in the clients list is fighting anything.
78 bool is_fighting(aClient *user);
79
80 bool player_fight(char *u); // True if the player is fighting another player.
81 bool player_fight(aClient *user);
82
83 bool master_fight(char *u); // True if the player is fighting their master.
84 bool master_fight(aClient *user);
85
86 bool dragon_fight(char *u); // True if the player is fighting the dragon.
87 bool dragon_fight(aClient *user);
88
89 bool alphaNumeric(const char *str); // Returns true if all of the characters in str are alphanumeric non-special chars
90 /********** GameServ Booleans **********/
91
92 void display_help(char *u, char *file = NULL);
93 void display_monster(char *u);
94 void display_players(char *u);
95 void display_players(aClient *user);
96 long int chartoint(char ch);
97 int isstringnum(char *num);
98 long int pow (int x, int y);
99 long int stringtoint(char *number);
100
101 char *spaces(int len, char *seperator);
102 void refresh(Player *p);
103 void refreshall();
104 void rollover(Player *p);
105 void rolloverall();
106
107 void updateTS(Player *p);
108 void reset(Player *p);
109 bool load_masters();
110 bool load_monsters();
111 bool load_levels();
112 void delete_monsters();
113
114 void do_admin(char *u);
115 void do_attack(char *u);
116 void do_bank(char *u);
117 void do_check(char *u);
118 void do_equip(char *u);
119 void do_fight(char *u);
120 void do_heal(char *u);
121 void do_help(char *u);
122 void do_identify(char *u);
123 void do_inventory(char *u);
124 void do_refresh(char *u);
125 void do_register(char *u);
126 void do_list(char *u);
127 void do_logout(char *u);
128 void do_master(char *u);
129 void do_dragon(char *u);
130 void do_play(char *u);
131 void do_quitg(char *u);
132 void do_reset(char *u);
133 void do_run(char *u);
134 void do_set(char *u);
135 void do_stats(char *u);
136 void do_store(char *u);
137 void do_tavern(char *u);
138 void do_use(char *u);
139 void see_master(char *u);
140
141 void logout(aClient *user);
142 void showstats(const char *u, const char *nick);
143 void showTavern(aClient *user);
144 void showinventory(Player *from, aClient *to);
145 void showBankBalance(const char *u);
146 void end_turn(aClient *user);
147
148 #define WNA 16
149
150 int hpbonus[11] = {10, 15, 20, 30, 50, 75, 125, 185, 250, 350, 550};
151 int strbonus[11] = {5, 7, 10, 12, 20, 35, 50, 75, 110, 150, 200};
152 int defbonus[11] = {2, 3, 5, 10, 15, 22, 35, 60, 80, 120, 150};
153
154 void gameserv(char *source, char *buf)
155 {
156 char *cmd, z;
157 cmd = strtok(buf, " ");
158
159 #ifndef P10
160 source++; // Get rid of that : at the beginning of a :Nick privmsg Gameserv :text
161 #endif
162
163 z = cmd[0];
164 if (z == ':')
165 cmd++; // Get rid of that : at the beginning of the :text (command)
166
167 #ifdef DEBUGMODE
168 log("Source: %s Command: %s", source, cmd);
169 #endif
170
171 if (strnicmp(cmd, "\1PING", 6) == 0)
172 {
173 char *ts;
174 ts = strtok(NULL, "\1");
175 notice(s_GameServ, source, "\1PING %s\1", ts);
176 } else if (stricmp(cmd, "\1VERSION\1") == 0) {
177 notice(s_GameServ, source, "\1VERSION %s %s\1", PACKAGE, VERSION);
178 } else if (stricmp(cmd, "SEARCH") == 0) {
179 cmd = strtok(NULL, " ");
180
181 if (!cmd)
182 notice(s_GameServ, source, "SYNTAX: /msg %S SEARCH FOREST");
183 else
184 do_forest(source);
185
186 } else if (stricmp(cmd, "ADMIN") == 0) {
187 do_admin(source);
188 } else if (stricmp(cmd, "ATTACK") == 0) {
189 do_attack(source);
190 } else if (stricmp(cmd, "BANK") == 0) {
191 do_bank(source);
192 } else if (stricmp(cmd, "CHECK") == 0) {
193 do_check(source);
194 } else if (stricmp(cmd, "DRAGON") == 0) {
195 do_dragon(source);
196 } else if (stricmp(cmd, "EQUIP") == 0) {
197 do_equip(source);
198 } else if (stricmp(cmd, "FIGHT") == 0) {
199 do_fight(source);
200 } else if (stricmp(cmd, "HEAL") == 0) {
201 do_heal(source);
202 } else if (stricmp(cmd, "HELP") == 0) {
203 do_help(source);
204 } else if (stricmp(cmd, "IDENTIFY") == 0) {
205 do_identify(source);
206 } else if (stricmp(cmd, "INVENTORY") == 0) {
207 do_inventory(source);
208 } else if (stricmp(cmd, "LIST") == 0) {
209 do_list(source);
210 } else if (stricmp(cmd, "LOGOUT") == 0) {
211 do_logout(source);
212 } else if (stricmp(cmd, "MASTER") == 0) {
213 do_master(source);
214 } else if (stricmp(cmd, "NEWS") == 0) {
215 do_news(source);
216 } else if (stricmp(cmd, "REGISTER") == 0) {
217 do_register(source);
218 } else if (stricmp(cmd, "REFRESH") == 0) {
219 do_refresh(source);
220 } else if (stricmp(cmd, "RESET") == 0) {
221 do_reset(source);
222 } else if (stricmp(cmd, "RUN") == 0) {
223 do_run(source);
224 } else if (stricmp(cmd, "SET") == 0) {
225 do_set(source);
226 } else if (stricmp(cmd, "STATS") == 0) {
227 do_stats(source);
228 } else if (stricmp(cmd, "STORE") == 0) {
229 do_store(source);
230 } else if (stricmp(cmd, "TAVERN") == 0) {
231 do_tavern(source);
232 } else if (stricmp(cmd, "USE") == 0) {
233 do_use(source);
234 } else if (stricmp(cmd, "SHUTDOWN") == 0) {
235 aClient *user;
236
237 if (!(user = find(source)))
238 {
239 notice(s_GameServ, source, "Error: aClient not found. Contact a %S admin");
240 log("Error: aClient not found: %s", source);
241 }
242 else if (!isAdmin(user))
243 {
244 notice(s_GameServ, source, "You must be a %S admin to use this command!");
245 }
246 else
247 {
248 save_gs_dbase();
249 #ifdef P10
250 raw("[] SQ %s 0 :leaving: %s used the Shutdown command.", servername, user->getRealNick());
251 #else
252 raw("SQUIT %s :leaving: %s used the Shutdown command.", servername, source);
253 #endif
254 shuttingdown = true;
255 }
256 } else if (stricmp(cmd, "SAVE") == 0) {
257 aClient *user;
258
259 if (!(user = find(source)))
260 {
261 notice(s_GameServ, source, "Error: aClient not found. Contact a %S admin");
262 log("Error: aClient not found: %s", source);
263 }
264 else if (!isAdmin(user))
265 {
266 notice(s_GameServ, source, "You must be a %S admin to use this command!");
267 }
268 else
269 {
270 save_gs_dbase();
271 }
272 } else if (stricmp(cmd, "LOAD") == 0) {
273 aClient *user;
274
275 if (!(user = find(source)))
276 {
277 notice(s_GameServ, source, "Error: aClient not found. Contact a %S admin");
278 log("Error: aClient not found: %s", source);
279 }
280 else if (!isAdmin(user))
281 {
282 notice(s_GameServ, source, "You must be a %S admin to use this command!");
283 }
284 else
285 {
286 char *cmd2 = strtok(NULL, " ");
287 if (!cmd2)
288 {
289 notice(s_GameServ, source, "Loading player data from %s", playerdata);
290 load_gs_dbase();
291 }
292 else if (stricmp(cmd2, "MONSTERS") == 0)
293 {
294 notice(s_GameServ, source, "Loading monster data");
295 load_monsters();
296 }
297 else
298 display_help(source, cmd);
299 }
300 #ifdef DEBUGMODE
301 } else if (stricmp(cmd, "RAW") == 0) {
302 aClient *user;
303
304 if (!(user = find(source)))
305 {
306 notice(s_GameServ, source, "Error: aClient not found. Contact a %S admin");
307 log("Error: aClient not found: %s", source);
308 }
309 else if (!isAdmin(user))
310 {
311 notice(s_GameServ, source, "You must be a %S admin to use this command!");
312 }
313 else
314 {
315 char *rest = strtok(NULL, "");
316 raw("%s", rest);
317 }
318 } else if (stricmp(cmd, "PRINT") == 0) {
319 for (int x = 0; x < LEVELS; x++)
320 levels[x].monsters.print();
321 } else if (stricmp(cmd, "RANDOM") == 0) {
322 char *rstr = strtok(NULL, "");
323 range trange;
324 trange.setRange(rstr);
325 notice(s_GameServ, source, "Random number in that range: %d", trange.random());
326 #endif
327 } else {
328 aClient *user;
329 if ((user = find(source)))
330 {
331 if (isIgnore(user))
332 {
333 #ifdef DEBUGMODE
334 log("Ignoring %s.", user->getNick());
335 #endif
336 }
337 else
338 {
339 notice(s_GameServ, source, "Unknown command \002%s\002. Type /msg %S \002HELP\002 to get a list of commands.", cmd);
340 }
341 }
342 }
343
344 #ifndef P10
345 source--; // Bring the ':' back so we don't leak memory
346 #endif
347 if (z == ':')
348 cmd--; // Same thing :)
349 }
350
351 int stricmp(const char *s1, const char *s2)
352 {
353 register int c;
354
355 while ((c = tolower(*s1)) == tolower(*s2)) {
356 if (c == 0)
357 return 0;
358 s1++;
359 s2++;
360 }
361 if (c < tolower(*s2))
362 return -1;
363 return 1;
364 }
365
366 void showstats(const char *u, const char *nick)
367 {
368 aClient *ni, *sender = find(u);
369 char *buf;
370 buf = new char[50];
371 char *space;
372
373
374 if (!(ni = findplayer(nick)))
375 {
376 notice(s_GameServ, u, "%s not found", nick);
377 }
378 else if (ni->stats)
379 {
380 notice(s_GameServ, sender->getNick(), "Stats for %s:", ni->stats->getName().c_str());
381
382 sprintf(buf, "Experience: %ld", ni->stats->getExp());
383 space = spaces(strlen(buf), " ");
384 notice(s_GameServ, sender->getNick(), "%s%sLevel: %d", buf, space,
385 ni->stats->getLevel());
386 delete [] space;
387
388 sprintf(buf, "Gold: %ld", ni->stats->getGold());
389 space = spaces(strlen(buf), " ");
390 notice(s_GameServ, sender->getNick(), "%s%sGold in Bank: %ld", buf, space, ni->stats->getBank());
391 delete [] space;
392
393 notice(s_GameServ, sender->getNick(), "Hit Points: %d of %d", ni->stats->getHP(),
394 ni->stats->getMaxHP());
395
396 sprintf(buf, "Strength: %d", ni->stats->getStrength());
397 space = spaces(strlen(buf), " ");
398 notice(s_GameServ, sender->getNick(), "%s%sDefense: %d",
399 buf, space, ni->stats->getDefense());
400 delete [] space;
401
402 sprintf(buf, "Armor: %s", (ni->stats->getArmor() ? ni->stats->getArmor()->getName().c_str() : "Nothing"));
403 space = spaces(strlen(buf), " ");
404
405 notice(s_GameServ, sender->getNick(), "%s%sWeapon: %s", buf, space,
406 (ni->stats->getWeapon() ? ni->stats->getWeapon()->getName().c_str() : "Fists"));
407
408 delete [] space;
409
410 sprintf(buf, "Forest Fights: %d", ni->stats->getForestFights());
411 space = spaces(strlen(buf), " ");
412 notice(s_GameServ, sender->getNick(), "%s%sPlayer Fights: %d", buf, space, ni->stats->getPlayerFights());
413 delete [] space;
414 if (ni == sender || isAdmin(sender))
415 {
416 showinventory(ni->stats, sender);
417 }
418 }
419 else
420 {
421 notice(s_GameServ, u, "%s is not playing!", ni->stats->getName().c_str());
422 }
423 delete [] buf;
424 }
425
426 char *spaces(int len, char *seperator)
427 {
428 char *final;
429 final = new char[30];
430 int y;
431 strcpy(final, seperator);
432 for (y = 0; y < 30 - len; y++)
433 strcat(final, seperator);
434 return final;
435 }
436
437 void raw(const char *fmt, ...)
438 {
439 va_list args;
440 char *input;
441 const char *t = fmt;
442 input = new char[1024];
443 va_start(args, fmt);
444 memset(input, 0, sizeof(input)); // Initialize to NULL
445 for (; *t; t++)
446 {
447 if (*t == '%')
448 {
449 switch(*++t) {
450 case 'd': sprintf(input, "%s%d", input, va_arg(args, int)); break;
451 case 's': sprintf(input, "%s%s", input, va_arg(args, char *)); break;
452 case 'S': sprintf(input, "%s%s", input, s_GameServ); break;
453 case 'l':
454 if (*++t == 'd')
455 sprintf(input, "%s%ld", input, va_arg(args, long int)); break;
456 }
457 }
458 else
459 {
460 sprintf(input, "%s%c", input, *t);
461 }
462
463 }
464 #ifdef DEBUGMODE
465 log("Input: %s", input);
466 #endif
467
468 sprintf(input, "%s%s", input, "\r\n");
469 sock_puts(sock, input);
470 delete [] input;
471 va_end(args);
472 }
473 /* Send a NOTICE from the given source to the given nick. */
474
475 void notice(const char *source, const char *dest, const char *fmt, ...)
476 {
477 if (fmt[0] == '\0')
478 return;
479
480 char *commanduse;
481 commanduse = new char[16];
482
483 #ifdef P10
484 if (isUsePrivmsg())
485 strcpy(commanduse, "P");
486 else
487 strcpy(commanduse, "O");
488 #else
489
490 if (isUsePrivmsg())
491 strcpy(commanduse, "PRIVMSG");
492 else
493 strcpy(commanduse, "NOTICE");
494 #endif
495
496 va_list args;
497 char *input;
498 const char *t = fmt;
499 input = new char[1024];
500 va_start(args, fmt);
501 if (dest[0] == ':')
502 {
503 dest++;
504
505 #if !defined(P10)
506 sprintf(input, ":%s %s %s :", source, commanduse, dest);
507 #else
508 sprintf(input, "%s %s %s :", gsnum, commanduse, dest);
509 #endif
510
511 dest--;
512 }
513 else
514 {
515 #if !defined(P10)
516 sprintf(input, ":%s %s %s :", source, commanduse, dest);
517 #else
518 sprintf(input, "%s %s %s :", gsnum, commanduse, dest);
519 #endif
520 }
521
522 for (; *t; t++)
523 {
524 if (*t == '%')
525 {
526 switch(*++t) {
527 case 'd': sprintf(input, "%s%d", input, va_arg(args, int)); break;
528 case 's': sprintf(input, "%s%s", input, va_arg(args, char *)); break;
529 case 'S': sprintf(input, "%s%s", input, s_GameServ); break;
530 case 'c': sprintf(input, "%s%c", input, va_arg(args, int)); break;
531 case 'l':
532 if (*++t == 'd')
533 sprintf(input, "%s%ld", input, va_arg(args, long int)); break;
534 }
535 }
536 else
537 {
538 sprintf(input, "%s%c", input, *t);
539 }
540
541 }
542 #ifdef DEBUGMODE
543 log("Input: %s", input);
544 #endif
545 sprintf(input, "%s%s", input, "\r\n");
546 sock_puts(sock, input);
547 delete [] commanduse;
548 delete [] input;
549 va_end(args);
550 }
551
552
553 int strnicmp(const char *s1, const char *s2, size_t len)
554 {
555 register int c;
556
557 if (!len)
558 return 0;
559 while ((c = tolower(*s1)) == tolower(*s2) && len > 0) {
560 if (c == 0 || --len == 0)
561 return 0;
562 s1++;
563 s2++;
564 }
565 if (c < tolower(*s2))
566 return -1;
567 return 1;
568 }
569
570 #ifndef HAVE_STRTOK
571 char *strtok(char *str, const char *delim)
572 {
573 static char *current = NULL;
574 char *ret;
575
576 if (str)
577 current = str;
578 if (!current)
579 return NULL;
580 current += strspn(current, delim);
581 ret = *current ? current : NULL;
582 current += strcspn(current, delim);
583 if (!*current)
584 current = NULL;
585 else
586 *current++ = 0;
587 return ret;
588 }
589 #endif
590
591 void do_check(char *u)
592 {
593 int days, hours, minutes, seconds;
594 long complete;
595 complete = (lastrefresh + refreshperiod) - time(NULL);
596 days = complete / 86400;
597 hours = (complete % 86400) / 3600;
598 minutes = (complete % 86400) % 3600 / 60;
599 seconds = (complete % 86400) % 3600 % 60;
600
601 notice(s_GameServ, u, "Time left to next refresh: %dd %dh %dm %ds",
602 days, hours, minutes, seconds);
603
604 if (isRolloverForestFights())
605 {
606 complete = (lastrollover + rolloverperiod) - time(NULL);
607
608 days = complete / 86400;
609 hours = (complete % 86400) / 3600;
610 minutes = (complete % 86400) % 3600 / 60;
611 seconds = (complete % 86400) % 3600 % 60;
612
613 notice(s_GameServ, u, "Time left to next rollover: %dd %dh %dm %ds",
614 days, hours, minutes, seconds);
615 }
616 }
617
618 void do_list(char *u)
619 {
620 aClient *user;
621 char *cmd = strtok(NULL, " ");
622
623 if (!(user = find(u)))
624 {
625 log("Fatal Error: Couldn't find %s in the client list", u);
626 return;
627 }
628 else if (isIgnore(user))
629 {
630 #ifdef DEBUGMODE
631 log("Ignoring %s. Command LIST", user->getNick());
632 #endif
633 return;
634 }
635
636 ListNode<aClient> *temp;
637 bool header = false;
638
639 for (unsigned long x = 0; x < U_TABLE_SIZE; x++)
640 {
641 temp = players[x].First();
642 if (!players[x].isEmpty())
643 {
644 while(temp)
645 {
646 if (cmd || is_playing(temp->getData()))
647 {
648 if (!header)
649 {
650 notice(s_GameServ, u, "Players:");
651 header = true;
652 }
653 #ifdef P10
654 notice(s_GameServ, u, "IRC: %s Game: %s", temp->getData()->getRealNick(),
655 temp->getData()->stats->getName().c_str());
656 #else
657 notice(s_GameServ, u, "IRC: %s Game: %s", temp->getData()->getNick(),
658 temp->getData()->stats->getName().c_str());
659 #endif
660 }
661
662 temp = temp->Next();
663 }
664 }
665 }
666 if (!header)
667 notice(s_GameServ, u, "No one is playing");
668 else
669 notice(s_GameServ, u, "End of List");
670
671 }
672 void do_set(char *u)
673 {
674 aClient *user, *target;
675 char *name = strtok(NULL, " ");
676 char *cmd = strtok(NULL, " ");
677 char *cmd2;
678
679 if (!(user = find(u)))
680 {
681 notice(s_GameServ, u, "Fatal error. Cannot find aClient. "\
682 "Buf: %s LOGOUT", u);
683 return;
684 }
685 else if (isIgnore(user))
686 {
687 #ifdef DEBUGMODE
688 log("Ignoring %s.", user->getNick());
689 #endif
690 return;
691 }
692 else if (!name || !cmd)
693 {
694 notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] {PASSWORD|BANK BALANCE|PLAYER FIGHTS|FOREST FIGHTS|GOLD|STRENGTH|DEFENSE|HP|MAXHP|EXP|LEVEL|ALIVE|SEEN MASTER} {STRING|NUMBER|TRUE|FALSE}");
695 return;
696 }
697 else if (!(target = findplayer(name)))
698 {
699 // Back the pointers up... they didn't send a name probably
700 cmd2 = cmd;
701 cmd = name;
702 target = user;
703
704 if (!is_playing(user))
705 {
706 notice(s_GameServ, u, "You must be playing to set things for yourself!");
707 return;
708 }
709 }
710 else
711 {
712 cmd2 = strtok(NULL, " ");
713 }
714 if (!cmd2)
715 {
716 notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] {PASSWORD|BANK BALANCE|PLAYER FIGHTS|FOREST FIGHTS|GOLD|STRENGTH|DEFENSE|HP|MAXHP|EXP|LEVEL|ALIVE|SEEN MASTER} {STRING|NUMBER|TRUE|FALSE}");
717 return;
718 }
719
720 // Regardless of the previous if/else, if it got here, we know we have the cmd pointer at the right spot.
721 if (stricmp(cmd, "PASSWORD") == 0)
722 {
723 // Person is looking to change their password
724 // If they're an admin, or it's theirself, allow it
725 // cmd2 is pointing to the password now
726 if (isAdmin(user) || user == target)
727 {
728 target->stats->setPassword(cmd2);
729 notice(s_GameServ, u, "Password successfully changed");
730 }
731 else if (user != target && !isAdmin(user))
732 {
733 notice(s_GameServ, u, "You must be a %S admin to set other peoples' passwords.");
734 return;
735 }
736 }
737 else if (stricmp(cmd, "BANK") == 0 || stricmp(cmd, "BALANCE") == 0)
738 {
739 if (!isAdmin(user))
740 {
741 notice(s_GameServ, u, "Admins Only!");
742 return;
743 }
744 else if (stricmp(cmd, "BANK") == 0)
745 {
746 cmd2 = strtok(NULL, " "); // Need an extra parameter for set bank balance
747 }
748 if (!cmd2)
749 {
750 notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] [BANK] BALANCE <NUMBER>");
751 return;
752 }
753
754 target->stats->setBank(stringtoint(cmd2));
755
756 notice(s_GameServ, u, "Bank balance changed to %ld!", target->stats->getBank());
757 }
758 else if (stricmp(cmd, "PLAYER") == 0)
759 {
760 if (!isAdmin(user))
761 {
762 notice(s_GameServ, u, "Admins Only!");
763 return;
764 }
765 else if (stricmp(cmd2, "FIGHTS") != 0)
766 {
767 notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] PLAYER FIGHTS <NUMBER>");
768 return;
769 }
770 else
771 {
772 cmd2 = strtok(NULL, " ");
773 if (!cmd2)
774 {
775 notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] PLAYER FIGHTS <NUMBER>");
776 return;
777 }
778 target->stats->setPlayerFights(stringtoint(cmd2));
779
780 notice(s_GameServ, u, "Player fights changed to %d!", target->stats->getPlayerFights());
781 }
782 }
783 else if (stricmp(cmd, "FOREST") == 0)
784 {
785 if (!isAdmin(user))
786 {
787 notice(s_GameServ, u, "Admins Only!");
788 return;
789 }
790 else if (stricmp(cmd2, "FIGHTS") != 0)
791 {
792 notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] FOREST FIGHTS <number>");
793 return;
794 }
795 else
796 {
797 cmd2 = strtok(NULL, " ");
798 if (!cmd2)
799 {
800 notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] FOREST FIGHTS <NUMBER>");
801 return;
802 }
803
804 target->stats->setForestFights(stringtoint(cmd2));
805
806 notice(s_GameServ, u, "Forest fights changed to %d!", target->stats->getForestFights());
807 }
808 }
809 else if (stricmp(cmd, "GOLD") == 0)
810 {
811 if (!isAdmin(user))
812 {
813 notice(s_GameServ, u, "Admins Only!");
814 return;
815 }
816 else
817 {
818 if (!cmd2)
819 {
820 notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] GOLD <NUMBER>");
821 return;
822 }
823 target->stats->setGold(stringtoint(cmd2));
824
825 notice(s_GameServ, u, "Gold set to %ld", target->stats->getGold());
826 return;
827 }
828 }
829 else if (stricmp(cmd, "STRENGTH") == 0 && stricmp(cmd2, "POTIONS") != 0)
830 {
831 if (!isAdmin(user))
832 {
833 notice(s_GameServ, u, "Admins Only!");
834 return;
835 }
836 else
837 {
838 if (!cmd2)
839 {
840 notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] STRENGTH <NUMBER>");
841 return;
842 }
843
844 target->stats->setStrength(stringtoint(cmd2));
845
846 notice(s_GameServ, u, "Strength set to %d", target->stats->getStrength());
847 return;
848 }
849 }
850 else if (stricmp(cmd, "DEFENSE") == 0 && stricmp(cmd2, "POTIONS") != 0)
851 {
852 if (!isAdmin(user))
853 {
854 notice(s_GameServ, u, "Admins Only!");
855 return;
856 }
857 else
858 {
859 if (!cmd2)
860 {
861 notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] DEFENSE <NUMBER>");
862 return;
863 }
864
865 target->stats->setDefense(stringtoint(cmd2));
866
867 notice(s_GameServ, u, "Defense set to %d", target->stats->getDefense());
868 return;
869 }
870 }
871 else if (stricmp(cmd, "HP") == 0 && stricmp(cmd2, "POTIONS") != 0)
872 {
873 if (!isAdmin(user))
874 {
875 notice(s_GameServ, u, "Admins Only!");
876 return;
877 }
878 else
879 {
880 if (!cmd2)
881 {
882 notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] HP <NUMBER>");
883 return;
884 }
885 target->stats->setHP(stringtoint(cmd2));
886
887 notice(s_GameServ, u, "HP set to %d", target->stats->getHP());
888 return;
889 }
890 }
891 else if (stricmp(cmd, "MAXHP") == 0)
892 {
893 if (!isAdmin(user))
894 {
895 notice(s_GameServ, u, "Admins Only!");
896 return;
897 }
898 else
899 {
900 if (!cmd2)
901 {
902 notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] MAXHP <NUMBER>");
903 return;
904 }
905 target->stats->setMaxHP(stringtoint(cmd2));
906
907 notice(s_GameServ, u, "MaxHP set to %d", target->stats->getMaxHP());
908 return;
909 }
910 }
911 else if (stricmp(cmd, "EXPERIENCE") == 0 || stricmp(cmd, "EXP") == 0)
912 {
913 if (!isAdmin(user))
914 {
915 notice(s_GameServ, u, "Admins Only!");
916 return;
917 }
918 else
919 {
920 if (!cmd2)
921 {
922 notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] {EXPERIENCE|EXP} <NUMBER>");
923 return;
924 }
925
926 target->stats->setExp(stringtoint(cmd2));
927
928 notice(s_GameServ, u, "Exp set to %ld", target->stats->getExp());
929 return;
930 }
931 }
932 else if (stricmp(cmd, "LEVEL") == 0)
933 {
934 if (!isAdmin(user))
935 {
936 notice(s_GameServ, u, "Admins Only!");
937 return;
938 }
939 else
940 {
941 if (!cmd2)
942 {
943 notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] LEVEL <NUMBER>");
944 return;
945 }
946 target->stats->setLevel(stringtoint(cmd2));
947
948 notice(s_GameServ, u, "Level set to %d", target->stats->getLevel());
949 return;
950 }
951 }
952 else if (stricmp(cmd, "ALIVE") == 0)
953 {
954 if (!isAdmin(user))
955 {
956 notice(s_GameServ, u, "Admins Only!");
957 return;
958 }
959 else
960 {
961 if (!cmd2)
962 {
963 notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] ALIVE TRUE|FALSE");
964 return;
965 }
966 else if (stricmp(cmd2, "TRUE") == 0)
967 {
968 notice(s_GameServ, u, "%s has been Resurrected!", target->stats->getName().c_str());
969 setAlive(target->stats);
970 }
971 else
972 {
973 notice(s_GameServ, u, "%s is now dead!", target->stats->getName().c_str());
974 clearAlive(target->stats);
975 }
976 }
977 }
978 else if (stricmp(cmd, "SEEN") == 0)
979 {
980 if (!isAdmin(user))
981 {
982 notice(s_GameServ, u, "Admins Only!");
983 return;
984 }
985 else if (stricmp(cmd2, "MASTER") != 0)
986 {
987 notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] SEEN MASTER {TRUE|FALSE}");
988 return;
989 }
990 else
991 {
992 cmd2 = strtok(NULL, " ");
993 if (!cmd2)
994 {
995 notice(s_GameServ, u, "SYNTAX: /msg %S SET [NICK] SEEN MASTER {TRUE|FALSE}");
996 return;
997 }
998 else if (stricmp(cmd2, "TRUE") == 0)
999 {
1000 notice(s_GameServ, u, "%s has seen their master now.", target->stats->getName().c_str());
1001 target->stats->addFlag(FLAG_MASTER);
1002 }
1003 else
1004 {
1005 notice(s_GameServ, u, "%s has not seen their master now.", target->stats->getName().c_str());
1006 target->stats->remFlag(FLAG_MASTER);
1007 }
1008 }
1009 }
1010 else
1011 {
1012 notice(s_GameServ, u, "Unknown command: SET %s", cmd);
1013 notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] {PASSWORD|BANK BALANCE|PLAYER FIGHTS|FOREST FIGHTS|GOLD|STRENGTH|DEFENSE|HP|MAXHP|EXP|LEVEL|ALIVE|SEEN MASTER} {STRING|NUMBER|TRUE|FALSE}");
1014 return;
1015 }
1016 }
1017
1018 void do_logout(char *u)
1019 {
1020 aClient *user;
1021 char *name = strtok(NULL, " ");
1022
1023 if (!(user = find(u)))
1024 {
1025 notice(s_GameServ, u, "Fatal error. Cannot find aClient. "\
1026 "Buf: %s LOGOUT", u);
1027 log("Could not find aClient Buf: %s LOGOUT",
1028 u);
1029 return;
1030 }
1031 else if (isIgnore(user))
1032 {
1033 #ifdef DEBUGMODE
1034 log("Ignoring %s.", user->getNick());
1035 #endif
1036 return;
1037 }
1038
1039 if (name)
1040 {
1041 if (!isAdmin(user))
1042 {
1043 notice(s_GameServ, u, "You must be a %S admin to use this command!");
1044 }
1045 else if (!(user = findplayer(name)))
1046 {
1047 notice(s_GameServ, u, "Couldn't find a player named %s", name);
1048 }
1049 else
1050 {
1051 notice(s_GameServ, u, "Logging out %s", user->stats->getName().c_str());
1052 logout(user);
1053 }
1054 }
1055 else if (!name)
1056 {
1057 if (!is_playing(user))
1058 {
1059 notice(s_GameServ, u, "You're not logged in!");
1060 }
1061 else if (is_fighting(user))
1062 {
1063 notice(s_GameServ, u, "You can't logout while fighting!");
1064 }
1065 else
1066 {
1067 notice(s_GameServ, u, "You have left the fields. You have lived to kill another day!");
1068 logout(user);
1069 }
1070 }
1071 }
1072
1073 void logout(aClient *user)
1074 {
1075 if (is_playing(user))
1076 {
1077 ListNode<aClient> *it;
1078 aClient *temp;
1079 unsigned long hv = iHASH((unsigned char *) user->stats->getName().c_str());
1080 it = players[hv].Find(user);
1081
1082 if (!it)
1083 {
1084 notice(s_GameServ, user->getNick(), "Fatal error. Contact "\
1085 "%S Admin. Cannot find you in the players list.");
1086 log("Error on logout(). Can't find %s in the players list",
1087 #ifdef P10
1088 user->getRealNick()
1089 #else
1090 user->getNick()
1091 #endif
1092 );
1093 return;
1094 }
1095 user->stats->delMonster();
1096 user->stats->delMaster();
1097 clearDragonFight(user->stats);
1098
1099 if (player_fight(user))
1100 user->stats->getBattle()->stats->delBattle();
1101
1102 user->stats->delBattle();
1103
1104 temp = new aClient;
1105 temp->stats = new Player;
1106 temp->stats->setData(user->stats);
1107 user->stats->setClient(NULL);
1108
1109
1110 delete user->stats;
1111 user->stats = NULL;
1112 temp->stats->setClient(NULL);
1113 #ifdef P10
1114 temp->setRealNick("Not Playing");
1115 #endif
1116 temp->setNick("Not Playing");
1117
1118 it->setNewPtr(temp);
1119 #ifdef DEBUGMODE
1120 log("Logged out player %s",
1121 #ifdef P10
1122 user->getRealNick()
1123 #else
1124 user->getNick()
1125 #endif
1126 );
1127 #endif
1128 }
1129 clearPlaying(user);
1130 }
1131
1132 void do_register(char *u)
1133 {
1134 char *password, *name;
1135 aClient *user;
1136 name = strtok(NULL, " ");
1137 password = strtok(NULL, " ");
1138
1139 if (!name)
1140 {
1141 notice(s_GameServ, u, "SYNTAX: /msg %S REGISTER NAME PASSWORD");
1142 }
1143 else if (stricmp(name, s_GameServ) == 0)
1144 {
1145 notice(s_GameServ, u, "You can't use %S as a name!");
1146 }
1147 else if (!password)
1148 {
1149 notice(s_GameServ, u, "SYNTAX: /msg %S REGISTER NAME PASSWORD");
1150 }
1151 else if ((user = findplayer(name)))
1152 {
1153 notice(s_GameServ, u, "%s is already registered!", name);
1154 notice(s_GameServ, u, "Choose another name!");
1155 }
1156 else if (!(user = find(u)))
1157 {
1158 log("Fatal Error: Couldn't find %s in the clients list", u);
1159 }
1160 else if (!alphaNumeric(name))
1161 {
1162 notice(s_GameServ, u, "That is not a valid name. Please use only AlphaNumeric (A-Z, 0-9) characters!");
1163 }
1164 else if (isIgnore(user))
1165 {
1166 #ifdef DEBUGMODE
1167 log("Ignoring %s.", user->getNick());
1168 #endif
1169 }
1170 else
1171 {
1172 if (!is_playing(user))
1173 {
1174 ListNode<aClient> *temp;
1175 item *tempItem;
1176 user->stats = new Player();
1177 user->stats->setClient(user); // Set the backwards pointer
1178 user->stats->reset(); // set the user up
1179 user->stats->setPassword(password);
1180 user->stats->setName(name);
1181 unsigned long hv = iHASH((unsigned char *) name);
1182 updateTS(user->stats);
1183 temp = players[hv].insertAtBack_RLN(user);
1184 temp->setPtr(user); // This is an extra step, but necessary for now
1185
1186 // Update the last login time
1187 user->stats->lastlogin = time(NULL);
1188
1189 notice(s_GameServ, u, "Player %s registered with password %s.", user->stats->getName().c_str(), password);
1190 notice(s_GameServ, u, "Write this password down. If you lose it, there is no way to retrieve it!");
1191 log("Nickname %s registered player %s.", u, user->stats->getName().c_str());
1192 setPlaying(user); // set the playing flag
1193 tempItem = findItemByID(3001);
1194 user->stats->inventory->addItem((*Items.begin()))->use(user->stats); // Add the stick
1195 user->stats->inventory->addItem(tempItem)->use(user->stats); // Add Clothes
1196 }
1197 else
1198 {
1199 notice(s_GameServ, u, "Already registered. Contact a %S admin for help.");
1200 }
1201 }
1202 }
1203
1204 void do_identify(char *u)
1205 {
1206 char *password, *name;
1207 aClient *user, *p;
1208 name = strtok(NULL, " ");
1209 password = strtok(NULL, " ");
1210 if (!password || !name)
1211 {
1212 notice(s_GameServ, u, "SYNTAX: /msg %S IDENTIFY NAME PASSWORD");
1213 }
1214 else if (!(user = find(u)))
1215 {
1216 notice(s_GameServ, u, "Fatal error. Cannot find aClient. Buf: %s", strtok(NULL, ""));
1217 log("Error: aClient not found: %s", u);
1218 }
1219 else if (isIgnore(user))
1220 {
1221 #ifdef DEBUGMODE
1222 log("Ignoring %s.", user->getNick());
1223 #endif
1224 return;
1225 }
1226 else if (!(p = findplayer(name)) || !p->stats)
1227 notice(s_GameServ, u, "Player %s not found", name);
1228 else if (is_playing(user))
1229 {
1230 notice(s_GameServ, u, "You are already playing!");
1231 }
1232 else if (p->stats->getClient() != NULL && !isAdmin(user))
1233 {
1234 notice(s_GameServ, u, "That player has already identified.");
1235 }
1236 else if (!check_password(name, password) && !isAdmin(user))
1237 {
1238 notice(s_GameServ, u, "Password incorrect");
1239 }
1240 else
1241 {
1242 ListNode<aClient> *temp;
1243 unsigned long hv = iHASH((unsigned char *) p->stats->getName().c_str());
1244 temp = players[hv].Find(p);
1245 if (!temp)
1246 {
1247 notice(s_GameServ, u, "Fatal error. Contact %S Admin. Buf: %s",
1248 strtok(NULL, ""));
1249 return;
1250 }
1251 user->stats = new Player(p->stats->getName());
1252 #ifdef DEBUGMODE
1253 log("Setting data for identified");
1254 #endif
1255 user->stats->setData(p->stats);
1256 user->stats->setClient(user);
1257 updateTS(user->stats);
1258
1259
1260 #ifdef DEBUGMODE
1261 log("Player %s IRC: %s Identified", user->stats->getName().c_str(),
1262 user->getNick());
1263 #endif
1264
1265 setPlaying(user); // set the playing flag
1266
1267 temp->setPtr(user);
1268
1269 // Update the last login time
1270 user->stats->lastlogin = time(NULL);
1271
1272 notice(s_GameServ, u, "Password Accepted. Identified.");
1273 showNews(u, todaysnews);
1274 }
1275 }
1276
1277 void do_stats(char *u)
1278 {
1279 char *nick;
1280 aClient *user;
1281
1282 nick = strtok(NULL, " ");
1283
1284 if (!(user = find(u)))
1285 {
1286 log("Fatal Error: %s not found in client list", u);
1287 return;
1288 }
1289 else if (isIgnore(user))
1290 {
1291 #ifdef DEBUGMODE
1292 log("Ignoring %s.", user->getNick());
1293 #endif
1294 return;
1295 }
1296 else if (!nick)
1297 {
1298 if (!is_playing(user))
1299 {
1300 notice(s_GameServ, u, "You're not playing, so you have no stats!");
1301 return;
1302 }
1303 else
1304 {
1305 updateTS(user->stats);
1306 showstats(u, user->stats->getName().c_str());
1307 }
1308 }
1309 else
1310 showstats(u, nick);
1311 }
1312
1313 bool load_masters()
1314 {
1315 ifstream infile(masterdata);
1316 char *buf;
1317 int l = 0;
1318 buf = new char[1024];
1319
1320 if (infile.fail())
1321 {
1322 log("Error opening %s", masterdata);
1323 return false;
1324 }
1325
1326 #ifdef DEBUGMODE
1327 log("Loading masters from %s", masterdata);
1328 #endif
1329
1330 for (l = 0; l < LEVELS - 1; l++)
1331 {
1332 infile.getline(buf, 1024, '\n');
1333
1334 log("%s", buf);
1335 if (buf[0] == '#' || buf[0] == '\n' || buf[0] == '\r')
1336 {
1337 l--;
1338 continue;
1339 }
1340 else if (buf[0] == '^')
1341 break;
1342
1343 Monster *master = &levels[l].master;
1344
1345 char *name, *weapon, *strength, *gold, *exp, *maxhp, *death;
1346
1347
1348 name = strtok(buf, "~");
1349 weapon = strtok(NULL, "~");
1350 strength = strtok(NULL, "~");
1351 gold = strtok(NULL, "~");
1352 exp = strtok(NULL, "~");
1353 maxhp = strtok(NULL, "~");
1354 death = strtok(NULL, "~");
1355
1356 master->name = name;
1357 master->weapon = weapon;
1358 master->strength = stringtoint(strength);
1359 master->gold = stringtoint(gold);
1360 master->exp = stringtoint(exp);
1361 master->maxhp = stringtoint(maxhp);
1362 master->hp = master->maxhp;
1363 master->death = death;
1364 }
1365
1366 delete []buf;
1367
1368 if (l < LEVELS - 1) // We didn't load a master for every level - check data/masters.dat
1369 return false;
1370 else
1371 return true;
1372 }
1373
1374 void delete_monsters()
1375 {
1376 for (int x = 0; x < LEVELS; x++)
1377 levels[x].monsters.deleteNodes();
1378 }
1379
1380 void display_monster(char *u)
1381 {
1382 if (is_playing(u))
1383 {
1384 aClient *user = find(u);
1385 Player *ni = user->stats;
1386
1387 notice(s_GameServ, u, "Your Hitpoints: \ 2%d\ 2", ni->getHP());
1388 notice(s_GameServ, u, "%s's Hitpoints: \ 2%d\ 2", ni->getMonster()->name.c_str(), ni->getMonster()->hp);
1389 notice(s_GameServ, u, "Here are your commands:");
1390 notice(s_GameServ, u, "/msg %S attack");
1391 notice(s_GameServ, u, "/msg %S run");
1392 notice(s_GameServ, u, "What will you do?");
1393 }
1394 }
1395
1396 void display_players(char *u)
1397 {
1398 aClient *user;
1399 if (!(user = find(u)))
1400 {
1401 log("Fatal error in display_players(): Couldn't find %s", u);
1402 }
1403 else
1404 display_players(user);
1405 }
1406
1407 void display_players(aClient *user)
1408 {
1409 char *u = user->getNick();
1410 if (is_playing(user) && player_fight(user))
1411 {
1412 aClient *battle = user->stats->getBattle();
1413 notice(s_GameServ, u, "Your Hitpoints: \ 2%d\ 2", user->stats->getHP());
1414 notice(s_GameServ, u, "%s's Hitpoints: \ 2%d\ 2", battle->stats->getName().c_str(), battle->stats->getHP());
1415 notice(s_GameServ, u, "Here are your commands:");
1416 notice(s_GameServ, u, "/msg %S attack");
1417 notice(s_GameServ, u, "/msg %S run");
1418 notice(s_GameServ, u, "What will you do?");
1419 }
1420 }
1421
1422
1423 bool is_playing(char *u)
1424 {
1425 aClient *user;
1426 if (!(user = find(u)))
1427 return false;
1428 else
1429 return is_playing(user);
1430 }
1431
1432 bool is_playing(aClient *user)
1433 {
1434 if (user->stats == NULL)
1435 {
1436 return false;
1437 }
1438 else if (user->stats->getClient() == NULL)
1439 {
1440 return false;
1441 }
1442 else if (!FL_is_playing(user))
1443 {
1444 return false;
1445 }
1446 else
1447 return true;
1448 }
1449
1450 bool is_fighting(char *u)
1451 {
1452 aClient *user;
1453
1454 if (!(user = find(u)))
1455 return false;
1456 else
1457 return is_fighting(user);
1458 }
1459
1460 bool is_fighting(aClient *user)
1461 {
1462 if (!is_playing(user))
1463 return false;
1464 else
1465 return player_fight(user) || master_fight(user) || user->stats->getMonster() != NULL;
1466 }
1467
1468 bool player_fight(char *u)
1469 {
1470 aClient *user;
1471
1472 if (!(user = find(u)))
1473 return false;
1474 else
1475 return player_fight(user);
1476 }
1477
1478 bool player_fight(aClient *user)
1479 {
1480 if (!is_playing(user))
1481 return false;
1482 else if (user->stats->getBattle() != NULL && is_playing(user->stats->getBattle()))
1483 {
1484 return user->stats->getBattle()->stats != NULL;
1485 }
1486 return false;
1487 }
1488
1489 bool master_fight(char *u)
1490 {
1491 aClient *user;
1492
1493 if (!(user = find(u)))
1494 return false;
1495 else
1496 return master_fight(user);
1497 }
1498
1499 bool master_fight(aClient *user)
1500 {
1501 if (!is_playing(user))
1502 return false;
1503 else
1504 return user->stats->getMaster() != NULL;
1505 }
1506
1507 bool dragon_fight(char *u)
1508 {
1509 aClient *user;
1510 if (!(user = find(u)))
1511 return false;
1512 else
1513 return dragon_fight(user);
1514 }
1515
1516 bool dragon_fight(aClient *user)
1517 {
1518 if (!is_playing(user))
1519 return false;
1520 else
1521 return (isDragonFight(user->stats));
1522 }
1523
1524 bool alphaNumeric(const char *str)
1525 {
1526 int len = strlen(str);
1527 for (int x = 0; x < len; x++)
1528 {
1529 if (!((int(str[x]) >= 65 && int(str[x]) <= 90) || (int(str[x]) >= 97 && int(str[x]) <= 122) || (int(str[x]) >= 48 && int(str[x]) <= 57) || int(str[x]) == 95))
1530 return false;
1531 }
1532 return true;
1533 }
1534
1535 void do_fight(char *u)
1536 {
1537 aClient *ni, *battle;
1538
1539 char *nick = strtok(NULL, " ");
1540
1541 if (!nick)
1542 {
1543 notice(s_GameServ, u, "SYNTAX: /msg %S FIGHT PLAYER");
1544 return;
1545 }
1546 else if (!(ni = find(u)))
1547 {
1548 notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, ""));
1549 return;
1550 }
1551 else if (isIgnore(ni))
1552 {
1553 #ifdef DEBUGMODE
1554 log("Ignoring %s.", ni->getNick());
1555 #endif
1556 return;
1557 }
1558 else if (!is_playing(ni))
1559 {
1560 notice(s_GameServ, u, "You are not playing!");
1561 return;
1562 }
1563
1564 updateTS(ni->stats);
1565
1566 if (ni->stats->getPlayerFights() <= 0)
1567 {
1568 ni->stats->setPlayerFights(0); // just to be safe
1569 notice(s_GameServ, u, "You are out of player fights for the "\
1570 "day. You have to wait until tomorrow!");
1571 }
1572 else if (!(battle = findplayer(nick)))
1573 {
1574 notice(s_GameServ, u, "Player %s not found!", nick);
1575 }
1576 else if (!isAlive(ni->stats))
1577 {
1578 notice(s_GameServ, u, "You are dead. Wait until tomorrow to fight others!");
1579 }
1580 else if (!is_playing(battle))
1581 {
1582 notice(s_GameServ, u, "You can't attack %s while they aren't playing!", nick);
1583 }
1584
1585 /* offline fighting not available yet
1586 else if (!(fight = finduser(nick)))
1587 {
1588 ni->stats->battle = battle;
1589 battle->battle = ni;
1590 setYourTurn(ni->stats);
1591 clearYourTurn(battle->stats);
1592
1593 notice(s_GameServ, u, "You decide to fight %s while they're "\
1594 "not in the realm!",
1595 battle->stats->name.c_str());
1596 display_players(u);
1597 }
1598 */
1599 else if (stricmp(ni->stats->getName().c_str(), battle->stats->getName().c_str()) == 0)
1600 {
1601 notice(s_GameServ, u, "Are you trying to commit suicide!?");
1602 }
1603 else if (!isAlive(battle->stats))
1604 {
1605 notice(s_GameServ, u, "They are dead. Cannot fight dead players!");
1606 }
1607 else if (player_fight(battle))
1608 {
1609 notice(s_GameServ, u, "%s is fighting %s already!", battle->stats->getName().c_str(), battle->stats->getBattle()->stats->getName().c_str());
1610 }
1611 else if (master_fight(battle))
1612 {
1613 notice(s_GameServ, u, "%s is fighting their master!", battle->stats->getName().c_str());
1614 }
1615 else if (is_fighting(battle))
1616 {
1617 notice(s_GameServ, u, "%s is fighting %s already!", battle->stats->getName().c_str(), battle->stats->getMonster()->name.c_str());
1618 }
1619 else if (!isAdmin(ni) && isFairFights() && (ni->stats->getStrength()/2 - battle->stats->getDefense()) > battle->stats->getHP())
1620 {
1621 notice(s_GameServ, u, "Fair fighting is enabled, and you're too strong for %s!", battle->stats->getName().c_str());
1622 }
1623 else if (ni->stats->getLevel() - battle->stats->getLevel() > maxbfightdistance)
1624 {
1625 // You can't fight someone below you by more than X level(s)
1626 // level 12 can fight level (12 - X) but not < (12 - X)
1627 notice(s_GameServ, u, "You may not fight %s. You're too strong!",
1628 battle->stats->getName().c_str());
1629 }
1630 else if (battle->stats->getLevel() - ni->stats->getLevel() > maxafightdistance)
1631 {
1632 // You can't fight someone above you by more than X level(S)
1633 // level 1 can fight level (1 + X), but not > (1 + X)
1634 notice(s_GameServ, u, "%s, do you really have a death wish? Try the forest you "\
1635 "weakling!", ni->stats->getName().c_str());
1636 }
1637 else
1638 {
1639 // Set your battle pointer to the other player
1640 ni->stats->setBattle(battle);
1641
1642 // Set the other player's battle pointer to you
1643 battle->stats->setBattle(ni);
1644
1645 // The initiator gets the first move (perhaps this should be 50/50)
1646 setYourTurn(ni->stats);
1647 clearYourTurn(battle->stats);
1648
1649 // Initiate Battle sequence!
1650 ni->stats->subtractPlayerFights(1);
1651
1652 notice(s_GameServ, u, "You challenge %s to an online duel!", battle->stats->getName().c_str());
1653 notice(s_GameServ, c_Forest, "%s walks up and hits %s in the face! Let's see who will bite the dust.",
1654 ni->stats->getName().c_str(), battle->stats->getName().c_str()); /* DrLnet - Modified by Kain*/
1655
1656 notice(s_GameServ, battle->getNick(), "%s has challenged you to an online duel!", ni->stats->getName().c_str());
1657 notice(s_GameServ, battle->getNick(), "%s gets to go first "\
1658 "because they initiated!", ni->stats->getName().c_str());
1659 notice(s_GameServ, battle->getNick(), "Please wait while %s decides what to do.", ni->stats->getName().c_str());
1660 display_players(ni);
1661 }
1662 }
1663
1664 void do_equip(char *u)
1665 {
1666 aClient *user;
1667 pouch *p;
1668 itemContainer *equip;
1669 int id;
1670
1671 char *item = strtok(NULL, " ");
1672
1673 if (!item || int(item[0]) < 48 || int(item[0] > 57))
1674 {
1675 notice(s_GameServ, u, "SYNTAX: EQUIP ####");
1676 notice(s_GameServ, u, "Type /msg %S HELP EQUIP for more information.");
1677 return;
1678 }
1679 else if (!(user = find(u)))
1680 {
1681 notice(s_GameServ, u, "Fatal error in do_equip. Contact a(n) %S Admin");
1682 return;
1683 }
1684 else if (isIgnore(user))
1685 {
1686 #ifdef DEBUGMODE
1687 log("Ignoring %s.", user->getNick());
1688 #endif
1689 return;
1690 }
1691 else if (!is_playing(user))
1692 {
1693 notice(s_GameServ, u, "You must be playing to equip weapons and armor!");
1694 return;
1695 }
1696 id = stringtoint(item);
1697 updateTS(user->stats);
1698 p = user->stats->inventory;
1699
1700
1701 if (!(equip = p->Find(id)))
1702 {
1703 if (!p->isEmpty())
1704 {
1705 notice(s_GameServ, u, "You aren't carrying that item!");
1706 }
1707 showinventory(user->stats, user);
1708 }
1709 else if (equip->getItem()->getType() != ARMOR && equip->getItem()->getType() != WEAPON)
1710 {
1711 notice(s_GameServ, u, "You can't use %s like that. Try /msg %S use", equip->getItem()->getName().c_str());
1712 }
1713 else
1714 {
1715 // Use the item
1716 notice(s_GameServ, u, "You equip %s.", equip->getItem()->getName().c_str());
1717 equip->use(user->stats);
1718 }
1719 }
1720 void do_use(char *u)
1721 {
1722 aClient *user;
1723 pouch *p;
1724
1725 char *item = strtok(NULL, " ");
1726 int id;
1727 itemContainer *used;
1728
1729 if (!item || int(item[0]) < 48 || int(item[0]) > 57)
1730 {
1731 notice(s_GameServ, u, "SYNTAX: USE ####");
1732 notice(s_GameServ, u, "Type /msg %S HELP USE for more information.");
1733 return;
1734 }
1735 else if (!(user = find(u)))
1736 {
1737 notice(s_GameServ, u, "Fatal Error in do_use. Contact a(n) %S Admin");
1738 return;
1739 }
1740 else if (isIgnore(user))
1741 {
1742 #ifdef DEBUGMODE
1743 log("Ignoring %s.", user->getNick());
1744 #endif
1745 return;
1746 }
1747 else if (!is_playing(user))
1748 {
1749 notice(s_GameServ, u, "You must be playing to use items!");
1750 return;
1751 }
1752 id = stringtoint(item);
1753 updateTS(user->stats);
1754 p = user->stats->inventory;
1755
1756
1757 if (!(used = p->Find(id)))
1758 {
1759 if (!p->isEmpty())
1760 {
1761 notice(s_GameServ, u, "You aren't carrying that item!");
1762 }
1763 showinventory(user->stats, user);
1764 }
1765 else if (used->getItem()->getType() != POTION)
1766 {
1767 notice(s_GameServ, u, "You can't use %s like that. Try /msg %S equip", used->getItem()->getName().c_str());
1768 }
1769 else
1770 {
1771 // Use the item
1772 notice(s_GameServ, u, "You used %s.", used->getItem()->getName().c_str());
1773 used->use(user->stats);
1774 if (used->getUses() <= 0)
1775 {
1776 p->deleteItem(used->getItem());
1777 }
1778 end_turn(user);
1779 }
1780 }
1781 void do_run(char *u)
1782 {
1783 aClient *user;
1784 Player *p, *p2 = NULL;
1785
1786 if (!(user = find(u)))
1787 {
1788 notice(s_GameServ, u, "Couldn't find you. Error. Contact a %S admin");
1789 return;
1790 }
1791 else if (isIgnore(user))
1792 {
1793 #ifdef DEBUGMODE
1794 log("Ignoring %s.", user->getNick());
1795 #endif
1796 return;
1797 }
1798 else if (!is_playing(user))
1799 {
1800 notice(s_GameServ, u, "You must be playing to run!");
1801 return;
1802 }
1803
1804 updateTS(user->stats);
1805 p = user->stats;
1806
1807 if (p->getBattle())
1808 p2 = p->getBattle()->stats;
1809
1810 if (!is_fighting(user))
1811 notice(s_GameServ, u, "You run in place... try fighting next time.");
1812 else if (!player_fight(user) && !master_fight(user) && !dragon_fight(user))
1813 {
1814 notice(s_GameServ, u, "You run away from \ 2%s\ 2 like a little baby!", p->getMonster()->name.c_str());
1815 p->delMonster();
1816 }
1817 else if (player_fight(user) && isYourTurn(p))
1818 {
1819 notice(s_GameServ, u, "You run away from \ 2%s\ 2 like a little baby!", p2->getName().c_str());
1820 notice(s_GameServ, p->getBattle()->getNick(), "\ 2%s\ 2 ran away from you like a little baby!", p->getName().c_str());
1821 addNews(todaysnews, "%s ran away from %s like a little baby!!", p->getName().c_str(), p2->getName().c_str()); /* DrLnet - edited by Kain */
1822 p2->delBattle();
1823 }
1824 else if (player_fight(user) && !isYourTurn(p))
1825 {
1826 notice(s_GameServ, u, "It is not your turn. Please wait until \ 2%s\ 2 decides what to do.", p2->getName().c_str());
1827 }
1828 else if (master_fight(user))
1829 {
1830 notice(s_GameServ, u, "You cannot run from \ 2%s\ 2! FIGHT!", p->getMaster()->name.c_str());
1831 }
1832 else if (dragon_fight(user))
1833 {
1834 notice(s_GameServ, u, "You cannot run from %s! FIGHT!", dragon.name.c_str());
1835 }
1836 }
1837
1838 void end_turn(aClient *user)
1839 {
1840 char *nick, *u = user->getNick();
1841 Monster *fight;
1842 aClient *battle;
1843 int mhit;
1844
1845 nick = new char[strlen(user->getNick()) + 1];
1846
1847 if (!user || !is_playing(user) || !is_fighting(user))
1848 goto endturn;
1849
1850 if (!player_fight(user) && !master_fight(user))
1851 fight = user->stats->getMonster();
1852 else
1853 fight = user->stats->getMaster();
1854 battle = user->stats->getBattle();
1855
1856 if (!player_fight(user))
1857 {
1858 // Opponent's Hit
1859 mhit = (fight->strength / 2) + (rand() % (fight->strength / 2)) - (user->stats->getDefense());
1860 }
1861 else
1862 {
1863 // Opponent's Hit
1864 mhit = (battle->stats->getStrength() / 2) + (rand() % (battle->stats->getStrength() / 2)) - user->stats->getDefense();
1865 }
1866 if (!player_fight(user))
1867 {
1868
1869 if (mhit > 0)
1870 {
1871 notice(s_GameServ, u, "\1f%s\1f attacks with their \1f%s\1f for \ 2%d\ 2 damage!",
1872 fight->name.c_str(), fight->weapon.c_str(), mhit);
1873 }
1874 else if (mhit <= 0)
1875 notice(s_GameServ, u, "%s completely misses you!", fight->name.c_str());
1876
1877 if (mhit >= user->stats->getHP())
1878 {
1879 if (!master_fight(user))
1880 {
1881 notice(s_GameServ, u, "You have been \ 2\1fkilled\1f\ 2 by %s!", fight->name.c_str());
1882 notice(s_GameServ, u, "You lose all gold on hand and lose 10 percent "\
1883 "of your experience!");
1884 user->stats->setGold(0);
1885 user->stats->subtractExp((long int)(user->stats->getExp() * .10));
1886 user->stats->setHP(0);
1887 user->stats->delMonster();
1888 clearAlive(user->stats);
1889 goto endturn;
1890 }
1891 else
1892 {
1893 notice(s_GameServ, u, "%s has bested you! You will have to wait "\
1894 "until tomorrow to try again", user->stats->getMaster()->name.c_str());
1895 user->stats->delMonster();
1896 user->stats->delMaster();
1897 goto endturn;
1898 }
1899 }
1900 else
1901 {
1902 if (mhit > 0)
1903 user->stats->subtractHP(mhit);
1904 display_monster(u);
1905 goto endturn;
1906 }
1907 }
1908 else
1909 {
1910 clearYourTurn(user->stats);
1911 setYourTurn(battle->stats);
1912 display_players(battle);
1913 }
1914 endturn:
1915 delete []nick;
1916 }
1917
1918 void do_heal(char *u)
1919 {
1920 aClient *ni;
1921 char *amount = strtok(NULL, " ");
1922 int price, num;
1923
1924 if (!amount)
1925 {
1926 notice(s_GameServ, u, "SYNTAX: /msg %S HEAL {ALL | #}");
1927 return;
1928 }
1929 else if (!(ni = find(u)))
1930 {
1931 notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, ""));
1932 return;
1933 }
1934 else if (isIgnore(ni))
1935 {
1936 #ifdef DEBUGMODE
1937 log("Ignoring %s.", ni->getNick());
1938 #endif
1939 return;
1940 }
1941 else if (!is_playing(ni))
1942 {
1943 notice(s_GameServ, u, "You aren't playing!");
1944 return;
1945 }
1946 else if (!isAlive(ni->stats))
1947 {
1948 notice(s_GameServ, u, "You are dead. Wait until tomorrow for healing.");
1949 return;
1950 }
1951 else if (is_fighting(ni))
1952 {
1953 notice(s_GameServ, u, "You can't heal in battle!");
1954 return;
1955 }
1956 else if (ni->stats->getHP() >= ni->stats->getMaxHP())
1957 {
1958 notice(s_GameServ, u, "You don't need healing!");
1959 return;
1960 }
1961
1962 updateTS(ni->stats);
1963 if (stricmp(amount, "ALL") == 0)
1964 {
1965 price = ni->stats->getLevel() * 3;
1966 if (ni->stats->getGold() < (ni->stats->getMaxHP() - ni->stats->getHP()) * price)
1967 {
1968 notice(s_GameServ, u, "Healing \ 2%d\ 2 points for \ 2%d\ 2 gold per point.",
1969 (long int)ni->stats->getGold()/price, price);
1970 ni->stats->addHP(ni->stats->getGold() / price);
1971 ni->stats->setGold(ni->stats->getGold() % price);
1972 }
1973 else
1974 {
1975 notice(s_GameServ, u, "Healing all possible points at \ 2%d\ 2 gold "\
1976 "per point.", price);
1977 notice(s_GameServ, u, "\ 2%d\ 2 points healed for \ 2%ld\ 2 gold. HP at MAX!",
1978 (ni->stats->getMaxHP() - ni->stats->getHP()),
1979 (price * (ni->stats->getMaxHP() - ni->stats->getHP())) );
1980 ni->stats->subtractGold(price * (ni->stats->getMaxHP() - ni->stats->getHP()));
1981 ni->stats->healall();
1982 }
1983 }
1984 else if (isstringnum(amount))
1985 {
1986 num = stringtoint(amount);
1987 price = ni->stats->getLevel() * 3;
1988 if (ni->stats->getGold() < price * num)
1989 {
1990 notice(s_GameServ, u, "You only have enough gold to heal \ 2%d\ 2 points!",
1991 (long int)ni->stats->getGold()/price);
1992 }
1993 else if (num <= ni->stats->getMaxHP() - ni->stats->getHP())
1994 {
1995 notice(s_GameServ, u, "Healing \ 2%d\ 2 points at \ 2%d\ 2 gold per point.",
1996 num, price);
1997 ni->stats->addHP(num);
1998 ni->stats->subtractGold(num * price);
1999 }
2000 else if (num > ni->stats->getMaxHP() - ni->stats->getHP())
2001 {
2002 notice(s_GameServ, u, "Healing all possible points at \ 2%d\ 2 gold "\
2003 "per point.", price);
2004 notice(s_GameServ, u, "\ 2%d\ 2 points healed. HP at MAX!",
2005 (ni->stats->getMaxHP() - ni->stats->getHP()));
2006 ni->stats->subtractGold(price * (ni->stats->getMaxHP() - ni->stats->getHP()));
2007 ni->stats->healall();
2008 }
2009 }
2010 else if (amount[0] == '-')
2011 notice(s_GameServ, u, "You trying to cheat?");
2012 else
2013 notice(s_GameServ, u, "SYNTAX: /msg %S HEAL {ALL | #}");
2014 }
2015
2016 int isstringnum(char *num)
2017 {
2018 unsigned int x;
2019 for (x = 0; x < strlen(num); x++)
2020 {
2021 if ((int)num[x] < 48 || (int)num[x] > 57)
2022 return 0;
2023 }
2024 return 1;
2025 }
2026
2027 long int stringtoint(char *number)
2028 {
2029 return atol(number);
2030 }
2031
2032 long int pow(int x, int y)
2033 {
2034 long int value = 0;
2035 int count = 0;
2036 value += x;
2037
2038 if (x != 0 && y != 0)
2039 {
2040 for (count = 1; count <= y - 1; count++)
2041 value *= x;
2042 }
2043 else
2044 return 1;
2045 return value;
2046 }
2047
2048 long int chartoint(char ch)
2049 {
2050 if (int(ch) >= 48 && int(ch) <= 57)
2051 return int(ch) - 48;
2052 else
2053 return 0;
2054 }
2055
2056 int save_gs_dbase()
2057 {
2058 ListNode<aClient> *ptr;
2059 Player *it;
2060 ofstream outfile;
2061
2062 outfile.open(playerdata);
2063
2064 if (!outfile)
2065 {
2066 log("Error opening %s", playerdata);
2067 return 0;
2068 }
2069
2070 for (unsigned long x = 0; x < U_TABLE_SIZE; x++)
2071 {
2072 ptr = players[x].First();
2073 while(ptr)
2074 {
2075 it = ptr->getData()->stats;
2076 clearYourTurn(it);
2077 item *w, *a;
2078 w = it->getWeapon();
2079 a = it->getArmor();
2080
2081 outfile << it->getName().c_str() << ' ' << it->getLevel() << ' ' << it->getExp() << ' ' << it->getGold() << ' ' << it->getBank() << ' '<< it->getHP() << ' ' << it->getMaxHP() << ' ' << it->getStrength() << ' ' << it->getDefense() << ' ' << it->getForestFights() << ' ' << it->getPlayerFights() << ' ' << it->getFlags() << ' ' << it->getPassword().c_str() << ' ' << it->lastlogin << ' ' << (w ? w->getID() : 0) << ' ' << (a ? a->getID() : 0);
2082
2083 // Traverse the list and write out each item ID and how many uses are left
2084 if (!it->inventory->isEmpty())
2085 {
2086 list<itemContainer> *myitems;
2087 list<itemContainer>::iterator item_iter;
2088 myitems = it->inventory->getItems();
2089
2090 for(item_iter = myitems->begin();item_iter != myitems->end();item_iter++)
2091 {
2092 outfile << ' ' << (*item_iter).getItem()->getID() << ' ' << (*item_iter).getUses();
2093 }
2094 }
2095 outfile << endl;
2096 ptr = ptr->Next();
2097 }
2098 }
2099 outfile.close();
2100 return 1;
2101 }
2102
2103 int load_dragon()
2104 {
2105 ifstream infile;
2106 char *buf;
2107
2108 infile.open(dragondata);
2109
2110 if (infile.fail())
2111 {
2112 infile.clear();
2113 log ("Error opening %s. Trying initialdragon.dat", dragondata);
2114 infile.open("data/initialdragon.dat");
2115 if (infile.fail())
2116 {
2117 log ("Error opening data/initialdragon.dat");
2118 return 0;
2119 }
2120 }
2121
2122 buf = new char[1024];
2123
2124 infile.getline(buf, 1024, '\n');
2125 infile.close(); // Done with the file... we have what we want
2126
2127 dragon.name = strtok(buf, "~");
2128 dragon.weapon = strtok(NULL, "~");
2129 dragon.gold = 0;
2130 dragon.exp = 0;
2131 dragon.strength = stringtoint(strtok(NULL, "~"));
2132 dragon.hp = stringtoint(strtok(NULL, "~"));
2133 dragon.defense = stringtoint(strtok(NULL, "~"));
2134 dragon.death = strtok(NULL, "");
2135
2136 log ("loaded dragon: %s", dragon.name.c_str());
2137
2138 delete []buf;
2139
2140 return save_dragon(); // Save the dragon file and return the status code :)
2141 }
2142
2143 int save_dragon()
2144 {
2145 ofstream outfile;
2146
2147 outfile.open(dragondata);
2148
2149 if (outfile.fail())
2150 {
2151 log ("Error opening %s. Exiting.", dragondata);
2152 return 0;
2153 }
2154
2155 outfile << dragon.name.c_str() << '~' << dragon.weapon.c_str() << '~'
2156 << dragon.strength << '~' << dragon.hp << '~'
2157 << dragon.defense << '~' << dragon.death.c_str() << "\n^"
2158 << endl;
2159
2160 outfile.close();
2161
2162 return 1;
2163 }
2164
2165 int load_store()
2166 {
2167 ifstream infile;
2168 char *buf;
2169 item *tempItem;
2170 buf = new char[1024];
2171 long id;
2172
2173 infile.open(storeitemdata);
2174
2175 if (infile.fail())
2176 {
2177 log("Error opening %s", storeitemdata);
2178 return 0;
2179 }
2180
2181 while (infile.getline(buf, 1024, '\n'))
2182 {
2183 try
2184 {
2185 if (buf[0] != '#' && buf[0] != '\n' && buf[0] != '\0')
2186 {
2187 item *tempItem2;
2188 id = stringtoint(strtok(buf, ""));
2189 tempItem2 = findItemByID(id);
2190 if (tempItem2 == NULL)
2191 {
2192 log("Invalid ID in %s", storeitemdata);
2193 return 0;
2194 }
2195
2196 tempItem = tempItem2;
2197 store.push_back(tempItem);
2198 }
2199 }
2200 catch (char *str)
2201 {
2202 log("Exception loading store: %s", str);
2203 delete []buf;
2204 return 0;
2205 }
2206 }
2207 delete []buf;
2208 return 1;
2209 }
2210 int load_tavern()
2211 {
2212 ifstream infile;
2213 char *buf;
2214 tavernItem tempItem;
2215 buf = new char[1024];
2216 long id, level;
2217
2218 infile.open(tavernitemdata);
2219 if (infile.fail())
2220 {
2221 log("Error opening %s", tavernitemdata);
2222 return 0;
2223 }
2224
2225 while (infile.getline(buf, 1024, '\n'))
2226 {
2227 try
2228 {
2229 if (buf[0] != '#' && buf[0] != '\n' && buf[0] != '\0')
2230 {
2231 item *tempItem2;
2232 id = stringtoint(strtok(buf, "~"));
2233 level = stringtoint(strtok(NULL, ""));
2234 tempItem2 = findItemByID(id);
2235 if (tempItem2 == NULL)
2236 {
2237 log("Invalid ID in %s", tavernitemdata);
2238 return 0;
2239 }
2240 tempItem.setItem(tempItem2);
2241 tempItem.setLevel(level);
2242 tavern.push_back(tempItem);
2243 }
2244 }
2245 catch (char *str)
2246 {
2247 log("Exception loading tavern: %s", str);
2248 delete []buf;
2249 return 0;
2250 }
2251 }
2252 delete []buf;
2253 return 1;
2254 }
2255 int load_items()
2256 {
2257 ifstream infile;
2258 char *buf;
2259 item *tempItem;
2260
2261
2262 buf = new char[1024];
2263
2264 infile.open(itemdata);
2265
2266 if (infile.fail())
2267 {
2268 log("Error opening %s", itemdata);
2269 return 0;
2270 }
2271
2272 while (infile.getline(buf, 1024, '\n'))
2273 {
2274 if (buf[0] == '^')
2275 break;
2276 try
2277 {
2278 if (buf[0] != '#' && buf[0] != '\n' && buf[0] != '\0')
2279 {
2280 switch(buf[0])
2281 {
2282 case '1':
2283 tempItem = new weapon();
2284 break;
2285 case '2':
2286 tempItem = new armor();
2287 break;
2288 case '3':
2289 tempItem = new potion();
2290 break;
2291 default:
2292 log("Invalid Item Type %c in %s", buf[0], itemdata);
2293 delete []buf;
2294 return 0;
2295 break;
2296 }
2297 if(tempItem->setData(buf))
2298 {
2299 Items.push_back(tempItem);
2300 }
2301 }
2302 }
2303 catch (char *str)
2304 {
2305 log("Exception loading items: %s", str);
2306 delete []buf;
2307 return 0;
2308 }
2309 }
2310 delete []buf;
2311 return 1;
2312 }
2313
2314 int load_gs_dbase()
2315 {
2316 ifstream infile;
2317 aClient *temp;
2318 Player *p;
2319 char *tempname, *buf, *password;
2320 int tempnum;
2321 buf = new char[100000];
2322
2323 infile.open(playerdata);
2324
2325 if (infile.fail())
2326 {
2327 log("Error opening %s", playerdata);
2328 return 0;
2329 }
2330
2331 for (int x = 0; x < U_TABLE_SIZE; x++)
2332 {
2333 ListNode<aClient> *tempNode;
2334 tempNode = players[x].First();
2335 while (tempNode)
2336 {
2337 if (tempNode->getData()->stats->getClient())
2338 {
2339 logout(tempNode->getData()->stats->getClient());
2340 }
2341 tempNode = tempNode->Next();
2342 }
2343 players[x].deleteNodes();
2344 }
2345
2346 while (infile.getline(buf, 100000, '\n'))
2347 {
2348 temp = new aClient;
2349 tempname = strtok(buf, " ");
2350 temp->stats = new Player(tempname);
2351 p = temp->stats;
2352
2353 p->setLevel(stringtoint(strtok(NULL, " ")));
2354 p->setExp(stringtoint(strtok(NULL, " ")));
2355 p->setGold(stringtoint(strtok(NULL, " ")));
2356 p->setBank(stringtoint(strtok(NULL, " ")));
2357 p->setHP(stringtoint(strtok(NULL, " ")));
2358 p->setMaxHP(stringtoint(strtok(NULL, " ")));
2359 p->setStrength(stringtoint(strtok(NULL, " ")));
2360 p->setDefense(stringtoint(strtok(NULL, " ")));
2361 p->setForestFights(stringtoint(strtok(NULL, " ")));
2362 p->setPlayerFights(stringtoint(strtok(NULL, " ")));
2363 p->setFlags(stringtoint(strtok(NULL, " ")));
2364
2365
2366
2367 password = strtok(NULL, " ");
2368 p->setRawPassword(password);
2369 temp->setNick("Not Playing");
2370 #ifdef P10
2371 temp->setRealNick("Not Playing");
2372 #endif
2373 tempname = strtok(NULL, " ");
2374 if (tempname)
2375 p->lastlogin = stringtoint(tempname);
2376 else
2377 p->lastlogin = time(NULL);
2378
2379 tempname = strtok(NULL, " ");
2380 tempnum = stringtoint(tempname);
2381 if (tempnum != 0)
2382 {
2383 p->setWeapon(*findItemByID(tempnum));
2384 }
2385
2386 tempname = strtok(NULL, " ");
2387 tempnum = stringtoint(tempname);
2388
2389 if (tempnum != 0)
2390 {
2391 p->setArmor(*findItemByID(tempnum));
2392 }
2393
2394
2395 for (tempname = strtok(NULL, " "); tempname != NULL; tempname = strtok(NULL, " "))
2396 {
2397 long int id, uses;
2398 list<item*>::iterator item_iter;
2399 id = stringtoint(tempname);
2400 tempname = strtok(NULL, " ");
2401 uses = stringtoint(tempname);
2402
2403 item_iter = Items.begin();
2404 while (item_iter != Items.end())
2405 {
2406 if ((*item_iter)->getID() == id)
2407 {
2408 // Don't sort every time you add an item or it eats CPU
2409 p->inventory->addItemNoChecks((*item_iter))->setUses(uses);
2410 }
2411 item_iter++;
2412 }
2413 }
2414 p->inventory->sort();
2415
2416 unsigned long hv = iHASH((unsigned char *) temp->stats->getName().c_str());
2417
2418 temp->stats->setClient(NULL);
2419 players[hv].insertAtBack(temp);
2420 delete temp;
2421 }
2422 delete [] buf;
2423 infile.close();
2424 return 1;
2425 }
2426
2427 bool passcmp(const char *encrypted, char *plaintext)
2428 {
2429 char salt[3];
2430 char *plaintext2, *plainToencrypt;
2431 bool same = false;
2432
2433 plaintext2 = new char[strlen(encrypted) + strlen(plaintext)]; // Extra
2434 strcpy(plaintext2, plaintext);
2435
2436 salt[0] = encrypted[0];
2437 salt[1] = encrypted[1];
2438 salt[3] = '\0';
2439
2440 plainToencrypt = crypt(plaintext2, salt);
2441
2442 same = (strcmp((const char *)encrypted, plainToencrypt) == 0 ? true : false);
2443
2444 delete []plaintext2;
2445
2446 return same;
2447 }
2448
2449 bool check_password(char *name, char *plaintext)
2450 {
2451 aClient *client;
2452
2453 if (!(client = findplayer(name)))
2454 return false;
2455 else
2456 {
2457 return passcmp(client->stats->getPassword().c_str(), plaintext);
2458 }
2459 }
2460
2461 void do_store(char *u)
2462 {
2463 list<item*>::iterator item_iterator;
2464 item *tempItem;
2465 char *cmd = strtok(NULL, " ");
2466 char *num = strtok(NULL, " ");
2467 char *space;
2468 int id;
2469 aClient *user;
2470 Player *p;
2471
2472
2473 if (!cmd || !num)
2474 {
2475 notice(s_GameServ, u, "SYNTAX: STORE LIST {ARMOR | WEAPONS}");
2476 notice(s_GameServ, u, " \ 2STORE SELL NUMBER\ 2");
2477 notice(s_GameServ, u, " \ 2STORE BUY \1fNUMBER\1f\ 2");
2478 return;
2479 }
2480 else if (!(user = find(u)))
2481 {
2482 log("Fatal Error: could not find %s in client list", u);
2483 return;
2484 }
2485 else if (isIgnore(user))
2486 {
2487 #ifdef DEBUGMODE
2488 log("Ignoring %s.", user->getNick());
2489 #endif
2490 return;
2491 }
2492 else if (!is_playing(user))
2493 {
2494 notice(s_GameServ, u, "You must be playing to use the store!");
2495 return;
2496 }
2497 else if (is_fighting(user))
2498 {
2499 notice(s_GameServ, u, "You can't go to the store while fighting!");
2500 return;
2501 }
2502 else if (!isAlive(user->stats))
2503 {
2504 notice(s_GameServ, u, "You are dead. Wait until tomorrow to purchase weapons and armor!");
2505 return;
2506 }
2507 updateTS(user->stats);
2508
2509 if (stricmp(cmd, "LIST") == 0)
2510 {
2511 if (stricmp(num, "WEAPONS") == 0)
2512 {
2513 notice(s_GameServ, u, "Welcome to Kain's Armory");
2514 notice(s_GameServ, u, "Here are the weapons we have available for the killing, sire:");
2515 for (item_iterator = store.begin(); item_iterator != store.end(); ++item_iterator)
2516 {
2517 if ((*item_iterator)->getType() == WEAPON)
2518 {
2519 space = spaces(strlen((*item_iterator)->getName().c_str()), ".");
2520 notice(s_GameServ, u, "%s%ld. %s%s%ld", ((*item_iterator)->getID() < 10 ? " " : ""), (*item_iterator)->getID(), (*item_iterator)->getName().c_str(), space, (*item_iterator)->price());
2521 free(space);
2522 }
2523 }
2524 notice(s_GameServ, u, "To purchase a weapon, type /msg %S STORE BUY \ 2#\ 2.");
2525 notice(s_GameServ, u, "Where # is the weapon number from the menu above.");
2526
2527 }
2528 else if (stricmp(num, "ARMOR") == 0)
2529 {
2530 notice(s_GameServ, u, "Welcome to Kain's Armory");
2531 notice(s_GameServ, u, "I hope you enjoy the fine armor we have available for your protection:");
2532 for (item_iterator = store.begin(); item_iterator != store.end(); ++item_iterator)
2533 {
2534 if ((*item_iterator)->getType() == ARMOR)
2535 {
2536 space = spaces(strlen((*item_iterator)->getName().c_str()), ".");
2537 notice(s_GameServ, u, "%s%ld. %s%s%d",((*item_iterator)->getID() < 10 ? " " : ""), (*item_iterator)->getID(), (*item_iterator)->getName().c_str(), space, (*item_iterator)->price());
2538 free(space);
2539 }
2540 }
2541
2542 notice(s_GameServ, u, "To purchase armor, type /msg %S store buy #");
2543 notice(s_GameServ, u, "Where # is the armor number from the menu above.");
2544 }
2545
2546 }
2547 else if (stricmp(cmd, "BUY") == 0)
2548 {
2549 p = user->stats;
2550 if (!num)
2551 {
2552 notice(s_GameServ, u, "SYNTAX: \ 2STORE BUY \1f#\1f\ 2");
2553 return;
2554 }
2555 else
2556 {
2557 id = stringtoint(num);
2558 }
2559
2560 if (!isstringnum(num))
2561 {
2562 notice(s_GameServ, u, "SYNTAX: \ 2STORE BUY \1f#\1f\ 2");
2563 return;
2564 }
2565 else if (!(tempItem = findStoreItemByID(id)))
2566 {
2567 notice(s_GameServ, u, "Sorry, we don't carry that item!");
2568 return;
2569 }
2570 else if (p->getGold() < tempItem->price())
2571 {
2572 notice(s_GameServ, u, "You can't afford to buy %s", tempItem->getName().c_str());
2573 return;
2574 }
2575 else if (p->inventory->addItem(tempItem))
2576 {
2577 notice(s_GameServ, u, "You have purchased %s! Thanks for the gold!", tempItem->getName().c_str());
2578 p->subtractGold(tempItem->price());
2579 notice(s_GameServ, u, "Don't forget to type /msg %S equip %ld", tempItem->getID());
2580 }
2581 else
2582 {
2583 notice(s_GameServ, u, "You can't carry any more!");
2584 }
2585 }
2586 else if (stricmp(cmd, "SELL" ) == 0)
2587 {
2588 itemContainer *tempContainer;
2589 p = user->stats;
2590 id = stringtoint(num);
2591 if (!isstringnum(num))
2592 {
2593 notice(s_GameServ, u, "SYNTAX: /msg %S store sell #");
2594 return;
2595 }
2596 else if (!(tempContainer = p->inventory->Find(id)))
2597 {
2598 notice(s_GameServ, u, "You're not carrying that!");
2599 return;
2600 }
2601 else if (p->getGold() >= 2000000000)
2602 {
2603 notice(s_GameServ, u, "You have enough gold. Just hang on to it for now.");
2604 }
2605 else
2606 {
2607 tempItem = tempContainer->getItem();
2608
2609 notice(s_GameServ, u, "Thank you for your business! We gave you %ld gold for %s!", (tempItem->price() / 2), tempItem->getName().c_str());
2610 p->addGold((tempItem->price() / 2));
2611 p->inventory->deleteItem(tempItem);
2612 if (tempItem == p->getWeapon())
2613 {
2614 notice(s_GameServ, u, "Since you equipped %s, you're going to have to reequip something", tempItem->getName().c_str());
2615 tempItem->undo(p);
2616 p->clearWeapon();
2617 }
2618 else if (tempItem == p->getArmor())
2619 {
2620 tempItem->undo(p);
2621 notice(s_GameServ, u, "Since you equipped %s, you're going to have to reequip something", tempItem->getName().c_str());
2622 p->clearArmor();
2623 }
2624 }
2625 }
2626 else
2627 {
2628 notice(s_GameServ, u, "SYNTAX: STORE LIST {ARMOR | WEAPONS}");
2629 notice(s_GameServ, u, " \ 2STORE SELL #\ 2");
2630 notice(s_GameServ, u, " \ 2STORE BUY \1f#\1f\ 2");
2631 return;
2632 }
2633 }
2634 void do_inventory(char *u)
2635 {
2636 aClient *user;
2637
2638 if (!(user = find(u)))
2639 {
2640 notice(s_GameServ, u, "Fatal Error. Contact a %S admin!");
2641 return;
2642 }
2643 else if (isIgnore(user))
2644 {
2645 #ifdef DEBUGMODE
2646 log("Ignoring %s.", user->getNick());
2647 #endif
2648 return;
2649 }
2650 else if (!is_playing(user))
2651 {
2652 notice(s_GameServ, u, "You must be playing to check your inventory!");
2653 return;
2654 }
2655 updateTS(user->stats);
2656 showinventory(user->stats, user);
2657 }
2658
2659 void showinventory(Player *from, aClient *to)
2660 {
2661 char *nick;
2662 if (!to || !from)
2663 {
2664 return;
2665 }
2666
2667 nick = to->getNick();
2668
2669 if (from->inventory->isEmpty())
2670 {
2671 notice(s_GameServ, nick, "You aren't carrying anything");
2672 return;
2673 }
2674
2675 list <itemContainer> *items;
2676 items = from->inventory->getItems();
2677
2678 list <itemContainer>::iterator item_iter, item_iter2;
2679 item_iter = items->begin();
2680
2681 notice(s_GameServ, nick, "Inventory for %s:", from->getName().c_str());
2682 long count;
2683 while (item_iter != items->end())
2684 {
2685 // Display a list of counted items so as not to show an extra line for duplicate items
2686 count = 0;
2687 item_iter2 = item_iter;
2688 while (item_iter != items->end() && (*item_iter) == (*item_iter2))
2689 {
2690 if ((*item_iter) == (*item_iter2))
2691 {
2692 ++count;
2693 }
2694 else
2695 {
2696 break;
2697 }
2698 ++item_iter;
2699 }
2700 notice(s_GameServ, nick, "%ld.) %s (%ld)", (*item_iter2).getItem()->getID(), (*item_iter2).getItem()->getName().c_str(), count);
2701 }
2702 }
2703
2704 void do_tavern(char *u)
2705 {
2706 char *cmd = strtok(NULL, " ");
2707
2708 aClient *user;
2709 Player *p;
2710
2711 if (!(user = find(u)))
2712 {
2713 notice(s_GameServ, u, "Fatal Error. See a %S admin for help");
2714 return;
2715 }
2716 else if (isIgnore(user))
2717 {
2718 #ifdef DEBUGMODE
2719 log("Ignoring %s.", user->getNick());
2720 #endif
2721 return;
2722 }
2723 else if (!is_playing(user))
2724 {
2725 notice(s_GameServ, u, "You must be playing to go to the Tavern");
2726 return;
2727 }
2728 else if (is_fighting(user))
2729 {
2730 notice(s_GameServ, u, "You cannot go to the Tavern during a fight!");
2731 return;
2732 }
2733
2734 updateTS(user->stats);
2735 p = user->stats;
2736
2737 if (!cmd)
2738 {
2739 notice(s_GameServ, u, "Welcome to Boot Liquors Mystic Apothecary and General Store");
2740 notice(s_GameServ, u, "Your commands:");
2741 notice(s_GameServ, u, "/msg %S TAVERN {LIST | BUY} [NUMBER]");
2742 notice(s_GameServ, u, "What'll it be?");
2743 }
2744 else if (stricmp(cmd, "LIST") == 0)
2745 {
2746 notice(s_GameServ, u, "Here is a list of what we have to offer:");
2747 showTavern(user);
2748 notice(s_GameServ, u, "To buy an item, type /msg %S TAVERN BUY #");
2749 }
2750 else if (stricmp(cmd, "BUY") == 0)
2751 {
2752 int amt = 1;
2753 char *chid = strtok(NULL, " ");
2754 char *amount = strtok(NULL, " ");
2755
2756 if (amount)
2757 amt = stringtoint(amount);
2758
2759 if (!chid)
2760 {
2761 notice(s_GameServ, u, "SYNTAX: TAVERN BUY # [#]");
2762 notice(s_GameServ, u, "Example: /msg %S TAVERN BUY 6001");
2763 notice(s_GameServ, u, "Example: /msg %S TAVERN BUY 6001 10");
2764 return;
2765 }
2766 long id = stringtoint(chid);
2767 tavernItem *tempItem;
2768
2769 if (!(tempItem = findTavernItemByID(id)) || user->stats->getLevel() < tempItem->getLevel())
2770 {
2771 notice(s_GameServ, u, "Invalid Choice!");
2772 notice(s_GameServ, u, "Here is a list of what we have to offer:");
2773 showTavern(user);
2774 notice(s_GameServ, u, "To buy an item, type /msg %S TAVERN BUY #");
2775 return;
2776 }
2777 else if (!amount && user->stats->getGold() < tempItem->getItem()->price())
2778 {
2779 notice(s_GameServ, u, "You don't have enough gold!");
2780 notice(s_GameServ, u, "Here is a list of what we have to offer:");
2781 showTavern(user);
2782 notice(s_GameServ, u, "To buy an item, type /msg %S TAVERN BUY #");
2783 }
2784 else if (user->stats->getGold() < amt * tempItem->getItem()->price())
2785 {
2786 notice(s_GameServ, u, "You don't have enough gold!");
2787 notice(s_GameServ, u, "Here is a list of what we have to offer:");
2788 showTavern(user);
2789 notice(s_GameServ, u, "To buy an item, type /msg %S TAVERN BUY # [#]");
2790 }
2791 else
2792 {
2793 if (amount)
2794 {
2795 int amt = stringtoint(amount);
2796 if (amt < 0 || amount[0] == '-')
2797 {
2798 notice(s_GameServ, u, "You trying to steal from me?");
2799 }
2800 else if (user->stats->inventory->addItem(tempItem->getItem(), amt) == NULL)
2801 {
2802 notice(s_GameServ, u, "You can't carry that many!");
2803 }
2804 else
2805 {
2806 notice(s_GameServ, u, "%d %s's coming right up!", amt, tempItem->getItem()->getName().c_str());
2807 user->stats->subtractGold(tempItem->getItem()->price() * amt);
2808 }
2809 }
2810 else
2811 {
2812 if (user->stats->inventory->addItem(tempItem->getItem()) == NULL)
2813 {
2814 notice(s_GameServ, u, "You can't carry any more!");
2815 }
2816 else
2817 {
2818 notice(s_GameServ, u, "One %s coming right up!", tempItem->getItem()->getName().c_str());
2819 user->stats->subtractGold(tempItem->getItem()->price());
2820 notice(s_GameServ, u, "%d", user->stats->inventory->getCount());
2821 }
2822 }
2823 }
2824 }
2825 else
2826 {
2827 notice(s_GameServ, u, "Improper Syntax.");
2828 notice(s_GameServ, u, "Type /msg %S HELP TAVERN for help");
2829 }
2830 return;
2831 }
2832
2833 void do_bank(char *u)
2834 {
2835 char *cmd = strtok(NULL, " ");
2836 char *amount = strtok(NULL, " ");
2837 char *nick = strtok(NULL, " ");
2838
2839 aClient *user;
2840 Player *p;
2841
2842 if (!cmd || (!amount && stricmp(cmd, "BALANCE") != 0) || (stricmp(cmd, "TRANSFER") == 0 && !nick))
2843 {
2844 notice(s_GameServ, u, "BANK {WITHDRAW | DEPOSIT} {ALL | AMOUNT}");
2845 notice (s_GameServ, u, "BANK BALANCE");
2846 return;
2847 }
2848 else if (!(user = find(u)))
2849 {
2850 notice(s_GameServ, u, "Fatal Error. Couldn't find your aClient. Contact a(n) %S "\
2851 " admin for help");
2852 log("Fatal Error. Couldn't find %s while executing do_bank()", u);
2853 return;
2854 }
2855 else if (isIgnore(user))
2856 {
2857 #ifdef DEBUGMODE
2858 log("Ignoring %s.", user->getNick());
2859 #endif
2860 return;
2861 }
2862 else if (!is_playing(user))
2863 {
2864 notice(s_GameServ, u, "You must be playing to use the bank!");
2865 return;
2866 }
2867 else if (is_fighting(user))
2868 {
2869 notice(s_GameServ, u, "You can't go to the bank during a fight!");
2870 return;
2871 }
2872 updateTS(user->stats);
2873 if (stricmp(cmd, "BALANCE") == 0)
2874 {
2875 showBankBalance(u);
2876 return;
2877 }
2878 else if (!isAlive(user->stats))
2879 {
2880 notice(s_GameServ, u, "You are dead. We don't accept gold from dead folk! Wait 'til tomorrow!");
2881 return;
2882 }
2883 else if (!isstringnum(amount) && stricmp(amount, "ALL") != 0)
2884 {
2885 notice(s_GameServ, u, "I don't know how to convert alphabet letters into currency, sire!");
2886 return;
2887 }
2888 if (stringtoint(amount) < 0)
2889 {
2890 notice(s_GameServ, u, "Sorry. This bank is not licensed "\
2891 "to handle such sums of cash, noble Lord.");
2892 return;
2893 }
2894 p = user->stats;
2895
2896 if (stricmp(cmd, "DEPOSIT") == 0)
2897 {
2898 if (p->getBank() == 2000000000)
2899 {
2900 notice(s_GameServ, u, "Your bank account is full, sire!");
2901 return;
2902 }
2903 else if (stricmp(amount, "ALL") == 0)
2904 {
2905 if (2000000000 - p->getBank() < p->getGold())
2906 {
2907 notice(s_GameServ, u, "You don't have enough room for all of your gold.");
2908 notice(s_GameServ, u, "Depositing %ld gold into your account", (2000000000 - p->getBank()));
2909 p->subtractGold((2000000000 - p->getBank()));
2910 p->setBank(2000000000);
2911 showBankBalance(u);
2912 }
2913 else
2914 {
2915 notice(s_GameServ, u, "Depositing %ld gold into your account!", p->getGold());
2916 p->addBank(p->getGold());
2917 p->setGold(0);
2918 showBankBalance(u);
2919 }
2920 }
2921 else if (stringtoint(amount) > p->getGold())
2922 {
2923 notice(s_GameServ, u, "Sire, you only have %ld gold!", p->getGold());
2924 showBankBalance(u);
2925 return;
2926 }
2927 else
2928 {
2929 if (2000000000 - p->getBank() < stringtoint(amount))
2930 {
2931 notice(s_GameServ, u, "You don't have room in your account for that much.");
2932 notice(s_GameServ, u, "Capping off your account with %ld gold!", (2000000000 - p->getBank()));
2933 p->subtractGold((2000000000 - p->getBank()));
2934 p->setBank(2000000000);
2935 showBankBalance(u);
2936 }
2937 else
2938 {
2939 notice(s_GameServ, u, "Depositing %d gold into your account!", stringtoint(amount));
2940 p->addBank(stringtoint(amount));
2941 p->subtractGold(stringtoint(amount));
2942 showBankBalance(u);
2943 }
2944 }
2945 }
2946 else if (stricmp(cmd, "WITHDRAW") == 0)
2947 {
2948 if (p->getGold() == 2000000000)
2949 {
2950 notice(s_GameServ, u, "You cannot carry any more gold, sire!");
2951 showBankBalance(u);
2952 return;
2953 }
2954 else if (stricmp(amount, "ALL") == 0)
2955 {
2956 if (2000000000 - p->getGold() < p->getBank())
2957 {
2958 notice(s_GameServ, u, "You don't have enough room to carry all that gold.");
2959 notice(s_GameServ, u, "Withdrawing %ld gold from your account", (2000000000 - p->getGold()));
2960 p->subtractBank((2000000000 - p->getGold()));
2961 p->setGold(2000000000);
2962 showBankBalance(u);
2963 }
2964 else
2965 {
2966 notice(s_GameServ, u, "Withdrawing %ld gold from your account!", p->getBank());
2967 p->addGold(p->getBank());
2968 p->setBank(0);
2969 showBankBalance(u);
2970 }
2971 }
2972 else if (stringtoint(amount) > p->getBank())
2973 {
2974 notice(s_GameServ, u, "Sire, you only have %ld gold in the bank!", p->getBank());
2975 showBankBalance(u);
2976 return;
2977 }
2978 else
2979 {
2980 if (2000000000 - p->getGold() < stringtoint(amount))
2981 {
2982 notice(s_GameServ, u, "You don't enough have room to carry that much gold!");
2983 notice(s_GameServ, u, "You fill your pockets with %ld gold!",
2984 (2000000000 - p->getGold()));
2985 p->subtractBank((2000000000 - p->getGold()));
2986 p->setGold(2000000000);
2987 showBankBalance(u);
2988 }
2989 else
2990 {
2991 notice(s_GameServ, u, "Withdrawing %d gold from your account!", stringtoint(amount));
2992 p->addGold(stringtoint(amount));
2993 p->subtractBank(stringtoint(amount));
2994 showBankBalance(u);
2995 }
2996 }
2997 }
2998 }
2999
3000 void do_dragon(char *u)
3001 {
3002 aClient *user;
3003
3004 if (!(user = find(u)))
3005 {
3006 notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, ""));
3007 return;
3008 }
3009 else if (isIgnore(user))
3010 {
3011 #ifdef DEBUGMODE
3012 log("Ignoring %s.", user->getNick());
3013 #endif
3014 return;
3015 }
3016 else if (!is_playing(user))
3017 {
3018 notice(s_GameServ, u, "You must be playing to fight the dragon!");
3019 return;
3020 }
3021 else if (is_fighting(user))
3022 {
3023 notice(s_GameServ, u, "You are already in a fight. How will you fight the almighty dragon!?");
3024 return;
3025 }
3026 else if (!isAlive(user->stats))
3027 {
3028 notice(s_GameServ, u, "You're dead. Wait until tomorrow to see your master!");
3029 return;
3030 }
3031 else if (user->stats->getLevel() < LEVELS)
3032 {
3033 notice(s_GameServ, u, "You fool! Only those strong enough "\
3034 "to vanquish any foe should DARE fight the dragon!");
3035 notice(s_GameServ, u, "To put it in terms you can understand: "\
3036 "You are too weak. You must be Level %d!", REALLEVELS);
3037 return;
3038 }
3039
3040 updateTS(user->stats);
3041
3042 Player *p = user->stats;
3043 setMaster(p);
3044 notice(s_GameServ, u, "You approach the dragon's lair cautiously.");
3045 notice(s_GameServ, u, "The stench of sulfer fills the air as a "\
3046 "deep, red fog rolls in. The air is filled with the "\
3047 "heated mist of deadly fire from beyond the cave "\
3048 "entrance.");
3049 notice(s_GameServ, u, "You adjust your %s, tighten your grip on "\
3050 "your %s, and venture into the hot, dark cave. "\
3051 "You are surprised at the angle of descent as you climb "\
3052 "lower and lower, deeper into the dragon's den.",
3053 (p->getArmor() ? p->getArmor()->getName().c_str() : "Fists"), (p->getWeapon() ? p->getWeapon()->getName().c_str() : "Birthday Suit"));
3054 notice(s_GameServ, u, "You come to the end of the cave to find "\
3055 "a tooth. It is a large tooth... bigger than your torso."\
3056 " Suddenly the darkness lifts from the gleam of an eye "\
3057 " staring into your soul! The eye is large... HUGE!");
3058 notice(s_GameServ, u, "Just then you notice the eye begin to "\
3059 "glare orange! The tooth is moving... but it is still too "\
3060 "dark for you to make out.... THE DRAGON! You see it!");
3061 p->setMonster(new Monster(dragon));
3062 setDragonFight(p);
3063 display_monster(u);
3064 }
3065
3066 void do_master(char *u)
3067 {
3068 aClient *user;
3069
3070
3071 if (!(user = find(u)))
3072 {
3073 notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, ""));
3074 return;
3075 }
3076 else if (isIgnore(user))
3077 {
3078 #ifdef DEBUGMODE
3079 log("Ignoring %s.", user->getNick());
3080 #endif
3081 return;
3082 }
3083 else if (!is_playing(user))
3084 {
3085 notice(s_GameServ, u, "You must be playing to see your master!");
3086 return;
3087 }
3088 else if (is_fighting(user))
3089 {
3090 notice(s_GameServ, u, "You're in the middle of a fight! Pay attention!");
3091 return;
3092 }
3093 else if (!isAlive(user->stats))
3094 {
3095 notice(s_GameServ, u, "You're dead. Wait until tomorrow to see your master!");
3096 return;
3097 }
3098
3099 updateTS(user->stats);
3100
3101 char *cmd = strtok(NULL, " ");
3102 Player *p = user->stats;
3103 long int need = 0;
3104
3105 if (seenMaster(p))
3106 {
3107 notice(s_GameServ, u, "You have already seen your master today. Wait until tomorrow to try again");
3108 return;
3109 }
3110
3111 if (cmd != NULL)
3112 {
3113 switch(p->getLevel())
3114 {
3115 case 1:
3116 need = 200;
3117 break;
3118 case 2:
3119 need = 800;
3120 break;
3121 case 3:
3122 need = 2000;
3123 break;
3124 case 4:
3125 need = 8000;
3126 break;
3127 case 5:
3128 need = 20000;
3129 break;
3130 case 6:
3131 need = 80000;
3132 break;
3133 case 7:
3134 need = 200000;
3135 break;
3136 case 8:
3137 need = 800000;
3138 break;
3139 case 9:
3140 need = 2000000;
3141 break;
3142 case 10:
3143 need = 8000000;
3144 break;
3145 case 11:
3146 need = 20000000;
3147 break;
3148
3149 case REALLEVELS:
3150 need = p->getExp() + 1;
3151 notice(s_GameServ, u, "You are at level %d. You are the master. What's left? The DRAGON!", REALLEVELS);
3152 return;
3153 break;
3154 default:
3155 need = p->getExp() + 1; // Unknown level... don't let them fight a fake master!
3156 break;
3157 }
3158 }
3159 else
3160 {
3161 notice(s_GameServ, u, "SYNTAX: MASTER {FIGHT | QUESTION}");
3162 return;
3163 }
3164
3165 if (stricmp(cmd, "FIGHT") == 0)
3166 {
3167 if (p->getExp() >= need)
3168 {
3169 setMaster(p);
3170 see_master(u);
3171 }
3172 else
3173 notice(s_GameServ, u, "You are not worthy of fighting %s! You need %ld more experience.",
3174 levels[p->getLevel() - 1].master.name.c_str(), (need - p->getExp()));
3175 return;
3176 }
3177 else if (stricmp(cmd, "QUESTION") == 0)
3178 {
3179 if (p->getExp() >= need)
3180 notice(s_GameServ, u, "%s looks you up and down and decides you are more ready than you will ever be.",
3181 levels[p->getLevel() - 1].master.name.c_str());
3182 else
3183 notice(s_GameServ, u, "You pathetic fool! You are no match for %s, %s!",
3184 levels[p->getLevel() - 1].master.name.c_str(), p->getName().c_str());
3185
3186 return;
3187 }
3188 else
3189 {
3190 notice(s_GameServ, u, "SYNTAX: MASTER {FIGHT | QUESTION}");
3191 }
3192 }
3193
3194 void see_master(char *u)
3195 {
3196 aClient *user;
3197
3198 if (!(user = find(u)))
3199 {
3200 notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, ""));
3201 return;
3202 }
3203
3204 if (!is_fighting(user) && is_playing(user))
3205 {
3206 Monster *temp;
3207 Player *p = user->stats;
3208 temp = new Monster(levels[p->getLevel() - 1].master);
3209 p->setMyMaster(temp);
3210 p->setMonster(temp);
3211 display_monster(u); // Since master is the same structure, use this function
3212 }
3213 }
3214
3215 void showTavern(aClient *user)
3216 {
3217 Player *p;
3218 list<tavernItem>::iterator item_iterator;
3219 item *tempItem;
3220
3221 p = user->stats;
3222
3223 if (!p)
3224 return;
3225
3226 item_iterator = tavern.begin();
3227 if (tavern.empty())
3228 {
3229 notice(s_GameServ, user->getNick(), "Tavern is empty");
3230 return;
3231 }
3232
3233 while (item_iterator != tavern.end())
3234 {
3235 if (p->getLevel() < (*item_iterator).getLevel())
3236 {
3237 item_iterator++;
3238 continue;
3239 }
3240 tempItem = (*item_iterator).getItem();
3241 notice(s_GameServ, user->getNick(), "%d. %s for %ld gold", tempItem->getID(), tempItem->getName().c_str(), tempItem->price());
3242 item_iterator++;
3243 }
3244 }
3245
3246 void showBankBalance(const char *u)
3247 {
3248 aClient *user;
3249 Player *p;
3250
3251 if (!(user = find(u)))
3252 return;
3253
3254 p = user->stats;
3255
3256 if (!p)
3257 return;
3258
3259 notice(s_GameServ, u, "Account Balance: %ld Gold On hand: %ld", p->getBank(), p->getGold());
3260 }
3261
3262 void rolloverall()
3263 {
3264 ListNode <aClient> *it;
3265 Player *p;
3266 for (unsigned long x = 0; x < U_TABLE_SIZE; x++)
3267 {
3268 it = players[x].First();
3269 while (it)
3270 {
3271 p = it->getData()->stats;
3272 rollover(p);
3273 it = it->Next();
3274 }
3275 }
3276 }
3277 void refreshall()
3278 {
3279 ListNode <aClient> *it;
3280 Player *p;
3281 for (unsigned long x = 0; x < U_TABLE_SIZE; x++)
3282 {
3283 it = players[x].First();
3284
3285 while (it)
3286 {
3287 p = it->getData()->stats;
3288 refresh(p);
3289 it = it->Next();
3290 }
3291 }
3292 }
3293
3294 void rollover(Player *p)
3295 {
3296 if (!p)
3297 return;
3298
3299 p->addForestFights(numrolloverfights);
3300
3301 if (p->getForestFights() > maxforestfights)
3302 p->setForestFights(maxforestfights);
3303 }
3304
3305 void refresh(Player *p)
3306 {
3307 if (!p)
3308 return;
3309
3310 if (p->getHP() < p->getMaxHP())
3311 p->healall();
3312 if (p->getForestFights() < forestfights)
3313 {
3314 p->setForestFights(forestfights);
3315 }
3316
3317 p->setPlayerFights(3);
3318 setAlive(p);
3319 clearMaster(p);
3320 }
3321
3322 void do_refresh(char *u)
3323 {
3324 char *nick = strtok(NULL, " ");
3325 aClient *user;
3326
3327 if (!(user = find(u)))
3328 {
3329 notice(s_GameServ, u, "Error: aClient not found. Contact a %S admin");
3330 log("Error: aClient not found: %s", u);
3331 return;
3332 }
3333 else if (isIgnore(user))
3334 {
3335 #ifdef DEBUGMODE
3336 log("Ignoring %s.", user->getNick());
3337 #endif
3338 return;
3339 }
3340 else if (!isAdmin(user))
3341 {
3342 notice(s_GameServ, u, "You must be a %S admin to use this command!");
3343 return;
3344 }
3345 if (!nick)
3346 {
3347 notice(s_GameServ, u, "SYNTAX: REFRESH {ALL | NICK}");
3348 return;
3349 }
3350 else if (stricmp(nick, "ALL") == 0)
3351 {
3352 notice(s_GameServ, u, "Refreshing everyone's stats!");
3353 refreshall();
3354 }
3355 else if ((user = findplayer(nick)))
3356 {
3357 if (is_playing(user))
3358 {
3359 #ifdef P10
3360 notice(s_GameServ, u, "Refreshing %s.", user->getRealNick());
3361 #else
3362 notice(s_GameServ, u, "Refreshing %s.", user->getNick());
3363 #endif
3364 refresh(user->stats);
3365 }
3366 else
3367 {
3368 #ifdef P10
3369 notice(s_GameServ, u, "%s is not playing.", user->getRealNick());
3370 #else
3371 notice(s_GameServ, u, "%s is not playing.", user->getNick());
3372 #endif
3373 }
3374 }
3375 else
3376 {
3377 notice(s_GameServ, u, "Nick %s not found.", nick);
3378 return;
3379 }
3380 }
3381
3382
3383 void resetall()
3384 {
3385 ListNode <aClient> *it;
3386 Player *p;
3387
3388 for (unsigned long x = 0; x < U_TABLE_SIZE; x++)
3389 {
3390 it = players[x].First();
3391
3392 while (it)
3393 {
3394 p = it->getData()->stats;
3395 reset(p);
3396 it = it->Next();
3397 }
3398 }
3399 }
3400
3401 void reset(Player *p)
3402 {
3403 item *tempItem;
3404 if (!p)
3405 return;
3406
3407 p->reset();
3408 tempItem = findItemByID(3001);
3409 p->inventory->addItem((*Items.begin()))->use(p); // Add the stick
3410 p->inventory->addItem(tempItem)->use(p); // Add Clothes
3411
3412 }
3413
3414 void updateTS(Player *p)
3415 {
3416 if (!p)
3417 return;
3418
3419 #ifdef DEBUGMODE
3420 log("Old timestamp for %s: %ld", p->getName().c_str(), p->lastcommand);
3421 #endif
3422 p->lastcommand = time(NULL);
3423 #ifdef DEBUGMODE
3424 log("New timestamp for %s: %ld", p->getName().c_str(), p->lastcommand);
3425 #endif
3426
3427 }
3428
3429 bool timedOut(Player *p)
3430 {
3431 if (!p)
3432 return false;
3433 else if (p->lastcommand == 0)
3434 return false;
3435 else
3436 {
3437 if ((time(NULL) - p->lastcommand) >= maxidletime)
3438 return true;
3439
3440 return false;
3441 }
3442 }
3443
3444 void timeOutEvent(Player *p)
3445 {
3446 aClient *user = findplayer(p->getName().c_str());
3447
3448 if (!user || !p->getClient()) // then they're not playing
3449 return;
3450
3451 char *nick = user->getNick();
3452
3453 if (player_fight(user) && isYourTurn(p))
3454 {
3455 // Check to see if they were the idler or if it was the other
3456 // person
3457 if (p->lastcommand != p->getBattle()->stats->lastcommand)
3458 {
3459 // This person's last command was given earlier,
3460 // so this person is the idler
3461 notice(s_GameServ, nick, "You timed out "\
3462 "during a fight. You lose your turn!");
3463 notice(s_GameServ, p->getBattle()->getNick(),
3464 "%s hesitated for too long. Your move.", p->getName().c_str());
3465 clearYourTurn(p);
3466 setYourTurn(p->getBattle()->stats);
3467
3468 // Update the TS for both players to give them another
3469 // Chance to wake up, but if the other player doesn't
3470 // Attack now, they both get logged out.
3471 updateTS(p);
3472 p->getBattle()->stats->lastcommand = p->lastcommand;
3473 display_players(p->getBattle());
3474 return;
3475 }
3476 else
3477 {
3478 notice(s_GameServ, p->getBattle()->getNick(),
3479 "You and %s timed out at the same time."\
3480 " Don't fight if you're just going to "\
3481 "sit there!", p->getName().c_str());
3482 notice(s_GameServ, user->getNick(),
3483 "You and %s timed out at the same time."\
3484 " Don't fight if you're just going to "\
3485 "sit there!", p->getBattle()->stats->getName().c_str());
3486 logout(p->getBattle());
3487 logout(user);
3488 return;
3489 }
3490 }
3491 else if (!player_fight(user))
3492 {
3493 if (isAlive(user->stats) && user->stats->getGold() > 0)
3494 {
3495 // Place fun stuff here :)
3496 int randnum = 1 + rand() % 100; // 1-100
3497 #define GSN(s) notice(s_GameServ, nick, s)
3498 #define GSN2(s, f) notice(s_GameServ, nick, s, f)
3499
3500 if (randnum < 50)
3501 {
3502 // 35-100% of your gold goes pffft - kain
3503 int stolen = (35 + (rand() % 66)) * (user->stats->getGold() / 100);
3504
3505 GSN("You stop for a moment to rest on the "\
3506 "street corner. All of a sudden, you "\
3507 "are ambushed from all sides by a hoarde "\
3508 "of knife wielding thugs.");
3509 GSN2("The thugs beat you into utter submission "\
3510 "and steal %ld gold from you!", stolen);
3511 user->stats->subtractGold(stolen);
3512 }
3513 else if (randnum >= 50 && randnum < 75)
3514 {
3515 // 25-65% of your gold goes pffft - kain
3516 int stolen = (25 + (rand() % 41)) * (user->stats->getGold() / 100);
3517 GSN("While dilly dallying around, you lose "\
3518 "your sense of time. Little did you know, "\
3519 "but thieves lifted your gold while you "\
3520 "weren't watching.");
3521 GSN2("Better luck next time... you lose %d gold", stolen);
3522 user->stats->subtractGold(stolen);
3523 }
3524 else if (randnum >= 75)
3525 {
3526 // 25-75% of your gold goes pffft - kain
3527 int stolen = (25 + (rand() % 51)) * (user->stats->getGold() / 100);
3528 GSN("Good grief! A gaggle of gooey green ghostlike "\
3529 "goblins grabbed your gold!");
3530 GSN2("They stole %d gold from you!", stolen);
3531 user->stats->subtractGold(stolen);
3532 }
3533 }
3534
3535 // Always log out the user
3536 logout(user);
3537 }
3538 }
3539
3540 void do_reset(char *u)
3541 {
3542 char *nick = strtok(NULL, " ");
3543 aClient *user;
3544
3545 if (!(user = find(u)))
3546 {
3547 notice(s_GameServ, u, "Error: aClient not found. Contact a %S admin");
3548 log("Error: aClient not found: %s", u);
3549 return;
3550 }
3551 else if (!isAdmin(user))
3552 {
3553 notice(s_GameServ, u, "You must be a %S admin to use this command!");
3554 return;
3555 }
3556
3557 if (!nick)
3558 {
3559 notice(s_GameServ, u, "SYNTAX: RESET {ALL | NICK}");
3560 return;
3561 }
3562 else if (stricmp(nick, "ALL") == 0)
3563 {
3564 notice(s_GameServ, u, "Resetting everyone's stats!");
3565 resetall();
3566 }
3567 else if ((user = findplayer(nick)))
3568 {
3569 if (is_playing(user))
3570 {
3571 #ifdef P10
3572 notice(s_GameServ, u, "Resetting %s.", user->getRealNick());
3573 #else
3574 notice(s_GameServ, u, "Resetting %s.", user->getNick());
3575 #endif
3576 reset(user->stats);
3577 }
3578 else
3579 {
3580 notice(s_GameServ, u, "Resetting %s", user->stats->getName().c_str());
3581 reset(user->stats);
3582 }
3583 }
3584 else
3585 {
3586 notice(s_GameServ, u, "Nick %s not found.", nick);
3587 return;
3588 }
3589 }
3590
3591 void do_help(char *u)
3592 {
3593 char *cmd = strtok(NULL, " ");
3594
3595 display_help(u, cmd);
3596 }
3597
3598 void display_help(char *u, char *file)
3599 {
3600 ifstream infile;
3601 char *buf;
3602
3603 if (!file)
3604 {
3605 infile.open("helpfiles/help");
3606 if (infile.fail())
3607 {
3608 log("Error opening helpfiles/help");
3609 notice(s_GameServ, u, "Error opening helpfiles/help");
3610 return;
3611 }
3612 buf = new char[1024];
3613 while(infile.getline(buf, 1024))
3614 {
3615 // Written this way, it will process %S in the helpfiles
3616 // Instead of notice(s_GameServ, u, "%s", buf);
3617 notice(s_GameServ, u, buf);
3618 }
3619
3620 // Minor recursion
3621 aClient *user = find(u);
3622 if (user && isAdmin(user))
3623 display_help(u, "admin_commands");
3624 }
3625 else
3626 {
3627 char *filename;
3628 filename = new char[strlen(file) + 11];
3629 strcpy(filename, "helpfiles/");
3630 strcat(filename, file);
3631
3632 for (unsigned int x = 10; x < strlen(filename); x++)
3633 filename[x] = tolower(filename[x]);
3634
3635 infile.open(filename);
3636 delete [] filename;
3637 if (infile.fail())
3638 {
3639 notice(s_GameServ, u, "No help for \ 2%s\ 2", file);
3640 return;
3641 }
3642 buf = new char[1024];
3643 while(infile.getline(buf, 1024))
3644 {
3645 // Written this way, it will process %S in the helpfiles
3646 // Instead of notice(s_GameServ, u, "%s", buf);
3647 notice(s_GameServ, u, buf);
3648 }
3649 }
3650 infile.close();
3651 delete [] buf;
3652 }
3653
3654 void do_admin(char *u)
3655 {
3656 aClient *user;
3657 char *pass = strtok(NULL, " ");
3658
3659 if (!(user = find(u)))
3660 {
3661 log("Error: aClient not found: %s", u);
3662 notice(s_GameServ, u, "Error: aClient not found. Contact %S admin.");
3663 return;
3664 }
3665
3666 if (!pass)
3667 {
3668 notice(s_GameServ, u, "SYNTAX: \ 2ADMIN\ 2 \ 2\1fpassword\1f\ 2");
3669 return;
3670 }
3671
3672 if (isAdmin(user))
3673 {
3674 notice(s_GameServ, u, "You already have administrator privledges.");
3675 return;
3676 }
3677 else if (strcmp(pass, adminpass) == 0)
3678 {
3679 notice(s_GameServ, u, "Password accepted. You now have administrator privledges.");
3680 setAdmin(user);
3681 #ifdef P10
3682 log("%s became an administrator.", user->getRealNick());
3683 #else
3684 log("%s became an administrator.", user->getNick());
3685 #endif
3686 }
3687 else
3688 {
3689 notice(s_GameServ, u, "Invalid password. Remember: case sensitive");
3690 return;
3691 }
3692 }
3693
3694 bool load_levels()
3695 {
3696 char *filename;
3697 filename = new char[256];
3698
3699 for (int x = 1; x <= LEVELS; x++)
3700 {
3701 sprintf(filename, "data/levels/level%d.dat", x);
3702 if (levels[x - 1].loadLevel(filename) == false)
3703 return false;
3704 }
3705
3706 delete []filename;
3707 return true;
3708 }
3709 bool load_monsters()
3710 {
3711 char *filename;
3712 ifstream infile;
3713 char *buf;
3714 buf = new char[2048];
3715
3716 for (int level = 1; level <= LEVELS; level++)
3717 {
3718 filename = new char[256];
3719 sprintf(filename, "data/monsters/level%d.dat", level);
3720 infile.open(filename);
3721
3722 if (!infile)
3723 {
3724 log("Error opening %s", filename);
3725 return false;
3726 }
3727
3728 #ifdef DEBUGMODE
3729 log("Loading monsters from %s", filename);
3730 #endif
3731
3732 while (infile.getline(buf, 2048))
3733 {
3734 if (buf[0] == '^')
3735 break;
3736 if (buf[0] == '\n' || buf[0] == '\0' || buf[0] == '#')
3737 continue;
3738 Monster *temp;
3739 temp = new Monster;
3740
3741 temp->name = strtok(buf, "~");
3742 temp->weapon = strtok(NULL, "~");
3743 temp->death = strtok(NULL, "~");
3744
3745 levels[level - 1].monsters.insertAtBack_RLN(temp);
3746 delete temp;
3747 }
3748 delete [] filename;
3749 infile.close();
3750 }
3751 delete [] buf;
3752 return true;
3753 }
3754
3755 item *findItemByID(int id)
3756 {
3757 list<item*>::iterator item_iterator;
3758
3759 item_iterator = Items.begin();
3760
3761 while (item_iterator != Items.end())
3762 {
3763 if ((*item_iterator)->getID() == id)
3764 {
3765 return (*item_iterator);
3766 }
3767 item_iterator++;
3768 }
3769 return NULL;
3770 }
3771
3772 item *findStoreItemByID(int id)
3773 {
3774 list<item*>::iterator item_iterator;
3775
3776 item_iterator = store.begin();
3777
3778 while (item_iterator != store.end())
3779 {
3780 if ((*item_iterator)->getID() == id)
3781 {
3782 return (*item_iterator);
3783 }
3784 item_iterator++;
3785 }
3786 return NULL;
3787 }
3788
3789 tavernItem *findTavernItemByID(int id)
3790 {
3791 list<tavernItem>::iterator item_iterator;
3792
3793 item_iterator = tavern.begin();
3794
3795 while (item_iterator != tavern.end())
3796 {
3797 if ((*item_iterator).getItem()->getID() == id)
3798 {
3799 return &(*item_iterator);
3800 }
3801 item_iterator++;
3802 }
3803 return NULL;
3804 }