Files
Leviathan/Client/Game/game/Utility/Util.h
T
2026-06-01 12:46:52 +02:00

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)