Yo.
So I’ve been bothering the people on the IRC a lot and thanks to some devs (heads up especially to Nayd) I found two problems in my custom code. Let me briefly explain it.
I customized the player chat log to give more segmented, “cleaner” output.
I created a custom table containing 5 parts, which each fulfills a specific “holder position”. Everything is alright and I managed to get it to my personal preferences.
So far so well.
The problem comes with the escaping. The function sends it’s log like this:
“sLog->outChatNewDB(player->GetName().c_str(), “say”, “Null”, area : “Null”, msg.c_str());”
Meaning that it segments each log of the category “Say” as: “Player / “Say” / Message / “Null” / “Name of area” or “Null””.
It goes into an escaping function, namely:
void outChatNewDB(char const* name, char const* type, char const* toplayer, char const* area, char const* msg, …)
{
if (!msg)
return;
va_list ap2;
va_start(ap2, msg);
char nnew_str[MAX_QUERY_LEN];
vsnprintf(nnew_str, MAX_QUERY_LEN, msg, ap2);
va_end(ap2);
outToNewChatDB(name, type, toplayer, area, nnew_str);
}
void outToNewChatDB(char const* name, char const* type, char const* toplayer, char const* area, char const* nnew_str, …)
{
std::string logStr(nnew_str);
if (logStr.empty())
return;
PreparedStatement* stdb = CharacterDatabase.GetPreparedStatement(CHAR_INS_LOG_CHAT);
stdb->setString(0, name);
stdb->setString(1, type);
stdb->setString(2, toplayer);
stdb->setString(3, area);
stdb->setString(4, logStr);
CharacterDatabase.Execute(stdb);
}
Names are just figurative in here by the way. Denting may be terrible. It would work regulary, however, the problem is significant; “%” can cause the vsnprintf to interpret % as variable, which would mean it tries to get any value to insert. This is, as this is supposed to be a message system, not the case. → It crashes in vsnprintf. So I need a way to escape further than vsnprintf. As it is a char const* though, I can not use common used methods (e.g. UTf8toWstr). I need a way to escape % to %%.
My second problem is the most recent one. As you can see within the log, I want the area to be given out. I got this function:
std::string areaName = “”;
AreaTableEntry const* area = GetAreaEntryByAreaID(player->GetZoneId());
if (area)
{
areaName = std::string(area->area_name);
}
As GetAreaEntryByAreaID gives a whole lot of informations out, I would need to get “just the area_name”. That’s why if (area) is there. That does not work though. I guess it’s a simple mistake, however, maybe anyone can enlighten me ?
Anyone an idea ?