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