mirror of
https://github.com/VCMP-SqMod/SqMod.git
synced 2024-11-08 08:47:17 +01:00
Fix the SetOption methods on the Player type which did not validate the managed player identifier and neither create a guard to prevent recursive event calls. Also, reduce duplicate code.
This commit is contained in:
parent
0861559e0b
commit
b4abe9dfc7
@ -361,47 +361,34 @@ Int32 CPlayer::GetOption(Int32 option_id) const
|
|||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void CPlayer::SetOption(Int32 option_id, bool toggle)
|
void CPlayer::SetOption(Int32 option_id, bool toggle)
|
||||||
{
|
{
|
||||||
// Attempt to obtain the current value of the specified option
|
SetOptionEx(option_id, toggle, 0, NullObject());
|
||||||
const bool value = _Func->GetPlayerOption(m_ID, static_cast< vcmpPlayerOption >(option_id));
|
|
||||||
// Do we even have to modify the specified option?
|
|
||||||
if (value == toggle)
|
|
||||||
{
|
|
||||||
return; // Nothing to change!
|
|
||||||
}
|
|
||||||
// Attempt to modify the current value of the specified option
|
|
||||||
else if (_Func->SetPlayerOption(m_ID, static_cast< vcmpPlayerOption >(option_id),
|
|
||||||
toggle) == vcmpErrorArgumentOutOfBounds)
|
|
||||||
{
|
|
||||||
STHROWF("Invalid option identifier: %d", option_id);
|
|
||||||
}
|
|
||||||
else if (!(m_CircularLocks & PCL_EMIT_PLAYER_OPTION))
|
|
||||||
{
|
|
||||||
Core::Get().EmitPlayerOption(m_ID, option_id, value, 0, NullObject());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void CPlayer::SetOptionEx(Int32 option_id, bool toggle, Int32 header, Object & payload)
|
void CPlayer::SetOptionEx(Int32 option_id, bool toggle, Int32 header, Object & payload)
|
||||||
{
|
{
|
||||||
// Attempt to obtain the current value of the specified option
|
// Validate the managed identifier
|
||||||
const bool value = _Func->GetPlayerOption(m_ID, static_cast< vcmpPlayerOption >(option_id));
|
Validate();
|
||||||
// Do we even have to modify the specified option?
|
// Grab the current value for this property
|
||||||
if (value == toggle)
|
const bool current = _Func->GetPlayerOption(m_ID, static_cast< vcmpPlayerOption >(option_id));
|
||||||
|
// Don't even bother if it's the same value
|
||||||
|
if (current == toggle)
|
||||||
{
|
{
|
||||||
return; // Nothing to change!
|
return;
|
||||||
}
|
}
|
||||||
// Attempt to modify the current value of the specified option
|
// Avoid property unwind from a recursive call
|
||||||
else if (_Func->SetPlayerOption(m_ID, static_cast< vcmpPlayerOption >(option_id),
|
else if (_Func->SetPlayerOption(m_ID,
|
||||||
toggle) == vcmpErrorArgumentOutOfBounds)
|
static_cast< vcmpPlayerOption >(option_id), toggle) == vcmpErrorArgumentOutOfBounds)
|
||||||
{
|
{
|
||||||
STHROWF("Invalid option identifier: %d", option_id);
|
STHROWF("Invalid option identifier: %d", option_id);
|
||||||
}
|
}
|
||||||
|
// Avoid infinite recursive event loops
|
||||||
else if (!(m_CircularLocks & PCL_EMIT_PLAYER_OPTION))
|
else if (!(m_CircularLocks & PCL_EMIT_PLAYER_OPTION))
|
||||||
{
|
{
|
||||||
// Prevent this event from triggering while executed
|
// Prevent this event from triggering while executed
|
||||||
BitGuardU32 bg(m_CircularLocks, PCL_EMIT_PLAYER_OPTION);
|
BitGuardU32 bg(m_CircularLocks, PCL_EMIT_PLAYER_OPTION);
|
||||||
// Now forward the event call
|
// Now forward the event call
|
||||||
Core::Get().EmitPlayerOption(m_ID, option_id, value, header, payload);
|
Core::Get().EmitPlayerOption(m_ID, option_id, current, header, payload);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user