]> jfr.im git - irc/gameservirc.git/blob - gameserv/gameserv.cpp
made myuses only decrement if it's greater than 0... makes for no negative uses
[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(temp);
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 item *tempitem;
2382 if (tempnum != 0)
2383 {
2384 tempitem = findItemByID(tempnum);
2385 p->setWeapon(*tempitem);
2386 }
2387
2388 tempname = strtok(NULL, " ");
2389 tempnum = stringtoint(tempname);
2390
2391 if (tempnum != 0)
2392 {
2393 tempitem = findItemByID(tempnum);
2394 p->setArmor(*tempitem);
2395 }
2396
2397
2398 unsigned long hv = iHASH((unsigned char *) temp->stats->getName().c_str());
2399
2400 temp->stats->setClient(NULL);
2401 p = players[hv].insertAtBack(temp)->stats;
2402
2403 for (tempname = strtok(NULL, " "); tempname != NULL; tempname = strtok(NULL, " "))
2404 {
2405 long int id, uses;
2406 list<item*>::iterator item_iter;
2407 id = stringtoint(tempname);
2408 tempname = strtok(NULL, " ");
2409 uses = stringtoint(tempname);
2410
2411 item_iter = Items.begin();
2412 while (item_iter != Items.end())
2413 {
2414 if ((*item_iter)->getID() == id)
2415 {
2416 // Don't sort every time you add an item or it eats CPU
2417 p->inventory->addItemNoChecks((*item_iter))->setUses(uses);
2418 log("Inventory Count: %d", p->inventory->getCount());
2419 }
2420 item_iter++;
2421 }
2422 }
2423 p->inventory->sort();
2424 log("Inventory Count: %d", p->inventory->getCount());
2425 delete temp;
2426 }
2427 delete [] buf;
2428 infile.close();
2429 return 1;
2430 }
2431
2432 bool passcmp(const char *encrypted, char *plaintext)
2433 {
2434 char salt[3];
2435 char *plaintext2, *plainToencrypt;
2436 bool same = false;
2437
2438 plaintext2 = new char[strlen(encrypted) + strlen(plaintext)]; // Extra
2439 strcpy(plaintext2, plaintext);
2440
2441 salt[0] = encrypted[0];
2442 salt[1] = encrypted[1];
2443 salt[3] = '\0';
2444
2445 plainToencrypt = crypt(plaintext2, salt);
2446
2447 same = (strcmp((const char *)encrypted, plainToencrypt) == 0 ? true : false);
2448
2449 delete []plaintext2;
2450
2451 return same;
2452 }
2453
2454 bool check_password(char *name, char *plaintext)
2455 {
2456 aClient *client;
2457
2458 if (!(client = findplayer(name)))
2459 return false;
2460 else
2461 {
2462 return passcmp(client->stats->getPassword().c_str(), plaintext);
2463 }
2464 }
2465
2466 void do_store(char *u)
2467 {
2468 list<item*>::iterator item_iterator;
2469 item *tempItem;
2470 char *cmd = strtok(NULL, " ");
2471 char *num = strtok(NULL, " ");
2472 char *space;
2473 int id;
2474 aClient *user;
2475 Player *p;
2476
2477
2478 if (!cmd || !num)
2479 {
2480 notice(s_GameServ, u, "SYNTAX: STORE LIST {ARMOR | WEAPONS}");
2481 notice(s_GameServ, u, " \ 2STORE SELL NUMBER\ 2");
2482 notice(s_GameServ, u, " \ 2STORE BUY \1fNUMBER\1f\ 2");
2483 return;
2484 }
2485 else if (!(user = find(u)))
2486 {
2487 log("Fatal Error: could not find %s in client list", u);
2488 return;
2489 }
2490 else if (isIgnore(user))
2491 {
2492 #ifdef DEBUGMODE
2493 log("Ignoring %s.", user->getNick());
2494 #endif
2495 return;
2496 }
2497 else if (!is_playing(user))
2498 {
2499 notice(s_GameServ, u, "You must be playing to use the store!");
2500 return;
2501 }
2502 else if (is_fighting(user))
2503 {
2504 notice(s_GameServ, u, "You can't go to the store while fighting!");
2505 return;
2506 }
2507 else if (!isAlive(user->stats))
2508 {
2509 notice(s_GameServ, u, "You are dead. Wait until tomorrow to purchase weapons and armor!");
2510 return;
2511 }
2512 updateTS(user->stats);
2513
2514 if (stricmp(cmd, "LIST") == 0)
2515 {
2516 if (stricmp(num, "WEAPONS") == 0)
2517 {
2518 notice(s_GameServ, u, "Welcome to Kain's Armory");
2519 notice(s_GameServ, u, "Here are the weapons we have available for the killing, sire:");
2520 for (item_iterator = store.begin(); item_iterator != store.end(); ++item_iterator)
2521 {
2522 if ((*item_iterator)->getType() == WEAPON)
2523 {
2524 space = spaces(strlen((*item_iterator)->getName().c_str()), ".");
2525 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());
2526 free(space);
2527 }
2528 }
2529 notice(s_GameServ, u, "To purchase a weapon, type /msg %S STORE BUY \ 2#\ 2.");
2530 notice(s_GameServ, u, "Where # is the weapon number from the menu above.");
2531
2532 }
2533 else if (stricmp(num, "ARMOR") == 0)
2534 {
2535 notice(s_GameServ, u, "Welcome to Kain's Armory");
2536 notice(s_GameServ, u, "I hope you enjoy the fine armor we have available for your protection:");
2537 for (item_iterator = store.begin(); item_iterator != store.end(); ++item_iterator)
2538 {
2539 if ((*item_iterator)->getType() == ARMOR)
2540 {
2541 space = spaces(strlen((*item_iterator)->getName().c_str()), ".");
2542 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());
2543 free(space);
2544 }
2545 }
2546
2547 notice(s_GameServ, u, "To purchase armor, type /msg %S store buy #");
2548 notice(s_GameServ, u, "Where # is the armor number from the menu above.");
2549 }
2550
2551 }
2552 else if (stricmp(cmd, "BUY") == 0)
2553 {
2554 p = user->stats;
2555 if (!num)
2556 {
2557 notice(s_GameServ, u, "SYNTAX: \ 2STORE BUY \1f#\1f\ 2");
2558 return;
2559 }
2560 else
2561 {
2562 id = stringtoint(num);
2563 }
2564
2565 if (!isstringnum(num))
2566 {
2567 notice(s_GameServ, u, "SYNTAX: \ 2STORE BUY \1f#\1f\ 2");
2568 return;
2569 }
2570 else if (!(tempItem = findStoreItemByID(id)))
2571 {
2572 notice(s_GameServ, u, "Sorry, we don't carry that item!");
2573 return;
2574 }
2575 else if (p->getGold() < tempItem->price())
2576 {
2577 notice(s_GameServ, u, "You can't afford to buy %s", tempItem->getName().c_str());
2578 return;
2579 }
2580 else if (p->inventory->addItem(tempItem))
2581 {
2582 notice(s_GameServ, u, "You have purchased %s! Thanks for the gold!", tempItem->getName().c_str());
2583 p->subtractGold(tempItem->price());
2584 notice(s_GameServ, u, "Don't forget to type /msg %S equip %ld", tempItem->getID());
2585 }
2586 else
2587 {
2588 notice(s_GameServ, u, "You can't carry any more!");
2589 }
2590 }
2591 else if (stricmp(cmd, "SELL" ) == 0)
2592 {
2593 itemContainer *tempContainer;
2594 p = user->stats;
2595 id = stringtoint(num);
2596 if (!isstringnum(num))
2597 {
2598 notice(s_GameServ, u, "SYNTAX: /msg %S store sell #");
2599 return;
2600 }
2601 else if (!(tempContainer = p->inventory->Find(id)))
2602 {
2603 notice(s_GameServ, u, "You're not carrying that!");
2604 return;
2605 }
2606 else if (p->getGold() >= 2000000000)
2607 {
2608 notice(s_GameServ, u, "You have enough gold. Just hang on to it for now.");
2609 }
2610 else
2611 {
2612 tempItem = tempContainer->getItem();
2613
2614 notice(s_GameServ, u, "Thank you for your business! We gave you %ld gold for %s!", (tempItem->price() / 2), tempItem->getName().c_str());
2615 p->addGold((tempItem->price() / 2));
2616 p->inventory->deleteItem(tempItem);
2617 if (tempItem == p->getWeapon())
2618 {
2619 notice(s_GameServ, u, "Since you equipped %s, you're going to have to reequip something", tempItem->getName().c_str());
2620 tempItem->undo(p);
2621 p->clearWeapon();
2622 }
2623 else if (tempItem == p->getArmor())
2624 {
2625 tempItem->undo(p);
2626 notice(s_GameServ, u, "Since you equipped %s, you're going to have to reequip something", tempItem->getName().c_str());
2627 p->clearArmor();
2628 }
2629 }
2630 }
2631 else
2632 {
2633 notice(s_GameServ, u, "SYNTAX: STORE LIST {ARMOR | WEAPONS}");
2634 notice(s_GameServ, u, " \ 2STORE SELL #\ 2");
2635 notice(s_GameServ, u, " \ 2STORE BUY \1f#\1f\ 2");
2636 return;
2637 }
2638 }
2639 void do_inventory(char *u)
2640 {
2641 aClient *user;
2642
2643 if (!(user = find(u)))
2644 {
2645 notice(s_GameServ, u, "Fatal Error. Contact a %S admin!");
2646 return;
2647 }
2648 else if (isIgnore(user))
2649 {
2650 #ifdef DEBUGMODE
2651 log("Ignoring %s.", user->getNick());
2652 #endif
2653 return;
2654 }
2655 else if (!is_playing(user))
2656 {
2657 notice(s_GameServ, u, "You must be playing to check your inventory!");
2658 return;
2659 }
2660 updateTS(user->stats);
2661 showinventory(user->stats, user);
2662 }
2663
2664 void showinventory(Player *from, aClient *to)
2665 {
2666 char *nick;
2667 if (!to || !from)
2668 {
2669 return;
2670 }
2671
2672 nick = to->getNick();
2673
2674 if (from->inventory->isEmpty())
2675 {
2676 notice(s_GameServ, nick, "You aren't carrying anything");
2677 return;
2678 }
2679
2680 list <itemContainer> *items;
2681 items = from->inventory->getItems();
2682
2683 list <itemContainer>::iterator item_iter, item_iter2;
2684 item_iter = items->begin();
2685
2686 notice(s_GameServ, nick, "Inventory for %s:", from->getName().c_str());
2687 long count;
2688 while (item_iter != items->end())
2689 {
2690 // Display a list of counted items so as not to show an extra line for duplicate items
2691 count = 0;
2692 item_iter2 = item_iter;
2693 while (item_iter != items->end() && (*item_iter) == (*item_iter2))
2694 {
2695 if ((*item_iter) == (*item_iter2))
2696 {
2697 ++count;
2698 }
2699 else
2700 {
2701 break;
2702 }
2703 ++item_iter;
2704 }
2705 notice(s_GameServ, nick, "%ld.) %s (%ld)", (*item_iter2).getItem()->getID(), (*item_iter2).getItem()->getName().c_str(), count);
2706 }
2707 }
2708
2709 void do_tavern(char *u)
2710 {
2711 char *cmd = strtok(NULL, " ");
2712
2713 aClient *user;
2714 Player *p;
2715
2716 if (!(user = find(u)))
2717 {
2718 notice(s_GameServ, u, "Fatal Error. See a %S admin for help");
2719 return;
2720 }
2721 else if (isIgnore(user))
2722 {
2723 #ifdef DEBUGMODE
2724 log("Ignoring %s.", user->getNick());
2725 #endif
2726 return;
2727 }
2728 else if (!is_playing(user))
2729 {
2730 notice(s_GameServ, u, "You must be playing to go to the Tavern");
2731 return;
2732 }
2733 else if (is_fighting(user))
2734 {
2735 notice(s_GameServ, u, "You cannot go to the Tavern during a fight!");
2736 return;
2737 }
2738
2739 updateTS(user->stats);
2740 p = user->stats;
2741
2742 if (!cmd)
2743 {
2744 notice(s_GameServ, u, "Welcome to Boot Liquors Mystic Apothecary and General Store");
2745 notice(s_GameServ, u, "Your commands:");
2746 notice(s_GameServ, u, "/msg %S TAVERN {LIST | BUY} [NUMBER]");
2747 notice(s_GameServ, u, "What'll it be?");
2748 }
2749 else if (stricmp(cmd, "LIST") == 0)
2750 {
2751 notice(s_GameServ, u, "Here is a list of what we have to offer:");
2752 showTavern(user);
2753 notice(s_GameServ, u, "To buy an item, type /msg %S TAVERN BUY #");
2754 }
2755 else if (stricmp(cmd, "BUY") == 0)
2756 {
2757 int amt = 1;
2758 char *chid = strtok(NULL, " ");
2759 char *amount = strtok(NULL, " ");
2760
2761 if (amount)
2762 amt = stringtoint(amount);
2763
2764 if (!chid)
2765 {
2766 notice(s_GameServ, u, "SYNTAX: TAVERN BUY # [#]");
2767 notice(s_GameServ, u, "Example: /msg %S TAVERN BUY 6001");
2768 notice(s_GameServ, u, "Example: /msg %S TAVERN BUY 6001 10");
2769 return;
2770 }
2771 long id = stringtoint(chid);
2772 tavernItem *tempItem;
2773
2774 if (!(tempItem = findTavernItemByID(id)) || user->stats->getLevel() < tempItem->getLevel())
2775 {
2776 notice(s_GameServ, u, "Invalid Choice!");
2777 notice(s_GameServ, u, "Here is a list of what we have to offer:");
2778 showTavern(user);
2779 notice(s_GameServ, u, "To buy an item, type /msg %S TAVERN BUY #");
2780 return;
2781 }
2782 else if (!amount && user->stats->getGold() < tempItem->getItem()->price())
2783 {
2784 notice(s_GameServ, u, "You don't have enough gold!");
2785 notice(s_GameServ, u, "Here is a list of what we have to offer:");
2786 showTavern(user);
2787 notice(s_GameServ, u, "To buy an item, type /msg %S TAVERN BUY #");
2788 }
2789 else if (user->stats->getGold() < amt * tempItem->getItem()->price())
2790 {
2791 notice(s_GameServ, u, "You don't have enough gold!");
2792 notice(s_GameServ, u, "Here is a list of what we have to offer:");
2793 showTavern(user);
2794 notice(s_GameServ, u, "To buy an item, type /msg %S TAVERN BUY # [#]");
2795 }
2796 else
2797 {
2798 if (amount)
2799 {
2800 int amt = stringtoint(amount);
2801 if (amt < 0 || amount[0] == '-')
2802 {
2803 notice(s_GameServ, u, "You trying to steal from me?");
2804 }
2805 else if (user->stats->inventory->addItem(tempItem->getItem(), amt) == NULL)
2806 {
2807 notice(s_GameServ, u, "You can't carry that many!");
2808 }
2809 else
2810 {
2811 notice(s_GameServ, u, "%d %s's coming right up!", amt, tempItem->getItem()->getName().c_str());
2812 user->stats->subtractGold(tempItem->getItem()->price() * amt);
2813 }
2814 }
2815 else
2816 {
2817 if (user->stats->inventory->addItem(tempItem->getItem()) == NULL)
2818 {
2819 notice(s_GameServ, u, "You can't carry any more!");
2820 }
2821 else
2822 {
2823 notice(s_GameServ, u, "One %s coming right up!", tempItem->getItem()->getName().c_str());
2824 user->stats->subtractGold(tempItem->getItem()->price());
2825 notice(s_GameServ, u, "%d", user->stats->inventory->getCount());
2826 }
2827 }
2828 }
2829 }
2830 else
2831 {
2832 notice(s_GameServ, u, "Improper Syntax.");
2833 notice(s_GameServ, u, "Type /msg %S HELP TAVERN for help");
2834 }
2835 return;
2836 }
2837
2838 void do_bank(char *u)
2839 {
2840 char *cmd = strtok(NULL, " ");
2841 char *amount = strtok(NULL, " ");
2842 char *nick = strtok(NULL, " ");
2843
2844 aClient *user;
2845 Player *p;
2846
2847 if (!cmd || (!amount && stricmp(cmd, "BALANCE") != 0) || (stricmp(cmd, "TRANSFER") == 0 && !nick))
2848 {
2849 notice(s_GameServ, u, "BANK {WITHDRAW | DEPOSIT} {ALL | AMOUNT}");
2850 notice (s_GameServ, u, "BANK BALANCE");
2851 return;
2852 }
2853 else if (!(user = find(u)))
2854 {
2855 notice(s_GameServ, u, "Fatal Error. Couldn't find your aClient. Contact a(n) %S "\
2856 " admin for help");
2857 log("Fatal Error. Couldn't find %s while executing do_bank()", u);
2858 return;
2859 }
2860 else if (isIgnore(user))
2861 {
2862 #ifdef DEBUGMODE
2863 log("Ignoring %s.", user->getNick());
2864 #endif
2865 return;
2866 }
2867 else if (!is_playing(user))
2868 {
2869 notice(s_GameServ, u, "You must be playing to use the bank!");
2870 return;
2871 }
2872 else if (is_fighting(user))
2873 {
2874 notice(s_GameServ, u, "You can't go to the bank during a fight!");
2875 return;
2876 }
2877 updateTS(user->stats);
2878 if (stricmp(cmd, "BALANCE") == 0)
2879 {
2880 showBankBalance(u);
2881 return;
2882 }
2883 else if (!isAlive(user->stats))
2884 {
2885 notice(s_GameServ, u, "You are dead. We don't accept gold from dead folk! Wait 'til tomorrow!");
2886 return;
2887 }
2888 else if (!isstringnum(amount) && stricmp(amount, "ALL") != 0)
2889 {
2890 notice(s_GameServ, u, "I don't know how to convert alphabet letters into currency, sire!");
2891 return;
2892 }
2893 if (stringtoint(amount) < 0)
2894 {
2895 notice(s_GameServ, u, "Sorry. This bank is not licensed "\
2896 "to handle such sums of cash, noble Lord.");
2897 return;
2898 }
2899 p = user->stats;
2900
2901 if (stricmp(cmd, "DEPOSIT") == 0)
2902 {
2903 if (p->getBank() == 2000000000)
2904 {
2905 notice(s_GameServ, u, "Your bank account is full, sire!");
2906 return;
2907 }
2908 else if (stricmp(amount, "ALL") == 0)
2909 {
2910 if (2000000000 - p->getBank() < p->getGold())
2911 {
2912 notice(s_GameServ, u, "You don't have enough room for all of your gold.");
2913 notice(s_GameServ, u, "Depositing %ld gold into your account", (2000000000 - p->getBank()));
2914 p->subtractGold((2000000000 - p->getBank()));
2915 p->setBank(2000000000);
2916 showBankBalance(u);
2917 }
2918 else
2919 {
2920 notice(s_GameServ, u, "Depositing %ld gold into your account!", p->getGold());
2921 p->addBank(p->getGold());
2922 p->setGold(0);
2923 showBankBalance(u);
2924 }
2925 }
2926 else if (stringtoint(amount) > p->getGold())
2927 {
2928 notice(s_GameServ, u, "Sire, you only have %ld gold!", p->getGold());
2929 showBankBalance(u);
2930 return;
2931 }
2932 else
2933 {
2934 if (2000000000 - p->getBank() < stringtoint(amount))
2935 {
2936 notice(s_GameServ, u, "You don't have room in your account for that much.");
2937 notice(s_GameServ, u, "Capping off your account with %ld gold!", (2000000000 - p->getBank()));
2938 p->subtractGold((2000000000 - p->getBank()));
2939 p->setBank(2000000000);
2940 showBankBalance(u);
2941 }
2942 else
2943 {
2944 notice(s_GameServ, u, "Depositing %d gold into your account!", stringtoint(amount));
2945 p->addBank(stringtoint(amount));
2946 p->subtractGold(stringtoint(amount));
2947 showBankBalance(u);
2948 }
2949 }
2950 }
2951 else if (stricmp(cmd, "WITHDRAW") == 0)
2952 {
2953 if (p->getGold() == 2000000000)
2954 {
2955 notice(s_GameServ, u, "You cannot carry any more gold, sire!");
2956 showBankBalance(u);
2957 return;
2958 }
2959 else if (stricmp(amount, "ALL") == 0)
2960 {
2961 if (2000000000 - p->getGold() < p->getBank())
2962 {
2963 notice(s_GameServ, u, "You don't have enough room to carry all that gold.");
2964 notice(s_GameServ, u, "Withdrawing %ld gold from your account", (2000000000 - p->getGold()));
2965 p->subtractBank((2000000000 - p->getGold()));
2966 p->setGold(2000000000);
2967 showBankBalance(u);
2968 }
2969 else
2970 {
2971 notice(s_GameServ, u, "Withdrawing %ld gold from your account!", p->getBank());
2972 p->addGold(p->getBank());
2973 p->setBank(0);
2974 showBankBalance(u);
2975 }
2976 }
2977 else if (stringtoint(amount) > p->getBank())
2978 {
2979 notice(s_GameServ, u, "Sire, you only have %ld gold in the bank!", p->getBank());
2980 showBankBalance(u);
2981 return;
2982 }
2983 else
2984 {
2985 if (2000000000 - p->getGold() < stringtoint(amount))
2986 {
2987 notice(s_GameServ, u, "You don't enough have room to carry that much gold!");
2988 notice(s_GameServ, u, "You fill your pockets with %ld gold!",
2989 (2000000000 - p->getGold()));
2990 p->subtractBank((2000000000 - p->getGold()));
2991 p->setGold(2000000000);
2992 showBankBalance(u);
2993 }
2994 else
2995 {
2996 notice(s_GameServ, u, "Withdrawing %d gold from your account!", stringtoint(amount));
2997 p->addGold(stringtoint(amount));
2998 p->subtractBank(stringtoint(amount));
2999 showBankBalance(u);
3000 }
3001 }
3002 }
3003 }
3004
3005 void do_dragon(char *u)
3006 {
3007 aClient *user;
3008
3009 if (!(user = find(u)))
3010 {
3011 notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, ""));
3012 return;
3013 }
3014 else if (isIgnore(user))
3015 {
3016 #ifdef DEBUGMODE
3017 log("Ignoring %s.", user->getNick());
3018 #endif
3019 return;
3020 }
3021 else if (!is_playing(user))
3022 {
3023 notice(s_GameServ, u, "You must be playing to fight the dragon!");
3024 return;
3025 }
3026 else if (is_fighting(user))
3027 {
3028 notice(s_GameServ, u, "You are already in a fight. How will you fight the almighty dragon!?");
3029 return;
3030 }
3031 else if (!isAlive(user->stats))
3032 {
3033 notice(s_GameServ, u, "You're dead. Wait until tomorrow to see your master!");
3034 return;
3035 }
3036 else if (user->stats->getLevel() < LEVELS)
3037 {
3038 notice(s_GameServ, u, "You fool! Only those strong enough "\
3039 "to vanquish any foe should DARE fight the dragon!");
3040 notice(s_GameServ, u, "To put it in terms you can understand: "\
3041 "You are too weak. You must be Level %d!", REALLEVELS);
3042 return;
3043 }
3044
3045 updateTS(user->stats);
3046
3047 Player *p = user->stats;
3048 setMaster(p);
3049 notice(s_GameServ, u, "You approach the dragon's lair cautiously.");
3050 notice(s_GameServ, u, "The stench of sulfer fills the air as a "\
3051 "deep, red fog rolls in. The air is filled with the "\
3052 "heated mist of deadly fire from beyond the cave "\
3053 "entrance.");
3054 notice(s_GameServ, u, "You adjust your %s, tighten your grip on "\
3055 "your %s, and venture into the hot, dark cave. "\
3056 "You are surprised at the angle of descent as you climb "\
3057 "lower and lower, deeper into the dragon's den.",
3058 (p->getArmor() ? p->getArmor()->getName().c_str() : "Fists"), (p->getWeapon() ? p->getWeapon()->getName().c_str() : "Birthday Suit"));
3059 notice(s_GameServ, u, "You come to the end of the cave to find "\
3060 "a tooth. It is a large tooth... bigger than your torso."\
3061 " Suddenly the darkness lifts from the gleam of an eye "\
3062 " staring into your soul! The eye is large... HUGE!");
3063 notice(s_GameServ, u, "Just then you notice the eye begin to "\
3064 "glare orange! The tooth is moving... but it is still too "\
3065 "dark for you to make out.... THE DRAGON! You see it!");
3066 p->setMonster(new Monster(dragon));
3067 setDragonFight(p);
3068 display_monster(u);
3069 }
3070
3071 void do_master(char *u)
3072 {
3073 aClient *user;
3074
3075
3076 if (!(user = find(u)))
3077 {
3078 notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, ""));
3079 return;
3080 }
3081 else if (isIgnore(user))
3082 {
3083 #ifdef DEBUGMODE
3084 log("Ignoring %s.", user->getNick());
3085 #endif
3086 return;
3087 }
3088 else if (!is_playing(user))
3089 {
3090 notice(s_GameServ, u, "You must be playing to see your master!");
3091 return;
3092 }
3093 else if (is_fighting(user))
3094 {
3095 notice(s_GameServ, u, "You're in the middle of a fight! Pay attention!");
3096 return;
3097 }
3098 else if (!isAlive(user->stats))
3099 {
3100 notice(s_GameServ, u, "You're dead. Wait until tomorrow to see your master!");
3101 return;
3102 }
3103
3104 updateTS(user->stats);
3105
3106 char *cmd = strtok(NULL, " ");
3107 Player *p = user->stats;
3108 long int need = 0;
3109
3110 if (seenMaster(p))
3111 {
3112 notice(s_GameServ, u, "You have already seen your master today. Wait until tomorrow to try again");
3113 return;
3114 }
3115
3116 if (cmd != NULL)
3117 {
3118 switch(p->getLevel())
3119 {
3120 case 1:
3121 need = 200;
3122 break;
3123 case 2:
3124 need = 800;
3125 break;
3126 case 3:
3127 need = 2000;
3128 break;
3129 case 4:
3130 need = 8000;
3131 break;
3132 case 5:
3133 need = 20000;
3134 break;
3135 case 6:
3136 need = 80000;
3137 break;
3138 case 7:
3139 need = 200000;
3140 break;
3141 case 8:
3142 need = 800000;
3143 break;
3144 case 9:
3145 need = 2000000;
3146 break;
3147 case 10:
3148 need = 8000000;
3149 break;
3150 case 11:
3151 need = 20000000;
3152 break;
3153
3154 case REALLEVELS:
3155 need = p->getExp() + 1;
3156 notice(s_GameServ, u, "You are at level %d. You are the master. What's left? The DRAGON!", REALLEVELS);
3157 return;
3158 break;
3159 default:
3160 need = p->getExp() + 1; // Unknown level... don't let them fight a fake master!
3161 break;
3162 }
3163 }
3164 else
3165 {
3166 notice(s_GameServ, u, "SYNTAX: MASTER {FIGHT | QUESTION}");
3167 return;
3168 }
3169
3170 if (stricmp(cmd, "FIGHT") == 0)
3171 {
3172 if (p->getExp() >= need)
3173 {
3174 setMaster(p);
3175 see_master(u);
3176 }
3177 else
3178 notice(s_GameServ, u, "You are not worthy of fighting %s! You need %ld more experience.",
3179 levels[p->getLevel() - 1].master.name.c_str(), (need - p->getExp()));
3180 return;
3181 }
3182 else if (stricmp(cmd, "QUESTION") == 0)
3183 {
3184 if (p->getExp() >= need)
3185 notice(s_GameServ, u, "%s looks you up and down and decides you are more ready than you will ever be.",
3186 levels[p->getLevel() - 1].master.name.c_str());
3187 else
3188 notice(s_GameServ, u, "You pathetic fool! You are no match for %s, %s!",
3189 levels[p->getLevel() - 1].master.name.c_str(), p->getName().c_str());
3190
3191 return;
3192 }
3193 else
3194 {
3195 notice(s_GameServ, u, "SYNTAX: MASTER {FIGHT | QUESTION}");
3196 }
3197 }
3198
3199 void see_master(char *u)
3200 {
3201 aClient *user;
3202
3203 if (!(user = find(u)))
3204 {
3205 notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, ""));
3206 return;
3207 }
3208
3209 if (!is_fighting(user) && is_playing(user))
3210 {
3211 Monster *temp;
3212 Player *p = user->stats;
3213 temp = new Monster(levels[p->getLevel() - 1].master);
3214 p->setMyMaster(temp);
3215 p->setMonster(temp);
3216 display_monster(u); // Since master is the same structure, use this function
3217 }
3218 }
3219
3220 void showTavern(aClient *user)
3221 {
3222 Player *p;
3223 list<tavernItem>::iterator item_iterator;
3224 item *tempItem;
3225
3226 p = user->stats;
3227
3228 if (!p)
3229 return;
3230
3231 item_iterator = tavern.begin();
3232 if (tavern.empty())
3233 {
3234 notice(s_GameServ, user->getNick(), "Tavern is empty");
3235 return;
3236 }
3237
3238 while (item_iterator != tavern.end())
3239 {
3240 if (p->getLevel() < (*item_iterator).getLevel())
3241 {
3242 item_iterator++;
3243 continue;
3244 }
3245 tempItem = (*item_iterator).getItem();
3246 notice(s_GameServ, user->getNick(), "%d. %s for %ld gold", tempItem->getID(), tempItem->getName().c_str(), tempItem->price());
3247 item_iterator++;
3248 }
3249 }
3250
3251 void showBankBalance(const char *u)
3252 {
3253 aClient *user;
3254 Player *p;
3255
3256 if (!(user = find(u)))
3257 return;
3258
3259 p = user->stats;
3260
3261 if (!p)
3262 return;
3263
3264 notice(s_GameServ, u, "Account Balance: %ld Gold On hand: %ld", p->getBank(), p->getGold());
3265 }
3266
3267 void rolloverall()
3268 {
3269 ListNode <aClient> *it;
3270 Player *p;
3271 for (unsigned long x = 0; x < U_TABLE_SIZE; x++)
3272 {
3273 it = players[x].First();
3274 while (it)
3275 {
3276 p = it->getData()->stats;
3277 rollover(p);
3278 it = it->Next();
3279 }
3280 }
3281 }
3282 void refreshall()
3283 {
3284 ListNode <aClient> *it;
3285 Player *p;
3286 for (unsigned long x = 0; x < U_TABLE_SIZE; x++)
3287 {
3288 it = players[x].First();
3289
3290 while (it)
3291 {
3292 p = it->getData()->stats;
3293 refresh(p);
3294 it = it->Next();
3295 }
3296 }
3297 }
3298
3299 void rollover(Player *p)
3300 {
3301 if (!p)
3302 return;
3303
3304 p->addForestFights(numrolloverfights);
3305
3306 if (p->getForestFights() > maxforestfights)
3307 p->setForestFights(maxforestfights);
3308 }
3309
3310 void refresh(Player *p)
3311 {
3312 if (!p)
3313 return;
3314
3315 if (p->getHP() < p->getMaxHP())
3316 p->healall();
3317 if (p->getForestFights() < forestfights)
3318 {
3319 p->setForestFights(forestfights);
3320 }
3321
3322 p->setPlayerFights(3);
3323 setAlive(p);
3324 clearMaster(p);
3325 }
3326
3327 void do_refresh(char *u)
3328 {
3329 char *nick = strtok(NULL, " ");
3330 aClient *user;
3331
3332 if (!(user = find(u)))
3333 {
3334 notice(s_GameServ, u, "Error: aClient not found. Contact a %S admin");
3335 log("Error: aClient not found: %s", u);
3336 return;
3337 }
3338 else if (isIgnore(user))
3339 {
3340 #ifdef DEBUGMODE
3341 log("Ignoring %s.", user->getNick());
3342 #endif
3343 return;
3344 }
3345 else if (!isAdmin(user))
3346 {
3347 notice(s_GameServ, u, "You must be a %S admin to use this command!");
3348 return;
3349 }
3350 if (!nick)
3351 {
3352 notice(s_GameServ, u, "SYNTAX: REFRESH {ALL | NICK}");
3353 return;
3354 }
3355 else if (stricmp(nick, "ALL") == 0)
3356 {
3357 notice(s_GameServ, u, "Refreshing everyone's stats!");
3358 refreshall();
3359 }
3360 else if ((user = findplayer(nick)))
3361 {
3362 if (is_playing(user))
3363 {
3364 #ifdef P10
3365 notice(s_GameServ, u, "Refreshing %s.", user->getRealNick());
3366 #else
3367 notice(s_GameServ, u, "Refreshing %s.", user->getNick());
3368 #endif
3369 refresh(user->stats);
3370 }
3371 else
3372 {
3373 #ifdef P10
3374 notice(s_GameServ, u, "%s is not playing.", user->getRealNick());
3375 #else
3376 notice(s_GameServ, u, "%s is not playing.", user->getNick());
3377 #endif
3378 }
3379 }
3380 else
3381 {
3382 notice(s_GameServ, u, "Nick %s not found.", nick);
3383 return;
3384 }
3385 }
3386
3387
3388 void resetall()
3389 {
3390 ListNode <aClient> *it;
3391 Player *p;
3392
3393 for (unsigned long x = 0; x < U_TABLE_SIZE; x++)
3394 {
3395 it = players[x].First();
3396
3397 while (it)
3398 {
3399 p = it->getData()->stats;
3400 reset(p);
3401 it = it->Next();
3402 }
3403 }
3404 }
3405
3406 void reset(Player *p)
3407 {
3408 item *tempItem;
3409 if (!p)
3410 return;
3411
3412 p->reset();
3413 tempItem = findItemByID(3001);
3414 p->inventory->addItem((*Items.begin()))->use(p); // Add the stick
3415 p->inventory->addItem(tempItem)->use(p); // Add Clothes
3416
3417 }
3418
3419 void updateTS(Player *p)
3420 {
3421 if (!p)
3422 return;
3423
3424 #ifdef DEBUGMODE
3425 log("Old timestamp for %s: %ld", p->getName().c_str(), p->lastcommand);
3426 #endif
3427 p->lastcommand = time(NULL);
3428 #ifdef DEBUGMODE
3429 log("New timestamp for %s: %ld", p->getName().c_str(), p->lastcommand);
3430 #endif
3431
3432 }
3433
3434 bool timedOut(Player *p)
3435 {
3436 if (!p)
3437 return false;
3438 else if (p->lastcommand == 0)
3439 return false;
3440 else
3441 {
3442 if ((time(NULL) - p->lastcommand) >= maxidletime)
3443 return true;
3444
3445 return false;
3446 }
3447 }
3448
3449 void timeOutEvent(Player *p)
3450 {
3451 aClient *user = findplayer(p->getName().c_str());
3452
3453 if (!user || !p->getClient()) // then they're not playing
3454 return;
3455
3456 char *nick = user->getNick();
3457
3458 if (player_fight(user) && isYourTurn(p))
3459 {
3460 // Check to see if they were the idler or if it was the other
3461 // person
3462 if (p->lastcommand != p->getBattle()->stats->lastcommand)
3463 {
3464 // This person's last command was given earlier,
3465 // so this person is the idler
3466 notice(s_GameServ, nick, "You timed out "\
3467 "during a fight. You lose your turn!");
3468 notice(s_GameServ, p->getBattle()->getNick(),
3469 "%s hesitated for too long. Your move.", p->getName().c_str());
3470 clearYourTurn(p);
3471 setYourTurn(p->getBattle()->stats);
3472
3473 // Update the TS for both players to give them another
3474 // Chance to wake up, but if the other player doesn't
3475 // Attack now, they both get logged out.
3476 updateTS(p);
3477 p->getBattle()->stats->lastcommand = p->lastcommand;
3478 display_players(p->getBattle());
3479 return;
3480 }
3481 else
3482 {
3483 notice(s_GameServ, p->getBattle()->getNick(),
3484 "You and %s timed out at the same time."\
3485 " Don't fight if you're just going to "\
3486 "sit there!", p->getName().c_str());
3487 notice(s_GameServ, user->getNick(),
3488 "You and %s timed out at the same time."\
3489 " Don't fight if you're just going to "\
3490 "sit there!", p->getBattle()->stats->getName().c_str());
3491 logout(p->getBattle());
3492 logout(user);
3493 return;
3494 }
3495 }
3496 else if (!player_fight(user))
3497 {
3498 if (isAlive(user->stats) && user->stats->getGold() > 0)
3499 {
3500 // Place fun stuff here :)
3501 int randnum = 1 + rand() % 100; // 1-100
3502 #define GSN(s) notice(s_GameServ, nick, s)
3503 #define GSN2(s, f) notice(s_GameServ, nick, s, f)
3504
3505 if (randnum < 50)
3506 {
3507 // 35-100% of your gold goes pffft - kain
3508 int stolen = (35 + (rand() % 66)) * (user->stats->getGold() / 100);
3509
3510 GSN("You stop for a moment to rest on the "\
3511 "street corner. All of a sudden, you "\
3512 "are ambushed from all sides by a hoarde "\
3513 "of knife wielding thugs.");
3514 GSN2("The thugs beat you into utter submission "\
3515 "and steal %ld gold from you!", stolen);
3516 user->stats->subtractGold(stolen);
3517 }
3518 else if (randnum >= 50 && randnum < 75)
3519 {
3520 // 25-65% of your gold goes pffft - kain
3521 int stolen = (25 + (rand() % 41)) * (user->stats->getGold() / 100);
3522 GSN("While dilly dallying around, you lose "\
3523 "your sense of time. Little did you know, "\
3524 "but thieves lifted your gold while you "\
3525 "weren't watching.");
3526 GSN2("Better luck next time... you lose %d gold", stolen);
3527 user->stats->subtractGold(stolen);
3528 }
3529 else if (randnum >= 75)
3530 {
3531 // 25-75% of your gold goes pffft - kain
3532 int stolen = (25 + (rand() % 51)) * (user->stats->getGold() / 100);
3533 GSN("Good grief! A gaggle of gooey green ghostlike "\
3534 "goblins grabbed your gold!");
3535 GSN2("They stole %d gold from you!", stolen);
3536 user->stats->subtractGold(stolen);
3537 }
3538 }
3539
3540 // Always log out the user
3541 logout(user);
3542 }
3543 }
3544
3545 void do_reset(char *u)
3546 {
3547 char *nick = strtok(NULL, " ");
3548 aClient *user;
3549
3550 if (!(user = find(u)))
3551 {
3552 notice(s_GameServ, u, "Error: aClient not found. Contact a %S admin");
3553 log("Error: aClient not found: %s", u);
3554 return;
3555 }
3556 else if (!isAdmin(user))
3557 {
3558 notice(s_GameServ, u, "You must be a %S admin to use this command!");
3559 return;
3560 }
3561
3562 if (!nick)
3563 {
3564 notice(s_GameServ, u, "SYNTAX: RESET {ALL | NICK}");
3565 return;
3566 }
3567 else if (stricmp(nick, "ALL") == 0)
3568 {
3569 notice(s_GameServ, u, "Resetting everyone's stats!");
3570 resetall();
3571 }
3572 else if ((user = findplayer(nick)))
3573 {
3574 if (is_playing(user))
3575 {
3576 #ifdef P10
3577 notice(s_GameServ, u, "Resetting %s.", user->getRealNick());
3578 #else
3579 notice(s_GameServ, u, "Resetting %s.", user->getNick());
3580 #endif
3581 reset(user->stats);
3582 }
3583 else
3584 {
3585 notice(s_GameServ, u, "Resetting %s", user->stats->getName().c_str());
3586 reset(user->stats);
3587 }
3588 }
3589 else
3590 {
3591 notice(s_GameServ, u, "Nick %s not found.", nick);
3592 return;
3593 }
3594 }
3595
3596 void do_help(char *u)
3597 {
3598 char *cmd = strtok(NULL, " ");
3599
3600 display_help(u, cmd);
3601 }
3602
3603 void display_help(char *u, char *file)
3604 {
3605 ifstream infile;
3606 char *buf;
3607
3608 if (!file)
3609 {
3610 infile.open("helpfiles/help");
3611 if (infile.fail())
3612 {
3613 log("Error opening helpfiles/help");
3614 notice(s_GameServ, u, "Error opening helpfiles/help");
3615 return;
3616 }
3617 buf = new char[1024];
3618 while(infile.getline(buf, 1024))
3619 {
3620 // Written this way, it will process %S in the helpfiles
3621 // Instead of notice(s_GameServ, u, "%s", buf);
3622 notice(s_GameServ, u, buf);
3623 }
3624
3625 // Minor recursion
3626 aClient *user = find(u);
3627 if (user && isAdmin(user))
3628 display_help(u, "admin_commands");
3629 }
3630 else
3631 {
3632 char *filename;
3633 filename = new char[strlen(file) + 11];
3634 strcpy(filename, "helpfiles/");
3635 strcat(filename, file);
3636
3637 for (unsigned int x = 10; x < strlen(filename); x++)
3638 filename[x] = tolower(filename[x]);
3639
3640 infile.open(filename);
3641 delete [] filename;
3642 if (infile.fail())
3643 {
3644 notice(s_GameServ, u, "No help for \ 2%s\ 2", file);
3645 return;
3646 }
3647 buf = new char[1024];
3648 while(infile.getline(buf, 1024))
3649 {
3650 // Written this way, it will process %S in the helpfiles
3651 // Instead of notice(s_GameServ, u, "%s", buf);
3652 notice(s_GameServ, u, buf);
3653 }
3654 }
3655 infile.close();
3656 delete [] buf;
3657 }
3658
3659 void do_admin(char *u)
3660 {
3661 aClient *user;
3662 char *pass = strtok(NULL, " ");
3663
3664 if (!(user = find(u)))
3665 {
3666 log("Error: aClient not found: %s", u);
3667 notice(s_GameServ, u, "Error: aClient not found. Contact %S admin.");
3668 return;
3669 }
3670
3671 if (!pass)
3672 {
3673 notice(s_GameServ, u, "SYNTAX: \ 2ADMIN\ 2 \ 2\1fpassword\1f\ 2");
3674 return;
3675 }
3676
3677 if (isAdmin(user))
3678 {
3679 notice(s_GameServ, u, "You already have administrator privledges.");
3680 return;
3681 }
3682 else if (strcmp(pass, adminpass) == 0)
3683 {
3684 notice(s_GameServ, u, "Password accepted. You now have administrator privledges.");
3685 setAdmin(user);
3686 #ifdef P10
3687 log("%s became an administrator.", user->getRealNick());
3688 #else
3689 log("%s became an administrator.", user->getNick());
3690 #endif
3691 }
3692 else
3693 {
3694 notice(s_GameServ, u, "Invalid password. Remember: case sensitive");
3695 return;
3696 }
3697 }
3698
3699 bool load_levels()
3700 {
3701 char *filename;
3702 filename = new char[256];
3703
3704 for (int x = 1; x <= LEVELS; x++)
3705 {
3706 sprintf(filename, "data/levels/level%d.dat", x);
3707 if (levels[x - 1].loadLevel(filename) == false)
3708 return false;
3709 }
3710
3711 delete []filename;
3712 return true;
3713 }
3714 bool load_monsters()
3715 {
3716 char *filename;
3717 ifstream infile;
3718 char *buf;
3719 buf = new char[2048];
3720
3721 for (int level = 1; level <= LEVELS; level++)
3722 {
3723 filename = new char[256];
3724 sprintf(filename, "data/monsters/level%d.dat", level);
3725 infile.open(filename);
3726
3727 if (!infile)
3728 {
3729 log("Error opening %s", filename);
3730 return false;
3731 }
3732
3733 #ifdef DEBUGMODE
3734 log("Loading monsters from %s", filename);
3735 #endif
3736
3737 while (infile.getline(buf, 2048))
3738 {
3739 if (buf[0] == '^')
3740 break;
3741 if (buf[0] == '\n' || buf[0] == '\0' || buf[0] == '#')
3742 continue;
3743 Monster *temp;
3744 temp = new Monster;
3745
3746 temp->name = strtok(buf, "~");
3747 temp->weapon = strtok(NULL, "~");
3748 temp->death = strtok(NULL, "~");
3749
3750 levels[level - 1].monsters.insertAtBack_RLN(temp);
3751 delete temp;
3752 }
3753 delete [] filename;
3754 infile.close();
3755 }
3756 delete [] buf;
3757 return true;
3758 }
3759
3760 item *findItemByID(int id)
3761 {
3762 list<item*>::iterator item_iterator;
3763
3764 item_iterator = Items.begin();
3765
3766 while (item_iterator != Items.end())
3767 {
3768 if ((*item_iterator)->getID() == id)
3769 {
3770 return (*item_iterator);
3771 }
3772 item_iterator++;
3773 }
3774 return NULL;
3775 }
3776
3777 item *findStoreItemByID(int id)
3778 {
3779 list<item*>::iterator item_iterator;
3780
3781 item_iterator = store.begin();
3782
3783 while (item_iterator != store.end())
3784 {
3785 if ((*item_iterator)->getID() == id)
3786 {
3787 return (*item_iterator);
3788 }
3789 item_iterator++;
3790 }
3791 return NULL;
3792 }
3793
3794 tavernItem *findTavernItemByID(int id)
3795 {
3796 list<tavernItem>::iterator item_iterator;
3797
3798 item_iterator = tavern.begin();
3799
3800 while (item_iterator != tavern.end())
3801 {
3802 if ((*item_iterator).getItem()->getID() == id)
3803 {
3804 return &(*item_iterator);
3805 }
3806 item_iterator++;
3807 }
3808 return NULL;
3809 }