Browse Source

Fix Resurrect Illegal Player State/Crash (#8349)

pull/8326/merge
Eric Robinson 3 months ago committed by GitHub
parent
commit
37daef5de3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 34
      Source/msg.cpp
  2. 4
      Source/msg.h
  3. 18
      Source/spells.cpp
  4. 8
      Source/spells.h

34
Source/msg.cpp

@ -1905,21 +1905,41 @@ size_t OnKnockback(const TCmdParam1 &message, Player &player)
return sizeof(message); 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); const uint16_t playerIdx = Swap16LE(message.wParam1);
if (gbBufferMsgs == 1) { if (gbBufferMsgs == 1) {
BufferMessage(player, &message, sizeof(message)); BufferMessage(caster, &message, sizeof(message));
} else if (playerIdx < Players.size()) { return sizeof(message);
DoResurrect(player, Players[playerIdx]); }
if (&player == MyPlayer)
pfile_update(true); 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); 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);
}
size_t OnHealOther(const TCmdParam1 &message, const Player &caster) size_t OnHealOther(const TCmdParam1 &message, const Player &caster)
{ {
const uint16_t playerIdx = Swap16LE(message.wParam1); const uint16_t playerIdx = Swap16LE(message.wParam1);
@ -3390,6 +3410,8 @@ size_t ParseCmd(uint8_t pnum, const TCmd *pCmd, size_t maxCmdSize)
return HandleCmd(OnMonstDamage, player, pCmd, maxCmdSize); return HandleCmd(OnMonstDamage, player, pCmd, maxCmdSize);
case CMD_PLRDEAD: case CMD_PLRDEAD:
return HandleCmd(OnPlayerDeath, player, pCmd, maxCmdSize); return HandleCmd(OnPlayerDeath, player, pCmd, maxCmdSize);
case CMD_PLRALIVE:
return HandleCmd(OnPlayerAlive, player, pCmd, maxCmdSize);
case CMD_PLRDAMAGE: case CMD_PLRDAMAGE:
return HandleCmd(OnPlayerDamage, player, pCmd, maxCmdSize); return HandleCmd(OnPlayerDamage, player, pCmd, maxCmdSize);
case CMD_OPENDOOR: case CMD_OPENDOOR:

4
Source/msg.h

@ -205,6 +205,10 @@ enum _cmd_id : uint8_t {
// body (TCmdParam1): // body (TCmdParam1):
// int16_t ear_flag // int16_t ear_flag
CMD_PLRDEAD, CMD_PLRDEAD,
// Player resurrection.
//
// body (TCmd)
CMD_PLRALIVE,
// Lift item to hand request. // Lift item to hand request.
// //
// body (TCmdGItem) // body (TCmdGItem)

18
Source/spells.cpp

@ -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); AddMissile(
target.position.tile,
if (!target.hasNoLife()) target.position.tile,
return; Direction::South,
MissileID::ResurrectBeam,
TARGET_MONSTERS,
caster.getId(),
0,
0);
}
void ApplyResurrect(Player &target)
{
if (&target == MyPlayer) { if (&target == MyPlayer) {
MyPlayerIsDead = false; MyPlayerIsDead = false;
gamemenu_off(); gamemenu_off();

8
Source/spells.h

@ -36,12 +36,8 @@ SpellCheckResult CheckSpell(const Player &player, SpellID sn, SpellType st, bool
*/ */
void EnsureValidReadiedSpell(Player &player); void EnsureValidReadiedSpell(Player &player);
void CastSpell(Player &player, SpellID spl, WorldTilePosition src, WorldTilePosition dst, int spllvl); void CastSpell(Player &player, SpellID spl, WorldTilePosition src, WorldTilePosition dst, int spllvl);
void SpawnResurrectBeam(Player &caster, Player &target);
/** void ApplyResurrect(Player &target);
* @param pnum player index
* @param rid target player index
*/
void DoResurrect(Player &player, Player &target);
void DoHealOther(const Player &caster, Player &target); void DoHealOther(const Player &caster, Player &target);
int GetSpellBookLevel(SpellID s); int GetSpellBookLevel(SpellID s);
int GetSpellStaffLevel(SpellID s); int GetSpellStaffLevel(SpellID s);

Loading…
Cancel
Save