Fix Resurrect Illegal Player State/Crash (#8349)

This commit is contained in:
Eric Robinson
2025-12-11 20:12:40 -05:00
committed by GitHub
parent fca50346e4
commit 37daef5de3
4 changed files with 47 additions and 17 deletions
+28 -6
View File
@@ -1905,18 +1905,38 @@ size_t OnKnockback(const TCmdParam1 &message, Player &player)
return sizeof(message);
}
size_t OnResurrect(const TCmdParam1 &message, Player &player)
size_t OnResurrect(const TCmdParam1 &message, Player &caster)
{
const uint16_t playerIdx = Swap16LE(message.wParam1);
if (gbBufferMsgs == 1) {
BufferMessage(player, &message, sizeof(message));
} else if (playerIdx < Players.size()) {
DoResurrect(player, Players[playerIdx]);
if (&player == MyPlayer)
pfile_update(true);
BufferMessage(caster, &message, sizeof(message));
return sizeof(message);
}
if (playerIdx >= Players.size())
return sizeof(message);
Player &target = Players[playerIdx];
SpawnResurrectBeam(caster, target);
if (&target == MyPlayer && target._pHitPoints <= 0) {
NetSendCmd(true, CMD_PLRALIVE);
}
return sizeof(message);
}
size_t OnPlayerAlive(const TCmd &message, Player &target)
{
if (gbBufferMsgs == 1) {
BufferMessage(target, &message, sizeof(message));
return sizeof(message);
}
ApplyResurrect(target);
return sizeof(message);
}
@@ -3390,6 +3410,8 @@ size_t ParseCmd(uint8_t pnum, const TCmd *pCmd, size_t maxCmdSize)
return HandleCmd(OnMonstDamage, player, pCmd, maxCmdSize);
case CMD_PLRDEAD:
return HandleCmd(OnPlayerDeath, player, pCmd, maxCmdSize);
case CMD_PLRALIVE:
return HandleCmd(OnPlayerAlive, player, pCmd, maxCmdSize);
case CMD_PLRDAMAGE:
return HandleCmd(OnPlayerDamage, player, pCmd, maxCmdSize);
case CMD_OPENDOOR:
+4
View File
@@ -205,6 +205,10 @@ enum _cmd_id : uint8_t {
// body (TCmdParam1):
// int16_t ear_flag
CMD_PLRDEAD,
// Player resurrection.
//
// body (TCmd)
CMD_PLRALIVE,
// Lift item to hand request.
//
// body (TCmdGItem)
+13 -5
View File
@@ -232,13 +232,21 @@ void CastSpell(Player &player, SpellID spl, WorldTilePosition src, WorldTilePosi
}
}
void DoResurrect(Player &player, Player &target)
void SpawnResurrectBeam(Player &caster, Player &target)
{
AddMissile(target.position.tile, target.position.tile, Direction::South, MissileID::ResurrectBeam, TARGET_MONSTERS, player, 0, 0);
if (!target.hasNoLife())
return;
AddMissile(
target.position.tile,
target.position.tile,
Direction::South,
MissileID::ResurrectBeam,
TARGET_MONSTERS,
caster.getId(),
0,
0);
}
void ApplyResurrect(Player &target)
{
if (&target == MyPlayer) {
MyPlayerIsDead = false;
gamemenu_off();
+2 -6
View File
@@ -36,12 +36,8 @@ SpellCheckResult CheckSpell(const Player &player, SpellID sn, SpellType st, bool
*/
void EnsureValidReadiedSpell(Player &player);
void CastSpell(Player &player, SpellID spl, WorldTilePosition src, WorldTilePosition dst, int spllvl);
/**
* @param pnum player index
* @param rid target player index
*/
void DoResurrect(Player &player, Player &target);
void SpawnResurrectBeam(Player &caster, Player &target);
void ApplyResurrect(Player &target);
void DoHealOther(const Player &caster, Player &target);
int GetSpellBookLevel(SpellID s);
int GetSpellStaffLevel(SpellID s);