1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-16 03:23:15 +01:00

Fix client being stuck on empty object list

This commit is contained in:
Matt
2020-07-25 15:23:26 +02:00
parent 241ff111dd
commit ab48c00a89

View File

@@ -1490,19 +1490,30 @@ void Network::Server_Send_OBJECTS_LIST(
{
log_verbose("Server sends objects list with %u items", objects.size());
bool startOfObjectList = true;
for (auto* object : objects)
if (objects.empty())
{
std::unique_ptr<NetworkPacket> packet(NetworkPacket::Allocate());
*packet << static_cast<uint32_t>(NETWORK_COMMAND_OBJECTS_LIST) << startOfObjectList
*packet << static_cast<uint32_t>(NETWORK_COMMAND_OBJECTS_LIST) << static_cast<uint32_t>(0)
<< static_cast<uint32_t>(objects.size());
log_verbose("Object %.8s (checksum %x)", object->ObjectEntry.name, object->ObjectEntry.checksum);
packet->Write(reinterpret_cast<const uint8_t*>(object->ObjectEntry.name), 8);
*packet << object->ObjectEntry.checksum << object->ObjectEntry.flags;
connection.QueuePacket(std::move(packet));
startOfObjectList = false;
}
else
{
for (size_t i = 0; i < objects.size(); ++i)
{
const auto* object = objects[i];
std::unique_ptr<NetworkPacket> packet(NetworkPacket::Allocate());
*packet << static_cast<uint32_t>(NETWORK_COMMAND_OBJECTS_LIST) << static_cast<uint32_t>(i)
<< static_cast<uint32_t>(objects.size());
log_verbose("Object %.8s (checksum %x)", object->ObjectEntry.name, object->ObjectEntry.checksum);
packet->Write(reinterpret_cast<const uint8_t*>(object->ObjectEntry.name), 8);
*packet << object->ObjectEntry.checksum << object->ObjectEntry.flags;
connection.QueuePacket(std::move(packet));
}
}
}
@@ -2571,12 +2582,13 @@ void Network::Client_Handle_OBJECTS_LIST(NetworkConnection& connection, NetworkP
{
auto& repo = GetContext()->GetObjectRepository();
bool startOfObjectList = false;
uint32_t index = 0;
uint32_t totalObjects = 0;
packet >> startOfObjectList >> totalObjects;
packet >> index >> totalObjects;
if (startOfObjectList)
if (index == 0)
{
// Start of objects list.
_missingObjects.clear();
}
@@ -2588,41 +2600,44 @@ void Network::Client_Handle_OBJECTS_LIST(NetworkConnection& connection, NetworkP
return;
}
auto name = reinterpret_cast<const char*>(packet.Read(8));
// Required, as packet has no null terminators.
std::string s(name, name + 8);
uint32_t checksum = 0;
uint32_t flags = 0;
packet >> checksum >> flags;
if (totalObjects > 0)
{
char objectListMsg[256];
const uint32_t args[] = {
index + 1,
totalObjects,
};
format_string(objectListMsg, 256, STR_MULTIPLAYER_RECEIVING_OBJECTS_LIST, &args);
const auto* ori = repo.FindObject(s.c_str());
// This could potentially request the object if checksums don't match, but since client
// won't replace its version with server-provided one, we don't do that.
if (ori == nullptr)
{
log_verbose("Requesting object %s with checksum %x from server", s.c_str(), checksum);
_missingObjects.push_back(s);
}
else if (ori->ObjectEntry.checksum != checksum || ori->ObjectEntry.flags != flags)
{
log_warning(
"Object %s has different checksum/flags (%x/%x) than server (%x/%x).", s.c_str(), ori->ObjectEntry.checksum,
ori->ObjectEntry.flags, checksum, flags);
auto intent = Intent(WC_NETWORK_STATUS);
intent.putExtra(INTENT_EXTRA_MESSAGE, std::string{ objectListMsg });
intent.putExtra(INTENT_EXTRA_CALLBACK, []() -> void { gNetwork.Close(); });
context_open_intent(&intent);
auto name = reinterpret_cast<const char*>(packet.Read(8));
// Required, as packet has no null terminators.
std::string s(name, name + 8);
uint32_t checksum = 0;
uint32_t flags = 0;
packet >> checksum >> flags;
const ObjectRepositoryItem* ori = repo.FindObject(s.c_str());
// This could potentially request the object if checksums don't match, but since client
// won't replace its version with server-provided one, we don't do that.
if (ori == nullptr)
{
log_verbose("Requesting object %s with checksum %x from server", s.c_str(), checksum);
_missingObjects.push_back(s);
}
else if (ori->ObjectEntry.checksum != checksum || ori->ObjectEntry.flags != flags)
{
log_warning(
"Object %s has different checksum/flags (%x/%x) than server (%x/%x).", s.c_str(), ori->ObjectEntry.checksum,
ori->ObjectEntry.flags, checksum, flags);
}
}
char objectListMsg[256];
uint32_t args[] = {
static_cast<uint32_t>(_missingObjects.size()),
totalObjects,
};
format_string(objectListMsg, 256, STR_MULTIPLAYER_RECEIVING_OBJECTS_LIST, &args);
auto intent = Intent(WC_NETWORK_STATUS);
intent.putExtra(INTENT_EXTRA_MESSAGE, std::string{ objectListMsg });
intent.putExtra(INTENT_EXTRA_CALLBACK, []() -> void { gNetwork.Close(); });
context_open_intent(&intent);
if (_missingObjects.size() == totalObjects)
if (index + 1 >= totalObjects)
{
log_verbose("client received object list, it has %u entries", totalObjects);
Client_Send_REQUESTMAP(_missingObjects);