aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSpp <none@none>2010-11-03 08:35:48 +0100
committerSpp <none@none>2010-11-03 08:35:48 +0100
commit43a5a3ced1d5feb7028487b2694a8eb33702bef8 (patch)
tree2129c0bbc704f9a49e1c85f7c1fb0266c6d95859
parent38ae2062d925145e69c6d1b1dab4e0aaa3973d7d (diff)
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
-rwxr-xr-xsrc/server/game/Chat/Chat.cpp65
-rwxr-xr-xsrc/server/game/Chat/Chat.h1
2 files changed, 47 insertions, 19 deletions
diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp
index 6bc7e5997c0..bba11c08b22 100755
--- a/src/server/game/Chat/Chat.cpp
+++ b/src/server/game/Chat/Chat.cpp
@@ -68,6 +68,26 @@ bool OldHandler(ChatHandler* chatHandler, const char* 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()
{
static ChatCommand accountSetCommandTable[] =
@@ -812,10 +832,32 @@ ChatCommand * ChatHandler::getCommandTable()
{ 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)
{
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");
if (result)
{
@@ -824,13 +866,13 @@ ChatCommand * ChatHandler::getCommandTable()
Field *fields = result->Fetch();
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());
}
}
- return commandTable;
+ return commandTableCache;
}
const char *ChatHandler::GetTrinityString(int32 entry) const
@@ -997,15 +1039,6 @@ void ChatHandler::PSendSysMessage(const char *format, ...)
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)
{
char const* oldtext = text;
@@ -1163,14 +1196,10 @@ int ChatHandler::ParseCommands(const char* text)
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)
- return 0;
+ if (m_session && m_session->GetSecurity() == SEC_PLAYER)
+ return 0;
- SendSysMessage(LANG_NO_CMD);
- }
+ SendSysMessage(LANG_NO_CMD);
}
return 1;
}
diff --git a/src/server/game/Chat/Chat.h b/src/server/game/Chat/Chat.h
index 2ec1bf2e39b..90a8a06125e 100755
--- a/src/server/game/Chat/Chat.h
+++ b/src/server/game/Chat/Chat.h
@@ -98,7 +98,6 @@ class ChatHandler
void SendGlobalGMSysMessage(const char *str);
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 ShowHelpForCommand(ChatCommand *table, const char* cmd);
bool ShowHelpForSubCommands(ChatCommand *table, char const* cmd, char const* subcmd);