Browse Source

Merge pull request #502 from Hoikas/game-score-leaders

Implement Leaderboards
Adam Johnson 9 years ago
parent
commit
1aab309979
  1. 11
      Sources/Plasma/FeatureLib/pfGameScoreMgr/pfGameScoreMgr.cpp
  2. 5
      Sources/Plasma/FeatureLib/pfGameScoreMgr/pfGameScoreMgr.h
  3. 14
      Sources/Plasma/FeatureLib/pfPython/pyGameScore.cpp
  4. 3
      Sources/Plasma/FeatureLib/pfPython/pyGameScore.h
  5. 36
      Sources/Plasma/FeatureLib/pfPython/pyGameScoreGlue.cpp
  6. 17
      Sources/Plasma/NucleusLib/pnNetProtocol/Private/Protocols/Cli2Auth/pnNpCli2Auth.cpp
  7. 31
      Sources/Plasma/NucleusLib/pnNetProtocol/Private/Protocols/Cli2Auth/pnNpCli2Auth.h
  8. 8
      Sources/Plasma/PubUtilLib/plNetGameLib/Intern.h
  9. 156
      Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglAuth.cpp
  10. 9
      Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglAuth.h

11
Sources/Plasma/FeatureLib/pfGameScoreMgr/pfGameScoreMgr.cpp

@ -149,7 +149,7 @@ static void OnScoreCreate(
delete p;
}
void pfGameScore::Create(uint32_t ownerId, const plString& name, uint32_t type, int32_t value, plKey rcvr)
void pfGameScore::Create(uint32_t ownerId, const plString& name, uint32_t type, int32_t value, const plKey& rcvr)
{
NetCliAuthScoreCreate(ownerId, name, type, value, OnScoreCreate, new ScoreUpdateParam(nil, rcvr));
}
@ -174,7 +174,12 @@ static void OnScoreFound(
delete p;
}
void pfGameScore::Find(uint32_t ownerId, const plString& name, plKey rcvr)
void pfGameScore::Find(uint32_t ownerId, const plString& name, const plKey& rcvr)
{
NetCliAuthScoreGetScores(ownerId, name.c_str(), OnScoreFound, new ScoreFindParam(ownerId, name, rcvr));
NetCliAuthScoreGetScores(ownerId, name, OnScoreFound, new ScoreFindParam(ownerId, name, rcvr));
}
void pfGameScore::FindHighScores(uint32_t ageId, uint32_t maxScores, const plString& name, const plKey& rcvr)
{
NetCliAuthScoreGetHighScores(ageId, maxScores, name, OnScoreFound, new ScoreFindParam(ageId, name, rcvr));
}

5
Sources/Plasma/FeatureLib/pfGameScoreMgr/pfGameScoreMgr.h

@ -84,8 +84,9 @@ public:
void TransferPoints(pfGameScore* to, plKey rcvr = nil) { TransferPoints(to, fValue, rcvr); }
void TransferPoints(pfGameScore* to, int32_t points, plKey rcvr = nil);
static void Create(uint32_t ownerId, const plString& name, uint32_t type, int32_t value, plKey rcvr);
static void Find(uint32_t ownerId, const plString& name, plKey rcvr);
static void Create(uint32_t ownerId, const plString& name, uint32_t type, int32_t value, const plKey& rcvr);
static void Find(uint32_t ownerId, const plString& name, const plKey& rcvr);
static void FindHighScores(uint32_t ageId, uint32_t maxScores, const plString& name, const plKey& rcvr);
};
#endif // _pfGameScoreMgr_h_

14
Sources/Plasma/FeatureLib/pfPython/pyGameScore.cpp

@ -183,3 +183,17 @@ void pyGameScore::FindScores(uint32_t ownerId, const plString& name, pyKey& rcvr
{
pfGameScore::Find(ownerId, name, rcvr.getKey());
}
void pyGameScore::FindAgeHighScores(const plString& name, uint32_t maxScores, pyKey& rcvr)
{
if (hsRef<RelVaultNode> ageInfo = VaultGetAgeInfoNode()) {
pfGameScore::FindHighScores(ageInfo->GetNodeId(), maxScores, name, rcvr.getKey());
}
else
hsAssert(false, "Age has no vault... Need to rewrite score python script?");
}
void pyGameScore::FindGlobalHighScores(const plString& name, uint32_t maxScores, pyKey& rcvr)
{
pfGameScore::FindHighScores(0, maxScores, name, rcvr.getKey());
}

3
Sources/Plasma/FeatureLib/pfPython/pyGameScore.h

@ -93,6 +93,9 @@ public:
static void FindGlobalScores(const plString& name, pyKey& rcvr);
static void FindPlayerScores(const plString& name, pyKey& rcvr);
static void FindScores(uint32_t ownerId, const plString& name, pyKey& rcvr);
static void FindAgeHighScores(const plString& name, uint32_t maxScores, pyKey& rcvr);
static void FindGlobalHighScores(const plString& name, uint32_t maxScores, pyKey& rcvr);
};
#endif

36
Sources/Plasma/FeatureLib/pfPython/pyGameScoreGlue.cpp

@ -331,6 +331,40 @@ PYTHON_METHOD_DEFINITION_STATIC(ptGameScore, findScores, args)
PYTHON_RETURN_NONE; // get result in callback
}
PYTHON_METHOD_DEFINITION_STATIC(ptGameScore, findAgeHighScores, args)
{
PyObject* nameObj;
uint32_t maxScores;
PyObject* keyObj;
if (!PyArg_ParseTuple(args, "OIO", &nameObj, &maxScores, &keyObj) ||
!PyString_CheckEx(nameObj) || !pyKey::Check(keyObj)) {
PyErr_SetString(PyExc_TypeError, "findAgeHighScores expects a string, an int, and a ptKey");
PYTHON_RETURN_ERROR;
}
plString name = PyString_AsStringEx(nameObj);
pyKey* rcvr = pyKey::ConvertFrom(keyObj);
pyGameScore::FindAgeHighScores(name, maxScores, *rcvr);
PYTHON_RETURN_NONE; // get result in callback
}
PYTHON_METHOD_DEFINITION_STATIC(ptGameScore, findGlobalHighScores, args)
{
PyObject* nameObj;
uint32_t maxScores;
PyObject* keyObj;
if (!PyArg_ParseTuple(args, "OIO", &nameObj, &maxScores, &keyObj) ||
!PyString_CheckEx(nameObj) || !pyKey::Check(keyObj)) {
PyErr_SetString(PyExc_TypeError, "findGlobalHighScores expects a string, an int, and a ptKey");
PYTHON_RETURN_ERROR;
}
plString name = PyString_AsStringEx(nameObj);
pyKey* rcvr = pyKey::ConvertFrom(keyObj);
pyGameScore::FindGlobalHighScores(name, maxScores, *rcvr);
PYTHON_RETURN_NONE; // get result in callback
}
PYTHON_START_METHODS_TABLE(ptGameScore)
PYTHON_METHOD_NOARGS(ptGameScore, getGameType, "Returns the score game type."),
PYTHON_METHOD_NOARGS(ptGameScore, getName, "Returns the score game name."),
@ -348,6 +382,8 @@ PYTHON_START_METHODS_TABLE(ptGameScore)
PYTHON_METHOD_STATIC(ptGameScore, findGlobalScores, "Params: scoreName, key\nFinds matching global scores"),
PYTHON_METHOD_STATIC(ptGameScore, findPlayerScores, "Params: scoreName, key\nFinds matching player scores"),
PYTHON_METHOD_STATIC(ptGameScore, findScores, "Params: ownerID, scoreName, key\nFinds matching scores for an arbitrary owner"),
PYTHON_METHOD_STATIC(ptGameScore, findAgeHighScores, "Params: name, maxScores, key\nFinds the highest matching scores for the current age's owners"),
PYTHON_METHOD_STATIC(ptGameScore, findGlobalHighScores, "Params: name, maxScores, key\nFinds the highest matching scores"),
PYTHON_END_METHODS_TABLE;
// Type structure definition

17
Sources/Plasma/NucleusLib/pnNetProtocol/Private/Protocols/Cli2Auth/pnNpCli2Auth.cpp

@ -335,6 +335,13 @@ static const NetMsgField kScoreGetRanksFields[] = {
NET_MSG_FIELD_DWORD(), // sortDesc
};
static const NetMsgField kScoreGetHighScoresFields[] = {
kNetMsgFieldTransId, // transId
NET_MSG_FIELD_DWORD(), // ageId
NET_MSG_FIELD_DWORD(), // maxScores
NET_MSG_FIELD_STRING(kMaxGameScoreNameLength), // gameName
};
/*****************************************************************************
*
@ -617,6 +624,14 @@ static const NetMsgField kScoreGetRanksReplyFields[] = {
NET_MSG_FIELD_VAR_PTR(), // nodeBuffer
};
static const NetMsgField kScoreGetHighScoresReplyFields[] = {
kNetMsgFieldTransId, // transId
kNetMsgFieldENetError, // result
NET_MSG_FIELD_DWORD(), // scoreCount
NET_MSG_FIELD_VAR_COUNT(1, 1024 * 1024), // scoreBytes
NET_MSG_FIELD_VAR_PTR(), // scoreBuffer
};
} using namespace Cli2Auth;
@ -673,6 +688,7 @@ const NetMsg kNetMsg_Cli2Auth_ScoreAddPoints = NET_MSG(kCli2Auth_Scor
const NetMsg kNetMsg_Cli2Auth_ScoreTransferPoints = NET_MSG(kCli2Auth_ScoreTransferPoints, kScoreTransferPointsFields);
const NetMsg kNetMsg_Cli2Auth_ScoreSetPoints = NET_MSG(kCli2Auth_ScoreSetPoints, kScoreSetPointsFields);
const NetMsg kNetMsg_Cli2Auth_ScoreGetRanks = NET_MSG(kCli2Auth_ScoreGetRanks, kScoreGetRanksFields);
const NetMsg kNetMsg_Cli2Auth_ScoreGetHighScores = NET_MSG(kCli2Auth_ScoreGetHighScores, kScoreGetHighScoresFields);
const NetMsg kNetMsg_Auth2Cli_PingReply = NET_MSG(kAuth2Cli_PingReply, kPingReplyFields);
const NetMsg kNetMsg_Auth2Cli_ClientRegisterReply = NET_MSG(kAuth2Cli_ClientRegisterReply, kClientRegisterReplyFields);
@ -719,3 +735,4 @@ const NetMsg kNetMsg_Auth2Cli_ScoreAddPointsReply = NET_MSG(kAuth2Cli_Scor
const NetMsg kNetMsg_Auth2Cli_ScoreTransferPointsReply = NET_MSG(kAuth2Cli_ScoreTransferPointsReply, kScoreTransferPointsReplyFields);
const NetMsg kNetMsg_Auth2Cli_ScoreSetPointsReply = NET_MSG(kAuth2Cli_ScoreSetPointsReply, kScoreSetPointsReplyFields);
const NetMsg kNetMsg_Auth2Cli_ScoreGetRanksReply = NET_MSG(kAuth2Cli_ScoreGetRanksReply, kScoreGetRanksReplyFields);
const NetMsg kNetMsg_Auth2Cli_ScoreGetHighScoresReply = NET_MSG(kAuth2Cli_ScoreGetHighScoresReply, kScoreGetHighScoresReplyFields);

31
Sources/Plasma/NucleusLib/pnNetProtocol/Private/Protocols/Cli2Auth/pnNpCli2Auth.h

@ -119,7 +119,7 @@ enum {
kCli2Auth_LogPythonTraceback,
kCli2Auth_LogStackDump,
kCli2Auth_LogClientDebuggerConnect,
// Score
kCli2Auth_ScoreCreate,
kCli2Auth_ScoreDelete,
@ -131,6 +131,10 @@ enum {
kCli2Auth_AccountExistsRequest,
// Extension messages
kCli2Auth_AgeRequestEx = 0x1000,
kCli2Auth_ScoreGetHighScores,
kNumCli2AuthMessages
};
static_assert(kNumCli2AuthMessages <= 0xFFFF, "Cli2Auth message types overflow uint16");
@ -210,6 +214,10 @@ enum {
kAuth2Cli_AccountExistsReply,
// Extension messages
kAuth2Cli_AgeReplyEx = 0x1000,
kAuth2Cli_ScoreGetHighScoresReply,
kNumAuth2CliMessages
};
static_assert(kNumAuth2CliMessages <= 0xFFFF, "Auth2Cli message types overflow uint16");
@ -641,6 +649,15 @@ struct Cli2Auth_ScoreGetRanks {
uint32_t sortDesc;
};
extern const NetMsg kNetMsg_Cli2Auth_ScoreGetHighScores;
struct Cli2Auth_ScoreGetHighScores {
uint32_t messageId;
uint32_t transId;
uint32_t ageId;
uint32_t maxScores;
wchar_t gameName[kMaxGameScoreNameLength];
};
/*****************************************************************************
*
@ -1043,6 +1060,18 @@ struct Auth2Cli_ScoreGetRanksReply {
// no more fields
};
// ScoreGetHighScoresReply
extern const NetMsg kNetMsg_Auth2Cli_ScoreGetHighScoresReply;
struct Auth2Cli_ScoreGetHighScoresReply {
uint32_t messageId;
uint32_t transId;
ENetError result;
uint32_t scoreCount;
uint32_t byteCount;
uint8_t buffer[1]; // [byteCount], actually
// no more fields
};
//============================================================================
// END PACKED DATA STRUCTURES
//============================================================================

8
Sources/Plasma/PubUtilLib/plNetGameLib/Intern.h

@ -181,20 +181,21 @@ enum ETransType {
kScoreSetPointsTrans,
kScoreGetRanksTrans,
kSendFriendInviteTrans,
kScoreGetHighScoresTrans,
//========================================================================
// NglGame.cpp transactions
kJoinAgeRequestTrans,
kGmRcvdPropagatedBufferTrans,
kGmRcvdGameMgrMsgTrans,
//========================================================================
// NglFile.cpp transactions
kBuildIdRequestTrans,
kManifestRequestTrans,
kDownloadRequestTrans,
kFileRcvdFileDownloadChunkTrans,
//========================================================================
// NglCore.cpp transactions
kReportNetErrorTrans,
@ -251,6 +252,7 @@ static const char * s_transTypes[] = {
"ScoreSetPointsTrans",
"ScoreGetRanksTrans",
"SendFriendInviteTrans",
"ScoreGetHighScoresTrans",
// NglGame.cpp
"JoinAgeRequestTrans",

156
Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglAuth.cpp

@ -1185,6 +1185,40 @@ struct ScoreGetRanksTrans : NetAuthTrans {
);
};
//============================================================================
// ScoreGetHighScoresTrans
//============================================================================
struct ScoreGetHighScoresTrans : NetAuthTrans {
FNetCliAuthGetScoresCallback m_callback;
void * m_param;
// send
unsigned m_ageId;
unsigned m_maxScores;
plString m_gameName;
// recv
NetGameScore * m_scores;
unsigned m_scoreCount;
ScoreGetHighScoresTrans(
unsigned ageId,
unsigned maxScores,
const plString& gameName,
FNetCliAuthGetScoresCallback callback,
void * param
);
~ScoreGetHighScoresTrans();
bool Send();
void Post();
bool Recv(
const uint8_t msg[],
unsigned bytes
);
};
/*****************************************************************************
*
@ -2339,6 +2373,19 @@ static bool Recv_ScoreGetRanksReply (
return true;
}
//============================================================================
static bool Recv_ScoreGetHighScoresReply(
const uint8_t msg[],
unsigned bytes,
void *
) {
const Auth2Cli_ScoreGetHighScoresReply & reply = *(const Auth2Cli_ScoreGetHighScoresReply *)msg;
NetTransRecv(reply.transId, msg, bytes);
return true;
}
/*****************************************************************************
*
* Cli2Auth protocol
@ -2393,6 +2440,7 @@ static NetMsgInitSend s_send[] = {
{ MSG(ScoreSetPoints) },
{ MSG(ScoreGetRanks) },
{ MSG(AccountExistsRequest) },
{ MSG(ScoreGetHighScores) },
};
#undef MSG
@ -2442,6 +2490,7 @@ static NetMsgInitRecv s_recv[] = {
{ MSG(ScoreSetPointsReply) },
{ MSG(ScoreGetRanksReply) },
{ MSG(AccountExistsReply) },
{ MSG(ScoreGetHighScoresReply) },
};
#undef MSG
@ -4976,6 +5025,95 @@ bool ScoreGetRanksTrans::Recv (
return true;
}
/*****************************************************************************
*
* ScoreGetHighScoresTrans
*
***/
//============================================================================
ScoreGetHighScoresTrans::ScoreGetHighScoresTrans(
unsigned ageId,
unsigned maxScores,
const plString& gameName,
FNetCliAuthGetScoresCallback callback,
void * param
) : NetAuthTrans(kScoreGetHighScoresTrans)
, m_callback(callback)
, m_param(param)
, m_ageId(ageId)
, m_maxScores(maxScores)
, m_gameName(gameName)
, m_scores(nullptr)
, m_scoreCount(0)
{
}
//============================================================================
ScoreGetHighScoresTrans::~ScoreGetHighScoresTrans() {
delete[] m_scores;
}
//============================================================================
bool ScoreGetHighScoresTrans::Send() {
if (!AcquireConn())
return false;
plStringBuffer<uint16_t> gameName = m_gameName.ToUtf16();
const uintptr_t msg[] = {
kCli2Auth_ScoreGetHighScores,
m_transId,
m_ageId,
m_maxScores,
(uintptr_t)gameName.GetData()
};
m_conn->Send(msg, arrsize(msg));
return true;
}
//============================================================================
void ScoreGetHighScoresTrans::Post() {
if (m_callback) {
m_callback(
m_result,
m_param,
m_scores,
m_scoreCount
);
}
}
//============================================================================
bool ScoreGetHighScoresTrans::Recv(
const uint8_t msg[],
unsigned bytes
) {
const Auth2Cli_ScoreGetHighScoresReply & reply = *(const Auth2Cli_ScoreGetHighScoresReply *)msg;
if (reply.scoreCount > 0) {
m_scoreCount = reply.scoreCount;
m_scores = new NetGameScore[m_scoreCount];
uint8_t* bufferPos = const_cast<uint8_t*>(reply.buffer);
unsigned bufferLength = reply.byteCount;
for (unsigned i = 0; i < m_scoreCount; ++i) {
bufferLength -= m_scores[i].Read(bufferPos, bufferLength, &bufferPos);
}
}
else {
m_scoreCount = 0;
m_scores = nullptr;
}
m_result = reply.result;
m_state = kTransStateComplete;
return true;
}
} using namespace Auth;
@ -6045,3 +6183,21 @@ void NetCliAuthScoreGetRankList(
);
NetTransSend(trans);
}
//============================================================================
void NetCliAuthScoreGetHighScores(
unsigned ageId,
unsigned maxScores,
const plString& gameName,
FNetCliAuthGetScoresCallback callback,
void * param
) {
ScoreGetHighScoresTrans * trans = new ScoreGetHighScoresTrans(
ageId,
maxScores,
gameName,
callback,
param
);
NetTransSend(trans);
}

9
Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglAuth.h

@ -715,3 +715,12 @@ void NetCliAuthScoreGetRankList(
FNetCliAuthGetRanksCallback callback,
void * param
);
//============================================================================
void NetCliAuthScoreGetHighScores(
unsigned ageId,
unsigned maxScores,
const plString& gameName,
FNetCliAuthGetScoresCallback callback,
void * param
);

Loading…
Cancel
Save