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

485 lines
13 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "stdafx.h"
// 2010.05.25 - prodongi
#include <windows.h>
//#include "Util.h"
#include "KSeqAvatarEx.h"
#include "SDefaultTextureResourceDB.h"
#include "SItemDB.h"
#include "KRenderObjectMesh.h"
// 2010.08.16 - prodongi
#include "SkillBaseFile.h"
#include <toolkit/nsl.h>
#include <toolkit/nsluni.h>
#include <kfile/KFileNameCipher.h>
#include <kfile/KFileManager.h>
#include "SGameAvatarEx.h"
#include "CommonUtil.h"
#include "SGameWorld.h"
#include "SGameSystem.h"
#include "TerrainSeamlessWorldInfo.h"
extern SGameSystem* g_pCurrentGameSystem;
// 2010.05.25 A function that keeps the color value of the default hair when changing from the default hair to a new hair. prodongi
void setMaintainHairColorNewToOld(int hairId, int hairColorIndex, int race, int sex, KSeqAvatarEx* seqAvatarEx)
{
if( hairId >= 701 && hairId <= 705 )
{
int nGroup = 1;
std::string texName = GetDefaultTextureResourceDB().GetTextureName( nGroup, hairColorIndex, race, sex);
int itemId = 0;
if (hairColorIndex == 1)
{
if (std::string::npos != texName.find("dem")) itemId = 960063;
else if (std::string::npos != texName.find("def")) itemId = 960063;
else if (std::string::npos != texName.find("asm")) itemId = 960065;
else if (std::string::npos != texName.find("asf")) itemId = 960065;
else if (std::string::npos != texName.find("gam")) itemId = 960067;
else if (std::string::npos != texName.find("gaf")) itemId = 960067;
}
else
{
if (std::string::npos != texName.find("dem")) itemId = 960064;
else if (std::string::npos != texName.find("def")) itemId = 960064;
else if (std::string::npos != texName.find("asm")) itemId = 960066;
else if (std::string::npos != texName.find("asf")) itemId = 960066;
else if (std::string::npos != texName.find("gam")) itemId = 960068;
else if (std::string::npos != texName.find("gaf")) itemId = 960068;
}
if (itemId == 0) return;
const ItemBaseEx_info* pItemInfo = GetItemDB().GetItemData(itemId);
if (!pItemInfo) return;
DWORD color = pItemInfo->dOptVar2[0];
color |= 0xff000000;
_CID( SET_COLORIZE );
KMsgSET_COLORIZE msg;
msg.color[0] = 0;
msg.color[1] = color; // Use only the second one
msg.color[2] = 0;
msg.color[3] = 0;
msg.nMode = K3DTexture::COLORIZED_GRAY;
seqAvatarEx->Perform( ANIPART_BIPED, MPART_HAIR, id_SET_COLORIZE, msg );
}
}
// 2010.08.16 - prodongi
int getHelmItemModelType(int race, int sex, ItemBaseEx_info const* itemInfo)
{
int flag = 0;
if( race == GCLAN_GAIA )
{
if( sex == SEX_MALE ) flag = itemInfo->model_type_gam;
else if( sex == SEX_FEMALE ) flag = itemInfo->model_type_gaf;
}
else if( race == GCLAN_DEVA )
{
if( sex == SEX_MALE ) flag = itemInfo->model_type_dem;
else if( sex == SEX_FEMALE ) flag = itemInfo->model_type_def;
}
else if(race == GCLAN_ASURA )
{
if( sex == SEX_MALE ) flag = itemInfo->model_type_asm;
else if( sex == SEX_FEMALE ) flag = itemInfo->model_type_asf;
}
return flag;
}
//#include "KUIControl.h" // bintitle. 2010.08.31.
#include "KUIControlScroll.h" // ''
#include <toolkit/XStringUtil.h>
// 최종수정 bintitle. 2010.09.29.
//
// *** 텍스트 목록 설정 ***
//
// 주어진 텍스트를 컨트롤의 너비에 맞게 잘라내어 리스트형태로 설정한다. // 도움말 윈도우등 문자를 리스트로 출력해야하는 부분들이 많아 추가하였습니다. bintitle. 2010.08.31.
//
// Argument -
// strText : 목록으로 설정할 텍스트.
// pCtrlText : 해당 컨트롤의 너비에 맞게 리스트를 만들고 리스트를 지정할 컨트롤.
// pScrollBase : 스크롤바.
// crrScrollPos : 현재 스크롤값.
// vLineList : 텍스트의 행을 보관할 배열.
// bNewText : arrList 를 새로 생성할지 여부.
//
void SetTextList( int nMaxListSize, std::string & strText, std::string & strDecoretion, char * pStrFontName, KUIControl * pCtrlText,
KUIControlScrollBase * pScrollBase, int & crrScrollPos, std::vector< std::string > & vLineList, bool bNewText )
{
std::string strNewStory("");
#ifdef _COUNTRY_ME_
if( bNewText )
pCtrlText->SplitLine( vLineList, strText, "Default", pCtrlText->GetFontSize(), false, true );
XStringUtil::Replace( strDecoretion, "<left>", "<right>" );
std::string::size_type fpos = strDecoretion.find( "<font:" );
if( fpos != std::string::npos )
{
std::string::size_type Epos = strDecoretion.find_first_of( ">" );
if( Epos != std::string::npos && Epos > fpos )
{
++Epos;
strDecoretion.replace( fpos, Epos - fpos, "<font:Default>" );
}
}
//strNewStory += "<font:Default><RIGHT>";
strNewStory += strDecoretion;
#else
if( bNewText )
/*pCtrlText->SplitLine( vLineList, strText,
pStrFontName ? pStrFontName : "Default",
pCtrlText->GetFontSize(), false, pCtrlText->GetFontSize() == KTextRender::KDEFAULT_FONT_SIZE ? false : true, true ); */
pCtrlText->SplitLine( vLineList, ( strDecoretion + strText ),
pStrFontName ? pStrFontName : "Default",
pCtrlText->GetFontSize(), false, true );
#endif
//strNewStory += strDecoretion;
int size = vLineList.size();
for( int i = 0; i < size; ++i )
{
if( i >= nMaxListSize || size <= crrScrollPos + i )
break;
// 각 행별로 꾸미기태그 적용.
strNewStory += strDecoretion + vLineList[ crrScrollPos + i ];
strNewStory += "<BR>";
}
// 스크롤바의 현재위치 조정추가. bintitle. 2010.10.29.
if( size < nMaxListSize || bNewText )
{
crrScrollPos = 0;
pScrollBase->SetPosition( crrScrollPos );
}
// 스크롤바 Thumb 조절.
pScrollBase->SetScrollRange( nMaxListSize, size );
// 텍스트 적용.
std::string fontName = CStringUtil::StringFormat("<font:%s>",pStrFontName); // 폰트 이름이 아예제거되서 기본폰트만 사용되서 추가..
strNewStory = fontName + strNewStory;
pCtrlText->SetCaption( strNewStory.c_str() );
}
/// 2010.10.27 - prodongi
std::string extractTokenValue(std::string const& str, std::string const& token)
{
std::string value;
std::string _token = "<" + token + ":";
std::string::size_type nPos = str.find(_token);
if( nPos != std::string::npos )
{
nPos += _token.length();
std::string strTemp( str.begin() + nPos, str.begin() + str.size() );
std::string::size_type nPos_End = strTemp.find_first_of( ">" );
strTemp = strTemp.substr( 0, nPos_End );
value = str.substr( nPos, strTemp.size());
}
return value;
}
/// 2010.11.04 - prodongi
void extractTokenAndText(std::string const& str, std::string& token, std::string& text)
{
std::string _str = str;
std::string::size_type posS, posE;
bool is = true;
while (is)
{
posS = _str.find_first_of("<");
if (posS == std::string::npos)
{
if (!_str.empty())
{
text += _str;
}
break;
}
else if (0 != posS)
{
text += _str.substr(0, posS);
_str = _str.substr(posS, _str.size());
}
else
{
posE = _str.find_first_of(">");
if (posE != std::string::npos)
{
token += _str.substr(posS, posE+1);
_str = _str.substr(posE+1, _str.size());
}
else
{
/// 잘 못된 스트링
break;
}
}
};
}
/// 2011.11.23 구분자가 L"|" 같은 경우에 대만 처럼 會같은 특별한 문자가 들어갈 경우에 wchar 변환 호환성으로 높이기 위해서 MultiByteToWideChar를 사용 - prodongi
void safeM2W(char const* szMsg, wchar_t const* delimiter, std::wstring& wstr)
{
if (0 == wcscmp(delimiter, L"|"))
{
static wchar_t wbuff[2049];
size_t _wbuffSize = 2048;
wchar_t* _wbuff = NULL;
bool _memAlloc = false;
size_t msgSize = strlen(szMsg);
if (msgSize > _wbuffSize)
{
_memAlloc = true;
_wbuffSize = msgSize;
_wbuff = new wchar_t[msgSize+1];
}
else
{
_wbuff = wbuff;
}
memset(_wbuff, 0, sizeof (wchar_t) * (_wbuffSize+1));
int codePage = KTextRender::GetDefaultCodePage();
::MultiByteToWideChar(codePage, 0, szMsg, strlen(szMsg), _wbuff, _wbuffSize);
wstr = _wbuff;
size_t a = wcslen(_wbuff);
if (_memAlloc)
{
SAFE_DELETE_ARRAY(_wbuff);
}
}
else
{
//유코드 변환 과정에서 윈도우 로컬 관련 문제점을 iconv로 수정
//2009-06-24: hunee
wstr = nsl::uni::conv(szMsg);
}
}
/// 2011.11.29 safeM2W를 사용해서 유니코드로 변환뒤에 해당 문자를 찾는다 - prodongi
bool safeFindString(char const* str, wchar_t const* delimiter)
{
std::wstring wstr;
safeM2W(str, delimiter, wstr);
std::wstring::size_type pos = wstr.find(delimiter);
return pos != std::string::npos;
}
/// 2011.11.29 - prodongi
void safeReplaceString(std::string& str, wchar_t const* from, wchar_t const* to)
{
std::wstring wstr;
safeM2W(str.c_str(), from, wstr);
std::wstring::size_type pos;
while( ( pos = wstr.find(from) ) != std::wstring::npos )
{
wstr.replace( pos, 1, to );
}
str = nsl::uni::conv(wstr);
}
void decodeDir(char const* curDir)
{
WIN32_FIND_DATA FileData;
HANDLE hSearch;
unsigned cnt = 0;
hSearch = FindFirstFile( (std::string( curDir ) + "*" ).c_str() , &FileData);
if (hSearch == INVALID_HANDLE_VALUE)
{
return ;
}
std::string decodeFileName;
std::string strFullPath;
while ( true )
{
if( strcmp( FileData.cFileName, "." ) && strcmp( FileData.cFileName, ".." ) )
{
decodeFileName = (FileData.cFileName);
KFileNameCipher::DecodeFileName(decodeFileName);
KStream* s = KFileManager::Instance().CreateStreamFromResource(decodeFileName.c_str());
if (s)
{
std::string reDir(curDir);
reDir += decodeFileName.c_str();
FILE* f = fopen(reDir.c_str(), "wb");
fwrite(s->GetMappedPtr(0), s->GetLength(), 1, f);
fclose(f);
}
}
if (!FindNextFile(hSearch, &FileData))
{
break;
}
}
FindClose(hSearch);
}
char* getIovationBlackBox()
{
typedef HRESULT (*RegProto)();
typedef int (*ioVerFn)( char ** );
typedef int (*ioBeginFn)( char ** );
typedef void (*ioFreeFn)( char **);
HMODULE hDLL = LoadLibrary( "StmOCX.dll" );
ioFreeFn freeFn;
ioBeginFn beginFn;
ioVerFn verFn;
char* bbData = NULL;
if ( hDLL == NULL )
{
_oprint("Faile iovation library load \n");
return NULL;
}
try {
freeFn = (ioFreeFn) GetProcAddress( hDLL, "io_FreeData" );
beginFn = (ioBeginFn) GetProcAddress( hDLL, "io_Begin" );
verFn = (ioVerFn) GetProcAddress( hDLL, "io_Version" );
#ifdef _DEV
// This is only for debugging purposes and is not needed
if ( verFn )
{
char *ver = NULL;
if ( verFn( &ver ) == 0 )
{
_oprint("iovation version: %d\n", ver);
if ( freeFn )
freeFn( &ver );
}
else
{
_oprint("failed get ioVersion version\n");
}
}
else
{
_oprint("Failed get address iovation io_vation function\n");
}
#endif
// this is the beginning of the call to get a blackbox
if ( beginFn )
{
char *bb = NULL;
int result = beginFn( &bb );
if ( result == 0 )
{
size_t dataSize = strlen(bb);
if (0 < dataSize)
{
bbData = new char[dataSize+1];
memcpy(bbData, bb, dataSize);
bbData[dataSize] = 0x00;
}
else
{
_oprint("invalid iovation black box data size\n");
}
#ifdef _DEV
_oprint(" iovation Blackbox: %s\n", bb);
#endif
if ( freeFn )
freeFn( &bb );
else
_oprint("iovation ioBegin failed\n");
}
}
else
{
_oprint("iovation Unable to locate io_Begin\n");
}
}
catch ( ... )
{
_oprint("iovation Caught exception\n");
}
FreeLibrary( hDLL );
return bbData;
}
bool getCurrentMapPostionXY(float x, float y, POINT& outPos)
{
if( g_pCurrentGameSystem == NULL )
return false;
SGameWorld* pGameWorld = dynamicCast<SGameWorld*>(g_pCurrentGameSystem->GetGame());
if( pGameWorld == NULL )
return false;
const CTerrainSeamlessWorldInfo* pSeamlessWorldInfo = pGameWorld->GetSeamlessWorldInfo();
if( pSeamlessWorldInfo == NULL )
return false;
float fMapLen = float( pSeamlessWorldInfo->GetTileCountPerSegment() ) * float(pSeamlessWorldInfo->GetSegmentCountPerMap() ) * pSeamlessWorldInfo->GetTileLength();
outPos.x = (int)(x / fMapLen);
outPos.y = (int)(y / fMapLen);
// nWorldID = m_pSeamlessWorldInfo->GetWorldID( nMapX, nMapY );
return true;
}
bool IsRamadanPrayRoom()
{
if( g_pCurrentGameSystem == NULL )
return false;
SGameAvatarEx* pMyCharacter = g_pCurrentGameSystem->GetLocalPlayer();
if( pMyCharacter == NULL )
return false;
K3DVector vPos = pMyCharacter->GetCurPosWithChangeDir();
SGameWorld* pGameWorld = dynamicCast<SGameWorld*>(g_pCurrentGameSystem->GetGame());
if( pGameWorld == NULL )
return false;
const CTerrainSeamlessWorldInfo* pSeamlessWorldInfo = pGameWorld->GetSeamlessWorldInfo();
if( pSeamlessWorldInfo == NULL )
return false;
float fMapLen = float( pSeamlessWorldInfo->GetTileCountPerSegment() ) * float(pSeamlessWorldInfo->GetSegmentCountPerMap() ) * pSeamlessWorldInfo->GetTileLength();
int nx = (int)(vPos.x / fMapLen);
int ny = (int)(vPos.y / fMapLen);
if( nx == RAMADAN_PRAY_ROOM_X && ny == RAMADAN_PRAY_ROOM_Y )
return true;
return false;
}