A customized Log system - crash on %, problem with Areaname

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 ?