Browse Source

Validate additional network messages

pull/3051/head
Anders Jenbo 5 years ago
parent
commit
31ba8e2bc6
  1. 2
      Source/gendung.h
  2. 23
      Source/inv.cpp
  3. 4
      Source/inv.h
  4. 133
      Source/msg.cpp
  5. 31
      Source/portal.cpp
  6. 4
      Source/portal.h

2
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,
};

23
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) {

4
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);
/**

133
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<const TCmdMonDamage *>(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<const TCmdDamage *>(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<const TCmdParam2 *>(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<const TCmdParam2 *>(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<inv_body_loc>(p->bLoc);
const auto &message = *reinterpret_cast<const TCmdChItem *>(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<inv_body_loc>(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<const TCmdDelItem *>(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<inv_body_loc>(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<const TCmdLocParam3 *>(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<dungeon_type>(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<dungeon_type>(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<dungeon_type>(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<const TCmdQuest *>(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)

31
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;

4
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);

Loading…
Cancel
Save