X-Git-Url: https://jfr.im/git/irc/gameservirc.git/blobdiff_plain/a3017ab1ff5714f9f8b0f10197f1d5677993a037..6d053d90c2a3552a3d3f6f67626c7efc4f9a8e3d:/gameserv/gameserv.cpp diff --git a/gameserv/gameserv.cpp b/gameserv/gameserv.cpp index fb61334..d2e37a4 100644 --- a/gameserv/gameserv.cpp +++ b/gameserv/gameserv.cpp @@ -10,6 +10,7 @@ using std::ifstream; using std::ofstream; +using std::ios; #if defined(HAVE_CRYPT_H) @@ -23,7 +24,8 @@ using std::ofstream; // this will be hash.cpp start // thank you wcampbel -unsigned long HASH(const unsigned char *name, int size_of_table); +unsigned long sHASH(const unsigned char *name); +unsigned long iHASH(const unsigned char *name); List players[U_TABLE_SIZE]; // this will be hash.cpp end @@ -46,7 +48,6 @@ int stricmp(const char *s1, const char *s2); int strnicmp(const char *s1, const char *s2, size_t len); // String Functions - /********** Password functions **********/ bool passcmp(char *encrypted, char *plaintext); // Compares an encrypted pass with a plain text one @@ -58,6 +59,11 @@ bool check_password(char *name, char *plaintext); // Finds a password for the gi /********** GameServ Booleans **********/ +bool shuttingdown; +bool timedOut(Player *p); +void updateTS(Player *p); +void timeOutEvent(Player *p); + bool is_playing(char *u); // True if the given nickname in the clients list is playing. bool is_playing(aClient *user); @@ -84,6 +90,7 @@ long int stringtoint(char *number); char *spaces(int len, char *seperator); void refresh(Player *p); void refreshall(); +void updateTS(Player *p); void reset(Player *p); void init_masters(); void init_monsters(); @@ -142,14 +149,15 @@ int defbonus[11] = {2, 3, 5, 10, 15, 22, 35, 60, 80, 120, 150}; void gameserv(char *source, char *buf) { - char *cmd; + char *cmd, z; cmd = strtok(buf, " "); #ifndef P10 source++; // Get rid of that : at the beginning of a :Nick privmsg Gameserv :text #endif - if (cmd[0] == ':') + z = cmd[0]; + if (z == ':') cmd++; // Get rid of that : at the beginning of the :text (command) #ifdef DEBUGMODE @@ -243,6 +251,7 @@ void gameserv(char *source, char *buf) #else raw("SQUIT %s :leaving: %s used the Shutdown command.", servername, source); #endif + shuttingdown = true; } } else if (stricmp(cmd, "SAVE") == 0) { aClient *user; @@ -308,11 +317,27 @@ void gameserv(char *source, char *buf) } #endif } else { - notice(s_GameServ, source, "Unknown command \002%s\002. Type /msg %S \002HELP\002 to get a list of commands.", cmd); + aClient *user; + if ((user = find(source))) + { + if (isIgnore(user)) + { + #ifdef DEBUGMODE + log("Ignoring %s.", user->getNick()); + #endif + } + else + { + notice(s_GameServ, source, "Unknown command \002%s\002. Type /msg %S \002HELP\002 to get a list of commands.", cmd); + } + } } - source--; // Bring the ':' back so we don't leak memory - cmd--; // Same thing :) + #ifndef P10 + source--; // Bring the ':' back so we don't leak memory + #endif + if (z == ':') + cmd--; // Same thing :) } int stricmp(const char *s1, const char *s2) @@ -438,6 +463,22 @@ void notice(const char *source, const char *dest, const char *fmt, ...) if (fmt[0] == '\0') return; + char *commanduse; + commanduse = new char[16]; + + #ifdef P10 + if (isUsePrivmsg()) + strcpy(commanduse, "P"); + else + strcpy(commanduse, "N"); + #else + + if (isUsePrivmsg()) + strcpy(commanduse, "PRIVMSG"); + else + strcpy(commanduse, "NOTICE"); + #endif + va_list args; char *input; const char *t = fmt; @@ -448,9 +489,9 @@ void notice(const char *source, const char *dest, const char *fmt, ...) dest++; #if !defined(P10) - sprintf(input, ":%s NOTICE %s :", source, dest); + sprintf(input, ":%s %s %s :", source, commanduse, dest); #else - sprintf(input, "%s O %s :", gsnum, dest); + sprintf(input, "%s %s %s :", gsnum, commanduse, dest); #endif dest--; @@ -458,9 +499,9 @@ void notice(const char *source, const char *dest, const char *fmt, ...) else { #if !defined(P10) - sprintf(input, ":%s NOTICE %s :", source, dest); + sprintf(input, ":%s %s %s :", source, commanduse, dest); #else - sprintf(input, "%s O %s :", gsnum, dest); + sprintf(input, "%s %s %s :", gsnum, commanduse, dest); #endif } @@ -488,6 +529,7 @@ void notice(const char *source, const char *dest, const char *fmt, ...) #endif sprintf(input, "%s%s", input, "\r\n"); sock_puts(sock, input); + delete [] commanduse; delete [] input; va_end(args); } @@ -533,6 +575,20 @@ char *strtok(char *str, const char *delim) void do_list(char *u) { + aClient *user; + if (!(user = find(u))) + { + log("Fatal Error: Couldn't find %s in the client list", u); + return; + } + else if (isIgnore(user)) + { + #ifdef DEBUGMODE + log("Ignoring %s. Command LIST", user->getNick()); + #endif + return; + } + ListNode *temp; bool header = false; for (unsigned long x = 0; x < U_TABLE_SIZE; x++) @@ -569,36 +625,67 @@ void do_list(char *u) void do_logout(char *u) { aClient *user; + char *name = strtok(NULL, " "); + if (!(user = find(u))) { notice(s_GameServ, u, "Fatal error. Cannot find aClient. "\ "Buf: %s LOGOUT", u); log("Could not find aClient Buf: %s LOGOUT", u); + return; } - else if (!is_playing(user)) + else if (isIgnore(user)) { - notice(s_GameServ, u, "You're not logged in!"); + #ifdef DEBUGMODE + log("Ignoring %s.", user->getNick()); + #endif + return; } - else if (is_fighting(user)) + + if (name) { - notice(s_GameServ, u, "You can't logout while fighting!"); + if (!isAdmin(user)) + { + notice(s_GameServ, u, "You must be a %S admin to use this command!"); + } + else if (!(user = findplayer(name))) + { + notice(s_GameServ, u, "Couldn't find a player named %s", name); + } + else + { + notice(s_GameServ, u, "Logging out %s", user->stats->name); + logout(user); + } } - else + else if (!name) { - notice(s_GameServ, u, "You have left the fields. You have lived to kill another day!"); - logout(user); + if (!is_playing(user)) + { + notice(s_GameServ, u, "You're not logged in!"); + } + else if (is_fighting(user)) + { + notice(s_GameServ, u, "You can't logout while fighting!"); + } + else + { + notice(s_GameServ, u, "You have left the fields. You have lived to kill another day!"); + logout(user); + } } } + void logout(aClient *user) { if (is_playing(user)) { ListNode *it; aClient *temp; - unsigned long hv = HASH((unsigned char *) user->stats->name, - U_TABLE_SIZE); + unsigned long hv = iHASH((unsigned char *) user->stats->name); it = players[hv].Find(user); + if (!it) { notice(s_GameServ, user->getNick(), "Fatal error. Contact "\ @@ -616,18 +703,18 @@ void logout(aClient *user) temp = new aClient; temp->stats = new Player; temp->stats->setData(user->stats); - user->stats->user = NULL; + user->stats->client = NULL; if (player_fight(user)) user->stats->battle->stats->battle = NULL; delete user->stats; user->stats = NULL; - temp->stats->user = NULL; + temp->stats->client = NULL; #ifdef P10 - temp->setRealNick("!NULL!"); + temp->setRealNick("Not Playing"); #endif - temp->setNick("!NULL!"); + temp->setNick("Not Playing"); it->setNewPtr(temp); #ifdef DEBUGMODE @@ -640,11 +727,13 @@ void logout(aClient *user) ); #endif } + clearPlaying(user); } + void do_register(char *u) { char *password, *name; - aClient *user, *p; + aClient *user; name = strtok(NULL, " "); password = strtok(NULL, " "); @@ -668,20 +757,36 @@ void do_register(char *u) notice(s_GameServ, u, "%s is already registered!", name); notice(s_GameServ, u, "Choose another name!"); } - else if ((user = find(u))) + else if (!(user = find(u))) + { + log("Fatal Error: Couldn't find %s in the clients list", u); + } + else if (isIgnore(user)) + { + #ifdef DEBUGMODE + log("Ignoring %s.", user->getNick()); + #endif + return; + } + else { - p = findplayer(u); - if (!user->stats && !p) + if (!is_playing(user)) { + ListNode *temp; user->stats = new Player(user); - user->stats->user = user; // Set the backwards pointer - strcpy(user->stats->password, crypt(password, salt)); - strcpy(user->stats->name, name); - unsigned long hv = HASH((unsigned char *) name, U_TABLE_SIZE); - players[hv].insertAtBack(user); + user->stats->client = user; // Set the backwards pointer + user->stats->reset(); // set the user up + strncpy(user->stats->password, crypt(password, salt), 255); + strncpy(user->stats->name, name, 255); + unsigned long hv = iHASH((unsigned char *) name); + updateTS(user->stats); + temp = players[hv].insertAtBack_RLN(user); + temp->setPtr(user); // This is an extra step, but necessary for now + notice(s_GameServ, u, "Player %s registered with password %s.", user->stats->name, password); notice(s_GameServ, u, "Write this password down. If you lose it, there is no way to retrieve it!"); log("Nickname %s registered player %s.", u, user->stats->name); + setPlaying(user); // set the playing flag } else { @@ -696,23 +801,29 @@ void do_identify(char *u) aClient *user, *p; name = strtok(NULL, " "); password = strtok(NULL, " "); - user = find(u); if (!password || !name) { notice(s_GameServ, u, "SYNTAX: /msg %S IDENTIFY NAME PASSWORD"); } - else if (!user) + else if (!(user = find(u))) { notice(s_GameServ, u, "Fatal error. Cannot find aClient. Buf: %s", strtok(NULL, "")); log("Error: aClient not found: %s", u); } + else if (isIgnore(user)) + { + #ifdef DEBUGMODE + log("Ignoring %s.", user->getNick()); + #endif + return; + } else if (!(p = findplayer(name)) || !p->stats) notice(s_GameServ, u, "Player %s not found", name); else if (is_playing(user)) { notice(s_GameServ, u, "You are already playing!"); } - else if (p->stats->user != NULL && !isAdmin(user)) + else if (p->stats->client != NULL && !isAdmin(user)) { notice(s_GameServ, u, "That player has already identified."); } @@ -722,8 +833,7 @@ void do_identify(char *u) } else { ListNode *temp; - unsigned long hv = HASH((unsigned char *) p->stats->name, - U_TABLE_SIZE); + unsigned long hv = iHASH((unsigned char *) p->stats->name); temp = players[hv].Find(p); if (!temp) { @@ -736,11 +846,17 @@ void do_identify(char *u) log("Setting data for identified"); #endif user->stats->setData(p->stats); + user->stats->client = user; + updateTS(user->stats); + #ifdef DEBUGMODE - log("Player Identified"); + log("Player %s IRC: %s Identified", user->stats->name, + user->getNick()); #endif + setPlaying(user); // set the playing flag + temp->setPtr(user); notice(s_GameServ, u, "Password Accepted. Identified."); } @@ -753,25 +869,35 @@ void do_stats(char *u) nick = strtok(NULL, " "); - if (!nick) + if (!(user = find(u))) { - if (!(user = find(u))) - { - notice(s_GameServ, u, "Fatal Error in do_stats(). Contact a %S admin for help!"); - log("Error: aClient not found: %s", u); - return; - } - else if (!is_playing(user)) + log("Fatal Error: %s not found in client list", u); + return; + } + else if (isIgnore(user)) + { + #ifdef DEBUGMODE + log("Ignoring %s.", user->getNick()); + #endif + return; + } + else if (!nick) + { + if (!is_playing(user)) { notice(s_GameServ, u, "You're not playing, so you have no stats!"); return; } else + { + updateTS(user->stats); showstats(u, user->stats->name); + } } else showstats(u, nick); } + void init_masters() { #ifdef DEBUGMODE @@ -789,104 +915,104 @@ void init_masters() strcpy(masters[0]->name, "Old Bones"); strcpy(masters[0]->weapon, "Dull Sword Cane"); - masters[0]->strength = 15; + masters[0]->strength = 30; masters[0]->gold = 0; masters[0]->exp = 0; - masters[0]->maxhp = 30; - masters[0]->hp = 30; + masters[0]->maxhp = 35; + masters[0]->hp = 35; strcpy(masters[0]->death, "You have done well my student, but the road is long. Use your new strength with humility and honor as you progress in levels!"); strcpy(masters[1]->name, "Master Chang"); strcpy(masters[1]->weapon, "Nanchaku"); - masters[1]->strength = 30; + masters[1]->strength = 45; masters[1]->gold = 0; masters[1]->exp = 0; - masters[1]->maxhp = 40; - masters[1]->hp = 40; + masters[1]->maxhp = 51; + masters[1]->hp = 51; strcpy(masters[1]->death, "You try to make out what Master Chang is saying, but the only thing you catch is something about a grasshopper."); strcpy(masters[2]->name, "Chuck Norris"); strcpy(masters[2]->weapon, "Ranger Kick"); - masters[2]->strength = 85; + masters[2]->strength = 83; masters[2]->gold = 0; masters[2]->exp = 0; - masters[2]->maxhp = 70; - masters[2]->hp = 70; + masters[2]->maxhp = 100; + masters[2]->hp = 100; strcpy(masters[2]->death, "Be strong, and keep your goals in site. Drink milk, and don't do drugs. One day you may be fighting next to me as a Texas Ranger YEEHAW!"); strcpy(masters[3]->name, "Mr. Miagi"); strcpy(masters[3]->weapon, "Petrified Bonsai"); - masters[3]->strength = 120; + masters[3]->strength = 159; masters[3]->gold = 0; masters[3]->exp = 0; - masters[3]->maxhp = 120; - masters[3]->hp = 120; + masters[3]->maxhp = 165; + masters[3]->hp = 165; strcpy(masters[3]->death, "Skill comes from repeating the correct but seemingly mundane actions. Wax ON, wax OFF!"); strcpy(masters[4]->name, "Jackie Chan"); strcpy(masters[4]->weapon, "Kung Fu Kick"); - masters[4]->strength = 135; + masters[4]->strength = 260; masters[4]->gold = 0; masters[4]->exp = 0; - masters[4]->maxhp = 200; - masters[4]->hp = 200; + masters[4]->maxhp = 232; + masters[4]->hp = 232; strcpy(masters[4]->death, "I like to let people talk who like to talk... it's easier to find out how full of it they really are!"); strcpy(masters[5]->name, "Jet Li"); strcpy(masters[5]->weapon, "Motorcycle"); - masters[5]->strength = 160; + masters[5]->strength = 325; masters[5]->gold = 0; masters[5]->exp = 0; - masters[5]->maxhp = 400; - masters[5]->hp = 400; + masters[5]->maxhp = 504; + masters[5]->hp = 504; strcpy(masters[5]->death, "Failure is a fuel for excuses. It's the doing the do, that makes the making."); strcpy(masters[6]->name, "Muhammad Ali"); strcpy(masters[6]->weapon, "Quick Jab"); - masters[6]->strength = 185; + masters[6]->strength = 380; masters[6]->gold = 0; masters[6]->exp = 0; - masters[6]->maxhp = 600; - masters[6]->hp = 600; + masters[6]->maxhp = 1078; + masters[6]->hp = 1078; strcpy(masters[6]->death, "It's just a job. Grass grows, birds fly, waves pound the sand. I beat people up."); strcpy(masters[7]->name, "Li Mu Bai"); strcpy(masters[7]->weapon, "Green Destiny"); - masters[7]->strength = 210; + masters[7]->strength = 462; masters[7]->gold = 0; masters[7]->exp = 0; - masters[7]->maxhp = 800; - masters[7]->hp = 800; + masters[7]->maxhp = 2207; + masters[7]->hp = 2207; strcpy(masters[7]->death, "No growth without resistance. No action without reaction. No desire without restraint."); strcpy(masters[8]->name, "Jimmy Wang Yu"); strcpy(masters[8]->weapon, "Flying Guillotine"); - masters[8]->strength = 275; + masters[8]->strength = 511; masters[8]->gold = 0; masters[8]->exp = 0; - masters[8]->maxhp = 1200; - masters[8]->hp = 1200; + masters[8]->maxhp = 2780; + masters[8]->hp = 2780; strcpy(masters[8]->death, "You have beaten the one armed boxer. Proceed with caution!"); strcpy(masters[9]->name, "Wong Fei Hung"); strcpy(masters[9]->weapon, "Drunken Boxing"); - masters[9]->strength = 360; + masters[9]->strength = 618; masters[9]->gold = 0; masters[9]->exp = 0; - masters[9]->maxhp = 1800; - masters[9]->hp = 1800; + masters[9]->maxhp = 3046; + masters[9]->hp = 3046; strcpy(masters[9]->death, "Hiccup! Monkey drinks master's wine!"); strcpy(masters[10]->name, "Bruce Lee"); strcpy(masters[10]->weapon, "Fists of fury"); - masters[10]->strength = 575; + masters[10]->strength = 725; masters[10]->gold = 0; masters[10]->exp = 0; - masters[10]->maxhp = 2500; - masters[10]->hp = 2500; + masters[10]->maxhp = 3988; + masters[10]->hp = 3988; strcpy(masters[10]->death, "You must learn to concentrate. It is like a finger pointing away to the moon... DONT concentrate on the finger, or you will miss all the heavenly glory."); } @@ -936,21 +1062,15 @@ void display_monster(char *u) void display_players(char *u) { - if (is_playing(u)) + aClient *user; + if (!(user = find(u))) { - aClient *ni = find(u); - - aClient *battle = ni->stats->battle; - - notice(s_GameServ, u, "Your Hitpoints: %d", ni->stats->hp); - notice(s_GameServ, u, "%s's Hitpoints: %d", battle->stats->name, - battle->stats->hp); - notice(s_GameServ, u, "Here are your commands:"); - notice(s_GameServ, u, "/msg %S attack"); - notice(s_GameServ, u, "/msg %S run"); - notice(s_GameServ, u, "What will you do?"); + log("Fatal error in display_players(): Couldn't find %s", u); } + else + display_players(user); } + void display_players(aClient *user) { char *u = user->getNick(); @@ -971,18 +1091,27 @@ bool is_playing(char *u) { aClient *user; if (!(user = find(u))) - { return false; - } else - { - return user->stats != NULL; - } + return is_playing(user); } bool is_playing(aClient *user) { - return user->stats != NULL && (stricmp(user->getNick(), "!NULL!") != 0); + if (user->stats == NULL) + { + return false; + } + else if (user->stats->client == NULL) + { + return false; + } + else if (!FL_is_playing(user)) + { + return false; + } + else + return true; } bool is_fighting(char *u) @@ -990,23 +1119,17 @@ bool is_fighting(char *u) aClient *user; if (!(user = find(u))) - { return false; - } - else if (user->stats) - { - return user->stats->fight != NULL || user->stats->battle != NULL - || user->stats->master != NULL; - } else - return false; + return is_fighting(user); } + bool is_fighting(aClient *user) { if (!is_playing(user)) return false; else - return (user->stats->fight != NULL || user->stats->battle != NULL || user->stats->master != NULL); + return player_fight(user) || master_fight(user) || user->stats->fight != NULL; } bool player_fight(char *u) @@ -1015,14 +1138,13 @@ bool player_fight(char *u) if (!(user = find(u))) return false; - else if (user->stats) - return user->stats->battle != NULL; - else - return false; + else + return player_fight(user); } + bool player_fight(aClient *user) { - if (!is_fighting(user)) + if (!is_playing(user)) return false; else return user->stats->battle != NULL; @@ -1034,11 +1156,10 @@ bool master_fight(char *u) if (!(user = find(u))) return false; - else if (user->stats) - return user->stats->master != NULL; else - return false; + return master_fight(user); } + bool master_fight(aClient *user) { if (!is_playing(user)) @@ -1056,16 +1177,29 @@ void do_fight(char *u) if (!nick) { notice(s_GameServ, u, "SYNTAX: /msg %S FIGHT PLAYER"); + return; } else if (!(ni = find(u))) { notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, "")); + return; + } + else if (isIgnore(ni)) + { + #ifdef DEBUGMODE + log("Ignoring %s.", ni->getNick()); + #endif + return; } else if (!is_playing(ni)) { notice(s_GameServ, u, "You are not playing!"); + return; } - else if (ni->stats->player_fights <= 0) + + updateTS(ni->stats); + + if (ni->stats->player_fights <= 0) { ni->stats->player_fights = 0; // just to be safe notice(s_GameServ, u, "You are out of player fights for the "\ @@ -1075,6 +1209,10 @@ void do_fight(char *u) { notice(s_GameServ, u, "Player %s not found!", nick); } + else if (!isAlive(ni->stats)) + { + notice(s_GameServ, u, "You are dead. Wait until tomorrow to fight others!"); + } else if (!is_playing(battle)) { notice(s_GameServ, u, "You can't attack %s while they aren't playing!", nick); @@ -1092,10 +1230,6 @@ void do_fight(char *u) * display_players(u); * } */ - else if (!isAlive(ni->stats)) - { - notice(s_GameServ, u, "You are dead. Wait until tomorrow to fight others!"); - } else if (stricmp(ni->stats->name, battle->stats->name) == 0) { notice(s_GameServ, u, "Are you trying to commit suicide!?"); @@ -1108,6 +1242,10 @@ void do_fight(char *u) { notice(s_GameServ, u, "%s is fighting %s already!", battle->stats->name, battle->stats->battle->stats->name); } + else if (master_fight(battle)) + { + notice(s_GameServ, u, "%s is fighting their master!", battle->stats->name); + } else if (is_fighting(battle)) { notice(s_GameServ, u, "%s is fighting %s already!", battle->stats->name, battle->stats->fight->name); @@ -1117,7 +1255,7 @@ void do_fight(char *u) // You can't fight someone below you by more than X level(s) // level 12 can fight level (12 - X) but not < (12 - X) notice(s_GameServ, u, "You may not fight %s. You're too strong!", - battle->stats->level); + battle->stats->name); } else if (battle->stats->level - ni->stats->level > maxafightdistance) { @@ -1132,7 +1270,7 @@ void do_fight(char *u) ni->stats->battle = battle; // Set the other player's battle pointer to you - battle->stats->battle = ni; + ni->stats->battle->stats->battle = ni; // The initiator gets the first move (perhaps this should be 50/50) setYourTurn(ni->stats); @@ -1146,9 +1284,10 @@ void do_fight(char *u) notice(s_GameServ, battle->getNick(), "%s gets to go first "\ "because they initiated!", ni->stats->name); notice(s_GameServ, battle->getNick(), "Please wait while %s decides what to do.", ni->stats->name); - display_players(u); + display_players(ni); } } + void do_use(char *u) { aClient *user; @@ -1167,12 +1306,21 @@ void do_use(char *u) notice(s_GameServ, u, "Fatal Error in do_use. Contact a(n) %S Admin"); return; } + else if (isIgnore(user)) + { + #ifdef DEBUGMODE + log("Ignoring %s.", user->getNick()); + #endif + return; + } else if (!is_playing(user)) { notice(s_GameServ, u, "You must be playing to use items!"); return; } + updateTS(user->stats); + p = &user->stats->inventory; if (stricmp(item, "HEALTH") == 0) @@ -1199,7 +1347,7 @@ void do_use(char *u) int oldstrength = user->stats->strength; notice(s_GameServ, u, "As you grip the flask containing pure power, you feel adrenaline coarse through your veins!"); notice(s_GameServ, u, "In one swallow you drink the potion and feel your muscle fibers bulging andgrowing!"); - user->stats->strength += 1 + rand() % 2; // 1 - 2 Strength Added + user->stats->strength += 1 + (rand() % 10 >= 8 ? 1 : 0); // 1-2 notice(s_GameServ, u, "You gain %d Strength points!", user->stats->strength - oldstrength); p->decStrength(); } @@ -1213,7 +1361,7 @@ void do_use(char *u) int olddefense = user->stats->defense; notice(s_GameServ, u, "You drink the foul tasting viscous liquid while pinching your nose in disgust."); notice(s_GameServ, u, "It tasted bad, but you feel like you are unbeatable!"); - user->stats->defense += 1 + rand() % 2; // 1 - 2 Defense Added + user->stats->defense += 1 + (rand() % 10 >= 8 ? 1 : 0); // 1-2 notice(s_GameServ, u, "You gain %d Defense points!", user->stats->defense - olddefense); p->decDefense(); } @@ -1226,7 +1374,9 @@ void do_use(char *u) } int oldHP = user->stats->maxhp; notice(s_GameServ, u, "You feel your life growing longer as you drink the green glowing liquid."); - user->stats->maxhp += 1 + rand() % 5; // 1 - 5 Maxhp + user->stats->maxhp += 2 + + (rand() % 100 > 70 ? (rand() % 7) : (rand() % 2) ); + notice(s_GameServ, u, "You gain %d Maximum hit points!", user->stats->maxhp - oldHP); p->decHP(); } @@ -1248,13 +1398,20 @@ void do_run(char *u) notice(s_GameServ, u, "Couldn't find you. Error. Contact a %S admin"); return; } - + else if (isIgnore(user)) + { + #ifdef DEBUGMODE + log("Ignoring %s.", user->getNick()); + #endif + return; + } else if (!is_playing(user)) { notice(s_GameServ, u, "You must be playing to run!"); return; } + updateTS(user->stats); p = user->stats; if (p->battle) @@ -1379,6 +1536,13 @@ void do_attack(char *u) notice(s_GameServ, u, "Fatal error in do_attack. Contact a(n) %S admin for help."); return; } + else if (isIgnore(ni)) + { + #ifdef DEBUGMODE + log("Ignoring %s.", ni->getNick()); + #endif + return; + } else if (!is_playing(ni)) { notice(s_GameServ, u, "You're not playing!"); @@ -1401,6 +1565,7 @@ void do_attack(char *u) // One has to be !NULL based on the previous else if // We wouldn't be here if they were all NULL } + updateTS(ni->stats); if (!player_fight(ni)) { @@ -1633,7 +1798,7 @@ void do_attack(char *u) weapons[ni->stats->weapon], hit); clearYourTurn(ni->stats); setYourTurn(battle->stats); - display_players(battle->getNick()); + display_players(battle); } else { @@ -1641,7 +1806,7 @@ void do_attack(char *u) notice(s_GameServ, battle->getNick(), "%s misses you completely!", ni->stats->name); clearYourTurn(ni->stats); setYourTurn(battle->stats); - display_players(battle->getNick()); + display_players(battle); } if (hit >= battle->stats->hp) { @@ -1712,12 +1877,20 @@ void do_heal(char *u) if (!amount) { notice(s_GameServ, u, "SYNTAX: /msg %S HEAL {ALL | #}"); + return; } else if (!(ni = find(u))) { notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, "")); return; } + else if (isIgnore(ni)) + { + #ifdef DEBUGMODE + log("Ignoring %s.", ni->getNick()); + #endif + return; + } else if (!is_playing(ni)) { notice(s_GameServ, u, "You aren't playing!"); @@ -1731,12 +1904,16 @@ void do_heal(char *u) else if (is_fighting(ni)) { notice(s_GameServ, u, "You can't heal in battle!"); + return; } else if (ni->stats->hp >= ni->stats->maxhp) { notice(s_GameServ, u, "You don't need healing!"); + return; } - else if (stricmp(amount, "ALL") == 0) + + updateTS(ni->stats); + if (stricmp(amount, "ALL") == 0) { price = ni->stats->level * 3; if (ni->stats->gold < (ni->stats->maxhp - ni->stats->hp) * price) @@ -1855,6 +2032,7 @@ int save_gs_dbase() while(ptr) { it = ptr->getData()->stats; + clearYourTurn(it); outfile << it->name << ' ' << it->level << ' ' << it->exp << ' ' << it->gold << ' ' << it->bank << ' ' << it->hp << ' ' << it->maxhp << ' ' << it->strength << ' ' << it->defense << ' ' << it->armor << ' ' << it->weapon << ' ' @@ -1907,9 +2085,9 @@ int load_gs_dbase() password = strtok(NULL, " "); strcpy(p->password, password); - temp->setNick("!NULL!"); + temp->setNick("Not Playing"); #ifdef P10 - temp->setRealNick("!NULL!"); + temp->setRealNick("Not Playing"); #endif p->inventory.reset(); // Set inventory to all 0s @@ -1931,8 +2109,9 @@ int load_gs_dbase() tempname = strtok(NULL, " "); if (tempname) p->inventory.setHP(stringtoint(tempname)); - temp->stats->user = NULL; - unsigned long hv = HASH((unsigned char *) temp->stats->name, U_TABLE_SIZE); + unsigned long hv = iHASH((unsigned char *) temp->stats->name); + + temp->stats->client = NULL; players[hv].insertAtBack(temp); delete temp; } @@ -1990,15 +2169,33 @@ void do_store(char *u) notice(s_GameServ, u, "SYNTAX: STORE LIST {ARMOR | WEAPONS}"); notice(s_GameServ, u, " STORE SELL {ARMOR | WEAPON}"); notice(s_GameServ, u, " STORE BUY {ARMOR | WEAPON} NUMBER"); + return; + } + else if (!(user = find(u))) + { + log("Fatal Error: could not find %s in client list", u); + return; + } + else if (isIgnore(user)) + { + #ifdef DEBUGMODE + log("Ignoring %s.", user->getNick()); + #endif + return; } - else if (!(user = find(u)) || !is_playing(user)) + else if (!is_playing(user)) + { notice(s_GameServ, u, "You must be playing to use the store!"); + return; + } else if (!isAlive(user->stats)) { notice(s_GameServ, u, "You are dead. Wait until tomorrow to purchase weapons and armor!"); return; } - else if (stricmp(cmd, "LIST") == 0) + updateTS(user->stats); + + if (stricmp(cmd, "LIST") == 0) { if (stricmp(item, "WEAPONS") == 0) { @@ -2152,6 +2349,13 @@ void do_store(char *u) notice(s_GameServ, u, " STORE BUY {ARMOR | WEAPON} NUMBER"); } } + else + { + notice(s_GameServ, u, "SYNTAX: STORE LIST {ARMOR | WEAPONS}"); + notice(s_GameServ, u, " STORE SELL {ARMOR | WEAPON}"); + notice(s_GameServ, u, " STORE BUY {ARMOR | WEAPON} NUMBER"); + return; + } } void do_inventory(char *u) { @@ -2162,11 +2366,19 @@ void do_inventory(char *u) notice(s_GameServ, u, "Fatal Error. Contact a %S admin!"); return; } + else if (isIgnore(user)) + { + #ifdef DEBUGMODE + log("Ignoring %s.", user->getNick()); + #endif + return; + } else if (!is_playing(user)) { notice(s_GameServ, u, "You must be playing to check your inventory!"); return; } + updateTS(user->stats); showinventory(user, user); } void showinventory(aClient *from, aClient *to) @@ -2197,6 +2409,13 @@ void do_tavern(char *u) notice(s_GameServ, u, "Fatal Error. See a %S admin for help"); return; } + else if (isIgnore(user)) + { + #ifdef DEBUGMODE + log("Ignoring %s.", user->getNick()); + #endif + return; + } else if (!is_playing(user)) { notice(s_GameServ, u, "You must be playing to go to the Tavern"); @@ -2207,7 +2426,10 @@ void do_tavern(char *u) notice(s_GameServ, u, "You cannot go to the Tavern during a fight!"); return; } + + updateTS(user->stats); p = user->stats; + if (!cmd) { notice(s_GameServ, u, "Welcome to Boot Liquors Mystic Apothecary"); @@ -2218,10 +2440,10 @@ void do_tavern(char *u) else if (stricmp(cmd, "LIST") == 0) { notice(s_GameServ, u, "Here is a list of what we have to offer:"); - notice(s_GameServ, u, "1. Healing Potions for %ld Gold", 1000 * p->level + (p->exp / 10)); - notice(s_GameServ, u, "2. Strength Potions for %ld Gold", 2050 * p->level + (p->exp / 10)); - notice(s_GameServ, u, "3. Defense Potions for %ld Gold", 2000 * p->level + (p->exp / 10)); - notice(s_GameServ, u, "4. HP Potions for %ld Gold", 2300 * p->level + (p->exp / 10)); + notice(s_GameServ, u, "1. Healing Potions for %ld Gold", 100 * p->level + (p->exp / 10)); + notice(s_GameServ, u, "2. Strength Potions for %ld Gold", 205 * p->level + (p->exp / 10)); + notice(s_GameServ, u, "3. Defense Potions for %ld Gold", 200 * p->level + (p->exp / 10)); + notice(s_GameServ, u, "4. HP Potions for %ld Gold", 230 * p->level + (p->exp / 10)); notice(s_GameServ, u, "To buy a potion, type /msg %S TAVERN BUY #"); notice(s_GameServ, u, "Example: /msg %S TAVERN BUY 1 buys a healing potion!"); notice(s_GameServ, u, "By something will ya!"); @@ -2241,10 +2463,10 @@ void do_tavern(char *u) { notice(s_GameServ, u, "Invalid Choice!"); notice(s_GameServ, u, "Here is a list of what we have to offer:"); - notice(s_GameServ, u, "1. Healing Potions for %ld Gold", 1000 * p->level + (p->exp / 10)); - notice(s_GameServ, u, "2. Strength Potions for %ld Gold", 2050 * p->level + (p->exp / 10)); - notice(s_GameServ, u, "3. Defense Potions for %ld Gold", 2000 * p->level + (p->exp / 10)); - notice(s_GameServ, u, "4. HP Potions for %ld Gold", 2300 * p->level + (p->exp / 10)); + notice(s_GameServ, u, "1. Healing Potions for %ld Gold", 100 * p->level + (p->exp / 10)); + notice(s_GameServ, u, "2. Strength Potions for %ld Gold", 205 * p->level + (p->exp / 10)); + notice(s_GameServ, u, "3. Defense Potions for %ld Gold", 200 * p->level + (p->exp / 10)); + notice(s_GameServ, u, "4. HP Potions for %ld Gold", 230 * p->level + (p->exp / 10)); notice(s_GameServ, u, "To buy a potion, type /msg %S TAVERN BUY #"); notice(s_GameServ, u, "Example: /msg %S TAVERN BUY 1 buys a healing potion!"); return; @@ -2252,7 +2474,7 @@ void do_tavern(char *u) switch(num) { case 1: - price = (1000 * p->level) + (p->exp / 10); + price = (100 * p->level) + (p->exp / 10); if (p->gold >= price) { notice(s_GameServ, u, "One healing potion coming right up!"); @@ -2263,7 +2485,7 @@ void do_tavern(char *u) notice(s_GameServ, u, "You don't have enough gold!"); break; case 2: - price = (2050 * p->level) + (p->exp / 10); + price = (205 * p->level) + (p->exp / 10); if (p->gold >= price) { notice(s_GameServ, u, "One strength boost coming right up!"); @@ -2274,7 +2496,7 @@ void do_tavern(char *u) notice(s_GameServ, u, "You don't have enough gold!"); break; case 3: - price = (2000 * p->level) + (p->exp / 10); + price = (200 * p->level) + (p->exp / 10); if (p->gold >= price) { notice(s_GameServ, u, "One defense boost coming right up!"); @@ -2285,7 +2507,7 @@ void do_tavern(char *u) notice(s_GameServ, u, "You don't have enough gold!"); break; case 4: - price = (2300 * p->level) + (p->exp / 10); + price = (230 * p->level) + (p->exp / 10); if (p->gold >= price) { notice(s_GameServ, u, "One HP Potion coming right up!"); @@ -2322,14 +2544,28 @@ void do_bank(char *u) notice (s_GameServ, u, "BANK BALANCE"); return; } - - user = find(u); - if (!is_playing(user)) + else if (!(user = find(u))) + { + notice(s_GameServ, u, "Fatal Error. Couldn't find your aClient. Contact a(n) %S "\ + " admin for help"); + log("Fatal Error. Couldn't find %s while executing do_bank()", u); + return; + } + else if (isIgnore(user)) + { + #ifdef DEBUGMODE + log("Ignoring %s.", user->getNick()); + #endif + return; + } + else if (!is_playing(user)) { notice(s_GameServ, u, "You must be playing to use the bank!"); return; } - else if (stricmp(cmd, "BALANCE") == 0) + + updateTS(user->stats); + if (stricmp(cmd, "BALANCE") == 0) { showBankBalance(u); return; @@ -2455,13 +2691,25 @@ void do_bank(char *u) void do_master(char *u) { aClient *user; - user = find(u); - if (!user) + + if (!(user = find(u))) { notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, "")); return; } + else if (isIgnore(user)) + { + #ifdef DEBUGMODE + log("Ignoring %s.", user->getNick()); + #endif + return; + } + else if (!is_playing(user)) + { + notice(s_GameServ, u, "You must be playing to see your master!"); + return; + } else if (is_fighting(user)) { notice(s_GameServ, u, "You're in the middle of a fight! Pay attention!"); @@ -2472,12 +2720,9 @@ void do_master(char *u) notice(s_GameServ, u, "You're dead. Wait until tomorrow to see your master!"); return; } - else if (!is_playing(user)) - { - notice(s_GameServ, u, "You must be playing to see your master!"); - return; - } - + + updateTS(user->stats); + char *cmd = strtok(NULL, " "); Player *p = user->stats; long int need = 0; @@ -2643,6 +2888,13 @@ void do_refresh(char *u) log("Error: aClient not found: %s", u); return; } + else if (isIgnore(user)) + { + #ifdef DEBUGMODE + log("Ignoring %s.", user->getNick()); + #endif + return; + } else if (!isAdmin(user)) { notice(s_GameServ, u, "You must be a %S admin to use this command!"); @@ -2658,7 +2910,7 @@ void do_refresh(char *u) notice(s_GameServ, u, "Refreshing everyone's stats!"); refreshall(); } - else if ((user = findbyrealnick(nick))) + else if ((user = findplayer(nick))) { if (is_playing(user)) { @@ -2712,6 +2964,132 @@ void reset(Player *p) p->reset(); } +void updateTS(Player *p) +{ + if (!p) + return; + + #ifdef DEBUGMODE + log("Old timestamp for %s: %ld", p->name, p->lastcommand); + #endif + p->lastcommand = time(NULL); + #ifdef DEBUGMODE + log("New timestamp for %s: %ld", p->name, p->lastcommand); + #endif + +} + +bool timedOut(Player *p) +{ + if (!p) + return false; + else if (p->lastcommand == 0) + return false; + else + { + if ((time(NULL) - p->lastcommand) >= maxidletime) + return true; + + return false; + } +} + +void timeOutEvent(Player *p) +{ + aClient *user = findplayer(p->name); + + if (!user || !p->client) // then they're not playing + return; + + char *nick = user->getNick(); + + if (player_fight(user) && isYourTurn(p)) + { + // Check to see if they were the idler or if it was the other + // person + if (p->lastcommand != p->battle->stats->lastcommand) + { + // This person's last command was given earlier, + // so this person is the idler + notice(s_GameServ, nick, "You timed out "\ + "during a fight. You lose your turn!"); + notice(s_GameServ, p->battle->getNick(), + "%s hesitated for too long. Your move.", p->name); + clearYourTurn(p); + setYourTurn(p->battle->stats); + + // Update the TS for both players to give them another + // Chance to wake up, but if the other player doesn't + // Attack now, they both get logged out. + updateTS(p); + p->battle->stats->lastcommand = p->lastcommand; + display_players(p->battle); + return; + } + else + { + notice(s_GameServ, p->battle->getNick(), + "You and %s timed out at the same time."\ + " Don't fight if you're just going to "\ + "sit there!", p->name); + notice(s_GameServ, user->getNick(), + "You and %s timed out at the same time."\ + " Don't fight if you're just going to "\ + "sit there!", p->battle->stats->name); + logout(p->battle); + logout(user); + return; + } + } + else if (!player_fight(user)) + { + if (isAlive(user->stats) && user->stats->gold > 0) + { + // Place fun stuff here :) + int randnum = 1 + rand() % 100; // 1-100 + #define GSN(s) notice(s_GameServ, nick, s) + #define GSN2(s, f) notice(s_GameServ, nick, s, f) + + if (randnum < 50) + { + // 35-100% of your gold goes pffft - kain + int stolen = (35 + (rand() % 66)) * user->stats->gold / 100; + + GSN("You stop for a moment to rest on the "\ + "street corner. All of a sudden, you "\ + "are ambushed from all sides by a hoarde "\ + "of knife wielding thugs."); + GSN2("The thugs beat you into utter submission "\ + "and steal %d gold from you!", stolen); + user->stats->gold -= stolen; + } + else if (randnum >= 50 && randnum < 75) + { + // 25-65% of your gold goes pffft - kain + int stolen = (25 + (rand() % 41)) * user->stats->gold / 100; + GSN("While dilly dallying around, you lose "\ + "your sense of time. Little did you know, "\ + "but thieves lifted your gold while you "\ + "weren't watching."); + GSN2("Better luck next time... you lose %d gold", stolen); + user->stats->gold -= stolen; + } + else if (randnum >= 75) + { + // 25-75% of your gold goes pffft - kain + int stolen = (25 + (rand() % 51)) * user->stats->gold / 100; + GSN("Good grief! A gaggle of gooey green ghostlike "\ + "goblins grabbed your gold!"); + GSN2("They stole %d gold from you!", stolen); + user->stats->gold -= stolen; + } + } + + // Always log out the user + logout(user); + } +} + void do_reset(char *u) { char *nick = strtok(NULL, " "); @@ -2728,6 +3106,7 @@ void do_reset(char *u) notice(s_GameServ, u, "You must be a %S admin to use this command!"); return; } + if (!nick) { notice(s_GameServ, u, "SYNTAX: RESET {ALL | NICK}"); @@ -2839,6 +3218,7 @@ void do_admin(char *u) notice(s_GameServ, u, "Error: aClient not found. Contact %S admin."); return; } + if (!pass) { notice(s_GameServ, u, "SYNTAX: ADMIN password"); @@ -2913,22 +3293,32 @@ return true; // this will be hash.cpp start // thank you wcampbel -unsigned long HASH(const unsigned char *name, int size_of_table) +unsigned long sHASH(const unsigned char *name) { unsigned long h = 0, g; while (*name) { - #ifdef P10 - h = (h << 4) + (*name++); // Case sensitive for numerics - #else - h = (h << 4) + tolower(*name++); - #endif + h = (h << 4) + (*name++); // Case sensitive for numerics + if ((g = (h & 0xF0000000))) + h ^= g >> 24; + h &= ~g; + } + return h % U_TABLE_SIZE; +} + +unsigned long iHASH(const unsigned char *name) +{ + unsigned long h = 0, g; + + while (*name) + { + h = (h << 4) + tolower(*name++); if ((g = (h & 0xF0000000))) h ^= g >> 24; h &= ~g; } - return h % size_of_table; + return h % U_TABLE_SIZE; } // this will be hash.cpp end