mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-11-14 07:47:13 +00:00
The master server dropped a transfer request it started no instance for, so the world server never heard back and the player waited. It now answers the request with an empty address and the reason in place of the port: no room for another instance (max_instances), a zone that is not in the ZoneTable, or another reason. A request for a private zone that does not exist is answered the same way. The world server passes this on as a TRANSFER_TO_WORLD without an address, which the client shows as a failed map change, and leaves the character where it is. The auth server fails the login when there is no character select to send the player to. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
74 lines
2.7 KiB
C++
74 lines
2.7 KiB
C++
#include "PropertyTeleportBehavior.h"
|
|
#include "WorldPackets.h"
|
|
|
|
#include "BehaviorBranchContext.h"
|
|
#include "BehaviorContext.h"
|
|
#include "Character.h"
|
|
#include "CharacterComponent.h"
|
|
#include "ChatPackets.h"
|
|
#include "ClientPackets.h"
|
|
#include "EntityManager.h"
|
|
#include "Game.h"
|
|
#include "ZoneInstanceManager.h"
|
|
#include "dZoneManager.h"
|
|
|
|
void PropertyTeleportBehavior::Handle(BehaviorContext* context, RakNet::BitStream& bitStream, BehaviorBranchContext branch) {
|
|
auto* caster = Game::entityManager->GetEntity(context->caster);
|
|
if (!caster) return;
|
|
|
|
auto* character = caster->GetCharacter();
|
|
if (!character) return;
|
|
|
|
LWOOBJID objId = caster->GetObjectID();
|
|
|
|
LWOMAPID targetMapId = m_MapId;
|
|
LWOCLONEID targetCloneId = character->GetPropertyCloneID();
|
|
|
|
if (Game::zoneManager->GetZoneID().GetCloneID() == character->GetPropertyCloneID()) {
|
|
targetMapId = character->GetLastNonInstanceZoneID();
|
|
targetCloneId = 0;
|
|
} else {
|
|
character->SetLastNonInstanceZoneID(Game::zoneManager->GetZoneID().GetMapID());
|
|
}
|
|
|
|
ZoneInstanceManager::Instance()->RequestZoneTransfer(Game::server, targetMapId, targetCloneId, false, [objId](bool mythranShift, uint32_t zoneID, uint32_t zoneInstance, uint32_t zoneClone, std::string serverIP, uint16_t serverPort) {
|
|
|
|
auto* entity = Game::entityManager->GetEntity(objId);
|
|
if (!entity) return;
|
|
|
|
const auto sysAddr = entity->GetSystemAddress();
|
|
|
|
if (WorldPackets::SendIfTransferFailed(sysAddr, serverIP, serverPort)) return;
|
|
|
|
if (zoneClone != 0) ChatPackets::SendSystemMessage(sysAddr, u"Transfering to your property!");
|
|
else ChatPackets::SendSystemMessage(sysAddr, u"Transfering back to previous world!");
|
|
|
|
LOG("Transferring %s to Zone %i (Instance %i | Clone %i | Mythran Shift: %s) with IP %s and Port %i", sysAddr.ToString(), zoneID, zoneInstance, zoneClone, mythranShift == true ? "true" : "false", serverIP.c_str(), serverPort);
|
|
if (entity->GetCharacter()) {
|
|
auto* characterComponent = entity->GetComponent<CharacterComponent>();
|
|
if (characterComponent) {
|
|
characterComponent->AddVisitedLevel(LWOZONEID(zoneID, LWOINSTANCEID_INVALID, zoneClone));
|
|
characterComponent->SetLastRocketConfig(u"");
|
|
}
|
|
|
|
entity->GetCharacter()->SetZoneID(zoneID);
|
|
entity->GetCharacter()->SetZoneInstance(zoneInstance);
|
|
entity->GetCharacter()->SetZoneClone(zoneClone);
|
|
}
|
|
|
|
entity->GetCharacter()->SaveXMLToDatabase();
|
|
|
|
ClientPackets::TransferToWorld transfer;
|
|
transfer.serverIP = LUString(serverIP);
|
|
transfer.serverPort = serverPort;
|
|
transfer.mythranShift = mythranShift;
|
|
transfer.Send(sysAddr);
|
|
return;
|
|
});
|
|
}
|
|
|
|
void PropertyTeleportBehavior::Load() {
|
|
this->m_CancelIfInteracting = GetBoolean("cancel_if_interacting"); // TODO unused
|
|
this->m_MapId = LWOMAPID(GetInt("mapID"));
|
|
}
|