|
|
|
|
@@ -360,7 +360,7 @@ Network::Network()
|
|
|
|
|
server_command_handlers[NETWORK_COMMAND_PING] = &Network::Server_Handle_PING;
|
|
|
|
|
server_command_handlers[NETWORK_COMMAND_GAMEINFO] = &Network::Server_Handle_GAMEINFO;
|
|
|
|
|
server_command_handlers[NETWORK_COMMAND_TOKEN] = &Network::Server_Handle_TOKEN;
|
|
|
|
|
server_command_handlers[NETWORK_COMMAND_MAP_REQUEST] = &Network::Server_Handle_MAPREQUEST;
|
|
|
|
|
server_command_handlers[NETWORK_COMMAND_MAPREQUEST] = &Network::Server_Handle_MAPREQUEST;
|
|
|
|
|
server_command_handlers[NETWORK_COMMAND_REQUEST_GAMESTATE] = &Network::Server_Handle_REQUEST_GAMESTATE;
|
|
|
|
|
server_command_handlers[NETWORK_COMMAND_HEARTBEAT] = &Network::Server_Handle_HEARTBEAT;
|
|
|
|
|
|
|
|
|
|
@@ -1468,7 +1468,7 @@ void Network::Client_Send_REQUESTMAP(const std::vector<std::string>& objects)
|
|
|
|
|
{
|
|
|
|
|
log_verbose("client requests %u objects", uint32_t(objects.size()));
|
|
|
|
|
std::unique_ptr<NetworkPacket> packet(NetworkPacket::Allocate());
|
|
|
|
|
*packet << static_cast<uint32_t>(NETWORK_COMMAND_MAP_REQUEST) << static_cast<uint32_t>(objects.size());
|
|
|
|
|
*packet << static_cast<uint32_t>(NETWORK_COMMAND_MAPREQUEST) << static_cast<uint32_t>(objects.size());
|
|
|
|
|
for (const auto& object : objects)
|
|
|
|
|
{
|
|
|
|
|
log_verbose("client requests object %s", object.c_str());
|
|
|
|
|
@@ -1490,12 +1490,11 @@ void Network::Server_Send_OBJECTS_LIST(
|
|
|
|
|
{
|
|
|
|
|
log_verbose("Server sends objects list with %u items", objects.size());
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < objects.size(); ++i)
|
|
|
|
|
bool startOfObjectList = true;
|
|
|
|
|
for (auto* object : objects)
|
|
|
|
|
{
|
|
|
|
|
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)
|
|
|
|
|
*packet << static_cast<uint32_t>(NETWORK_COMMAND_OBJECTS_LIST) << startOfObjectList
|
|
|
|
|
<< static_cast<uint32_t>(objects.size());
|
|
|
|
|
|
|
|
|
|
log_verbose("Object %.8s (checksum %x)", object->ObjectEntry.name, object->ObjectEntry.checksum);
|
|
|
|
|
@@ -1503,6 +1502,7 @@ void Network::Server_Send_OBJECTS_LIST(
|
|
|
|
|
*packet << object->ObjectEntry.checksum << object->ObjectEntry.flags;
|
|
|
|
|
|
|
|
|
|
connection.QueuePacket(std::move(packet));
|
|
|
|
|
startOfObjectList = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -2571,13 +2571,12 @@ void Network::Client_Handle_OBJECTS_LIST(NetworkConnection& connection, NetworkP
|
|
|
|
|
{
|
|
|
|
|
auto& repo = GetContext()->GetObjectRepository();
|
|
|
|
|
|
|
|
|
|
uint32_t index = 0;
|
|
|
|
|
bool startOfObjectList = false;
|
|
|
|
|
uint32_t totalObjects = 0;
|
|
|
|
|
packet >> index >> totalObjects;
|
|
|
|
|
packet >> startOfObjectList >> totalObjects;
|
|
|
|
|
|
|
|
|
|
if (index == 0)
|
|
|
|
|
if (startOfObjectList)
|
|
|
|
|
{
|
|
|
|
|
// Start of objects list.
|
|
|
|
|
_missingObjects.clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -2589,25 +2588,14 @@ void Network::Client_Handle_OBJECTS_LIST(NetworkConnection& connection, NetworkP
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char objectListMsg[256];
|
|
|
|
|
uint32_t args[] = {
|
|
|
|
|
index + 1,
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
const char* name = reinterpret_cast<const char*>(packet.Read(8));
|
|
|
|
|
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, flags;
|
|
|
|
|
uint32_t checksum = 0;
|
|
|
|
|
uint32_t flags = 0;
|
|
|
|
|
packet >> checksum >> flags;
|
|
|
|
|
|
|
|
|
|
const ObjectRepositoryItem* ori = repo.FindObject(s.c_str());
|
|
|
|
|
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)
|
|
|
|
|
@@ -2622,6 +2610,18 @@ void Network::Client_Handle_OBJECTS_LIST(NetworkConnection& connection, NetworkP
|
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
|
log_verbose("client received object list, it has %u entries", totalObjects);
|
|
|
|
|
|