|
From: <cn...@us...> - 2024-03-16 03:07:02
|
Revision: 1458
http://sourceforge.net/p/seq/svn/1458
Author: cn187
Date: 2024-03-16 03:07:01 +0000 (Sat, 16 Mar 2024)
Log Message:
-----------
Fix issues with player-controlled entities
* Fix crash due to use-after-free when taking control of
player-controlled entities (eye of zomm, row boats, etc.)
* Fix spawnId and position ping-pong between player and
player-controlled entities.
Modified Paths:
--------------
showeq/branches/cn187_devel/src/player.cpp
showeq/branches/cn187_devel/src/player.h
showeq/branches/cn187_devel/src/spawnshell.cpp
showeq/branches/cn187_devel/src/spawnshell.h
Modified: showeq/branches/cn187_devel/src/player.cpp
===================================================================
--- showeq/branches/cn187_devel/src/player.cpp 2024-03-13 22:18:59 UTC (rev 1457)
+++ showeq/branches/cn187_devel/src/player.cpp 2024-03-16 03:07:01 UTC (rev 1458)
@@ -833,15 +833,27 @@
clear();
}
-void Player::playerUpdateSelf(const uint8_t* data, size_t, uint8_t dir)
+void Player::playerUpdateSelf(const uint8_t* data, size_t len, uint8_t dir)
{
const playerSelfPosStruct *pupdate = (const playerSelfPosStruct*)data;
if ((dir != DIR_Client) && (pupdate->spawnId != id()))
return;
- else if (dir == DIR_Client)
- setPlayerID(pupdate->spawnId);
+ if (dir == DIR_Client && id() == 0)
+ setPlayerID(pupdate->spawnId);
+ // When casting Eye of Zomm, using a row boat, or doing something else
+ // where you're controlling another spawn, the client will send multiple
+ // update packets, one for with your player spawn ID, and the other
+ // with the ID of the other object. So we can't assume that if the
+ // id changes, we can automatically update the player's ID like we used to.
+ // Instead, we'll pass the other ID to spawnshell for handling
+ if (pupdate->spawnId != id())
+ {
+ emit playerUpdate(data, len, dir);
+ return;
+ }
+
int16_t py = int16_t(pupdate->y);
int16_t px = int16_t(pupdate->x);
int16_t pz = int16_t(pupdate->z);
@@ -968,9 +980,10 @@
{
if (id() != playerID)
{
+ uint16_t old_id = id();
seqInfo("Your player's id is %i", playerID);
setID(playerID);
- emit changedID(id());
+ emit changedID(old_id, id());
updateLastChanged();
emit changeItem(this, tSpawnChangedALL);
}
@@ -1282,6 +1295,7 @@
void Player::savePlayerState(void)
{
+ return;
QFile keyFile(showeq_params->saveRestoreBaseFilename + "Player.dat");
if (keyFile.open(QIODevice::WriteOnly))
{
Modified: showeq/branches/cn187_devel/src/player.h
===================================================================
--- showeq/branches/cn187_devel/src/player.h 2024-03-13 22:18:59 UTC (rev 1457)
+++ showeq/branches/cn187_devel/src/player.h 2024-03-16 03:07:01 UTC (rev 1458)
@@ -200,7 +200,7 @@
void stamChanged ( int, int, int, int);
void hpChanged(int16_t, int16_t);
- void changedID(uint16_t playerID);
+ void changedID(uint16_t oldPlayerID, uint16_t newPlayerID);
void posChanged(int16_t x, int16_t y, int16_t z,
int16_t deltaX, int16_t deltaY, int16_t deltaZ,
int32_t heading);
@@ -208,6 +208,7 @@
void headingChanged(int32_t heading);
void levelChanged(uint8_t level);
void guildChanged();
+ void playerUpdate(const uint8_t* data, size_t len, uint8_t dir);
protected:
void fillConTable();
Modified: showeq/branches/cn187_devel/src/spawnshell.cpp
===================================================================
--- showeq/branches/cn187_devel/src/spawnshell.cpp 2024-03-13 22:18:59 UTC (rev 1457)
+++ showeq/branches/cn187_devel/src/spawnshell.cpp 2024-03-16 03:07:01 UTC (rev 1458)
@@ -144,10 +144,12 @@
// connect Player signals to SpawnShell signals
connect(m_player, SIGNAL(changeItem(const Item*, uint32_t)),
this, SIGNAL(changeItem(const Item*, uint32_t)));
+ connect(m_player, SIGNAL(playerUpdate(const uint8_t*, size_t, uint8_t)),
+ this, SLOT(playerUpdate2(const uint8_t*, size_t, uint8_t)));
// connect Player signals to SpawnShell slots
- connect(m_player, SIGNAL(changedID(uint16_t)),
- this, SLOT(playerChangedID(uint16_t)));
+ connect(m_player, SIGNAL(changedID(uint16_t, uint16_t)),
+ this, SLOT(playerChangedID(uint16_t, uint16_t)));
// connect to guildmgr to receive notifications of guild tag updates
connect(m_guildMgr, SIGNAL(guildTagUpdated(uint32_t)),
@@ -963,6 +965,29 @@
}
}
+void SpawnShell::playerUpdate2(const uint8_t* data, size_t len, uint8_t dir)
+{
+ if (m_zoneMgr->isZoning())
+ return;
+
+ //This payload is normally handled by Player::playerUpdateSelf,
+ //but sometimes it contains an update for a different spawn, such as
+ //an Eye of Zomm cast by the player, a rowboat being controlled by the
+ //player, etc. So in that case, we'll handle it.
+ const playerSelfPosStruct *pupdate = (const playerSelfPosStruct *)data;
+
+ int16_t py = int16_t(pupdate->y);
+ int16_t px = int16_t(pupdate->x);
+ int16_t pz = int16_t(pupdate->z);
+ int16_t pdeltaX = int16_t(pupdate->deltaX);
+ int16_t pdeltaY = int16_t(pupdate->deltaY);
+ int16_t pdeltaZ = int16_t(pupdate->deltaZ);
+
+
+ updateSpawn(pupdate->spawnId, px, py, pz, pdeltaX, pdeltaY, pdeltaZ,
+ pupdate->heading, pupdate->deltaHeading, pupdate->animation);
+}
+
void SpawnShell::playerUpdate(const uint8_t* data, size_t len, uint8_t dir)
{
// if zoning, then don't do anything
@@ -1667,14 +1692,13 @@
}
}
-void SpawnShell::playerChangedID(uint16_t playerID)
+void SpawnShell::playerChangedID(uint16_t oldPlayerID, uint16_t newPlayerID)
{
// remove the player from the list (if it had a 0 id)
m_players.take(0);
// re-insert the player into the list
- delete m_players.take(playerID);
- m_players.insert(playerID, m_player);
+ m_players.insert(newPlayerID, m_players.take(oldPlayerID));
emit changeItem(m_player, tSpawnChangedALL);
}
Modified: showeq/branches/cn187_devel/src/spawnshell.h
===================================================================
--- showeq/branches/cn187_devel/src/spawnshell.h 2024-03-13 22:18:59 UTC (rev 1457)
+++ showeq/branches/cn187_devel/src/spawnshell.h 2024-03-16 03:07:01 UTC (rev 1458)
@@ -122,6 +122,7 @@
void zoneEntry(const uint8_t* spawn, size_t len);
void newSpawn(const uint8_t* spawn);
void newSpawn(const spawnStruct& s);
+ void playerUpdate2(const uint8_t*pupdate, size_t, uint8_t);
void playerUpdate(const uint8_t*pupdate, size_t, uint8_t);
void npcMoveUpdate(const uint8_t*npcupdate, size_t, uint8_t);
void updateSpawn(uint16_t id,
@@ -144,7 +145,7 @@
void respawnFromHover(const uint8_t* respawn, size_t len, uint8_t dir);
void corpseLoc(const uint8_t* corpseLoc);
- void playerChangedID(uint16_t playerID);
+ void playerChangedID(uint16_t oldPlayerID, uint16_t newPlayerID);
void refilterSpawns();
void refilterSpawnsRuntime();
void saveSpawns(void);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|