2
0
mirror of https://github.com/AxioDL/metaforce.git synced 2025-07-09 13:25:53 +00:00

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 "Runtime/CObjectList.hpp"
#include <logvisor/logvisor.hpp>
namespace urde { namespace urde {
namespace {
logvisor::Module Log("urde::CObjectList");
}
CObjectList::CObjectList(EGameObjectList listEnum) : x2004_listEnum(listEnum) {} CObjectList::CObjectList(EGameObjectList listEnum) : x2004_listEnum(listEnum) {}
void CObjectList::AddObject(CEntity& entity) { void CObjectList::AddObject(CEntity& entity) {
if (IsQualified(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(); x0_list[x2008_firstId].prev = entity.GetUniqueId().Value();
s16 prevFirst = x2008_firstId; prevFirst = x2008_firstId;
}
x2008_firstId = entity.GetUniqueId().Value(); x2008_firstId = entity.GetUniqueId().Value();
SObjectListEntry& newEnt = x0_list[x2008_firstId]; SObjectListEntry& newEnt = x0_list[x2008_firstId];
newEnt.entity = &entity; newEnt.entity = &entity;

View File

@ -97,7 +97,7 @@ private:
std::unique_ptr<CAiWaypointList> x83c_aiWaypointObjs; std::unique_ptr<CAiWaypointList> x83c_aiWaypointObjs;
std::unique_ptr<CPlatformAndDoorList> x844_platformAndDoorObjs; std::unique_ptr<CPlatformAndDoorList> x844_platformAndDoorObjs;
*/ */
std::unique_ptr<CObjectList> x808_objLists[8] = {std::make_unique<CObjectList>(EGameObjectList::All), std::array<std::unique_ptr<CObjectList>, 8> x808_objLists = {std::make_unique<CObjectList>(EGameObjectList::All),
std::make_unique<CActorList>(), std::make_unique<CActorList>(),
std::make_unique<CPhysicsActorList>(), std::make_unique<CPhysicsActorList>(),
std::make_unique<CGameCameraList>(), std::make_unique<CGameCameraList>(),

View File

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

View File

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

View File

@ -44,8 +44,8 @@ void CScriptBeam::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId, CSt
x154_projectileId = mgr.AllocateUniqueId(); x154_projectileId = mgr.AllocateUniqueId();
mgr.AddObject(new CPlasmaProjectile(xe8_weaponDescription, x10_name + "-Projectile", mgr.AddObject(new CPlasmaProjectile(xe8_weaponDescription, x10_name + "-Projectile",
x138_damageInfo.GetWeaponMode().GetType(), xf4_beamInfo, x34_transform, x138_damageInfo.GetWeaponMode().GetType(), xf4_beamInfo, x34_transform,
EMaterialTypes::Projectile, x138_damageInfo, x8_uid, x4_areaId, EMaterialTypes::Projectile, x138_damageInfo, x154_projectileId, x4_areaId,
x154_projectileId, {}, false, EProjectileAttrib::PlasmaProjectile)); GetUniqueId(), {}, false, EProjectileAttrib::PlasmaProjectile));
} else if (msg == EScriptObjectMessage::Deleted) { } else if (msg == EScriptObjectMessage::Deleted) {
mgr.FreeScriptObject(x154_projectileId); 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) if (conn.x4_msg != EScriptObjectMessage::Increment && conn.x4_msg != EScriptObjectMessage::Decrement)
continue; 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; const SConnection& conn2 = *it;
if (conn2.x4_msg != EScriptObjectMessage::Increment && conn2.x4_msg != EScriptObjectMessage::Decrement) if (conn2.x4_msg != EScriptObjectMessage::Increment && conn2.x4_msg != EScriptObjectMessage::Decrement)
continue; continue;
TUniqueId id = mgr.GetIdForScript(conn2.x8_objId); TUniqueId id = mgr.GetIdForScript(conn2.x8_objId);
if (TCastToPtr<CPathCamera>(mgr.ObjectById(id)) || TCastToPtr<CScriptSpindleCamera>(mgr.ObjectById((id)))) { if (TCastToPtr<CPathCamera>(mgr.ObjectById(id)) || TCastToPtr<CScriptSpindleCamera>(mgr.ObjectById((id)))) {
ent->ConnectionList().erase(it); it = ent->ConnectionList().erase(it);
if (x164_delegatedCamera != id) if (x164_delegatedCamera != id)
x164_delegatedCamera = id; x164_delegatedCamera = id;
break; break;