diff --git a/extern/MinaCalc/MinaCalc.lib b/extern/MinaCalc/MinaCalc.lib index ffb6bb439a..890b041ebd 100644 Binary files a/extern/MinaCalc/MinaCalc.lib and b/extern/MinaCalc/MinaCalc.lib differ diff --git a/src/GameConstantsAndTypes.cpp b/src/GameConstantsAndTypes.cpp index d072bcd239..b25ac991ad 100644 --- a/src/GameConstantsAndTypes.cpp +++ b/src/GameConstantsAndTypes.cpp @@ -281,6 +281,18 @@ Skillset StringToSkillset(const RString &s) { return Skill_Overall; } +static const char *ValidationKeyNames[] = { + "Brittle", + "Weak", +}; +XToString(ValidationKey); +LuaXType(ValidationKey); +ValidationKey StringToValidationKey(const RString &s) { + if (s == "Brittle") return ValidationKey_Brittle; + if (s == "Weak") return ValidationKey_Weak; + return ValidationKey_Brittle; +} + static const char *TimingWindowNames[] = { "W1", "W2", diff --git a/src/GameConstantsAndTypes.h b/src/GameConstantsAndTypes.h index ebeda00b7b..f74a8c6cda 100644 --- a/src/GameConstantsAndTypes.h +++ b/src/GameConstantsAndTypes.h @@ -36,6 +36,15 @@ enum Skillset { const RString& SkillsetToString(Skillset ss); +enum ValidationKey { + ValidationKey_Brittle, + ValidationKey_Weak, + NUM_ValidationKey, + ValidationKey_Invalid, +}; + +const RString& ValidationKeyToString(ValidationKey ss); + /** * @brief The various radar categories available. * diff --git a/src/HighScore.cpp b/src/HighScore.cpp index 6657a334fa..3584e1baf2 100644 --- a/src/HighScore.cpp +++ b/src/HighScore.cpp @@ -52,6 +52,7 @@ struct HighScoreImpl int iTapNoteScores[NUM_TapNoteScore]; int iHoldNoteScores[NUM_HoldNoteScore]; float fSkillsetSSRs[NUM_Skillset]; + string ValidationKeys[NUM_ValidationKey]; RadarValues radarValues; float fLifeRemainingSeconds; bool bDisqualified; @@ -344,7 +345,10 @@ XNode *HighScoreImpl::CreateEttNode() const { pSkillsetSSRs->AppendChild(SkillsetToString(ss), FloatToString(fSkillsetSSRs[ss]).substr(0, 5)); } - pNode->AppendChild("ValidationKey", ValidationKey); + XNode* pValidationKeys = pNode->AppendChild("ValidationKeys"); + pValidationKeys->AppendChild(ValidationKeyToString(ValidationKey_Brittle), ValidationKeys[ValidationKey_Brittle]); + pValidationKeys->AppendChild(ValidationKeyToString(ValidationKey_Weak), ValidationKeys[ValidationKey_Weak]); + return pNode; } @@ -384,7 +388,13 @@ void HighScoreImpl::LoadFromEttNode(const XNode *pNode) { pSkillsetSSRs->GetChildValue(SkillsetToString(ss), fSkillsetSSRs[ss]); } - pNode->GetChildValue("ValidationKey", s); ValidationKey = s; + if (fWifeScore > 0.f) { + const XNode* pValidationKeys = pNode->GetChild("ValidationKeys"); + if (pValidationKeys) { + pValidationKeys->GetChildValue(ValidationKeyToString(ValidationKey_Brittle), s); ValidationKeys[ValidationKey_Brittle] = s; + pValidationKeys->GetChildValue(ValidationKeyToString(ValidationKey_Weak), s); ValidationKeys[ValidationKey_Weak] = s; + } + } if (ScoreKey == "") ScoreKey = "S" + BinaryToHex(CryptManager::GetSHA1ForString(dateTime.GetString())); @@ -749,6 +759,7 @@ void HighScore::SetProductID( int i ) { m_Impl->iProductID = i; } void HighScore::SetTapNoteScore( TapNoteScore tns, int i ) { m_Impl->iTapNoteScores[tns] = i; } void HighScore::SetHoldNoteScore( HoldNoteScore hns, int i ) { m_Impl->iHoldNoteScores[hns] = i; } void HighScore::SetSkillsetSSR(Skillset ss, float ssr) { m_Impl->fSkillsetSSRs[ss] = ssr; } +void HighScore::SetValidationKey(ValidationKey vk, string k) { m_Impl->ValidationKeys[vk] = k; } void HighScore::SetRadarValues( const RadarValues &rv ) { m_Impl->radarValues = rv; } void HighScore::SetLifeRemainingSeconds( float f ) { m_Impl->fLifeRemainingSeconds = f; } void HighScore::SetDisqualified( bool b ) { m_Impl->bDisqualified = b; } diff --git a/src/HighScore.h b/src/HighScore.h index 51a127cb1d..07bccc71e3 100644 --- a/src/HighScore.h +++ b/src/HighScore.h @@ -144,6 +144,7 @@ struct HighScore float RescoreToDPJudge(int x); float GetSkillsetSSR(Skillset ss) const; void SetSkillsetSSR(Skillset ss, float ssr); + void SetValidationKey(ValidationKey vk, string k); vector GetRescoreJudgeVector(int x); // Lua void PushSelf( lua_State *L ); diff --git a/src/MinaCalc.h b/src/MinaCalc.h index 5d56f00ca2..dcf492b371 100644 --- a/src/MinaCalc.h +++ b/src/MinaCalc.h @@ -158,4 +158,5 @@ class Calc { MINACALC_API vector MinaSDCalc(const vector& NoteInfo, int numTracks, float musicrate, float goal, float timingscale, bool negbpms); MINACALC_API MinaSD MinaSDCalc(const vector& NoteInfo, int numTracks, float goal, float timingscale, bool negbpms); MINACALC_API int GetCalcVersion(); -MINACALC_API string GenerateWeakValidationKey(const int* tns, const int* hns); \ No newline at end of file +MINACALC_API string GenerateWeakValidationKey(const int* tns, const int* hns); +MINACALC_API string MinaCalc2(MinaSD& output, vector& NoteInfo, float musicrate, float goal); \ No newline at end of file diff --git a/src/PlayerStageStats.cpp b/src/PlayerStageStats.cpp index 3953d143b2..6ab6c83a97 100644 --- a/src/PlayerStageStats.cpp +++ b/src/PlayerStageStats.cpp @@ -12,6 +12,7 @@ #include "PrefsManager.h" #include "CommonMetrics.h" #include "MinaCalc.h" +#include "CryptManager.h" #define GRADE_PERCENT_TIER(i) THEME->GetMetricF("PlayerStageStats",ssprintf("GradePercent%s",GradeToString((Grade)i).c_str())) // deprecated, but no solution to replace them exists yet: @@ -314,10 +315,27 @@ vector PlayerStageStats::CalcSSR(float ssrpercent ) const { float musicrate = GAMESTATE->m_SongOptions.GetCurrent().m_fMusicRate; return MinaSDCalc(serializednd, steps->GetNoteData().GetNumTracks(), musicrate, ssrpercent, 1.f, steps->GetTimingData()->HasWarps()); } -// to be array'd in future i guess? -mina -string PlayerStageStats::GenerateValidationKeys() const { - string weak = GenerateWeakValidationKey(m_iTapNoteScores, m_iHoldNoteScores); - return weak; + +void PlayerStageStats::GenerateValidationKeys(HighScore& hs) const { + string key = ""; + + // just designed to catch shameless stats xml tampering by people who aren't experienced enough to look this up -mina + FOREACH_ENUM(TapNoteScore, tns) + key.append(to_string(hs.GetTapNoteScore(tns))); + FOREACH_ENUM(TapNoteScore, tns) + key.append(to_string(hs.GetTapNoteScore(tns))); + + key.append(hs.GetScoreKey()); + key.append(to_string(lround(hs.GetWifeScore() * 1000.f))); + key.append(to_string(lround(hs.GetSSRNormPercent() * 1000.f))); + key.append(to_string(lround(hs.GetMusicRate() * 1000.f))); + key.append(to_string(lround(hs.GetJudgeScale() * 1000.f))); + key.append(to_string(hs.GetEtternaValid())); + + hs.SetValidationKey(ValidationKey_Brittle, BinaryToHex(CryptManager::GetSHA1ForString(key))); + + // just testing stuff + hs.SetValidationKey(ValidationKey_Weak, GenerateWeakValidationKey(m_iTapNoteScores, m_iHoldNoteScores)); } float PlayerStageStats::GetTimingScale() const { return m_fTimingScale; diff --git a/src/PlayerStageStats.h b/src/PlayerStageStats.h index 8fa1875b49..80a984c014 100644 --- a/src/PlayerStageStats.h +++ b/src/PlayerStageStats.h @@ -33,7 +33,7 @@ class PlayerStageStats // Calculate the difficulty rating for a specific score obtained by a player - Mina Grade GetWifeGrade(); vector CalcSSR(float ssrpercent) const; - string GenerateValidationKeys() const; + void GenerateValidationKeys(HighScore& hs) const; float GetPercentDancePoints() const; float GetWifeScore() const; float GetTimingScale() const; diff --git a/src/StageStats.cpp b/src/StageStats.cpp index d2e9a9f694..ef53f44254 100644 --- a/src/StageStats.cpp +++ b/src/StageStats.cpp @@ -227,6 +227,8 @@ static HighScore FillInHighScore(const PlayerStageStats &pss, const PlayerState // this whole thing needs to be redone, ssr calculation should be moved into highscore -mina hs.SetSSRCalcVersion(GetCalcVersion()); + pss.GenerateValidationKeys(hs); + if (!pss.InputData.empty()) hs.WriteInputData(pss.InputData); return hs;