summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuillaume Melquiond <guillaume.melquiond@gmail.com>2007-09-16 11:10:06 +0000
committerGuillaume Melquiond <guillaume.melquiond@gmail.com>2007-09-16 11:10:06 +0000
commit88e3d219588052a8ab222ab4f6f2b27c9c29c1b2 (patch)
tree6b15bf0fe700d61b3aa451d0810a07a175b06774
parentbe461a5ca51e10dad40c87385440f6ddae14fca0 (diff)
downloadmanaserv-88e3d219588052a8ab222ab4f6f2b27c9c29c1b2.tar.gz
manaserv-88e3d219588052a8ab222ab4f6f2b27c9c29c1b2.tar.bz2
manaserv-88e3d219588052a8ab222ab4f6f2b27c9c29c1b2.tar.xz
manaserv-88e3d219588052a8ab222ab4f6f2b27c9c29c1b2.zip
Added global accounting of beings.
-rw-r--r--ChangeLog7
-rw-r--r--src/Makefile.am1
-rw-r--r--src/account-server/main-account.cpp43
-rw-r--r--src/account-server/serverhandler.cpp53
-rw-r--r--src/account-server/serverhandler.hpp6
-rw-r--r--src/game-server/accountconnection.cpp46
-rw-r--r--src/game-server/accountconnection.hpp7
-rw-r--r--src/game-server/main-game.cpp1
8 files changed, 156 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog
index c2b0daa2..22f48f60 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -7,6 +7,13 @@
* src/chat-server/chathandler.hpp: Fixed missing header.
* src/account-server/serverhandler.cpp: Moved map/server data into
connection local storage.
+ * src/game-server/accountconnection.cpp, src/game-server/main-game.cpp,
+ src/game-server/accountconnection.hpp: Added statistic sender to
+ game server.
+ * src/account-server/serverhandler.cpp,
+ src/account-server/serverhandler.hpp, src/Makefile.am,
+ src/account-server/main-account.cpp: Added statistic receiver and
+ dumper to account server.
2007-09-10 Eugenio Favalli <elvenprogrammer@gmail.com>
diff --git a/src/Makefile.am b/src/Makefile.am
index f63ef660..7f2dcba7 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -60,6 +60,7 @@ tmwserv_account_SOURCES = \
utils/processorutils.cpp \
utils/stringfilter.h \
utils/stringfilter.cpp \
+ utils/timer.cpp \
utils/tokencollector.hpp \
utils/tokencollector.cpp \
utils/tokendispenser.hpp \
diff --git a/src/account-server/main-account.cpp b/src/account-server/main-account.cpp
index 1aacf2fb..68cb134b 100644
--- a/src/account-server/main-account.cpp
+++ b/src/account-server/main-account.cpp
@@ -24,6 +24,7 @@
#include <getopt.h>
#include <signal.h>
#include <iostream>
+#include <fstream>
#include <physfs.h>
#include <enet/enet.h>
@@ -44,13 +45,15 @@
#include "utils/logger.h"
#include "utils/processorutils.hpp"
#include "utils/stringfilter.h"
+#include "utils/timer.h"
// Default options that automake should be able to override.
#define DEFAULT_LOG_FILE "tmwserv-account.log"
+#define DEFAULT_STATS_FILE "tmwserv.stats"
#define DEFAULT_CONFIG_FILE "tmwserv.xml"
#define DEFAULT_ITEMSDB_FILE "items.xml"
-bool running = true; /**< Determines if server keeps running */
+static bool running = true; /**< Determines if server keeps running */
Configuration config; /**< XML config reader */
@@ -75,7 +78,7 @@ ChatChannelManager *chatChannelManager;
GuildManager *guildManager;
/** Callback used when SIGQUIT signal is received. */
-void closeGracefully(int)
+static void closeGracefully(int)
{
running = false;
}
@@ -83,7 +86,7 @@ void closeGracefully(int)
/**
* Initializes the server.
*/
-void initialize()
+static void initialize()
{
// Reset to default segmentation fault handling for debugging purposes
@@ -185,7 +188,7 @@ void initialize()
/**
* Deinitializes the server.
*/
-void deinitialize()
+static void deinitialize()
{
delete stringFilter;
// Write configuration file
@@ -211,11 +214,35 @@ void deinitialize()
PHYSFS_deinit();
}
+/**
+ * Dumps statistics.
+ */
+static void dumpStatistics()
+{
+#if defined STATS_FILE
+ std::string path = STATS_FILE;
+#else
+
+#if (defined __USE_UNIX98 || defined __FreeBSD__)
+ std::string path = getenv("HOME");
+ path += "/.";
+ path += DEFAULT_STATS_FILE;
+#else // Win32, ...
+ std::string path = DEFAULT_STATS_FILE;
+#endif
+
+#endif
+
+ std::ofstream os(path.c_str());
+ os << "<statistics>\n";
+ serverHandler->dumpStatistics(os);
+ os << "</statistics>\n";
+}
/**
* Show command line arguments
*/
-void printHelp()
+static void printHelp()
{
std::cout << "tmwserv" << std::endl << std::endl
<< "Options: " << std::endl
@@ -228,7 +255,7 @@ void printHelp()
/**
* Parse the command line arguments
*/
-void parseOptions(int argc, char *argv[])
+static void parseOptions(int argc, char *argv[])
{
const char *optstring = "h";
@@ -293,10 +320,14 @@ int main(int argc, char *argv[])
return 3;
}
+ // Dump statistics every 10 seconds.
+ utils::Timer statTimer(10000);
+
while (running) {
accountHandler->process(50);
chatHandler->process(50);
serverHandler->process(50);
+ if (statTimer.poll()) dumpStatistics();
}
LOG_INFO("Received: Quit signal, closing down...");
diff --git a/src/account-server/serverhandler.cpp b/src/account-server/serverhandler.cpp
index 87f99c81..39e63c6e 100644
--- a/src/account-server/serverhandler.cpp
+++ b/src/account-server/serverhandler.cpp
@@ -249,6 +249,32 @@ void ServerHandler::processMessage(NetComputer *comp, MessageIn &msg)
storage->banCharacter(id, duration);
} break;
+ case GAMSG_STATISTICS:
+ {
+ while (msg.getUnreadLength())
+ {
+ int mapId = msg.readShort();
+ ServerStatistics::iterator i = server->maps.find(mapId);
+ if (i == server->maps.end())
+ {
+ LOG_ERROR("Server " << server->address << ':'
+ << server->port << " should not be sending stati"
+ "stics for map " << mapId << '.');
+ // Skip remaining data.
+ break;
+ }
+ MapStatistics &m = i->second;
+ m.nbThings = msg.readShort();
+ m.nbMonsters = msg.readShort();
+ int nb = msg.readShort();
+ m.players.resize(nb);
+ for (int j = 0; j < nb; ++j)
+ {
+ m.players[j] = msg.readLong();
+ }
+ }
+ } break;
+
#if 0
case GAMSG_GUILD_CREATE:
{
@@ -424,6 +450,33 @@ void ServerHandler::processMessage(NetComputer *comp, MessageIn &msg)
comp->send(result);
}
+void ServerHandler::dumpStatistics(std::ostream &os) const
+{
+ for (NetComputers::const_iterator i = clients.begin(),
+ i_end = clients.end(); i != i_end; ++i)
+ {
+ GameServer *server = static_cast< GameServer * >(*i);
+ if (!server->port) continue;
+ os << "<gameserver address=\"" << server->address << "\" port=\""
+ << server->port << "\">\n";
+
+ for (ServerStatistics::const_iterator j = server->maps.begin(),
+ j_end = server->maps.end(); j != j_end; ++j)
+ {
+ MapStatistics const &m = j->second;
+ os << "<map id=\"" << j->first << "\" nb_things=\"" << m.nbThings
+ << "\" nb_monsters=\"" << m.nbMonsters << "\">\n";
+ for (std::vector< int >::const_iterator k = m.players.begin(),
+ k_end = m.players.end(); k != k_end; ++k)
+ {
+ os << "<character id=\"" << *k << "\"/>\n";
+ }
+ os << "</map>\n";
+ }
+ os << "</gameserver>\n";
+ }
+}
+
#if 0
void ServerHandler::enterChannel(const std::string &name,
CharacterData *player)
diff --git a/src/account-server/serverhandler.hpp b/src/account-server/serverhandler.hpp
index febc663e..76151569 100644
--- a/src/account-server/serverhandler.hpp
+++ b/src/account-server/serverhandler.hpp
@@ -24,6 +24,7 @@
#ifndef _TMWSERV_SERVERHANDLER_H_
#define _TMWSERV_SERVERHANDLER_H_
+#include <iosfwd>
#include <string>
#include "net/connectionhandler.hpp"
@@ -68,6 +69,11 @@ class ServerHandler: public ConnectionHandler
*/
void enterChannel(const std::string &guildName, Character *player);
+ /**
+ * Dumps per-server statistics into given stream
+ */
+ void dumpStatistics(std::ostream &) const;
+
protected:
/**
* Processes server messages.
diff --git a/src/game-server/accountconnection.cpp b/src/game-server/accountconnection.cpp
index 9a2084df..4219b33d 100644
--- a/src/game-server/accountconnection.cpp
+++ b/src/game-server/accountconnection.cpp
@@ -21,9 +21,10 @@
* $Id$
*/
+#include "game-server/accountconnection.hpp"
+
#include "configuration.h"
#include "defines.h"
-#include "game-server/accountconnection.hpp"
#include "game-server/character.hpp"
#include "game-server/gamehandler.hpp"
#include "game-server/map.hpp"
@@ -260,6 +261,49 @@ void AccountConnection::banCharacter(Character *ch, int duration)
send(msg);
}
+void AccountConnection::sendStatistics()
+{
+ MessageOut msg(GAMSG_STATISTICS);
+ MapManager::Maps const &maps = MapManager::getMaps();
+ for (MapManager::Maps::const_iterator i = maps.begin(),
+ i_end = maps.end(); i != i_end; ++i)
+ {
+ MapComposite *m = i->second;
+ if (!m->isActive()) continue;
+ msg.writeShort(i->first);
+ int nbThings = 0, nbMonsters = 0;
+ typedef std::vector< Thing * > Things;
+ Things const &things = m->getEverything();
+ std::vector< int > players;
+ for (Things::const_iterator j = things.begin(),
+ j_end = things.end(); j != j_end; ++j)
+ {
+ Thing *t = *j;
+ switch (t->getType())
+ {
+ case OBJECT_CHARACTER:
+ players.push_back
+ (static_cast< Character * >(t)->getDatabaseID());
+ break;
+ case OBJECT_MONSTER:
+ ++nbMonsters;
+ break;
+ default:
+ ++nbThings;
+ }
+ }
+ msg.writeShort(nbThings);
+ msg.writeShort(nbMonsters);
+ msg.writeShort(players.size());
+ for (std::vector< int >::const_iterator j = players.begin(),
+ j_end = players.end(); j != j_end; ++j)
+ {
+ msg.writeLong(*j);
+ }
+ }
+ send(msg);
+}
+
#if 0
void AccountConnection::playerCreateGuild(int id, const std::string &guildName)
{
diff --git a/src/game-server/accountconnection.hpp b/src/game-server/accountconnection.hpp
index b591df16..59652dd5 100644
--- a/src/game-server/accountconnection.hpp
+++ b/src/game-server/accountconnection.hpp
@@ -64,7 +64,12 @@ class AccountConnection : public Connection
/**
* Sends ban message.
*/
- void banCharacter(Character *, int);
+ void banCharacter(Character *, int);
+
+ /**
+ * Gathers statistics and sends them.
+ */
+ void sendStatistics();
#if 0
/**
diff --git a/src/game-server/main-game.cpp b/src/game-server/main-game.cpp
index 0325f28c..db8fee45 100644
--- a/src/game-server/main-game.cpp
+++ b/src/game-server/main-game.cpp
@@ -301,6 +301,7 @@ int main(int argc, char *argv[])
// Print world time at 10 second intervals to show we're alive
if (worldTime % 100 == 0) {
LOG_INFO("World time: " << worldTime);
+ accountHandler->sendStatistics();
}
// Handle all messages that are in the message queues