mirror of https://github.com/stella-emu/stella.git
fixed high scores hashing
This commit is contained in:
parent
e90cb925b0
commit
44a8ef1db3
|
@ -564,6 +564,24 @@ Int32 HighScoresManager::fromBCD(uInt8 bcd) const
|
|||
return (bcd >> 4) * 10 + bcd % 16;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string HighScoresManager::hash(ScoresData& data) const
|
||||
{
|
||||
ostringstream buf;
|
||||
|
||||
buf << HIGHSCORE_HEADER << data.md5 << md5Props() << data.variation;
|
||||
|
||||
for(uInt32 r = 0; r < NUM_RANKS && data.scores[r].score; ++r)
|
||||
{
|
||||
buf << data.scores[r].score
|
||||
<< data.scores[r].special
|
||||
<< data.scores[r].name
|
||||
<< data.scores[r].date;
|
||||
}
|
||||
|
||||
return MD5::hash(buf.str());
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void HighScoresManager::saveHighScores(ScoresData& data) const
|
||||
{
|
||||
|
@ -571,14 +589,13 @@ void HighScoresManager::saveHighScores(ScoresData& data) const
|
|||
{
|
||||
json hsObject = json::object();
|
||||
json hsData = json::object();
|
||||
json jScores = json::array();
|
||||
|
||||
// Add header so that if the high score format changes in the future,
|
||||
// we'll know right away, without having to parse the rest of the data
|
||||
hsData[VERSION] = HIGHSCORE_HEADER;
|
||||
hsData[MD5] = data.md5;
|
||||
hsData[VARIATION] = data.variation;
|
||||
|
||||
json jScores = json::array();
|
||||
hsObject[VERSION] = HIGHSCORE_HEADER;
|
||||
hsObject[MD5] = data.md5;
|
||||
hsObject[PROPCHECK] = md5Props();
|
||||
|
||||
for(uInt32 r = 0; r < NUM_RANKS && data.scores[r].score; ++r)
|
||||
{
|
||||
|
@ -592,10 +609,10 @@ void HighScoresManager::saveHighScores(ScoresData& data) const
|
|||
jScores.push_back(jScore);
|
||||
}
|
||||
hsData[SCORES] = jScores;
|
||||
hsData[PROPCHECK] = md5Props();
|
||||
hsData[VARIATION] = data.variation;
|
||||
|
||||
hsObject[DATA] = hsData;
|
||||
hsObject[CHECKSUM] = MD5::hash(hsData.dump());
|
||||
hsObject[CHECKSUM] = hash(data);
|
||||
|
||||
myHighscoreRepository->save(data.md5, to_string(data.variation), hsObject.dump(2));
|
||||
}
|
||||
|
@ -608,11 +625,11 @@ void HighScoresManager::saveHighScores(ScoresData& data) const
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void HighScoresManager::loadHighScores(ScoresData& data)
|
||||
{
|
||||
bool invalid = false;
|
||||
ostringstream buf;
|
||||
|
||||
clearHighScores(data);
|
||||
|
||||
bool invalid = false;
|
||||
try {
|
||||
Variant serializedHighscore;
|
||||
|
||||
|
@ -620,27 +637,27 @@ void HighScoresManager::loadHighScores(ScoresData& data)
|
|||
{
|
||||
const json hsObject = json::parse(serializedHighscore.toString());
|
||||
|
||||
if(hsObject.contains(DATA))
|
||||
// First test if we have a valid header
|
||||
// If so, do a complete high score data load
|
||||
if(!hsObject.contains(VERSION) || hsObject.at(VERSION) != HIGHSCORE_HEADER)
|
||||
buf << "Error: Incompatible high scores data for variation " << data.variation << ".";
|
||||
else if(hsObject.contains(DATA))
|
||||
{
|
||||
const json hsData = hsObject.at(DATA);
|
||||
|
||||
// First test if we have a valid header
|
||||
// If so, do a complete high score data load
|
||||
if(!hsData.contains(VERSION) || hsData.at(VERSION) != HIGHSCORE_HEADER)
|
||||
buf << "Error: Incompatible high scores data for variation " << data.variation << ".";
|
||||
if(!load(hsData, data)
|
||||
|| !hsObject.contains(MD5) || hsObject.at(MD5) != data.md5
|
||||
|| !hsObject.contains(PROPCHECK) || hsObject.at(PROPCHECK) != md5Props()
|
||||
|| !hsObject.contains(CHECKSUM) || hsObject.at(CHECKSUM) != hash(data))
|
||||
invalid = true;
|
||||
else
|
||||
{
|
||||
if(!load(hsData, data)
|
||||
|| !hsData.contains(PROPCHECK) || hsData.at(PROPCHECK) != md5Props()
|
||||
|| !hsObject.contains(CHECKSUM) || hsObject.at(CHECKSUM) != MD5::hash(hsData.dump()))
|
||||
invalid = true;
|
||||
else
|
||||
return;
|
||||
}
|
||||
return; // scores loaded OK
|
||||
}
|
||||
else
|
||||
invalid = true;
|
||||
}
|
||||
else
|
||||
return; // no scores for variation found
|
||||
}
|
||||
catch(...) { invalid = true; }
|
||||
|
||||
|
@ -655,8 +672,7 @@ void HighScoresManager::loadHighScores(ScoresData& data)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool HighScoresManager::load(const json& hsData, ScoresData& data)
|
||||
{
|
||||
if(!hsData.contains(MD5) || hsData.at(MD5) != data.md5
|
||||
|| !hsData.contains(VARIATION) || hsData.at(VARIATION) != data.variation
|
||||
if(!hsData.contains(VARIATION) || hsData.at(VARIATION) != data.variation
|
||||
|| !hsData.contains(SCORES))
|
||||
return false;
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#ifndef HIGHSCORES_MANAGER_HXX
|
||||
#define HIGHSCORES_MANAGER_HXX
|
||||
|
||||
#define HIGHSCORE_HEADER "06010000highscores"
|
||||
#define HIGHSCORE_HEADER "06050000highscores"
|
||||
|
||||
class OSystem;
|
||||
|
||||
|
@ -232,6 +232,7 @@ class HighScoresManager
|
|||
|
||||
uInt16 fromHexStr(const string& addr) const;
|
||||
Int32 fromBCD(uInt8 bcd) const;
|
||||
string hash(HSM::ScoresData& data) const;
|
||||
|
||||
/**
|
||||
Loads the current high scores for this game and variation from the given JSON object.
|
||||
|
|
|
@ -204,6 +204,8 @@ HighScoresDialog::HighScoresDialog(OSystem& osystem, DialogContainer& parent,
|
|||
addDefaultsOKCancelBGroup(wid, _font, "Save", "Cancel", " Reset ");
|
||||
_defaultWidget->setToolTip("Click to reset all high scores of this variation.");
|
||||
addToFocusList(wid);
|
||||
|
||||
_focusedWidget = _okWidget; // start with focus on 'Save' button
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
Loading…
Reference in New Issue