536 lines
14 KiB
C++
536 lines
14 KiB
C++
#pragma once
|
|
|
|
//#include <vector>
|
|
//#include <string>
|
|
#include <assert.h>
|
|
#include <kfile/KStream.h>
|
|
|
|
#pragma warning(push)
|
|
#pragma warning(disable:4996)
|
|
|
|
|
|
class SGameSystem;
|
|
|
|
|
|
typedef std::vector<std::string> STRING_VECTOR;
|
|
|
|
// 2010.50.25 - prodongi
|
|
class KSeqAvatarEx;
|
|
// 2010.08.16 - prodongi
|
|
struct ItemBaseEx_info;
|
|
|
|
namespace CStringUtil
|
|
{
|
|
inline bool isCommand( const char *pString, const char *pCmd )
|
|
{
|
|
if( strlen(pString) < strlen(pCmd) ) return false; // by Testors;
|
|
if( pString[strlen(pCmd)] && pString[strlen(pCmd)] != ' ' ) return false; // by Testors;
|
|
return !_strnicmp( pString, pCmd, strlen(pCmd ) );
|
|
}
|
|
|
|
inline std::string ReadString( KStream* pStream )
|
|
{
|
|
DWORD dwLength = 0;
|
|
pStream->Read( &dwLength, sizeof(dwLength) );
|
|
|
|
char* szBuffer = new char[dwLength + 1];
|
|
pStream->Read( szBuffer, sizeof(char) * dwLength );
|
|
szBuffer[dwLength] = '\0';
|
|
|
|
std::string str = szBuffer;
|
|
delete [] szBuffer;
|
|
|
|
return str;
|
|
}
|
|
inline void WriteString( KStream* pStream, const char* szString )
|
|
{
|
|
DWORD dwLength = DWORD(::strlen( szString ));
|
|
|
|
pStream->Write( &dwLength, sizeof(dwLength) );
|
|
pStream->Write( szString, sizeof(char) * dwLength );
|
|
}
|
|
|
|
inline void GetTextLinesFromString( const std::string& rEntireText, STRING_VECTOR& rGetTextLines, const char* szLineDivision = "\r\n" )
|
|
{
|
|
rGetTextLines.clear();
|
|
|
|
int nDivisionSize = int(::strlen( szLineDivision ));
|
|
|
|
// 문자열을 라인 단위로 나눠서 rGetTextLines에 넣는다.
|
|
for( int nCurrentPos = 0; ; )
|
|
{
|
|
std::string strLine;
|
|
|
|
int nLineFeed = int( rEntireText.find( szLineDivision, nCurrentPos ) );
|
|
if( nLineFeed != std::string::npos )
|
|
{
|
|
strLine.assign( rEntireText, nCurrentPos, nLineFeed - nCurrentPos );
|
|
if( strLine.size() > 0 )
|
|
rGetTextLines.push_back( strLine );
|
|
|
|
nCurrentPos = (nLineFeed + nDivisionSize);
|
|
}
|
|
else
|
|
{
|
|
strLine.assign( rEntireText, nCurrentPos, rEntireText.size() - nCurrentPos );
|
|
if( strLine.size() > 0 )
|
|
rGetTextLines.push_back( strLine );
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
inline void GetTextLinesFromString( const char* szEntireText, STRING_VECTOR& rGetTextLines, const char* szLineDivision = "\r\n" )
|
|
{
|
|
GetTextLinesFromString( std::string( szEntireText ), rGetTextLines, szLineDivision );
|
|
}
|
|
|
|
static void ReplacePhrase( std::string& rText, const std::string& rFindPhrase, const std::string& rReplacePhrase )
|
|
{
|
|
// 찾는 문자열(rFindPhrase)이 비어있을 경우 무한루프?!
|
|
if ((rText.empty()) || (rFindPhrase.empty()))
|
|
return;
|
|
|
|
for( size_t nCurrentPos = 0; ; )
|
|
{
|
|
size_t nFindPos = rText.find( rFindPhrase, nCurrentPos );
|
|
if( nFindPos == std::string::npos ) break;
|
|
|
|
rText.replace( nFindPos, rFindPhrase.size(), rReplacePhrase );
|
|
nCurrentPos = (nFindPos + rReplacePhrase.size());
|
|
}
|
|
}
|
|
|
|
inline bool GetContentString( const std::string& rString, const char* szHeadString, std::string& rGetContentString )
|
|
{
|
|
if( rString.compare( 0, ::strlen( szHeadString ), szHeadString ) == 0 )
|
|
{
|
|
rGetContentString.assign( rString, ::strlen( szHeadString ), rString.size() - ::strlen( szHeadString ) );
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
inline std::string StringFormat( const char* szString, ... )
|
|
{
|
|
char szBuf[2048];
|
|
|
|
va_list va;
|
|
va_start( va, szString );
|
|
_vsnprintf( szBuf, _countof(szBuf), szString, va );
|
|
va_end( va );
|
|
|
|
return std::string( szBuf );
|
|
}
|
|
|
|
/// { [sonador][3.4.1]소지금 한도 증가 관련 서버 메시지 변경
|
|
inline std::string GetCommaNumberString( __int64 n64Value )
|
|
{
|
|
const int c_nCommaGap = 3;
|
|
|
|
std::string strNum = CStringUtil::StringFormat( "%I64d", n64Value );
|
|
std::string strCommaNum;
|
|
|
|
int nCount( 0 );
|
|
int nCommaPos = int(strNum.size()) % c_nCommaGap;
|
|
|
|
for( std::string::iterator it = strNum.begin(); it != strNum.end(); it++, ++nCount )
|
|
{
|
|
if( it != strNum.begin() && nCommaPos == (nCount % c_nCommaGap) )
|
|
strCommaNum.push_back( ',' );
|
|
|
|
strCommaNum.push_back( (*it) );
|
|
}
|
|
return strCommaNum;
|
|
}
|
|
|
|
/// 2012.06.13 기존 GetCommaNumberString에 태그를 추가 - prodongi
|
|
inline std::string GetCommaNumberString(char const* tag, __int64 n64Value )
|
|
{
|
|
std::string strTag = tag;
|
|
std::string strNumber = GetCommaNumberString(n64Value);
|
|
return strTag + strNumber;
|
|
}
|
|
// }
|
|
|
|
inline void GetAniSetName( const char* szString, char szChar, std::string & strOut )
|
|
{
|
|
std::string strName = szString;
|
|
std::string strKey;
|
|
|
|
std::string::size_type pos;
|
|
const std::string::size_type npos = -1;
|
|
char szName[_MAX_PATH]; memset( szName, 0, sizeof(szName) );
|
|
|
|
pos = strName.rfind(szChar);
|
|
|
|
if ( pos != npos )
|
|
{
|
|
strKey = strName.substr( 0, pos );
|
|
}
|
|
|
|
strOut = szName;
|
|
}
|
|
|
|
inline void GetStrKey( const char* szString, char szChar, std::string & strOut, BOOL bOld = FALSE )
|
|
{
|
|
//Ani Name은 화일명을 잘라서 만든다.
|
|
std::string strName = szString;
|
|
std::string strKey;
|
|
|
|
std::string::size_type pos, pos1, pos2;
|
|
const std::string::size_type npos = -1;
|
|
char szName[128]; memset( szName, 0, sizeof(szName) );
|
|
|
|
if( bOld )
|
|
{
|
|
pos = strName.rfind(szChar);
|
|
|
|
if ( pos != npos )
|
|
{
|
|
pos2 = strName.rfind('.');
|
|
strName.copy(szName, (pos2 - (pos+1)), pos+1);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pos = strName.rfind('\\');
|
|
strName.erase( 0, pos+1 );
|
|
|
|
pos = strName.find('_');
|
|
pos1 = strName.rfind('_');
|
|
|
|
//애니키는 모션 타입과 무기 종류 저장
|
|
strKey = strName.substr( pos+1, (pos1-(pos+1)) );
|
|
strcpy(szName, strKey.c_str() );
|
|
}
|
|
|
|
strOut = szName;
|
|
}
|
|
|
|
inline void GetEventStrKey( const char* szString, char szChar, std::string & strOut )
|
|
{
|
|
//Ani Name은 화일명을 잘라서 만든다.
|
|
std::string strName = szString;
|
|
std::string strKey;
|
|
|
|
std::string::size_type pos;
|
|
const std::string::size_type npos = -1;
|
|
char szName[128]; memset( szName, 0, sizeof(szName) );
|
|
|
|
pos = strName.rfind(szChar);
|
|
|
|
if ( pos != npos )
|
|
{
|
|
strKey = strName.substr( 0, pos );
|
|
strcpy(szName, strKey.c_str() );
|
|
}
|
|
|
|
strOut = szName;
|
|
}
|
|
|
|
inline bool GetIconAniName( const char * pFileName, std::string & strOutAniName )
|
|
{
|
|
std::string strAniName = pFileName;
|
|
|
|
std::string::size_type pos = strAniName.rfind( '.' );
|
|
if( pos != std::string::npos )
|
|
{
|
|
strAniName.erase( pos, strAniName.length()-pos ); //확장자 제거
|
|
pos = std::string::npos;
|
|
|
|
pos = strAniName.rfind( '\\' );
|
|
if( pos != std::string::npos )
|
|
{
|
|
strAniName.erase( 0, pos+1 ); //폴더 제거
|
|
}
|
|
else
|
|
{
|
|
assert(0);
|
|
return false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
assert(0);
|
|
return false;
|
|
}
|
|
|
|
strOutAniName = strAniName;
|
|
return true;
|
|
}
|
|
|
|
inline std::string GetRandBlankName( const char* pFileName, bool& bIsExistRB )
|
|
{
|
|
static const char* szSymbol = "<rb:";
|
|
static int nSymbolSize = sizeof( szSymbol );
|
|
|
|
std::string strDestName;
|
|
std::string strSrcName = pFileName;
|
|
|
|
std::string::size_type curpos = 0;
|
|
std::string::size_type strsize = strSrcName.size();
|
|
while( curpos < strsize )
|
|
{
|
|
size_t pos = strSrcName.find( szSymbol, 0 );
|
|
strDestName += strSrcName.substr( 0, pos );
|
|
if( pos != strSrcName.npos )
|
|
{
|
|
bIsExistRB = true;
|
|
|
|
curpos += pos+nSymbolSize;
|
|
strSrcName.erase( 0, (pos+nSymbolSize) );
|
|
|
|
size_t end = strSrcName.find( ">", 0 );
|
|
if( end != strSrcName.npos )
|
|
{
|
|
int nRand = atoi( strSrcName.substr( 0, end ).c_str() );
|
|
if( nRand > 0 )
|
|
{
|
|
int nRandSpace = 0;
|
|
|
|
do
|
|
{
|
|
nRandSpace = rand() % nRand;
|
|
|
|
} while( nRandSpace == 0 );
|
|
|
|
for( int nSpace = 0; nSpace < nRandSpace; ++nSpace )
|
|
{
|
|
strDestName += " ";
|
|
}
|
|
}
|
|
|
|
strSrcName.erase( 0, (end+1) ); // 1 == sizeof(">")
|
|
curpos += (end+1); // 1 == sizeof(">")
|
|
}
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
|
|
return strDestName.c_str(); //Empty일때 호출쪽에서 처리하자
|
|
}
|
|
|
|
|
|
// 추가. bintitle. 2010.05.14.
|
|
// nui의 Caption 에서 텍스트를 꾸며주는 데코레이션을 뽑아낸다.
|
|
// <font:굴림><size:10><hcenter>텍스트 <= "텍스트" 를 제외한 앞의 Decoration.
|
|
inline void GetTextDecoration( const char * pText, std::string & strDecoration )
|
|
{
|
|
std::string strText( pText );
|
|
|
|
std::string::size_type sizeEnd = strText.find( "<$" );
|
|
if( sizeEnd != std::string::npos )
|
|
strDecoration = strText.substr( 0, sizeEnd );
|
|
else
|
|
{
|
|
sizeEnd = strText.find_last_of( ">" );
|
|
if( sizeEnd != std::string::npos )
|
|
strDecoration = strText.substr( 0, ++sizeEnd );
|
|
}
|
|
}
|
|
|
|
|
|
// bintitle. 2010.09.03.
|
|
// << Font명 얻기 >>
|
|
// nui의 Caption 에서 <font:font_XXXX> 의 font_XXXX 를 얻어낸다.
|
|
// <font:font_01><size:10><hcenter>텍스트 <= font_01
|
|
inline void GetTextFontName( std::string & strText, std::string & strFontName )
|
|
{
|
|
strFontName = "Default";
|
|
std::string::size_type nPos = strText.find( "<font:" );
|
|
if( nPos != std::string::npos )
|
|
{
|
|
nPos += strlen( "<font:" );
|
|
std::string strTemp( strText.begin() + nPos, strText.begin() + strText.size() );
|
|
std::string::size_type nPos_End = strTemp.find_first_of( ">" );
|
|
strFontName = strTemp.substr( 0, nPos_End );
|
|
}
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------------------------------------------
|
|
// .NUI의 Caption 에서 글자 색상 값을 얻어낸다.
|
|
// 설명 : <font:font_01><size:10><hcenter><#000000>텍스트 <= 000000
|
|
// lenahyang. 2012.09.20
|
|
inline void GetTextColorValue( IN std::string& strCaption, OUT std::string& strColorValue )
|
|
{
|
|
std::string::size_type nPos = strCaption.find( "<#" );
|
|
if( nPos != std::string::npos )
|
|
{
|
|
nPos += strlen( "<#" );
|
|
std::string strTemp( strCaption.begin() + nPos, strCaption.begin() + strCaption.size() );
|
|
std::string::size_type nPos_End = strTemp.find_first_of( ">" );
|
|
strColorValue = strTemp.substr( 0, nPos_End );
|
|
}
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------------------------------------------
|
|
// .NUI의 Caption 에서 글자 색상 값을 변경한다.
|
|
// 설명 : <font:font_01><size:10><hcenter><#000000> => <#111111>
|
|
// : strReplaceColorValue 변수는 6자리의 변경 될 칼라 값 을 가지고 있어야 한다.
|
|
// lenahyang. 2012.09.20
|
|
inline void ReplaceTextColorValue( OUT std::string& strCaption, IN std::string& strReplaceColorValue )
|
|
{
|
|
std::string::size_type nPos = strCaption.find( "<#" );
|
|
if( nPos != std::string::npos )
|
|
{
|
|
std::string strColorValue( "" );
|
|
GetTextColorValue( strCaption, strColorValue );
|
|
|
|
ReplacePhrase( strCaption, strColorValue, strReplaceColorValue );
|
|
}
|
|
}
|
|
|
|
|
|
inline void GetTextFontBold( std::string & strText, bool & bBold )
|
|
{
|
|
bBold = false;
|
|
std::string::size_type nPos = strText.find( "<b>" );
|
|
if( nPos != std::string::npos )
|
|
{
|
|
bBold = true;
|
|
}
|
|
}
|
|
|
|
};
|
|
|
|
/** prodongi */
|
|
template <class T>
|
|
struct sUpdateTime
|
|
{
|
|
sUpdateTime() : m_active(false), m_loop(false), m_toggle(false), m_toggleDir(true)
|
|
{
|
|
m_elapsedTime = (T)0;
|
|
m_upateTime = (T)0;
|
|
}
|
|
void begin(T updateTime, bool loop = false)
|
|
{
|
|
m_active = true;
|
|
m_loop = loop;
|
|
m_elapsedTime = (T)0;
|
|
m_upateTime = updateTime;
|
|
}
|
|
void end()
|
|
{
|
|
m_active = false;
|
|
}
|
|
T getRate() const
|
|
{
|
|
if (m_upateTime < (T)0) return (T)0;
|
|
return min(m_elapsedTime / m_upateTime, (T)1);
|
|
}
|
|
bool update(T elapsedTime)
|
|
{
|
|
if (!m_active)
|
|
return false;
|
|
|
|
if (m_toggle)
|
|
{
|
|
// inc
|
|
if (m_toggleDir)
|
|
{
|
|
m_elapsedTime += elapsedTime;
|
|
if (m_elapsedTime >= m_upateTime)
|
|
{
|
|
m_toggleDir = false;
|
|
if (m_loop) m_elapsedTime = m_upateTime;
|
|
else end();
|
|
return false;
|
|
}
|
|
}
|
|
// dec
|
|
else
|
|
{
|
|
m_elapsedTime -= elapsedTime;
|
|
if (m_elapsedTime <= (T)0)
|
|
{
|
|
m_toggleDir = true;
|
|
if (m_loop) m_elapsedTime = (T)0;
|
|
else end();
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_elapsedTime += elapsedTime;
|
|
if (m_elapsedTime >= m_upateTime)
|
|
{
|
|
if (m_loop) m_elapsedTime -= m_upateTime;
|
|
else end();
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
bool m_active;
|
|
bool m_loop;
|
|
T m_elapsedTime;
|
|
T m_upateTime;
|
|
|
|
// toggle
|
|
bool m_toggle;
|
|
// toggle 방향 true : inc, false : dec
|
|
bool m_toggleDir;
|
|
};
|
|
|
|
// 2010.05.25 - prodongi
|
|
void setMaintainHairColorNewToOld(int hairId, int hairColorIndex, int race, int sex, KSeqAvatarEx* seqAvatarEx);
|
|
// 2010.08.16 - prodongi
|
|
int getHelmItemModelType(int race, int sex, ItemBaseEx_info const* itemInfo);
|
|
|
|
//
|
|
// *** 텍스트 목록 설정 ***
|
|
//
|
|
// 주어진 텍스트를 컨트롤의 너비에 맞게 잘라내어 리스트형태로 설정한다. // 도움말 윈도우등 문자를 리스트로 출력해야하는 부분들이 많아 추가하였습니다. bintitle. 2010.08.31.
|
|
//
|
|
// Argument -
|
|
// strText : 목록으로 설정할 텍스트.
|
|
// pCtrlText : 해당 컨트롤의 너비에 맞게 리스트를 만들고 리스트를 지정할 컨트롤.
|
|
// pScrollBase : 스크롤바.
|
|
// crrScrollPos : 현재 스크롤값.
|
|
// vLineList : 텍스트의 행을 보관할 배열.
|
|
// bNewText : arrList 를 새로 생성할지 여부.
|
|
//
|
|
void SetTextList( int nMaxListSize, std::string & strText, std::string & strDecoretion, char * pStrFontName,
|
|
class KUIControl * pCtrlText, class KUIControlScrollBase * pScrollBase, int & crrScrollPos,
|
|
std::vector< std::string > & vLineList, bool bNewText=false );
|
|
|
|
/// 2010.10.27 문자열에서 해당 태그의 값을 뽑는다 - prodongi
|
|
std::string extractTokenValue(std::string const& str, std::string const& token);
|
|
/// 2010.10.27 str에서 토큰과 text를 분리한다, 토큰이 str의 앞 부분에만 있는 경우만 유효함 - prodongi
|
|
void extractTokenAndText(std::string const& str, std::string& token, std::string& text);
|
|
/// 2011.11.23 구분자가 L"|" 같은 경우에 대만 처럼 會같은 특별한 문자가 들어갈 경우에 wchar 변환 호환성으로 높이기 위해서 MultiByteToWideChar를 사용 - prodongi
|
|
void safeM2W(char const* szMsg, wchar_t const* delimiter, std::wstring& wstr);
|
|
/// 2011.11.29 safeM2W를 사용해서 유니코드로 변환뒤에 해당 문자를 찾는다 - prodongi
|
|
bool safeFindString(char const* str, wchar_t const* delimiter);
|
|
/// 2011.11.29 safeM2W를 사용해서 유니코드로 변환뒤에 치환 - prodongi
|
|
void safeReplaceString(std::string& str, wchar_t const* from, wchar_t const* to);
|
|
void decodeDir(char const* curDir);
|
|
|
|
/*
|
|
2011.08.22 아이오 베이션의 블랙 박스 정보를 구한다 - prodongi
|
|
*/
|
|
char* getIovationBlackBox();
|
|
|
|
|
|
/// 2012.04.04 패스워드 틀린 횟수 체크에 쓰인다. - prodongi
|
|
template <int MAX_COUNT = 5>
|
|
struct sPasswordCount
|
|
{
|
|
sPasswordCount() : m_count(0) {}
|
|
void inc() { ++m_count; }
|
|
void clear() { m_count = 0; }
|
|
bool end() { return m_count >= MAX_COUNT; }
|
|
|
|
int m_count;
|
|
};
|
|
|
|
bool getCurrentMapPostionXY(float x, float y, POINT& outPos);
|
|
bool IsRamadanPrayRoom();
|
|
|
|
#pragma warning(pop) |