- added game statistics gathering and saving on masterserver.

see Table glestserver now has the field: gameUUID
Table glestgamestats has game header stats
Table glestgameplayerstats has game player stats
This commit is contained in:
Mark Vejvoda
2013-10-31 00:57:36 +00:00
parent c0150e752f
commit 7ad30f92bf
48 changed files with 9641 additions and 9188 deletions

View File

@@ -4,6 +4,7 @@
# Written by Mark Vejvoda <mark_vejvoda@hotmail.com>
# Copyright (c) 2011 Mark Vejvoda under GNU GPL v3.0+
echo 'Requires tools from: sudo apt-get install tofrodos'
cd ../../
find -name "*\.cpp" -exec fromdos -d {} \;
find -name "*\.c" -exec fromdos -d {} \;
@@ -13,4 +14,7 @@ find -name "*\.lng" -exec fromdos -d {} \;
find -name "*\.xml" -exec fromdos -d {} \;
find -name "*\.ini" -exec fromdos -d {} \;
find -name "*\.sh" -exec fromdos -d {} \;
find -name "*\.php" -exec fromdos -d {} \;
find -name "*\.sql" -exec fromdos -d {} \;
find -name "*\.pl" -exec fromdos -d {} \;

View File

@@ -19,3 +19,11 @@ find ${CURRENTDIR}/../../data/glest_game/ -iname '*.xml' -exec svn propset svn:m
find ${CURRENTDIR}/ -iname '*.sh' -exec svn propset svn:mime-type text/plain '{}' \;
find ${CURRENTDIR}/ -iname '*.sh' -exec svn propset svn:eol-style native '{}' \;
# php scripts
find ${CURRENTDIR}/../../source/masterserver -iname '*.php' -exec svn propset svn:mime-type text/plain '{}' \;
find ${CURRENTDIR}/../../source/masterserver -iname '*.php' -exec svn propset svn:eol-style native '{}' \;
# sql scripts
find ${CURRENTDIR}/../../source/masterserver -iname '*.sql' -exec svn propset svn:mime-type text/plain '{}' \;
find ${CURRENTDIR}/../../source/masterserver -iname '*.sql' -exec svn propset svn:eol-style native '{}' \;

View File

@@ -1567,6 +1567,8 @@ void Game::init(bool initForPreviewOnly) {
}
}
printf("Game unique identifier is: %s\n",this->gameSettings.getGameUUID().c_str());
gameStarted = true;
if(this->masterserverMode == true) {
@@ -2281,6 +2283,8 @@ void Game::update() {
if(role == nrServer) {
ServerInterface *server = NetworkManager::getInstance().getServerInterface();
server->setGameStats(world.getStats());
if(server->getPauseForInGameConnection() == true) {
bool clientNeedsGameSetup = false;
@@ -6521,6 +6525,7 @@ void Game::loadGame(string name,Program *programPtr,bool isMasterserverMode,cons
}
Game *newGame = new Game(programPtr, &newGameSettings, isMasterserverMode);
newGame->loadGameNode = gameNode;
newGame->inJoinGameLoading = (joinGameSettings != NULL);

View File

@@ -59,7 +59,8 @@ enum LoadGameItem {
//
// Main game class
// =====================================================
class Game: public ProgramState, public FileCRCPreCacheThreadCallbackInterface, public CustomInputCallbackInterface {
class Game: public ProgramState, public FileCRCPreCacheThreadCallbackInterface,
public CustomInputCallbackInterface {
public:
static const float highlightTime;

View File

@@ -135,6 +135,8 @@ private:
bool networkAllowNativeLanguageTechtree;
string gameUUID;
public:
static string playerDisconnectedText;
@@ -361,6 +363,8 @@ public:
uint32 getTechCRC() const { return techCRC; }
vector<pair<string,uint32> > getFactionCRCList() const { return factionCRCList; }
const string &getGameUUID() const {return gameUUID;}
//set
void setDescription(const string& description) {this->description= description;}
void setMap(const string& map) {this->map= map;}
@@ -505,13 +509,15 @@ public:
int getMasterserver_admin_faction_index() const { return masterserver_admin_factionIndex;}
void setMasterserver_admin_faction_index(int value) { masterserver_admin_factionIndex = value; }
bool getNetworkAllowNativeLanguageTechtree() const { return networkAllowNativeLanguageTechtree;}
void setNetworkAllowNativeLanguageTechtree(bool value) { networkAllowNativeLanguageTechtree = value; }
void setGameUUID(const string& gameUUID) {this->gameUUID= gameUUID;}
string toString() const {
string result = "";
result += "Game ID = " + gameUUID + "\n";
result += "description = " + description + "\n";
result += "mapFilterIndex = " + intToStr(mapFilterIndex) + "\n";
result += "map = " + map + "\n";
@@ -566,6 +572,8 @@ public:
std::map<string,string> mapTagReplacements;
XmlNode *gameSettingsNode = rootNode->addChild("GameSettings");
gameSettingsNode->addAttribute("gameUUID",gameUUID, mapTagReplacements);
// string description;
gameSettingsNode->addAttribute("description",description, mapTagReplacements);
// string map;
@@ -694,6 +702,10 @@ public:
void loadGame(const XmlNode *rootNode) {
const XmlNode *gameSettingsNode = rootNode->getChild("GameSettings");
if(gameSettingsNode->hasAttribute("gameUUID") == true) {
gameUUID = gameSettingsNode->getAttribute("gameUUID")->getValue();
}
// string description;
description = gameSettingsNode->getAttribute("description")->getValue();
// string map;

View File

@@ -216,8 +216,6 @@ void Stats::saveGame(XmlNode *rootNode) {
statsNode->addAttribute("framesPlayed",intToStr(framesPlayed), mapTagReplacements);
// int framesToCalculatePlaytime;
statsNode->addAttribute("framesToCalculatePlaytime",intToStr(framesToCalculatePlaytime), mapTagReplacements);
// time_t timePlayed;
statsNode->addAttribute("timePlayed",intToStr(timePlayed), mapTagReplacements);
// int maxConcurrentUnitCount;
statsNode->addAttribute("maxConcurrentUnitCount",intToStr(maxConcurrentUnitCount), mapTagReplacements);
// int totalEndGameConcurrentUnitCount;
@@ -276,8 +274,6 @@ void Stats::loadGame(const XmlNode *rootNode) {
framesPlayed = statsNode->getAttribute("framesPlayed")->getIntValue();
// int framesToCalculatePlaytime;
framesToCalculatePlaytime = statsNode->getAttribute("framesToCalculatePlaytime")->getIntValue();
// time_t timePlayed;
timePlayed = statsNode->getAttribute("timePlayed")->getIntValue();
// int maxConcurrentUnitCount;
maxConcurrentUnitCount = statsNode->getAttribute("maxConcurrentUnitCount")->getIntValue();
// int totalEndGameConcurrentUnitCount;

View File

@@ -69,7 +69,6 @@ private:
float worldTimeElapsed;
int framesPlayed;
int framesToCalculatePlaytime;
time_t timePlayed;
int maxConcurrentUnitCount;
int totalEndGameConcurrentUnitCount;
bool isMasterserverMode;
@@ -88,7 +87,6 @@ public:
maxConcurrentUnitCount = 0;
totalEndGameConcurrentUnitCount = 0;
isMasterserverMode = false;
timePlayed = 0;
//techName = "";
}

View File

@@ -32,6 +32,7 @@
#include "map_preview.h"
#include "string_utils.h"
#include "network_message.h"
#include "gen_uuid.h"
#include "leak_dumper.h"
namespace Glest{ namespace Game{
@@ -68,6 +69,8 @@ MenuStateCustomGame::MenuStateCustomGame(Program *program, MainMenu *mainMenu,
printf("Waiting for players to join and start a game...\n");
}
this->gameUUID = getUUIDAsString();
this->lastMasterServerSettingsUpdateCount = 0;
this->masterserverModeMinimalResources = true;
this->parentMenuState=parentMenuState;
@@ -2886,6 +2889,7 @@ void MenuStateCustomGame::publishToMasterserver() {
publishToServerInfo["gameStatus"] = intToStr(game_status_waiting_for_start);
}
publishToServerInfo["gameUUID"] = gameSettings.getGameUUID();
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
}
@@ -2970,7 +2974,8 @@ void MenuStateCustomGame::simpleTask(BaseThread *callingThread) {
}
}
//printf("the request is:\n%s\n",request.c_str());
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("The Lobby request is:\n%s\n",request.c_str());
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d] the request is:\n%s\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,request.c_str());
safeMutex.ReleaseLock(true);
safeMutexThreadOwner.ReleaseLock();
@@ -3131,6 +3136,8 @@ void MenuStateCustomGame::loadGameSettings(GameSettings *gameSettings,bool force
gameSettings->setScenarioDir("");
}
gameSettings->setGameUUID(this->gameUUID);
//printf("scenarioInfo.name [%s] [%s] [%s]\n",scenarioInfo.name.c_str(),listBoxMap.getSelectedItem().c_str(),getCurrentMapFile().c_str());
gameSettings->setMapFilterIndex(listBoxMapFilter.getSelectedItemIndex());

View File

@@ -219,6 +219,7 @@ private:
std::auto_ptr<TechTree> techTree;
string gameUUID;
public:
MenuStateCustomGame(Program *program, MainMenu *mainMenu ,
bool openNetworkSlots= false, ParentMenuState parentMenuState=pNewGame,

View File

@@ -36,8 +36,6 @@ using namespace Shared::Platform;
namespace Glest{ namespace Game{
//class GameSettings;
// =====================================================
// class NetworkInterface
// =====================================================

View File

@@ -547,6 +547,7 @@ NetworkMessageLaunch::NetworkMessageLaunch(const GameSettings *gameSettings,int8
data.masterserver_admin_factionIndex = gameSettings->getMasterserver_admin_faction_index();
data.scenario = gameSettings->getScenario();
data.gameUUID = gameSettings->getGameUUID();
data.networkAllowNativeLanguageTechtree = gameSettings->getNetworkAllowNativeLanguageTechtree();
}
@@ -606,6 +607,8 @@ void NetworkMessageLaunch::buildGameSettings(GameSettings *gameSettings) const {
gameSettings->setScenario(data.scenario.getString());
gameSettings->setGameUUID(data.gameUUID.getString());
gameSettings->setNetworkAllowNativeLanguageTechtree(data.networkAllowNativeLanguageTechtree);
}
@@ -621,7 +624,7 @@ vector<pair<string,uint32> > NetworkMessageLaunch::getFactionCRCList() const {
}
const char * NetworkMessageLaunch::getPackedMessageFormat() const {
return "c256s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60sllllllll60s60s60s60s60s60s60s60sLLL60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60sLLLLLLLLLLLLLLLLLLLLcccccccccccccccccccccccccccccccccccccccccCccLccll256s60s60s60s60s60s60s60s60sc";
return "c256s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60sllllllll60s60s60s60s60s60s60s60sLLL60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60sLLLLLLLLLLLLLLLLLLLLcccccccccccccccccccccccccccccccccccccccccCccLccll256s60s60s60s60s60s60s60s60sc60s";
}
unsigned int NetworkMessageLaunch::getPackedSize() {
@@ -768,7 +771,8 @@ unsigned int NetworkMessageLaunch::getPackedSize() {
packedData.networkPlayerUUID[5].getBuffer(),
packedData.networkPlayerUUID[6].getBuffer(),
packedData.networkPlayerUUID[7].getBuffer(),
packedData.networkAllowNativeLanguageTechtree
packedData.networkAllowNativeLanguageTechtree,
packedData.gameUUID.getBuffer()
);
delete [] buf;
}
@@ -914,7 +918,8 @@ void NetworkMessageLaunch::unpackMessage(unsigned char *buf) {
data.networkPlayerUUID[5].getBuffer(),
data.networkPlayerUUID[6].getBuffer(),
data.networkPlayerUUID[7].getBuffer(),
&data.networkAllowNativeLanguageTechtree
&data.networkAllowNativeLanguageTechtree,
data.gameUUID.getBuffer()
);
}
@@ -1059,7 +1064,8 @@ unsigned char * NetworkMessageLaunch::packMessage() {
data.networkPlayerUUID[5].getBuffer(),
data.networkPlayerUUID[6].getBuffer(),
data.networkPlayerUUID[7].getBuffer(),
data.networkAllowNativeLanguageTechtree
data.networkAllowNativeLanguageTechtree,
data.gameUUID.getBuffer()
);
return buf;
}
@@ -1096,6 +1102,8 @@ bool NetworkMessageLaunch::receive(Socket* socket) {
data.scenario.nullTerminate();
data.gameUUID.nullTerminate();
//for(int i= 0; i < GameConstants::maxPlayers; ++i){
// printf("Receive index: %d resource multiplier index: %d sizeof(data): %d\n",i,data.resourceMultiplierIndex[i],sizeof(data));
//}

View File

@@ -299,6 +299,7 @@ private:
NetworkString<maxSmallStringSize> networkPlayerUUID[GameConstants::maxPlayers];
int8 networkAllowNativeLanguageTechtree;
NetworkString<maxSmallStringSize> gameUUID;
};
void toEndian();
void fromEndian();

View File

@@ -28,6 +28,7 @@
#include <iostream>
#include "map_preview.h"
#include <iterator>
#include "stats.h"
#include "leak_dumper.h"
using namespace std;
@@ -119,6 +120,9 @@ ServerInterface::ServerInterface(bool publishEnabled) :GameNetworkInterface() {
serverSocket.setBindPort(Config::getInstance().getInt("PortServer", intToStr(GameConstants::serverPort).c_str()));
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
gameStatsThreadAccessor = new Mutex();
gameStats = NULL;
Config &config = Config::getInstance();
vector<string> results;
string scenarioDir = "";
@@ -306,6 +310,12 @@ ServerInterface::~ServerInterface() {
delete switchSetupRequestsSynchAccessor;
switchSetupRequestsSynchAccessor = NULL;
delete gameStatsThreadAccessor;
gameStatsThreadAccessor = NULL;
delete gameStats;
gameStats = NULL;
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
}
@@ -2781,10 +2791,67 @@ std::map<string,string> ServerInterface::publishToMasterserver() {
publishToServerInfo["gameCmd"]= "gameOver";
publishToServerInfo["gameStatus"] = intToStr(game_status_finished);
}
//printf("Host game id = %s\n",this->getGameSettings()->getGameUUID().c_str());
publishToServerInfo["gameUUID"] = this->getGameSettings()->getGameUUID();
//if(statsInterface != NULL) {
//
//}
// !!!
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
return publishToServerInfo;
}
std::map<string,string> ServerInterface::publishToMasterserverStats() {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
MutexSafeWrapper safeMutex(gameStatsThreadAccessor,CODE_AT_LINE);
std::map < string, string > publishToServerInfo;
if(gameStats != NULL) {
publishToServerInfo["gameUUID"] = this->getGameSettings()->getGameUUID();
publishToServerInfo["tech"] = this->getGameSettings()->getTech();
publishToServerInfo["factionCount"] = intToStr(gameStats->getFactionCount());
publishToServerInfo["framesPlayed"] = intToStr(gameStats->getFramesPlayed());
publishToServerInfo["framesToCalculatePlaytime"] = intToStr(gameStats->getFramesToCalculatePlaytime());
publishToServerInfo["maxConcurrentUnitCount"] = intToStr(gameStats->getMaxConcurrentUnitCount());
publishToServerInfo["totalEndGameConcurrentUnitCount"] = intToStr(gameStats->getTotalEndGameConcurrentUnitCount());
publishToServerInfo["isHeadlessServer"] = intToStr(gameStats->getIsMasterserverMode());
for(int factionIndex = 0; factionIndex < gameStats->getFactionCount(); ++factionIndex) {
publishToServerInfo["factionIndex_" + intToStr(factionIndex)] = intToStr(factionIndex);
publishToServerInfo["controlType_" + intToStr(factionIndex)] = intToStr(gameStats->getControl(factionIndex));
publishToServerInfo["resourceMultiplier_" + intToStr(factionIndex)] = floatToStr(gameStats->getResourceMultiplier(factionIndex));
publishToServerInfo["factionTypeName_" + intToStr(factionIndex)] = gameStats->getFactionTypeName(factionIndex);
publishToServerInfo["personalityType_" + intToStr(factionIndex)] = intToStr(gameStats->getPersonalityType(factionIndex));
publishToServerInfo["teamIndex_" + intToStr(factionIndex)] = intToStr(gameStats->getTeam(factionIndex));
publishToServerInfo["wonGame_" + intToStr(factionIndex)] = intToStr(gameStats->getVictory(factionIndex));
publishToServerInfo["killCount_" + intToStr(factionIndex)] = intToStr(gameStats->getKills(factionIndex));
publishToServerInfo["enemyKillCount_" + intToStr(factionIndex)] = intToStr(gameStats->getEnemyKills(factionIndex));
publishToServerInfo["deathCount_" + intToStr(factionIndex)] = intToStr(gameStats->getDeaths(factionIndex));
publishToServerInfo["unitsProducedCount_" + intToStr(factionIndex)] = intToStr(gameStats->getUnitsProduced(factionIndex));
publishToServerInfo["resourceHarvestedCount_" + intToStr(factionIndex)] = intToStr(gameStats->getResourcesHarvested(factionIndex));
publishToServerInfo["playerName_" + intToStr(factionIndex)] = gameStats->getPlayerName(factionIndex);
publishToServerInfo["quitBeforeGameEnd_" + intToStr(factionIndex)] = intToStr(gameStats->getPlayerLeftBeforeEnd(factionIndex));
publishToServerInfo["quitTime_" + intToStr(factionIndex)] = intToStr(gameStats->getTimePlayerLeft(factionIndex));
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
}
return publishToServerInfo;
}
void ServerInterface::setGameStats(Stats *stats) {
if(stats == NULL) {
return;
}
MutexSafeWrapper safeMutex(gameStatsThreadAccessor,CODE_AT_LINE);
if(gameStats == NULL) {
gameStats = new Stats();
}
*gameStats = *stats;
}
void ServerInterface::simpleTask(BaseThread *callingThread) {
MutexSafeWrapper safeMutex(masterServerThreadAccessor,CODE_AT_LINE);
@@ -2811,12 +2878,39 @@ void ServerInterface::simpleTask(BaseThread *callingThread) {
request += "&";
}
//printf("the request is:\n%s\n",request.c_str());
//printf("The Host request is:\n%s\n",request.c_str());
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("The Host request is:\n%s\n",request.c_str());
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line %d] the request is:\n%s\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,request.c_str());
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Calling masterserver [%s]...\n",request.c_str());
std::string serverInfo = SystemFlags::getHTTP(request,handle);
//printf("Result:\n%s\n",serverInfo .c_str());
string requestStats = Config::getInstance().getString("Masterserver") + "addGameStats.php?";
std::map<string,string> newPublishToServerInfoStats = publishToMasterserverStats();
if(newPublishToServerInfoStats.empty() == false) {
for(std::map<string,string>::const_iterator iterMap = newPublishToServerInfoStats.begin();
iterMap != newPublishToServerInfoStats.end(); ++iterMap) {
requestStats += iterMap->first;
requestStats += "=";
requestStats += SystemFlags::escapeURL(iterMap->second,handle);
requestStats += "&";
}
//printf("The Host stats request is:\n%s\n",requestStats.c_str());
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("The Host request is:\n%s\n",requestStats.c_str());
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line %d] the request is:\n%s\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,requestStats.c_str());
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Calling masterserver [%s]...\n",requestStats.c_str());
std::string serverInfoStats = SystemFlags::getHTTP(requestStats,handle);
//printf("Result:\n%s\n",serverInfoStats .c_str());
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line %d] the result is:\n'%s'\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,serverInfoStats.c_str());
}
SystemFlags::cleanupHTTP(&handle);
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Done Calling masterserver\n");

View File

@@ -31,6 +31,7 @@ namespace Shared { namespace PlatformCommon { class FTPServerThread; }}
namespace Glest{ namespace Game{
class Stats;
// =====================================================
// class ServerInterface
// =====================================================
@@ -103,10 +104,15 @@ private:
time_t resumeGameStartTime;
Mutex *gameStatsThreadAccessor;
Stats *gameStats;
public:
ServerInterface(bool publishEnabled);
virtual ~ServerInterface();
void setGameStats(Stats *gameStats);
virtual Socket* getSocket(bool mutexLock=true) {return &serverSocket;}
time_t getGameStartTime() const { return gameStartTime; }
@@ -240,7 +246,10 @@ private:
bool shouldDiscardNetworkMessage(NetworkMessageType networkMessageType, ConnectionSlot *connectionSlot);
void updateSlot(ConnectionSlotEvent *event);
void validateConnectedClients();
std::map<string,string> publishToMasterserver();
std::map<string,string> publishToMasterserverStats();
int64 getNextEventId();
void processTextMessageQueue();
void processBroadCastMessageQueue();

View File

@@ -23,6 +23,7 @@
#include "socket.h"
#include "config.h"
#include "platform_util.h"
#include "gen_uuid.h"
#include "leak_dumper.h"
using namespace Shared::Xml;
@@ -470,6 +471,11 @@ void Scenario::loadGameSettings(const vector<string> &dirList,
const ScenarioInfo *scenarioInfo, GameSettings *gameSettings,
string scenarioDescription) {
int factionCount= 0;
if(gameSettings->getGameUUID() == "") {
gameSettings->setGameUUID(getUUIDAsString());
}
gameSettings->setDescription(scenarioDescription);
gameSettings->setMap(scenarioInfo->mapName);
gameSettings->setTileset(scenarioInfo->tilesetName);

View File

@@ -187,8 +187,10 @@ public:
inline Faction *getFaction(int i) {return factions[i];}
inline const Minimap *getMinimap() const {return &minimap;}
inline Minimap *getMiniMapObject() {return &minimap;}
inline const Stats *getStats() const {return &stats;};
inline Stats *getStats() {return &stats;};
inline const WaterEffects *getWaterEffects() const {return &waterEffects;}
inline const WaterEffects *getAttackEffects() const {return &attackEffects;}
int getNextUnitId(Faction *faction);

View File

@@ -0,0 +1,242 @@
<?php
// Copyright (C) 2012 Mark Vejvoda, Titus Tscharntke and Tom Reynolds
// The Megaglest Team, under GNU GPL v3.0
// ==============================================================
define( 'INCLUSION_PERMITTED', true );
require_once( 'config.php' );
require_once( 'functions.php' );
// Consider using HTTP POST instead of HTTP GET here, data should always be sent via POST for privacy and security reasons
// Alternatively, do not retrieve (and transmit) this data at all via HTTP (other than the IP address the game servers advertises) but fetch it from the game server instead
// consider replacing this by a cron job
// cleanupServerList();
// Representation starts here (but it should really be starting much later, there is way too much logic behind this point)
header( 'Content-Type: text/plain; charset=utf-8' );
//echo '#0 ' . $_GET['gameUUID'];
if ( isset( $_GET['gameUUID'] ) ) {
define( 'DB_LINK', db_connect() );
$gameUUID = (string) clean_str( $_GET['gameUUID'] );
$whereClause = 'gameUUID=\'' . mysql_real_escape_string( $gameUUID ) . '\';';
$stats_in_db = @mysql_query( 'SELECT COUNT(*) FROM glestgamestats WHERE ' . $whereClause );
$statsCount = @mysql_fetch_row( $stats_in_db );
$player_stats_in_db = @mysql_query( 'SELECT COUNT(*) FROM glestgameplayerstats WHERE ' . $whereClause );
$player_statsCount = @mysql_fetch_row( $player_stats_in_db );
$gameUUID = (string) clean_str( $_GET['gameUUID'] );
$tech = (string) clean_str( $_GET['tech'] );
$factionCount = 0;
if ( isset( $_GET['factionCount'] ) ) {
$factionCount = (string) clean_str( $_GET['factionCount'] );
}
$framesPlayed = 0;
if ( isset( $_GET['framesPlayed'] ) ) {
$framesPlayed = (string) clean_str( $_GET['framesPlayed'] );
}
$framesToCalculatePlaytime = 0;
if ( isset( $_GET['framesToCalculatePlaytime'] ) ) {
$framesToCalculatePlaytime = (string) clean_str( $_GET['framesToCalculatePlaytime'] );
}
$maxConcurrentUnitCount = 0;
if ( isset( $_GET['maxConcurrentUnitCount'] ) ) {
$maxConcurrentUnitCount = (string) clean_str( $_GET['maxConcurrentUnitCount'] );
}
$totalEndGameConcurrentUnitCount = 0;
if ( isset( $_GET['totalEndGameConcurrentUnitCount'] ) ) {
$totalEndGameConcurrentUnitCount = (string) clean_str( $_GET['totalEndGameConcurrentUnitCount'] );
}
$isHeadlessServer = 0;
if ( isset( $_GET['isHeadlessServer'] ) ) {
$isHeadlessServer = (string) clean_str( $_GET['isHeadlessServer'] );
}
//echo '#1 ' . $whereClause;
//echo '#2 ' . $statsCount[0];
if ( $statsCount[0] > 0 ) // this game is contained in the database
{
// update database info on this game server; no checks are performed
$result = mysql_query( 'UPDATE glestgamestats SET ' .
'gameUUID=\'' . mysql_real_escape_string( $gameUUID ) . '\', ' .
'tech=\'' . mysql_real_escape_string( $tech ) . '\', ' .
'factionCount=\'' . mysql_real_escape_string( $factionCount ) . '\', ' .
'framesPlayed=\'' . mysql_real_escape_string( $framesPlayed ) . '\', ' .
'framesToCalculatePlaytime=\'' . mysql_real_escape_string( $framesToCalculatePlaytime ) . '\', ' .
'maxConcurrentUnitCount=\'' . mysql_real_escape_string( $maxConcurrentUnitCount ) . '\', ' .
'totalEndGameConcurrentUnitCount=\'' . mysql_real_escape_string( $totalEndGameConcurrentUnitCount ) . '\', ' .
'isHeadlessServer=\'' . mysql_real_escape_string( $isHeadlessServer ) . '\', ' .
'lasttime=' . 'now()' . ' ' .
'WHERE ' . $whereClause);
if (!$result) {
die('part 1a: Invalid query: ' . mysql_error());
}
echo 'OK1a';
}
else // this game server is not listed in the database, yet
{ // check whether this game server is available from the Internet; if it is, add it to the database
// update database info on this game server; no checks are performed
$result = mysql_query( 'INSERT INTO glestgamestats SET ' .
'gameUUID=\'' . mysql_real_escape_string( $gameUUID ) . '\', ' .
'tech=\'' . mysql_real_escape_string( $tech ) . '\', ' .
'factionCount=\'' . mysql_real_escape_string( $factionCount ) . '\', ' .
'framesPlayed=\'' . mysql_real_escape_string( $framesPlayed ) . '\', ' .
'framesToCalculatePlaytime=\'' . mysql_real_escape_string( $framesToCalculatePlaytime ) . '\', ' .
'maxConcurrentUnitCount=\'' . mysql_real_escape_string( $maxConcurrentUnitCount ) . '\', ' .
'totalEndGameConcurrentUnitCount=\'' . mysql_real_escape_string( $totalEndGameConcurrentUnitCount ) . '\', ' .
'isHeadlessServer=\'' . mysql_real_escape_string( $isHeadlessServer ) . '\';');
if (!$result) {
die('part 2a: Invalid query: ' . mysql_error());
}
echo 'OK2b';
}
for ( $factionNumber = 0; $factionNumber < $factionCount ; $factionNumber++)
{
// Player details
$factionIndex = 0;
if ( isset( $_GET['factionIndex_' . $factionNumber ] ) ) {
$factionIndex = clean_str( $_GET['factionIndex_' . $factionNumber] );
}
$controlType = 0;
if ( isset( $_GET['controlType_' . $factionNumber] ) ) {
$controlType = clean_str( $_GET['controlType_' . $factionNumber] );
}
$resourceMultiplier = 0;
if ( isset( $_GET['resourceMultiplier_' . $factionNumber] ) ) {
$resourceMultiplier = clean_str( $_GET['resourceMultiplier_' . $factionNumber] );
}
$factionTypeName = "";
if ( isset( $_GET['factionTypeName_' . $factionNumber] ) ) {
$factionTypeName = (string) clean_str( $_GET['factionTypeName_' . $factionNumber] );
}
$personalityType = 0;
if ( isset( $_GET['personalityType_' . $factionNumber] ) ) {
$personalityType = clean_str( $_GET['personalityType_' . $factionNumber] );
}
$teamIndex = 0;
if ( isset( $_GET['teamIndex_' . $factionNumber] ) ) {
$teamIndex = clean_str( $_GET['teamIndex_' . $factionNumber] );
}
$wonGame = 0;
if ( isset( $_GET['wonGame_' . $factionNumber] ) ) {
$wonGame = clean_str( $_GET['wonGame_' . $factionNumber] );
}
$killCount = 0;
if ( isset( $_GET['killCount_' . $factionNumber] ) ) {
$killCount = clean_str( $_GET['killCount_' . $factionNumber] );
}
$enemyKillCount = 0;
if ( isset( $_GET['enemyKillCount_' . $factionNumber] ) ) {
$enemyKillCount = clean_str( $_GET['enemyKillCount_' . $factionNumber] );
}
$deathCount = 0;
if ( isset( $_GET['deathCount_' . $factionNumber] ) ) {
$deathCount = clean_str( $_GET['deathCount_' . $factionNumber] );
}
$unitsProducedCount = 0;
if ( isset( $_GET['unitsProducedCount_' . $factionNumber] ) ) {
$unitsProducedCount = clean_str( $_GET['unitsProducedCount_' . $factionNumber] );
}
$resourceHarvestedCount = 0;
if ( isset( $_GET['resourceHarvestedCount_' . $factionNumber] ) ) {
$resourceHarvestedCount = clean_str( $_GET['resourceHarvestedCount_' . $factionNumber] );
}
$playerName = "";
if ( isset( $_GET['playerName_' . $factionNumber] ) ) {
$playerName = (string) clean_str( $_GET['playerName_' . $factionNumber] );
}
$quitBeforeGameEnd = 0;
if ( isset( $_GET['quitBeforeGameEnd_' . $factionNumber] ) ) {
$quitBeforeGameEnd = clean_str( $_GET['quitBeforeGameEnd_' . $factionNumber] );
}
$quitTime = 0;
if ( isset( $_GET['quitTime_' . $factionNumber] ) ) {
$quitTimer = clean_str( $_GET['quitTime_' . $factionNumber] );
}
if($player_statsCount[0] > 0)
{
$result = mysql_query( 'UPDATE glestgameplayerstats SET ' .
'gameUUID=\'' . mysql_real_escape_string( $gameUUID ) . '\', ' .
'factionIndex=' . $factionIndex . ', ' .
'controlType=' . $controlType . ', ' .
'resourceMultiplier=' . $resourceMultiplier . ', ' .
'factionTypeName=\'' . mysql_real_escape_string( $factionTypeName ) . '\', ' .
'personalityType=' . $personalityType . ', ' .
'teamIndex=' . $teamIndex . ', ' .
'wonGame=' . $wonGame . ', ' .
'killCount=' . $killCount . ', ' .
'enemyKillCount=' . $enemyKillCount . ', ' .
'deathCount=' . $deathCount . ', ' .
'unitsProducedCount=' . $unitsProducedCount . ', ' .
'resourceHarvestedCount=' . $resourceHarvestedCount . ', ' .
'playerName=\'' . mysql_real_escape_string( $playerName ) . '\', ' .
'quitBeforeGameEnd=' . $quitBeforeGameEnd . ', ' .
'quitTime=' . $quitTime . ', ' .
'lasttime=' . 'now()' . ' ' .
'WHERE ' . $whereClause);
if (!$result) {
die('part 1b: Invalid query: ' . mysql_error());
}
//echo 'OK1 $factionNumber = ' . $factionNumber;
echo 'OK1b' . $factionNumber;
}
else
{
$result = mysql_query( 'INSERT INTO glestgameplayerstats SET ' .
'gameUUID=\'' . mysql_real_escape_string( $gameUUID ) . '\', ' .
'factionIndex=' . $factionIndex . ', ' .
'controlType=' . $controlType . ', ' .
'resourceMultiplier=' . $resourceMultiplier . ', ' .
'factionTypeName=\'' . mysql_real_escape_string( $factionTypeName ) . '\', ' .
'personalityType=' . $personalityType . ', ' .
'teamIndex=' . $teamIndex . ', ' .
'wonGame=' . $wonGame . ', ' .
'killCount=' . $killCount . ', ' .
'enemyKillCount=' . $enemyKillCount . ', ' .
'deathCount=' . $deathCount . ', ' .
'unitsProducedCount=' . $unitsProducedCount . ', ' .
'resourceHarvestedCount=' . $resourceHarvestedCount . ', ' .
'playerName=\'' . mysql_real_escape_string( $playerName ) . '\', ' .
'quitBeforeGameEnd=' . $quitBeforeGameEnd . ', ' .
'quitTime=' . $quitTime . ';');
if (!$result) {
die('part 2b: Invalid query: ' . mysql_error());
}
//echo 'OK2 $factionNumber = ' . $factionNumber;
echo 'OK2b' . $factionNumber;
}
}
db_disconnect( DB_LINK );
}
?>

View File

@@ -78,9 +78,18 @@
// Representation starts here (but it should really be starting much later, there is way too much logic behind this point)
header( 'Content-Type: text/plain; charset=utf-8' );
$gameUUID = "";
$whereClause = 'ip=\'' . mysql_real_escape_string( $remote_ip ) . '\' && externalServerPort=\'' . mysql_real_escape_string( $service_port ) . '\';';
if ( isset( $_GET['gameUUID'] ) ) {
$gameUUID = (string) clean_str( $_GET['gameUUID'] );
$whereClause = 'gameUUID=\'' . mysql_real_escape_string( $gameUUID ) . '\';';
}
// echo '#1 ' . $whereClause;
if ( (version_compare($glestVersion,"v3.4.0-dev","<") && $connectedClients == $networkSlots) || $gameCmd == "gameOver") // game servers' slots are all full
{ // delete server; no checks are performed
mysql_query( 'DELETE FROM glestserver WHERE ip=\'' . mysql_real_escape_string( $remote_ip ) . '\' && externalServerPort=\'' . mysql_real_escape_string( $service_port ) . '\';' );
mysql_query( 'DELETE FROM glestserver WHERE ' . $whereClause );
echo 'OK' ;
} // game in progress
else if ( ($remote_ip == $server[0] && $service_port == $server[1]) || $status == 2 ) // this server is contained in the database
@@ -102,7 +111,7 @@
'externalServerPort=\''. mysql_real_escape_string( $service_port ) . '\', ' .
'status=\'' . mysql_real_escape_string( $status ) . '\', ' .
'lasttime=' . 'now()' . ' ' .
'where ip=\'' . mysql_real_escape_string( $remote_ip ) . '\' && externalServerPort=\'' . mysql_real_escape_string( $service_port ) . '\';' );
'WHERE ' . $whereClause);
//updateServer($remote_ip, $service_port, $serverTitle, $connectedClients, $networkSlots);
echo 'OK';
}
@@ -120,13 +129,11 @@
$country = '';
}
}
// cleanup old entrys with same remote port and ip
// I hope this fixes those double entrys of servers
mysql_query( 'DELETE FROM glestserver WHERE '.
'externalServerPort=\''. mysql_real_escape_string( $service_port ) . '\', ' .
' AND ' .
'ip=\'' . mysql_real_escape_string( $remote_ip ) . '\', '
);
mysql_query( 'DELETE FROM glestserver WHERE '. $whereClause );
// insert new entry
mysql_query( 'INSERT INTO glestserver SET ' .
'glestVersion=\'' . mysql_real_escape_string( $glestVersion ) . '\', ' .
@@ -142,7 +149,8 @@
'connectedClients=\'' . mysql_real_escape_string( $connectedClients ) . '\', ' .
'externalServerPort=\''. mysql_real_escape_string( $service_port ) . '\', ' .
'country=\'' . mysql_real_escape_string( $country ) . '\', ' .
'status=\'' . mysql_real_escape_string( $status ) . '\';'
'status=\'' . mysql_real_escape_string( $status ) . '\', ' .
'gameUUID=\'' . mysql_real_escape_string( $gameUUID ) . '\';'
);
echo 'OK';
}
@@ -238,13 +246,10 @@
$country = '';
}
}
// cleanup old entrys with same remote port and ip
// I hope this fixes those double entrys of servers
mysql_query( 'DELETE FROM glestserver WHERE '.
'externalServerPort=\''. mysql_real_escape_string( $service_port ) . '\', ' .
' AND ' .
'ip=\'' . mysql_real_escape_string( $remote_ip ) . '\', '
);
mysql_query( 'DELETE FROM glestserver WHERE '. $whereClause );
// insert new entry
mysql_query( 'INSERT INTO glestserver SET ' .
'glestVersion=\'' . mysql_real_escape_string( $glestVersion ) . '\', ' .
@@ -260,7 +265,8 @@
'connectedClients=\'' . mysql_real_escape_string( $connectedClients ) . '\', ' .
'externalServerPort=\''. mysql_real_escape_string( $service_port ) . '\', ' .
'country=\'' . mysql_real_escape_string( $country ) . '\', ' .
'status=\'' . mysql_real_escape_string( $status ) . '\';'
'status=\'' . mysql_real_escape_string( $status ) . '\', ' .
'gameUUID=\'' . mysql_real_escape_string( $gameUUID ) . '\';'
);
echo 'OK';
//addLatestServer($remote_ip, $service_port, $serverTitle, $connectedClients, $networkSlots);

View File

@@ -56,9 +56,56 @@ CREATE TABLE `glestserver` (
`externalServerPort` int(11) NOT NULL,
`country` varchar(2) COLLATE utf8_unicode_ci NOT NULL,
`status` int(11) NOT NULL DEFAULT '0',
`gameUUID` varchar(60) COLLATE utf8_unicode_ci DEFAULT NULL,
KEY `lasttime` (`lasttime`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
--
-- Table structure for table `glestgamestats`
--
DROP TABLE IF EXISTS `glestgamestats`;
CREATE TABLE `glestgamestats` (
`lasttime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`gameUUID` varchar(60) COLLATE utf8_unicode_ci DEFAULT NULL,
`tech` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
`factionCount` int(11) NOT NULL,
`framesPlayed` int(11) NOT NULL,
`framesToCalculatePlaytime` int(11) NOT NULL,
`maxConcurrentUnitCount` int(11) NOT NULL,
`totalEndGameConcurrentUnitCount` int(11) NOT NULL,
`isHeadlessServer` int(11) NOT NULL,
KEY `gameUUID` (`gameUUID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
--
-- Table structure for table `glestgameplayerstats`
--
DROP TABLE IF EXISTS `glestgameplayerstats`;
CREATE TABLE `glestgameplayerstats` (
`lasttime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`gameUUID` varchar(60) COLLATE utf8_unicode_ci DEFAULT NULL,
`factionIndex` int(11) NOT NULL,
`controlType` int(11) NOT NULL,
`resourceMultiplier` DECIMAL(10,6) NOT NULL,
`factionTypeName` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL,
`personalityType` int(11) NOT NULL,
`teamIndex` int(11) NOT NULL,
`wonGame` int(11) NOT NULL,
`killCount` int(11) NOT NULL,
`enemyKillCount` int(11) NOT NULL,
`deathCount` int(11) NOT NULL,
`unitsProducedCount` int(11) NOT NULL,
`resourceHarvestedCount` int(11) NOT NULL,
`playerName` varchar(60) COLLATE utf8_unicode_ci DEFAULT NULL,
`quitBeforeGameEnd` int(11) NOT NULL,
`quitTime` int(11) NOT NULL,
KEY `gameUUID` (`gameUUID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
--
-- Table structure for table `glesttechs`
--
@@ -108,3 +155,5 @@ CREATE TABLE `recent_servers` (
`players` varchar(10) COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=550 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

View File

@@ -103,11 +103,11 @@ typedef struct {
/* some forward declarations. kind of wimpy to do that but heck, we
are all friends here right? raj 20081024 */
static uint16_t true_random(void);
inline static uint16_t true_random(void);
#ifdef WIN32
static void get_system_time(uuid_time_t *uuid_time) {
inline static void get_system_time(uuid_time_t *uuid_time) {
ULARGE_INTEGER time;
/* NT keeps time in FILETIME format which is 100ns ticks since
@@ -124,7 +124,7 @@ static void get_system_time(uuid_time_t *uuid_time) {
}
/* Sample code, not for use in production; see RFC 1750 */
static void get_random_info(char seed[16]) {
inline static void get_random_info(char seed[16]) {
uint16_t myrand;
int i;
@@ -138,7 +138,7 @@ static void get_random_info(char seed[16]) {
#else
static void get_system_time(uuid_time_t *uuid_time) {
inline static void get_system_time(uuid_time_t *uuid_time) {
struct timeval tp;
gettimeofday(&tp, (struct timezone *)0);
@@ -151,7 +151,7 @@ static void get_system_time(uuid_time_t *uuid_time) {
}
/* Sample code, not for use in production; see RFC 1750 */
static void get_random_info(char seed[16]) {
inline static void get_random_info(char seed[16]) {
FILE *fp;
uint16_t myrand;
int i;
@@ -182,7 +182,7 @@ static void get_random_info(char seed[16]) {
/* true_random -- generate a crypto-quality random number.
**This sample doesn't do that.** */
static uint16_t true_random(void) {
inline static uint16_t true_random(void) {
static int inited = 0;
uuid_time_t time_now;
@@ -197,7 +197,7 @@ static uint16_t true_random(void) {
}
/* puid -- print a UUID */
void puid(uuid_t u) {
inline void puid(uuid_t u) {
int i;
printf("%8.8x-%4.4x-%4.4x-%2.2x%2.2x-", u.time_low, u.time_mid,
@@ -209,7 +209,7 @@ void puid(uuid_t u) {
}
/* snpuid -- print a UUID in the supplied buffer */
void snpuid(char *str, size_t size, uuid_t u) {
inline void snpuid(char *str, size_t size, uuid_t u) {
int i;
char *tmp = str;
@@ -237,7 +237,7 @@ void snpuid(char *str, size_t size, uuid_t u) {
/* get-current_time -- get time as 60-bit 100ns ticks since UUID epoch.
Compensate for the fact that real clock resolution is
less than 100ns. */
static void get_current_time(uuid_time_t *timestamp) {
inline static void get_current_time(uuid_time_t *timestamp) {
static int inited = 0;
static uuid_time_t time_last;
static uint16_t uuids_this_tick;
@@ -273,7 +273,7 @@ static void get_current_time(uuid_time_t *timestamp) {
/* system dependent call to get IEEE node ID.
This sample implementation generates a random node ID. */
/* netperf mod - don't bother trying to read or write the nodeid */
static void get_ieee_node_identifier(uuid_node_t *node) {
inline static void get_ieee_node_identifier(uuid_node_t *node) {
static int inited = 0;
static uuid_node_t saved_node;
char seed[16];
@@ -290,7 +290,7 @@ static void get_ieee_node_identifier(uuid_node_t *node) {
/* format_uuid_v1 -- make a UUID from the timestamp, clockseq,
and node ID */
static void format_uuid_v1(uuid_t* uuid, uint16_t clock_seq,
inline static void format_uuid_v1(uuid_t* uuid, uint16_t clock_seq,
uuid_time_t timestamp, uuid_node_t node) {
/* Construct a version 1 uuid with the information we've gathered
plus a few constants. */
@@ -306,7 +306,7 @@ static void format_uuid_v1(uuid_t* uuid, uint16_t clock_seq,
}
/* uuid_create -- generator a UUID */
int uuid_create(uuid_t *uuid) {
inline int uuid_create(uuid_t *uuid) {
uuid_time_t timestamp;
uint16_t clockseq;
uuid_node_t node;
@@ -323,7 +323,7 @@ int uuid_create(uuid_t *uuid) {
return 1;
}
void get_uuid_string(char *uuid_str, size_t size) {
inline void get_uuid_string(char *uuid_str, size_t size) {
uuid_t u;
uuid_create(&u);
@@ -332,6 +332,12 @@ void get_uuid_string(char *uuid_str, size_t size) {
return;
}
inline string getUUIDAsString() {
char uuid_str[38];
get_uuid_string(uuid_str,sizeof(uuid_str));
return uuid_str;
}
//#ifdef NETPERF_STANDALONE_DEBUG
//
//int