X-Git-Url: https://jfr.im/git/irc/gameservirc.git/blobdiff_plain/9f8c2accae45b8dcb8c4e26009230c5e87ed53b5..f2072f1a322a388903ce463f9cb736d6576cce4f:/gameserv/tcpclient.cpp diff --git a/gameserv/tcpclient.cpp b/gameserv/tcpclient.cpp index 2a35d82..69d5dd7 100644 --- a/gameserv/tcpclient.cpp +++ b/gameserv/tcpclient.cpp @@ -20,31 +20,80 @@ #include #include #include -#include -#include -#include +#include #include +#include +#include +//#include +//#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.0 +devel"; int sock; -long timestamp; +int day; List clients; -void save_timestamp(); -void load_timestamp(); +void save_day(); +void load_day(); +void prettyIntro(); + +// Make this a daemon +int daemon(int nochdir, int noclose); -int main() +// Close all file descriptors from >= fd +void closeall(int fd); + +int main(int argc, char *argv[]) { char buffer[1024], buf[1024]; int connected = 1; - char *cmd, *source = NULL; + char *cmd, *source = NULL, *conf = "gameserv.conf"; srand(time(NULL)); - - load_config_file(); // default = 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; + } + conf = new char[strlen(argv[1])]; + strcpy(conf, argv[1]); + } + + prettyIntro(); + + if (load_config_file(conf)) + { + cout << "Config file loaded ok...\n" + << "Turning into a daemon" << endl; + } + else + exit(2); + + // Turn into a daemon + if (daemon(1,0) < 0) + { + perror("Could not turn into a daemon"); + exit(2); + } ignore_pipe(); sock = make_connection(remoteport, SOCK_STREAM, remoteserver); @@ -68,9 +117,30 @@ int main() 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); +#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); +#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); #endif + +#if defined(P10) + raw("%s T %s :%s", gsnum, c_Forest, c_ForestTopic); + raw("[] EB"); // End burst +#else +#ifndef HYBRID raw(":%S MODE %s +o %S", c_Forest); +#endif raw(":%S TOPIC %s :%s", c_Forest, c_ForestTopic); +#endif sock_gets(sock,buffer,sizeof(buffer)-1); /* -1 added thanks to David Duchene for pointing out the possible @@ -81,9 +151,18 @@ int main() log("Server: %s",buffer); #endif + 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!"); + init_masters(); load_gs_dbase(); - load_timestamp(); + load_day(); long int loadtime = time(NULL); long int currentTime; long int oldTime = loadtime; @@ -98,6 +177,7 @@ int main() } strcpy(buf, buffer); + #if !defined(P10) if (buffer[0] == ':') { source = strtok(buf, " "); @@ -105,6 +185,10 @@ int main() } else cmd = strtok(buf, " "); + #else + source = strtok(buf, " "); + cmd = strtok(NULL, " "); + #endif #ifdef DEBUGMODE log("Server: %s", buffer); @@ -125,15 +209,28 @@ int main() save_gs_dbase(); } + + #if !defined(P10) if (stricmp(cmd, "PING") == 0) { char *timestamp; timestamp = strtok(NULL, ""); raw("PONG %s", timestamp); + #else + if (stricmp(cmd, "G") == 0) { + char *timestamp; + timestamp = strtok(NULL, " "); + raw("[] Z [] %s 0 %s", timestamp + 1, timestamp); + #endif + #ifdef P10 + } else if (stricmp(cmd, "EB") == 0) { + raw("[] EA"); + #endif } else if (stricmp(cmd, "VERSION") == 0) { 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] == ':') { @@ -148,25 +245,113 @@ int main() else { char *nick; + #else + } else if (stricmp(cmd, "N") == 0 && strlen(source) == 2) { + { + char *nick, *realnick; + realnick = strtok(NULL, " "); + + for (int x = 0; x < 5; x++) + nick = strtok(NULL, " "); + + if (nick[0] == '+') + { + #ifdef DEBUGMODE + log ("aClient has modes"); + #endif + + // Searching for the +r mode (extra parameter) + for (unsigned int count = 1; count < strlen(nick); count++) + { + if (nick[count] == 'r') + { + nick = strtok(NULL, " "); + break; + } + } + nick = strtok(NULL, " "); + } + #endif aClient *newuser; + nick = strtok(NULL, " "); - newuser = new aClient(nick); + + #ifdef P10 + newuser = new aClient(nick, realnick); + #else + newuser = new aClient(nick); + #endif + + if (loaded) + #ifdef P10 + notice(s_GameServ, nick, welcomemsg, realnick); + #else notice(s_GameServ, nick, welcomemsg, nick); + #endif clients.insertAtBack(newuser); delete newuser; } + #if defined(P10) + } else if (stricmp(cmd, "Q") == 0) { + #else } else if (stricmp(cmd, "QUIT") == 0) { + #endif aClient *quitter; - if ((quitter = find(source + 1))) + char z = source[0]; + + if (z == ':') + source++; + + if ((quitter = find(source))) clients.remove(quitter); - if ((quitter = findIRCplayer(source + 1))) + 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("!NULL!"); + #ifdef P10 + quitter->setRealNick("!NULL!"); + #endif quitter->stats->user = NULL; // Unidentify them } + if (z == ':') + source--; + + #if defined(P10) + } else if (stricmp(cmd, "P") == 0) { + char *rest, *dest; + char *longname; + longname = new char[strlen(s_GameServ) + strlen(servername) + 2]; + + sprintf(longname, "%S@%s", servername); + + dest = strtok(NULL, " "); + rest = strtok(NULL, ""); + if (stricmp(dest, gsnum) == 0 || stricmp(dest, longname) == 0) + { + delete [] longname; + gameserv(source, rest); + } + else if (stricmp(dest, c_Forest) == 0) + { + delete [] longname; + forest(source, rest); + } + #else } else if (stricmp(cmd, "PRIVMSG") == 0) { char *rest, *dest; dest = strtok(NULL, " "); @@ -175,25 +360,66 @@ int main() gameserv(source, rest); 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) { - char *channel, *nick; + char *channel, *nick, *tmp, *rest; strtok(NULL, " "); // Ignore the TS +#ifndef HYBRID strtok(NULL, " "); // Ignore the TS +#endif channel = strtok(NULL, " "); - strtok(NULL, " "); - nick = strtok(NULL, " "); - nick++; // Get rid of the : - if (stricmp(channel, c_Forest) == 0 && is_playing(nick)) - raw(":%S MODE %s +v %s", channel, nick); - #endif - + rest = strtok(NULL, ""); + tmp = strchr(rest, ':'); + tmp++; + nick = strtok(tmp, " "); + while (nick != NULL) + { + if (*nick == '@') + nick++; + if (*nick == '+') + nick++; // Assume for users set op and voice, they + // are never passed as +@nick + if (stricmp(channel, c_Forest) == 0 && is_playing(nick)) + raw(":%S MODE %s +v %s", channel, nick); + + nick = strtok(NULL, " "); + } +#endif } else { #ifdef DEBUGMODE log("Unrecognized Message: cmd = %s source = %s", cmd, source); @@ -204,7 +430,7 @@ int main() end: save_gs_dbase(); - save_timestamp(); + save_day(); delete_monsters(); delete_masters(); @@ -228,6 +454,34 @@ aClient *find(const char *nick) return findbynick(nick); } +#ifdef P10 + +aClient *findbyrealnick(char *realnick) +{ + ListNode *newPtr; + newPtr = clients.First(); + + aClient *client = NULL; + + while (newPtr) + { + client = newPtr->getData(); + if (stricmp(client->getRealNick(), realnick) == 0) + return client; + client = NULL; + newPtr = newPtr->Next(); + } + return client; +} + +#else + +aClient *findbyrealnick(char *realnick) +{ + return findbynick(realnick); +} + +#endif aClient *findbynick(char *nick) { @@ -239,7 +493,11 @@ aClient *findbynick(char *nick) while (newPtr) { client = newPtr->getData(); - if (stricmp(client->getNick(), nick) == 0) + #ifdef P10 + if (strcmp(client->getNick(), nick) == 0) + #else + if (stricmp(client->getNick(), nick) == 0) + #endif return client; client = NULL; newPtr = newPtr->Next(); @@ -255,7 +513,11 @@ aClient *findIRCplayer(const char *nick) for (newPtr = players.First(); newPtr; newPtr = newPtr->Next()) { p = newPtr->getData(); - if (stricmp(p->getNick(), nick) == 0) + #ifdef P10 + if (strcmp(p->getNick(), nick) == 0) + #else + if (stricmp(p->getNick(), nick) == 0) + #endif return p; p = NULL; } @@ -286,7 +548,11 @@ aClient *findbynick(const char *nick) while (newPtr) { client = newPtr->getData(); - if (stricmp(client->getNick(), nick) == 0) + #ifdef P10 + if (strcmp(client->getNick(), nick) == 0) + #else + if (stricmp(client->getNick(), nick) == 0) + #endif return client; client = NULL; newPtr = newPtr->Next(); @@ -294,51 +560,127 @@ 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()) { - cerr << "Error creating new file." << endl; + log("Error creating new file .gsday"); return; } - outfile << timestamp << endl; + outfile << day << endl; outfile.close(); } -long int midnight(long int offset) +/* 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, + * so the caller is responsible for things like the umask, etc. + */ + +/* believed to work on all Posix systems */ + +int daemon(int nochdir, int noclose) +{ + pid_t pid; + switch (pid = fork()) + { + case 0: break; + case -1: return -1; + default: _exit(0); /* exit the original process */ + } + + if (setsid() < 0) /* shoudn't fail */ + return -1; + + /* dyke out this switch if you want to acquire a control tty in */ + /* the future -- not normally advisable for daemons */ + + switch (pid = fork()) + { + case 0: break; + case -1: return -1; + default: + ofstream outfile; + outfile.open(pidfile); + if (outfile.fail()) + cerr << "Unable to open " << pidfile << endl; + outfile << pid << endl; + outfile.close(); + + _exit(0); + } + + if (!nochdir) + chdir("/"); + + if (!noclose) + { + closeall(0); + open("/dev/null",O_RDWR); + dup(0); dup(0); + } + + return 0; +} + + +/* closeall() -- close all FDs >= a specified value */ + +void closeall(int fd) +{ + int fdlimit = sysconf(_SC_OPEN_MAX); + + while (fd < fdlimit) + close(fd++); +} + +void prettyIntro() { - return (time(NULL) - (time(NULL) % 86400)) + (offset * 3600); +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; }