1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2024-11-08 08:47:17 +01:00

Compare commits

...

5 Commits

Author SHA1 Message Date
Sandu Liviu Catalin
dfee411de5 Emulate embarking event when done from server-side.
Also change the order of other events to happen before performing the action.
2021-09-12 15:55:55 +03:00
Sandu Liviu Catalin
37383b9383 Emulate embarking event when done from server-side.
Also change the order of other events to happen before performing the action.
2021-09-12 15:49:29 +03:00
Sandu Liviu Catalin
ba4b8524e5 Update SQLite.cpp 2021-09-12 15:13:20 +03:00
Sandu Liviu Catalin
f1ef37bdf3 Fix sqlite3_snprintf not having a room for a null terminator in the buffer. 2021-09-12 15:12:35 +03:00
Sandu Liviu Catalin
9235cb5069 Update Official.cpp
Allow null in `SpectateTarget` property to match official plugin.
2021-09-12 14:52:49 +03:00
6 changed files with 140 additions and 79 deletions

View File

@ -168,8 +168,6 @@ void CPlayer::SetAdmin(bool toggle)
{ {
return; return;
} }
// Avoid property unwind from a recursive call
_Func->SetPlayerAdmin(m_ID, static_cast< uint8_t >(toggle));
// Avoid infinite recursive event loops // Avoid infinite recursive event loops
if (!(m_CircularLocks & PLAYERCL_EMIT_PLAYER_ADMIN)) if (!(m_CircularLocks & PLAYERCL_EMIT_PLAYER_ADMIN))
{ {
@ -178,6 +176,8 @@ void CPlayer::SetAdmin(bool toggle)
// Now forward the event call // Now forward the event call
Core::Get().EmitPlayerAdmin(m_ID, current, toggle); Core::Get().EmitPlayerAdmin(m_ID, current, toggle);
} }
// Avoid property unwind from a recursive call
_Func->SetPlayerAdmin(m_ID, static_cast< uint8_t >(toggle));
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -373,13 +373,6 @@ void CPlayer::SetOptionEx(int32_t option_id, bool toggle, int32_t header, LightO
{ {
return; return;
} }
// Avoid property unwind from a recursive call
else if (_Func->SetPlayerOption(m_ID,
static_cast< vcmpPlayerOption >(option_id),
static_cast< uint8_t >(toggle)) == vcmpErrorArgumentOutOfBounds)
{
STHROWF("Invalid option identifier: {}", option_id);
}
// Avoid infinite recursive event loops // Avoid infinite recursive event loops
else if (!(m_CircularLocks & PLAYERCL_EMIT_PLAYER_OPTION)) else if (!(m_CircularLocks & PLAYERCL_EMIT_PLAYER_OPTION))
{ {
@ -388,6 +381,13 @@ void CPlayer::SetOptionEx(int32_t option_id, bool toggle, int32_t header, LightO
// Now forward the event call // Now forward the event call
Core::Get().EmitPlayerOption(m_ID, option_id, current, header, payload); Core::Get().EmitPlayerOption(m_ID, option_id, current, header, payload);
} }
// Avoid property unwind from a recursive call
if (_Func->SetPlayerOption(m_ID,
static_cast< vcmpPlayerOption >(option_id),
static_cast< uint8_t >(toggle)) == vcmpErrorArgumentOutOfBounds)
{
STHROWF("Invalid option identifier: {}", option_id);
}
} }
#if SQMOD_SDK_LEAST(2, 1) #if SQMOD_SDK_LEAST(2, 1)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -433,8 +433,6 @@ void CPlayer::SetWorld(int32_t world)
{ {
return; return;
} }
// Avoid property unwind from a recursive call
_Func->SetPlayerWorld(m_ID, world);
// Avoid infinite recursive event loops // Avoid infinite recursive event loops
if (!(m_CircularLocks & PLAYERCL_EMIT_PLAYER_WORLD)) if (!(m_CircularLocks & PLAYERCL_EMIT_PLAYER_WORLD))
{ {
@ -443,6 +441,8 @@ void CPlayer::SetWorld(int32_t world)
// Now forward the event call // Now forward the event call
Core::Get().EmitPlayerWorld(m_ID, current, world, false); Core::Get().EmitPlayerWorld(m_ID, current, world, false);
} }
// Avoid property unwind from a recursive call
_Func->SetPlayerWorld(m_ID, world);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -466,8 +466,6 @@ void CPlayer::SetSecondaryWorld(int32_t world)
{ {
return; return;
} }
// Avoid property unwind from a recursive call
_Func->SetPlayerSecondaryWorld(m_ID, world);
// Avoid infinite recursive event loops // Avoid infinite recursive event loops
if (!(m_CircularLocks & PLAYERCL_EMIT_PLAYER_WORLD)) if (!(m_CircularLocks & PLAYERCL_EMIT_PLAYER_WORLD))
{ {
@ -476,6 +474,8 @@ void CPlayer::SetSecondaryWorld(int32_t world)
// Now forward the event call // Now forward the event call
Core::Get().EmitPlayerWorld(m_ID, current, world, true); Core::Get().EmitPlayerWorld(m_ID, current, world, true);
} }
// Avoid property unwind from a recursive call
_Func->SetPlayerSecondaryWorld(m_ID, world);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -526,11 +526,6 @@ void CPlayer::SetTeam(int32_t team)
{ {
return; return;
} }
// Avoid property unwind from a recursive call
else if (_Func->SetPlayerTeam(m_ID, team) == vcmpErrorArgumentOutOfBounds)
{
STHROWF("Invalid team identifier: {}", team);
}
// Avoid infinite recursive event loops // Avoid infinite recursive event loops
else if (!(m_CircularLocks & PLAYERCL_EMIT_PLAYER_TEAM)) else if (!(m_CircularLocks & PLAYERCL_EMIT_PLAYER_TEAM))
{ {
@ -539,6 +534,11 @@ void CPlayer::SetTeam(int32_t team)
// Now forward the event call // Now forward the event call
Core::Get().EmitPlayerTeam(m_ID, current, team); Core::Get().EmitPlayerTeam(m_ID, current, team);
} }
// Avoid property unwind from a recursive call
if (_Func->SetPlayerTeam(m_ID, team) == vcmpErrorArgumentOutOfBounds)
{
STHROWF("Invalid team identifier: {}", team);
}
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -562,11 +562,6 @@ void CPlayer::SetSkin(int32_t skin)
{ {
return; return;
} }
// Avoid property unwind from a recursive call
else if (_Func->SetPlayerSkin(m_ID, skin) == vcmpErrorArgumentOutOfBounds)
{
STHROWF("Invalid skin identifier: {}", skin);
}
// Avoid infinite recursive event loops // Avoid infinite recursive event loops
else if (!(m_CircularLocks & PLAYERCL_EMIT_PLAYER_SKIN)) else if (!(m_CircularLocks & PLAYERCL_EMIT_PLAYER_SKIN))
{ {
@ -575,6 +570,11 @@ void CPlayer::SetSkin(int32_t skin)
// Now forward the event call // Now forward the event call
Core::Get().EmitPlayerSkin(m_ID, current, skin); Core::Get().EmitPlayerSkin(m_ID, current, skin);
} }
// Avoid property unwind from a recursive call
if (_Func->SetPlayerSkin(m_ID, skin) == vcmpErrorArgumentOutOfBounds)
{
STHROWF("Invalid skin identifier: {}", skin);
}
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -665,8 +665,6 @@ void CPlayer::SetMoney(int32_t amount)
{ {
return; return;
} }
// Avoid property unwind from a recursive call
_Func->SetPlayerMoney(m_ID, amount);
// Avoid infinite recursive event loops // Avoid infinite recursive event loops
if (!(m_CircularLocks & PLAYERCL_EMIT_PLAYER_MONEY)) if (!(m_CircularLocks & PLAYERCL_EMIT_PLAYER_MONEY))
{ {
@ -675,6 +673,8 @@ void CPlayer::SetMoney(int32_t amount)
// Now forward the event call // Now forward the event call
Core::Get().EmitPlayerMoney(m_ID, current, amount); Core::Get().EmitPlayerMoney(m_ID, current, amount);
} }
// Avoid property unwind from a recursive call
_Func->SetPlayerMoney(m_ID, amount);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -684,8 +684,6 @@ void CPlayer::GiveMoney(int32_t amount)
Validate(); Validate();
// Grab the current value for this property // Grab the current value for this property
const int32_t current = _Func->GetPlayerMoney(m_ID); const int32_t current = _Func->GetPlayerMoney(m_ID);
// Avoid property unwind from a recursive call
_Func->GivePlayerMoney(m_ID, amount);
// Avoid infinite recursive event loops // Avoid infinite recursive event loops
if (!(m_CircularLocks & PLAYERCL_EMIT_PLAYER_MONEY)) if (!(m_CircularLocks & PLAYERCL_EMIT_PLAYER_MONEY))
{ {
@ -694,6 +692,8 @@ void CPlayer::GiveMoney(int32_t amount)
// Now forward the event call // Now forward the event call
Core::Get().EmitPlayerMoney(m_ID, current, current + amount); Core::Get().EmitPlayerMoney(m_ID, current, current + amount);
} }
// Avoid property unwind from a recursive call
_Func->GivePlayerMoney(m_ID, amount);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -717,8 +717,6 @@ void CPlayer::SetScore(int32_t score)
{ {
return; return;
} }
// Avoid property unwind from a recursive call
_Func->SetPlayerScore(m_ID, score);
// Avoid infinite recursive event loops // Avoid infinite recursive event loops
if (!(m_CircularLocks & PLAYERCL_EMIT_PLAYER_SCORE)) if (!(m_CircularLocks & PLAYERCL_EMIT_PLAYER_SCORE))
{ {
@ -727,6 +725,8 @@ void CPlayer::SetScore(int32_t score)
// Now forward the event call // Now forward the event call
Core::Get().EmitPlayerScore(m_ID, current, score); Core::Get().EmitPlayerScore(m_ID, current, score);
} }
// Avoid property unwind from a recursive call
_Func->SetPlayerScore(m_ID, score);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -750,8 +750,6 @@ void CPlayer::SetWantedLevel(int32_t level)
{ {
return; return;
} }
// Avoid property unwind from a recursive call
_Func->SetPlayerWantedLevel(m_ID, level);
// Avoid infinite recursive event loops // Avoid infinite recursive event loops
if (!(m_CircularLocks & PLAYERCL_EMIT_PLAYER_WANTED_LEVEL)) if (!(m_CircularLocks & PLAYERCL_EMIT_PLAYER_WANTED_LEVEL))
{ {
@ -760,6 +758,8 @@ void CPlayer::SetWantedLevel(int32_t level)
// Now forward the event call // Now forward the event call
Core::Get().EmitPlayerWantedLevel(m_ID, current, level); Core::Get().EmitPlayerWantedLevel(m_ID, current, level);
} }
// Avoid property unwind from a recursive call
_Func->SetPlayerWantedLevel(m_ID, level);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -832,8 +832,6 @@ void CPlayer::SetImmunity(uint32_t flags)
Validate(); Validate();
// Grab the current value for this property // Grab the current value for this property
const uint32_t current = _Func->GetPlayerImmunityFlags(m_ID); const uint32_t current = _Func->GetPlayerImmunityFlags(m_ID);
// Avoid property unwind from a recursive call
_Func->SetPlayerImmunityFlags(m_ID, static_cast< uint32_t >(flags));
// Avoid infinite recursive event loops // Avoid infinite recursive event loops
if (!(m_CircularLocks & PLAYERCL_EMIT_PLAYER_IMMUNITY)) if (!(m_CircularLocks & PLAYERCL_EMIT_PLAYER_IMMUNITY))
{ {
@ -842,6 +840,8 @@ void CPlayer::SetImmunity(uint32_t flags)
// Now forward the event call // Now forward the event call
Core::Get().EmitPlayerImmunity(m_ID, static_cast< int32_t >(current), static_cast< int32_t >(flags)); Core::Get().EmitPlayerImmunity(m_ID, static_cast< int32_t >(current), static_cast< int32_t >(flags));
} }
// Avoid property unwind from a recursive call
_Func->SetPlayerImmunityFlags(m_ID, static_cast< uint32_t >(flags));
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -969,8 +969,6 @@ void CPlayer::SetAlphaEx(int32_t alpha, int32_t fade)
{ {
return; return;
} }
// Avoid property unwind from a recursive call
_Func->SetPlayerAlpha(m_ID, alpha, static_cast< uint32_t >(fade));
// Avoid infinite recursive event loops // Avoid infinite recursive event loops
if (!(m_CircularLocks & PLAYERCL_EMIT_PLAYER_ALPHA)) if (!(m_CircularLocks & PLAYERCL_EMIT_PLAYER_ALPHA))
{ {
@ -979,6 +977,8 @@ void CPlayer::SetAlphaEx(int32_t alpha, int32_t fade)
// Now forward the event call // Now forward the event call
Core::Get().EmitPlayerAlpha(m_ID, current, alpha, fade); Core::Get().EmitPlayerAlpha(m_ID, current, alpha, fade);
} }
// Avoid property unwind from a recursive call
_Func->SetPlayerAlpha(m_ID, alpha, static_cast< uint32_t >(fade));
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -1044,7 +1044,7 @@ uint32_t CPlayer::GetGameKeys() const
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool CPlayer::Embark(CVehicle & vehicle) const bool CPlayer::Embark(CVehicle & vehicle)
{ {
// Is the specified vehicle even valid? // Is the specified vehicle even valid?
if (!vehicle.IsActive()) if (!vehicle.IsActive())
@ -1053,13 +1053,26 @@ bool CPlayer::Embark(CVehicle & vehicle) const
} }
// Validate the managed identifier // Validate the managed identifier
Validate(); Validate();
// If the player embarks in the same vehicle then ignore
if (_Func->GetPlayerVehicleId(m_ID) == vehicle.GetID())
{
return true; // I guess this is somewhat successful
}
// Avoid infinite recursive event loops
else if (!(m_CircularLocks & PLAYERCL_EMIT_PLAYER_EMBARK))
{
// Prevent this event from triggering while executed
BitGuardU32 bg(m_CircularLocks, PLAYERCL_EMIT_PLAYER_EMBARK);
// Now forward the event call
Core::Get().EmitPlayerEmbarking(m_ID, vehicle.GetID(), 0);
}
// Perform the requested operation // Perform the requested operation
return (_Func->PutPlayerInVehicle(m_ID, vehicle.GetID(), 0, return (_Func->PutPlayerInVehicle(m_ID, vehicle.GetID(), 0,
static_cast< uint8_t >(true), static_cast< uint8_t >(true)) != vcmpErrorRequestDenied); static_cast< uint8_t >(true), static_cast< uint8_t >(true)) != vcmpErrorRequestDenied);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool CPlayer::EmbarkEx(CVehicle & vehicle, int32_t slot, bool allocate, bool warp) const bool CPlayer::EmbarkEx(CVehicle & vehicle, int32_t slot, bool allocate, bool warp)
{ {
// Is the specified vehicle even valid? // Is the specified vehicle even valid?
if (!vehicle.IsActive()) if (!vehicle.IsActive())
@ -1068,6 +1081,19 @@ bool CPlayer::EmbarkEx(CVehicle & vehicle, int32_t slot, bool allocate, bool war
} }
// Validate the managed identifier // Validate the managed identifier
Validate(); Validate();
// If the player embarks in the same vehicle then ignore
if (_Func->GetPlayerVehicleId(m_ID) == vehicle.GetID())
{
return true; // I guess this is somewhat successful
}
// Avoid infinite recursive event loops
else if (!(m_CircularLocks & PLAYERCL_EMIT_PLAYER_EMBARK))
{
// Prevent this event from triggering while executed
BitGuardU32 bg(m_CircularLocks, PLAYERCL_EMIT_PLAYER_EMBARK);
// Now forward the event call
Core::Get().EmitPlayerEmbarking(m_ID, vehicle.GetID(), slot);
}
// Perform the requested operation // Perform the requested operation
return (_Func->PutPlayerInVehicle(m_ID, vehicle.GetID(), slot, return (_Func->PutPlayerInVehicle(m_ID, vehicle.GetID(), slot,
static_cast< uint8_t >(allocate), static_cast< uint8_t >(warp)) != vcmpErrorRequestDenied); static_cast< uint8_t >(allocate), static_cast< uint8_t >(warp)) != vcmpErrorRequestDenied);

View File

@ -21,7 +21,8 @@ enum PlayerCircularLocks
PLAYERCL_EMIT_PLAYER_SCORE = (1u << 6u), PLAYERCL_EMIT_PLAYER_SCORE = (1u << 6u),
PLAYERCL_EMIT_PLAYER_WANTED_LEVEL = (1u << 7u), PLAYERCL_EMIT_PLAYER_WANTED_LEVEL = (1u << 7u),
PLAYERCL_EMIT_PLAYER_IMMUNITY = (1u << 8u), PLAYERCL_EMIT_PLAYER_IMMUNITY = (1u << 8u),
PLAYERCL_EMIT_PLAYER_ALPHA = (1u << 9u) PLAYERCL_EMIT_PLAYER_ALPHA = (1u << 9u),
PLAYERCL_EMIT_PLAYER_EMBARK = (1u << 10u)
}; };
/* ------------------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------------------
@ -593,12 +594,12 @@ public:
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Embark the managed player entity into the specified vehicle entity. * Embark the managed player entity into the specified vehicle entity.
*/ */
bool Embark(CVehicle & vehicle) const; bool Embark(CVehicle & vehicle);
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Embark the managed player entity into the specified vehicle entity. * Embark the managed player entity into the specified vehicle entity.
*/ */
bool EmbarkEx(CVehicle & vehicle, int32_t slot, bool allocate, bool warp) const; bool EmbarkEx(CVehicle & vehicle, int32_t slot, bool allocate, bool warp);
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Disembark the managed player entity from the currently embarked vehicle entity. * Disembark the managed player entity from the currently embarked vehicle entity.

View File

@ -148,19 +148,20 @@ void CVehicle::SetOption(int32_t option_id, bool toggle)
{ {
// Attempt to obtain the current value of the specified option // Attempt to obtain the current value of the specified option
const bool value = _Func->GetVehicleOption(m_ID, static_cast< vcmpVehicleOption >(option_id)); const bool value = _Func->GetVehicleOption(m_ID, static_cast< vcmpVehicleOption >(option_id));
// Attempt to modify the current value of the specified option // Avoid infinite recursive event loops
if (_Func->SetVehicleOption(m_ID, static_cast< vcmpVehicleOption >(option_id), if (!(m_CircularLocks & VEHICLECL_EMIT_VEHICLE_OPTION))
static_cast< uint8_t >(toggle)) == vcmpErrorArgumentOutOfBounds)
{
STHROWF("Invalid option identifier: {}", option_id);
}
else if (!(m_CircularLocks & VEHICLECL_EMIT_VEHICLE_OPTION))
{ {
// Prevent this event from triggering while executed // Prevent this event from triggering while executed
BitGuardU32 bg(m_CircularLocks, VEHICLECL_EMIT_VEHICLE_OPTION); BitGuardU32 bg(m_CircularLocks, VEHICLECL_EMIT_VEHICLE_OPTION);
// Now forward the event call // Now forward the event call
Core::Get().EmitVehicleOption(m_ID, option_id, value, 0, NullLightObj()); Core::Get().EmitVehicleOption(m_ID, option_id, value, 0, NullLightObj());
} }
// Attempt to modify the current value of the specified option
if (_Func->SetVehicleOption(m_ID, static_cast< vcmpVehicleOption >(option_id),
static_cast< uint8_t >(toggle)) == vcmpErrorArgumentOutOfBounds)
{
STHROWF("Invalid option identifier: {}", option_id);
}
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -168,19 +169,20 @@ void CVehicle::SetOptionEx(int32_t option_id, bool toggle, int32_t header, Light
{ {
// Attempt to obtain the current value of the specified option // Attempt to obtain the current value of the specified option
const bool value = _Func->GetVehicleOption(m_ID, static_cast< vcmpVehicleOption >(option_id)); const bool value = _Func->GetVehicleOption(m_ID, static_cast< vcmpVehicleOption >(option_id));
// Attempt to modify the current value of the specified option // Avoid infinite recursive event loops
if (_Func->SetVehicleOption(m_ID, static_cast< vcmpVehicleOption >(option_id), if (!(m_CircularLocks & VEHICLECL_EMIT_VEHICLE_OPTION))
static_cast< uint8_t >(toggle)) == vcmpErrorArgumentOutOfBounds)
{
STHROWF("Invalid option identifier: {}", option_id);
}
else if (!(m_CircularLocks & VEHICLECL_EMIT_VEHICLE_OPTION))
{ {
// Prevent this event from triggering while executed // Prevent this event from triggering while executed
BitGuardU32 bg(m_CircularLocks, VEHICLECL_EMIT_VEHICLE_OPTION); BitGuardU32 bg(m_CircularLocks, VEHICLECL_EMIT_VEHICLE_OPTION);
// Now forward the event call // Now forward the event call
Core::Get().EmitVehicleOption(m_ID, option_id, value, header, payload); Core::Get().EmitVehicleOption(m_ID, option_id, value, header, payload);
} }
// Attempt to modify the current value of the specified option
if (_Func->SetVehicleOption(m_ID, static_cast< vcmpVehicleOption >(option_id),
static_cast< uint8_t >(toggle)) == vcmpErrorArgumentOutOfBounds)
{
STHROWF("Invalid option identifier: {}", option_id);
}
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -222,8 +224,6 @@ void CVehicle::SetWorld(int32_t world)
{ {
return; return;
} }
// Avoid property unwind from a recursive call
_Func->SetVehicleWorld(m_ID, world);
// Avoid infinite recursive event loops // Avoid infinite recursive event loops
if (!(m_CircularLocks & VEHICLECL_EMIT_VEHICLE_WORLD)) if (!(m_CircularLocks & VEHICLECL_EMIT_VEHICLE_WORLD))
{ {
@ -232,6 +232,8 @@ void CVehicle::SetWorld(int32_t world)
// Now forward the event call // Now forward the event call
Core::Get().EmitVehicleWorld(m_ID, current, world); Core::Get().EmitVehicleWorld(m_ID, current, world);
} }
// Avoid property unwind from a recursive call
_Func->SetVehicleWorld(m_ID, world);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -321,8 +323,6 @@ void CVehicle::SetImmunity(uint32_t flags)
Validate(); Validate();
// Grab the current value for this property // Grab the current value for this property
const uint32_t current = _Func->GetVehicleImmunityFlags(m_ID); const uint32_t current = _Func->GetVehicleImmunityFlags(m_ID);
// Avoid property unwind from a recursive call
_Func->SetVehicleImmunityFlags(m_ID, static_cast< uint32_t >(flags));
// Avoid infinite recursive event loops // Avoid infinite recursive event loops
if (!(m_CircularLocks & VEHICLECL_EMIT_VEHICLE_IMMUNITY)) if (!(m_CircularLocks & VEHICLECL_EMIT_VEHICLE_IMMUNITY))
{ {
@ -331,6 +331,8 @@ void CVehicle::SetImmunity(uint32_t flags)
// Now forward the event call // Now forward the event call
Core::Get().EmitVehicleImmunity(m_ID, static_cast< int32_t >(current), static_cast< int32_t >(flags)); Core::Get().EmitVehicleImmunity(m_ID, static_cast< int32_t >(current), static_cast< int32_t >(flags));
} }
// Avoid property unwind from a recursive call
_Func->SetVehicleImmunityFlags(m_ID, static_cast< uint32_t >(flags));
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -914,8 +916,6 @@ void CVehicle::SetPartStatus(int32_t part, int32_t status)
{ {
return; return;
} }
// Avoid property unwind from a recursive call
_Func->SetVehiclePartStatus(m_ID, part, status);
// Avoid infinite recursive event loops // Avoid infinite recursive event loops
if (!(m_CircularLocks & VEHICLECL_EMIT_VEHICLE_PARTSTATUS)) if (!(m_CircularLocks & VEHICLECL_EMIT_VEHICLE_PARTSTATUS))
{ {
@ -924,6 +924,8 @@ void CVehicle::SetPartStatus(int32_t part, int32_t status)
// Now forward the event call // Now forward the event call
Core::Get().EmitVehiclePartStatus(m_ID, part, current, status); Core::Get().EmitVehiclePartStatus(m_ID, part, current, status);
} }
// Avoid property unwind from a recursive call
_Func->SetVehiclePartStatus(m_ID, part, status);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -947,8 +949,6 @@ void CVehicle::SetTyreStatus(int32_t tyre, int32_t status)
{ {
return; return;
} }
// Avoid property unwind from a recursive call
_Func->SetVehicleTyreStatus(m_ID, tyre, status);
// Avoid infinite recursive event loops // Avoid infinite recursive event loops
if (!(m_CircularLocks & VEHICLECL_EMIT_VEHICLE_TYRESTATUS)) if (!(m_CircularLocks & VEHICLECL_EMIT_VEHICLE_TYRESTATUS))
{ {
@ -957,6 +957,8 @@ void CVehicle::SetTyreStatus(int32_t tyre, int32_t status)
// Now forward the event call // Now forward the event call
Core::Get().EmitVehicleTyreStatus(m_ID, tyre, current, status); Core::Get().EmitVehicleTyreStatus(m_ID, tyre, current, status);
} }
// Avoid property unwind from a recursive call
_Func->SetVehicleTyreStatus(m_ID, tyre, status);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -980,8 +982,6 @@ void CVehicle::SetDamageData(uint32_t data)
{ {
return; return;
} }
// Avoid property unwind from a recursive call
_Func->SetVehicleDamageData(m_ID, data);
// Avoid infinite recursive event loops // Avoid infinite recursive event loops
if (!(m_CircularLocks & VEHICLECL_EMIT_VEHICLE_DAMAGEDATA)) if (!(m_CircularLocks & VEHICLECL_EMIT_VEHICLE_DAMAGEDATA))
{ {
@ -990,6 +990,8 @@ void CVehicle::SetDamageData(uint32_t data)
// Now forward the event call // Now forward the event call
Core::Get().EmitVehicleDamageData(m_ID, current, data); Core::Get().EmitVehicleDamageData(m_ID, current, data);
} }
// Avoid property unwind from a recursive call
_Func->SetVehicleDamageData(m_ID, data);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -1013,8 +1015,6 @@ void CVehicle::SetRadio(int32_t radio)
{ {
return; return;
} }
// Avoid property unwind from a recursive call
_Func->SetVehicleRadio(m_ID, radio);
// Avoid infinite recursive event loops // Avoid infinite recursive event loops
if (!(m_CircularLocks & VEHICLECL_EMIT_VEHICLE_RADIO)) if (!(m_CircularLocks & VEHICLECL_EMIT_VEHICLE_RADIO))
{ {
@ -1023,6 +1023,8 @@ void CVehicle::SetRadio(int32_t radio)
// Now forward the event call // Now forward the event call
Core::Get().EmitVehicleRadio(m_ID, current, radio); Core::Get().EmitVehicleRadio(m_ID, current, radio);
} }
// Avoid property unwind from a recursive call
_Func->SetVehicleRadio(m_ID, radio);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -1089,8 +1091,6 @@ void CVehicle::SetHandlingRule(int32_t rule, float data)
Validate(); Validate();
// Grab the current value for this property // Grab the current value for this property
const auto current = static_cast< SQFloat >(_Func->GetInstHandlingRule(m_ID, rule)); const auto current = static_cast< SQFloat >(_Func->GetInstHandlingRule(m_ID, rule));
// Avoid property unwind from a recursive call
_Func->SetInstHandlingRule(m_ID, rule, data);
// Avoid infinite recursive event loops // Avoid infinite recursive event loops
if (!(m_CircularLocks & VEHICLECL_EMIT_VEHICLE_HANDLINGRULE)) if (!(m_CircularLocks & VEHICLECL_EMIT_VEHICLE_HANDLINGRULE))
{ {
@ -1099,6 +1099,8 @@ void CVehicle::SetHandlingRule(int32_t rule, float data)
// Now forward the event call // Now forward the event call
Core::Get().EmitVehicleHandlingRule(m_ID, rule, current, data); Core::Get().EmitVehicleHandlingRule(m_ID, rule, current, data);
} }
// Avoid property unwind from a recursive call
_Func->SetInstHandlingRule(m_ID, rule, data);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -1108,8 +1110,6 @@ void CVehicle::ResetHandlingRule(int32_t rule)
Validate(); Validate();
// Grab the current value for this property // Grab the current value for this property
const auto current = static_cast< SQFloat >(_Func->GetInstHandlingRule(m_ID, rule)); const auto current = static_cast< SQFloat >(_Func->GetInstHandlingRule(m_ID, rule));
// Avoid property unwind from a recursive call
_Func->ResetInstHandlingRule(m_ID, rule);
// Avoid infinite recursive event loops // Avoid infinite recursive event loops
if (!(m_CircularLocks & VEHICLECL_EMIT_VEHICLE_HANDLINGRULE)) if (!(m_CircularLocks & VEHICLECL_EMIT_VEHICLE_HANDLINGRULE))
{ {
@ -1118,6 +1118,8 @@ void CVehicle::ResetHandlingRule(int32_t rule)
// Now forward the event call // Now forward the event call
Core::Get().EmitVehicleHandlingRule(m_ID, rule, current, static_cast< SQFloat >(_Func->GetInstHandlingRule(m_ID, rule))); Core::Get().EmitVehicleHandlingRule(m_ID, rule, current, static_cast< SQFloat >(_Func->GetInstHandlingRule(m_ID, rule)));
} }
// Avoid property unwind from a recursive call
_Func->ResetInstHandlingRule(m_ID, rule);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -1148,7 +1150,7 @@ void CVehicle::SetLightsData(int32_t data) const
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool CVehicle::Embark(CPlayer & player) const bool CVehicle::Embark(CPlayer & player)
{ {
// Is the specified player even valid? // Is the specified player even valid?
if (!player.IsActive()) if (!player.IsActive())
@ -1157,6 +1159,19 @@ bool CVehicle::Embark(CPlayer & player) const
} }
// Validate the managed identifier // Validate the managed identifier
Validate(); Validate();
// If the player embarks in the same vehicle then ignore
if (_Func->GetPlayerVehicleId(player.GetID()) == m_ID)
{
return true; // I guess this is somewhat successful
}
// Avoid infinite recursive event loops
else if (!(m_CircularLocks & VEHICLECL_EMIT_VEHICLE_EMBARK))
{
// Prevent this event from triggering while executed
BitGuardU32 bg(m_CircularLocks, VEHICLECL_EMIT_VEHICLE_EMBARK);
// Now forward the event call
Core::Get().EmitPlayerEmbarking(player.GetID(), m_ID, 0);
}
// Perform the requested operation // Perform the requested operation
return (_Func->PutPlayerInVehicle(player.GetID(), m_ID, 0, return (_Func->PutPlayerInVehicle(player.GetID(), m_ID, 0,
static_cast< uint8_t >(true), static_cast< uint8_t >(true)) static_cast< uint8_t >(true), static_cast< uint8_t >(true))
@ -1164,7 +1179,7 @@ bool CVehicle::Embark(CPlayer & player) const
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool CVehicle::EmbarkEx(CPlayer & player, int32_t slot, bool allocate, bool warp) const bool CVehicle::EmbarkEx(CPlayer & player, int32_t slot, bool allocate, bool warp)
{ {
// Is the specified player even valid? // Is the specified player even valid?
if (!player.IsActive()) if (!player.IsActive())
@ -1173,6 +1188,19 @@ bool CVehicle::EmbarkEx(CPlayer & player, int32_t slot, bool allocate, bool warp
} }
// Validate the managed identifier // Validate the managed identifier
Validate(); Validate();
// If the player embarks in the same vehicle then ignore
if (_Func->GetPlayerVehicleId(player.GetID()) == m_ID)
{
return true; // I guess this is somewhat successful
}
// Avoid infinite recursive event loops
else if (!(m_CircularLocks & VEHICLECL_EMIT_VEHICLE_EMBARK))
{
// Prevent this event from triggering while executed
BitGuardU32 bg(m_CircularLocks, VEHICLECL_EMIT_VEHICLE_EMBARK);
// Now forward the event call
Core::Get().EmitPlayerEmbarking(player.GetID(), m_ID, 0);
}
// Perform the requested operation // Perform the requested operation
return (_Func->PutPlayerInVehicle(player.GetID(), m_ID, slot, return (_Func->PutPlayerInVehicle(player.GetID(), m_ID, slot,
static_cast< uint8_t >(allocate), static_cast< uint8_t >(warp)) != vcmpErrorRequestDenied); static_cast< uint8_t >(allocate), static_cast< uint8_t >(warp)) != vcmpErrorRequestDenied);

View File

@ -18,7 +18,8 @@ enum VehicleCircularLocks
VEHICLECL_EMIT_VEHICLE_TYRESTATUS = (1u << 4u), VEHICLECL_EMIT_VEHICLE_TYRESTATUS = (1u << 4u),
VEHICLECL_EMIT_VEHICLE_DAMAGEDATA = (1u << 5u), VEHICLECL_EMIT_VEHICLE_DAMAGEDATA = (1u << 5u),
VEHICLECL_EMIT_VEHICLE_RADIO = (1u << 6u), VEHICLECL_EMIT_VEHICLE_RADIO = (1u << 6u),
VEHICLECL_EMIT_VEHICLE_HANDLINGRULE = (1u << 7u) VEHICLECL_EMIT_VEHICLE_HANDLINGRULE = (1u << 7u),
VEHICLECL_EMIT_VEHICLE_EMBARK = (1u << 8u) // This should probably be shared with CPlayer
}; };
/* ------------------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------------------
@ -615,12 +616,12 @@ public:
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Embark the specified player entity into the managed vehicle entity. * Embark the specified player entity into the managed vehicle entity.
*/ */
bool Embark(CPlayer & player) const; bool Embark(CPlayer & player);
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Embark the specified player entity into the managed vehicle entity. * Embark the specified player entity into the managed vehicle entity.
*/ */
bool EmbarkEx(CPlayer & player, int32_t slot, bool allocate, bool warp) const; bool EmbarkEx(CPlayer & player, int32_t slot, bool allocate, bool warp);
#if SQMOD_SDK_LEAST(2, 1) #if SQMOD_SDK_LEAST(2, 1)
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Set whether the target player will see an objective arrow over a vehicle. * Set whether the target player will see an objective arrow over a vehicle.

View File

@ -451,11 +451,15 @@ LightObj EscapeString(StackStrF & str)
} }
// Allocate a memory buffer // Allocate a memory buffer
std::vector< SQChar > b; std::vector< SQChar > b;
b.reserve(static_cast< size_t >(str.mLen)); // Allocate extra space to make sure there's room for a null terminator since we need it
// This is a f* up from SQLite devs not returning the number of written characters from snprintf
// So we can figure out if we actually had room for the null terminator or not
b.reserve(static_cast< size_t >(str.mLen * 2 + 1));
// Attempt to escape the specified string // Attempt to escape the specified string
sqlite3_snprintf(static_cast<int>(b.capacity()), b.data(), "%q", str.mPtr); sqlite3_snprintf(static_cast<int>(b.capacity()), b.data(), "%q", str.mPtr);
// Return the resulted string // Return the resulted string
return LightObj(b.data()); LightObj o(b.data(), -1);
return o;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -477,7 +481,8 @@ LightObj EscapeStringEx(SQChar spec, StackStrF & str)
fs[1] = spec; fs[1] = spec;
// Allocate a memory buffer // Allocate a memory buffer
std::vector< SQChar > b; std::vector< SQChar > b;
b.reserve(static_cast< size_t >(str.mLen)); // Allocate extra space to make sure there's room for a null terminator since we need it (see above)
b.reserve(static_cast< size_t >(str.mLen * 2 + 1));
// Attempt to escape the specified string // Attempt to escape the specified string
sqlite3_snprintf(static_cast<int>(b.capacity()), b.data(), fs, str.mPtr); sqlite3_snprintf(static_cast<int>(b.capacity()), b.data(), fs, str.mPtr);
// Return the resulted string // Return the resulted string

View File

@ -673,7 +673,7 @@ struct LgPlayer
void SetCanAttack(bool toggle) const { _Func->SetPlayerOption(GetIdentifier(), vcmpPlayerOptionCanAttack, static_cast< uint8_t >(toggle)); } void SetCanAttack(bool toggle) const { _Func->SetPlayerOption(GetIdentifier(), vcmpPlayerOptionCanAttack, static_cast< uint8_t >(toggle)); }
void SetWeaponSlot(int slot) const { Get().SetWeaponSlot(slot); } void SetWeaponSlot(int slot) const { Get().SetWeaponSlot(slot); }
void ShowMarkers(bool toggle) const { _Func->SetPlayerOption(GetIdentifier(), vcmpPlayerOptionShowMarkers, static_cast< uint8_t >(toggle)); } void ShowMarkers(bool toggle) const { _Func->SetPlayerOption(GetIdentifier(), vcmpPlayerOptionShowMarkers, static_cast< uint8_t >(toggle)); }
void SetSpectateTarget(LgPlayer & player) const { Get().SetSpectator(player.Get()); } void SetSpectateTarget(LightObj & player) const { player.IsNull() ? Get().SetSpectatorID(-1) : Get().SetSpectator(player.CastI< LgPlayer >()->Get()); }
void SetMarkerVisible(bool toggle) const { _Func->SetPlayerOption(GetIdentifier(), vcmpPlayerOptionHasMarker, static_cast< uint8_t >(toggle)); } void SetMarkerVisible(bool toggle) const { _Func->SetPlayerOption(GetIdentifier(), vcmpPlayerOptionHasMarker, static_cast< uint8_t >(toggle)); }
void SetCanUseColors(bool toggle) const { _Func->SetPlayerOption(GetIdentifier(), vcmpPlayerOptionChatTagsEnabled, static_cast< uint8_t >(toggle)); } void SetCanUseColors(bool toggle) const { _Func->SetPlayerOption(GetIdentifier(), vcmpPlayerOptionChatTagsEnabled, static_cast< uint8_t >(toggle)); }
void SetDrunkStatus(bool toggle) const { _Func->SetPlayerOption(GetIdentifier(), vcmpPlayerOptionDrunkEffects, static_cast< uint8_t >(toggle)); } void SetDrunkStatus(bool toggle) const { _Func->SetPlayerOption(GetIdentifier(), vcmpPlayerOptionDrunkEffects, static_cast< uint8_t >(toggle)); }