Skip to content

Commit

Permalink
[added] session stats
Browse files Browse the repository at this point in the history
Change-Id: I336fab0cbdd8a730564df644987c00d0d0650d4f
  • Loading branch information
karlbunch committed Jul 5, 2019
1 parent 7396569 commit cd5b463
Show file tree
Hide file tree
Showing 6 changed files with 183 additions and 1 deletion.
2 changes: 2 additions & 0 deletions MMOCoreORB/src/conf/ConfigManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ void ConfigManager::clearConfigData() {
cache_ProgressMonitors = false;
cache_UnloadContainers = false;
cache_UseMetrics = false;
cache_SessionStatsSeconds = 0;
}

void ConfigManager::cacheHotItems() {
Expand All @@ -107,6 +108,7 @@ void ConfigManager::cacheHotItems() {
cache_ProgressMonitors = getBool("Core3.ProgressMonitors", false);
cache_UnloadContainers = getBool("Core3.UnloadContainers", true);
cache_UseMetrics = getBool("Core3.UseMetrics", false);
cache_SessionStatsSeconds = getInt("Core3.SessionStatsSeconds", 3600);
}

void ConfigManager::dumpConfig(bool includeSecure) {
Expand Down
5 changes: 5 additions & 0 deletions MMOCoreORB/src/conf/ConfigManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ namespace conf {
bool cache_ProgressMonitors;
bool cache_UnloadContainers;
bool cache_UseMetrics;
int cache_SessionStatsSeconds;

public:
ConfigManager();
Expand Down Expand Up @@ -493,6 +494,10 @@ namespace conf {
inline int getMaxLogLines() {
return getInt("Core3.MaxLogLines", 1000000);
}

inline int getSessionStatsSeconds() {
return cache_SessionStatsSeconds;
}
};
}

Expand Down
25 changes: 24 additions & 1 deletion MMOCoreORB/src/server/db/ServerDatabase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,13 @@ ServerDatabase::ServerDatabase(ConfigManager* configManager) {
String createTable = "CREATE TABLE `db_metadata` AS SELECT 1000 as `schema_version`;";
try {
Reference<ResultSet*> result = instance()->executeQuery(createTable);
updateDatabaseSchema();
} catch (Exception& e) {
error("Failed to create db_metadata table, please manually create in mysql: " + createTable);
}
}

updateDatabaseSchema();

info("schema_version = " + String::valueOf(dbSchemaVersion), true);
}

Expand Down Expand Up @@ -85,4 +86,26 @@ void ServerDatabase::updateDatabaseSchema() {
" ADD COLUMN `galaxy_id` INT(5) DEFAULT -1 AFTER `account_id`,"
" ADD COLUMN `online_count` INT(4) DEFAULT -1 AFTER `logout`;"
);

alterDatabase(1002,
"CREATE TABLE `session_stats` ("
"`timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP"
",`ip` char(15) NOT NULL"
",`galaxy_id` int(5) DEFAULT '-1'"
",`account_id` int(10) unsigned NOT NULL"
",`character_oid` bigint(20) NOT NULL"
",`session_seconds` int(10) unsigned NOT NULL"
",`delta_seconds` int(10) unsigned NOT NULL"
",`delta_credits` int(11) NOT NULL"
",`delta_skillpoints` int(3) NOT NULL"
",`activity_xp` int(10) unsigned NOT NULL"
",`activity_movement` int(5) unsigned NOT NULL"
",`current_credits` int(11) unsigned NOT NULL"
",`ip_account_count` int(2) unsigned NOT NULL"
",`session_end` int(1) unsigned NOT NULL"
",KEY `idx_timestamp` (`timestamp`)"
",KEY `idx_ip` (`ip`)"
",KEY `idx_galaxy_ip` (`galaxy_id`,`ip`,`account_id`,`character_oid`)"
") ENGINE=MyISAM DEFAULT CHARSET=latin1;"
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3437,6 +3437,8 @@ int PlayerManagerImplementation::checkSpeedHackSecondTest(CreatureObject* player

if (ghost->isOnLoadScreen())
ghost->setOnLoadScreen(false);

ghost->incrementSessionMovement(dist);
}

return ret;
Expand Down
10 changes: 10 additions & 0 deletions MMOCoreORB/src/server/zone/objects/player/PlayerObject.idl
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,12 @@ class PlayerObject extends IntangibleObject {

protected unsigned long miliSecsPlayed;
protected unsigned long miliSecsSession;
protected unsigned long sessionStatsMiliSecs;
protected transient unsigned long sessionStatsLastCredits;
protected transient int sessionStatsLastSkillPoints;
protected transient unsigned long sessionStatsActivityXP;
protected transient unsigned long sessionStatsActivityMovement;
protected transient string sessionStatsIPAddress;

public static final int LFG = 1;
public static final int NEWBIEHELPER = 2;
Expand Down Expand Up @@ -1200,6 +1206,10 @@ class PlayerObject extends IntangibleObject {
*/
public native void notifyOffline();

public native void resetSessionStats(boolean isSessionStart);
public native void incrementSessionMovement(float moveDelta);
public native void logSessionStats(boolean isSessionEnd);

public void setBadge(unsigned int badge) {
badges.setBadge(badge);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@
#include "server/zone/objects/player/sui/messagebox/SuiMessageBox.h"
#include "server/chat/PendingMessageList.h"
#include "server/zone/managers/director/DirectorManager.h"
#include "server/db/ServerDatabase.h"
#include "server/ServerCore.h"

void PlayerObjectImplementation::initializeTransientMembers() {
playerLogLevel = ConfigManager::instance()->getPlayerLogLevel();
Expand All @@ -88,6 +90,13 @@ void PlayerObjectImplementation::initializeTransientMembers() {
setLoggingName("PlayerObject");

initializeAccount();

sessionStatsMiliSecs = 0;
sessionStatsLastCredits = 0;
sessionStatsLastSkillPoints = 0;
sessionStatsActivityXP = 0;
sessionStatsActivityMovement = 0;
sessionStatsIPAddress = "";
}

PlayerObject* PlayerObjectImplementation::asPlayerObject() {
Expand Down Expand Up @@ -552,6 +561,9 @@ int PlayerObjectImplementation::addExperience(const String& xpType, int xp, bool

Locker locker(_this.getReferenceUnsafeStaticCast());

if (xp > 0)
sessionStatsActivityXP += xp; // Count all xp as we're looking for activity not caps etc.

if (experienceList.contains(xpType)) {
xp += experienceList.get(xpType);

Expand Down Expand Up @@ -1282,6 +1294,8 @@ void PlayerObjectImplementation::notifyOnline() {

miliSecsSession = 0;

resetSessionStats(true);

ChatManager* chatManager = server->getChatManager();
ZoneServer* zoneServer = server->getZoneServer();

Expand Down Expand Up @@ -1398,6 +1412,128 @@ void PlayerObjectImplementation::notifyOffline() {
if (missionManager != nullptr && playerCreature->hasSkill("force_title_jedi_rank_02")) {
missionManager->updatePlayerBountyOnlineStatus(playerCreature->getObjectID(), false);
}

logSessionStats(true);
}

void PlayerObjectImplementation::incrementSessionMovement(float moveDelta) {
sessionStatsActivityMovement += (int)moveDelta;
}

void PlayerObjectImplementation::resetSessionStats(bool isSessionStart) {
sessionStatsActivityXP = 0;
sessionStatsActivityMovement = 0;
sessionStatsLastSkillPoints = skillPoints;

Reference<SceneObject*> parent = getParent().get();

if (parent != nullptr) {
CreatureObject* playerCreature = parent->asCreatureObject();

if (playerCreature != nullptr) {
sessionStatsLastCredits = playerCreature->getCashCredits() + playerCreature->getBankCredits();

if (sessionStatsIPAddress.isEmpty()) {
auto client = playerCreature->getClient();

if (client != nullptr)
sessionStatsIPAddress = client->getIPAddress();
}
}
} else
error("parent == nullptr in resetSessionStats");

sessionStatsMiliSecs = 0;
}

void PlayerObjectImplementation::logSessionStats(bool isSessionEnd) {
// Wait for stable state before logging
if (sessionStatsMiliSecs == 0 || sessionStatsIPAddress.isEmpty())
return;

int galaxyID = 0;
uint64 objectID = 0;
int64 currentCredits = sessionStatsLastCredits;

Reference<SceneObject*> parent = getParent().get();

if (parent != nullptr) {
objectID = parent->getObjectID();

CreatureObject* playerCreature = parent->asCreatureObject();

if (playerCreature != nullptr) {
currentCredits = playerCreature->getCashCredits() + playerCreature->getBankCredits();
galaxyID = playerCreature->getZoneServer()->getGalaxyID();
} else {
error("playerCreature == nullptr in logSessionStats");
}
} else {
error("parent == nullptr in logSessionStats");
}

int skillPointDelta = skillPoints - sessionStatsLastSkillPoints;
int64 creditsDelta = (int64)currentCredits - (int64)sessionStatsLastCredits;

int ipAccountCount = 0;

if (!sessionStatsIPAddress.isEmpty()) {
SortedVector<uint32> loggedInAccounts = getZoneServer()->getPlayerManager()->getOnlineZoneClientMap()->getAccountsLoggedIn(sessionStatsIPAddress);
ipAccountCount = loggedInAccounts.size();
}

// Need the session_stats table to log to database
if (ServerCore::getSchemaVersion() >= 1002) {
StringBuffer query;

query << "INSERT INTO `session_stats` ("
<< "`account_id`, `galaxy_id`, `character_oid`, `ip`, `session_end`"
<< ", `session_seconds`, `delta_seconds`, `delta_credits`, `delta_skillpoints`"
<< ", `activity_xp`, `activity_movement`, `current_credits`, `ip_account_count`"
<< ") VALUES"
<< " (" << getAccountID()
<< ", " << galaxyID
<< ", " << objectID
<< ", '" << sessionStatsIPAddress << "'"
<< ", " << isSessionEnd
<< ", " << (int)(miliSecsSession / 1000.0f)
<< ", " << (int)(sessionStatsMiliSecs / 1000.0f)
<< ", " << creditsDelta
<< ", " << skillPointDelta
<< ", " << sessionStatsActivityXP
<< ", " << sessionStatsActivityMovement
<< ", " << currentCredits
<< ", " << ipAccountCount
<< ");"
;

Core::getTaskManager()->executeTask([=] () {
try {
ServerDatabase::instance()->executeStatement(query);
} catch(DatabaseException& e) {
error(e.getMessage());
}
}, "logSessionStats");
} else {
StringBuffer logMsg;

logMsg << "SessionStats:"
<< " isSessionEnd: " << isSessionEnd
<< " sessionSeconds: " << (int)(miliSecsSession / 1000.0f)
<< " logSeconds: " << (int)(sessionStatsMiliSecs / 1000.0f)
<< " creditsDelta: " << creditsDelta
<< " skillPointDelta: " << skillPointDelta
<< " activityXP: " << sessionStatsActivityXP
<< " activityMovement: " << sessionStatsActivityMovement
<< " ip: " << sessionStatsIPAddress
<< " ipAccountCount: " << ipAccountCount
<< " currentCredits: " << currentCredits
;

info(logMsg.toString(), true);
}

resetSessionStats(false);
}

void PlayerObjectImplementation::setLanguageID(byte language, bool notifyClient) {
Expand Down Expand Up @@ -1708,6 +1844,10 @@ void PlayerObjectImplementation::doRecovery(int latency) {

miliSecsPlayed += latency;
miliSecsSession += latency;
sessionStatsMiliSecs += latency;

if (sessionStatsMiliSecs >= ConfigManager::instance()->getSessionStatsSeconds() * 1000)
logSessionStats(false);
}

if (cooldownTimerMap->isPast("spawnCheckTimer")) {
Expand Down

0 comments on commit cd5b463

Please sign in to comment.