2008-08-27 19:41:02 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
#include <engine/graphics.h>
|
|
|
|
#include <engine/textrender.h>
|
|
|
|
#include <engine/keys.h>
|
|
|
|
#include <engine/shared/config.h>
|
2008-08-27 15:48:50 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
#include <game/generated/protocol.h>
|
|
|
|
#include <game/generated/client_data.h>
|
2008-08-27 15:48:50 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
#include <game/client/gameclient.h>
|
2008-08-29 05:34:18 +00:00
|
|
|
|
2010-08-18 01:57:35 +00:00
|
|
|
#include <game/client/components/scoreboard.h>
|
2010-05-29 07:25:38 +00:00
|
|
|
#include <game/client/components/sounds.h>
|
|
|
|
#include <game/localization.h>
|
2008-08-27 15:48:50 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
#include "chat.h"
|
|
|
|
|
|
|
|
|
|
|
|
CChat::CChat()
|
2008-08-27 15:48:50 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
OnReset();
|
|
|
|
}
|
|
|
|
|
|
|
|
void CChat::OnReset()
|
|
|
|
{
|
|
|
|
for(int i = 0; i < MAX_LINES; i++)
|
2009-05-31 09:44:20 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
m_aLines[i].m_Time = 0;
|
|
|
|
m_aLines[i].m_aText[0] = 0;
|
|
|
|
m_aLines[i].m_aName[0] = 0;
|
|
|
|
}
|
2010-05-30 12:01:11 +00:00
|
|
|
|
|
|
|
m_Show = false;
|
2010-10-11 00:29:30 +00:00
|
|
|
m_InputUpdate = false;
|
|
|
|
m_ChatStringOffset = 0;
|
2010-05-29 07:25:38 +00:00
|
|
|
}
|
|
|
|
|
2010-09-12 10:43:03 +00:00
|
|
|
void CChat::OnRelease()
|
|
|
|
{
|
|
|
|
m_Show = false;
|
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CChat::OnStateChange(int NewState, int OldState)
|
|
|
|
{
|
|
|
|
if(OldState <= IClient::STATE_CONNECTING)
|
|
|
|
{
|
|
|
|
m_Mode = MODE_NONE;
|
2009-05-31 09:44:20 +00:00
|
|
|
for(int i = 0; i < MAX_LINES; i++)
|
2010-05-29 07:25:38 +00:00
|
|
|
m_aLines[i].m_Time = 0;
|
|
|
|
m_CurrentLine = 0;
|
2009-05-31 09:44:20 +00:00
|
|
|
}
|
2008-08-27 15:48:50 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CChat::ConSay(IConsole::IResult *pResult, void *pUserData)
|
2008-08-27 19:41:02 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
((CChat*)pUserData)->Say(0, pResult->GetString(0));
|
2008-08-27 19:41:02 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CChat::ConSayTeam(IConsole::IResult *pResult, void *pUserData)
|
2008-08-27 19:41:02 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
((CChat*)pUserData)->Say(1, pResult->GetString(0));
|
2008-08-27 19:41:02 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CChat::ConChat(IConsole::IResult *pResult, void *pUserData)
|
2008-08-27 19:41:02 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
const char *pMode = pResult->GetString(0);
|
|
|
|
if(str_comp(pMode, "all") == 0)
|
|
|
|
((CChat*)pUserData)->EnableMode(0);
|
|
|
|
else if(str_comp(pMode, "team") == 0)
|
|
|
|
((CChat*)pUserData)->EnableMode(1);
|
2008-08-27 19:41:02 +00:00
|
|
|
else
|
2010-08-17 22:06:00 +00:00
|
|
|
((CChat*)pUserData)->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "console", "expected all or team as mode");
|
2008-08-27 19:41:02 +00:00
|
|
|
}
|
|
|
|
|
2010-05-30 12:01:11 +00:00
|
|
|
void CChat::ConShowChat(IConsole::IResult *pResult, void *pUserData)
|
|
|
|
{
|
|
|
|
((CChat *)pUserData)->m_Show = pResult->GetInteger(0) != 0;
|
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CChat::OnConsoleInit()
|
2008-08-27 19:41:02 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
Console()->Register("say", "r", CFGFLAG_CLIENT, ConSay, this, "Say in chat");
|
|
|
|
Console()->Register("say_team", "r", CFGFLAG_CLIENT, ConSayTeam, this, "Say in team chat");
|
|
|
|
Console()->Register("chat", "s", CFGFLAG_CLIENT, ConChat, this, "Enable chat with all/team mode");
|
2010-05-30 12:01:11 +00:00
|
|
|
Console()->Register("+show_chat", "", CFGFLAG_CLIENT, ConShowChat, this, "Show chat");
|
2008-08-27 19:41:02 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
bool CChat::OnInput(IInput::CEvent e)
|
2008-08-27 15:48:50 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
if(m_Mode == MODE_NONE)
|
2008-08-27 15:48:50 +00:00
|
|
|
return false;
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
if(e.m_Flags&IInput::FLAG_PRESS && e.m_Key == KEY_ESCAPE)
|
2010-09-12 10:43:03 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
m_Mode = MODE_NONE;
|
2010-09-12 10:43:03 +00:00
|
|
|
m_pClient->OnRelease();
|
|
|
|
}
|
2010-05-29 07:25:38 +00:00
|
|
|
else if(e.m_Flags&IInput::FLAG_PRESS && (e.m_Key == KEY_RETURN || e.m_Key == KEY_KP_ENTER))
|
2008-08-27 15:48:50 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
if(m_Input.GetString()[0])
|
|
|
|
Say(m_Mode == MODE_ALL ? 0 : 1, m_Input.GetString());
|
|
|
|
m_Mode = MODE_NONE;
|
2010-09-12 10:43:03 +00:00
|
|
|
m_pClient->OnRelease();
|
2008-08-27 15:48:50 +00:00
|
|
|
}
|
|
|
|
else
|
2010-10-11 00:29:30 +00:00
|
|
|
{
|
2010-10-11 10:31:45 +00:00
|
|
|
m_OldChatStringLength = m_Input.GetLength();
|
2010-05-29 07:25:38 +00:00
|
|
|
m_Input.ProcessInput(e);
|
2010-10-11 00:29:30 +00:00
|
|
|
m_InputUpdate = true;
|
|
|
|
}
|
2008-08-27 15:48:50 +00:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CChat::EnableMode(int Team)
|
2008-08-27 15:48:50 +00:00
|
|
|
{
|
2010-09-07 18:01:51 +00:00
|
|
|
if(Client()->State() == IClient::STATE_DEMOPLAYBACK)
|
|
|
|
return;
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
if(m_Mode == MODE_NONE)
|
2008-08-27 15:48:50 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
if(Team)
|
|
|
|
m_Mode = MODE_TEAM;
|
2008-08-27 15:48:50 +00:00
|
|
|
else
|
2010-05-29 07:25:38 +00:00
|
|
|
m_Mode = MODE_ALL;
|
2008-08-27 15:48:50 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
m_Input.Clear();
|
|
|
|
Input()->ClearEvents();
|
2008-08-27 15:48:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CChat::OnMessage(int MsgType, void *pRawMsg)
|
2008-08-27 15:48:50 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
if(MsgType == NETMSGTYPE_SV_CHAT)
|
2008-08-27 15:48:50 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
CNetMsg_Sv_Chat *pMsg = (CNetMsg_Sv_Chat *)pRawMsg;
|
|
|
|
AddLine(pMsg->m_Cid, pMsg->m_Team, pMsg->m_pMessage);
|
2008-08-27 15:48:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CChat::AddLine(int ClientId, int Team, const char *pLine)
|
2008-08-27 15:48:50 +00:00
|
|
|
{
|
2010-09-06 10:32:41 +00:00
|
|
|
if(ClientId != -1 && m_pClient->m_aClients[ClientId].m_aName[0] == '\0') // unknown client
|
|
|
|
return;
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
char *p = const_cast<char*>(pLine);
|
|
|
|
while(*p)
|
2008-08-27 15:48:50 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
pLine = p;
|
|
|
|
// find line seperator and strip multiline
|
|
|
|
while(*p)
|
|
|
|
{
|
|
|
|
if(*p++ == '\n')
|
|
|
|
{
|
|
|
|
*(p-1) = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2008-08-27 15:48:50 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
m_CurrentLine = (m_CurrentLine+1)%MAX_LINES;
|
|
|
|
m_aLines[m_CurrentLine].m_Time = time_get();
|
|
|
|
m_aLines[m_CurrentLine].m_ClientId = ClientId;
|
|
|
|
m_aLines[m_CurrentLine].m_Team = Team;
|
|
|
|
m_aLines[m_CurrentLine].m_NameColor = -2;
|
|
|
|
|
|
|
|
if(ClientId == -1) // server message
|
|
|
|
{
|
|
|
|
str_copy(m_aLines[m_CurrentLine].m_aName, "*** ", sizeof(m_aLines[m_CurrentLine].m_aName));
|
|
|
|
str_format(m_aLines[m_CurrentLine].m_aText, sizeof(m_aLines[m_CurrentLine].m_aText), "%s", pLine);
|
|
|
|
}
|
|
|
|
else
|
2008-08-27 15:48:50 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
if(m_pClient->m_aClients[ClientId].m_Team == -1)
|
|
|
|
m_aLines[m_CurrentLine].m_NameColor = -1;
|
|
|
|
|
|
|
|
if(m_pClient->m_Snap.m_pGameobj && m_pClient->m_Snap.m_pGameobj->m_Flags&GAMEFLAG_TEAMS)
|
|
|
|
{
|
|
|
|
if(m_pClient->m_aClients[ClientId].m_Team == 0)
|
|
|
|
m_aLines[m_CurrentLine].m_NameColor = 0;
|
|
|
|
else if(m_pClient->m_aClients[ClientId].m_Team == 1)
|
|
|
|
m_aLines[m_CurrentLine].m_NameColor = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
str_copy(m_aLines[m_CurrentLine].m_aName, m_pClient->m_aClients[ClientId].m_aName, sizeof(m_aLines[m_CurrentLine].m_aName));
|
|
|
|
str_format(m_aLines[m_CurrentLine].m_aText, sizeof(m_aLines[m_CurrentLine].m_aText), ": %s", pLine);
|
2008-08-27 15:48:50 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
char aBuf[1024];
|
2010-08-17 22:06:00 +00:00
|
|
|
str_format(aBuf, sizeof(aBuf), "%s%s", m_aLines[m_CurrentLine].m_aName, m_aLines[m_CurrentLine].m_aText);
|
|
|
|
Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "chat", aBuf);
|
2008-08-27 15:48:50 +00:00
|
|
|
}
|
2010-05-29 07:25:38 +00:00
|
|
|
|
2009-06-15 13:01:04 +00:00
|
|
|
// play sound
|
2010-05-29 07:25:38 +00:00
|
|
|
if(ClientId >= 0)
|
|
|
|
m_pClient->m_pSounds->Play(CSounds::CHN_GUI, SOUND_CHAT_CLIENT, 0, vec2(0,0));
|
2009-06-15 13:01:04 +00:00
|
|
|
else
|
2010-05-29 07:25:38 +00:00
|
|
|
m_pClient->m_pSounds->Play(CSounds::CHN_GUI, SOUND_CHAT_SERVER, 0, vec2(0,0));
|
2008-08-27 15:48:50 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CChat::OnRender()
|
2008-08-27 15:48:50 +00:00
|
|
|
{
|
2009-10-27 14:38:53 +00:00
|
|
|
Graphics()->MapScreen(0,0,300*Graphics()->ScreenAspect(),300);
|
2008-08-27 15:48:50 +00:00
|
|
|
float x = 10.0f;
|
2008-09-07 08:44:30 +00:00
|
|
|
float y = 300.0f-20.0f;
|
2010-05-29 07:25:38 +00:00
|
|
|
if(m_Mode != MODE_NONE)
|
2008-08-27 15:48:50 +00:00
|
|
|
{
|
|
|
|
// render chat input
|
2010-05-29 07:25:38 +00:00
|
|
|
CTextCursor Cursor;
|
|
|
|
TextRender()->SetCursor(&Cursor, x, y, 8.0f, TEXTFLAG_RENDER);
|
|
|
|
Cursor.m_LineWidth = 200.0f;
|
2010-10-11 00:29:30 +00:00
|
|
|
Cursor.m_MaxLines = 2;
|
2008-08-27 15:48:50 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
if(m_Mode == MODE_ALL)
|
|
|
|
TextRender()->TextEx(&Cursor, Localize("All"), -1);
|
|
|
|
else if(m_Mode == MODE_TEAM)
|
|
|
|
TextRender()->TextEx(&Cursor, Localize("Team"), -1);
|
2008-08-27 15:48:50 +00:00
|
|
|
else
|
2010-05-29 07:25:38 +00:00
|
|
|
TextRender()->TextEx(&Cursor, Localize("Chat"), -1);
|
2009-06-15 07:34:25 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
TextRender()->TextEx(&Cursor, ": ", -1);
|
2008-08-27 15:48:50 +00:00
|
|
|
|
2010-10-11 00:29:30 +00:00
|
|
|
// check if the visible text has to be moved
|
|
|
|
if(m_InputUpdate)
|
|
|
|
{
|
2010-10-11 10:31:45 +00:00
|
|
|
if(m_ChatStringOffset > 0 && m_Input.GetLength() < m_OldChatStringLength)
|
|
|
|
m_ChatStringOffset = max(0, m_ChatStringOffset-(m_OldChatStringLength-m_Input.GetLength()));
|
|
|
|
|
2010-10-11 00:29:30 +00:00
|
|
|
if(m_ChatStringOffset > m_Input.GetCursorOffset())
|
2010-10-11 10:31:45 +00:00
|
|
|
m_ChatStringOffset -= m_ChatStringOffset-m_Input.GetCursorOffset();
|
2010-10-11 00:29:30 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
CTextCursor Temp = Cursor;
|
|
|
|
Temp.m_Flags = 0;
|
|
|
|
TextRender()->TextEx(&Temp, m_Input.GetString()+m_ChatStringOffset, m_Input.GetCursorOffset()-m_ChatStringOffset);
|
|
|
|
TextRender()->TextEx(&Temp, "|", -1);
|
2010-10-11 10:31:45 +00:00
|
|
|
while(Temp.m_LineCount > 2)
|
|
|
|
{
|
2010-10-11 00:29:30 +00:00
|
|
|
++m_ChatStringOffset;
|
2010-10-11 10:31:45 +00:00
|
|
|
Temp = Cursor;
|
|
|
|
Temp.m_Flags = 0;
|
|
|
|
TextRender()->TextEx(&Temp, m_Input.GetString()+m_ChatStringOffset, m_Input.GetCursorOffset()-m_ChatStringOffset);
|
|
|
|
TextRender()->TextEx(&Temp, "|", -1);
|
|
|
|
}
|
2010-10-11 00:29:30 +00:00
|
|
|
}
|
2010-10-11 10:31:45 +00:00
|
|
|
m_InputUpdate = false;
|
2010-10-11 00:29:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TextRender()->TextEx(&Cursor, m_Input.GetString()+m_ChatStringOffset, m_Input.GetCursorOffset()-m_ChatStringOffset);
|
2010-05-29 07:25:38 +00:00
|
|
|
CTextCursor Marker = Cursor;
|
|
|
|
TextRender()->TextEx(&Marker, "|", -1);
|
|
|
|
TextRender()->TextEx(&Cursor, m_Input.GetString()+m_Input.GetCursorOffset(), -1);
|
2008-08-27 15:48:50 +00:00
|
|
|
}
|
|
|
|
|
2010-08-16 00:21:18 +00:00
|
|
|
y -= 8.0f;
|
2008-08-27 15:48:50 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
int64 Now = time_get();
|
2010-09-06 15:04:10 +00:00
|
|
|
float LineWidth = m_pClient->m_pScoreboard->Active() ? 95.0f : 200.0f;
|
|
|
|
float HeightLimit = m_pClient->m_pScoreboard->Active() ? 220.0f : m_Show ? 50.0f : 200.0f;
|
2010-08-18 01:57:35 +00:00
|
|
|
for(int i = 0; i < MAX_LINES; i++)
|
2008-08-27 15:48:50 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
int r = ((m_CurrentLine-i)+MAX_LINES)%MAX_LINES;
|
2010-05-30 12:01:11 +00:00
|
|
|
if(Now > m_aLines[r].m_Time+15*time_freq() && !m_Show)
|
2008-08-27 15:48:50 +00:00
|
|
|
break;
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
float Begin = x;
|
2010-05-30 17:08:54 +00:00
|
|
|
float FontSize = 6.0f;
|
2008-08-27 15:48:50 +00:00
|
|
|
|
|
|
|
// get the y offset
|
2010-05-29 07:25:38 +00:00
|
|
|
CTextCursor Cursor;
|
|
|
|
TextRender()->SetCursor(&Cursor, Begin, 0, FontSize, 0);
|
2010-08-18 01:57:35 +00:00
|
|
|
Cursor.m_LineWidth = LineWidth;
|
2010-05-29 07:25:38 +00:00
|
|
|
TextRender()->TextEx(&Cursor, m_aLines[r].m_aName, -1);
|
|
|
|
TextRender()->TextEx(&Cursor, m_aLines[r].m_aText, -1);
|
|
|
|
y -= Cursor.m_Y + Cursor.m_FontSize;
|
2008-08-27 15:48:50 +00:00
|
|
|
|
2008-09-07 08:44:30 +00:00
|
|
|
// cut off if msgs waste too much space
|
2010-05-30 12:01:11 +00:00
|
|
|
if(y < HeightLimit)
|
2008-09-07 08:44:30 +00:00
|
|
|
break;
|
|
|
|
|
2008-08-27 15:48:50 +00:00
|
|
|
// reset the cursor
|
2010-05-29 07:25:38 +00:00
|
|
|
TextRender()->SetCursor(&Cursor, Begin, y, FontSize, TEXTFLAG_RENDER);
|
2010-08-18 01:57:35 +00:00
|
|
|
Cursor.m_LineWidth = LineWidth;
|
2008-08-27 15:48:50 +00:00
|
|
|
|
|
|
|
// render name
|
2010-05-29 07:25:38 +00:00
|
|
|
TextRender()->TextColor(0.8f,0.8f,0.8f,1);
|
|
|
|
if(m_aLines[r].m_ClientId == -1)
|
|
|
|
TextRender()->TextColor(1,1,0.5f,1); // system
|
|
|
|
else if(m_aLines[r].m_Team)
|
|
|
|
TextRender()->TextColor(0.45f,0.9f,0.45f,1); // team message
|
|
|
|
else if(m_aLines[r].m_NameColor == 0)
|
|
|
|
TextRender()->TextColor(1.0f,0.5f,0.5f,1); // red
|
|
|
|
else if(m_aLines[r].m_NameColor == 1)
|
|
|
|
TextRender()->TextColor(0.7f,0.7f,1.0f,1); // blue
|
|
|
|
else if(m_aLines[r].m_NameColor == -1)
|
|
|
|
TextRender()->TextColor(0.75f,0.5f,0.75f, 1); // spectator
|
2008-08-27 15:48:50 +00:00
|
|
|
|
|
|
|
// render name
|
2010-05-29 07:25:38 +00:00
|
|
|
TextRender()->TextEx(&Cursor, m_aLines[r].m_aName, -1);
|
2008-08-27 15:48:50 +00:00
|
|
|
|
|
|
|
// render line
|
2010-05-29 07:25:38 +00:00
|
|
|
TextRender()->TextColor(1,1,1,1);
|
|
|
|
if(m_aLines[r].m_ClientId == -1)
|
|
|
|
TextRender()->TextColor(1,1,0.5f,1); // system
|
|
|
|
else if(m_aLines[r].m_Team)
|
|
|
|
TextRender()->TextColor(0.65f,1,0.65f,1); // team message
|
2008-08-27 15:48:50 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
TextRender()->TextEx(&Cursor, m_aLines[r].m_aText, -1);
|
2008-08-27 15:48:50 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
TextRender()->TextColor(1,1,1,1);
|
2008-08-27 15:48:50 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CChat::Say(int Team, const char *pLine)
|
2008-08-27 15:48:50 +00:00
|
|
|
{
|
|
|
|
// send chat message
|
2010-05-29 07:25:38 +00:00
|
|
|
CNetMsg_Cl_Say Msg;
|
|
|
|
Msg.m_Team = Team;
|
|
|
|
Msg.m_pMessage = pLine;
|
|
|
|
Client()->SendPackMsg(&Msg, MSGFLAG_VITAL);
|
2008-08-27 15:48:50 +00:00
|
|
|
}
|