mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-10-25 22:22:48 +00:00
fix(master): a rocket launch preps the clone the player is going to
Launching to a property started an extra clone 0 instance of the zone besides the property's own, because the prep only carried the zone. PrepZone now carries the clone when there is one (written only then, so a plain prep is unchanged). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -71,8 +71,9 @@ void RocketLaunchpadControlComponent::Launch(Entity* originator, LWOMAPID mapId,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// we have the ability to launch, so now we prep the zone
|
// we have the ability to launch, so now we prep the zone: the clone the player is going to (a property), not an extra
|
||||||
TellMasterToPrepZone(zone);
|
// clone 0 instance nobody asked for
|
||||||
|
TellMasterToPrepZone(zone, cloneId == LWOCLONEID_INVALID ? 0 : cloneId);
|
||||||
|
|
||||||
// Achievement unlocked: "All zones unlocked"
|
// Achievement unlocked: "All zones unlocked"
|
||||||
if (!m_AltLandingScene.empty() && m_AltPrecondition->Check(originator)) {
|
if (!m_AltLandingScene.empty() && m_AltPrecondition->Check(originator)) {
|
||||||
@@ -142,9 +143,10 @@ LWOCLONEID RocketLaunchpadControlComponent::GetSelectedCloneId(LWOOBJID player)
|
|||||||
return index->second;
|
return index->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RocketLaunchpadControlComponent::TellMasterToPrepZone(int zoneID) {
|
void RocketLaunchpadControlComponent::TellMasterToPrepZone(int zoneID, LWOCLONEID cloneID) {
|
||||||
MasterPackets::PrepZone request;
|
MasterPackets::PrepZone request;
|
||||||
request.zoneID = zoneID;
|
request.zoneID = zoneID;
|
||||||
|
request.cloneID = cloneID;
|
||||||
MasterPackets::SendToMaster(request);
|
MasterPackets::SendToMaster(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ private:
|
|||||||
* Notifies the master server to prepare some world for a player to be able to travel to it
|
* Notifies the master server to prepare some world for a player to be able to travel to it
|
||||||
* @param zoneID the ID of the zone to prepare
|
* @param zoneID the ID of the zone to prepare
|
||||||
*/
|
*/
|
||||||
void TellMasterToPrepZone(int zoneID);
|
void TellMasterToPrepZone(int zoneID, LWOCLONEID cloneID = 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ROCKETLAUNCHPADCONTROLCOMPONENT_H
|
#endif // ROCKETLAUNCHPADCONTROLCOMPONENT_H
|
||||||
|
|||||||
@@ -899,8 +899,8 @@ namespace {
|
|||||||
if (shutdownSequenceStarted) {
|
if (shutdownSequenceStarted) {
|
||||||
LOG("Shutdown sequence has been started. Not prepping a new zone.");
|
LOG("Shutdown sequence has been started. Not prepping a new zone.");
|
||||||
} else {
|
} else {
|
||||||
LOG("Prepping zone %i", zoneID);
|
LOG("Prepping zone %i clone %u", zoneID, request.cloneID);
|
||||||
Game::im->GetInstance(zoneID, false, 0);
|
Game::im->GetInstance(zoneID, false, request.cloneID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -201,10 +201,13 @@ namespace MasterPackets {
|
|||||||
|
|
||||||
void PrepZone::Serialize(RakNet::BitStream& bitStream) const {
|
void PrepZone::Serialize(RakNet::BitStream& bitStream) const {
|
||||||
bitStream.Write(zoneID);
|
bitStream.Write(zoneID);
|
||||||
|
if (cloneID != 0) bitStream.Write(cloneID);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PrepZone::Deserialize(RakNet::BitStream& bitStream) {
|
bool PrepZone::Deserialize(RakNet::BitStream& bitStream) {
|
||||||
VALIDATE_READ(bitStream.Read(zoneID));
|
VALIDATE_READ(bitStream.Read(zoneID));
|
||||||
|
cloneID = 0;
|
||||||
|
if (bitStream.GetNumberOfUnreadBits() >= 32) VALIDATE_READ(bitStream.Read(cloneID));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -190,9 +190,11 @@ namespace MasterPackets {
|
|||||||
bool Deserialize(RakNet::BitStream& bitStream) override;
|
bool Deserialize(RakNet::BitStream& bitStream) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
// World -> master: start an instance of zoneID now, players are about to ask for it
|
// World -> master: start an instance of zoneID now, players are about to ask for it. cloneID: the clone they will ask
|
||||||
|
// for (a property), written only when not 0 so a plain prep stays as it always was
|
||||||
struct PrepZone : public LUBitStream {
|
struct PrepZone : public LUBitStream {
|
||||||
int32_t zoneID{};
|
int32_t zoneID{};
|
||||||
|
uint32_t cloneID{};
|
||||||
|
|
||||||
PrepZone() : LUBitStream(ServiceType::MASTER, MessageType::Master::PREP_ZONE) {}
|
PrepZone() : LUBitStream(ServiceType::MASTER, MessageType::Master::PREP_ZONE) {}
|
||||||
void Serialize(RakNet::BitStream& bitStream) const override;
|
void Serialize(RakNet::BitStream& bitStream) const override;
|
||||||
|
|||||||
@@ -290,6 +290,22 @@ TEST(MasterPacketsTests, WorldStateMatchesLegacy) {
|
|||||||
RoundTrip(prep);
|
RoundTrip(prep);
|
||||||
ExpectTruncatedFails(prep);
|
ExpectTruncatedFails(prep);
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
// A property's clone rides after the zone; a prep without one reads as clone 0
|
||||||
|
MasterPackets::PrepZone prep;
|
||||||
|
prep.zoneID = 1251;
|
||||||
|
prep.cloneID = 2290;
|
||||||
|
RakNet::BitStream stream;
|
||||||
|
prep.Serialize(stream);
|
||||||
|
MasterPackets::PrepZone read;
|
||||||
|
ASSERT_TRUE(read.Deserialize(stream));
|
||||||
|
EXPECT_EQ(read.zoneID, 1251);
|
||||||
|
EXPECT_EQ(read.cloneID, 2290u);
|
||||||
|
RakNet::BitStream plain;
|
||||||
|
plain.Write<int32_t>(1100);
|
||||||
|
ASSERT_TRUE(read.Deserialize(plain));
|
||||||
|
EXPECT_EQ(read.cloneID, 0u);
|
||||||
|
}
|
||||||
|
|
||||||
for (const auto requestID : g_RequestIds) {
|
for (const auto requestID : g_RequestIds) {
|
||||||
MasterPackets::AffirmTransferRequest request;
|
MasterPackets::AffirmTransferRequest request;
|
||||||
|
|||||||
Reference in New Issue
Block a user