Таким образом, у меня есть фабрика для создания объектов на основе RakNet NetworkIDObjects. Если это авторитет, то он просто создаст новый объект, в противном случае он создаст объект, а затем установит Net ID:
std::shared_ptr<CNetObject> CNetObjectFactory::Create(int netObjectType, bool IsAuthority, RakNet::NetworkID networkID) const
{
auto entry = m_RegisteredObjects.find(netObjectType);
auto clone = std::shared_ptr<CNetObject>(entry->second->Clone());
clone->SetNetworkIDManager(m_NetworkIDManager.get());
if (IsAuthority)
{
clone->SetAuthority();
}
else if (networkID != 0)
{
clone->SetNetworkID(networkID);
}
return clone;
}
Это отлично работает для первой пары NetObjects, порожденных на клиенте, но третий всегда падает в SetNetworkID:
Assertion Failed! nio->GetNetworkID()!=rawId
Со следующим стеком вызовов:
MyApp.exe!RakNet::NetworkIDManager::TrackNetworkIDObject(class RakNet::NetworkIDObject *) Unknown
MyApp.exe!RakNet::NetworkIDObject::SetNetworkID(unsigned __int64) Unknown
MyApp.exe!CNetObjectFactory::Create(int netObjectType, bool IsAuthority, unsigned __int64 networkID) Line 42 C++
Я не могу найти информацию об этой ошибке где-либо еще, и при этом я не могу понять, что отличает этот конкретный объект. Кажется, что идентификаторы сети не отличаются от предыдущих объектов (за исключением того, что они увеличены на единицу). Насколько я могу судить, нет ничего очевидного, что может быть причиной этой аварии.
Итак, я выяснил проблему — выдается ошибка, потому что я пытаюсь добавить объект с тем же NetworkID, что и уже добавленный.
Это вытекает из дальнейшего вверх по стеку вызовов:
auto netObject = m_NetworkIDManager->GET_OBJECT_FROM_ID<CNetObject *>(networkId);
if (netObject == nullptr)
{
netObject = m_NetObjectFactory->Create(netObjectType, false, networkId).get();
}
Я проверяю, существует ли объект, а если нет, то я создаю его. Проблема заключалась в том, что NetworkIDManager, на который ссылается этот фрагмент кода, был совершенно другим экземпляром, что означало, что проверка всегда будет неудачной, и каждый раз будет пытаться создать новый объект.
Других решений пока нет …