Ticket #3637: hash_dump.patch

File hash_dump.patch, 4.3 KB (added by elexis, 8 years ago)

Creates one directory per turn, with one file per component containing all bytes that are hashed for that component. Thus should be able to identify the diff in the data that is hashed (rather than a diff of simstates).

  • source/ps/Game.cpp

    extern GameLoopState* g_AtlasGameLoop;  
    5656
    5757/**
    5858 * Globally accessible pointer to the CGame object.
    5959 **/
    6060CGame *g_Game=NULL;
     61// I'm not supposed to be here
     62char g_HashDirectory[2048];
     63FILE* g_HashFile;
    6164
    6265/**
    6366 * Constructor
    6467 *
    6568 **/
  • source/ps/Game.h

     
    1717
    1818#ifndef INCLUDED_GAME
    1919#define INCLUDED_GAME
    2020
    2121#include "ps/Errors.h"
     22#include "ps/Filesystem.h"
    2223#include <vector>
    2324
    2425#include "scriptinterface/ScriptVal.h"
    2526#include "simulation2/helpers/Player.h"
    2627
    private:  
    210211    u32 m_FinalReplayTurn;
    211212};
    212213
    213214extern CGame *g_Game;
    214215
     216// I'm not supposed to be here
     217extern char g_HashDirectory[2048];
     218extern FILE* g_HashFile;
     219
    215220#endif
  • source/simulation2/serialization/HashSerializer.h

     
    1717
    1818#ifndef INCLUDED_HASHSERIALIZER
    1919#define INCLUDED_HASHSERIALIZER
    2020
    2121#include "BinarySerializer.h"
    22 
     22#include "network/NetTurnManager.h"
    2323#include "maths/MD5.h"
     24#include "ps/Game.h"
    2425
    2526class CHashSerializerImpl
    2627{
    2728    // We don't care about cryptographic strength, just about detection of
    2829    // unintended changes and about performance, so MD5 is an adequate choice
    class CHashSerializerImpl  
    3031
    3132public:
    3233    size_t GetHashLength();
    3334    const u8* ComputeHash();
    3435
    35     void Put(const char* UNUSED(name), const u8* data, size_t len)
     36    CHashSerializerImpl()
     37    {
     38        sprintf(g_HashDirectory, "/media/tmpfs2/oos/hash/turn_%u/", g_Game->GetTurnManager()->GetCurrentTurn());
     39        CreateDirectories(g_HashDirectory, 0700);
     40    }
     41
     42    void Put(const char* name, const u8* data, size_t len)
    3643    {
    37         m_Hash.Update(data, len);
     44        if (!g_HashFile)
     45        {
     46            // We don't care about the RNG and next entity id field for now
     47            debug_printf("Hash file not opened yet!");
     48            return;
     49        }
     50
     51        if (!name)
     52        {
     53            debug_printf("Bad property name\n");
     54            return;
     55        }
     56
     57        if (data)
     58        {
     59            fwrite(name, 1, strlen(name), g_HashFile);
     60            fwrite(data, 1, len, g_HashFile);
     61
     62            m_Hash.Update(data, len);
     63        }
     64        else
     65            debug_printf("Bad file or bad data\n");
    3866    }
    3967
    4068private:
    4169    HashFunc m_Hash;
    4270    u8 m_HashData[HashFunc::DIGESTSIZE];
  • source/simulation2/system/ComponentManagerSerialization.cpp

    bool CComponentManager::DumpDebugState(s  
    9595    return true;
    9696}
    9797
    9898bool CComponentManager::ComputeStateHash(std::string& outHash, bool quick)
    9999{
     100    // Always do full checks
     101    quick = false;
     102
    100103    // Hash serialization: this includes the minimal data necessary to detect
    101104    // differences in the state, and ignores things like counts and names
    102105
    103106    // If 'quick' is set, this checks even fewer things, so that it will
    104107    // be fast enough to run every turn but will typically detect any
    bool CComponentManager::ComputeStateHash  
    129132        }
    130133
    131134        if (!needsSerialization)
    132135            continue;
    133136
     137        // Write the data of every component to a separate file every turn
     138        CStr componentName = m_ComponentTypesById.find(cit->first)->second.name;
     139        char filename[2048];
     140        sprintf(filename, "%s/%s", g_HashDirectory, componentName.c_str());
     141        g_HashFile = fopen(filename, "wb");
    134142        serializer.NumberI32_Unbounded("component type id", cit->first);
    135143
    136144        for (std::map<entity_id_t, IComponent*>::const_iterator eit = cit->second.begin(); eit != cit->second.end(); ++eit)
    137145        {
    138146            // Don't serialize local entities
    bool CComponentManager::ComputeStateHash  
    140148                continue;
    141149
    142150            serializer.NumberU32_Unbounded("entity id", eit->first);
    143151            eit->second->Serialize(serializer);
    144152        }
     153        fclose(g_HashFile);
    145154    }
    146155
    147156    outHash = std::string((const char*)serializer.ComputeHash(), serializer.GetHashLength());
    148157
    149158    // TODO: catch exceptions