mirror of https://github.com/OpenRCT2/OpenRCT2.git
Merge pull request #18259 from Gymnasiast/fix/17341
Close #17341: Always allow loading with incorrect checksum
This commit is contained in:
commit
4878db7c06
|
@ -2710,8 +2710,6 @@ STR_5503 :Enter hostname or IP address:
|
||||||
STR_5504 :Show multiplayer status
|
STR_5504 :Show multiplayer status
|
||||||
STR_5505 :Unable to connect to server.
|
STR_5505 :Unable to connect to server.
|
||||||
STR_5506 :Guests ignore intensities
|
STR_5506 :Guests ignore intensities
|
||||||
STR_5508 :Allow loading files with incorrect checksums
|
|
||||||
STR_5509 :Allows loading scenarios and saves{NEWLINE}that have an incorrect checksum,{NEWLINE}like the scenarios from the demo{NEWLINE}or damaged saves.
|
|
||||||
STR_5510 :Default sound device
|
STR_5510 :Default sound device
|
||||||
STR_5511 :(UNKNOWN)
|
STR_5511 :(UNKNOWN)
|
||||||
STR_5512 :Save Game As
|
STR_5512 :Save Game As
|
||||||
|
|
|
@ -196,7 +196,6 @@ enum WindowOptionsWidgetIdx {
|
||||||
|
|
||||||
// Advanced
|
// Advanced
|
||||||
WIDX_DEBUGGING_TOOLS = WIDX_PAGE_START,
|
WIDX_DEBUGGING_TOOLS = WIDX_PAGE_START,
|
||||||
WIDX_ALLOW_LOADING_WITH_INCORRECT_CHECKSUM,
|
|
||||||
WIDX_SAVE_PLUGIN_DATA_CHECKBOX,
|
WIDX_SAVE_PLUGIN_DATA_CHECKBOX,
|
||||||
WIDX_STAY_CONNECTED_AFTER_DESYNC,
|
WIDX_STAY_CONNECTED_AFTER_DESYNC,
|
||||||
WIDX_ALWAYS_NATIVE_LOADSAVE,
|
WIDX_ALWAYS_NATIVE_LOADSAVE,
|
||||||
|
@ -384,7 +383,6 @@ static rct_widget window_options_misc_widgets[] = {
|
||||||
static rct_widget window_options_advanced_widgets[] = {
|
static rct_widget window_options_advanced_widgets[] = {
|
||||||
MAIN_OPTIONS_WIDGETS,
|
MAIN_OPTIONS_WIDGETS,
|
||||||
MakeWidget ({ 10, 54}, {290, 12}, WindowWidgetType::Checkbox, WindowColour::Tertiary , STR_ENABLE_DEBUGGING_TOOLS, STR_ENABLE_DEBUGGING_TOOLS_TIP ), // Enable debugging tools
|
MakeWidget ({ 10, 54}, {290, 12}, WindowWidgetType::Checkbox, WindowColour::Tertiary , STR_ENABLE_DEBUGGING_TOOLS, STR_ENABLE_DEBUGGING_TOOLS_TIP ), // Enable debugging tools
|
||||||
MakeWidget ({ 10, 69}, {290, 12}, WindowWidgetType::Checkbox, WindowColour::Tertiary , STR_ALLOW_LOADING_WITH_INCORRECT_CHECKSUM, STR_ALLOW_LOADING_WITH_INCORRECT_CHECKSUM_TIP), // Allow loading with incorrect checksum
|
|
||||||
MakeWidget ({ 10, 84}, {290, 12}, WindowWidgetType::Checkbox, WindowColour::Tertiary , STR_SAVE_PLUGIN_DATA, STR_SAVE_PLUGIN_DATA_TIP ), // Export plug-in objects with saved games
|
MakeWidget ({ 10, 84}, {290, 12}, WindowWidgetType::Checkbox, WindowColour::Tertiary , STR_SAVE_PLUGIN_DATA, STR_SAVE_PLUGIN_DATA_TIP ), // Export plug-in objects with saved games
|
||||||
MakeWidget ({ 10, 99}, {290, 12}, WindowWidgetType::Checkbox, WindowColour::Tertiary , STR_STAY_CONNECTED_AFTER_DESYNC, STR_STAY_CONNECTED_AFTER_DESYNC_TIP ), // Do not disconnect after the client desynchronises with the server
|
MakeWidget ({ 10, 99}, {290, 12}, WindowWidgetType::Checkbox, WindowColour::Tertiary , STR_STAY_CONNECTED_AFTER_DESYNC, STR_STAY_CONNECTED_AFTER_DESYNC_TIP ), // Do not disconnect after the client desynchronises with the server
|
||||||
MakeWidget ({ 10, 114}, {290, 12}, WindowWidgetType::Checkbox, WindowColour::Secondary, STR_ALWAYS_NATIVE_LOADSAVE, STR_ALWAYS_NATIVE_LOADSAVE_TIP ), // Use native load/save window
|
MakeWidget ({ 10, 114}, {290, 12}, WindowWidgetType::Checkbox, WindowColour::Secondary, STR_ALWAYS_NATIVE_LOADSAVE, STR_ALWAYS_NATIVE_LOADSAVE_TIP ), // Use native load/save window
|
||||||
|
@ -1878,11 +1876,6 @@ private:
|
||||||
config_save_default();
|
config_save_default();
|
||||||
gfx_invalidate_screen();
|
gfx_invalidate_screen();
|
||||||
break;
|
break;
|
||||||
case WIDX_ALLOW_LOADING_WITH_INCORRECT_CHECKSUM:
|
|
||||||
gConfigGeneral.allow_loading_with_incorrect_checksum = !gConfigGeneral.allow_loading_with_incorrect_checksum;
|
|
||||||
config_save_default();
|
|
||||||
Invalidate();
|
|
||||||
break;
|
|
||||||
case WIDX_SAVE_PLUGIN_DATA_CHECKBOX:
|
case WIDX_SAVE_PLUGIN_DATA_CHECKBOX:
|
||||||
gConfigGeneral.save_plugin_data ^= 1;
|
gConfigGeneral.save_plugin_data ^= 1;
|
||||||
config_save_default();
|
config_save_default();
|
||||||
|
@ -2001,8 +1994,6 @@ private:
|
||||||
void AdvancedPrepareDraw()
|
void AdvancedPrepareDraw()
|
||||||
{
|
{
|
||||||
SetCheckboxValue(WIDX_DEBUGGING_TOOLS, gConfigGeneral.debugging_tools);
|
SetCheckboxValue(WIDX_DEBUGGING_TOOLS, gConfigGeneral.debugging_tools);
|
||||||
WidgetSetCheckboxValue(
|
|
||||||
*this, WIDX_ALLOW_LOADING_WITH_INCORRECT_CHECKSUM, gConfigGeneral.allow_loading_with_incorrect_checksum);
|
|
||||||
SetCheckboxValue(WIDX_SAVE_PLUGIN_DATA_CHECKBOX, gConfigGeneral.save_plugin_data);
|
SetCheckboxValue(WIDX_SAVE_PLUGIN_DATA_CHECKBOX, gConfigGeneral.save_plugin_data);
|
||||||
SetCheckboxValue(WIDX_STAY_CONNECTED_AFTER_DESYNC, gConfigNetwork.stay_connected);
|
SetCheckboxValue(WIDX_STAY_CONNECTED_AFTER_DESYNC, gConfigNetwork.stay_connected);
|
||||||
SetCheckboxValue(WIDX_ALWAYS_NATIVE_LOADSAVE, gConfigGeneral.use_native_browse_dialog);
|
SetCheckboxValue(WIDX_ALWAYS_NATIVE_LOADSAVE, gConfigGeneral.use_native_browse_dialog);
|
||||||
|
|
|
@ -192,7 +192,6 @@ namespace Config
|
||||||
model->enable_light_fx_for_vehicles = isHardware && reader->GetBoolean("enable_light_fx_for_vehicles", false);
|
model->enable_light_fx_for_vehicles = isHardware && reader->GetBoolean("enable_light_fx_for_vehicles", false);
|
||||||
model->upper_case_banners = reader->GetBoolean("upper_case_banners", false);
|
model->upper_case_banners = reader->GetBoolean("upper_case_banners", false);
|
||||||
model->disable_lightning_effect = reader->GetBoolean("disable_lightning_effect", false);
|
model->disable_lightning_effect = reader->GetBoolean("disable_lightning_effect", false);
|
||||||
model->allow_loading_with_incorrect_checksum = reader->GetBoolean("allow_loading_with_incorrect_checksum", true);
|
|
||||||
model->steam_overlay_pause = reader->GetBoolean("steam_overlay_pause", true);
|
model->steam_overlay_pause = reader->GetBoolean("steam_overlay_pause", true);
|
||||||
model->window_scale = reader->GetFloat("window_scale", Platform::GetDefaultScale());
|
model->window_scale = reader->GetFloat("window_scale", Platform::GetDefaultScale());
|
||||||
model->show_fps = reader->GetBoolean("show_fps", false);
|
model->show_fps = reader->GetBoolean("show_fps", false);
|
||||||
|
@ -278,7 +277,6 @@ namespace Config
|
||||||
writer->WriteBoolean("enable_light_fx_for_vehicles", model->enable_light_fx_for_vehicles);
|
writer->WriteBoolean("enable_light_fx_for_vehicles", model->enable_light_fx_for_vehicles);
|
||||||
writer->WriteBoolean("upper_case_banners", model->upper_case_banners);
|
writer->WriteBoolean("upper_case_banners", model->upper_case_banners);
|
||||||
writer->WriteBoolean("disable_lightning_effect", model->disable_lightning_effect);
|
writer->WriteBoolean("disable_lightning_effect", model->disable_lightning_effect);
|
||||||
writer->WriteBoolean("allow_loading_with_incorrect_checksum", model->allow_loading_with_incorrect_checksum);
|
|
||||||
writer->WriteBoolean("steam_overlay_pause", model->steam_overlay_pause);
|
writer->WriteBoolean("steam_overlay_pause", model->steam_overlay_pause);
|
||||||
writer->WriteFloat("window_scale", model->window_scale);
|
writer->WriteFloat("window_scale", model->window_scale);
|
||||||
writer->WriteBoolean("show_fps", model->show_fps);
|
writer->WriteBoolean("show_fps", model->show_fps);
|
||||||
|
|
|
@ -89,7 +89,6 @@ struct GeneralConfiguration
|
||||||
// Miscellaneous
|
// Miscellaneous
|
||||||
bool play_intro;
|
bool play_intro;
|
||||||
int32_t window_snap_proximity;
|
int32_t window_snap_proximity;
|
||||||
bool allow_loading_with_incorrect_checksum;
|
|
||||||
bool save_plugin_data;
|
bool save_plugin_data;
|
||||||
bool debugging_tools;
|
bool debugging_tools;
|
||||||
int32_t autosave_frequency;
|
int32_t autosave_frequency;
|
||||||
|
|
|
@ -345,7 +345,6 @@
|
||||||
<ClInclude Include="rct12\SawyerChunk.h" />
|
<ClInclude Include="rct12\SawyerChunk.h" />
|
||||||
<ClInclude Include="rct12\SawyerChunkReader.h" />
|
<ClInclude Include="rct12\SawyerChunkReader.h" />
|
||||||
<ClInclude Include="rct12\SawyerChunkWriter.h" />
|
<ClInclude Include="rct12\SawyerChunkWriter.h" />
|
||||||
<ClInclude Include="rct12\SawyerEncoding.h" />
|
|
||||||
<ClInclude Include="rct1\Limits.h" />
|
<ClInclude Include="rct1\Limits.h" />
|
||||||
<ClInclude Include="rct1\RCT1.h" />
|
<ClInclude Include="rct1\RCT1.h" />
|
||||||
<ClInclude Include="rct1\Tables.h" />
|
<ClInclude Include="rct1\Tables.h" />
|
||||||
|
@ -841,7 +840,6 @@
|
||||||
<ClCompile Include="rct12\SawyerChunk.cpp" />
|
<ClCompile Include="rct12\SawyerChunk.cpp" />
|
||||||
<ClCompile Include="rct12\SawyerChunkReader.cpp" />
|
<ClCompile Include="rct12\SawyerChunkReader.cpp" />
|
||||||
<ClCompile Include="rct12\SawyerChunkWriter.cpp" />
|
<ClCompile Include="rct12\SawyerChunkWriter.cpp" />
|
||||||
<ClCompile Include="rct12\SawyerEncoding.cpp" />
|
|
||||||
<ClCompile Include="rct1\S4Importer.cpp" />
|
<ClCompile Include="rct1\S4Importer.cpp" />
|
||||||
<ClCompile Include="rct1\T4Importer.cpp" />
|
<ClCompile Include="rct1\T4Importer.cpp" />
|
||||||
<ClCompile Include="rct1\Tables.cpp" />
|
<ClCompile Include="rct1\Tables.cpp" />
|
||||||
|
|
|
@ -2841,8 +2841,6 @@ enum : uint16_t
|
||||||
STR_SHOW_MULTIPLAYER_STATUS_TIP = 5504,
|
STR_SHOW_MULTIPLAYER_STATUS_TIP = 5504,
|
||||||
STR_UNABLE_TO_CONNECT_TO_SERVER = 5505,
|
STR_UNABLE_TO_CONNECT_TO_SERVER = 5505,
|
||||||
STR_CHEAT_IGNORE_INTENSITY = 5506,
|
STR_CHEAT_IGNORE_INTENSITY = 5506,
|
||||||
STR_ALLOW_LOADING_WITH_INCORRECT_CHECKSUM = 5508,
|
|
||||||
STR_ALLOW_LOADING_WITH_INCORRECT_CHECKSUM_TIP = 5509,
|
|
||||||
STR_OPTIONS_SOUND_VALUE_DEFAULT = 5510,
|
STR_OPTIONS_SOUND_VALUE_DEFAULT = 5510,
|
||||||
STR_OPTIONS_SOUND_VALUE_UNKNOWN = 5511,
|
STR_OPTIONS_SOUND_VALUE_UNKNOWN = 5511,
|
||||||
STR_SAVE_GAME_AS = 5512,
|
STR_SAVE_GAME_AS = 5512,
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
#include "../rct1/RCT1.h"
|
#include "../rct1/RCT1.h"
|
||||||
#include "../rct1/Tables.h"
|
#include "../rct1/Tables.h"
|
||||||
#include "../rct12/SawyerChunkReader.h"
|
#include "../rct12/SawyerChunkReader.h"
|
||||||
#include "../rct12/SawyerEncoding.h"
|
|
||||||
#include "../ride/Ride.h"
|
#include "../ride/Ride.h"
|
||||||
#include "../ride/RideData.h"
|
#include "../ride/RideData.h"
|
||||||
#include "../ride/TrackDesign.h"
|
#include "../ride/TrackDesign.h"
|
||||||
|
@ -53,12 +52,6 @@ namespace RCT1
|
||||||
|
|
||||||
bool LoadFromStream(OpenRCT2::IStream* stream) override
|
bool LoadFromStream(OpenRCT2::IStream* stream) override
|
||||||
{
|
{
|
||||||
auto checksumType = SawyerEncoding::ValidateTrackChecksum(stream);
|
|
||||||
if (!gConfigGeneral.allow_loading_with_incorrect_checksum && checksumType == RCT12TrackDesignVersion::unknown)
|
|
||||||
{
|
|
||||||
throw IOException("Invalid checksum.");
|
|
||||||
}
|
|
||||||
|
|
||||||
auto chunkReader = SawyerChunkReader(stream);
|
auto chunkReader = SawyerChunkReader(stream);
|
||||||
auto data = chunkReader.ReadChunkTrack();
|
auto data = chunkReader.ReadChunkTrack();
|
||||||
_stream.WriteArray<const uint8_t>(reinterpret_cast<const uint8_t*>(data->GetData()), data->GetLength());
|
_stream.WriteArray<const uint8_t>(reinterpret_cast<const uint8_t*>(data->GetData()), data->GetLength());
|
||||||
|
|
|
@ -1,107 +0,0 @@
|
||||||
/*****************************************************************************
|
|
||||||
* Copyright (c) 2014-2022 OpenRCT2 developers
|
|
||||||
*
|
|
||||||
* For a complete list of all authors, please refer to contributors.md
|
|
||||||
* Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
|
|
||||||
*
|
|
||||||
* OpenRCT2 is licensed under the GNU General Public License version 3.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
#include "SawyerEncoding.h"
|
|
||||||
|
|
||||||
#include "../core/IStream.hpp"
|
|
||||||
#include "../core/Numerics.hpp"
|
|
||||||
#include "RCT12.h"
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
namespace SawyerEncoding
|
|
||||||
{
|
|
||||||
bool ValidateChecksum(OpenRCT2::IStream* stream)
|
|
||||||
{
|
|
||||||
uint64_t initialPosition = stream->GetPosition();
|
|
||||||
uint64_t dataSize = stream->GetLength() - initialPosition;
|
|
||||||
if (dataSize < 8)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
dataSize -= 4;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// Calculate checksum
|
|
||||||
uint32_t checksum = 0;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
uint8_t buffer[4096];
|
|
||||||
uint64_t bufferSize = std::min<uint64_t>(dataSize, sizeof(buffer));
|
|
||||||
stream->Read(buffer, bufferSize);
|
|
||||||
|
|
||||||
for (uint64_t i = 0; i < bufferSize; i++)
|
|
||||||
{
|
|
||||||
checksum += buffer[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
dataSize -= bufferSize;
|
|
||||||
} while (dataSize != 0);
|
|
||||||
|
|
||||||
// Read file checksum
|
|
||||||
uint32_t fileChecksum = stream->ReadValue<uint32_t>();
|
|
||||||
|
|
||||||
// Rewind back to original position
|
|
||||||
stream->SetPosition(initialPosition);
|
|
||||||
return checksum == fileChecksum;
|
|
||||||
}
|
|
||||||
catch (const std::exception&)
|
|
||||||
{
|
|
||||||
// Rewind back to original position
|
|
||||||
stream->SetPosition(initialPosition);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns version number
|
|
||||||
RCT12TrackDesignVersion ValidateTrackChecksum(OpenRCT2::IStream* stream)
|
|
||||||
{
|
|
||||||
uint64_t initialPosition = stream->GetPosition();
|
|
||||||
uint64_t dataSize = stream->GetLength() - initialPosition;
|
|
||||||
|
|
||||||
if (dataSize < 4)
|
|
||||||
{
|
|
||||||
return RCT12TrackDesignVersion::unknown;
|
|
||||||
}
|
|
||||||
dataSize -= 4;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
const auto buffer = stream->ReadArray<uint8_t>(dataSize);
|
|
||||||
const auto* data = buffer.get();
|
|
||||||
uint32_t checksum = 0;
|
|
||||||
for (size_t i = 0; i < dataSize; i++, ++data)
|
|
||||||
{
|
|
||||||
uint8_t newByte = ((checksum & 0xFF) + *data) & 0xFF;
|
|
||||||
checksum = (checksum & 0xFFFFFF00) + newByte;
|
|
||||||
checksum = Numerics::rol32(checksum, 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t fileChecksum = stream->ReadValue<uint32_t>();
|
|
||||||
// Rewind back to original position
|
|
||||||
stream->SetPosition(initialPosition);
|
|
||||||
|
|
||||||
if (checksum - 0x1D4C1 == fileChecksum)
|
|
||||||
return RCT12TrackDesignVersion::TD6;
|
|
||||||
if (checksum - 0x1A67C == fileChecksum)
|
|
||||||
return RCT12TrackDesignVersion::TD4;
|
|
||||||
if (checksum - 0x1A650 == fileChecksum)
|
|
||||||
return RCT12TrackDesignVersion::TD4;
|
|
||||||
|
|
||||||
return RCT12TrackDesignVersion::unknown;
|
|
||||||
}
|
|
||||||
catch (const std::exception&)
|
|
||||||
{
|
|
||||||
// Rewind back to original position
|
|
||||||
stream->SetPosition(initialPosition);
|
|
||||||
return RCT12TrackDesignVersion::unknown;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // namespace SawyerEncoding
|
|
|
@ -1,25 +0,0 @@
|
||||||
/*****************************************************************************
|
|
||||||
* Copyright (c) 2014-2022 OpenRCT2 developers
|
|
||||||
*
|
|
||||||
* For a complete list of all authors, please refer to contributors.md
|
|
||||||
* Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
|
|
||||||
*
|
|
||||||
* OpenRCT2 is licensed under the GNU General Public License version 3.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "../common.h"
|
|
||||||
|
|
||||||
namespace OpenRCT2
|
|
||||||
{
|
|
||||||
struct IStream;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum class RCT12TrackDesignVersion : uint8_t;
|
|
||||||
|
|
||||||
namespace SawyerEncoding
|
|
||||||
{
|
|
||||||
bool ValidateChecksum(OpenRCT2::IStream* stream);
|
|
||||||
RCT12TrackDesignVersion ValidateTrackChecksum(OpenRCT2::IStream* stream);
|
|
||||||
} // namespace SawyerEncoding
|
|
|
@ -52,7 +52,6 @@
|
||||||
#include "../rct12/EntryList.h"
|
#include "../rct12/EntryList.h"
|
||||||
#include "../rct12/RCT12.h"
|
#include "../rct12/RCT12.h"
|
||||||
#include "../rct12/SawyerChunkReader.h"
|
#include "../rct12/SawyerChunkReader.h"
|
||||||
#include "../rct12/SawyerEncoding.h"
|
|
||||||
#include "../rct2/RCT2.h"
|
#include "../rct2/RCT2.h"
|
||||||
#include "../ride/Ride.h"
|
#include "../ride/Ride.h"
|
||||||
#include "../ride/RideData.h"
|
#include "../ride/RideData.h"
|
||||||
|
@ -141,12 +140,6 @@ namespace RCT2
|
||||||
OpenRCT2::IStream* stream, bool isScenario, [[maybe_unused]] bool skipObjectCheck = false,
|
OpenRCT2::IStream* stream, bool isScenario, [[maybe_unused]] bool skipObjectCheck = false,
|
||||||
const utf8* path = String::Empty) override
|
const utf8* path = String::Empty) override
|
||||||
{
|
{
|
||||||
if (isScenario && !gConfigGeneral.allow_loading_with_incorrect_checksum
|
|
||||||
&& !SawyerEncoding::ValidateChecksum(stream))
|
|
||||||
{
|
|
||||||
throw IOException("Invalid checksum.");
|
|
||||||
}
|
|
||||||
|
|
||||||
auto chunkReader = SawyerChunkReader(stream);
|
auto chunkReader = SawyerChunkReader(stream);
|
||||||
chunkReader.ReadChunk(&_s6.header, sizeof(_s6.header));
|
chunkReader.ReadChunk(&_s6.header, sizeof(_s6.header));
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
#include "../object/ObjectRepository.h"
|
#include "../object/ObjectRepository.h"
|
||||||
#include "../object/RideObject.h"
|
#include "../object/RideObject.h"
|
||||||
#include "../rct12/SawyerChunkReader.h"
|
#include "../rct12/SawyerChunkReader.h"
|
||||||
#include "../rct12/SawyerEncoding.h"
|
|
||||||
#include "../ride/Ride.h"
|
#include "../ride/Ride.h"
|
||||||
#include "../ride/RideData.h"
|
#include "../ride/RideData.h"
|
||||||
#include "../ride/TrackDesign.h"
|
#include "../ride/TrackDesign.h"
|
||||||
|
@ -57,12 +56,6 @@ namespace RCT2
|
||||||
|
|
||||||
bool LoadFromStream(OpenRCT2::IStream* stream) override
|
bool LoadFromStream(OpenRCT2::IStream* stream) override
|
||||||
{
|
{
|
||||||
if (!gConfigGeneral.allow_loading_with_incorrect_checksum
|
|
||||||
&& SawyerEncoding::ValidateTrackChecksum(stream) != RCT12TrackDesignVersion::TD6)
|
|
||||||
{
|
|
||||||
throw IOException("Invalid checksum.");
|
|
||||||
}
|
|
||||||
|
|
||||||
auto chunkReader = SawyerChunkReader(stream);
|
auto chunkReader = SawyerChunkReader(stream);
|
||||||
auto data = chunkReader.ReadChunkTrack();
|
auto data = chunkReader.ReadChunkTrack();
|
||||||
_stream.WriteArray<const uint8_t>(reinterpret_cast<const uint8_t*>(data->GetData()), data->GetLength());
|
_stream.WriteArray<const uint8_t>(reinterpret_cast<const uint8_t*>(data->GetData()), data->GetLength());
|
||||||
|
|
Loading…
Reference in New Issue