diff --git a/Sources/Plasma/FeatureLib/pfGameScoreMgr/pfGameScoreMgr.cpp b/Sources/Plasma/FeatureLib/pfGameScoreMgr/pfGameScoreMgr.cpp index fa4114dd..9a4687df 100644 --- a/Sources/Plasma/FeatureLib/pfGameScoreMgr/pfGameScoreMgr.cpp +++ b/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)); } diff --git a/Sources/Plasma/FeatureLib/pfGameScoreMgr/pfGameScoreMgr.h b/Sources/Plasma/FeatureLib/pfGameScoreMgr/pfGameScoreMgr.h index 438db954..0f1f770e 100644 --- a/Sources/Plasma/FeatureLib/pfGameScoreMgr/pfGameScoreMgr.h +++ b/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_ diff --git a/Sources/Plasma/FeatureLib/pfPython/pyGameScore.cpp b/Sources/Plasma/FeatureLib/pfPython/pyGameScore.cpp index d0b625b1..75474f2c 100644 --- a/Sources/Plasma/FeatureLib/pfPython/pyGameScore.cpp +++ b/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 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()); +} diff --git a/Sources/Plasma/FeatureLib/pfPython/pyGameScore.h b/Sources/Plasma/FeatureLib/pfPython/pyGameScore.h index 8fbd64c7..3307f658 100644 --- a/Sources/Plasma/FeatureLib/pfPython/pyGameScore.h +++ b/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 diff --git a/Sources/Plasma/FeatureLib/pfPython/pyGameScoreGlue.cpp b/Sources/Plasma/FeatureLib/pfPython/pyGameScoreGlue.cpp index 97878094..7745bbc1 100644 --- a/Sources/Plasma/FeatureLib/pfPython/pyGameScoreGlue.cpp +++ b/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 diff --git a/Sources/Plasma/NucleusLib/pnNetProtocol/Private/Protocols/Cli2Auth/pnNpCli2Auth.cpp b/Sources/Plasma/NucleusLib/pnNetProtocol/Private/Protocols/Cli2Auth/pnNpCli2Auth.cpp index e8aeb8bb..dc3e8be0 100644 --- a/Sources/Plasma/NucleusLib/pnNetProtocol/Private/Protocols/Cli2Auth/pnNpCli2Auth.cpp +++ b/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); diff --git a/Sources/Plasma/NucleusLib/pnNetProtocol/Private/Protocols/Cli2Auth/pnNpCli2Auth.h b/Sources/Plasma/NucleusLib/pnNetProtocol/Private/Protocols/Cli2Auth/pnNpCli2Auth.h index 776ac59f..be705032 100644 --- a/Sources/Plasma/NucleusLib/pnNetProtocol/Private/Protocols/Cli2Auth/pnNpCli2Auth.h +++ b/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 //============================================================================ diff --git a/Sources/Plasma/PubUtilLib/plNetGameLib/Intern.h b/Sources/Plasma/PubUtilLib/plNetGameLib/Intern.h index 41fadc8a..92ef0f78 100644 --- a/Sources/Plasma/PubUtilLib/plNetGameLib/Intern.h +++ b/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", diff --git a/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglAuth.cpp b/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglAuth.cpp index d6aec334..22c87f97 100644 --- a/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglAuth.cpp +++ b/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 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(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); +} diff --git a/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglAuth.h b/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglAuth.h index bfda8de4..6c658e9f 100644 --- a/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglAuth.h +++ b/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 +);