X-Git-Url: https://jfr.im/git/irc/gameservirc.git/blobdiff_plain/7031d99e6b340e812ee4bd73c4b39e96ee8cd3c4..05c527e6933d9fcf1d8b6ddba59b9b81baa6afa9:/gameserv/gameserv.cpp diff --git a/gameserv/gameserv.cpp b/gameserv/gameserv.cpp index 5c03a59..2239ce7 100644 --- a/gameserv/gameserv.cpp +++ b/gameserv/gameserv.cpp @@ -21,18 +21,15 @@ using std::ofstream; #endif -List players; +// this will be hash.cpp start +// thank you wcampbel +unsigned long HASH(const unsigned char *name, int size_of_table); +List players[U_TABLE_SIZE]; +// this will be hash.cpp end + Monster *monsters[LEVELS][MONSTERS]; // Monsters per level. Total = MONSTERS * LEVELS Monster boss; // The boss monster -strcpy(boss.name, "Red Dragon"); -strcpy(boss.weapon, "Breath of Unholy Fire"); -boss.strength = 6667; -boss.gold = 2000000000; -boss.exp = 2000000000; -strcpy(boss.death, "You finally snuff out the deadly murderous \" - "dragon's dark flames. You have freed the land of its terror \" - "filled reign from above!"); Monster *masters[LEVELS]; // A master for each level @@ -49,7 +46,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 @@ -61,6 +57,7 @@ bool check_password(char *name, char *plaintext); // Finds a password for the gi /********** GameServ Booleans **********/ +bool shuttingdown; bool is_playing(char *u); // True if the given nickname in the clients list is playing. bool is_playing(aClient *user); @@ -105,6 +102,7 @@ void do_inventory(char *u); void do_refresh(char *u); void do_register(char *u); void do_list(char *u); +void do_logout(char *u); void do_master(char *u); void do_play(char *u); void do_quitg(char *u); @@ -116,6 +114,7 @@ void do_tavern(char *u); void do_use(char *u); void see_master(char *u); +void logout(aClient *user); void showstats(const char *u, const char *nick); void showinventory(aClient *from, aClient *to); void showBankBalance(const char *u); @@ -134,8 +133,8 @@ char *armors[WNA] = { "Nothing", "Clothes", "Leather Vest", "Chain Mail", "Plate int prices[WNA - 1] = {200, 1000, 3000, 10000, 30000, 100000, 150000, 200000, 400000, 1000000, 4000000, 10000000, 40000000, 100000000, 400000000}; -int webonus[WNA] = {0, 10, 15, 25, 35, 45, 65, 85, 125, 185, 255, 355, 505, 805, 1205, 1805}; -int arbonus[WNA] = {0, 1, 3, 10, 15, 25, 35, 50, 75, 100, 150, 225, 300, 400, 600, 1000}; +int webonus[WNA] = {1, 10, 15, 25, 35, 45, 65, 85, 125, 185, 255, 355, 505, 805, 1205, 1805}; +int arbonus[WNA] = {1, 2, 4, 10, 15, 25, 35, 50, 75, 100, 150, 225, 300, 400, 600, 1000}; int hpbonus[11] = {10, 15, 20, 30, 50, 75, 125, 185, 250, 350, 550}; int strbonus[11] = {5, 7, 10, 12, 20, 35, 50, 75, 110, 150, 200}; @@ -168,7 +167,7 @@ void gameserv(char *source, char *buf) { refreshall(); day = curday; - save_day(); + save_day(); // here i come to save the day! } if (strnicmp(cmd, "\1PING", 6) == 0) @@ -177,7 +176,7 @@ void gameserv(char *source, char *buf) ts = strtok(NULL, "\1"); notice(s_GameServ, source, "\1PING %s\1", ts); } else if (stricmp(cmd, "\1VERSION\1") == 0) { - notice(s_GameServ, source, "\1VERSION %s %s +devel\1", PACKAGE, VERSION); + notice(s_GameServ, source, "\1VERSION %s %s\1", PACKAGE, VERSION); } else if (stricmp(cmd, "SEARCH") == 0) { cmd = strtok(NULL, " "); @@ -214,13 +213,8 @@ void gameserv(char *source, char *buf) do_tavern(source); } else if (stricmp(cmd, "LIST") == 0) { do_list(source); - #ifdef DEBUGMODE - } else if (stricmp(cmd, "PRINT") == 0) { - cout << "Printing the clients list:" << endl; - clients.print(); - cout << "\nPrinting the players list:" << endl; - players.print(); - #endif + } else if (stricmp(cmd, "LOGOUT") == 0) { + do_logout(source); } else if (stricmp(cmd, "REGISTER") == 0) { do_register(source); } else if (stricmp(cmd, "IDENTIFY") == 0) { @@ -249,6 +243,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; @@ -294,6 +289,7 @@ void gameserv(char *source, char *buf) else display_help(source, cmd); } + #ifdef DEBUGMODE } else if (stricmp(cmd, "RAW") == 0) { aClient *user; @@ -311,6 +307,7 @@ void gameserv(char *source, char *buf) char *rest = strtok(NULL, ""); raw("%s", rest); } + #endif } else { notice(s_GameServ, source, "Unknown command \002%s\002. Type /msg %S \002HELP\002 to get a list of commands.", cmd); } @@ -538,13 +535,19 @@ char *strtok(char *str, const char *delim) void do_list(char *u) { ListNode *temp; - temp = players.First(); - if (!players.isEmpty()) + bool header = false; + for (unsigned long x = 0; x < U_TABLE_SIZE; x++) + { + temp = players[x].First(); + if (!players[x].isEmpty()) { - notice(s_GameServ, u, "People Playing:"); + if (!header) + { + notice(s_GameServ, u, "People Playing:"); + header = true; + } while(temp) { - #ifdef P10 notice(s_GameServ, u, "IRC: %s Game: %s", temp->getData()->getRealNick(), temp->getData()->stats->name); @@ -555,12 +558,90 @@ void do_list(char *u) temp = temp->Next(); } + } + } + if (!header) + notice(s_GameServ, u, "No one is playing"); + else notice(s_GameServ, u, "End of List"); + +} + +void do_logout(char *u) +{ + aClient *user; + 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); + } + else 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, "No one is playing"); + { + 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); + it = players[hv].Find(user); + if (!it) + { + notice(s_GameServ, user->getNick(), "Fatal error. Contact "\ + "%S Admin. Cannot find you in the players list."); + log("Error on logout(). Can't find %s in the players list", + #ifdef P10 + user->getRealNick() + #else + user->getNick() + #endif + ); + return; + } + + temp = new aClient; + temp->stats = new Player; + temp->stats->setData(user->stats); + user->stats->user = NULL; + if (player_fight(user)) + user->stats->battle->stats->battle = NULL; + + delete user->stats; + user->stats = NULL; + temp->stats->user = NULL; + #ifdef P10 + temp->setRealNick("!NULL!"); + #endif + temp->setNick("!NULL!"); + + it->setNewPtr(temp); + #ifdef DEBUGMODE + log("Logged out player %s", + #ifdef P10 + user->getRealNick() + #else + user->getNick() + #endif + ); + #endif + } +} void do_register(char *u) { char *password, *name; @@ -583,6 +664,11 @@ void do_register(char *u) { notice(s_GameServ, u, "SYNTAX: /msg %S REGISTER NAME PASSWORD"); } + else if ((user = findplayer(name))) + { + notice(s_GameServ, u, "%s is already registered!", name); + notice(s_GameServ, u, "Choose another name!"); + } else if ((user = find(u))) { p = findplayer(u); @@ -592,7 +678,8 @@ void do_register(char *u) user->stats->user = user; // Set the backwards pointer strcpy(user->stats->password, crypt(password, salt)); strcpy(user->stats->name, name); - players.insertAtBack(user); + unsigned long hv = HASH((unsigned char *) name, U_TABLE_SIZE); + players[hv].insertAtBack(user); 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); @@ -622,46 +709,41 @@ void do_identify(char *u) } 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)) + { + notice(s_GameServ, u, "That player has already identified."); + } else if (!check_password(name, password) && !isAdmin(user)) { notice(s_GameServ, u, "Password incorrect"); } - else - { - if (p->stats->user && !isAdmin(user)) + else { + ListNode *temp; + unsigned long hv = HASH((unsigned char *) p->stats->name, + U_TABLE_SIZE); + temp = players[hv].Find(p); + if (!temp) { - notice(s_GameServ, u, "That player has already identified."); + notice(s_GameServ, u, "Fatal error. Contact %S Admin. Buf: %s", + strtok(NULL, "")); return; } - if (!user->stats) - { - ListNode *temp; - temp = players.Find(p); - if (!temp) - { - notice(s_GameServ, u, "Fatal error. Contact %S Admin. Buf: %s", - strtok(NULL, "")); - return; - } - user->stats = new Player(p->stats->name); - #ifdef DEBUGMODE - log("Setting data for identified"); - #endif - user->stats->setData(p->stats); - - #ifdef DEBUGMODE - log("Player Identified"); - #endif - - temp->setPtr(user); + user->stats = new Player(p->stats->name); + #ifdef DEBUGMODE + log("Setting data for identified"); + #endif + user->stats->setData(p->stats); - notice(s_GameServ, u, "Password Accepted. Identified."); + #ifdef DEBUGMODE + log("Player Identified"); + #endif - } - else - { - notice(s_GameServ, u, "Already identified. Contact a %S admin for help."); - } + temp->setPtr(user); + notice(s_GameServ, u, "Password Accepted. Identified."); } } @@ -979,17 +1061,24 @@ void do_fight(char *u) else if (!(ni = find(u))) { notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, "")); - return; - } - else if (!(battle = findbyrealnick(nick))) - { - notice(s_GameServ, u, "You can't attack %s while they aren't playing!", nick); - return; } else if (!is_playing(ni)) { notice(s_GameServ, u, "You are not playing!"); - return; + } + else 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 "\ + "day. You have to wait until tomorrow!"); + } + else if (!(battle = findplayer(nick))) + { + notice(s_GameServ, u, "Player %s not found!", nick); + } + else if (!is_playing(battle)) + { + notice(s_GameServ, u, "You can't attack %s while they aren't playing!", nick); } /* * Offline fighting not implemented yet. @@ -1007,19 +1096,38 @@ void do_fight(char *u) else if (!isAlive(ni->stats)) { notice(s_GameServ, u, "You are dead. Wait until tomorrow to fight others!"); - return; + } + else if (stricmp(ni->stats->name, battle->stats->name) == 0) + { + notice(s_GameServ, u, "Are you trying to commit suicide!?"); + } + else if (!isAlive(battle->stats)) + { + notice(s_GameServ, u, "They are dead. Cannot fight dead players!"); } else if (player_fight(battle)) { notice(s_GameServ, u, "%s is fighting %s already!", battle->stats->name, battle->stats->battle->stats->name); - return; } else if (is_fighting(battle)) { notice(s_GameServ, u, "%s is fighting %s already!", battle->stats->name, battle->stats->fight->name); - return; } - else if (is_playing(ni) && is_playing(battle) && stricmp(ni->stats->name, battle->stats->name) != 0) + else if (ni->stats->level - battle->stats->level > maxbfightdistance) + { + // 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); + } + else if (battle->stats->level - ni->stats->level > maxafightdistance) + { + // You can't fight someone above you by more than X level(S) + // level 1 can fight level (1 + X), but not > (1 + X) + notice(s_GameServ, u, "%s, do you really have a death wish? Try the forest you "\ + "weakling!", ni->stats->name); + } + else { // Set your battle pointer to the other player ni->stats->battle = battle; @@ -1032,9 +1140,12 @@ void do_fight(char *u) clearYourTurn(battle->stats); // Initiate Battle sequence! + ni->stats->player_fights -= 1; + notice(s_GameServ, u, "You challenge %s to an online duel!", battle->stats->name); notice(s_GameServ, battle->getNick(), "%s has challenged you to an online duel!", ni->stats->name); - notice(s_GameServ, battle->getNick(), "%s gets to go first because he initiated!", ni->stats->name); + 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); } @@ -1139,6 +1250,12 @@ void do_run(char *u) return; } + else if (!is_playing(user)) + { + notice(s_GameServ, u, "You must be playing to run!"); + return; + } + p = user->stats; if (p->battle) @@ -1721,7 +1838,7 @@ long int chartoint(char ch) int save_gs_dbase() { - ListNode *ptr = players.First(); + ListNode *ptr; Player *it; ofstream outfile; @@ -1733,6 +1850,9 @@ int save_gs_dbase() return 0; } + for (unsigned long x = 0; x < U_TABLE_SIZE; x++) + { + ptr = players[x].First(); while(ptr) { it = ptr->getData()->stats; @@ -1744,6 +1864,7 @@ int save_gs_dbase() << ' ' << it->inventory.Strength() << ' ' << it->inventory.Defense() << ' ' << it->inventory.HP() << endl; ptr = ptr->Next(); } + } outfile.close(); return 1; } @@ -1811,8 +1932,9 @@ int load_gs_dbase() tempname = strtok(NULL, " "); if (tempname) p->inventory.setHP(stringtoint(tempname)); - - players.insertAtBack(temp); + temp->stats->user = NULL; + unsigned long hv = HASH((unsigned char *) temp->stats->name, U_TABLE_SIZE); + players[hv].insertAtBack(temp); delete temp; } delete [] buf; @@ -2485,8 +2607,9 @@ void refreshall() { ListNode *it; Player *p; - - it = players.First(); + for (unsigned long x = 0; x < U_TABLE_SIZE; x++) + { + it = players[x].First(); while (it) { @@ -2494,6 +2617,7 @@ void refreshall() refresh(p); it = it->Next(); } + } } void refresh(Player *p) @@ -2568,7 +2692,9 @@ void resetall() ListNode *it; Player *p; - it = players.First(); + for (unsigned long x = 0; x < U_TABLE_SIZE; x++) + { + it = players[x].First(); while (it) { @@ -2576,6 +2702,7 @@ void resetall() reset(p); it = it->Next(); } + } } void reset(Player *p) @@ -2784,3 +2911,25 @@ bool load_monsters() delete [] buf; return true; } + +// this will be hash.cpp start +// thank you wcampbel +unsigned long HASH(const unsigned char *name, int size_of_table) +{ + unsigned long h = 0, g; + + while (*name) + { + #ifdef P10 + h = (h << 4) + (*name++); // Case sensitive for numerics + #else + h = (h << 4) + tolower(*name++); + #endif + if ((g = (h & 0xF0000000))) + h ^= g >> 24; + h &= ~g; + } + return h % size_of_table; +} + +// this will be hash.cpp end