From 31ba8e2bc68f4efab5ba4cd7c7dc911d288fc719 Mon Sep 17 00:00:00 2001 From: Anders Jenbo Date: Tue, 5 Oct 2021 23:13:43 +0200 Subject: [PATCH] Validate additional network messages --- Source/gendung.h | 2 + Source/inv.cpp | 23 ++++---- Source/inv.h | 4 +- Source/msg.cpp | 133 ++++++++++++++++++++++++---------------------- Source/portal.cpp | 31 ++++++----- Source/portal.h | 4 +- 6 files changed, 101 insertions(+), 96 deletions(-) diff --git a/Source/gendung.h b/Source/gendung.h index 362a8984d..9ce557280 100644 --- a/Source/gendung.h +++ b/Source/gendung.h @@ -44,6 +44,8 @@ enum dungeon_type : int8_t { DTYPE_HELL, DTYPE_NEST, DTYPE_CRYPT, + + DTYPE_LAST = DTYPE_CRYPT, DTYPE_NONE = -1, }; diff --git a/Source/inv.cpp b/Source/inv.cpp index 830efb6bc..28ccb0b0f 100644 --- a/Source/inv.cpp +++ b/Source/inv.cpp @@ -1476,7 +1476,7 @@ bool GoldAutoPlaceInInventorySlot(Player &player, int slotIndex) return true; } -void CheckInvSwap(Player &player, BYTE bLoc, int idx, uint16_t wCI, int seed, bool bId, uint32_t dwBuff) +void CheckInvSwap(Player &player, inv_body_loc bLoc, int idx, uint16_t wCI, int seed, bool bId, uint32_t dwBuff) { auto &item = Items[MAXITEMS]; memset(&item, 0, sizeof(item)); @@ -1488,24 +1488,20 @@ void CheckInvSwap(Player &player, BYTE bLoc, int idx, uint16_t wCI, int seed, bo player.HoldItem._iIdentified = true; } - if (bLoc < NUM_INVLOC) { - player.InvBody[bLoc] = player.HoldItem; + player.InvBody[bLoc] = player.HoldItem; - if (bLoc == INVLOC_HAND_LEFT && player.HoldItem._iLoc == ILOC_TWOHAND) { - player.InvBody[INVLOC_HAND_RIGHT]._itype = ItemType::None; - } else if (bLoc == INVLOC_HAND_RIGHT && player.HoldItem._iLoc == ILOC_TWOHAND) { - player.InvBody[INVLOC_HAND_LEFT]._itype = ItemType::None; - } + if (bLoc == INVLOC_HAND_LEFT && player.HoldItem._iLoc == ILOC_TWOHAND) { + player.InvBody[INVLOC_HAND_RIGHT]._itype = ItemType::None; + } else if (bLoc == INVLOC_HAND_RIGHT && player.HoldItem._iLoc == ILOC_TWOHAND) { + player.InvBody[INVLOC_HAND_LEFT]._itype = ItemType::None; } CalcPlrInv(player, true); } -void inv_update_rem_item(Player &player, BYTE iv) +void inv_update_rem_item(Player &player, inv_body_loc iv) { - if (iv < NUM_INVLOC) { - player.InvBody[iv]._itype = ItemType::None; - } + player.InvBody[iv]._itype = ItemType::None; CalcPlrInv(player, player._pmode != PM_DEATH); } @@ -1735,8 +1731,7 @@ int InvPutItem(Player &player, Point position) int yp = cursPosition.y; int xp = cursPosition.x; if (player.HoldItem._iCurs == ICURS_RUNE_BOMB && xp >= 79 && xp <= 82 && yp >= 61 && yp <= 64) { - Displacement relativePosition = position - player.position.tile; - NetSendCmdLocParam2(false, CMD_OPENHIVE, player.position.tile, relativePosition.deltaX, relativePosition.deltaY); + NetSendCmd(false, CMD_OPENHIVE); auto &quest = Quests[Q_FARMER]; quest._qactive = QUEST_DONE; if (gbIsMultiplayer) { diff --git a/Source/inv.h b/Source/inv.h index 47157d22a..c2ef7c7b2 100644 --- a/Source/inv.h +++ b/Source/inv.h @@ -148,8 +148,8 @@ bool AutoPlaceItemInInventorySlot(Player &player, int slotIndex, const Item &ite bool AutoPlaceItemInBelt(Player &player, const Item &item, bool persistItem = false); bool GoldAutoPlace(Player &player); bool GoldAutoPlaceInInventorySlot(Player &player, int slotIndex); -void CheckInvSwap(Player &player, BYTE bLoc, int idx, uint16_t wCI, int seed, bool bId, uint32_t dwBuff); -void inv_update_rem_item(Player &player, BYTE iv); +void CheckInvSwap(Player &player, inv_body_loc bLoc, int idx, uint16_t wCI, int seed, bool bId, uint32_t dwBuff); +void inv_update_rem_item(Player &player, inv_body_loc iv); void CheckInvItem(bool isShiftHeld = false, bool isCtrlHeld = false); /** diff --git a/Source/msg.cpp b/Source/msg.cpp index f0588de83..4c298116c 100644 --- a/Source/msg.cpp +++ b/Source/msg.cpp @@ -529,11 +529,11 @@ bool IOwnLevel(int nReqLevel) return i == MyPlayerId; } -void DeltaOpenPortal(int pnum, uint8_t x, uint8_t y, uint8_t bLevel, dungeon_type bLType, bool bSetLvl) +void DeltaOpenPortal(int pnum, Point position, uint8_t bLevel, dungeon_type bLType, bool bSetLvl) { sgbDeltaChanged = true; - sgJunk.portal[pnum].x = x; - sgJunk.portal[pnum].y = y; + sgJunk.portal[pnum].x = position.x; + sgJunk.portal[pnum].y = position.y; sgJunk.portal[pnum].level = bLevel; sgJunk.portal[pnum].ltype = bLType; sgJunk.portal[pnum].setlvl = bSetLvl ? 1 : 0; @@ -1403,25 +1403,25 @@ DWORD OnAwakeGolem(const TCmd *pCmd, int pnum) DWORD OnMonstDamage(const TCmd *pCmd, int pnum) { - auto *p = (TCmdMonDamage *)pCmd; + const auto &message = *reinterpret_cast(pCmd); - if (gbBufferMsgs == 1) - SendPacket(pnum, p, sizeof(*p)); // BUGFIX: change to sizeof(*p) or it still uses TCmdParam2 size for hellfire (fixed) - else if (pnum != MyPlayerId) { + if (gbBufferMsgs == 1) { + SendPacket(pnum, &message, sizeof(message)); + } else if (pnum != MyPlayerId) { int playerLevel = Players[pnum].plrlevel; - if (currlevel == playerLevel) { - auto &monster = Monsters[p->wMon]; + if (currlevel == playerLevel && message.wMon < MAXMONSTERS) { + auto &monster = Monsters[message.wMon]; monster.mWhoHit |= 1 << pnum; if (monster._mhitpoints > 0) { - monster._mhitpoints -= p->dwDam; + monster._mhitpoints -= message.dwDam; if ((monster._mhitpoints >> 6) < 1) monster._mhitpoints = 1 << 6; - delta_monster_hp(p->wMon, monster._mhitpoints, playerLevel); + delta_monster_hp(message.wMon, monster._mhitpoints, playerLevel); } } } - return sizeof(*p); + return sizeof(message); } DWORD OnPlayerDeath(const TCmd *pCmd, int pnum) @@ -1440,15 +1440,15 @@ DWORD OnPlayerDeath(const TCmd *pCmd, int pnum) DWORD OnPlayerDamage(const TCmd *pCmd, Player &player) { - auto *p = (TCmdDamage *)pCmd; + const auto &message = *reinterpret_cast(pCmd); - if (p->bPlr == MyPlayerId && currlevel != 0 && gbBufferMsgs != 1) { - if (currlevel == player.plrlevel && p->dwDam <= 192000 && Players[MyPlayerId]._pHitPoints >> 6 > 0) { - ApplyPlrDamage(MyPlayerId, 0, 0, p->dwDam, 1); + if (message.bPlr == MyPlayerId && currlevel != 0 && gbBufferMsgs != 1) { + if (currlevel == player.plrlevel && message.dwDam <= 192000 && Players[MyPlayerId]._pHitPoints >> 6 > 0) { + ApplyPlrDamage(MyPlayerId, 0, 0, message.dwDam, 1); } } - return sizeof(*p); + return sizeof(message); } DWORD OnOpenDoor(const TCmd *pCmd, int pnum) @@ -1501,63 +1501,63 @@ DWORD OnOperateObject(const TCmd *pCmd, int pnum) DWORD OnPlayerOperateObject(const TCmd *pCmd, int pnum) { - auto *p = (TCmdParam2 *)pCmd; + const auto &message = *reinterpret_cast(pCmd); if (gbBufferMsgs == 1) { - SendPacket(pnum, p, sizeof(*p)); - } else { + SendPacket(pnum, &message, sizeof(message)); + } else if (message.wParam1 < MAX_PLRS && message.wParam2 < MAXOBJECTS) { int playerLevel = Players[pnum].plrlevel; if (currlevel == playerLevel) - SyncOpObject(p->wParam1, CMD_PLROPOBJ, p->wParam2); - DeltaSyncObject(p->wParam2, CMD_PLROPOBJ, playerLevel); + SyncOpObject(message.wParam1, CMD_PLROPOBJ, message.wParam2); + DeltaSyncObject(message.wParam2, CMD_PLROPOBJ, playerLevel); } - return sizeof(*p); + return sizeof(message); } DWORD OnBreakObject(const TCmd *pCmd, int pnum) { - auto *p = (TCmdParam2 *)pCmd; + const auto &message = *reinterpret_cast(pCmd); if (gbBufferMsgs == 1) { - SendPacket(pnum, p, sizeof(*p)); - } else { + SendPacket(pnum, &message, sizeof(message)); + } else if (message.wParam1 < MAX_PLRS && message.wParam2 < MAXOBJECTS) { int playerLevel = Players[pnum].plrlevel; if (currlevel == playerLevel) - SyncBreakObj(p->wParam1, p->wParam2); - DeltaSyncObject(p->wParam2, CMD_BREAKOBJ, playerLevel); + SyncBreakObj(message.wParam1, message.wParam2); + DeltaSyncObject(message.wParam2, CMD_BREAKOBJ, playerLevel); } - return sizeof(*p); + return sizeof(message); } DWORD OnChangePlayerItems(const TCmd *pCmd, int pnum) { - auto *p = (TCmdChItem *)pCmd; - auto bodyLocation = static_cast(p->bLoc); + const auto &message = *reinterpret_cast(pCmd); - auto &player = Players[pnum]; - - if (gbBufferMsgs == 1) - SendPacket(pnum, p, sizeof(*p)); - else if (pnum != MyPlayerId) - CheckInvSwap(player, p->bLoc, p->wIndx, p->wCI, p->dwSeed, p->bId != 0, p->dwBuff); + if (gbBufferMsgs == 1) { + SendPacket(pnum, &message, sizeof(message)); + } else if (pnum != MyPlayerId && message.bLoc < NUM_INVLOC && message.wIndx <= IDI_LAST) { + auto &player = Players[pnum]; + auto bodyLocation = static_cast(message.bLoc); - player.ReadySpellFromEquipment(bodyLocation); + CheckInvSwap(player, bodyLocation, message.wIndx, message.wCI, message.dwSeed, message.bId != 0, message.dwBuff); + player.ReadySpellFromEquipment(bodyLocation); + } - return sizeof(*p); + return sizeof(message); } DWORD OnDeletePlayerItems(const TCmd *pCmd, int pnum) { - auto *p = (TCmdDelItem *)pCmd; + const auto &message = *reinterpret_cast(pCmd); if (gbBufferMsgs == 1) - SendPacket(pnum, p, sizeof(*p)); - else if (pnum != MyPlayerId) - inv_update_rem_item(Players[pnum], p->bLoc); + SendPacket(pnum, &message, sizeof(message)); + else if (pnum != MyPlayerId && message.bLoc < NUM_INVLOC) + inv_update_rem_item(Players[pnum], static_cast(message.bLoc)); - return sizeof(*p); + return sizeof(message); } DWORD OnPlayerLevel(const TCmd *pCmd, int pnum) @@ -1646,35 +1646,41 @@ DWORD OnPlayerJoinLevel(const TCmd *pCmd, int pnum) DWORD OnActivatePortal(const TCmd *pCmd, int pnum) { - auto *p = (TCmdLocParam3 *)pCmd; + const auto &message = *reinterpret_cast(pCmd); + const Point position { message.x, message.y }; if (gbBufferMsgs == 1) { - SendPacket(pnum, p, sizeof(*p)); - } else { - ActivatePortal(pnum, p->x, p->y, p->wParam1, static_cast(p->wParam2), p->wParam3 != 0); + SendPacket(pnum, &message, sizeof(message)); + } else if (InDungeonBounds(position) && message.wParam1 < NUMLEVELS && message.wParam2 <= DTYPE_LAST) { + int level = message.wParam1; + auto dungeonType = static_cast(message.wParam2); + bool isSetLevel = message.wParam3 != 0; + + ActivatePortal(pnum, position, level, dungeonType, isSetLevel); if (pnum != MyPlayerId) { - if (currlevel == 0) + if (currlevel == 0) { AddInTownPortal(pnum); - else if (currlevel == Players[pnum].plrlevel) { + } else if (currlevel == Players[pnum].plrlevel) { bool addPortal = true; for (int i = 0; i < ActiveMissileCount; i++) { int mi = ActiveMissiles[i]; auto &missile = Missiles[mi]; if (missile._mitype == MIS_TOWN && missile._misource == pnum) { addPortal = false; - // CODEFIX: break + break; } } - if (addPortal) - AddWarpMissile(pnum, p->x, p->y); + if (addPortal) { + AddWarpMissile(pnum, position); + } } else { RemovePortalMissile(pnum); } } - DeltaOpenPortal(pnum, p->x, p->y, p->wParam1, static_cast(p->wParam2), p->wParam3 != 0); + DeltaOpenPortal(pnum, position, level, dungeonType, isSetLevel); } - return sizeof(*p); + return sizeof(message); } DWORD OnDeactivatePortal(const TCmd *pCmd, int pnum) @@ -1767,17 +1773,17 @@ DWORD OnString(const TCmd *pCmd, int pnum) DWORD OnSyncQuest(const TCmd *pCmd, int pnum) { - auto *p = (TCmdQuest *)pCmd; + const auto &message = *reinterpret_cast(pCmd); if (gbBufferMsgs == 1) { - SendPacket(pnum, p, sizeof(*p)); + SendPacket(pnum, &message, sizeof(message)); } else { - if (pnum != MyPlayerId) - SetMultiQuest(p->q, p->qstate, p->qlog != 0, p->qvar1); + if (pnum != MyPlayerId && message.q < MAXQUESTS && message.qstate <= QUEST_HIVE_DONE) + SetMultiQuest(message.q, message.qstate, message.qlog != 0, message.qvar1); sgbDeltaChanged = true; } - return sizeof(*p); + return sizeof(message); } DWORD OnCheatExperience(const TCmd *pCmd, int pnum) // NOLINT(misc-unused-parameters) @@ -1874,14 +1880,13 @@ DWORD OnNakrul(const TCmd *pCmd) DWORD OnOpenHive(const TCmd *pCmd, int pnum) { - auto *p = (TCmdLocParam2 *)pCmd; - if (gbBufferMsgs != 1) { - AddMissile({ p->x, p->y }, { p->wParam1, p->wParam2 }, Direction::South, MIS_HIVEEXP2, TARGET_MONSTERS, pnum, 0, 0); + AddMissile({ 0, 0 }, { 0, 0 }, Direction::South, MIS_HIVEEXP2, TARGET_MONSTERS, pnum, 0, 0); TownOpenHive(); InitTownTriggers(); } - return sizeof(*p); + + return sizeof(*pCmd); } DWORD OnOpenCrypt(const TCmd *pCmd) diff --git a/Source/portal.cpp b/Source/portal.cpp index 7d17967c9..7d18311a8 100644 --- a/Source/portal.cpp +++ b/Source/portal.cpp @@ -21,10 +21,13 @@ namespace { /** Current portal number (a portal array index). */ int portalindex; -/** X-coordinate of each players portal in town. */ -int WarpDropX[MAXPORTAL] = { 57, 59, 61, 63 }; -/** Y-coordinate of each players portal in town. */ -int WarpDropY[MAXPORTAL] = { 40, 40, 40, 40 }; +/** Coordinate of each players portal in town. */ +Point WarpDrop[MAXPORTAL] = { + { 57, 40 }, + { 59, 40 }, + { 61, 40 }, + { 63, 40 }, +}; } // namespace @@ -45,11 +48,11 @@ void SetPortalStats(int i, bool o, int x, int y, int lvl, dungeon_type lvltype) Portals[i].setlvl = false; } -void AddWarpMissile(int i, int x, int y) +void AddWarpMissile(int i, Point position) { MissilesData[MIS_TOWN].mlSFX = SFX_NONE; - int mi = AddMissile({ 0, 0 }, { x, y }, Direction::South, MIS_TOWN, TARGET_MONSTERS, i, 0, 0); + int mi = AddMissile({ 0, 0 }, position, Direction::South, MIS_TOWN, TARGET_MONSTERS, i, 0, 0); if (mi == -1) return; @@ -68,31 +71,31 @@ void SyncPortals() if (!Portals[i].open) continue; if (currlevel == 0) - AddWarpMissile(i, WarpDropX[i], WarpDropY[i]); + AddWarpMissile(i, WarpDrop[i]); else { int lvl = currlevel; if (setlevel) lvl = setlvlnum; if (Portals[i].level == lvl && Portals[i].setlvl == setlevel) - AddWarpMissile(i, Portals[i].position.x, Portals[i].position.y); + AddWarpMissile(i, Portals[i].position); } } } void AddInTownPortal(int i) { - AddWarpMissile(i, WarpDropX[i], WarpDropY[i]); + AddWarpMissile(i, WarpDrop[i]); } -void ActivatePortal(int i, int x, int y, int lvl, dungeon_type lvltype, bool sp) +void ActivatePortal(int i, Point position, int lvl, dungeon_type dungeonType, bool isSetLevel) { Portals[i].open = true; if (lvl != 0) { - Portals[i].position = { x, y }; + Portals[i].position = position; Portals[i].level = lvl; - Portals[i].ltype = lvltype; - Portals[i].setlvl = sp; + Portals[i].ltype = dungeonType; + Portals[i].setlvl = isSetLevel; } } @@ -162,7 +165,7 @@ void GetPortalLevel() void GetPortalLvlPos() { if (currlevel == 0) { - ViewPosition = Point { WarpDropX[portalindex], WarpDropY[portalindex] } + Displacement { 1, 1 }; + ViewPosition = WarpDrop[portalindex] + Displacement { 1, 1 }; } else { ViewPosition = Portals[portalindex].position; diff --git a/Source/portal.h b/Source/portal.h index c874cc98c..20113a53d 100644 --- a/Source/portal.h +++ b/Source/portal.h @@ -24,10 +24,10 @@ extern Portal Portals[MAXPORTAL]; void InitPortals(); void SetPortalStats(int i, bool o, int x, int y, int lvl, dungeon_type lvltype); -void AddWarpMissile(int i, int x, int y); +void AddWarpMissile(int i, Point position); void SyncPortals(); void AddInTownPortal(int i); -void ActivatePortal(int i, int x, int y, int lvl, dungeon_type lvltype, bool sp); +void ActivatePortal(int i, Point position, int lvl, dungeon_type lvltype, bool sp); void DeactivatePortal(int i); bool PortalOnLevel(int i); void RemovePortalMissile(int id);