diff --git a/source-code/source/plugins/TLAC/Components/ScoreSaver.cpp b/source-code/source/plugins/TLAC/Components/ScoreSaver.cpp index 778fd77..017b39d 100644 --- a/source-code/source/plugins/TLAC/Components/ScoreSaver.cpp +++ b/source-code/source/plugins/TLAC/Components/ScoreSaver.cpp @@ -11,10 +11,13 @@ namespace TLAC::Components { WCHAR ScoreSaver::configPath[256]; + WCHAR ScoreSaver::rival_configPath[256]; ScoreSaver::ScoreSaver() { std::string utf8path = TLAC::framework::GetModuleDirectory() + "/scores.ini"; MultiByteToWideChar(CP_UTF8, 0, utf8path.c_str(), -1, configPath, 256); + utf8path = TLAC::framework::GetModuleDirectory() + "/rivalscores.ini"; + MultiByteToWideChar(CP_UTF8, 0, utf8path.c_str(), -1, rival_configPath, 256); } ScoreSaver::~ScoreSaver() @@ -307,23 +310,75 @@ namespace TLAC::Components DivaScore* cachedScore = GetCachedScore(pvNum, diff, exDiff); if (cachedScore == nullptr) { - ScoreCache[diff].push_back({ pvNum, exDiff }); // minimum needed to find it + ScoreCache[diff].push_back(DivaScore(pvNum, exDiff)); cachedScore = GetCachedScore(pvNum, diff, exDiff); } - if (cachedScore != nullptr) - { - cachedScore->score = score; - cachedScore->percent = percent; - cachedScore->clearRank = allTimeRank; - cachedScore->optionA = 0; - cachedScore->optionB = 0; - cachedScore->optionC = 0; - } + cachedScore->score = score; + cachedScore->percent = percent; + cachedScore->clearRank = allTimeRank; } else { DivaScore* cachedScore = GetCachedScore(pvNum, diff, exDiff); - if (cachedScore != nullptr) + if (cachedScore != nullptr && cachedScore->rival_score <= 0) // only remove it if no rival score is set too + ScoreCache[diff].erase(std::remove(ScoreCache[diff].begin(), ScoreCache[diff].end(), *cachedScore), ScoreCache[diff].end()); + } + + // update begin and end vars from game + if (ScoreCache[diff].size() > 0) + { + ScoreCache[diff].shrink_to_fit(); + *(DivaScore**)(PLAYER_DATA_ADDRESS + diff * 0x18 + 0x5d0) = &*ScoreCache[diff].begin(); + *(DivaScore**)(PLAYER_DATA_ADDRESS + diff * 0x18 + 0x5d8) = &*ScoreCache[diff].end(); + } + else + { + *(DivaScore**)(PLAYER_DATA_ADDRESS + diff * 0x18 + 0x5d0) = nullptr; + *(DivaScore**)(PLAYER_DATA_ADDRESS + diff * 0x18 + 0x5d8) = nullptr; + } + } + + void ScoreSaver::UpdateSingleScoreCacheRivalEntry(int pvNum, int diff, int exDiff) + { + if (pvNum < 0 || diff < 0 || exDiff < 0 || pvNum > 999 || diff > 3 || exDiff > 1) + return; + + + WCHAR keyBase[32]; // needs to be big enough to store pv.999.diff.4.ex + WCHAR key[32]; // needs to be big enough to store pv.999.diff.4.challengescore + + const WCHAR section[] = L"scores"; + + if (exDiff == 0) + swprintf(keyBase, 32, L"pv.%03d.diff.%01d", pvNum, diff); + else + swprintf(keyBase, 32, L"pv.%03d.diff.%01d.ex", pvNum, diff); + + + swprintf(key, 32, L"%ls.%ls", keyBase, L"score"); + int score = GetPrivateProfileIntW(section, key, -1, rival_configPath); + + if (score >= 0) + { + if (score > 99999999) + score = 99999999; + + swprintf(key, 32, L"%ls.%ls", keyBase, L"percent"); + int percent = GetPrivateProfileIntW(section, key, 0, rival_configPath); + + DivaScore* cachedScore = GetCachedScore(pvNum, diff, exDiff); + if (cachedScore == nullptr) + { + ScoreCache[diff].push_back(DivaScore(pvNum, exDiff)); + cachedScore = GetCachedScore(pvNum, diff, exDiff); + } + cachedScore->rival_score = score; + cachedScore->rival_percent = percent; + } + else + { + DivaScore* cachedScore = GetCachedScore(pvNum, diff, exDiff); + if (cachedScore != nullptr && cachedScore->score <= 0) // only remove it if no regular score is set too ScoreCache[diff].erase(std::remove(ScoreCache[diff].begin(), ScoreCache[diff].end(), *cachedScore), ScoreCache[diff].end()); } @@ -350,6 +405,7 @@ namespace TLAC::Components for (int exDiff = 0; exDiff < 2; exDiff++) { UpdateSingleScoreCacheEntry(pvNum, diff, exDiff); + UpdateSingleScoreCacheRivalEntry(pvNum, diff, exDiff); } } } diff --git a/source-code/source/plugins/TLAC/Components/ScoreSaver.h b/source-code/source/plugins/TLAC/Components/ScoreSaver.h index d78a57f..0b8b838 100644 --- a/source-code/source/plugins/TLAC/Components/ScoreSaver.h +++ b/source-code/source/plugins/TLAC/Components/ScoreSaver.h @@ -26,7 +26,10 @@ namespace TLAC::Components int clearRank; // +0xac: clear rank int score; // +0xb0: score int percent; // +0xb4: best percent - byte paddingB8[0x28]; // ??? + byte paddingB8[0x18]; // ??? + int rival_score; // +0xd0: rival score + int rival_percent; // +0xd4: rival percent + byte paddingD8[0x8]; // ??? byte optionA; // +0xe0: gamemode options byte optionB; byte optionC; @@ -36,6 +39,58 @@ namespace TLAC::Components { return cmp.pvNum == pvNum && cmp.exDifficulty == exDifficulty; } + + DivaScore(int pv, int exDiff) + { + // this is just copied from 140113510 + // no clue what most of it is + pvNum = pv; + exDifficulty = exDiff; + *(int*)((uint64_t)this + 0x08) = 0; + *(int*)((uint64_t)this + 0x0c) = 0; + *(int*)((uint64_t)this + 0x10) = 0; + *(int*)((uint64_t)this + 0x14) = 0; + *(int*)((uint64_t)this + 0x18) = 0; + *(int*)((uint64_t)this + 0x1c) = 0; + *(long long*)((uint64_t)this + 0x20) = -1; + *(long long*)((uint64_t)this + 0x28) = -1; + *(long long*)((uint64_t)this + 0x30) = -1; + *(long long*)((uint64_t)this + 0x38) = -1; + *(long long*)((uint64_t)this + 0x40) = -1; + *(long long*)((uint64_t)this + 0x48) = -1; + *(long long*)((uint64_t)this + 0x50) = -1; + *(long long*)((uint64_t)this + 0x58) = -1; + *(long long*)((uint64_t)this + 0x60) = -1; + *(long long*)((uint64_t)this + 0x68) = -1; + *(long long*)((uint64_t)this + 0x70) = -1; + *(long long*)((uint64_t)this + 0x78) = -1; + *(int*)((uint64_t)this + 0x80) = 0x01010101; + *(int*)((uint64_t)this + 0x84) = 0x01010101; + *(int*)((uint64_t)this + 0x88) = 0x01010101; + *(int*)((uint64_t)this + 0x8c) = 0x01010101; + *(int*)((uint64_t)this + 0x90) = 0x01010101; + *(int*)((uint64_t)this + 0x94) = 0x01010101; + *(int*)((uint64_t)this + 0x98) = 0; + *(long long*)((uint64_t)this + 0x9c) = -1; + *(long long*)((uint64_t)this + 0xa4) = -1; + *(int*)((uint64_t)this + 0xac) = -1; + *(long long*)((uint64_t)this + 0xb0) = 0; + *(int*)((uint64_t)this + 0xb8) = -1; + *(byte*)((uint64_t)this + 0xbc) = 0; + *(long long*)((uint64_t)this + 0xc0) = -1; + *(byte*)((uint64_t)this + 0xc8) = 0; + *(int*)((uint64_t)this + 0xcc) = -1; + *(long long*)((uint64_t)this + 0xd0) = 0; + *(int*)((uint64_t)this + 0xd8) = -1; + *(byte*)((uint64_t)this + 0xdc) = 0; + *(byte*)((uint64_t)this + 0xdd) = 0; + *(byte*)((uint64_t)this + 0xde) = 0; + *(byte*)((uint64_t)this + 0xdf) = 0; + *(byte*)((uint64_t)this + 0xe0) = 0; + *(byte*)((uint64_t)this + 0xe1) = 0; + *(byte*)((uint64_t)this + 0xe2) = 0; + *(byte*)((uint64_t)this + 0xe3) = 0; + } }; @@ -43,6 +98,7 @@ namespace TLAC::Components static void UpdateScoreCache(); static void UpdateSingleScoreCacheEntry(int pvNum, int diff, int exDiff); + static void UpdateSingleScoreCacheRivalEntry(int pvNum, int diff, int exDiff); static DivaScore* GetCachedScore(int pvNum, int diff, int exDiff); static void UpdateClearCounts(); @@ -53,5 +109,6 @@ namespace TLAC::Components static bool checkExistingScoreValid(int pv, int difficulty, int isEx); static WCHAR configPath[256]; + static WCHAR rival_configPath[256]; }; }