Fix infinite loop in CObjectList, and add an assert to detect invalid assignments

This commit is contained in:
Phillip Stephens 2020-03-07 09:14:07 -08:00
parent 4daa8ac374
commit f06c26e7d6
Signed by: Antidote
GPG Key ID: F8BEE4C83DACA60D
6 changed files with 29 additions and 17 deletions

View File

@ -1,14 +1,26 @@
#include "Runtime/CObjectList.hpp"
#include <logvisor/logvisor.hpp>
namespace urde {
namespace {
logvisor::Module Log("urde::CObjectList");
}
CObjectList::CObjectList(EGameObjectList listEnum) : x2004_listEnum(listEnum) {}
void CObjectList::AddObject(CEntity& entity) {
if (IsQualified(entity)) {
if (x2008_firstId != -1)
#ifndef NDEBUG
if (x0_list[entity.GetUniqueId().Value()].entity != nullptr &&
x0_list[entity.GetUniqueId().Value()].entity != &entity)
Log.report(logvisor::Level::Fatal, fmt("INVALID USAGE DETECTED: Attempting to assign entity '{} ({})' to existing node '{}'!!!"),
entity.GetName(), entity.GetEditorId(), entity.GetUniqueId().Value());
#endif
s16 prevFirst = -1;
if (x2008_firstId != -1) {
x0_list[x2008_firstId].prev = entity.GetUniqueId().Value();
s16 prevFirst = x2008_firstId;
prevFirst = x2008_firstId;
}
x2008_firstId = entity.GetUniqueId().Value();
SObjectListEntry& newEnt = x0_list[x2008_firstId];
newEnt.entity = &entity;

View File

@ -97,14 +97,14 @@ private:
std::unique_ptr<CAiWaypointList> x83c_aiWaypointObjs;
std::unique_ptr<CPlatformAndDoorList> x844_platformAndDoorObjs;
*/
std::unique_ptr<CObjectList> x808_objLists[8] = {std::make_unique<CObjectList>(EGameObjectList::All),
std::make_unique<CActorList>(),
std::make_unique<CPhysicsActorList>(),
std::make_unique<CGameCameraList>(),
std::make_unique<CGameLightList>(),
std::make_unique<CListeningAiList>(),
std::make_unique<CAiWaypointList>(),
std::make_unique<CPlatformAndDoorList>()};
std::array<std::unique_ptr<CObjectList>, 8> x808_objLists = {std::make_unique<CObjectList>(EGameObjectList::All),
std::make_unique<CActorList>(),
std::make_unique<CPhysicsActorList>(),
std::make_unique<CGameCameraList>(),
std::make_unique<CGameLightList>(),
std::make_unique<CListeningAiList>(),
std::make_unique<CAiWaypointList>(),
std::make_unique<CPlatformAndDoorList>()};
std::unique_ptr<CPlayer> x84c_player;
std::unique_ptr<CWorld> x850_world;

View File

@ -3,8 +3,8 @@
namespace urde {
void CWeaponMgr::Add(TUniqueId uid, EWeaponType type) {
x0_weapons.insert(std::make_pair(uid, rstl::reserved_vector<s32, 10>()));
x0_weapons[uid].resize(10);
x0_weapons.insert(std::make_pair(uid, rstl::reserved_vector<s32, 15>()));
x0_weapons[uid].resize(15);
++x0_weapons[uid][u32(type)];
}

View File

@ -9,7 +9,7 @@
namespace urde {
class CWeaponMgr {
std::map<TUniqueId, rstl::reserved_vector<s32, 10>> x0_weapons;
std::map<TUniqueId, rstl::reserved_vector<s32, 15>> x0_weapons;
public:
void Add(TUniqueId, EWeaponType);

View File

@ -44,8 +44,8 @@ void CScriptBeam::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId, CSt
x154_projectileId = mgr.AllocateUniqueId();
mgr.AddObject(new CPlasmaProjectile(xe8_weaponDescription, x10_name + "-Projectile",
x138_damageInfo.GetWeaponMode().GetType(), xf4_beamInfo, x34_transform,
EMaterialTypes::Projectile, x138_damageInfo, x8_uid, x4_areaId,
x154_projectileId, {}, false, EProjectileAttrib::PlasmaProjectile));
EMaterialTypes::Projectile, x138_damageInfo, x154_projectileId, x4_areaId,
GetUniqueId(), {}, false, EProjectileAttrib::PlasmaProjectile));
} else if (msg == EScriptObjectMessage::Deleted) {
mgr.FreeScriptObject(x154_projectileId);
}

View File

@ -34,13 +34,13 @@ void CScriptCameraHint::InitializeInArea(CStateManager& mgr) {
if (conn.x4_msg != EScriptObjectMessage::Increment && conn.x4_msg != EScriptObjectMessage::Decrement)
continue;
for (auto it = ent->GetConnectionList().begin(); it != ent->GetConnectionList().cend(); ++it) {
for (auto it = ent->GetConnectionList().begin(); it != ent->GetConnectionList().end(); ++it) {
const SConnection& conn2 = *it;
if (conn2.x4_msg != EScriptObjectMessage::Increment && conn2.x4_msg != EScriptObjectMessage::Decrement)
continue;
TUniqueId id = mgr.GetIdForScript(conn2.x8_objId);
if (TCastToPtr<CPathCamera>(mgr.ObjectById(id)) || TCastToPtr<CScriptSpindleCamera>(mgr.ObjectById((id)))) {
ent->ConnectionList().erase(it);
it = ent->ConnectionList().erase(it);
if (x164_delegatedCamera != id)
x164_delegatedCamera = id;
break;