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