1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-06 06:32:56 +01:00

Fix #2845: Remove file size limit on map send

This commit is contained in:
zsilencer
2016-02-02 14:11:19 -07:00
parent b2083deed0
commit 41a52065fa
2 changed files with 63 additions and 56 deletions

View File

@@ -1279,14 +1279,23 @@ void Network::Server_Send_AUTH(NetworkConnection& connection)
void Network::Server_Send_MAP(NetworkConnection* connection)
{
int buffersize = 0x600000;
std::vector<uint8> buffer(buffersize);
bool RLEState = gUseRLE;
gUseRLE = false;
SDL_RWops* rw = SDL_RWFromMem(&buffer[0], buffersize);
FILE* temp = tmpfile();
if (!temp) {
log_warning("Failed to create temporary file to save map.");
return;
}
SDL_RWops* rw = SDL_RWFromFP(temp, SDL_TRUE);
scenario_save_network(rw);
gUseRLE = RLEState;
int size = (int)SDL_RWtell(rw);
std::vector<uint8> buffer(size);
SDL_RWseek(rw, 0, RW_SEEK_SET);
if (SDL_RWread(rw, &buffer[0], size, 1) == 0) {
log_warning("Failed to read temporary map file into memory.");
return;
}
size_t chunksize = 1000;
size_t out_size;
unsigned char *compressed = util_zlib_deflate(&buffer[0], size, &out_size);
@@ -1671,62 +1680,55 @@ void Network::Client_Handle_MAP(NetworkConnection& connection, NetworkPacket& pa
{
uint32 size, offset;
packet >> size >> offset;
if (offset > 0x600000) {
// too big
int chunksize = packet.size - packet.read;
if (chunksize <= 0) {
return;
} else {
int chunksize = packet.size - packet.read;
if (chunksize <= 0) {
return;
}
if (offset + chunksize > chunk_buffer.size()) {
chunk_buffer.resize(offset + chunksize);
}
char status[256];
sprintf(status, "Downloading map ... (%u / %u)", (offset + chunksize) / 1000, size / 1000);
window_network_status_open(status);
memcpy(&chunk_buffer[offset], (void*)packet.Read(chunksize), chunksize);
if (offset + chunksize == size) {
window_network_status_close();
bool has_to_free = false;
unsigned char *data = &chunk_buffer[0];
size_t data_size = size;
// zlib-compressed
if (strcmp("open2_sv6_zlib", (char *)&chunk_buffer[0]) == 0)
{
log_warning("Received zlib-compressed sv6 map");
has_to_free = true;
size_t header_len = strlen("open2_sv6_zlib") + 1;
data = util_zlib_inflate(&chunk_buffer[header_len], size - header_len, &data_size);
if (data == NULL)
{
log_warning("Failed to decompress data sent from server.");
return;
}
} else {
log_warning("Assuming received map is in plain sv6 format");
}
if (offset + chunksize > chunk_buffer.size()) {
chunk_buffer.resize(offset + chunksize);
SDL_RWops* rw = SDL_RWFromMem(data, data_size);
if (game_load_network(rw)) {
game_load_init();
game_command_queue.clear();
server_tick = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, uint32);
server_srand0_tick = 0;
// window_network_status_open("Loaded new map from network");
_desynchronised = false;
}
char status[256];
sprintf(status, "Downloading map ... (%u / %u)", (offset + chunksize) / 1000, size / 1000);
window_network_status_open(status);
memcpy(&chunk_buffer[offset], (void*)packet.Read(chunksize), chunksize);
if (offset + chunksize == size) {
window_network_status_close();
bool has_to_free = false;
unsigned char *data = &chunk_buffer[0];
size_t data_size = size;
// zlib-compressed
if (strcmp("open2_sv6_zlib", (char *)&chunk_buffer[0]) == 0)
{
log_warning("Received zlib-compressed sv6 map");
has_to_free = true;
size_t header_len = strlen("open2_sv6_zlib") + 1;
data = util_zlib_inflate(&chunk_buffer[header_len], size - header_len, &data_size);
if (data == NULL)
{
log_warning("Failed to decompress data sent from server.");
return;
}
} else {
log_warning("Assuming received map is in plain sv6 format");
}
SDL_RWops* rw = SDL_RWFromMem(data, data_size);
if (game_load_network(rw)) {
game_load_init();
game_command_queue.clear();
server_tick = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, uint32);
server_srand0_tick = 0;
// window_network_status_open("Loaded new map from network");
_desynchronised = false;
}
else
{
//Something went wrong, game is not loaded. Return to main screen.
game_do_command(0, GAME_COMMAND_FLAG_APPLY, 0, 0, GAME_COMMAND_LOAD_OR_QUIT, 1, 0);
}
SDL_RWclose(rw);
if (has_to_free)
{
free(data);
}
else
{
//Something went wrong, game is not loaded. Return to main screen.
game_do_command(0, GAME_COMMAND_FLAG_APPLY, 0, 0, GAME_COMMAND_LOAD_OR_QUIT, 1, 0);
}
SDL_RWclose(rw);
if (has_to_free)
{
free(data);
}
}
}

View File

@@ -1085,11 +1085,16 @@ int scenario_save_network(SDL_RWops* rw)
memcpy(s6->map_elements, (void*)0x00F663B8, 0x180000);
memcpy(&s6->dword_010E63B8, (void*)0x010E63B8, 0x2E8570);
safe_strcpy(s6->scenario_filename, _scenarioFileName, sizeof(s6->scenario_filename));
scenario_fix_ghosts(s6);
game_convert_strings_to_rct2(s6);
scenario_save_s6(rw, s6);
free(s6);
reset_loaded_objects();
// Write other data not in normal save files
SDL_WriteLE32(rw, RCT2_GLOBAL(RCT2_ADDRESS_GAME_PAUSED, uint32));
SDL_WriteLE32(rw, _guestGenerationProbability);