forked from Mirrors/openclonk
Send script-defined statistics to the masterserver
After GameOver(), the global function CollectStatistics() is called which in turn calls CollectStats() on all definitions and the Scenario. The results are collected into a proplist and sent to the masterserver as JSON. The intended purpose is to collect statistics like weapon kill counts and evaluate them across all online games to improve balancing.alut-include-path
parent
ee0b1c2599
commit
87ee44964c
|
@ -0,0 +1,28 @@
|
||||||
|
|
||||||
|
/*--
|
||||||
|
CollectStatistics.c
|
||||||
|
Authors: Luchs
|
||||||
|
|
||||||
|
Global entry point for statistics collection for the masterserver.
|
||||||
|
--*/
|
||||||
|
|
||||||
|
|
||||||
|
// This function is called after the round ends. The return value is passed to
|
||||||
|
// the masterserver.
|
||||||
|
global func CollectStatistics()
|
||||||
|
{
|
||||||
|
var result = {};
|
||||||
|
var i = 0, def, stats;
|
||||||
|
while (def = GetDefinition(i++))
|
||||||
|
{
|
||||||
|
stats = def->~CollectStats();
|
||||||
|
if (stats != nil)
|
||||||
|
result[def->GetName(true)] = stats;
|
||||||
|
}
|
||||||
|
stats = Scenario->~CollectStats();
|
||||||
|
if (stats != nil)
|
||||||
|
result.Scenario = stats;
|
||||||
|
if (GetLength(GetProperties(result)))
|
||||||
|
return result;
|
||||||
|
return nil;
|
||||||
|
}
|
|
@ -249,6 +249,7 @@ void C4RoundResults::Clear()
|
||||||
sNetResult.Clear();
|
sNetResult.Clear();
|
||||||
eNetResult = NR_None;
|
eNetResult = NR_None;
|
||||||
fHideSettlementScore=false;
|
fHideSettlementScore=false;
|
||||||
|
Statistics.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void C4RoundResults::Init()
|
void C4RoundResults::Init()
|
||||||
|
@ -308,6 +309,19 @@ void C4RoundResults::EvaluateGame()
|
||||||
int32_t iFirstLocalPlayer = pFirstLocalPlayer ? pFirstLocalPlayer->Number : NO_OWNER;
|
int32_t iFirstLocalPlayer = pFirstLocalPlayer ? pFirstLocalPlayer->Number : NO_OWNER;
|
||||||
EvaluateGoals(Goals, FulfilledGoals, iFirstLocalPlayer);
|
EvaluateGoals(Goals, FulfilledGoals, iFirstLocalPlayer);
|
||||||
iPlayingTime = Game.Time;
|
iPlayingTime = Game.Time;
|
||||||
|
|
||||||
|
// collect statistics
|
||||||
|
try
|
||||||
|
{
|
||||||
|
C4AulParSet Pars;
|
||||||
|
auto stats = ::ScriptEngine.GetPropList()->Call(PSF_CollectStatistics, &Pars);
|
||||||
|
if (stats != C4VNull)
|
||||||
|
Statistics = stats.ToJSON();
|
||||||
|
}
|
||||||
|
catch (C4JSONSerializationError& e)
|
||||||
|
{
|
||||||
|
DebugLogF("ERROR: cannot serialize CollectStatistics() result: %s", e.what());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void C4RoundResults::EvaluateNetwork(C4RoundResults::NetResult eNetResult, const char *szResultMsg)
|
void C4RoundResults::EvaluateNetwork(C4RoundResults::NetResult eNetResult, const char *szResultMsg)
|
||||||
|
|
|
@ -149,6 +149,7 @@ private:
|
||||||
|
|
||||||
// scenario-specific
|
// scenario-specific
|
||||||
StdCopyStrBuf sCustomEvaluationStrings;
|
StdCopyStrBuf sCustomEvaluationStrings;
|
||||||
|
StdCopyStrBuf Statistics; // stats collected by script at the end of the round
|
||||||
|
|
||||||
public:
|
public:
|
||||||
C4RoundResults() : iPlayingTime(0) {}
|
C4RoundResults() : iPlayingTime(0) {}
|
||||||
|
@ -190,6 +191,8 @@ public:
|
||||||
void SetLeaguePerformance(int32_t iNewPerf, int32_t idPlayer = 0);
|
void SetLeaguePerformance(int32_t iNewPerf, int32_t idPlayer = 0);
|
||||||
int32_t GetLeaguePerformance(int32_t idPlayer = 0) const;
|
int32_t GetLeaguePerformance(int32_t idPlayer = 0) const;
|
||||||
|
|
||||||
|
StdCopyStrBuf GetStatistics() const { return Statistics; }
|
||||||
|
|
||||||
const C4RoundResultsPlayers &GetPlayers() const { return Players; }
|
const C4RoundResultsPlayers &GetPlayers() const { return Players; }
|
||||||
const char *GetCustomEvaluationStrings() const { return sCustomEvaluationStrings.getData(); }
|
const char *GetCustomEvaluationStrings() const { return sCustomEvaluationStrings.getData(); }
|
||||||
NetResult GetNetResult() const { return eNetResult; }
|
NetResult GetNetResult() const { return eNetResult; }
|
||||||
|
|
|
@ -102,6 +102,8 @@ bool C4ValueToMatrix(const C4ValueArray& array, StdMeshMatrix* matrix);
|
||||||
#define PSF_CommandFailure "~CommandFailure" // string command, pTarget, iTx, iTy, pTarget2, iData
|
#define PSF_CommandFailure "~CommandFailure" // string command, pTarget, iTx, iTy, pTarget2, iData
|
||||||
#define PSF_OnCompletionChange "~OnCompletionChange" // int old_con, int new_con
|
#define PSF_OnCompletionChange "~OnCompletionChange" // int old_con, int new_con
|
||||||
|
|
||||||
|
#define PSF_CollectStatistics "CollectStatistics"
|
||||||
|
|
||||||
// Effect callbacks
|
// Effect callbacks
|
||||||
|
|
||||||
#define PSF_FxStart "Fx%sStart" // C4Object *pTarget, int iEffectNumber, int iTemp, C4Value vVar1, C4Value vVar2, C4Value vVar3, C4Value vVar4
|
#define PSF_FxStart "Fx%sStart" // C4Object *pTarget, int iEffectNumber, int iTemp, C4Value vVar1, C4Value vVar2, C4Value vVar3, C4Value vVar4
|
||||||
|
|
|
@ -80,6 +80,7 @@ void C4Network2Reference::InitLocal()
|
||||||
IsEditor = !!::Application.isEditor;
|
IsEditor = !!::Application.isEditor;
|
||||||
NetpuncherGameID = ::Network.getNetpuncherGameID();
|
NetpuncherGameID = ::Network.getNetpuncherGameID();
|
||||||
NetpuncherAddr = ::Network.getNetpuncherAddr();
|
NetpuncherAddr = ::Network.getNetpuncherAddr();
|
||||||
|
Statistics = ::Game.RoundResults.GetStatistics();
|
||||||
Game.Set();
|
Game.Set();
|
||||||
|
|
||||||
// Addresses
|
// Addresses
|
||||||
|
@ -129,6 +130,7 @@ void C4Network2Reference::CompileFunc(StdCompiler *pComp)
|
||||||
pComp->Value(mkNamingAdapt(OfficialServer, "OfficialServer", false));
|
pComp->Value(mkNamingAdapt(OfficialServer, "OfficialServer", false));
|
||||||
pComp->Value(mkNamingAdapt(NetpuncherGameID, "NetpuncherID", C4NetpuncherID(), false, false));
|
pComp->Value(mkNamingAdapt(NetpuncherGameID, "NetpuncherID", C4NetpuncherID(), false, false));
|
||||||
pComp->Value(mkNamingAdapt(NetpuncherAddr, "NetpuncherAddr", "", false, false));
|
pComp->Value(mkNamingAdapt(NetpuncherAddr, "NetpuncherAddr", "", false, false));
|
||||||
|
pComp->Value(mkNamingAdapt(Statistics, "Statistics", "", false, false));
|
||||||
|
|
||||||
pComp->Value(Parameters);
|
pComp->Value(Parameters);
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,7 @@ private:
|
||||||
bool IsEditor;
|
bool IsEditor;
|
||||||
C4NetpuncherID NetpuncherGameID;
|
C4NetpuncherID NetpuncherGameID;
|
||||||
StdCopyStrBuf NetpuncherAddr;
|
StdCopyStrBuf NetpuncherAddr;
|
||||||
|
StdCopyStrBuf Statistics;
|
||||||
|
|
||||||
// Engine information
|
// Engine information
|
||||||
C4GameVersion Game;
|
C4GameVersion Game;
|
||||||
|
|
Loading…
Reference in New Issue