mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-04-12 07:43:51 +00:00
make a user friendly delete message
Signed-off-by: Pavel Okhlopkov <pavel.okhlopkov@flant.com>
This commit is contained in:
parent
5b47d034c5
commit
fe1dc5e02b
5 changed files with 62 additions and 10 deletions
|
|
@ -199,7 +199,7 @@ public:
|
|||
using CharCreateCallback = std::function<void(bool success, const std::string& message)>;
|
||||
void setCharCreateCallback(CharCreateCallback cb) { charCreateCallback_ = std::move(cb); }
|
||||
|
||||
using CharDeleteCallback = std::function<void(bool success)>;
|
||||
using CharDeleteCallback = std::function<void(bool success, const std::string& message)>;
|
||||
void setCharDeleteCallback(CharDeleteCallback cb) { charDeleteCallback_ = std::move(cb); }
|
||||
uint8_t getLastCharDeleteResult() const { return lastCharDeleteResult_; }
|
||||
|
||||
|
|
@ -3336,6 +3336,10 @@ private:
|
|||
CharDeleteCallback charDeleteCallback_;
|
||||
CharLoginFailCallback charLoginFailCallback_;
|
||||
uint8_t lastCharDeleteResult_ = 0xFF;
|
||||
bool pendingCharDeleteResponse_ = false;
|
||||
uint64_t pendingDeleteGuid_ = 0;
|
||||
float pendingDeleteTimer_ = 0.0f;
|
||||
bool pendingDeleteFallbackEnum_ = false;
|
||||
bool pendingCharCreateResult_ = false;
|
||||
bool pendingCharCreateSuccess_ = false;
|
||||
std::string pendingCharCreateMsg_;
|
||||
|
|
|
|||
|
|
@ -166,15 +166,10 @@ void UIScreenCallbackHandler::setupCallbacks() {
|
|||
});
|
||||
|
||||
// Character delete result callback
|
||||
gameHandler_.setCharDeleteCallback([this](bool success) {
|
||||
gameHandler_.setCharDeleteCallback([this](bool success, const std::string& message) {
|
||||
uiManager_.getCharacterScreen().setStatus(message, !success);
|
||||
if (success) {
|
||||
uiManager_.getCharacterScreen().setStatus("Character deleted.");
|
||||
// Refresh character list
|
||||
gameHandler_.requestCharacterList();
|
||||
} else {
|
||||
uint8_t code = gameHandler_.getLastCharDeleteResult();
|
||||
uiManager_.getCharacterScreen().setStatus(
|
||||
"Delete failed (code " + std::to_string(static_cast<int>(code)) + ").", true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -756,6 +756,43 @@ void GameHandler::update(float deltaTime) {
|
|||
updateNetworking(deltaTime);
|
||||
if (!socket) return; // disconnect() may have been called
|
||||
|
||||
// Fallback for CMSG_CHAR_DELETE with no server response: if the server
|
||||
// doesn't send SMSG_CHAR_DELETE within 3 seconds, re-request the character
|
||||
// list. Some server cores silently process the delete without responding.
|
||||
if (pendingCharDeleteResponse_) {
|
||||
pendingDeleteTimer_ += deltaTime;
|
||||
if (pendingDeleteTimer_ >= 3.0f) {
|
||||
LOG_WARNING("No SMSG_CHAR_DELETE response after 3s — requesting character list to verify");
|
||||
pendingCharDeleteResponse_ = false;
|
||||
pendingDeleteFallbackEnum_ = true;
|
||||
requestCharacterList();
|
||||
}
|
||||
}
|
||||
|
||||
// After the fallback SMSG_CHAR_ENUM has been processed, check if the
|
||||
// character was actually removed and fire the delete callback.
|
||||
if (pendingDeleteFallbackEnum_ && state == WorldState::CHAR_LIST_RECEIVED) {
|
||||
pendingDeleteFallbackEnum_ = false;
|
||||
uint64_t deletedGuid = pendingDeleteGuid_;
|
||||
pendingDeleteGuid_ = 0;
|
||||
bool found = false;
|
||||
for (const auto& ch : characters) {
|
||||
if (ch.guid == deletedGuid) { found = true; break; }
|
||||
}
|
||||
bool deleted = !found;
|
||||
LOG_INFO("Char delete fallback: GUID 0x", std::hex, deletedGuid, std::dec,
|
||||
deleted ? " was deleted" : " still exists");
|
||||
std::string msg;
|
||||
if (deleted) {
|
||||
msg = "Character deleted.";
|
||||
} else {
|
||||
msg = "Delete failed: the server did not respond. "
|
||||
"This usually happens if you recently logged out — "
|
||||
"wait 20-30 seconds and try again.";
|
||||
}
|
||||
if (charDeleteCallback_) charDeleteCallback_(deleted, msg);
|
||||
}
|
||||
|
||||
// Validate target still exists
|
||||
if (targetGuid != 0 && !entityController_->getEntityManager().hasEntity(targetGuid)) {
|
||||
clearTarget();
|
||||
|
|
|
|||
|
|
@ -342,13 +342,16 @@ void GameHandler::handleCharCreateResponse(network::Packet& packet) {
|
|||
|
||||
void GameHandler::deleteCharacter(uint64_t characterGuid) {
|
||||
if (!socket) {
|
||||
if (charDeleteCallback_) charDeleteCallback_(false);
|
||||
if (charDeleteCallback_) charDeleteCallback_(false, "Delete failed: not connected to server.");
|
||||
return;
|
||||
}
|
||||
|
||||
network::Packet packet(wireOpcode(Opcode::CMSG_CHAR_DELETE));
|
||||
packet.writeUInt64(characterGuid);
|
||||
socket->send(packet);
|
||||
pendingCharDeleteResponse_ = true;
|
||||
pendingDeleteGuid_ = characterGuid;
|
||||
pendingDeleteTimer_ = 0.0f;
|
||||
LOG_INFO("CMSG_CHAR_DELETE sent for GUID: 0x", std::hex, characterGuid, std::dec);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -151,10 +151,23 @@ void GameHandler::registerOpcodeHandlers() {
|
|||
dispatchTable_[Opcode::SMSG_CHAR_DELETE] = [this](network::Packet& packet) {
|
||||
uint8_t result = packet.readUInt8();
|
||||
lastCharDeleteResult_ = result;
|
||||
pendingCharDeleteResponse_ = false;
|
||||
bool success = (result == 0x00 || result == 0x47);
|
||||
LOG_INFO("SMSG_CHAR_DELETE result: ", static_cast<int>(result), success ? " (success)" : " (failed)");
|
||||
requestCharacterList();
|
||||
if (charDeleteCallback_) charDeleteCallback_(success);
|
||||
std::string msg;
|
||||
if (success) {
|
||||
msg = "Character deleted.";
|
||||
} else {
|
||||
// Map known CHAR_DELETE_* result codes to user-friendly messages
|
||||
switch (result) {
|
||||
case 0x31: msg = "Delete failed: character is a guild leader. Transfer leadership first."; break;
|
||||
case 0x32: msg = "Delete failed: character is in an arena team."; break;
|
||||
case 0x3A: msg = "Delete failed: character has mail. Check mailbox first."; break;
|
||||
default: msg = "Delete failed (server error code " + std::to_string(static_cast<int>(result)) + ")."; break;
|
||||
}
|
||||
}
|
||||
if (charDeleteCallback_) charDeleteCallback_(success, msg);
|
||||
};
|
||||
dispatchTable_[Opcode::SMSG_CHAR_ENUM] = [this](network::Packet& packet) {
|
||||
if (state == WorldState::CHAR_LIST_REQUESTED)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue