From 619b2afc15333cb885abb5342477fd6629df9f8d Mon Sep 17 00:00:00 2001 From: Duncan Date: Sat, 27 Mar 2021 09:36:41 +0000 Subject: [PATCH] Compute checksum by entity type (#14383) * Compute checksum by entity type * Copy only the entity size * Update replays and network version --- CMakeLists.txt | 4 +- openrct2.proj | 4 +- src/openrct2/network/NetworkBase.cpp | 2 +- src/openrct2/world/Sprite.cpp | 57 +++++++++++++++------------- 4 files changed, 36 insertions(+), 31 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0048a089a6..7b78109770 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,8 +48,8 @@ set(TITLE_SEQUENCE_SHA1 "304d13a126c15bf2c86ff13b81a2f2cc1856ac8d") set(OBJECTS_URL "https://github.com/OpenRCT2/objects/releases/download/v1.0.21/objects.zip") set(OBJECTS_SHA1 "c38af45d51a6e440386180feacf76c64720b6ac5") -set(REPLAYS_URL "https://github.com/OpenRCT2/replays/releases/download/v0.0.35/replays.zip") -set(REPLAYS_SHA1 "5875A182E2828B8E0234F496B5D5E84CFE25EFCB") +set(REPLAYS_URL "https://github.com/OpenRCT2/replays/releases/download/v0.0.36/replays.zip") +set(REPLAYS_SHA1 "F539E5BD4F5062C2972C6E0DA974318DB01A0308") option(FORCE32 "Force 32-bit build. It will add `-m32` to compiler flags.") option(WITH_TESTS "Build tests") diff --git a/openrct2.proj b/openrct2.proj index 514df8c008..00eddedcdb 100644 --- a/openrct2.proj +++ b/openrct2.proj @@ -48,8 +48,8 @@ 304d13a126c15bf2c86ff13b81a2f2cc1856ac8d https://github.com/OpenRCT2/objects/releases/download/v1.0.21/objects.zip c38af45d51a6e440386180feacf76c64720b6ac5 - https://github.com/OpenRCT2/replays/releases/download/v0.0.35/replays.zip - 5875A182E2828B8E0234F496B5D5E84CFE25EFCB + https://github.com/OpenRCT2/replays/releases/download/v0.0.36/replays.zip + F539E5BD4F5062C2972C6E0DA974318DB01A0308 diff --git a/src/openrct2/network/NetworkBase.cpp b/src/openrct2/network/NetworkBase.cpp index cfd420b216..bea96f556c 100644 --- a/src/openrct2/network/NetworkBase.cpp +++ b/src/openrct2/network/NetworkBase.cpp @@ -36,7 +36,7 @@ // This string specifies which version of network stream current build uses. // It is used for making sure only compatible builds get connected, even within // single OpenRCT2 version. -#define NETWORK_STREAM_VERSION "6" +#define NETWORK_STREAM_VERSION "7" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION static Peep* _pickup_peep = nullptr; diff --git a/src/openrct2/world/Sprite.cpp b/src/openrct2/world/Sprite.cpp index 593b605d41..7d6f5e40b7 100644 --- a/src/openrct2/world/Sprite.cpp +++ b/src/openrct2/world/Sprite.cpp @@ -275,6 +275,36 @@ void reset_sprite_spatial_index() #ifndef DISABLE_NETWORK +template void ComputeChecksumForEntityType(Crypt::HashAlgorithm<20>* _entityHashAlg) +{ + for (auto* ent : EntityList()) + { + T copy = *ent; + + // Only required for rendering/invalidation, has no meaning to the game state. + copy.sprite_left = copy.sprite_right = copy.sprite_top = copy.sprite_bottom = 0; + copy.sprite_width = copy.sprite_height_negative = copy.sprite_height_positive = 0; + + if constexpr (std::is_base_of_v) + { + // Name is pointer and will not be the same across clients + copy.Name = {}; + + // We set this to 0 because as soon the client selects a guest the window will remove the + // invalidation flags causing the sprite checksum to be different than on server, the flag does not + // affect game state. + copy.WindowInvalidateFlags = 0; + } + + _entityHashAlg->Update(©, sizeof(copy)); + } +} + +template void ComputeChecksumForEntityTypes(Crypt::HashAlgorithm<20>* _entityHashAlg) +{ + (ComputeChecksumForEntityType(_entityHashAlg), ...); +} + rct_sprite_checksum sprite_checksum() { using namespace Crypt; @@ -293,33 +323,8 @@ rct_sprite_checksum sprite_checksum() } _spriteHashAlg->Clear(); - for (size_t i = 0; i < MAX_ENTITIES; i++) - { - // TODO create a way to copy only the specific type - auto sprite = GetEntity(i); - if (sprite != nullptr && sprite->Type != EntityType::Null && !sprite->Is()) - { - // Upconvert it to rct_sprite so that the full size is copied. - auto copy = *reinterpret_cast(sprite); - // Only required for rendering/invalidation, has no meaning to the game state. - copy.misc.sprite_left = copy.misc.sprite_right = copy.misc.sprite_top = copy.misc.sprite_bottom = 0; - copy.misc.sprite_width = copy.misc.sprite_height_negative = copy.misc.sprite_height_positive = 0; - - if (copy.misc.Is()) - { - // Name is pointer and will not be the same across clients - copy.peep.Name = {}; - - // We set this to 0 because as soon the client selects a guest the window will remove the - // invalidation flags causing the sprite checksum to be different than on server, the flag does not - // affect game state. - copy.peep.WindowInvalidateFlags = 0; - } - - _spriteHashAlg->Update(©, sizeof(copy)); - } - } + ComputeChecksumForEntityTypes(_spriteHashAlg.get()); checksum.raw = _spriteHashAlg->Finish(); }