Files
Leviathan/Client/Game/game/Interface/SUIChattingWnd.cpp
T
2026-06-01 12:46:52 +02:00

3800 lines
106 KiB
C++

#include "stdafx.h"
#include "KUITabControl.h"
#include "KUIControlEdit.h"
#include "KUIControlStatic.h"
#include "KUIControlScroll.h"
#include "KUIControlButton.h"
#include "SGameManager.h"
#include "SGameMessage.h"
//#include "SGameMessageUI.h"
#include "SUIChattingWnd.h"
#include "SUIDisplayInfo.h"
#include "SUISysMsgDefine.h"
#include <toolkit/XStringUtil.h> // by Testors
#include <toolkit/nsl.h>
#include <toolkit/nsluni.h>
#include "SStringDB.h"
#include "ErrorCode/ErrorCode.h"
#include "SGameOption.h"
#include "SPlayerInfoMgr.h"
#include <kfile/KFileManager.h>
#include "SChatType.h"
#include <toolkit/XEnv.h>
#include "SDebug_Util.h"
#include "SMessengerMgr.h"
#include "Slog.h"
/// 2010.11.10 - prodongi
#include "SGameLobbyDefine.h"
/// 2010.11.15 - prodongi
#include <fstream>
#include "SGameSystem.h"
#include "SGameAvatarEx.h"
#include "sgame.h"
#include "SItemDB.h"
#include "SNpcResourceDB.h"
#include "SGameOption.h"
extern SGameSystem * g_pCurrentGameSystem;
bool g_GMDEV = FALSE;
// 2010.09.02 - prodongi
namespace AutoMsg
{
// 2010.09.02 - prodongi
std::string makeKey(int msgId, AR_HANDLE itemHandle)
{
static char temp[32];
sprintf(temp, "%d_%u", msgId, itemHandle);
return temp;
}
// 2010.09.02 - prodongi
std::string makeKey(AutoMsgInfo const* msgInfo)
{
return makeKey(msgInfo->m_nSystemMsg, msgInfo->m_hItem);
}
}
namespace
{
const int c_nEditLimit = 170;
const int c_nCategoryEditLimit = 20;
const int c_nAddLine = 14;
const int c_nLineHeight = 12;
const int c_nLineDelta = 2;
const int c_nMaxChatHistory = 300;
const int c_nWndMaxHeight = 570;
const int c_nTabClickArea = 9;
enum {
KIND_ALLMSG = 0,
KIND_WHISPER, //1
KIND_PARTY, //2
KIND_GUILD, //3
KIND_AD, //4
KIND_SIEGE, //5
};
const char szParty[2] = "#" ;
const char szGuild[2] = "%" ;
const char szAd[2] = "$" ;
const char szWhisper[2] = "\"";
const char szYell[2] = "!" ;
const char szSiege[2] = "'" ;
const int c_nWhisperMaxUser = 3;
const int c_nChatSpase = 7;
enum CHAT_OPTION
{
//=================================
CHAT_CHECK_00 = 0, //사용자 채팅
//
CHAT_CHECK_01, //일반 채팅
CHAT_CHECK_02, //외치기
CHAT_CHECK_03, //광고
CHAT_CHECK_04, //귓속말
CHAT_CHECK_05, //친한 귓속말
//=================================
CHAT_CHECK_06, //그룹 채팅
//
CHAT_CHECK_07, //파티 채팅
CHAT_CHECK_08, //길드 채팅
CHAT_CHECK_09, //공대 채팅
//=================================
CHAT_CHECK_10, //시스템 메시지
CHAT_CHECK_11, //경험치
CHAT_CHECK_12, //NPC 관련
CHAT_CHECK_13, //기본 데미지
CHAT_CHECK_14, //스킬 데미지
CHAT_CHECK_15, //아이템 관련
CHAT_CHECK_16, //전투 상황
CHAT_CHECK_17, //크리쳐 관련
CHAT_CHECK_18, //기타
};
const short c_nFillterTagCnt = 12;
const char* c_szFillterTag[] =
{
"<BR>" ,//01
"<br>" ,//02
"<P>" ,//03
"<p>" ,//04
"<B>" ,//05
"<b>" ,//06
"<U>" ,//07
"<u>" ,//08
"<STRIKE>" ,//09
"<strike>" ,//10
"<INV>" ,//11
"<inv>" ,//12
};
/*
const char* c_szlowerframe01 = "lowerframe01";
const char* c_szbutton_set = "button_set";
const char* c_szchat_edit = "chat_edit";
const char* c_szchat_string = "chat_string";
const char* c_szbutton_Type = "button_Type";
*/
const AR_TIME c_ar15Minutes = 100*60*15;
const AR_TIME c_ar30Minutes = 100*60*30;
const AR_TIME c_ar1Hour = 100*60*60;
const AR_TIME c_ar2Hour = c_ar1Hour*2;
const AR_TIME c_ar3Hour = c_ar1Hour*3;
const AR_TIME c_ar4Hour = c_ar1Hour*4;
const AR_TIME c_ar5Hour = c_ar1Hour*5;
}
using namespace AutoMsg;
extern HWND g_hWnd;
extern bool g_bDefSet[SGAME_OPT_DATA::c_nMaxChannel][SGAME_OPT_DATA::c_nMaxChatOption];
extern void MsgSplit( const char* szMsg, std::vector<std::string>& vecText, const wchar_t* lpDelimiter, bool bProcSpecialCharacter=false );
SUIChattingWnd::~SUIChattingWnd()
{
FreeList();
CloseHandle( m_hChatLog );
}
SUIWnd* SUIChattingWnd::CreateWnd( const char* szFile, KUIWndManager* pWndManager, KPoint kPos, int nWindowID )
{
KStream* pStream = KFileManager::Instance().CreateStreamFromResource( szFile );
if( pStream )
{
SetGenWndAniName( "button_chat_size", GENWND_RESIZE );
Create( *pStream, pWndManager );
InitControls( KPoint(0,529) );
m_nWindowID = nWindowID;
}
KFileManager::Instance().DeleteStream( pStream );
return this;
}
bool SUIChattingWnd::InitControls( KPoint kPos )
{
#ifdef _DEV_CHAT
SetCustomMovingRect( KRect( 16, 0, 425, 96 ) );
#endif
// 에디트 박스 리밋
KUIControlEdit* pEdit = NULL;
if( (pEdit = dynamicCast<KUIControlEdit*>(GetChild("chat_edit"))) )
{
pEdit->SetLimitation(c_nEditLimit);
pEdit->SetLineChange( true );
pEdit->SetText("");
pEdit->SetCaption("");
pEdit->UseEmoticonFilter( false );
}
// 리사이즈 설정
KRect rtChat = GetRect();
KSize szMin, szMax;
rtChat.bottom = rtChat.GetHeight(); rtChat.top = 0;
szMin.cx = rtChat.right - rtChat.left;
szMin.cy = ( rtChat.bottom - rtChat.top ) - ( c_nLineHeight + c_nLineDelta );
szMax.cx = rtChat.right - rtChat.left;
szMax.cy = c_nWndMaxHeight;
SetResizeUnit( 0, c_nLineHeight+c_nLineDelta, szMin, szMax );
CreateStatic();
CreateTab();
SetChildShow( "background", false );
SetChildShow( "chat_scroll", false );
SetChildShow( "_Resize", false );
KUIWnd* pWnd(NULL);
pWnd = GetChild("background");
if( pWnd ) pWnd->ChangeAlpha(0.f);
pWnd = GetChild("chat_scroll");
if( pWnd ) pWnd->ChangeAlpha(0.f);
pWnd = GetChild("_Resize");
if( pWnd ) pWnd->ChangeAlpha(0.f);
SetChildAsTop( "chat_tab" );
SetChildAsTop( "chat_edit" );
SetChildShow( "chat_string", false );
pWnd = GetChild("chat_string"); //IME
if( pWnd ) pWnd->ChangeAlpha(0.f);
SetCorrectionRect( KRect(0,0,0,0) );
KUIWnd* pTabWnd = GetChild("chat_tab");
if( pTabWnd ) pTabWnd->SetShow(false);
if( ENV().GetString("chat_mode") == "mode0" )
m_nChattingMode = 0;
else if( ENV().GetString("chat_mode") == "mode1" )
m_nChattingMode = 1;
else if( ENV().GetString("chat_mode") == "mode2" )
m_nChattingMode = 2;
#ifdef _DEV
m_pEditBox = dynamicCast< KUIControlEdit* >( GetChild( "chat_edit" ) );
m_strPreChatSave = "";
#endif
return SUIWnd::InitControls(kPos);
}
void SUIChattingWnd::CreateStatic()
{
RECT rc;
rc.left = 0; rc.top = c_nLineHeight+c_nLineDelta; rc.right = 0; rc.bottom = c_nLineHeight+c_nLineDelta;
for( int i = 1; i < CHAT_MAX_LIST; i++ )
{
// 채팅창 표시되는 이모티콘 표시 비활성화. 유럽
KUIControl *pkKUIControl = (KUIControl *)CopyControl( CStringUtil::StringFormat( "chat_line%02d", i-1 ).c_str(), CStringUtil::StringFormat( "chat_line%02d", i ).c_str(), rc );
pkKUIControl->UseEmoticonFilter(false);
}
}
void SUIChattingWnd::CreateTab()
{
KUISimpleTabControl* pTabControl = NULL;
pTabControl = dynamicCast<KUISimpleTabControl*>(GetChild("chat_tab"));
if( pTabControl )
{
pTabControl->SetTabProperty( 0, false, CHAT_CHANNEL_MAX );
pTabControl->AddTabItem( CStringUtil::StringFormat( "<size:10>%s", GetGameOption().GetChatTabName(0) ).c_str(), GetGameOption().GetChatTabName(0) );
pTabControl->AddTabItem( CStringUtil::StringFormat( "<size:10>%s", GetGameOption().GetChatTabName(1) ).c_str(), GetGameOption().GetChatTabName(1) );
pTabControl->AddTabItem( CStringUtil::StringFormat( "<size:10>%s", GetGameOption().GetChatTabName(2) ).c_str(), GetGameOption().GetChatTabName(2) );
pTabControl->AddTabItem( CStringUtil::StringFormat( "<size:10>%s", GetGameOption().GetChatTabName(3) ).c_str(), GetGameOption().GetChatTabName(3) );
pTabControl->AddTabItem( CStringUtil::StringFormat( "<size:10>%s", GetGameOption().GetChatTabName(4) ).c_str(), GetGameOption().GetChatTabName(4) );
// pTabControl->SetCorrectionRect( KRect( c_nTabClickArea, 0, -c_nTabClickArea, 0 ) );
}
}
bool SUIChattingWnd::InitData( bool bReload )
{
m_nOldTabType = 0;
m_nTabType = 0;
m_nCurChatCount = 0;
m_bYell = false;
m_dwYellTime = 0;
m_nMaxLine = CHAT_MAX_LIST;
m_dwTime = 0;
m_bColse = true;
m_dwAlphaTime = 0;
m_bNoAlphaProc = false;
m_dwIMEAlphaTime = 0;
m_fWeightRatio = 0.0f;
m_nTime = 0;
m_nTimeCount = 0;
FreeList();
for( int i = 0; i < CHAT_MAX_LIST; i++ )
{
m_pStaticHistories[i] = NULL;
m_vecChatSneder[i].clear();
}
m_cacheWhisperUser.clear( ); // [sonador][7.0.2]귓속말 스택 기능 오류 수정
m_nMaxLine = 6; //채팅창에 보이는 문자열 수
//RefreshMaxLine();하고 ResizeScrollbar(); ToggleShowChatTab(); 함수 안에서 호출한다
ToggleShowChatTab();
EditAlpha(true);
return SUIWnd::InitData(bReload);
}
bool SUIChattingWnd::GetImeState()
{
//static bool bToggle = false;
KUIControlEdit* pEdit = NULL;
if( (pEdit = dynamicCast<KUIControlEdit*>(GetChild("chat_edit")) ))
{
if( pEdit->HasFocus() )
{
std::string strTemp = pEdit->GetText();
if( strTemp.empty() )
{
if( GetGameOption().IsEnterChat() )
{
return false;
}
else
{
return true;
}
}
if( ( !m_strPreText.empty() && strcmp( strTemp.c_str(), m_strPreText.c_str() ) == 0 ) )
return false;
return true;
}
else
{
return false;
}
}
return false;
}
void SUIChattingWnd::OnNotifyUIWindowOpen( bool bOpen, bool bLimitWnd )
{
SUIWnd::OnNotifyUIWindowOpen(bOpen);
GetGameOption().SetChattingOpen( bOpen );
if( bOpen )
{
//한영 전환, 중국 IME 지원 하려면, 더 확장 해야 함.
KUIControlCheck* pBtnLang = dynamicCast<KUIControlCheck*>(GetChild("chat_string"));
if( pBtnLang )
{
pBtnLang->SetCheck( IsEnglish() );
}
for( int i = KIND_ALLMSG; i <= KIND_AD; i++ )
{
KUISimpleTabControl* pTab = dynamicCast<KUISimpleTabControl*>(GetChild( "chat_tab" ));
if( pTab ) pTab->ChangeTabName( i, GetGameOption().GetChatTabName(i), S(6394) );
}
}
}
void SUIChattingWnd::UpdateChattingResize()
{
if( GetGameOption().GetChattingLine() > 0 && GetGameOption().GetChattingLine() <= CHAT_MAX_LIST )
{
m_nMaxLine = GetGameOption().GetChattingLine();
m_nMaxLine = min( m_nMaxLine, (int)CHAT_MAX_LIST );
m_nMaxLine = max( m_nMaxLine, (int)CHAT_MIN_LIST );
//TODO : 수정 요망.
Resize( KRect( GetRect().left, GetRect().bottom-GetGameOption().GetChattingHeight(), GetRect().right, GetRect().bottom ) );
ResizeScrollbar();
RefreshMaxLine();
m_bScrollClick = false;
UpdateChatText();
}
}
void SUIChattingWnd::RefreshScrollbar( bool bCrrPos )
{
int nScrollRange = max(m_nCurChatCount - m_nMaxLine -1, 0);
KUIControlVScroll* pScrollBar = dynamicCast<KUIControlVScroll*>(GetChild( "chat_scroll" ));
if( NULL != pScrollBar )
{
pScrollBar->SetMaxRange( DWORD(nScrollRange+1) );
if( bCrrPos )
{
pScrollBar->SetPosition( pScrollBar->GetPosition() );
}
else pScrollBar->SetPosition( nScrollRange );
}
}
void SUIChattingWnd::RefreshMaxLine()
{
KUIControlStatic* pBGStatic = dynamicCast<KUIControlStatic*>(GetChild( "background" ));
if( !pBGStatic ) return;
int nLineSize = c_nLineHeight + c_nLineDelta;
int nHeight = pBGStatic->GetRect().GetHeight();
nHeight -= c_nChatSpase; //위에 공백
m_nMaxLine = nHeight / nLineSize;
m_nMaxLine = min( m_nMaxLine, (int)CHAT_MAX_LIST );
m_nMaxLine = max( m_nMaxLine, (int)CHAT_MIN_LIST );
for( int i = 0; i < CHAT_MAX_LIST; i++ )
{
if( i < m_nMaxLine )
{
m_pStaticHistories[i] = dynamicCast<KUIControlStatic*>(GetChild( CStringUtil::StringFormat( "chat_line%02d", i ).c_str() ));
SetChildShow( CStringUtil::StringFormat( "chat_line%02d", i ).c_str(), true );
// 2010.07.28 - prodongi
DWORD captionAlign = m_pStaticHistories[i]->GetCaptionAlign();
m_pStaticHistories[i]->SetCaptionAlign(captionAlign |KTextRender::KTALIGN_BOTTOM);
}
else
{
m_pStaticHistories[i] = NULL;
m_vecChatSneder[i].clear();
SetChildShow( CStringUtil::StringFormat( "chat_line%02d", i ).c_str(), false );
}
}
}
void SUIChattingWnd::Process( DWORD dwTime )
{
if( m_bYell && (dwTime - m_dwYellTime)/1000 >= 3.f )
m_bYell = false;
m_dwTime = dwTime;
if( m_dwIMEAlphaTime )
{
float fAlphaValue = 1.f-(float(dwTime-m_dwIMEAlphaTime))/2500.f;
if( fAlphaValue >= 0.f )
{
GetChild("chat_string")->ChangeAlpha(fAlphaValue); //IME
}
else
{
SetChildShow( "chat_string", false );
GetChild("chat_string")->ChangeAlpha(0.f); //IME
m_dwIMEAlphaTime = 0;
}
}
bool bChange(false), bChangeAlphaComplete(false);
float fAlphaValue(0.0f);
if( !GetGameOption().IsChatHide() )
{
SetChildShow( "background", true );
SetChildShow( "chat_scroll", true );
SetChildShow( "_Resize", true );
fAlphaValue = 1.f;
bChange = true;
bChangeAlphaComplete = true;
}
else if( !m_bNoAlphaProc ) //체팅창 자동 숨김이면서 !m_bNoAlphaProc라면...
{
bChange = true;
if( m_bColse ) //Close
{
float fTempAlphaValue = 1.f-(float(dwTime-m_dwAlphaTime))/600.f;
fAlphaValue = max( fTempAlphaValue, 0.f );
if( fTempAlphaValue < 0.f )
bChangeAlphaComplete = true;
}
else //Open
{
float fTempAlphaValue = (float(dwTime-m_dwAlphaTime))/600.f;
fAlphaValue = min( fTempAlphaValue, 1.f );
if( fTempAlphaValue > 1.f )
bChangeAlphaComplete = true;
}
}
if( bChange )
{
GetChild("background")->ChangeAlpha(fAlphaValue);
GetChild("chat_scroll")->ChangeAlpha(fAlphaValue);
GetChild("_Resize")->ChangeAlpha(fAlphaValue);
if( bChangeAlphaComplete ) m_dwAlphaTime = 0;
}
// 2010.09.02 - prodongi
//if( !m_vAutoMsgInfo.empty() )
if( !m_autoMsgInfo.empty() )
{
//std::vector< AutoMsgInfo* >::iterator iter = m_vAutoMsgInfo.begin();
it_autoMsgInfo iter = m_autoMsgInfo.begin();
//for( ; iter != m_vAutoMsgInfo.end() ; )
for( ; iter != m_autoMsgInfo.end() ; )
{
//AutoMsgInfo* msgset = (*iter);
AutoMsgInfo* msgset = iter->second;
if( msgset->IsEnd() )
{
//SAFE_DELETE( (*iter) );
//iter = m_vAutoMsgInfo.erase( iter );
SAFE_DELETE(iter->second);
iter = m_autoMsgInfo.erase( iter );
}
else
{
if( msgset->m_bUseMsgCount )
OutputAutoMsgWithMsgCount( msgset );
else
OutputAutoMsg( msgset );
++iter;
}
}
}
KUIControlEdit* pEditWnd = dynamicCast<KUIControlEdit*>(GetChild("chat_edit"));
if( pEditWnd->HasFocus() )
{
EditAlpha(false);
}
else EditAlpha(true);
KUIWnd::Process(dwTime);
}
void SUIChattingWnd::ProcMsgAtStatic( SGameMessage* pMsg )
{
switch(pMsg->nType)
{
case MSG_CHATTING:
{
SMSG_CHATTING* pChatMsg = (SMSG_CHATTING*)pMsg;
XStringUtil::TranslateKoreanPostfix( pChatMsg->strText );
AddChatText( pChatMsg->strText.c_str(), pChatMsg->szSender.c_str(), pChatMsg->nChatType );
pMsg->bUse = true;
}
break;
case MSG_RESULT: // 귓말 경우
{
SMSG_RESULT* pMsgResult = (SMSG_RESULT*)pMsg;
switch( pMsgResult->request_msg_id )
{
case TM_CS_CHAT_REQUEST: UpdateWhisperList(pMsgResult->result); break;
case TM_CS_TURN_ON_PK_MODE:
{
if( pMsgResult->result == RESULT_SUCCESS )
{
AutoMsgInfo* pAutoMsgInfo = new AutoMsgInfo;
pAutoMsgInfo->m_nSystemMsg = SYS_MSG_PKMODE_ON;
pAutoMsgInfo->m_nMsgCount = 1;
pAutoMsgInfo->m_strTag1 = "#@second@#";
pAutoMsgInfo->m_dwAutoMsgTime = m_dwTime;
pAutoMsgInfo->m_dwDelayTime = 1000;
pAutoMsgInfo->m_bUseMsgCount = true;
AddAutoMsgInfo( pAutoMsgInfo );
}
else if( pMsgResult->result == RESULT_NOT_ACTABLE )
{
DeleteAutoMsg( SYS_MSG_PKMODE_ON );
AddChatText( "PK OFF", "", CHAT_ETC );
}
}
break;
case TM_CS_TURN_OFF_PK_MODE:
{
if( pMsgResult->result == RESULT_SUCCESS )
{
AutoMsgInfo* pAutoMsgInfo = new AutoMsgInfo;
pAutoMsgInfo->m_nSystemMsg = SYS_MSG_PKMODE_OFF;
pAutoMsgInfo->m_nMsgCount = 1;
pAutoMsgInfo->m_strTag1 = "#@second@#";
pAutoMsgInfo->m_dwAutoMsgTime = m_dwTime;
pAutoMsgInfo->m_dwDelayTime = 1000;
pAutoMsgInfo->m_bUseMsgCount = true;
AddAutoMsgInfo( pAutoMsgInfo );
}
}
break;
}
pMsg->bUse = true;
}
break;
case MSG_ITEM_DESTROY:
case MSG_UPDATE_ITEM_COUNT:
case MSG_ITEM_INVEN:
case MSG_ITEM_WEAR_INFO:
case MSG_SKILLCARD_INFO:
case MSG_PROPERTY:
case MSG_STAT_INFO:
{
float fInvenWeight = m_PlayerInfoMgr.GetInvenWeigth();
int nMaxWeight = m_PlayerInfoMgr.GetWeight();
float fWeightRatio = ( fInvenWeight / (float)nMaxWeight ) * 100.f;
/* if( fWeightRatio >= 50 && fWeightRatio < 70 )
{
if( m_fWeightRatio != 50 )
{
DeleteAutoMsg(SYS_MSG_WEIGHT_70_EXCESS_HANDICAP);
DeleteAutoMsg(SYS_MSG_WEIGHT_90_EXCESS_HANDICAP);
AutoMsgInfo* pAutoMsgInfo = new AutoMsgInfo;
pAutoMsgInfo->m_nSystemMsg = SYS_MSG_WEIGHT_50_EXCESS_HANDICAP;
pAutoMsgInfo->m_dwAutoMsgTime = m_dwTime;
pAutoMsgInfo->m_dwDelayTime = 30000;
AddAutoMsgInfo( pAutoMsgInfo );
m_fWeightRatio = 50;
}
}*/
if( fWeightRatio >= 75.0f && fWeightRatio < 100.0f )
{
if( m_fWeightRatio != 75.0f )
{
DeleteAutoMsg(SYS_MSG_WEIGHT_50_EXCESS_HANDICAP);
DeleteAutoMsg(SYS_MSG_WEIGHT_90_EXCESS_HANDICAP);
AutoMsgInfo* pAutoMsgInfo = new AutoMsgInfo;
pAutoMsgInfo->m_nSystemMsg = SYS_MSG_WEIGHT_70_EXCESS_HANDICAP;
pAutoMsgInfo->m_dwAutoMsgTime = m_dwTime;
pAutoMsgInfo->m_dwDelayTime = 30000;
AddAutoMsgInfo( pAutoMsgInfo );
m_fWeightRatio = 75.0f;
}
}
else if( fWeightRatio >= 100.0f )
{
if( m_fWeightRatio != 100.0f )
{
DeleteAutoMsg(SYS_MSG_WEIGHT_50_EXCESS_HANDICAP);
DeleteAutoMsg(SYS_MSG_WEIGHT_70_EXCESS_HANDICAP);
AutoMsgInfo* pAutoMsgInfo = new AutoMsgInfo;
pAutoMsgInfo->m_nSystemMsg = SYS_MSG_WEIGHT_90_EXCESS_HANDICAP;
pAutoMsgInfo->m_dwAutoMsgTime = m_dwTime;
pAutoMsgInfo->m_dwDelayTime = 30000;
AddAutoMsgInfo( pAutoMsgInfo );
m_fWeightRatio = 100.0f;
}
}
else
{
if( m_fWeightRatio != 0.0f )
{
DeleteAutoMsg(SYS_MSG_WEIGHT_50_EXCESS_HANDICAP);
DeleteAutoMsg(SYS_MSG_WEIGHT_70_EXCESS_HANDICAP);
DeleteAutoMsg(SYS_MSG_WEIGHT_90_EXCESS_HANDICAP);
m_fWeightRatio = 0.0f;
}
}
#ifdef _COUNTRY_CN_
bool bResetTimeCount = true;
if( m_PlayerInfoMgr.GetContinuousPlayTime() >= c_ar5Hour ) //5시간 보다 크냐
{
if( m_PlayerInfoMgr.GetContinuousPlayTime() >= c_ar5Hour + ( m_nTimeCount * c_ar15Minutes ) )
{
AddChatText( S( SYS_MSG_CHINA_BAD_TIME_WARNING ), "", CHAT_ETC );
m_nTimeCount += 1;
}
m_nTime = 500;
bResetTimeCount = false;
}
else if( m_PlayerInfoMgr.GetContinuousPlayTime() >= c_ar3Hour ) //3시간 보다 크냐
{
if( m_PlayerInfoMgr.GetContinuousPlayTime() >= c_ar4Hour + c_ar30Minutes )
{
if( m_nTime != 430 )
{
AddChatText( S( SYS_MSG_CHINA_FATIGUE_TIME_WARNING ), "", CHAT_ETC );
m_nTime = 430;
}
}
else if( m_PlayerInfoMgr.GetContinuousPlayTime() >= c_ar4Hour )
{
if( m_nTime != 400 )
{
AddChatText( S( SYS_MSG_CHINA_FATIGUE_TIME_WARNING ), "", CHAT_ETC );
m_nTime = 400;
}
}
else if( m_PlayerInfoMgr.GetContinuousPlayTime() >= c_ar3Hour + c_ar30Minutes )
{
if( m_nTime != 330 )
{
AddChatText( S( SYS_MSG_CHINA_FATIGUE_TIME_WARNING ), "", CHAT_ETC );
m_nTime = 330;
}
}
else
{
if( m_nTime != 300 )
{
AddChatText( S( SYS_MSG_CHINA_FATIGUE_TIME_START ), "", CHAT_ETC );
AddChatText( S( SYS_MSG_CHINA_FATIGUE_TIME_WARNING ), "", CHAT_ETC );
m_nTime = 300;
}
}
}
else
{
if( m_PlayerInfoMgr.GetContinuousPlayTime() >= c_ar2Hour )
{
if( m_nTime != 200 )
{
AddChatText( SR( SYS_MSG_CHINA_PLAY_TIME, "#@hour@#", 2 ).c_str(), "", CHAT_ETC );
m_nTime = 200;
}
}
else if( m_PlayerInfoMgr.GetContinuousPlayTime() >= c_ar1Hour )
{
if( m_nTime != 100 )
{
AddChatText( SR( SYS_MSG_CHINA_PLAY_TIME, "#@hour@#", 1 ).c_str(), "", CHAT_ETC );
m_nTime = 100;
}
}
}
if( bResetTimeCount )
m_nTimeCount = 0;
#endif
}
break;
//case IMSG_UI_CHAT_OPTION:
// {
// // 채팅의 위치를(pos) 전달하기 위해 sgameworld 에서 채팅의 chat_option 을 호출하면,
// // 다시 채팅 옵션에 pos 와 함께 재 호출해준다.
// SIMSG_UI_CHAT_OPTION* pChatOptionMsg = ( SIMSG_UI_CHAT_OPTION* )pMsg;
// m_pGameManager->PostMsgAtDynamic( new SIMSG_UI_CHAT_OPTION( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_CHAT_OPTION, pChatOptionMsg->m_Kind, GetRect().right, GetRect().top ) );
// pMsg->bUse = true;
// }
// break;
case IMSG_HOTKEY_EX:
{
SIMSG_HOTKEY_EX* pHotKeyMsg = (SIMSG_HOTKEY_EX*)pMsg;
//Key Down 만 처리
if( !pHotKeyMsg->bUp && !pHotKeyMsg->bAlt && !pHotKeyMsg->bCtrl && !pHotKeyMsg->bShift )
{
KUIControlVScroll* pScrollBar = dynamicCast<KUIControlVScroll*>(GetChild( "chat_scroll" ));
if( NULL == pScrollBar ) return;
bool bProc = false;
int nScrollRange = 0;
if ( LOWORD(pHotKeyMsg->wParam ) == VK_PRIOR )
{
//페이지 업
// _oprint( "페이지 업\n" );
nScrollRange = pScrollBar->GetPosition();
nScrollRange -= m_nMaxLine;
bProc = true;
}
if ( LOWORD(pHotKeyMsg->wParam ) == VK_NEXT )
{
//페이지 다운
// _oprint( "페이지 다운\n" );
nScrollRange = pScrollBar->GetPosition();
nScrollRange += m_nMaxLine;
bProc = true;
}
if ( LOWORD(pHotKeyMsg->wParam ) == VK_UP )
{
// { [sonador][7.0.2]귓속말 스택 기능 오류 수정
if( !IsImeDoingComposition( ) )
RemindWhisper( true );
// }
}
if ( LOWORD(pHotKeyMsg->wParam ) == VK_DOWN )
{
// { [sonador][7.0.2]귓속말 스택 기능 오류 수정
if( !IsImeDoingComposition( ) )
{
RemindWhisper( false );
}
// }
}
if( bProc )
{
pScrollBar->SetPosition( nScrollRange );
nScrollRange = pScrollBar->GetPosition();
UpdateChatText(nScrollRange, true);
}
}
}
break;
case IMSG_UI_CHAT_UPDATE:
{
SIMSG_UI_CHAT_UPDATE* pChatUpdateMsg = ( SIMSG_UI_CHAT_UPDATE* )pMsg;
//말머리 변경 됐을 가능성이 있으므로, 채팅창 초기화
KUIControlEdit* pEdit = NULL;
if( (pEdit = dynamicCast<KUIControlEdit*>(GetChild("chat_edit"))) )
{
pEdit->SetText("");
SetChatType();
}
if( m_nTabType != pChatUpdateMsg->m_Kind ) break;
else
{
// if(!m_bScrollClick)
UpdateChatText();
}
pMsg->bUse = true;
}
break;
case IMSG_UI_CHAT_TABNAME_CHANGE:
{
SIMSG_UI_CHAT_TABNAME_CHANGE* pTabNameMsg = ( SIMSG_UI_CHAT_TABNAME_CHANGE* )pMsg;
KUISimpleTabControl* pTab = dynamicCast< KUISimpleTabControl* >(GetChild( "chat_tab" ));
if( pTab )
{
pTab->ChangeTabName( pTabNameMsg->m_nTabKind, pTabNameMsg->m_strName.c_str(), S(6394) );
}
pMsg->bUse = true;
}
break;
case IMSG_MOUSEMOVE:
{
SIMSG_MOUSEMOVE* pMouseMove = (SIMSG_MOUSEMOVE* )pMsg;
//시간 카메라로 바꾸자~
int x = ((int)(short)LOWORD(pMouseMove->lParam));
int y = ((int)(short)HIWORD(pMouseMove->lParam));
KUIWnd * pWnd = GetChild( "_Resize" );
if( pWnd )
{
KUIControlSimpleButton* pSimpleBtn = (KUIControlSimpleButton*)pWnd;
if( pSimpleBtn->GetLeftButton() )
{
m_bNoAlphaProc = true;
}
else
{
//if( x < pWnd->GetRect().left || x > pWnd->GetRect().right ||
// y < (pWnd->GetRect().top) || y > (pWnd->GetRect().bottom) )
{
m_bNoAlphaProc = false;
}
}
}
if( (GetRect().right / 2) > x && ( y > GetRect().top && y < GetRect().bottom ) )
{
if( m_dwAlphaTime == 0 && m_bColse )
{
SetChildShow( "background", true );
SetChildShow( "chat_scroll", true );
SetChildShow( "_Resize", true );
m_bColse = false;
m_dwAlphaTime = m_dwTime;
}
}
else
{
if( m_dwAlphaTime == 0 && !m_bColse )
{
SetChildShow( "background", true );
SetChildShow( "chat_scroll", true );
SetChildShow( "_Resize", true );
m_bColse = true;
m_dwAlphaTime = m_dwTime;
}
}
}
break;
case IMSG_IME_NOTIFY :
{
////한영 전환, 중국 IME 지원 하려면, 더 확장 해야 함.
KUIControlCheck* pBtnLang = dynamicCast<KUIControlCheck*>(GetChild("chat_string"));
if( pBtnLang )
{
pBtnLang->SetCheck( IsEnglish() );
pBtnLang->ChangeAlpha(1.f);
pBtnLang->SetShow( true );
m_dwIMEAlphaTime = m_dwTime;
// _oprint( "IME Change\n" );
}
}
break;
case IMSG_UI_WHISPER:
{
SIMSG_UI_WHISPER* pWhisper = (SIMSG_UI_WHISPER* )pMsg;
AddWhisperUser( pWhisper->m_strWhisperName.c_str() );
RemindWhisper( false, true );
}
break;
case IMSG_UI_EMPTY_SOULPWER_MSG:
{
SIMSG_UI_EMPTY_SOULPWER_MSG* pSoulMsg = (SIMSG_UI_EMPTY_SOULPWER_MSG* )pMsg;
if( !pSoulMsg ) break;
// 2010.09.02 - prodongi
/*
if( m_bEmptySoulpwerMsg == false )
{
if( pSoulMsg->bOn )
{
AutoMsgInfo* pAutoMsgInfo = new AutoMsgInfo;
pAutoMsgInfo->m_nMsgCount = 20;
pAutoMsgInfo->m_dwAutoMsgTime = m_dwTime;
pAutoMsgInfo->m_dwDelayTime = 120000;
pAutoMsgInfo->m_bUseMsgCount = false;
pAutoMsgInfo->m_strMsg = SR(SYS_MSG_SOUL_EMPTY, "#@item_name@#", m_pDisplayInfo->GetItemName(pSoulMsg->Handle).c_str());
pAutoMsgInfo->m_nSystemMsg = SYS_MSG_SOUL_EMPTY;
pAutoMsgInfo->m_hItem = pSoulMsg->Handle;
AddAutoMsgInfo( pAutoMsgInfo );
AddChatText( pAutoMsgInfo->m_strMsg.c_str(), "", CHAT_ETC );
m_bEmptySoulpwerMsg = true;
}
}
else
{
if( !pSoulMsg->bOn ) // sonador #2.3.1.5 소울스톤 영혼력 고갈 메시지 출력 오류 수정
{
DeleteAutoEmptySoulpwerMsg(SYS_MSG_SOUL_EMPTY, pSoulMsg->Handle);
m_bEmptySoulpwerMsg = false;
}
}
*/
it_autoMsgInfo it;
if (findAutoMsgInfo(SYS_MSG_SOUL_EMPTY, pSoulMsg->Handle, it))
{
if( !pSoulMsg->bOn ) // sonador #2.3.1.5 소울스톤 영혼력 고갈 메시지 출력 오류 수정
{
DeleteAutoMsg(SYS_MSG_SOUL_EMPTY, pSoulMsg->Handle);
}
}
else
{
if( pSoulMsg->bOn )
{
AutoMsgInfo* pAutoMsgInfo = new AutoMsgInfo;
pAutoMsgInfo->m_nMsgCount = 20;
pAutoMsgInfo->m_dwAutoMsgTime = m_dwTime;
pAutoMsgInfo->m_dwDelayTime = 120000;
pAutoMsgInfo->m_bUseMsgCount = false;
pAutoMsgInfo->m_strMsg = SR(SYS_MSG_SOUL_EMPTY, "#@item_name@#", m_pDisplayInfo->GetItemName(pSoulMsg->Handle).c_str());
pAutoMsgInfo->m_nSystemMsg = SYS_MSG_SOUL_EMPTY;
pAutoMsgInfo->m_hItem = pSoulMsg->Handle;
AddAutoMsgInfo( pAutoMsgInfo );
AddChatText( pAutoMsgInfo->m_strMsg.c_str(), "", CHAT_ETC );
}
}
}
break;
case IMSG_UI_QUICKSLOT_STATECHANGE:
{
//_oprint("오케이!!");
SIMSG_UI_QUICKSLOT_STATECHANGE* pQSSMsg = (SIMSG_UI_QUICKSLOT_STATECHANGE* )pMsg;
MovePos(2, pQSSMsg->m_nQSPosY - GetRect().GetHeight()-5);
//m_QSPosY = pQSSMsg->m_nQSPosY;
//MoveWnd();
}
break;
case MSG_BATTLE_ARENA_LEAVE:
{
/// 경기장에서 채팅창 입력한 후에, 경기가 끝난후에 채팅창을 입력하면 필터가 남아 있기 때문에
/// 초기화 해준다
setArenaFilterToChatEdit(true);
}
break;
}
}
/*
bool SUIChattingWnd::MoveWnd()
{
if(m_QSPosY>0)
{
MovePos(2, m_QSPosY - GetRect().GetHeight()-5);
return true;
}
return false;
}*/
bool SUIChattingWnd::IsChatBufferEmpty()
{
KUIControlEdit* pEditConsole = dynamicCast<KUIControlEdit*>(GetChild( "chat_edit" ));
if( NULL == pEditConsole ) return false;
std::string strText = pEditConsole->GetText();
return strText.empty() && !pEditConsole->IsCandidate();
}
bool SUIChattingWnd::RemindWhisper( bool bBackward, bool bForceActivate )
{
if( m_cacheWhisperUser.empty( ) )
return false;
KUIControlEdit* pEdit = dynamicCast<KUIControlEdit*>(GetChild( "chat_edit" ));
if( !pEdit ) return false;
bool bActiveEdit( pEdit->HasFocus() );
bool bEnterChat( GetGameOption().IsEnterChat() );
if( bForceActivate )
{
bActiveEdit = true;
bEnterChat = true;
pEdit->SetActivate( true );
pEdit->SetFocus( true );
}
if( !bEnterChat || (bEnterChat&&bActiveEdit) )
{
// [ [sonador][7.0.5]자동 귓속말 오류 수정
sui::spin_cache< std::string >::iterator iuser;
if( bBackward )
iuser = m_cacheWhisperUser.prev( );
else
iuser = m_cacheWhisperUser.next( );
if( iuser != m_cacheWhisperUser.end( ) )
{
AutoWhisper( ( *iuser ).c_str( ) );
}
// }
}
return true;
}
// { [sonador][7.0.5]자동 귓속말 오류 수정
void SUIChattingWnd::AutoWhisper( const char* pDestUser )
{
if( ::strlen( pDestUser ) == 0 )
return;
KUIControlEdit* pEdit = dynamicCast<KUIControlEdit*>(GetChild( "chat_edit" ));
if( !pEdit )
return;
std::string strWhisper( "\"" );
strWhisper += pDestUser;
strWhisper += " ";
pEdit->SetText( strWhisper.c_str() );
pEdit->SetFontColor( GetColor( CHAT_WHISPER ) );
SetFocusEdit( true );
}
// }
void SUIChattingWnd::AutoPartyInvite( const char* pDestUser )
{
if( ::strlen( pDestUser ) == 0 )
return;
KUIControlEdit* pEdit = dynamicCast<KUIControlEdit*>(GetChild( "chat_edit" ));
if( !pEdit )
return;
std::string strDestUser;
strDestUser = pDestUser;
strDestUser.replace ( strlen(pDestUser)-2, 2, "");
std::string strWhisper( "/" );
strWhisper += "pinvite";
strWhisper += " ";
strWhisper += strDestUser;
pEdit->SetText( strWhisper.c_str() );
pEdit->SetFontColor( GetColor( CHAT_PARTY ) );
SetFocusEdit( true );
}
bool SUIChattingWnd::IsEnglish()
{
HIMC hIMC = ImmGetContext(g_hWnd);
DWORD dwConv, dwSent;
ImmGetConversionStatus(hIMC, &dwConv, &dwSent);
bool bEnglish;
switch( dwConv & IME_CMODE_LANGUAGE )
{
default :
case IME_CMODE_ALPHANUMERIC:
bEnglish = true;
break;
case IME_CMODE_NATIVE:
bEnglish = false;
break;
}
ImmReleaseContext(g_hWnd, hIMC);
return bEnglish;
}
void SUIChattingWnd::PumpUpMessage( LPCSTR lpszControlID, DWORD nMessage, DWORD lparam, DWORD wparam )
{
switch(nMessage)
{
case KUI_MESSAGE::KBUTTON_CLICK:
{
if( ::_stricmp( "idok", lpszControlID ) == 0 )
{
RequestChatText();
}
else if( ::_stricmp( "button_set", lpszControlID ) == 0 )
{
// if( GetGameOption().IsEnterChat() )
{
SetFocusEdit( false );
SetFocus( false );
}
//채팅 창 옵션 처리
m_pGameManager->PostMsgAtDynamic( new SIMSG_UI_CHAT_OPTION( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_CHAT_OPTION, m_nTabType, GetRect().right, GetRect().top ) );
}
else if( ::_stricmp( "button_Type", lpszControlID ) == 0 )
{
ToggleShowChatTab();
}
}
break;
case KUI_MESSAGE::KCHECK_CHANGE:
{
if( ::_stricmp( "chat_string", lpszControlID ) == 0 )
{
KUIControlCheck* pBtnLang = dynamicCast<KUIControlCheck*>(GetChild("chat_string"));
KUIControlEdit* pChatEdit = dynamicCast<KUIControlEdit*>(GetChild("chat_edit"));
if( !pBtnLang && !pChatEdit ) return;
if( IsEnglish() )
{
pBtnLang->SetCheck( false );
// 한글모드 ON
HIMC hIMC = ImmGetContext(g_hWnd);
ImmSetConversionStatus(hIMC, IME_CMODE_NATIVE, IME_SMODE_NONE);
ImmReleaseContext(g_hWnd, hIMC);
}
else
{
pBtnLang->SetCheck( true );
// 한글모드 OFF
HIMC hIMC = ImmGetContext(g_hWnd);
ImmSetConversionStatus(hIMC, IME_CMODE_ALPHANUMERIC, IME_SMODE_NONE);
ImmReleaseContext(g_hWnd, hIMC);
}
}
}
break;
case KUI_MESSAGE::KSCROLL_SELECT: // 스크롤 선택
{
int nPos = int(lparam);
nPos = max( nPos, 0 );
if( m_bScrollLbuttonDown )
{
m_bScrollClick = true;
m_pManager->SetCapture(this);
}
UpdateChatText(nPos, true);
_oprint( "Scroll Pos : %d\n", nPos );
}
break;
case KUI_MESSAGE::KTAB_SELECT: // 탭 변경
{
KUISimpleTabControl* pTab = dynamicCast< KUISimpleTabControl* >(GetChild("chat_tab"));
if( pTab == NULL ) break;
int nSelectTab = pTab->GetSelectedItem();
if( nSelectTab == m_nTabType ) return;
if( nSelectTab < 0 || nSelectTab > CHAT_CHANNEL_MAX ) return;
m_pGameManager->StartSound( "ui_button_click.wav" );
m_nOldTabType = m_nTabType;
m_nTabType = nSelectTab;
m_bScrollClick = false;
UpdateChatText();
SetChatType(); // 에디트 박스에 탭 타입에 따라 기호 표시해준다(기호, 컬러)
printArenaSystemMsg(); // 아래나일 경우 탭변경시 출력메세지가 있음
KUIControlEdit* pEditConsole = dynamicCast<KUIControlEdit*>(GetChild( "chat_edit" ));
if( NULL != pEditConsole )
{
std::string str = pEditConsole->GetText();
m_OldStaSize = str.size();
SetFocusEdit(true);
}
//Chating Option Window Refresh
m_pGameManager->PostMsgAtDynamic( new SIMSG_UI_CHAT_OPTION( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_CHAT_OPTION, m_nTabType, GetRect().right, GetRect().top, true ) );
}
break;
case KUI_MESSAGE::KGENWND_RESIZE:
{
ResizeScrollbar();
_oprint( "KUI_MESSAGE::KGENWND_RESIZE %d\n", wparam );
RefreshMaxLine();
m_bScrollClick = false;
UpdateChatText();
GetGameOption().SetChattingLine( m_nMaxLine );
GetGameOption().SetChattingHeight( GetRect().GetHeight() );
// 챗 옵션 닫아버린다
m_pGameManager->PostMsgAtDynamic( new SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_CHAT_OPTION, false ) );
}
break;
case KUI_MESSAGE::KEDIT_CHANGE: // 에디트
{
KUIControlEdit* pEditConsole = dynamicCast<KUIControlEdit*>(GetChild( "chat_edit" ));
if( NULL != pEditConsole )
{
KColor color;
std::string str = pEditConsole->GetText();
if( m_OldStaSize > str.size() && CheckChatTabMarkCutting(str) )
{
pEditConsole->SetText("");
color = GetColor( CHAT_NORMAL );
m_OldStaSize = 0;
}
else
{
color = GetColor( str );
m_OldStaSize = str.size();
}
pEditConsole->SetFontColor(color);
}
}
break;
case KUI_MESSAGE::KEDIT_IME_CHANGE:
{
KUIControlEdit* pEditWnd(NULL);
pEditWnd = dynamicCast<KUIControlEdit*>(GetChild( "chat_edit" ));
if( pEditWnd == NULL ) break;
KUIControlCheck* pBtnLang = dynamicCast<KUIControlCheck*>(GetChild("chat_string"));
if( pBtnLang )
{
pBtnLang->SetCheck( IsEnglish() );
if( m_dwTime )
{
pBtnLang->ChangeAlpha(1.f);
pBtnLang->SetShow( true );
m_dwIMEAlphaTime = m_dwTime;
}
}
}
break;
case KUI_MESSAGE::KEDIT_LINE_CHANGE:
{
KUIControlEdit* pEditConsole = dynamicCast<KUIControlEdit*>(GetChild( lpszControlID ));
if( NULL == pEditConsole ) return;
static int def_height = pEditConsole->GetRect().GetHeight();
int nOldLineCnt = static_cast<int>(lparam);
int nNewLineCnt = static_cast<int>(wparam);
nNewLineCnt = std::max(0, nNewLineCnt - 1);
KRect editRect = pEditConsole->GetRect();
editRect.top = editRect.bottom - def_height - ((12+3)*nNewLineCnt);
pEditConsole->SetReSize( editRect );
}
break;
case KUI_MESSAGE::KEDIT_SYSKEY: // 에디트 탭키 처리
{
int TapKeyType = GetGameOption().GetTapKeyType();
if( TapKeyType == 1 && lparam == VK_TAB )
{
//탭키는 다음으로 넘어가면 클라요.
//SUIWnd::PumpUpMessage( lpszControlID, nMessage, lparam, wparam ); 안에서 탭키 처리 부분이 있는데 항상 체팅에디트에 포커스를 줌
return;
}
break;
}
case KUI_MESSAGE::KBUTTON_PRESSING:
{
}
break;
/// 2012.04.30 - prodongi
case KUI_MESSAGE::KFOCUS_ACTIVATED:
{
setArenaFilterToChatEdit();
}
break;
#ifdef _DEV
case KUI_MESSAGE::KEDIT_VK_UP:
{
// bintitle. 2011.11.09.
switch( lparam )
{
case VK_UP:
if( m_pEditBox )
{
// EditBox에 이전 문자열 적용.
m_pEditBox->SetText( m_strPreChatSave.c_str() );
}
break;
case VK_DOWN:
if( m_pEditBox )
{
// 현재 문자열 적용.
m_pEditBox->SetText( "" );
}
break;
}
}
#endif
}
SUIWnd::PumpUpMessage( lpszControlID, nMessage, lparam, wparam );
}
void SUIChattingWnd::EditAlpha( bool bOn )
{
if( m_bChatAlpha == bOn ) return;
float EditAlpha(0.8f), FrameAlpha(0.65f);
if( bOn )
{
EditAlpha = 0.25f;
FrameAlpha = 0.1f;
}
KUIWnd* pEditWnd = GetChild("chat_edit");
if( pEditWnd ) pEditWnd->ChangeAlpha(EditAlpha);
KUIWnd* pFrameWnd = GetChild("lowerframe01");
if( pFrameWnd ) pFrameWnd->ChangeAlpha(FrameAlpha);
m_bChatAlpha = bOn;
}
void SUIChattingWnd::ToggleShowChatTab()
{
KUIWnd* pTabWnd = GetChild("chat_tab");
if( !pTabWnd ) return;
if( pTabWnd->IsShow() ) m_bShowTab = false;
else m_bShowTab = true;
SetChildShow( "chat_tab", m_bShowTab );
ResizeScrollbar();
RefreshMaxLine();
m_bScrollClick = false;
UpdateChatText();
}
void SUIChattingWnd::ResizeScrollbar()
{
KUIWnd* pTabWnd = GetChild("chat_tab");
KUIWnd* pBackWnd = GetChild("background");
KUIWnd* pFrame = GetChild("lowerframe01");
KUIWnd* pScrollWnd = GetChild("chat_scroll");
KUIWnd* pChatWnd = GetChild("chat_line00");
KUIWnd* pResizeWnd = GetChild("_Resize");
if( !pBackWnd || !pFrame || !pScrollWnd || !pChatWnd || !pResizeWnd )
return;
/// 2011.06.22 - prodongi
KUIControlScrollBase* scrollBase = dynamicCast<KUIControlScrollBase*>(pScrollWnd);
assert(scrollBase && "failed chat_scroll KUIControlScrollBase casting");
// 채팅창 표시되는 이모티콘 표시 비활성화. 유럽
((KUIControl *)pChatWnd)->UseEmoticonFilter(false);
KRect rcTab ( pTabWnd->GetRect() );
KRect rcFrame ( pFrame->GetRect() );
KRect rcResize ( pResizeWnd->GetRect() );
KRect rcScroll ( pScrollWnd->GetRect() );
KRect rcBack ( pBackWnd->GetRect() );
rcScroll.top = GetRect().top+rcResize.GetHeight()+2;
/// 2011.06.22 - prodongi
KRect tempr;
scrollBase->getButtonRect(0, tempr);
rcScroll.top += tempr.GetHeight();
/// 2011.06.22 - prodongi
scrollBase->getButtonRect(1, tempr);
int sh = tempr.GetHeight() + 2;
if( m_bShowTab )
rcScroll.bottom = rcTab.top-sh; //sfreer 2009.07.13 스크롤바
else
rcScroll.bottom = rcFrame.top-sh; //sfreer 2009.07.13 스크롤바
pScrollWnd->Resize( rcScroll );
//배경 처리
rcBack.top = rcResize.top;
if( m_bShowTab )
rcBack.bottom = rcTab.top;
else rcBack.bottom = rcFrame.top;
pBackWnd->Resize( rcBack );
}
//인자로 들어오는 str은 ←로 한글자가 삭제된 후에 에디트창에 남아있는 텍스트이다...
bool SUIChattingWnd::CheckChatTabMarkCutting( std::string& str )
{
std::string strChatTab = GetGameOption().GetChatTabMark(m_nTabType);
std::wstring wname = nsl::uni::conv( strChatTab );
//여기서 마지막 한자를 삭제하는 것은 ←로 삭제된 후의 텍스트와 비교해야 하기 때문에
//현재 에디트창에 남아있는 텍스트와 TabMark에 들어있는 택스트가 동일하다면 아직은 지울 타이밍이 이닌 것이다...
//즉 에디트 창에 남아있는 텍스트가 TabMark에서 마지막 한자를 삭제한 텍스트와 같아야 TabMark를 지우려고 유저가 ←를 누른 것이된다.
if( wname.size() > 2 )
{
wname.erase( wname.size()-1, wname.size() );
strChatTab = nsl::uni::conv( wname );
}
else if( wname.size() == 1 )
{
//TabMark에 한글이던 영어던 1자만 등록되어 있다면 str에 빈텍스트가 들어와야만 TabMark를 삭제한다는 의미이다.
//헌데 이미 str에 빈텍스트가 들어왔다면 이미 다 지운 것이니 무시해버리면된다. 따라서 return false;
return false;
}
return str == strChatTab;
}
void SUIChattingWnd::UpdateSelectUser( int x, int y )
{
bool bChang(false);
KRect rcStaticHistories;
for( int i = 0; i < CHAT_MAX_LIST; i++ )
{
if( m_pStaticHistories[i] == NULL ) continue;
rcStaticHistories = m_pStaticHistories[i]->GetRect();
if( rcStaticHistories.IsInRect(x, y) )
{
if( rcStaticHistories.right/3 <= x ) break;
if( m_nSelectUserIndex != i )
bChang = UpdateSelectUserColor(i);
else bChang = true;
}
}
if(!bChang)
{
CancleSelectUserColor();
}
}
void SUIChattingWnd::CancleSelectUserColor()
{
if( m_nSelectUserIndex < 0 || CHAT_MAX_LIST <= m_nSelectUserIndex )
return;
if( m_pStaticHistories[m_nSelectUserIndex] )
{
std::string strTemp = m_pStaticHistories[m_nSelectUserIndex]->GetCaption();
int pos1 = strTemp.find("<U>");
if (pos1 != std::string::npos)
strTemp.erase(pos1, 3);
int pos2 = strTemp.find("</U>");
if (pos2 != std::string::npos)
strTemp.erase(pos2, 4);
m_pStaticHistories[m_nSelectUserIndex]->SetCaption(strTemp.c_str()); // m_nBackupText를 없애고 태그만 제거하도록 변경. 백업텍스트가 제대로 갱신이 안되서 채팅창을 줄였다 늘였다 하면 채팅창이 이상해지는 문제 수정.
m_nSelectUserIndex = -1;
}
}
bool SUIChattingWnd::UpdateSelectUserColor(int nIndex)
{
if( CHAT_MAX_LIST <= nIndex || nIndex < 0 ) return false;
std::string strText = m_pStaticHistories[nIndex]->GetCaption();
if( strText.empty() ) return false;
/// 2011.07.26 유저 아이디가 태그랑 같은 경우에 find가 제대로 안되기 때문에 꽁수로 '>'를 같이 찾도록 한다- prodongi
if (m_vecChatSneder[nIndex].length()>0)
{
std::string userNick = ">";
userNick += m_vecChatSneder[nIndex];
std::string::size_type Pos = strText.find(userNick.c_str());
//std::string::size_type Pos2 = userNick.find("<>");
//if(Pos == std::string::npos && Pos2 == std::string::npos ) // +
//{ int nSize = strText.size();
// strText.insert(nSize, "</U>");
// strText.insert(0, "<U>");
//
//return false;
//} else
if (Pos == std::string::npos) return false;
else
{
/// 2011.07.26 '>' 때문에 +1 해줌 - prodongi
Pos += 1;
if(m_nSelectUserIndex > -1 && CHAT_MAX_LIST > m_nSelectUserIndex )
{
if( m_pStaticHistories[m_nSelectUserIndex] )
{
std::string strTemp = m_pStaticHistories[m_nSelectUserIndex]->GetCaption();
int pos1 = strTemp.find("<U>");
if (pos1 != std::string::npos)
strTemp.erase(pos1, 3);
int pos2 = strTemp.find("</U>");
if (pos2 != std::string::npos)
strTemp.erase(pos2, 4);
m_pStaticHistories[m_nSelectUserIndex]->SetCaption(strTemp.c_str());
}
}
m_nSelectUserIndex = nIndex;
int nSize = m_vecChatSneder[nIndex].size();
strText.insert(Pos+nSize, "</U>");
strText.insert(Pos, "<U>");
}
m_pStaticHistories[nIndex]->SetCaption(strText.c_str());
}
return true;
}
void SUIChattingWnd::OffScrollClick()
{
m_bScrollClick = false;
for( int j(0); CHAT_CHANNEL_MAX>j; j++ )
{
for( int i(0); i<m_vecTempChatList[j].size(); ++i )
{
if( m_vecChatList[j].size() > c_nMaxChatHistory ) DelHistory(m_vecChatList[j]); // 200 개 이상이 되면 처음데이터 지운후 저장
if( m_vecTempChatList[j][i] )
{
//아래서 push하는 것은 m_vecChatList이지만 m_vecTempChatList와 어차피 동일한 주소값이니 이넘을 ++ 해도 무관
m_vecTempChatList[j][i]->nReferenceCnt++;
m_vecChatList[j].push_back(m_vecTempChatList[j][i]);
}
}
ClearChatListBuffer(m_vecTempChatList[j]);
}
}
DWORD SUIChattingWnd::OnMouseMessage(DWORD dwMessage, int x, int y)
{
if( dwMessage == KLBUTTON_UP )
{
m_bScrollLbuttonDown = false;
if( m_bScrollClick )
{
KUIControlVScroll* pScrollBar = dynamicCast<KUIControlVScroll*>(GetChild( "chat_scroll" ));
if( NULL != pScrollBar )
{
if( m_nChattingMode == 2 )
{
OffScrollClick();
UpdateChatText();
}
else
{
//OffScrollClick()
int nScrollPos = pScrollBar->GetPosition();
if( IsScrollEnd() )
{
if( m_nChattingMode == 1 )
m_bScrollClick = false;
else OffScrollClick();
UpdateChatText();
}
else UpdateChatText(nScrollPos, true);
}
int nScrollRange = max(m_nCurChatCount - m_nMaxLine -1, 0);
pScrollBar->SetMaxRange( DWORD(nScrollRange+1) );
}
m_pManager->ReleaseCapture(this);
}
}
else if( dwMessage == KLBUTTON_DOWN )
{
KUIWnd* pBackWnd = GetChild( "background" );
KUIWnd* pResizeWnd = GetChild( "_Resize" );
KUIControlScrollBase* pScrollWnd = dynamicCast<KUIControlScrollBase*>(GetChild( "chat_scroll" ));
if( pBackWnd && pScrollWnd && pResizeWnd )
{
bool bWhisper(false);
if( pBackWnd->IsInRect(x, y) && pBackWnd->GetRect().right/3 > x)
{
if( m_nSelectUserIndex > -1 && m_nSelectUserIndex < CHAT_MAX_LIST )
{
if( !m_vecChatSneder[m_nSelectUserIndex].empty() )
{
std::string::size_type Pos = m_vecChatSneder[m_nSelectUserIndex].find("<>");
if ( Pos == std::string::npos )
AutoWhisper( m_vecChatSneder[m_nSelectUserIndex].c_str() ); // { [sonador][7.0.5]자동 귓속말 오류 수정
else
AutoPartyInvite ( m_vecChatSneder[m_nSelectUserIndex].c_str() );
bWhisper = true;
}
}
}
if( pScrollWnd->IsInRect(x, y) )
m_bScrollLbuttonDown = true;
#ifndef _DEV_CHAT
/// 2011.06.22 - prodongi
if( !bWhisper && pBackWnd->IsInRect(x, y) && !pScrollWnd->getRectWithButton().IsInRect(x, y) && !pResizeWnd->IsInRect(x, y) )
return KMR_GET_PASS;
#endif
}
}
else if( dwMessage == KMOUSE_MOVE )
{
KUIWnd* pBackWnd = GetChild( "background" );
if( pBackWnd->IsInRect(x, y) && pBackWnd->GetRect().right/3 > x)
UpdateSelectUser(x, y);
else CancleSelectUserColor();
}
//m_EditboxInfo
bool bPrevFocus = dynamicCast<KUIControlEdit*>(GetChild( "chat_edit" ))->HasFocus();
//int iPrevCursorPos = ((KUIControlEdit*)GetChild( "chat_edit" ))->m_EditboxInfo.GetCursorPos();
DWORD rvalue = SUIWnd::OnMouseMessage( dwMessage, x, y );
bool bNowFocus = dynamicCast<KUIControlEdit*>(GetChild( "chat_edit" ))->HasFocus();
//int iNowCursorPos = ((KUIControlEdit*)GetChild( "chat_edit" ))->m_EditboxInfo.GetCursorPos();
// mantis:5002 [Chat Window] This is a bug with the Enter chat function on the Japanese client. Related fix 2009.08.14 sfreer
// For now, it will only be applied for Japan and China.
if(bPrevFocus==false && bNowFocus==true || (bNowFocus&&bPrevFocus&&dwMessage == KLBUTTON_DOWN) )
{
if(ENV().GetString( "country" ) == "JP" || ENV().GetString( "country" ) == "CN")
{
HIMC hIMC = ImmGetContext(g_hWnd);
ImmNotifyIME( hIMC, NI_COMPOSITIONSTR, CPS_CANCEL, 0 );
}
}
return rvalue;
}
void SUIChattingWnd::AllKillFocusChild()
{
std::list<KUIWnd*>::iterator it = m_listChild.begin();
while( it != m_listChild.end() )
{
KUIWnd* pWnd = (*it);
pWnd->SetFocus(false);
++it;
}
}
void SUIChattingWnd::SetFocusEdit( bool bFocus )
{
// if( GetGameOption().IsEnterChat() )
{
KUIControlEdit* pEdit0(NULL);
KUIControlEdit* pEdit1(NULL);
pEdit0 = dynamicCast<KUIControlEdit*>(GetChild( "chat_edit" ));
KUISimpleTabControl* pTab = dynamicCast< KUISimpleTabControl* >(GetChild("chat_tab"));
if( bFocus )
{ //하나만 활성화
AllKillFocusChild();
if( pEdit0 ) pEdit0->SetFocus(bFocus);
}
else
{
if( pEdit0 ) pEdit0->SetFocus(bFocus);
}
}
}
bool SUIChattingWnd::GetFocusEdit( )
{
KUIControlEdit* pEdit0(NULL);
pEdit0 = dynamicCast<KUIControlEdit*>(GetChild( "chat_edit" ));
if( pEdit0 )
return pEdit0->HasFocus();
return false;
}
///////////////////////////////////////
// 메지시 리스트
///////////////////////////////////////
void SUIChattingWnd::FreeList()
{
//CHATDATA* 포인트 이므로 한곳에서만 삭제됨
for( int i(0); CHAT_CHANNEL_MAX>i; i++ )
{
ClearChatListBuffer( m_vecChatList[i] );
ClearChatListBuffer( m_vecTempChatList[i] );
}
std::vector<std::string>::iterator it_whisper = m_vecWhisperList.begin();
while( it_whisper != m_vecWhisperList.end() )
{
it_whisper = m_vecWhisperList.erase(it_whisper);
}
m_vecWhisperList.clear();
// 2010.09.02 - prodongi
/*
std::vector< AutoMsgInfo* >::iterator it_automsg = m_vAutoMsgInfo.begin();
for( ; it_automsg != m_vAutoMsgInfo.end() ; )
{
SAFE_DELETE( (*it_automsg) );
it_automsg = m_vAutoMsgInfo.erase( it_automsg );
}
*/
it_autoMsgInfo it = m_autoMsgInfo.begin();
for( ; it != m_autoMsgInfo.end() ; )
{
SAFE_DELETE(it->second);
it = m_autoMsgInfo.erase(it);
}
}
void SUIChattingWnd::ClearChatListBuffer( CHAT_LIST& chat_list )
{
std::vector<CHATDATA*>::iterator it = chat_list.begin();
while( it != chat_list.end() )
{
(*it)->nReferenceCnt--;
if( (*it)->nReferenceCnt<=0 )
SAFE_DELETE((*it));
it = chat_list.erase(it);
}
chat_list.clear();
}
void SUIChattingWnd::DelHistory( CHAT_LIST& rList )
{
CHATDATA* pData = NULL;
CHAT_LIST::iterator it = rList.begin();
if( it != rList.end() )
{
(*it)->nReferenceCnt--;
if( (*it)->nReferenceCnt<=0 )
SAFE_DELETE( (*it) );
rList.erase(it);
}
}
void SUIChattingWnd::DelTempHistory( CHAT_LIST& rList )
{
CHATDATA* pData = NULL;
CHAT_LIST::iterator it = rList.begin();
if( it != rList.end() )
{
(*it)->nReferenceCnt--;
if( (*it)->nReferenceCnt<=0 )
SAFE_DELETE( (*it) );
rList.erase(it);
}
}
//"\n" 와 <BR>를 모두 선별하여 줄바꿈 처리하지 않는다.
void SUIChattingWnd::FillterBR( std::string& rstrText )
{
XStringUtil::Replace( rstrText, "\n", "" );
}
void SUIChattingWnd::LogChatMsg( const char* fileName )
{
FILE* fp = fopen(fileName, "w");
if (fp != NULL)
{
fprintf( fp, "============Chatting log START=============\n" );
CHAT_LIST::iterator iter;
for( int i = 0; i < CHAT_CHANNEL_MAX; ++i )
{
CHAT_LIST& kVec = m_vecChatList[i];
for( iter = kVec.begin(); iter != kVec.end(); ++iter )
{
CHATDATA* pData = *iter;
if( pData )
fprintf( fp, "%s\n", pData->szText.c_str() );
}
}
fprintf( fp, "==============Chatting log END==============\n" );
fclose(fp);
}
}
void SUIChattingWnd::SetChatLog( bool bOn )
{
m_bChatLog = bOn;
if( true == m_bChatLog )
{
//keep going...
if( m_hChatLog != INVALID_HANDLE_VALUE )
return;
//ready to write
SYSTEMTIME kTime;
::GetLocalTime( &kTime );
std::string buf;
XStringUtil::Format( buf, "LOG/ChatHistory_%04d%02d%02d_%02d%02d%02d.log", kTime.wYear, kTime.wMonth, kTime.wDay, kTime.wHour, kTime.wMinute, kTime.wSecond );
m_hChatLog = CreateFile( buf.c_str(), GENERIC_READ|GENERIC_WRITE, 1, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
if ( m_hChatLog == INVALID_HANDLE_VALUE )
{
CreateDirectory( "LOG", NULL );
m_hChatLog = CreateFile( buf.c_str(), GENERIC_READ|GENERIC_WRITE, 1, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
if( m_hChatLog == INVALID_HANDLE_VALUE )
{
m_bChatLog = false;
AddChatText( "file open failed", "chatlog", CHAT_SYSTEM );
return;
}
}
else
{
//ok begin
AddChatText( "---------begin log!----", "chatlog", CHAT_SYSTEM );
}
}
else
{
if( m_hChatLog != INVALID_HANDLE_VALUE )
{
//ok end
AddChatText( "---------end log!----", "chatlog", CHAT_SYSTEM );
CloseHandle( m_hChatLog );
m_hChatLog = INVALID_HANDLE_VALUE;
}
}
}
void SUIChattingWnd::AddChatText( const char* szText, const char* szSender, int nChatType )
{
// 채팅창에 'F' 라고 뜨는거 문제 임시 수정 2009.08.21 sfreer
//SDEBUGLOG("ChatMSG = chattype:%d Sender[%s] : Text[%s] ", nChatType, szSender, szText );
if( nChatType == CHAT_ETC && strcmp(szText,"F") == 0)
{
SDEBUGLOG("Block F");
return;
}
/// 2012.07.06 중앙 공지 채팅 타입은 notification에서 출력해주기 때문에 여기서는 무시해야 된다. - prodongi
if (CHAT_CENTER_NOTICE == nChatType)
return ;
if( ::strlen(szText) <= 0 ) return;
std::string str;
if( nChatType == CHAT_COMMAND ) return;
//if( nChatType == CHAT_PARTY_SYSTEM ) return;
//return;
if( nChatType == CHAT_QUEST_SYSTEM ) return;
// if (nChatType == CHAT_PARTY_SYSTEM) return; // AziaMafia some sort of shit fix
if( nChatType == CHAT_QUEST_SYSTEM ) return;
if( nChatType == CHAT_GUILD_SYSTEM ) return;
if( nChatType == CHAT_RAID_SYSTEM ) return;
if( nChatType == CHAT_FRIEND_SYSTEM ) return;
if( nChatType == CHAT_ALLIANCE_SYSTEM ) return;
if ( nChatType == CHAT_DUNGEON_SYSTEM) return; /// 2011.11.30 - prodongi
//gmpbigsun(20131114): chat log
if( m_bChatLog && INVALID_HANDLE_VALUE != m_hChatLog )
{
std::string strTemp;
XStringUtil::Format( strTemp, "[%s]: %s\r\n", szSender, szText );
DWORD dwWritten;
WriteFile( m_hChatLog, strTemp.c_str(), strTemp.size(), &dwWritten, NULL );
FlushFileBuffers( m_hChatLog );
}
std::string strFilter;
strFilter = szText;
//차단리스트 유저의 채팅 필터링 2009.07.29 sfreer
std::vector<SPlayerSlot*>& MemberList = m_CutMgr.GetMemberList();
for( int i(0); i<MemberList.size() && MemberList[i]; ++i )
{
if( ::strcmpi(MemberList[i]->GetName(), szSender ) == 0)
{
return;
}
}
// MJ 2004/12/22 필터링 ============================
if( nChatType == CHAT_NOTICE )
{
// 공지타입이면서, 텍스트 시작이 ~~ 인것은 운영자의 명령이므로 skipp
if( strFilter.size() > 2 && ::_stricmp( strFilter.substr(0, 2).c_str(), "~~" ) == 0 ) return;
//아이템 사용 제한 시간이 경과했다면
else
{
if( strFilter.size() >= 2 )
{
std::vector< std::string > vToken;
MsgSplit( szText, vToken, L"|" );
if( vToken.size() > 0 )
{
if( vToken[0] == "ITEM_EXPIRE" || vToken[0] == "ITEM_EXPIRE_STORAGE" )
{
vToken.clear();
return;
}
}
vToken.clear();
}
}
}
// 텍스트 시작이 ~~ 이면서, 보내는 사람이 @SCRIPT 이면 운영자의 명령이므로 skipp
if( ::_stricmp( strFilter.substr(0, 2).c_str(), "~~" ) == 0 && ((::_stricmp( szSender, "@SCRIPT" ) == 0 || ::_stricmp( szSender, "@script" ) == 0)) ) return;
// 텍스트가 err 이면 skipp
if( ::_stricmp( szText, "err" ) == 0 ) return;
std::string strSender;
strSender = szSender;
// 보내는 사람 이름 변경 : Game -> system ==========
// CStringUtil::ReplacePhrase( strSender, "Game", "system" ); ==> 왜 보내는 사람이름이 Game이면 system으로 바꾸는 것인지 모르겠삼... 삭제 ^^
// 보내는 사람 타입에 맞게 모두 변경 : -> system ===
// if( false == strSender.empty() )
{
if( ::_stricmp(strSender.c_str(), "@SCRIPT") == 0 || ::_stricmp(strSender.c_str(), "@DEBUG") == 0 )
{
nChatType = CHAT_SYSTEM;
//strSender = "system";
strSender = "";
}
else if( ::_stricmp(strSender.c_str(), "@NOTICE") == 0 )
{
nChatType = CHAT_NOTICE;
strSender = S(6302);//"공지";
}
else if( ::_stricmp(strSender.c_str(), "@GUILD") == 0 )
{
nChatType = CHAT_PARTY;
// strSender = "system";
strSender = "";
}
else if( ::_stricmp(strSender.c_str(), "@PARTY") == 0 )
{
if( nChatType == CHAT_PARTY_SYSTEM ) return;
nChatType = CHAT_PARTY;
// strSender = "system";
strSender = "";
}
else if( ::_stricmp(strSender.c_str(), "@RAID") == 0 )
{
nChatType = CHAT_PARTY;
// strSender = "system";
strSender = "";
}
else if( ::_stricmp(strSender.c_str(), "@COMMON") == 0 )
{
nChatType = CHAT_SYSTEM;
//strSender = "system";
strSender = "";
}
else if( ::_stricmp(strSender.c_str(), "@FRIEND") == 0 )
{
nChatType = CHAT_SYSTEM;
//strSender = "system";
strSender = "";
}
else if( ::_stricmp(strSender.c_str(), "@BATTLE") == 0 )
{
return;
}
/// 2011.07.15
else if( ::_stricmp(strSender.c_str(), "@ANNOUNCE") == 0 )
{
nChatType = CHAT_ANNOUNCE;
//strSender = "system";
strSender = S(825);
}
else if(strSender.size()>0 && strSender[0] == '@' )
{
nChatType = CHAT_SYSTEM;
strSender = "";
} // by Testors
// 최종적으로 저장
// strSender = "<%%10>";
AddHistory( szText, strSender.c_str(), nChatType );
}
DWORD dwScrollRange;
int npos;
bool bEndScroll(false);
KUIControlVScroll* pScrollBar = dynamicCast<KUIControlVScroll*>(GetChild( "chat_scroll" ));
if( NULL != pScrollBar )
{
dwScrollRange = pScrollBar->GetMaxRange();
npos = pScrollBar->GetPosition();
bEndScroll = dwScrollRange-1 == npos;
}
if( !m_bScrollLbuttonDown )
{
if( bEndScroll )
UpdateChatText();
else UpdateChatText(npos, true);
}
// KUIControlEdit* pEdit = (KUIControlEdit*)GetChild( "chat_edit" );
// if( pEdit ) pEdit->SetFocus(false);
// EditAlpha(true);
m_nSelectUserIndex = -1;
}
void SUIChattingWnd::SplitChat( std::vector< std::string > & vTextList, CHATDATA & chatData )
{
bool bFirst = true;
for( std::vector< std::string >::iterator it = vTextList.begin(); it != vTextList.end(); ++it )
{
CHATDATA *pData = new CHATDATA;
if( bFirst )
{
//처음 것만 Sender 표시
pData->szSenderColor = chatData.szSenderColor;
pData->szSender = chatData.szSender;
pData->nChatType = chatData.nChatType;
pData->szColor = chatData.szColor;
bFirst = false;
if( chatData.szSender.length() ) //일반 메세지
{
pData->szText = CStringUtil::StringFormat( "<#%s>%s", chatData.szSenderColor.c_str(), (*it).c_str() ).c_str();
// 2012. 8. 7 - marine redmine_24796
// 이름 뒤에 ": " 를 검색하여 컬러태그를 붙여주는데
// offset 태그가 ": "를 ":"로 만들어서 문제 발생
// 이름 뒤의 ": "를 찾아서 없으면 ":" 를 ": "로 만들고 컬러태그를 붙여주도록 수정
std::string strSenderA = pData->szSender + ": ";
if( std::string::npos == pData->szText.find( strSenderA ) )
{
std::string strSenderB = pData->szSender + ":";
size_t npos = pData->szText.find( strSenderB );
if( std::string::npos != npos )
{
npos = pData->szText.find_first_of( ":", npos );
if( std::string::npos != npos )
pData->szText.replace( npos, 1, CStringUtil::StringFormat( ": <#%s>", chatData.szColor.c_str() ).c_str() );
}
}
else
nsl::replace( &pData->szText, ": ", CStringUtil::StringFormat( ": <#%s>", chatData.szColor.c_str() ).c_str(), 2 );
}
else //시스템 메세지
pData->szText = CStringUtil::StringFormat( "<#%s>%s", chatData.szColor.c_str(), (*it).c_str() ).c_str();
}
else
{ //두번 째 것은 타입과 기본 칼라만 복사
pData->szSenderColor = "00000000";
pData->szSender = chatData.szSender;
pData->nChatType = chatData.nChatType;
pData->szColor = chatData.szColor;
pData->szText = CStringUtil::StringFormat( "<#%s>%s", chatData.szColor.c_str(), (*it).c_str() ).c_str();
}
//모든 채널에 추가
bool bAddBuffer(false);
for( int i(0); CHAT_CHANNEL_MAX>i; i++ )
{
if( !_IsVisibleType(pData->nChatType, i) )
continue;
if( m_nChattingMode == 1 )
{
bAddBuffer = true;
AddChatList( m_vecChatList[i], pData );
}
else if( m_nChattingMode == 0 )
{
bAddBuffer = true;
if( !m_bScrollClick )
AddChatList( m_vecChatList[i], pData );
else AddTempChatList( m_vecTempChatList[i], pData );
}
else if( m_nChattingMode == 2 )
{
bAddBuffer = true;
if( !m_bScrollLbuttonDown )
AddChatList( m_vecChatList[i], pData );
else AddTempChatList( m_vecTempChatList[i], pData );
}
}
if( !bAddBuffer )
SAFE_DELETE(pData);
}
}
void SUIChattingWnd::AddChatList( CHAT_LIST& rChatList, CHATDATA* pData )
{
if( rChatList.size() > c_nMaxChatHistory ) DelHistory(rChatList);
rChatList.push_back(pData);
pData->nReferenceCnt++;
}
void SUIChattingWnd::AddTempChatList( CHAT_LIST& rChatList, CHATDATA* pData )
{
if( rChatList.size() > c_nMaxChatHistory ) DelTempHistory(rChatList);
rChatList.push_back(pData);
pData->nReferenceCnt++;
}
void SUIChattingWnd::AddHistory( const char* szText, const char* szSender, int nChatType )
{
if( !szText || ::strlen(szText)<=0 ) return;
/// 2010.11.10 - prodongi
//#ifdef _DEV
// extern bool g_bDebugMode;
//#endif
CHATDATA chatData;
chatData.szSenderColor = GetColorSender ( nChatType );
chatData.szSender = szSender;
chatData.nChatType = nChatType;
chatData.szText = szText;
/// 2010.11.10 - prodongi
//#ifdef _DEV
if (g_UserInfo.isMonkeyTail())
{
extern bool g_bDebugMode;
// 디버그 텍스트는 디버그 모드가 On 일 경우만 출력
if( CHAT_DEBUG == chatData.nChatType && g_bDebugMode == false )
return;
}
//#endif
// sender / text 세팅
switch(chatData.nChatType)
{
// case CHAT_PARTY:
// {
//서버에서 @케릭명 : 쳇내용 -> 이렇게 보내주고 있었는데 왜 그런 것인지 이유는 모르겠다.
//우선 서버에서 그냥 쳇내용만 보내도록 수정하였으니 추후에 문제가 생긴다면 수정하자 -N4-
// chatData.szText = CStringUtil::StringFormat( "# %s", FilterText(&chatData.szText) );
// chatData.szText.erase( 0, chatData.szSender.size()+3 ); //파티원 이름삭제 "+ #" 삭제 +2를 +3으로 수정 -N4-
// }
// break;
case CHAT_FRIEND:
{
chatData.szText;
}
break;
case CHAT_WHISPER:
case CHAT_GM_WHISPER:
case CHAT_HELPER_WHISPER:
{
if( !chatData.szSender.empty() )
{
std::string strTemp;
SPlayerInfo & info = m_PlayerInfoMgr.GetPlayerInfo();
if( ::_stricmp( info.GetName(), chatData.szSender.c_str() ) == 0 )
{
//strTemp = "[To:" + m_strTarget + "]";
/** 국가별 귓말 텍스트 변경 To -> 국가별 텍스트
* 2009-01-23 : hunee
*/
std::string strMsg; strMsg.clear();
strMsg = SStringDB::ParseString( GetStringDB().GetString(SYS_MSG_WHISPER_01) );
strTemp = "[" + strMsg + ": " + m_strTarget + "]";
//strTemp = "[" + strMsg + ":" + m_strTarget + "]";
}
else
{
//strTemp = "[From:" + chatData.szSender + "]";
/** 국가별 귓말 텍스트 변경 From -> 국가별 텍스트
* 2009-01-23 : hunee
*/
std::string strMsg; strMsg.clear();
strMsg = SStringDB::ParseString( GetStringDB().GetString(SYS_MSG_WHISPER_02) );
strTemp = "[" + strMsg + ": " + chatData.szSender + "]";
//strTemp = "[" + strMsg + ":" + chatData.szSender + "]";
}
chatData.szSender = strTemp;
chatData.szText = ": " + chatData.szText;
}
}
break;
case CHAT_GM:
{
std::string strTemp;
std::string strMsg; strMsg.clear();
strMsg = "ADMIN";
strTemp = "[" + strMsg + ": " + chatData.szSender + "]";
chatData.szSender = strTemp;
chatData.szText = ": " + chatData.szText;
}
break;
case CHAT_HELPER:
{
std::string strTemp;
std::string strMsg; strMsg.clear();
strMsg = "HELPEUR";
strTemp = "[" + strMsg + ": " + chatData.szSender + "]";
chatData.szSender = strTemp;
chatData.szText = ": " + chatData.szText;
}
break;
case CHAT_EXP :
case CHAT_DAMAGE :
case CHAT_ITEM :
case CHAT_BATTLE :
case CHAT_SUMMON :
case CHAT_ETC :
case CHAT_COMMUNITY :
case CHAT_DEBUG :
case CHAT_EXT_DAMAGE :
case CHAT_SYSTEM :
{
// chatData.szText = chatData.szText;
XStringUtil::Replace( chatData.szText, "|", "" );
}
break;
case CHAT_PARTY_SYSTEM:
{
if( strnicmp( szText, "/requestparty", strlen("/requestparty") ) == 0 && strlen(szText) > 2 )
{
std::vector< std::string > vString;
XStringUtil::Split( szText, vString, " " );
int nJobID = atoi(vString[3].c_str());
std::string strJobName = GetJobDB().GetJobName(nJobID);
chatData.szText = "<B>"+SR(SYS_MSG_PARTY_INVITE_REQUEST, "#@user_name@#", vString[1].c_str(), "#@level@#", vString[2].c_str(),"#@job_name@#",strJobName.c_str())+"</B>";
chatData.nChatType = CHAT_PARTY; //CHAT_PARTY
nChatType = CHAT_PARTY; //CHAT_PARTY
chatData.szSender = "";
}
else
return;
} break;
default:
{
//chatData.szText = ":" + chatData.szText; // 다시 넣었음. by Testors
// 2012. 1. 3 - marine ':'다음에 한칸 띄움....
/* 이렇게 수정된 이유.
**2바이트를 사용하는 국가에서 캐릭터 이름이 "아자abc" 인 유저가 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 와 같이
한라인을 넘기는 공백없는 긴문자를 채팅으로 입력하게 되면 "아자" 와 "abcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 가 따로 출력되어
유저의 캐릭터 명이 짤리고 원하는 출력도 되지 않는 경우가 발생...
**Textparser를 분석해본 결과 한라인을 넘어가는 문자의 경우에 '공백문자' 또는 '2바이트문자 다음의 1바이트 문자'를 기준으로 라인을 나누는데서 문제가 발생함.
Textparser를 프로젝트 전반에 걸처 사용되기 때문에 ':'를 구분자로 사용하는 것은 또 다른 버그를 유발하게 될지도 모른다고 판단되어 강제로 ':'뒤에 공백문자를 붙여주게됨...
*/
chatData.szText = ": " + chatData.szText;
}
break;
}
// 저장하기
chatData.szColor = GetColorText(chatData.nChatType);
if( !chatData.szText.empty() )
{
std::string strText;
if( chatData.szSender.length() )
strText = chatData.szSender;
strText += chatData.szText;
XStringUtil::Replace( strText, "<BR>", "\n" );
XStringUtil::Replace( strText, "<br>", "\n" );
std::vector< std::string > vTextList;
MsgSplit( strText.c_str(), vTextList, L"\n" );
KUIControlStatic* pLine = dynamicCast<KUIControlStatic*>(GetChild( "chat_line00" ));
if( pLine )
{
//각 문자열을 컨트롤 크기만큼 자른다.
for( unsigned int i(0); vTextList.size()>i; i++ )
{
KSize size = KTextPhrase::GetStringSize( CStringUtil::StringFormat("<size:9>%s%s", S(6425), vTextList[i].c_str()).c_str(), 512 );
if( size.width < pLine->GetRect().GetWidth() )
{
STRING_VECTOR vecLineList;
vecLineList.push_back( vTextList[i].c_str() );
SplitChat( vecLineList, chatData );
}
else
{
STRING_VECTOR vecLineList;
pLine->SplitLine( vecLineList, vTextList[i].c_str(), S(6426), 9 );
SplitChat( vecLineList, chatData );
}
}
}
vTextList.clear();
}
}
bool SUIChattingWnd::IsScrollEnd()
{
KUIControlVScroll* pScrollBar = dynamicCast<KUIControlVScroll*>(GetChild( "chat_scroll" ));
if( NULL != pScrollBar )
{
int dwScrollRange = pScrollBar->GetMaxRange();
int npos = pScrollBar->GetPosition();
if( dwScrollRange-1 == npos )
return true;
}
return false;
}
void SUIChattingWnd::UpdateChatText( int nRange /*= 0*/, bool bScroll /*=false*/ )
{
for( int i = 0; i < CHAT_MAX_LIST; i++ )
{
if( m_pStaticHistories[i] )
{
m_pStaticHistories[i]->SetCaption("");
m_vecChatSneder[i].clear();
}
}
if( m_nTabType >= CHAT_CHANNEL_MAX ) return;
if( m_vecChatList[m_nTabType].size() <= 0 ) return;
if( m_vecChatList[m_nTabType].size() <= m_nMaxLine ) nRange = 0;
m_nCurChatCount = static_cast<int>(m_vecChatList[m_nTabType].size());
m_nCurChatCount = max( m_nCurChatCount, 0 );
int nScrollPos = nRange + m_nMaxLine;
if( nRange == 0 && !bScroll ) nScrollPos = m_nCurChatCount-1;
if( nScrollPos>=m_nCurChatCount ) nScrollPos = m_nCurChatCount-1;
int nEndPos( nScrollPos-m_nMaxLine );
int nCurIndex = m_nMaxLine-1;
for( int i = nScrollPos; i >= 0 && i >= nEndPos; i-- )
{
CHATDATA* pData = m_vecChatList[m_nTabType][i];
if( pData )
{
// if( CHAT_MAX_LIST > nCurIndex && nCurIndex >= 0 && m_pStaticHistories[nCurIndex] )
if( m_nMaxLine > nCurIndex && nCurIndex >= 0 && nCurIndex < CHAT_MAX_LIST )
{
if( m_pStaticHistories[nCurIndex] )
{
#ifdef _DEBUG
m_pStaticHistories[nCurIndex]->SetCaption( CStringUtil::StringFormat("%s<SIZE:9><SHADOW>%s</SHADOW><#ffffff><SIZE:10>(%d)", S(6425), pData->szText.c_str(), i).c_str(), false );
#else
m_pStaticHistories[nCurIndex]->SetCaption( CStringUtil::StringFormat("%s<SIZE:9><SHADOW>%s</SHADOW>", S(6425), pData->szText.c_str()).c_str(), false );
#endif
if( pData->nChatType == CHAT_WHISPER ||
pData->nChatType == CHAT_GM_WHISPER ||
pData->nChatType == CHAT_HELPER ||
pData->nChatType == CHAT_HELPER_WHISPER ||
pData->nChatType == CHAT_GM)
{
std::string strRealSender;
WhisperSenderFillter(pData->szSender, strRealSender);
m_vecChatSneder[nCurIndex] = strRealSender;
}
else if ( pData->nChatType == CHAT_PARTY )
{
m_vecChatSneder[nCurIndex] = pData->szSender + "<>";
}
else
m_vecChatSneder[nCurIndex] = pData->szSender;
}
}
nCurIndex--;
}
}
if( !m_bScrollLbuttonDown )
{
bool bCrrPos( !IsScrollEnd() && bScroll );
RefreshScrollbar(bCrrPos);
}
}
void SUIChattingWnd::WhisperSenderFillter( std::string& strSender, std::string& strRealSender )
{
if( strSender.empty() ) return;
strRealSender = strSender;
std::string::size_type Pos = strRealSender.find(": ");
//std::string::size_type Pos = strRealSender.find(":");
if( Pos == std::string::npos ) return;
/// 공백 + 1을 해준다
strRealSender.erase(0, Pos+2);
//strRealSender.erase(0, Pos+1);
int nSize( strRealSender.size() );
strRealSender.erase(nSize-1, nSize);
}
int SUIChattingWnd::GetChattingType( int nChatType )
{
/// 2010.11.10 - prodongi
//#ifdef _DEV
extern bool g_bDebugMode;
//#endif
int nType = -1;
switch(nChatType)
{
//사용자 채팅
case CHAT_NORMAL : nType = CHAT_CHECK_01; break; // 일반채팅
case CHAT_GLOBAL : nType = CHAT_CHECK_02; break; // 전체메세지
case CHAT_YELL : nType = CHAT_CHECK_02; break; // 외치기
case CHAT_ADV : nType = CHAT_CHECK_03; break; // 광고채팅
case CHAT_GM_WHISPER :
case CHAT_HELPER_WHISPER :
case CHAT_WHISPER : nType = CHAT_CHECK_04; break; // 귓속말
//그룹 채팅
case CHAT_PARTY : nType = CHAT_CHECK_07; break; // 파티
case CHAT_GUILD : nType = CHAT_CHECK_08; break; // 길드
case CHAT_ATTACKTEAM : nType = CHAT_CHECK_09; break; // 공대
case CHAT_NOTICE :
case CHAT_GM :
case CHAT_HELPER:
case CHAT_ANNOUNCE: /// 2011.07.15
case CHAT_CENTER_NOTICE:
return true; // 공지, GM 채팅 : 항상 출력
//시스템 메세지
case CHAT_EXP : nType = CHAT_CHECK_11; break; // 경험치 관련
case CHAT_DAMAGE : nType = CHAT_CHECK_13; break; // 데미지 (공격&마법데미지양)
case CHAT_EXT_DAMAGE : nType = CHAT_CHECK_14; break; // 확장데미지
case CHAT_ITEM : nType = CHAT_CHECK_15; break; // 아이템 관련
case CHAT_BATTLE : nType = CHAT_CHECK_16; break; // 전투관련
case CHAT_SUMMON : nType = CHAT_CHECK_17; break; // 소환수 관련
case CHAT_ETC : nType = CHAT_CHECK_18; break; // 기타
case CHAT_COMMUNITY : nType = CHAT_CHECK_12; break; // 커뮤니티 메세지
/// 2010.11.10 - prodongi
//#ifdef _DEV
case CHAT_DEBUG : return g_bDebugMode; // 디버그 메세지 : 디버그 모드 on 일때 출력
//#endif
case CHAT_SYSTEM : nType = CHAT_CHECK_18; break; // 게임 System 메세지
}
return nType;
}
// 채팅 옵션
bool SUIChattingWnd::_IsVisibleType( int nChatType, int nTabType )
{
int nType = GetChattingType(nChatType);
if( nType >= CHAT_CHECK_01 && nType < CHAT_CHECK_06 )
{
if( GetGameOption().IsChatOptionCheck( nTabType, CHAT_CHECK_00 ) == false )
return false;
}
else if( nType >= CHAT_CHECK_07 && nType < CHAT_CHECK_10 )
{
if( GetGameOption().IsChatOptionCheck( nTabType, CHAT_CHECK_06 ) == false )
return false;
}
else if( nType >= CHAT_CHECK_11 )
{
if( GetGameOption().IsChatOptionCheck( nTabType, CHAT_CHECK_10 ) == false )
return false;
}
//개별 검사
return GetGameOption().IsChatOptionCheck( nTabType, nType );
}
bool SUIChattingWnd::IsVisibleType( int nChatType )
{
return _IsVisibleType(nChatType, m_nTabType);
}
///////////////////////////////////////
// 서버에 요청
///////////////////////////////////////
void SUIChattingWnd::RequestChatText()
{
KUIControlEdit* pEditConsole = dynamicCast<KUIControlEdit*>(GetChild( "chat_edit" ));
if( NULL == pEditConsole ) return;
//170 자만 체팅이 가능하다.
std::string strText = pEditConsole->GetText();
if( strText.empty() ) return;
m_pGameManager->StartSound( "ui_button_click.wav" );
if( strText.size()>=c_nEditLimit )
{
std::string::iterator it = strText.begin();
it+=169;
strText.erase(it, strText.end() );
}
// char szText[c_nEditLimit];
// szText[_countof(szText)-1] = '\0';
// if( strlen( pEditConsole->GetText() ) >= c_nEditLimit )
// ::strncpy( szText, pEditConsole->GetText(), _countof(szText)-1 );
// else
// ::strcpy( szText, pEditConsole->GetText() );
std::string strMark = GetGameOption().GetChatTabMark(m_nTabType);
if( ::_stricmp( strText.c_str(), strMark.c_str() ) == 0 ) return;
strMark += " ";
if( ::_stricmp( strText.c_str(), strMark.c_str() ) == 0 ) return;
#ifdef _DEV
// bintitle. 2011.11.09. 이전 채팅문자열 저장.
m_strPreChatSave = strText;
//GetLog().Log("_CHAT_SAVE : %s\n", m_strPreChatSave.c_str() );
#endif
//// 파티말은 모두 스킵
//if( !FilterParty(strText) )
//{
// pEditConsole->SetText( "" );
// return;
//}
// strText = FilterText(&strText);
int nType = FilterType(strText);
if (!checkIsValidArenaRequest(strText, nType))
{
return ;
}
//특수 문자 삭제
if( ::_strnicmp( strText.c_str(), szParty , 1 ) == 0 ||
::_strnicmp( strText.c_str(), szGuild , 1 ) == 0 ||
::_strnicmp( strText.c_str(), szAd , 1 ) == 0 ||
::_strnicmp( strText.c_str(), szWhisper, 1 ) == 0 ||
::_strnicmp( strText.c_str(), szYell , 1 ) == 0 ||
::_strnicmp( strText.c_str(), szSiege , 1 ) == 0 ) strText.erase(0,1);
// 텍스트가 비어 있으면 리턴
if( ::strlen( strText.c_str() ) <= 0 || ::_stricmp( strText.c_str(), "err" ) == 0 ) return;
std::string strTarget;
if( nType == CHAT_WHISPER || nType == CHAT_GM_WHISPER )
{
std::string strTempText( strText );
if( WhisperFillter( strTempText, strTarget, strText ) )
{
// if( ::_strnicmp( strText.c_str(), "/", 1 ) == 0 )
if( ::_strnicmp( strTempText.c_str(), "/", 1 ) == 0 )
nType = CHAT_NORMAL;
else
AddWhisperUser( strTarget.c_str() );
/*
const char* pPlayerName = m_PlayerInfoMgr.GetPlayerInfo().GetName();
if( strTarget == pPlayerName )
{
strTarget.clear();
nType = CHAT_NORMAL;
}*/
}
else
nType = CHAT_NORMAL;
}
//유저들이 메모장에서 복사해서 체팅창을 사용할 경우 \n을 붙일 수 있는데 이건 무시한다...
FillterBR(strText);
// 서버에 채팅 요청
SMSG_CHATTING_REQUEST msgChatReq;
memset( msgChatReq.szTarget, 0, sizeof(msgChatReq.szTarget) );
msgChatReq.type = nType;
if( msgChatReq.type == CHAT_NORMAL || msgChatReq.type == CHAT_YELL || msgChatReq.type == CHAT_ADV || msgChatReq.type == CHAT_WHISPER
|| msgChatReq.type == CHAT_GLOBAL || msgChatReq.type == CHAT_PARTY || msgChatReq.type == CHAT_GUILD || msgChatReq.type == CHAT_ATTACKTEAM
|| msgChatReq.type == CHAT_FRIEND )
{
TagFillter(strText);
}
switch( msgChatReq.type )
{
case CHAT_NOTICE:
msgChatReq.strText = CStringUtil::StringFormat( "/run notice(\"%s\")", strText.c_str() );
break;
case CHAT_PARTY:
msgChatReq.strText = CStringUtil::StringFormat( "%s", strText.c_str() );
break;
case CHAT_YELL:
{
SPlayerInfo & info = m_PlayerInfoMgr.GetPlayerInfo();
if( info.GetStatus() & TS_ENTER::PlayerInfo::FLAG_GM )
{
msgChatReq.type = CHAT_GLOBAL;
msgChatReq.strText = strText;
}
else
{
// 임시로 global 로 처리
if( !m_bYell )
{
msgChatReq.type = CHAT_GLOBAL;
msgChatReq.strText = strText;
m_dwYellTime = m_dwTime;
m_bYell = true;
}
else
{
m_pDisplayInfo->AddSystemMessage( S(507), 99 ); // You just sent a message. You must wait a moment before you can send another
return;
}
}
}
break;
case CHAT_GM_WHISPER:
case CHAT_HELPER_WHISPER:
case CHAT_WHISPER:
{
std::string strTemp = strText;
if( FilterType(strText) == CHAT_WHISPER )
{
strText = GetTarget(&strText);
if( ::_stricmp( strText.c_str(), "err" ) == 0 ) // 일반 채팅으로 취급
{
msgChatReq.type = CHAT_NORMAL;
msgChatReq.strText = strTemp;
break;
}
strcpy( msgChatReq.szTarget, m_strTarget.c_str() );
msgChatReq.strText = strText;
m_vecWhisperList.insert(m_vecWhisperList.begin(), strText); // 귓말 저장
}
else
{
if( strTarget.size() > 0 )
{
strcpy( msgChatReq.szTarget, strTarget.c_str() );
msgChatReq.strText = strText;
m_strTarget = strTarget;
m_vecWhisperList.insert(m_vecWhisperList.begin(), strText); // 귓말 저장
break;
}
}
}
break;
default:
{
if ( NULL == strText.compare( 0, 5, "/info" ) )
{
g_GMDEV = !g_GMDEV;
}
if ( NULL == strText.compare( 0, 11, "/autotarget" ) )
{
GetGameOption().InvertAutoTarget();
}
// If in Korea and the user is a GM (administrator)
if( GameRule::GetCurrentLocalBitSet() == GameRule::LOCAL_BITSET::KR &&
g_pCurrentGameSystem->GetLocalPlayerPermission() > 0 )
{
std::string strCmdItemFindKor( "//아아 " );
std::string strCmdItemFindEng( "//itemid " );
std::string strCmdNPCFindKor( "//엔아 " );
std::string strCmdNPCFindEng( "//npcid " );
std::string strCommand( "" );
if( NULL == strText.compare( 0, 7, strCmdItemFindKor ) ||
NULL == strText.compare( 0, 9, strCmdItemFindEng ) )
{
char szBuffer_Command[32] = { NULL, };
if( NULL == strText.compare( 0, 7, strCmdItemFindKor ) )
strText.copy( szBuffer_Command, 7, 0 );
if( NULL == strText.compare( 0, 9, strCmdItemFindEng ) )
strText.copy( szBuffer_Command, 9, 0 );
strCommand.append( szBuffer_Command );
XStringUtil::Replace( strText, strCommand, "" );
vector<nsItemDB::ITEMIDENTITYFORDEV> vecItemIdentity = GetItemDB().GetItemIdentityList( strText );
for( UINT nCount = 0; nCount < vecItemIdentity.size(); nCount++ )
{
string strOutput = CStringUtil::StringFormat( "ItemID - [ %u ]", vecItemIdentity[nCount].m_uItemID );
strOutput.append( ", ItemName - [ " );
strOutput.append( vecItemIdentity[nCount].m_strItemName );
strOutput.append( " ]" );
if( m_pDisplayInfo )
m_pDisplayInfo->AddSystemMessage( strOutput.c_str() );
}
pEditConsole->SetText("");
pEditConsole->SetCaption("");
return;
}
else if( NULL == strText.compare( 0, 7, strCmdNPCFindKor ) ||
NULL == strText.compare( 0, 9, strCmdNPCFindEng ) )
{
char szBuffer_Command[32] = { NULL, };
if( NULL == strText.compare( 0, 7, strCmdNPCFindKor ) )
strText.copy( szBuffer_Command, 7, 0 );
if( NULL == strText.compare( 0, 9, strCmdNPCFindEng ) )
strText.copy( szBuffer_Command, 9, 0 );
strCommand.append( szBuffer_Command );
XStringUtil::Replace( strText, strCommand, "" );
vector<NPCIDENTITYFORDEV> vecNpcIdentity = GetNpcResourceDB().GetNpcIdentityList( strText );
for( UINT nCount = 0; nCount < vecNpcIdentity.size(); nCount++ )
{
string strOutput = CStringUtil::StringFormat( "NpcID - [ %u ]", vecNpcIdentity[nCount].m_uNpcID );
strOutput.append( ", NPCName - [ " );
strOutput.append( vecNpcIdentity[nCount].m_strNpcName );
strOutput.append( " ]" );
if( m_pDisplayInfo )
m_pDisplayInfo->AddSystemMessage( strOutput.c_str() );
}
pEditConsole->SetText("");
pEditConsole->SetCaption("");
return;
}
}
msgChatReq.strText = strText;
}
break;
}
pEditConsole->SetText("");
pEditConsole->SetCaption("");
m_pGameManager->ProcMsgAtStatic( &msgChatReq );
SetChatType();
/// 2010.11.15 - prodongi
#ifdef _DEV
saveLocalAvatarPos(strText);
#endif
}
void SUIChattingWnd::TagFillter( std::string& strChat )
{
EraseColorTag(strChat);
for( int i(0); i<c_nFillterTagCnt; ++i )
{
EraseTag( strChat, c_szFillterTag[i] );
}
}
//채팅창에 태그 나오는 부분 수정
//2009-06-30 : hunee
void SUIChattingWnd::EraseColorTag( std::string& strChat )
{
//color
int nsPos = strChat.find("<#");
int nePos = strChat.find(">", nsPos);
int eraseCnt = 0;
while( nsPos != -1 && nePos != -1 && nePos > nsPos )
{
eraseCnt = nePos - nsPos + 1;
strChat.erase( nsPos, eraseCnt );
nsPos = strChat.find("<#");
nePos = strChat.find(">", nsPos);
}
//erase #@ @#
nsPos = strChat.find("#@");
nePos = strChat.find("@#", nsPos);
eraseCnt = 0;
while( nsPos != -1 && nePos != -1 && nePos > nsPos )
{
eraseCnt = nePos - nsPos + 2;
strChat.erase( nsPos, eraseCnt );
nsPos = strChat.find("#@");
nePos = strChat.find("@#", nsPos);
}
// erase <>
nsPos = strChat.find("<");
nePos = strChat.find(">", nsPos);
eraseCnt = 0;
while( nsPos != -1 && nePos != -1 && nePos > nsPos )
{
eraseCnt = nePos - nsPos + 1;
strChat.erase( nsPos, eraseCnt );
nsPos = strChat.find("<");
nePos = strChat.find(">", nsPos);
}
}
void SUIChattingWnd::EraseTag( std::string& strChat, const char* lpTag )
{
int nPos = strChat.find(lpTag);
while( nPos != -1 )
{
strChat.erase( nPos, nPos+sizeof(lpTag) );
nPos = strChat.find(lpTag);
}
}
bool SUIChattingWnd::WhisperFillter( const std::string& strChat, std::string& strPlayer, std::string& strText )
{
if( strChat.empty() ) return false;
std::string strTemp = strChat;
size_t WhisperPos = strTemp.find(" ");
if( WhisperPos != std::string::npos )
{
strPlayer = strTemp.substr(0, WhisperPos);
strTemp.erase(0, WhisperPos+1);
strText = strTemp;
return true;
}
return false;
}
void SUIChattingWnd::AddWhisperUser( const char* pName )
{
if( pName == NULL || ::strlen(pName) == 0 ) return;
m_cacheWhisperUser.push( pName );
}
std::string SUIChattingWnd::GetColorSender ( int nType )
{
switch(nType)
{
case CHAT_NORMAL : return CStringUtil :: StringFormat( "3bc5fe" );
case CHAT_WHISPER: return CStringUtil :: StringFormat( "ffde00" );
case CHAT_PARTY : return CStringUtil :: StringFormat( "97ff00" );
case CHAT_GUILD : return CStringUtil :: StringFormat( "d26efc" );
case CHAT_ATTACKTEAM : return CStringUtil :: StringFormat( "3862ed" ); ///aliance chat original color #3862ed
case CHAT_ADV : return CStringUtil :: StringFormat( "00fffc" );
case CHAT_NOTICE : return CStringUtil :: StringFormat( "ffea00" );
case CHAT_CENTER_NOTICE : return CStringUtil :: StringFormat( "ffea00" );
case CHAT_GM_WHISPER:
case CHAT_GM : return CStringUtil :: StringFormat( "ff9900" );
case CHAT_HELPER_WHISPER:
case CHAT_HELPER: return CStringUtil::StringFormat("97ff00");
case CHAT_GLOBAL : return CStringUtil :: StringFormat( "3bc5fe" );
case CHAT_YELL : return CStringUtil :: StringFormat( "3bc5fe" );
case CHAT_EXP : return CStringUtil :: StringFormat( "fdddb0" );
case CHAT_DAMAGE : return CStringUtil :: StringFormat( "fdddb0" );
case CHAT_ITEM : return CStringUtil :: StringFormat( "fdddb0" );
case CHAT_BATTLE : return CStringUtil :: StringFormat( "fdddb0" );
case CHAT_SUMMON : return CStringUtil :: StringFormat( "fdddb0" );
case CHAT_ETC : return CStringUtil :: StringFormat( "fdddb0" );
case CHAT_EXT_DAMAGE : return CStringUtil :: StringFormat( "fdddb0" );
case CHAT_COMMUNITY : return CStringUtil :: StringFormat( "fda72d" );
case CHAT_DEBUG : return CStringUtil :: StringFormat( "FFFFFF" );
case CHAT_SYSTEM : return CStringUtil :: StringFormat( "fdddb0" );
case CHAT_ANNOUNCE : return CStringUtil :: StringFormat( "00FF00" ); /// 2011.07.15
}
return CStringUtil :: StringFormat( "3bc5fe" );
}
///////////////////////////////////
// 컬러
///////////////////////////////////
// 채팅창 컬러
std::string SUIChattingWnd::GetColorText( int nType )
{
switch(nType)
{
case CHAT_NORMAL : return CStringUtil :: StringFormat( "ffffff" );
case CHAT_WHISPER: return CStringUtil :: StringFormat( "ffffff" );
case CHAT_PARTY : return CStringUtil :: StringFormat( "d7fd8d" );
case CHAT_GUILD : return CStringUtil :: StringFormat( "f3b9fd" );
case CHAT_ATTACKTEAM : return CStringUtil :: StringFormat( "8ca2eb" );
case CHAT_ADV : return CStringUtil :: StringFormat( "00fffc" );
case CHAT_NOTICE : return CStringUtil :: StringFormat( "ffea00" );
case CHAT_CENTER_NOTICE : return CStringUtil :: StringFormat( "ffea00" );
case CHAT_ANNOUNCE: return CStringUtil::StringFormat("00ff00" ); /// 2011.07.15
case CHAT_GM_WHISPER:
case CHAT_GM : return CStringUtil :: StringFormat( "ff9900" );
case CHAT_HELPER_WHISPER:
case CHAT_HELPER: return CStringUtil::StringFormat("97ff00");
case CHAT_GLOBAL : return CStringUtil :: StringFormat( "a9e9fe" );
case CHAT_YELL : return CStringUtil :: StringFormat( "a9e9fe" );
case CHAT_EXP : return CStringUtil :: StringFormat( "fdddb0" );
case CHAT_DAMAGE : return CStringUtil :: StringFormat( "fdddb0" );
case CHAT_ITEM : return CStringUtil :: StringFormat( "fdddb0" );
case CHAT_BATTLE : return CStringUtil :: StringFormat( "fdddb0" );
case CHAT_SUMMON : return CStringUtil :: StringFormat( "fdddb0" );
case CHAT_ETC : return CStringUtil :: StringFormat( "fdddb0" );
case CHAT_EXT_DAMAGE : return CStringUtil :: StringFormat( "fdddb0" );
case CHAT_COMMUNITY : return CStringUtil :: StringFormat( "fdddb0" );
case CHAT_DEBUG : return CStringUtil :: StringFormat( "FFFFFF" );
case CHAT_SYSTEM : return CStringUtil :: StringFormat( "fdddb0" );
}
return CStringUtil :: StringFormat( "ffffff" );
}
// 에디터창 컬러
KColor SUIChattingWnd::GetColor( std::string& rText )
{
std::string szFilter = rText.substr( 0, 1 );
int nType = FilterType(szFilter);
return GetColor(nType);
}
KColor SUIChattingWnd::GetColor( int nType )
{
switch(nType)
{
case CHAT_NORMAL: return KColor( 0xFFFFFFFF );
case CHAT_WHISPER: return KColor( 0xFFFFD200 );
case CHAT_PARTY: return KColor( 0xFFC6FF00 );
case CHAT_ADV: return KColor( 0xFF00FFFC );
case CHAT_NOTICE: return KColor( 0xFFFFEA00 );
case CHAT_CENTER_NOTICE: return KColor( 0xFFFFEA00 );
case CHAT_ANNOUNCE: return KColor( 0xFF00FF00 ); /// 2011.07.15
case CHAT_GUILD: return KColor( 0xFFFC81F2 );
case CHAT_ATTACKTEAM: return KColor( 0xFF3862ED );
case CHAT_DEBUG:
case CHAT_SYSTEM: return KColor( 0xFFFDDDB0 );
case CHAT_PARTY_SYSTEM: return KColor( 0xF1C1F100 );
}
return KColor( 0xFFFFFFFF );
}
/////////////////////////////////////////////////////
// 탭
/////////////////////////////////////////////////////
void SUIChattingWnd::SetChatType()
{
/// 2012.05.02 - prodongi
if (setArenaFilterToChatEdit())
return ;
m_strPreText = "";
m_strFilter = "";
KUIControlEdit* pEdit = dynamicCast<KUIControlEdit*>(GetChild( "chat_edit" ));
// KUIControlEdit* pNameEdit = ( KUIControlEdit* )GetChild( "chat_catagory_edit" );
if( pEdit == NULL /*|| pNameEdit == NULL*/ ) return;
switch(m_nTabType)
{
case KIND_ALLMSG: m_strFilter = ""; break;
// case KIND_WHISPER:
case KIND_PARTY: m_strFilter = GetGameOption().GetChatTabMark(m_nTabType); break;
case KIND_GUILD: m_strFilter = GetGameOption().GetChatTabMark(m_nTabType); break;
case KIND_AD: m_strFilter = GetGameOption().GetChatTabMark(m_nTabType); break;
default: m_strFilter = ""; break;
}
std::string szText = pEdit->GetText();
if( szText.size() > 0 )
{
szText = FilterText(&szText);
if( ::_stricmp( szText.c_str(), "err" ) == 0 ) szText = "";
}
std::string::iterator it = szText.begin();
while( it != szText.end() )
{
const char Text = *it;
if( Text == ' ' )
it = szText.erase(it);
else break;
}
KColor color = GetColor( GetTypeByTab() );
pEdit->SetFontColor( color );
if( m_strFilter.size()>1 )
m_strFilter += " ";
std::string szInput = CStringUtil::StringFormat("%s%s", m_strFilter.c_str(), szText.c_str());
if( !szInput.empty() )
m_strPreText = szInput;
pEdit->SetText( szInput.c_str() );
}
int SUIChattingWnd::GetTypeByTab()
{
switch(m_nTabType)
{
case KIND_ALLMSG: return CHAT_NORMAL;
case KIND_WHISPER: return CHAT_WHISPER;
case KIND_PARTY: return CHAT_PARTY;
case KIND_GUILD: return CHAT_GUILD;
case KIND_AD: return CHAT_ADV;
case KIND_SIEGE: return CHAT_ATTACKTEAM;
}
return CHAT_NORMAL;
}
/////////////////////////////////////////////
// 필터링
/////////////////////////////////////////////
const char* SUIChattingWnd::FilterText( std::string* str )
{
if( str->size() <= 0 ) return "err";
std::string strMark;
switch(m_nOldTabType)
{
case KIND_PARTY: strMark = GetGameOption().GetChatTabMark(m_nOldTabType); break;
case KIND_GUILD: strMark = GetGameOption().GetChatTabMark(m_nOldTabType); break;
case KIND_AD: strMark = GetGameOption().GetChatTabMark(m_nOldTabType); break;
default: strMark = GetGameOption().GetChatTabMark(m_nOldTabType); break;
}
if( strMark.length() <= 0 ) return str->c_str();
//이전 키워드와 같은 것 삭제
//키워드 검사
if( ::_strnicmp( str->c_str(), strMark.c_str(), strMark.length() ) == 0 )
{
std::string::iterator it = str->begin();
str->erase( 0, strMark.length() );
}
if( str->size() <= 0 ) return "err";
return str->c_str();
}
int SUIChattingWnd::FilterType( std::string& str )
{
if( str.size() <= 0 ) return CHAT_NORMAL;
std::string szText = str.substr(0, 1);
if( ::_stricmp( szText.c_str(), szParty ) == 0 ) return CHAT_PARTY;
else if( ::_stricmp( szText.c_str(), szGuild ) == 0 ) return CHAT_GUILD;
else if( ::_stricmp( szText.c_str(), szAd ) == 0 ) return CHAT_ADV;
else if( ::_stricmp( szText.c_str(), szWhisper ) == 0 ) return CHAT_WHISPER;
else if( ::_stricmp( szText.c_str(), szYell ) == 0 ) return CHAT_YELL;
else if( ::_stricmp( szText.c_str(), szSiege ) == 0 ) return CHAT_ATTACKTEAM;
//if( m_nTabType == KIND_NOTICE ) return CHAT_NOTICE;
return CHAT_NORMAL;
}
bool SUIChattingWnd::FilterParty( std::string & str )
{
if( str.size() < 5 ) return true;
if( str[0] != '/' ) return true;
if( str.find( "/p" ) < 0 ) return true;
std::string strText = str.substr( 0, 9 );
if( ::_stricmp( strText.c_str(), "/pcreate" ) == 0 || ::_stricmp( strText.c_str(), "/set_party" ) == 0 ) return false;
if( ::_stricmp( strText.c_str(), "/pinvite" ) == 0 || ::_stricmp( strText.c_str(), "/invite" ) == 0) return false;
if( ::_stricmp( strText.c_str(), "/pkick" ) == 0 || ::_stricmp( strText.c_str(), "/ban" ) == 0) return false;
if( ::_stricmp( strText.c_str(), "/pdestroy" ) == 0 ) return false;
if( ::_stricmp( strText.c_str(), "/pleave" ) == 0 || ::_stricmp( strText.c_str(), "/leave" ) == 0) return false;
if( ::_stricmp( strText.c_str(), "/plist" ) == 0 ) return false;
if( ::_stricmp( strText.c_str(), "/pshare" ) == 0 ) return false;
if( ::_stricmp( strText.c_str(), "/ppromote" ) == 0 ) return false;
return true;
}
///////////////////////////////////////////////
// 귓속말
///////////////////////////////////////////////
void SUIChattingWnd::UpdateWhisperList( int nResult )
{
if( nResult == RESULT_SUCCESS )
{
if( m_vecWhisperList.size() <= 0 ) return;
SPlayerInfo & info = m_PlayerInfoMgr.GetPlayerInfo();
AddChatText( m_vecWhisperList[0].c_str(), info.GetName(), CHAT_WHISPER );
if( m_vecWhisperList.size() <= 0 ) return;
m_vecWhisperList.erase(m_vecWhisperList.begin());
}
else if( nResult == RESULT_NOT_EXIST )
{
// 귓속말 대화 상대가 없는 경우
AddChatText( GetStringDB().GetString(501), "system", CHAT_WHISPER );
if( m_vecWhisperList.size() <= 0 ) return;
m_vecWhisperList.erase(m_vecWhisperList.begin());
m_cacheWhisperUser.pop_front( );
}
else if( nResult == RESULT_ACCESS_DENIED )
{
AddChatText( GetStringDB().GetString(479), "", CHAT_SYSTEM );
if( m_vecWhisperList.size() <= 0 ) return;
m_vecWhisperList.erase(m_vecWhisperList.begin());
m_cacheWhisperUser.pop_front( );
}
// 자신이 채팅 금지 당했을 경우.
else if( nResult == RESULT_BLOCK_CHAT)
{
if( m_vecWhisperList.size() <= 0 ) return;
m_vecWhisperList.erase(m_vecWhisperList.begin());
m_cacheWhisperUser.pop_front( );
}
}
const char* SUIChattingWnd::GetTarget( std::string* str )
{
if( str->size() <= 0 ) return "err";
std::string szText = *str;
std::string::size_type cpos=-1;
// target
int nPos = (int)szText.find( ' ' );
if( cpos == nPos ) return "err";
if( cpos == szText.length() ) return "err";
szText.erase( nPos, szText.length() );
m_strTarget = szText;
// text
*str = str->substr( nPos+1, str->length()-nPos );
return str->c_str();
}
void SUIChattingWnd::AddAutoMsgInfo( AutoMsgInfo* pAutoMsgInfo )
{
// 2010.09.02 - prodongi
//m_vAutoMsgInfo.push_back( pAutoMsgInfo );
it_autoMsgInfo it;
if (findAutoMsgInfo(pAutoMsgInfo, it))
{
it->second->m_bEnd = pAutoMsgInfo->m_bEnd;
it->second->m_bUseMsgCount = pAutoMsgInfo->m_bUseMsgCount;
it->second->m_dwAutoMsgTime = pAutoMsgInfo->m_dwAutoMsgTime;
it->second->m_dwDelayTime = pAutoMsgInfo->m_dwDelayTime;
it->second->m_nMsgCount = pAutoMsgInfo->m_nMsgCount;
it->second->m_strMsg = pAutoMsgInfo->m_strMsg;
it->second->m_strTag1 = pAutoMsgInfo->m_strTag1;
SAFE_DELETE(pAutoMsgInfo);
}
else
{
std::string key = AutoMsg::makeKey(pAutoMsgInfo);
m_autoMsgInfo.insert(std::make_pair(key, pAutoMsgInfo));
}
}
void SUIChattingWnd::OutputAutoMsgWithMsgCount( AutoMsgInfo* pAutoMsgInfo )
{
if( (m_dwTime - pAutoMsgInfo->m_dwAutoMsgTime) > pAutoMsgInfo->m_dwDelayTime )
{
pAutoMsgInfo->m_dwAutoMsgTime = m_dwTime;
//SUiDisplayInfo에서 출력 시켜야함
AddChatText( GetStringDB().ParseString( GetStringDB().GetString(pAutoMsgInfo->m_nSystemMsg), pAutoMsgInfo->m_strTag1.c_str(), GetStringDB().ToString( pAutoMsgInfo->m_nMsgCount ).c_str() ).c_str(), "", CHAT_ETC );
--pAutoMsgInfo->m_nMsgCount;
if( pAutoMsgInfo->m_nMsgCount <= 0 )
pAutoMsgInfo->SetEnd(true);
}
}
void SUIChattingWnd::OutputAutoMsg( AutoMsgInfo* pAutoMsgInfo )
{
if( (m_dwTime - pAutoMsgInfo->m_dwAutoMsgTime) > pAutoMsgInfo->m_dwDelayTime )
{
pAutoMsgInfo->m_dwAutoMsgTime = m_dwTime;
//SUiDisplayInfo에서 출력 시켜야함
if( !pAutoMsgInfo->m_strMsg.empty() )
AddChatText( pAutoMsgInfo->m_strMsg.c_str(), "", CHAT_ETC );
else AddChatText( GetStringDB().ParseString( GetStringDB().GetString(pAutoMsgInfo->m_nSystemMsg) ).c_str(), "", CHAT_ETC );
}
}
// 2010.09.02 - prodongi
//void SUIChattingWnd::DeleteAutoMsg( int nSystemMsg )
void SUIChattingWnd::DeleteAutoMsg(int systemMsg, AR_HANDLE itemHandle)
{
// 2010.09.02 - prodongi
/*
std::vector< AutoMsgInfo* >::iterator iter = m_vAutoMsgInfo.begin();
for( ; iter != m_vAutoMsgInfo.end(); ++iter )
{
if( (*iter)->m_nSystemMsg == nSystemMsg )
(*iter)->SetEnd(true);
}
*/
it_autoMsgInfo it;
if (findAutoMsgInfo(systemMsg, itemHandle, it))
it->second->SetEnd(true);
}
// 2010.09.02 - prodongi
/*
void SUIChattingWnd::DeleteAutoEmptySoulpwerMsg( int nSystemMsg, AR_HANDLE hItem )
{
std::vector< AutoMsgInfo* >::iterator iter = m_vAutoMsgInfo.begin();
for( ; iter != m_vAutoMsgInfo.end(); ++iter )
{
if( (*iter)->m_nSystemMsg == nSystemMsg && (*iter)->m_hItem == hItem )
(*iter)->SetEnd(true);
}
}
*/
bool SUIChattingWnd::IsImeDoingComposition( ) const
{
if( KUIControlEdit* pEdit = dynamicCast<KUIControlEdit*>(GetChild("chat_edit") ))
{
return pEdit->IsCandidate( );
}
return false;
}
// 2010.09.02 - prodongi
bool SUIChattingWnd::findAutoMsgInfo(int msgId, AR_HANDLE itemHandle, it_autoMsgInfo& it)
{
std::string key = AutoMsg::makeKey(msgId, itemHandle);
it = m_autoMsgInfo.find(key);
return it != m_autoMsgInfo.end();
}
// 2010.09.02 - prodongi
bool SUIChattingWnd::findAutoMsgInfo(AutoMsg::AutoMsgInfo* autoMsgInfo, it_autoMsgInfo& it)
{
return findAutoMsgInfo(autoMsgInfo->m_nSystemMsg, autoMsgInfo->m_hItem, it);
}
/// 2010.11.15 - prodongi
#ifdef _DEV
void SUIChattingWnd::saveLocalAvatarPos(std::string const& str)
{
if (str == "/position" || str == "/위치")
{
std::ofstream fout("position.txt", ios_base::app);
if (fout.is_open())
{
SGameAvatarEx* avatar = g_pCurrentGameSystem->GetLocalPlayer();
K3DVector myPos = avatar->getMyPos();
fout << "X : " << myPos.x << " Y : " << myPos.y << "\n";
fout.close();
}
}
}
#endif
bool SUIChattingWnd::checkIsValidArenaRequest(std::string const& str, int chatType)
{
if (!g_pCurrentGameSystem->isInArena())
return true;
if (!str.empty())
{
if (str[0] == '/')
return true;
}
if (CHAT_NORMAL == chatType || CHAT_YELL == chatType || CHAT_ADV == chatType || CHAT_GLOBAL == chatType)
{
AddChatText(S(2478), "", CHAT_SYSTEM);
return false;
}
return true;
}
void SUIChattingWnd::printArenaSystemMsg()
{
if (g_pCurrentGameSystem->isInArena())
AddChatText(S(2478), "", CHAT_SYSTEM);
}
bool SUIChattingWnd::setArenaFilterToChatEdit(bool clear)
{
if (!g_pCurrentGameSystem->isInArena())
return false;
KUIControlEdit* chatEdit = dynamicCast<KUIControlEdit*>(GetChild("chat_edit"));
if (!chatEdit)
return false;
if (clear)
{
m_strFilter = "";
}
else
{
m_strFilter = szSiege;
m_strFilter += " ";
}
chatEdit->SetText(m_strFilter.c_str());
KColor color = GetColor(m_strFilter);
chatEdit->SetFontColor(color);
m_strPreText = m_strFilter;
return true;
}
//////////////////////////////////////////////////////////////////////////
// chat option
//////////////////////////////////////////////////////////////////////////
const int TAB_NAME_MAX = 8;
const int TAB_MARK_MAX = 18;
bool SUIChattingOptionWnd::InitControls( KPoint kPos )
{
// 버튼
//SetValidRect( "chatop_confirm_button", KRect(0, 0, -20,0) );
//SetValidRect( "chatop_cancle_button", KRect(20,0,0,0) );
// 체크 버튼
//SetValidRect 는 OffSet(KRect(0, 0, 60, 0)) 데이타를 줘서, 영역을 재 설정.
// for( i = 0; i < 19; i++ ) SetValidRect( CStringUtil::StringFormat( "chatop_check%02d", i ).c_str(), KRect(0, 0, 60, 0) );
KUIControlEdit * pEdit00 = dynamicCast<KUIControlEdit *>(GetChild("edit00"));
if( pEdit00 ) pEdit00->SetLimitation( TAB_NAME_MAX, true );
KUIControlEdit* pEdit01 = dynamicCast<KUIControlEdit*>(GetChild("edit01"));
if( pEdit01 ) pEdit01->SetLimitation( TAB_MARK_MAX, true );
return SUIWnd::InitControls(kPos);
}
void SUIChattingOptionWnd::OnNotifyUIWindowOpen( bool bOpen, bool bLimitWnd )
{
SUIWnd::OnNotifyUIWindowOpen(bOpen);
if( GetGameOption().IsEnterChat() )
{
if( m_bIsOpen )
SetFocus( true );
else
SetFocus( false );
}
}
void SUIChattingOptionWnd::SetCheckEnable( LPCSTR lpszControlID, bool bFlag )
{
KUIControlCheck* pCheck = dynamicCast<KUIControlCheck*>( GetChild(lpszControlID) );
if( pCheck )
{
if( bFlag )
pCheck->Enable();
else
pCheck->Disable();
}
}
void SUIChattingOptionWnd::SetCheck( LPCSTR lpszControlID, bool bFlag )
{
KUIControlCheck* pCheck = dynamicCast<KUIControlCheck*>( GetChild(lpszControlID) );
if( pCheck )
pCheck->SetCheck( bFlag );
}
bool SUIChattingOptionWnd::IsCheck( LPCSTR lpszControlID )
{
KUIControlCheck* pCheck = dynamicCast<KUIControlCheck*>( GetChild(lpszControlID) );
if( pCheck )
return pCheck->GetCheck();
return false;
}
void SUIChattingOptionWnd::PumpUpMessage( LPCSTR lpszControlID, DWORD nMessage, DWORD lparam, DWORD wparam )
{
switch(nMessage)
{
case KUI_MESSAGE::KEDIT_CHANGE:
{
if( ::_stricmp( lpszControlID, "edit00" ) == 0 )
{
//채널명 변경
KUIControlEdit * pEdit00 = dynamicCast<KUIControlEdit *>(GetChild("edit00"));
if( pEdit00 )
{
m_pGameManager->PostMsgAtDynamic( new SIMSG_UI_CHAT_TABNAME_CHANGE( pEdit00->GetText(), m_nCurKind ) );
}
}
}
break;
case KUI_MESSAGE::KBUTTON_CLICK:
{
//servantes 2010.10.13
if( ::_stricmp( lpszControlID, "button_ok" ) == 0 || ::_stricmp( lpszControlID, "IDOK" ) == 0 )
{
// if( m_nCurKind != 0 ) //전체 채팅은 설정 불가
{
//확인
KUIControlEdit * pEdit00 = dynamicCast<KUIControlEdit *>(GetChild("edit00"));
if( pEdit00 )
{
m_strTabName = pEdit00->GetText();
if( GetGameOption().SetChatTabName( m_nCurKind, m_strTabName.c_str() ) )
{
m_pGameManager->PostMsgAtDynamic( new SIMSG_UI_CHAT_TABNAME_CHANGE( m_strTabName, m_nCurKind ) );
}
}
KUIControlEdit * pEdit01 = dynamicCast<KUIControlEdit *>(GetChild("edit01"));
if( pEdit01 )
{
m_strTabMark = pEdit01->GetText();
if( GetGameOption().SetChatTabMark( m_nCurKind, m_strTabMark.c_str() ) )
{
m_pGameManager->PostMsgAtDynamic( new SIMSG_UI_CHAT_TABNAME_CHANGE( m_strTabName, m_nCurKind ) );
}
}
GetGameOption().ChatOptionApply( m_nCurKind, m_bChatOption );
// 메인 채팅창에 알리기,
m_pGameManager->PostMsgAtDynamic( new SIMSG_UI_CHAT_UPDATE( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_CHATTING, m_nCurKind ) );
}
}
//servantes 2010.10.13
else if( ::_stricmp( lpszControlID, "button_cancel" ) == 0 )
{ //취소
//기존것 복구
m_pGameManager->PostMsgAtDynamic( new SIMSG_UI_CHAT_TABNAME_CHANGE( GetGameOption().GetChatTabName( m_nCurKind ), m_nCurKind ) );
}
m_pGameManager->PostMsgAtDynamic( new SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_CHAT_OPTION, false ) );
//{
// ConfirmCheckOption();
// m_pGameManager->PostMsgAtDynamic( new SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_CHAT_OPTION, false ) );
//}
//else if( ::_stricmp( lpszControlID, "chatop_namebar" ) == 0 )
// m_pGameManager->PostMsgAtDynamic( new SIMSG_UI_REQ_INPUTTEXT( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_CHAT_OPTION, "채널명을 입력해 주세요" ) );
}
break;
case KUI_MESSAGE::KCHECK_CHANGE:
{
m_pGameManager->StartSound( "ui_button_click.wav" );
bool bCheck = false;
if( !::_stricmp( lpszControlID, "check00" ) )
{//사용자 채팅
m_bChatOption[0] = IsCheck( lpszControlID );
bCheck = m_bChatOption[0];
SetCheckEnable( "check01", bCheck );
SetCheckEnable( "check02", bCheck );
SetCheckEnable( "check03", bCheck );
SetCheckEnable( "check04", bCheck );
SetCheckEnable( "check05", bCheck );
}
else if( !::_stricmp( lpszControlID, "check06" ) )
{//그룹채팅
m_bChatOption[6] = IsCheck( lpszControlID );
bCheck = m_bChatOption[6];
SetCheckEnable( "check07", bCheck );
SetCheckEnable( "check08", bCheck );
SetCheckEnable( "check09", bCheck );
}
else if( !::_stricmp( lpszControlID, "check10" ) )
{//시스템 메세지
m_bChatOption[10] = IsCheck( lpszControlID );
bCheck = m_bChatOption[10];
SetCheckEnable( "check11", bCheck );
SetCheckEnable( "check12", bCheck );
SetCheckEnable( "check13", bCheck );
SetCheckEnable( "check14", bCheck );
SetCheckEnable( "check15", bCheck );
SetCheckEnable( "check16", bCheck );
SetCheckEnable( "check17", bCheck );
SetCheckEnable( "check18", bCheck );
}
//사용자 채팅
else if( !::_stricmp( lpszControlID, "check01" ) )
{//사용자 채팅_일반 채팅
m_bChatOption[1] = IsCheck( lpszControlID );
}
else if( !::_stricmp( lpszControlID, "check02" ) )
{//사용자 채팅_외치기
m_bChatOption[2] = IsCheck( lpszControlID );
}
else if( !::_stricmp( lpszControlID, "check03" ) )
{//사용자 채팅_광고 채팅
m_bChatOption[3] = IsCheck( lpszControlID );
}
else if( !::_stricmp( lpszControlID, "check04" ) )
{//사용자 채팅_친한 귓속말
m_bChatOption[4] = IsCheck( lpszControlID );
}
else if( !::_stricmp( lpszControlID, "check05" ) )
{//사용자 채팅_귓속말
m_bChatOption[5] = IsCheck( lpszControlID );
}
//그룹 채팅
else if( !::_stricmp( lpszControlID, "check07" ) )
{//그룹 채팅_파티 채팅
m_bChatOption[7] = IsCheck( lpszControlID );
}
else if( !::_stricmp( lpszControlID, "check08" ) )
{//그룹 채팅_길드 채팅
m_bChatOption[8] = IsCheck( lpszControlID );
}
else if( !::_stricmp( lpszControlID, "check09" ) )
{//그룹 채팅_공대 채팅
m_bChatOption[9] = IsCheck( lpszControlID );
}
else if( !::_stricmp( lpszControlID, "check11" ) )
{//시스템 메세지_경험치
m_bChatOption[11] = IsCheck( lpszControlID );
}
else if( !::_stricmp( lpszControlID, "check12" ) )
{//시스템 메세지_NPC 관련
m_bChatOption[12] = IsCheck( lpszControlID );
}
else if( !::_stricmp( lpszControlID, "check13" ) )
{//시스템 메세지_기본 데미지
m_bChatOption[13] = IsCheck( lpszControlID );
}
else if( !::_stricmp( lpszControlID, "check14" ) )
{//시스템 메세지_스킬 데미지
m_bChatOption[14] = IsCheck( lpszControlID );
}
else if( !::_stricmp( lpszControlID, "check15" ) )
{//시스템 메세지_아이템 관련
m_bChatOption[15] = IsCheck( lpszControlID );
}
else if( !::_stricmp( lpszControlID, "check16" ) )
{//시스템 메세지_전투 상황
m_bChatOption[16] = IsCheck( lpszControlID );
}
else if( !::_stricmp( lpszControlID, "check17" ) )
{//시스템 메세지_크리쳐 관련
m_bChatOption[17] = IsCheck( lpszControlID );
}
else if( !::_stricmp( lpszControlID, "check18" ) )
{//시스템 메세지_기타
m_bChatOption[18] = IsCheck( lpszControlID );
}
}
break;
}
SUIWnd::PumpUpMessage( lpszControlID, nMessage, lparam, wparam );
}
void SUIChattingOptionWnd::ProcMsgAtStatic( SGameMessage* pMsg )
{
switch(pMsg->nType)
{
case IMSG_UI_CHAT_OPTION:
{
SIMSG_UI_CHAT_OPTION* pChatOptionMsg = ( SIMSG_UI_CHAT_OPTION* )pMsg;
if( pChatOptionMsg->m_bTabChange )
{
if( IsShow() == true )
{
m_nCurKind = pChatOptionMsg->m_Kind;
UpdateChatOption();
}
}
else
{
if( IsShow() == false )
{
// MovePos( 0, pChatOptionMsg->m_nPosY - GetRect().GetHeight() );
m_pGameManager->PostMsgAtDynamic( new SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_CHAT_OPTION, true ) );
m_nCurKind = pChatOptionMsg->m_Kind;
UpdateChatOption();
}
else
{
m_pGameManager->PostMsgAtDynamic( new SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_CHAT_OPTION, false ) );
}
}
pMsg->bUse = true;
}
break;
}
}
void SUIChattingOptionWnd::UpdateChatOption()
{
//if( m_nCurKind == 0 ) //전체 채팅은 설정 불가
//{
// KUIControlEdit* pEdit00 = (KUIControlEdit*)GetChild("edit00");
// if( pEdit00 ) pEdit00->Disable();
// KUIControlEdit* pEdit01 = (KUIControlEdit*)GetChild("edit01");
// if( pEdit01 ) pEdit01->Disable();
// for( int i = 0; i < CHAT_OPTION_MAX; i++ )
// {
// SetCheckEnable( CStringUtil::StringFormat( "check%02d", i ).c_str(), false );
// }
// return;
//}
//else
{
KUIControlEdit* pEdit00 = dynamicCast<KUIControlEdit*>(GetChild("edit00"));
if( pEdit00 )
{
pEdit00->Enable();
pEdit00->SetText( "" );
}
KUIControlEdit* pEdit01 = dynamicCast<KUIControlEdit*>(GetChild("edit01"));
if( pEdit01 )
{
pEdit01->Enable();
pEdit01->SetText( "" );
}
for( int i = 0; i < CHAT_OPTION_MAX; i++ )
{
SetCheckEnable( CStringUtil::StringFormat( "check%02d", i ).c_str(), true );
}
}
// // 이름
std::string strName = GetChatKindName();
KUIControlEdit * pEdit = dynamicCast<KUIControlEdit *>(GetChild("edit00"));
if( pEdit )
{
pEdit->SetText( strName.c_str() );
}
KUIControlEdit * pEdit01 = dynamicCast<KUIControlEdit *>(GetChild("edit01"));
if( pEdit01 )
{
pEdit01->SetText( GetGameOption().GetChatTabMark( m_nCurKind ) );
}
//
// 옵션에서 가져온다
int i;
for( i = 0; i < CHAT_OPTION_MAX; i++ )
{
m_bChatOption[i] = GetGameOption().IsChatOptionCheck( m_nCurKind, i );
SetCheck( CStringUtil::StringFormat( "check%02d", i ).c_str(), m_bChatOption[i] );
}
{//사용자 채팅
SetCheckEnable( "check01", m_bChatOption[0] );
SetCheckEnable( "check02", m_bChatOption[0] );
SetCheckEnable( "check03", m_bChatOption[0] );
SetCheckEnable( "check04", m_bChatOption[0] );
SetCheckEnable( "check05", m_bChatOption[0] );
}
{//그룹채팅
SetCheckEnable( "check07", m_bChatOption[6] );
SetCheckEnable( "check08", m_bChatOption[6] );
SetCheckEnable( "check09", m_bChatOption[6] );
}
{//시스템 메세지
SetCheckEnable( "check11", m_bChatOption[10] );
SetCheckEnable( "check12", m_bChatOption[10] );
SetCheckEnable( "check13", m_bChatOption[10] );
SetCheckEnable( "check14", m_bChatOption[10] );
SetCheckEnable( "check15", m_bChatOption[10] );
SetCheckEnable( "check16", m_bChatOption[10] );
SetCheckEnable( "check17", m_bChatOption[10] );
SetCheckEnable( "check18", m_bChatOption[10] );
}
}
std::string SUIChattingOptionWnd::GetChatKindName()
{
switch(m_nCurKind)
{
case 0:
case 1:
case 2:
case 3:
case 4: return CStringUtil::StringFormat( "%s", GetGameOption().GetChatTabName( m_nCurKind ) );
}
return CStringUtil::StringFormat( "Error" );
}