X-Git-Url: https://jfr.im/git/irc/gameservirc.git/blobdiff_plain/a3017ab1ff5714f9f8b0f10197f1d5677993a037..903cd8615208a3e02ac9efbd881d73c409f996e2:/gameserv/gameserv.cpp diff --git a/gameserv/gameserv.cpp b/gameserv/gameserv.cpp index fb61334..1929a2f 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++) @@ -576,6 +632,13 @@ void do_logout(char *u) log("Could not find aClient Buf: %s LOGOUT", u); } + else if (isIgnore(user)) + { + #ifdef DEBUGMODE + log("Ignoring %s.", user->getNick()); + #endif + return; + } else if (!is_playing(user)) { notice(s_GameServ, u, "You're not logged in!"); @@ -590,15 +653,16 @@ void do_logout(char *u) 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 +680,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 +704,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 +734,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)) { - p = findplayer(u); - if (!user->stats && !p) + #ifdef DEBUGMODE + log("Ignoring %s.", user->getNick()); + #endif + return; + } + else + { + 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 +778,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 +810,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 +823,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 +846,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,7 +892,7 @@ void init_masters() strcpy(masters[0]->name, "Old Bones"); strcpy(masters[0]->weapon, "Dull Sword Cane"); - masters[0]->strength = 15; + masters[0]->strength = 25; masters[0]->gold = 0; masters[0]->exp = 0; masters[0]->maxhp = 30; @@ -798,7 +901,7 @@ void init_masters() strcpy(masters[1]->name, "Master Chang"); strcpy(masters[1]->weapon, "Nanchaku"); - masters[1]->strength = 30; + masters[1]->strength = 35; masters[1]->gold = 0; masters[1]->exp = 0; masters[1]->maxhp = 40; @@ -807,7 +910,7 @@ void init_masters() strcpy(masters[2]->name, "Chuck Norris"); strcpy(masters[2]->weapon, "Ranger Kick"); - masters[2]->strength = 85; + masters[2]->strength = 95; masters[2]->gold = 0; masters[2]->exp = 0; masters[2]->maxhp = 70; @@ -817,7 +920,7 @@ void init_masters() strcpy(masters[3]->name, "Mr. Miagi"); strcpy(masters[3]->weapon, "Petrified Bonsai"); - masters[3]->strength = 120; + masters[3]->strength = 130; masters[3]->gold = 0; masters[3]->exp = 0; masters[3]->maxhp = 120; @@ -826,7 +929,7 @@ void init_masters() strcpy(masters[4]->name, "Jackie Chan"); strcpy(masters[4]->weapon, "Kung Fu Kick"); - masters[4]->strength = 135; + masters[4]->strength = 156; masters[4]->gold = 0; masters[4]->exp = 0; masters[4]->maxhp = 200; @@ -835,7 +938,7 @@ void init_masters() strcpy(masters[5]->name, "Jet Li"); strcpy(masters[5]->weapon, "Motorcycle"); - masters[5]->strength = 160; + masters[5]->strength = 180; masters[5]->gold = 0; masters[5]->exp = 0; masters[5]->maxhp = 400; @@ -845,7 +948,7 @@ void init_masters() strcpy(masters[6]->name, "Muhammad Ali"); strcpy(masters[6]->weapon, "Quick Jab"); - masters[6]->strength = 185; + masters[6]->strength = 200; masters[6]->gold = 0; masters[6]->exp = 0; masters[6]->maxhp = 600; @@ -854,7 +957,7 @@ void init_masters() strcpy(masters[7]->name, "Li Mu Bai"); strcpy(masters[7]->weapon, "Green Destiny"); - masters[7]->strength = 210; + masters[7]->strength = 225; masters[7]->gold = 0; masters[7]->exp = 0; masters[7]->maxhp = 800; @@ -864,7 +967,7 @@ void init_masters() strcpy(masters[8]->name, "Jimmy Wang Yu"); strcpy(masters[8]->weapon, "Flying Guillotine"); - masters[8]->strength = 275; + masters[8]->strength = 290; masters[8]->gold = 0; masters[8]->exp = 0; masters[8]->maxhp = 1200; @@ -873,7 +976,7 @@ void init_masters() strcpy(masters[9]->name, "Wong Fei Hung"); strcpy(masters[9]->weapon, "Drunken Boxing"); - masters[9]->strength = 360; + masters[9]->strength = 385; masters[9]->gold = 0; masters[9]->exp = 0; masters[9]->maxhp = 1800; @@ -882,7 +985,7 @@ void init_masters() strcpy(masters[10]->name, "Bruce Lee"); strcpy(masters[10]->weapon, "Fists of fury"); - masters[10]->strength = 575; + masters[10]->strength = 600; masters[10]->gold = 0; masters[10]->exp = 0; masters[10]->maxhp = 2500; @@ -936,21 +1039,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 +1068,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 +1096,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 +1115,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 +1133,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 +1154,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 +1186,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 +1207,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 +1219,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 +1232,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 +1247,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 +1261,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 +1283,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 +1324,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 +1338,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 +1351,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 +1375,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 +1513,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 +1542,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 +1775,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 +1783,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 +1854,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 +1881,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 +2009,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 +2062,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 +2086,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 +2146,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 (!(user = find(u)) || !is_playing(user)) + 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 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) { @@ -2162,11 +2336,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 +2379,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 +2396,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 +2410,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 +2433,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 +2444,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 +2455,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 +2466,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 +2477,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 +2514,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 +2661,20 @@ 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_fighting(user)) { notice(s_GameServ, u, "You're in the middle of a fight! Pay attention!"); @@ -2477,7 +2690,8 @@ void do_master(char *u) 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 +2857,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 +2879,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 +2933,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) && 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 +3075,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 +3187,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 +3262,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