[7411] Use similar localization classes for World::SendWorldText muti-line message.

This commit is contained in:
VladimirMangos 2009-03-08 12:30:56 +03:00
parent c9ca06a630
commit f42815f04b
4 changed files with 109 additions and 43 deletions

View file

@ -862,6 +862,27 @@ namespace MaNGOS
std::vector<WorldPacket*> i_data_cache; // 0 = default, i => i-1 locale index std::vector<WorldPacket*> i_data_cache; // 0 = default, i => i-1 locale index
}; };
// Prepare using Builder localized packets with caching and send to player
template<class Builder>
class LocalizedPacketListDo
{
public:
typedef std::vector<WorldPacket*> WorldPacketList;
explicit LocalizedPacketListDo(Builder& builder) : i_builder(builder) {}
~LocalizedPacketListDo()
{
for(size_t i = 0; i < i_data_cache.size(); ++i)
for(int j = 0; j < i_data_cache[i].size(); ++j)
delete i_data_cache[i][j];
}
void operator()( Player* p );
private:
Builder& i_builder;
std::vector<WorldPacketList> i_data_cache;
// 0 = default, i => i-1 locale index
};
#ifndef WIN32 #ifndef WIN32
template<> void PlayerRelocationNotifier::Visit<Creature>(CreatureMapType &); template<> void PlayerRelocationNotifier::Visit<Creature>(CreatureMapType &);

View file

@ -562,4 +562,28 @@ void MaNGOS::LocalizedPacketDo<Builder>::operator()( Player* p )
p->SendDirectMessage(data); p->SendDirectMessage(data);
} }
template<class Builder>
void MaNGOS::LocalizedPacketListDo<Builder>::operator()( Player* p )
{
uint32 loc_idx = p->GetSession()->GetSessionDbLocaleIndex();
uint32 cache_idx = loc_idx+1;
WorldPacketList* data_list;
// create if not cached yet
if(i_data_cache.size() < cache_idx+1 || i_data_cache[cache_idx].empty())
{
if(i_data_cache.size() < cache_idx+1)
i_data_cache.resize(cache_idx+1);
data_list = &i_data_cache[cache_idx];
i_builder(*data_list,loc_idx);
}
else
data_list = &i_data_cache[cache_idx];
for(size_t i = 0; i < data_list->size(); ++i)
p->SendDirectMessage((*data_list)[i]);
}
#endif // MANGOS_GRIDNOTIFIERSIMPL_H #endif // MANGOS_GRIDNOTIFIERSIMPL_H

View file

@ -21,7 +21,6 @@
*/ */
#include "Common.h" #include "Common.h"
//#include "WorldSocket.h"
#include "Database/DatabaseEnv.h" #include "Database/DatabaseEnv.h"
#include "Config/ConfigEnv.h" #include "Config/ConfigEnv.h"
#include "SystemConfig.h" #include "SystemConfig.h"
@ -2265,58 +2264,80 @@ void World::SendGlobalMessage(WorldPacket *packet, WorldSession *self, uint32 te
} }
} }
namespace MaNGOS
{
class WorldWorldTextBuilder
{
public:
typedef std::vector<WorldPacket*> WorldPacketList;
explicit WorldWorldTextBuilder(int32 textId, va_list* args = NULL) : i_textId(textId), i_args(args) {}
void operator()(WorldPacketList& data_list, int32 loc_idx)
{
char const* text = objmgr.GetMangosString(i_textId,loc_idx);
if(i_args)
{
// we need copy va_list before use or original va_list will corrupted
va_list ap;
va_copy(ap,*i_args);
char str [2048];
vsnprintf(str,2048,text, ap );
va_end(ap);
do_helper(data_list,&str[0]);
}
else
do_helper(data_list,(char*)text);
}
private:
char* lineFromMessage(char*& pos) { char* start = strtok(pos,"\n"); pos = NULL; return start; }
void do_helper(WorldPacketList& data_list, char* text)
{
char* pos = text;
while(char* line = lineFromMessage(pos))
{
WorldPacket* data = new WorldPacket();
uint32 lineLength = (line ? strlen(line) : 0) + 1;
data->Initialize(SMSG_MESSAGECHAT, 100); // guess size
*data << uint8(CHAT_MSG_SYSTEM);
*data << uint32(LANG_UNIVERSAL);
*data << uint64(0);
*data << uint32(0); // can be chat msg group or something
*data << uint64(0);
*data << uint32(lineLength);
*data << line;
*data << uint8(0);
data_list.push_back(data);
}
}
int32 i_textId;
va_list* i_args;
};
} // namespace MaNGOS
/// Send a System Message to all players (except self if mentioned) /// Send a System Message to all players (except self if mentioned)
void World::SendWorldText(int32 string_id, ...) void World::SendWorldText(int32 string_id, ...)
{ {
std::vector<std::vector<WorldPacket*> > data_cache; // 0 = default, i => i-1 locale index va_list ap;
va_start(ap, string_id);
MaNGOS::WorldWorldTextBuilder wt_builder(string_id, &ap);
MaNGOS::LocalizedPacketListDo<MaNGOS::WorldWorldTextBuilder> wt_do(wt_builder);
for(SessionMap::iterator itr = m_sessions.begin(); itr != m_sessions.end(); ++itr) for(SessionMap::iterator itr = m_sessions.begin(); itr != m_sessions.end(); ++itr)
{ {
if(!itr->second || !itr->second->GetPlayer() || !itr->second->GetPlayer()->IsInWorld() ) if(!itr->second || !itr->second->GetPlayer() || !itr->second->GetPlayer()->IsInWorld() )
continue; continue;
uint32 loc_idx = itr->second->GetSessionDbLocaleIndex(); wt_do(itr->second->GetPlayer());
uint32 cache_idx = loc_idx+1;
std::vector<WorldPacket*>* data_list;
// create if not cached yet
if(data_cache.size() < cache_idx+1 || data_cache[cache_idx].empty())
{
if(data_cache.size() < cache_idx+1)
data_cache.resize(cache_idx+1);
data_list = &data_cache[cache_idx];
char const* text = objmgr.GetMangosString(string_id,loc_idx);
char buf[1000];
va_list argptr;
va_start( argptr, string_id );
vsnprintf( buf,1000, text, argptr );
va_end( argptr );
char* pos = &buf[0];
while(char* line = ChatHandler::LineFromMessage(pos))
{
WorldPacket* data = new WorldPacket();
ChatHandler::FillMessageData(data, NULL, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, NULL, 0, line, NULL);
data_list->push_back(data);
}
}
else
data_list = &data_cache[cache_idx];
for(int i = 0; i < data_list->size(); ++i)
itr->second->SendPacket((*data_list)[i]);
} }
// free memory va_end(ap);
for(int i = 0; i < data_cache.size(); ++i)
for(int j = 0; j < data_cache[i].size(); ++j)
delete data_cache[i][j];
} }
/// DEPRICATED, only for debug purpose. Send a System Message to all players (except self if mentioned) /// DEPRICATED, only for debug purpose. Send a System Message to all players (except self if mentioned)

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__ #ifndef __REVISION_NR_H__
#define __REVISION_NR_H__ #define __REVISION_NR_H__
#define REVISION_NR "7410" #define REVISION_NR "7411"
#endif // __REVISION_NR_H__ #endif // __REVISION_NR_H__