Ejemplo n.º 1
0
// 생성자
// client mode
XSessionWinsock::XSessionWinsock( XSessionDelegate *pDelegate, const char *cIP, unsigned short port ) 
: XSession( pDelegate )
{ 
	Init(); 
	//
	if( WSAStartup( MAKEWORD(1,1), &m_WSAData ) != 0 ) 
	{
		XALERT( "WSAStartup failed" );
		return;
	}
	//
	m_Socket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP ); 
	if( m_Socket == INVALID_SOCKET ) 
	{
		XALERT( "create socket failed" );
		return;
	}
	//
	SOCKADDR_IN addr; 
	addr.sin_family = AF_INET; 
	addr.sin_port = htons(0); 
	addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY); 
	if( bind( m_Socket, (struct sockaddr *)&addr, sizeof(addr) ) == SOCKET_ERROR ) 
	{ 
		XALERT( "Network bind error" );
		Destroy();
		return; 
	} 
	strcpy_s( m_cIP, sizeof(m_cIP), cIP );
	m_Port = port;
	m_Mode = xCLIENT;
	//
	InitializeCriticalSection( &m_cs );
}
Ejemplo n.º 2
0
	/**
	 @brief 테이블형태로 된 스트링을 읽어 어레이에 담는다.
	*/
int XESkillMng::ReadTableAry2( LPCTSTR szAttrName,
															LPCTSTR idsSkill,
															XVector<float>* pOutAry,
															LPCTSTR szStr,
															xtValType valType ) {
	CToken token;
	token.LoadStr( szStr );
	int idx = 0;
	// pOutAry.size() != 0 경우도 있다. 상위블럭에서 값을 입력한 경우 하위에 상속되기때문에. 그러므로 그런경우는 클리어 시키고 다시 읽는다.
	pOutAry->Clear();
	pOutAry->Add( 0.f );	// index0은 쓰지 않음.
	int level = 0;
	float numFirst = 0;
	while( 1 ) {
		if( token.IsEof() )
			break;
		numFirst = token.GetNumberF();
		if( numFirst == TOKEN_ERROR )
			break;
		if( token.IsEof() )
			break;
		level = (int)numFirst;
		if( level != idx + 1 ) {
			XALERT( "skill %s(%s):레벨번호가 순차적이지 않습니다.level:%d",
				idsSkill,
				szAttrName,
				level );
			return 0;
		}
		token.GetToken();	// :
		float ability = token.GetNumberF();
		if( token.IsError() ) {
			XALERT( "skill %s(%s):잘못된 숫자입니다..level:%d", idsSkill,
																												szAttrName,
																												level );
			return 0;
		}
		if( valType == xPERCENT ) {
			pOutAry->Add( ability / 100.f );
		} else {
			pOutAry->Add( ability );
		}
		++idx;
		// 레벨 10을 넘어가도 더이상 읽지 않는다.
		if( idx >= XGAME::MAX_SKILL_LEVEL )
			break;
	}
	// 만약 스트링이 테이블형태가 아니고 숫자하나일경우 0번인덱스에 값을 넣는다.
	if( pOutAry->size() == 1 ) {
		if( valType == xPERCENT )
			( *pOutAry )[0] = numFirst / 100.f;
		else
			( *pOutAry )[0] = numFirst;
	}
	return pOutAry->size();
}
Ejemplo n.º 3
0
// server mode
XSessionWinsock::XSessionWinsock( XSessionDelegate *pDelegate, unsigned short port ) 
: XSession( pDelegate )
{
	Init(); 
	//
	if( WSAStartup( MAKEWORD(1,1), &m_WSAData ) != 0 ) 
	{
		XALERT( "WSAStartup failed" );
		return;
	}
	//
	m_Socket = socket( AF_INET, SOCK_STREAM, 0 ); 
	if( m_Socket == INVALID_SOCKET ) 
	{
		XALERT( "create socket failed" );
		return;
	}
	//
	SOCKADDR_IN addr; 
	addr.sin_family = AF_INET; 
	addr.sin_port = htons(port); 
	addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY); 
	if( bind( m_Socket, (struct sockaddr *)&addr, sizeof(addr) ) == SOCKET_ERROR ) 
	{ 
		XALERT( "Network bind error" );
		Destroy();
		return; 
	} 
	//
	if( listen( m_Socket, SOMAXCONN ) == SOCKET_ERROR ) 
	{
		XALERT( "Network::listen error" );
		Destroy();
		return; 
	}
	//
//	m_pDelegate = pDelegate;
//	strcpy_s( m_cIP, strlen(cIP), cIP );
	m_Port = port;
	m_Mode = xSERVER;
	// 리쓴완료, 억셉트 대기중
	if( m_pDelegate )
		m_pDelegate->DelegateFinishListen( this );
	//
	InitializeCriticalSection( &m_cs );

	DWORD idThread;
	m_hAcceptThread = CreateThread( NULL, 0, _AcceptThread, (LPVOID)this, 0, &idThread); 

}
Ejemplo n.º 4
0
//====================================================
//#include "etc/InputMng.h"
BOOL XConnectINI::Load( LPCTSTR szFile )
{
	CToken token;
	if( token.LoadFromDoc( szFile, XE::TXT_EUCKR ) == xFAIL )
	{
#ifdef WIN32
  #ifdef _DEBUG
		strcpy_s( m_cIP, "192.168.100.44" );
  #else
		_tstring strDocPath = XE::MakeDocFullPath( _T(""), szFile );
		XALERT( "%s file not found", strDocPath.c_str() );
		exit(1);
//		strcpy_s( m_cIP, "49.239.180.50" );
  #endif 
#else
        if( XInputMng::s_Device == XE::DEVICE_IPAD ||
           XInputMng::s_Device == XE::DEVICE_IPOD )
            strcpy_s( m_cIP, XIP_LOGIN );
        else
        if( XInputMng::s_Device == XE::DEVICE_ANDROID )
            strcpy_s( m_cIP, XIP_LOGIN );
        else
        {
            strcpy_s( m_cIP, XIP_LOGIN );
    //		strcpy_s( m_cIP, "59.5.5.245" );
        }
#endif
        m_Port = XPORT_LOGIN;
		strcpy_s( m_cIPPatch, XIP_PATCH );
		strcpy_s( m_cID, "test3" );
		return FALSE;
	}
	AXLOGXN("try read ip");
	strcpy_s( m_cIP, Convert_TCHAR_To_char( token.GetToken() ) );		// ip
	AXLOGXN("login ip:%s", token.m_Token);
	if( XE::IsEmpty(m_cIP) )
		strcpy_s( m_cIP, "211.52.84.50" );
		
	AXLOGXN("try read port");
	m_Port = token.GetNumber();
	AXLOGXN("login port:%d", m_Port);
#ifdef _XBOT2
  #ifdef _XPATCH
  #error "봇 클라이언트에서는 _XPATCH를 빼시오"
  #endif
	token.GetNumber();		// dummy
	m_numBot = token.GetNumber();
#endif
#ifdef _XPATCH
	AXLOGXN("try read patch ip");
	strcpy_s( m_cIPPatch, SZ2C( token.GetToken() ) );	// patchsvr ip
	AXLOGXN("patch ip:%s", token.m_Token);
	if( XE::IsEmpty(m_cIPPatch) )
		strcpy_s( m_cIPPatch, "49.239.180.50" );
#endif

	return TRUE;
}
Ejemplo n.º 5
0
XFontDatSpr::XFontDatSpr( LPCTSTR szFontSpr ) 
	: XBaseFontDat( szFontSpr, 0 ) {
	Init();
	const bool bBatch = true;
	m_spDat = SPRMNG->Load( szFontSpr, XE::xHSL(), true, TRUE, false, bBatch, nullptr );
	if( m_spDat == nullptr ) {
		XALERT( "%s읽기 실패", szFontSpr );
	}
}
Ejemplo n.º 6
0
XSkillDat* XESkillMng::Add( XSkillDat *pSkillDat )
{
	for( auto pDat : m_listSkillDat )
	{
		if( pDat->GetstrIdentifier() == pSkillDat->GetstrIdentifier() )
		{
			XALERT("중복된 스킬식별자: %s", pSkillDat->GetstrIdentifier().c_str() );
		}
	}
	m_listSkillDat.push_back( pSkillDat );
	return pSkillDat;
}
Ejemplo n.º 7
0
BOOL XESocketClientInServer::CreateSocket()
{
	XAUTO_LOCK;
	m_Socket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP ); 
	if( m_Socket == INVALID_SOCKET ) 
	{
		XALERT( "create socket failed" );
		return FALSE; 
	}
	SOCKADDR_IN addr; 
	addr.sin_family = AF_INET; 
	addr.sin_port = htons(0); 
	addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY); 
	if( bind( m_Socket, (struct sockaddr *)&addr, sizeof(addr) ) == SOCKET_ERROR ) { 
		XBREAK( 1 );
		XALERT( "Network bind error" );
		Destroy();
		return FALSE; 
	} 
	return TRUE;
}
Ejemplo n.º 8
0
/**
 @brief 비보정 파라메터 효과를 적용한다.
*/
int XSkillReceiver::ApplyEffectNotAdjParam( XSkillDat *pDat, 
																						XSkillUser *pCaster, 
																						const EFFECT *pEff, 
																						int level )
{
	// 보정파라메터이거나 invalid한것은 0을 리턴
	///< 발동되는 효과를 직접 하드코딩 하고 싶을때는 발동파라메터가 보통 0이기때문에 하위에서 상속받을수 있는 이곳에서 검사하게 했다. 웒하면 상속받는쪽에서 검사안할수 있으니까
//	if( IsAdjParam( pEffect->invokeParameter ) >= 0 )	return 0;		// 함수명이 모호해서 삭제
	if( pEff->invokeParameter >= 0 )
		return 0;
//	if( pEffect->invokeParameter < 0 ) {
	float ivkAbilMin = pEff->GetAbilityMin(level);
	if( pEff->invokeAddAbility != 0.f ) {
		if( pEff->idAddAbilityToClass == 0 )
			XALERT("경고:%s:추가능력치는 있는데 추가능력치대상이 없습니다.", pDat->GetstrIdentifier().c_str() );
		if( IsInvokeAddTarget( pEff->idAddAbilityToClass ) == TRUE )
			ivkAbilMin += pEff->invokeAddAbility;
	}
	// 커스텀 추가 증폭
// 		루프( 증폭버프 = 증폭스킬리스트 )	이와같은 방식으로 시스템화.
// 		{
// 			증폭Effect = 증폭버프->GetEffectIndex(0);
// 			if( 증폭이펙트->증폭파라메터 == 능력치 )
// 			{
// 				float add = 0.f;
// //				float addMultiply = 0.f;
// 				add = 증폭이펙트->능력치[level];
// 				invokeAbilityMin += add;
// //				invokeAbilityMin = invokeAbilityMin + invokeAbilityMin * addMultiply;
// 			}
// 		}
	float add = 0.f;
	float addMultiply = 0.f;
	pCaster->OnSkillAmplifyUser( pDat, this, pEff, xEA_ABILITY, &addMultiply, &add );
	ivkAbilMin += add;
	ivkAbilMin = ivkAbilMin + ivkAbilMin * addMultiply;
	// 능력치값을 다른 다른형태로 변형해서 사용하고 싶다면 아래 핸들러를 정의해서 바꾼다.
	pCaster->OnAdjustEffectAbility( pDat, pEff, pEff->invokeParameter, &ivkAbilMin );
	//
	return OnApplyEffectNotAdjParam( pCaster, pDat, pEff, ivkAbilMin );
//	}
// 	return 0;
}
Ejemplo n.º 9
0
void XAppMain::OnError( XE::xtError codeError, DWORD p1, DWORD p2 )
{
	switch( codeError )
	{
		// 기본 시스템 폰트가 없거나 손상되었다.
	case XE::xERR_FAIL_CREATE_ASIC_FONT:
		{
			if( XE::GetLoadType() == XE::xLT_WORK_TO_PACKAGE_COPY )
			{
				// 패키지에 있는 파일을 워크에 카피해 넣는다.
				LPCTSTR szFont = (LPCTSTR)p1;
				XE::CopyPackageToWork( XE::MakePath( DIR_FONT, szFont ) );
				XALERT("error! app restart please.");
				DoExit();
			}
		}
		break;
	}
}
Ejemplo n.º 10
0
/**
 @brief 객체가 생성된 후 가장먼저 불려짐.
*/
bool XESocketClientInServer::OnCreate( const std::string& strcIP
																		, WORD port
																		, XNetworkDelegate* pDelegate
																		, DWORD param/* = 0*/ )
{
	if( XBREAK(strcIP.empty() || port == 0) ) {
		return false;
	}
	m_strcIP = strcIP;
	m_strtIP = C2SZ(strcIP);
	m_Port = port;
	m_dwConnectParam = param;
	SetpDelegate( pDelegate );
	if( !XWinNetwork::sStartUp() ) {
		XALERT( "WSAStartup failed" );
		return false;
	}
	return CreateSocket() != FALSE;
}
Ejemplo n.º 11
0
/**
 @brief 확률표에따라 주사위를 굴려 테이블의 인덱스를 리턴한다.
 확률표는 확률의 합이 1.0(100%)이 되어야 한다.
*/
int GetDiceChance( const std::vector<float>& aryChance ) 
{
	DWORD maxDice = 1000;
	DWORD dice = random( maxDice );
	double addChance = 0;
	int size = aryChance.size();
	for( int i = 0; i < size; ++i ) {
		addChance += aryChance[ i ];
		if( i == size - 1 && addChance != 1.0f ) {
			if( aryChance[ i ] == 0 )
				return i - 1;
			addChance = 1.f;
		}
		if( addChance > 1.01 )
			XALERT( "warning: Go beyond the sum of the probability of 1.0" );
		if( dice < (DWORD)( maxDice * addChance ) )
			return i;
	}
	// 확률표 합이 100미만일경우 여기까지 오는경우도 있다.
	return -1;
}
Ejemplo n.º 12
0
/**
 full_list.txt를 만든다.
 core_list.txt를 만든다.(apk50메가선을 유지하도록)
*/
void XMain::DoExtract( void )
{
    // 일단 모든 리소스 파일의 목록을 뽑는다.
//	XArrayLinear<XSYSTEM::XFILE_INFO> aryAll;
    XVector<XSYSTEM::XFILE_INFO> aryAll;
//	XSYSTEM::CreateFileList( XE::_GetPathPackageRoot(), _T("*.*"), &aryAll );
    XSYSTEM::GetFileList( XE::_GetPathPackageRoot(), _T("*.*"), &aryAll, _T("") );
    if( aryAll.Size() > 1500 ) {

    }
    // full_list.txt를 만든다.
    {
// 		XArrayLinear<XPatch::XRES_INFO> ary;
// 		ary.Create( aryAll.size() );
        XVector<XPatch::XRES_INFO> ary;
        int cnt = 1;
        // 파일별로 체크섬을 뽑아 둔다.
//		XARRAYLINEAR_LOOP( aryAll, XSYSTEM::XFILE_INFO, info )
        for( auto& info : aryAll ) {
            XPatch::XRES_INFO resInfo;
            resInfo.strFile = info.strFile;
            resInfo.size = info.size;
            resInfo.llChecksum = XE::CalcCheckSum( info.strFile.c_str() );
            _tstring strFilename = XE::GetFileName( resInfo.strFile.c_str() );
            int idxDuplicate = GetResIdxByCheckSum( ary, resInfo.llChecksum );
            if( idxDuplicate != -1 ) {
                XALERT( "duplicate checksum file: idx=%d,%d", idxDuplicate, cnt );
            }
            ary.Add( resInfo );
            CONSOLE( "%d:%s.... %d byte ....checksum=0x%I64x",
                     cnt++,
                     strFilename.c_str(),
                     resInfo.size,
                     resInfo.llChecksum );
        }
        // full_list.txt를 생성한다.
        WriteFullList( ary );
    }
    // core_list.txt를 뽑아낸다.
    {
// 		XArrayLinear<_tstring> aryCore;
// 		aryCore.Create( aryAll.size() );
        XVector<_tstring> aryCore;
        int  i = 0;
//		XARRAYLINEAR_LOOP( aryAll, XSYSTEM::XFILE_INFO, info )
        for( auto& info : aryAll ) {
//			TCHAR szFlename[ 256 ];
//			_tcscpy_s( szFlename, XE::GetFileName( info.strFile.c_str() ) );
            const _tstring strFileName = XE::GetFileName( info.strFile );
            // 테마에 속하지 않는 몬스터중에 mob_ 으로 시작하는 몬스터는
            // 제작은 되었으나 아직 테마에 반영이 안된 몬스터이므로 제외시킨다.
            BOOL bCore = TRUE;
//			TCHAR szExt[ 16 ];
//			_tcscpy_s( szExt, XE::GetFileExt( strFileName ) );
            const _tstring strExt = XE::GetFileExt( strFileName );
            // 다음 단어가 포함되어 있는 파일은 모두 제외
// 			if( _tcsstr( szFlename, _T( "treant" ) ) ||
// 				_tcsstr( szFlename, _T( "rock" ) ) )
// 				bCore = FALSE;
            // 액셀 파일 제외
//			if( XE::IsSame( szExt, _T("xlsx") ) )
            if( strExt == _T("xlsx") )
                bCore = FALSE;
// 			if( XE::IsSame( szFlename, _T("core_list.txt") ) ||
// 				XE::IsSame( szFlename, _T("full_list.txt") ) )
// 				bCore = FALSE;
            if( strFileName == _T("core_list.txt")
                    || strFileName == _T("full_list.txt") )
                bCore = FALSE;
            if( _tcsstr( strFileName.c_str(), _T("sample")) )
                bCore = FALSE;
            //
            if( bCore )
            {
                aryCore.Add( info.strFile );
                XTRACE( "%d: %s", i ++, info.strFile.c_str() );
            } else
            {
                // 제외된 파일명
                XTRACE( "-----------%s", info.strFile.c_str() );
            }

        }
        // core_list.txt로 저장한다.
        WriteCoreList( aryCore );
    }

}
Ejemplo n.º 13
0
// pRoot의 모든 스킬을 읽는다.
XSkillDat* XESkillMng::LoadSkill( TiXmlElement *pRoot, 
							XSkillDat *pParentDat,
							EFFECT *pParentEffect )
{
	XSkillDat *pSkillDat = NULL;
	EFFECT *pEffect = NULL;
	//////////////////////////////////////////////////////////////////////////
	// 먼저 Attribute(폴더가 아닌것)가 있는지 살펴본다.
	TiXmlAttribute *pAttr = pRoot->FirstAttribute();
	if( pAttr )
	{
		const char *cAttrName = pAttr->Name();
		if( cAttrName )
		{
			// 속성이 하나라도 있으면 skillDat객체를 생성한다.
			// Attribute가 있으면 일단 스킬로 인식하고 Dat객체를 생성한다.
			pSkillDat = CreateSkillDat();
			if( pParentDat )
			{
				ID idSkill = pSkillDat->GetidSkill();
				*pSkillDat = *pParentDat;		// 부모의 데이타를 상속받는다.
				pSkillDat->SetidSkill( idSkill );
				_tstring strIdentifier = U82SZ( pRoot->Value() );
				pSkillDat->SetstrIdentifier( strIdentifier );
			}
			// 디폴트 이펙트버퍼도 하나 받는다.
			pEffect = new EFFECT;		
			if( pParentEffect )
				*pEffect = *pParentEffect;
			// 루프 시작
			do 
			{
				const char *cAttrName = pAttr->Name();
				const char *cParam = pAttr->Value();
				if( cAttrName && cAttrName[ 0 ] != '_' )
				{
					XU8LOG( cAttrName );
					XU8LOG( cParam );
					// 변수명과 값을 파싱해서 pSkillDat에 넣는다.
					ParsingAttr( pAttr, cAttrName, cParam, pSkillDat, pEffect );
				}
			} while (( pAttr = pAttr->Next() ));
		}
	}
	
	// pRoot에 폴더가 있는지 찾는다.
	TiXmlElement *pElemChild = pRoot->FirstChildElement();
	if( pElemChild  )
	{
		do 
		{
			// pRoot하의 모든 폴더를 하나씩 꺼낸다.
			const char *cFolderName = pElemChild->Value();
			if( cFolderName && cFolderName[0] != '_' ) {
				XU8LOG( cFolderName );
				//////////////////////////////////////////////////////////////////////////
				// "효과"블럭은 따로 처리
				if( XSAME( pElemChild->Value(), 96 ) ||
					XSAME( pElemChild->Value(), 226 ) )	{ // 효과/발동효과
					if( pSkillDat == NULL ) {
						pSkillDat = CreateSkillDat();
						if( pParentDat ) {
							ID idSkill = pSkillDat->GetidSkill();
							*pSkillDat = *pParentDat;		// 부모의 데이타를 상속받는다.
							pSkillDat->SetidSkill( idSkill );
							_tstring strIdentifier = U82SZ( pRoot->Value() );
							pSkillDat->SetstrIdentifier( strIdentifier );
						}
					}
					EFFECT *pEffBlock = new EFFECT;
					if( pEffect )
						*pEffBlock = *pEffect;	// 하위상속을 위해 내용 복사.
					else
						*pEffBlock = *pParentEffect;		// 스킬블럭에 디폴트 파라메터가 없으면 부모것을 디폴트로 쓴다.

					int numAttr = LoadEffect( pElemChild, pSkillDat, pEffBlock );
					// 효과블럭안에 아무것도 없었으면 지운다.
					if( numAttr == 0 )
						SAFE_DELETE( pEffBlock );
					if( pEffBlock )
						pSkillDat->AddEffect( pEffBlock );
				} else
				if( XSAME( pElemChild->Value(), 235 ) )	{	// 발동조건
					if( pEffect == nullptr ) {
						pEffect = new EFFECT;
						if( pParentEffect )
							*pEffect = *pParentEffect;
					}
					LoadCond( pElemChild, pEffect );
				} else
					if( cFolderName[0] != '_' )		// 스킬이름이 _로 시작되면 읽지 않는다.
					{
						// 그외 폴더는 일단 스킬로 인식한다.
						XSkillDat* pNewSkillDat = NULL;
						pNewSkillDat = LoadSkill( pElemChild,
							( pSkillDat ) ? pSkillDat : pParentDat,
							( pEffect ) ? pEffect : pParentEffect );
						if( pNewSkillDat ) {
							Add( pNewSkillDat );
						}
					}
			}
		} while (( pElemChild = pElemChild->NextSiblingElement() ));
	}
	if( pSkillDat )	{
		// "효과"블럭이 추가된게 있었으면 디폴트용으로 생성되었던 이펙트 블럭은 필요없으므로 지운다.
		if( pSkillDat->GetNumEffect() > 0 ) {
			SAFE_DELETE( pEffect );
		}
		else
		// 효과폴더가 없고 발동파라메터가 지정되지 않은 폴더는 스킬이 아니라고 보고 지운다.
		if( pSkillDat->GetNumEffect() == 0 ) {
			if( pEffect->invokeParameter == 0 && 
				pEffect->invokeState == 0 &&
				pEffect->strInvokeSkill.empty() && 
				pEffect->idInvokeSkill == 0 &&
				pEffect->invokeAbilityMin.size() == 0 &&
				pEffect->invokeJuncture != 99 )	{	// 발동시점:하드코딩
				SAFE_RELEASE_REF( pSkillDat );
				SAFE_DELETE( pEffect );
			} else
				// "효과"블럭으로 추가된게 없고 발동파라메터는 지정되었으면 디폴트 이펙트를 이펙트로 추가한다.
				pSkillDat->AddEffect( pEffect );
		} else {
			XBREAK(1);
		}
		if( pSkillDat )
		{
			XBREAK( pSkillDat->GetTargetEff().IsHave() && pSkillDat->GetTargetEff().m_Loop == xAL_LOOP );
			if( pSkillDat->m_strShootObj.empty() == false && pSkillDat->m_idShootObj == 0 )
				pSkillDat->m_idShootObj = 1;
			// 파라메터 보정
			for( const auto pEffect : pSkillDat->GetlistEffects() ) {
				// 지속시간이 있는데 발동시점이 지정안되면 디폴트로 persist동작을 하도록 수정.(버프라도 지속시간계속 발동하는게 있고 버프받는최초에만 적용되는게 있다, 버프끝날때 발동되는것도 있고.
				if( pEffect->IsDuration() && pEffect->invokeJuncture == xJC_NONE ) {
						pEffect->invokeJuncture = xJC_PERSIST;
				}
				LCONSOLE( !pEffect->IsDuration() && pEffect->invokeJuncture == xJC_PERSIST
						 , "%s", _T("지속시간이 없는스킬인데 지속발동으로 지정되어 있음.") );
				// 발동시점스킬이 지정되어 있다면 발동시점은 무조건 스킬발동시가 된다.
				if( pEffect->strInvokeTimeSkill.empty() == false ) {
					pEffect->invokeJuncture = xJC_INVOKE_SKILL;	// 이걸하지않으면 지속형 스킬이 되어버림.
				}
				// 발동대상우호가 지정되지 않았으면 시전대상우호를 가져다 쓴다.
				if( pEffect->invokefiltFriendship == xfNONESHIP )
					pEffect->invokefiltFriendship = pEffect->castfiltFriendship;
				// 시전거리는 정해졌는데 시전범위타입이 지정되지 않았으면 디폴트로 원형이 됨
				if( pEffect->castSize.w > 0.f && pEffect->castSize.h > 0.f &&
					pEffect->castTargetRange == xTR_ONE )
					pEffect->castTargetRange = xTR_LINE;
				if( pEffect->castSize.w > 0.f && 
					pEffect->castTargetRange == xTR_ONE )
					pEffect->castTargetRange = xTR_CIRCLE;
				if( pEffect->invokeTarget == xIVT_NONE )
					pEffect->invokeTarget = xIVT_CAST_TARGET;
				if( pEffect->invokeTarget == xIVT_CAST_TARGET_RADIUS 
						|| pEffect->invokeTarget == xIVT_CAST_TARGET_SURROUND ) {
					if( pEffect->IsHaveInvokeSize() == false )
						XALERT("스킬\"%s\":발동범위가 지정되지 않음", pSkillDat->GetstrIdentifier().c_str() );
				}
				// 지속시간스킬이면서 발동스킬이 있는건 에러(매프레임 스킬을 발동시키게 됨)
				XBREAK( pEffect->IsDuration() 
								&& pEffect->secInvokeDOT == 0 
								&& pEffect->invokeJuncture == xJC_PERSIST
								&& !pEffect->strInvokeSkill.empty() );
				XBREAK( pEffect->castTarget == xCST_BASE_TARGET_POS			// 시전대상이 좌표형
								&& pEffect->IsDuration()												// 지속시간형
								&& pEffect->m_PersistEff.IsEmpty() );						// 일때 지속효과 spr이 없으면 안됨.(투명 객체됨)
				AdjustEffectParam( pSkillDat, pEffect );	// virtual
			} // for effect
		}
	} else {
		SAFE_DELETE( pEffect );
	}
	return pSkillDat;
}
Ejemplo n.º 14
0
/**
 @brief 
*/
BOOL XESkillMng::ParsingEffect( TiXmlAttribute *pAttr,
								const char *cAttrName,
								const char *cParam,
								XSkillDat* pSkillDat,
								EFFECT *pEffect )
{
#ifdef _DEBUG
	_tstring strUTF16 = U82SZ(cAttrName);
#endif
	if( XSAME( cAttrName, 2 ) ) {	// 시전대상
		pEffect->castTarget = (xtCastTarget) ParsingParam( cParam );
	} else
	if( XSAME( cAttrName, 15 ) )	// 시전대상 우호
	{
		pEffect->castfiltFriendship = (xtFriendshipFilt) ParsingParam( cParam );
	} else
	if( XSAME( cAttrName, 199 ) )	// 시전조건
	{
		pEffect->castTargetCond = (xtTargetCond) ParsingParam( cParam );
	} else
	if( XSAME( cAttrName, 17 ) )	// 시전대상플레이어
	{
		pEffect->castfiltPlayerType = (xtPlayerTypeFilt) ParsingParam( cParam );
	} else
	if( XSAME( cAttrName, 126 ) )	// 시전범위타입
	{
		pEffect->castTargetRange = (xtTargetRangeType) ParsingParam( cParam );
	} else
	if( XSAME( cAttrName, 20 ) )	// 시전대상이펙트
	{	
		pEffect->m_CastTargetEff.m_strSpr = U82SZ( cParam );
	} else
	if( XSAME( cAttrName, 21 ) )	// 시전대상이펙트id
	{	
		pEffect->m_CastTargetEff.m_idAct = (int)pAttr->IntValue();
	} else
	if( XSAME( cAttrName, 261 ) )	// 시전대상이펙트반복
	{
		pEffect->m_CastTargetEff.m_Loop = (xtAniLoop)ParsingParam( cParam );
	} else
	if( XSAME( cAttrName, 156 ) )	// 시전대상이펙트생성지점
	{
		pEffect->m_CastTargetEff.m_Point = (xtPoint) ParsingParam( cParam );
	} else
	if( XSAME( cAttrName, 60 ) || XSAME( cAttrName, 127 ) )	// /시전범위 시전길이
	{	
		pEffect->castSize.w = (float)pAttr->DoubleValue();
	} else
	if( XSAME( cAttrName, 128 ) )	// 시전폭
	{
		pEffect->castSize.h = (float)pAttr->DoubleValue();
	} else
	if( XSAME( cAttrName, 22 ) )	// 지속시간
	{	
//		pEffect->secDuration = (float)pAttr->DoubleValue();
		_tstring strParam = U82SZ( cParam );
		_tstring strAttrName = U82SZ( cAttrName );
		ReadTableAry( strAttrName.c_str(),
			pSkillDat->GetstrIdentifier().c_str(),
			&pEffect->arySecDuration, strParam.c_str(), xVAL );
	} else
	if( XSAME( cAttrName, 233 ) )	// 발동지속시간
	{	
		pEffect->secDurationInvoke = (float)pAttr->DoubleValue();
	} else
	if( XSAME( cAttrName, 23 ) )	// 시전사운드
	{	
		pEffect->idCastSound = (int)pAttr->IntValue();
	} else
	if( XSAME( cAttrName, 3 ) )	// 발동대상
	{
		pEffect->invokeTarget = (xtInvokeTarget) ParsingParam( cParam );
	} else
	if( XSAME( cAttrName, 10 ) )	// 발동대상 우호
	{
		pEffect->invokefiltFriendship = (xtFriendshipFilt) ParsingParam( cParam );
	} else
	if( XSAME( cAttrName, 24 ) )	// 발동대상플레이어
	{
		pEffect->invokefiltPlayerType = (xtPlayerTypeFilt) ParsingParam( cParam );
	} else
	if( XSAME( cAttrName, 122 ) )	// 발동시점
	{
		pEffect->invokeJuncture = (xtJuncture) ParsingParam( cParam );
	} else
	if( XSAME( cAttrName, 25 ) )	// 발동대상조건
	{
		pEffect->invokeTargetCondition = (xtCondition) ParsingParam( cParam );
	} else
	if( XSAME( cAttrName, 99 ) )	// 발동스킬id
	{	
		pEffect->idInvokeSkill = (ID)pAttr->IntValue();
	} else
	if( XSAME( cAttrName, 26 ) )	// 발동스킬
	{	
		pEffect->strInvokeSkill = U82SZ( cParam );
	} else
	if( XSAME( cAttrName, 232 ) )	// 발동시점스킬
	{
		pEffect->strInvokeTimeSkill = U82SZ( cParam );
	} else
	if( XSAME( cAttrName, 239 ) )	// 발동조건스킬
	{
		pEffect->strInvokeIfHaveBuff = U82SZ( cParam ); 
	} else
	if( XSAME( cAttrName, 116 ) )	// 발동확률
	{
		const _tstring strParam = U82SZ( cParam ); 
		const _tstring strAttrName = U82SZ( cAttrName );
		ReadTableAry( strAttrName.c_str(), 
					pSkillDat->GetstrIdentifier().c_str(), 
					&pEffect->aryInvokeRatio, strParam.c_str(), xPERCENT );
	} else
	if( XSAME( cAttrName, 257 ) )	{// 발동적용확률
		const _tstring strParam = U82SZ( cParam ); 
		const _tstring strAttrName = U82SZ( cAttrName );
		ReadTableAry2( strAttrName.c_str(), 
					pSkillDat->GetstrIdentifier().c_str(), 
					&pEffect->m_aryInvokeApplyRatio, strParam.c_str(), xPERCENT );
	} else
	if( XSAME( cAttrName, 7 ) || XSAME( cAttrName, 161 ) )	// 발동파라메터/효과인덱스.
	{	
		pEffect->invokeParameter = (int)ParsingParam( cParam );
	} else
	if( XSAME( cAttrName, 30 ) )	// 발동대상이펙트
	{	
		pEffect->m_invokeTargetEff.m_strSpr = U82SZ( cParam );
	} else
	if( XSAME( cAttrName, 31 )  )	// 발동대상이펙트id
	{	
		pEffect->m_invokeTargetEff.m_idAct = (int)pAttr->IntValue();
	} else
	if( XSAME( cAttrName, 157 ) )	// 발동대상이펙트생성지점
	{
		pEffect->m_invokeTargetEff.m_Point = (xtPoint) ParsingParam( cParam );
	} else
	if( XSAME( cAttrName, 262 ) )	// 발동대상이펙트반복
	{
		pEffect->m_invokeTargetEff.m_Loop = (xtAniLoop)ParsingParam( cParam );
	} else
	if( XSAME( cAttrName, 228) )	// 증폭파라메터
	{
		pEffect->attrAmplify = (xtEffectAttr)ParsingParam( cParam );
	} else
	if( XSAME( cAttrName, 8 ) )	// 능력치
	{	
		CToken token;
		token.LoadStr( U82SZ( cParam ) );
		token.GetToken();
		pEffect->valtypeInvokeAbility = GetValType( token.m_Token[0] );
		if( pEffect->valtypeInvokeAbility == xNONE_VALTYPE )
		{	
			XALERT( "skill %s:unknown valtype.", pSkillDat->GetszIdentifier() );
			return FALSE;
		}
		// %#기호뒤에 숫자가 더 있을때만 읽는다.

		if( token.IsEof() == FALSE )
		{
			float ability = token.GetNumberF();
			if( pEffect->invokeAbilityMin.size() != 0 )
			{
				XALERT( "skill %s(%s):이미 능력치값이 존재합니다.",
					pSkillDat->GetszIdentifier(),
					U82SZ( cAttrName ) );
				return FALSE;
			}
			// "능력치"만 단독으로 쓰일때는 index 0을 사용한다.
			if( pEffect->valtypeInvokeAbility == xPERCENT )
				pEffect->invokeAbilityMin.Add( ability / 100.f );
			else
				pEffect->invokeAbilityMin.Add( ability );
		}

	} else
	if( XSAME( cAttrName, 125 ))	// 능력치테이블
	{
		_tstring strParam = U82SZ( cParam ); 
		_tstring strAttrName = U82SZ( cAttrName );
		ReadTableAry( strAttrName.c_str(), 
					pSkillDat->GetstrIdentifier().c_str(), 
					&pEffect->invokeAbilityMin, strParam.c_str(), pEffect->valtypeInvokeAbility );
		if( pEffect->invokeParameter == 0 )
		{
			XALERT( "skill %s(%s):발동파라메터가 없거나(해석하지 못했거나) 능력치테이블의 앞에 있지 않습니다.",
							pSkillDat->GetszIdentifier(),
							U82SZ( cAttrName ) );
		}
	} else
	if( XSAME( cAttrName, 101 ) )	// 상태발동
	{
		pEffect->invokeState = (int)ParsingParam( cParam );
	} else
	if( XSAME( cAttrName, 65 ) || XSAME( cAttrName, 28 ) )	// 발동반경/범위
	{	
		_tstring strParam = U82SZ( cParam );
		_tstring strAttrName = U82SZ( cAttrName );
		ReadTableAry( strAttrName.c_str(),
			pSkillDat->GetstrIdentifier().c_str(),
			&pEffect->aryInvokeSize, strParam.c_str(), xVAL );
	} else
	if( XSAME( cAttrName, 159 ) )	// 발동길이
	{
		pEffect->_invokeSize.w = (float)pAttr->DoubleValue();
	} else
	if( XSAME( cAttrName, 160 ) )	// 발동폭
	{
		pEffect->_invokeSize.h = (float)pAttr->DoubleValue();
	} else
	if( XSAME( cAttrName, 29 ) )	// 발동주기
	{	
		pEffect->secInvokeDOT = (float)pAttr->DoubleValue();
	} else
	if( XSAME( cAttrName, 32 ) )	// 적용대상수
	{	
		pEffect->invokeNumApply = pAttr->IntValue();
	} else
	if( XSAME( cAttrName, 162 )  )	// 발동자이펙트
	{	
		if( pEffect->m_invokerEff.m_strSpr.empty() == false )
			XLOGXN("%s: 중복입력. 기존값:%s", U82SZ(cAttrName), pEffect->m_invokerEff.m_strSpr.c_str() );
		pEffect->m_invokerEff.m_strSpr = U82SZ( cParam );
	} else
	if( XSAME( cAttrName, 163 ) )	// 발동자대상이펙트id
	{	
		pEffect->m_invokerEff.m_idAct = (int)pAttr->IntValue();
	} else
	if( XSAME( cAttrName, 258 ) )	// 발동자이펙트생성지점
	{
		pEffect->m_invokerEff.m_Point = (xtPoint) ParsingParam( cParam );
	} else
	if( XSAME( cAttrName, 33 ) )	// 발동사운드
	{	
		pEffect->idInvokeSound = (int)pAttr->IntValue();
	} else
	if( XSAME( cAttrName, 34 ) )	// 중복가능
	{
		pEffect->bDuplicate = (BOOL)ParsingParam( cParam );
	} else
	if( XSAME( cAttrName, 100 ) )	// 버프중첩
	{	
		pEffect->numOverlap = (int)pAttr->IntValue();
	} else
	if( XSAME( cAttrName, 175 ) )	// 대상생존
	{
		pEffect->liveTarget = (xtTargetLive) ParsingParam( cParam );
	} else
	if( XSAME( cAttrName, 129 ) )	// 소환
	{
		pEffect->strCreateObj = U82SZ( cParam );
	} else
	if( XSAME( cAttrName, 134 ) )	// 소환id
	{
		pEffect->idCreateObj = (ID)pAttr->IntValue();
	} else
	if( XSAME( cAttrName, 130 ) )	// 소환변수1
	{
		pEffect->createObjParam[0] = (float) pAttr->DoubleValue();
	} else
	if( XSAME( cAttrName, 130 ) )	// 소환변수1
	{
		pEffect->createObjParam[0] = (float) pAttr->DoubleValue();
	} else
	if( XSAME( cAttrName, 131 ) )	// 소환변수2
	{
		pEffect->createObjParam[1] = (float) pAttr->DoubleValue();
	} else
	if( XSAME( cAttrName, 132 ) )	// 소환변수3
	{
		pEffect->createObjParam[2] = (float) pAttr->DoubleValue();
	} else
	if( XSAME( cAttrName, 133 ) )	// 소환변수4
	{
		pEffect->createObjParam[1] = (float) pAttr->DoubleValue();
	} else
	if( XSAME( cAttrName, 44 ) )	// 사용
	{	
		pEffect->scriptUse = cParam;
	} else
	if( XSAME( cAttrName, 43 ) )	// 대상시전
	{	
		pEffect->scriptCast = cParam;
	} else
	if( XSAME( cAttrName, 39 ) )	// 발동시작
	{	
		pEffect->scriptInit = cParam;
	} else
	if( XSAME( cAttrName, 40 ) )	// 발동중
	{	
		pEffect->scriptProcess = cParam;
	} else
	if( XSAME( cAttrName, 41 ) )	// 발동끝
	{	
		pEffect->scriptUninit = cParam;
	} else
	if( XSAME( cAttrName, 42 ) )	// 도트
	{	
		pEffect->scriptDOT = cParam;
	} else
	if( XSAME( cAttrName, 171 ) )	// 면역여부
	{ 
		pEffect->bImmunity = (BOOL) ParsingParam( cParam );
	} else
	if( XSAME( cAttrName, 189 ) )	// 지속이펙트
	{	
		pEffect->m_PersistEff.m_strSpr = U82SZ( cParam );
	} else
	if( XSAME( cAttrName, 191 ) )	// 지속이펙트생성지점
	{
		pEffect->m_PersistEff.m_Point = (xtPoint) ParsingParam( cParam );
	} else
	if( XSAME( cAttrName, 190 ) )	// 지속이펙트id
	{	
		pEffect->m_PersistEff.m_idAct = (int)pAttr->IntValue();
	} else
	if( XSAME( cAttrName, 207 ) )	// 파라메터1
	{	
		pEffect->dwParam[ 0 ] = ParsingConstantAndNumber( cParam );
	} else
	if( XSAME( cAttrName, 208 ) )	// 파라메터2
	{	
		pEffect->dwParam[1] = ParsingConstantAndNumber( cParam );
	} else
	if( XSAME( cAttrName, 209 ) )	// 파라메터3
	{	
		pEffect->dwParam[2] = ParsingConstantAndNumber( cParam );
	} else
	if( XSAME( cAttrName, 210 ) )	// 파라메터4
	{	
		pEffect->dwParam[3] = ParsingConstantAndNumber( cParam );
	} else
	if( XE::IsSame(cAttrName, "debug") ) {
		int a = pAttr->IntValue();
		pEffect->m_Debug = a;
	} else
	if( CustomParsingEffect( pAttr, cAttrName, cParam, pSkillDat, pEffect ) == FALSE )
	{
		XLOGXN( "unknown variable name: %s", U82SZ( cAttrName ) );
		return FALSE;
	}
	return TRUE;
}
Ejemplo n.º 15
0
/**
 @brief 
 @param numWorkThread 0이면 시스템 코어에 맞춰 자동
*/
void XEWinSocketSvr::Create( WORD port, int numWorkThread )
{
	XBREAK( port == 0 );
	if( XWinNetwork::sStartUp() == false ) {
		XALERT( "WSAStartup failed" );
		return;
	}
	//
//	m_Socket = socket( AF_INET, SOCK_STREAM, 0 );
	m_Socket = WSASocket( PF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED );
	if( m_Socket == INVALID_SOCKET ) {
		XALERT( "create socket failed" );
		return;
	}
	SOCKADDR_IN addr;
	addr.sin_family = AF_INET;
	addr.sin_port = htons( port );
	addr.sin_addr.S_un.S_addr = htonl( INADDR_ANY );
	if( bind( m_Socket, ( struct sockaddr * )&addr, sizeof( addr ) ) == SOCKET_ERROR ) {
		XBREAK(1);
		XALERT( "Network bind error" );
		Destroy();
		return;
	}
	//
	m_Port = port;
	// 클라로부터 접속을 받을 준비
	if( listen( m_Socket, SOMAXCONN ) == SOCKET_ERROR ) {
		XALERT( "Network::listen error" );
		Destroy();
		return;
	}
	//
	m_pUserMng = CreateUserMng( m_maxConnect );
	XBREAK( m_pUserMng == NULL );
	// 유저 커스텀 create
	OnCreate(); // virtual
	// IOCP 객체 생성
	m_hIOCP = CreateIoCompletionPort( INVALID_HANDLE_VALUE, NULL, 0, 0 ); 
	// 워커 스레드 생성
	SYSTEM_INFO si;
	memset( &si, 0, sizeof(si));
	GetSystemInfo( &si );
#if defined(_DEBUG) && !defined(_XBOT)
	const int numThread = 4;		// 개발중엔 편의상 스레드 적게쓴다.
#else
	const int numThread = (numWorkThread == 0)? 
														(int)(si.dwNumberOfProcessors * 2)
													: numWorkThread;
#endif
	XBREAK( numThread <= 0 || numThread > 32 );
	for( int i = 0; i < numThread; ++i ) {
		m_aryThreadWork.push_back( CreateWorkThread() );
	}
	// accept( 클라이언트로부터의 접속대기 ) 스레드 생성
	m_thAccept = CreateAcceptThread();
	//
#if _DEV_LEVEL <= DLV_OPEN_BETA
	m_timerSec.Set( 1.f );
#endif
}
Ejemplo n.º 16
0
Archivo: Debug.cpp Proyecto: xahgo/tama
/**
 @brief 
*/
int __xLog( int type, LPCTSTR str, ...)
{
	XCheckRecursive checkRecursive;
	if( checkRecursive.IsRecursive() )
		return 1;
    TCHAR szBuff[1024];	// utf8이 길어서 넉넉하게 잡았다.
    va_list         vl;
	
    va_start(vl, str);
    _vstprintf_s(szBuff, str, vl);
    va_end(vl);
#ifdef _DEBUG
#else
	// 릴리즈 모드에선 로그나 에러모두 파일에 써야 한다
	{
		char szChar[8192];
		memset( szChar, 0, sizeof(szChar) );
		WideCharToMultiByte(CP_ACP, 0, szBuff, -1, szChar, 1024, NULL, NULL);
		int len = strlen(szChar);
		szChar[len] = '\n';
		szChar[len+1] = 0;
		FILE *fp;
#ifdef _XTOOL
		CString str = XE::GetCwd();
		str += "error.txt";
		fopen_s( &fp, Convert_TCHAR_To_char( str ), "a+" );
#else
		fopen_s( &fp, "error.txt", "a+" );
#endif
		//XBREAK( fp == NULL );
		if( XASSERT(fp) ) {
			xPutsTimeString( fp );
			fputs( szChar, fp );
			int size = ftell( fp );
			fclose(fp);
		}
#ifdef _GAME	// 게임에서만...
		// 로그파일이 무한정 쌓이지 않도록 한다.
		if( size >= 0xffff ) {
			fopen_s( &fp, "error.txt", "w+" );
			if( fp ) {
				xPutsTimeString( fp );
				fputs( szChar, fp );
				fclose( fp );
#ifndef _MASTER	// 마스터본이 아닐때만
				XALERT( "로그파일 삭제" );
#endif
			}
		}
#endif 
	}
#endif
	TCHAR szTitle[256] = {0,};
	if( type == XLOGTYPE_ERROR )
	{
		_tcscpy_s( szTitle, _T("Error!") );
//		::OutputDebugString( szBuff );		// TRACE로 한글출력이 안되서 이걸로 바꿈
	#ifdef _XTOOL
		AfxDebugBreak();
		AfxMessageBox( szBuff, MB_OK );
		// 툴에선 XERROR를 불러도 exit()시키지 않는다. 데이터를 저장하지 않은상태이기때문에 어떻게 해서든 살리려고 시도해야한다
	#else
//		::MessageBox( NULL, szBuff, szTitle, MB_OK );
		AfxMessageBox( szBuff, MB_OK );
		AfxDebugBreak();
		exit(1);
	#endif
	} else
	if( type == XLOGTYPE_LOG ) {
		// LOG
		_tcscpy_s( szTitle, _T("Message!") );
		_tcscat_s( szBuff, _T("\n") );
//		::OutputDebugString( szBuff );		// TRACE로 한글출력이 안되서 이걸로 바꿈
	} else
	if( type == XLOGTYPE_ALERT ) {
		AfxDebugBreak();
		_tcscpy_s( szTitle, _T("Message!") );
//		::OutputDebugString( szBuff );		// TRACE로 한글출력이 안되서 이걸로 바꿈
	#ifdef _XTOOL
		AfxMessageBox( szBuff, MB_OK );
	#else
//		int retv = ::MessageBox( NULL, szBuff, szTitle, MB_OK );
		AfxMessageBox( szBuff, MB_OK );
	#endif
	}
#ifdef _XCONSOLE
	CONSOLE( "%s", szBuff );		// 툴에서는 콘솔뷰로도 보낸다
#endif
	return 1;		// XBREAK()같은데서 쓰이므로 항상 1을 리턴해야함
}