Core/Scripts: Cached command definitions at first use to allow dynamic commands take security levels and help text from the database.
Core/Scripts: Removed unused function related to executing dynamic commands. Patch by Paradox --HG-- branch : trunk
This commit is contained in:
@@ -68,6 +68,26 @@ bool OldHandler(ChatHandler* chatHandler, const char* args)
|
|||||||
return (chatHandler->*F)(args);
|
return (chatHandler->*F)(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// get number of commands in table
|
||||||
|
static size_t getCommandTableSize(const ChatCommand* commands)
|
||||||
|
{
|
||||||
|
if (!commands)
|
||||||
|
return 0;
|
||||||
|
size_t count = 0;
|
||||||
|
while (commands[count].Name != NULL)
|
||||||
|
count++;
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
// append source command table to target, return number of appended commands
|
||||||
|
static size_t appendCommandTable(ChatCommand* target, const ChatCommand* source)
|
||||||
|
{
|
||||||
|
const size_t count = getCommandTableSize(source);
|
||||||
|
if (count)
|
||||||
|
memcpy(target, source, count * sizeof(ChatCommand));
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
ChatCommand * ChatHandler::getCommandTable()
|
ChatCommand * ChatHandler::getCommandTable()
|
||||||
{
|
{
|
||||||
static ChatCommand accountSetCommandTable[] =
|
static ChatCommand accountSetCommandTable[] =
|
||||||
@@ -812,10 +832,32 @@ ChatCommand * ChatHandler::getCommandTable()
|
|||||||
{ NULL, 0, false, NULL, "", NULL }
|
{ NULL, 0, false, NULL, "", NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// cache for commands, needed because some commands are loaded dynamically through ScriptMgr
|
||||||
|
// cache is never freed and will show as a memory leak in diagnostic tools
|
||||||
|
// can't use vector as vector storage is implementation-dependent, eg, there can be alignment gaps between elements
|
||||||
|
static ChatCommand* commandTableCache = 0;
|
||||||
|
|
||||||
if (load_command_table)
|
if (load_command_table)
|
||||||
{
|
{
|
||||||
load_command_table = false;
|
load_command_table = false;
|
||||||
|
|
||||||
|
{
|
||||||
|
// count total number of top-level commands
|
||||||
|
size_t total = getCommandTableSize(commandTable);
|
||||||
|
std::vector<ChatCommand*> const& dynamic = sScriptMgr.GetChatCommands();
|
||||||
|
for (std::vector<ChatCommand*>::const_iterator it = dynamic.begin(); it != dynamic.end(); ++it)
|
||||||
|
total += getCommandTableSize(*it);
|
||||||
|
total += 1; // ending zero
|
||||||
|
|
||||||
|
// cache top-level commands
|
||||||
|
commandTableCache = (ChatCommand*)malloc(sizeof(ChatCommand) * total);
|
||||||
|
memset(commandTableCache, 0, sizeof(ChatCommand) * total);
|
||||||
|
ACE_ASSERT(commandTableCache);
|
||||||
|
size_t added = appendCommandTable(commandTableCache, commandTable);
|
||||||
|
for (std::vector<ChatCommand*>::const_iterator it = dynamic.begin(); it != dynamic.end(); ++it)
|
||||||
|
added += appendCommandTable(commandTableCache + added, *it);
|
||||||
|
}
|
||||||
|
|
||||||
QueryResult result = WorldDatabase.Query("SELECT name,security,help FROM command");
|
QueryResult result = WorldDatabase.Query("SELECT name,security,help FROM command");
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
@@ -824,13 +866,13 @@ ChatCommand * ChatHandler::getCommandTable()
|
|||||||
Field *fields = result->Fetch();
|
Field *fields = result->Fetch();
|
||||||
std::string name = fields[0].GetString();
|
std::string name = fields[0].GetString();
|
||||||
|
|
||||||
SetDataForCommandInTable(commandTable, name.c_str(), fields[1].GetUInt16(), fields[2].GetString(), name);
|
SetDataForCommandInTable(commandTableCache, name.c_str(), fields[1].GetUInt16(), fields[2].GetString(), name);
|
||||||
|
|
||||||
} while (result->NextRow());
|
} while (result->NextRow());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return commandTable;
|
return commandTableCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *ChatHandler::GetTrinityString(int32 entry) const
|
const char *ChatHandler::GetTrinityString(int32 entry) const
|
||||||
@@ -997,15 +1039,6 @@ void ChatHandler::PSendSysMessage(const char *format, ...)
|
|||||||
SendSysMessage(str);
|
SendSysMessage(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ChatHandler::ExecuteCommandInTables(std::vector<ChatCommand*> const& tables, const char* text, const std::string& fullcmd)
|
|
||||||
{
|
|
||||||
for (std::vector<ChatCommand*>::const_iterator it = tables.begin(); it != tables.end(); ++it)
|
|
||||||
if (ExecuteCommandInTable((*it), text, fullcmd))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ChatHandler::ExecuteCommandInTable(ChatCommand *table, const char* text, const std::string& fullcmd)
|
bool ChatHandler::ExecuteCommandInTable(ChatCommand *table, const char* text, const std::string& fullcmd)
|
||||||
{
|
{
|
||||||
char const* oldtext = text;
|
char const* oldtext = text;
|
||||||
@@ -1162,16 +1195,12 @@ int ChatHandler::ParseCommands(const char* text)
|
|||||||
++text;
|
++text;
|
||||||
|
|
||||||
if (!ExecuteCommandInTable(getCommandTable(), text, fullcmd))
|
if (!ExecuteCommandInTable(getCommandTable(), text, fullcmd))
|
||||||
{
|
|
||||||
std::vector<ChatCommand*> const& tables = sScriptMgr.GetChatCommands();
|
|
||||||
if (!ExecuteCommandInTables(tables, text, fullcmd))
|
|
||||||
{
|
{
|
||||||
if (m_session && m_session->GetSecurity() == SEC_PLAYER)
|
if (m_session && m_session->GetSecurity() == SEC_PLAYER)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
SendSysMessage(LANG_NO_CMD);
|
SendSysMessage(LANG_NO_CMD);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -98,7 +98,6 @@ class ChatHandler
|
|||||||
void SendGlobalGMSysMessage(const char *str);
|
void SendGlobalGMSysMessage(const char *str);
|
||||||
|
|
||||||
static bool SetDataForCommandInTable(ChatCommand *table, const char* text, uint32 security, std::string const& help, std::string const& fullcommand);
|
static bool SetDataForCommandInTable(ChatCommand *table, const char* text, uint32 security, std::string const& help, std::string const& fullcommand);
|
||||||
bool ExecuteCommandInTables(std::vector<ChatCommand*> const& tables, const char* text, const std::string& fullcmd);
|
|
||||||
bool ExecuteCommandInTable(ChatCommand *table, const char* text, const std::string& fullcmd);
|
bool ExecuteCommandInTable(ChatCommand *table, const char* text, const std::string& fullcmd);
|
||||||
bool ShowHelpForCommand(ChatCommand *table, const char* cmd);
|
bool ShowHelpForCommand(ChatCommand *table, const char* cmd);
|
||||||
bool ShowHelpForSubCommands(ChatCommand *table, char const* cmd, char const* subcmd);
|
bool ShowHelpForSubCommands(ChatCommand *table, char const* cmd, char const* subcmd);
|
||||||
|
|||||||
Reference in New Issue
Block a user