X-Git-Url: https://jfr.im/git/irc/gameservirc.git/blobdiff_plain/4dde2ed9f323c87a1f54b002c66da835f7dc0baa..1fe6fccdcc6c293d4d0ce7278698f5847175d4ec:/gameserv/tcpclient.cpp diff --git a/gameserv/tcpclient.cpp b/gameserv/tcpclient.cpp index 998ab43..86a0b84 100644 --- a/gameserv/tcpclient.cpp +++ b/gameserv/tcpclient.cpp @@ -17,86 +17,242 @@ #include "list.h" #include "aClient.h" #include "extern.h" +#include "flags.h" #include #include #include -#include -#include -#include +#include #include +#include +#include + +//#include +//#include +//#include + +using namespace std; char *PACKAGE = "GameServ"; -char *VERSION = "1.1.2"; +char *VERSION = "1.3.0 +devel"; int sock; -long timestamp; +long lastrefresh; +long lastrollover; + +List clients[U_TABLE_SIZE]; + +void save_lastrefresh(); +void load_lastrefresh(); +void load_lastrollover(); +void save_lastrollover(); +void prettyIntro(); +void check_idles(); -List clients; +// Make this a daemon +int daemon(int nochdir, int noclose); -void save_timestamp(); -void load_timestamp(); +// 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; - srand(time(NULL)); - - load_config_file(); - - if (argc == 1) { - argc = 3; - argv[1] = remoteserver; - argv[2] = remoteport; + 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]; } - if (argc != 3) { - fprintf(stderr,"Usage: tcpclient host port\n"); - fprintf(stderr,"where host is the machine which is running the\n"); - fprintf(stderr,"tcpserver program, and port is the port it is\n"); - fprintf(stderr,"listening on.\n"); - exit(EXIT_FAILURE); + + prettyIntro(); + + if (load_config_file(conf)) + { + cout << "Config file loaded ok...\n" + << "Turning into a daemon" << endl; } - ignore_pipe(); - sock = make_connection(argv[2], SOCK_STREAM, argv[1]); - if (sock == -1) { - fprintf(stderr,"make_connection failed.\n"); + 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(3); + } + if (load_items() == 0) + { + log("Error loading items"); + goto end; + } + + if (load_store() == 0) + { + log("Error loading store"); + goto end; + } + if (load_tavern() == 0) + { + log("Error loading tavern"); + goto end; + } + + load_gs_dbase(); + loadNews(newsdata, todaysnews); + + + if (load_masters() == false) + { + log("Error loading masters"); + goto end; + } + + if (load_monsters() == false) + { + log("Error loading monsters"); + goto end; + } + + if (!load_dragon()) + { + log("Error loading dragon"); + goto end; + } + + if (load_levels() == false) + { + log("Error loading levels"); + 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, " "); + } + + // This loop will retry the connection 3 times + for (int retry = 0; retry < 3 && !shuttingdown; retry++) + { + connected = 1; + load_lastrefresh(); + load_lastrollover(); + + 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 = conn(remoteserver, remoteport, localhost, 0); + // 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 :%s v%s", time(NULL), gshost, + servername, time(NULL), 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 +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(ULTIMATE2) + raw("PASS %s :TS", remotepass); + raw("SERVER %s 1 :%s", servername, servername); + raw("NICK %S 1 %d %s %s %s 0 :GameServ", + time(NULL), gsident, gshost, servername); + if (isBOper()) + raw(":%S mode %S +o"); + raw(":%S JOIN %s", 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 %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 - raw(":%S MODE %s +o %S", c_Forest); + +#if defined(P10) + raw("%s T %s :%s", gsnum, c_Forest, c_ForestTopic); + raw("[] EB"); // End burst +#else + #ifndef HYBRID + #if defined(ULTIMATE2) + raw(":%s MODE %s +o %S %ld", servername, c_Forest, + time(NULL)); + #else + raw(":%S MODE %s +o %S", c_Forest); + #endif + #endif raw(":%S TOPIC %s :%s", c_Forest, c_ForestTopic); +#endif + #ifndef P10 + if (isUseNickServ()) + { + raw(":%S PRIVMSG %s :IDENTIFY %s", nsname, nspass); + } + #endif sock_gets(sock,buffer,sizeof(buffer)-1); /* -1 added thanks to David Duchene for pointing out the possible buffer overflow resulting from the linefeed added below. */ - printf("Server: %s\n",buffer); - init_masters(); - load_gs_dbase(); - load_timestamp(); - int loadtime = time(NULL); - bool loaded = false; - - if (load_monsters() == false) - goto end; + #ifdef DEBUGMODE + log("Server: %s",buffer); + #endif while (connected) { if (sock_gets(sock,buffer,sizeof(buffer)) == -1) { @@ -104,6 +260,7 @@ int main(int argc, char *argv[]) } strcpy(buf, buffer); + #if !defined(P10) if (buffer[0] == ':') { source = strtok(buf, " "); @@ -111,25 +268,96 @@ int main(int argc, char *argv[]) } else cmd = strtok(buf, " "); + #else + source = strtok(buf, " "); + cmd = strtok(NULL, " "); + #endif - cout << "Server: " << buffer << endl << flush; + #ifdef DEBUGMODE + log("Server: %s", buffer); + #endif // Wait N seconds then we're loaded. if (!loaded) { - if (time(NULL) >= confloadtime + loadtime) + 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; + } } + // Refresh players and clear news if the time is up + currentTime = time(NULL); + + if (isRolloverForestFights()) + { + if (currentTime - lastrollover >= rolloverperiod) + { + rolloverall(); + lastrollover = currentTime; + save_lastrollover(); + notice(s_GameServ, c_Forest, "Adding %d forest fights to all players!", forestfights); + } + } + + if (currentTime - lastrefresh >= refreshperiod) + { + refreshall(); + clearNews(todaysnews); + saveNews(newsdata, todaysnews); + lastrefresh = currentTime; + save_lastrefresh(); + notice(s_GameServ, c_Forest, "Refreshing all players "\ + "and resetting news!"); + } + + // Save the player data every updateperiod seconds + if (currentTime - oldTime >= updateperiod) + { + oldTime = currentTime; + log("Saving to %s", playerdata); + + save_gs_dbase(); + saveNews(newsdata, todaysnews); + if (isSavedNotice()) + { + // Send notice to the channel of the update + notice(s_GameServ, c_Forest, "%S player data saved"); + } + } + + + #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] == ':') { @@ -137,71 +365,270 @@ int main(int argc, char *argv[]) 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 { char *nick; - aClient *newuser; + #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, *temp; + nick = strtok(NULL, " "); - newuser = new aClient(nick); + + #ifdef P10 + newuser = new aClient(nick, realnick); + #else + newuser = new aClient(nick); + #endif + + if (loaded) - notice(s_GameServ, nick, welcomemsg, nick); - clients.insertAtBack(newuser); + if (isWelcome()) + { + #ifdef P10 + notice(s_GameServ, nick, welcomemsg, realnick); + #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 + + temp = clients[hv].insertAtBack(newuser); + + #if defined(HYBRID) || defined(BAHAMUT) || defined(ULTIMATE2) + 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; + } + } + #elif defined(UNREAL) + char *nickserver; + strtok(NULL, " "); + strtok(NULL, " "); + 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; - if ((quitter = find(source + 1))) - clients.remove(quitter); - if ((quitter = findplayer(source + 1))) - quitter->setNick("NULL"); + char z = source[0]; + + if (z == ':') + source++; + + if (!(quitter = find(source))) + { + 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; + 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 && isListenOnCF()) + { + delete [] longname; + forest(source, rest); + } + #else } else if (stricmp(cmd, "PRIVMSG") == 0) { char *rest, *dest; dest = strtok(NULL, " "); rest = strtok(NULL, ""); if (strnicmp(dest, s_GameServ, strlen(s_GameServ)) == 0) gameserv(source, rest); - else if (stricmp(dest, c_Forest) == 0) + else if (stricmp(dest, c_Forest) == 0 && isListenOnCF()) 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.c_str(), + #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 { - // cout << "Unrecognized Message: cmd = " << cmd << setw(30) << "source = " << - // source << endl; + #ifdef DEBUGMODE + log("Unrecognized Message: cmd = %s source = %s", cmd, source); + #endif } } + } // for loop for connection retry + end: save_gs_dbase(); - save_timestamp(); + save_dragon(); + saveNews(newsdata, todaysnews); delete_monsters(); - delete_masters(); - printf("\n"); + #ifdef DEBUGMODE + log(""); + #endif + close(sock); unload_config_file(); return 0; @@ -217,18 +644,57 @@ aClient *find(const char *nick) return findbynick(nick); } +#ifdef P10 + +aClient *findbyrealnick(char *realnick) +{ + ListNode *newPtr; + unsigned long hv = sHASH((unsigned char *) realnick); + newPtr = clients[hv].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) { 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; 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(); @@ -236,32 +702,106 @@ aClient *findbynick(char *nick) return client; } +aClient *findIRCplayer(const char *nick) +{ + ListNode *newPtr; + aClient *p = NULL; + + p = find(nick); + + if (!is_playing(p)) + return NULL; + + unsigned long hv = iHASH((unsigned char *) p->stats->name.c_str()); + + for (newPtr = players[hv].First(); newPtr; newPtr = newPtr->Next()) + { + p = newPtr->getData(); + #ifdef P10 + if (strcmp(p->getNick(), nick) == 0) + #else + if (stricmp(p->getNick(), nick) == 0) + #endif + return p; + p = NULL; + } + 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) + if (stricmp(p->name.c_str(), name) == 0) return newPtr->getData(); p = NULL; } 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; + switch(p->level) + { + case 1: + if ((time(NULL) - p->lastlogin) / 86400 >= level1expire) + { + logout(newPtr->getData()); + players[x].remove(newPtr->getData()); + return; + } + break; + + default: + if ((time(NULL) - p->lastlogin) / 86400 >= defaultexpire) + { + logout(newPtr->getData()); + players[x].remove(newPtr->getData()); + return; + } + break; + } + 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; 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(); @@ -269,46 +809,171 @@ aClient *findbynick(const char *nick) return client; } -void load_timestamp() +/* 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) { - ifstream infile; + pid_t pid; + switch (pid = fork()) + { + case 0: break; + case -1: return -1; + default: _exit(0); /* exit the original process */ + } - infile.open(".gstimestamp"); + 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() +{ + 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; + cout << "http://www.gameserv.us - http://www.sourceforge.net/projects/gameservirc" << endl; +} + +void load_lastrefresh() +{ + ifstream infile; + infile.open(".gsrefresh"); if (infile.fail()) { - cout << "Error opening .gstimestamp" << endl; - cout << "Generating new timestamp" << endl; + #ifdef DEBUGMODE + log("Error opening .gsrefresh"); + #endif + generate: - timestamp = midnight(); - save_timestamp(); + long mytime = time(NULL); + #ifdef DEBUGMODE + log("Generating new refresh time"); + #endif + + // Just a safety measure... tho no one should + // get anywhere near the actual time as their refreshperiod + if (refreshperiod >= mytime) + { + log("Refresh period is greater than or equal to the actual time... setting it to 86400"); + refreshperiod = 86400; + } + + lastrefresh = mytime - (mytime % refreshperiod); + + refreshall(); + save_lastrefresh(); return; } + infile >> lastrefresh; - infile >> timestamp; infile.close(); - if (timestamp < 1000000) + if (lastrefresh < 0) goto generate; } -void save_timestamp() +void load_lastrollover() +{ + ifstream infile; + infile.open(".gsrollover"); + if (infile.fail()) + { +#ifdef DEBUGMODE + log("Error opening .gsrollover"); +#endif + + generate: + long mytime = time(NULL); +#ifdef DEBUGMODE + log("Generating new rollover time"); +#endif + lastrollover = mytime; + return; + } + infile >> lastrollover; + + infile.close(); + if (lastrollover < 0) + goto generate; +} + +void save_lastrefresh() { ofstream outfile; - outfile.open(".gstimestamp"); + outfile.open(".gsrefresh"); if (outfile.fail()) { - cout << "Error creating new file." << endl; + log("Error creating new file .gsrefresh"); return; } - - outfile << timestamp << endl; + outfile << lastrefresh << endl << lastrollover; outfile.close(); } -long int midnight(long int offset) +void save_lastrollover() { - return (time(NULL) - (time(NULL) % 86400)) + (offset * 3600); + ofstream outfile; + + outfile.open(".gsrollover"); + + if (outfile.fail()) + { + log("Error creating new file .gsrollover"); + return; + } + outfile << lastrollover << endl; + outfile.close(); }