X-Git-Url: https://jfr.im/git/irc/gameservirc.git/blobdiff_plain/4e5760fd103583efe4d1762b6cf8f8e7036734e6..e3ede4a7b12fd781e2ea8f7a97adb7806629d59f:/gameserv/tcpclient.cpp diff --git a/gameserv/tcpclient.cpp b/gameserv/tcpclient.cpp index 14d7ba4..b54dba7 100644 --- a/gameserv/tcpclient.cpp +++ b/gameserv/tcpclient.cpp @@ -17,6 +17,7 @@ #include "list.h" #include "aClient.h" #include "extern.h" +#include "flags.h" #include #include #include @@ -28,23 +29,23 @@ //#include //#include - - using std::ofstream; using std::ifstream; using std::cerr; using std::endl; char *PACKAGE = "GameServ"; -char *VERSION = "1.1.8"; +char *VERSION = "1.2.1 +devel"; int sock; -long timestamp; +int day; -List clients; +List clients[U_TABLE_SIZE]; -void save_timestamp(); -void load_timestamp(); +void save_day(); +void load_day(); +void prettyIntro(); +void check_idles(); // Make this a daemon int daemon(int nochdir, int noclose); @@ -52,58 +53,137 @@ int daemon(int nochdir, int noclose); // Close all file descriptors from >= fd void closeall(int fd); -int main() +int main(int argc, char *argv[]) { - char buffer[1024], buf[1024]; - int connected = 1; - char *cmd, *source = NULL; - srand(time(NULL)); - + char buffer[1024], buf[1024]; + memset(buffer, 0, 1024); + memset(buf, 0, 1024); + int connected; + long lastidlecheck; + char *cmd, *source = NULL, *conf; + srand(time(NULL)); + conf = new char[16]; + strcpy(conf, "gameserv.conf"); + + /* + * This needs to be fixed to work for any number of arguments in any + * order + * + */ + if (argc > 1) + { + if ( argc > 2 || stricmp(argv[1], "--help") == 0) + { + cout << "Usage: gameserv [options] [configfile]" << endl; + cout << "Options:" << endl; + cout << "--help Displays this help dialogue" << endl; + return 1; + } + delete []conf; + conf = argv[1]; + } + + prettyIntro(); - load_config_file(); // default = gameserv.conf + if (load_config_file(conf)) + { + cout << "Config file loaded ok...\n" + << "Turning into a daemon" << endl; + } + else + exit(2); + + if (argc <= 1) + delete []conf; // Turn into a daemon if (daemon(1,0) < 0) { perror("Could not turn into a daemon"); - exit(2); + exit(3); + } + init_masters(); + load_gs_dbase(); + + if (load_monsters() == false) + goto end; + + shuttingdown = false; + + char ignoreservers[32][256]; + char *currentserver; + currentserver = strtok(ignoreserverslist, " "); + for (int server = 0; server < 32 && currentserver != NULL; server++) + { + strncpy(ignoreservers[server], currentserver, 255); + log("Placing %s on the server ignore list", currentserver); + currentserver = strtok(NULL, " "); } - ignore_pipe(); - sock = make_connection(remoteport, SOCK_STREAM, remoteserver); - if (sock == -1) { - fprintf(stderr,"make_connection failed.\n"); + 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!"); + + + // This loop will retry the connection 3 times + for (int retry = 0; retry < 3 && !shuttingdown; retry++) + { + connected = 1; + load_day(); + + + long int loadtime = time(NULL); + long int currentTime; + long int oldTime = loadtime; + + lastidlecheck = loadtime; + + #ifdef DEBUGMODE + log("Setting primary Idle Check timestamp: %ld", lastidlecheck); + #endif + bool loaded = false; + + ignore_pipe(); + sock = make_connection(remoteport, SOCK_STREAM, remoteserver); + if (sock == -1) { + fprintf(stderr,"make_connection failed.\n"); unload_config_file(); return -1; } + log("%S socket connected."); #ifdef UNREAL raw("PROTOCTL NICKv2 VHP"); raw("PASS :%s", remotepass); raw("SERVER %s 1 :%s", servername, servername); - raw("NICK %S 1 %d %S %s %s %d +owghraAxNt %s :%s v%s", time(NULL), gshost, - servername, time(NULL), gshost, PACKAGE, VERSION); + raw("NICK %S 1 %d %S %s %s %d +w%s %s :%s v%s", time(NULL), gshost, + servername, time(NULL), (isBOper() ? "o" : ""), gshost, PACKAGE, VERSION); raw(":%S JOIN %s", c_Forest); - raw(":%S MODE %s +mtn", c_Forest); + raw(":%S MODE %s +tn", c_Forest); #elif defined(BAHAMUT) raw("PASS %s :TS", remotepass); raw("SERVER %s 1 :%s", servername, servername); - raw("NICK %S 1 %d +o %s %s %s 0 :GameServ", time(NULL), gsident, gshost, - servername); - raw(":%s SJOIN %d %d %s +mnt :@%S", servername, time(NULL), time(NULL), c_Forest); + raw("NICK %S 1 %d +w%s %s %s %s 0 :GameServ", time(NULL), (isBOper() ? "o" : ""), + gsident, gshost, servername); + raw(":%s SJOIN %d %d %s +nt :@%S", servername, time(NULL), time(NULL), c_Forest); #elif defined(HYBRID) raw("PASS %s :TS", remotepass); raw("SERVER %s 1 :%s", servername, servername); - raw("NICK %S 1 %d +o %s %s %s :GameServ", time(NULL), gsident, gshost, - servername); - // Sending a timestamp of 1 to force ops. - raw(":%s SJOIN 1 %s +ntm :@%S", servername, c_Forest); + raw("NICK %S 1 %d +w%s %s %s %s :GameServ", time(NULL), (isBOper() ? "o" : ""), + gsident, gshost, servername); + raw(":%s SJOIN %ld %s +nt :@%S", servername, time(NULL), c_Forest); #elif defined(P10) // Server numeric is: [] <-- must be unique raw("PASS :%s", remotepass); raw("SERVER %s 1 %d %d P10 []AAF :%s", servername, time(NULL), time(NULL), servername); - raw("[] N %S 1 %d %s %s DAqAoB %s :%S", time(NULL), gsident, gshost, gsnum); - raw("[] B %s %d +tnm %s:o", c_Forest, time(NULL) - 864000, gsnum); + raw("[] N %S 1 %d %s %s %s DAqAoB %s :%S", time(NULL), gsident, gshost, + (isBOper() ? "+o" : "") gsnum); + raw("[] B %s %d +tn %s:o", c_Forest, time(NULL) - 864000, gsnum); #endif #if defined(P10) @@ -125,17 +205,6 @@ int main() log("Server: %s",buffer); #endif - init_masters(); - load_gs_dbase(); - load_timestamp(); - long int loadtime = time(NULL); - long int currentTime; - long int oldTime = loadtime; - bool loaded = false; - - if (load_monsters() == false) - goto end; - while (connected) { if (sock_gets(sock,buffer,sizeof(buffer)) == -1) { connected = 0; @@ -163,7 +232,19 @@ int main() if (!loaded) { if (time(NULL) >= welcomedelay + loadtime) + { loaded = true; + retry = 0; // Start the reconnection cycle over + } + } + else + { + long TIME = time(NULL); + if (TIME - lastidlecheck >= idlecheckperiod) + { + check_idles(); + lastidlecheck = TIME; + } } // Save the player data every updateperiod seconds @@ -171,6 +252,7 @@ int main() if (currentTime - oldTime >= updateperiod) { oldTime = currentTime; + log("Saving to %s", playerdata); save_gs_dbase(); } @@ -194,7 +276,7 @@ int main() char *server; server = strtok(NULL, " "); server++; - raw(":%s 351 %s %s %s. %s", servername, source+1, PACKAGE, VERSION, servername); + raw(":%s 351 %s %s_%s. %s", servername, source+1, PACKAGE, VERSION, servername); #if !defined(P10) } else if (strncmp(cmd, "NICK", 4) == 0) { if (buffer[0] == ':') @@ -203,8 +285,13 @@ int main() if ((tempPtr = find((source + 1)))) { char *nick; + unsigned long oldhv, newhv; nick = strtok(NULL, " "); + oldhv = iHASH((unsigned char *) tempPtr->getNick()); + newhv = iHASH((unsigned char *) nick); tempPtr->setNick(nick); + clients[oldhv].remove(tempPtr); + clients[newhv].insertAtBack(tempPtr); } } else @@ -237,7 +324,7 @@ int main() nick = strtok(NULL, " "); } #endif - aClient *newuser; + aClient *newuser, *temp; nick = strtok(NULL, " "); @@ -254,14 +341,41 @@ int main() #else notice(s_GameServ, nick, welcomemsg, nick); #endif + #ifdef P10 + unsigned long hv = sHASH((unsigned char *) nick) + #else + unsigned long hv = iHASH((unsigned char *) nick); + #endif - clients.insertAtBack(newuser); + temp = clients[hv].insertAtBack(newuser); + + #if defined(HYBRID) || defined(BAHAMUT) + char *nickserver; + strtok(NULL, " "); + strtok(NULL, " "); + nickserver = strtok(NULL, " "); + if (nickserver[0] == '+') + strtok(NULL, " "); + strtok(NULL, " "); + + nickserver = strtok(NULL, " "); + for (int x = 0; x < 32; x++) + { + if (stricmp(ignoreservers[x], nickserver) == 0) + { + setIgnore(temp); + break; + } + } + #endif delete newuser; } #if defined(P10) } else if (stricmp(cmd, "Q") == 0) { +// unsigned long hv = sHASH((unsigned char *) source); #else } else if (stricmp(cmd, "QUIT") == 0) { +// unsigned long hv = iHASH((unsigned char *) source); #endif aClient *quitter; char z = source[0]; @@ -269,17 +383,44 @@ int main() if (z == ':') source++; - if ((quitter = find(source))) - clients.remove(quitter); - if ((quitter = findIRCplayer(source))) + if (!(quitter = find(source))) { - quitter->setNick("!NULL!"); - quitter->stats->user = NULL; // Unidentify them + log("Fatal Error: could not find %s in the "\ + "clients list", source); + goto end; } + logout(quitter); + if (z == ':') source--; + /* Attempting to use the logout() function + if ((quitter = find(source))) + clients[hv].remove(quitter); + if ((quitter = findIRCplayer(source))) + { + if (player_fight(quitter)) + { + // Stop the fight on the other client + aClient *otherplayer = quitter->stats->battle; + otherplayer->stats->battle = NULL; + notice(s_GameServ, otherplayer->getNick(), "%s "\ + "has quit IRC. The fight stops here.", + quitter->stats->name); + } + quitter->stats->battle = NULL; + quitter->stats->fight = NULL; + quitter->stats->master = NULL; + + quitter->setNick("Not Playing"); + #ifdef P10 + quitter->setRealNick("Not Playing"); + #endif + quitter->stats->client = NULL; // Unidentify them + } + */ + #if defined(P10) } else if (stricmp(cmd, "P") == 0) { char *rest, *dest; @@ -295,7 +436,7 @@ int main() delete [] longname; gameserv(source, rest); } - else if (stricmp(dest, c_Forest) == 0) + else if (stricmp(dest, c_Forest) == 0 && isListenOnCF()) { delete [] longname; forest(source, rest); @@ -310,11 +451,39 @@ int main() else if (stricmp(dest, c_Forest) == 0) forest(source, rest); #endif + #if defined(P10) + } else if (stricmp(cmd, "J") == 0) { + #else } else if (stricmp(cmd, "JOIN") == 0) { + #endif char *channel; + aClient *joiner; channel = strtok(NULL, " "); - if (stricmp(channel, c_Forest) == 0 && is_playing(source + 1)) - raw(":%S MODE %s +v %s", c_Forest, (source + 1)); + + char z = source[0]; + + if (z == ':') + source++; + + joiner = find(source); + + if (stricmp(channel, c_Forest) == 0 && is_playing(joiner)) + { + #ifdef DEBUGMODE + log("Player %s (IRC: %s) joined %s", + joiner->stats->name, + #ifdef P10 + joiner->getRealNick(), + #else + joiner->getNick(), + #endif + c_Forest); + #endif + raw(":%S MODE %s +v %s", c_Forest, (source)); + } + + if (z == ':') + source--; #if defined(BAHAMUT) } else if (stricmp(cmd, "SJOIN") == 0) { @@ -348,10 +517,12 @@ int main() } } + } // for loop for connection retry + end: save_gs_dbase(); - save_timestamp(); + save_day(); delete_monsters(); delete_masters(); @@ -380,7 +551,8 @@ aClient *find(const char *nick) aClient *findbyrealnick(char *realnick) { ListNode *newPtr; - newPtr = clients.First(); + unsigned long hv = sHASH((unsigned char *) realnick); + newPtr = clients[hv].First(); aClient *client = NULL; @@ -407,7 +579,13 @@ aClient *findbyrealnick(char *realnick) aClient *findbynick(char *nick) { ListNode *newPtr; - newPtr = clients.First(); + #ifdef P10 + unsigned long hv = sHASH((unsigned char *) nick); + #else + unsigned long hv = iHASH((unsigned char *) nick); + #endif + + newPtr = clients[hv].First(); aClient *client = NULL; @@ -431,7 +609,14 @@ aClient *findIRCplayer(const char *nick) ListNode *newPtr; aClient *p = NULL; - for (newPtr = players.First(); newPtr; newPtr = newPtr->Next()) + p = find(nick); + + if (!is_playing(p)) + return NULL; + + unsigned long hv = iHASH((unsigned char *) p->stats->name); + + for (newPtr = players[hv].First(); newPtr; newPtr = newPtr->Next()) { p = newPtr->getData(); #ifdef P10 @@ -444,12 +629,13 @@ aClient *findIRCplayer(const char *nick) } return NULL; } + aClient *findplayer(const char *name) { ListNode *newPtr; Player *p = NULL; - - for (newPtr = players.First(); newPtr; newPtr = newPtr->Next()) + unsigned long hv = iHASH((unsigned char *) name); + for (newPtr = players[hv].First(); newPtr; newPtr = newPtr->Next()) { p = newPtr->getData()->stats; if (stricmp(p->name, name) == 0) @@ -459,10 +645,34 @@ aClient *findplayer(const char *name) return NULL; } +void check_idles() +{ + ListNode *newPtr; + Player *p = NULL; + + for (int x = 0; x < U_TABLE_SIZE; x++) + { + for (newPtr = players[x].First(); newPtr; newPtr = newPtr->Next()) + { + p = newPtr->getData()->stats; + if (timedOut(p)) + { + timeOutEvent(p); + } + } + } +} + aClient *findbynick(const char *nick) { ListNode *newPtr; - newPtr = clients.First(); + #ifdef P10 + unsigned long hv = sHASH((unsigned char *) nick); + #else + unsigned long hv = iHASH((unsigned char *) nick); + #endif + + newPtr = clients[hv].First(); aClient *client = NULL; @@ -481,55 +691,56 @@ aClient *findbynick(const char *nick) return client; } -void load_timestamp() +void load_day() { ifstream infile; - infile.open(".gstimestamp"); + infile.open(".gsday"); if (infile.fail()) { #ifdef DEBUGMODE - log("Error opening .gstimestamp"); + log("Error opening .gsday"); #endif generate: #ifdef DEBUGMODE - log("Generating new timestamp"); + log("Generating new day"); #endif - timestamp = midnight(); - save_timestamp(); + struct tm *tm; + time_t ti; + time(&ti); + tm = localtime(&ti); + + day = tm->tm_mday; + + save_day(); return; } - infile >> timestamp; + infile >> day; infile.close(); - if (timestamp < 1000000) + if (day < 1 || day > 31) goto generate; } -void save_timestamp() +void save_day() { ofstream outfile; - outfile.open(".gstimestamp"); + outfile.open(".gsday"); if (outfile.fail()) { - log("Error creating new file .gstimestamp"); + log("Error creating new file .gsday"); return; } - outfile << timestamp << endl; + outfile << day << endl; outfile.close(); } -long int midnight(long int offset) -{ - return (time(NULL) - (time(NULL) % 86400)) + (offset * 3600); -} - /* daemon() - detach process from user and disappear into the background * returns -1 on failure, but you can't do much except exit in that case * since we may already have forked. This is based on the BSD version, @@ -560,9 +771,9 @@ int daemon(int nochdir, int noclose) case -1: return -1; default: ofstream outfile; - outfile.open("gameserv.pid"); + outfile.open(pidfile); if (outfile.fail()) - cerr << "Unable to open gameserv.pid" << endl; + cerr << "Unable to open " << pidfile << endl; outfile << pid << endl; outfile.close(); @@ -593,4 +804,14 @@ void closeall(int fd) close(fd++); } - +void prettyIntro() +{ +cout << endl; +cout << " GGGG AAA MM MM EEEEEEE SSSSS EEEEEEE RRRRRR VV VV " << endl; +cout << " GG GG AAAAA MMM MMM EE SS EE RR RR VV VV " << endl; +cout << "GG AA AA MM MM MM EEEEE SSSSS EEEEE RRRRRR VV VV " << endl; +cout << "GG GGG AAAAAAA MM MM EE SS EE RR RR VV VV " << endl; +cout << "G G AA AA MM MM EEEEEEE SSSSS EEEEEEE RR RR VVV" << endl; +cout << " GGGGG V\n\n" << endl; +cout << "Version: " << VERSION << endl; +}