From 6e2514cd0d78bdb23e8f1aba133d5c4fd0e8444c Mon Sep 17 00:00:00 2001 From: Matt Date: Tue, 11 Dec 2018 03:05:57 +0100 Subject: [PATCH] Refactor sprite_checksum, returns rct_sprite_checksum now. --- src/openrct2/network/Network.cpp | 11 +++++----- src/openrct2/world/Sprite.cpp | 35 ++++++++++++++++++++------------ src/openrct2/world/Sprite.h | 9 +++++++- 3 files changed, 36 insertions(+), 19 deletions(-) diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index fe9a10dd15..51c65597e3 100644 --- a/src/openrct2/network/Network.cpp +++ b/src/openrct2/network/Network.cpp @@ -941,14 +941,14 @@ bool Network::CheckSRAND(uint32_t tick, uint32_t srand0) { server_srand0_tick = 0; // Check that the server and client sprite hashes match - const char* client_sprite_hash = sprite_checksum(); - const bool sprites_mismatch = server_sprite_hash[0] != '\0' - && strcmp(client_sprite_hash, server_sprite_hash.c_str()) != 0; + rct_sprite_checksum checksum = sprite_checksum(); + std::string client_sprite_hash = checksum.ToString(); + const bool sprites_mismatch = server_sprite_hash[0] != '\0' && client_sprite_hash != server_sprite_hash; // Check PRNG values and sprite hashes, if exist if ((srand0 != server_srand0) || sprites_mismatch) { # ifdef DEBUG_DESYNC - dbg_report_desync(tick, srand0, server_srand0, client_sprite_hash, server_sprite_hash.c_str()); + dbg_report_desync(tick, srand0, server_srand0, client_sprite_hash.c_str(), server_sprite_hash.c_str()); # endif return false; } @@ -1613,7 +1613,8 @@ void Network::Server_Send_TICK() *packet << flags; if (flags & NETWORK_TICK_FLAG_CHECKSUMS) { - packet->WriteString(sprite_checksum()); + rct_sprite_checksum checksum = sprite_checksum(); + packet->WriteString(checksum.ToString().c_str()); } SendPacketToClients(*packet); } diff --git a/src/openrct2/world/Sprite.cpp b/src/openrct2/world/Sprite.cpp index 507e4732d4..09e64c05a3 100644 --- a/src/openrct2/world/Sprite.cpp +++ b/src/openrct2/world/Sprite.cpp @@ -53,6 +53,22 @@ static LocationXYZ16 _spritelocations2[MAX_SPRITES]; static size_t GetSpatialIndexOffset(int32_t x, int32_t y); +std::string rct_sprite_checksum::ToString() const +{ + std::string result; + + result.clear(); + result.reserve(raw.size() * 2); + for (auto b : raw) + { + char buf[3]; + snprintf(buf, 3, "%02x", b); + result.append(buf); + } + + return result; +} + rct_sprite* try_get_sprite(size_t spriteIndex) { rct_sprite* sprite = nullptr; @@ -207,14 +223,15 @@ static size_t GetSpatialIndexOffset(int32_t x, int32_t y) #ifndef DISABLE_NETWORK -const char* sprite_checksum() +rct_sprite_checksum sprite_checksum() { using namespace Crypt; // TODO Remove statics, should be one of these per sprite manager / OpenRCT2 context. // Alternatively, make a new class for this functionality. static std::unique_ptr> _spriteHashAlg; - static std::string result; + + rct_sprite_checksum checksum; try { @@ -245,23 +262,15 @@ const char* sprite_checksum() } } - auto hash = _spriteHashAlg->Finish(); - - result.clear(); - result.reserve(hash.size() * 2); - for (auto b : hash) - { - char buf[3]; - snprintf(buf, 3, "%02x", b); - result.append(buf); - } - return result.c_str(); + checksum.raw = std::move(_spriteHashAlg->Finish()); } catch (std::exception& e) { log_error("sprite_checksum failed: %s", e.what()); throw; } + + return checksum; } #else diff --git a/src/openrct2/world/Sprite.h b/src/openrct2/world/Sprite.h index eed4bf90de..8b6cfd6ec4 100644 --- a/src/openrct2/world/Sprite.h +++ b/src/openrct2/world/Sprite.h @@ -201,6 +201,13 @@ union rct_sprite }; assert_struct_size(rct_sprite, 0x100); +struct rct_sprite_checksum +{ + std::array raw; + + std::string ToString() const; +}; + #pragma pack(pop) enum @@ -305,7 +312,7 @@ void crashed_vehicle_particle_update(rct_crashed_vehicle_particle* particle); void crash_splash_create(int32_t x, int32_t y, int32_t z); void crash_splash_update(rct_crash_splash* splash); -const char* sprite_checksum(); +rct_sprite_checksum sprite_checksum(); void sprite_set_flashing(rct_sprite* sprite, bool flashing); bool sprite_get_flashing(rct_sprite* sprite);