core: add clientless player GM test adapter
This commit is contained in:
1 parent
fe96d310d6
commit
7013087bcd
1 file changed
+114
-1
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include "ScriptMgr.h"
|
#include "ScriptMgr.h"
|
||||||
#include "Chat.h"
|
#include "Chat.h"
|
||||||
|
#include "DatabaseEnv.h"
|
||||||
#include "Creature.h"
|
#include "Creature.h"
|
||||||
#include "Group.h"
|
#include "Group.h"
|
||||||
#include "ObjectAccessor.h"
|
#include "ObjectAccessor.h"
|
||||||
@@ -20,7 +21,9 @@
|
|||||||
#include "RBAC.h"
|
#include "RBAC.h"
|
||||||
#include "TemporarySummon.h"
|
#include "TemporarySummon.h"
|
||||||
#include "Unit.h"
|
#include "Unit.h"
|
||||||
|
#include "World.h"
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace VianoBotCommands
|
namespace VianoBotCommands
|
||||||
@@ -571,6 +574,109 @@ namespace VianoBotCommands
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CLIENTLESS_PLAYER_CORE_C4_TEST_ADAPTER
|
||||||
|
// Temporary GM-only test surface for the generic clientless Player lifecycle.
|
||||||
|
// Final production GM commands will use a different command contract.
|
||||||
|
static bool ParseCharacterGuid(ChatHandler* handler, char const* args, uint32& characterGuid)
|
||||||
|
{
|
||||||
|
if (!args)
|
||||||
|
{
|
||||||
|
handler->SendSysMessage("Usage: .clientless login <characterGuid> or .clientless logout <characterGuid>");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (*args == ' ' || *args == '\t')
|
||||||
|
++args;
|
||||||
|
|
||||||
|
if (!*args)
|
||||||
|
{
|
||||||
|
handler->SendSysMessage("Usage: .clientless login <characterGuid> or .clientless logout <characterGuid>");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* end = nullptr;
|
||||||
|
unsigned long value = std::strtoul(args, &end, 10);
|
||||||
|
|
||||||
|
while (end && (*end == ' ' || *end == '\t'))
|
||||||
|
++end;
|
||||||
|
|
||||||
|
if (!value || !end || *end != '\0' || value > 0xFFFFFFFFul)
|
||||||
|
{
|
||||||
|
handler->SendSysMessage("characterGuid must be a non-zero numeric low GUID.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
characterGuid = uint32(value);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool HandleClientlessLogin(ChatHandler* handler, char const* args)
|
||||||
|
{
|
||||||
|
uint32 characterGuid = 0;
|
||||||
|
if (!ParseCharacterGuid(handler, args, characterGuid))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
QueryResult result = CharacterDatabase.PQuery(
|
||||||
|
"SELECT account, name FROM characters WHERE guid = %u",
|
||||||
|
characterGuid);
|
||||||
|
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
handler->PSendSysMessage(
|
||||||
|
"No character found for GUID %u.",
|
||||||
|
characterGuid);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Field* fields = result->Fetch();
|
||||||
|
uint32 accountId = fields[0].GetUInt32();
|
||||||
|
std::string characterName = fields[1].GetString();
|
||||||
|
|
||||||
|
if (!sWorld->CreateClientlessPlayerSession(accountId, characterGuid))
|
||||||
|
{
|
||||||
|
handler->PSendSysMessage(
|
||||||
|
"Clientless login failed for '%s' (GUID %u, account %u). Check worldserver log for the rejection reason.",
|
||||||
|
characterName.c_str(), characterGuid, accountId);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
handler->PSendSysMessage(
|
||||||
|
"Clientless login started for '%s' (GUID %u, account %u).",
|
||||||
|
characterName.c_str(), characterGuid, accountId);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool HandleClientlessLogout(ChatHandler* handler, char const* args)
|
||||||
|
{
|
||||||
|
uint32 characterGuid = 0;
|
||||||
|
if (!ParseCharacterGuid(handler, args, characterGuid))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
WorldSession* session = sWorld->FindClientlessSession(characterGuid);
|
||||||
|
if (!session)
|
||||||
|
{
|
||||||
|
handler->PSendSysMessage(
|
||||||
|
"No clientless session is registered for character GUID %u.",
|
||||||
|
characterGuid);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 accountId = session->GetAccountId();
|
||||||
|
|
||||||
|
if (!sWorld->RemoveClientlessSession(characterGuid))
|
||||||
|
{
|
||||||
|
handler->PSendSysMessage(
|
||||||
|
"Clientless logout failed for character GUID %u.",
|
||||||
|
characterGuid);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
handler->PSendSysMessage(
|
||||||
|
"Clientless session removed for character GUID %u (account %u).",
|
||||||
|
characterGuid, accountId);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
class VianoBotCommandScript : public CommandScript
|
class VianoBotCommandScript : public CommandScript
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -594,9 +700,16 @@ namespace VianoBotCommands
|
|||||||
{ "bot", rbac::RBAC_PERM_COMMAND_GM, false, nullptr, "", botCommands },
|
{ "bot", rbac::RBAC_PERM_COMMAND_GM, false, nullptr, "", botCommands },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static std::vector<ChatCommand> clientlessCommands =
|
||||||
|
{
|
||||||
|
{ "login", rbac::RBAC_PERM_COMMAND_GM, false, &HandleClientlessLogin, "" },
|
||||||
|
{ "logout", rbac::RBAC_PERM_COMMAND_GM, false, &HandleClientlessLogout, "" },
|
||||||
|
};
|
||||||
|
|
||||||
static std::vector<ChatCommand> commandTable =
|
static std::vector<ChatCommand> commandTable =
|
||||||
{
|
{
|
||||||
{ "viano", rbac::RBAC_PERM_COMMAND_GM, false, nullptr, "", vianoCommands },
|
{ "viano", rbac::RBAC_PERM_COMMAND_GM, false, nullptr, "", vianoCommands },
|
||||||
|
{ "clientless", rbac::RBAC_PERM_COMMAND_GM, false, nullptr, "", clientlessCommands },
|
||||||
};
|
};
|
||||||
|
|
||||||
return commandTable;
|
return commandTable;
|
||||||
|
|||||||
Reference in new issue
Block a user